root/opal/mca/event/libevent2022/libevent/test/regress_util.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. regress_ipv4_parse
  2. regress_ipv6_parse
  3. regress_sockaddr_port_parse
  4. regress_sockaddr_port_format
  5. test_evutil_sockaddr_predicates
  6. test_evutil_strtoll
  7. test_evutil_snprintf
  8. test_evutil_casecmp
  9. logfn
  10. fatalfn
  11. check_error_logging
  12. errx_fn
  13. err_fn
  14. sock_err_fn
  15. test_evutil_log
  16. test_evutil_strlcpy
  17. test_evutil_upcast
  18. test_evutil_integers
  19. ai_find_by_family
  20. ai_find_by_protocol
  21. _test_ai_eq
  22. test_evutil_rand
  23. test_evutil_getaddrinfo
  24. test_evutil_loadsyslib

   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 
  62 enum entry_status { NORMAL, CANONICAL, BAD };
  63 
  64 /* This is a big table of results we expect from generating and parsing */
  65 static struct ipv4_entry {
  66         const char *addr;
  67         ev_uint32_t res;
  68         enum entry_status status;
  69 } ipv4_entries[] = {
  70         { "1.2.3.4", 0x01020304u, CANONICAL },
  71         { "255.255.255.255", 0xffffffffu, CANONICAL },
  72         { "256.0.0.0", 0, BAD },
  73         { "ABC", 0, BAD },
  74         { "1.2.3.4.5", 0, BAD },
  75         { "176.192.208.244", 0xb0c0d0f4, CANONICAL },
  76         { NULL, 0, BAD },
  77 };
  78 
  79 static struct ipv6_entry {
  80         const char *addr;
  81         ev_uint32_t res[4];
  82         enum entry_status status;
  83 } ipv6_entries[] = {
  84         { "::", { 0, 0, 0, 0, }, CANONICAL },
  85         { "0:0:0:0:0:0:0:0", { 0, 0, 0, 0, }, NORMAL },
  86         { "::1", { 0, 0, 0, 1, }, CANONICAL },
  87         { "::1.2.3.4", { 0, 0, 0, 0x01020304, }, CANONICAL },
  88         { "ffff:1::", { 0xffff0001u, 0, 0, 0, }, CANONICAL },
  89         { "ffff:0000::", { 0xffff0000u, 0, 0, 0, }, NORMAL },
  90         { "ffff::1234", { 0xffff0000u, 0, 0, 0x1234, }, CANONICAL },
  91         { "0102::1.2.3.4", {0x01020000u, 0, 0, 0x01020304u }, NORMAL },
  92         { "::9:c0a8:1:1", { 0, 0, 0x0009c0a8u, 0x00010001u }, CANONICAL },
  93         { "::ffff:1.2.3.4", { 0, 0, 0x000ffffu, 0x01020304u }, CANONICAL },
  94         { "FFFF::", { 0xffff0000u, 0, 0, 0 }, NORMAL },
  95         { "foobar.", { 0, 0, 0, 0 }, BAD },
  96         { "foobar", { 0, 0, 0, 0 }, BAD },
  97         { "fo:obar", { 0, 0, 0, 0 }, BAD },
  98         { "ffff", { 0, 0, 0, 0 }, BAD },
  99         { "fffff::", { 0, 0, 0, 0 }, BAD },
 100         { "fffff::", { 0, 0, 0, 0 }, BAD },
 101         { "::1.0.1.1000", { 0, 0, 0, 0 }, BAD },
 102         { "1:2:33333:4::", { 0, 0, 0, 0 }, BAD },
 103         { "1:2:3:4:5:6:7:8:9", { 0, 0, 0, 0 }, BAD },
 104         { "1::2::3", { 0, 0, 0, 0 }, BAD },
 105         { ":::1", { 0, 0, 0, 0 }, BAD },
 106         { NULL, { 0, 0, 0, 0,  }, BAD },
 107 };
 108 
 109 static void
 110 regress_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 
 154 static void
 155 regress_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 
 207 static struct sa_port_ent {
 208         const char *parse;
 209         int safamily;
 210         const char *addr;
 211         int port;
 212 } sa_port_ents[] = {
 213         { "[ffff::1]:1000", AF_INET6, "ffff::1", 1000 },
 214         { "[ffff::1]", AF_INET6, "ffff::1", 0 },
 215         { "[ffff::1", 0, NULL, 0 },
 216         { "[ffff::1]:65599", 0, NULL, 0 },
 217         { "[ffff::1]:0", 0, NULL, 0 },
 218         { "[ffff::1]:-1", 0, NULL, 0 },
 219         { "::1", AF_INET6, "::1", 0 },
 220         { "1:2::1", AF_INET6, "1:2::1", 0 },
 221         { "192.168.0.1:50", AF_INET, "192.168.0.1", 50 },
 222         { "1.2.3.4", AF_INET, "1.2.3.4", 0 },
 223         { NULL, 0, NULL, 0 },
 224 };
 225 
 226 static void
 227 regress_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 
 282 static void
 283 regress_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>");
 314 end:
 315         ;
 316 }
 317 
 318 static 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 
 337 static void
 338 test_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 
 362 static void
 363 test_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 
 378 static void
 379 test_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 
 413 static void
 414 test_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);
 430 end:
 431         ;
 432 }
 433 
 434 static int logsev = 0;
 435 static char *logmsg = NULL;
 436 
 437 static void
 438 logfn(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 
 449 static int fatal_want_severity = 0;
 450 static const char *fatal_want_message = NULL;
 451 static void
 452 fatalfn(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
 464 static void
 465 check_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         }
 481 end:
 482         ;
 483 }
 484 
 485 static void
 486 errx_fn(void)
 487 {
 488         event_errx(2, "Fatal error; too many kumquats (%d)", 5);
 489 }
 490 
 491 static void
 492 err_fn(void)
 493 {
 494         errno = ENOENT;
 495         event_err(5,"Couldn't open %s", "/very/bad/file");
 496 }
 497 
 498 static void
 499 sock_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 
 511 static void
 512 test_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
 595 end:
 596         if (logmsg)
 597                 free(logmsg);
 598         if (fd >= 0)
 599                 evutil_closesocket(fd);
 600 }
 601 
 602 static void
 603 test_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");
 618 end:
 619         ;
 620 }
 621 
 622 struct example_struct {
 623         const char *a;
 624         const char *b;
 625         long c;
 626 };
 627 
 628 static void
 629 test_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 
 642 end:
 643         ;
 644 }
 645 
 646 static void
 647 test_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);
 740 end:
 741         ;
 742 }
 743 
 744 struct evutil_addrinfo *
 745 ai_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 
 755 struct evutil_addrinfo *
 756 ai_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 
 767 int
 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;
 818 end:
 819         TT_FAIL(("Test failed on line %d", line));
 820         return -1;
 821 }
 822 
 823 static void
 824 test_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]); } */
 870 end:
 871         ;
 872 }
 873 
 874 static void
 875 test_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_ptr_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 
