1 /* $NetBSD: regress_util.c,v 1.2 2013/04/11 16:56:42 christos Exp $ */
3 * Copyright (c) 2009-2012 Nick Mathewson and Niels Provos
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "event2/event-config.h"
34 #include <sys/cdefs.h>
35 __RCSID("$NetBSD: regress_util.c,v 1.2 2013/04/11 16:56:42 christos Exp $");
37 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
45 #ifdef _EVENT_HAVE_NETINET_IN6_H
46 #include <netinet/in6.h>
48 #ifdef _EVENT_HAVE_SYS_WAIT_H
57 #include "event2/event.h"
58 #include "event2/util.h"
59 #include "../ipv6-internal.h"
60 #include "../util-internal.h"
61 #include "../log-internal.h"
62 #include "../strlcpy-internal.h"
66 enum entry_status
{ NORMAL
, CANONICAL
, BAD
};
68 /* This is a big table of results we expect from generating and parsing */
69 static struct ipv4_entry
{
72 enum entry_status status
;
74 { "1.2.3.4", 0x01020304u
, CANONICAL
},
75 { "255.255.255.255", 0xffffffffu
, CANONICAL
},
76 { "256.0.0.0", 0, BAD
},
78 { "1.2.3.4.5", 0, BAD
},
79 { "176.192.208.244", 0xb0c0d0f4, CANONICAL
},
83 static struct ipv6_entry
{
86 enum entry_status status
;
88 { "::", { 0, 0, 0, 0, }, CANONICAL
},
89 { "0:0:0:0:0:0:0:0", { 0, 0, 0, 0, }, NORMAL
},
90 { "::1", { 0, 0, 0, 1, }, CANONICAL
},
91 { "::1.2.3.4", { 0, 0, 0, 0x01020304, }, CANONICAL
},
92 { "ffff:1::", { 0xffff0001u
, 0, 0, 0, }, CANONICAL
},
93 { "ffff:0000::", { 0xffff0000u
, 0, 0, 0, }, NORMAL
},
94 { "ffff::1234", { 0xffff0000u
, 0, 0, 0x1234, }, CANONICAL
},
95 { "0102::1.2.3.4", {0x01020000u
, 0, 0, 0x01020304u
}, NORMAL
},
96 { "::9:c0a8:1:1", { 0, 0, 0x0009c0a8u
, 0x00010001u
}, CANONICAL
},
97 { "::ffff:1.2.3.4", { 0, 0, 0x000ffffu
, 0x01020304u
}, CANONICAL
},
98 { "FFFF::", { 0xffff0000u
, 0, 0, 0 }, NORMAL
},
99 { "foobar.", { 0, 0, 0, 0 }, BAD
},
100 { "foobar", { 0, 0, 0, 0 }, BAD
},
101 { "fo:obar", { 0, 0, 0, 0 }, BAD
},
102 { "ffff", { 0, 0, 0, 0 }, BAD
},
103 { "fffff::", { 0, 0, 0, 0 }, BAD
},
104 { "fffff::", { 0, 0, 0, 0 }, BAD
},
105 { "::1.0.1.1000", { 0, 0, 0, 0 }, BAD
},
106 { "1:2:33333:4::", { 0, 0, 0, 0 }, BAD
},
107 { "1:2:3:4:5:6:7:8:9", { 0, 0, 0, 0 }, BAD
},
108 { "1::2::3", { 0, 0, 0, 0 }, BAD
},
109 { ":::1", { 0, 0, 0, 0 }, BAD
},
110 { NULL
, { 0, 0, 0, 0, }, BAD
},
114 regress_ipv4_parse(void *ptr
)
117 for (i
= 0; ipv4_entries
[i
].addr
; ++i
) {
119 struct ipv4_entry
*ent
= &ipv4_entries
[i
];
122 r
= evutil_inet_pton(AF_INET
, ent
->addr
, &in
);
124 if (ent
->status
!= BAD
) {
125 TT_FAIL(("%s did not parse, but it's a good address!",
130 if (ent
->status
== BAD
) {
131 TT_FAIL(("%s parsed, but we expected an error", ent
->addr
));
134 if (ntohl(in
.s_addr
) != ent
->res
) {
135 TT_FAIL(("%s parsed to %lx, but we expected %lx", ent
->addr
,
136 (unsigned long)ntohl(in
.s_addr
),
137 (unsigned long)ent
->res
));
140 if (ent
->status
== CANONICAL
) {
141 const char *w
= evutil_inet_ntop(AF_INET
, &in
, written
,
144 TT_FAIL(("Tried to write out %s; got NULL.", ent
->addr
));
147 if (strcmp(written
, ent
->addr
)) {
148 TT_FAIL(("Tried to write out %s; got %s",
149 ent
->addr
, written
));
159 regress_ipv6_parse(void *ptr
)
164 for (i
= 0; ipv6_entries
[i
].addr
; ++i
) {
166 struct ipv6_entry
*ent
= &ipv6_entries
[i
];
169 r
= evutil_inet_pton(AF_INET6
, ent
->addr
, &in6
);
171 if (ent
->status
!= BAD
)
172 TT_FAIL(("%s did not parse, but it's a good address!",
176 if (ent
->status
== BAD
) {
177 TT_FAIL(("%s parsed, but we expected an error", ent
->addr
));
180 for (j
= 0; j
< 4; ++j
) {
181 /* Can't use s6_addr32 here; some don't have it. */
183 (in6
.s6_addr
[j
*4 ] << 24) |
184 (in6
.s6_addr
[j
*4+1] << 16) |
185 (in6
.s6_addr
[j
*4+2] << 8) |
186 (in6
.s6_addr
[j
*4+3]);
187 if (u
!= ent
->res
[j
]) {
188 TT_FAIL(("%s did not parse as expected.", ent
->addr
));
192 if (ent
->status
== CANONICAL
) {
193 const char *w
= evutil_inet_ntop(AF_INET6
, &in6
, written
,
196 TT_FAIL(("Tried to write out %s; got NULL.", ent
->addr
));
199 if (strcmp(written
, ent
->addr
)) {
200 TT_FAIL(("Tried to write out %s; got %s", ent
->addr
, written
));
207 TT_BLATHER(("Skipping IPv6 address parsing."));
211 static struct sa_port_ent
{
217 { "[ffff::1]:1000", AF_INET6
, "ffff::1", 1000 },
218 { "[ffff::1]", AF_INET6
, "ffff::1", 0 },
219 { "[ffff::1", 0, NULL
, 0 },
220 { "[ffff::1]:65599", 0, NULL
, 0 },
221 { "[ffff::1]:0", 0, NULL
, 0 },
222 { "[ffff::1]:-1", 0, NULL
, 0 },
223 { "::1", AF_INET6
, "::1", 0 },
224 { "1:2::1", AF_INET6
, "1:2::1", 0 },
225 { "192.168.0.1:50", AF_INET
, "192.168.0.1", 50 },
226 { "1.2.3.4", AF_INET
, "1.2.3.4", 0 },
227 { NULL
, 0, NULL
, 0 },
231 regress_sockaddr_port_parse(void *ptr
)
233 struct sockaddr_storage ss
;
236 for (i
= 0; sa_port_ents
[i
].parse
; ++i
) {
237 struct sa_port_ent
*ent
= &sa_port_ents
[i
];
238 int len
= sizeof(ss
);
239 memset(&ss
, 0, sizeof(ss
));
240 r
= evutil_parse_sockaddr_port(ent
->parse
, (struct sockaddr
*)&ss
, &len
);
243 TT_FAIL(("Couldn't parse %s!", ent
->parse
));
245 } else if (! ent
->safamily
) {
246 TT_FAIL(("Shouldn't have been able to parse %s!", ent
->parse
));
249 if (ent
->safamily
== AF_INET
) {
250 struct sockaddr_in sin
;
251 memset(&sin
, 0, sizeof(sin
));
252 #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
253 sin
.sin_len
= sizeof(sin
);
255 sin
.sin_family
= AF_INET
;
256 sin
.sin_port
= htons(ent
->port
);
257 r
= evutil_inet_pton(AF_INET
, ent
->addr
, &sin
.sin_addr
);
259 TT_FAIL(("Couldn't parse ipv4 target %s.", ent
->addr
));
260 } else if (memcmp(&sin
, &ss
, sizeof(sin
))) {
261 TT_FAIL(("Parse for %s was not as expected.", ent
->parse
));
262 } else if (len
!= sizeof(sin
)) {
263 TT_FAIL(("Length for %s not as expected.",ent
->parse
));
266 struct sockaddr_in6 sin6
;
267 memset(&sin6
, 0, sizeof(sin6
));
268 #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
269 sin6
.sin6_len
= sizeof(sin6
);
271 sin6
.sin6_family
= AF_INET6
;
272 sin6
.sin6_port
= htons(ent
->port
);
273 r
= evutil_inet_pton(AF_INET6
, ent
->addr
, &sin6
.sin6_addr
);
275 TT_FAIL(("Couldn't parse ipv6 target %s.", ent
->addr
));
276 } else if (memcmp(&sin6
, &ss
, sizeof(sin6
))) {
277 TT_FAIL(("Parse for %s was not as expected.", ent
->parse
));
278 } else if (len
!= sizeof(sin6
)) {
279 TT_FAIL(("Length for %s not as expected.",ent
->parse
));
287 regress_sockaddr_port_format(void *ptr
)
289 struct sockaddr_storage ss
;
296 r
= evutil_parse_sockaddr_port("192.168.1.1:80",
297 (struct sockaddr
*)&ss
, &len
);
299 cp
= evutil_format_sockaddr_port(
300 (struct sockaddr
*)&ss
, cbuf
, sizeof(cbuf
));
301 tt_ptr_op(cp
,==,cbuf
);
302 tt_str_op(cp
,==,"192.168.1.1:80");
305 r
= evutil_parse_sockaddr_port("[ff00::8010]:999",
306 (struct sockaddr
*)&ss
, &len
);
308 cp
= evutil_format_sockaddr_port(
309 (struct sockaddr
*)&ss
, cbuf
, sizeof(cbuf
));
310 tt_ptr_op(cp
,==,cbuf
);
311 tt_str_op(cp
,==,"[ff00::8010]:999");
314 cp
= evutil_format_sockaddr_port(
315 (struct sockaddr
*)&ss
, cbuf
, sizeof(cbuf
));
316 tt_ptr_op(cp
,==,cbuf
);
317 tt_str_op(cp
,==,"<addr with socktype 99>");
322 static struct sa_pred_ent
{
326 } sa_pred_entries
[] = {
331 { "129.168.1.1", 0 },
342 test_evutil_sockaddr_predicates(void *ptr
)
344 struct sockaddr_storage ss
;
347 for (i
=0; sa_pred_entries
[i
].parse
; ++i
) {
348 struct sa_pred_ent
*ent
= &sa_pred_entries
[i
];
349 int len
= sizeof(ss
);
351 r
= evutil_parse_sockaddr_port(ent
->parse
, (struct sockaddr
*)&ss
, &len
);
354 TT_FAIL(("Couldn't parse %s!", ent
->parse
));
358 /* sockaddr_is_loopback */
359 if (ent
->is_loopback
!= evutil_sockaddr_is_loopback((struct sockaddr
*)&ss
)) {
360 TT_FAIL(("evutil_sockaddr_loopback(%s) not as expected",
367 test_evutil_strtoll(void *ptr
)
372 tt_want(evutil_strtoll("5000000000", NULL
, 10) ==
373 ((ev_int64_t
)5000000)*1000);
374 tt_want(evutil_strtoll("-5000000000", NULL
, 10) ==
375 ((ev_int64_t
)5000000)*-1000);
377 tt_want(evutil_strtoll(s
, &endptr
, 10) == (ev_int64_t
)99999);
378 tt_want(endptr
== s
+6);
379 tt_want(evutil_strtoll("foo", NULL
, 10) == 0);
383 test_evutil_snprintf(void *ptr
)
387 ev_uint64_t u64
= ((ev_uint64_t
)1000000000)*200;
388 ev_int64_t i64
= -1 * (ev_int64_t
) u64
;
390 ev_ssize_t ssize
= -9000;
392 r
= evutil_snprintf(buf
, sizeof(buf
), "%d %d", 50, 100);
393 tt_str_op(buf
, ==, "50 100");
396 r
= evutil_snprintf(buf
, sizeof(buf
), "longish %d", 1234567890);
397 tt_str_op(buf
, ==, "longish 1234567");
398 tt_int_op(r
, ==, 18);
400 r
= evutil_snprintf(buf
, sizeof(buf
), EV_U64_FMT
, EV_U64_ARG(u64
));
401 tt_str_op(buf
, ==, "200000000000");
402 tt_int_op(r
, ==, 12);
404 r
= evutil_snprintf(buf
, sizeof(buf
), EV_I64_FMT
, EV_I64_ARG(i64
));
405 tt_str_op(buf
, ==, "-200000000000");
406 tt_int_op(r
, ==, 13);
408 r
= evutil_snprintf(buf
, sizeof(buf
), EV_SIZE_FMT
" "EV_SSIZE_FMT
,
409 EV_SIZE_ARG(size
), EV_SSIZE_ARG(ssize
));
410 tt_str_op(buf
, ==, "8000 -9000");
411 tt_int_op(r
, ==, 10);
418 test_evutil_casecmp(void *ptr
)
420 tt_int_op(evutil_ascii_strcasecmp("ABC", "ABC"), ==, 0);
421 tt_int_op(evutil_ascii_strcasecmp("ABC", "abc"), ==, 0);
422 tt_int_op(evutil_ascii_strcasecmp("ABC", "abcd"), <, 0);
423 tt_int_op(evutil_ascii_strcasecmp("ABC", "abb"), >, 0);
424 tt_int_op(evutil_ascii_strcasecmp("ABCd", "abc"), >, 0);
426 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 100), ==, 0);
427 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 4), ==, 0);
428 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEXXXX", 4), ==, 0);
429 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibE", 4), ==, 0);
430 tt_int_op(evutil_ascii_strncasecmp("Libe", "LibEvEnT", 4), ==, 0);
431 tt_int_op(evutil_ascii_strncasecmp("Lib", "LibEvEnT", 4), <, 0);
432 tt_int_op(evutil_ascii_strncasecmp("abc", "def", 99), <, 0);
433 tt_int_op(evutil_ascii_strncasecmp("Z", "qrst", 1), >, 0);
438 static int logsev
= 0;
439 static char *logmsg
= NULL
;
442 logfn(int severity
, const char *msg
)
449 logmsg
= strdup(msg
);
453 static int fatal_want_severity
= 0;
454 static const char *fatal_want_message
= NULL
;
456 fatalfn(int exitcode
)
458 if (logsev
!= fatal_want_severity
||
460 strcmp(logmsg
, fatal_want_message
))
467 #define CAN_CHECK_ERR
469 check_error_logging(void (*fn
)(void), int wantexitcode
,
470 int wantseverity
, const char *wantmsg
)
473 int status
= 0, exitcode
;
474 fatal_want_severity
= wantseverity
;
475 fatal_want_message
= wantmsg
;
476 if ((pid
= regress_fork()) == 0) {
479 exit(0); /* should be unreachable. */
482 exitcode
= WEXITSTATUS(status
);
483 tt_int_op(wantexitcode
, ==, exitcode
);
492 event_errx(2, "Fatal error; too many kumquats (%d)", 5);
499 event_err(5,"Couldn't open %s", "/very/bad/file");
505 evutil_socket_t fd
= socket(AF_INET
, SOCK_STREAM
, 0);
507 EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK
);
511 event_sock_err(20, fd
, "Unhappy socket");
516 test_evutil_log(void *ptr
)
518 evutil_socket_t fd
= -1;
521 event_set_log_callback(logfn
);
522 event_set_fatal_callback(fatalfn
);
523 #define RESET() do { \
525 if (logmsg) free(logmsg); \
527 } while (/*CONSTCOND*/0)
528 #define LOGEQ(sev,msg) do { \
529 tt_int_op(logsev,==,sev); \
530 tt_assert(logmsg != NULL); \
531 tt_str_op(logmsg,==,msg); \
532 } while (/*CONSTCOND*/0)
535 /* We need to disable these tests for now. Previously, the logging
536 * module didn't enforce the requirement that a fatal callback
537 * actually exit. Now, it exits no matter what, so if we wan to
538 * reinstate these tests, we'll need to fork for each one. */
539 check_error_logging(errx_fn
, 2, _EVENT_LOG_ERR
,
540 "Fatal error; too many kumquats (5)");
544 event_warnx("Far too many %s (%d)", "wombats", 99);
545 LOGEQ(_EVENT_LOG_WARN
, "Far too many wombats (99)");
548 event_msgx("Connecting lime to coconut");
549 LOGEQ(_EVENT_LOG_MSG
, "Connecting lime to coconut");
552 event_debug(("A millisecond passed! We should log that!"));
554 LOGEQ(_EVENT_LOG_DEBUG
, "A millisecond passed! We should log that!");
556 tt_int_op(logsev
,==,0);
557 tt_ptr_op(logmsg
,==,NULL
);
561 /* Try with an errno. */
563 event_warn("Couldn't open %s", "/bad/file");
564 evutil_snprintf(buf
, sizeof(buf
),
565 "Couldn't open /bad/file: %s",strerror(ENOENT
));
566 LOGEQ(_EVENT_LOG_WARN
,buf
);
570 evutil_snprintf(buf
, sizeof(buf
),
571 "Couldn't open /very/bad/file: %s",strerror(ENOENT
));
572 check_error_logging(err_fn
, 5, _EVENT_LOG_ERR
, buf
);
576 /* Try with a socket errno. */
577 fd
= socket(AF_INET
, SOCK_STREAM
, 0);
579 evutil_snprintf(buf
, sizeof(buf
),
580 "Unhappy socket: %s",
581 evutil_socket_error_to_string(WSAEWOULDBLOCK
));
582 EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK
);
584 evutil_snprintf(buf
, sizeof(buf
),
585 "Unhappy socket: %s", strerror(EAGAIN
));
588 event_sock_warn(fd
, "Unhappy socket");
589 LOGEQ(_EVENT_LOG_WARN
, buf
);
593 check_error_logging(sock_err_fn
, 20, _EVENT_LOG_ERR
, buf
);
603 evutil_closesocket(fd
);
607 test_evutil_strlcpy(void *arg
)
611 /* Successful case. */
612 tt_int_op(5, ==, strlcpy(buf
, "Hello", sizeof(buf
)));
613 tt_str_op(buf
, ==, "Hello");
615 /* Overflow by a lot. */
616 tt_int_op(13, ==, strlcpy(buf
, "pentasyllabic", sizeof(buf
)));
617 tt_str_op(buf
, ==, "pentasy");
619 /* Overflow by exactly one. */
620 tt_int_op(8, ==, strlcpy(buf
, "overlong", sizeof(buf
)));
621 tt_str_op(buf
, ==, "overlon");
626 struct example_struct
{
633 test_evutil_upcast(void *arg
)
635 struct example_struct es1
;
641 tt_int_op(evutil_offsetof(struct example_struct
, b
), ==, sizeof(char*));
644 tt_ptr_op(EVUTIL_UPCAST(cp
, struct example_struct
, b
), ==, &es1
);
651 test_evutil_integers(void *arg
)
668 tt_int_op(sizeof(u64
), ==, 8);
669 tt_int_op(sizeof(i64
), ==, 8);
670 tt_int_op(sizeof(u32
), ==, 4);
671 tt_int_op(sizeof(i32
), ==, 4);
672 tt_int_op(sizeof(u16
), ==, 2);
673 tt_int_op(sizeof(i16
), ==, 2);
674 tt_int_op(sizeof(u8
), ==, 1);
675 tt_int_op(sizeof(i8
), ==, 1);
677 tt_int_op(sizeof(ev_ssize_t
), ==, sizeof(size_t));
678 tt_int_op(sizeof(ev_intptr_t
), >=, sizeof(void *));
679 tt_int_op(sizeof(ev_uintptr_t
), ==, sizeof(intptr_t));
683 tt_assert(u64
/ 1000000000 == 1000000000);
686 tt_assert(i64
/ 1000000000 == -1000000000);
695 tt_assert(i64
== EV_INT64_MIN
);
705 tt_assert(i32
== EV_INT32_MIN
);
715 tt_assert(i16
== EV_INT16_MIN
);
725 tt_assert(i8
== EV_INT8_MIN
);
728 ssize
= EV_SSIZE_MAX
;
729 tt_assert(ssize
> 0);
731 tt_assert(ssize
< 0);
732 tt_assert(ssize
== EV_SSIZE_MIN
);
735 iptr
= (ev_intptr_t
)ptr
;
736 uptr
= (ev_uintptr_t
)ptr
;
738 tt_assert(ptr
== &ssize
);
740 tt_assert(ptr
== &ssize
);
748 struct evutil_addrinfo
*
749 ai_find_by_family(struct evutil_addrinfo
*ai
, int family
)
752 if (ai
->ai_family
== family
)
759 struct evutil_addrinfo
*
760 ai_find_by_protocol(struct evutil_addrinfo
*ai
, int protocol
)
763 if (ai
->ai_protocol
== protocol
)
772 _test_ai_eq(const struct evutil_addrinfo
*ai
, const char *sockaddr_port
,
773 int socktype
, int protocol
, int line
)
775 struct sockaddr_storage ss
;
776 int slen
= sizeof(ss
);
779 memset(&ss
, 0, sizeof(ss
));
781 tt_int_op(ai
->ai_socktype
, ==, socktype
);
783 tt_int_op(ai
->ai_protocol
, ==, protocol
);
785 if (evutil_parse_sockaddr_port(
786 sockaddr_port
, (struct sockaddr
*)&ss
, &slen
)<0) {
787 TT_FAIL(("Couldn't parse expected address %s on line %d",
788 sockaddr_port
, line
));
791 if (ai
->ai_family
!= ss
.ss_family
) {
792 TT_FAIL(("Address family %d did not match %d on line %d",
793 ai
->ai_family
, ss
.ss_family
, line
));
796 if (ai
->ai_addr
->sa_family
== AF_INET
) {
797 struct sockaddr_in
*sin
= (struct sockaddr_in
*)ai
->ai_addr
;
798 evutil_inet_ntop(AF_INET
, &sin
->sin_addr
, buf
, sizeof(buf
));
799 gotport
= ntohs(sin
->sin_port
);
800 if (ai
->ai_addrlen
!= sizeof(struct sockaddr_in
)) {
801 TT_FAIL(("Addr size mismatch on line %d", line
));
805 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)ai
->ai_addr
;
806 evutil_inet_ntop(AF_INET6
, &sin6
->sin6_addr
, buf
, sizeof(buf
));
807 gotport
= ntohs(sin6
->sin6_port
);
808 if (ai
->ai_addrlen
!= sizeof(struct sockaddr_in6
)) {
809 TT_FAIL(("Addr size mismatch on line %d", line
));
813 if (evutil_sockaddr_cmp(ai
->ai_addr
, (struct sockaddr
*)&ss
, 1)) {
814 TT_FAIL(("Wanted %s, got %s:%d on line %d", sockaddr_port
,
815 buf
, gotport
, line
));
818 TT_BLATHER(("Wanted %s, got %s:%d on line %d", sockaddr_port
,
819 buf
, gotport
, line
));
823 TT_FAIL(("Test failed on line %d", line
));
828 test_evutil_rand(void *arg
)
835 memset(buf2
, 0, sizeof(buf2
));
836 memset(counts
, 0, sizeof(counts
));
839 /* Try a few different start and end points; try to catch
840 * the various misaligned cases of arc4random_buf */
841 int startpoint
= _evutil_weakrand() % 4;
842 int endpoint
= 32 - (_evutil_weakrand() % 4);
844 memset(buf2
, 0, sizeof(buf2
));
846 /* Do 6 runs over buf1, or-ing the result into buf2 each
847 * time, to make sure we're setting each byte that we mean
850 memset(buf1
, 0, sizeof(buf1
));
851 evutil_secure_rng_get_bytes(buf1
+ startpoint
,
852 endpoint
-startpoint
);
853 n
+= endpoint
- startpoint
;
854 for (j
=0; j
<32; ++j
) {
855 if (j
>= startpoint
&& j
< endpoint
) {
857 ++counts
[(unsigned char)buf1
[j
]];
859 tt_assert(buf1
[j
] == 0);
860 tt_int_op(buf1
[j
], ==, 0);
866 /* This will give a false positive with P=(256**8)==(2**64)
867 * for each character. */
868 for (j
=startpoint
;j
<endpoint
;++j
) {
869 tt_int_op(buf2
[j
], !=, 0);
873 /* for (i=0;i<256;++i) { printf("%3d %2d\n", i, counts[i]); } */
879 test_evutil_getaddrinfo(void *arg
)
881 struct evutil_addrinfo
*ai
= NULL
, *a
;
882 struct evutil_addrinfo hints
;
884 struct sockaddr_in6
*sin6
;
885 struct sockaddr_in
*sin
;
890 /* Try using it as a pton. */
891 memset(&hints
, 0, sizeof(hints
));
892 hints
.ai_family
= PF_UNSPEC
;
893 hints
.ai_socktype
= SOCK_STREAM
;
894 r
= evutil_getaddrinfo("1.2.3.4", "8080", &hints
, &ai
);
897 tt_ptr_op(ai
->ai_next
, ==, NULL
); /* no ambiguity */
898 test_ai_eq(ai
, "1.2.3.4:8080", SOCK_STREAM
, IPPROTO_TCP
);
899 evutil_freeaddrinfo(ai
);
902 memset(&hints
, 0, sizeof(hints
));
903 hints
.ai_family
= PF_UNSPEC
;
904 hints
.ai_protocol
= IPPROTO_UDP
;
905 r
= evutil_getaddrinfo("1001:b0b::f00f", "4321", &hints
, &ai
);
908 tt_ptr_op(ai
->ai_next
, ==, NULL
); /* no ambiguity */
909 test_ai_eq(ai
, "[1001:b0b::f00f]:4321", SOCK_DGRAM
, IPPROTO_UDP
);
910 evutil_freeaddrinfo(ai
);
913 /* Try out the behavior of nodename=NULL */
914 memset(&hints
, 0, sizeof(hints
));
915 hints
.ai_family
= PF_INET
;
916 hints
.ai_protocol
= IPPROTO_TCP
;
917 hints
.ai_flags
= EVUTIL_AI_PASSIVE
; /* as if for bind */
918 r
= evutil_getaddrinfo(NULL
, "9999", &hints
, &ai
);
921 tt_ptr_op(ai
->ai_next
, ==, NULL
);
922 test_ai_eq(ai
, "0.0.0.0:9999", SOCK_STREAM
, IPPROTO_TCP
);
923 evutil_freeaddrinfo(ai
);
925 hints
.ai_flags
= 0; /* as if for connect */
926 r
= evutil_getaddrinfo(NULL
, "9998", &hints
, &ai
);
929 test_ai_eq(ai
, "127.0.0.1:9998", SOCK_STREAM
, IPPROTO_TCP
);
930 tt_ptr_op(ai
->ai_next
, ==, NULL
);
931 evutil_freeaddrinfo(ai
);
934 hints
.ai_flags
= 0; /* as if for connect */
935 hints
.ai_family
= PF_INET6
;
936 r
= evutil_getaddrinfo(NULL
, "9997", &hints
, &ai
);
939 tt_ptr_op(ai
->ai_next
, ==, NULL
);
940 test_ai_eq(ai
, "[::1]:9997", SOCK_STREAM
, IPPROTO_TCP
);
941 evutil_freeaddrinfo(ai
);
944 hints
.ai_flags
= EVUTIL_AI_PASSIVE
; /* as if for bind. */
945 hints
.ai_family
= PF_INET6
;
946 r
= evutil_getaddrinfo(NULL
, "9996", &hints
, &ai
);
949 tt_ptr_op(ai
->ai_next
, ==, NULL
);
950 test_ai_eq(ai
, "[::]:9996", SOCK_STREAM
, IPPROTO_TCP
);
951 evutil_freeaddrinfo(ai
);
954 /* Now try an unspec one. We should get a v6 and a v4. */
955 hints
.ai_family
= PF_UNSPEC
;
956 r
= evutil_getaddrinfo(NULL
, "9996", &hints
, &ai
);
959 a
= ai_find_by_family(ai
, PF_INET6
);
961 test_ai_eq(a
, "[::]:9996", SOCK_STREAM
, IPPROTO_TCP
);
962 a
= ai_find_by_family(ai
, PF_INET
);
964 test_ai_eq(a
, "0.0.0.0:9996", SOCK_STREAM
, IPPROTO_TCP
);
965 evutil_freeaddrinfo(ai
);
968 /* Try out AI_NUMERICHOST: successful case. Also try
970 memset(&hints
, 0, sizeof(hints
));
971 hints
.ai_family
= PF_UNSPEC
;
972 hints
.ai_flags
= EVUTIL_AI_NUMERICHOST
;
973 r
= evutil_getaddrinfo("1.2.3.4", NULL
, &hints
, &ai
);
975 a
= ai_find_by_protocol(ai
, IPPROTO_TCP
);
977 test_ai_eq(a
, "1.2.3.4", SOCK_STREAM
, IPPROTO_TCP
);
978 a
= ai_find_by_protocol(ai
, IPPROTO_UDP
);
980 test_ai_eq(a
, "1.2.3.4", SOCK_DGRAM
, IPPROTO_UDP
);
981 evutil_freeaddrinfo(ai
);
984 /* Try the failing case of AI_NUMERICHOST */
985 memset(&hints
, 0, sizeof(hints
));
986 hints
.ai_family
= PF_UNSPEC
;
987 hints
.ai_flags
= EVUTIL_AI_NUMERICHOST
;
988 r
= evutil_getaddrinfo("www.google.com", "80", &hints
, &ai
);
989 tt_int_op(r
, ==, EVUTIL_EAI_NONAME
);
990 tt_ptr_op(ai
, ==, NULL
);
992 /* Try symbolic service names wit AI_NUMERICSERV */
993 memset(&hints
, 0, sizeof(hints
));
994 hints
.ai_family
= PF_UNSPEC
;
995 hints
.ai_socktype
= SOCK_STREAM
;
996 hints
.ai_flags
= EVUTIL_AI_NUMERICSERV
;
997 r
= evutil_getaddrinfo("1.2.3.4", "http", &hints
, &ai
);
998 tt_int_op(r
,==,EVUTIL_EAI_NONAME
);
1000 /* Try symbolic service names */
1001 memset(&hints
, 0, sizeof(hints
));
1002 hints
.ai_family
= PF_UNSPEC
;
1003 hints
.ai_socktype
= SOCK_STREAM
;
1004 r
= evutil_getaddrinfo("1.2.3.4", "http", &hints
, &ai
);
1006 TT_DECLARE("SKIP", ("Symbolic service names seem broken."));
1009 test_ai_eq(ai
, "1.2.3.4:80", SOCK_STREAM
, IPPROTO_TCP
);
1010 evutil_freeaddrinfo(ai
);
1014 /* Now do some actual lookups. */
1015 memset(&hints
, 0, sizeof(hints
));
1016 hints
.ai_family
= PF_INET
;
1017 hints
.ai_protocol
= IPPROTO_TCP
;
1018 hints
.ai_socktype
= SOCK_STREAM
;
1019 r
= evutil_getaddrinfo("www.google.com", "80", &hints
, &ai
);
1021 TT_DECLARE("SKIP", ("Couldn't resolve www.google.com"));
1024 tt_int_op(ai
->ai_family
, ==, PF_INET
);
1025 tt_int_op(ai
->ai_protocol
, ==, IPPROTO_TCP
);
1026 tt_int_op(ai
->ai_socktype
, ==, SOCK_STREAM
);
1027 tt_int_op(ai
->ai_addrlen
, ==, sizeof(struct sockaddr_in
));
1028 sin
= (struct sockaddr_in
*)ai
->ai_addr
;
1029 tt_int_op(sin
->sin_family
, ==, AF_INET
);
1030 tt_int_op(sin
->sin_port
, ==, htons(80));
1031 tt_int_op(sin
->sin_addr
.s_addr
, !=, 0xffffffff);
1033 cp
= evutil_inet_ntop(AF_INET
, &sin
->sin_addr
, buf
, sizeof(buf
));
1034 TT_BLATHER(("www.google.com resolved to %s",
1035 cp
?cp
:"<unwriteable>"));
1036 evutil_freeaddrinfo(ai
);
1040 hints
.ai_family
= PF_INET6
;
1041 r
= evutil_getaddrinfo("ipv6.google.com", "80", &hints
, &ai
);
1043 TT_BLATHER(("Couldn't do an ipv6 lookup for ipv6.google.com"));
1046 tt_int_op(ai
->ai_family
, ==, PF_INET6
);
1047 tt_int_op(ai
->ai_addrlen
, ==, sizeof(struct sockaddr_in6
));
1048 sin6
= (struct sockaddr_in6
*)ai
->ai_addr
;
1049 tt_int_op(sin6
->sin6_port
, ==, htons(80));
1051 cp
= evutil_inet_ntop(AF_INET6
, &sin6
->sin6_addr
, buf
,
1053 TT_BLATHER(("ipv6.google.com resolved to %s",
1054 cp
?cp
:"<unwriteable>"));
1059 evutil_freeaddrinfo(ai
);
1064 test_evutil_loadsyslib(void *arg
)
1068 h
= evutil_load_windows_system_library(TEXT("kernel32.dll"));
1078 struct testcase_t util_testcases
[] = {
1079 { "ipv4_parse", regress_ipv4_parse
, 0, NULL
, NULL
},
1080 { "ipv6_parse", regress_ipv6_parse
, 0, NULL
, NULL
},
1081 { "sockaddr_port_parse", regress_sockaddr_port_parse
, 0, NULL
, NULL
},
1082 { "sockaddr_port_format", regress_sockaddr_port_format
, 0, NULL
, NULL
},
1083 { "sockaddr_predicates", test_evutil_sockaddr_predicates
, 0,NULL
,NULL
},
1084 { "evutil_snprintf", test_evutil_snprintf
, 0, NULL
, NULL
},
1085 { "evutil_strtoll", test_evutil_strtoll
, 0, NULL
, NULL
},
1086 { "evutil_casecmp", test_evutil_casecmp
, 0, NULL
, NULL
},
1087 { "strlcpy", test_evutil_strlcpy
, 0, NULL
, NULL
},
1088 { "log", test_evutil_log
, TT_FORK
, NULL
, NULL
},
1089 { "upcast", test_evutil_upcast
, 0, NULL
, NULL
},
1090 { "integers", test_evutil_integers
, 0, NULL
, NULL
},
1091 { "rand", test_evutil_rand
, TT_FORK
, NULL
, NULL
},
1092 { "getaddrinfo", test_evutil_getaddrinfo
, TT_FORK
, NULL
, NULL
},
1094 { "loadsyslib", test_evutil_loadsyslib
, TT_FORK
, NULL
, NULL
},