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