dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / dnscrypt / src / libevent-modified / test / regress_util.c
blob9805df4edbc4bb470d45ebf2dda153871c246f18
1 /*
2 * Copyright (c) 2009-2012 Nick Mathewson and Niels Provos
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.
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.
26 #ifdef WIN32
27 #include <winsock2.h>
28 #include <windows.h>
29 #include <ws2tcpip.h>
30 #endif
32 #include "event2/event-config.h"
34 #include <sys/types.h>
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>
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"
60 #include "regress.h"
62 enum entry_status { NORMAL, CANONICAL, BAD };
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 },
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 },
109 static void
110 regress_ipv4_parse(void *ptr)
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));
124 continue;
126 if (ent->status == BAD) {
127 TT_FAIL(("%s parsed, but we expected an error", ent->addr));
128 continue;
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;
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;
143 if (strcmp(written, ent->addr)) {
144 TT_FAIL(("Tried to write out %s; got %s",
145 ent->addr, written));
146 continue;
154 static void
155 regress_ipv6_parse(void *ptr)
157 #ifdef AF_INET6
158 int i, j;
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;
172 if (ent->status == BAD) {
173 TT_FAIL(("%s parsed, but we expected an error", ent->addr));
174 continue;
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;
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;
195 if (strcmp(written, ent->addr)) {
196 TT_FAIL(("Tried to write out %s; got %s", ent->addr, written));
197 continue;
202 #else
203 TT_BLATHER(("Skipping IPv6 address parsing."));
204 #endif
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 },
226 static void
227 regress_sockaddr_port_parse(void *ptr)
229 struct sockaddr_storage ss;
230 int i, r;
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;
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));
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));
282 static void
283 regress_sockaddr_port_format(void *ptr)
285 struct sockaddr_storage ss;
286 int len;
287 const char *cp;
288 char cbuf[128];
289 int r;
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");
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");
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:
318 static struct sa_pred_ent {
319 const char *parse;
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 },
329 { "::1", 1 },
330 { "::0", 0 },
331 { "f::1", 0 },
332 { "::501", 0 },
333 { NULL, 0 },
337 static void
338 test_evutil_sockaddr_predicates(void *ptr)
340 struct sockaddr_storage ss;
341 int r, i;
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);
347 r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len);
349 if (r<0) {
350 TT_FAIL(("Couldn't parse %s!", ent->parse));
351 continue;
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));
362 static void
363 test_evutil_strtoll(void *ptr)
365 const char *s;
366 char *endptr;
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);
378 static void
379 test_evutil_snprintf(void *ptr)
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;
388 r = evutil_snprintf(buf, sizeof(buf), "%d %d", 50, 100);
389 tt_str_op(buf, ==, "50 100");
390 tt_int_op(r, ==, 6);
392 r = evutil_snprintf(buf, sizeof(buf), "longish %d", 1234567890);
393 tt_str_op(buf, ==, "longish 1234567");
394 tt_int_op(r, ==, 18);
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);
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);
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);
409 end:
413 static void
414 test_evutil_casecmp(void *ptr)
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);
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:
434 static int logsev = 0;
435 static char *logmsg = NULL;
437 static void
438 logfn(int severity, const char *msg)
440 logsev = severity;
441 tt_want(msg);
442 if (msg) {
443 if (logmsg)
444 free(logmsg);
445 logmsg = strdup(msg);
449 static int fatal_want_severity = 0;
450 static const char *fatal_want_message = NULL;
451 static void
452 fatalfn(int exitcode)
454 if (logsev != fatal_want_severity ||
455 !logmsg ||
456 strcmp(logmsg, fatal_want_message))
457 exit(0);
458 else
459 exit(exitcode);
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)
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);
481 end:
485 static void
486 errx_fn(void)
488 event_errx(2, "Fatal error; too many kumquats (%d)", 5);
491 static void
492 err_fn(void)
494 errno = ENOENT;
495 event_err(5,"Couldn't open %s", "/very/bad/file");
498 static void
499 sock_err_fn(void)
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");
509 #endif
511 static void
512 test_evutil_log(void *ptr)
514 evutil_socket_t fd = -1;
515 char buf[128];
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)
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
540 event_warnx("Far too many %s (%d)", "wombats", 99);
541 LOGEQ(_EVENT_LOG_WARN, "Far too many wombats (99)");
542 RESET();
544 event_msgx("Connecting lime to coconut");
545 LOGEQ(_EVENT_LOG_MSG, "Connecting lime to coconut");
546 RESET();
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();
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();
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
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();
588 #ifdef CAN_CHECK_ERR
589 check_error_logging(sock_err_fn, 20, _EVENT_LOG_ERR, buf);
590 RESET();
591 #endif
593 #undef RESET
594 #undef LOGEQ
595 end:
596 if (logmsg)
597 free(logmsg);
598 if (fd >= 0)
599 evutil_closesocket(fd);
602 static void
603 test_evutil_strlcpy(void *arg)
605 char buf[8];
607 /* Successful case. */
608 tt_int_op(5, ==, strlcpy(buf, "Hello", sizeof(buf)));
609 tt_str_op(buf, ==, "Hello");
611 /* Overflow by a lot. */
612 tt_int_op(13, ==, strlcpy(buf, "pentasyllabic", sizeof(buf)));
613 tt_str_op(buf, ==, "pentasy");
615 /* Overflow by exactly one. */
616 tt_int_op(8, ==, strlcpy(buf, "overlong", sizeof(buf)));
617 tt_str_op(buf, ==, "overlon");
618 end:
622 struct example_struct {
623 const char *a;
624 const char *b;
625 long c;
628 static void
629 test_evutil_upcast(void *arg)
631 struct example_struct es1;
632 const char **cp;
633 es1.a = "World";
634 es1.b = "Hello";
635 es1.c = -99;
637 tt_int_op(evutil_offsetof(struct example_struct, b), ==, sizeof(char*));
639 cp = &es1.b;
640 tt_ptr_op(EVUTIL_UPCAST(cp, struct example_struct, b), ==, &es1);
642 end:
646 static void
647 test_evutil_integers(void *arg)
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;
658 void *ptr;
659 ev_intptr_t iptr;
660 ev_uintptr_t uptr;
662 ev_ssize_t ssize;
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);
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));
677 u64 = 1000000000;
678 u64 *= 1000000000;
679 tt_assert(u64 / 1000000000 == 1000000000);
680 i64 = -1000000000;
681 i64 *= 1000000000;
682 tt_assert(i64 / 1000000000 == -1000000000);
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);
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);
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);
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);
724 ssize = EV_SSIZE_MAX;
725 tt_assert(ssize > 0);
726 ssize++;
727 tt_assert(ssize < 0);
728 tt_assert(ssize == EV_SSIZE_MIN);
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);
738 iptr = -1;
739 tt_assert(iptr < 0);
740 end:
744 struct evutil_addrinfo *
745 ai_find_by_family(struct evutil_addrinfo *ai, int family)
747 while (ai) {
748 if (ai->ai_family == family)
749 return ai;
750 ai = ai->ai_next;
752 return NULL;
755 struct evutil_addrinfo *
756 ai_find_by_protocol(struct evutil_addrinfo *ai, int protocol)
758 while (ai) {
759 if (ai->ai_protocol == protocol)
760 return ai;
761 ai = ai->ai_next;
763 return NULL;
768 _test_ai_eq(const struct evutil_addrinfo *ai, const char *sockaddr_port,
769 int socktype, int protocol, int line)
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);
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;
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;
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;
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;
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));
817 return 0;
818 end:
819 TT_FAIL(("Test failed on line %d", line));
820 return -1;
823 static void
824 test_evutil_rand(void *arg)
826 char buf1[32];
827 char buf2[32];
828 int counts[256];
829 int i, j, k, n=0;
831 memset(buf2, 0, sizeof(buf2));
832 memset(counts, 0, sizeof(counts));
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);
840 memset(buf2, 0, sizeof(buf2));
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);
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);
869 /* for (i=0;i<256;++i) { printf("%3d %2d\n", i, counts[i]); } */
870 end:
874 static void
875 test_evutil_getaddrinfo(void *arg)
877 struct evutil_addrinfo *ai = NULL, *a;
878 struct evutil_addrinfo hints;
880 struct sockaddr_in6 *sin6;
881 struct sockaddr_in *sin;
882 char buf[128];
883 const char *cp;
884 int r;
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;
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;
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;
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;
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;
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;
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;
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);
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);
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;
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);
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;
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));
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>"));
1053 end:
1054 if (ai)
1055 evutil_freeaddrinfo(ai);
1058 #ifdef WIN32
1059 static void
1060 test_evutil_loadsyslib(void *arg)
1062 HANDLE h=NULL;
1064 h = evutil_load_windows_system_library(TEXT("kernel32.dll"));
1065 tt_assert(h);
1067 end:
1068 if (h)
1069 CloseHandle(h);
1072 #endif
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,