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
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.
32 #include "event2/event-config.h"
34 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
42 #ifdef _EVENT_HAVE_NETINET_IN6_H
43 #include <netinet/in6.h>
45 #ifdef _EVENT_HAVE_SYS_WAIT_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"
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
{
68 enum entry_status status
;
70 { "1.2.3.4", 0x01020304u
, CANONICAL
},
71 { "255.255.255.255", 0xffffffffu
, CANONICAL
},
72 { "256.0.0.0", 0, BAD
},
74 { "1.2.3.4.5", 0, BAD
},
75 { "176.192.208.244", 0xb0c0d0f4, CANONICAL
},
79 static struct ipv6_entry
{
82 enum entry_status status
;
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
},
110 regress_ipv4_parse(void *ptr
)
113 for (i
= 0; ipv4_entries
[i
].addr
; ++i
) {
115 struct ipv4_entry
*ent
= &ipv4_entries
[i
];
118 r
= evutil_inet_pton(AF_INET
, ent
->addr
, &in
);
120 if (ent
->status
!= BAD
) {
121 TT_FAIL(("%s did not parse, but it's a good address!",
126 if (ent
->status
== BAD
) {
127 TT_FAIL(("%s parsed, but we expected an error", ent
->addr
));
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
));
136 if (ent
->status
== CANONICAL
) {
137 const char *w
= evutil_inet_ntop(AF_INET
, &in
, written
,
140 TT_FAIL(("Tried to write out %s; got NULL.", ent
->addr
));
143 if (strcmp(written
, ent
->addr
)) {
144 TT_FAIL(("Tried to write out %s; got %s",
145 ent
->addr
, written
));
155 regress_ipv6_parse(void *ptr
)
160 for (i
= 0; ipv6_entries
[i
].addr
; ++i
) {
162 struct ipv6_entry
*ent
= &ipv6_entries
[i
];
165 r
= evutil_inet_pton(AF_INET6
, ent
->addr
, &in6
);
167 if (ent
->status
!= BAD
)
168 TT_FAIL(("%s did not parse, but it's a good address!",
172 if (ent
->status
== BAD
) {
173 TT_FAIL(("%s parsed, but we expected an error", ent
->addr
));
176 for (j
= 0; j
< 4; ++j
) {
177 /* Can't use s6_addr32 here; some don't have it. */
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
));
188 if (ent
->status
== CANONICAL
) {
189 const char *w
= evutil_inet_ntop(AF_INET6
, &in6
, written
,
192 TT_FAIL(("Tried to write out %s; got NULL.", ent
->addr
));
195 if (strcmp(written
, ent
->addr
)) {
196 TT_FAIL(("Tried to write out %s; got %s", ent
->addr
, written
));
203 TT_BLATHER(("Skipping IPv6 address parsing."));
207 static struct sa_port_ent
{
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 },
227 regress_sockaddr_port_parse(void *ptr
)
229 struct sockaddr_storage ss
;
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
);
239 TT_FAIL(("Couldn't parse %s!", ent
->parse
));
241 } else if (! ent
->safamily
) {
242 TT_FAIL(("Shouldn't have been able to parse %s!", ent
->parse
));
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
);
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
);
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
));
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
);
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
);
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
));
283 regress_sockaddr_port_format(void *ptr
)
285 struct sockaddr_storage ss
;
292 r
= evutil_parse_sockaddr_port("192.168.1.1:80",
293 (struct sockaddr
*)&ss
, &len
);
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");
301 r
= evutil_parse_sockaddr_port("[ff00::8010]:999",
302 (struct sockaddr
*)&ss
, &len
);
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");
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>");
318 static struct sa_pred_ent
{
322 } sa_pred_entries
[] = {
327 { "129.168.1.1", 0 },
338 test_evutil_sockaddr_predicates(void *ptr
)
340 struct sockaddr_storage ss
;
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
);
350 TT_FAIL(("Couldn't parse %s!", ent
->parse
));
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",
363 test_evutil_strtoll(void *ptr
)
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);
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);
379 test_evutil_snprintf(void *ptr
)
383 ev_uint64_t u64
= ((ev_uint64_t
)1000000000)*200;
384 ev_int64_t i64
= -1 * (ev_int64_t
) u64
;
386 ev_ssize_t ssize
= -9000;
388 r
= evutil_snprintf(buf
, sizeof(buf
), "%d %d", 50, 100);
389 tt_str_op(buf
, ==, "50 100");
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);
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);
434 static int logsev
= 0;
435 static char *logmsg
= NULL
;
438 logfn(int severity
, const char *msg
)
445 logmsg
= strdup(msg
);
449 static int fatal_want_severity
= 0;
450 static const char *fatal_want_message
= NULL
;
452 fatalfn(int exitcode
)
454 if (logsev
!= fatal_want_severity
||
456 strcmp(logmsg
, fatal_want_message
))
463 #define CAN_CHECK_ERR
465 check_error_logging(void (*fn
)(void), int wantexitcode
,
466 int wantseverity
, const char *wantmsg
)
469 int status
= 0, exitcode
;
470 fatal_want_severity
= wantseverity
;
471 fatal_want_message
= wantmsg
;
472 if ((pid
= regress_fork()) == 0) {
475 exit(0); /* should be unreachable. */
478 exitcode
= WEXITSTATUS(status
);
479 tt_int_op(wantexitcode
, ==, exitcode
);
488 event_errx(2, "Fatal error; too many kumquats (%d)", 5);
495 event_err(5,"Couldn't open %s", "/very/bad/file");
501 evutil_socket_t fd
= socket(AF_INET
, SOCK_STREAM
, 0);
503 EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK
);
507 event_sock_err(20, fd
, "Unhappy socket");
512 test_evutil_log(void *ptr
)
514 evutil_socket_t fd
= -1;
517 event_set_log_callback(logfn
);
518 event_set_fatal_callback(fatalfn
);
519 #define RESET() do { \
521 if (logmsg) free(logmsg); \
524 #define LOGEQ(sev,msg) do { \
525 tt_int_op(logsev,==,sev); \
526 tt_assert(logmsg != NULL); \
527 tt_str_op(logmsg,==,msg); \
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)");
540 event_warnx("Far too many %s (%d)", "wombats", 99);
541 LOGEQ(_EVENT_LOG_WARN
, "Far too many wombats (99)");
544 event_msgx("Connecting lime to coconut");
545 LOGEQ(_EVENT_LOG_MSG
, "Connecting lime to coconut");
548 event_debug(("A millisecond passed! We should log that!"));
550 LOGEQ(_EVENT_LOG_DEBUG
, "A millisecond passed! We should log that!");
552 tt_int_op(logsev
,==,0);
553 tt_ptr_op(logmsg
,==,NULL
);
557 /* Try with an errno. */
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
);
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
);
572 /* Try with a socket errno. */
573 fd
= socket(AF_INET
, SOCK_STREAM
, 0);
575 evutil_snprintf(buf
, sizeof(buf
),
576 "Unhappy socket: %s",
577 evutil_socket_error_to_string(WSAEWOULDBLOCK
));
578 EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK
);
580 evutil_snprintf(buf
, sizeof(buf
),
581 "Unhappy socket: %s", strerror(EAGAIN
));
584 event_sock_warn(fd
, "Unhappy socket");
585 LOGEQ(_EVENT_LOG_WARN
, buf
);
589 check_error_logging(sock_err_fn
, 20, _EVENT_LOG_ERR
, buf
);
599 evutil_closesocket(fd
);
603 test_evutil_strlcpy(void *arg
)
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");
622 struct example_struct
{
629 test_evutil_upcast(void *arg
)
631 struct example_struct es1
;
637 tt_int_op(evutil_offsetof(struct example_struct
, b
), ==, sizeof(char*));
640 tt_ptr_op(EVUTIL_UPCAST(cp
, struct example_struct
, b
), ==, &es1
);
647 test_evutil_integers(void *arg
)
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));
679 tt_assert(u64
/ 1000000000 == 1000000000);
682 tt_assert(i64
/ 1000000000 == -1000000000);
691 tt_assert(i64
== EV_INT64_MIN
);
701 tt_assert(i32
== EV_INT32_MIN
);
711 tt_assert(i16
== EV_INT16_MIN
);
721 tt_assert(i8
== EV_INT8_MIN
);
724 ssize
= EV_SSIZE_MAX
;
725 tt_assert(ssize
> 0);
727 tt_assert(ssize
< 0);
728 tt_assert(ssize
== EV_SSIZE_MIN
);
731 iptr
= (ev_intptr_t
)ptr
;
732 uptr
= (ev_uintptr_t
)ptr
;
734 tt_assert(ptr
== &ssize
);
736 tt_assert(ptr
== &ssize
);
744 struct evutil_addrinfo
*
745 ai_find_by_family(struct evutil_addrinfo
*ai
, int family
)
748 if (ai
->ai_family
== family
)
755 struct evutil_addrinfo
*
756 ai_find_by_protocol(struct evutil_addrinfo
*ai
, int protocol
)
759 if (ai
->ai_protocol
== protocol
)
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
);
775 memset(&ss
, 0, sizeof(ss
));
777 tt_int_op(ai
->ai_socktype
, ==, socktype
);
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
));
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
));
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
));
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
));
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
));
814 TT_BLATHER(("Wanted %s, got %s:%d on line %d", sockaddr_port
,
815 buf
, gotport
, line
));
819 TT_FAIL(("Test failed on line %d", line
));
824 test_evutil_rand(void *arg
)
831 memset(buf2
, 0, sizeof(buf2
));
832 memset(counts
, 0, sizeof(counts
));
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
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
) {
853 ++counts
[(unsigned char)buf1
[j
]];
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]); } */
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
;
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
);
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
);
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
);
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
);
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
);
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
);
921 hints
.ai_flags
= 0; /* as if for connect */
922 r
= evutil_getaddrinfo(NULL
, "9998", &hints
, &ai
);
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
);
930 hints
.ai_flags
= 0; /* as if for connect */
931 hints
.ai_family
= PF_INET6
;
932 r
= evutil_getaddrinfo(NULL
, "9997", &hints
, &ai
);
935 tt_ptr_op(ai
->ai_next
, ==, NULL
);
936 test_ai_eq(ai
, "[::1]:9997", SOCK_STREAM
, IPPROTO_TCP
);
937 evutil_freeaddrinfo(ai
);
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
);
945 tt_ptr_op(ai
->ai_next
, ==, NULL
);
946 test_ai_eq(ai
, "[::]:9996", SOCK_STREAM
, IPPROTO_TCP
);
947 evutil_freeaddrinfo(ai
);
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
);
955 a
= ai_find_by_family(ai
, PF_INET6
);
957 test_ai_eq(a
, "[::]:9996", SOCK_STREAM
, IPPROTO_TCP
);
958 a
= ai_find_by_family(ai
, PF_INET
);
960 test_ai_eq(a
, "0.0.0.0:9996", SOCK_STREAM
, IPPROTO_TCP
);
961 evutil_freeaddrinfo(ai
);
964 /* Try out AI_NUMERICHOST: successful case. Also try
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
);
971 a
= ai_find_by_protocol(ai
, IPPROTO_TCP
);
973 test_ai_eq(a
, "1.2.3.4", SOCK_STREAM
, IPPROTO_TCP
);
974 a
= ai_find_by_protocol(ai
, IPPROTO_UDP
);
976 test_ai_eq(a
, "1.2.3.4", SOCK_DGRAM
, IPPROTO_UDP
);
977 evutil_freeaddrinfo(ai
);
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
);
1002 TT_DECLARE("SKIP", ("Symbolic service names seem broken."));
1005 test_ai_eq(ai
, "1.2.3.4:80", SOCK_STREAM
, IPPROTO_TCP
);
1006 evutil_freeaddrinfo(ai
);
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
);
1017 TT_DECLARE("SKIP", ("Couldn't resolve www.google.com"));
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
);
1036 hints
.ai_family
= PF_INET6
;
1037 r
= evutil_getaddrinfo("ipv6.google.com", "80", &hints
, &ai
);
1039 TT_BLATHER(("Couldn't do an ipv6 lookup for ipv6.google.com"));
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
,
1049 TT_BLATHER(("ipv6.google.com resolved to %s",
1050 cp
?cp
:"<unwriteable>"));
1055 evutil_freeaddrinfo(ai
);
1060 test_evutil_loadsyslib(void *arg
)
1064 h
= evutil_load_windows_system_library(TEXT("kernel32.dll"));
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
},
1090 { "loadsyslib", test_evutil_loadsyslib
, TT_FORK
, NULL
, NULL
},