Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(445)

Side by Side Diff: fusl/src/network/res_msend.c

Issue 1714623002: [fusl] clang-format fusl (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: headers too Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #include <sys/socket.h> 1 #include <sys/socket.h>
2 #include <netinet/in.h> 2 #include <netinet/in.h>
3 #include <netdb.h> 3 #include <netdb.h>
4 #include <arpa/inet.h> 4 #include <arpa/inet.h>
5 #include <stdint.h> 5 #include <stdint.h>
6 #include <string.h> 6 #include <string.h>
7 #include <poll.h> 7 #include <poll.h>
8 #include <time.h> 8 #include <time.h>
9 #include <ctype.h> 9 #include <ctype.h>
10 #include <unistd.h> 10 #include <unistd.h>
11 #include <errno.h> 11 #include <errno.h>
12 #include <pthread.h> 12 #include <pthread.h>
13 #include "stdio_impl.h" 13 #include "stdio_impl.h"
14 #include "syscall.h" 14 #include "syscall.h"
15 #include "lookup.h" 15 #include "lookup.h"
16 16
17 static void cleanup(void *p) 17 static void cleanup(void* p) {
18 { 18 __syscall(SYS_close, (intptr_t)p);
19 » __syscall(SYS_close, (intptr_t)p);
20 } 19 }
21 20
22 static unsigned long mtime() 21 static unsigned long mtime() {
23 { 22 struct timespec ts;
24 » struct timespec ts; 23 clock_gettime(CLOCK_REALTIME, &ts);
25 » clock_gettime(CLOCK_REALTIME, &ts); 24 return (unsigned long)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
26 » return (unsigned long)ts.tv_sec * 1000
27 » » + ts.tv_nsec / 1000000;
28 } 25 }
29 26
30 int __res_msend_rc(int nqueries, const unsigned char *const *queries, 27 int __res_msend_rc(int nqueries,
31 » const int *qlens, unsigned char *const *answers, int *alens, int asize, 28 const unsigned char* const* queries,
32 » const struct resolvconf *conf) 29 const int* qlens,
33 { 30 unsigned char* const* answers,
34 » int fd; 31 int* alens,
35 » int timeout, attempts, retry_interval, servfail_retry; 32 int asize,
36 » union { 33 const struct resolvconf* conf) {
37 » » struct sockaddr_in sin; 34 int fd;
38 » » struct sockaddr_in6 sin6; 35 int timeout, attempts, retry_interval, servfail_retry;
39 » } sa = {0}, ns[MAXNS] = {{0}}; 36 union {
40 » socklen_t sl = sizeof sa.sin; 37 struct sockaddr_in sin;
41 » int nns = 0; 38 struct sockaddr_in6 sin6;
42 » int family = AF_INET; 39 } sa = {0}, ns[MAXNS] = {{0}};
43 » int rlen; 40 socklen_t sl = sizeof sa.sin;
44 » int next; 41 int nns = 0;
45 » int i, j; 42 int family = AF_INET;
46 » int cs; 43 int rlen;
47 » struct pollfd pfd; 44 int next;
48 » unsigned long t0, t1, t2; 45 int i, j;
46 int cs;
47 struct pollfd pfd;
48 unsigned long t0, t1, t2;
49 49
50 » pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); 50 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
51 51
52 » timeout = 1000*conf->timeout; 52 timeout = 1000 * conf->timeout;
53 » attempts = conf->attempts; 53 attempts = conf->attempts;
54 54
55 » nns = conf->nns; 55 nns = conf->nns;
56 » for (nns=0; nns<conf->nns; nns++) { 56 for (nns = 0; nns < conf->nns; nns++) {
57 » » const struct address *iplit = &conf->ns[nns]; 57 const struct address* iplit = &conf->ns[nns];
58 » » if (iplit->family == AF_INET) { 58 if (iplit->family == AF_INET) {
59 » » » memcpy(&ns[nns].sin.sin_addr, iplit->addr, 4); 59 memcpy(&ns[nns].sin.sin_addr, iplit->addr, 4);
60 » » » ns[nns].sin.sin_port = htons(53); 60 ns[nns].sin.sin_port = htons(53);
61 » » » ns[nns].sin.sin_family = AF_INET; 61 ns[nns].sin.sin_family = AF_INET;
62 » » } else { 62 } else {
63 » » » sl = sizeof sa.sin6; 63 sl = sizeof sa.sin6;
64 » » » memcpy(&ns[nns].sin6.sin6_addr, iplit->addr, 16); 64 memcpy(&ns[nns].sin6.sin6_addr, iplit->addr, 16);
65 » » » ns[nns].sin6.sin6_port = htons(53); 65 ns[nns].sin6.sin6_port = htons(53);
66 » » » ns[nns].sin6.sin6_scope_id = iplit->scopeid; 66 ns[nns].sin6.sin6_scope_id = iplit->scopeid;
67 » » » ns[nns].sin6.sin6_family = family = AF_INET6; 67 ns[nns].sin6.sin6_family = family = AF_INET6;
68 » » } 68 }
69 » } 69 }
70 70
71 » /* Get local address and open/bind a socket */ 71 /* Get local address and open/bind a socket */
72 » sa.sin.sin_family = family; 72 sa.sin.sin_family = family;
73 » fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); 73 fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
74 74
75 » /* Handle case where system lacks IPv6 support */ 75 /* Handle case where system lacks IPv6 support */
76 » if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) { 76 if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
77 » » fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); 77 fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
78 » » family = AF_INET; 78 family = AF_INET;
79 » } 79 }
80 » if (fd < 0 || bind(fd, (void *)&sa, sl) < 0) return -1; 80 if (fd < 0 || bind(fd, (void*)&sa, sl) < 0)
81 return -1;
81 82
82 » /* Past this point, there are no errors. Each individual query will 83 /* Past this point, there are no errors. Each individual query will
83 » * yield either no reply (indicated by zero length) or an answer 84 * yield either no reply (indicated by zero length) or an answer
84 » * packet which is up to the caller to interpret. */ 85 * packet which is up to the caller to interpret. */
85 86
86 » pthread_cleanup_push(cleanup, (void *)(intptr_t)fd); 87 pthread_cleanup_push(cleanup, (void*)(intptr_t)fd);
87 » pthread_setcancelstate(cs, 0); 88 pthread_setcancelstate(cs, 0);
88 89
89 » /* Convert any IPv4 addresses in a mixed environment to v4-mapped */ 90 /* Convert any IPv4 addresses in a mixed environment to v4-mapped */
90 » if (family == AF_INET6) { 91 if (family == AF_INET6) {
91 » » setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0); 92 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
92 » » for (i=0; i<nns; i++) { 93 for (i = 0; i < nns; i++) {
93 » » » if (ns[i].sin.sin_family != AF_INET) continue; 94 if (ns[i].sin.sin_family != AF_INET)
94 » » » memcpy(ns[i].sin6.sin6_addr.s6_addr+12, 95 continue;
95 » » » » &ns[i].sin.sin_addr, 4); 96 memcpy(ns[i].sin6.sin6_addr.s6_addr + 12, &ns[i].sin.sin_addr, 4);
96 » » » memcpy(ns[i].sin6.sin6_addr.s6_addr, 97 memcpy(ns[i].sin6.sin6_addr.s6_addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
97 » » » » "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); 98 ns[i].sin6.sin6_family = AF_INET6;
98 » » » ns[i].sin6.sin6_family = AF_INET6; 99 ns[i].sin6.sin6_flowinfo = 0;
99 » » » ns[i].sin6.sin6_flowinfo = 0; 100 ns[i].sin6.sin6_scope_id = 0;
100 » » » ns[i].sin6.sin6_scope_id = 0; 101 }
101 » » } 102 }
102 » }
103 103
104 » memset(alens, 0, sizeof *alens * nqueries); 104 memset(alens, 0, sizeof *alens * nqueries);
105 105
106 » pfd.fd = fd; 106 pfd.fd = fd;
107 » pfd.events = POLLIN; 107 pfd.events = POLLIN;
108 » retry_interval = timeout / attempts; 108 retry_interval = timeout / attempts;
109 » next = 0; 109 next = 0;
110 » t0 = t2 = mtime(); 110 t0 = t2 = mtime();
111 » t1 = t2 - retry_interval; 111 t1 = t2 - retry_interval;
112 112
113 » for (; t2-t0 < timeout; t2=mtime()) { 113 for (; t2 - t0 < timeout; t2 = mtime()) {
114 » » if (t2-t1 >= retry_interval) { 114 if (t2 - t1 >= retry_interval) {
115 » » » /* Query all configured namservers in parallel */ 115 /* Query all configured namservers in parallel */
116 » » » for (i=0; i<nqueries; i++) 116 for (i = 0; i < nqueries; i++)
117 » » » » if (!alens[i]) 117 if (!alens[i])
118 » » » » » for (j=0; j<nns; j++) 118 for (j = 0; j < nns; j++)
119 » » » » » » sendto(fd, queries[i], 119 sendto(fd, queries[i], qlens[i], MSG_NOSIGNAL, (void*)&ns[j], sl);
120 » » » » » » » qlens[i], MSG_NOSIGNAL, 120 t1 = t2;
121 » » » » » » » (void *)&ns[j], sl); 121 servfail_retry = 2 * nqueries;
122 » » » t1 = t2; 122 }
123 » » » servfail_retry = 2 * nqueries;
124 » » }
125 123
126 » » /* Wait for a response, or until time to retry */ 124 /* Wait for a response, or until time to retry */
127 » » if (poll(&pfd, 1, t1+retry_interval-t2) <= 0) continue; 125 if (poll(&pfd, 1, t1 + retry_interval - t2) <= 0)
126 continue;
128 127
129 » » while ((rlen = recvfrom(fd, answers[next], asize, 0, 128 while ((rlen = recvfrom(fd, answers[next], asize, 0, (void*)&sa,
130 » » (void *)&sa, (socklen_t[1]){sl})) >= 0) { 129 (socklen_t[1]){sl})) >= 0) {
130 /* Ignore non-identifiable packets */
131 if (rlen < 4)
132 continue;
131 133
132 » » » /* Ignore non-identifiable packets */ 134 /* Ignore replies from addresses we didn't send to */
133 » » » if (rlen < 4) continue; 135 for (j = 0; j < nns && memcmp(ns + j, &sa, sl); j++)
136 ;
137 if (j == nns)
138 continue;
134 139
135 » » » /* Ignore replies from addresses we didn't send to */ 140 /* Find which query this answer goes with, if any */
136 » » » for (j=0; j<nns && memcmp(ns+j, &sa, sl); j++); 141 for (i = next; i < nqueries && (answers[next][0] != queries[i][0] ||
137 » » » if (j==nns) continue; 142 answers[next][1] != queries[i][1]);
143 i++)
144 ;
145 if (i == nqueries)
146 continue;
147 if (alens[i])
148 continue;
138 149
139 » » » /* Find which query this answer goes with, if any */ 150 /* Only accept positive or negative responses;
140 » » » for (i=next; i<nqueries && ( 151 * retry immediately on server failure, and ignore
141 » » » » answers[next][0] != queries[i][0] || 152 * all other codes such as refusal. */
142 » » » » answers[next][1] != queries[i][1] ); i++); 153 switch (answers[next][3] & 15) {
143 » » » if (i==nqueries) continue; 154 case 0:
144 » » » if (alens[i]) continue; 155 case 3:
156 break;
157 case 2:
158 if (servfail_retry && servfail_retry--)
159 sendto(fd, queries[i], qlens[i], MSG_NOSIGNAL, (void*)&ns[j], sl);
160 default:
161 continue;
162 }
145 163
146 » » » /* Only accept positive or negative responses; 164 /* Store answer in the right slot, or update next
147 » » » * retry immediately on server failure, and ignore 165 * available temp slot if it's already in place. */
148 » » » * all other codes such as refusal. */ 166 alens[i] = rlen;
149 » » » switch (answers[next][3] & 15) { 167 if (i == next)
150 » » » case 0: 168 for (; next < nqueries && alens[next]; next++)
151 » » » case 3: 169 ;
152 » » » » break; 170 else
153 » » » case 2: 171 memcpy(answers[i], answers[next], rlen);
154 » » » » if (servfail_retry && servfail_retry--)
155 » » » » » sendto(fd, queries[i],
156 » » » » » » qlens[i], MSG_NOSIGNAL,
157 » » » » » » (void *)&ns[j], sl);
158 » » » default:
159 » » » » continue;
160 » » » }
161 172
162 » » » /* Store answer in the right slot, or update next 173 if (next == nqueries)
163 » » » * available temp slot if it's already in place. */ 174 goto out;
164 » » » alens[i] = rlen; 175 }
165 » » » if (i == next) 176 }
166 » » » » for (; next<nqueries && alens[next]; next++); 177 out:
167 » » » else 178 pthread_cleanup_pop(1);
168 » » » » memcpy(answers[i], answers[next], rlen);
169 179
170 » » » if (next == nqueries) goto out; 180 return 0;
171 » » }
172 » }
173 out:
174 » pthread_cleanup_pop(1);
175
176 » return 0;
177 } 181 }
178 182
179 int __res_msend(int nqueries, const unsigned char *const *queries, 183 int __res_msend(int nqueries,
180 » const int *qlens, unsigned char *const *answers, int *alens, int asize) 184 const unsigned char* const* queries,
181 { 185 const int* qlens,
182 » struct resolvconf conf; 186 unsigned char* const* answers,
183 » if (__get_resolv_conf(&conf, 0, 0) < 0) return -1; 187 int* alens,
184 » return __res_msend_rc(nqueries, queries, qlens, answers, alens, asize, & conf); 188 int asize) {
189 struct resolvconf conf;
190 if (__get_resolv_conf(&conf, 0, 0) < 0)
191 return -1;
192 return __res_msend_rc(nqueries, queries, qlens, answers, alens, asize, &conf);
185 } 193 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698