1/* $NetBSD: regress_util.c,v 1.5 2021/04/10 19:02:37 rillig Exp $ */ 2 3/* 4 * Copyright (c) 2009-2012 Nick Mathewson and Niels Provos 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/** For event_debug() usage/coverage */ 30#define EVENT_VISIBILITY_WANT_DLLIMPORT 31 32#include "../util-internal.h" 33 34#ifdef _WIN32 35#include <winsock2.h> 36#include <windows.h> 37#include <ws2tcpip.h> 38#endif 39 40#include "event2/event-config.h" 41#include <sys/cdefs.h> 42__RCSID("$NetBSD: regress_util.c,v 1.5 2021/04/10 19:02:37 rillig Exp $"); 43 44#include <sys/types.h> 45 46#ifndef _WIN32 47#include <sys/socket.h> 48#include <netinet/in.h> 49#include <arpa/inet.h> 50#include <unistd.h> 51#endif 52#ifdef EVENT__HAVE_NETINET_IN6_H 53#include <netinet/in6.h> 54#endif 55#ifdef EVENT__HAVE_SYS_WAIT_H 56#include <sys/wait.h> 57#endif 58#include <signal.h> 59#include <stdio.h> 60#include <stdlib.h> 61#include <string.h> 62#include <limits.h> 63 64#include "event2/event.h" 65#include "event2/util.h" 66#include "../ipv6-internal.h" 67#include "../log-internal.h" 68#include "../strlcpy-internal.h" 69#include "../mm-internal.h" 70#include "../time-internal.h" 71 72#include "regress.h" 73 74enum entry_status { NORMAL, CANONICAL, BAD }; 75 76/* This is a big table of results we expect from generating and parsing */ 77static struct ipv4_entry { 78 const char *addr; 79 ev_uint32_t res; 80 enum entry_status status; 81} ipv4_entries[] = { 82 { "1.2.3.4", 0x01020304u, CANONICAL }, 83 { "255.255.255.255", 0xffffffffu, CANONICAL }, 84 { "256.0.0.0", 0, BAD }, 85 { "ABC", 0, BAD }, 86 { "1.2.3.4.5", 0, BAD }, 87 { "176.192.208.244", 0xb0c0d0f4, CANONICAL }, 88 { NULL, 0, BAD }, 89}; 90 91static struct ipv6_entry { 92 const char *addr; 93 ev_uint32_t res[4]; 94 enum entry_status status; 95} ipv6_entries[] = { 96 { "::", { 0, 0, 0, 0, }, CANONICAL }, 97 { "0:0:0:0:0:0:0:0", { 0, 0, 0, 0, }, NORMAL }, 98 { "::1", { 0, 0, 0, 1, }, CANONICAL }, 99 { "::1.2.3.4", { 0, 0, 0, 0x01020304, }, CANONICAL }, 100 { "ffff:1::", { 0xffff0001u, 0, 0, 0, }, CANONICAL }, 101 { "ffff:0000::", { 0xffff0000u, 0, 0, 0, }, NORMAL }, 102 { "ffff::1234", { 0xffff0000u, 0, 0, 0x1234, }, CANONICAL }, 103 { "0102::1.2.3.4", {0x01020000u, 0, 0, 0x01020304u }, NORMAL }, 104 { "::9:c0a8:1:1", { 0, 0, 0x0009c0a8u, 0x00010001u }, CANONICAL }, 105 { "::ffff:1.2.3.4", { 0, 0, 0x000ffffu, 0x01020304u }, CANONICAL }, 106 { "FFFF::", { 0xffff0000u, 0, 0, 0 }, NORMAL }, 107 { "foobar.", { 0, 0, 0, 0 }, BAD }, 108 { "foobar", { 0, 0, 0, 0 }, BAD }, 109 { "fo:obar", { 0, 0, 0, 0 }, BAD }, 110 { "ffff", { 0, 0, 0, 0 }, BAD }, 111 { "fffff::", { 0, 0, 0, 0 }, BAD }, 112 { "fffff::", { 0, 0, 0, 0 }, BAD }, 113 { "::1.0.1.1000", { 0, 0, 0, 0 }, BAD }, 114 { "1:2:33333:4::", { 0, 0, 0, 0 }, BAD }, 115 { "1:2:3:4:5:6:7:8:9", { 0, 0, 0, 0 }, BAD }, 116 { "1::2::3", { 0, 0, 0, 0 }, BAD }, 117 { ":::1", { 0, 0, 0, 0 }, BAD }, 118 { NULL, { 0, 0, 0, 0, }, BAD }, 119}; 120 121static void 122regress_ipv4_parse(void *ptr) 123{ 124 int i; 125 for (i = 0; ipv4_entries[i].addr; ++i) { 126 char written[128]; 127 struct ipv4_entry *ent = &ipv4_entries[i]; 128 struct in_addr in; 129 int r; 130 r = evutil_inet_pton(AF_INET, ent->addr, &in); 131 if (r == 0) { 132 if (ent->status != BAD) { 133 TT_FAIL(("%s did not parse, but it's a good address!", 134 ent->addr)); 135 } 136 continue; 137 } 138 if (ent->status == BAD) { 139 TT_FAIL(("%s parsed, but we expected an error", ent->addr)); 140 continue; 141 } 142 if (ntohl(in.s_addr) != ent->res) { 143 TT_FAIL(("%s parsed to %lx, but we expected %lx", ent->addr, 144 (unsigned long)ntohl(in.s_addr), 145 (unsigned long)ent->res)); 146 continue; 147 } 148 if (ent->status == CANONICAL) { 149 const char *w = evutil_inet_ntop(AF_INET, &in, written, 150 sizeof(written)); 151 if (!w) { 152 TT_FAIL(("Tried to write out %s; got NULL.", ent->addr)); 153 continue; 154 } 155 if (strcmp(written, ent->addr)) { 156 TT_FAIL(("Tried to write out %s; got %s", 157 ent->addr, written)); 158 continue; 159 } 160 } 161 162 } 163 164} 165 166static void 167regress_ipv6_parse(void *ptr) 168{ 169#ifdef AF_INET6 170 int i, j; 171 172 for (i = 0; ipv6_entries[i].addr; ++i) { 173 char written[128]; 174 struct ipv6_entry *ent = &ipv6_entries[i]; 175 struct in6_addr in6; 176 int r; 177 r = evutil_inet_pton(AF_INET6, ent->addr, &in6); 178 if (r == 0) { 179 if (ent->status != BAD) 180 TT_FAIL(("%s did not parse, but it's a good address!", 181 ent->addr)); 182 continue; 183 } 184 if (ent->status == BAD) { 185 TT_FAIL(("%s parsed, but we expected an error", ent->addr)); 186 continue; 187 } 188 for (j = 0; j < 4; ++j) { 189 /* Can't use s6_addr32 here; some don't have it. */ 190 ev_uint32_t u = 191 ((ev_uint32_t)in6.s6_addr[j*4 ] << 24) | 192 ((ev_uint32_t)in6.s6_addr[j*4+1] << 16) | 193 ((ev_uint32_t)in6.s6_addr[j*4+2] << 8) | 194 ((ev_uint32_t)in6.s6_addr[j*4+3]); 195 if (u != ent->res[j]) { 196 TT_FAIL(("%s did not parse as expected.", ent->addr)); 197 continue; 198 } 199 } 200 if (ent->status == CANONICAL) { 201 const char *w = evutil_inet_ntop(AF_INET6, &in6, written, 202 sizeof(written)); 203 if (!w) { 204 TT_FAIL(("Tried to write out %s; got NULL.", ent->addr)); 205 continue; 206 } 207 if (strcmp(written, ent->addr)) { 208 TT_FAIL(("Tried to write out %s; got %s", ent->addr, written)); 209 continue; 210 } 211 } 212 213 } 214#else 215 TT_BLATHER(("Skipping IPv6 address parsing.")); 216#endif 217} 218 219static struct ipv6_entry_scope { 220 const char *addr; 221 ev_uint32_t res[4]; 222 unsigned scope; 223 enum entry_status status; 224} ipv6_entries_scope[] = { 225 { "2001:DB8::", { 0x20010db8, 0, 0 }, 0, NORMAL }, 226 { "2001:DB8::%0", { 0x20010db8, 0, 0, 0 }, 0, NORMAL }, 227 { "2001:DB8::%1", { 0x20010db8, 0, 0, 0 }, 1, NORMAL }, 228 { "foobar.", { 0, 0, 0, 0 }, 0, BAD }, 229 { "2001:DB8::%does-not-exist", { 0, 0, 0, 0 }, 0, BAD }, 230 { NULL, { 0, 0, 0, 0, }, 0, BAD }, 231}; 232static void 233regress_ipv6_parse_scope(void *ptr) 234{ 235#ifdef AF_INET6 236 int i, j; 237 unsigned if_scope; 238 239 for (i = 0; ipv6_entries_scope[i].addr; ++i) { 240 struct ipv6_entry_scope *ent = &ipv6_entries_scope[i]; 241 struct in6_addr in6; 242 int r; 243 r = evutil_inet_pton_scope(AF_INET6, ent->addr, &in6, 244 &if_scope); 245 if (r == 0) { 246 if (ent->status != BAD) 247 TT_FAIL(("%s did not parse, but it's a good address!", 248 ent->addr)); 249 continue; 250 } 251 if (ent->status == BAD) { 252 TT_FAIL(("%s parsed, but we expected an error", ent->addr)); 253 continue; 254 } 255 for (j = 0; j < 4; ++j) { 256 /* Can't use s6_addr32 here; some don't have it. */ 257 ev_uint32_t u = 258 ((ev_uint32_t)in6.s6_addr[j*4 ] << 24) | 259 ((ev_uint32_t)in6.s6_addr[j*4+1] << 16) | 260 ((ev_uint32_t)in6.s6_addr[j*4+2] << 8) | 261 ((ev_uint32_t)in6.s6_addr[j*4+3]); 262 if (u != ent->res[j]) { 263 TT_FAIL(("%s did not parse as expected.", ent->addr)); 264 continue; 265 } 266 } 267 if (if_scope != ent->scope) { 268 TT_FAIL(("%s did not parse as expected.", ent->addr)); 269 continue; 270 } 271 } 272#else 273 TT_BLATHER(("Skipping IPv6 address parsing.")); 274#endif 275} 276 277 278static struct sa_port_ent { 279 const char *parse; 280 int safamily; 281 const char *addr; 282 int port; 283} sa_port_ents[] = { 284 { "[ffff::1]:1000", AF_INET6, "ffff::1", 1000 }, 285 { "[ffff::1]", AF_INET6, "ffff::1", 0 }, 286 { "[ffff::1", 0, NULL, 0 }, 287 { "[ffff::1]:65599", 0, NULL, 0 }, 288 { "[ffff::1]:0", 0, NULL, 0 }, 289 { "[ffff::1]:-1", 0, NULL, 0 }, 290 { "::1", AF_INET6, "::1", 0 }, 291 { "1:2::1", AF_INET6, "1:2::1", 0 }, 292 { "192.168.0.1:50", AF_INET, "192.168.0.1", 50 }, 293 { "1.2.3.4", AF_INET, "1.2.3.4", 0 }, 294 { NULL, 0, NULL, 0 }, 295}; 296 297static void 298regress_sockaddr_port_parse(void *ptr) 299{ 300 struct sockaddr_storage ss; 301 int i, r; 302 303 for (i = 0; sa_port_ents[i].parse; ++i) { 304 struct sa_port_ent *ent = &sa_port_ents[i]; 305 int len = sizeof(ss); 306 memset(&ss, 0, sizeof(ss)); 307 r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len); 308 if (r < 0) { 309 if (ent->safamily) 310 TT_FAIL(("Couldn't parse %s!", ent->parse)); 311 continue; 312 } else if (! ent->safamily) { 313 TT_FAIL(("Shouldn't have been able to parse %s!", ent->parse)); 314 continue; 315 } 316 if (ent->safamily == AF_INET) { 317 struct sockaddr_in sin; 318 memset(&sin, 0, sizeof(sin)); 319#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 320 sin.sin_len = sizeof(sin); 321#endif 322 sin.sin_family = AF_INET; 323 sin.sin_port = htons(ent->port); 324 r = evutil_inet_pton(AF_INET, ent->addr, &sin.sin_addr); 325 if (1 != r) { 326 TT_FAIL(("Couldn't parse ipv4 target %s.", ent->addr)); 327 } else if (memcmp(&sin, &ss, sizeof(sin))) { 328 TT_FAIL(("Parse for %s was not as expected.", ent->parse)); 329 } else if (len != sizeof(sin)) { 330 TT_FAIL(("Length for %s not as expected.",ent->parse)); 331 } 332 } else { 333 struct sockaddr_in6 sin6; 334 memset(&sin6, 0, sizeof(sin6)); 335#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 336 sin6.sin6_len = sizeof(sin6); 337#endif 338 sin6.sin6_family = AF_INET6; 339 sin6.sin6_port = htons(ent->port); 340 r = evutil_inet_pton(AF_INET6, ent->addr, &sin6.sin6_addr); 341 if (1 != r) { 342 TT_FAIL(("Couldn't parse ipv6 target %s.", ent->addr)); 343 } else if (memcmp(&sin6, &ss, sizeof(sin6))) { 344 TT_FAIL(("Parse for %s was not as expected.", ent->parse)); 345 } else if (len != sizeof(sin6)) { 346 TT_FAIL(("Length for %s not as expected.",ent->parse)); 347 } 348 } 349 } 350} 351 352 353static void 354regress_sockaddr_port_format(void *ptr) 355{ 356 struct sockaddr_storage ss; 357 int len; 358 const char *cp; 359 char cbuf[128]; 360 int r; 361 362 len = sizeof(ss); 363 r = evutil_parse_sockaddr_port("192.168.1.1:80", 364 (struct sockaddr*)&ss, &len); 365 tt_int_op(r,==,0); 366 cp = evutil_format_sockaddr_port_( 367 (struct sockaddr*)&ss, cbuf, sizeof(cbuf)); 368 tt_ptr_op(cp,==,cbuf); 369 tt_str_op(cp,==,"192.168.1.1:80"); 370 371 len = sizeof(ss); 372 r = evutil_parse_sockaddr_port("[ff00::8010]:999", 373 (struct sockaddr*)&ss, &len); 374 tt_int_op(r,==,0); 375 cp = evutil_format_sockaddr_port_( 376 (struct sockaddr*)&ss, cbuf, sizeof(cbuf)); 377 tt_ptr_op(cp,==,cbuf); 378 tt_str_op(cp,==,"[ff00::8010]:999"); 379 380 ss.ss_family=99; 381 cp = evutil_format_sockaddr_port_( 382 (struct sockaddr*)&ss, cbuf, sizeof(cbuf)); 383 tt_ptr_op(cp,==,cbuf); 384 tt_str_op(cp,==,"<addr with socktype 99>"); 385end: 386 ; 387} 388 389static struct sa_pred_ent { 390 const char *parse; 391 392 int is_loopback; 393} sa_pred_entries[] = { 394 { "127.0.0.1", 1 }, 395 { "127.0.3.2", 1 }, 396 { "128.1.2.3", 0 }, 397 { "18.0.0.1", 0 }, 398 { "129.168.1.1", 0 }, 399 400 { "::1", 1 }, 401 { "::0", 0 }, 402 { "f::1", 0 }, 403 { "::501", 0 }, 404 { NULL, 0 }, 405 406}; 407 408static void 409test_evutil_sockaddr_predicates(void *ptr) 410{ 411 struct sockaddr_storage ss; 412 int r, i; 413 414 for (i=0; sa_pred_entries[i].parse; ++i) { 415 struct sa_pred_ent *ent = &sa_pred_entries[i]; 416 int len = sizeof(ss); 417 418 r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len); 419 420 if (r<0) { 421 TT_FAIL(("Couldn't parse %s!", ent->parse)); 422 continue; 423 } 424 425 /* sockaddr_is_loopback */ 426 if (ent->is_loopback != evutil_sockaddr_is_loopback_((struct sockaddr*)&ss)) { 427 TT_FAIL(("evutil_sockaddr_loopback(%s) not as expected", 428 ent->parse)); 429 } 430 } 431} 432 433static void 434test_evutil_strtoll(void *ptr) 435{ 436 const char *s; 437 char *endptr; 438 439 tt_want(evutil_strtoll("5000000000", NULL, 10) == 440 ((ev_int64_t)5000000)*1000); 441 tt_want(evutil_strtoll("-5000000000", NULL, 10) == 442 ((ev_int64_t)5000000)*-1000); 443 s = " 99999stuff"; 444 tt_want(evutil_strtoll(s, &endptr, 10) == (ev_int64_t)99999); 445 tt_want(endptr == s+6); 446 tt_want(evutil_strtoll("foo", NULL, 10) == 0); 447 } 448 449static void 450test_evutil_snprintf(void *ptr) 451{ 452 char buf[16]; 453 int r; 454 ev_uint64_t u64 = ((ev_uint64_t)1000000000)*200; 455 ev_int64_t i64 = -1 * (ev_int64_t) u64; 456 size_t size = 8000; 457 ev_ssize_t ssize = -9000; 458 459 r = evutil_snprintf(buf, sizeof(buf), "%d %d", 50, 100); 460 tt_str_op(buf, ==, "50 100"); 461 tt_int_op(r, ==, 6); 462 463 r = evutil_snprintf(buf, sizeof(buf), "longish %d", 1234567890); 464 tt_str_op(buf, ==, "longish 1234567"); 465 tt_int_op(r, ==, 18); 466 467 r = evutil_snprintf(buf, sizeof(buf), EV_U64_FMT, EV_U64_ARG(u64)); 468 tt_str_op(buf, ==, "200000000000"); 469 tt_int_op(r, ==, 12); 470 471 r = evutil_snprintf(buf, sizeof(buf), EV_I64_FMT, EV_I64_ARG(i64)); 472 tt_str_op(buf, ==, "-200000000000"); 473 tt_int_op(r, ==, 13); 474 475 r = evutil_snprintf(buf, sizeof(buf), EV_SIZE_FMT" "EV_SSIZE_FMT, 476 EV_SIZE_ARG(size), EV_SSIZE_ARG(ssize)); 477 tt_str_op(buf, ==, "8000 -9000"); 478 tt_int_op(r, ==, 10); 479 480 end: 481 ; 482} 483 484static void 485test_evutil_casecmp(void *ptr) 486{ 487 tt_int_op(evutil_ascii_strcasecmp("ABC", "ABC"), ==, 0); 488 tt_int_op(evutil_ascii_strcasecmp("ABC", "abc"), ==, 0); 489 tt_int_op(evutil_ascii_strcasecmp("ABC", "abcd"), <, 0); 490 tt_int_op(evutil_ascii_strcasecmp("ABC", "abb"), >, 0); 491 tt_int_op(evutil_ascii_strcasecmp("ABCd", "abc"), >, 0); 492 493 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 100), ==, 0); 494 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 4), ==, 0); 495 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEXXXX", 4), ==, 0); 496 tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibE", 4), ==, 0); 497 tt_int_op(evutil_ascii_strncasecmp("Libe", "LibEvEnT", 4), ==, 0); 498 tt_int_op(evutil_ascii_strncasecmp("Lib", "LibEvEnT", 4), <, 0); 499 tt_int_op(evutil_ascii_strncasecmp("abc", "def", 99), <, 0); 500 tt_int_op(evutil_ascii_strncasecmp("Z", "qrst", 1), >, 0); 501end: 502 ; 503} 504 505static void 506test_evutil_rtrim(void *ptr) 507{ 508#define TEST_TRIM(s, result) \ 509 do { \ 510 if (cp) mm_free(cp); \ 511 cp = mm_strdup(s); \ 512 tt_assert(cp); \ 513 evutil_rtrim_lws_(cp); \ 514 tt_str_op(cp, ==, result); \ 515 } while(0) 516 517 char *cp = NULL; 518 (void) ptr; 519 520 TEST_TRIM("", ""); 521 TEST_TRIM("a", "a"); 522 TEST_TRIM("abcdef ghi", "abcdef ghi"); 523 524 TEST_TRIM(" ", ""); 525 TEST_TRIM(" ", ""); 526 TEST_TRIM("a ", "a"); 527 TEST_TRIM("abcdef gH ", "abcdef gH"); 528 529 TEST_TRIM("\t\t", ""); 530 TEST_TRIM(" \t", ""); 531 TEST_TRIM("\t", ""); 532 TEST_TRIM("a \t", "a"); 533 TEST_TRIM("a\t ", "a"); 534 TEST_TRIM("a\t", "a"); 535 TEST_TRIM("abcdef gH \t ", "abcdef gH"); 536 537end: 538 if (cp) 539 mm_free(cp); 540} 541 542static int logsev = 0; 543static char *logmsg = NULL; 544 545static void 546logfn(int severity, const char *msg) 547{ 548 logsev = severity; 549 tt_want(msg); 550 if (msg) { 551 if (logmsg) 552 free(logmsg); 553 logmsg = strdup(msg); 554 } 555} 556 557static int fatal_want_severity = 0; 558static const char *fatal_want_message = NULL; 559static void 560fatalfn(int exitcode) 561{ 562 if (logsev != fatal_want_severity || 563 !logmsg || 564 strcmp(logmsg, fatal_want_message)) 565 exit(0); 566 else 567 exit(exitcode); 568} 569 570#ifndef _WIN32 571#define CAN_CHECK_ERR 572static void 573check_error_logging(void (*fn)(void), int wantexitcode, 574 int wantseverity, const char *wantmsg) 575{ 576 pid_t pid; 577 int status = 0, exitcode; 578 fatal_want_severity = wantseverity; 579 fatal_want_message = wantmsg; 580 if ((pid = regress_fork()) == 0) { 581 /* child process */ 582 fn(); 583 exit(0); /* should be unreachable. */ 584 } else { 585 wait(&status); 586 exitcode = WEXITSTATUS(status); 587 tt_int_op(wantexitcode, ==, exitcode); 588 } 589end: 590 ; 591} 592 593static void 594errx_fn(void) 595{ 596 event_errx(2, "Fatal error; too many kumquats (%d)", 5); 597} 598 599static void 600err_fn(void) 601{ 602 errno = ENOENT; 603 event_err(5,"Couldn't open %s", "/very/bad/file"); 604} 605 606static void 607sock_err_fn(void) 608{ 609 evutil_socket_t fd = socket(AF_INET, SOCK_STREAM, 0); 610#ifdef _WIN32 611 EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK); 612#else 613 errno = EAGAIN; 614#endif 615 event_sock_err(20, fd, "Unhappy socket"); 616} 617#endif 618 619static void 620test_evutil_log(void *ptr) 621{ 622 evutil_socket_t fd = -1; 623 char buf[128]; 624 625 event_set_log_callback(logfn); 626 event_set_fatal_callback(fatalfn); 627#define RESET() do { \ 628 logsev = 0; \ 629 if (logmsg) free(logmsg); \ 630 logmsg = NULL; \ 631 } while (0) 632#define LOGEQ(sev,msg) do { \ 633 tt_int_op(logsev,==,sev); \ 634 tt_assert(logmsg != NULL); \ 635 tt_str_op(logmsg,==,msg); \ 636 } while (0) 637 638#ifdef CAN_CHECK_ERR 639 /* We need to disable these tests for now. Previously, the logging 640 * module didn't enforce the requirement that a fatal callback 641 * actually exit. Now, it exits no matter what, so if we wan to 642 * reinstate these tests, we'll need to fork for each one. */ 643 check_error_logging(errx_fn, 2, EVENT_LOG_ERR, 644 "Fatal error; too many kumquats (5)"); 645 RESET(); 646#endif 647 648 event_warnx("Far too many %s (%d)", "wombats", 99); 649 LOGEQ(EVENT_LOG_WARN, "Far too many wombats (99)"); 650 RESET(); 651 652 event_msgx("Connecting lime to coconut"); 653 LOGEQ(EVENT_LOG_MSG, "Connecting lime to coconut"); 654 RESET(); 655 656 event_debug(("A millisecond passed! We should log that!")); 657#ifdef USE_DEBUG 658 LOGEQ(EVENT_LOG_DEBUG, "A millisecond passed! We should log that!"); 659#else 660 tt_int_op(logsev,==,0); 661 tt_ptr_op(logmsg,==,NULL); 662#endif 663 RESET(); 664 665 /* Try with an errno. */ 666 errno = ENOENT; 667 event_warn("Couldn't open %s", "/bad/file"); 668 evutil_snprintf(buf, sizeof(buf), 669 "Couldn't open /bad/file: %s",strerror(ENOENT)); 670 LOGEQ(EVENT_LOG_WARN,buf); 671 RESET(); 672 673#ifdef CAN_CHECK_ERR 674 evutil_snprintf(buf, sizeof(buf), 675 "Couldn't open /very/bad/file: %s",strerror(ENOENT)); 676 check_error_logging(err_fn, 5, EVENT_LOG_ERR, buf); 677 RESET(); 678#endif 679 680 /* Try with a socket errno. */ 681 fd = socket(AF_INET, SOCK_STREAM, 0); 682#ifdef _WIN32 683 evutil_snprintf(buf, sizeof(buf), 684 "Unhappy socket: %s", 685 evutil_socket_error_to_string(WSAEWOULDBLOCK)); 686 EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK); 687#else 688 evutil_snprintf(buf, sizeof(buf), 689 "Unhappy socket: %s", strerror(EAGAIN)); 690 errno = EAGAIN; 691#endif 692 event_sock_warn(fd, "Unhappy socket"); 693 LOGEQ(EVENT_LOG_WARN, buf); 694 RESET(); 695 696#ifdef CAN_CHECK_ERR 697 check_error_logging(sock_err_fn, 20, EVENT_LOG_ERR, buf); 698 RESET(); 699#endif 700 701#undef RESET 702#undef LOGEQ 703end: 704 if (logmsg) 705 free(logmsg); 706 if (fd >= 0) 707 evutil_closesocket(fd); 708} 709 710static void 711test_evutil_strlcpy(void *arg) 712{ 713 char buf[8]; 714 715 /* Successful case. */ 716 tt_int_op(5, ==, strlcpy(buf, "Hello", sizeof(buf))); 717 tt_str_op(buf, ==, "Hello"); 718 719 /* Overflow by a lot. */ 720 tt_int_op(13, ==, strlcpy(buf, "pentasyllabic", sizeof(buf))); 721 tt_str_op(buf, ==, "pentasy"); 722 723 /* Overflow by exactly one. */ 724 tt_int_op(8, ==, strlcpy(buf, "overlong", sizeof(buf))); 725 tt_str_op(buf, ==, "overlon"); 726end: 727 ; 728} 729 730struct example_struct { 731 const char *a; 732 const char *b; 733 long c; 734}; 735 736static void 737test_evutil_upcast(void *arg) 738{ 739 struct example_struct es1; 740 const char **cp; 741 es1.a = "World"; 742 es1.b = "Hello"; 743 es1.c = -99; 744 745 tt_int_op(evutil_offsetof(struct example_struct, b), ==, sizeof(char*)); 746 747 cp = &es1.b; 748 tt_ptr_op(EVUTIL_UPCAST(cp, struct example_struct, b), ==, &es1); 749 750end: 751 ; 752} 753 754static void 755test_evutil_integers(void *arg) 756{ 757 ev_int64_t i64; 758 ev_uint64_t u64; 759 ev_int32_t i32; 760 ev_uint32_t u32; 761 ev_int16_t i16; 762 ev_uint16_t u16; 763 ev_int8_t i8; 764 ev_uint8_t u8; 765 766 void *ptr; 767 ev_intptr_t iptr; 768 ev_uintptr_t uptr; 769 770 ev_ssize_t ssize; 771 772 tt_int_op(sizeof(u64), ==, 8); 773 tt_int_op(sizeof(i64), ==, 8); 774 tt_int_op(sizeof(u32), ==, 4); 775 tt_int_op(sizeof(i32), ==, 4); 776 tt_int_op(sizeof(u16), ==, 2); 777 tt_int_op(sizeof(i16), ==, 2); 778 tt_int_op(sizeof(u8), ==, 1); 779 tt_int_op(sizeof(i8), ==, 1); 780 781 tt_int_op(sizeof(ev_ssize_t), ==, sizeof(size_t)); 782 tt_int_op(sizeof(ev_intptr_t), >=, sizeof(void *)); 783 tt_int_op(sizeof(ev_uintptr_t), ==, sizeof(intptr_t)); 784 785 u64 = 1000000000; 786 u64 *= 1000000000; 787 tt_assert(u64 / 1000000000 == 1000000000); 788 i64 = -1000000000; 789 i64 *= 1000000000; 790 tt_assert(i64 / 1000000000 == -1000000000); 791 792 u64 = EV_UINT64_MAX; 793 i64 = EV_INT64_MAX; 794 tt_assert(u64 > 0); 795 tt_assert(i64 > 0); 796 u64++; 797/* i64++; */ 798 tt_assert(u64 == 0); 799/* tt_assert(i64 == EV_INT64_MIN); */ 800/* tt_assert(i64 < 0); */ 801 802 u32 = EV_UINT32_MAX; 803 i32 = EV_INT32_MAX; 804 tt_assert(u32 > 0); 805 tt_assert(i32 > 0); 806 u32++; 807/* i32++; */ 808 tt_assert(u32 == 0); 809/* tt_assert(i32 == EV_INT32_MIN); */ 810/* tt_assert(i32 < 0); */ 811 812 u16 = EV_UINT16_MAX; 813 i16 = EV_INT16_MAX; 814 tt_assert(u16 > 0); 815 tt_assert(i16 > 0); 816 u16++; 817/* i16++; */ 818 tt_assert(u16 == 0); 819/* tt_assert(i16 == EV_INT16_MIN); */ 820/* tt_assert(i16 < 0); */ 821 822 u8 = EV_UINT8_MAX; 823 i8 = EV_INT8_MAX; 824 tt_assert(u8 > 0); 825 tt_assert(i8 > 0); 826 u8++; 827/* i8++;*/ 828 tt_assert(u8 == 0); 829/* tt_assert(i8 == EV_INT8_MIN); */ 830/* tt_assert(i8 < 0); */ 831 832/* 833 ssize = EV_SSIZE_MAX; 834 tt_assert(ssize > 0); 835 ssize++; 836 tt_assert(ssize < 0); 837 tt_assert(ssize == EV_SSIZE_MIN); 838*/ 839 840 ptr = &ssize; 841 iptr = (ev_intptr_t)ptr; 842 uptr = (ev_uintptr_t)ptr; 843 ptr = (void *)iptr; 844 tt_assert(ptr == &ssize); 845 ptr = (void *)uptr; 846 tt_assert(ptr == &ssize); 847 848 iptr = -1; 849 tt_assert(iptr < 0); 850end: 851 ; 852} 853 854struct evutil_addrinfo * 855ai_find_by_family(struct evutil_addrinfo *ai, int family) 856{ 857 while (ai) { 858 if (ai->ai_family == family) 859 return ai; 860 ai = ai->ai_next; 861 } 862 return NULL; 863} 864 865struct evutil_addrinfo * 866ai_find_by_protocol(struct evutil_addrinfo *ai, int protocol) 867{ 868 while (ai) { 869 if (ai->ai_protocol == protocol) 870 return ai; 871 ai = ai->ai_next; 872 } 873 return NULL; 874} 875 876 877int 878test_ai_eq_(const struct evutil_addrinfo *ai, const char *sockaddr_port, 879 int socktype, int protocol, int line) 880{ 881 struct sockaddr_storage ss; 882 int slen = sizeof(ss); 883 int gotport; 884 char buf[128]; 885 memset(&ss, 0, sizeof(ss)); 886 if (socktype > 0) 887 tt_int_op(ai->ai_socktype, ==, socktype); 888 if (protocol > 0) 889 tt_int_op(ai->ai_protocol, ==, protocol); 890 891 if (evutil_parse_sockaddr_port( 892 sockaddr_port, (struct sockaddr*)&ss, &slen)<0) { 893 TT_FAIL(("Couldn't parse expected address %s on line %d", 894 sockaddr_port, line)); 895 return -1; 896 } 897 if (ai->ai_family != ss.ss_family) { 898 TT_FAIL(("Address family %d did not match %d on line %d", 899 ai->ai_family, ss.ss_family, line)); 900 return -1; 901 } 902 if (ai->ai_addr->sa_family == AF_INET) { 903 struct sockaddr_in *sin = (struct sockaddr_in*)ai->ai_addr; 904 evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); 905 gotport = ntohs(sin->sin_port); 906 if (ai->ai_addrlen != sizeof(struct sockaddr_in)) { 907 TT_FAIL(("Addr size mismatch on line %d", line)); 908 return -1; 909 } 910 } else { 911 struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr; 912 evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf)); 913 gotport = ntohs(sin6->sin6_port); 914 if (ai->ai_addrlen != sizeof(struct sockaddr_in6)) { 915 TT_FAIL(("Addr size mismatch on line %d", line)); 916 return -1; 917 } 918 } 919 if (evutil_sockaddr_cmp(ai->ai_addr, (struct sockaddr*)&ss, 1)) { 920 TT_FAIL(("Wanted %s, got %s:%d on line %d", sockaddr_port, 921 buf, gotport, line)); 922 return -1; 923 } else { 924 TT_BLATHER(("Wanted %s, got %s:%d on line %d", sockaddr_port, 925 buf, gotport, line)); 926 } 927 return 0; 928end: 929 TT_FAIL(("Test failed on line %d", line)); 930 return -1; 931} 932 933static void 934test_evutil_rand(void *arg) 935{ 936 char buf1[32]; 937 char buf2[32]; 938 int counts[256]; 939 int i, j, k, n=0; 940 struct evutil_weakrand_state seed = { 12346789U }; 941 942 memset(buf2, 0, sizeof(buf2)); 943 memset(counts, 0, sizeof(counts)); 944 945 for (k=0;k<32;++k) { 946 /* Try a few different start and end points; try to catch 947 * the various misaligned cases of arc4random_buf */ 948 int startpoint = evutil_weakrand_(&seed) % 4; 949 int endpoint = 32 - (evutil_weakrand_(&seed) % 4); 950 951 memset(buf2, 0, sizeof(buf2)); 952 953 /* Do 6 runs over buf1, or-ing the result into buf2 each 954 * time, to make sure we're setting each byte that we mean 955 * to set. */ 956 for (i=0;i<8;++i) { 957 memset(buf1, 0, sizeof(buf1)); 958 evutil_secure_rng_get_bytes(buf1 + startpoint, 959 endpoint-startpoint); 960 n += endpoint - startpoint; 961 for (j=0; j<32; ++j) { 962 if (j >= startpoint && j < endpoint) { 963 buf2[j] |= buf1[j]; 964 ++counts[(unsigned char)buf1[j]]; 965 } else { 966 tt_assert(buf1[j] == 0); 967 tt_int_op(buf1[j], ==, 0); 968 969 } 970 } 971 } 972 973 /* This will give a false positive with P=(256**8)==(2**64) 974 * for each character. */ 975 for (j=startpoint;j<endpoint;++j) { 976 tt_int_op(buf2[j], !=, 0); 977 } 978 } 979 980 evutil_weakrand_seed_(&seed, 0); 981 for (i = 0; i < 10000; ++i) { 982 ev_int32_t r = evutil_weakrand_range_(&seed, 9999); 983 tt_int_op(0, <=, r); 984 tt_int_op(r, <, 9999); 985 } 986 987 /* for (i=0;i<256;++i) { printf("%3d %2d\n", i, counts[i]); } */ 988end: 989 ; 990} 991 992static void 993test_EVUTIL_IS_(void *arg) 994{ 995 tt_int_op(EVUTIL_ISDIGIT_('0'), ==, 1); 996 tt_int_op(EVUTIL_ISDIGIT_('a'), ==, 0); 997 tt_int_op(EVUTIL_ISDIGIT_('\xff'), ==, 0); 998end: 999 ; 1000} 1001 1002static void 1003test_evutil_getaddrinfo(void *arg) 1004{ 1005 struct evutil_addrinfo *ai = NULL, *a; 1006 struct evutil_addrinfo hints; 1007 int r; 1008 1009 /* Try using it as a pton. */ 1010 memset(&hints, 0, sizeof(hints)); 1011 hints.ai_family = PF_UNSPEC; 1012 hints.ai_socktype = SOCK_STREAM; 1013 r = evutil_getaddrinfo("1.2.3.4", "8080", &hints, &ai); 1014 tt_int_op(r, ==, 0); 1015 tt_assert(ai); 1016 tt_ptr_op(ai->ai_next, ==, NULL); /* no ambiguity */ 1017 test_ai_eq(ai, "1.2.3.4:8080", SOCK_STREAM, IPPROTO_TCP); 1018 evutil_freeaddrinfo(ai); 1019 ai = NULL; 1020 1021 memset(&hints, 0, sizeof(hints)); 1022 hints.ai_family = PF_UNSPEC; 1023 hints.ai_protocol = IPPROTO_UDP; 1024 r = evutil_getaddrinfo("1001:b0b::f00f", "4321", &hints, &ai); 1025 tt_int_op(r, ==, 0); 1026 tt_assert(ai); 1027 tt_ptr_op(ai->ai_next, ==, NULL); /* no ambiguity */ 1028 test_ai_eq(ai, "[1001:b0b::f00f]:4321", SOCK_DGRAM, IPPROTO_UDP); 1029 evutil_freeaddrinfo(ai); 1030 ai = NULL; 1031 1032 /* Try out the behavior of nodename=NULL */ 1033 memset(&hints, 0, sizeof(hints)); 1034 hints.ai_family = PF_INET; 1035 hints.ai_protocol = IPPROTO_TCP; 1036 hints.ai_flags = EVUTIL_AI_PASSIVE; /* as if for bind */ 1037 r = evutil_getaddrinfo(NULL, "9999", &hints, &ai); 1038 tt_int_op(r,==,0); 1039 tt_assert(ai); 1040 tt_ptr_op(ai->ai_next, ==, NULL); 1041 test_ai_eq(ai, "0.0.0.0:9999", SOCK_STREAM, IPPROTO_TCP); 1042 evutil_freeaddrinfo(ai); 1043 ai = NULL; 1044 hints.ai_flags = 0; /* as if for connect */ 1045 r = evutil_getaddrinfo(NULL, "9998", &hints, &ai); 1046 tt_assert(ai); 1047 tt_int_op(r,==,0); 1048 test_ai_eq(ai, "127.0.0.1:9998", SOCK_STREAM, IPPROTO_TCP); 1049 tt_ptr_op(ai->ai_next, ==, NULL); 1050 evutil_freeaddrinfo(ai); 1051 ai = NULL; 1052 1053 hints.ai_flags = 0; /* as if for connect */ 1054 hints.ai_family = PF_INET6; 1055 r = evutil_getaddrinfo(NULL, "9997", &hints, &ai); 1056 tt_assert(ai); 1057 tt_int_op(r,==,0); 1058 tt_ptr_op(ai->ai_next, ==, NULL); 1059 test_ai_eq(ai, "[::1]:9997", SOCK_STREAM, IPPROTO_TCP); 1060 evutil_freeaddrinfo(ai); 1061 ai = NULL; 1062 1063 hints.ai_flags = EVUTIL_AI_PASSIVE; /* as if for bind. */ 1064 hints.ai_family = PF_INET6; 1065 r = evutil_getaddrinfo(NULL, "9996", &hints, &ai); 1066 tt_assert(ai); 1067 tt_int_op(r,==,0); 1068 tt_ptr_op(ai->ai_next, ==, NULL); 1069 test_ai_eq(ai, "[::]:9996", SOCK_STREAM, IPPROTO_TCP); 1070 evutil_freeaddrinfo(ai); 1071 ai = NULL; 1072 1073 /* Now try an unspec one. We should get a v6 and a v4. */ 1074 hints.ai_family = PF_UNSPEC; 1075 r = evutil_getaddrinfo(NULL, "9996", &hints, &ai); 1076 tt_assert(ai); 1077 tt_int_op(r,==,0); 1078 a = ai_find_by_family(ai, PF_INET6); 1079 tt_assert(a); 1080 test_ai_eq(a, "[::]:9996", SOCK_STREAM, IPPROTO_TCP); 1081 a = ai_find_by_family(ai, PF_INET); 1082 tt_assert(a); 1083 test_ai_eq(a, "0.0.0.0:9996", SOCK_STREAM, IPPROTO_TCP); 1084 evutil_freeaddrinfo(ai); 1085 ai = NULL; 1086 1087 /* Try out AI_NUMERICHOST: successful case. Also try 1088 * multiprotocol. */ 1089 memset(&hints, 0, sizeof(hints)); 1090 hints.ai_family = PF_UNSPEC; 1091 hints.ai_flags = EVUTIL_AI_NUMERICHOST; 1092 r = evutil_getaddrinfo("1.2.3.4", NULL, &hints, &ai); 1093 tt_int_op(r, ==, 0); 1094 a = ai_find_by_protocol(ai, IPPROTO_TCP); 1095 tt_assert(a); 1096 test_ai_eq(a, "1.2.3.4", SOCK_STREAM, IPPROTO_TCP); 1097 a = ai_find_by_protocol(ai, IPPROTO_UDP); 1098 tt_assert(a); 1099 test_ai_eq(a, "1.2.3.4", SOCK_DGRAM, IPPROTO_UDP); 1100 evutil_freeaddrinfo(ai); 1101 ai = NULL; 1102 1103 /* Try the failing case of AI_NUMERICHOST */ 1104 memset(&hints, 0, sizeof(hints)); 1105 hints.ai_family = PF_UNSPEC; 1106 hints.ai_flags = EVUTIL_AI_NUMERICHOST; 1107 r = evutil_getaddrinfo("www.google.com", "80", &hints, &ai); 1108 tt_int_op(r, ==, EVUTIL_EAI_NONAME); 1109 tt_ptr_op(ai, ==, NULL); 1110 1111 /* Try symbolic service names wit AI_NUMERICSERV */ 1112 memset(&hints, 0, sizeof(hints)); 1113 hints.ai_family = PF_UNSPEC; 1114 hints.ai_socktype = SOCK_STREAM; 1115 hints.ai_flags = EVUTIL_AI_NUMERICSERV; 1116 r = evutil_getaddrinfo("1.2.3.4", "http", &hints, &ai); 1117 tt_int_op(r,==,EVUTIL_EAI_NONAME); 1118 1119 /* Try symbolic service names */ 1120 memset(&hints, 0, sizeof(hints)); 1121 hints.ai_family = PF_UNSPEC; 1122 hints.ai_socktype = SOCK_STREAM; 1123 r = evutil_getaddrinfo("1.2.3.4", "http", &hints, &ai); 1124 if (r!=0) { 1125 TT_DECLARE("SKIP", ("Symbolic service names seem broken.")); 1126 } else { 1127 tt_assert(ai); 1128 test_ai_eq(ai, "1.2.3.4:80", SOCK_STREAM, IPPROTO_TCP); 1129 evutil_freeaddrinfo(ai); 1130 ai = NULL; 1131 } 1132 1133end: 1134 if (ai) 1135 evutil_freeaddrinfo(ai); 1136} 1137 1138static void 1139test_evutil_getaddrinfo_live(void *arg) 1140{ 1141 struct evutil_addrinfo *ai = NULL; 1142 struct evutil_addrinfo hints; 1143 1144 struct sockaddr_in6 *sin6; 1145 struct sockaddr_in *sin; 1146 char buf[128]; 1147 const char *cp; 1148 int r; 1149 1150 /* Now do some actual lookups. */ 1151 memset(&hints, 0, sizeof(hints)); 1152 hints.ai_family = PF_INET; 1153 hints.ai_protocol = IPPROTO_TCP; 1154 hints.ai_socktype = SOCK_STREAM; 1155 r = evutil_getaddrinfo("www.google.com", "80", &hints, &ai); 1156 if (r != 0) { 1157 TT_DECLARE("SKIP", ("Couldn't resolve www.google.com")); 1158 } else { 1159 tt_assert(ai); 1160 tt_int_op(ai->ai_family, ==, PF_INET); 1161 tt_int_op(ai->ai_protocol, ==, IPPROTO_TCP); 1162 tt_int_op(ai->ai_socktype, ==, SOCK_STREAM); 1163 tt_int_op(ai->ai_addrlen, ==, sizeof(struct sockaddr_in)); 1164 sin = (struct sockaddr_in*)ai->ai_addr; 1165 tt_int_op(sin->sin_family, ==, AF_INET); 1166 tt_int_op(sin->sin_port, ==, htons(80)); 1167 tt_int_op(sin->sin_addr.s_addr, !=, 0xffffffff); 1168 1169 cp = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); 1170 TT_BLATHER(("www.google.com resolved to %s", 1171 cp?cp:"<unwriteable>")); 1172 evutil_freeaddrinfo(ai); 1173 ai = NULL; 1174 } 1175 1176 hints.ai_family = PF_INET6; 1177 r = evutil_getaddrinfo("ipv6.google.com", "80", &hints, &ai); 1178 if (r != 0) { 1179 TT_BLATHER(("Couldn't do an ipv6 lookup for ipv6.google.com")); 1180 } else { 1181 tt_assert(ai); 1182 tt_int_op(ai->ai_family, ==, PF_INET6); 1183 tt_int_op(ai->ai_addrlen, ==, sizeof(struct sockaddr_in6)); 1184 sin6 = (struct sockaddr_in6*)ai->ai_addr; 1185 tt_int_op(sin6->sin6_port, ==, htons(80)); 1186 1187 cp = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, 1188 sizeof(buf)); 1189 TT_BLATHER(("ipv6.google.com resolved to %s", 1190 cp?cp:"<unwriteable>")); 1191 } 1192 1193end: 1194 if (ai) 1195 evutil_freeaddrinfo(ai); 1196} 1197 1198static void 1199test_evutil_getaddrinfo_AI_ADDRCONFIG(void *arg) 1200{ 1201 struct evutil_addrinfo *ai = NULL; 1202 struct evutil_addrinfo hints; 1203 int r; 1204 1205 memset(&hints, 0, sizeof(hints)); 1206 hints.ai_family = AF_UNSPEC; 1207 hints.ai_socktype = SOCK_STREAM; 1208 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG; 1209 1210 /* IPv4 */ 1211 r = evutil_getaddrinfo("127.0.0.1", "80", &hints, &ai); 1212 tt_int_op(r, ==, 0); 1213 tt_assert(ai); 1214 tt_ptr_op(ai->ai_next, ==, NULL); 1215 test_ai_eq(ai, "127.0.0.1:80", SOCK_STREAM, IPPROTO_TCP); 1216 evutil_freeaddrinfo(ai); 1217 ai = NULL; 1218 1219 /* IPv6 */ 1220 r = evutil_getaddrinfo("::1", "80", &hints, &ai); 1221 tt_int_op(r, ==, 0); 1222 tt_assert(ai); 1223 tt_ptr_op(ai->ai_next, ==, NULL); 1224 test_ai_eq(ai, "[::1]:80", SOCK_STREAM, IPPROTO_TCP); 1225 evutil_freeaddrinfo(ai); 1226 ai = NULL; 1227 1228end: 1229 if (ai) 1230 evutil_freeaddrinfo(ai); 1231} 1232 1233#ifdef _WIN32 1234static void 1235test_evutil_loadsyslib(void *arg) 1236{ 1237 HMODULE h=NULL; 1238 1239 h = evutil_load_windows_system_library_(TEXT("kernel32.dll")); 1240 tt_assert(h); 1241 1242end: 1243 if (h) 1244 CloseHandle(h); 1245 1246} 1247#endif 1248 1249/** Test mm_malloc(). */ 1250static void 1251test_event_malloc(void *arg) 1252{ 1253 void *p = NULL; 1254 (void)arg; 1255 1256 /* mm_malloc(0) should simply return NULL. */ 1257#ifndef EVENT__DISABLE_MM_REPLACEMENT 1258 errno = 0; 1259 p = mm_malloc(0); 1260 tt_assert(p == NULL); 1261 tt_int_op(errno, ==, 0); 1262#endif 1263 1264 /* Trivial case. */ 1265 errno = 0; 1266 p = mm_malloc(8); 1267 tt_assert(p != NULL); 1268 tt_int_op(errno, ==, 0); 1269 mm_free(p); 1270 1271 end: 1272 errno = 0; 1273 return; 1274} 1275 1276static void 1277test_event_calloc(void *arg) 1278{ 1279 void *p = NULL; 1280 (void)arg; 1281 1282#ifndef EVENT__DISABLE_MM_REPLACEMENT 1283 /* mm_calloc() should simply return NULL 1284 * if either argument is zero. */ 1285 errno = 0; 1286 p = mm_calloc(0, 0); 1287 tt_assert(p == NULL); 1288 tt_int_op(errno, ==, 0); 1289 errno = 0; 1290 p = mm_calloc(0, 1); 1291 tt_assert(p == NULL); 1292 tt_int_op(errno, ==, 0); 1293 errno = 0; 1294 p = mm_calloc(1, 0); 1295 tt_assert(p == NULL); 1296 tt_int_op(errno, ==, 0); 1297#endif 1298 1299 /* Trivial case. */ 1300 errno = 0; 1301 p = mm_calloc(8, 8); 1302 tt_assert(p != NULL); 1303 tt_int_op(errno, ==, 0); 1304 mm_free(p); 1305 p = NULL; 1306 1307 /* mm_calloc() should set errno = ENOMEM and return NULL 1308 * in case of potential overflow. */ 1309 errno = 0; 1310 p = mm_calloc(EV_SIZE_MAX/2, EV_SIZE_MAX/2 + 8); 1311 tt_assert(p == NULL); 1312 tt_int_op(errno, ==, ENOMEM); 1313 1314 end: 1315 errno = 0; 1316 if (p) 1317 mm_free(p); 1318 1319 return; 1320} 1321 1322static void 1323test_event_strdup(void *arg) 1324{ 1325 void *p = NULL; 1326 (void)arg; 1327 1328#ifndef EVENT__DISABLE_MM_REPLACEMENT 1329 /* mm_strdup(NULL) should set errno = EINVAL and return NULL. */ 1330 errno = 0; 1331 p = mm_strdup(NULL); 1332 tt_assert(p == NULL); 1333 tt_int_op(errno, ==, EINVAL); 1334#endif 1335 1336 /* Trivial cases. */ 1337 1338 errno = 0; 1339 p = mm_strdup(""); 1340 tt_assert(p != NULL); 1341 tt_int_op(errno, ==, 0); 1342 tt_str_op(p, ==, ""); 1343 mm_free(p); 1344 1345 errno = 0; 1346 p = mm_strdup("foo"); 1347 tt_assert(p != NULL); 1348 tt_int_op(errno, ==, 0); 1349 tt_str_op(p, ==, "foo"); 1350 mm_free(p); 1351 1352 /* XXX 1353 * mm_strdup(str) where str is a string of length EV_SIZE_MAX 1354 * should set errno = ENOMEM and return NULL. */ 1355 1356 end: 1357 errno = 0; 1358 return; 1359} 1360 1361static void 1362test_evutil_usleep(void *arg) 1363{ 1364 struct timeval tv1, tv2, tv3, diff1, diff2; 1365 const struct timeval quarter_sec = {0, 250*1000}; 1366 const struct timeval tenth_sec = {0, 100*1000}; 1367 long usec1, usec2; 1368 1369 evutil_gettimeofday(&tv1, NULL); 1370 evutil_usleep_(&quarter_sec); 1371 evutil_gettimeofday(&tv2, NULL); 1372 evutil_usleep_(&tenth_sec); 1373 evutil_gettimeofday(&tv3, NULL); 1374 1375 evutil_timersub(&tv2, &tv1, &diff1); 1376 evutil_timersub(&tv3, &tv2, &diff2); 1377 usec1 = diff1.tv_sec * 1000000 + diff1.tv_usec; 1378 usec2 = diff2.tv_sec * 1000000 + diff2.tv_usec; 1379 1380 tt_int_op(usec1, >, 200000); 1381 tt_int_op(usec1, <, 300000); 1382 tt_int_op(usec2, >, 80000); 1383 tt_int_op(usec2, <, 120000); 1384 1385end: 1386 ; 1387} 1388 1389static void 1390test_evutil_monotonic_res(void *data_) 1391{ 1392 /* Basic santity-test for monotonic timers. What we'd really like 1393 * to do is make sure that they can't go backwards even when the 1394 * system clock goes backwards. But we haven't got a good way to 1395 * move the system clock backwards. 1396 */ 1397 struct basic_test_data *data = data_; 1398 struct evutil_monotonic_timer timer; 1399 const int precise = strstr(data->setup_data, "precise") != NULL; 1400 const int fallback = strstr(data->setup_data, "fallback") != NULL; 1401 struct timeval tv[10], delay; 1402 int total_diff = 0; 1403 1404 int flags = 0, wantres, acceptdiff, i; 1405 if (precise) 1406 flags |= EV_MONOT_PRECISE; 1407 if (fallback) 1408 flags |= EV_MONOT_FALLBACK; 1409 if (precise || fallback) { 1410#ifdef _WIN32 1411 wantres = 10*1000; 1412 acceptdiff = 1000; 1413#else 1414 wantres = 1000; 1415 acceptdiff = 300; 1416#endif 1417 } else { 1418 wantres = 40*1000; 1419 acceptdiff = 20*1000; 1420 } 1421 1422 TT_BLATHER(("Precise = %d", precise)); 1423 TT_BLATHER(("Fallback = %d", fallback)); 1424 1425 /* First, make sure we match up with usleep. */ 1426 1427 delay.tv_sec = 0; 1428 delay.tv_usec = wantres; 1429 1430 tt_int_op(evutil_configure_monotonic_time_(&timer, flags), ==, 0); 1431 1432 for (i = 0; i < 10; ++i) { 1433 evutil_gettime_monotonic_(&timer, &tv[i]); 1434 evutil_usleep_(&delay); 1435 } 1436 1437 for (i = 0; i < 9; ++i) { 1438 struct timeval diff; 1439 tt_assert(evutil_timercmp(&tv[i], &tv[i+1], <)); 1440 evutil_timersub(&tv[i+1], &tv[i], &diff); 1441 tt_int_op(diff.tv_sec, ==, 0); 1442 total_diff += diff.tv_usec; 1443 TT_BLATHER(("Difference = %d", (int)diff.tv_usec)); 1444 } 1445 tt_int_op(abs(total_diff/9 - wantres), <, acceptdiff); 1446 1447end: 1448 ; 1449} 1450 1451static void 1452test_evutil_monotonic_prc(void *data_) 1453{ 1454 struct basic_test_data *data = data_; 1455 struct evutil_monotonic_timer timer; 1456 const int precise = strstr(data->setup_data, "precise") != NULL; 1457 const int fallback = strstr(data->setup_data, "fallback") != NULL; 1458 struct timeval tv[10]; 1459 int total_diff = 0; 1460 int i, maxstep = 25*1000,flags=0; 1461 if (precise) 1462 maxstep = 500; 1463 if (precise) 1464 flags |= EV_MONOT_PRECISE; 1465 if (fallback) 1466 flags |= EV_MONOT_FALLBACK; 1467 tt_int_op(evutil_configure_monotonic_time_(&timer, flags), ==, 0); 1468 1469 /* find out what precision we actually see. */ 1470 1471 evutil_gettime_monotonic_(&timer, &tv[0]); 1472 for (i = 1; i < 10; ++i) { 1473 do { 1474 evutil_gettime_monotonic_(&timer, &tv[i]); 1475 } while (evutil_timercmp(&tv[i-1], &tv[i], ==)); 1476 } 1477 1478 total_diff = 0; 1479 for (i = 0; i < 9; ++i) { 1480 struct timeval diff; 1481 tt_assert(evutil_timercmp(&tv[i], &tv[i+1], <)); 1482 evutil_timersub(&tv[i+1], &tv[i], &diff); 1483 tt_int_op(diff.tv_sec, ==, 0); 1484 total_diff += diff.tv_usec; 1485 TT_BLATHER(("Step difference = %d", (int)diff.tv_usec)); 1486 } 1487 TT_BLATHER(("Average step difference = %d", total_diff / 9)); 1488 tt_int_op(total_diff/9, <, maxstep); 1489 1490end: 1491 ; 1492} 1493 1494static void 1495create_tm_from_unix_epoch(struct tm *cur_p, const time_t t) 1496{ 1497#ifdef _WIN32 1498 struct tm *tmp = gmtime(&t); 1499 if (!tmp) { 1500 fprintf(stderr, "gmtime: %s (%i)", strerror(errno), (int)t); 1501 exit(1); 1502 } 1503 *cur_p = *tmp; 1504#else 1505 gmtime_r(&t, cur_p); 1506#endif 1507} 1508 1509static struct date_rfc1123_case { 1510 time_t t; 1511 char date[30]; 1512} date_rfc1123_cases[] = { 1513 { 0, "Thu, 01 Jan 1970 00:00:00 GMT"} /* UNIX time of zero */, 1514 { 946684799, "Fri, 31 Dec 1999 23:59:59 GMT"} /* the last moment of the 20th century */, 1515 { 946684800, "Sat, 01 Jan 2000 00:00:00 GMT"} /* the first moment of the 21st century */, 1516 { 981072000, "Fri, 02 Feb 2001 00:00:00 GMT"}, 1517 { 1015113600, "Sun, 03 Mar 2002 00:00:00 GMT"}, 1518 { 1049414400, "Fri, 04 Apr 2003 00:00:00 GMT"}, 1519 { 1083715200, "Wed, 05 May 2004 00:00:00 GMT"}, 1520 { 1118016000, "Mon, 06 Jun 2005 00:00:00 GMT"}, 1521 { 1152230400, "Fri, 07 Jul 2006 00:00:00 GMT"}, 1522 { 1186531200, "Wed, 08 Aug 2007 00:00:00 GMT"}, 1523 { 1220918400, "Tue, 09 Sep 2008 00:00:00 GMT"}, 1524 { 1255132800, "Sat, 10 Oct 2009 00:00:00 GMT"}, 1525 { 1289433600, "Thu, 11 Nov 2010 00:00:00 GMT"}, 1526 { 1323648000, "Mon, 12 Dec 2011 00:00:00 GMT"}, 1527#ifndef _WIN32 1528#if EVENT__SIZEOF_TIME_T > 4 1529 /** In win32 case we have max "23:59:59 January 18, 2038, UTC" for time32 */ 1530 { 4294967296, "Sun, 07 Feb 2106 06:28:16 GMT"} /* 2^32 */, 1531 /** In win32 case we have max "23:59:59, December 31, 3000, UTC" for time64 */ 1532 {253402300799, "Fri, 31 Dec 9999 23:59:59 GMT"} /* long long future no one can imagine */, 1533#endif /* time_t != 32bit */ 1534 { 1456704000, "Mon, 29 Feb 2016 00:00:00 GMT"} /* leap year */, 1535#endif 1536 { 1435708800, "Wed, 01 Jul 2015 00:00:00 GMT"} /* leap second */, 1537 { 1481866376, "Fri, 16 Dec 2016 05:32:56 GMT"} /* the time this test case is generated */, 1538 {0, ""} /* end of test cases. */ 1539}; 1540 1541static void 1542test_evutil_date_rfc1123(void *arg) 1543{ 1544 struct tm query; 1545 char result[30]; 1546 size_t i = 0; 1547 1548 /* Checks if too small buffers are safely accepted. */ 1549 { 1550 create_tm_from_unix_epoch(&query, 0); 1551 evutil_date_rfc1123(result, 8, &query); 1552 tt_str_op(result, ==, "Thu, 01"); 1553 } 1554 1555 /* Checks for testcases. */ 1556 for (i = 0; ; i++) { 1557 struct date_rfc1123_case c = date_rfc1123_cases[i]; 1558 1559 if (strlen(c.date) == 0) 1560 break; 1561 1562 create_tm_from_unix_epoch(&query, c.t); 1563 evutil_date_rfc1123(result, sizeof(result), &query); 1564 tt_str_op(result, ==, c.date); 1565 } 1566 1567end: 1568 ; 1569} 1570 1571static void 1572test_evutil_v4addr_is_local(void *arg) 1573{ 1574 struct sockaddr_in sin; 1575 sin.sin_family = AF_INET; 1576 1577 /* we use evutil_inet_pton() here to fill in network-byte order */ 1578#define LOCAL(str, yes) do { \ 1579 tt_int_op(evutil_inet_pton(AF_INET, str, &sin.sin_addr), ==, 1); \ 1580 tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, yes); \ 1581} while (0) 1582 1583 /** any */ 1584 sin.sin_addr.s_addr = INADDR_ANY; 1585 tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, 1); 1586 1587 /** loopback */ 1588 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 1589 tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, 1); 1590 LOCAL("127.0.0.1", 1); 1591 LOCAL("127.255.255.255", 1); 1592 LOCAL("121.0.0.1", 0); 1593 1594 /** link-local */ 1595 LOCAL("169.254.0.1", 1); 1596 LOCAL("169.254.255.255", 1); 1597 LOCAL("170.0.0.0", 0); 1598 1599 /** Multicast */ 1600 LOCAL("224.0.0.0", 1); 1601 LOCAL("239.255.255.255", 1); 1602 LOCAL("240.0.0.0", 0); 1603end: 1604 ; 1605} 1606 1607static void 1608test_evutil_v6addr_is_local(void *arg) 1609{ 1610 struct sockaddr_in6 sin6; 1611 struct in6_addr anyaddr = IN6ADDR_ANY_INIT; 1612 struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT; 1613 1614 sin6.sin6_family = AF_INET6; 1615#define LOCAL6(str, yes) do { \ 1616 tt_int_op(evutil_inet_pton(AF_INET6, str, &sin6.sin6_addr), ==, 1);\ 1617 tt_int_op(evutil_v6addr_is_local_(&sin6.sin6_addr), ==, yes); \ 1618} while (0) 1619 1620 /** any */ 1621 tt_int_op(evutil_v6addr_is_local_(&anyaddr), ==, 1); 1622 LOCAL6("::0", 1); 1623 1624 /** loopback */ 1625 tt_int_op(evutil_v6addr_is_local_(&loopback), ==, 1); 1626 LOCAL6("::1", 1); 1627 1628 /** IPV4 mapped */ 1629 LOCAL6("::ffff:0:0", 1); 1630 /** IPv4 translated */ 1631 LOCAL6("::ffff:0:0:0", 1); 1632 /** IPv4/IPv6 translation */ 1633 LOCAL6("64:ff9b::", 0); 1634 /** Link-local */ 1635 LOCAL6("fe80::", 1); 1636 /** Multicast */ 1637 LOCAL6("ff00::", 1); 1638 /** Unspecified */ 1639 LOCAL6("::", 1); 1640 1641 /** Global Internet */ 1642 LOCAL6("2001::", 0); 1643 LOCAL6("2001:4860:4802:32::1b", 0); 1644end: 1645 ; 1646} 1647 1648struct testcase_t util_testcases[] = { 1649 { "ipv4_parse", regress_ipv4_parse, 0, NULL, NULL }, 1650 { "ipv6_parse", regress_ipv6_parse, 0, NULL, NULL }, 1651 { "ipv6_parse_scope", regress_ipv6_parse_scope, 0, NULL, NULL }, 1652 { "sockaddr_port_parse", regress_sockaddr_port_parse, 0, NULL, NULL }, 1653 { "sockaddr_port_format", regress_sockaddr_port_format, 0, NULL, NULL }, 1654 { "sockaddr_predicates", test_evutil_sockaddr_predicates, 0,NULL,NULL }, 1655 { "evutil_snprintf", test_evutil_snprintf, 0, NULL, NULL }, 1656 { "evutil_strtoll", test_evutil_strtoll, 0, NULL, NULL }, 1657 { "evutil_casecmp", test_evutil_casecmp, 0, NULL, NULL }, 1658 { "evutil_rtrim", test_evutil_rtrim, 0, NULL, NULL }, 1659 { "strlcpy", test_evutil_strlcpy, 0, NULL, NULL }, 1660 { "log", test_evutil_log, TT_FORK, NULL, NULL }, 1661 { "upcast", test_evutil_upcast, 0, NULL, NULL }, 1662 { "integers", test_evutil_integers, 0, NULL, NULL }, 1663 { "rand", test_evutil_rand, TT_FORK, NULL, NULL }, 1664 { "EVUTIL_IS_", test_EVUTIL_IS_, 0, NULL, NULL }, 1665 { "getaddrinfo", test_evutil_getaddrinfo, TT_FORK, NULL, NULL }, 1666 { "getaddrinfo_live", test_evutil_getaddrinfo_live, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL }, 1667 { "getaddrinfo_AI_ADDRCONFIG", test_evutil_getaddrinfo_AI_ADDRCONFIG, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL }, 1668#ifdef _WIN32 1669 { "loadsyslib", test_evutil_loadsyslib, TT_FORK, NULL, NULL }, 1670#endif 1671 { "mm_malloc", test_event_malloc, 0, NULL, NULL }, 1672 { "mm_calloc", test_event_calloc, 0, NULL, NULL }, 1673 { "mm_strdup", test_event_strdup, 0, NULL, NULL }, 1674 { "usleep", test_evutil_usleep, TT_RETRIABLE, NULL, NULL }, 1675 { "monotonic_res", test_evutil_monotonic_res, 0, &basic_setup, __UNCONST("") }, 1676 { "monotonic_res_precise", test_evutil_monotonic_res, TT_OFF_BY_DEFAULT, &basic_setup, __UNCONST("precise") }, 1677 { "monotonic_res_fallback", test_evutil_monotonic_res, TT_OFF_BY_DEFAULT, &basic_setup, __UNCONST("fallback") }, 1678 { "monotonic_prc", test_evutil_monotonic_prc, 0, &basic_setup, __UNCONST("") }, 1679 { "monotonic_prc_precise", test_evutil_monotonic_prc, TT_RETRIABLE, &basic_setup, __UNCONST("precise") }, 1680 { "monotonic_prc_fallback", test_evutil_monotonic_prc, 0, &basic_setup, __UNCONST("fallback") }, 1681 { "date_rfc1123", test_evutil_date_rfc1123, 0, NULL, NULL }, 1682 { "evutil_v4addr_is_local", test_evutil_v4addr_is_local, 0, NULL, NULL }, 1683 { "evutil_v6addr_is_local", test_evutil_v6addr_is_local, 0, NULL, NULL }, 1684 END_OF_TESTCASES, 1685}; 1686 1687