1e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/*
2e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
3e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
4e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Redistribution and use in source and binary forms, with or without
5e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * modification, are permitted provided that the following conditions
6e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * are met:
7e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * 1. Redistributions of source code must retain the above copyright
8e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *    notice, this list of conditions and the following disclaimer.
9e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * 2. Redistributions in binary form must reproduce the above copyright
10e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *    notice, this list of conditions and the following disclaimer in the
11e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *    documentation and/or other materials provided with the distribution.
12e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * 3. The name of the author may not be used to endorse or promote products
13e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *    derived from this software without specific prior written permission.
14e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
15e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
26e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
27e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include "event2/event-config.h"
28fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#include "evconfig-private.h"
29e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
30fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
31e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <winsock2.h>
32e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <ws2tcpip.h>
33e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define WIN32_LEAN_AND_MEAN
34e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <windows.h>
35e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#undef WIN32_LEAN_AND_MEAN
36e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <io.h>
37e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <tchar.h>
38fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#include <process.h>
39fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#undef _WIN32_WINNT
40fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath/* For structs needed by GetAdaptersAddresses */
41fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#define _WIN32_WINNT 0x0501
42fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#include <iphlpapi.h>
43e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
44e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
45e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <sys/types.h>
46fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_SYS_SOCKET_H
47e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <sys/socket.h>
48e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
49fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_UNISTD_H
50e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <unistd.h>
51e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
52fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_FCNTL_H
53e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <fcntl.h>
54e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
55fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_STDLIB_H
56e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <stdlib.h>
57e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
58e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <errno.h>
59e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <limits.h>
60e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <stdio.h>
61e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <string.h>
62fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_NETINET_IN_H
63e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <netinet/in.h>
64e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
65fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_NETINET_IN6_H
66e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <netinet/in6.h>
67e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
68fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_NETINET_TCP_H
69fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#include <netinet/tcp.h>
70fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
71fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_ARPA_INET_H
72e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <arpa/inet.h>
73e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
74e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <time.h>
7583a0c9c65a60a92d3ea5542596b3ba56db492c37Josh Gao#include <sys/stat.h>
76fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_IFADDRS_H
77fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#include <ifaddrs.h>
78fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
79e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
80e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include "event2/util.h"
81e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include "util-internal.h"
82e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include "log-internal.h"
83e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include "mm-internal.h"
84fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#include "evthread-internal.h"
85e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
86e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include "strlcpy-internal.h"
87e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include "ipv6-internal.h"
88e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
89fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
90fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#define HT_NO_CACHE_HASH_VALUES
91fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#include "ht-internal.h"
92e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define open _open
93e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define read _read
94e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define close _close
95fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifndef fstat
96e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define fstat _fstati64
97fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
98fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifndef stat
99e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define stat _stati64
100fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
101e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define mode_t int
102e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
103e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
104e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
105fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_open_closeonexec_(const char *pathname, int flags, unsigned mode)
106e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
107e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int fd;
108e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
109e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef O_CLOEXEC
110fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	fd = open(pathname, flags|O_CLOEXEC, (mode_t)mode);
111fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (fd >= 0 || errno == EINVAL)
112fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return fd;
113fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* If we got an EINVAL, fall through and try without O_CLOEXEC */
114e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
115fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	fd = open(pathname, flags, (mode_t)mode);
116e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (fd < 0)
117e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
118e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
119fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(FD_CLOEXEC)
120fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
121fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		close(fd);
122e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
123fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
124e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
125e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
126e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return fd;
127e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
128e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
129e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/**
130e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   Read the contents of 'filename' into a newly allocated NUL-terminated
131e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   string.  Set *content_out to hold this string, and *len_out to hold its
132e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   length (not including the appended NUL).  If 'is_binary', open the file in
133e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   binary mode.
134e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
135e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   Returns 0 on success, -1 if the open fails, and -2 for all other failures.
136e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
137e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   Used internally only; may go away in a future version.
138e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
139e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
140fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_read_file_(const char *filename, char **content_out, size_t *len_out,
141e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    int is_binary)
142e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
143e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int fd, r;
144e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct stat st;
145e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	char *mem;
146e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	size_t read_so_far=0;
147e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int mode = O_RDONLY;
148e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
149e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	EVUTIL_ASSERT(content_out);
150e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	EVUTIL_ASSERT(len_out);
151e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	*content_out = NULL;
152e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	*len_out = 0;
153e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
154e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef O_BINARY
155e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (is_binary)
156e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		mode |= O_BINARY;
157e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
158e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
159fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	fd = evutil_open_closeonexec_(filename, mode, 0);
160e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (fd < 0)
161e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
162e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (fstat(fd, &st) || st.st_size < 0 ||
163e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    st.st_size > EV_SSIZE_MAX-1 ) {
164e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		close(fd);
165e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -2;
166e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
167e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	mem = mm_malloc((size_t)st.st_size + 1);
168e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!mem) {
169e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		close(fd);
170e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -2;
171e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
172e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	read_so_far = 0;
173fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
174e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x))
175e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
176e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define N_TO_READ(x) (x)
177e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
178e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) {
179e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		read_so_far += r;
180e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (read_so_far >= (size_t)st.st_size)
181e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			break;
182e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		EVUTIL_ASSERT(read_so_far < (size_t)st.st_size);
183e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
184e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	close(fd);
185e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (r < 0) {
186e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		mm_free(mem);
187e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -2;
188e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
189e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	mem[read_so_far] = 0;
190e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
191e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	*len_out = read_so_far;
192e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	*content_out = mem;
193e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
194e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
195e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
196e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
197e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
198e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
199fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifndef _WIN32
200e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return socketpair(family, type, protocol, fd);
201e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
202fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return evutil_ersatz_socketpair_(family, type, protocol, fd);
203e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
204e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
205e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
206e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
207fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_ersatz_socketpair_(int family, int type, int protocol,
208e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    evutil_socket_t fd[2])
209e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
210e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* This code is originally from Tor.  Used with permission. */
211e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
212e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* This socketpair does not work when localhost is down. So
213e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * it's really not the same thing at all. But it's close enough
214e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * for now, and really, when localhost is down sometimes, we
215e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * have other problems too.
216e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 */
217fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
218e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define ERR(e) WSA##e
219e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
220e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define ERR(e) e
221e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
222e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_socket_t listener = -1;
223e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_socket_t connector = -1;
224e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_socket_t acceptor = -1;
225e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct sockaddr_in listen_addr;
226e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct sockaddr_in connect_addr;
227e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	ev_socklen_t size;
228e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int saved_errno = -1;
229fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	int family_test;
230fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
231fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	family_test = family != AF_INET;
232e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AF_UNIX
233fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	family_test = family_test && (family != AF_UNIX);
234e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
235fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (protocol || family_test) {
236e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		EVUTIL_SET_SOCKET_ERROR(ERR(EAFNOSUPPORT));
237e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
238e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
239fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
240e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!fd) {
241e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
242e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
243e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
244e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
245e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	listener = socket(AF_INET, type, 0);
246e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (listener < 0)
247e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
248e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	memset(&listen_addr, 0, sizeof(listen_addr));
249e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	listen_addr.sin_family = AF_INET;
250e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
251e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	listen_addr.sin_port = 0;	/* kernel chooses port.	 */
252e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
253e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		== -1)
254e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto tidy_up_and_fail;
255e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (listen(listener, 1) == -1)
256e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto tidy_up_and_fail;
257e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
258e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	connector = socket(AF_INET, type, 0);
259e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (connector < 0)
260e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto tidy_up_and_fail;
261fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
262fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	memset(&connect_addr, 0, sizeof(connect_addr));
263fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
264e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* We want to find out the port number to connect to.  */
265e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	size = sizeof(connect_addr);
266e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
267e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto tidy_up_and_fail;
268e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (size != sizeof (connect_addr))
269e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto abort_tidy_up_and_fail;
270e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (connect(connector, (struct sockaddr *) &connect_addr,
271e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				sizeof(connect_addr)) == -1)
272e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto tidy_up_and_fail;
273e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
274e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	size = sizeof(listen_addr);
275e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
276e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (acceptor < 0)
277e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto tidy_up_and_fail;
278e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (size != sizeof(listen_addr))
279e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto abort_tidy_up_and_fail;
280e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Now check we are talking to ourself by matching port and host on the
281e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	   two sockets.	 */
282e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
283e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto tidy_up_and_fail;
284e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (size != sizeof (connect_addr)
285e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		|| listen_addr.sin_family != connect_addr.sin_family
286e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		|| listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
287e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		|| listen_addr.sin_port != connect_addr.sin_port)
288e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto abort_tidy_up_and_fail;
289e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_closesocket(listener);
290e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	fd[0] = connector;
291e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	fd[1] = acceptor;
292e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
293e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
294e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
295e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley abort_tidy_up_and_fail:
296e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	saved_errno = ERR(ECONNABORTED);
297e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley tidy_up_and_fail:
298e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (saved_errno < 0)
299e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		saved_errno = EVUTIL_SOCKET_ERROR();
300e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (listener != -1)
301e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evutil_closesocket(listener);
302e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (connector != -1)
303e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evutil_closesocket(connector);
304e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (acceptor != -1)
305e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evutil_closesocket(acceptor);
306e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
307e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	EVUTIL_SET_SOCKET_ERROR(saved_errno);
308e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return -1;
309e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#undef ERR
310e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
311e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
312e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
313e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_make_socket_nonblocking(evutil_socket_t fd)
314e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
315fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
316e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	{
317fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		unsigned long nonblocking = 1;
318e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) {
319e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			event_sock_warn(fd, "fcntl(%d, F_GETFL)", (int)fd);
320e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
321e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
322e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
323e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
324e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	{
325e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		int flags;
326e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
327e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			event_warn("fcntl(%d, F_GETFL)", fd);
328e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
329e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
330fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (!(flags & O_NONBLOCK)) {
331fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
332fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath				event_warn("fcntl(%d, F_SETFL)", fd);
333fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath				return -1;
334fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			}
335e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
336e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
337e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
338e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
339e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
340e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
341fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath/* Faster version of evutil_make_socket_nonblocking for internal use.
342fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath *
343fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * Requires that no F_SETFL flags were previously set on the fd.
344fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath */
345fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic int
346fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_fast_socket_nonblocking(evutil_socket_t fd)
347fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
348fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
349fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return evutil_make_socket_nonblocking(fd);
350fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#else
351fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
352fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		event_warn("fcntl(%d, F_SETFL)", fd);
353fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return -1;
354fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
355fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return 0;
356fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
357fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
358fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
359e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
360e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_make_listen_socket_reuseable(evutil_socket_t sock)
361e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
362fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(SO_REUSEADDR) && !defined(_WIN32)
363e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int one = 1;
364e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* REUSEADDR on Unix means, "don't hang on to this address after the
365e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * listener is closed."  On Windows, though, it means "don't keep other
366e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * processes from binding to this address while we're using it. */
367e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
368e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    (ev_socklen_t)sizeof(one));
369e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
370e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
371e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
372e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
373e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
374e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
375fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_make_listen_socket_reuseable_port(evutil_socket_t sock)
376fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
377fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined __linux__ && defined(SO_REUSEPORT)
378fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	int one = 1;
379fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* REUSEPORT on Linux 3.9+ means, "Multiple servers (processes or
380fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * threads) can bind to the same port if they each set the option. */
381fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void*) &one,
382fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    (ev_socklen_t)sizeof(one));
383fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#else
384fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return 0;
385fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
386fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
387fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
388fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathint
389fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_make_tcp_listen_socket_deferred(evutil_socket_t sock)
390fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
391fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EVENT__HAVE_NETINET_TCP_H) && defined(TCP_DEFER_ACCEPT)
392fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	int one = 1;
393fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
394fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* TCP_DEFER_ACCEPT tells the kernel to call defer accept() only after data
395fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * has arrived and ready to read */
396fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, &one,
397fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		(ev_socklen_t)sizeof(one));
398fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
399fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return 0;
400fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
401fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
402fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathint
403e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_make_socket_closeonexec(evutil_socket_t fd)
404e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
405fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
406e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int flags;
407e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) {
408e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		event_warn("fcntl(%d, F_GETFD)", fd);
409e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
410e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
411fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (!(flags & FD_CLOEXEC)) {
412fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
413fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			event_warn("fcntl(%d, F_SETFD)", fd);
414fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return -1;
415fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
416fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
417fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
418fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return 0;
419fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
420fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
421fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath/* Faster version of evutil_make_socket_closeonexec for internal use.
422fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath *
423fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * Requires that no F_SETFD flags were previously set on the fd.
424fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath */
425fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic int
426fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_fast_socket_closeonexec(evutil_socket_t fd)
427fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
428fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
429fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
430e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		event_warn("fcntl(%d, F_SETFD)", fd);
431e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
432e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
433e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
434e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
435e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
436e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
437e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
438e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_closesocket(evutil_socket_t sock)
439e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
440fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifndef _WIN32
441e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return close(sock);
442e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
443e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return closesocket(sock);
444e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
445e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
446e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
447e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyev_int64_t
448e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_strtoll(const char *s, char **endptr, int base)
449e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
450fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_STRTOLL
451e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return (ev_int64_t)strtoll(s, endptr, base);
452fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#elif EVENT__SIZEOF_LONG == 8
453e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return (ev_int64_t)strtol(s, endptr, base);
454fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#elif defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
455e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* XXXX on old versions of MS APIs, we only support base
456e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * 10. */
457e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	ev_int64_t r;
458e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (base != 10)
459e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 0;
460e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	r = (ev_int64_t) _atoi64(s);
461e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	while (isspace(*s))
462e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		++s;
463e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (*s == '-')
464e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		++s;
465e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	while (isdigit(*s))
466e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		++s;
467e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (endptr)
468e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		*endptr = (char*) s;
469e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return r;
470fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#elif defined(_WIN32)
471e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return (ev_int64_t) _strtoi64(s, endptr, base);
472fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#elif defined(EVENT__SIZEOF_LONG_LONG) && EVENT__SIZEOF_LONG_LONG == 8
473e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	long long r;
474e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int n;
475e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (base != 10 && base != 16)
476e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 0;
477e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (base == 10) {
478e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		n = sscanf(s, "%lld", &r);
479e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
480e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		unsigned long long ru=0;
481e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		n = sscanf(s, "%llx", &ru);
482e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ru > EV_INT64_MAX)
483e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
484e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		r = (long long) ru;
485e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
486e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (n != 1)
487e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 0;
488fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	while (EVUTIL_ISSPACE_(*s))
489e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		++s;
490e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (*s == '-')
491e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		++s;
492e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (base == 10) {
493fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		while (EVUTIL_ISDIGIT_(*s))
494e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			++s;
495e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
496fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		while (EVUTIL_ISXDIGIT_(*s))
497e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			++s;
498e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
499e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (endptr)
500e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		*endptr = (char*) s;
501e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return r;
502e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
503e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#error "I don't know how to parse 64-bit integers."
504e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
505e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
506e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
507fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
508e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
509e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_socket_geterror(evutil_socket_t sock)
510e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
511e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int optval, optvallen=sizeof(optval);
512e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int err = WSAGetLastError();
513e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (err == WSAEWOULDBLOCK && sock >= 0) {
514e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
515e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					   &optvallen))
516e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return err;
517e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (optval)
518e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return optval;
519e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
520e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return err;
521e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
522e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
523e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
524e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* XXX we should use an enum here. */
525e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
526e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
527fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_socket_connect_(evutil_socket_t *fd_ptr, const struct sockaddr *sa, int socklen)
528e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
529e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int made_fd = 0;
530e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
531e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (*fd_ptr < 0) {
532e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
533e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			goto err;
534e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		made_fd = 1;
535e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (evutil_make_socket_nonblocking(*fd_ptr) < 0) {
536e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			goto err;
537e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
538e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
539e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
540e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (connect(*fd_ptr, sa, socklen) < 0) {
541e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		int e = evutil_socket_geterror(*fd_ptr);
542e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
543e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
544e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (EVUTIL_ERR_CONNECT_REFUSED(e))
545e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 2;
546e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		goto err;
547e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
548e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 1;
549e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
550e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
551e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyerr:
552e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (made_fd) {
553e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evutil_closesocket(*fd_ptr);
554e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		*fd_ptr = -1;
555e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
556e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return -1;
557e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
558e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
559e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Check whether a socket on which we called connect() is done
560e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   connecting. Return 1 for connected, 0 for not yet, -1 for error.  In the
561e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   error case, set the current socket errno to the error that happened during
562e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   the connect operation. */
563e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
564fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_socket_finished_connecting_(evutil_socket_t fd)
565e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
566e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int e;
567e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	ev_socklen_t elen = sizeof(e);
568e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
569e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
570e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
571e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
572e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (e) {
573e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
574e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
575e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		EVUTIL_SET_SOCKET_ERROR(e);
576e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
577e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
578e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
579e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 1;
580e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
581e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
582e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#if (EVUTIL_AI_PASSIVE|EVUTIL_AI_CANONNAME|EVUTIL_AI_NUMERICHOST| \
583e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley     EVUTIL_AI_NUMERICSERV|EVUTIL_AI_V4MAPPED|EVUTIL_AI_ALL| \
584e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley     EVUTIL_AI_ADDRCONFIG) != \
585e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    (EVUTIL_AI_PASSIVE^EVUTIL_AI_CANONNAME^EVUTIL_AI_NUMERICHOST^ \
586e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley     EVUTIL_AI_NUMERICSERV^EVUTIL_AI_V4MAPPED^EVUTIL_AI_ALL^ \
587e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley     EVUTIL_AI_ADDRCONFIG)
588e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#error "Some of our EVUTIL_AI_* flags seem to overlap with system AI_* flags"
589e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
590e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
591e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* We sometimes need to know whether we have an ipv4 address and whether we
592e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   have an ipv6 address. If 'have_checked_interfaces', then we've already done
593e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   the test.  If 'had_ipv4_address', then it turns out we had an ipv4 address.
594e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   If 'had_ipv6_address', then it turns out we had an ipv6 address.   These are
595e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   set by evutil_check_interfaces. */
596e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
597e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
598e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Macro: True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8
599e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
600e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define EVUTIL_V4ADDR_IS_LOCALHOST(addr) (((addr)>>24) == 127)
601e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
602e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Macro: True iff the IPv4 address 'addr', in host order, is a class D
603e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * (multiclass) address.
604e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
605e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define EVUTIL_V4ADDR_IS_CLASSD(addr) ((((addr)>>24) & 0xf0) == 0xe0)
606e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
607fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic void
608fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_found_ifaddr(const struct sockaddr *sa)
609fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
610fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	const char ZEROES[] = "\x00\x00\x00\x00\x00\x00\x00\x00"
611fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    "\x00\x00\x00\x00\x00\x00\x00\x00";
612fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
613fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (sa->sa_family == AF_INET) {
614fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		const struct sockaddr_in *sin = (struct sockaddr_in *)sa;
615fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		ev_uint32_t addr = ntohl(sin->sin_addr.s_addr);
616fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (addr == 0 ||
617fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    EVUTIL_V4ADDR_IS_LOCALHOST(addr) ||
618fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    EVUTIL_V4ADDR_IS_CLASSD(addr)) {
619fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			/* Not actually a usable external address. */
620fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		} else {
621fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			event_debug(("Detected an IPv4 interface"));
622fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			had_ipv4_address = 1;
623fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
624fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	} else if (sa->sa_family == AF_INET6) {
625fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
626fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		const unsigned char *addr =
627fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    (unsigned char*)sin6->sin6_addr.s6_addr;
628fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (!memcmp(addr, ZEROES, 8) ||
629fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    ((addr[0] & 0xfe) == 0xfc) ||
630fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80) ||
631fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    (addr[0] == 0xfe && (addr[1] & 0xc0) == 0xc0) ||
632fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    (addr[0] == 0xff)) {
633fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			/* This is a reserved, ipv4compat, ipv4map, loopback,
634fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			 * link-local, multicast, or unspecified address. */
635fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		} else {
636fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			event_debug(("Detected an IPv6 interface"));
637fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			had_ipv6_address = 1;
638fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
639fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
640fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
641fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
642fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
643fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathtypedef ULONG (WINAPI *GetAdaptersAddresses_fn_t)(
644fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath              ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
645fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
646fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
647fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic int
648fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_check_ifaddrs(void)
649fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
650fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EVENT__HAVE_GETIFADDRS)
651fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* Most free Unixy systems provide getifaddrs, which gives us a linked list
652fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * of struct ifaddrs. */
653fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	struct ifaddrs *ifa = NULL;
654fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	const struct ifaddrs *i;
655fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (getifaddrs(&ifa) < 0) {
656fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		event_warn("Unable to call getifaddrs()");
657fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return -1;
658fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
659fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
660fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	for (i = ifa; i; i = i->ifa_next) {
661fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (!i->ifa_addr)
662fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			continue;
663fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		evutil_found_ifaddr(i->ifa_addr);
664fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
665fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
666fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	freeifaddrs(ifa);
667fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return 0;
668fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#elif defined(_WIN32)
669fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* Windows XP began to provide GetAdaptersAddresses. Windows 2000 had a
670fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	   "GetAdaptersInfo", but that's deprecated; let's just try
671fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	   GetAdaptersAddresses and fall back to connect+getsockname.
672fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	*/
673fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	HMODULE lib = evutil_load_windows_system_library_(TEXT("ihplapi.dll"));
674fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	GetAdaptersAddresses_fn_t fn;
675fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	ULONG size, res;
676fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	IP_ADAPTER_ADDRESSES *addresses = NULL, *address;
677fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	int result = -1;
678fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
679fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#define FLAGS (GAA_FLAG_SKIP_ANYCAST | \
680fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath               GAA_FLAG_SKIP_MULTICAST | \
681fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath               GAA_FLAG_SKIP_DNS_SERVER)
682fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
683fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (!lib)
684fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		goto done;
685fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
686fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (!(fn = (GetAdaptersAddresses_fn_t) GetProcAddress(lib, "GetAdaptersAddresses")))
687fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		goto done;
688fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
689fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* Guess how much space we need. */
690fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	size = 15*1024;
691fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	addresses = mm_malloc(size);
692fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (!addresses)
693fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		goto done;
694fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
695fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (res == ERROR_BUFFER_OVERFLOW) {
696fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		/* we didn't guess that we needed enough space; try again */
697fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		mm_free(addresses);
698fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		addresses = mm_malloc(size);
699fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (!addresses)
700fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			goto done;
701fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
702fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
703fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (res != NO_ERROR)
704fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		goto done;
705fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
706fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	for (address = addresses; address; address = address->Next) {
707fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		IP_ADAPTER_UNICAST_ADDRESS *a;
708fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		for (a = address->FirstUnicastAddress; a; a = a->Next) {
709fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			/* Yes, it's a linked list inside a linked list */
710fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			struct sockaddr *sa = a->Address.lpSockaddr;
711fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			evutil_found_ifaddr(sa);
712fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
713fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
714fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
715fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	result = 0;
716fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathdone:
717fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (lib)
718fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		FreeLibrary(lib);
719fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (addresses)
720fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		mm_free(addresses);
721fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return result;
722fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#else
723fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return -1;
724fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
725fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
726fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
727e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Test whether we have an ipv4 interface and an ipv6 interface.  Return 0 if
728e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * the test seemed successful. */
729e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
730e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_check_interfaces(int force_recheck)
731e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
732e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_socket_t fd = -1;
733e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct sockaddr_in sin, sin_out;
734e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct sockaddr_in6 sin6, sin6_out;
735e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	ev_socklen_t sin_out_len = sizeof(sin_out);
736e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	ev_socklen_t sin6_out_len = sizeof(sin6_out);
737e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int r;
738e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (have_checked_interfaces && !force_recheck)
739e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 0;
740e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
741fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (evutil_check_ifaddrs() == 0) {
742fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		/* Use a nice sane interface, if this system has one. */
743fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return 0;
744fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
745fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
746fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* Ugh. There was no nice sane interface.  So to check whether we have
747fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * an interface open for a given protocol, will try to make a UDP
748fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * 'connection' to a remote host on the internet.  We don't actually
749fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * use it, so the address doesn't matter, but we want to pick one that
750fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * keep us from using a host- or link-local interface. */
751e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	memset(&sin, 0, sizeof(sin));
752e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	sin.sin_family = AF_INET;
753e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	sin.sin_port = htons(53);
754e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	r = evutil_inet_pton(AF_INET, "18.244.0.188", &sin.sin_addr);
755e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	EVUTIL_ASSERT(r);
756e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
757e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	memset(&sin6, 0, sizeof(sin6));
758e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	sin6.sin6_family = AF_INET6;
759e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	sin6.sin6_port = htons(53);
760e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	r = evutil_inet_pton(AF_INET6, "2001:4860:b002::68", &sin6.sin6_addr);
761e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	EVUTIL_ASSERT(r);
762e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
763e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	memset(&sin_out, 0, sizeof(sin_out));
764e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	memset(&sin6_out, 0, sizeof(sin6_out));
765e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
766e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* XXX some errnos mean 'no address'; some mean 'not enough sockets'. */
767e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
768e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
769e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    getsockname(fd, (struct sockaddr*)&sin_out, &sin_out_len) == 0) {
770e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* We might have an IPv4 interface. */
771fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		evutil_found_ifaddr((struct sockaddr*) &sin_out);
772e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
773e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (fd >= 0)
774e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evutil_closesocket(fd);
775e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
776e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
777e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    connect(fd, (struct sockaddr*)&sin6, sizeof(sin6)) == 0 &&
778e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    getsockname(fd, (struct sockaddr*)&sin6_out, &sin6_out_len) == 0) {
779e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* We might have an IPv6 interface. */
780fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		evutil_found_ifaddr((struct sockaddr*) &sin6_out);
781e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
782e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
783e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (fd >= 0)
784e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evutil_closesocket(fd);
785e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
786e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
787e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
788e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
789e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Internal addrinfo flag.  This one is set when we allocate the addrinfo from
790e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * inside libevent.  Otherwise, the built-in getaddrinfo() function allocated
791e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * it, and we should trust what they said.
792e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley **/
793e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define EVUTIL_AI_LIBEVENT_ALLOCATED 0x80000000
794e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
795e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Helper: construct a new addrinfo containing the socket address in
796e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * 'sa', which must be a sockaddr_in or a sockaddr_in6.  Take the
797e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * socktype and protocol info from hints.  If they weren't set, then
798e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * allocate both a TCP and a UDP addrinfo.
799e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
800e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystruct evutil_addrinfo *
801fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_new_addrinfo_(struct sockaddr *sa, ev_socklen_t socklen,
802e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    const struct evutil_addrinfo *hints)
803e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
804e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct evutil_addrinfo *res;
805e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	EVUTIL_ASSERT(hints);
806e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
807e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (hints->ai_socktype == 0 && hints->ai_protocol == 0) {
808e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* Indecisive user! Give them a UDP and a TCP. */
809e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct evutil_addrinfo *r1, *r2;
810e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct evutil_addrinfo tmp;
811e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memcpy(&tmp, hints, sizeof(tmp));
812e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		tmp.ai_socktype = SOCK_STREAM; tmp.ai_protocol = IPPROTO_TCP;
813fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		r1 = evutil_new_addrinfo_(sa, socklen, &tmp);
814e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (!r1)
815e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return NULL;
816e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		tmp.ai_socktype = SOCK_DGRAM; tmp.ai_protocol = IPPROTO_UDP;
817fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		r2 = evutil_new_addrinfo_(sa, socklen, &tmp);
818e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (!r2) {
819e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			evutil_freeaddrinfo(r1);
820e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return NULL;
821e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
822e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		r1->ai_next = r2;
823e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return r1;
824e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
825e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
826e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* We're going to allocate extra space to hold the sockaddr. */
827e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	res = mm_calloc(1,sizeof(struct evutil_addrinfo)+socklen);
828e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!res)
829e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return NULL;
830e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	res->ai_addr = (struct sockaddr*)
831e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    (((char*)res) + sizeof(struct evutil_addrinfo));
832e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	memcpy(res->ai_addr, sa, socklen);
833e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	res->ai_addrlen = socklen;
834e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	res->ai_family = sa->sa_family; /* Same or not? XXX */
835e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	res->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
836e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	res->ai_socktype = hints->ai_socktype;
837e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	res->ai_protocol = hints->ai_protocol;
838e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
839e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return res;
840e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
841e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
842e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Append the addrinfo 'append' to the end of 'first', and return the start of
843e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * the list.  Either element can be NULL, in which case we return the element
844e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * that is not NULL. */
845e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystruct evutil_addrinfo *
846fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_addrinfo_append_(struct evutil_addrinfo *first,
847e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    struct evutil_addrinfo *append)
848e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
849e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct evutil_addrinfo *ai = first;
850e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!ai)
851e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return append;
852e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	while (ai->ai_next)
853e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ai = ai->ai_next;
854e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	ai->ai_next = append;
855e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
856e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return first;
857e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
858e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
859e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
860e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyparse_numeric_servname(const char *servname)
861e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
862e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int n;
863e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	char *endptr=NULL;
864e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	n = (int) strtol(servname, &endptr, 10);
865e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (n>=0 && n <= 65535 && servname[0] && endptr && !endptr[0])
866e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return n;
867e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	else
868e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
869e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
870e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
871e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/** Parse a service name in 'servname', which can be a decimal port.
872e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Return the port number, or -1 on error.
873e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
874e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
875e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_parse_servname(const char *servname, const char *protocol,
876e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    const struct evutil_addrinfo *hints)
877e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
878e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int n = parse_numeric_servname(servname);
879e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (n>=0)
880e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return n;
881fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EVENT__HAVE_GETSERVBYNAME) || defined(_WIN32)
882e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!(hints->ai_flags & EVUTIL_AI_NUMERICSERV)) {
883e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct servent *ent = getservbyname(servname, protocol);
884e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ent) {
885e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return ntohs(ent->s_port);
886e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
887e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
888e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
889e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return -1;
890e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
891e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
892e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Return a string corresponding to a protocol number that we can pass to
893e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * getservyname.  */
894e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const char *
895e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_unparse_protoname(int proto)
896e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
897e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	switch (proto) {
898e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case 0:
899e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return NULL;
900e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case IPPROTO_TCP:
901e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "tcp";
902e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case IPPROTO_UDP:
903e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "udp";
904e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef IPPROTO_SCTP
905e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case IPPROTO_SCTP:
906e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "sctp";
907e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
908e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	default:
909fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_GETPROTOBYNUMBER
910e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		{
911e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			struct protoent *ent = getprotobynumber(proto);
912e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (ent)
913e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return ent->p_name;
914e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
915e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
916e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return NULL;
917e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
918e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
919e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
920e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic void
921e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints)
922e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
923e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* If we can guess the protocol from the socktype, do so. */
924e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!hints->ai_protocol && hints->ai_socktype) {
925e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (hints->ai_socktype == SOCK_DGRAM)
926e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			hints->ai_protocol = IPPROTO_UDP;
927e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (hints->ai_socktype == SOCK_STREAM)
928e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			hints->ai_protocol = IPPROTO_TCP;
929e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
930e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
931e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Set the socktype if it isn't set. */
932e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!hints->ai_socktype && hints->ai_protocol) {
933e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (hints->ai_protocol == IPPROTO_UDP)
934e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			hints->ai_socktype = SOCK_DGRAM;
935e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (hints->ai_protocol == IPPROTO_TCP)
936e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			hints->ai_socktype = SOCK_STREAM;
937e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef IPPROTO_SCTP
938e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (hints->ai_protocol == IPPROTO_SCTP)
939e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			hints->ai_socktype = SOCK_STREAM;
940e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
941e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
942e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
943e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
944e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#if AF_UNSPEC != PF_UNSPEC
945e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC"
946e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
947e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
948e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/** Implements the part of looking up hosts by name that's common to both
949e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * the blocking and nonblocking resolver:
950e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *   - Adjust 'hints' to have a reasonable socktype and protocol.
951e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *   - Look up the port based on 'servname', and store it in *portnum,
952e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *   - Handle the nodename==NULL case
953e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *   - Handle some invalid arguments cases.
954e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *   - Handle the cases where nodename is an IPv4 or IPv6 address.
955e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
956e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * If we need the resolver to look up the hostname, we return
957e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * EVUTIL_EAI_NEED_RESOLVE.  Otherwise, we can completely implement
958e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * getaddrinfo: we return 0 or an appropriate EVUTIL_EAI_* error, and
959e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * set *res as getaddrinfo would.
960e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
961e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
962fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_getaddrinfo_common_(const char *nodename, const char *servname,
963e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
964e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
965e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int port = 0;
966e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	const char *pname;
967e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
968e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (nodename == NULL && servname == NULL)
969e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return EVUTIL_EAI_NONAME;
970e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
971e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* We only understand 3 families */
972e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET &&
973e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    hints->ai_family != PF_INET6)
974e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return EVUTIL_EAI_FAMILY;
975e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
976e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_getaddrinfo_infer_protocols(hints);
977e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
978e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Look up the port number and protocol, if possible. */
979e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	pname = evutil_unparse_protoname(hints->ai_protocol);
980e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (servname) {
981e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* XXXX We could look at the protocol we got back from
982e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		 * getservbyname, but it doesn't seem too useful. */
983e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		port = evutil_parse_servname(servname, pname, hints);
984e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (port < 0) {
985e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return EVUTIL_EAI_NONAME;
986e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
987e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
988e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
989e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* If we have no node name, then we're supposed to bind to 'any' and
990e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * connect to localhost. */
991e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (nodename == NULL) {
992e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct evutil_addrinfo *res4=NULL, *res6=NULL;
993e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (hints->ai_family != PF_INET) { /* INET6 or UNSPEC. */
994e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			struct sockaddr_in6 sin6;
995e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			memset(&sin6, 0, sizeof(sin6));
996e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin6.sin6_family = AF_INET6;
997e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin6.sin6_port = htons(port);
998e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
999e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				/* Bind to :: */
1000e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			} else {
1001e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				/* connect to ::1 */
1002e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				sin6.sin6_addr.s6_addr[15] = 1;
1003e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			}
1004fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			res6 = evutil_new_addrinfo_((struct sockaddr*)&sin6,
1005e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			    sizeof(sin6), hints);
1006e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (!res6)
1007e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return EVUTIL_EAI_MEMORY;
1008e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1009e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1010e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (hints->ai_family != PF_INET6) { /* INET or UNSPEC */
1011e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			struct sockaddr_in sin;
1012e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			memset(&sin, 0, sizeof(sin));
1013e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin.sin_family = AF_INET;
1014e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin.sin_port = htons(port);
1015e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
1016e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				/* Bind to 0.0.0.0 */
1017e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			} else {
1018e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				/* connect to 127.0.0.1 */
1019e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				sin.sin_addr.s_addr = htonl(0x7f000001);
1020e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			}
1021fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			res4 = evutil_new_addrinfo_((struct sockaddr*)&sin,
1022e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			    sizeof(sin), hints);
1023e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (!res4) {
1024e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				if (res6)
1025e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					evutil_freeaddrinfo(res6);
1026e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return EVUTIL_EAI_MEMORY;
1027e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			}
1028e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1029fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		*res = evutil_addrinfo_append_(res4, res6);
1030e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 0;
1031e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1032e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1033e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* If we can, we should try to parse the hostname without resolving
1034e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * it. */
1035e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Try ipv6. */
1036e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
1037e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct sockaddr_in6 sin6;
1038e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(&sin6, 0, sizeof(sin6));
1039e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (1==evutil_inet_pton(AF_INET6, nodename, &sin6.sin6_addr)) {
1040e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			/* Got an ipv6 address. */
1041e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin6.sin6_family = AF_INET6;
1042e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin6.sin6_port = htons(port);
1043fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			*res = evutil_new_addrinfo_((struct sockaddr*)&sin6,
1044e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			    sizeof(sin6), hints);
1045e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (!*res)
1046e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return EVUTIL_EAI_MEMORY;
1047e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
1048e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1049e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1050e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1051e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Try ipv4. */
1052e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC) {
1053e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct sockaddr_in sin;
1054e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(&sin, 0, sizeof(sin));
1055e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
1056e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			/* Got an ipv6 address. */
1057e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin.sin_family = AF_INET;
1058e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin.sin_port = htons(port);
1059fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			*res = evutil_new_addrinfo_((struct sockaddr*)&sin,
1060e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			    sizeof(sin), hints);
1061e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (!*res)
1062e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return EVUTIL_EAI_MEMORY;
1063e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
1064e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1065e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1066e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1067e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1068e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* If we have reached this point, we definitely need to do a DNS
1069e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * lookup. */
1070e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if ((hints->ai_flags & EVUTIL_AI_NUMERICHOST)) {
1071e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* If we're not allowed to do one, then say so. */
1072e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return EVUTIL_EAI_NONAME;
1073e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1074e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	*portnum = port;
1075e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return EVUTIL_EAI_NEED_RESOLVE;
1076e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1077e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1078fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_GETADDRINFO
1079e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define USE_NATIVE_GETADDRINFO
1080e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1081e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1082e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef USE_NATIVE_GETADDRINFO
1083e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* A mask of all the flags that we declare, so we can clear them before calling
1084e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * the native getaddrinfo */
1085e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const unsigned int ALL_NONNATIVE_AI_FLAGS =
1086e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef AI_PASSIVE
1087e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    EVUTIL_AI_PASSIVE |
1088e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1089e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef AI_CANONNAME
1090e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    EVUTIL_AI_CANONNAME |
1091e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1092e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef AI_NUMERICHOST
1093e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    EVUTIL_AI_NUMERICHOST |
1094e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1095e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef AI_NUMERICSERV
1096e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    EVUTIL_AI_NUMERICSERV |
1097e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1098e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef AI_ADDRCONFIG
1099e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    EVUTIL_AI_ADDRCONFIG |
1100e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1101e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef AI_ALL
1102e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    EVUTIL_AI_ALL |
1103e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1104e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef AI_V4MAPPED
1105e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    EVUTIL_AI_V4MAPPED |
1106e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1107e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    EVUTIL_AI_LIBEVENT_ALLOCATED;
1108e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1109e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const unsigned int ALL_NATIVE_AI_FLAGS =
1110e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AI_PASSIVE
1111e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    AI_PASSIVE |
1112e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1113e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AI_CANONNAME
1114e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    AI_CANONNAME |
1115e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1116e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AI_NUMERICHOST
1117e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    AI_NUMERICHOST |
1118e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1119e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AI_NUMERICSERV
1120e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    AI_NUMERICSERV |
1121e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1122e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AI_ADDRCONFIG
1123e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    AI_ADDRCONFIG |
1124e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1125e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AI_ALL
1126e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    AI_ALL |
1127e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1128e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AI_V4MAPPED
1129e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    AI_V4MAPPED |
1130e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1131e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    0;
1132e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1133e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1134e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef USE_NATIVE_GETADDRINFO
1135e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Helper for systems with no getaddrinfo(): make one or more addrinfos out of
1136e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * a struct hostent.
1137e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
1138e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic struct evutil_addrinfo *
1139e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyaddrinfo_from_hostent(const struct hostent *ent,
1140e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    int port, const struct evutil_addrinfo *hints)
1141e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1142e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int i;
1143e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct sockaddr_in sin;
1144e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct sockaddr_in6 sin6;
1145e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct sockaddr *sa;
1146e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int socklen;
1147e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct evutil_addrinfo *res=NULL, *ai;
1148e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	void *addrp;
1149e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1150e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (ent->h_addrtype == PF_INET) {
1151e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(&sin, 0, sizeof(sin));
1152e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin.sin_family = AF_INET;
1153e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin.sin_port = htons(port);
1154e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sa = (struct sockaddr *)&sin;
1155e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		socklen = sizeof(struct sockaddr_in);
1156e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		addrp = &sin.sin_addr;
1157e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ent->h_length != sizeof(sin.sin_addr)) {
1158e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			event_warnx("Weird h_length from gethostbyname");
1159e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return NULL;
1160e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1161e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else if (ent->h_addrtype == PF_INET6) {
1162e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(&sin6, 0, sizeof(sin6));
1163e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin6.sin6_family = AF_INET6;
1164e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin6.sin6_port = htons(port);
1165e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sa = (struct sockaddr *)&sin6;
1166fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		socklen = sizeof(struct sockaddr_in6);
1167e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		addrp = &sin6.sin6_addr;
1168e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ent->h_length != sizeof(sin6.sin6_addr)) {
1169e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			event_warnx("Weird h_length from gethostbyname");
1170e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return NULL;
1171e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1172e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else
1173e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return NULL;
1174e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1175e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (i = 0; ent->h_addr_list[i]; ++i) {
1176e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memcpy(addrp, ent->h_addr_list[i], ent->h_length);
1177fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		ai = evutil_new_addrinfo_(sa, socklen, hints);
1178e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (!ai) {
1179e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			evutil_freeaddrinfo(res);
1180e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return NULL;
1181e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1182fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		res = evutil_addrinfo_append_(res, ai);
1183e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1184e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1185e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) {
1186e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		res->ai_canonname = mm_strdup(ent->h_name);
1187e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (res->ai_canonname == NULL) {
1188e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			evutil_freeaddrinfo(res);
1189e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return NULL;
1190e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1191e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1192e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1193e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return res;
1194e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1195e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1196e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1197e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* If the EVUTIL_AI_ADDRCONFIG flag is set on hints->ai_flags, and
1198e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * hints->ai_family is PF_UNSPEC, then revise the value of hints->ai_family so
1199e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * that we'll only get addresses we could maybe connect to.
1200e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
1201e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyvoid
1202fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints)
1203e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1204e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!(hints->ai_flags & EVUTIL_AI_ADDRCONFIG))
1205e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return;
1206e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (hints->ai_family != PF_UNSPEC)
1207e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return;
1208e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!have_checked_interfaces)
1209e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evutil_check_interfaces(0);
1210e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (had_ipv4_address && !had_ipv6_address) {
1211e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		hints->ai_family = PF_INET;
1212e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else if (!had_ipv4_address && had_ipv6_address) {
1213e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		hints->ai_family = PF_INET6;
1214e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1215e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1216e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1217e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef USE_NATIVE_GETADDRINFO
1218e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int need_numeric_port_hack_=0;
1219e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int need_socktype_protocol_hack_=0;
1220e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int tested_for_getaddrinfo_hacks=0;
1221e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1222e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Some older BSDs (like OpenBSD up to 4.6) used to believe that
1223e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   giving a numeric port without giving an ai_socktype was verboten.
1224e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   We test for this so we can apply an appropriate workaround.  If it
1225e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   turns out that the bug is present, then:
1226e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1227e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    - If nodename==NULL and servname is numeric, we build an answer
1228fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath      ourselves using evutil_getaddrinfo_common_().
1229e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1230e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    - If nodename!=NULL and servname is numeric, then we set
1231e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley      servname=NULL when calling getaddrinfo, and post-process the
1232e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley      result to set the ports on it.
1233e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1234e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   We test for this bug at runtime, since otherwise we can't have the
1235e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   same binary run on multiple BSD versions.
1236e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1237e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley   - Some versions of Solaris believe that it's nice to leave to protocol
1238e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley     field set to 0.  We test for this so we can apply an appropriate
1239e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley     workaround.
1240e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley*/
1241fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic struct evutil_addrinfo *ai_find_protocol(struct evutil_addrinfo *ai)
1242fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1243fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	while (ai) {
1244fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (ai->ai_protocol)
1245fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return ai;
1246fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		ai = ai->ai_next;
1247fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
1248fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return NULL;
1249fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1250e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic void
1251e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileytest_for_getaddrinfo_hacks(void)
1252e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1253e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int r, r2;
1254fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	struct evutil_addrinfo *ai=NULL, *ai2=NULL, *ai3=NULL;
1255e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct evutil_addrinfo hints;
1256e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1257e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	memset(&hints,0,sizeof(hints));
1258e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	hints.ai_family = PF_UNSPEC;
1259e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	hints.ai_flags =
1260e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AI_NUMERICHOST
1261e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    AI_NUMERICHOST |
1262e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1263e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AI_NUMERICSERV
1264e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    AI_NUMERICSERV |
1265e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1266e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    0;
1267e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	r = getaddrinfo("1.2.3.4", "80", &hints, &ai);
1268fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	getaddrinfo("1.2.3.4", NULL, &hints, &ai3);
1269e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	hints.ai_socktype = SOCK_STREAM;
1270e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	r2 = getaddrinfo("1.2.3.4", "80", &hints, &ai2);
1271e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (r2 == 0 && r != 0) {
1272e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		need_numeric_port_hack_=1;
1273e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1274fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (!ai_find_protocol(ai2) || !ai_find_protocol(ai3)) {
1275e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		need_socktype_protocol_hack_=1;
1276e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1277e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1278e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (ai)
1279e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		freeaddrinfo(ai);
1280e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (ai2)
1281e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		freeaddrinfo(ai2);
1282fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (ai3)
1283fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		freeaddrinfo(ai3);
1284e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	tested_for_getaddrinfo_hacks=1;
1285e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1286e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1287e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic inline int
1288e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyneed_numeric_port_hack(void)
1289e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1290e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!tested_for_getaddrinfo_hacks)
1291e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		test_for_getaddrinfo_hacks();
1292e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return need_numeric_port_hack_;
1293e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1294e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1295e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic inline int
1296e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyneed_socktype_protocol_hack(void)
1297e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1298e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!tested_for_getaddrinfo_hacks)
1299e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		test_for_getaddrinfo_hacks();
1300e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return need_socktype_protocol_hack_;
1301e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1302e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1303e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic void
1304e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyapply_numeric_port_hack(int port, struct evutil_addrinfo **ai)
1305e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1306e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Now we run through the list and set the ports on all of the
1307e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * results where ports would make sense. */
1308e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for ( ; *ai; ai = &(*ai)->ai_next) {
1309e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct sockaddr *sa = (*ai)->ai_addr;
1310e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (sa && sa->sa_family == AF_INET) {
1311e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			struct sockaddr_in *sin = (struct sockaddr_in*)sa;
1312e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin->sin_port = htons(port);
1313e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		} else if (sa && sa->sa_family == AF_INET6) {
1314e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
1315e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			sin6->sin6_port = htons(port);
1316e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		} else {
1317e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			/* A numeric port makes no sense here; remove this one
1318e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			 * from the list. */
1319e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			struct evutil_addrinfo *victim = *ai;
1320e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			*ai = victim->ai_next;
1321e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			victim->ai_next = NULL;
1322e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			freeaddrinfo(victim);
1323e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1324e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1325e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1326e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1327e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
1328e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyapply_socktype_protocol_hack(struct evutil_addrinfo *ai)
1329e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1330e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct evutil_addrinfo *ai_new;
1331e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (; ai; ai = ai->ai_next) {
1332e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evutil_getaddrinfo_infer_protocols(ai);
1333e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ai->ai_socktype || ai->ai_protocol)
1334e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			continue;
1335e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ai_new = mm_malloc(sizeof(*ai_new));
1336e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (!ai_new)
1337e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
1338e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memcpy(ai_new, ai, sizeof(*ai_new));
1339e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ai->ai_socktype = SOCK_STREAM;
1340e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ai->ai_protocol = IPPROTO_TCP;
1341e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ai_new->ai_socktype = SOCK_DGRAM;
1342e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ai_new->ai_protocol = IPPROTO_UDP;
1343e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1344e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ai_new->ai_next = ai->ai_next;
1345e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ai->ai_next = ai_new;
1346e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1347e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
1348e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1349e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1350e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1351e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
1352e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_getaddrinfo(const char *nodename, const char *servname,
1353e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res)
1354e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1355e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef USE_NATIVE_GETADDRINFO
1356e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct evutil_addrinfo hints;
1357e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int portnum=-1, need_np_hack, err;
1358e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1359e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (hints_in) {
1360e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memcpy(&hints, hints_in, sizeof(hints));
1361e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
1362e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(&hints, 0, sizeof(hints));
1363e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		hints.ai_family = PF_UNSPEC;
1364e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1365e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1366e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef AI_ADDRCONFIG
1367e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Not every system has AI_ADDRCONFIG, so fake it. */
1368e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (hints.ai_family == PF_UNSPEC &&
1369e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    (hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
1370fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		evutil_adjust_hints_for_addrconfig_(&hints);
1371e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1372e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1373e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1374e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef AI_NUMERICSERV
1375e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Not every system has AI_NUMERICSERV, so fake it. */
1376e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (hints.ai_flags & EVUTIL_AI_NUMERICSERV) {
1377e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (servname && parse_numeric_servname(servname)<0)
1378e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return EVUTIL_EAI_NONAME;
1379e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1380e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1381e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1382e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Enough operating systems handle enough common non-resolve
1383e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * cases here weirdly enough that we are better off just
1384e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * overriding them.  For example:
1385e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *
1386e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * - Windows doesn't like to infer the protocol from the
1387e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *   socket type, or fill in socket or protocol types much at
1388e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *   all.  It also seems to do its own broken implicit
1389e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *   always-on version of AI_ADDRCONFIG that keeps it from
1390e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *   ever resolving even a literal IPv6 address when
1391e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *   ai_addrtype is PF_UNSPEC.
1392e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 */
1393fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
1394e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	{
1395e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		int tmp_port;
1396fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		err = evutil_getaddrinfo_common_(nodename,servname,&hints,
1397e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    res, &tmp_port);
1398e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (err == 0 ||
1399e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    err == EVUTIL_EAI_MEMORY ||
1400e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    err == EVUTIL_EAI_NONAME)
1401e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return err;
1402e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* If we make it here, the system getaddrinfo can
1403e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		 * have a crack at it. */
1404e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1405e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1406e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1407e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* See documentation for need_numeric_port_hack above.*/
1408e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	need_np_hack = need_numeric_port_hack() && servname && !hints.ai_socktype
1409e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    && ((portnum=parse_numeric_servname(servname)) >= 0);
1410e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (need_np_hack) {
1411e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (!nodename)
1412fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return evutil_getaddrinfo_common_(
1413e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				NULL,servname,&hints, res, &portnum);
1414e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		servname = NULL;
1415e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1416e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1417e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (need_socktype_protocol_hack()) {
1418e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evutil_getaddrinfo_infer_protocols(&hints);
1419e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1420e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1421e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Make sure that we didn't actually steal any AI_FLAGS values that
1422e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * the system is using.  (This is a constant expression, and should ge
1423e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * optimized out.)
1424e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *
1425e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * XXXX Turn this into a compile-time failure rather than a run-time
1426e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * failure.
1427e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 */
1428e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	EVUTIL_ASSERT((ALL_NONNATIVE_AI_FLAGS & ALL_NATIVE_AI_FLAGS) == 0);
1429e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1430e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Clear any flags that only libevent understands. */
1431e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	hints.ai_flags &= ~ALL_NONNATIVE_AI_FLAGS;
1432e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1433e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	err = getaddrinfo(nodename, servname, &hints, res);
1434e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (need_np_hack)
1435e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		apply_numeric_port_hack(portnum, res);
1436e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1437e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (need_socktype_protocol_hack()) {
1438e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (apply_socktype_protocol_hack(*res) < 0) {
1439e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			evutil_freeaddrinfo(*res);
1440e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			*res = NULL;
1441e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return EVUTIL_EAI_MEMORY;
1442e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1443e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1444e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return err;
1445e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
1446e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int port=0, err;
1447e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct hostent *ent = NULL;
1448e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	struct evutil_addrinfo hints;
1449e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1450e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (hints_in) {
1451e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memcpy(&hints, hints_in, sizeof(hints));
1452e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
1453e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(&hints, 0, sizeof(hints));
1454e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		hints.ai_family = PF_UNSPEC;
1455e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1456e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1457fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	evutil_adjust_hints_for_addrconfig_(&hints);
1458e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1459fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	err = evutil_getaddrinfo_common_(nodename, servname, &hints, res, &port);
1460e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (err != EVUTIL_EAI_NEED_RESOLVE) {
1461e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* We either succeeded or failed.  No need to continue */
1462e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return err;
1463e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1464e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1465e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	err = 0;
1466e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Use any of the various gethostbyname_r variants as available. */
1467e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	{
1468fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_GETHOSTBYNAME_R_6_ARG
1469e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* This one is what glibc provides. */
1470e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		char buf[2048];
1471e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct hostent hostent;
1472e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		int r;
1473e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		r = gethostbyname_r(nodename, &hostent, buf, sizeof(buf), &ent,
1474e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    &err);
1475fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#elif defined(EVENT__HAVE_GETHOSTBYNAME_R_5_ARG)
1476e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		char buf[2048];
1477e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct hostent hostent;
1478e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ent = gethostbyname_r(nodename, &hostent, buf, sizeof(buf),
1479e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    &err);
1480fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#elif defined(EVENT__HAVE_GETHOSTBYNAME_R_3_ARG)
1481e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct hostent_data data;
1482e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct hostent hostent;
1483e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(&data, 0, sizeof(data));
1484e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		err = gethostbyname_r(nodename, &hostent, &data);
1485e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ent = err ? NULL : &hostent;
1486e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
1487e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* fall back to gethostbyname. */
1488e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* XXXX This needs a lock everywhere but Windows. */
1489e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ent = gethostbyname(nodename);
1490fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
1491e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		err = WSAGetLastError();
1492e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
1493e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		err = h_errno;
1494e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1495e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1496e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1497e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* Now we have either ent or err set. */
1498e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (!ent) {
1499e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			/* XXX is this right for windows ? */
1500e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			switch (err) {
1501e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			case TRY_AGAIN:
1502e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return EVUTIL_EAI_AGAIN;
1503e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			case NO_RECOVERY:
1504e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			default:
1505e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return EVUTIL_EAI_FAIL;
1506e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			case HOST_NOT_FOUND:
1507e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return EVUTIL_EAI_NONAME;
1508e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			case NO_ADDRESS:
1509e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#if NO_DATA != NO_ADDRESS
1510e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			case NO_DATA:
1511e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1512e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return EVUTIL_EAI_NODATA;
1513e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			}
1514e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1515e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1516e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ent->h_addrtype != hints.ai_family &&
1517e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    hints.ai_family != PF_UNSPEC) {
1518e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			/* This wasn't the type we were hoping for.  Too bad
1519e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			 * we never had a chance to ask gethostbyname for what
1520e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			 * we wanted. */
1521e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return EVUTIL_EAI_NONAME;
1522e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1523e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1524e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* Make sure we got _some_ answers. */
1525e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ent->h_length == 0)
1526e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return EVUTIL_EAI_NODATA;
1527e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1528e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* If we got an address type we don't know how to make a
1529e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		   sockaddr for, give up. */
1530e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ent->h_addrtype != PF_INET && ent->h_addrtype != PF_INET6)
1531e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return EVUTIL_EAI_FAMILY;
1532e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1533e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		*res = addrinfo_from_hostent(ent, port, &hints);
1534e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (! *res)
1535e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return EVUTIL_EAI_MEMORY;
1536e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1537e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1538e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
1539e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1540e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1541e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1542e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyvoid
1543e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_freeaddrinfo(struct evutil_addrinfo *ai)
1544e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1545fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_GETADDRINFO
1546e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!(ai->ai_flags & EVUTIL_AI_LIBEVENT_ALLOCATED)) {
1547e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		freeaddrinfo(ai);
1548e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return;
1549e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1550e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1551e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	while (ai) {
1552e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct evutil_addrinfo *next = ai->ai_next;
1553e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (ai->ai_canonname)
1554e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			mm_free(ai->ai_canonname);
1555e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		mm_free(ai);
1556e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ai = next;
1557e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1558e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1559e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1560e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic evdns_getaddrinfo_fn evdns_getaddrinfo_impl = NULL;
1561fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic evdns_getaddrinfo_cancel_fn evdns_getaddrinfo_cancel_impl = NULL;
1562e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1563e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyvoid
1564fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn)
1565e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1566e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!evdns_getaddrinfo_impl)
1567e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		evdns_getaddrinfo_impl = fn;
1568e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1569fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathvoid
1570fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel_fn fn)
1571fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1572fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (!evdns_getaddrinfo_cancel_impl)
1573fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		evdns_getaddrinfo_cancel_impl = fn;
1574fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1575e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1576e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Internal helper function: act like evdns_getaddrinfo if dns_base is set;
1577e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * otherwise do a blocking resolve and pass the result to the callback in the
1578e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * way that evdns_getaddrinfo would.
1579e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
1580fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstruct evdns_getaddrinfo_request *evutil_getaddrinfo_async_(
1581fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath    struct evdns_base *dns_base,
1582e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    const char *nodename, const char *servname,
1583e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    const struct evutil_addrinfo *hints_in,
1584e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    void (*cb)(int, struct evutil_addrinfo *, void *), void *arg)
1585e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1586e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (dns_base && evdns_getaddrinfo_impl) {
1587fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return evdns_getaddrinfo_impl(
1588e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			dns_base, nodename, servname, hints_in, cb, arg);
1589e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
1590e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct evutil_addrinfo *ai=NULL;
1591e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		int err;
1592e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		err = evutil_getaddrinfo(nodename, servname, hints_in, &ai);
1593e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		cb(err, ai, arg);
1594fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return NULL;
1595fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
1596fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1597fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1598fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathvoid evutil_getaddrinfo_cancel_async_(struct evdns_getaddrinfo_request *data)
1599fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1600fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (evdns_getaddrinfo_cancel_impl && data) {
1601fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		evdns_getaddrinfo_cancel_impl(data);
1602e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1603e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1604e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1605e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyconst char *
1606e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_gai_strerror(int err)
1607e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1608e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* As a sneaky side-benefit, this case statement will get most
1609e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * compilers to tell us if any of the error codes we defined
1610e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * conflict with the platform's native error codes. */
1611e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	switch (err) {
1612e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_CANCEL:
1613e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "Request canceled";
1614e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case 0:
1615e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "No error";
1616e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1617e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_ADDRFAMILY:
1618e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "address family for nodename not supported";
1619e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_AGAIN:
1620e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "temporary failure in name resolution";
1621e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_BADFLAGS:
1622e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "invalid value for ai_flags";
1623e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_FAIL:
1624e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "non-recoverable failure in name resolution";
1625e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_FAMILY:
1626e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "ai_family not supported";
1627e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_MEMORY:
1628e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "memory allocation failure";
1629e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_NODATA:
1630e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "no address associated with nodename";
1631e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_NONAME:
1632e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "nodename nor servname provided, or not known";
1633e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_SERVICE:
1634e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "servname not supported for ai_socktype";
1635e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_SOCKTYPE:
1636e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "ai_socktype not supported";
1637e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	case EVUTIL_EAI_SYSTEM:
1638e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "system error";
1639e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	default:
1640fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(USE_NATIVE_GETADDRINFO) && defined(_WIN32)
1641e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return gai_strerrorA(err);
1642e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#elif defined(USE_NATIVE_GETADDRINFO)
1643e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return gai_strerror(err);
1644e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
1645e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return "Unknown error code";
1646e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1647e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1648e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1649e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1650fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
1651fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath/* destructively remove a trailing line terminator from s */
1652fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic void
1653fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathchomp (char *s)
1654fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1655fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	size_t len;
1656fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (s && (len = strlen (s)) > 0 && s[len - 1] == '\n') {
1657fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		s[--len] = 0;
1658fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (len > 0 && s[len - 1] == '\r')
1659fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			s[--len] = 0;
1660fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
1661fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1662fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1663fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath/* FormatMessage returns allocated strings, but evutil_socket_error_to_string
1664fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * is supposed to return a string which is good indefinitely without having
1665fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * to be freed.  To make this work without leaking memory, we cache the
1666fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * string the first time FormatMessage is called on a particular error
1667fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * code, and then return the cached string on subsequent calls with the
1668fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * same code.  The strings aren't freed until libevent_global_shutdown
1669fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * (or never).  We use a linked list to cache the errors, because we
1670fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * only expect there to be a few dozen, and that should be fast enough.
1671fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath */
1672fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1673fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstruct cached_sock_errs_entry {
1674fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	HT_ENTRY(cached_sock_errs_entry) node;
1675fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	DWORD code;
1676fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	char *msg; /* allocated with LocalAlloc; free with LocalFree */
1677e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley};
1678fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1679fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic inline unsigned
1680fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathhash_cached_sock_errs(const struct cached_sock_errs_entry *e)
1681fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1682fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* Use Murmur3's 32-bit finalizer as an integer hash function */
1683fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	DWORD h = e->code;
1684fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	h ^= h >> 16;
1685fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	h *= 0x85ebca6b;
1686fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	h ^= h >> 13;
1687fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	h *= 0xc2b2ae35;
1688fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	h ^= h >> 16;
1689fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return h;
1690fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1691fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1692fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic inline int
1693fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamatheq_cached_sock_errs(const struct cached_sock_errs_entry *a,
1694fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    const struct cached_sock_errs_entry *b)
1695fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1696fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return a->code == b->code;
1697fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1698fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1699fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifndef EVENT__DISABLE_THREAD_SUPPORT
1700fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic void *windows_socket_errors_lock_ = NULL;
1701fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
1702fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1703fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic HT_HEAD(cached_sock_errs_map, cached_sock_errs_entry)
1704fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath     windows_socket_errors = HT_INITIALIZER();
1705fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1706fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan KamathHT_PROTOTYPE(cached_sock_errs_map,
1707fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	     cached_sock_errs_entry,
1708fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	     node,
1709fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	     hash_cached_sock_errs,
1710fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	     eq_cached_sock_errs);
1711fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1712fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan KamathHT_GENERATE(cached_sock_errs_map,
1713fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    cached_sock_errs_entry,
1714fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    node,
1715fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    hash_cached_sock_errs,
1716fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    eq_cached_sock_errs,
1717fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    0.5,
1718fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    mm_malloc,
1719fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    mm_realloc,
1720fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	    mm_free);
1721fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1722e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/** Equivalent to strerror, but for windows socket errors. */
1723e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyconst char *
1724e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_socket_error_to_string(int errcode)
1725e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1726fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	struct cached_sock_errs_entry *errs, *newerr, find;
1727fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	char *msg = NULL;
1728fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1729fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	EVLOCK_LOCK(windows_socket_errors_lock_, 0);
1730fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1731fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	find.code = errcode;
1732fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	errs = HT_FIND(cached_sock_errs_map, &windows_socket_errors, &find);
1733fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (errs) {
1734fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		msg = errs->msg;
1735fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		goto done;
1736fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
1737fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1738fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (0 != FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
1739fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			       FORMAT_MESSAGE_IGNORE_INSERTS |
1740fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			       FORMAT_MESSAGE_ALLOCATE_BUFFER,
1741fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			       NULL, errcode, 0, (char *)&msg, 0, NULL))
1742fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		chomp (msg);	/* because message has trailing newline */
1743fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	else {
1744fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		size_t len = 50;
1745fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		/* use LocalAlloc because FormatMessage does */
1746fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		msg = LocalAlloc(LMEM_FIXED, len);
1747fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (!msg) {
1748fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			msg = (char *)"LocalAlloc failed during Winsock error";
1749fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			goto done;
1750fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
1751fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		evutil_snprintf(msg, len, "winsock error 0x%08x", errcode);
1752fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
1753fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1754fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	newerr = (struct cached_sock_errs_entry *)
1755fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		mm_malloc(sizeof (struct cached_sock_errs_entry));
1756fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1757fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (!newerr) {
1758fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		LocalFree(msg);
1759fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		msg = (char *)"malloc failed during Winsock error";
1760fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		goto done;
1761fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
1762fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1763fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	newerr->code = errcode;
1764fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	newerr->msg = msg;
1765fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	HT_INSERT(cached_sock_errs_map, &windows_socket_errors, newerr);
1766fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1767fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath done:
1768fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	EVLOCK_UNLOCK(windows_socket_errors_lock_, 0);
1769fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1770fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return msg;
1771fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1772fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1773fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifndef EVENT__DISABLE_THREAD_SUPPORT
1774fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathint
1775fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_global_setup_locks_(const int enable_locks)
1776fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1777fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	EVTHREAD_SETUP_GLOBAL_LOCK(windows_socket_errors_lock_, 0);
1778fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return 0;
1779e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1780e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1781e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1782fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic void
1783fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_free_sock_err_globals(void)
1784fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1785fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	struct cached_sock_errs_entry **errs, *tofree;
1786fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1787fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	for (errs = HT_START(cached_sock_errs_map, &windows_socket_errors)
1788fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		     ; errs; ) {
1789fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		tofree = *errs;
1790fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		errs = HT_NEXT_RMV(cached_sock_errs_map,
1791fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath				   &windows_socket_errors,
1792fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath				   errs);
1793fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		LocalFree(tofree->msg);
1794fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		mm_free(tofree);
1795fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
1796fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1797fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	HT_CLEAR(cached_sock_errs_map, &windows_socket_errors);
1798fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1799fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifndef EVENT__DISABLE_THREAD_SUPPORT
1800fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (windows_socket_errors_lock_ != NULL) {
1801fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		EVTHREAD_FREE_LOCK(windows_socket_errors_lock_, 0);
1802fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		windows_socket_errors_lock_ = NULL;
1803fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
1804fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
1805fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1806fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1807fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#else
1808fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1809fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifndef EVENT__DISABLE_THREAD_SUPPORT
1810fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathint
1811fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_global_setup_locks_(const int enable_locks)
1812fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1813fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return 0;
1814fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1815fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
1816fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1817fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathstatic void
1818fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_free_sock_err_globals(void)
1819fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
1820fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
1821fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1822fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
1823fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
1824e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
1825e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_snprintf(char *buf, size_t buflen, const char *format, ...)
1826e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1827e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int r;
1828e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	va_list ap;
1829e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	va_start(ap, format);
1830e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	r = evutil_vsnprintf(buf, buflen, format, ap);
1831e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	va_end(ap);
1832e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return r;
1833e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1834e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1835e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
1836e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
1837e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1838e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int r;
1839e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!buflen)
1840e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 0;
1841fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(_MSC_VER) || defined(_WIN32)
1842e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	r = _vsnprintf(buf, buflen, format, ap);
1843e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (r < 0)
1844e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		r = _vscprintf(format, ap);
1845e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#elif defined(sgi)
1846e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Make sure we always use the correct vsnprintf on IRIX */
1847e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	extern int      _xpg5_vsnprintf(char * __restrict,
1848e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		__SGI_LIBC_NAMESPACE_QUALIFIER size_t,
1849e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const char * __restrict, /* va_list */ char *);
1850e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1851e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	r = _xpg5_vsnprintf(buf, buflen, format, ap);
1852e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
1853e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	r = vsnprintf(buf, buflen, format, ap);
1854e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1855e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	buf[buflen-1] = '\0';
1856e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return r;
1857e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1858e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1859e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define USE_INTERNAL_NTOP
1860e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define USE_INTERNAL_PTON
1861e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1862e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyconst char *
1863e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_inet_ntop(int af, const void *src, char *dst, size_t len)
1864e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1865fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EVENT__HAVE_INET_NTOP) && !defined(USE_INTERNAL_NTOP)
1866e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return inet_ntop(af, src, dst, len);
1867e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
1868e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (af == AF_INET) {
1869e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const struct in_addr *in = src;
1870e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const ev_uint32_t a = ntohl(in->s_addr);
1871e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		int r;
1872e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		r = evutil_snprintf(dst, len, "%d.%d.%d.%d",
1873e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    (int)(ev_uint8_t)((a>>24)&0xff),
1874e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    (int)(ev_uint8_t)((a>>16)&0xff),
1875e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    (int)(ev_uint8_t)((a>>8 )&0xff),
1876e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    (int)(ev_uint8_t)((a    )&0xff));
1877e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (r<0||(size_t)r>=len)
1878e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return NULL;
1879e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else
1880e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return dst;
1881e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AF_INET6
1882e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else if (af == AF_INET6) {
1883e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const struct in6_addr *addr = src;
1884e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		char buf[64], *cp;
1885e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		int longestGapLen = 0, longestGapPos = -1, i,
1886e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			curGapPos = -1, curGapLen = 0;
1887e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ev_uint16_t words[8];
1888e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		for (i = 0; i < 8; ++i) {
1889e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			words[i] =
1890e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			    (((ev_uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
1891e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1892e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
1893e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
1894e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			(words[5] == 0xffff))) {
1895e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			/* This is an IPv4 address. */
1896e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (words[5] == 0) {
1897e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				evutil_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
1898e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				    addr->s6_addr[12], addr->s6_addr[13],
1899e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				    addr->s6_addr[14], addr->s6_addr[15]);
1900e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			} else {
1901e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				evutil_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
1902e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				    addr->s6_addr[12], addr->s6_addr[13],
1903e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				    addr->s6_addr[14], addr->s6_addr[15]);
1904e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			}
1905e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (strlen(buf) > len)
1906e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return NULL;
1907e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			strlcpy(dst, buf, len);
1908e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return dst;
1909e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1910e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		i = 0;
1911e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		while (i < 8) {
1912e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (words[i] == 0) {
1913e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				curGapPos = i++;
1914e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				curGapLen = 1;
1915e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				while (i<8 && words[i] == 0) {
1916e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					++i; ++curGapLen;
1917e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				}
1918e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				if (curGapLen > longestGapLen) {
1919e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					longestGapPos = curGapPos;
1920e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					longestGapLen = curGapLen;
1921e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				}
1922e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			} else {
1923e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				++i;
1924e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			}
1925e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1926e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (longestGapLen<=1)
1927e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			longestGapPos = -1;
1928e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1929e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		cp = buf;
1930e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		for (i = 0; i < 8; ++i) {
1931e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (words[i] == 0 && longestGapPos == i) {
1932e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				if (i == 0)
1933e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					*cp++ = ':';
1934e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				*cp++ = ':';
1935e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				while (i < 8 && words[i] == 0)
1936e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					++i;
1937e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				--i; /* to compensate for loop increment. */
1938e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			} else {
1939e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				evutil_snprintf(cp,
1940e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley								sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
1941e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				cp += strlen(cp);
1942e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				if (i != 7)
1943e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					*cp++ = ':';
1944e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			}
1945e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
1946e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		*cp = '\0';
1947e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (strlen(buf) > len)
1948e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return NULL;
1949e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		strlcpy(dst, buf, len);
1950e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return dst;
1951e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1952e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
1953e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return NULL;
1954e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
1955e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
1956e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
1957e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1958e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
1959e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_inet_pton(int af, const char *src, void *dst)
1960e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
1961fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EVENT__HAVE_INET_PTON) && !defined(USE_INTERNAL_PTON)
1962e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return inet_pton(af, src, dst);
1963e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
1964e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (af == AF_INET) {
1965fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		unsigned a,b,c,d;
1966e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		char more;
1967e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct in_addr *addr = dst;
1968fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (sscanf(src, "%u.%u.%u.%u%c", &a,&b,&c,&d,&more) != 4)
1969e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
1970fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (a > 255) return 0;
1971fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (b > 255) return 0;
1972fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (c > 255) return 0;
1973fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (d > 255) return 0;
1974e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
1975e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 1;
1976e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AF_INET6
1977e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else if (af == AF_INET6) {
1978e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct in6_addr *out = dst;
1979e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ev_uint16_t words[8];
1980e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		int gapPos = -1, i, setWords=0;
1981e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const char *dot = strchr(src, '.');
1982e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const char *eow; /* end of words. */
1983e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (dot == src)
1984e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
1985e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (!dot)
1986e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			eow = src+strlen(src);
1987e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else {
1988fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			unsigned byte1,byte2,byte3,byte4;
1989e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			char more;
1990fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT_(*eow); --eow)
1991e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				;
1992e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			++eow;
1993e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
1994e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			/* We use "scanf" because some platform inet_aton()s are too lax
1995e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			 * about IPv4 addresses of the form "1.2.3" */
1996fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			if (sscanf(eow, "%u.%u.%u.%u%c",
1997e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					   &byte1,&byte2,&byte3,&byte4,&more) != 4)
1998e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return 0;
1999e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2000fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			if (byte1 > 255 ||
2001fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			    byte2 > 255 ||
2002fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			    byte3 > 255 ||
2003fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			    byte4 > 255)
2004e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return 0;
2005e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2006e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			words[6] = (byte1<<8) | byte2;
2007e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			words[7] = (byte3<<8) | byte4;
2008e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			setWords += 2;
2009e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2010e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2011e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		i = 0;
2012e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		while (src < eow) {
2013e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (i > 7)
2014e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return 0;
2015fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			if (EVUTIL_ISXDIGIT_(*src)) {
2016e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				char *next;
2017e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				long r = strtol(src, &next, 16);
2018e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				if (next > 4+src)
2019e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					return 0;
2020e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				if (next == src)
2021e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					return 0;
2022e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				if (r<0 || r>65536)
2023e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					return 0;
2024e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2025e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				words[i++] = (ev_uint16_t)r;
2026e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				setWords++;
2027e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				src = next;
2028e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				if (*src != ':' && src != eow)
2029e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					return 0;
2030e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				++src;
2031e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			} else if (*src == ':' && i > 0 && gapPos==-1) {
2032e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				gapPos = i;
2033e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				++src;
2034e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			} else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
2035e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				gapPos = i;
2036e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				src += 2;
2037e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			} else {
2038e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return 0;
2039e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			}
2040e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2041e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2042e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (setWords > 8 ||
2043e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			(setWords == 8 && gapPos != -1) ||
2044e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			(setWords < 8 && gapPos == -1))
2045e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
2046e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2047e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (gapPos >= 0) {
2048e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			int nToMove = setWords - (dot ? 2 : 0) - gapPos;
2049e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			int gapLen = 8 - setWords;
2050e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			/* assert(nToMove >= 0); */
2051e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (nToMove < 0)
2052e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return -1; /* should be impossible */
2053e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			memmove(&words[gapPos+gapLen], &words[gapPos],
2054e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					sizeof(ev_uint16_t)*nToMove);
2055e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			memset(&words[gapPos], 0, sizeof(ev_uint16_t)*gapLen);
2056e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2057e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		for (i = 0; i < 8; ++i) {
2058e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			out->s6_addr[2*i  ] = words[i] >> 8;
2059e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			out->s6_addr[2*i+1] = words[i] & 0xff;
2060e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2061e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2062e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 1;
2063e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2064e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
2065e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
2066e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2067e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2068e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2069e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2070e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
2071e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
2072e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2073e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int port;
2074e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	char buf[128];
2075e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	const char *cp, *addr_part, *port_part;
2076e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int is_ipv6;
2077e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* recognized formats are:
2078e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * [ipv6]:port
2079e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * ipv6
2080e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * [ipv6]
2081e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * ipv4:port
2082e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * ipv4
2083e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 */
2084e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2085e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	cp = strchr(ip_as_string, ':');
2086e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (*ip_as_string == '[') {
2087fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		size_t len;
2088e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (!(cp = strchr(ip_as_string, ']'))) {
2089e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2090e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2091fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		len = ( cp-(ip_as_string + 1) );
2092fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (len > sizeof(buf)-1) {
2093e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2094e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2095e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memcpy(buf, ip_as_string+1, len);
2096e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		buf[len] = '\0';
2097e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		addr_part = buf;
2098e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (cp[1] == ':')
2099e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			port_part = cp+2;
2100e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else
2101e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			port_part = NULL;
2102e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		is_ipv6 = 1;
2103e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else if (cp && strchr(cp+1, ':')) {
2104e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		is_ipv6 = 1;
2105e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		addr_part = ip_as_string;
2106e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		port_part = NULL;
2107e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else if (cp) {
2108e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		is_ipv6 = 0;
2109e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (cp - ip_as_string > (int)sizeof(buf)-1) {
2110e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2111e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2112e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memcpy(buf, ip_as_string, cp-ip_as_string);
2113e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		buf[cp-ip_as_string] = '\0';
2114e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		addr_part = buf;
2115e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		port_part = cp+1;
2116e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
2117e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		addr_part = ip_as_string;
2118e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		port_part = NULL;
2119e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		is_ipv6 = 0;
2120e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2121e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2122e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (port_part == NULL) {
2123e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		port = 0;
2124e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else {
2125e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		port = atoi(port_part);
2126e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (port <= 0 || port > 65535) {
2127e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2128e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2129e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2130e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2131e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!addr_part)
2132e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1; /* Should be impossible. */
2133e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AF_INET6
2134e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (is_ipv6)
2135e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	{
2136e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct sockaddr_in6 sin6;
2137e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(&sin6, 0, sizeof(sin6));
2138fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
2139e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin6.sin6_len = sizeof(sin6);
2140e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2141e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin6.sin6_family = AF_INET6;
2142e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin6.sin6_port = htons(port);
2143e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (1 != evutil_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr))
2144e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2145e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if ((int)sizeof(sin6) > *outlen)
2146e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2147e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(out, 0, *outlen);
2148e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memcpy(out, &sin6, sizeof(sin6));
2149e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		*outlen = sizeof(sin6);
2150e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 0;
2151e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2152e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	else
2153e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2154e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	{
2155e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct sockaddr_in sin;
2156e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(&sin, 0, sizeof(sin));
2157fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
2158e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin.sin_len = sizeof(sin);
2159e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2160e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin.sin_family = AF_INET;
2161e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin.sin_port = htons(port);
2162e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr))
2163e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2164e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if ((int)sizeof(sin) > *outlen)
2165e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2166e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(out, 0, *outlen);
2167e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memcpy(out, &sin, sizeof(sin));
2168e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		*outlen = sizeof(sin);
2169e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 0;
2170e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2171e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2172e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2173e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyconst char *
2174fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen)
2175e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2176e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	char b[128];
2177e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	const char *res=NULL;
2178e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int port;
2179e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (sa->sa_family == AF_INET) {
2180e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const struct sockaddr_in *sin = (const struct sockaddr_in*)sa;
2181e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		res = evutil_inet_ntop(AF_INET, &sin->sin_addr,b,sizeof(b));
2182e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		port = ntohs(sin->sin_port);
2183e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (res) {
2184e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			evutil_snprintf(out, outlen, "%s:%d", b, port);
2185e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return out;
2186e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2187e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else if (sa->sa_family == AF_INET6) {
2188e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6*)sa;
2189e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		res = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr,b,sizeof(b));
2190e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		port = ntohs(sin6->sin6_port);
2191e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (res) {
2192e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			evutil_snprintf(out, outlen, "[%s]:%d", b, port);
2193e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return out;
2194e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
2195e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2196e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2197e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_snprintf(out, outlen, "<addr with socktype %d>",
2198e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    (int)sa->sa_family);
2199e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return out;
2200e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2201e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2202e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
2203e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
2204e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    int include_port)
2205e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2206e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int r;
2207e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (0 != (r = (sa1->sa_family - sa2->sa_family)))
2208e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return r;
2209e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2210e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (sa1->sa_family == AF_INET) {
2211e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const struct sockaddr_in *sin1, *sin2;
2212e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin1 = (const struct sockaddr_in *)sa1;
2213e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin2 = (const struct sockaddr_in *)sa2;
2214e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
2215e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2216e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
2217e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 1;
2218e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (include_port &&
2219e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    (r = ((int)sin1->sin_port - (int)sin2->sin_port)))
2220e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return r;
2221e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else
2222e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
2223e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2224e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef AF_INET6
2225e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	else if (sa1->sa_family == AF_INET6) {
2226e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		const struct sockaddr_in6 *sin1, *sin2;
2227e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin1 = (const struct sockaddr_in6 *)sa1;
2228e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		sin2 = (const struct sockaddr_in6 *)sa2;
2229e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
2230e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return r;
2231e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (include_port &&
2232e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    (r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
2233e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return r;
2234e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else
2235e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
2236e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2237e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2238e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 1;
2239e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2240e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2241e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Tables to implement ctypes-replacement EVUTIL_IS*() functions.  Each table
2242e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * has 256 bits to look up whether a character is in some set or not.  This
2243e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * fails on non-ASCII platforms, but so does every other place where we
2244e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * take a char and write it onto the network.
2245e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley **/
2246e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const ev_uint32_t EVUTIL_ISALPHA_TABLE[8] =
2247e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
2248e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const ev_uint32_t EVUTIL_ISALNUM_TABLE[8] =
2249e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
2250e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const ev_uint32_t EVUTIL_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
2251e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const ev_uint32_t EVUTIL_ISXDIGIT_TABLE[8] =
2252e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
2253e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const ev_uint32_t EVUTIL_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
2254e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const ev_uint32_t EVUTIL_ISPRINT_TABLE[8] =
2255e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
2256e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const ev_uint32_t EVUTIL_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
2257e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const ev_uint32_t EVUTIL_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
2258e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Upper-casing and lowercasing tables to map characters to upper/lowercase
2259e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * equivalents. */
2260e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const unsigned char EVUTIL_TOUPPER_TABLE[256] = {
2261e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2262e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2263e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2264e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2265e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2266e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
2267e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2268e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
2269e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2270e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2271e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2272e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2273e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2274e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2275e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2276e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2277e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley};
2278e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
2279e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2280e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2281e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2282e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2283e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2284e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
2285e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2286e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
2287e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2288e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2289e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2290e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2291e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2292e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2293e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2294e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2295e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley};
2296e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2297e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define IMPL_CTYPE_FN(name)						\
2298fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	int EVUTIL_##name##_(char c) {					\
2299e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ev_uint8_t u = c;					\
2300e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31))); \
2301e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2302e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyIMPL_CTYPE_FN(ISALPHA)
2303e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyIMPL_CTYPE_FN(ISALNUM)
2304e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyIMPL_CTYPE_FN(ISSPACE)
2305e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyIMPL_CTYPE_FN(ISDIGIT)
2306e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyIMPL_CTYPE_FN(ISXDIGIT)
2307e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyIMPL_CTYPE_FN(ISPRINT)
2308e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyIMPL_CTYPE_FN(ISLOWER)
2309e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyIMPL_CTYPE_FN(ISUPPER)
2310e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2311fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathchar EVUTIL_TOLOWER_(char c)
2312e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2313e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return ((char)EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]);
2314e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2315fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathchar EVUTIL_TOUPPER_(char c)
2316e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2317e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return ((char)EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]);
2318e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2319e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
2320e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_ascii_strcasecmp(const char *s1, const char *s2)
2321e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2322e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	char c1, c2;
2323e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	while (1) {
2324fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		c1 = EVUTIL_TOLOWER_(*s1++);
2325fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		c2 = EVUTIL_TOLOWER_(*s2++);
2326e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (c1 < c2)
2327e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2328e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (c1 > c2)
2329e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 1;
2330e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (c1 == 0)
2331e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
2332e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2333e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2334e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint evutil_ascii_strncasecmp(const char *s1, const char *s2, size_t n)
2335e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2336e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	char c1, c2;
2337e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	while (n--) {
2338fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		c1 = EVUTIL_TOLOWER_(*s1++);
2339fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		c2 = EVUTIL_TOLOWER_(*s2++);
2340e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (c1 < c2)
2341e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
2342e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (c1 > c2)
2343e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 1;
2344e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (c1 == 0)
2345e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
2346e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2347e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
2348e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2349e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2350fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathvoid
2351fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_rtrim_lws_(char *str)
2352fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
2353fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	char *cp;
2354fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2355fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (str == NULL)
2356fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return;
2357fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2358fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if ((cp = strchr(str, '\0')) == NULL || (cp == str))
2359fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return;
2360fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2361fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	--cp;
2362fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2363fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	while (*cp == ' ' || *cp == '\t') {
2364fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		*cp = '\0';
2365fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (cp == str)
2366fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			break;
2367fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		--cp;
2368fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2369fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
2370fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2371e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
2372e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_issetugid(void)
2373e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2374fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_ISSETUGID
2375e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return issetugid();
2376e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
2377e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2378fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_GETEUID
2379e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (getuid() != geteuid())
2380e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 1;
2381e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2382fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef EVENT__HAVE_GETEGID
2383e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (getgid() != getegid())
2384e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 1;
2385e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2386e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
2387e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2388e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2389e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2390e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyconst char *
2391fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_getenv_(const char *varname)
2392e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2393e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (evutil_issetugid())
2394e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return NULL;
2395e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2396e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return getenv(varname);
2397e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2398e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2399fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathev_uint32_t
2400fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed)
2401e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2402fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (seed == 0) {
2403fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		struct timeval tv;
2404fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		evutil_gettimeofday(&tv, NULL);
2405fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		seed = (ev_uint32_t)tv.tv_sec + (ev_uint32_t)tv.tv_usec;
2406fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
2407fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		seed += (ev_uint32_t) _getpid();
2408e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
2409fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		seed += (ev_uint32_t) getpid();
2410e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2411fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2412fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	state->seed = seed;
2413fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return seed;
2414fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
2415fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2416fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathev_int32_t
2417fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_weakrand_(struct evutil_weakrand_state *state)
2418fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
2419fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* This RNG implementation is a linear congruential generator, with
2420fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * modulus 2^31, multiplier 1103515245, and addend 12345.  It's also
2421fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * used by OpenBSD, and by Glibc's TYPE_0 RNG.
2422fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 *
2423fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * The linear congruential generator is not an industrial-strength
2424fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * RNG!  It's fast, but it can have higher-order patterns.  Notably,
2425fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * the low bits tend to have periodicity.
2426fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 */
2427fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	state->seed = ((state->seed) * 1103515245 + 12345) & 0x7fffffff;
2428fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return (ev_int32_t)(state->seed);
2429fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
2430fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2431fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathev_int32_t
2432fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_weakrand_range_(struct evutil_weakrand_state *state, ev_int32_t top)
2433fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
2434fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	ev_int32_t divisor, result;
2435fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2436fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/* We can't just do weakrand() % top, since the low bits of the LCG
2437fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * are less random than the high ones.  (Specifically, since the LCG
2438fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * modulus is 2^N, every 2^m for m<N will divide the modulus, and so
2439fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	 * therefore the low m bits of the LCG will have period 2^m.) */
2440fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	divisor = EVUTIL_WEAKRAND_MAX / top;
2441fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	do {
2442fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		result = evutil_weakrand_(state) / divisor;
2443fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	} while (result >= top);
2444fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return result;
2445e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2446e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2447e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/**
2448e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Volatile pointer to memset: we use this to keep the compiler from
2449e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * eliminating our call to memset.
2450e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
2451e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyvoid * (*volatile evutil_memset_volatile_)(void *, int, size_t) = memset;
2452e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2453e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyvoid
2454e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyevutil_memclear_(void *mem, size_t len)
2455e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2456e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_memset_volatile_(mem, 0, len);
2457e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2458e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2459e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
2460fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_sockaddr_is_loopback_(const struct sockaddr *addr)
2461e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2462e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	static const char LOOPBACK_S6[16] =
2463e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
2464e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (addr->sa_family == AF_INET) {
2465e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct sockaddr_in *sin = (struct sockaddr_in *)addr;
2466e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
2467e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	} else if (addr->sa_family == AF_INET6) {
2468e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
2469e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
2470e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2471e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
2472e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2473e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2474e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyint
2475fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_hex_char_to_int_(char c)
2476e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2477e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	switch(c)
2478e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	{
2479e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '0': return 0;
2480e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '1': return 1;
2481e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '2': return 2;
2482e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '3': return 3;
2483e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '4': return 4;
2484e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '5': return 5;
2485e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '6': return 6;
2486e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '7': return 7;
2487e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '8': return 8;
2488e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case '9': return 9;
2489e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case 'A': case 'a': return 10;
2490e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case 'B': case 'b': return 11;
2491e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case 'C': case 'c': return 12;
2492e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case 'D': case 'd': return 13;
2493e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case 'E': case 'e': return 14;
2494e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		case 'F': case 'f': return 15;
2495e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
2496e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return -1;
2497e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2498e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2499fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
2500fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan KamathHMODULE
2501fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_load_windows_system_library_(const TCHAR *library_name)
2502e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
2503e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  TCHAR path[MAX_PATH];
2504e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  unsigned n;
2505e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  n = GetSystemDirectory(path, MAX_PATH);
2506e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
2507e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley    return 0;
2508e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  _tcscat(path, TEXT("\\"));
2509e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  _tcscat(path, library_name);
2510e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley  return LoadLibrary(path);
2511e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
2512e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
2513e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
2514fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath/* Internal wrapper around 'socket' to provide Linux-style support for
2515fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * syscall-saving methods where available.
2516fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath *
2517fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * In addition to regular socket behavior, you can use a bitwise or to set the
2518fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * flags EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'type' argument,
2519fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * to make the socket nonblocking or close-on-exec with as few syscalls as
2520fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * possible.
2521fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath */
2522fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_socket_t
2523fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_socket_(int domain, int type, int protocol)
2524fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
2525fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	evutil_socket_t r;
2526fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
2527fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	r = socket(domain, type, protocol);
2528fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (r >= 0)
2529fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return r;
2530fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	else if ((type & (SOCK_NONBLOCK|SOCK_CLOEXEC)) == 0)
2531fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return -1;
2532fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
2533fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#define SOCKET_TYPE_MASK (~(EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC))
2534fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	r = socket(domain, type & SOCKET_TYPE_MASK, protocol);
2535fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (r < 0)
2536fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return -1;
2537fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (type & EVUTIL_SOCK_NONBLOCK) {
2538fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (evutil_fast_socket_nonblocking(r) < 0) {
2539fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			evutil_closesocket(r);
2540fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return -1;
2541fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
2542fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2543fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (type & EVUTIL_SOCK_CLOEXEC) {
2544fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (evutil_fast_socket_closeonexec(r) < 0) {
2545fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			evutil_closesocket(r);
2546fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return -1;
2547fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
2548fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2549fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return r;
2550fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
2551fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2552fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath/* Internal wrapper around 'accept' or 'accept4' to provide Linux-style
2553fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * support for syscall-saving methods where available.
2554fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath *
2555fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * In addition to regular accept behavior, you can set one or more of flags
2556fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'flags' argument, to
2557fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * make the socket nonblocking or close-on-exec with as few syscalls as
2558fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * possible.
2559fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath */
2560fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_socket_t
2561fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr,
2562fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath    ev_socklen_t *addrlen, int flags)
2563fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
2564fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	evutil_socket_t result;
2565fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EVENT__HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
2566fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	result = accept4(sockfd, addr, addrlen, flags);
2567fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (result >= 0 || (errno != EINVAL && errno != ENOSYS)) {
2568fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		/* A nonnegative result means that we succeeded, so return.
2569fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		 * Failing with EINVAL means that an option wasn't supported,
2570fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		 * and failing with ENOSYS means that the syscall wasn't
2571fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		 * there: in those cases we want to fall back.  Otherwise, we
2572fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		 * got a real error, and we should return. */
2573fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return result;
2574fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2575fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
2576fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	result = accept(sockfd, addr, addrlen);
2577fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (result < 0)
2578fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return result;
2579fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2580fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (flags & EVUTIL_SOCK_CLOEXEC) {
2581fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (evutil_fast_socket_closeonexec(result) < 0) {
2582fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			evutil_closesocket(result);
2583fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return -1;
2584fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
2585fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2586fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (flags & EVUTIL_SOCK_NONBLOCK) {
2587fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (evutil_fast_socket_nonblocking(result) < 0) {
2588fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			evutil_closesocket(result);
2589fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return -1;
2590fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
2591fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2592fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return result;
2593fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
2594fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2595fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath/* Internal function: Set fd[0] and fd[1] to a pair of fds such that writes on
2596fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * fd[0] get read from fd[1].  Make both fds nonblocking and close-on-exec.
2597fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * Return 0 on success, -1 on failure.
2598fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath */
2599fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathint
2600fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_make_internal_pipe_(evutil_socket_t fd[2])
2601fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
2602fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	/*
2603fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	  Making the second socket nonblocking is a bit subtle, given that we
2604fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	  ignore any EAGAIN returns when writing to it, and you don't usally
2605fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	  do that for a nonblocking socket. But if the kernel gives us EAGAIN,
2606fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	  then there's no need to add any more data to the buffer, since
2607fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	  the main thread is already either about to wake up and drain it,
2608fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	  or woken up and in the process of draining it.
2609fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	*/
2610fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2611fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EVENT__HAVE_PIPE2)
2612fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (pipe2(fd, O_NONBLOCK|O_CLOEXEC) == 0)
2613fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return 0;
2614fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
2615fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EVENT__HAVE_PIPE)
2616fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (pipe(fd) == 0) {
2617fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (evutil_fast_socket_nonblocking(fd[0]) < 0 ||
2618fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    evutil_fast_socket_nonblocking(fd[1]) < 0 ||
2619fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    evutil_fast_socket_closeonexec(fd[0]) < 0 ||
2620fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    evutil_fast_socket_closeonexec(fd[1]) < 0) {
2621fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			close(fd[0]);
2622fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			close(fd[1]);
2623fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			fd[0] = fd[1] = -1;
2624fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return -1;
2625fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
2626fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return 0;
2627fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	} else {
2628fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		event_warn("%s: pipe", __func__);
2629fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2630fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
2631fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2632fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#ifdef _WIN32
2633fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#define LOCAL_SOCKETPAIR_AF AF_INET
2634fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#else
2635fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#define LOCAL_SOCKETPAIR_AF AF_UNIX
2636fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
2637fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, fd) == 0) {
2638fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (evutil_fast_socket_nonblocking(fd[0]) < 0 ||
2639fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    evutil_fast_socket_nonblocking(fd[1]) < 0 ||
2640fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    evutil_fast_socket_closeonexec(fd[0]) < 0 ||
2641fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		    evutil_fast_socket_closeonexec(fd[1]) < 0) {
2642fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			evutil_closesocket(fd[0]);
2643fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			evutil_closesocket(fd[1]);
2644fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			fd[0] = fd[1] = -1;
2645fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return -1;
2646fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
2647fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return 0;
2648fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2649fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	fd[0] = fd[1] = -1;
2650fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return -1;
2651fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
2652fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2653fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath/* Wrapper around eventfd on systems that provide it.  Unlike the system
2654fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * eventfd, it always supports EVUTIL_EFD_CLOEXEC and EVUTIL_EFD_NONBLOCK as
2655fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath * flags.  Returns -1 on error or if eventfd is not supported.
2656fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath */
2657fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_socket_t
2658fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_eventfd_(unsigned initval, int flags)
2659fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
2660fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EVENT__HAVE_EVENTFD) && defined(EVENT__HAVE_SYS_EVENTFD_H)
2661fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	int r;
2662fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
2663fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	r = eventfd(initval, flags);
2664fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (r >= 0 || flags == 0)
2665fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return r;
2666fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
2667fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	r = eventfd(initval, 0);
2668fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (r < 0)
2669fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		return r;
2670fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (flags & EVUTIL_EFD_CLOEXEC) {
2671fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (evutil_fast_socket_closeonexec(r) < 0) {
2672fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			evutil_closesocket(r);
2673fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return -1;
2674fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
2675fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2676fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	if (flags & EVUTIL_EFD_NONBLOCK) {
2677fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		if (evutil_fast_socket_nonblocking(r) < 0) {
2678fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			evutil_closesocket(r);
2679fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath			return -1;
2680fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath		}
2681fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	}
2682fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return r;
2683fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#else
2684fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	return -1;
2685fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath#endif
2686fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
2687fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath
2688fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathvoid
2689fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamathevutil_free_globals_(void)
2690fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath{
2691fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	evutil_free_secure_rng_globals_();
2692fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath	evutil_free_sock_err_globals();
2693fc74cb45eafe51162b10a850016c6d2e1f8fd23cNarayan Kamath}
2694