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 62enum entry_status { NORMAL, CANONICAL, BAD }; 63 64/* This is a big table of results we expect from generating and parsing */ 65static 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 79static 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 109static void 110regress_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 154static void 155regress_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 207static 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 226static void 227regress_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 282static void 283regress_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>"); 314end: 315 ; 316} 317 318static 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 337static void 338test_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 362static void 363test_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 378static void 379test_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 413static void 414test_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); 430end: 431 ; 432} 433 434static int logsev = 0; 435static char *logmsg = NULL; 436 437static void 438logfn(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 449static int fatal_want_severity = 0; 450static const char *fatal_want_message = NULL; 451static void 452fatalfn(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 464static void 465check_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 } 481end: 482 ; 483} 484 485static void 486errx_fn(void) 487{ 488 event_errx(2, "Fatal error; too many kumquats (%d)", 5); 489} 490 491static void 492err_fn(void) 493{ 494 errno = ENOENT; 495 event_err(5,"Couldn't open %s", "/very/bad/file"); 496} 497 498static void 499sock_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 511static void 512test_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 595end: 596 if (logmsg) 597 free(logmsg); 598 if (fd >= 0) 599 evutil_closesocket(fd); 600} 601 602static void 603test_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"); 618end: 619 ; 620} 621 622struct example_struct { 623 const char *a; 624 const char *b; 625 long c; 626}; 627 628static void 629test_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 642end: 643 ; 644} 645 646static void 647test_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); 740end: 741 ; 742} 743 744struct evutil_addrinfo * 745ai_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 755struct evutil_addrinfo * 756ai_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 767int 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; 818end: 819 TT_FAIL(("Test failed on line %d", line)); 820 return -1; 821} 822 823static void 824test_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]); } */ 870end: 871 ; 872} 873 874static void 875test_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_int_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 1053end: 1054 if (ai) 1055 evutil_freeaddrinfo(ai); 1056} 1057 1058#ifdef WIN32 1059static void 1060test_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 1067end: 1068 if (h) 1069 CloseHandle(h); 1070 1071} 1072#endif 1073 1074struct 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 1095