1 /*	$NetBSD: regress_util.c,v 1.2 2013/04/11 16:56:42 christos Exp $	*/
2 /*
3  * Copyright (c) 2009-2012 Nick Mathewson and Niels Provos
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 #ifdef WIN32
28 #include <winsock2.h>
29 #include <windows.h>
30 #include <ws2tcpip.h>
31 #endif
32 
33 #include "event2/event-config.h"
34 #include <sys/cdefs.h>
35 __RCSID("$NetBSD: regress_util.c,v 1.2 2013/04/11 16:56:42 christos Exp $");
36 
37 #include <sys/types.h>
38 
39 #ifndef WIN32
40 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
43 #include <unistd.h>
44 #endif
45 #ifdef _EVENT_HAVE_NETINET_IN6_H
46 #include <netinet/in6.h>
47 #endif
48 #ifdef _EVENT_HAVE_SYS_WAIT_H
49 #include <sys/wait.h>
50 #endif
51 #include <signal.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <limits.h>
56 
57 #include "event2/event.h"
58 #include "event2/util.h"
59 #include "../ipv6-internal.h"
60 #include "../util-internal.h"
61 #include "../log-internal.h"
62 #include "../strlcpy-internal.h"
63 
64 #include "regress.h"
65 
66 enum entry_status { NORMAL, CANONICAL, BAD };
67 
68 /* This is a big table of results we expect from generating and parsing */
69 static struct ipv4_entry {
70 	const char *addr;
71 	ev_uint32_t res;
72 	enum entry_status status;
73 } ipv4_entries[] = {
74 	{ "1.2.3.4", 0x01020304u, CANONICAL },
75 	{ "255.255.255.255", 0xffffffffu, CANONICAL },
76 	{ "256.0.0.0", 0, BAD },
77 	{ "ABC", 0, BAD },
78 	{ "1.2.3.4.5", 0, BAD },
79 	{ "176.192.208.244", 0xb0c0d0f4, CANONICAL },
80 	{ NULL, 0, BAD },
81 };
82 
83 static struct ipv6_entry {
84 	const char *addr;
85 	ev_uint32_t res[4];
86 	enum entry_status status;
87 } ipv6_entries[] = {
88 	{ "::", { 0, 0, 0, 0, }, CANONICAL },
89 	{ "0:0:0:0:0:0:0:0", { 0, 0, 0, 0, }, NORMAL },
90 	{ "::1", { 0, 0, 0, 1, }, CANONICAL },
91 	{ "::1.2.3.4", { 0, 0, 0, 0x01020304, }, CANONICAL },
92 	{ "ffff:1::", { 0xffff0001u, 0, 0, 0, }, CANONICAL },
93 	{ "ffff:0000::", { 0xffff0000u, 0, 0, 0, }, NORMAL },
94 	{ "ffff::1234", { 0xffff0000u, 0, 0, 0x1234, }, CANONICAL },
95 	{ "0102::1.2.3.4", {0x01020000u, 0, 0, 0x01020304u }, NORMAL },
96 	{ "::9:c0a8:1:1", { 0, 0, 0x0009c0a8u, 0x00010001u }, CANONICAL },
97 	{ "::ffff:1.2.3.4", { 0, 0, 0x000ffffu, 0x01020304u }, CANONICAL },
98 	{ "FFFF::", { 0xffff0000u, 0, 0, 0 }, NORMAL },
99 	{ "foobar.", { 0, 0, 0, 0 }, BAD },
100 	{ "foobar", { 0, 0, 0, 0 }, BAD },
101 	{ "fo:obar", { 0, 0, 0, 0 }, BAD },
102 	{ "ffff", { 0, 0, 0, 0 }, BAD },
103 	{ "fffff::", { 0, 0, 0, 0 }, BAD },
104 	{ "fffff::", { 0, 0, 0, 0 }, BAD },
105 	{ "::1.0.1.1000", { 0, 0, 0, 0 }, BAD },
106 	{ "1:2:33333:4::", { 0, 0, 0, 0 }, BAD },
107 	{ "1:2:3:4:5:6:7:8:9", { 0, 0, 0, 0 }, BAD },
108 	{ "1::2::3", { 0, 0, 0, 0 }, BAD },
109 	{ ":::1", { 0, 0, 0, 0 }, BAD },
110 	{ NULL, { 0, 0, 0, 0,  }, BAD },
111 };
112 
113 static void
114 regress_ipv4_parse(void *ptr)
115 {
116 	int i;
117 	for (i = 0; ipv4_entries[i].addr; ++i) {
118 		char written[128];
119 		struct ipv4_entry *ent = &ipv4_entries[i];
120 		struct in_addr in;
121 		int r;
122 		r = evutil_inet_pton(AF_INET, ent->addr, &in);
123 		if (r == 0) {
124 			if (ent->status != BAD) {
125 				TT_FAIL(("%s did not parse, but it's a good address!",
126 					ent->addr));
127 			}
128 			continue;
129 		}
130 		if (ent->status == BAD) {
131 			TT_FAIL(("%s parsed, but we expected an error", ent->addr));
132 			continue;
133 		}
134 		if (ntohl(in.s_addr) != ent->res) {
135 			TT_FAIL(("%s parsed to %lx, but we expected %lx", ent->addr,
136 				(unsigned long)ntohl(in.s_addr),
137 				(unsigned long)ent->res));
138 			continue;
139 		}
140 		if (ent->status == CANONICAL) {
141 			const char *w = evutil_inet_ntop(AF_INET, &in, written,
142 											 sizeof(written));
143 			if (!w) {
144 				TT_FAIL(("Tried to write out %s; got NULL.", ent->addr));
145 				continue;
146 			}
147 			if (strcmp(written, ent->addr)) {
148 				TT_FAIL(("Tried to write out %s; got %s",
149 					ent->addr, written));
150 				continue;
151 			}
152 		}
153 
154 	}
155 
156 }
157 
158 static void
159 regress_ipv6_parse(void *ptr)
160 {
161 #ifdef AF_INET6
162 	int i, j;
163 
164 	for (i = 0; ipv6_entries[i].addr; ++i) {
165 		char written[128];
166 		struct ipv6_entry *ent = &ipv6_entries[i];
167 		struct in6_addr in6;
168 		int r;
169 		r = evutil_inet_pton(AF_INET6, ent->addr, &in6);
170 		if (r == 0) {
171 			if (ent->status != BAD)
172 				TT_FAIL(("%s did not parse, but it's a good address!",
173 					ent->addr));
174 			continue;
175 		}
176 		if (ent->status == BAD) {
177 			TT_FAIL(("%s parsed, but we expected an error", ent->addr));
178 			continue;
179 		}
180 		for (j = 0; j < 4; ++j) {
181 			/* Can't use s6_addr32 here; some don't have it. */
182 			ev_uint32_t u =
183 				(in6.s6_addr[j*4  ] << 24) |
184 				(in6.s6_addr[j*4+1] << 16) |
185 				(in6.s6_addr[j*4+2] << 8) |
186 				(in6.s6_addr[j*4+3]);
187 			if (u != ent->res[j]) {
188 				TT_FAIL(("%s did not parse as expected.", ent->addr));
189 				continue;
190 			}
191 		}
192 		if (ent->status == CANONICAL) {
193 			const char *w = evutil_inet_ntop(AF_INET6, &in6, written,
194 											 sizeof(written));
195 			if (!w) {
196 				TT_FAIL(("Tried to write out %s; got NULL.", ent->addr));
197 				continue;
198 			}
199 			if (strcmp(written, ent->addr)) {
200 				TT_FAIL(("Tried to write out %s; got %s", ent->addr, written));
201 				continue;
202 			}
203 		}
204 
205 	}
206 #else
207 	TT_BLATHER(("Skipping IPv6 address parsing."));
208 #endif
209 }
210 
211 static struct sa_port_ent {
212 	const char *parse;
213 	int safamily;
214 	const char *addr;
215 	int port;
216 } sa_port_ents[] = {
217 	{ "[ffff::1]:1000", AF_INET6, "ffff::1", 1000 },
218 	{ "[ffff::1]", AF_INET6, "ffff::1", 0 },
219 	{ "[ffff::1", 0, NULL, 0 },
220 	{ "[ffff::1]:65599", 0, NULL, 0 },
221 	{ "[ffff::1]:0", 0, NULL, 0 },
222 	{ "[ffff::1]:-1", 0, NULL, 0 },
223 	{ "::1", AF_INET6, "::1", 0 },
224 	{ "1:2::1", AF_INET6, "1:2::1", 0 },
225 	{ "192.168.0.1:50", AF_INET, "192.168.0.1", 50 },
226 	{ "1.2.3.4", AF_INET, "1.2.3.4", 0 },
227 	{ NULL, 0, NULL, 0 },
228 };
229 
230 static void
231 regress_sockaddr_port_parse(void *ptr)
232 {
233 	struct sockaddr_storage ss;
234 	int i, r;
235 
236 	for (i = 0; sa_port_ents[i].parse; ++i) {
237 		struct sa_port_ent *ent = &sa_port_ents[i];
238 		int len = sizeof(ss);
239 		memset(&ss, 0, sizeof(ss));
240 		r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len);
241 		if (r < 0) {
242 			if (ent->safamily)
243 				TT_FAIL(("Couldn't parse %s!", ent->parse));
244 			continue;
245 		} else if (! ent->safamily) {
246 			TT_FAIL(("Shouldn't have been able to parse %s!", ent->parse));
247 			continue;
248 		}
249 		if (ent->safamily == AF_INET) {
250 			struct sockaddr_in sin;
251 			memset(&sin, 0, sizeof(sin));
252 #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
253 			sin.sin_len = sizeof(sin);
254 #endif
255 			sin.sin_family = AF_INET;
256 			sin.sin_port = htons(ent->port);
257 			r = evutil_inet_pton(AF_INET, ent->addr, &sin.sin_addr);
258 			if (1 != r) {
259 				TT_FAIL(("Couldn't parse ipv4 target %s.", ent->addr));
260 			} else if (memcmp(&sin, &ss, sizeof(sin))) {
261 				TT_FAIL(("Parse for %s was not as expected.", ent->parse));
262 			} else if (len != sizeof(sin)) {
263 				TT_FAIL(("Length for %s not as expected.",ent->parse));
264 			}
265 		} else {
266 			struct sockaddr_in6 sin6;
267 			memset(&sin6, 0, sizeof(sin6));
268 #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
269 			sin6.sin6_len = sizeof(sin6);
270 #endif
271 			sin6.sin6_family = AF_INET6;
272 			sin6.sin6_port = htons(ent->port);
273 			r = evutil_inet_pton(AF_INET6, ent->addr, &sin6.sin6_addr);
274 			if (1 != r) {
275 				TT_FAIL(("Couldn't parse ipv6 target %s.", ent->addr));
276 			} else if (memcmp(&sin6, &ss, sizeof(sin6))) {
277 				TT_FAIL(("Parse for %s was not as expected.", ent->parse));
278 			} else if (len != sizeof(sin6)) {
279 				TT_FAIL(("Length for %s not as expected.",ent->parse));
280 			}
281 		}
282 	}
283 }
284 
285 
286 static void
287 regress_sockaddr_port_format(void *ptr)
288 {
289 	struct sockaddr_storage ss;
290 	int len;
291 	const char *cp;
292 	char cbuf[128];
293 	int r;
294 
295 	len = sizeof(ss);
296 	r = evutil_parse_sockaddr_port("192.168.1.1:80",
297 	    (struct sockaddr*)&ss, &len);
298 	tt_int_op(r,==,0);
299 	cp = evutil_format_sockaddr_port(
300 		(struct sockaddr*)&ss, cbuf, sizeof(cbuf));
301 	tt_ptr_op(cp,==,cbuf);
302 	tt_str_op(cp,==,"192.168.1.1:80");
303 
304 	len = sizeof(ss);
305 	r = evutil_parse_sockaddr_port("[ff00::8010]:999",
306 	    (struct sockaddr*)&ss, &len);
307 	tt_int_op(r,==,0);
308 	cp = evutil_format_sockaddr_port(
309 		(struct sockaddr*)&ss, cbuf, sizeof(cbuf));
310 	tt_ptr_op(cp,==,cbuf);
311 	tt_str_op(cp,==,"[ff00::8010]:999");
312 
313 	ss.ss_family=99;
314 	cp = evutil_format_sockaddr_port(
315 		(struct sockaddr*)&ss, cbuf, sizeof(cbuf));
316 	tt_ptr_op(cp,==,cbuf);
317 	tt_str_op(cp,==,"<addr with socktype 99>");
318 end:
319 	;
320 }
321 
322 static struct sa_pred_ent {
323 	const char *parse;
324 
325 	int is_loopback;
326 } sa_pred_entries[] = {
327 	{ "127.0.0.1",	 1 },
328 	{ "127.0.3.2",	 1 },
329 	{ "128.1.2.3",	 0 },
330 	{ "18.0.0.1",	 0 },
331 	{ "129.168.1.1", 0 },
332 
333 	{ "::1",	 1 },
334 	{ "::0",	 0 },
335 	{ "f::1",	 0 },
336 	{ "::501",	 0 },
337 	{ NULL,		 0 },
338 
339 };
340 
341 static void
342 test_evutil_sockaddr_predicates(void *ptr)
343 {
344 	struct sockaddr_storage ss;
345 	int r, i;
346 
347 	for (i=0; sa_pred_entries[i].parse; ++i) {
348 		struct sa_pred_ent *ent = &sa_pred_entries[i];
349 		int len = sizeof(ss);
350 
351 		r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len);
352 
353 		if (r<0) {
354 			TT_FAIL(("Couldn't parse %s!", ent->parse));
355 			continue;
356 		}
357 
358 		/* sockaddr_is_loopback */
359 		if (ent->is_loopback != evutil_sockaddr_is_loopback((struct sockaddr*)&ss)) {
360 			TT_FAIL(("evutil_sockaddr_loopback(%s) not as expected",
361 				ent->parse));
362 		}
363 	}
364 }
365 
366 static void
367 test_evutil_strtoll(void *ptr)
368 {
369 	const char *s;
370 	char *endptr;
371 
372 	tt_want(evutil_strtoll("5000000000", NULL, 10) ==
373 		((ev_int64_t)5000000)*1000);
374 	tt_want(evutil_strtoll("-5000000000", NULL, 10) ==
375 		((ev_int64_t)5000000)*-1000);
376 	s = " 99999stuff";
377 	tt_want(evutil_strtoll(s, &endptr, 10) == (ev_int64_t)99999);
378 	tt_want(endptr == s+6);
379 	tt_want(evutil_strtoll("foo", NULL, 10) == 0);
380  }
381 
382 static void
383 test_evutil_snprintf(void *ptr)
384 {
385 	char buf[16];
386 	int r;
387 	ev_uint64_t u64 = ((ev_uint64_t)1000000000)*200;
388 	ev_int64_t i64 = -1 * (ev_int64_t) u64;
389 	size_t size = 8000;
390 	ev_ssize_t ssize = -9000;
391 
392 	r = evutil_snprintf(buf, sizeof(buf), "%d %d", 50, 100);
393 	tt_str_op(buf, ==, "50 100");
394 	tt_int_op(r, ==, 6);
395 
396 	r = evutil_snprintf(buf, sizeof(buf), "longish %d", 1234567890);
397 	tt_str_op(buf, ==, "longish 1234567");
398 	tt_int_op(r, ==, 18);
399 
400 	r = evutil_snprintf(buf, sizeof(buf), EV_U64_FMT, EV_U64_ARG(u64));
401 	tt_str_op(buf, ==, "200000000000");
402 	tt_int_op(r, ==, 12);
403 
404 	r = evutil_snprintf(buf, sizeof(buf), EV_I64_FMT, EV_I64_ARG(i64));
405 	tt_str_op(buf, ==, "-200000000000");
406 	tt_int_op(r, ==, 13);
407 
408 	r = evutil_snprintf(buf, sizeof(buf), EV_SIZE_FMT" "EV_SSIZE_FMT,
409 	    EV_SIZE_ARG(size), EV_SSIZE_ARG(ssize));
410 	tt_str_op(buf, ==, "8000 -9000");
411 	tt_int_op(r, ==, 10);
412 
413       end:
414 	;
415 }
416 
417 static void
418 test_evutil_casecmp(void *ptr)
419 {
420 	tt_int_op(evutil_ascii_strcasecmp("ABC", "ABC"), ==, 0);
421 	tt_int_op(evutil_ascii_strcasecmp("ABC", "abc"), ==, 0);
422 	tt_int_op(evutil_ascii_strcasecmp("ABC", "abcd"), <, 0);
423 	tt_int_op(evutil_ascii_strcasecmp("ABC", "abb"), >, 0);
424 	tt_int_op(evutil_ascii_strcasecmp("ABCd", "abc"), >, 0);
425 
426 	tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 100), ==, 0);
427 	tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 4), ==, 0);
428 	tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEXXXX", 4), ==, 0);
429 	tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibE", 4), ==, 0);
430 	tt_int_op(evutil_ascii_strncasecmp("Libe", "LibEvEnT", 4), ==, 0);
431 	tt_int_op(evutil_ascii_strncasecmp("Lib", "LibEvEnT", 4), <, 0);
432 	tt_int_op(evutil_ascii_strncasecmp("abc", "def", 99), <, 0);
433 	tt_int_op(evutil_ascii_strncasecmp("Z", "qrst", 1), >, 0);
434 end:
435 	;
436 }
437 
438 static int logsev = 0;
439 static char *logmsg = NULL;
440 
441 static void
442 logfn(int severity, const char *msg)
443 {
444 	logsev = severity;
445 	tt_want(msg);
446 	if (msg) {
447 		if (logmsg)
448 			free(logmsg);
449 		logmsg = strdup(msg);
450 	}
451 }
452 
453 static int fatal_want_severity = 0;
454 static const char *fatal_want_message = NULL;
455 static void
456 fatalfn(int exitcode)
457 {
458 	if (logsev != fatal_want_severity ||
459 	    !logmsg ||
460 	    strcmp(logmsg, fatal_want_message))
461 		exit(0);
462 	else
463 		exit(exitcode);
464 }
465 
466 #ifndef WIN32
467 #define CAN_CHECK_ERR
468 static void
469 check_error_logging(void (*fn)(void), int wantexitcode,
470     int wantseverity, const char *wantmsg)
471 {
472 	pid_t pid;
473 	int status = 0, exitcode;
474 	fatal_want_severity = wantseverity;
475 	fatal_want_message = wantmsg;
476 	if ((pid = regress_fork()) == 0) {
477 		/* child process */
478 		fn();
479 		exit(0); /* should be unreachable. */
480 	} else {
481 		wait(&status);
482 		exitcode = WEXITSTATUS(status);
483 		tt_int_op(wantexitcode, ==, exitcode);
484 	}
485 end:
486 	;
487 }
488 
489 static void
490 errx_fn(void)
491 {
492 	event_errx(2, "Fatal error; too many kumquats (%d)", 5);
493 }
494 
495 static void
496 err_fn(void)
497 {
498 	errno = ENOENT;
499 	event_err(5,"Couldn't open %s", "/very/bad/file");
500 }
501 
502 static void
503 sock_err_fn(void)
504 {
505 	evutil_socket_t fd = socket(AF_INET, SOCK_STREAM, 0);
506 #ifdef WIN32
507 	EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK);
508 #else
509 	errno = EAGAIN;
510 #endif
511 	event_sock_err(20, fd, "Unhappy socket");
512 }
513 #endif
514 
515 static void
516 test_evutil_log(void *ptr)
517 {
518 	evutil_socket_t fd = -1;
519 	char buf[128];
520 
521 	event_set_log_callback(logfn);
522 	event_set_fatal_callback(fatalfn);
523 #define RESET() do {				\
524 		logsev = 0;	\
525 		if (logmsg) free(logmsg);	\
526 		logmsg = NULL;			\
527 	} while (/*CONSTCOND*/0)
528 #define LOGEQ(sev,msg) do {			\
529 		tt_int_op(logsev,==,sev);	\
530 		tt_assert(logmsg != NULL);	\
531 		tt_str_op(logmsg,==,msg);	\
532 	} while (/*CONSTCOND*/0)
533 
534 #ifdef CAN_CHECK_ERR
535 	/* We need to disable these tests for now.  Previously, the logging
536 	 * module didn't enforce the requirement that a fatal callback
537 	 * actually exit.  Now, it exits no matter what, so if we wan to
538 	 * reinstate these tests, we'll need to fork for each one. */
539 	check_error_logging(errx_fn, 2, _EVENT_LOG_ERR,
540 	    "Fatal error; too many kumquats (5)");
541 	RESET();
542 #endif
543 
544 	event_warnx("Far too many %s (%d)", "wombats", 99);
545 	LOGEQ(_EVENT_LOG_WARN, "Far too many wombats (99)");
546 	RESET();
547 
548 	event_msgx("Connecting lime to coconut");
549 	LOGEQ(_EVENT_LOG_MSG, "Connecting lime to coconut");
550 	RESET();
551 
552 	event_debug(("A millisecond passed! We should log that!"));
553 #ifdef USE_DEBUG
554 	LOGEQ(_EVENT_LOG_DEBUG, "A millisecond passed! We should log that!");
555 #else
556 	tt_int_op(logsev,==,0);
557 	tt_ptr_op(logmsg,==,NULL);
558 #endif
559 	RESET();
560 
561 	/* Try with an errno. */
562 	errno = ENOENT;
563 	event_warn("Couldn't open %s", "/bad/file");
564 	evutil_snprintf(buf, sizeof(buf),
565 	    "Couldn't open /bad/file: %s",strerror(ENOENT));
566 	LOGEQ(_EVENT_LOG_WARN,buf);
567 	RESET();
568 
569 #ifdef CAN_CHECK_ERR
570 	evutil_snprintf(buf, sizeof(buf),
571 	    "Couldn't open /very/bad/file: %s",strerror(ENOENT));
572 	check_error_logging(err_fn, 5, _EVENT_LOG_ERR, buf);
573 	RESET();
574 #endif
575 
576 	/* Try with a socket errno. */
577 	fd = socket(AF_INET, SOCK_STREAM, 0);
578 #ifdef WIN32
579 	evutil_snprintf(buf, sizeof(buf),
580 	    "Unhappy socket: %s",
581 	    evutil_socket_error_to_string(WSAEWOULDBLOCK));
582 	EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK);
583 #else
584 	evutil_snprintf(buf, sizeof(buf),
585 	    "Unhappy socket: %s", strerror(EAGAIN));
586 	errno = EAGAIN;
587 #endif
588 	event_sock_warn(fd, "Unhappy socket");
589 	LOGEQ(_EVENT_LOG_WARN, buf);
590 	RESET();
591 
592 #ifdef CAN_CHECK_ERR
593 	check_error_logging(sock_err_fn, 20, _EVENT_LOG_ERR, buf);
594 	RESET();
595 #endif
596 
597 #undef RESET
598 #undef LOGEQ
599 end:
600 	if (logmsg)
601 		free(logmsg);
602 	if (fd >= 0)
603 		evutil_closesocket(fd);
604 }
605 
606 static void
607 test_evutil_strlcpy(void *arg)
608 {
609 	char buf[8];
610 
611 	/* Successful case. */
612 	tt_int_op(5, ==, strlcpy(buf, "Hello", sizeof(buf)));
613 	tt_str_op(buf, ==, "Hello");
614 
615 	/* Overflow by a lot. */
616 	tt_int_op(13, ==, strlcpy(buf, "pentasyllabic", sizeof(buf)));
617 	tt_str_op(buf, ==, "pentasy");
618 
619 	/* Overflow by exactly one. */
620 	tt_int_op(8, ==, strlcpy(buf, "overlong", sizeof(buf)));
621 	tt_str_op(buf, ==, "overlon");
622 end:
623 	;
624 }
625 
626 struct example_struct {
627 	const char *a;
628 	const char *b;
629 	long c;
630 };
631 
632 static void
633 test_evutil_upcast(void *arg)
634 {
635 	struct example_struct es1;
636 	const char **cp;
637 	es1.a = "World";
638 	es1.b = "Hello";
639 	es1.c = -99;
640 
641 	tt_int_op(evutil_offsetof(struct example_struct, b), ==, sizeof(char*));
642 
643 	cp = &es1.b;
644 	tt_ptr_op(EVUTIL_UPCAST(cp, struct example_struct, b), ==, &es1);
645 
646 end:
647 	;
648 }
649 
650 static void
651 test_evutil_integers(void *arg)
652 {
653 	ev_int64_t i64;
654 	ev_uint64_t u64;
655 	ev_int32_t i32;
656 	ev_uint32_t u32;
657 	ev_int16_t i16;
658 	ev_uint16_t u16;
659 	ev_int8_t  i8;
660 	ev_uint8_t  u8;
661 
662 	void *ptr;
663 	ev_intptr_t iptr;
664 	ev_uintptr_t uptr;
665 
666 	ev_ssize_t ssize;
667 
668 	tt_int_op(sizeof(u64), ==, 8);
669 	tt_int_op(sizeof(i64), ==, 8);
670 	tt_int_op(sizeof(u32), ==, 4);
671 	tt_int_op(sizeof(i32), ==, 4);
672 	tt_int_op(sizeof(u16), ==, 2);
673 	tt_int_op(sizeof(i16), ==, 2);
674 	tt_int_op(sizeof(u8), ==,  1);
675 	tt_int_op(sizeof(i8), ==,  1);
676 
677 	tt_int_op(sizeof(ev_ssize_t), ==, sizeof(size_t));
678 	tt_int_op(sizeof(ev_intptr_t), >=, sizeof(void *));
679 	tt_int_op(sizeof(ev_uintptr_t), ==, sizeof(intptr_t));
680 
681 	u64 = 1000000000;
682 	u64 *= 1000000000;
683 	tt_assert(u64 / 1000000000 == 1000000000);
684 	i64 = -1000000000;
685 	i64 *= 1000000000;
686 	tt_assert(i64 / 1000000000 == -1000000000);
687 
688 	u64 = EV_UINT64_MAX;
689 	i64 = EV_INT64_MAX;
690 	tt_assert(u64 > 0);
691 	tt_assert(i64 > 0);
692 	u64++;
693 	i64++;
694 	tt_assert(u64 == 0);
695 	tt_assert(i64 == EV_INT64_MIN);
696 	tt_assert(i64 < 0);
697 
698 	u32 = EV_UINT32_MAX;
699 	i32 = EV_INT32_MAX;
700 	tt_assert(u32 > 0);
701 	tt_assert(i32 > 0);
702 	u32++;
703 	i32++;
704 	tt_assert(u32 == 0);
705 	tt_assert(i32 == EV_INT32_MIN);
706 	tt_assert(i32 < 0);
707 
708 	u16 = EV_UINT16_MAX;
709 	i16 = EV_INT16_MAX;
710 	tt_assert(u16 > 0);
711 	tt_assert(i16 > 0);
712 	u16++;
713 	i16++;
714 	tt_assert(u16 == 0);
715 	tt_assert(i16 == EV_INT16_MIN);
716 	tt_assert(i16 < 0);
717 
718 	u8 = EV_UINT8_MAX;
719 	i8 = EV_INT8_MAX;
720 	tt_assert(u8 > 0);
721 	tt_assert(i8 > 0);
722 	u8++;
723 	i8++;
724 	tt_assert(u8 == 0);
725 	tt_assert(i8 == EV_INT8_MIN);
726 	tt_assert(i8 < 0);
727 
728 	ssize = EV_SSIZE_MAX;
729 	tt_assert(ssize > 0);
730 	ssize++;
731 	tt_assert(ssize < 0);
732 	tt_assert(ssize == EV_SSIZE_MIN);
733 
734 	ptr = &ssize;
735 	iptr = (ev_intptr_t)ptr;
736 	uptr = (ev_uintptr_t)ptr;
737 	ptr = (void *)iptr;
738 	tt_assert(ptr == &ssize);
739 	ptr = (void *)uptr;
740 	tt_assert(ptr == &ssize);
741 
742 	iptr = -1;
743 	tt_assert(iptr < 0);
744 end:
745 	;
746 }
747 
748 struct evutil_addrinfo *
749 ai_find_by_family(struct evutil_addrinfo *ai, int family)
750 {
751 	while (ai) {
752 		if (ai->ai_family == family)
753 			return ai;
754 		ai = ai->ai_next;
755 	}
756 	return NULL;
757 }
758 
759 struct evutil_addrinfo *
760 ai_find_by_protocol(struct evutil_addrinfo *ai, int protocol)
761 {
762 	while (ai) {
763 		if (ai->ai_protocol == protocol)
764 			return ai;
765 		ai = ai->ai_next;
766 	}
767 	return NULL;
768 }
769 
770 
771 int
772 _test_ai_eq(const struct evutil_addrinfo *ai, const char *sockaddr_port,
773     int socktype, int protocol, int line)
774 {
775 	struct sockaddr_storage ss;
776 	int slen = sizeof(ss);
777 	int gotport;
778 	char buf[128];
779 	memset(&ss, 0, sizeof(ss));
780 	if (socktype > 0)
781 		tt_int_op(ai->ai_socktype, ==, socktype);
782 	if (protocol > 0)
783 		tt_int_op(ai->ai_protocol, ==, protocol);
784 
785 	if (evutil_parse_sockaddr_port(
786 		    sockaddr_port, (struct sockaddr*)&ss, &slen)<0) {
787 		TT_FAIL(("Couldn't parse expected address %s on line %d",
788 			sockaddr_port, line));
789 		return -1;
790 	}
791 	if (ai->ai_family != ss.ss_family) {
792 		TT_FAIL(("Address family %d did not match %d on line %d",
793 			ai->ai_family, ss.ss_family, line));
794 		return -1;
795 	}
796 	if (ai->ai_addr->sa_family == AF_INET) {
797 		struct sockaddr_in *sin = (struct sockaddr_in*)ai->ai_addr;
798 		evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf));
799 		gotport = ntohs(sin->sin_port);
800 		if (ai->ai_addrlen != sizeof(struct sockaddr_in)) {
801 			TT_FAIL(("Addr size mismatch on line %d", line));
802 			return -1;
803 		}
804 	} else {
805 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr;
806 		evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
807 		gotport = ntohs(sin6->sin6_port);
808 		if (ai->ai_addrlen != sizeof(struct sockaddr_in6)) {
809 			TT_FAIL(("Addr size mismatch on line %d", line));
810 			return -1;
811 		}
812 	}
813 	if (evutil_sockaddr_cmp(ai->ai_addr, (struct sockaddr*)&ss, 1)) {
814 		TT_FAIL(("Wanted %s, got %s:%d on line %d", sockaddr_port,
815 			buf, gotport, line));
816 		return -1;
817 	} else {
818 		TT_BLATHER(("Wanted %s, got %s:%d on line %d", sockaddr_port,
819 			buf, gotport, line));
820 	}
821 	return 0;
822 end:
823 	TT_FAIL(("Test failed on line %d", line));
824 	return -1;
825 }
826 
827 static void
828 test_evutil_rand(void *arg)
829 {
830 	char buf1[32];
831 	char buf2[32];
832 	int counts[256];
833 	int i, j, k, n=0;
834 
835 	memset(buf2, 0, sizeof(buf2));
836 	memset(counts, 0, sizeof(counts));
837 
838 	for (k=0;k<32;++k) {
839 		/* Try a few different start and end points; try to catch
840 		 * the various misaligned cases of arc4random_buf */
841 		int startpoint = _evutil_weakrand() % 4;
842 		int endpoint = 32 - (_evutil_weakrand() % 4);
843 
844 		memset(buf2, 0, sizeof(buf2));
845 
846 		/* Do 6 runs over buf1, or-ing the result into buf2 each
847 		 * time, to make sure we're setting each byte that we mean
848 		 * to set. */
849 		for (i=0;i<8;++i) {
850 			memset(buf1, 0, sizeof(buf1));
851 			evutil_secure_rng_get_bytes(buf1 + startpoint,
852 			    endpoint-startpoint);
853 			n += endpoint - startpoint;
854 			for (j=0; j<32; ++j) {
855 				if (j >= startpoint && j < endpoint) {
856 					buf2[j] |= buf1[j];
857 					++counts[(unsigned char)buf1[j]];
858 				} else {
859 					tt_assert(buf1[j] == 0);
860 					tt_int_op(buf1[j], ==, 0);
861 
862 				}
863 			}
864 		}
865 
866 		/* This will give a false positive with P=(256**8)==(2**64)
867 		 * for each character. */
868 		for (j=startpoint;j<endpoint;++j) {
869 			tt_int_op(buf2[j], !=, 0);
870 		}
871 	}
872 
873 	/* for (i=0;i<256;++i) { printf("%3d %2d\n", i, counts[i]); } */
874 end:
875 	;
876 }
877 
878 static void
879 test_evutil_getaddrinfo(void *arg)
880 {
881 	struct evutil_addrinfo *ai = NULL, *a;
882 	struct evutil_addrinfo hints;
883 
884 	struct sockaddr_in6 *sin6;
885 	struct sockaddr_in *sin;
886 	char buf[128];
887 	const char *cp;
888 	int r;
889 
890 	/* Try using it as a pton. */
891 	memset(&hints, 0, sizeof(hints));
892 	hints.ai_family = PF_UNSPEC;
893 	hints.ai_socktype = SOCK_STREAM;
894 	r = evutil_getaddrinfo("1.2.3.4", "8080", &hints, &ai);
895 	tt_int_op(r, ==, 0);
896 	tt_assert(ai);
897 	tt_ptr_op(ai->ai_next, ==, NULL); /* no ambiguity */
898 	test_ai_eq(ai, "1.2.3.4:8080", SOCK_STREAM, IPPROTO_TCP);
899 	evutil_freeaddrinfo(ai);
900 	ai = NULL;
901 
902 	memset(&hints, 0, sizeof(hints));
903 	hints.ai_family = PF_UNSPEC;
904 	hints.ai_protocol = IPPROTO_UDP;
905 	r = evutil_getaddrinfo("1001:b0b::f00f", "4321", &hints, &ai);
906 	tt_int_op(r, ==, 0);
907 	tt_assert(ai);
908 	tt_ptr_op(ai->ai_next, ==, NULL); /* no ambiguity */
909 	test_ai_eq(ai, "[1001:b0b::f00f]:4321", SOCK_DGRAM, IPPROTO_UDP);
910 	evutil_freeaddrinfo(ai);
911 	ai = NULL;
912 
913 	/* Try out the behavior of nodename=NULL */
914 	memset(&hints, 0, sizeof(hints));
915 	hints.ai_family = PF_INET;
916 	hints.ai_protocol = IPPROTO_TCP;
917 	hints.ai_flags = EVUTIL_AI_PASSIVE; /* as if for bind */
918 	r = evutil_getaddrinfo(NULL, "9999", &hints, &ai);
919 	tt_int_op(r,==,0);
920 	tt_assert(ai);
921 	tt_ptr_op(ai->ai_next, ==, NULL);
922 	test_ai_eq(ai, "0.0.0.0:9999", SOCK_STREAM, IPPROTO_TCP);
923 	evutil_freeaddrinfo(ai);
924 	ai = NULL;
925 	hints.ai_flags = 0; /* as if for connect */
926 	r = evutil_getaddrinfo(NULL, "9998", &hints, &ai);
927 	tt_assert(ai);
928 	tt_int_op(r,==,0);
929 	test_ai_eq(ai, "127.0.0.1:9998", SOCK_STREAM, IPPROTO_TCP);
930 	tt_ptr_op(ai->ai_next, ==, NULL);
931 	evutil_freeaddrinfo(ai);
932 	ai = NULL;
933 
934 	hints.ai_flags = 0; /* as if for connect */
935 	hints.ai_family = PF_INET6;
936 	r = evutil_getaddrinfo(NULL, "9997", &hints, &ai);
937 	tt_assert(ai);
938 	tt_int_op(r,==,0);
939 	tt_ptr_op(ai->ai_next, ==, NULL);
940 	test_ai_eq(ai, "[::1]:9997", SOCK_STREAM, IPPROTO_TCP);
941 	evutil_freeaddrinfo(ai);
942 	ai = NULL;
943 
944 	hints.ai_flags = EVUTIL_AI_PASSIVE; /* as if for bind. */
945 	hints.ai_family = PF_INET6;
946 	r = evutil_getaddrinfo(NULL, "9996", &hints, &ai);
947 	tt_assert(ai);
948 	tt_int_op(r,==,0);
949 	tt_ptr_op(ai->ai_next, ==, NULL);
950 	test_ai_eq(ai, "[::]:9996", SOCK_STREAM, IPPROTO_TCP);
951 	evutil_freeaddrinfo(ai);
952 	ai = NULL;
953 
954 	/* Now try an unspec one. We should get a v6 and a v4. */
955 	hints.ai_family = PF_UNSPEC;
956 	r = evutil_getaddrinfo(NULL, "9996", &hints, &ai);
957 	tt_assert(ai);
958 	tt_int_op(r,==,0);
959 	a = ai_find_by_family(ai, PF_INET6);
960 	tt_assert(a);
961 	test_ai_eq(a, "[::]:9996", SOCK_STREAM, IPPROTO_TCP);
962 	a = ai_find_by_family(ai, PF_INET);
963 	tt_assert(a);
964 	test_ai_eq(a, "0.0.0.0:9996", SOCK_STREAM, IPPROTO_TCP);
965 	evutil_freeaddrinfo(ai);
966 	ai = NULL;
967 
968 	/* Try out AI_NUMERICHOST: successful case.  Also try
969 	 * multiprotocol. */
970 	memset(&hints, 0, sizeof(hints));
971 	hints.ai_family = PF_UNSPEC;
972 	hints.ai_flags = EVUTIL_AI_NUMERICHOST;
973 	r = evutil_getaddrinfo("1.2.3.4", NULL, &hints, &ai);
974 	tt_int_op(r, ==, 0);
975 	a = ai_find_by_protocol(ai, IPPROTO_TCP);
976 	tt_assert(a);
977 	test_ai_eq(a, "1.2.3.4", SOCK_STREAM, IPPROTO_TCP);
978 	a = ai_find_by_protocol(ai, IPPROTO_UDP);
979 	tt_assert(a);
980 	test_ai_eq(a, "1.2.3.4", SOCK_DGRAM, IPPROTO_UDP);
981 	evutil_freeaddrinfo(ai);
982 	ai = NULL;
983 
984 	/* Try the failing case of AI_NUMERICHOST */
985 	memset(&hints, 0, sizeof(hints));
986 	hints.ai_family = PF_UNSPEC;
987 	hints.ai_flags = EVUTIL_AI_NUMERICHOST;
988 	r = evutil_getaddrinfo("www.google.com", "80", &hints, &ai);
989 	tt_int_op(r, ==, EVUTIL_EAI_NONAME);
990 	tt_ptr_op(ai, ==, NULL);
991 
992 	/* Try symbolic service names wit AI_NUMERICSERV */
993 	memset(&hints, 0, sizeof(hints));
994 	hints.ai_family = PF_UNSPEC;
995 	hints.ai_socktype = SOCK_STREAM;
996 	hints.ai_flags = EVUTIL_AI_NUMERICSERV;
997 	r = evutil_getaddrinfo("1.2.3.4", "http", &hints, &ai);
998 	tt_int_op(r,==,EVUTIL_EAI_NONAME);
999 
1000 	/* Try symbolic service names */
1001 	memset(&hints, 0, sizeof(hints));
1002 	hints.ai_family = PF_UNSPEC;
1003 	hints.ai_socktype = SOCK_STREAM;
1004 	r = evutil_getaddrinfo("1.2.3.4", "http", &hints, &ai);
1005 	if (r!=0) {
1006 		TT_DECLARE("SKIP", ("Symbolic service names seem broken."));
1007 	} else {
1008 		tt_assert(ai);
1009 		test_ai_eq(ai, "1.2.3.4:80", SOCK_STREAM, IPPROTO_TCP);
1010 		evutil_freeaddrinfo(ai);
1011 		ai = NULL;
1012 	}
1013 
1014 	/* Now do some actual lookups. */
1015 	memset(&hints, 0, sizeof(hints));
1016 	hints.ai_family = PF_INET;
1017 	hints.ai_protocol = IPPROTO_TCP;
1018 	hints.ai_socktype = SOCK_STREAM;
1019 	r = evutil_getaddrinfo("www.google.com", "80", &hints, &ai);
1020 	if (r != 0) {
1021 		TT_DECLARE("SKIP", ("Couldn't resolve www.google.com"));
1022 	} else {
1023 		tt_assert(ai);
1024 		tt_int_op(ai->ai_family, ==, PF_INET);
1025 		tt_int_op(ai->ai_protocol, ==, IPPROTO_TCP);
1026 		tt_int_op(ai->ai_socktype, ==, SOCK_STREAM);
1027 		tt_int_op(ai->ai_addrlen, ==, sizeof(struct sockaddr_in));
1028 		sin = (struct sockaddr_in*)ai->ai_addr;
1029 		tt_int_op(sin->sin_family, ==, AF_INET);
1030 		tt_int_op(sin->sin_port, ==, htons(80));
1031 		tt_int_op(sin->sin_addr.s_addr, !=, 0xffffffff);
1032 
1033 		cp = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf));
1034 		TT_BLATHER(("www.google.com resolved to %s",
1035 			cp?cp:"<unwriteable>"));
1036 		evutil_freeaddrinfo(ai);
1037 		ai = NULL;
1038 	}
1039 
1040 	hints.ai_family = PF_INET6;
1041 	r = evutil_getaddrinfo("ipv6.google.com", "80", &hints, &ai);
1042 	if (r != 0) {
1043 		TT_BLATHER(("Couldn't do an ipv6 lookup for ipv6.google.com"));
1044 	} else {
1045 		tt_assert(ai);
1046 		tt_int_op(ai->ai_family, ==, PF_INET6);
1047 		tt_int_op(ai->ai_addrlen, ==, sizeof(struct sockaddr_in6));
1048 		sin6 = (struct sockaddr_in6*)ai->ai_addr;
1049 		tt_int_op(sin6->sin6_port, ==, htons(80));
1050 
1051 		cp = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf,
1052 		    sizeof(buf));
1053 		TT_BLATHER(("ipv6.google.com resolved to %s",
1054 			cp?cp:"<unwriteable>"));
1055 	}
1056 
1057 end:
1058 	if (ai)
1059 		evutil_freeaddrinfo(ai);
1060 }
1061 
1062 #ifdef WIN32
1063 static void
1064 test_evutil_loadsyslib(void *arg)
1065 {
1066 	HANDLE h=NULL;
1067 
1068 	h = evutil_load_windows_system_library(TEXT("kernel32.dll"));
1069 	tt_assert(h);
1070 
1071 end:
1072 	if (h)
1073 		CloseHandle(h);
1074 
1075 }
1076 #endif
1077 
1078 struct testcase_t util_testcases[] = {
1079 	{ "ipv4_parse", regress_ipv4_parse, 0, NULL, NULL },
1080 	{ "ipv6_parse", regress_ipv6_parse, 0, NULL, NULL },
1081 	{ "sockaddr_port_parse", regress_sockaddr_port_parse, 0, NULL, NULL },
1082 	{ "sockaddr_port_format", regress_sockaddr_port_format, 0, NULL, NULL },
1083 	{ "sockaddr_predicates", test_evutil_sockaddr_predicates, 0,NULL,NULL },
1084 	{ "evutil_snprintf", test_evutil_snprintf, 0, NULL, NULL },
1085 	{ "evutil_strtoll", test_evutil_strtoll, 0, NULL, NULL },
1086 	{ "evutil_casecmp", test_evutil_casecmp, 0, NULL, NULL },
1087 	{ "strlcpy", test_evutil_strlcpy, 0, NULL, NULL },
1088 	{ "log", test_evutil_log, TT_FORK, NULL, NULL },
1089 	{ "upcast", test_evutil_upcast, 0, NULL, NULL },
1090 	{ "integers", test_evutil_integers, 0, NULL, NULL },
1091 	{ "rand", test_evutil_rand, TT_FORK, NULL, NULL },
1092 	{ "getaddrinfo", test_evutil_getaddrinfo, TT_FORK, NULL, NULL },
1093 #ifdef WIN32
1094 	{ "loadsyslib", test_evutil_loadsyslib, TT_FORK, NULL, NULL },
1095 #endif
1096 	END_OF_TESTCASES,
1097 };
1098 
1099