|
1 /* |
|
2 * Copyright (c) 2009-2012 Nick Mathewson and Niels Provos |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions |
|
6 * are met: |
|
7 * 1. Redistributions of source code must retain the above copyright |
|
8 * notice, this list of conditions and the following disclaimer. |
|
9 * 2. Redistributions in binary form must reproduce the above copyright |
|
10 * notice, this list of conditions and the following disclaimer in the |
|
11 * documentation and/or other materials provided with the distribution. |
|
12 * 3. The name of the author may not be used to endorse or promote products |
|
13 * derived from this software without specific prior written permission. |
|
14 * |
|
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
25 */ |
|
26 #ifdef WIN32 |
|
27 #include <winsock2.h> |
|
28 #include <windows.h> |
|
29 #include <ws2tcpip.h> |
|
30 #endif |
|
31 |
|
32 #include "event2/event-config.h" |
|
33 |
|
34 #include <sys/types.h> |
|
35 |
|
36 #ifndef WIN32 |
|
37 #include <sys/socket.h> |
|
38 #include <netinet/in.h> |
|
39 #include <arpa/inet.h> |
|
40 #include <unistd.h> |
|
41 #endif |
|
42 #ifdef _EVENT_HAVE_NETINET_IN6_H |
|
43 #include <netinet/in6.h> |
|
44 #endif |
|
45 #ifdef _EVENT_HAVE_SYS_WAIT_H |
|
46 #include <sys/wait.h> |
|
47 #endif |
|
48 #include <signal.h> |
|
49 #include <stdio.h> |
|
50 #include <stdlib.h> |
|
51 #include <string.h> |
|
52 |
|
53 #include "event2/event.h" |
|
54 #include "event2/util.h" |
|
55 #include "../ipv6-internal.h" |
|
56 #include "../util-internal.h" |
|
57 #include "../log-internal.h" |
|
58 #include "../strlcpy-internal.h" |
|
59 |
|
60 #include "regress.h" |
|
61 |
|
62 enum entry_status { NORMAL, CANONICAL, BAD }; |
|
63 |
|
64 /* This is a big table of results we expect from generating and parsing */ |
|
65 static struct ipv4_entry { |
|
66 const char *addr; |
|
67 ev_uint32_t res; |
|
68 enum entry_status status; |
|
69 } ipv4_entries[] = { |
|
70 { "1.2.3.4", 0x01020304u, CANONICAL }, |
|
71 { "255.255.255.255", 0xffffffffu, CANONICAL }, |
|
72 { "256.0.0.0", 0, BAD }, |
|
73 { "ABC", 0, BAD }, |
|
74 { "1.2.3.4.5", 0, BAD }, |
|
75 { "176.192.208.244", 0xb0c0d0f4, CANONICAL }, |
|
76 { NULL, 0, BAD }, |
|
77 }; |
|
78 |
|
79 static struct ipv6_entry { |
|
80 const char *addr; |
|
81 ev_uint32_t res[4]; |
|
82 enum entry_status status; |
|
83 } ipv6_entries[] = { |
|
84 { "::", { 0, 0, 0, 0, }, CANONICAL }, |
|
85 { "0:0:0:0:0:0:0:0", { 0, 0, 0, 0, }, NORMAL }, |
|
86 { "::1", { 0, 0, 0, 1, }, CANONICAL }, |
|
87 { "::1.2.3.4", { 0, 0, 0, 0x01020304, }, CANONICAL }, |
|
88 { "ffff:1::", { 0xffff0001u, 0, 0, 0, }, CANONICAL }, |
|
89 { "ffff:0000::", { 0xffff0000u, 0, 0, 0, }, NORMAL }, |
|
90 { "ffff::1234", { 0xffff0000u, 0, 0, 0x1234, }, CANONICAL }, |
|
91 { "0102::1.2.3.4", {0x01020000u, 0, 0, 0x01020304u }, NORMAL }, |
|
92 { "::9:c0a8:1:1", { 0, 0, 0x0009c0a8u, 0x00010001u }, CANONICAL }, |
|
93 { "::ffff:1.2.3.4", { 0, 0, 0x000ffffu, 0x01020304u }, CANONICAL }, |
|
94 { "FFFF::", { 0xffff0000u, 0, 0, 0 }, NORMAL }, |
|
95 { "foobar.", { 0, 0, 0, 0 }, BAD }, |
|
96 { "foobar", { 0, 0, 0, 0 }, BAD }, |
|
97 { "fo:obar", { 0, 0, 0, 0 }, BAD }, |
|
98 { "ffff", { 0, 0, 0, 0 }, BAD }, |
|
99 { "fffff::", { 0, 0, 0, 0 }, BAD }, |
|
100 { "fffff::", { 0, 0, 0, 0 }, BAD }, |
|
101 { "::1.0.1.1000", { 0, 0, 0, 0 }, BAD }, |
|
102 { "1:2:33333:4::", { 0, 0, 0, 0 }, BAD }, |
|
103 { "1:2:3:4:5:6:7:8:9", { 0, 0, 0, 0 }, BAD }, |
|
104 { "1::2::3", { 0, 0, 0, 0 }, BAD }, |
|
105 { ":::1", { 0, 0, 0, 0 }, BAD }, |
|
106 { NULL, { 0, 0, 0, 0, }, BAD }, |
|
107 }; |
|
108 |
|
109 static void |
|
110 regress_ipv4_parse(void *ptr) |
|
111 { |
|
112 int i; |
|
113 for (i = 0; ipv4_entries[i].addr; ++i) { |
|
114 char written[128]; |
|
115 struct ipv4_entry *ent = &ipv4_entries[i]; |
|
116 struct in_addr in; |
|
117 int r; |
|
118 r = evutil_inet_pton(AF_INET, ent->addr, &in); |
|
119 if (r == 0) { |
|
120 if (ent->status != BAD) { |
|
121 TT_FAIL(("%s did not parse, but it's a good address!", |
|
122 ent->addr)); |
|
123 } |
|
124 continue; |
|
125 } |
|
126 if (ent->status == BAD) { |
|
127 TT_FAIL(("%s parsed, but we expected an error", ent->addr)); |
|
128 continue; |
|
129 } |
|
130 if (ntohl(in.s_addr) != ent->res) { |
|
131 TT_FAIL(("%s parsed to %lx, but we expected %lx", ent->addr, |
|
132 (unsigned long)ntohl(in.s_addr), |
|
133 (unsigned long)ent->res)); |
|
134 continue; |
|
135 } |
|
136 if (ent->status == CANONICAL) { |
|
137 const char *w = evutil_inet_ntop(AF_INET, &in, written, |
|
138 sizeof(written)); |
|
139 if (!w) { |
|
140 TT_FAIL(("Tried to write out %s; got NULL.", ent->addr)); |
|
141 continue; |
|
142 } |
|
143 if (strcmp(written, ent->addr)) { |
|
144 TT_FAIL(("Tried to write out %s; got %s", |
|
145 ent->addr, written)); |
|
146 continue; |
|
147 } |
|
148 } |
|
149 |
|
150 } |
|
151 |
|
152 } |
|
153 |
|
154 static void |
|
155 regress_ipv6_parse(void *ptr) |
|
156 { |
|
157 #ifdef AF_INET6 |
|
158 int i, j; |
|
159 |
|
160 for (i = 0; ipv6_entries[i].addr; ++i) { |
|
161 char written[128]; |
|
162 struct ipv6_entry *ent = &ipv6_entries[i]; |
|
163 struct in6_addr in6; |
|
164 int r; |
|
165 r = evutil_inet_pton(AF_INET6, ent->addr, &in6); |
|
166 if (r == 0) { |
|
167 if (ent->status != BAD) |
|
168 TT_FAIL(("%s did not parse, but it's a good address!", |
|
169 ent->addr)); |
|
170 continue; |
|
171 } |
|
172 if (ent->status == BAD) { |
|
173 TT_FAIL(("%s parsed, but we expected an error", ent->addr)); |
|
174 continue; |
|
175 } |
|
176 for (j = 0; j < 4; ++j) { |
|
177 /* Can't use s6_addr32 here; some don't have it. */ |
|
178 ev_uint32_t u = |
|
179 (in6.s6_addr[j*4 ] << 24) | |
|
180 (in6.s6_addr[j*4+1] << 16) | |
|
181 (in6.s6_addr[j*4+2] << 8) | |
|
182 (in6.s6_addr[j*4+3]); |
|
183 if (u != ent->res[j]) { |
|
184 TT_FAIL(("%s did not parse as expected.", ent->addr)); |
|
185 continue; |
|
186 } |
|
187 } |
|
188 if (ent->status == CANONICAL) { |
|
189 const char *w = evutil_inet_ntop(AF_INET6, &in6, written, |
|
190 sizeof(written)); |
|
191 if (!w) { |
|
192 TT_FAIL(("Tried to write out %s; got NULL.", ent->addr)); |
|
193 continue; |
|
194 } |
|
195 if (strcmp(written, ent->addr)) { |
|
196 TT_FAIL(("Tried to write out %s; got %s", ent->addr, written)); |
|
197 continue; |
|
198 } |
|
199 } |
|
200 |
|
201 } |
|
202 #else |
|
203 TT_BLATHER(("Skipping IPv6 address parsing.")); |
|
204 #endif |
|
205 } |
|
206 |
|
207 static struct sa_port_ent { |
|
208 const char *parse; |
|
209 int safamily; |
|
210 const char *addr; |
|
211 int port; |
|
212 } sa_port_ents[] = { |
|
213 { "[ffff::1]:1000", AF_INET6, "ffff::1", 1000 }, |
|
214 { "[ffff::1]", AF_INET6, "ffff::1", 0 }, |
|
215 { "[ffff::1", 0, NULL, 0 }, |
|
216 { "[ffff::1]:65599", 0, NULL, 0 }, |
|
217 { "[ffff::1]:0", 0, NULL, 0 }, |
|
218 { "[ffff::1]:-1", 0, NULL, 0 }, |
|
219 { "::1", AF_INET6, "::1", 0 }, |
|
220 { "1:2::1", AF_INET6, "1:2::1", 0 }, |
|
221 { "192.168.0.1:50", AF_INET, "192.168.0.1", 50 }, |
|
222 { "1.2.3.4", AF_INET, "1.2.3.4", 0 }, |
|
223 { NULL, 0, NULL, 0 }, |
|
224 }; |
|
225 |
|
226 static void |
|
227 regress_sockaddr_port_parse(void *ptr) |
|
228 { |
|
229 struct sockaddr_storage ss; |
|
230 int i, r; |
|
231 |
|
232 for (i = 0; sa_port_ents[i].parse; ++i) { |
|
233 struct sa_port_ent *ent = &sa_port_ents[i]; |
|
234 int len = sizeof(ss); |
|
235 memset(&ss, 0, sizeof(ss)); |
|
236 r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len); |
|
237 if (r < 0) { |
|
238 if (ent->safamily) |
|
239 TT_FAIL(("Couldn't parse %s!", ent->parse)); |
|
240 continue; |
|
241 } else if (! ent->safamily) { |
|
242 TT_FAIL(("Shouldn't have been able to parse %s!", ent->parse)); |
|
243 continue; |
|
244 } |
|
245 if (ent->safamily == AF_INET) { |
|
246 struct sockaddr_in sin; |
|
247 memset(&sin, 0, sizeof(sin)); |
|
248 #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN |
|
249 sin.sin_len = sizeof(sin); |
|
250 #endif |
|
251 sin.sin_family = AF_INET; |
|
252 sin.sin_port = htons(ent->port); |
|
253 r = evutil_inet_pton(AF_INET, ent->addr, &sin.sin_addr); |
|
254 if (1 != r) { |
|
255 TT_FAIL(("Couldn't parse ipv4 target %s.", ent->addr)); |
|
256 } else if (memcmp(&sin, &ss, sizeof(sin))) { |
|
257 TT_FAIL(("Parse for %s was not as expected.", ent->parse)); |
|
258 } else if (len != sizeof(sin)) { |
|
259 TT_FAIL(("Length for %s not as expected.",ent->parse)); |
|
260 } |
|
261 } else { |
|
262 struct sockaddr_in6 sin6; |
|
263 memset(&sin6, 0, sizeof(sin6)); |
|
264 #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN |
|
265 sin6.sin6_len = sizeof(sin6); |
|
266 #endif |
|
267 sin6.sin6_family = AF_INET6; |
|
268 sin6.sin6_port = htons(ent->port); |
|
269 r = evutil_inet_pton(AF_INET6, ent->addr, &sin6.sin6_addr); |
|
270 if (1 != r) { |
|
271 TT_FAIL(("Couldn't parse ipv6 target %s.", ent->addr)); |
|
272 } else if (memcmp(&sin6, &ss, sizeof(sin6))) { |
|
273 TT_FAIL(("Parse for %s was not as expected.", ent->parse)); |
|
274 } else if (len != sizeof(sin6)) { |
|
275 TT_FAIL(("Length for %s not as expected.",ent->parse)); |
|
276 } |
|
277 } |
|
278 } |
|
279 } |
|
280 |
|
281 |
|
282 static void |
|
283 regress_sockaddr_port_format(void *ptr) |
|
284 { |
|
285 struct sockaddr_storage ss; |
|
286 int len; |
|
287 const char *cp; |
|
288 char cbuf[128]; |
|
289 int r; |
|
290 |
|
291 len = sizeof(ss); |
|
292 r = evutil_parse_sockaddr_port("192.168.1.1:80", |
|
293 (struct sockaddr*)&ss, &len); |
|
294 tt_int_op(r,==,0); |
|
295 cp = evutil_format_sockaddr_port( |
|
296 (struct sockaddr*)&ss, cbuf, sizeof(cbuf)); |
|
297 tt_ptr_op(cp,==,cbuf); |
|
298 tt_str_op(cp,==,"192.168.1.1:80"); |
|
299 |
|
300 len = sizeof(ss); |
|
301 r = evutil_parse_sockaddr_port("[ff00::8010]:999", |
|
302 (struct sockaddr*)&ss, &len); |
|
303 tt_int_op(r,==,0); |
|
304 cp = evutil_format_sockaddr_port( |
|
305 (struct sockaddr*)&ss, cbuf, sizeof(cbuf)); |
|
306 tt_ptr_op(cp,==,cbuf); |
|
307 tt_str_op(cp,==,"[ff00::8010]:999"); |
|
308 |
|
309 ss.ss_family=99; |
|
310 cp = evutil_format_sockaddr_port( |
|
311 (struct sockaddr*)&ss, cbuf, sizeof(cbuf)); |
|
312 tt_ptr_op(cp,==,cbuf); |
|
313 tt_str_op(cp,==,"<addr with socktype 99>"); |
|
314 end: |
|
315 ; |
|
316 } |
|
317 |
|
318 static struct sa_pred_ent { |
|
319 const char *parse; |
|
320 |
|
321 int is_loopback; |
|
322 } sa_pred_entries[] = { |
|
323 { "127.0.0.1", 1 }, |
|
324 { "127.0.3.2", 1 }, |
|
325 { "128.1.2.3", 0 }, |
|
326 { "18.0.0.1", 0 }, |
|
327 { "129.168.1.1", 0 }, |
|
328 |
|
329 { "::1", 1 }, |
|
330 { "::0", 0 }, |
|
331 { "f::1", 0 }, |
|
332 { "::501", 0 }, |
|
333 { NULL, 0 }, |
|
334 |
|
335 }; |
|
336 |
|
337 static void |
|
338 test_evutil_sockaddr_predicates(void *ptr) |
|
339 { |
|
340 struct sockaddr_storage ss; |
|
341 int r, i; |
|
342 |
|
343 for (i=0; sa_pred_entries[i].parse; ++i) { |
|
344 struct sa_pred_ent *ent = &sa_pred_entries[i]; |
|
345 int len = sizeof(ss); |
|
346 |
|
347 r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len); |
|
348 |
|
349 if (r<0) { |
|
350 TT_FAIL(("Couldn't parse %s!", ent->parse)); |
|
351 continue; |
|
352 } |
|
353 |
|
354 /* sockaddr_is_loopback */ |
|
355 if (ent->is_loopback != evutil_sockaddr_is_loopback((struct sockaddr*)&ss)) { |
|
356 TT_FAIL(("evutil_sockaddr_loopback(%s) not as expected", |
|
357 ent->parse)); |
|
358 } |
|
359 } |
|
360 } |
|
361 |
|
362 static void |
|
363 test_evutil_strtoll(void *ptr) |
|
364 { |
|
365 const char *s; |
|
366 char *endptr; |
|
367 |
|
368 tt_want(evutil_strtoll("5000000000", NULL, 10) == |
|
369 ((ev_int64_t)5000000)*1000); |
|
370 tt_want(evutil_strtoll("-5000000000", NULL, 10) == |
|
371 ((ev_int64_t)5000000)*-1000); |
|
372 s = " 99999stuff"; |
|
373 tt_want(evutil_strtoll(s, &endptr, 10) == (ev_int64_t)99999); |
|
374 tt_want(endptr == s+6); |
|
375 tt_want(evutil_strtoll("foo", NULL, 10) == 0); |
|
376 } |
|
377 |
|
378 static void |
|
379 test_evutil_snprintf(void *ptr) |
|
380 { |
|
381 char buf[16]; |
|
382 int r; |
|
383 ev_uint64_t u64 = ((ev_uint64_t)1000000000)*200; |
|
384 ev_int64_t i64 = -1 * (ev_int64_t) u64; |
|
385 size_t size = 8000; |
|
386 ev_ssize_t ssize = -9000; |
|
387 |
|
388 r = evutil_snprintf(buf, sizeof(buf), "%d %d", 50, 100); |
|
389 tt_str_op(buf, ==, "50 100"); |
|
390 tt_int_op(r, ==, 6); |
|
391 |
|
392 r = evutil_snprintf(buf, sizeof(buf), "longish %d", 1234567890); |
|
393 tt_str_op(buf, ==, "longish 1234567"); |
|
394 tt_int_op(r, ==, 18); |
|
395 |
|
396 r = evutil_snprintf(buf, sizeof(buf), EV_U64_FMT, EV_U64_ARG(u64)); |
|
397 tt_str_op(buf, ==, "200000000000"); |
|
398 tt_int_op(r, ==, 12); |
|
399 |
|
400 r = evutil_snprintf(buf, sizeof(buf), EV_I64_FMT, EV_I64_ARG(i64)); |
|
401 tt_str_op(buf, ==, "-200000000000"); |
|
402 tt_int_op(r, ==, 13); |
|
403 |
|
404 r = evutil_snprintf(buf, sizeof(buf), EV_SIZE_FMT" "EV_SSIZE_FMT, |
|
405 EV_SIZE_ARG(size), EV_SSIZE_ARG(ssize)); |
|
406 tt_str_op(buf, ==, "8000 -9000"); |
|
407 tt_int_op(r, ==, 10); |
|
408 |
|
409 end: |
|
410 ; |
|
411 } |
|
412 |
|
413 static void |
|
414 test_evutil_casecmp(void *ptr) |
|
415 { |
|
416 tt_int_op(evutil_ascii_strcasecmp("ABC", "ABC"), ==, 0); |
|
417 tt_int_op(evutil_ascii_strcasecmp("ABC", "abc"), ==, 0); |
|
418 tt_int_op(evutil_ascii_strcasecmp("ABC", "abcd"), <, 0); |
|
419 tt_int_op(evutil_ascii_strcasecmp("ABC", "abb"), >, 0); |
|
420 tt_int_op(evutil_ascii_strcasecmp("ABCd", "abc"), >, 0); |
|
421 |
|
422 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 100), ==, 0); |
|
423 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 4), ==, 0); |
|
424 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEXXXX", 4), ==, 0); |
|
425 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibE", 4), ==, 0); |
|
426 tt_int_op(evutil_ascii_strncasecmp("Libe", "LibEvEnT", 4), ==, 0); |
|
427 tt_int_op(evutil_ascii_strncasecmp("Lib", "LibEvEnT", 4), <, 0); |
|
428 tt_int_op(evutil_ascii_strncasecmp("abc", "def", 99), <, 0); |
|
429 tt_int_op(evutil_ascii_strncasecmp("Z", "qrst", 1), >, 0); |
|
430 end: |
|
431 ; |
|
432 } |
|
433 |
|
434 static int logsev = 0; |
|
435 static char *logmsg = NULL; |
|
436 |
|
437 static void |
|
438 logfn(int severity, const char *msg) |
|
439 { |
|
440 logsev = severity; |
|
441 tt_want(msg); |
|
442 if (msg) { |
|
443 if (logmsg) |
|
444 free(logmsg); |
|
445 logmsg = strdup(msg); |
|
446 } |
|
447 } |
|
448 |
|
449 static int fatal_want_severity = 0; |
|
450 static const char *fatal_want_message = NULL; |
|
451 static void |
|
452 fatalfn(int exitcode) |
|
453 { |
|
454 if (logsev != fatal_want_severity || |
|
455 !logmsg || |
|
456 strcmp(logmsg, fatal_want_message)) |
|
457 exit(0); |
|
458 else |
|
459 exit(exitcode); |
|
460 } |
|
461 |
|
462 #ifndef WIN32 |
|
463 #define CAN_CHECK_ERR |
|
464 static void |
|
465 check_error_logging(void (*fn)(void), int wantexitcode, |
|
466 int wantseverity, const char *wantmsg) |
|
467 { |
|
468 pid_t pid; |
|
469 int status = 0, exitcode; |
|
470 fatal_want_severity = wantseverity; |
|
471 fatal_want_message = wantmsg; |
|
472 if ((pid = regress_fork()) == 0) { |
|
473 /* child process */ |
|
474 fn(); |
|
475 exit(0); /* should be unreachable. */ |
|
476 } else { |
|
477 wait(&status); |
|
478 exitcode = WEXITSTATUS(status); |
|
479 tt_int_op(wantexitcode, ==, exitcode); |
|
480 } |
|
481 end: |
|
482 ; |
|
483 } |
|
484 |
|
485 static void |
|
486 errx_fn(void) |
|
487 { |
|
488 event_errx(2, "Fatal error; too many kumquats (%d)", 5); |
|
489 } |
|
490 |
|
491 static void |
|
492 err_fn(void) |
|
493 { |
|
494 errno = ENOENT; |
|
495 event_err(5,"Couldn't open %s", "/very/bad/file"); |
|
496 } |
|
497 |
|
498 static void |
|
499 sock_err_fn(void) |
|
500 { |
|
501 evutil_socket_t fd = socket(AF_INET, SOCK_STREAM, 0); |
|
502 #ifdef WIN32 |
|
503 EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK); |
|
504 #else |
|
505 errno = EAGAIN; |
|
506 #endif |
|
507 event_sock_err(20, fd, "Unhappy socket"); |
|
508 } |
|
509 #endif |
|
510 |
|
511 static void |
|
512 test_evutil_log(void *ptr) |
|
513 { |
|
514 evutil_socket_t fd = -1; |
|
515 char buf[128]; |
|
516 |
|
517 event_set_log_callback(logfn); |
|
518 event_set_fatal_callback(fatalfn); |
|
519 #define RESET() do { \ |
|
520 logsev = 0; \ |
|
521 if (logmsg) free(logmsg); \ |
|
522 logmsg = NULL; \ |
|
523 } while (0) |
|
524 #define LOGEQ(sev,msg) do { \ |
|
525 tt_int_op(logsev,==,sev); \ |
|
526 tt_assert(logmsg != NULL); \ |
|
527 tt_str_op(logmsg,==,msg); \ |
|
528 } while (0) |
|
529 |
|
530 #ifdef CAN_CHECK_ERR |
|
531 /* We need to disable these tests for now. Previously, the logging |
|
532 * module didn't enforce the requirement that a fatal callback |
|
533 * actually exit. Now, it exits no matter what, so if we wan to |
|
534 * reinstate these tests, we'll need to fork for each one. */ |
|
535 check_error_logging(errx_fn, 2, _EVENT_LOG_ERR, |
|
536 "Fatal error; too many kumquats (5)"); |
|
537 RESET(); |
|
538 #endif |
|
539 |
|
540 event_warnx("Far too many %s (%d)", "wombats", 99); |
|
541 LOGEQ(_EVENT_LOG_WARN, "Far too many wombats (99)"); |
|
542 RESET(); |
|
543 |
|
544 event_msgx("Connecting lime to coconut"); |
|
545 LOGEQ(_EVENT_LOG_MSG, "Connecting lime to coconut"); |
|
546 RESET(); |
|
547 |
|
548 event_debug(("A millisecond passed! We should log that!")); |
|
549 #ifdef USE_DEBUG |
|
550 LOGEQ(_EVENT_LOG_DEBUG, "A millisecond passed! We should log that!"); |
|
551 #else |
|
552 tt_int_op(logsev,==,0); |
|
553 tt_ptr_op(logmsg,==,NULL); |
|
554 #endif |
|
555 RESET(); |
|
556 |
|
557 /* Try with an errno. */ |
|
558 errno = ENOENT; |
|
559 event_warn("Couldn't open %s", "/bad/file"); |
|
560 evutil_snprintf(buf, sizeof(buf), |
|
561 "Couldn't open /bad/file: %s",strerror(ENOENT)); |
|
562 LOGEQ(_EVENT_LOG_WARN,buf); |
|
563 RESET(); |
|
564 |
|
565 #ifdef CAN_CHECK_ERR |
|
566 evutil_snprintf(buf, sizeof(buf), |
|
567 "Couldn't open /very/bad/file: %s",strerror(ENOENT)); |
|
568 check_error_logging(err_fn, 5, _EVENT_LOG_ERR, buf); |
|
569 RESET(); |
|
570 #endif |
|
571 |
|
572 /* Try with a socket errno. */ |
|
573 fd = socket(AF_INET, SOCK_STREAM, 0); |
|
574 #ifdef WIN32 |
|
575 evutil_snprintf(buf, sizeof(buf), |
|
576 "Unhappy socket: %s", |
|
577 evutil_socket_error_to_string(WSAEWOULDBLOCK)); |
|
578 EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK); |
|
579 #else |
|
580 evutil_snprintf(buf, sizeof(buf), |
|
581 "Unhappy socket: %s", strerror(EAGAIN)); |
|
582 errno = EAGAIN; |
|
583 #endif |
|
584 event_sock_warn(fd, "Unhappy socket"); |
|
585 LOGEQ(_EVENT_LOG_WARN, buf); |
|
586 RESET(); |
|
587 |
|
588 #ifdef CAN_CHECK_ERR |
|
589 check_error_logging(sock_err_fn, 20, _EVENT_LOG_ERR, buf); |
|
590 RESET(); |
|
591 #endif |
|
592 |
|
593 #undef RESET |
|
594 #undef LOGEQ |
|
595 end: |
|
596 if (logmsg) |
|
597 free(logmsg); |
|
598 if (fd >= 0) |
|
599 evutil_closesocket(fd); |
|
600 } |
|
601 |
|
602 static void |
|
603 test_evutil_strlcpy(void *arg) |
|
604 { |
|
605 char buf[8]; |
|
606 |
|
607 /* Successful case. */ |
|
608 tt_int_op(5, ==, strlcpy(buf, "Hello", sizeof(buf))); |
|
609 tt_str_op(buf, ==, "Hello"); |
|
610 |
|
611 /* Overflow by a lot. */ |
|
612 tt_int_op(13, ==, strlcpy(buf, "pentasyllabic", sizeof(buf))); |
|
613 tt_str_op(buf, ==, "pentasy"); |
|
614 |
|
615 /* Overflow by exactly one. */ |
|
616 tt_int_op(8, ==, strlcpy(buf, "overlong", sizeof(buf))); |
|
617 tt_str_op(buf, ==, "overlon"); |
|
618 end: |
|
619 ; |
|
620 } |
|
621 |
|
622 struct example_struct { |
|
623 const char *a; |
|
624 const char *b; |
|
625 long c; |
|
626 }; |
|
627 |
|
628 static void |
|
629 test_evutil_upcast(void *arg) |
|
630 { |
|
631 struct example_struct es1; |
|
632 const char **cp; |
|
633 es1.a = "World"; |
|
634 es1.b = "Hello"; |
|
635 es1.c = -99; |
|
636 |
|
637 tt_int_op(evutil_offsetof(struct example_struct, b), ==, sizeof(char*)); |
|
638 |
|
639 cp = &es1.b; |
|
640 tt_ptr_op(EVUTIL_UPCAST(cp, struct example_struct, b), ==, &es1); |
|
641 |
|
642 end: |
|
643 ; |
|
644 } |
|
645 |
|
646 static void |
|
647 test_evutil_integers(void *arg) |
|
648 { |
|
649 ev_int64_t i64; |
|
650 ev_uint64_t u64; |
|
651 ev_int32_t i32; |
|
652 ev_uint32_t u32; |
|
653 ev_int16_t i16; |
|
654 ev_uint16_t u16; |
|
655 ev_int8_t i8; |
|
656 ev_uint8_t u8; |
|
657 |
|
658 void *ptr; |
|
659 ev_intptr_t iptr; |
|
660 ev_uintptr_t uptr; |
|
661 |
|
662 ev_ssize_t ssize; |
|
663 |
|
664 tt_int_op(sizeof(u64), ==, 8); |
|
665 tt_int_op(sizeof(i64), ==, 8); |
|
666 tt_int_op(sizeof(u32), ==, 4); |
|
667 tt_int_op(sizeof(i32), ==, 4); |
|
668 tt_int_op(sizeof(u16), ==, 2); |
|
669 tt_int_op(sizeof(i16), ==, 2); |
|
670 tt_int_op(sizeof(u8), ==, 1); |
|
671 tt_int_op(sizeof(i8), ==, 1); |
|
672 |
|
673 tt_int_op(sizeof(ev_ssize_t), ==, sizeof(size_t)); |
|
674 tt_int_op(sizeof(ev_intptr_t), >=, sizeof(void *)); |
|
675 tt_int_op(sizeof(ev_uintptr_t), ==, sizeof(intptr_t)); |
|
676 |
|
677 u64 = 1000000000; |
|
678 u64 *= 1000000000; |
|
679 tt_assert(u64 / 1000000000 == 1000000000); |
|
680 i64 = -1000000000; |
|
681 i64 *= 1000000000; |
|
682 tt_assert(i64 / 1000000000 == -1000000000); |
|
683 |
|
684 u64 = EV_UINT64_MAX; |
|
685 i64 = EV_INT64_MAX; |
|
686 tt_assert(u64 > 0); |
|
687 tt_assert(i64 > 0); |
|
688 u64++; |
|
689 i64++; |
|
690 tt_assert(u64 == 0); |
|
691 tt_assert(i64 == EV_INT64_MIN); |
|
692 tt_assert(i64 < 0); |
|
693 |
|
694 u32 = EV_UINT32_MAX; |
|
695 i32 = EV_INT32_MAX; |
|
696 tt_assert(u32 > 0); |
|
697 tt_assert(i32 > 0); |
|
698 u32++; |
|
699 i32++; |
|
700 tt_assert(u32 == 0); |
|
701 tt_assert(i32 == EV_INT32_MIN); |
|
702 tt_assert(i32 < 0); |
|
703 |
|
704 u16 = EV_UINT16_MAX; |
|
705 i16 = EV_INT16_MAX; |
|
706 tt_assert(u16 > 0); |
|
707 tt_assert(i16 > 0); |
|
708 u16++; |
|
709 i16++; |
|
710 tt_assert(u16 == 0); |
|
711 tt_assert(i16 == EV_INT16_MIN); |
|
712 tt_assert(i16 < 0); |
|
713 |
|
714 u8 = EV_UINT8_MAX; |
|
715 i8 = EV_INT8_MAX; |
|
716 tt_assert(u8 > 0); |
|
717 tt_assert(i8 > 0); |
|
718 u8++; |
|
719 i8++; |
|
720 tt_assert(u8 == 0); |
|
721 tt_assert(i8 == EV_INT8_MIN); |
|
722 tt_assert(i8 < 0); |
|
723 |
|
724 ssize = EV_SSIZE_MAX; |
|
725 tt_assert(ssize > 0); |
|
726 ssize++; |
|
727 tt_assert(ssize < 0); |
|
728 tt_assert(ssize == EV_SSIZE_MIN); |
|
729 |
|
730 ptr = &ssize; |
|
731 iptr = (ev_intptr_t)ptr; |
|
732 uptr = (ev_uintptr_t)ptr; |
|
733 ptr = (void *)iptr; |
|
734 tt_assert(ptr == &ssize); |
|
735 ptr = (void *)uptr; |
|
736 tt_assert(ptr == &ssize); |
|
737 |
|
738 iptr = -1; |
|
739 tt_assert(iptr < 0); |
|
740 end: |
|
741 ; |
|
742 } |
|
743 |
|
744 struct evutil_addrinfo * |
|
745 ai_find_by_family(struct evutil_addrinfo *ai, int family) |
|
746 { |
|
747 while (ai) { |
|
748 if (ai->ai_family == family) |
|
749 return ai; |
|
750 ai = ai->ai_next; |
|
751 } |
|
752 return NULL; |
|
753 } |
|
754 |
|
755 struct evutil_addrinfo * |
|
756 ai_find_by_protocol(struct evutil_addrinfo *ai, int protocol) |
|
757 { |
|
758 while (ai) { |
|
759 if (ai->ai_protocol == protocol) |
|
760 return ai; |
|
761 ai = ai->ai_next; |
|
762 } |
|
763 return NULL; |
|
764 } |
|
765 |
|
766 |
|
767 int |
|
768 _test_ai_eq(const struct evutil_addrinfo *ai, const char *sockaddr_port, |
|
769 int socktype, int protocol, int line) |
|
770 { |
|
771 struct sockaddr_storage ss; |
|
772 int slen = sizeof(ss); |
|
773 int gotport; |
|
774 char buf[128]; |
|
775 memset(&ss, 0, sizeof(ss)); |
|
776 if (socktype > 0) |
|
777 tt_int_op(ai->ai_socktype, ==, socktype); |
|
778 if (protocol > 0) |
|
779 tt_int_op(ai->ai_protocol, ==, protocol); |
|
780 |
|
781 if (evutil_parse_sockaddr_port( |
|
782 sockaddr_port, (struct sockaddr*)&ss, &slen)<0) { |
|
783 TT_FAIL(("Couldn't parse expected address %s on line %d", |
|
784 sockaddr_port, line)); |
|
785 return -1; |
|
786 } |
|
787 if (ai->ai_family != ss.ss_family) { |
|
788 TT_FAIL(("Address family %d did not match %d on line %d", |
|
789 ai->ai_family, ss.ss_family, line)); |
|
790 return -1; |
|
791 } |
|
792 if (ai->ai_addr->sa_family == AF_INET) { |
|
793 struct sockaddr_in *sin = (struct sockaddr_in*)ai->ai_addr; |
|
794 evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); |
|
795 gotport = ntohs(sin->sin_port); |
|
796 if (ai->ai_addrlen != sizeof(struct sockaddr_in)) { |
|
797 TT_FAIL(("Addr size mismatch on line %d", line)); |
|
798 return -1; |
|
799 } |
|
800 } else { |
|
801 struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr; |
|
802 evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf)); |
|
803 gotport = ntohs(sin6->sin6_port); |
|
804 if (ai->ai_addrlen != sizeof(struct sockaddr_in6)) { |
|
805 TT_FAIL(("Addr size mismatch on line %d", line)); |
|
806 return -1; |
|
807 } |
|
808 } |
|
809 if (evutil_sockaddr_cmp(ai->ai_addr, (struct sockaddr*)&ss, 1)) { |
|
810 TT_FAIL(("Wanted %s, got %s:%d on line %d", sockaddr_port, |
|
811 buf, gotport, line)); |
|
812 return -1; |
|
813 } else { |
|
814 TT_BLATHER(("Wanted %s, got %s:%d on line %d", sockaddr_port, |
|
815 buf, gotport, line)); |
|
816 } |
|
817 return 0; |
|
818 end: |
|
819 TT_FAIL(("Test failed on line %d", line)); |
|
820 return -1; |
|
821 } |
|
822 |
|
823 static void |
|
824 test_evutil_rand(void *arg) |
|
825 { |
|
826 char buf1[32]; |
|
827 char buf2[32]; |
|
828 int counts[256]; |
|
829 int i, j, k, n=0; |
|
830 |
|
831 memset(buf2, 0, sizeof(buf2)); |
|
832 memset(counts, 0, sizeof(counts)); |
|
833 |
|
834 for (k=0;k<32;++k) { |
|
835 /* Try a few different start and end points; try to catch |
|
836 * the various misaligned cases of arc4random_buf */ |
|
837 int startpoint = _evutil_weakrand() % 4; |
|
838 int endpoint = 32 - (_evutil_weakrand() % 4); |
|
839 |
|
840 memset(buf2, 0, sizeof(buf2)); |
|
841 |
|
842 /* Do 6 runs over buf1, or-ing the result into buf2 each |
|
843 * time, to make sure we're setting each byte that we mean |
|
844 * to set. */ |
|
845 for (i=0;i<8;++i) { |
|
846 memset(buf1, 0, sizeof(buf1)); |
|
847 evutil_secure_rng_get_bytes(buf1 + startpoint, |
|
848 endpoint-startpoint); |
|
849 n += endpoint - startpoint; |
|
850 for (j=0; j<32; ++j) { |
|
851 if (j >= startpoint && j < endpoint) { |
|
852 buf2[j] |= buf1[j]; |
|
853 ++counts[(unsigned char)buf1[j]]; |
|
854 } else { |
|
855 tt_assert(buf1[j] == 0); |
|
856 tt_int_op(buf1[j], ==, 0); |
|
857 |
|
858 } |
|
859 } |
|
860 } |
|
861 |
|
862 /* This will give a false positive with P=(256**8)==(2**64) |
|
863 * for each character. */ |
|
864 for (j=startpoint;j<endpoint;++j) { |
|
865 tt_int_op(buf2[j], !=, 0); |
|
866 } |
|
867 } |
|
868 |
|
869 /* for (i=0;i<256;++i) { printf("%3d %2d\n", i, counts[i]); } */ |
|
870 end: |
|
871 ; |
|
872 } |
|
873 |
|
874 static void |
|
875 test_evutil_getaddrinfo(void *arg) |
|
876 { |
|
877 struct evutil_addrinfo *ai = NULL, *a; |
|
878 struct evutil_addrinfo hints; |
|
879 |
|
880 struct sockaddr_in6 *sin6; |
|
881 struct sockaddr_in *sin; |
|
882 char buf[128]; |
|
883 const char *cp; |
|
884 int r; |
|
885 |
|
886 /* Try using it as a pton. */ |
|
887 memset(&hints, 0, sizeof(hints)); |
|
888 hints.ai_family = PF_UNSPEC; |
|
889 hints.ai_socktype = SOCK_STREAM; |
|
890 r = evutil_getaddrinfo("1.2.3.4", "8080", &hints, &ai); |
|
891 tt_int_op(r, ==, 0); |
|
892 tt_assert(ai); |
|
893 tt_ptr_op(ai->ai_next, ==, NULL); /* no ambiguity */ |
|
894 test_ai_eq(ai, "1.2.3.4:8080", SOCK_STREAM, IPPROTO_TCP); |
|
895 evutil_freeaddrinfo(ai); |
|
896 ai = NULL; |
|
897 |
|
898 memset(&hints, 0, sizeof(hints)); |
|
899 hints.ai_family = PF_UNSPEC; |
|
900 hints.ai_protocol = IPPROTO_UDP; |
|
901 r = evutil_getaddrinfo("1001:b0b::f00f", "4321", &hints, &ai); |
|
902 tt_int_op(r, ==, 0); |
|
903 tt_assert(ai); |
|
904 tt_ptr_op(ai->ai_next, ==, NULL); /* no ambiguity */ |
|
905 test_ai_eq(ai, "[1001:b0b::f00f]:4321", SOCK_DGRAM, IPPROTO_UDP); |
|
906 evutil_freeaddrinfo(ai); |
|
907 ai = NULL; |
|
908 |
|
909 /* Try out the behavior of nodename=NULL */ |
|
910 memset(&hints, 0, sizeof(hints)); |
|
911 hints.ai_family = PF_INET; |
|
912 hints.ai_protocol = IPPROTO_TCP; |
|
913 hints.ai_flags = EVUTIL_AI_PASSIVE; /* as if for bind */ |
|
914 r = evutil_getaddrinfo(NULL, "9999", &hints, &ai); |
|
915 tt_int_op(r,==,0); |
|
916 tt_assert(ai); |
|
917 tt_ptr_op(ai->ai_next, ==, NULL); |
|
918 test_ai_eq(ai, "0.0.0.0:9999", SOCK_STREAM, IPPROTO_TCP); |
|
919 evutil_freeaddrinfo(ai); |
|
920 ai = NULL; |
|
921 hints.ai_flags = 0; /* as if for connect */ |
|
922 r = evutil_getaddrinfo(NULL, "9998", &hints, &ai); |
|
923 tt_assert(ai); |
|
924 tt_int_op(r,==,0); |
|
925 test_ai_eq(ai, "127.0.0.1:9998", SOCK_STREAM, IPPROTO_TCP); |
|
926 tt_ptr_op(ai->ai_next, ==, NULL); |
|
927 evutil_freeaddrinfo(ai); |
|
928 ai = NULL; |
|
929 |
|
930 hints.ai_flags = 0; /* as if for connect */ |
|
931 hints.ai_family = PF_INET6; |
|
932 r = evutil_getaddrinfo(NULL, "9997", &hints, &ai); |
|
933 tt_assert(ai); |
|
934 tt_int_op(r,==,0); |
|
935 tt_ptr_op(ai->ai_next, ==, NULL); |
|
936 test_ai_eq(ai, "[::1]:9997", SOCK_STREAM, IPPROTO_TCP); |
|
937 evutil_freeaddrinfo(ai); |
|
938 ai = NULL; |
|
939 |
|
940 hints.ai_flags = EVUTIL_AI_PASSIVE; /* as if for bind. */ |
|
941 hints.ai_family = PF_INET6; |
|
942 r = evutil_getaddrinfo(NULL, "9996", &hints, &ai); |
|
943 tt_assert(ai); |
|
944 tt_int_op(r,==,0); |
|
945 tt_ptr_op(ai->ai_next, ==, NULL); |
|
946 test_ai_eq(ai, "[::]:9996", SOCK_STREAM, IPPROTO_TCP); |
|
947 evutil_freeaddrinfo(ai); |
|
948 ai = NULL; |
|
949 |
|
950 /* Now try an unspec one. We should get a v6 and a v4. */ |
|
951 hints.ai_family = PF_UNSPEC; |
|
952 r = evutil_getaddrinfo(NULL, "9996", &hints, &ai); |
|
953 tt_assert(ai); |
|
954 tt_int_op(r,==,0); |
|
955 a = ai_find_by_family(ai, PF_INET6); |
|
956 tt_assert(a); |
|
957 test_ai_eq(a, "[::]:9996", SOCK_STREAM, IPPROTO_TCP); |
|
958 a = ai_find_by_family(ai, PF_INET); |
|
959 tt_assert(a); |
|
960 test_ai_eq(a, "0.0.0.0:9996", SOCK_STREAM, IPPROTO_TCP); |
|
961 evutil_freeaddrinfo(ai); |
|
962 ai = NULL; |
|
963 |
|
964 /* Try out AI_NUMERICHOST: successful case. Also try |
|
965 * multiprotocol. */ |
|
966 memset(&hints, 0, sizeof(hints)); |
|
967 hints.ai_family = PF_UNSPEC; |
|
968 hints.ai_flags = EVUTIL_AI_NUMERICHOST; |
|
969 r = evutil_getaddrinfo("1.2.3.4", NULL, &hints, &ai); |
|
970 tt_int_op(r, ==, 0); |
|
971 a = ai_find_by_protocol(ai, IPPROTO_TCP); |
|
972 tt_assert(a); |
|
973 test_ai_eq(a, "1.2.3.4", SOCK_STREAM, IPPROTO_TCP); |
|
974 a = ai_find_by_protocol(ai, IPPROTO_UDP); |
|
975 tt_assert(a); |
|
976 test_ai_eq(a, "1.2.3.4", SOCK_DGRAM, IPPROTO_UDP); |
|
977 evutil_freeaddrinfo(ai); |
|
978 ai = NULL; |
|
979 |
|
980 /* Try the failing case of AI_NUMERICHOST */ |
|
981 memset(&hints, 0, sizeof(hints)); |
|
982 hints.ai_family = PF_UNSPEC; |
|
983 hints.ai_flags = EVUTIL_AI_NUMERICHOST; |
|
984 r = evutil_getaddrinfo("www.google.com", "80", &hints, &ai); |
|
985 tt_int_op(r, ==, EVUTIL_EAI_NONAME); |
|
986 tt_ptr_op(ai, ==, NULL); |
|
987 |
|
988 /* Try symbolic service names wit AI_NUMERICSERV */ |
|
989 memset(&hints, 0, sizeof(hints)); |
|
990 hints.ai_family = PF_UNSPEC; |
|
991 hints.ai_socktype = SOCK_STREAM; |
|
992 hints.ai_flags = EVUTIL_AI_NUMERICSERV; |
|
993 r = evutil_getaddrinfo("1.2.3.4", "http", &hints, &ai); |
|
994 tt_int_op(r,==,EVUTIL_EAI_NONAME); |
|
995 |
|
996 /* Try symbolic service names */ |
|
997 memset(&hints, 0, sizeof(hints)); |
|
998 hints.ai_family = PF_UNSPEC; |
|
999 hints.ai_socktype = SOCK_STREAM; |
|
1000 r = evutil_getaddrinfo("1.2.3.4", "http", &hints, &ai); |
|
1001 if (r!=0) { |
|
1002 TT_DECLARE("SKIP", ("Symbolic service names seem broken.")); |
|
1003 } else { |
|
1004 tt_assert(ai); |
|
1005 test_ai_eq(ai, "1.2.3.4:80", SOCK_STREAM, IPPROTO_TCP); |
|
1006 evutil_freeaddrinfo(ai); |
|
1007 ai = NULL; |
|
1008 } |
|
1009 |
|
1010 /* Now do some actual lookups. */ |
|
1011 memset(&hints, 0, sizeof(hints)); |
|
1012 hints.ai_family = PF_INET; |
|
1013 hints.ai_protocol = IPPROTO_TCP; |
|
1014 hints.ai_socktype = SOCK_STREAM; |
|
1015 r = evutil_getaddrinfo("www.google.com", "80", &hints, &ai); |
|
1016 if (r != 0) { |
|
1017 TT_DECLARE("SKIP", ("Couldn't resolve www.google.com")); |
|
1018 } else { |
|
1019 tt_assert(ai); |
|
1020 tt_int_op(ai->ai_family, ==, PF_INET); |
|
1021 tt_int_op(ai->ai_protocol, ==, IPPROTO_TCP); |
|
1022 tt_int_op(ai->ai_socktype, ==, SOCK_STREAM); |
|
1023 tt_int_op(ai->ai_addrlen, ==, sizeof(struct sockaddr_in)); |
|
1024 sin = (struct sockaddr_in*)ai->ai_addr; |
|
1025 tt_int_op(sin->sin_family, ==, AF_INET); |
|
1026 tt_int_op(sin->sin_port, ==, htons(80)); |
|
1027 tt_int_op(sin->sin_addr.s_addr, !=, 0xffffffff); |
|
1028 |
|
1029 cp = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); |
|
1030 TT_BLATHER(("www.google.com resolved to %s", |
|
1031 cp?cp:"<unwriteable>")); |
|
1032 evutil_freeaddrinfo(ai); |
|
1033 ai = NULL; |
|
1034 } |
|
1035 |
|
1036 hints.ai_family = PF_INET6; |
|
1037 r = evutil_getaddrinfo("ipv6.google.com", "80", &hints, &ai); |
|
1038 if (r != 0) { |
|
1039 TT_BLATHER(("Couldn't do an ipv6 lookup for ipv6.google.com")); |
|
1040 } else { |
|
1041 tt_assert(ai); |
|
1042 tt_int_op(ai->ai_family, ==, PF_INET6); |
|
1043 tt_int_op(ai->ai_addrlen, ==, sizeof(struct sockaddr_in6)); |
|
1044 sin6 = (struct sockaddr_in6*)ai->ai_addr; |
|
1045 tt_int_op(sin6->sin6_port, ==, htons(80)); |
|
1046 |
|
1047 cp = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, |
|
1048 sizeof(buf)); |
|
1049 TT_BLATHER(("ipv6.google.com resolved to %s", |
|
1050 cp?cp:"<unwriteable>")); |
|
1051 } |
|
1052 |
|
1053 end: |
|
1054 if (ai) |
|
1055 evutil_freeaddrinfo(ai); |
|
1056 } |
|
1057 |
|
1058 #ifdef WIN32 |
|
1059 static void |
|
1060 test_evutil_loadsyslib(void *arg) |
|
1061 { |
|
1062 HANDLE h=NULL; |
|
1063 |
|
1064 h = evutil_load_windows_system_library(TEXT("kernel32.dll")); |
|
1065 tt_assert(h); |
|
1066 |
|
1067 end: |
|
1068 if (h) |
|
1069 CloseHandle(h); |
|
1070 |
|
1071 } |
|
1072 #endif |
|
1073 |
|
1074 struct testcase_t util_testcases[] = { |
|
1075 { "ipv4_parse", regress_ipv4_parse, 0, NULL, NULL }, |
|
1076 { "ipv6_parse", regress_ipv6_parse, 0, NULL, NULL }, |
|
1077 { "sockaddr_port_parse", regress_sockaddr_port_parse, 0, NULL, NULL }, |
|
1078 { "sockaddr_port_format", regress_sockaddr_port_format, 0, NULL, NULL }, |
|
1079 { "sockaddr_predicates", test_evutil_sockaddr_predicates, 0,NULL,NULL }, |
|
1080 { "evutil_snprintf", test_evutil_snprintf, 0, NULL, NULL }, |
|
1081 { "evutil_strtoll", test_evutil_strtoll, 0, NULL, NULL }, |
|
1082 { "evutil_casecmp", test_evutil_casecmp, 0, NULL, NULL }, |
|
1083 { "strlcpy", test_evutil_strlcpy, 0, NULL, NULL }, |
|
1084 { "log", test_evutil_log, TT_FORK, NULL, NULL }, |
|
1085 { "upcast", test_evutil_upcast, 0, NULL, NULL }, |
|
1086 { "integers", test_evutil_integers, 0, NULL, NULL }, |
|
1087 { "rand", test_evutil_rand, TT_FORK, NULL, NULL }, |
|
1088 { "getaddrinfo", test_evutil_getaddrinfo, TT_FORK, NULL, NULL }, |
|
1089 #ifdef WIN32 |
|
1090 { "loadsyslib", test_evutil_loadsyslib, TT_FORK, NULL, NULL }, |
|
1091 #endif |
|
1092 END_OF_TESTCASES, |
|
1093 }; |
|
1094 |