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