1053 end:
1054         if (ai)
1055                 evutil_freeaddrinfo(ai);
1056 }
1057 
1058 #ifdef WIN32
1059 static void
1060 test_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 
1067 end:
1068         if (h)
1069                 CloseHandle(h);
1070 
1071 }
1072 #endif
1073 
1074 struct testcase_t util_testcases[] = {
1075         { "ipv4_parse", regress_ipv4_parse, 0, NULL, NULL },
1076         { "ipv6_parse", regress_ipv6_parse, 0, NULL, NULL },
1077         { "sockaddr_port_parse", regress_sockaddr_port_parse, 0, NULL, NULL },
1078         { "sockaddr_port_format", regress_sockaddr_port_format, 0, NULL, NULL },
1079         { "sockaddr_predicates", test_evutil_sockaddr_predicates, 0,NULL,NULL },
1080         { "evutil_snprintf", test_evutil_snprintf, 0, NULL, NULL },
1081         { "evutil_strtoll", test_evutil_strtoll, 0, NULL, NULL },
1082         { "evutil_casecmp", test_evutil_casecmp, 0, NULL, NULL },
1083         { "strlcpy", test_evutil_strlcpy, 0, NULL, NULL },
1084         { "log", test_evutil_log, TT_FORK, NULL, NULL },
1085         { "upcast", test_evutil_upcast, 0, NULL, NULL },
1086         { "integers", test_evutil_integers, 0, NULL, NULL },
1087         { "rand", test_evutil_rand, TT_FORK, NULL, NULL },
1088         { "getaddrinfo", test_evutil_getaddrinfo, TT_FORK, NULL, NULL },
1089 #ifdef WIN32
1090         { "loadsyslib", test_evutil_loadsyslib, TT_FORK, NULL, NULL },
1091 #endif
1092         END_OF_TESTCASES,
1093 };
1094 

/* [<][>][^][v][top][bottom][index][help] */