1047f369cy/*
2047f369cy * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
3047f369cy *
4047f369cy * Redistribution and use in source and binary forms, with or without
5047f369cy * modification, are permitted provided that the following conditions
6047f369cy * are met:
7047f369cy * 1. Redistributions of source code must retain the above copyright
8047f369cy *    notice, this list of conditions and the following disclaimer.
9047f369cy * 2. Redistributions in binary form must reproduce the above copyright
10047f369cy *    notice, this list of conditions and the following disclaimer in the
11047f369cy *    documentation and/or other materials provided with the distribution.
12047f369cy * 3. The name of the author may not be used to endorse or promote products
13047f369cy *    derived from this software without specific prior written permission.
14047f369cy *
15047f369cy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16047f369cy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17047f369cy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18047f369cy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19047f369cy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20047f369cy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21047f369cy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22047f369cy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23047f369cy * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24047f369cy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25047f369cy */
26047f369cy
27047f369cy#include "event2/event-config.h"
28047f369cy#include "evconfig-private.h"
29047f369cy
30047f369cy#ifdef _WIN32
31047f369cy#include <winsock2.h>
32047f369cy#include <ws2tcpip.h>
33047f369cy#define WIN32_LEAN_AND_MEAN
34047f369cy#include <windows.h>
35047f369cy#undef WIN32_LEAN_AND_MEAN
36047f369cy#include <io.h>
37047f369cy#include <tchar.h>
38047f369cy#include <process.h>
39047f369cy#undef _WIN32_WINNT
40047f369cy/* For structs needed by GetAdaptersAddresses */
41047f369cy#define _WIN32_WINNT 0x0501
42047f369cy#include <iphlpapi.h>
43047f369cy#endif
44047f369cy
45047f369cy#include <sys/types.h>
46047f369cy#ifdef EVENT__HAVE_SYS_SOCKET_H
47047f369cy#include <sys/socket.h>
48047f369cy#endif
49047f369cy#ifdef EVENT__HAVE_UNISTD_H
50047f369cy#include <unistd.h>
51047f369cy#endif
52047f369cy#ifdef EVENT__HAVE_FCNTL_H
53047f369cy#include <fcntl.h>
54047f369cy#endif
55047f369cy#ifdef EVENT__HAVE_STDLIB_H
56047f369cy#include <stdlib.h>
57047f369cy#endif
58047f369cy#include <errno.h>
59047f369cy#include <limits.h>
60047f369cy#include <stdio.h>
61047f369cy#include <string.h>
62047f369cy#ifdef EVENT__HAVE_NETINET_IN_H
63047f369cy#include <netinet/in.h>
64047f369cy#endif
65047f369cy#ifdef EVENT__HAVE_NETINET_IN6_H
66047f369cy#include <netinet/in6.h>
67047f369cy#endif
68047f369cy#ifdef EVENT__HAVE_NETINET_TCP_H
69047f369cy#include <netinet/tcp.h>
70047f369cy#endif
71047f369cy#ifdef EVENT__HAVE_ARPA_INET_H
72047f369cy#include <arpa/inet.h>
73047f369cy#endif
74047f369cy#include <time.h>
75047f369cy#include <sys/stat.h>
76047f369cy#ifdef EVENT__HAVE_IFADDRS_H
77047f369cy#include <ifaddrs.h>
78047f369cy#endif
79047f369cy
80047f369cy#include "event2/util.h"
81047f369cy#include "util-internal.h"
82047f369cy#include "log-internal.h"
83047f369cy#include "mm-internal.h"
84047f369cy#include "evthread-internal.h"
85047f369cy
86047f369cy#include "strlcpy-internal.h"
87047f369cy#include "ipv6-internal.h"
88047f369cy
89047f369cy#ifdef _WIN32
90047f369cy#define HT_NO_CACHE_HASH_VALUES
91047f369cy#include "ht-internal.h"
92047f369cy#define open _open
93047f369cy#define read _read
94047f369cy#define close _close
95047f369cy#ifndef fstat
96047f369cy#define fstat _fstati64
97047f369cy#endif
98047f369cy#ifndef stat
99047f369cy#define stat _stati64
100047f369cy#endif
101047f369cy#define mode_t int
102047f369cy#endif
103047f369cy
104047f369cyint
105047f369cyevutil_open_closeonexec_(const char *pathname, int flags, unsigned mode)
106047f369cy{
107047f369cy	int fd;
108047f369cy
109047f369cy#ifdef O_CLOEXEC
110047f369cy	fd = open(pathname, flags|O_CLOEXEC, (mode_t)mode);
111047f369cy	if (fd >= 0 || errno == EINVAL)
112047f369cy		return fd;
113047f369cy	/* If we got an EINVAL, fall through and try without O_CLOEXEC */
114047f369cy#endif
115047f369cy	fd = open(pathname, flags, (mode_t)mode);
116047f369cy	if (fd < 0)
117047f369cy		return -1;
118047f369cy
119047f369cy#if defined(FD_CLOEXEC)
120047f369cy	if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
121047f369cy		close(fd);
122047f369cy		return -1;
123047f369cy	}
124047f369cy#endif
125047f369cy
126047f369cy	return fd;
127047f369cy}
128047f369cy
129047f369cy/**
130047f369cy   Read the contents of 'filename' into a newly allocated NUL-terminated
131047f369cy   string.  Set *content_out to hold this string, and *len_out to hold its
132047f369cy   length (not including the appended NUL).  If 'is_binary', open the file in
133047f369cy   binary mode.
134047f369cy
135047f369cy   Returns 0 on success, -1 if the open fails, and -2 for all other failures.
136047f369cy
137047f369cy   Used internally only; may go away in a future version.
138047f369cy */
139047f369cyint
140047f369cyevutil_read_file_(const char *filename, char **content_out, size_t *len_out,
141047f369cy    int is_binary)
142047f369cy{
143047f369cy	int fd, r;
144047f369cy	struct stat st;
145047f369cy	char *mem;
146047f369cy	size_t read_so_far=0;
147047f369cy	int mode = O_RDONLY;
148047f369cy
149047f369cy	EVUTIL_ASSERT(content_out);
150047f369cy	EVUTIL_ASSERT(len_out);
151047f369cy	*content_out = NULL;
152047f369cy	*len_out = 0;
153047f369cy
154047f369cy#ifdef O_BINARY
155047f369cy	if (is_binary)
156047f369cy		mode |= O_BINARY;
157047f369cy#endif
158047f369cy
159047f369cy	fd = evutil_open_closeonexec_(filename, mode, 0);
160047f369cy	if (fd < 0)
161047f369cy		return -1;
162047f369cy	if (fstat(fd, &st) || st.st_size < 0 ||
163047f369cy	    st.st_size > EV_SSIZE_MAX-1 ) {
164047f369cy		close(fd);
165047f369cy		return -2;
166047f369cy	}
167047f369cy	mem = mm_malloc((size_t)st.st_size + 1);
168047f369cy	if (!mem) {
169047f369cy		close(fd);
170047f369cy		return -2;
171047f369cy	}
172047f369cy	read_so_far = 0;
173047f369cy#ifdef _WIN32
174047f369cy#define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x))
175047f369cy#else
176047f369cy#define N_TO_READ(x) (x)
177047f369cy#endif
178047f369cy	while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) {
179047f369cy		read_so_far += r;
180047f369cy		if (read_so_far >= (size_t)st.st_size)
181047f369cy			break;
182047f369cy		EVUTIL_ASSERT(read_so_far < (size_t)st.st_size);
183047f369cy	}
184047f369cy	close(fd);
185047f369cy	if (r < 0) {
186047f369cy		mm_free(mem);
187047f369cy		return -2;
188047f369cy	}
189047f369cy	mem[read_so_far] = 0;
190047f369cy
191047f369cy	*len_out = read_so_far;
192047f369cy	*content_out = mem;
193047f369cy	return 0;
194047f369cy}
195047f369cy
196047f369cyint
197047f369cyevutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
198047f369cy{
199047f369cy#ifndef _WIN32
200047f369cy	return socketpair(family, type, protocol, fd);
201047f369cy#else
202047f369cy	return evutil_ersatz_socketpair_(family, type, protocol, fd);
203047f369cy#endif
204047f369cy}
205047f369cy
206047f369cyint
207047f369cyevutil_ersatz_socketpair_(int family, int type, int protocol,
208047f369cy    evutil_socket_t fd[2])
209047f369cy{
210047f369cy	/* This code is originally from Tor.  Used with permission. */
211047f369cy
212047f369cy	/* This socketpair does not work when localhost is down. So
213047f369cy	 * it's really not the same thing at all. But it's close enough
214047f369cy	 * for now, and really, when localhost is down sometimes, we
215047f369cy	 * have other problems too.
216047f369cy	 */
217047f369cy#ifdef _WIN32
218047f369cy#define ERR(e) WSA##e
219047f369cy#else
220047f369cy#define ERR(e) e
221047f369cy#endif
222047f369cy	evutil_socket_t listener = -1;
223047f369cy	evutil_socket_t connector = -1;
224047f369cy	evutil_socket_t acceptor = -1;
225047f369cy	struct sockaddr_in listen_addr;
226047f369cy	struct sockaddr_in connect_addr;
227047f369cy	ev_socklen_t size;
228047f369cy	int saved_errno = -1;
229047f369cy
230047f369cy	if (protocol
231047f369cy		|| (family != AF_INET
232047f369cy#ifdef AF_UNIX
233047f369cy		    && family != AF_UNIX
234047f369cy#endif
235047f369cy		)) {
236047f369cy		EVUTIL_SET_SOCKET_ERROR(ERR(EAFNOSUPPORT));
237047f369cy		return -1;
238047f369cy	}
239047f369cy	if (!fd) {
240047f369cy		EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
241047f369cy		return -1;
242047f369cy	}
243047f369cy
244047f369cy	listener = socket(AF_INET, type, 0);
245047f369cy	if (listener < 0)
246047f369cy		return -1;
247047f369cy	memset(&listen_addr, 0, sizeof(listen_addr));
248047f369cy	listen_addr.sin_family = AF_INET;
249047f369cy	listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
250047f369cy	listen_addr.sin_port = 0;	/* kernel chooses port.	 */
251047f369cy	if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
252047f369cy		== -1)
253047f369cy		goto tidy_up_and_fail;
254047f369cy	if (listen(listener, 1) == -1)
255047f369cy		goto tidy_up_and_fail;
256047f369cy
257047f369cy	connector = socket(AF_INET, type, 0);
258047f369cy	if (connector < 0)
259047f369cy		goto tidy_up_and_fail;
260047f369cy	/* We want to find out the port number to connect to.  */
261047f369cy	size = sizeof(connect_addr);
262047f369cy	if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
263047f369cy		goto tidy_up_and_fail;
264047f369cy	if (size != sizeof (connect_addr))
265047f369cy		goto abort_tidy_up_and_fail;
266047f369cy	if (connect(connector, (struct sockaddr *) &connect_addr,
267047f369cy				sizeof(connect_addr)) == -1)
268047f369cy		goto tidy_up_and_fail;
269047f369cy
270047f369cy	size = sizeof(listen_addr);
271047f369cy	acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
272047f369cy	if (acceptor < 0)
273047f369cy		goto tidy_up_and_fail;
274047f369cy	if (size != sizeof(listen_addr))
275047f369cy		goto abort_tidy_up_and_fail;
276047f369cy	/* Now check we are talking to ourself by matching port and host on the
277047f369cy	   two sockets.	 */
278047f369cy	if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
279047f369cy		goto tidy_up_and_fail;
280047f369cy	if (size != sizeof (connect_addr)
281047f369cy		|| listen_addr.sin_family != connect_addr.sin_family
282047f369cy		|| listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
283047f369cy		|| listen_addr.sin_port != connect_addr.sin_port)
284047f369cy		goto abort_tidy_up_and_fail;
285047f369cy	evutil_closesocket(listener);
286047f369cy	fd[0] = connector;
287047f369cy	fd[1] = acceptor;
288047f369cy
289047f369cy	return 0;
290047f369cy
291047f369cy abort_tidy_up_and_fail:
292047f369cy	saved_errno = ERR(ECONNABORTED);
293047f369cy tidy_up_and_fail:
294047f369cy	if (saved_errno < 0)
295047f369cy		saved_errno = EVUTIL_SOCKET_ERROR();
296047f369cy	if (listener != -1)
297047f369cy		evutil_closesocket(listener);
298047f369cy	if (connector != -1)
299047f369cy		evutil_closesocket(connector);
300047f369cy	if (acceptor != -1)
301047f369cy		evutil_closesocket(acceptor);
302047f369cy
303047f369cy	EVUTIL_SET_SOCKET_ERROR(saved_errno);
304047f369cy	return -1;
305047f369cy#undef ERR
306047f369cy}
307047f369cy
308047f369cyint
309047f369cyevutil_make_socket_nonblocking(evutil_socket_t fd)
310047f369cy{
311047f369cy#ifdef _WIN32
312047f369cy	{
313047f369cy		u_long nonblocking = 1;
314047f369cy		if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) {
315047f369cy			event_sock_warn(fd, "fcntl(%d, F_GETFL)", (int)fd);
316047f369cy			return -1;
317047f369cy		}
318047f369cy	}
319047f369cy#else
320047f369cy	{
321047f369cy		int flags;
322047f369cy		if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
323047f369cy			event_warn("fcntl(%d, F_GETFL)", fd);
324047f369cy			return -1;
325047f369cy		}
326047f369cy		if (!(flags & O_NONBLOCK)) {
327047f369cy			if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
328047f369cy				event_warn("fcntl(%d, F_SETFL)", fd);
329047f369cy				return -1;
330047f369cy			}
331047f369cy		}
332047f369cy	}
333047f369cy#endif
334047f369cy	return 0;
335047f369cy}
336047f369cy
337047f369cy/* Faster version of evutil_make_socket_nonblocking for internal use.
338047f369cy *
339047f369cy * Requires that no F_SETFL flags were previously set on the fd.
340047f369cy */
341047f369cystatic int
342047f369cyevutil_fast_socket_nonblocking(evutil_socket_t fd)
343047f369cy{
344047f369cy#ifdef _WIN32
345047f369cy	return evutil_make_socket_nonblocking(fd);
346047f369cy#else
347047f369cy	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
348047f369cy		event_warn("fcntl(%d, F_SETFL)", fd);
349047f369cy		return -1;
350047f369cy	}
351047f369cy	return 0;
352047f369cy#endif
353047f369cy}
354047f369cy
355047f369cyint
356047f369cyevutil_make_listen_socket_reuseable(evutil_socket_t sock)
357047f369cy{
358047f369cy#ifndef _WIN32
359047f369cy	int one = 1;
360047f369cy	/* REUSEADDR on Unix means, "don't hang on to this address after the
361047f369cy	 * listener is closed."  On Windows, though, it means "don't keep other
362047f369cy	 * processes from binding to this address while we're using it. */
363047f369cy	return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
364047f369cy	    (ev_socklen_t)sizeof(one));
365047f369cy#else
366047f369cy	return 0;
367047f369cy#endif
368047f369cy}
369047f369cy
370047f369cyint
371f63afe2cyevutil_make_listen_socket_reuseable_port(evutil_socket_t sock)
372f63afe2cy{
373f63afe2cy#if defined __linux__ && defined(SO_REUSEPORT)
374f63afe2cy	int one = 1;
375f63afe2cy	/* REUSEPORT on Linux 3.9+ means, "Multiple servers (processes or
376f63afe2cy	 * threads) can bind to the same port if they each set the option. */
377f63afe2cy	return setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void*) &one,
378f63afe2cy	    (ev_socklen_t)sizeof(one));
379f63afe2cy#else
380f63afe2cy	return 0;
381f63afe2cy#endif
382f63afe2cy}
383f63afe2cy
384f63afe2cyint
385047f369cyevutil_make_tcp_listen_socket_deferred(evutil_socket_t sock)
386047f369cy{
387047f369cy#if defined(EVENT__HAVE_NETINET_TCP_H) && defined(TCP_DEFER_ACCEPT)
388047f369cy	int one = 1;
389047f369cy
390047f369cy	/* TCP_DEFER_ACCEPT tells the kernel to call defer accept() only after data
391047f369cy	 * has arrived and ready to read */
392047f369cy	return setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, &one,
393047f369cy		(ev_socklen_t)sizeof(one));
394047f369cy#endif
395047f369cy	return 0;
396047f369cy}
397047f369cy
398047f369cyint
399047f369cyevutil_make_socket_closeonexec(evutil_socket_t fd)
400047f369cy{
401047f369cy#if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
402047f369cy	int flags;
403047f369cy	if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) {
404047f369cy		event_warn("fcntl(%d, F_GETFD)", fd);
405047f369cy		return -1;
406047f369cy	}
407047f369cy	if (!(flags & FD_CLOEXEC)) {
408047f369cy		if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
409047f369cy			event_warn("fcntl(%d, F_SETFD)", fd);
410047f369cy			return -1;
411047f369cy		}
412047f369cy	}
413047f369cy#endif
414047f369cy	return 0;
415047f369cy}
416047f369cy
417047f369cy/* Faster version of evutil_make_socket_closeonexec for internal use.
418047f369cy *
419047f369cy * Requires that no F_SETFD flags were previously set on the fd.
420047f369cy */
421047f369cystatic int
422047f369cyevutil_fast_socket_closeonexec(evutil_socket_t fd)
423047f369cy{
424047f369cy#if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
425047f369cy	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
426047f369cy		event_warn("fcntl(%d, F_SETFD)", fd);
427047f369cy		return -1;
428047f369cy	}
429047f369cy#endif
430047f369cy	return 0;
431047f369cy}
432047f369cy
433047f369cyint
434047f369cyevutil_closesocket(evutil_socket_t sock)
435047f369cy{
436047f369cy#ifndef _WIN32
437047f369cy	return close(sock);
438047f369cy#else
439047f369cy	return closesocket(sock);
440047f369cy#endif
441047f369cy}
442047f369cy
443047f369cyev_int64_t
444047f369cyevutil_strtoll(const char *s, char **endptr, int base)
445047f369cy{
446047f369cy#ifdef EVENT__HAVE_STRTOLL
447047f369cy	return (ev_int64_t)strtoll(s, endptr, base);
448047f369cy#elif EVENT__SIZEOF_LONG == 8
449047f369cy	return (ev_int64_t)strtol(s, endptr, base);
450047f369cy#elif defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
451047f369cy	/* XXXX on old versions of MS APIs, we only support base
452047f369cy	 * 10. */
453047f369cy	ev_int64_t r;
454047f369cy	if (base != 10)
455047f369cy		return 0;
456047f369cy	r = (ev_int64_t) _atoi64(s);
457047f369cy	while (isspace(*s))
458047f369cy		++s;
459047f369cy	if (*s == '-')
460047f369cy		++s;
461047f369cy	while (isdigit(*s))
462047f369cy		++s;
463047f369cy	if (endptr)
464047f369cy		*endptr = (char*) s;
465047f369cy	return r;
466047f369cy#elif defined(_WIN32)
467047f369cy	return (ev_int64_t) _strtoi64(s, endptr, base);
468047f369cy#elif defined(EVENT__SIZEOF_LONG_LONG) && EVENT__SIZEOF_LONG_LONG == 8
469047f369cy	long long r;
470047f369cy	int n;
471047f369cy	if (base != 10 && base != 16)
472047f369cy		return 0;
473047f369cy	if (base == 10) {
474047f369cy		n = sscanf(s, "%lld", &r);
475047f369cy	} else {
476047f369cy		unsigned long long ru=0;
477047f369cy		n = sscanf(s, "%llx", &ru);
478047f369cy		if (ru > EV_INT64_MAX)
479047f369cy			return 0;
480047f369cy		r = (long long) ru;
481047f369cy	}
482047f369cy	if (n != 1)
483047f369cy		return 0;
484047f369cy	while (EVUTIL_ISSPACE_(*s))
485047f369cy		++s;
486047f369cy	if (*s == '-')
487047f369cy		++s;
488047f369cy	if (base == 10) {
489047f369cy		while (EVUTIL_ISDIGIT_(*s))
490047f369cy			++s;
491047f369cy	} else {
492047f369cy		while (EVUTIL_ISXDIGIT_(*s))
493047f369cy			++s;
494047f369cy	}
495047f369cy	if (endptr)
496047f369cy		*endptr = (char*) s;
497047f369cy	return r;
498047f369cy#else
499047f369cy#error "I don't know how to parse 64-bit integers."
500047f369cy#endif
501047f369cy}
502047f369cy
503047f369cy#ifdef _WIN32
504047f369cyint
505047f369cyevutil_socket_geterror(evutil_socket_t sock)
506047f369cy{
507047f369cy	int optval, optvallen=sizeof(optval);
508047f369cy	int err = WSAGetLastError();
509047f369cy	if (err == WSAEWOULDBLOCK && sock >= 0) {
510047f369cy		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
511047f369cy					   &optvallen))
512047f369cy			return err;
513047f369cy		if (optval)
514047f369cy			return optval;
515047f369cy	}
516047f369cy	return err;
517047f369cy}
518047f369cy#endif
519047f369cy
520047f369cy/* XXX we should use an enum here. */
521047f369cy/* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
522047f369cyint
523047f369cyevutil_socket_connect_(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen)
524047f369cy{
525047f369cy	int made_fd = 0;
526047f369cy
527047f369cy	if (*fd_ptr < 0) {
528047f369cy		if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
529047f369cy			goto err;
530047f369cy		made_fd = 1;
531047f369cy		if (evutil_make_socket_nonblocking(*fd_ptr) < 0) {
532047f369cy			goto err;
533047f369cy		}
534047f369cy	}
535047f369cy
536047f369cy	if (connect(*fd_ptr, sa, socklen) < 0) {
537047f369cy		int e = evutil_socket_geterror(*fd_ptr);
538047f369cy		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
539047f369cy			return 0;
540047f369cy		if (EVUTIL_ERR_CONNECT_REFUSED(e))
541047f369cy			return 2;
542047f369cy		goto err;
543047f369cy	} else {
544047f369cy		return 1;
545047f369cy	}
546047f369cy
547047f369cyerr:
548047f369cy	if (made_fd) {
549047f369cy		evutil_closesocket(*fd_ptr);
550047f369cy		*fd_ptr = -1;
551047f369cy	}
552047f369cy	return -1;
553047f369cy}
554047f369cy
555047f369cy/* Check whether a socket on which we called connect() is done
556047f369cy   connecting. Return 1 for connected, 0 for not yet, -1 for error.  In the
557047f369cy   error case, set the current socket errno to the error that happened during
558047f369cy   the connect operation. */
559047f369cyint
560047f369cyevutil_socket_finished_connecting_(evutil_socket_t fd)
561047f369cy{
562047f369cy	int e;
563047f369cy	ev_socklen_t elen = sizeof(e);
564047f369cy
565047f369cy	if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
566047f369cy		return -1;
567047f369cy
568047f369cy	if (e) {
569047f369cy		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
570047f369cy			return 0;
571047f369cy		EVUTIL_SET_SOCKET_ERROR(e);
572047f369cy		return -1;
573047f369cy	}
574047f369cy
575047f369cy	return 1;
576047f369cy}
577047f369cy
578047f369cy#if (EVUTIL_AI_PASSIVE|EVUTIL_AI_CANONNAME|EVUTIL_AI_NUMERICHOST| \
579047f369cy     EVUTIL_AI_NUMERICSERV|EVUTIL_AI_V4MAPPED|EVUTIL_AI_ALL| \
580047f369cy     EVUTIL_AI_ADDRCONFIG) != \
581047f369cy    (EVUTIL_AI_PASSIVE^EVUTIL_AI_CANONNAME^EVUTIL_AI_NUMERICHOST^ \
582047f369cy     EVUTIL_AI_NUMERICSERV^EVUTIL_AI_V4MAPPED^EVUTIL_AI_ALL^ \
583047f369cy     EVUTIL_AI_ADDRCONFIG)
584047f369cy#error "Some of our EVUTIL_AI_* flags seem to overlap with system AI_* flags"
585047f369cy#endif
586047f369cy
587047f369cy/* We sometimes need to know whether we have an ipv4 address and whether we
588047f369cy   have an ipv6 address. If 'have_checked_interfaces', then we've already done
589047f369cy   the test.  If 'had_ipv4_address', then it turns out we had an ipv4 address.
590047f369cy   If 'had_ipv6_address', then it turns out we had an ipv6 address.   These are
591047f369cy   set by evutil_check_interfaces. */
592047f369cystatic int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
593047f369cy
594047f369cy/* Macro: True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8
595047f369cy */
596047f369cy#define EVUTIL_V4ADDR_IS_LOCALHOST(addr) (((addr)>>24) == 127)
597047f369cy
598047f369cy/* Macro: True iff the IPv4 address 'addr', in host order, is a class D
599047f369cy * (multiclass) address.
600047f369cy */
601047f369cy#define EVUTIL_V4ADDR_IS_CLASSD(addr) ((((addr)>>24) & 0xf0) == 0xe0)
602047f369cy
603047f369cystatic void
604047f369cyevutil_found_ifaddr(const struct sockaddr *sa)
605047f369cy{
606047f369cy	const char ZEROES[] = "\x00\x00\x00\x00\x00\x00\x00\x00"
607047f369cy	    "\x00\x00\x00\x00\x00\x00\x00\x00";
608047f369cy
609047f369cy	if (sa->sa_family == AF_INET) {
610047f369cy		const struct sockaddr_in *sin = (struct sockaddr_in *)sa;
611047f369cy		ev_uint32_t addr = ntohl(sin->sin_addr.s_addr);
612047f369cy		if (addr == 0 ||
613047f369cy		    EVUTIL_V4ADDR_IS_LOCALHOST(addr) ||
614047f369cy		    EVUTIL_V4ADDR_IS_CLASSD(addr)) {
615047f369cy			/* Not actually a usable external address. */
616047f369cy		} else {
617047f369cy			event_debug(("Detected an IPv4 interface"));
618047f369cy			had_ipv4_address = 1;
619047f369cy		}
620047f369cy	} else if (sa->sa_family == AF_INET6) {
621047f369cy		const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
622047f369cy		const unsigned char *addr =
623047f369cy		    (unsigned char*)sin6->sin6_addr.s6_addr;
624047f369cy		if (!memcmp(addr, ZEROES, 8) ||
625047f369cy		    ((addr[0] & 0xfe) == 0xfc) ||
626047f369cy		    (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80) ||
627047f369cy		    (addr[0] == 0xfe && (addr[1] & 0xc0) == 0xc0) ||
628047f369cy		    (addr[0] == 0xff)) {
629047f369cy			/* This is a reserved, ipv4compat, ipv4map, loopback,
630047f369cy			 * link-local, multicast, or unspecified address. */
631047f369cy		} else {
632047f369cy			event_debug(("Detected an IPv6 interface"));
633047f369cy			had_ipv6_address = 1;
634047f369cy		}
635047f369cy	}
636047f369cy}
637047f369cy
638047f369cy#ifdef _WIN32
639047f369cytypedef ULONG (WINAPI *GetAdaptersAddresses_fn_t)(
640047f369cy              ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
641047f369cy#endif
642047f369cy
643047f369cystatic int
644047f369cyevutil_check_ifaddrs(void)
645047f369cy{
646047f369cy#if defined(EVENT__HAVE_GETIFADDRS)
647047f369cy	/* Most free Unixy systems provide getifaddrs, which gives us a linked list
648047f369cy	 * of struct ifaddrs. */
649047f369cy	struct ifaddrs *ifa = NULL;
650047f369cy	const struct ifaddrs *i;
651047f369cy	if (getifaddrs(&ifa) < 0) {
652047f369cy		event_warn("Unable to call getifaddrs()");
653047f369cy		return -1;
654047f369cy	}
655047f369cy
656047f369cy	for (i = ifa; i; i = i->ifa_next) {
657047f369cy		if (!i->ifa_addr)
658047f369cy			continue;
659047f369cy		evutil_found_ifaddr(i->ifa_addr);
660047f369cy	}
661047f369cy
662047f369cy	freeifaddrs(ifa);
663047f369cy	return 0;
664047f369cy#elif defined(_WIN32)
665047f369cy	/* Windows XP began to provide GetAdaptersAddresses. Windows 2000 had a
666047f369cy	   "GetAdaptersInfo", but that's deprecated; let's just try
667047f369cy	   GetAdaptersAddresses and fall back to connect+getsockname.
668047f369cy	*/
669f63afe2cy	HMODULE lib = evutil_load_windows_system_library_(TEXT("ihplapi.dll"));
670047f369cy	GetAdaptersAddresses_fn_t fn;
671047f369cy	ULONG size, res;
672047f369cy	IP_ADAPTER_ADDRESSES *addresses = NULL, *address;
673047f369cy	int result = -1;
674047f369cy
675047f369cy#define FLAGS (GAA_FLAG_SKIP_ANYCAST | \
676047f369cy               GAA_FLAG_SKIP_MULTICAST | \
677047f369cy               GAA_FLAG_SKIP_DNS_SERVER)
678047f369cy
679047f369cy	if (!lib)
680047f369cy		goto done;
681047f369cy
682047f369cy	if (!(fn = (GetAdaptersAddresses_fn_t) GetProcAddress(lib, "GetAdaptersAddresses")))
683047f369cy		goto done;
684047f369cy
685047f369cy	/* Guess how much space we need. */
686047f369cy	size = 15*1024;
687047f369cy	addresses = mm_malloc(size);
688047f369cy	if (!addresses)
689047f369cy		goto done;
690047f369cy	res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
691047f369cy	if (res == ERROR_BUFFER_OVERFLOW) {
692047f369cy		/* we didn't guess that we needed enough space; try again */
693047f369cy		mm_free(addresses);
694047f369cy		addresses = mm_malloc(size);
695047f369cy		if (!addresses)
696047f369cy			goto done;
697047f369cy		res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
698047f369cy	}
699047f369cy	if (res != NO_ERROR)
700047f369cy		goto done;
701047f369cy
702047f369cy	for (address = addresses; address; address = address->Next) {
703047f369cy		IP_ADAPTER_UNICAST_ADDRESS *a;
704047f369cy		for (a = address->FirstUnicastAddress; a; a = a->Next) {
705047f369cy			/* Yes, it's a linked list inside a linked list */
706047f369cy			struct sockaddr *sa = a->Address.lpSockaddr;
707047f369cy			evutil_found_ifaddr(sa);
708047f369cy		}
709047f369cy	}
710047f369cy
711047f369cy	result = 0;
712047f369cydone:
713047f369cy	if (lib)
714047f369cy		FreeLibrary(lib);
715047f369cy	if (addresses)
716047f369cy		mm_free(addresses);
717047f369cy	return result;
718047f369cy#else
719047f369cy	return -1;
720047f369cy#endif
721047f369cy}
722047f369cy
723047f369cy/* Test whether we have an ipv4 interface and an ipv6 interface.  Return 0 if
724047f369cy * the test seemed successful. */
725047f369cystatic int
726047f369cyevutil_check_interfaces(int force_recheck)
727047f369cy{
728047f369cy	evutil_socket_t fd = -1;
729047f369cy	struct sockaddr_in sin, sin_out;
730047f369cy	struct sockaddr_in6 sin6, sin6_out;
731047f369cy	ev_socklen_t sin_out_len = sizeof(sin_out);
732047f369cy	ev_socklen_t sin6_out_len = sizeof(sin6_out);
733047f369cy	int r;
734047f369cy	if (have_checked_interfaces && !force_recheck)
735047f369cy		return 0;
736047f369cy
737047f369cy	if (evutil_check_ifaddrs() == 0) {
738047f369cy		/* Use a nice sane interface, if this system has one. */
739047f369cy		return 0;
740047f369cy	}
741047f369cy
742047f369cy	/* Ugh. There was no nice sane interface.  So to check whether we have
743047f369cy	 * an interface open for a given protocol, will try to make a UDP
744047f369cy	 * 'connection' to a remote host on the internet.  We don't actually
745047f369cy	 * use it, so the address doesn't matter, but we want to pick one that
746047f369cy	 * keep us from using a host- or link-local interface. */
747047f369cy	memset(&sin, 0, sizeof(sin));
748047f369cy	sin.sin_family = AF_INET;
749047f369cy	sin.sin_port = htons(53);
750047f369cy	r = evutil_inet_pton(AF_INET, "18.244.0.188", &sin.sin_addr);
751047f369cy	EVUTIL_ASSERT(r);
752047f369cy
753047f369cy	memset(&sin6, 0, sizeof(sin6));
754047f369cy	sin6.sin6_family = AF_INET6;
755047f369cy	sin6.sin6_port = htons(53);
756047f369cy	r = evutil_inet_pton(AF_INET6, "2001:4860:b002::68", &sin6.sin6_addr);
757047f369cy	EVUTIL_ASSERT(r);
758047f369cy
759047f369cy	memset(&sin_out, 0, sizeof(sin_out));
760047f369cy	memset(&sin6_out, 0, sizeof(sin6_out));
761047f369cy
762047f369cy	/* XXX some errnos mean 'no address'; some mean 'not enough sockets'. */
763047f369cy	if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
764047f369cy	    connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
765047f369cy	    getsockname(fd, (struct sockaddr*)&sin_out, &sin_out_len) == 0) {
766047f369cy		/* We might have an IPv4 interface. */
767047f369cy		evutil_found_ifaddr((struct sockaddr*) &sin_out);
768047f369cy	}
769047f369cy	if (fd >= 0)
770047f369cy		evutil_closesocket(fd);
771047f369cy
772047f369cy	if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
773047f369cy	    connect(fd, (struct sockaddr*)&sin6, sizeof(sin6)) == 0 &&
774047f369cy	    getsockname(fd, (struct sockaddr*)&sin6_out, &sin6_out_len) == 0) {
775047f369cy		/* We might have an IPv6 interface. */
776047f369cy		evutil_found_ifaddr((struct sockaddr*) &sin6_out);
777047f369cy	}
778047f369cy
779047f369cy	if (fd >= 0)
780047f369cy		evutil_closesocket(fd);
781047f369cy
782047f369cy	return 0;
783047f369cy}
784047f369cy
785047f369cy/* Internal addrinfo flag.  This one is set when we allocate the addrinfo from
786047f369cy * inside libevent.  Otherwise, the built-in getaddrinfo() function allocated
787047f369cy * it, and we should trust what they said.
788047f369cy **/
789047f369cy#define EVUTIL_AI_LIBEVENT_ALLOCATED 0x80000000
790047f369cy
791047f369cy/* Helper: construct a new addrinfo containing the socket address in
792047f369cy * 'sa', which must be a sockaddr_in or a sockaddr_in6.  Take the
793047f369cy * socktype and protocol info from hints.  If they weren't set, then
794047f369cy * allocate both a TCP and a UDP addrinfo.
795047f369cy */
796047f369cystruct evutil_addrinfo *
797047f369cyevutil_new_addrinfo_(struct sockaddr *sa, ev_socklen_t socklen,
798047f369cy    const struct evutil_addrinfo *hints)
799047f369cy{
800047f369cy	struct evutil_addrinfo *res;
801047f369cy	EVUTIL_ASSERT(hints);
802047f369cy
803047f369cy	if (hints->ai_socktype == 0 && hints->ai_protocol == 0) {
804047f369cy		/* Indecisive user! Give them a UDP and a TCP. */
805047f369cy		struct evutil_addrinfo *r1, *r2;
806047f369cy		struct evutil_addrinfo tmp;
807047f369cy		memcpy(&tmp, hints, sizeof(tmp));
808047f369cy		tmp.ai_socktype = SOCK_STREAM; tmp.ai_protocol = IPPROTO_TCP;
809047f369cy		r1 = evutil_new_addrinfo_(sa, socklen, &tmp);
810047f369cy		if (!r1)
811047f369cy			return NULL;
812047f369cy		tmp.ai_socktype = SOCK_DGRAM; tmp.ai_protocol = IPPROTO_UDP;
813047f369cy		r2 = evutil_new_addrinfo_(sa, socklen, &tmp);
814047f369cy		if (!r2) {
815047f369cy			evutil_freeaddrinfo(r1);
816047f369cy			return NULL;
817047f369cy		}
818047f369cy		r1->ai_next = r2;
819047f369cy		return r1;
820047f369cy	}
821047f369cy
822047f369cy	/* We're going to allocate extra space to hold the sockaddr. */
823047f369cy	res = mm_calloc(1,sizeof(struct evutil_addrinfo)+socklen);
824047f369cy	if (!res)
825047f369cy		return NULL;
826047f369cy	res->ai_addr = (struct sockaddr*)
827047f369cy	    (((char*)res) + sizeof(struct evutil_addrinfo));
828047f369cy	memcpy(res->ai_addr, sa, socklen);
829047f369cy	res->ai_addrlen = socklen;
830047f369cy	res->ai_family = sa->sa_family; /* Same or not? XXX */
831047f369cy	res->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
832047f369cy	res->ai_socktype = hints->ai_socktype;
833047f369cy	res->ai_protocol = hints->ai_protocol;
834047f369cy
835047f369cy	return res;
836047f369cy}
837047f369cy
838047f369cy/* Append the addrinfo 'append' to the end of 'first', and return the start of
839047f369cy * the list.  Either element can be NULL, in which case we return the element
840047f369cy * that is not NULL. */
841047f369cystruct evutil_addrinfo *
842047f369cyevutil_addrinfo_append_(struct evutil_addrinfo *first,
843047f369cy    struct evutil_addrinfo *append)
844047f369cy{
845047f369cy	struct evutil_addrinfo *ai = first;
846047f369cy	if (!ai)
847047f369cy		return append;
848047f369cy	while (ai->ai_next)
849047f369cy		ai = ai->ai_next;
850047f369cy	ai->ai_next = append;
851047f369cy
852047f369cy	return first;
853047f369cy}
854047f369cy
855047f369cystatic int
856047f369cyparse_numeric_servname(const char *servname)
857047f369cy{
858047f369cy	int n;
859047f369cy	char *endptr=NULL;
860047f369cy	n = (int) strtol(servname, &endptr, 10);
861047f369cy	if (n>=0 && n <= 65535 && servname[0] && endptr && !endptr[0])
862047f369cy		return n;
863047f369cy	else
864047f369cy		return -1;
865047f369cy}
866047f369cy
867047f369cy/** Parse a service name in 'servname', which can be a decimal port.
868047f369cy * Return the port number, or -1 on error.
869047f369cy */
870047f369cystatic int
871047f369cyevutil_parse_servname(const char *servname, const char *protocol,
872047f369cy    const struct evutil_addrinfo *hints)
873047f369cy{
874047f369cy	int n = parse_numeric_servname(servname);
875047f369cy	if (n>=0)
876047f369cy		return n;
877047f369cy#if defined(EVENT__HAVE_GETSERVBYNAME) || defined(_WIN32)
878047f369cy	if (!(hints->ai_flags & EVUTIL_AI_NUMERICSERV)) {
879047f369cy		struct servent *ent = getservbyname(servname, protocol);
880047f369cy		if (ent) {
881047f369cy			return ntohs(ent->s_port);
882047f369cy		}
883047f369cy	}
884047f369cy#endif
885047f369cy	return -1;
886047f369cy}
887047f369cy
888047f369cy/* Return a string corresponding to a protocol number that we can pass to
889047f369cy * getservyname.  */
890047f369cystatic const char *
891047f369cyevutil_unparse_protoname(int proto)
892047f369cy{
893047f369cy	switch (proto) {
894047f369cy	case 0:
895047f369cy		return NULL;
896047f369cy	case IPPROTO_TCP:
897047f369cy		return "tcp";
898047f369cy	case IPPROTO_UDP:
899047f369cy		return "udp";
900047f369cy#ifdef IPPROTO_SCTP
901047f369cy	case IPPROTO_SCTP:
902047f369cy		return "sctp";
903047f369cy#endif
904047f369cy	default:
905047f369cy#ifdef EVENT__HAVE_GETPROTOBYNUMBER
906047f369cy		{
907047f369cy			struct protoent *ent = getprotobynumber(proto);
908047f369cy			if (ent)
909047f369cy				return ent->p_name;
910047f369cy		}
911047f369cy#endif
912047f369cy		return NULL;
913047f369cy	}
914047f369cy}
915047f369cy
916047f369cystatic void
917047f369cyevutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints)
918047f369cy{
919047f369cy	/* If we can guess the protocol from the socktype, do so. */
920047f369cy	if (!hints->ai_protocol && hints->ai_socktype) {
921047f369cy		if (hints->ai_socktype == SOCK_DGRAM)
922047f369cy			hints->ai_protocol = IPPROTO_UDP;
923047f369cy		else if (hints->ai_socktype == SOCK_STREAM)
924047f369cy			hints->ai_protocol = IPPROTO_TCP;
925047f369cy	}
926047f369cy
927047f369cy	/* Set the socktype if it isn't set. */
928047f369cy	if (!hints->ai_socktype && hints->ai_protocol) {
929047f369cy		if (hints->ai_protocol == IPPROTO_UDP)
930047f369cy			hints->ai_socktype = SOCK_DGRAM;
931047f369cy		else if (hints->ai_protocol == IPPROTO_TCP)
932047f369cy			hints->ai_socktype = SOCK_STREAM;
933047f369cy#ifdef IPPROTO_SCTP
934047f369cy		else if (hints->ai_protocol == IPPROTO_SCTP)
935047f369cy			hints->ai_socktype = SOCK_STREAM;
936047f369cy#endif
937047f369cy	}
938047f369cy}
939047f369cy
940047f369cy#if AF_UNSPEC != PF_UNSPEC
941047f369cy#error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC"
942047f369cy#endif
943047f369cy
944047f369cy/** Implements the part of looking up hosts by name that's common to both
945047f369cy * the blocking and nonblocking resolver:
946047f369cy *   - Adjust 'hints' to have a reasonable socktype and protocol.
947047f369cy *   - Look up the port based on 'servname', and store it in *portnum,
948047f369cy *   - Handle the nodename==NULL case
949047f369cy *   - Handle some invalid arguments cases.
950047f369cy *   - Handle the cases where nodename is an IPv4 or IPv6 address.
951047f369cy *
952047f369cy * If we need the resolver to look up the hostname, we return
953047f369cy * EVUTIL_EAI_NEED_RESOLVE.  Otherwise, we can completely implement
954047f369cy * getaddrinfo: we return 0 or an appropriate EVUTIL_EAI_* error, and
955047f369cy * set *res as getaddrinfo would.
956047f369cy */
957047f369cyint
958047f369cyevutil_getaddrinfo_common_(const char *nodename, const char *servname,
959047f369cy    struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
960047f369cy{
961047f369cy	int port = 0;
962047f369cy	const char *pname;
963047f369cy
964047f369cy	if (nodename == NULL && servname == NULL)
965047f369cy		return EVUTIL_EAI_NONAME;
966047f369cy
967047f369cy	/* We only understand 3 families */
968047f369cy	if (hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET &&
969047f369cy	    hints->ai_family != PF_INET6)
970047f369cy		return EVUTIL_EAI_FAMILY;
971047f369cy
972047f369cy	evutil_getaddrinfo_infer_protocols(hints);
973047f369cy
974047f369cy	/* Look up the port number and protocol, if possible. */
975047f369cy	pname = evutil_unparse_protoname(hints->ai_protocol);
976047f369cy	if (servname) {
977047f369cy		/* XXXX We could look at the protocol we got back from
978047f369cy		 * getservbyname, but it doesn't seem too useful. */
979047f369cy		port = evutil_parse_servname(servname, pname, hints);
980047f369cy		if (port < 0) {
981047f369cy			return EVUTIL_EAI_NONAME;
982047f369cy		}
983047f369cy	}
984047f369cy
985047f369cy	/* If we have no node name, then we're supposed to bind to 'any' and
986047f369cy	 * connect to localhost. */
987047f369cy	if (nodename == NULL) {
988047f369cy		struct evutil_addrinfo *res4=NULL, *res6=NULL;
989047f369cy		if (hints->ai_family != PF_INET) { /* INET6 or UNSPEC. */
990047f369cy			struct sockaddr_in6 sin6;
991047f369cy			memset(&sin6, 0, sizeof(sin6));
992047f369cy			sin6.sin6_family = AF_INET6;
993047f369cy			sin6.sin6_port = htons(port);
994047f369cy			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
995047f369cy				/* Bind to :: */
996047f369cy			} else {
997047f369cy				/* connect to ::1 */
998047f369cy				sin6.sin6_addr.s6_addr[15] = 1;
999047f369cy			}
1000047f369cy			res6 = evutil_new_addrinfo_((struct sockaddr*)&sin6,
1001047f369cy			    sizeof(sin6), hints);
1002047f369cy			if (!res6)
1003047f369cy				return EVUTIL_EAI_MEMORY;
1004047f369cy		}
1005047f369cy
1006047f369cy		if (hints->ai_family != PF_INET6) { /* INET or UNSPEC */
1007047f369cy			struct sockaddr_in sin;
1008047f369cy			memset(&sin, 0, sizeof(sin));
1009047f369cy			sin.sin_family = AF_INET;
1010047f369cy			sin.sin_port = htons(port);
1011047f369cy			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
1012047f369cy				/* Bind to 0.0.0.0 */
1013047f369cy			} else {
1014047f369cy				/* connect to 127.0.0.1 */
1015047f369cy				sin.sin_addr.s_addr = htonl(0x7f000001);
1016047f369cy			}
1017047f369cy			res4 = evutil_new_addrinfo_((struct sockaddr*)&sin,
1018047f369cy			    sizeof(sin), hints);
1019047f369cy			if (!res4) {
1020047f369cy				if (res6)
1021047f369cy					evutil_freeaddrinfo(res6);
1022047f369cy				return EVUTIL_EAI_MEMORY;
1023047f369cy			}
1024047f369cy		}
1025047f369cy		*res = evutil_addrinfo_append_(res4, res6);
1026047f369cy		return 0;
1027047f369cy	}
1028047f369cy
1029047f369cy	/* If we can, we should try to parse the hostname without resolving
1030047f369cy	 * it. */
1031047f369cy	/* Try ipv6. */
1032047f369cy	if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
1033047f369cy		struct sockaddr_in6 sin6;
1034047f369cy		memset(&sin6, 0, sizeof(sin6));
1035047f369cy		if (1==evutil_inet_pton(AF_INET6, nodename, &sin6.sin6_addr)) {
1036047f369cy			/* Got an ipv6 address. */
1037047f369cy			sin6.sin6_family = AF_INET6;
1038047f369cy			sin6.sin6_port = htons(port);
1039047f369cy			*res = evutil_new_addrinfo_((struct sockaddr*)&sin6,
1040047f369cy			    sizeof(sin6), hints);
1041047f369cy			if (!*res)
1042047f369cy				return EVUTIL_EAI_MEMORY;
1043047f369cy			return 0;
1044047f369cy		}
1045047f369cy	}
1046047f369cy
1047047f369cy	/* Try ipv4. */
1048047f369cy	if (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC) {
1049047f369cy		struct sockaddr_in sin;
1050047f369cy		memset(&sin, 0, sizeof(sin));
1051047f369cy		if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
1052047f369cy			/* Got an ipv6 address. */
1053047f369cy			sin.sin_family = AF_INET;
1054047f369cy			sin.sin_port = htons(port);
1055047f369cy			*res = evutil_new_addrinfo_((struct sockaddr*)&sin,
1056047f369cy			    sizeof(sin), hints);
1057047f369cy			if (!*res)
1058047f369cy				return EVUTIL_EAI_MEMORY;
1059047f369cy			return 0;
1060047f369cy		}
1061047f369cy	}
1062047f369cy
1063047f369cy
1064047f369cy	/* If we have reached this point, we definitely need to do a DNS
1065047f369cy	 * lookup. */
1066047f369cy	if ((hints->ai_flags & EVUTIL_AI_NUMERICHOST)) {
1067047f369cy		/* If we're not allowed to do one, then say so. */
1068047f369cy		return EVUTIL_EAI_NONAME;
1069047f369cy	}
1070047f369cy	*portnum = port;
1071047f369cy	return EVUTIL_EAI_NEED_RESOLVE;
1072047f369cy}
1073047f369cy
1074047f369cy#ifdef EVENT__HAVE_GETADDRINFO
1075047f369cy#define USE_NATIVE_GETADDRINFO
1076047f369cy#endif
1077047f369cy
1078047f369cy#ifdef USE_NATIVE_GETADDRINFO
1079047f369cy/* A mask of all the flags that we declare, so we can clear them before calling
1080047f369cy * the native getaddrinfo */
1081047f369cystatic const unsigned int ALL_NONNATIVE_AI_FLAGS =
1082047f369cy#ifndef AI_PASSIVE
1083047f369cy    EVUTIL_AI_PASSIVE |
1084047f369cy#endif
1085047f369cy#ifndef AI_CANONNAME
1086047f369cy    EVUTIL_AI_CANONNAME |
1087047f369cy#endif
1088047f369cy#ifndef AI_NUMERICHOST
1089047f369cy    EVUTIL_AI_NUMERICHOST |
1090047f369cy#endif
1091047f369cy#ifndef AI_NUMERICSERV
1092047f369cy    EVUTIL_AI_NUMERICSERV |
1093047f369cy#endif
1094047f369cy#ifndef AI_ADDRCONFIG
1095047f369cy    EVUTIL_AI_ADDRCONFIG |
1096047f369cy#endif
1097047f369cy#ifndef AI_ALL
1098047f369cy    EVUTIL_AI_ALL |
1099047f369cy#endif
1100047f369cy#ifndef AI_V4MAPPED
1101047f369cy    EVUTIL_AI_V4MAPPED |
1102047f369cy#endif
1103047f369cy    EVUTIL_AI_LIBEVENT_ALLOCATED;
1104047f369cy
1105047f369cystatic const unsigned int ALL_NATIVE_AI_FLAGS =
1106047f369cy#ifdef AI_PASSIVE
1107047f369cy    AI_PASSIVE |
1108047f369cy#endif
1109047f369cy#ifdef AI_CANONNAME
1110047f369cy    AI_CANONNAME |
1111047f369cy#endif
1112047f369cy#ifdef AI_NUMERICHOST
1113047f369cy    AI_NUMERICHOST |
1114047f369cy#endif
1115047f369cy#ifdef AI_NUMERICSERV
1116047f369cy    AI_NUMERICSERV |
1117047f369cy#endif
1118047f369cy#ifdef AI_ADDRCONFIG
1119047f369cy    AI_ADDRCONFIG |
1120047f369cy#endif
1121047f369cy#ifdef AI_ALL
1122047f369cy    AI_ALL |
1123047f369cy#endif
1124047f369cy#ifdef AI_V4MAPPED
1125047f369cy    AI_V4MAPPED |
1126047f369cy#endif
1127047f369cy    0;
1128047f369cy#endif
1129047f369cy
1130047f369cy#ifndef USE_NATIVE_GETADDRINFO
1131047f369cy/* Helper for systems with no getaddrinfo(): make one or more addrinfos out of
1132047f369cy * a struct hostent.
1133047f369cy */
1134047f369cystatic struct evutil_addrinfo *
1135047f369cyaddrinfo_from_hostent(const struct hostent *ent,
1136047f369cy    int port, const struct evutil_addrinfo *hints)
1137047f369cy{
1138047f369cy	int i;
1139047f369cy	struct sockaddr_in sin;
1140047f369cy	struct sockaddr_in6 sin6;
1141047f369cy	struct sockaddr *sa;
1142047f369cy	int socklen;
1143047f369cy	struct evutil_addrinfo *res=NULL, *ai;
1144047f369cy	void *addrp;
1145047f369cy
1146047f369cy	if (ent->h_addrtype == PF_INET) {
1147047f369cy		memset(&sin, 0, sizeof(sin));
1148047f369cy		sin.sin_family = AF_INET;
1149047f369cy		sin.sin_port = htons(port);
1150047f369cy		sa = (struct sockaddr *)&sin;
1151047f369cy		socklen = sizeof(struct sockaddr_in);
1152047f369cy		addrp = &sin.sin_addr;
1153047f369cy		if (ent->h_length != sizeof(sin.sin_addr)) {
1154047f369cy			event_warnx("Weird h_length from gethostbyname");
1155047f369cy			return NULL;
1156047f369cy		}
1157047f369cy	} else if (ent->h_addrtype == PF_INET6) {
1158047f369cy		memset(&sin6, 0, sizeof(sin6));
1159047f369cy		sin6.sin6_family = AF_INET6;
1160047f369cy		sin6.sin6_port = htons(port);
1161047f369cy		sa = (struct sockaddr *)&sin6;
1162047f369cy		socklen = sizeof(struct sockaddr_in);
1163047f369cy		addrp = &sin6.sin6_addr;
1164047f369cy		if (ent->h_length != sizeof(sin6.sin6_addr)) {
1165047f369cy			event_warnx("Weird h_length from gethostbyname");
1166047f369cy			return NULL;
1167047f369cy		}
1168047f369cy	} else
1169047f369cy		return NULL;
1170047f369cy
1171047f369cy	for (i = 0; ent->h_addr_list[i]; ++i) {
1172047f369cy		memcpy(addrp, ent->h_addr_list[i], ent->h_length);
1173047f369cy		ai = evutil_new_addrinfo_(sa, socklen, hints);
1174047f369cy		if (!ai) {
1175047f369cy			evutil_freeaddrinfo(res);
1176047f369cy			return NULL;
1177047f369cy		}
1178047f369cy		res = evutil_addrinfo_append_(res, ai);
1179047f369cy	}
1180047f369cy
1181047f369cy	if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) {
1182047f369cy		res->ai_canonname = mm_strdup(ent->h_name);
1183047f369cy		if (res->ai_canonname == NULL) {
1184047f369cy			evutil_freeaddrinfo(res);
1185047f369cy			return NULL;
1186047f369cy		}
1187047f369cy	}
1188047f369cy
1189047f369cy	return res;
1190047f369cy}
1191047f369cy#endif
1192047f369cy
1193047f369cy/* If the EVUTIL_AI_ADDRCONFIG flag is set on hints->ai_flags, and
1194047f369cy * hints->ai_family is PF_UNSPEC, then revise the value of hints->ai_family so
1195047f369cy * that we'll only get addresses we could maybe connect to.
1196047f369cy */
1197047f369cyvoid
1198047f369cyevutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints)
1199047f369cy{
1200047f369cy	if (!(hints->ai_flags & EVUTIL_AI_ADDRCONFIG))
1201047f369cy		return;
1202047f369cy	if (hints->ai_family != PF_UNSPEC)
1203047f369cy		return;
1204047f369cy	if (!have_checked_interfaces)
1205047f369cy		evutil_check_interfaces(0);
1206047f369cy	if (had_ipv4_address && !had_ipv6_address) {
1207047f369cy		hints->ai_family = PF_INET;
1208047f369cy	} else if (!had_ipv4_address && had_ipv6_address) {
1209047f369cy		hints->ai_family = PF_INET6;
1210047f369cy	}
1211047f369cy}
1212047f369cy
1213047f369cy#ifdef USE_NATIVE_GETADDRINFO
1214047f369cystatic int need_numeric_port_hack_=0;
1215047f369cystatic int need_socktype_protocol_hack_=0;
1216047f369cystatic int tested_for_getaddrinfo_hacks=0;
1217047f369cy
1218047f369cy/* Some older BSDs (like OpenBSD up to 4.6) used to believe that
1219047f369cy   giving a numeric port without giving an ai_socktype was verboten.
1220047f369cy   We test for this so we can apply an appropriate workaround.  If it
1221047f369cy   turns out that the bug is present, then:
1222047f369cy
1223047f369cy    - If nodename==NULL and servname is numeric, we build an answer
1224047f369cy      ourselves using evutil_getaddrinfo_common_().
1225047f369cy
1226047f369cy    - If nodename!=NULL and servname is numeric, then we set
1227047f369cy      servname=NULL when calling getaddrinfo, and post-process the
1228047f369cy      result to set the ports on it.
1229047f369cy
1230047f369cy   We test for this bug at runtime, since otherwise we can't have the
1231047f369cy   same binary run on multiple BSD versions.
1232047f369cy
1233047f369cy   - Some versions of Solaris believe that it's nice to leave to protocol
1234047f369cy     field set to 0.  We test for this so we can apply an appropriate
1235047f369cy     workaround.
1236047f369cy*/
1237047f369cystatic void
1238047f369cytest_for_getaddrinfo_hacks(void)
1239047f369cy{
1240047f369cy	int r, r2;
1241047f369cy	struct evutil_addrinfo *ai=NULL, *ai2=NULL;
1242047f369cy	struct evutil_addrinfo hints;
1243047f369cy
1244047f369cy	memset(&hints,0,sizeof(hints));
1245047f369cy	hints.ai_family = PF_UNSPEC;
1246047f369cy	hints.ai_flags =
1247047f369cy#ifdef AI_NUMERICHOST
1248047f369cy	    AI_NUMERICHOST |
1249047f369cy#endif
1250047f369cy#ifdef AI_NUMERICSERV
1251047f369cy	    AI_NUMERICSERV |
1252047f369cy#endif
1253047f369cy	    0;
1254047f369cy	r = getaddrinfo("1.2.3.4", "80", &hints, &ai);
1255047f369cy	hints.ai_socktype = SOCK_STREAM;
1256047f369cy	r2 = getaddrinfo("1.2.3.4", "80", &hints, &ai2);
1257047f369cy	if (r2 == 0 && r != 0) {
1258047f369cy		need_numeric_port_hack_=1;
1259047f369cy	}
1260047f369cy	if (ai2 && ai2->ai_protocol == 0) {
1261047f369cy		need_socktype_protocol_hack_=1;
1262047f369cy	}
1263047f369cy
1264047f369cy	if (ai)
1265047f369cy		freeaddrinfo(ai);
1266047f369cy	if (ai2)
1267047f369cy		freeaddrinfo(ai2);
1268047f369cy	tested_for_getaddrinfo_hacks=1;
1269047f369cy}
1270047f369cy
1271047f369cystatic inline int
1272047f369cyneed_numeric_port_hack(void)
1273047f369cy{
1274047f369cy	if (!tested_for_getaddrinfo_hacks)
1275047f369cy		test_for_getaddrinfo_hacks();
1276047f369cy	return need_numeric_port_hack_;
1277047f369cy}
1278047f369cy
1279047f369cystatic inline int
1280047f369cyneed_socktype_protocol_hack(void)
1281047f369cy{
1282047f369cy	if (!tested_for_getaddrinfo_hacks)
1283047f369cy		test_for_getaddrinfo_hacks();
1284047f369cy	return need_socktype_protocol_hack_;
1285047f369cy}
1286047f369cy
1287047f369cystatic void
1288047f369cyapply_numeric_port_hack(int port, struct evutil_addrinfo **ai)
1289047f369cy{
1290047f369cy	/* Now we run through the list and set the ports on all of the
1291047f369cy	 * results where ports would make sense. */
1292047f369cy	for ( ; *ai; ai = &(*ai)->ai_next) {
1293047f369cy		struct sockaddr *sa = (*ai)->ai_addr;
1294047f369cy		if (sa && sa->sa_family == AF_INET) {
1295047f369cy			struct sockaddr_in *sin = (struct sockaddr_in*)sa;
1296047f369cy			sin->sin_port = htons(port);
1297047f369cy		} else if (sa && sa->sa_family == AF_INET6) {
1298047f369cy			struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
1299047f369cy			sin6->sin6_port = htons(port);
1300047f369cy		} else {
1301047f369cy			/* A numeric port makes no sense here; remove this one
1302047f369cy			 * from the list. */
1303047f369cy			struct evutil_addrinfo *victim = *ai;
1304047f369cy			*ai = victim->ai_next;
1305047f369cy			victim->ai_next = NULL;
1306047f369cy			freeaddrinfo(victim);
1307047f369cy		}
1308047f369cy	}
1309047f369cy}
1310047f369cy
1311047f369cystatic int
1312047f369cyapply_socktype_protocol_hack(struct evutil_addrinfo *ai)
1313047f369cy{
1314047f369cy	struct evutil_addrinfo *ai_new;
1315047f369cy	for (; ai; ai = ai->ai_next) {
1316047f369cy		evutil_getaddrinfo_infer_protocols(ai);
1317047f369cy		if (ai->ai_socktype || ai->ai_protocol)
1318047f369cy			continue;
1319047f369cy		ai_new = mm_malloc(sizeof(*ai_new));
1320047f369cy		if (!ai_new)
1321047f369cy			return -1;
1322047f369cy		memcpy(ai_new, ai, sizeof(*ai_new));
1323047f369cy		ai->ai_socktype = SOCK_STREAM;
1324047f369cy		ai->ai_protocol = IPPROTO_TCP;
1325047f369cy		ai_new->ai_socktype = SOCK_DGRAM;
1326047f369cy		ai_new->ai_protocol = IPPROTO_UDP;
1327047f369cy
1328047f369cy		ai_new->ai_next = ai->ai_next;
1329047f369cy		ai->ai_next = ai_new;
1330047f369cy	}
1331047f369cy	return 0;
1332047f369cy}
1333047f369cy#endif
1334047f369cy
1335047f369cyint
1336047f369cyevutil_getaddrinfo(const char *nodename, const char *servname,
1337047f369cy    const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res)
1338047f369cy{
1339047f369cy#ifdef USE_NATIVE_GETADDRINFO
1340047f369cy	struct evutil_addrinfo hints;
1341047f369cy	int portnum=-1, need_np_hack, err;
1342047f369cy
1343047f369cy	if (hints_in) {
1344047f369cy		memcpy(&hints, hints_in, sizeof(hints));
1345047f369cy	} else {
1346047f369cy		memset(&hints, 0, sizeof(hints));
1347047f369cy		hints.ai_family = PF_UNSPEC;
1348047f369cy	}
1349047f369cy
1350047f369cy#ifndef AI_ADDRCONFIG
1351047f369cy	/* Not every system has AI_ADDRCONFIG, so fake it. */
1352047f369cy	if (hints.ai_family == PF_UNSPEC &&
1353047f369cy	    (hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
1354047f369cy		evutil_adjust_hints_for_addrconfig_(&hints);
1355047f369cy	}
1356047f369cy#endif
1357047f369cy
1358047f369cy#ifndef AI_NUMERICSERV
1359047f369cy	/* Not every system has AI_NUMERICSERV, so fake it. */
1360047f369cy	if (hints.ai_flags & EVUTIL_AI_NUMERICSERV) {
1361047f369cy		if (servname && parse_numeric_servname(servname)<0)
1362047f369cy			return EVUTIL_EAI_NONAME;
1363047f369cy	}
1364047f369cy#endif
1365047f369cy
1366047f369cy	/* Enough operating systems handle enough common non-resolve
1367047f369cy	 * cases here weirdly enough that we are better off just
1368047f369cy	 * overriding them.  For example:
1369047f369cy	 *
1370047f369cy	 * - Windows doesn't like to infer the protocol from the
1371047f369cy	 *   socket type, or fill in socket or protocol types much at
1372047f369cy	 *   all.  It also seems to do its own broken implicit
1373047f369cy	 *   always-on version of AI_ADDRCONFIG that keeps it from
1374047f369cy	 *   ever resolving even a literal IPv6 address when
1375047f369cy	 *   ai_addrtype is PF_UNSPEC.
1376047f369cy	 */
1377047f369cy#ifdef _WIN32
1378047f369cy	{
1379047f369cy		int tmp_port;
1380047f369cy		err = evutil_getaddrinfo_common_(nodename,servname,&hints,
1381047f369cy		    res, &tmp_port);
1382047f369cy		if (err == 0 ||
1383047f369cy		    err == EVUTIL_EAI_MEMORY ||
1384047f369cy		    err == EVUTIL_EAI_NONAME)
1385047f369cy			return err;
1386047f369cy		/* If we make it here, the system getaddrinfo can
1387047f369cy		 * have a crack at it. */
1388047f369cy	}
1389047f369cy#endif
1390047f369cy
1391047f369cy	/* See documentation for need_numeric_port_hack above.*/
1392047f369cy	need_np_hack = need_numeric_port_hack() && servname && !hints.ai_socktype
1393047f369cy	    && ((portnum=parse_numeric_servname(servname)) >= 0);
1394047f369cy	if (need_np_hack) {
1395047f369cy		if (!nodename)
1396047f369cy			return evutil_getaddrinfo_common_(
1397047f369cy				NULL,servname,&hints, res, &portnum);
1398047f369cy		servname = NULL;
1399047f369cy	}
1400047f369cy
1401047f369cy	if (need_socktype_protocol_hack()) {
1402047f369cy		evutil_getaddrinfo_infer_protocols(&hints);
1403047f369cy	}
1404047f369cy
1405047f369cy	/* Make sure that we didn't actually steal any AI_FLAGS values that
1406047f369cy	 * the system is using.  (This is a constant expression, and should ge
1407047f369cy	 * optimized out.)
1408047f369cy	 *
1409047f369cy	 * XXXX Turn this into a compile-time failure rather than a run-time
1410047f369cy	 * failure.
1411047f369cy	 */
1412047f369cy	EVUTIL_ASSERT((ALL_NONNATIVE_AI_FLAGS & ALL_NATIVE_AI_FLAGS) == 0);
1413047f369cy
1414047f369cy	/* Clear any flags that only libevent understands. */
1415047f369cy	hints.ai_flags &= ~ALL_NONNATIVE_AI_FLAGS;
1416047f369cy
1417047f369cy	err = getaddrinfo(nodename, servname, &hints, res);
1418047f369cy	if (need_np_hack)
1419047f369cy		apply_numeric_port_hack(portnum, res);
1420047f369cy
1421047f369cy	if (need_socktype_protocol_hack()) {
1422047f369cy		if (apply_socktype_protocol_hack(*res) < 0) {
1423047f369cy			evutil_freeaddrinfo(*res);
1424047f369cy			*res = NULL;
1425047f369cy			return EVUTIL_EAI_MEMORY;
1426047f369cy		}
1427047f369cy	}
1428047f369cy	return err;
1429047f369cy#else
1430047f369cy	int port=0, err;
1431047f369cy	struct hostent *ent = NULL;
1432047f369cy	struct evutil_addrinfo hints;
1433047f369cy
1434047f369cy	if (hints_in) {
1435047f369cy		memcpy(&hints, hints_in, sizeof(hints));
1436047f369cy	} else {
1437047f369cy		memset(&hints, 0, sizeof(hints));
1438047f369cy		hints.ai_family = PF_UNSPEC;
1439047f369cy	}
1440047f369cy
1441047f369cy	evutil_adjust_hints_for_addrconfig_(&hints);
1442047f369cy
1443047f369cy	err = evutil_getaddrinfo_common_(nodename, servname, &hints, res, &port);
1444047f369cy	if (err != EVUTIL_EAI_NEED_RESOLVE) {
1445047f369cy		/* We either succeeded or failed.  No need to continue */
1446047f369cy		return err;
1447047f369cy	}
1448047f369cy
1449047f369cy	err = 0;
1450047f369cy	/* Use any of the various gethostbyname_r variants as available. */
1451047f369cy	{
1452047f369cy#ifdef EVENT__HAVE_GETHOSTBYNAME_R_6_ARG
1453047f369cy		/* This one is what glibc provides. */
1454047f369cy		char buf[2048];
1455047f369cy		struct hostent hostent;
1456047f369cy		int r;
1457047f369cy		r = gethostbyname_r(nodename, &hostent, buf, sizeof(buf), &ent,
1458047f369cy		    &err);
1459047f369cy#elif defined(EVENT__HAVE_GETHOSTBYNAME_R_5_ARG)
1460047f369cy		char buf[2048];
1461047f369cy		struct hostent hostent;
1462047f369cy		ent = gethostbyname_r(nodename, &hostent, buf, sizeof(buf),
1463047f369cy		    &err);
1464047f369cy#elif defined(EVENT__HAVE_GETHOSTBYNAME_R_3_ARG)
1465047f369cy		struct hostent_data data;
1466047f369cy		struct hostent hostent;
1467047f369cy		memset(&data, 0, sizeof(data));
1468047f369cy		err = gethostbyname_r(nodename, &hostent, &data);
1469047f369cy		ent = err ? NULL : &hostent;
1470047f369cy#else
1471047f369cy		/* fall back to gethostbyname. */
1472047f369cy		/* XXXX This needs a lock everywhere but Windows. */
1473047f369cy		ent = gethostbyname(nodename);
1474047f369cy#ifdef _WIN32
1475047f369cy		err = WSAGetLastError();
1476047f369cy#else
1477047f369cy		err = h_errno;
1478047f369cy#endif
1479047f369cy#endif
1480047f369cy
1481047f369cy		/* Now we have either ent or err set. */
1482047f369cy		if (!ent) {
1483047f369cy			/* XXX is this right for windows ? */
1484047f369cy			switch (err) {
1485047f369cy			case TRY_AGAIN:
1486047f369cy				return EVUTIL_EAI_AGAIN;
1487047f369cy			case NO_RECOVERY:
1488047f369cy			default:
1489047f369cy				return EVUTIL_EAI_FAIL;
1490047f369cy			case HOST_NOT_FOUND:
1491047f369cy				return EVUTIL_EAI_NONAME;
1492047f369cy			case NO_ADDRESS:
1493047f369cy#if NO_DATA != NO_ADDRESS
1494047f369cy			case NO_DATA:
1495047f369cy#endif
1496047f369cy				return EVUTIL_EAI_NODATA;
1497047f369cy			}
1498047f369cy		}
1499047f369cy
1500047f369cy		if (ent->h_addrtype != hints.ai_family &&
1501047f369cy		    hints.ai_family != PF_UNSPEC) {
1502047f369cy			/* This wasn't the type we were hoping for.  Too bad
1503047f369cy			 * we never had a chance to ask gethostbyname for what
1504047f369cy			 * we wanted. */
1505047f369cy			return EVUTIL_EAI_NONAME;
1506047f369cy		}
1507047f369cy
1508047f369cy		/* Make sure we got _some_ answers. */
1509047f369cy		if (ent->h_length == 0)
1510047f369cy			return EVUTIL_EAI_NODATA;
1511047f369cy
1512047f369cy		/* If we got an address type we don't know how to make a
1513047f369cy		   sockaddr for, give up. */
1514047f369cy		if (ent->h_addrtype != PF_INET && ent->h_addrtype != PF_INET6)
1515047f369cy			return EVUTIL_EAI_FAMILY;
1516047f369cy
1517047f369cy		*res = addrinfo_from_hostent(ent, port, &hints);
1518047f369cy		if (! *res)
1519047f369cy			return EVUTIL_EAI_MEMORY;
1520047f369cy	}
1521047f369cy
1522047f369cy	return 0;
1523047f369cy#endif
1524047f369cy}
1525047f369cy
1526047f369cyvoid
1527047f369cyevutil_freeaddrinfo(struct evutil_addrinfo *ai)
1528047f369cy{
1529047f369cy#ifdef EVENT__HAVE_GETADDRINFO
1530047f369cy	if (!(ai->ai_flags & EVUTIL_AI_LIBEVENT_ALLOCATED)) {
1531047f369cy		freeaddrinfo(ai);
1532047f369cy		return;
1533047f369cy	}
1534047f369cy#endif
1535047f369cy	while (ai) {
1536047f369cy		struct evutil_addrinfo *next = ai->ai_next;
1537047f369cy		if (ai->ai_canonname)
1538047f369cy			mm_free(ai->ai_canonname);
1539047f369cy		mm_free(ai);
1540047f369cy		ai = next;
1541047f369cy	}
1542047f369cy}
1543047f369cy
1544047f369cystatic evdns_getaddrinfo_fn evdns_getaddrinfo_impl = NULL;
1545047f369cy
1546047f369cyvoid
1547047f369cyevutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn)
1548047f369cy{
1549047f369cy	if (!evdns_getaddrinfo_impl)
1550047f369cy		evdns_getaddrinfo_impl = fn;
1551047f369cy}
1552047f369cy
1553047f369cy/* Internal helper function: act like evdns_getaddrinfo if dns_base is set;
1554047f369cy * otherwise do a blocking resolve and pass the result to the callback in the
1555047f369cy * way that evdns_getaddrinfo would.
1556047f369cy */
1557047f369cyint
1558047f369cyevutil_getaddrinfo_async_(struct evdns_base *dns_base,
1559047f369cy    const char *nodename, const char *servname,
1560047f369cy    const struct evutil_addrinfo *hints_in,
1561047f369cy    void (*cb)(int, struct evutil_addrinfo *, void *), void *arg)
1562047f369cy{
1563047f369cy	if (dns_base && evdns_getaddrinfo_impl) {
1564047f369cy		evdns_getaddrinfo_impl(
1565047f369cy			dns_base, nodename, servname, hints_in, cb, arg);
1566047f369cy	} else {
1567047f369cy		struct evutil_addrinfo *ai=NULL;
1568047f369cy		int err;
1569047f369cy		err = evutil_getaddrinfo(nodename, servname, hints_in, &ai);
1570047f369cy		cb(err, ai, arg);
1571047f369cy	}
1572047f369cy	return 0;
1573047f369cy}
1574047f369cy
1575047f369cyconst char *
1576047f369cyevutil_gai_strerror(int err)
1577047f369cy{
1578047f369cy	/* As a sneaky side-benefit, this case statement will get most
1579047f369cy	 * compilers to tell us if any of the error codes we defined
1580047f369cy	 * conflict with the platform's native error codes. */
1581047f369cy	switch (err) {
1582047f369cy	case EVUTIL_EAI_CANCEL:
1583047f369cy		return "Request canceled";
1584047f369cy	case 0:
1585047f369cy		return "No error";
1586047f369cy
1587047f369cy	case EVUTIL_EAI_ADDRFAMILY:
1588047f369cy		return "address family for nodename not supported";
1589047f369cy	case EVUTIL_EAI_AGAIN:
1590047f369cy		return "temporary failure in name resolution";
1591047f369cy	case EVUTIL_EAI_BADFLAGS:
1592047f369cy		return "invalid value for ai_flags";
1593047f369cy	case EVUTIL_EAI_FAIL:
1594047f369cy		return "non-recoverable failure in name resolution";
1595047f369cy	case EVUTIL_EAI_FAMILY:
1596047f369cy		return "ai_family not supported";
1597047f369cy	case EVUTIL_EAI_MEMORY:
1598047f369cy		return "memory allocation failure";
1599047f369cy	case EVUTIL_EAI_NODATA:
1600047f369cy		return "no address associated with nodename";
1601047f369cy	case EVUTIL_EAI_NONAME:
1602047f369cy		return "nodename nor servname provided, or not known";
1603047f369cy	case EVUTIL_EAI_SERVICE:
1604047f369cy		return "servname not supported for ai_socktype";
1605047f369cy	case EVUTIL_EAI_SOCKTYPE:
1606047f369cy		return "ai_socktype not supported";
1607047f369cy	case EVUTIL_EAI_SYSTEM:
1608047f369cy		return "system error";
1609047f369cy	default:
1610047f369cy#if defined(USE_NATIVE_GETADDRINFO) && defined(_WIN32)
1611047f369cy		return gai_strerrorA(err);
1612047f369cy#elif defined(USE_NATIVE_GETADDRINFO)
1613047f369cy		return gai_strerror(err);
1614047f369cy#else
1615047f369cy		return "Unknown error code";
1616047f369cy#endif
1617047f369cy	}
1618047f369cy}
1619047f369cy
1620047f369cy#ifdef _WIN32
1621047f369cy/* destructively remove a trailing line terminator from s */
1622047f369cystatic void
1623047f369cychomp (char *s)
1624047f369cy{
1625047f369cy	size_t len;
1626047f369cy	if (s && (len = strlen (s)) > 0 && s[len - 1] == '\n') {
1627047f369cy		s[--len] = 0;
1628047f369cy		if (len > 0 && s[len - 1] == '\r')
1629047f369cy			s[--len] = 0;
1630047f369cy	}
1631047f369cy}
1632047f369cy
1633047f369cy/* FormatMessage returns allocated strings, but evutil_socket_error_to_string
1634047f369cy * is supposed to return a string which is good indefinitely without having
1635047f369cy * to be freed.  To make this work without leaking memory, we cache the
1636047f369cy * string the first time FormatMessage is called on a particular error
1637047f369cy * code, and then return the cached string on subsequent calls with the
1638047f369cy * same code.  The strings aren't freed until libevent_global_shutdown
1639047f369cy * (or never).  We use a linked list to cache the errors, because we
1640047f369cy * only expect there to be a few dozen, and that should be fast enough.
1641047f369cy */
1642047f369cy
1643047f369cystruct cached_sock_errs_entry {
1644047f369cy	HT_ENTRY(cached_sock_errs_entry) node;
1645047f369cy	DWORD code;
1646047f369cy	char *msg; /* allocated with LocalAlloc; free with LocalFree */
1647047f369cy};
1648047f369cy
1649047f369cystatic inline unsigned
1650047f369cyhash_cached_sock_errs(const struct cached_sock_errs_entry *e)
1651047f369cy{
1652047f369cy	/* Use Murmur3's 32-bit finalizer as an integer hash function */
1653047f369cy	DWORD h = e->code;
1654047f369cy	h ^= h >> 16;
1655047f369cy	h *= 0x85ebca6b;
1656047f369cy	h ^= h >> 13;
1657047f369cy	h *= 0xc2b2ae35;
1658047f369cy	h ^= h >> 16;
1659047f369cy	return h;
1660047f369cy}
1661047f369cy
1662047f369cystatic inline int
1663047f369cyeq_cached_sock_errs(const struct cached_sock_errs_entry *a,
1664047f369cy		    const struct cached_sock_errs_entry *b)
1665047f369cy{
1666047f369cy	return a->code == b->code;
1667047f369cy}
1668047f369cy
1669047f369cy#ifndef EVENT__DISABLE_THREAD_SUPPORT
1670047f369cystatic void *windows_socket_errors_lock_ = NULL;
1671047f369cy#endif
1672047f369cy
1673047f369cystatic HT_HEAD(cached_sock_errs_map, cached_sock_errs_entry)
1674047f369cy     windows_socket_errors = HT_INITIALIZER();
1675047f369cy
1676047f369cyHT_PROTOTYPE(cached_sock_errs_map,
1677047f369cy	     cached_sock_errs_entry,
1678047f369cy	     node,
1679047f369cy	     hash_cached_sock_errs,
1680047f369cy	     eq_cached_sock_errs);
1681047f369cy
1682047f369cyHT_GENERATE(cached_sock_errs_map,
1683047f369cy	    cached_sock_errs_entry,
1684047f369cy	    node,
1685047f369cy	    hash_cached_sock_errs,
1686047f369cy	    eq_cached_sock_errs,
1687047f369cy	    0.5,
1688047f369cy	    mm_malloc,
1689047f369cy	    mm_realloc,
1690047f369cy	    mm_free);
1691047f369cy
1692047f369cy/** Equivalent to strerror, but for windows socket errors. */
1693047f369cyconst char *
1694047f369cyevutil_socket_error_to_string(int errcode)
1695047f369cy{
1696047f369cy	struct cached_sock_errs_entry *errs, *newerr, find;
1697047f369cy	char *msg = NULL;
1698047f369cy
1699047f369cy	EVLOCK_LOCK(windows_socket_errors_lock_, 0);
1700047f369cy
1701047f369cy	find.code = errcode;
1702047f369cy	errs = HT_FIND(cached_sock_errs_map, &windows_socket_errors, &find);
1703047f369cy	if (errs) {
1704047f369cy		msg = errs->msg;
1705047f369cy		goto done;
1706047f369cy	}
1707047f369cy
1708047f369cy	if (0 != FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
1709047f369cy			       FORMAT_MESSAGE_IGNORE_INSERTS |
1710047f369cy			       FORMAT_MESSAGE_ALLOCATE_BUFFER,
1711047f369cy			       NULL, errcode, 0, (LPTSTR)&msg, 0, NULL))
1712047f369cy		chomp (msg);	/* because message has trailing newline */
1713047f369cy	else {
1714047f369cy		size_t len = 50;
1715047f369cy		/* use LocalAlloc because FormatMessage does */
1716047f369cy		msg = LocalAlloc(LMEM_FIXED, len);
1717047f369cy		if (!msg) {
1718047f369cy			msg = (char *)"LocalAlloc failed during Winsock error";
1719047f369cy			goto done;
1720047f369cy		}
1721047f369cy		evutil_snprintf(msg, len, "winsock error 0x%08x", errcode);
1722047f369cy	}
1723047f369cy
1724047f369cy	newerr = (struct cached_sock_errs_entry *)
1725047f369cy		mm_malloc(sizeof (struct cached_sock_errs_entry));
1726047f369cy
1727047f369cy	if (!newerr) {
1728047f369cy		LocalFree(msg);
1729047f369cy		msg = (char *)"malloc failed during Winsock error";
1730047f369cy		goto done;
1731047f369cy	}
1732047f369cy
1733047f369cy	newerr->code = errcode;
1734047f369cy	newerr->msg = msg;
1735047f369cy	HT_INSERT(cached_sock_errs_map, &windows_socket_errors, newerr);
1736047f369cy
1737047f369cy done:
1738047f369cy	EVLOCK_UNLOCK(windows_socket_errors_lock_, 0);
1739047f369cy
1740047f369cy	return msg;
1741047f369cy}
1742047f369cy
1743047f369cy#ifndef EVENT__DISABLE_THREAD_SUPPORT
1744047f369cyint
1745047f369cyevutil_global_setup_locks_(const int enable_locks)
1746047f369cy{
1747047f369cy	EVTHREAD_SETUP_GLOBAL_LOCK(windows_socket_errors_lock_, 0);
1748047f369cy	return 0;
1749047f369cy}
1750047f369cy#endif
1751047f369cy
1752047f369cystatic void
1753047f369cyevutil_free_sock_err_globals(void)
1754047f369cy{
1755047f369cy	struct cached_sock_errs_entry **errs, *tofree;
1756047f369cy
1757047f369cy	for (errs = HT_START(cached_sock_errs_map, &windows_socket_errors)
1758047f369cy		     ; errs; ) {
1759047f369cy		tofree = *errs;
1760047f369cy		errs = HT_NEXT_RMV(cached_sock_errs_map,
1761047f369cy				   &windows_socket_errors,
1762047f369cy				   errs);
1763047f369cy		LocalFree(tofree->msg);
1764047f369cy		mm_free(tofree);
1765047f369cy	}
1766047f369cy
1767047f369cy	HT_CLEAR(cached_sock_errs_map, &windows_socket_errors);
1768047f369cy
1769047f369cy#ifndef EVENT__DISABLE_THREAD_SUPPORT
1770047f369cy	if (windows_socket_errors_lock_ != NULL) {
1771047f369cy		EVTHREAD_FREE_LOCK(windows_socket_errors_lock_, 0);
1772047f369cy		windows_socket_errors_lock_ = NULL;
1773047f369cy	}
1774047f369cy#endif
1775047f369cy}
1776047f369cy
1777047f369cy#else
1778047f369cy
1779047f369cy#ifndef EVENT__DISABLE_THREAD_SUPPORT
1780047f369cyint
1781047f369cyevutil_global_setup_locks_(const int enable_locks)
1782047f369cy{
1783047f369cy	return 0;
1784047f369cy}
1785047f369cy#endif
1786047f369cy
1787047f369cystatic void
1788047f369cyevutil_free_sock_err_globals(void)
1789047f369cy{
1790047f369cy}
1791047f369cy
1792047f369cy#endif
1793047f369cy
1794047f369cyint
1795047f369cyevutil_snprintf(char *buf, size_t buflen, const char *format, ...)
1796047f369cy{
1797047f369cy	int r;
1798047f369cy	va_list ap;
1799047f369cy	va_start(ap, format);
1800047f369cy	r = evutil_vsnprintf(buf, buflen, format, ap);
1801047f369cy	va_end(ap);
1802047f369cy	return r;
1803047f369cy}
1804047f369cy
1805047f369cyint
1806047f369cyevutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
1807047f369cy{
1808047f369cy	int r;
1809047f369cy	if (!buflen)
1810047f369cy		return 0;
1811047f369cy#if defined(_MSC_VER) || defined(_WIN32)
1812047f369cy	r = _vsnprintf(buf, buflen, format, ap);
1813047f369cy	if (r < 0)
1814047f369cy		r = _vscprintf(format, ap);
1815047f369cy#elif defined(sgi)
1816047f369cy	/* Make sure we always use the correct vsnprintf on IRIX */
1817047f369cy	extern int      _xpg5_vsnprintf(char * __restrict,
1818047f369cy		__SGI_LIBC_NAMESPACE_QUALIFIER size_t,
1819047f369cy		const char * __restrict, /* va_list */ char *);
1820047f369cy
1821047f369cy	r = _xpg5_vsnprintf(buf, buflen, format, ap);
1822047f369cy#else
1823047f369cy	r = vsnprintf(buf, buflen, format, ap);
1824047f369cy#endif
1825047f369cy	buf[buflen-1] = '\0';
1826047f369cy	return r;
1827047f369cy}
1828047f369cy
1829047f369cy#define USE_INTERNAL_NTOP
1830047f369cy#define USE_INTERNAL_PTON
1831047f369cy
1832047f369cyconst char *
1833047f369cyevutil_inet_ntop(int af, const void *src, char *dst, size_t len)
1834047f369cy{
1835047f369cy#if defined(EVENT__HAVE_INET_NTOP) && !defined(USE_INTERNAL_NTOP)
1836047f369cy	return inet_ntop(af, src, dst, len);
1837047f369cy#else
1838047f369cy	if (af == AF_INET) {
1839047f369cy		const struct in_addr *in = src;
1840047f369cy		const ev_uint32_t a = ntohl(in->s_addr);
1841047f369cy		int r;
1842047f369cy		r = evutil_snprintf(dst, len, "%d.%d.%d.%d",
1843047f369cy		    (int)(ev_uint8_t)((a>>24)&0xff),
1844047f369cy		    (int)(ev_uint8_t)((a>>16)&0xff),
1845047f369cy		    (int)(ev_uint8_t)((a>>8 )&0xff),
1846047f369cy		    (int)(ev_uint8_t)((a    )&0xff));
1847047f369cy		if (r<0||(size_t)r>=len)
1848047f369cy			return NULL;
1849047f369cy		else
1850047f369cy			return dst;
1851047f369cy#ifdef AF_INET6
1852047f369cy	} else if (af == AF_INET6) {
1853047f369cy		const struct in6_addr *addr = src;
1854047f369cy		char buf[64], *cp;
1855047f369cy		int longestGapLen = 0, longestGapPos = -1, i,
1856047f369cy			curGapPos = -1, curGapLen = 0;
1857047f369cy		ev_uint16_t words[8];
1858047f369cy		for (i = 0; i < 8; ++i) {
1859047f369cy			words[i] =
1860047f369cy			    (((ev_uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
1861047f369cy		}
1862047f369cy		if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
1863047f369cy		    words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
1864047f369cy			(words[5] == 0xffff))) {
1865047f369cy			/* This is an IPv4 address. */
1866047f369cy			if (words[5] == 0) {
1867047f369cy				evutil_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
1868047f369cy				    addr->s6_addr[12], addr->s6_addr[13],
1869047f369cy				    addr->s6_addr[14], addr->s6_addr[15]);
1870047f369cy			} else {
1871047f369cy				evutil_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
1872047f369cy				    addr->s6_addr[12], addr->s6_addr[13],
1873047f369cy				    addr->s6_addr[14], addr->s6_addr[15]);
1874047f369cy			}
1875047f369cy			if (strlen(buf) > len)
1876047f369cy				return NULL;
1877047f369cy			strlcpy(dst, buf, len);
1878047f369cy			return dst;
1879047f369cy		}
1880047f369cy		i = 0;
1881047f369cy		while (i < 8) {
1882047f369cy			if (words[i] == 0) {
1883047f369cy				curGapPos = i++;
1884047f369cy				curGapLen = 1;
1885047f369cy				while (i<8 && words[i] == 0) {
1886047f369cy					++i; ++curGapLen;
1887047f369cy				}
1888047f369cy				if (curGapLen > longestGapLen) {
1889047f369cy					longestGapPos = curGapPos;
1890047f369cy					longestGapLen = curGapLen;
1891047f369cy				}
1892047f369cy			} else {
1893047f369cy				++i;
1894047f369cy			}
1895047f369cy		}
1896047f369cy		if (longestGapLen<=1)
1897047f369cy			longestGapPos = -1;
1898047f369cy
1899047f369cy		cp = buf;
1900047f369cy		for (i = 0; i < 8; ++i) {
1901047f369cy			if (words[i] == 0 && longestGapPos == i) {
1902047f369cy				if (i == 0)
1903047f369cy					*cp++ = ':';
1904047f369cy				*cp++ = ':';
1905047f369cy				while (i < 8 && words[i] == 0)
1906047f369cy					++i;
1907047f369cy				--i; /* to compensate for loop increment. */
1908047f369cy			} else {
1909047f369cy				evutil_snprintf(cp,
1910047f369cy								sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
1911047f369cy				cp += strlen(cp);
1912047f369cy				if (i != 7)
1913047f369cy					*cp++ = ':';
1914047f369cy			}
1915047f369cy		}
1916047f369cy		*cp = '\0';
1917047f369cy		if (strlen(buf) > len)
1918047f369cy			return NULL;
1919047f369cy		strlcpy(dst, buf, len);
1920047f369cy		return dst;
1921047f369cy#endif
1922047f369cy	} else {
1923047f369cy		return NULL;
1924047f369cy	}
1925047f369cy#endif
1926047f369cy}
1927047f369cy
1928047f369cyint
1929047f369cyevutil_inet_pton(int af, const char *src, void *dst)
1930047f369cy{
1931047f369cy#if defined(EVENT__HAVE_INET_PTON) && !defined(USE_INTERNAL_PTON)
1932047f369cy	return inet_pton(af, src, dst);
1933047f369cy#else
1934047f369cy	if (af == AF_INET) {
1935f63afe2cy		unsigned a,b,c,d;
1936047f369cy		char more;
1937047f369cy		struct in_addr *addr = dst;
1938f63afe2cy		if (sscanf(src, "%u.%u.%u.%u%c", &a,&b,&c,&d,&more) != 4)
1939047f369cy			return 0;
1940f63afe2cy		if (a > 255) return 0;
1941f63afe2cy		if (b > 255) return 0;
1942f63afe2cy		if (c > 255) return 0;
1943f63afe2cy		if (d > 255) return 0;
1944047f369cy		addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
1945047f369cy		return 1;
1946047f369cy#ifdef AF_INET6
1947047f369cy	} else if (af == AF_INET6) {
1948047f369cy		struct in6_addr *out = dst;
1949047f369cy		ev_uint16_t words[8];
1950047f369cy		int gapPos = -1, i, setWords=0;
1951047f369cy		const char *dot = strchr(src, '.');
1952047f369cy		const char *eow; /* end of words. */
1953047f369cy		if (dot == src)
1954047f369cy			return 0;
1955047f369cy		else if (!dot)
1956047f369cy			eow = src+strlen(src);
1957047f369cy		else {
1958f63afe2cy			unsigned byte1,byte2,byte3,byte4;
1959047f369cy			char more;
1960047f369cy			for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT_(*eow); --eow)
1961047f369cy				;
1962047f369cy			++eow;
1963047f369cy
1964047f369cy			/* We use "scanf" because some platform inet_aton()s are too lax
1965047f369cy			 * about IPv4 addresses of the form "1.2.3" */
1966f63afe2cy			if (sscanf(eow, "%u.%u.%u.%u%c",
1967047f369cy					   &byte1,&byte2,&byte3,&byte4,&more) != 4)
1968047f369cy				return 0;
1969047f369cy
1970f63afe2cy			if (byte1 > 255 ||
1971f63afe2cy			    byte2 > 255 ||
1972f63afe2cy			    byte3 > 255 ||
1973f63afe2cy			    byte4 > 255)
1974047f369cy				return 0;
1975047f369cy
1976047f369cy			words[6] = (byte1<<8) | byte2;
1977047f369cy			words[7] = (byte3<<8) | byte4;
1978047f369cy			setWords += 2;
1979047f369cy		}
1980047f369cy
1981047f369cy		i = 0;
1982047f369cy		while (src < eow) {
1983047f369cy			if (i > 7)
1984047f369cy				return 0;
1985047f369cy			if (EVUTIL_ISXDIGIT_(*src)) {
1986047f369cy				char *next;
1987047f369cy				long r = strtol(src, &next, 16);
1988047f369cy				if (next > 4+src)
1989047f369cy					return 0;
1990047f369cy				if (next == src)
1991047f369cy					return 0;
1992047f369cy				if (r<0 || r>65536)
1993047f369cy					return 0;
1994047f369cy
1995047f369cy				words[i++] = (ev_uint16_t)r;
1996047f369cy				setWords++;
1997047f369cy				src = next;
1998047f369cy				if (*src != ':' && src != eow)
1999047f369cy					return 0;
2000047f369cy				++src;
2001047f369cy			} else if (*src == ':' && i > 0 && gapPos==-1) {
2002047f369cy				gapPos = i;
2003047f369cy				++src;
2004047f369cy			} else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
2005047f369cy				gapPos = i;
2006047f369cy				src += 2;
2007047f369cy			} else {
2008047f369cy				return 0;
2009047f369cy			}
2010047f369cy		}
2011047f369cy
2012047f369cy		if (setWords > 8 ||
2013047f369cy			(setWords == 8 && gapPos != -1) ||
2014047f369cy			(setWords < 8 && gapPos == -1))
2015047f369cy			return 0;
2016047f369cy
2017047f369cy		if (gapPos >= 0) {
2018047f369cy			int nToMove = setWords - (dot ? 2 : 0) - gapPos;
2019047f369cy			int gapLen = 8 - setWords;
2020047f369cy			/* assert(nToMove >= 0); */
2021047f369cy			if (nToMove < 0)
2022047f369cy				return -1; /* should be impossible */
2023047f369cy			memmove(&words[gapPos+gapLen], &words[gapPos],
2024047f369cy					sizeof(ev_uint16_t)*nToMove);
2025047f369cy			memset(&words[gapPos], 0, sizeof(ev_uint16_t)*gapLen);
2026047f369cy		}
2027047f369cy		for (i = 0; i < 8; ++i) {
2028047f369cy			out->s6_addr[2*i  ] = words[i] >> 8;
2029047f369cy			out->s6_addr[2*i+1] = words[i] & 0xff;
2030047f369cy		}
2031047f369cy
2032047f369cy		return 1;
2033047f369cy#endif
2034047f369cy	} else {
2035047f369cy		return -1;
2036047f369cy	}
2037047f369cy#endif
2038047f369cy}
2039047f369cy
2040047f369cyint
2041047f369cyevutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
2042047f369cy{
2043047f369cy	int port;
2044047f369cy	char buf[128];
2045047f369cy	const char *cp, *addr_part, *port_part;
2046047f369cy	int is_ipv6;
2047047f369cy	/* recognized formats are:
2048047f369cy	 * [ipv6]:port
2049047f369cy	 * ipv6
2050047f369cy	 * [ipv6]
2051047f369cy	 * ipv4:port
2052047f369cy	 * ipv4
2053047f369cy	 */
2054047f369cy
2055047f369cy	cp = strchr(ip_as_string, ':');
2056047f369cy	if (*ip_as_string == '[') {
2057047f369cy		int len;
2058047f369cy		if (!(cp = strchr(ip_as_string, ']'))) {
2059047f369cy			return -1;
2060047f369cy		}
2061047f369cy		len = (int) ( cp-(ip_as_string + 1) );
2062047f369cy		if (len > (int)sizeof(buf)-1) {
2063047f369cy			return -1;
2064047f369cy		}
2065047f369cy		memcpy(buf, ip_as_string+1, len);
2066047f369cy		buf[len] = '\0';
2067047f369cy		addr_part = buf;
2068047f369cy		if (cp[1] == ':')
2069047f369cy			port_part = cp+2;
2070047f369cy		else
2071047f369cy			port_part = NULL;
2072047f369cy		is_ipv6 = 1;
2073047f369cy	} else if (cp && strchr(cp+1, ':')) {
2074047f369cy		is_ipv6 = 1;
2075047f369cy		addr_part = ip_as_string;
2076047f369cy		port_part = NULL;
2077047f369cy	} else if (cp) {
2078047f369cy		is_ipv6 = 0;
2079047f369cy		if (cp - ip_as_string > (int)sizeof(buf)-1) {
2080047f369cy			return -1;
2081047f369cy		}
2082047f369cy		memcpy(buf, ip_as_string, cp-ip_as_string);
2083047f369cy		buf[cp-ip_as_string] = '\0';
2084047f369cy		addr_part = buf;
2085047f369cy		port_part = cp+1;
2086047f369cy	} else {
2087047f369cy		addr_part = ip_as_string;
2088047f369cy		port_part = NULL;
2089047f369cy		is_ipv6 = 0;
2090047f369cy	}
2091047f369cy
2092047f369cy	if (port_part == NULL) {
2093047f369cy		port = 0;
2094047f369cy	} else {
2095047f369cy		port = atoi(port_part);
2096047f369cy		if (port <= 0 || port > 65535) {
2097047f369cy			return -1;
2098047f369cy		}
2099047f369cy	}
2100047f369cy
2101047f369cy	if (!addr_part)
2102047f369cy		return -1; /* Should be impossible. */
2103047f369cy#ifdef AF_INET6
2104047f369cy	if (is_ipv6)
2105047f369cy	{
2106047f369cy		struct sockaddr_in6 sin6;
2107047f369cy		memset(&sin6, 0, sizeof(sin6));
2108047f369cy#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
2109047f369cy		sin6.sin6_len = sizeof(sin6);
2110047f369cy#endif
2111047f369cy		sin6.sin6_family = AF_INET6;
2112047f369cy		sin6.sin6_port = htons(port);
2113047f369cy		if (1 != evutil_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr))
2114047f369cy			return -1;
2115047f369cy		if ((int)sizeof(sin6) > *outlen)
2116047f369cy			return -1;
2117047f369cy		memset(out, 0, *outlen);
2118047f369cy		memcpy(out, &sin6, sizeof(sin6));
2119047f369cy		*outlen = sizeof(sin6);
2120047f369cy		return 0;
2121047f369cy	}
2122047f369cy	else
2123047f369cy#endif
2124047f369cy	{
2125047f369cy		struct sockaddr_in sin;
2126047f369cy		memset(&sin, 0, sizeof(sin));
2127047f369cy#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
2128047f369cy		sin.sin_len = sizeof(sin);
2129047f369cy#endif
2130047f369cy		sin.sin_family = AF_INET;
2131047f369cy		sin.sin_port = htons(port);
2132047f369cy		if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr))
2133047f369cy			return -1;
2134047f369cy		if ((int)sizeof(sin) > *outlen)
2135047f369cy			return -1;
2136047f369cy		memset(out, 0, *outlen);
2137047f369cy		memcpy(out, &sin, sizeof(sin));
2138047f369cy		*outlen = sizeof(sin);
2139047f369cy		return 0;
2140047f369cy	}
2141047f369cy}
2142047f369cy
2143047f369cyconst char *
2144047f369cyevutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen)
2145047f369cy{
2146047f369cy	char b[128];
2147047f369cy	const char *res=NULL;
2148047f369cy	int port;
2149047f369cy	if (sa->sa_family == AF_INET) {
2150047f369cy		const struct sockaddr_in *sin = (const struct sockaddr_in*)sa;
2151047f369cy		res = evutil_inet_ntop(AF_INET, &sin->sin_addr,b,sizeof(b));
2152047f369cy		port = ntohs(sin->sin_port);
2153047f369cy		if (res) {
2154047f369cy			evutil_snprintf(out, outlen, "%s:%d", b, port);
2155047f369cy			return out;
2156047f369cy		}
2157047f369cy	} else if (sa->sa_family == AF_INET6) {
2158047f369cy		const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6*)sa;
2159047f369cy		res = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr,b,sizeof(b));
2160047f369cy		port = ntohs(sin6->sin6_port);
2161047f369cy		if (res) {
2162047f369cy			evutil_snprintf(out, outlen, "[%s]:%d", b, port);
2163047f369cy			return out;
2164047f369cy		}
2165047f369cy	}
2166047f369cy
2167047f369cy	evutil_snprintf(out, outlen, "<addr with socktype %d>",
2168047f369cy	    (int)sa->sa_family);
2169047f369cy	return out;
2170047f369cy}
2171047f369cy
2172047f369cyint
2173047f369cyevutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
2174047f369cy    int include_port)
2175047f369cy{
2176047f369cy	int r;
2177047f369cy	if (0 != (r = (sa1->sa_family - sa2->sa_family)))
2178047f369cy		return r;
2179047f369cy
2180047f369cy	if (sa1->sa_family == AF_INET) {
2181047f369cy		const struct sockaddr_in *sin1, *sin2;
2182047f369cy		sin1 = (const struct sockaddr_in *)sa1;
2183047f369cy		sin2 = (const struct sockaddr_in *)sa2;
2184047f369cy		if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
2185047f369cy			return -1;
2186047f369cy		else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
2187047f369cy			return 1;
2188047f369cy		else if (include_port &&
2189047f369cy		    (r = ((int)sin1->sin_port - (int)sin2->sin_port)))
2190047f369cy			return r;
2191047f369cy		else
2192047f369cy			return 0;
2193047f369cy	}
2194047f369cy#ifdef AF_INET6
2195047f369cy	else if (sa1->sa_family == AF_INET6) {
2196047f369cy		const struct sockaddr_in6 *sin1, *sin2;
2197047f369cy		sin1 = (const struct sockaddr_in6 *)sa1;
2198047f369cy		sin2 = (const struct sockaddr_in6 *)sa2;
2199047f369cy		if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
2200047f369cy			return r;
2201047f369cy		else if (include_port &&
2202047f369cy		    (r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
2203047f369cy			return r;
2204047f369cy		else
2205047f369cy			return 0;
2206047f369cy	}
2207047f369cy#endif
2208047f369cy	return 1;
2209047f369cy}
2210047f369cy
2211047f369cy/* Tables to implement ctypes-replacement EVUTIL_IS*() functions.  Each table
2212047f369cy * has 256 bits to look up whether a character is in some set or not.  This
2213047f369cy * fails on non-ASCII platforms, but so does every other place where we
2214047f369cy * take a char and write it onto the network.
2215047f369cy **/
2216047f369cystatic const ev_uint32_t EVUTIL_ISALPHA_TABLE[8] =
2217047f369cy  { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
2218047f369cystatic const ev_uint32_t EVUTIL_ISALNUM_TABLE[8] =
2219047f369cy  { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
2220047f369cystatic const ev_uint32_t EVUTIL_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
2221047f369cystatic const ev_uint32_t EVUTIL_ISXDIGIT_TABLE[8] =
2222047f369cy  { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
2223047f369cystatic const ev_uint32_t EVUTIL_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
2224047f369cystatic const ev_uint32_t EVUTIL_ISPRINT_TABLE[8] =
2225047f369cy  { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
2226047f369cystatic const ev_uint32_t EVUTIL_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
2227047f369cystatic const ev_uint32_t EVUTIL_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
2228047f369cy/* Upper-casing and lowercasing tables to map characters to upper/lowercase
2229047f369cy * equivalents. */
2230047f369cystatic const unsigned char EVUTIL_TOUPPER_TABLE[256] = {
2231047f369cy  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2232047f369cy  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2233047f369cy  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2234047f369cy  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2235047f369cy  64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2236047f369cy  80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
2237047f369cy  96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2238047f369cy  80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
2239047f369cy  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2240047f369cy  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2241047f369cy  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2242047f369cy  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2243047f369cy  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2244047f369cy  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2245047f369cy  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2246047f369cy  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2247047f369cy};
2248047f369cystatic const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
2249047f369cy  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2250047f369cy  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2251047f369cy  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2252047f369cy  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2253047f369cy  64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2254047f369cy  112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
2255047f369cy  96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2256047f369cy  112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
2257047f369cy  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2258047f369cy  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2259047f369cy  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2260047f369cy  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2261047f369cy  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2262047f369cy  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2263047f369cy  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2264047f369cy  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2265047f369cy};
2266047f369cy
2267047f369cy#define IMPL_CTYPE_FN(name)						\
2268047f369cy	int EVUTIL_##name##_(char c) {					\
2269047f369cy		ev_uint8_t u = c;					\
2270047f369cy		return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31))); \
2271047f369cy	}
2272047f369cyIMPL_CTYPE_FN(ISALPHA)
2273047f369cyIMPL_CTYPE_FN(ISALNUM)
2274047f369cyIMPL_CTYPE_FN(ISSPACE)
2275047f369cyIMPL_CTYPE_FN(ISDIGIT)
2276047f369cyIMPL_CTYPE_FN(ISXDIGIT)
2277047f369cyIMPL_CTYPE_FN(ISPRINT)
2278047f369cyIMPL_CTYPE_FN(ISLOWER)
2279047f369cyIMPL_CTYPE_FN(ISUPPER)
2280047f369cy
2281047f369cychar EVUTIL_TOLOWER_(char c)
2282047f369cy{
2283047f369cy	return ((char)EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]);
2284047f369cy}
2285047f369cychar EVUTIL_TOUPPER_(char c)
2286047f369cy{
2287047f369cy	return ((char)EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]);
2288047f369cy}
2289047f369cyint
2290047f369cyevutil_ascii_strcasecmp(const char *s1, const char *s2)
2291047f369cy{
2292047f369cy	char c1, c2;
2293047f369cy	while (1) {
2294047f369cy		c1 = EVUTIL_TOLOWER_(*s1++);
2295047f369cy		c2 = EVUTIL_TOLOWER_(*s2++);
2296047f369cy		if (c1 < c2)
2297047f369cy			return -1;
2298047f369cy		else if (c1 > c2)
2299047f369cy			return 1;
2300047f369cy		else if (c1 == 0)
2301047f369cy			return 0;
2302047f369cy	}
2303047f369cy}
2304047f369cyint evutil_ascii_strncasecmp(const char *s1, const char *s2, size_t n)
2305047f369cy{
2306047f369cy	char c1, c2;
2307047f369cy	while (n--) {
2308047f369cy		c1 = EVUTIL_TOLOWER_(*s1++);
2309047f369cy		c2 = EVUTIL_TOLOWER_(*s2++);
2310047f369cy		if (c1 < c2)
2311047f369cy			return -1;
2312047f369cy		else if (c1 > c2)
2313047f369cy			return 1;
2314047f369cy		else if (c1 == 0)
2315047f369cy			return 0;
2316047f369cy	}
2317047f369cy	return 0;
2318047f369cy}
2319047f369cy
2320047f369cyvoid
2321047f369cyevutil_rtrim_lws_(char *str)
2322047f369cy{
2323047f369cy	char *cp;
2324047f369cy
2325047f369cy	if (str == NULL)
2326047f369cy		return;
2327047f369cy
2328047f369cy	if ((cp = strchr(str, '\0')) == NULL || (cp == str))
2329047f369cy		return;
2330047f369cy
2331047f369cy	--cp;
2332047f369cy
2333047f369cy	while (*cp == ' ' || *cp == '\t') {
2334047f369cy		*cp = '\0';
2335047f369cy		if (cp == str)
2336047f369cy			break;
2337047f369cy		--cp;
2338047f369cy	}
2339047f369cy}
2340047f369cy
2341047f369cystatic int
2342047f369cyevutil_issetugid(void)
2343047f369cy{
2344047f369cy#ifdef EVENT__HAVE_ISSETUGID
2345047f369cy	return issetugid();
2346047f369cy#else
2347047f369cy
2348047f369cy#ifdef EVENT__HAVE_GETEUID
2349047f369cy	if (getuid() != geteuid())
2350047f369cy		return 1;
2351047f369cy#endif
2352047f369cy#ifdef EVENT__HAVE_GETEGID
2353047f369cy	if (getgid() != getegid())
2354047f369cy		return 1;
2355047f369cy#endif
2356047f369cy	return 0;
2357047f369cy#endif
2358047f369cy}
2359047f369cy
2360047f369cyconst char *
2361047f369cyevutil_getenv_(const char *varname)
2362047f369cy{
2363047f369cy	if (evutil_issetugid())
2364047f369cy		return NULL;
2365047f369cy
2366047f369cy	return getenv(varname);
2367047f369cy}
2368047f369cy
2369047f369cyev_uint32_t
2370047f369cyevutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed)
2371047f369cy{
2372047f369cy	if (seed == 0) {
2373047f369cy		struct timeval tv;
2374047f369cy		evutil_gettimeofday(&tv, NULL);
2375047f369cy		seed = (ev_uint32_t)tv.tv_sec + (ev_uint32_t)tv.tv_usec;
2376047f369cy#ifdef _WIN32
2377047f369cy		seed += (ev_uint32_t) _getpid();
2378047f369cy#else
2379047f369cy		seed += (ev_uint32_t) getpid();
2380047f369cy#endif
2381047f369cy	}
2382047f369cy	state->seed = seed;
2383047f369cy	return seed;
2384047f369cy}
2385047f369cy
2386047f369cyev_int32_t
2387047f369cyevutil_weakrand_(struct evutil_weakrand_state *state)
2388047f369cy{
2389047f369cy	/* This RNG implementation is a linear congruential generator, with
2390047f369cy	 * modulus 2^31, multiplier 1103515245, and addend 12345.  It's also
2391047f369cy	 * used by OpenBSD, and by Glibc's TYPE_0 RNG.
2392047f369cy	 *
2393047f369cy	 * The linear congruential generator is not an industrial-strength
2394047f369cy	 * RNG!  It's fast, but it can have higher-order patterns.  Notably,
2395047f369cy	 * the low bits tend to have periodicity.
2396047f369cy	 */
2397047f369cy	state->seed = ((state->seed) * 1103515245 + 12345) & 0x7fffffff;
2398047f369cy	return (ev_int32_t)(state->seed);
2399047f369cy}
2400047f369cy
2401047f369cyev_int32_t
2402047f369cyevutil_weakrand_range_(struct evutil_weakrand_state *state, ev_int32_t top)
2403047f369cy{
2404047f369cy	ev_int32_t divisor, result;
2405047f369cy
2406047f369cy	/* We can't just do weakrand() % top, since the low bits of the LCG
2407047f369cy	 * are less random than the high ones.  (Specifically, since the LCG
2408047f369cy	 * modulus is 2^N, every 2^m for m<N will divide the modulus, and so
2409047f369cy	 * therefore the low m bits of the LCG will have period 2^m.) */
2410047f369cy	divisor = EVUTIL_WEAKRAND_MAX / top;
2411047f369cy	do {
2412047f369cy		result = evutil_weakrand_(state) / divisor;
2413047f369cy	} while (result >= top);
2414047f369cy	return result;
2415047f369cy}
2416047f369cy
2417047f369cy/**
2418047f369cy * Volatile pointer to memset: we use this to keep the compiler from
2419047f369cy * eliminating our call to memset.
2420047f369cy */
2421047f369cyvoid * (*volatile evutil_memset_volatile_)(void *, int, size_t) = memset;
2422047f369cy
2423047f369cyvoid
2424047f369cyevutil_memclear_(void *mem, size_t len)
2425047f369cy{
2426047f369cy	evutil_memset_volatile_(mem, 0, len);
2427047f369cy}
2428047f369cy
2429047f369cyint
2430047f369cyevutil_sockaddr_is_loopback_(const struct sockaddr *addr)
2431047f369cy{
2432047f369cy	static const char LOOPBACK_S6[16] =
2433047f369cy	    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
2434047f369cy	if (addr->sa_family == AF_INET) {
2435047f369cy		struct sockaddr_in *sin = (struct sockaddr_in *)addr;
2436047f369cy		return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
2437047f369cy	} else if (addr->sa_family == AF_INET6) {
2438047f369cy		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
2439047f369cy		return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
2440047f369cy	}
2441047f369cy	return 0;
2442047f369cy}
2443047f369cy
2444047f369cyint
2445047f369cyevutil_hex_char_to_int_(char c)
2446047f369cy{
2447047f369cy	switch(c)
2448047f369cy	{
2449047f369cy		case '0': return 0;
2450047f369cy		case '1': return 1;
2451047f369cy		case '2': return 2;
2452047f369cy		case '3': return 3;
2453047f369cy		case '4': return 4;
2454047f369cy		case '5': return 5;
2455047f369cy		case '6': return 6;
2456047f369cy		case '7': return 7;
2457047f369cy		case '8': return 8;
2458047f369cy		case '9': return 9;
2459047f369cy		case 'A': case 'a': return 10;
2460047f369cy		case 'B': case 'b': return 11;
2461047f369cy		case 'C': case 'c': return 12;
2462047f369cy		case 'D': case 'd': return 13;
2463047f369cy		case 'E': case 'e': return 14;
2464047f369cy		case 'F': case 'f': return 15;
2465047f369cy	}
2466047f369cy	return -1;
2467047f369cy}
2468047f369cy
2469047f369cy#ifdef _WIN32
2470f63afe2cyHMODULE
2471047f369cyevutil_load_windows_system_library_(const TCHAR *library_name)
2472047f369cy{
2473047f369cy  TCHAR path[MAX_PATH];
2474047f369cy  unsigned n;
2475047f369cy  n = GetSystemDirectory(path, MAX_PATH);
2476047f369cy  if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
2477047f369cy    return 0;
2478047f369cy  _tcscat(path, TEXT("\\"));
2479047f369cy  _tcscat(path, library_name);
2480047f369cy  return LoadLibrary(path);
2481047f369cy}
2482047f369cy#endif
2483047f369cy
2484047f369cy/* Internal wrapper around 'socket' to provide Linux-style support for
2485047f369cy * syscall-saving methods where available.
2486047f369cy *
2487047f369cy * In addition to regular socket behavior, you can use a bitwise or to set the
2488047f369cy * flags EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'type' argument,
2489047f369cy * to make the socket nonblocking or close-on-exec with as few syscalls as
2490047f369cy * possible.
2491047f369cy */
2492047f369cyevutil_socket_t
2493047f369cyevutil_socket_(int domain, int type, int protocol)
2494047f369cy{
2495047f369cy	evutil_socket_t r;
2496047f369cy#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
2497047f369cy	r = socket(domain, type, protocol);
2498047f369cy	if (r >= 0)
2499047f369cy		return r;
2500047f369cy	else if ((type & (SOCK_NONBLOCK|SOCK_CLOEXEC)) == 0)
2501047f369cy		return -1;
2502047f369cy#endif
2503047f369cy#define SOCKET_TYPE_MASK (~(EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC))
2504047f369cy	r = socket(domain, type & SOCKET_TYPE_MASK, protocol);
2505047f369cy	if (r < 0)
2506047f369cy		return -1;
2507047f369cy	if (type & EVUTIL_SOCK_NONBLOCK) {
2508047f369cy		if (evutil_fast_socket_nonblocking(r) < 0) {
2509047f369cy			evutil_closesocket(r);
2510047f369cy			return -1;
2511047f369cy		}
2512047f369cy	}
2513047f369cy	if (type & EVUTIL_SOCK_CLOEXEC) {
2514047f369cy		if (evutil_fast_socket_closeonexec(r) < 0) {
2515047f369cy			evutil_closesocket(r);
2516047f369cy			return -1;
2517047f369cy		}
2518047f369cy	}
2519047f369cy	return r;
2520047f369cy}
2521047f369cy
2522047f369cy/* Internal wrapper around 'accept' or 'accept4' to provide Linux-style
2523047f369cy * support for syscall-saving methods where available.
2524047f369cy *
2525047f369cy * In addition to regular accept behavior, you can set one or more of flags
2526047f369cy * EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'flags' argument, to
2527047f369cy * make the socket nonblocking or close-on-exec with as few syscalls as
2528047f369cy * possible.
2529047f369cy */
2530047f369cyevutil_socket_t
2531047f369cyevutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr,
2532047f369cy    ev_socklen_t *addrlen, int flags)
2533047f369cy{
2534047f369cy	evutil_socket_t result;
2535047f369cy#if defined(EVENT__HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
2536047f369cy	result = accept4(sockfd, addr, addrlen, flags);
2537047f369cy	if (result >= 0 || (errno != EINVAL && errno != ENOSYS)) {
2538047f369cy		/* A nonnegative result means that we succeeded, so return.
2539047f369cy		 * Failing with EINVAL means that an option wasn't supported,
2540047f369cy		 * and failing with ENOSYS means that the syscall wasn't
2541047f369cy		 * there: in those cases we want to fall back.  Otherwise, we
2542047f369cy		 * got a real error, and we should return. */
2543047f369cy		return result;
2544047f369cy	}
2545047f369cy#endif
2546047f369cy	result = accept(sockfd, addr, addrlen);
2547047f369cy	if (result < 0)
2548047f369cy		return result;
2549047f369cy
2550047f369cy	if (flags & EVUTIL_SOCK_CLOEXEC) {
2551047f369cy		if (evutil_fast_socket_closeonexec(result) < 0) {
2552047f369cy			evutil_closesocket(result);
2553047f369cy			return -1;
2554047f369cy		}
2555047f369cy	}
2556047f369cy	if (flags & EVUTIL_SOCK_NONBLOCK) {
2557047f369cy		if (evutil_fast_socket_nonblocking(result) < 0) {
2558047f369cy			evutil_closesocket(result);
2559047f369cy			return -1;
2560047f369cy		}
2561047f369cy	}
2562047f369cy	return result;
2563047f369cy}
2564047f369cy
2565047f369cy/* Internal function: Set fd[0] and fd[1] to a pair of fds such that writes on
2566047f369cy * fd[0] get read from fd[1].  Make both fds nonblocking and close-on-exec.
2567047f369cy * Return 0 on success, -1 on failure.
2568047f369cy */
2569047f369cyint
2570047f369cyevutil_make_internal_pipe_(evutil_socket_t fd[2])
2571047f369cy{
2572047f369cy	/*
2573047f369cy	  Making the second socket nonblocking is a bit subtle, given that we
2574047f369cy	  ignore any EAGAIN returns when writing to it, and you don't usally
2575047f369cy	  do that for a nonblocking socket. But if the kernel gives us EAGAIN,
2576047f369cy	  then there's no need to add any more data to the buffer, since
2577047f369cy	  the main thread is already either about to wake up and drain it,
2578047f369cy	  or woken up and in the process of draining it.
2579047f369cy	*/
2580047f369cy
2581047f369cy#if defined(EVENT__HAVE_PIPE2)
2582047f369cy	if (pipe2(fd, O_NONBLOCK|O_CLOEXEC) == 0)
2583047f369cy		return 0;
2584047f369cy#endif
2585047f369cy#if defined(EVENT__HAVE_PIPE)
2586047f369cy	if (pipe(fd) == 0) {
2587047f369cy		if (evutil_fast_socket_nonblocking(fd[0]) < 0 ||
2588047f369cy		    evutil_fast_socket_nonblocking(fd[1]) < 0 ||
2589047f369cy		    evutil_fast_socket_closeonexec(fd[0]) < 0 ||
2590047f369cy		    evutil_fast_socket_closeonexec(fd[1]) < 0) {
2591047f369cy			close(fd[0]);
2592047f369cy			close(fd[1]);
2593047f369cy			fd[0] = fd[1] = -1;
2594047f369cy			return -1;
2595047f369cy		}
2596047f369cy		return 0;
2597047f369cy	} else {
2598047f369cy		event_warn("%s: pipe", __func__);
2599047f369cy	}
2600047f369cy#endif
2601047f369cy
2602047f369cy#ifdef _WIN32
2603047f369cy#define LOCAL_SOCKETPAIR_AF AF_INET
2604047f369cy#else
2605047f369cy#define LOCAL_SOCKETPAIR_AF AF_UNIX
2606047f369cy#endif
2607047f369cy	if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, fd) == 0) {
2608047f369cy		if (evutil_fast_socket_nonblocking(fd[0]) < 0 ||
2609047f369cy		    evutil_fast_socket_nonblocking(fd[1]) < 0 ||
2610047f369cy		    evutil_fast_socket_closeonexec(fd[0]) < 0 ||
2611047f369cy		    evutil_fast_socket_closeonexec(fd[1]) < 0) {
2612047f369cy			evutil_closesocket(fd[0]);
2613047f369cy			evutil_closesocket(fd[1]);
2614047f369cy			fd[0] = fd[1] = -1;
2615047f369cy			return -1;
2616047f369cy		}
2617047f369cy		return 0;
2618047f369cy	}
2619047f369cy	fd[0] = fd[1] = -1;
2620047f369cy	return -1;
2621047f369cy}
2622047f369cy
2623047f369cy/* Wrapper around eventfd on systems that provide it.  Unlike the system
2624047f369cy * eventfd, it always supports EVUTIL_EFD_CLOEXEC and EVUTIL_EFD_NONBLOCK as
2625047f369cy * flags.  Returns -1 on error or if eventfd is not supported.
2626047f369cy */
2627047f369cyevutil_socket_t
2628047f369cyevutil_eventfd_(unsigned initval, int flags)
2629047f369cy{
2630047f369cy#if defined(EVENT__HAVE_EVENTFD) && defined(EVENT__HAVE_SYS_EVENTFD_H)
2631047f369cy	int r;
2632047f369cy#if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
2633047f369cy	r = eventfd(initval, flags);
2634047f369cy	if (r >= 0 || flags == 0)
2635047f369cy		return r;
2636047f369cy#endif
2637047f369cy	r = eventfd(initval, 0);
2638047f369cy	if (r < 0)
2639047f369cy		return r;
2640047f369cy	if (flags & EVUTIL_EFD_CLOEXEC) {
2641047f369cy		if (evutil_fast_socket_closeonexec(r) < 0) {
2642047f369cy			evutil_closesocket(r);
2643047f369cy			return -1;
2644047f369cy		}
2645047f369cy	}
2646047f369cy	if (flags & EVUTIL_EFD_NONBLOCK) {
2647047f369cy		if (evutil_fast_socket_nonblocking(r) < 0) {
2648047f369cy			evutil_closesocket(r);
2649047f369cy			return -1;
2650047f369cy		}
2651047f369cy	}
2652047f369cy	return r;
2653047f369cy#else
2654047f369cy	return -1;
2655047f369cy#endif
2656047f369cy}
2657047f369cy
2658047f369cyvoid
2659047f369cyevutil_free_globals_(void)
2660047f369cy{
2661047f369cy	evutil_free_secure_rng_globals_();
2662047f369cy	evutil_free_sock_err_globals();
2663047f369cy}
2664