xref: /freebsd/contrib/ntp/sntp/libevent/evutil.c (revision a466cc55373fc3cf86837f09da729535b57e69a1)
12b15cb3dSCy Schubert /*
22b15cb3dSCy Schubert  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
32b15cb3dSCy Schubert  *
42b15cb3dSCy Schubert  * Redistribution and use in source and binary forms, with or without
52b15cb3dSCy Schubert  * modification, are permitted provided that the following conditions
62b15cb3dSCy Schubert  * are met:
72b15cb3dSCy Schubert  * 1. Redistributions of source code must retain the above copyright
82b15cb3dSCy Schubert  *    notice, this list of conditions and the following disclaimer.
92b15cb3dSCy Schubert  * 2. Redistributions in binary form must reproduce the above copyright
102b15cb3dSCy Schubert  *    notice, this list of conditions and the following disclaimer in the
112b15cb3dSCy Schubert  *    documentation and/or other materials provided with the distribution.
122b15cb3dSCy Schubert  * 3. The name of the author may not be used to endorse or promote products
132b15cb3dSCy Schubert  *    derived from this software without specific prior written permission.
142b15cb3dSCy Schubert  *
152b15cb3dSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
162b15cb3dSCy Schubert  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
172b15cb3dSCy Schubert  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
182b15cb3dSCy Schubert  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
192b15cb3dSCy Schubert  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
202b15cb3dSCy Schubert  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
212b15cb3dSCy Schubert  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
222b15cb3dSCy Schubert  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
232b15cb3dSCy Schubert  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
242b15cb3dSCy Schubert  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
252b15cb3dSCy Schubert  */
262b15cb3dSCy Schubert 
272b15cb3dSCy Schubert #include "event2/event-config.h"
282b15cb3dSCy Schubert #include "evconfig-private.h"
292b15cb3dSCy Schubert 
302b15cb3dSCy Schubert #ifdef _WIN32
312b15cb3dSCy Schubert #include <winsock2.h>
32*a466cc55SCy Schubert #include <winerror.h>
332b15cb3dSCy Schubert #include <ws2tcpip.h>
342b15cb3dSCy Schubert #define WIN32_LEAN_AND_MEAN
352b15cb3dSCy Schubert #include <windows.h>
362b15cb3dSCy Schubert #undef WIN32_LEAN_AND_MEAN
372b15cb3dSCy Schubert #include <io.h>
382b15cb3dSCy Schubert #include <tchar.h>
392b15cb3dSCy Schubert #include <process.h>
402b15cb3dSCy Schubert #undef _WIN32_WINNT
412b15cb3dSCy Schubert /* For structs needed by GetAdaptersAddresses */
422b15cb3dSCy Schubert #define _WIN32_WINNT 0x0501
432b15cb3dSCy Schubert #include <iphlpapi.h>
44*a466cc55SCy Schubert #include <netioapi.h>
452b15cb3dSCy Schubert #endif
462b15cb3dSCy Schubert 
472b15cb3dSCy Schubert #include <sys/types.h>
482b15cb3dSCy Schubert #ifdef EVENT__HAVE_SYS_SOCKET_H
492b15cb3dSCy Schubert #include <sys/socket.h>
502b15cb3dSCy Schubert #endif
512b15cb3dSCy Schubert #ifdef EVENT__HAVE_UNISTD_H
522b15cb3dSCy Schubert #include <unistd.h>
532b15cb3dSCy Schubert #endif
542b15cb3dSCy Schubert #ifdef EVENT__HAVE_FCNTL_H
552b15cb3dSCy Schubert #include <fcntl.h>
562b15cb3dSCy Schubert #endif
572b15cb3dSCy Schubert #ifdef EVENT__HAVE_STDLIB_H
582b15cb3dSCy Schubert #include <stdlib.h>
592b15cb3dSCy Schubert #endif
602b15cb3dSCy Schubert #include <errno.h>
612b15cb3dSCy Schubert #include <limits.h>
622b15cb3dSCy Schubert #include <stdio.h>
632b15cb3dSCy Schubert #include <string.h>
642b15cb3dSCy Schubert #ifdef EVENT__HAVE_NETINET_IN_H
652b15cb3dSCy Schubert #include <netinet/in.h>
662b15cb3dSCy Schubert #endif
672b15cb3dSCy Schubert #ifdef EVENT__HAVE_NETINET_IN6_H
682b15cb3dSCy Schubert #include <netinet/in6.h>
692b15cb3dSCy Schubert #endif
702b15cb3dSCy Schubert #ifdef EVENT__HAVE_NETINET_TCP_H
712b15cb3dSCy Schubert #include <netinet/tcp.h>
722b15cb3dSCy Schubert #endif
732b15cb3dSCy Schubert #ifdef EVENT__HAVE_ARPA_INET_H
742b15cb3dSCy Schubert #include <arpa/inet.h>
752b15cb3dSCy Schubert #endif
762b15cb3dSCy Schubert #include <time.h>
772b15cb3dSCy Schubert #include <sys/stat.h>
78*a466cc55SCy Schubert #ifndef _WIN32
79*a466cc55SCy Schubert #include <net/if.h>
80*a466cc55SCy Schubert #endif
812b15cb3dSCy Schubert #ifdef EVENT__HAVE_IFADDRS_H
822b15cb3dSCy Schubert #include <ifaddrs.h>
832b15cb3dSCy Schubert #endif
842b15cb3dSCy Schubert 
852b15cb3dSCy Schubert #include "event2/util.h"
862b15cb3dSCy Schubert #include "util-internal.h"
872b15cb3dSCy Schubert #include "log-internal.h"
882b15cb3dSCy Schubert #include "mm-internal.h"
892b15cb3dSCy Schubert #include "evthread-internal.h"
902b15cb3dSCy Schubert 
912b15cb3dSCy Schubert #include "strlcpy-internal.h"
922b15cb3dSCy Schubert #include "ipv6-internal.h"
932b15cb3dSCy Schubert 
942b15cb3dSCy Schubert #ifdef _WIN32
952b15cb3dSCy Schubert #define HT_NO_CACHE_HASH_VALUES
962b15cb3dSCy Schubert #include "ht-internal.h"
972b15cb3dSCy Schubert #define open _open
982b15cb3dSCy Schubert #define read _read
992b15cb3dSCy Schubert #define close _close
1002b15cb3dSCy Schubert #ifndef fstat
1012b15cb3dSCy Schubert #define fstat _fstati64
1022b15cb3dSCy Schubert #endif
1032b15cb3dSCy Schubert #ifndef stat
1042b15cb3dSCy Schubert #define stat _stati64
1052b15cb3dSCy Schubert #endif
1062b15cb3dSCy Schubert #define mode_t int
1072b15cb3dSCy Schubert #endif
1082b15cb3dSCy Schubert 
1092b15cb3dSCy Schubert int
evutil_open_closeonexec_(const char * pathname,int flags,unsigned mode)1102b15cb3dSCy Schubert evutil_open_closeonexec_(const char *pathname, int flags, unsigned mode)
1112b15cb3dSCy Schubert {
1122b15cb3dSCy Schubert 	int fd;
1132b15cb3dSCy Schubert 
1142b15cb3dSCy Schubert #ifdef O_CLOEXEC
1152b15cb3dSCy Schubert 	fd = open(pathname, flags|O_CLOEXEC, (mode_t)mode);
1162b15cb3dSCy Schubert 	if (fd >= 0 || errno == EINVAL)
1172b15cb3dSCy Schubert 		return fd;
1182b15cb3dSCy Schubert 	/* If we got an EINVAL, fall through and try without O_CLOEXEC */
1192b15cb3dSCy Schubert #endif
1202b15cb3dSCy Schubert 	fd = open(pathname, flags, (mode_t)mode);
1212b15cb3dSCy Schubert 	if (fd < 0)
1222b15cb3dSCy Schubert 		return -1;
1232b15cb3dSCy Schubert 
1242b15cb3dSCy Schubert #if defined(FD_CLOEXEC)
1252b15cb3dSCy Schubert 	if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
1262b15cb3dSCy Schubert 		close(fd);
1272b15cb3dSCy Schubert 		return -1;
1282b15cb3dSCy Schubert 	}
1292b15cb3dSCy Schubert #endif
1302b15cb3dSCy Schubert 
1312b15cb3dSCy Schubert 	return fd;
1322b15cb3dSCy Schubert }
1332b15cb3dSCy Schubert 
1342b15cb3dSCy Schubert /**
1352b15cb3dSCy Schubert    Read the contents of 'filename' into a newly allocated NUL-terminated
1362b15cb3dSCy Schubert    string.  Set *content_out to hold this string, and *len_out to hold its
1372b15cb3dSCy Schubert    length (not including the appended NUL).  If 'is_binary', open the file in
1382b15cb3dSCy Schubert    binary mode.
1392b15cb3dSCy Schubert 
1402b15cb3dSCy Schubert    Returns 0 on success, -1 if the open fails, and -2 for all other failures.
1412b15cb3dSCy Schubert 
1422b15cb3dSCy Schubert    Used internally only; may go away in a future version.
1432b15cb3dSCy Schubert  */
1442b15cb3dSCy Schubert int
evutil_read_file_(const char * filename,char ** content_out,size_t * len_out,int is_binary)1452b15cb3dSCy Schubert evutil_read_file_(const char *filename, char **content_out, size_t *len_out,
1462b15cb3dSCy Schubert     int is_binary)
1472b15cb3dSCy Schubert {
1482b15cb3dSCy Schubert 	int fd, r;
1492b15cb3dSCy Schubert 	struct stat st;
1502b15cb3dSCy Schubert 	char *mem;
1512b15cb3dSCy Schubert 	size_t read_so_far=0;
1522b15cb3dSCy Schubert 	int mode = O_RDONLY;
1532b15cb3dSCy Schubert 
1542b15cb3dSCy Schubert 	EVUTIL_ASSERT(content_out);
1552b15cb3dSCy Schubert 	EVUTIL_ASSERT(len_out);
1562b15cb3dSCy Schubert 	*content_out = NULL;
1572b15cb3dSCy Schubert 	*len_out = 0;
1582b15cb3dSCy Schubert 
1592b15cb3dSCy Schubert #ifdef O_BINARY
1602b15cb3dSCy Schubert 	if (is_binary)
1612b15cb3dSCy Schubert 		mode |= O_BINARY;
1622b15cb3dSCy Schubert #endif
1632b15cb3dSCy Schubert 
1642b15cb3dSCy Schubert 	fd = evutil_open_closeonexec_(filename, mode, 0);
1652b15cb3dSCy Schubert 	if (fd < 0)
1662b15cb3dSCy Schubert 		return -1;
1672b15cb3dSCy Schubert 	if (fstat(fd, &st) || st.st_size < 0 ||
1682b15cb3dSCy Schubert 	    st.st_size > EV_SSIZE_MAX-1 ) {
1692b15cb3dSCy Schubert 		close(fd);
1702b15cb3dSCy Schubert 		return -2;
1712b15cb3dSCy Schubert 	}
1722b15cb3dSCy Schubert 	mem = mm_malloc((size_t)st.st_size + 1);
1732b15cb3dSCy Schubert 	if (!mem) {
1742b15cb3dSCy Schubert 		close(fd);
1752b15cb3dSCy Schubert 		return -2;
1762b15cb3dSCy Schubert 	}
1772b15cb3dSCy Schubert 	read_so_far = 0;
1782b15cb3dSCy Schubert #ifdef _WIN32
1792b15cb3dSCy Schubert #define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x))
1802b15cb3dSCy Schubert #else
1812b15cb3dSCy Schubert #define N_TO_READ(x) (x)
1822b15cb3dSCy Schubert #endif
1832b15cb3dSCy Schubert 	while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) {
1842b15cb3dSCy Schubert 		read_so_far += r;
1852b15cb3dSCy Schubert 		if (read_so_far >= (size_t)st.st_size)
1862b15cb3dSCy Schubert 			break;
1872b15cb3dSCy Schubert 		EVUTIL_ASSERT(read_so_far < (size_t)st.st_size);
1882b15cb3dSCy Schubert 	}
1892b15cb3dSCy Schubert 	close(fd);
1902b15cb3dSCy Schubert 	if (r < 0) {
1912b15cb3dSCy Schubert 		mm_free(mem);
1922b15cb3dSCy Schubert 		return -2;
1932b15cb3dSCy Schubert 	}
1942b15cb3dSCy Schubert 	mem[read_so_far] = 0;
1952b15cb3dSCy Schubert 
1962b15cb3dSCy Schubert 	*len_out = read_so_far;
1972b15cb3dSCy Schubert 	*content_out = mem;
1982b15cb3dSCy Schubert 	return 0;
1992b15cb3dSCy Schubert }
2002b15cb3dSCy Schubert 
2012b15cb3dSCy Schubert int
evutil_socketpair(int family,int type,int protocol,evutil_socket_t fd[2])2022b15cb3dSCy Schubert evutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
2032b15cb3dSCy Schubert {
2042b15cb3dSCy Schubert #ifndef _WIN32
2052b15cb3dSCy Schubert 	return socketpair(family, type, protocol, fd);
2062b15cb3dSCy Schubert #else
2072b15cb3dSCy Schubert 	return evutil_ersatz_socketpair_(family, type, protocol, fd);
2082b15cb3dSCy Schubert #endif
2092b15cb3dSCy Schubert }
2102b15cb3dSCy Schubert 
2112b15cb3dSCy Schubert int
evutil_ersatz_socketpair_(int family,int type,int protocol,evutil_socket_t fd[2])2122b15cb3dSCy Schubert evutil_ersatz_socketpair_(int family, int type, int protocol,
2132b15cb3dSCy Schubert     evutil_socket_t fd[2])
2142b15cb3dSCy Schubert {
2152b15cb3dSCy Schubert 	/* This code is originally from Tor.  Used with permission. */
2162b15cb3dSCy Schubert 
2172b15cb3dSCy Schubert 	/* This socketpair does not work when localhost is down. So
2182b15cb3dSCy Schubert 	 * it's really not the same thing at all. But it's close enough
2192b15cb3dSCy Schubert 	 * for now, and really, when localhost is down sometimes, we
2202b15cb3dSCy Schubert 	 * have other problems too.
2212b15cb3dSCy Schubert 	 */
2222b15cb3dSCy Schubert #ifdef _WIN32
2232b15cb3dSCy Schubert #define ERR(e) WSA##e
2242b15cb3dSCy Schubert #else
2252b15cb3dSCy Schubert #define ERR(e) e
2262b15cb3dSCy Schubert #endif
2272b15cb3dSCy Schubert 	evutil_socket_t listener = -1;
2282b15cb3dSCy Schubert 	evutil_socket_t connector = -1;
2292b15cb3dSCy Schubert 	evutil_socket_t acceptor = -1;
2302b15cb3dSCy Schubert 	struct sockaddr_in listen_addr;
2312b15cb3dSCy Schubert 	struct sockaddr_in connect_addr;
2322b15cb3dSCy Schubert 	ev_socklen_t size;
2332b15cb3dSCy Schubert 	int saved_errno = -1;
234*a466cc55SCy Schubert 	int family_test;
2352b15cb3dSCy Schubert 
236*a466cc55SCy Schubert 	family_test = family != AF_INET;
2372b15cb3dSCy Schubert #ifdef AF_UNIX
238*a466cc55SCy Schubert 	family_test = family_test && (family != AF_UNIX);
2392b15cb3dSCy Schubert #endif
240*a466cc55SCy Schubert 	if (protocol || family_test) {
2412b15cb3dSCy Schubert 		EVUTIL_SET_SOCKET_ERROR(ERR(EAFNOSUPPORT));
2422b15cb3dSCy Schubert 		return -1;
2432b15cb3dSCy Schubert 	}
244*a466cc55SCy Schubert 
2452b15cb3dSCy Schubert 	if (!fd) {
2462b15cb3dSCy Schubert 		EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
2472b15cb3dSCy Schubert 		return -1;
2482b15cb3dSCy Schubert 	}
2492b15cb3dSCy Schubert 
2502b15cb3dSCy Schubert 	listener = socket(AF_INET, type, 0);
2512b15cb3dSCy Schubert 	if (listener < 0)
2522b15cb3dSCy Schubert 		return -1;
2532b15cb3dSCy Schubert 	memset(&listen_addr, 0, sizeof(listen_addr));
2542b15cb3dSCy Schubert 	listen_addr.sin_family = AF_INET;
2552b15cb3dSCy Schubert 	listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2562b15cb3dSCy Schubert 	listen_addr.sin_port = 0;	/* kernel chooses port.	 */
2572b15cb3dSCy Schubert 	if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
2582b15cb3dSCy Schubert 		== -1)
2592b15cb3dSCy Schubert 		goto tidy_up_and_fail;
2602b15cb3dSCy Schubert 	if (listen(listener, 1) == -1)
2612b15cb3dSCy Schubert 		goto tidy_up_and_fail;
2622b15cb3dSCy Schubert 
2632b15cb3dSCy Schubert 	connector = socket(AF_INET, type, 0);
2642b15cb3dSCy Schubert 	if (connector < 0)
2652b15cb3dSCy Schubert 		goto tidy_up_and_fail;
266*a466cc55SCy Schubert 
267*a466cc55SCy Schubert 	memset(&connect_addr, 0, sizeof(connect_addr));
268*a466cc55SCy Schubert 
2692b15cb3dSCy Schubert 	/* We want to find out the port number to connect to.  */
2702b15cb3dSCy Schubert 	size = sizeof(connect_addr);
2712b15cb3dSCy Schubert 	if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
2722b15cb3dSCy Schubert 		goto tidy_up_and_fail;
2732b15cb3dSCy Schubert 	if (size != sizeof (connect_addr))
2742b15cb3dSCy Schubert 		goto abort_tidy_up_and_fail;
2752b15cb3dSCy Schubert 	if (connect(connector, (struct sockaddr *) &connect_addr,
2762b15cb3dSCy Schubert 				sizeof(connect_addr)) == -1)
2772b15cb3dSCy Schubert 		goto tidy_up_and_fail;
2782b15cb3dSCy Schubert 
2792b15cb3dSCy Schubert 	size = sizeof(listen_addr);
2802b15cb3dSCy Schubert 	acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
2812b15cb3dSCy Schubert 	if (acceptor < 0)
2822b15cb3dSCy Schubert 		goto tidy_up_and_fail;
2832b15cb3dSCy Schubert 	if (size != sizeof(listen_addr))
2842b15cb3dSCy Schubert 		goto abort_tidy_up_and_fail;
2852b15cb3dSCy Schubert 	/* Now check we are talking to ourself by matching port and host on the
2862b15cb3dSCy Schubert 	   two sockets.	 */
2872b15cb3dSCy Schubert 	if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
2882b15cb3dSCy Schubert 		goto tidy_up_and_fail;
2892b15cb3dSCy Schubert 	if (size != sizeof (connect_addr)
2902b15cb3dSCy Schubert 		|| listen_addr.sin_family != connect_addr.sin_family
2912b15cb3dSCy Schubert 		|| listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
2922b15cb3dSCy Schubert 		|| listen_addr.sin_port != connect_addr.sin_port)
2932b15cb3dSCy Schubert 		goto abort_tidy_up_and_fail;
2942b15cb3dSCy Schubert 	evutil_closesocket(listener);
2952b15cb3dSCy Schubert 	fd[0] = connector;
2962b15cb3dSCy Schubert 	fd[1] = acceptor;
2972b15cb3dSCy Schubert 
2982b15cb3dSCy Schubert 	return 0;
2992b15cb3dSCy Schubert 
3002b15cb3dSCy Schubert  abort_tidy_up_and_fail:
3012b15cb3dSCy Schubert 	saved_errno = ERR(ECONNABORTED);
3022b15cb3dSCy Schubert  tidy_up_and_fail:
3032b15cb3dSCy Schubert 	if (saved_errno < 0)
3042b15cb3dSCy Schubert 		saved_errno = EVUTIL_SOCKET_ERROR();
3052b15cb3dSCy Schubert 	if (listener != -1)
3062b15cb3dSCy Schubert 		evutil_closesocket(listener);
3072b15cb3dSCy Schubert 	if (connector != -1)
3082b15cb3dSCy Schubert 		evutil_closesocket(connector);
3092b15cb3dSCy Schubert 	if (acceptor != -1)
3102b15cb3dSCy Schubert 		evutil_closesocket(acceptor);
3112b15cb3dSCy Schubert 
3122b15cb3dSCy Schubert 	EVUTIL_SET_SOCKET_ERROR(saved_errno);
3132b15cb3dSCy Schubert 	return -1;
3142b15cb3dSCy Schubert #undef ERR
3152b15cb3dSCy Schubert }
3162b15cb3dSCy Schubert 
3172b15cb3dSCy Schubert int
evutil_make_socket_nonblocking(evutil_socket_t fd)3182b15cb3dSCy Schubert evutil_make_socket_nonblocking(evutil_socket_t fd)
3192b15cb3dSCy Schubert {
3202b15cb3dSCy Schubert #ifdef _WIN32
3212b15cb3dSCy Schubert 	{
322*a466cc55SCy Schubert 		unsigned long nonblocking = 1;
3232b15cb3dSCy Schubert 		if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) {
3242b15cb3dSCy Schubert 			event_sock_warn(fd, "fcntl(%d, F_GETFL)", (int)fd);
3252b15cb3dSCy Schubert 			return -1;
3262b15cb3dSCy Schubert 		}
3272b15cb3dSCy Schubert 	}
3282b15cb3dSCy Schubert #else
3292b15cb3dSCy Schubert 	{
3302b15cb3dSCy Schubert 		int flags;
3312b15cb3dSCy Schubert 		if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
3322b15cb3dSCy Schubert 			event_warn("fcntl(%d, F_GETFL)", fd);
3332b15cb3dSCy Schubert 			return -1;
3342b15cb3dSCy Schubert 		}
3352b15cb3dSCy Schubert 		if (!(flags & O_NONBLOCK)) {
3362b15cb3dSCy Schubert 			if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
3372b15cb3dSCy Schubert 				event_warn("fcntl(%d, F_SETFL)", fd);
3382b15cb3dSCy Schubert 				return -1;
3392b15cb3dSCy Schubert 			}
3402b15cb3dSCy Schubert 		}
3412b15cb3dSCy Schubert 	}
3422b15cb3dSCy Schubert #endif
3432b15cb3dSCy Schubert 	return 0;
3442b15cb3dSCy Schubert }
3452b15cb3dSCy Schubert 
3462b15cb3dSCy Schubert /* Faster version of evutil_make_socket_nonblocking for internal use.
3472b15cb3dSCy Schubert  *
3482b15cb3dSCy Schubert  * Requires that no F_SETFL flags were previously set on the fd.
3492b15cb3dSCy Schubert  */
3502b15cb3dSCy Schubert static int
evutil_fast_socket_nonblocking(evutil_socket_t fd)3512b15cb3dSCy Schubert evutil_fast_socket_nonblocking(evutil_socket_t fd)
3522b15cb3dSCy Schubert {
3532b15cb3dSCy Schubert #ifdef _WIN32
3542b15cb3dSCy Schubert 	return evutil_make_socket_nonblocking(fd);
3552b15cb3dSCy Schubert #else
3562b15cb3dSCy Schubert 	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
3572b15cb3dSCy Schubert 		event_warn("fcntl(%d, F_SETFL)", fd);
3582b15cb3dSCy Schubert 		return -1;
3592b15cb3dSCy Schubert 	}
3602b15cb3dSCy Schubert 	return 0;
3612b15cb3dSCy Schubert #endif
3622b15cb3dSCy Schubert }
3632b15cb3dSCy Schubert 
3642b15cb3dSCy Schubert int
evutil_make_listen_socket_reuseable(evutil_socket_t sock)3652b15cb3dSCy Schubert evutil_make_listen_socket_reuseable(evutil_socket_t sock)
3662b15cb3dSCy Schubert {
367*a466cc55SCy Schubert #if defined(SO_REUSEADDR) && !defined(_WIN32)
3682b15cb3dSCy Schubert 	int one = 1;
3692b15cb3dSCy Schubert 	/* REUSEADDR on Unix means, "don't hang on to this address after the
3702b15cb3dSCy Schubert 	 * listener is closed."  On Windows, though, it means "don't keep other
3712b15cb3dSCy Schubert 	 * processes from binding to this address while we're using it. */
3722b15cb3dSCy Schubert 	return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
3732b15cb3dSCy Schubert 	    (ev_socklen_t)sizeof(one));
3742b15cb3dSCy Schubert #else
3752b15cb3dSCy Schubert 	return 0;
3762b15cb3dSCy Schubert #endif
3772b15cb3dSCy Schubert }
3782b15cb3dSCy Schubert 
3792b15cb3dSCy Schubert int
evutil_make_listen_socket_reuseable_port(evutil_socket_t sock)380a25439b6SCy Schubert evutil_make_listen_socket_reuseable_port(evutil_socket_t sock)
381a25439b6SCy Schubert {
382a25439b6SCy Schubert #if defined __linux__ && defined(SO_REUSEPORT)
383a25439b6SCy Schubert 	int one = 1;
384a25439b6SCy Schubert 	/* REUSEPORT on Linux 3.9+ means, "Multiple servers (processes or
385a25439b6SCy Schubert 	 * threads) can bind to the same port if they each set the option. */
386a25439b6SCy Schubert 	return setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void*) &one,
387a25439b6SCy Schubert 	    (ev_socklen_t)sizeof(one));
388a25439b6SCy Schubert #else
389a25439b6SCy Schubert 	return 0;
390a25439b6SCy Schubert #endif
391a25439b6SCy Schubert }
392a25439b6SCy Schubert 
393a25439b6SCy Schubert int
evutil_make_listen_socket_ipv6only(evutil_socket_t sock)394*a466cc55SCy Schubert evutil_make_listen_socket_ipv6only(evutil_socket_t sock)
395*a466cc55SCy Schubert {
396*a466cc55SCy Schubert #if defined(IPV6_V6ONLY)
397*a466cc55SCy Schubert 	int one = 1;
398*a466cc55SCy Schubert 	return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &one,
399*a466cc55SCy Schubert 	    (ev_socklen_t)sizeof(one));
400*a466cc55SCy Schubert #endif
401*a466cc55SCy Schubert 	return 0;
402*a466cc55SCy Schubert }
403*a466cc55SCy Schubert 
404*a466cc55SCy Schubert int
evutil_make_tcp_listen_socket_deferred(evutil_socket_t sock)4052b15cb3dSCy Schubert evutil_make_tcp_listen_socket_deferred(evutil_socket_t sock)
4062b15cb3dSCy Schubert {
4072b15cb3dSCy Schubert #if defined(EVENT__HAVE_NETINET_TCP_H) && defined(TCP_DEFER_ACCEPT)
4082b15cb3dSCy Schubert 	int one = 1;
4092b15cb3dSCy Schubert 
4102b15cb3dSCy Schubert 	/* TCP_DEFER_ACCEPT tells the kernel to call defer accept() only after data
4112b15cb3dSCy Schubert 	 * has arrived and ready to read */
4122b15cb3dSCy Schubert 	return setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, &one,
4132b15cb3dSCy Schubert 		(ev_socklen_t)sizeof(one));
4142b15cb3dSCy Schubert #endif
4152b15cb3dSCy Schubert 	return 0;
4162b15cb3dSCy Schubert }
4172b15cb3dSCy Schubert 
4182b15cb3dSCy Schubert int
evutil_make_socket_closeonexec(evutil_socket_t fd)4192b15cb3dSCy Schubert evutil_make_socket_closeonexec(evutil_socket_t fd)
4202b15cb3dSCy Schubert {
4212b15cb3dSCy Schubert #if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
4222b15cb3dSCy Schubert 	int flags;
4232b15cb3dSCy Schubert 	if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) {
4242b15cb3dSCy Schubert 		event_warn("fcntl(%d, F_GETFD)", fd);
4252b15cb3dSCy Schubert 		return -1;
4262b15cb3dSCy Schubert 	}
4272b15cb3dSCy Schubert 	if (!(flags & FD_CLOEXEC)) {
4282b15cb3dSCy Schubert 		if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
4292b15cb3dSCy Schubert 			event_warn("fcntl(%d, F_SETFD)", fd);
4302b15cb3dSCy Schubert 			return -1;
4312b15cb3dSCy Schubert 		}
4322b15cb3dSCy Schubert 	}
4332b15cb3dSCy Schubert #endif
4342b15cb3dSCy Schubert 	return 0;
4352b15cb3dSCy Schubert }
4362b15cb3dSCy Schubert 
4372b15cb3dSCy Schubert /* Faster version of evutil_make_socket_closeonexec for internal use.
4382b15cb3dSCy Schubert  *
4392b15cb3dSCy Schubert  * Requires that no F_SETFD flags were previously set on the fd.
4402b15cb3dSCy Schubert  */
4412b15cb3dSCy Schubert static int
evutil_fast_socket_closeonexec(evutil_socket_t fd)4422b15cb3dSCy Schubert evutil_fast_socket_closeonexec(evutil_socket_t fd)
4432b15cb3dSCy Schubert {
4442b15cb3dSCy Schubert #if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
4452b15cb3dSCy Schubert 	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
4462b15cb3dSCy Schubert 		event_warn("fcntl(%d, F_SETFD)", fd);
4472b15cb3dSCy Schubert 		return -1;
4482b15cb3dSCy Schubert 	}
4492b15cb3dSCy Schubert #endif
4502b15cb3dSCy Schubert 	return 0;
4512b15cb3dSCy Schubert }
4522b15cb3dSCy Schubert 
4532b15cb3dSCy Schubert int
evutil_closesocket(evutil_socket_t sock)4542b15cb3dSCy Schubert evutil_closesocket(evutil_socket_t sock)
4552b15cb3dSCy Schubert {
4562b15cb3dSCy Schubert #ifndef _WIN32
4572b15cb3dSCy Schubert 	return close(sock);
4582b15cb3dSCy Schubert #else
4592b15cb3dSCy Schubert 	return closesocket(sock);
4602b15cb3dSCy Schubert #endif
4612b15cb3dSCy Schubert }
4622b15cb3dSCy Schubert 
4632b15cb3dSCy Schubert ev_int64_t
evutil_strtoll(const char * s,char ** endptr,int base)4642b15cb3dSCy Schubert evutil_strtoll(const char *s, char **endptr, int base)
4652b15cb3dSCy Schubert {
4662b15cb3dSCy Schubert #ifdef EVENT__HAVE_STRTOLL
4672b15cb3dSCy Schubert 	return (ev_int64_t)strtoll(s, endptr, base);
4682b15cb3dSCy Schubert #elif EVENT__SIZEOF_LONG == 8
4692b15cb3dSCy Schubert 	return (ev_int64_t)strtol(s, endptr, base);
4702b15cb3dSCy Schubert #elif defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
4712b15cb3dSCy Schubert 	/* XXXX on old versions of MS APIs, we only support base
4722b15cb3dSCy Schubert 	 * 10. */
4732b15cb3dSCy Schubert 	ev_int64_t r;
4742b15cb3dSCy Schubert 	if (base != 10)
4752b15cb3dSCy Schubert 		return 0;
4762b15cb3dSCy Schubert 	r = (ev_int64_t) _atoi64(s);
4772b15cb3dSCy Schubert 	while (isspace(*s))
4782b15cb3dSCy Schubert 		++s;
4792b15cb3dSCy Schubert 	if (*s == '-')
4802b15cb3dSCy Schubert 		++s;
4812b15cb3dSCy Schubert 	while (isdigit(*s))
4822b15cb3dSCy Schubert 		++s;
4832b15cb3dSCy Schubert 	if (endptr)
4842b15cb3dSCy Schubert 		*endptr = (char*) s;
4852b15cb3dSCy Schubert 	return r;
4862b15cb3dSCy Schubert #elif defined(_WIN32)
4872b15cb3dSCy Schubert 	return (ev_int64_t) _strtoi64(s, endptr, base);
4882b15cb3dSCy Schubert #elif defined(EVENT__SIZEOF_LONG_LONG) && EVENT__SIZEOF_LONG_LONG == 8
4892b15cb3dSCy Schubert 	long long r;
4902b15cb3dSCy Schubert 	int n;
4912b15cb3dSCy Schubert 	if (base != 10 && base != 16)
4922b15cb3dSCy Schubert 		return 0;
4932b15cb3dSCy Schubert 	if (base == 10) {
4942b15cb3dSCy Schubert 		n = sscanf(s, "%lld", &r);
4952b15cb3dSCy Schubert 	} else {
4962b15cb3dSCy Schubert 		unsigned long long ru=0;
4972b15cb3dSCy Schubert 		n = sscanf(s, "%llx", &ru);
4982b15cb3dSCy Schubert 		if (ru > EV_INT64_MAX)
4992b15cb3dSCy Schubert 			return 0;
5002b15cb3dSCy Schubert 		r = (long long) ru;
5012b15cb3dSCy Schubert 	}
5022b15cb3dSCy Schubert 	if (n != 1)
5032b15cb3dSCy Schubert 		return 0;
5042b15cb3dSCy Schubert 	while (EVUTIL_ISSPACE_(*s))
5052b15cb3dSCy Schubert 		++s;
5062b15cb3dSCy Schubert 	if (*s == '-')
5072b15cb3dSCy Schubert 		++s;
5082b15cb3dSCy Schubert 	if (base == 10) {
5092b15cb3dSCy Schubert 		while (EVUTIL_ISDIGIT_(*s))
5102b15cb3dSCy Schubert 			++s;
5112b15cb3dSCy Schubert 	} else {
5122b15cb3dSCy Schubert 		while (EVUTIL_ISXDIGIT_(*s))
5132b15cb3dSCy Schubert 			++s;
5142b15cb3dSCy Schubert 	}
5152b15cb3dSCy Schubert 	if (endptr)
5162b15cb3dSCy Schubert 		*endptr = (char*) s;
5172b15cb3dSCy Schubert 	return r;
5182b15cb3dSCy Schubert #else
5192b15cb3dSCy Schubert #error "I don't know how to parse 64-bit integers."
5202b15cb3dSCy Schubert #endif
5212b15cb3dSCy Schubert }
5222b15cb3dSCy Schubert 
5232b15cb3dSCy Schubert #ifdef _WIN32
5242b15cb3dSCy Schubert int
evutil_socket_geterror(evutil_socket_t sock)5252b15cb3dSCy Schubert evutil_socket_geterror(evutil_socket_t sock)
5262b15cb3dSCy Schubert {
5272b15cb3dSCy Schubert 	int optval, optvallen=sizeof(optval);
5282b15cb3dSCy Schubert 	int err = WSAGetLastError();
5292b15cb3dSCy Schubert 	if (err == WSAEWOULDBLOCK && sock >= 0) {
5302b15cb3dSCy Schubert 		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
5312b15cb3dSCy Schubert 					   &optvallen))
5322b15cb3dSCy Schubert 			return err;
5332b15cb3dSCy Schubert 		if (optval)
5342b15cb3dSCy Schubert 			return optval;
5352b15cb3dSCy Schubert 	}
5362b15cb3dSCy Schubert 	return err;
5372b15cb3dSCy Schubert }
5382b15cb3dSCy Schubert #endif
5392b15cb3dSCy Schubert 
5402b15cb3dSCy Schubert /* XXX we should use an enum here. */
5412b15cb3dSCy Schubert /* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
5422b15cb3dSCy Schubert int
evutil_socket_connect_(evutil_socket_t * fd_ptr,const struct sockaddr * sa,int socklen)543*a466cc55SCy Schubert evutil_socket_connect_(evutil_socket_t *fd_ptr, const struct sockaddr *sa, int socklen)
5442b15cb3dSCy Schubert {
5452b15cb3dSCy Schubert 	int made_fd = 0;
5462b15cb3dSCy Schubert 
5472b15cb3dSCy Schubert 	if (*fd_ptr < 0) {
5482b15cb3dSCy Schubert 		if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
5492b15cb3dSCy Schubert 			goto err;
5502b15cb3dSCy Schubert 		made_fd = 1;
5512b15cb3dSCy Schubert 		if (evutil_make_socket_nonblocking(*fd_ptr) < 0) {
5522b15cb3dSCy Schubert 			goto err;
5532b15cb3dSCy Schubert 		}
5542b15cb3dSCy Schubert 	}
5552b15cb3dSCy Schubert 
5562b15cb3dSCy Schubert 	if (connect(*fd_ptr, sa, socklen) < 0) {
5572b15cb3dSCy Schubert 		int e = evutil_socket_geterror(*fd_ptr);
5582b15cb3dSCy Schubert 		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
5592b15cb3dSCy Schubert 			return 0;
5602b15cb3dSCy Schubert 		if (EVUTIL_ERR_CONNECT_REFUSED(e))
5612b15cb3dSCy Schubert 			return 2;
5622b15cb3dSCy Schubert 		goto err;
5632b15cb3dSCy Schubert 	} else {
5642b15cb3dSCy Schubert 		return 1;
5652b15cb3dSCy Schubert 	}
5662b15cb3dSCy Schubert 
5672b15cb3dSCy Schubert err:
5682b15cb3dSCy Schubert 	if (made_fd) {
5692b15cb3dSCy Schubert 		evutil_closesocket(*fd_ptr);
5702b15cb3dSCy Schubert 		*fd_ptr = -1;
5712b15cb3dSCy Schubert 	}
5722b15cb3dSCy Schubert 	return -1;
5732b15cb3dSCy Schubert }
5742b15cb3dSCy Schubert 
5752b15cb3dSCy Schubert /* Check whether a socket on which we called connect() is done
5762b15cb3dSCy Schubert    connecting. Return 1 for connected, 0 for not yet, -1 for error.  In the
5772b15cb3dSCy Schubert    error case, set the current socket errno to the error that happened during
5782b15cb3dSCy Schubert    the connect operation. */
5792b15cb3dSCy Schubert int
evutil_socket_finished_connecting_(evutil_socket_t fd)5802b15cb3dSCy Schubert evutil_socket_finished_connecting_(evutil_socket_t fd)
5812b15cb3dSCy Schubert {
5822b15cb3dSCy Schubert 	int e;
5832b15cb3dSCy Schubert 	ev_socklen_t elen = sizeof(e);
5842b15cb3dSCy Schubert 
5852b15cb3dSCy Schubert 	if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
5862b15cb3dSCy Schubert 		return -1;
5872b15cb3dSCy Schubert 
5882b15cb3dSCy Schubert 	if (e) {
5892b15cb3dSCy Schubert 		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
5902b15cb3dSCy Schubert 			return 0;
5912b15cb3dSCy Schubert 		EVUTIL_SET_SOCKET_ERROR(e);
5922b15cb3dSCy Schubert 		return -1;
5932b15cb3dSCy Schubert 	}
5942b15cb3dSCy Schubert 
5952b15cb3dSCy Schubert 	return 1;
5962b15cb3dSCy Schubert }
5972b15cb3dSCy Schubert 
5982b15cb3dSCy Schubert #if (EVUTIL_AI_PASSIVE|EVUTIL_AI_CANONNAME|EVUTIL_AI_NUMERICHOST| \
5992b15cb3dSCy Schubert      EVUTIL_AI_NUMERICSERV|EVUTIL_AI_V4MAPPED|EVUTIL_AI_ALL| \
6002b15cb3dSCy Schubert      EVUTIL_AI_ADDRCONFIG) != \
6012b15cb3dSCy Schubert     (EVUTIL_AI_PASSIVE^EVUTIL_AI_CANONNAME^EVUTIL_AI_NUMERICHOST^ \
6022b15cb3dSCy Schubert      EVUTIL_AI_NUMERICSERV^EVUTIL_AI_V4MAPPED^EVUTIL_AI_ALL^ \
6032b15cb3dSCy Schubert      EVUTIL_AI_ADDRCONFIG)
6042b15cb3dSCy Schubert #error "Some of our EVUTIL_AI_* flags seem to overlap with system AI_* flags"
6052b15cb3dSCy Schubert #endif
6062b15cb3dSCy Schubert 
6072b15cb3dSCy Schubert /* We sometimes need to know whether we have an ipv4 address and whether we
6082b15cb3dSCy Schubert    have an ipv6 address. If 'have_checked_interfaces', then we've already done
6092b15cb3dSCy Schubert    the test.  If 'had_ipv4_address', then it turns out we had an ipv4 address.
6102b15cb3dSCy Schubert    If 'had_ipv6_address', then it turns out we had an ipv6 address.   These are
6112b15cb3dSCy Schubert    set by evutil_check_interfaces. */
6122b15cb3dSCy Schubert static int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
6132b15cb3dSCy Schubert 
614*a466cc55SCy 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*a466cc55SCy Schubert static inline int evutil_v4addr_is_localhost(ev_uint32_t addr)
616*a466cc55SCy Schubert { return addr>>24 == 127; }
6172b15cb3dSCy Schubert 
618*a466cc55SCy Schubert /* True iff the IPv4 address 'addr', in host order, is link-local
619*a466cc55SCy Schubert  * 169.254.0.0/16 (RFC3927) */
evutil_v4addr_is_linklocal(ev_uint32_t addr)620*a466cc55SCy Schubert static inline int evutil_v4addr_is_linklocal(ev_uint32_t addr)
621*a466cc55SCy Schubert { return ((addr & 0xffff0000U) == 0xa9fe0000U); }
622*a466cc55SCy Schubert 
623*a466cc55SCy Schubert /* True iff the IPv4 address 'addr', in host order, is a class D
624*a466cc55SCy Schubert  * (multiclass) address.  */
evutil_v4addr_is_classd(ev_uint32_t addr)625*a466cc55SCy Schubert static inline int evutil_v4addr_is_classd(ev_uint32_t addr)
626*a466cc55SCy Schubert { return ((addr>>24) & 0xf0) == 0xe0; }
627*a466cc55SCy Schubert 
628*a466cc55SCy Schubert int
evutil_v4addr_is_local_(const struct in_addr * in)629*a466cc55SCy Schubert evutil_v4addr_is_local_(const struct in_addr *in)
630*a466cc55SCy Schubert {
631*a466cc55SCy Schubert 	const ev_uint32_t addr = ntohl(in->s_addr);
632*a466cc55SCy Schubert 	return addr == INADDR_ANY ||
633*a466cc55SCy Schubert 		evutil_v4addr_is_localhost(addr) ||
634*a466cc55SCy Schubert 		evutil_v4addr_is_linklocal(addr) ||
635*a466cc55SCy Schubert 		evutil_v4addr_is_classd(addr);
636*a466cc55SCy Schubert }
637*a466cc55SCy Schubert int
evutil_v6addr_is_local_(const struct in6_addr * in)638*a466cc55SCy Schubert evutil_v6addr_is_local_(const struct in6_addr *in)
639*a466cc55SCy Schubert {
640*a466cc55SCy Schubert 	static const char ZEROES[] =
641*a466cc55SCy Schubert 		"\x00\x00\x00\x00\x00\x00\x00\x00"
642*a466cc55SCy Schubert 		"\x00\x00\x00\x00\x00\x00\x00\x00";
643*a466cc55SCy Schubert 
644*a466cc55SCy Schubert 	const unsigned char *addr = (const unsigned char *)in->s6_addr;
645*a466cc55SCy Schubert 	return !memcmp(addr, ZEROES, 8) ||
646*a466cc55SCy Schubert 		((addr[0] & 0xfe) == 0xfc) ||
647*a466cc55SCy Schubert 		(addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80) ||
648*a466cc55SCy Schubert 		(addr[0] == 0xfe && (addr[1] & 0xc0) == 0xc0) ||
649*a466cc55SCy Schubert 		(addr[0] == 0xff);
650*a466cc55SCy Schubert }
6512b15cb3dSCy Schubert 
6522b15cb3dSCy Schubert static void
evutil_found_ifaddr(const struct sockaddr * sa)6532b15cb3dSCy Schubert evutil_found_ifaddr(const struct sockaddr *sa)
6542b15cb3dSCy Schubert {
6552b15cb3dSCy Schubert 	if (sa->sa_family == AF_INET) {
6562b15cb3dSCy Schubert 		const struct sockaddr_in *sin = (struct sockaddr_in *)sa;
657*a466cc55SCy Schubert 		if (!evutil_v4addr_is_local_(&sin->sin_addr)) {
6582b15cb3dSCy Schubert 			event_debug(("Detected an IPv4 interface"));
6592b15cb3dSCy Schubert 			had_ipv4_address = 1;
6602b15cb3dSCy Schubert 		}
6612b15cb3dSCy Schubert 	} else if (sa->sa_family == AF_INET6) {
6622b15cb3dSCy Schubert 		const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
663*a466cc55SCy Schubert 		if (!evutil_v6addr_is_local_(&sin6->sin6_addr)) {
6642b15cb3dSCy Schubert 			event_debug(("Detected an IPv6 interface"));
6652b15cb3dSCy Schubert 			had_ipv6_address = 1;
6662b15cb3dSCy Schubert 		}
6672b15cb3dSCy Schubert 	}
6682b15cb3dSCy Schubert }
6692b15cb3dSCy Schubert 
6702b15cb3dSCy Schubert #ifdef _WIN32
6712b15cb3dSCy Schubert typedef ULONG (WINAPI *GetAdaptersAddresses_fn_t)(
6722b15cb3dSCy Schubert               ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
6732b15cb3dSCy Schubert #endif
6742b15cb3dSCy Schubert 
6752b15cb3dSCy Schubert static int
evutil_check_ifaddrs(void)6762b15cb3dSCy Schubert evutil_check_ifaddrs(void)
6772b15cb3dSCy Schubert {
6782b15cb3dSCy Schubert #if defined(EVENT__HAVE_GETIFADDRS)
6792b15cb3dSCy Schubert 	/* Most free Unixy systems provide getifaddrs, which gives us a linked list
6802b15cb3dSCy Schubert 	 * of struct ifaddrs. */
6812b15cb3dSCy Schubert 	struct ifaddrs *ifa = NULL;
6822b15cb3dSCy Schubert 	const struct ifaddrs *i;
6832b15cb3dSCy Schubert 	if (getifaddrs(&ifa) < 0) {
6842b15cb3dSCy Schubert 		event_warn("Unable to call getifaddrs()");
6852b15cb3dSCy Schubert 		return -1;
6862b15cb3dSCy Schubert 	}
6872b15cb3dSCy Schubert 
6882b15cb3dSCy Schubert 	for (i = ifa; i; i = i->ifa_next) {
6892b15cb3dSCy Schubert 		if (!i->ifa_addr)
6902b15cb3dSCy Schubert 			continue;
6912b15cb3dSCy Schubert 		evutil_found_ifaddr(i->ifa_addr);
6922b15cb3dSCy Schubert 	}
6932b15cb3dSCy Schubert 
6942b15cb3dSCy Schubert 	freeifaddrs(ifa);
6952b15cb3dSCy Schubert 	return 0;
6962b15cb3dSCy Schubert #elif defined(_WIN32)
6972b15cb3dSCy Schubert 	/* Windows XP began to provide GetAdaptersAddresses. Windows 2000 had a
6982b15cb3dSCy Schubert 	   "GetAdaptersInfo", but that's deprecated; let's just try
6992b15cb3dSCy Schubert 	   GetAdaptersAddresses and fall back to connect+getsockname.
7002b15cb3dSCy Schubert 	*/
701*a466cc55SCy Schubert 	HMODULE lib = evutil_load_windows_system_library_(TEXT("iphlpapi.dll"));
7022b15cb3dSCy Schubert 	GetAdaptersAddresses_fn_t fn;
7032b15cb3dSCy Schubert 	ULONG size, res;
7042b15cb3dSCy Schubert 	IP_ADAPTER_ADDRESSES *addresses = NULL, *address;
7052b15cb3dSCy Schubert 	int result = -1;
7062b15cb3dSCy Schubert 
7072b15cb3dSCy Schubert #define FLAGS (GAA_FLAG_SKIP_ANYCAST | \
7082b15cb3dSCy Schubert                GAA_FLAG_SKIP_MULTICAST | \
7092b15cb3dSCy Schubert                GAA_FLAG_SKIP_DNS_SERVER)
7102b15cb3dSCy Schubert 
7112b15cb3dSCy Schubert 	if (!lib)
7122b15cb3dSCy Schubert 		goto done;
7132b15cb3dSCy Schubert 
7142b15cb3dSCy Schubert 	if (!(fn = (GetAdaptersAddresses_fn_t) GetProcAddress(lib, "GetAdaptersAddresses")))
7152b15cb3dSCy Schubert 		goto done;
7162b15cb3dSCy Schubert 
7172b15cb3dSCy Schubert 	/* Guess how much space we need. */
7182b15cb3dSCy Schubert 	size = 15*1024;
7192b15cb3dSCy Schubert 	addresses = mm_malloc(size);
7202b15cb3dSCy Schubert 	if (!addresses)
7212b15cb3dSCy Schubert 		goto done;
7222b15cb3dSCy Schubert 	res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
7232b15cb3dSCy Schubert 	if (res == ERROR_BUFFER_OVERFLOW) {
7242b15cb3dSCy Schubert 		/* we didn't guess that we needed enough space; try again */
7252b15cb3dSCy Schubert 		mm_free(addresses);
7262b15cb3dSCy Schubert 		addresses = mm_malloc(size);
7272b15cb3dSCy Schubert 		if (!addresses)
7282b15cb3dSCy Schubert 			goto done;
7292b15cb3dSCy Schubert 		res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
7302b15cb3dSCy Schubert 	}
7312b15cb3dSCy Schubert 	if (res != NO_ERROR)
7322b15cb3dSCy Schubert 		goto done;
7332b15cb3dSCy Schubert 
7342b15cb3dSCy Schubert 	for (address = addresses; address; address = address->Next) {
7352b15cb3dSCy Schubert 		IP_ADAPTER_UNICAST_ADDRESS *a;
7362b15cb3dSCy Schubert 		for (a = address->FirstUnicastAddress; a; a = a->Next) {
7372b15cb3dSCy Schubert 			/* Yes, it's a linked list inside a linked list */
7382b15cb3dSCy Schubert 			struct sockaddr *sa = a->Address.lpSockaddr;
7392b15cb3dSCy Schubert 			evutil_found_ifaddr(sa);
7402b15cb3dSCy Schubert 		}
7412b15cb3dSCy Schubert 	}
7422b15cb3dSCy Schubert 
7432b15cb3dSCy Schubert 	result = 0;
7442b15cb3dSCy Schubert done:
7452b15cb3dSCy Schubert 	if (lib)
7462b15cb3dSCy Schubert 		FreeLibrary(lib);
7472b15cb3dSCy Schubert 	if (addresses)
7482b15cb3dSCy Schubert 		mm_free(addresses);
7492b15cb3dSCy Schubert 	return result;
7502b15cb3dSCy Schubert #else
7512b15cb3dSCy Schubert 	return -1;
7522b15cb3dSCy Schubert #endif
7532b15cb3dSCy Schubert }
7542b15cb3dSCy Schubert 
7552b15cb3dSCy Schubert /* Test whether we have an ipv4 interface and an ipv6 interface.  Return 0 if
7562b15cb3dSCy Schubert  * the test seemed successful. */
7572b15cb3dSCy Schubert static int
evutil_check_interfaces(void)758*a466cc55SCy Schubert evutil_check_interfaces(void)
7592b15cb3dSCy Schubert {
7602b15cb3dSCy Schubert 	evutil_socket_t fd = -1;
7612b15cb3dSCy Schubert 	struct sockaddr_in sin, sin_out;
7622b15cb3dSCy Schubert 	struct sockaddr_in6 sin6, sin6_out;
7632b15cb3dSCy Schubert 	ev_socklen_t sin_out_len = sizeof(sin_out);
7642b15cb3dSCy Schubert 	ev_socklen_t sin6_out_len = sizeof(sin6_out);
7652b15cb3dSCy Schubert 	int r;
766*a466cc55SCy Schubert 	if (have_checked_interfaces)
7672b15cb3dSCy Schubert 		return 0;
7682b15cb3dSCy Schubert 
769*a466cc55SCy Schubert 	/* From this point on we have done the ipv4/ipv6 interface check */
770*a466cc55SCy Schubert 	have_checked_interfaces = 1;
771*a466cc55SCy Schubert 
7722b15cb3dSCy Schubert 	if (evutil_check_ifaddrs() == 0) {
7732b15cb3dSCy Schubert 		/* Use a nice sane interface, if this system has one. */
7742b15cb3dSCy Schubert 		return 0;
7752b15cb3dSCy Schubert 	}
7762b15cb3dSCy Schubert 
7772b15cb3dSCy Schubert 	/* Ugh. There was no nice sane interface.  So to check whether we have
7782b15cb3dSCy Schubert 	 * an interface open for a given protocol, will try to make a UDP
7792b15cb3dSCy Schubert 	 * 'connection' to a remote host on the internet.  We don't actually
7802b15cb3dSCy Schubert 	 * use it, so the address doesn't matter, but we want to pick one that
7812b15cb3dSCy Schubert 	 * keep us from using a host- or link-local interface. */
7822b15cb3dSCy Schubert 	memset(&sin, 0, sizeof(sin));
7832b15cb3dSCy Schubert 	sin.sin_family = AF_INET;
7842b15cb3dSCy Schubert 	sin.sin_port = htons(53);
7852b15cb3dSCy Schubert 	r = evutil_inet_pton(AF_INET, "18.244.0.188", &sin.sin_addr);
7862b15cb3dSCy Schubert 	EVUTIL_ASSERT(r);
7872b15cb3dSCy Schubert 
7882b15cb3dSCy Schubert 	memset(&sin6, 0, sizeof(sin6));
7892b15cb3dSCy Schubert 	sin6.sin6_family = AF_INET6;
7902b15cb3dSCy Schubert 	sin6.sin6_port = htons(53);
7912b15cb3dSCy Schubert 	r = evutil_inet_pton(AF_INET6, "2001:4860:b002::68", &sin6.sin6_addr);
7922b15cb3dSCy Schubert 	EVUTIL_ASSERT(r);
7932b15cb3dSCy Schubert 
7942b15cb3dSCy Schubert 	memset(&sin_out, 0, sizeof(sin_out));
7952b15cb3dSCy Schubert 	memset(&sin6_out, 0, sizeof(sin6_out));
7962b15cb3dSCy Schubert 
7972b15cb3dSCy Schubert 	/* XXX some errnos mean 'no address'; some mean 'not enough sockets'. */
7982b15cb3dSCy Schubert 	if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
7992b15cb3dSCy Schubert 	    connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
8002b15cb3dSCy Schubert 	    getsockname(fd, (struct sockaddr*)&sin_out, &sin_out_len) == 0) {
8012b15cb3dSCy Schubert 		/* We might have an IPv4 interface. */
8022b15cb3dSCy Schubert 		evutil_found_ifaddr((struct sockaddr*) &sin_out);
8032b15cb3dSCy Schubert 	}
8042b15cb3dSCy Schubert 	if (fd >= 0)
8052b15cb3dSCy Schubert 		evutil_closesocket(fd);
8062b15cb3dSCy Schubert 
8072b15cb3dSCy Schubert 	if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
8082b15cb3dSCy Schubert 	    connect(fd, (struct sockaddr*)&sin6, sizeof(sin6)) == 0 &&
8092b15cb3dSCy Schubert 	    getsockname(fd, (struct sockaddr*)&sin6_out, &sin6_out_len) == 0) {
8102b15cb3dSCy Schubert 		/* We might have an IPv6 interface. */
8112b15cb3dSCy Schubert 		evutil_found_ifaddr((struct sockaddr*) &sin6_out);
8122b15cb3dSCy Schubert 	}
8132b15cb3dSCy Schubert 
8142b15cb3dSCy Schubert 	if (fd >= 0)
8152b15cb3dSCy Schubert 		evutil_closesocket(fd);
8162b15cb3dSCy Schubert 
8172b15cb3dSCy Schubert 	return 0;
8182b15cb3dSCy Schubert }
8192b15cb3dSCy Schubert 
8202b15cb3dSCy Schubert /* Internal addrinfo flag.  This one is set when we allocate the addrinfo from
8212b15cb3dSCy Schubert  * inside libevent.  Otherwise, the built-in getaddrinfo() function allocated
8222b15cb3dSCy Schubert  * it, and we should trust what they said.
8232b15cb3dSCy Schubert  **/
8242b15cb3dSCy Schubert #define EVUTIL_AI_LIBEVENT_ALLOCATED 0x80000000
8252b15cb3dSCy Schubert 
8262b15cb3dSCy Schubert /* Helper: construct a new addrinfo containing the socket address in
8272b15cb3dSCy Schubert  * 'sa', which must be a sockaddr_in or a sockaddr_in6.  Take the
8282b15cb3dSCy Schubert  * socktype and protocol info from hints.  If they weren't set, then
8292b15cb3dSCy Schubert  * allocate both a TCP and a UDP addrinfo.
8302b15cb3dSCy Schubert  */
8312b15cb3dSCy Schubert struct evutil_addrinfo *
evutil_new_addrinfo_(struct sockaddr * sa,ev_socklen_t socklen,const struct evutil_addrinfo * hints)8322b15cb3dSCy Schubert evutil_new_addrinfo_(struct sockaddr *sa, ev_socklen_t socklen,
8332b15cb3dSCy Schubert     const struct evutil_addrinfo *hints)
8342b15cb3dSCy Schubert {
8352b15cb3dSCy Schubert 	struct evutil_addrinfo *res;
8362b15cb3dSCy Schubert 	EVUTIL_ASSERT(hints);
8372b15cb3dSCy Schubert 
8382b15cb3dSCy Schubert 	if (hints->ai_socktype == 0 && hints->ai_protocol == 0) {
8392b15cb3dSCy Schubert 		/* Indecisive user! Give them a UDP and a TCP. */
8402b15cb3dSCy Schubert 		struct evutil_addrinfo *r1, *r2;
8412b15cb3dSCy Schubert 		struct evutil_addrinfo tmp;
8422b15cb3dSCy Schubert 		memcpy(&tmp, hints, sizeof(tmp));
8432b15cb3dSCy Schubert 		tmp.ai_socktype = SOCK_STREAM; tmp.ai_protocol = IPPROTO_TCP;
8442b15cb3dSCy Schubert 		r1 = evutil_new_addrinfo_(sa, socklen, &tmp);
8452b15cb3dSCy Schubert 		if (!r1)
8462b15cb3dSCy Schubert 			return NULL;
8472b15cb3dSCy Schubert 		tmp.ai_socktype = SOCK_DGRAM; tmp.ai_protocol = IPPROTO_UDP;
8482b15cb3dSCy Schubert 		r2 = evutil_new_addrinfo_(sa, socklen, &tmp);
8492b15cb3dSCy Schubert 		if (!r2) {
8502b15cb3dSCy Schubert 			evutil_freeaddrinfo(r1);
8512b15cb3dSCy Schubert 			return NULL;
8522b15cb3dSCy Schubert 		}
8532b15cb3dSCy Schubert 		r1->ai_next = r2;
8542b15cb3dSCy Schubert 		return r1;
8552b15cb3dSCy Schubert 	}
8562b15cb3dSCy Schubert 
8572b15cb3dSCy Schubert 	/* We're going to allocate extra space to hold the sockaddr. */
8582b15cb3dSCy Schubert 	res = mm_calloc(1,sizeof(struct evutil_addrinfo)+socklen);
8592b15cb3dSCy Schubert 	if (!res)
8602b15cb3dSCy Schubert 		return NULL;
8612b15cb3dSCy Schubert 	res->ai_addr = (struct sockaddr*)
8622b15cb3dSCy Schubert 	    (((char*)res) + sizeof(struct evutil_addrinfo));
8632b15cb3dSCy Schubert 	memcpy(res->ai_addr, sa, socklen);
8642b15cb3dSCy Schubert 	res->ai_addrlen = socklen;
8652b15cb3dSCy Schubert 	res->ai_family = sa->sa_family; /* Same or not? XXX */
8662b15cb3dSCy Schubert 	res->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
8672b15cb3dSCy Schubert 	res->ai_socktype = hints->ai_socktype;
8682b15cb3dSCy Schubert 	res->ai_protocol = hints->ai_protocol;
8692b15cb3dSCy Schubert 
8702b15cb3dSCy Schubert 	return res;
8712b15cb3dSCy Schubert }
8722b15cb3dSCy Schubert 
8732b15cb3dSCy Schubert /* Append the addrinfo 'append' to the end of 'first', and return the start of
8742b15cb3dSCy Schubert  * the list.  Either element can be NULL, in which case we return the element
8752b15cb3dSCy Schubert  * that is not NULL. */
8762b15cb3dSCy Schubert struct evutil_addrinfo *
evutil_addrinfo_append_(struct evutil_addrinfo * first,struct evutil_addrinfo * append)8772b15cb3dSCy Schubert evutil_addrinfo_append_(struct evutil_addrinfo *first,
8782b15cb3dSCy Schubert     struct evutil_addrinfo *append)
8792b15cb3dSCy Schubert {
8802b15cb3dSCy Schubert 	struct evutil_addrinfo *ai = first;
8812b15cb3dSCy Schubert 	if (!ai)
8822b15cb3dSCy Schubert 		return append;
8832b15cb3dSCy Schubert 	while (ai->ai_next)
8842b15cb3dSCy Schubert 		ai = ai->ai_next;
8852b15cb3dSCy Schubert 	ai->ai_next = append;
8862b15cb3dSCy Schubert 
8872b15cb3dSCy Schubert 	return first;
8882b15cb3dSCy Schubert }
8892b15cb3dSCy Schubert 
8902b15cb3dSCy Schubert static int
parse_numeric_servname(const char * servname)8912b15cb3dSCy Schubert parse_numeric_servname(const char *servname)
8922b15cb3dSCy Schubert {
8932b15cb3dSCy Schubert 	int n;
8942b15cb3dSCy Schubert 	char *endptr=NULL;
8952b15cb3dSCy Schubert 	n = (int) strtol(servname, &endptr, 10);
8962b15cb3dSCy Schubert 	if (n>=0 && n <= 65535 && servname[0] && endptr && !endptr[0])
8972b15cb3dSCy Schubert 		return n;
8982b15cb3dSCy Schubert 	else
8992b15cb3dSCy Schubert 		return -1;
9002b15cb3dSCy Schubert }
9012b15cb3dSCy Schubert 
9022b15cb3dSCy Schubert /** Parse a service name in 'servname', which can be a decimal port.
9032b15cb3dSCy Schubert  * Return the port number, or -1 on error.
9042b15cb3dSCy Schubert  */
9052b15cb3dSCy Schubert static int
evutil_parse_servname(const char * servname,const char * protocol,const struct evutil_addrinfo * hints)9062b15cb3dSCy Schubert evutil_parse_servname(const char *servname, const char *protocol,
9072b15cb3dSCy Schubert     const struct evutil_addrinfo *hints)
9082b15cb3dSCy Schubert {
9092b15cb3dSCy Schubert 	int n = parse_numeric_servname(servname);
9102b15cb3dSCy Schubert 	if (n>=0)
9112b15cb3dSCy Schubert 		return n;
9122b15cb3dSCy Schubert #if defined(EVENT__HAVE_GETSERVBYNAME) || defined(_WIN32)
9132b15cb3dSCy Schubert 	if (!(hints->ai_flags & EVUTIL_AI_NUMERICSERV)) {
9142b15cb3dSCy Schubert 		struct servent *ent = getservbyname(servname, protocol);
9152b15cb3dSCy Schubert 		if (ent) {
9162b15cb3dSCy Schubert 			return ntohs(ent->s_port);
9172b15cb3dSCy Schubert 		}
9182b15cb3dSCy Schubert 	}
9192b15cb3dSCy Schubert #endif
9202b15cb3dSCy Schubert 	return -1;
9212b15cb3dSCy Schubert }
9222b15cb3dSCy Schubert 
9232b15cb3dSCy Schubert /* Return a string corresponding to a protocol number that we can pass to
9242b15cb3dSCy Schubert  * getservyname.  */
9252b15cb3dSCy Schubert static const char *
evutil_unparse_protoname(int proto)9262b15cb3dSCy Schubert evutil_unparse_protoname(int proto)
9272b15cb3dSCy Schubert {
9282b15cb3dSCy Schubert 	switch (proto) {
9292b15cb3dSCy Schubert 	case 0:
9302b15cb3dSCy Schubert 		return NULL;
9312b15cb3dSCy Schubert 	case IPPROTO_TCP:
9322b15cb3dSCy Schubert 		return "tcp";
9332b15cb3dSCy Schubert 	case IPPROTO_UDP:
9342b15cb3dSCy Schubert 		return "udp";
9352b15cb3dSCy Schubert #ifdef IPPROTO_SCTP
9362b15cb3dSCy Schubert 	case IPPROTO_SCTP:
9372b15cb3dSCy Schubert 		return "sctp";
9382b15cb3dSCy Schubert #endif
9392b15cb3dSCy Schubert 	default:
9402b15cb3dSCy Schubert #ifdef EVENT__HAVE_GETPROTOBYNUMBER
9412b15cb3dSCy Schubert 		{
9422b15cb3dSCy Schubert 			struct protoent *ent = getprotobynumber(proto);
9432b15cb3dSCy Schubert 			if (ent)
9442b15cb3dSCy Schubert 				return ent->p_name;
9452b15cb3dSCy Schubert 		}
9462b15cb3dSCy Schubert #endif
9472b15cb3dSCy Schubert 		return NULL;
9482b15cb3dSCy Schubert 	}
9492b15cb3dSCy Schubert }
9502b15cb3dSCy Schubert 
9512b15cb3dSCy Schubert static void
evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo * hints)9522b15cb3dSCy Schubert evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints)
9532b15cb3dSCy Schubert {
9542b15cb3dSCy Schubert 	/* If we can guess the protocol from the socktype, do so. */
9552b15cb3dSCy Schubert 	if (!hints->ai_protocol && hints->ai_socktype) {
9562b15cb3dSCy Schubert 		if (hints->ai_socktype == SOCK_DGRAM)
9572b15cb3dSCy Schubert 			hints->ai_protocol = IPPROTO_UDP;
9582b15cb3dSCy Schubert 		else if (hints->ai_socktype == SOCK_STREAM)
9592b15cb3dSCy Schubert 			hints->ai_protocol = IPPROTO_TCP;
9602b15cb3dSCy Schubert 	}
9612b15cb3dSCy Schubert 
9622b15cb3dSCy Schubert 	/* Set the socktype if it isn't set. */
9632b15cb3dSCy Schubert 	if (!hints->ai_socktype && hints->ai_protocol) {
9642b15cb3dSCy Schubert 		if (hints->ai_protocol == IPPROTO_UDP)
9652b15cb3dSCy Schubert 			hints->ai_socktype = SOCK_DGRAM;
9662b15cb3dSCy Schubert 		else if (hints->ai_protocol == IPPROTO_TCP)
9672b15cb3dSCy Schubert 			hints->ai_socktype = SOCK_STREAM;
9682b15cb3dSCy Schubert #ifdef IPPROTO_SCTP
9692b15cb3dSCy Schubert 		else if (hints->ai_protocol == IPPROTO_SCTP)
9702b15cb3dSCy Schubert 			hints->ai_socktype = SOCK_STREAM;
9712b15cb3dSCy Schubert #endif
9722b15cb3dSCy Schubert 	}
9732b15cb3dSCy Schubert }
9742b15cb3dSCy Schubert 
9752b15cb3dSCy Schubert #if AF_UNSPEC != PF_UNSPEC
9762b15cb3dSCy Schubert #error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC"
9772b15cb3dSCy Schubert #endif
9782b15cb3dSCy Schubert 
9792b15cb3dSCy Schubert /** Implements the part of looking up hosts by name that's common to both
9802b15cb3dSCy Schubert  * the blocking and nonblocking resolver:
9812b15cb3dSCy Schubert  *   - Adjust 'hints' to have a reasonable socktype and protocol.
9822b15cb3dSCy Schubert  *   - Look up the port based on 'servname', and store it in *portnum,
9832b15cb3dSCy Schubert  *   - Handle the nodename==NULL case
9842b15cb3dSCy Schubert  *   - Handle some invalid arguments cases.
9852b15cb3dSCy Schubert  *   - Handle the cases where nodename is an IPv4 or IPv6 address.
9862b15cb3dSCy Schubert  *
9872b15cb3dSCy Schubert  * If we need the resolver to look up the hostname, we return
9882b15cb3dSCy Schubert  * EVUTIL_EAI_NEED_RESOLVE.  Otherwise, we can completely implement
9892b15cb3dSCy Schubert  * getaddrinfo: we return 0 or an appropriate EVUTIL_EAI_* error, and
9902b15cb3dSCy Schubert  * set *res as getaddrinfo would.
9912b15cb3dSCy Schubert  */
9922b15cb3dSCy Schubert int
evutil_getaddrinfo_common_(const char * nodename,const char * servname,struct evutil_addrinfo * hints,struct evutil_addrinfo ** res,int * portnum)9932b15cb3dSCy Schubert evutil_getaddrinfo_common_(const char *nodename, const char *servname,
9942b15cb3dSCy Schubert     struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
9952b15cb3dSCy Schubert {
9962b15cb3dSCy Schubert 	int port = 0;
997*a466cc55SCy Schubert 	unsigned int if_index;
9982b15cb3dSCy Schubert 	const char *pname;
9992b15cb3dSCy Schubert 
10002b15cb3dSCy Schubert 	if (nodename == NULL && servname == NULL)
10012b15cb3dSCy Schubert 		return EVUTIL_EAI_NONAME;
10022b15cb3dSCy Schubert 
10032b15cb3dSCy Schubert 	/* We only understand 3 families */
10042b15cb3dSCy Schubert 	if (hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET &&
10052b15cb3dSCy Schubert 	    hints->ai_family != PF_INET6)
10062b15cb3dSCy Schubert 		return EVUTIL_EAI_FAMILY;
10072b15cb3dSCy Schubert 
10082b15cb3dSCy Schubert 	evutil_getaddrinfo_infer_protocols(hints);
10092b15cb3dSCy Schubert 
10102b15cb3dSCy Schubert 	/* Look up the port number and protocol, if possible. */
10112b15cb3dSCy Schubert 	pname = evutil_unparse_protoname(hints->ai_protocol);
10122b15cb3dSCy Schubert 	if (servname) {
10132b15cb3dSCy Schubert 		/* XXXX We could look at the protocol we got back from
10142b15cb3dSCy Schubert 		 * getservbyname, but it doesn't seem too useful. */
10152b15cb3dSCy Schubert 		port = evutil_parse_servname(servname, pname, hints);
10162b15cb3dSCy Schubert 		if (port < 0) {
10172b15cb3dSCy Schubert 			return EVUTIL_EAI_NONAME;
10182b15cb3dSCy Schubert 		}
10192b15cb3dSCy Schubert 	}
10202b15cb3dSCy Schubert 
10212b15cb3dSCy Schubert 	/* If we have no node name, then we're supposed to bind to 'any' and
10222b15cb3dSCy Schubert 	 * connect to localhost. */
10232b15cb3dSCy Schubert 	if (nodename == NULL) {
10242b15cb3dSCy Schubert 		struct evutil_addrinfo *res4=NULL, *res6=NULL;
10252b15cb3dSCy Schubert 		if (hints->ai_family != PF_INET) { /* INET6 or UNSPEC. */
10262b15cb3dSCy Schubert 			struct sockaddr_in6 sin6;
10272b15cb3dSCy Schubert 			memset(&sin6, 0, sizeof(sin6));
10282b15cb3dSCy Schubert 			sin6.sin6_family = AF_INET6;
10292b15cb3dSCy Schubert 			sin6.sin6_port = htons(port);
10302b15cb3dSCy Schubert 			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
10312b15cb3dSCy Schubert 				/* Bind to :: */
10322b15cb3dSCy Schubert 			} else {
10332b15cb3dSCy Schubert 				/* connect to ::1 */
10342b15cb3dSCy Schubert 				sin6.sin6_addr.s6_addr[15] = 1;
10352b15cb3dSCy Schubert 			}
10362b15cb3dSCy Schubert 			res6 = evutil_new_addrinfo_((struct sockaddr*)&sin6,
10372b15cb3dSCy Schubert 			    sizeof(sin6), hints);
10382b15cb3dSCy Schubert 			if (!res6)
10392b15cb3dSCy Schubert 				return EVUTIL_EAI_MEMORY;
10402b15cb3dSCy Schubert 		}
10412b15cb3dSCy Schubert 
10422b15cb3dSCy Schubert 		if (hints->ai_family != PF_INET6) { /* INET or UNSPEC */
10432b15cb3dSCy Schubert 			struct sockaddr_in sin;
10442b15cb3dSCy Schubert 			memset(&sin, 0, sizeof(sin));
10452b15cb3dSCy Schubert 			sin.sin_family = AF_INET;
10462b15cb3dSCy Schubert 			sin.sin_port = htons(port);
10472b15cb3dSCy Schubert 			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
10482b15cb3dSCy Schubert 				/* Bind to 0.0.0.0 */
10492b15cb3dSCy Schubert 			} else {
10502b15cb3dSCy Schubert 				/* connect to 127.0.0.1 */
10512b15cb3dSCy Schubert 				sin.sin_addr.s_addr = htonl(0x7f000001);
10522b15cb3dSCy Schubert 			}
10532b15cb3dSCy Schubert 			res4 = evutil_new_addrinfo_((struct sockaddr*)&sin,
10542b15cb3dSCy Schubert 			    sizeof(sin), hints);
10552b15cb3dSCy Schubert 			if (!res4) {
10562b15cb3dSCy Schubert 				if (res6)
10572b15cb3dSCy Schubert 					evutil_freeaddrinfo(res6);
10582b15cb3dSCy Schubert 				return EVUTIL_EAI_MEMORY;
10592b15cb3dSCy Schubert 			}
10602b15cb3dSCy Schubert 		}
10612b15cb3dSCy Schubert 		*res = evutil_addrinfo_append_(res4, res6);
10622b15cb3dSCy Schubert 		return 0;
10632b15cb3dSCy Schubert 	}
10642b15cb3dSCy Schubert 
10652b15cb3dSCy Schubert 	/* If we can, we should try to parse the hostname without resolving
10662b15cb3dSCy Schubert 	 * it. */
10672b15cb3dSCy Schubert 	/* Try ipv6. */
10682b15cb3dSCy Schubert 	if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
10692b15cb3dSCy Schubert 		struct sockaddr_in6 sin6;
10702b15cb3dSCy Schubert 		memset(&sin6, 0, sizeof(sin6));
1071*a466cc55SCy Schubert 		if (1 == evutil_inet_pton_scope(
1072*a466cc55SCy Schubert 			AF_INET6, nodename, &sin6.sin6_addr, &if_index)) {
10732b15cb3dSCy Schubert 			/* Got an ipv6 address. */
10742b15cb3dSCy Schubert 			sin6.sin6_family = AF_INET6;
10752b15cb3dSCy Schubert 			sin6.sin6_port = htons(port);
1076*a466cc55SCy Schubert 			sin6.sin6_scope_id = if_index;
10772b15cb3dSCy Schubert 			*res = evutil_new_addrinfo_((struct sockaddr*)&sin6,
10782b15cb3dSCy Schubert 			    sizeof(sin6), hints);
10792b15cb3dSCy Schubert 			if (!*res)
10802b15cb3dSCy Schubert 				return EVUTIL_EAI_MEMORY;
10812b15cb3dSCy Schubert 			return 0;
10822b15cb3dSCy Schubert 		}
10832b15cb3dSCy Schubert 	}
10842b15cb3dSCy Schubert 
10852b15cb3dSCy Schubert 	/* Try ipv4. */
10862b15cb3dSCy Schubert 	if (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC) {
10872b15cb3dSCy Schubert 		struct sockaddr_in sin;
10882b15cb3dSCy Schubert 		memset(&sin, 0, sizeof(sin));
10892b15cb3dSCy Schubert 		if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
1090*a466cc55SCy Schubert 			/* Got an ipv4 address. */
10912b15cb3dSCy Schubert 			sin.sin_family = AF_INET;
10922b15cb3dSCy Schubert 			sin.sin_port = htons(port);
10932b15cb3dSCy Schubert 			*res = evutil_new_addrinfo_((struct sockaddr*)&sin,
10942b15cb3dSCy Schubert 			    sizeof(sin), hints);
10952b15cb3dSCy Schubert 			if (!*res)
10962b15cb3dSCy Schubert 				return EVUTIL_EAI_MEMORY;
10972b15cb3dSCy Schubert 			return 0;
10982b15cb3dSCy Schubert 		}
10992b15cb3dSCy Schubert 	}
11002b15cb3dSCy Schubert 
11012b15cb3dSCy Schubert 
11022b15cb3dSCy Schubert 	/* If we have reached this point, we definitely need to do a DNS
11032b15cb3dSCy Schubert 	 * lookup. */
11042b15cb3dSCy Schubert 	if ((hints->ai_flags & EVUTIL_AI_NUMERICHOST)) {
11052b15cb3dSCy Schubert 		/* If we're not allowed to do one, then say so. */
11062b15cb3dSCy Schubert 		return EVUTIL_EAI_NONAME;
11072b15cb3dSCy Schubert 	}
11082b15cb3dSCy Schubert 	*portnum = port;
11092b15cb3dSCy Schubert 	return EVUTIL_EAI_NEED_RESOLVE;
11102b15cb3dSCy Schubert }
11112b15cb3dSCy Schubert 
11122b15cb3dSCy Schubert #ifdef EVENT__HAVE_GETADDRINFO
11132b15cb3dSCy Schubert #define USE_NATIVE_GETADDRINFO
11142b15cb3dSCy Schubert #endif
11152b15cb3dSCy Schubert 
11162b15cb3dSCy Schubert #ifdef USE_NATIVE_GETADDRINFO
11172b15cb3dSCy Schubert /* A mask of all the flags that we declare, so we can clear them before calling
11182b15cb3dSCy Schubert  * the native getaddrinfo */
11192b15cb3dSCy Schubert static const unsigned int ALL_NONNATIVE_AI_FLAGS =
11202b15cb3dSCy Schubert #ifndef AI_PASSIVE
11212b15cb3dSCy Schubert     EVUTIL_AI_PASSIVE |
11222b15cb3dSCy Schubert #endif
11232b15cb3dSCy Schubert #ifndef AI_CANONNAME
11242b15cb3dSCy Schubert     EVUTIL_AI_CANONNAME |
11252b15cb3dSCy Schubert #endif
11262b15cb3dSCy Schubert #ifndef AI_NUMERICHOST
11272b15cb3dSCy Schubert     EVUTIL_AI_NUMERICHOST |
11282b15cb3dSCy Schubert #endif
11292b15cb3dSCy Schubert #ifndef AI_NUMERICSERV
11302b15cb3dSCy Schubert     EVUTIL_AI_NUMERICSERV |
11312b15cb3dSCy Schubert #endif
11322b15cb3dSCy Schubert #ifndef AI_ADDRCONFIG
11332b15cb3dSCy Schubert     EVUTIL_AI_ADDRCONFIG |
11342b15cb3dSCy Schubert #endif
11352b15cb3dSCy Schubert #ifndef AI_ALL
11362b15cb3dSCy Schubert     EVUTIL_AI_ALL |
11372b15cb3dSCy Schubert #endif
11382b15cb3dSCy Schubert #ifndef AI_V4MAPPED
11392b15cb3dSCy Schubert     EVUTIL_AI_V4MAPPED |
11402b15cb3dSCy Schubert #endif
11412b15cb3dSCy Schubert     EVUTIL_AI_LIBEVENT_ALLOCATED;
11422b15cb3dSCy Schubert 
11432b15cb3dSCy Schubert static const unsigned int ALL_NATIVE_AI_FLAGS =
11442b15cb3dSCy Schubert #ifdef AI_PASSIVE
11452b15cb3dSCy Schubert     AI_PASSIVE |
11462b15cb3dSCy Schubert #endif
11472b15cb3dSCy Schubert #ifdef AI_CANONNAME
11482b15cb3dSCy Schubert     AI_CANONNAME |
11492b15cb3dSCy Schubert #endif
11502b15cb3dSCy Schubert #ifdef AI_NUMERICHOST
11512b15cb3dSCy Schubert     AI_NUMERICHOST |
11522b15cb3dSCy Schubert #endif
11532b15cb3dSCy Schubert #ifdef AI_NUMERICSERV
11542b15cb3dSCy Schubert     AI_NUMERICSERV |
11552b15cb3dSCy Schubert #endif
11562b15cb3dSCy Schubert #ifdef AI_ADDRCONFIG
11572b15cb3dSCy Schubert     AI_ADDRCONFIG |
11582b15cb3dSCy Schubert #endif
11592b15cb3dSCy Schubert #ifdef AI_ALL
11602b15cb3dSCy Schubert     AI_ALL |
11612b15cb3dSCy Schubert #endif
11622b15cb3dSCy Schubert #ifdef AI_V4MAPPED
11632b15cb3dSCy Schubert     AI_V4MAPPED |
11642b15cb3dSCy Schubert #endif
11652b15cb3dSCy Schubert     0;
11662b15cb3dSCy Schubert #endif
11672b15cb3dSCy Schubert 
11682b15cb3dSCy Schubert #ifndef USE_NATIVE_GETADDRINFO
11692b15cb3dSCy Schubert /* Helper for systems with no getaddrinfo(): make one or more addrinfos out of
11702b15cb3dSCy Schubert  * a struct hostent.
11712b15cb3dSCy Schubert  */
11722b15cb3dSCy Schubert static struct evutil_addrinfo *
addrinfo_from_hostent(const struct hostent * ent,int port,const struct evutil_addrinfo * hints)11732b15cb3dSCy Schubert addrinfo_from_hostent(const struct hostent *ent,
11742b15cb3dSCy Schubert     int port, const struct evutil_addrinfo *hints)
11752b15cb3dSCy Schubert {
11762b15cb3dSCy Schubert 	int i;
11772b15cb3dSCy Schubert 	struct sockaddr_in sin;
11782b15cb3dSCy Schubert 	struct sockaddr_in6 sin6;
11792b15cb3dSCy Schubert 	struct sockaddr *sa;
11802b15cb3dSCy Schubert 	int socklen;
11812b15cb3dSCy Schubert 	struct evutil_addrinfo *res=NULL, *ai;
11822b15cb3dSCy Schubert 	void *addrp;
11832b15cb3dSCy Schubert 
11842b15cb3dSCy Schubert 	if (ent->h_addrtype == PF_INET) {
11852b15cb3dSCy Schubert 		memset(&sin, 0, sizeof(sin));
11862b15cb3dSCy Schubert 		sin.sin_family = AF_INET;
11872b15cb3dSCy Schubert 		sin.sin_port = htons(port);
11882b15cb3dSCy Schubert 		sa = (struct sockaddr *)&sin;
11892b15cb3dSCy Schubert 		socklen = sizeof(struct sockaddr_in);
11902b15cb3dSCy Schubert 		addrp = &sin.sin_addr;
11912b15cb3dSCy Schubert 		if (ent->h_length != sizeof(sin.sin_addr)) {
11922b15cb3dSCy Schubert 			event_warnx("Weird h_length from gethostbyname");
11932b15cb3dSCy Schubert 			return NULL;
11942b15cb3dSCy Schubert 		}
11952b15cb3dSCy Schubert 	} else if (ent->h_addrtype == PF_INET6) {
11962b15cb3dSCy Schubert 		memset(&sin6, 0, sizeof(sin6));
11972b15cb3dSCy Schubert 		sin6.sin6_family = AF_INET6;
11982b15cb3dSCy Schubert 		sin6.sin6_port = htons(port);
11992b15cb3dSCy Schubert 		sa = (struct sockaddr *)&sin6;
1200*a466cc55SCy Schubert 		socklen = sizeof(struct sockaddr_in6);
12012b15cb3dSCy Schubert 		addrp = &sin6.sin6_addr;
12022b15cb3dSCy Schubert 		if (ent->h_length != sizeof(sin6.sin6_addr)) {
12032b15cb3dSCy Schubert 			event_warnx("Weird h_length from gethostbyname");
12042b15cb3dSCy Schubert 			return NULL;
12052b15cb3dSCy Schubert 		}
12062b15cb3dSCy Schubert 	} else
12072b15cb3dSCy Schubert 		return NULL;
12082b15cb3dSCy Schubert 
12092b15cb3dSCy Schubert 	for (i = 0; ent->h_addr_list[i]; ++i) {
12102b15cb3dSCy Schubert 		memcpy(addrp, ent->h_addr_list[i], ent->h_length);
12112b15cb3dSCy Schubert 		ai = evutil_new_addrinfo_(sa, socklen, hints);
12122b15cb3dSCy Schubert 		if (!ai) {
12132b15cb3dSCy Schubert 			evutil_freeaddrinfo(res);
12142b15cb3dSCy Schubert 			return NULL;
12152b15cb3dSCy Schubert 		}
12162b15cb3dSCy Schubert 		res = evutil_addrinfo_append_(res, ai);
12172b15cb3dSCy Schubert 	}
12182b15cb3dSCy Schubert 
12192b15cb3dSCy Schubert 	if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) {
12202b15cb3dSCy Schubert 		res->ai_canonname = mm_strdup(ent->h_name);
12212b15cb3dSCy Schubert 		if (res->ai_canonname == NULL) {
12222b15cb3dSCy Schubert 			evutil_freeaddrinfo(res);
12232b15cb3dSCy Schubert 			return NULL;
12242b15cb3dSCy Schubert 		}
12252b15cb3dSCy Schubert 	}
12262b15cb3dSCy Schubert 
12272b15cb3dSCy Schubert 	return res;
12282b15cb3dSCy Schubert }
12292b15cb3dSCy Schubert #endif
12302b15cb3dSCy Schubert 
12312b15cb3dSCy Schubert /* If the EVUTIL_AI_ADDRCONFIG flag is set on hints->ai_flags, and
12322b15cb3dSCy Schubert  * hints->ai_family is PF_UNSPEC, then revise the value of hints->ai_family so
12332b15cb3dSCy Schubert  * that we'll only get addresses we could maybe connect to.
12342b15cb3dSCy Schubert  */
12352b15cb3dSCy Schubert void
evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo * hints)12362b15cb3dSCy Schubert evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints)
12372b15cb3dSCy Schubert {
12382b15cb3dSCy Schubert 	if (!(hints->ai_flags & EVUTIL_AI_ADDRCONFIG))
12392b15cb3dSCy Schubert 		return;
12402b15cb3dSCy Schubert 	if (hints->ai_family != PF_UNSPEC)
12412b15cb3dSCy Schubert 		return;
1242*a466cc55SCy Schubert 	evutil_check_interfaces();
12432b15cb3dSCy Schubert 	if (had_ipv4_address && !had_ipv6_address) {
12442b15cb3dSCy Schubert 		hints->ai_family = PF_INET;
12452b15cb3dSCy Schubert 	} else if (!had_ipv4_address && had_ipv6_address) {
12462b15cb3dSCy Schubert 		hints->ai_family = PF_INET6;
12472b15cb3dSCy Schubert 	}
12482b15cb3dSCy Schubert }
12492b15cb3dSCy Schubert 
12502b15cb3dSCy Schubert #ifdef USE_NATIVE_GETADDRINFO
12512b15cb3dSCy Schubert static int need_numeric_port_hack_=0;
12522b15cb3dSCy Schubert static int need_socktype_protocol_hack_=0;
12532b15cb3dSCy Schubert static int tested_for_getaddrinfo_hacks=0;
12542b15cb3dSCy Schubert 
12552b15cb3dSCy Schubert /* Some older BSDs (like OpenBSD up to 4.6) used to believe that
12562b15cb3dSCy Schubert    giving a numeric port without giving an ai_socktype was verboten.
12572b15cb3dSCy Schubert    We test for this so we can apply an appropriate workaround.  If it
12582b15cb3dSCy Schubert    turns out that the bug is present, then:
12592b15cb3dSCy Schubert 
12602b15cb3dSCy Schubert     - If nodename==NULL and servname is numeric, we build an answer
12612b15cb3dSCy Schubert       ourselves using evutil_getaddrinfo_common_().
12622b15cb3dSCy Schubert 
12632b15cb3dSCy Schubert     - If nodename!=NULL and servname is numeric, then we set
12642b15cb3dSCy Schubert       servname=NULL when calling getaddrinfo, and post-process the
12652b15cb3dSCy Schubert       result to set the ports on it.
12662b15cb3dSCy Schubert 
12672b15cb3dSCy Schubert    We test for this bug at runtime, since otherwise we can't have the
12682b15cb3dSCy Schubert    same binary run on multiple BSD versions.
12692b15cb3dSCy Schubert 
12702b15cb3dSCy Schubert    - Some versions of Solaris believe that it's nice to leave to protocol
12712b15cb3dSCy Schubert      field set to 0.  We test for this so we can apply an appropriate
12722b15cb3dSCy Schubert      workaround.
12732b15cb3dSCy Schubert */
ai_find_protocol(struct evutil_addrinfo * ai)1274*a466cc55SCy Schubert static struct evutil_addrinfo *ai_find_protocol(struct evutil_addrinfo *ai)
1275*a466cc55SCy Schubert {
1276*a466cc55SCy Schubert 	while (ai) {
1277*a466cc55SCy Schubert 		if (ai->ai_protocol)
1278*a466cc55SCy Schubert 			return ai;
1279*a466cc55SCy Schubert 		ai = ai->ai_next;
1280*a466cc55SCy Schubert 	}
1281*a466cc55SCy Schubert 	return NULL;
1282*a466cc55SCy Schubert }
12832b15cb3dSCy Schubert static void
test_for_getaddrinfo_hacks(void)12842b15cb3dSCy Schubert test_for_getaddrinfo_hacks(void)
12852b15cb3dSCy Schubert {
12862b15cb3dSCy Schubert 	int r, r2;
1287*a466cc55SCy Schubert 	struct evutil_addrinfo *ai=NULL, *ai2=NULL, *ai3=NULL;
12882b15cb3dSCy Schubert 	struct evutil_addrinfo hints;
12892b15cb3dSCy Schubert 
12902b15cb3dSCy Schubert 	memset(&hints,0,sizeof(hints));
12912b15cb3dSCy Schubert 	hints.ai_family = PF_UNSPEC;
12922b15cb3dSCy Schubert 	hints.ai_flags =
12932b15cb3dSCy Schubert #ifdef AI_NUMERICHOST
12942b15cb3dSCy Schubert 	    AI_NUMERICHOST |
12952b15cb3dSCy Schubert #endif
12962b15cb3dSCy Schubert #ifdef AI_NUMERICSERV
12972b15cb3dSCy Schubert 	    AI_NUMERICSERV |
12982b15cb3dSCy Schubert #endif
12992b15cb3dSCy Schubert 	    0;
13002b15cb3dSCy Schubert 	r = getaddrinfo("1.2.3.4", "80", &hints, &ai);
1301*a466cc55SCy Schubert 	getaddrinfo("1.2.3.4", NULL, &hints, &ai3);
13022b15cb3dSCy Schubert 	hints.ai_socktype = SOCK_STREAM;
13032b15cb3dSCy Schubert 	r2 = getaddrinfo("1.2.3.4", "80", &hints, &ai2);
13042b15cb3dSCy Schubert 	if (r2 == 0 && r != 0) {
13052b15cb3dSCy Schubert 		need_numeric_port_hack_=1;
13062b15cb3dSCy Schubert 	}
1307*a466cc55SCy Schubert 	if (!ai_find_protocol(ai2) || !ai_find_protocol(ai3)) {
13082b15cb3dSCy Schubert 		need_socktype_protocol_hack_=1;
13092b15cb3dSCy Schubert 	}
13102b15cb3dSCy Schubert 
13112b15cb3dSCy Schubert 	if (ai)
13122b15cb3dSCy Schubert 		freeaddrinfo(ai);
13132b15cb3dSCy Schubert 	if (ai2)
13142b15cb3dSCy Schubert 		freeaddrinfo(ai2);
1315*a466cc55SCy Schubert 	if (ai3)
1316*a466cc55SCy Schubert 		freeaddrinfo(ai3);
13172b15cb3dSCy Schubert 	tested_for_getaddrinfo_hacks=1;
13182b15cb3dSCy Schubert }
13192b15cb3dSCy Schubert 
13202b15cb3dSCy Schubert static inline int
need_numeric_port_hack(void)13212b15cb3dSCy Schubert need_numeric_port_hack(void)
13222b15cb3dSCy Schubert {
13232b15cb3dSCy Schubert 	if (!tested_for_getaddrinfo_hacks)
13242b15cb3dSCy Schubert 		test_for_getaddrinfo_hacks();
13252b15cb3dSCy Schubert 	return need_numeric_port_hack_;
13262b15cb3dSCy Schubert }
13272b15cb3dSCy Schubert 
13282b15cb3dSCy Schubert static inline int
need_socktype_protocol_hack(void)13292b15cb3dSCy Schubert need_socktype_protocol_hack(void)
13302b15cb3dSCy Schubert {
13312b15cb3dSCy Schubert 	if (!tested_for_getaddrinfo_hacks)
13322b15cb3dSCy Schubert 		test_for_getaddrinfo_hacks();
13332b15cb3dSCy Schubert 	return need_socktype_protocol_hack_;
13342b15cb3dSCy Schubert }
13352b15cb3dSCy Schubert 
13362b15cb3dSCy Schubert static void
apply_numeric_port_hack(int port,struct evutil_addrinfo ** ai)13372b15cb3dSCy Schubert apply_numeric_port_hack(int port, struct evutil_addrinfo **ai)
13382b15cb3dSCy Schubert {
13392b15cb3dSCy Schubert 	/* Now we run through the list and set the ports on all of the
13402b15cb3dSCy Schubert 	 * results where ports would make sense. */
13412b15cb3dSCy Schubert 	for ( ; *ai; ai = &(*ai)->ai_next) {
13422b15cb3dSCy Schubert 		struct sockaddr *sa = (*ai)->ai_addr;
13432b15cb3dSCy Schubert 		if (sa && sa->sa_family == AF_INET) {
13442b15cb3dSCy Schubert 			struct sockaddr_in *sin = (struct sockaddr_in*)sa;
13452b15cb3dSCy Schubert 			sin->sin_port = htons(port);
13462b15cb3dSCy Schubert 		} else if (sa && sa->sa_family == AF_INET6) {
13472b15cb3dSCy Schubert 			struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
13482b15cb3dSCy Schubert 			sin6->sin6_port = htons(port);
13492b15cb3dSCy Schubert 		} else {
13502b15cb3dSCy Schubert 			/* A numeric port makes no sense here; remove this one
13512b15cb3dSCy Schubert 			 * from the list. */
13522b15cb3dSCy Schubert 			struct evutil_addrinfo *victim = *ai;
13532b15cb3dSCy Schubert 			*ai = victim->ai_next;
13542b15cb3dSCy Schubert 			victim->ai_next = NULL;
13552b15cb3dSCy Schubert 			freeaddrinfo(victim);
13562b15cb3dSCy Schubert 		}
13572b15cb3dSCy Schubert 	}
13582b15cb3dSCy Schubert }
13592b15cb3dSCy Schubert 
13602b15cb3dSCy Schubert static int
apply_socktype_protocol_hack(struct evutil_addrinfo * ai)13612b15cb3dSCy Schubert apply_socktype_protocol_hack(struct evutil_addrinfo *ai)
13622b15cb3dSCy Schubert {
13632b15cb3dSCy Schubert 	struct evutil_addrinfo *ai_new;
13642b15cb3dSCy Schubert 	for (; ai; ai = ai->ai_next) {
13652b15cb3dSCy Schubert 		evutil_getaddrinfo_infer_protocols(ai);
13662b15cb3dSCy Schubert 		if (ai->ai_socktype || ai->ai_protocol)
13672b15cb3dSCy Schubert 			continue;
13682b15cb3dSCy Schubert 		ai_new = mm_malloc(sizeof(*ai_new));
13692b15cb3dSCy Schubert 		if (!ai_new)
13702b15cb3dSCy Schubert 			return -1;
13712b15cb3dSCy Schubert 		memcpy(ai_new, ai, sizeof(*ai_new));
13722b15cb3dSCy Schubert 		ai->ai_socktype = SOCK_STREAM;
13732b15cb3dSCy Schubert 		ai->ai_protocol = IPPROTO_TCP;
13742b15cb3dSCy Schubert 		ai_new->ai_socktype = SOCK_DGRAM;
13752b15cb3dSCy Schubert 		ai_new->ai_protocol = IPPROTO_UDP;
13762b15cb3dSCy Schubert 
13772b15cb3dSCy Schubert 		ai_new->ai_next = ai->ai_next;
13782b15cb3dSCy Schubert 		ai->ai_next = ai_new;
13792b15cb3dSCy Schubert 	}
13802b15cb3dSCy Schubert 	return 0;
13812b15cb3dSCy Schubert }
13822b15cb3dSCy Schubert #endif
13832b15cb3dSCy Schubert 
13842b15cb3dSCy Schubert int
evutil_getaddrinfo(const char * nodename,const char * servname,const struct evutil_addrinfo * hints_in,struct evutil_addrinfo ** res)13852b15cb3dSCy Schubert evutil_getaddrinfo(const char *nodename, const char *servname,
13862b15cb3dSCy Schubert     const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res)
13872b15cb3dSCy Schubert {
13882b15cb3dSCy Schubert #ifdef USE_NATIVE_GETADDRINFO
13892b15cb3dSCy Schubert 	struct evutil_addrinfo hints;
13902b15cb3dSCy Schubert 	int portnum=-1, need_np_hack, err;
13912b15cb3dSCy Schubert 
13922b15cb3dSCy Schubert 	if (hints_in) {
13932b15cb3dSCy Schubert 		memcpy(&hints, hints_in, sizeof(hints));
13942b15cb3dSCy Schubert 	} else {
13952b15cb3dSCy Schubert 		memset(&hints, 0, sizeof(hints));
13962b15cb3dSCy Schubert 		hints.ai_family = PF_UNSPEC;
13972b15cb3dSCy Schubert 	}
13982b15cb3dSCy Schubert 
13992b15cb3dSCy Schubert #ifndef AI_ADDRCONFIG
14002b15cb3dSCy Schubert 	/* Not every system has AI_ADDRCONFIG, so fake it. */
14012b15cb3dSCy Schubert 	if (hints.ai_family == PF_UNSPEC &&
14022b15cb3dSCy Schubert 	    (hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
14032b15cb3dSCy Schubert 		evutil_adjust_hints_for_addrconfig_(&hints);
14042b15cb3dSCy Schubert 	}
14052b15cb3dSCy Schubert #endif
14062b15cb3dSCy Schubert 
14072b15cb3dSCy Schubert #ifndef AI_NUMERICSERV
14082b15cb3dSCy Schubert 	/* Not every system has AI_NUMERICSERV, so fake it. */
14092b15cb3dSCy Schubert 	if (hints.ai_flags & EVUTIL_AI_NUMERICSERV) {
14102b15cb3dSCy Schubert 		if (servname && parse_numeric_servname(servname)<0)
14112b15cb3dSCy Schubert 			return EVUTIL_EAI_NONAME;
14122b15cb3dSCy Schubert 	}
14132b15cb3dSCy Schubert #endif
14142b15cb3dSCy Schubert 
14152b15cb3dSCy Schubert 	/* Enough operating systems handle enough common non-resolve
14162b15cb3dSCy Schubert 	 * cases here weirdly enough that we are better off just
14172b15cb3dSCy Schubert 	 * overriding them.  For example:
14182b15cb3dSCy Schubert 	 *
14192b15cb3dSCy Schubert 	 * - Windows doesn't like to infer the protocol from the
14202b15cb3dSCy Schubert 	 *   socket type, or fill in socket or protocol types much at
14212b15cb3dSCy Schubert 	 *   all.  It also seems to do its own broken implicit
14222b15cb3dSCy Schubert 	 *   always-on version of AI_ADDRCONFIG that keeps it from
14232b15cb3dSCy Schubert 	 *   ever resolving even a literal IPv6 address when
14242b15cb3dSCy Schubert 	 *   ai_addrtype is PF_UNSPEC.
14252b15cb3dSCy Schubert 	 */
14262b15cb3dSCy Schubert #ifdef _WIN32
14272b15cb3dSCy Schubert 	{
14282b15cb3dSCy Schubert 		int tmp_port;
14292b15cb3dSCy Schubert 		err = evutil_getaddrinfo_common_(nodename,servname,&hints,
14302b15cb3dSCy Schubert 		    res, &tmp_port);
14312b15cb3dSCy Schubert 		if (err == 0 ||
14322b15cb3dSCy Schubert 		    err == EVUTIL_EAI_MEMORY ||
14332b15cb3dSCy Schubert 		    err == EVUTIL_EAI_NONAME)
14342b15cb3dSCy Schubert 			return err;
14352b15cb3dSCy Schubert 		/* If we make it here, the system getaddrinfo can
14362b15cb3dSCy Schubert 		 * have a crack at it. */
14372b15cb3dSCy Schubert 	}
14382b15cb3dSCy Schubert #endif
14392b15cb3dSCy Schubert 
14402b15cb3dSCy Schubert 	/* See documentation for need_numeric_port_hack above.*/
14412b15cb3dSCy Schubert 	need_np_hack = need_numeric_port_hack() && servname && !hints.ai_socktype
14422b15cb3dSCy Schubert 	    && ((portnum=parse_numeric_servname(servname)) >= 0);
14432b15cb3dSCy Schubert 	if (need_np_hack) {
14442b15cb3dSCy Schubert 		if (!nodename)
14452b15cb3dSCy Schubert 			return evutil_getaddrinfo_common_(
14462b15cb3dSCy Schubert 				NULL,servname,&hints, res, &portnum);
14472b15cb3dSCy Schubert 		servname = NULL;
14482b15cb3dSCy Schubert 	}
14492b15cb3dSCy Schubert 
14502b15cb3dSCy Schubert 	if (need_socktype_protocol_hack()) {
14512b15cb3dSCy Schubert 		evutil_getaddrinfo_infer_protocols(&hints);
14522b15cb3dSCy Schubert 	}
14532b15cb3dSCy Schubert 
14542b15cb3dSCy Schubert 	/* Make sure that we didn't actually steal any AI_FLAGS values that
14552b15cb3dSCy Schubert 	 * the system is using.  (This is a constant expression, and should ge
14562b15cb3dSCy Schubert 	 * optimized out.)
14572b15cb3dSCy Schubert 	 *
14582b15cb3dSCy Schubert 	 * XXXX Turn this into a compile-time failure rather than a run-time
14592b15cb3dSCy Schubert 	 * failure.
14602b15cb3dSCy Schubert 	 */
14612b15cb3dSCy Schubert 	EVUTIL_ASSERT((ALL_NONNATIVE_AI_FLAGS & ALL_NATIVE_AI_FLAGS) == 0);
14622b15cb3dSCy Schubert 
14632b15cb3dSCy Schubert 	/* Clear any flags that only libevent understands. */
14642b15cb3dSCy Schubert 	hints.ai_flags &= ~ALL_NONNATIVE_AI_FLAGS;
14652b15cb3dSCy Schubert 
14662b15cb3dSCy Schubert 	err = getaddrinfo(nodename, servname, &hints, res);
14672b15cb3dSCy Schubert 	if (need_np_hack)
14682b15cb3dSCy Schubert 		apply_numeric_port_hack(portnum, res);
14692b15cb3dSCy Schubert 
14702b15cb3dSCy Schubert 	if (need_socktype_protocol_hack()) {
14712b15cb3dSCy Schubert 		if (apply_socktype_protocol_hack(*res) < 0) {
14722b15cb3dSCy Schubert 			evutil_freeaddrinfo(*res);
14732b15cb3dSCy Schubert 			*res = NULL;
14742b15cb3dSCy Schubert 			return EVUTIL_EAI_MEMORY;
14752b15cb3dSCy Schubert 		}
14762b15cb3dSCy Schubert 	}
14772b15cb3dSCy Schubert 	return err;
14782b15cb3dSCy Schubert #else
14792b15cb3dSCy Schubert 	int port=0, err;
14802b15cb3dSCy Schubert 	struct hostent *ent = NULL;
14812b15cb3dSCy Schubert 	struct evutil_addrinfo hints;
14822b15cb3dSCy Schubert 
14832b15cb3dSCy Schubert 	if (hints_in) {
14842b15cb3dSCy Schubert 		memcpy(&hints, hints_in, sizeof(hints));
14852b15cb3dSCy Schubert 	} else {
14862b15cb3dSCy Schubert 		memset(&hints, 0, sizeof(hints));
14872b15cb3dSCy Schubert 		hints.ai_family = PF_UNSPEC;
14882b15cb3dSCy Schubert 	}
14892b15cb3dSCy Schubert 
14902b15cb3dSCy Schubert 	evutil_adjust_hints_for_addrconfig_(&hints);
14912b15cb3dSCy Schubert 
14922b15cb3dSCy Schubert 	err = evutil_getaddrinfo_common_(nodename, servname, &hints, res, &port);
14932b15cb3dSCy Schubert 	if (err != EVUTIL_EAI_NEED_RESOLVE) {
14942b15cb3dSCy Schubert 		/* We either succeeded or failed.  No need to continue */
14952b15cb3dSCy Schubert 		return err;
14962b15cb3dSCy Schubert 	}
14972b15cb3dSCy Schubert 
14982b15cb3dSCy Schubert 	err = 0;
14992b15cb3dSCy Schubert 	/* Use any of the various gethostbyname_r variants as available. */
15002b15cb3dSCy Schubert 	{
15012b15cb3dSCy Schubert #ifdef EVENT__HAVE_GETHOSTBYNAME_R_6_ARG
15022b15cb3dSCy Schubert 		/* This one is what glibc provides. */
15032b15cb3dSCy Schubert 		char buf[2048];
15042b15cb3dSCy Schubert 		struct hostent hostent;
15052b15cb3dSCy Schubert 		int r;
15062b15cb3dSCy Schubert 		r = gethostbyname_r(nodename, &hostent, buf, sizeof(buf), &ent,
15072b15cb3dSCy Schubert 		    &err);
15082b15cb3dSCy Schubert #elif defined(EVENT__HAVE_GETHOSTBYNAME_R_5_ARG)
15092b15cb3dSCy Schubert 		char buf[2048];
15102b15cb3dSCy Schubert 		struct hostent hostent;
15112b15cb3dSCy Schubert 		ent = gethostbyname_r(nodename, &hostent, buf, sizeof(buf),
15122b15cb3dSCy Schubert 		    &err);
15132b15cb3dSCy Schubert #elif defined(EVENT__HAVE_GETHOSTBYNAME_R_3_ARG)
15142b15cb3dSCy Schubert 		struct hostent_data data;
15152b15cb3dSCy Schubert 		struct hostent hostent;
15162b15cb3dSCy Schubert 		memset(&data, 0, sizeof(data));
15172b15cb3dSCy Schubert 		err = gethostbyname_r(nodename, &hostent, &data);
15182b15cb3dSCy Schubert 		ent = err ? NULL : &hostent;
15192b15cb3dSCy Schubert #else
15202b15cb3dSCy Schubert 		/* fall back to gethostbyname. */
15212b15cb3dSCy Schubert 		/* XXXX This needs a lock everywhere but Windows. */
15222b15cb3dSCy Schubert 		ent = gethostbyname(nodename);
15232b15cb3dSCy Schubert #ifdef _WIN32
15242b15cb3dSCy Schubert 		err = WSAGetLastError();
15252b15cb3dSCy Schubert #else
15262b15cb3dSCy Schubert 		err = h_errno;
15272b15cb3dSCy Schubert #endif
15282b15cb3dSCy Schubert #endif
15292b15cb3dSCy Schubert 
15302b15cb3dSCy Schubert 		/* Now we have either ent or err set. */
15312b15cb3dSCy Schubert 		if (!ent) {
15322b15cb3dSCy Schubert 			/* XXX is this right for windows ? */
15332b15cb3dSCy Schubert 			switch (err) {
15342b15cb3dSCy Schubert 			case TRY_AGAIN:
15352b15cb3dSCy Schubert 				return EVUTIL_EAI_AGAIN;
15362b15cb3dSCy Schubert 			case NO_RECOVERY:
15372b15cb3dSCy Schubert 			default:
15382b15cb3dSCy Schubert 				return EVUTIL_EAI_FAIL;
15392b15cb3dSCy Schubert 			case HOST_NOT_FOUND:
15402b15cb3dSCy Schubert 				return EVUTIL_EAI_NONAME;
15412b15cb3dSCy Schubert 			case NO_ADDRESS:
15422b15cb3dSCy Schubert #if NO_DATA != NO_ADDRESS
15432b15cb3dSCy Schubert 			case NO_DATA:
15442b15cb3dSCy Schubert #endif
15452b15cb3dSCy Schubert 				return EVUTIL_EAI_NODATA;
15462b15cb3dSCy Schubert 			}
15472b15cb3dSCy Schubert 		}
15482b15cb3dSCy Schubert 
15492b15cb3dSCy Schubert 		if (ent->h_addrtype != hints.ai_family &&
15502b15cb3dSCy Schubert 		    hints.ai_family != PF_UNSPEC) {
15512b15cb3dSCy Schubert 			/* This wasn't the type we were hoping for.  Too bad
15522b15cb3dSCy Schubert 			 * we never had a chance to ask gethostbyname for what
15532b15cb3dSCy Schubert 			 * we wanted. */
15542b15cb3dSCy Schubert 			return EVUTIL_EAI_NONAME;
15552b15cb3dSCy Schubert 		}
15562b15cb3dSCy Schubert 
15572b15cb3dSCy Schubert 		/* Make sure we got _some_ answers. */
15582b15cb3dSCy Schubert 		if (ent->h_length == 0)
15592b15cb3dSCy Schubert 			return EVUTIL_EAI_NODATA;
15602b15cb3dSCy Schubert 
15612b15cb3dSCy Schubert 		/* If we got an address type we don't know how to make a
15622b15cb3dSCy Schubert 		   sockaddr for, give up. */
15632b15cb3dSCy Schubert 		if (ent->h_addrtype != PF_INET && ent->h_addrtype != PF_INET6)
15642b15cb3dSCy Schubert 			return EVUTIL_EAI_FAMILY;
15652b15cb3dSCy Schubert 
15662b15cb3dSCy Schubert 		*res = addrinfo_from_hostent(ent, port, &hints);
15672b15cb3dSCy Schubert 		if (! *res)
15682b15cb3dSCy Schubert 			return EVUTIL_EAI_MEMORY;
15692b15cb3dSCy Schubert 	}
15702b15cb3dSCy Schubert 
15712b15cb3dSCy Schubert 	return 0;
15722b15cb3dSCy Schubert #endif
15732b15cb3dSCy Schubert }
15742b15cb3dSCy Schubert 
15752b15cb3dSCy Schubert void
evutil_freeaddrinfo(struct evutil_addrinfo * ai)15762b15cb3dSCy Schubert evutil_freeaddrinfo(struct evutil_addrinfo *ai)
15772b15cb3dSCy Schubert {
15782b15cb3dSCy Schubert #ifdef EVENT__HAVE_GETADDRINFO
15792b15cb3dSCy Schubert 	if (!(ai->ai_flags & EVUTIL_AI_LIBEVENT_ALLOCATED)) {
15802b15cb3dSCy Schubert 		freeaddrinfo(ai);
15812b15cb3dSCy Schubert 		return;
15822b15cb3dSCy Schubert 	}
15832b15cb3dSCy Schubert #endif
15842b15cb3dSCy Schubert 	while (ai) {
15852b15cb3dSCy Schubert 		struct evutil_addrinfo *next = ai->ai_next;
15862b15cb3dSCy Schubert 		if (ai->ai_canonname)
15872b15cb3dSCy Schubert 			mm_free(ai->ai_canonname);
15882b15cb3dSCy Schubert 		mm_free(ai);
15892b15cb3dSCy Schubert 		ai = next;
15902b15cb3dSCy Schubert 	}
15912b15cb3dSCy Schubert }
15922b15cb3dSCy Schubert 
15932b15cb3dSCy Schubert static evdns_getaddrinfo_fn evdns_getaddrinfo_impl = NULL;
1594*a466cc55SCy Schubert static evdns_getaddrinfo_cancel_fn evdns_getaddrinfo_cancel_impl = NULL;
15952b15cb3dSCy Schubert 
15962b15cb3dSCy Schubert void
evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn)15972b15cb3dSCy Schubert evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn)
15982b15cb3dSCy Schubert {
15992b15cb3dSCy Schubert 	if (!evdns_getaddrinfo_impl)
16002b15cb3dSCy Schubert 		evdns_getaddrinfo_impl = fn;
16012b15cb3dSCy Schubert }
1602*a466cc55SCy Schubert void
evutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel_fn fn)1603*a466cc55SCy Schubert evutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel_fn fn)
1604*a466cc55SCy Schubert {
1605*a466cc55SCy Schubert 	if (!evdns_getaddrinfo_cancel_impl)
1606*a466cc55SCy Schubert 		evdns_getaddrinfo_cancel_impl = fn;
1607*a466cc55SCy Schubert }
16082b15cb3dSCy Schubert 
16092b15cb3dSCy Schubert /* Internal helper function: act like evdns_getaddrinfo if dns_base is set;
16102b15cb3dSCy Schubert  * otherwise do a blocking resolve and pass the result to the callback in the
16112b15cb3dSCy Schubert  * way that evdns_getaddrinfo would.
16122b15cb3dSCy Schubert  */
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)1613*a466cc55SCy Schubert struct evdns_getaddrinfo_request *evutil_getaddrinfo_async_(
1614*a466cc55SCy Schubert     struct evdns_base *dns_base,
16152b15cb3dSCy Schubert     const char *nodename, const char *servname,
16162b15cb3dSCy Schubert     const struct evutil_addrinfo *hints_in,
16172b15cb3dSCy Schubert     void (*cb)(int, struct evutil_addrinfo *, void *), void *arg)
16182b15cb3dSCy Schubert {
16192b15cb3dSCy Schubert 	if (dns_base && evdns_getaddrinfo_impl) {
1620*a466cc55SCy Schubert 		return evdns_getaddrinfo_impl(
16212b15cb3dSCy Schubert 			dns_base, nodename, servname, hints_in, cb, arg);
16222b15cb3dSCy Schubert 	} else {
16232b15cb3dSCy Schubert 		struct evutil_addrinfo *ai=NULL;
16242b15cb3dSCy Schubert 		int err;
16252b15cb3dSCy Schubert 		err = evutil_getaddrinfo(nodename, servname, hints_in, &ai);
16262b15cb3dSCy Schubert 		cb(err, ai, arg);
1627*a466cc55SCy Schubert 		return NULL;
16282b15cb3dSCy Schubert 	}
1629*a466cc55SCy Schubert }
1630*a466cc55SCy Schubert 
evutil_getaddrinfo_cancel_async_(struct evdns_getaddrinfo_request * data)1631*a466cc55SCy Schubert void evutil_getaddrinfo_cancel_async_(struct evdns_getaddrinfo_request *data)
1632*a466cc55SCy Schubert {
1633*a466cc55SCy Schubert 	if (evdns_getaddrinfo_cancel_impl && data) {
1634*a466cc55SCy Schubert 		evdns_getaddrinfo_cancel_impl(data);
1635*a466cc55SCy Schubert 	}
16362b15cb3dSCy Schubert }
16372b15cb3dSCy Schubert 
16382b15cb3dSCy Schubert const char *
evutil_gai_strerror(int err)16392b15cb3dSCy Schubert evutil_gai_strerror(int err)
16402b15cb3dSCy Schubert {
16412b15cb3dSCy Schubert 	/* As a sneaky side-benefit, this case statement will get most
16422b15cb3dSCy Schubert 	 * compilers to tell us if any of the error codes we defined
16432b15cb3dSCy Schubert 	 * conflict with the platform's native error codes. */
16442b15cb3dSCy Schubert 	switch (err) {
16452b15cb3dSCy Schubert 	case EVUTIL_EAI_CANCEL:
16462b15cb3dSCy Schubert 		return "Request canceled";
16472b15cb3dSCy Schubert 	case 0:
16482b15cb3dSCy Schubert 		return "No error";
16492b15cb3dSCy Schubert 
16502b15cb3dSCy Schubert 	case EVUTIL_EAI_ADDRFAMILY:
16512b15cb3dSCy Schubert 		return "address family for nodename not supported";
16522b15cb3dSCy Schubert 	case EVUTIL_EAI_AGAIN:
16532b15cb3dSCy Schubert 		return "temporary failure in name resolution";
16542b15cb3dSCy Schubert 	case EVUTIL_EAI_BADFLAGS:
16552b15cb3dSCy Schubert 		return "invalid value for ai_flags";
16562b15cb3dSCy Schubert 	case EVUTIL_EAI_FAIL:
16572b15cb3dSCy Schubert 		return "non-recoverable failure in name resolution";
16582b15cb3dSCy Schubert 	case EVUTIL_EAI_FAMILY:
16592b15cb3dSCy Schubert 		return "ai_family not supported";
16602b15cb3dSCy Schubert 	case EVUTIL_EAI_MEMORY:
16612b15cb3dSCy Schubert 		return "memory allocation failure";
16622b15cb3dSCy Schubert 	case EVUTIL_EAI_NODATA:
16632b15cb3dSCy Schubert 		return "no address associated with nodename";
16642b15cb3dSCy Schubert 	case EVUTIL_EAI_NONAME:
16652b15cb3dSCy Schubert 		return "nodename nor servname provided, or not known";
16662b15cb3dSCy Schubert 	case EVUTIL_EAI_SERVICE:
16672b15cb3dSCy Schubert 		return "servname not supported for ai_socktype";
16682b15cb3dSCy Schubert 	case EVUTIL_EAI_SOCKTYPE:
16692b15cb3dSCy Schubert 		return "ai_socktype not supported";
16702b15cb3dSCy Schubert 	case EVUTIL_EAI_SYSTEM:
16712b15cb3dSCy Schubert 		return "system error";
16722b15cb3dSCy Schubert 	default:
16732b15cb3dSCy Schubert #if defined(USE_NATIVE_GETADDRINFO) && defined(_WIN32)
16742b15cb3dSCy Schubert 		return gai_strerrorA(err);
16752b15cb3dSCy Schubert #elif defined(USE_NATIVE_GETADDRINFO)
16762b15cb3dSCy Schubert 		return gai_strerror(err);
16772b15cb3dSCy Schubert #else
16782b15cb3dSCy Schubert 		return "Unknown error code";
16792b15cb3dSCy Schubert #endif
16802b15cb3dSCy Schubert 	}
16812b15cb3dSCy Schubert }
16822b15cb3dSCy Schubert 
16832b15cb3dSCy Schubert #ifdef _WIN32
16842b15cb3dSCy Schubert /* destructively remove a trailing line terminator from s */
16852b15cb3dSCy Schubert static void
chomp(char * s)16862b15cb3dSCy Schubert chomp (char *s)
16872b15cb3dSCy Schubert {
16882b15cb3dSCy Schubert 	size_t len;
16892b15cb3dSCy Schubert 	if (s && (len = strlen (s)) > 0 && s[len - 1] == '\n') {
16902b15cb3dSCy Schubert 		s[--len] = 0;
16912b15cb3dSCy Schubert 		if (len > 0 && s[len - 1] == '\r')
16922b15cb3dSCy Schubert 			s[--len] = 0;
16932b15cb3dSCy Schubert 	}
16942b15cb3dSCy Schubert }
16952b15cb3dSCy Schubert 
16962b15cb3dSCy Schubert /* FormatMessage returns allocated strings, but evutil_socket_error_to_string
16972b15cb3dSCy Schubert  * is supposed to return a string which is good indefinitely without having
16982b15cb3dSCy Schubert  * to be freed.  To make this work without leaking memory, we cache the
16992b15cb3dSCy Schubert  * string the first time FormatMessage is called on a particular error
17002b15cb3dSCy Schubert  * code, and then return the cached string on subsequent calls with the
17012b15cb3dSCy Schubert  * same code.  The strings aren't freed until libevent_global_shutdown
17022b15cb3dSCy Schubert  * (or never).  We use a linked list to cache the errors, because we
17032b15cb3dSCy Schubert  * only expect there to be a few dozen, and that should be fast enough.
17042b15cb3dSCy Schubert  */
17052b15cb3dSCy Schubert 
17062b15cb3dSCy Schubert struct cached_sock_errs_entry {
17072b15cb3dSCy Schubert 	HT_ENTRY(cached_sock_errs_entry) node;
17082b15cb3dSCy Schubert 	DWORD code;
17092b15cb3dSCy Schubert 	char *msg; /* allocated with LocalAlloc; free with LocalFree */
17102b15cb3dSCy Schubert };
17112b15cb3dSCy Schubert 
17122b15cb3dSCy Schubert static inline unsigned
hash_cached_sock_errs(const struct cached_sock_errs_entry * e)17132b15cb3dSCy Schubert hash_cached_sock_errs(const struct cached_sock_errs_entry *e)
17142b15cb3dSCy Schubert {
17152b15cb3dSCy Schubert 	/* Use Murmur3's 32-bit finalizer as an integer hash function */
17162b15cb3dSCy Schubert 	DWORD h = e->code;
17172b15cb3dSCy Schubert 	h ^= h >> 16;
17182b15cb3dSCy Schubert 	h *= 0x85ebca6b;
17192b15cb3dSCy Schubert 	h ^= h >> 13;
17202b15cb3dSCy Schubert 	h *= 0xc2b2ae35;
17212b15cb3dSCy Schubert 	h ^= h >> 16;
17222b15cb3dSCy Schubert 	return h;
17232b15cb3dSCy Schubert }
17242b15cb3dSCy Schubert 
17252b15cb3dSCy Schubert static inline int
eq_cached_sock_errs(const struct cached_sock_errs_entry * a,const struct cached_sock_errs_entry * b)17262b15cb3dSCy Schubert eq_cached_sock_errs(const struct cached_sock_errs_entry *a,
17272b15cb3dSCy Schubert 		    const struct cached_sock_errs_entry *b)
17282b15cb3dSCy Schubert {
17292b15cb3dSCy Schubert 	return a->code == b->code;
17302b15cb3dSCy Schubert }
17312b15cb3dSCy Schubert 
17322b15cb3dSCy Schubert #ifndef EVENT__DISABLE_THREAD_SUPPORT
17332b15cb3dSCy Schubert static void *windows_socket_errors_lock_ = NULL;
17342b15cb3dSCy Schubert #endif
17352b15cb3dSCy Schubert 
17362b15cb3dSCy Schubert static HT_HEAD(cached_sock_errs_map, cached_sock_errs_entry)
17372b15cb3dSCy Schubert      windows_socket_errors = HT_INITIALIZER();
17382b15cb3dSCy Schubert 
17392b15cb3dSCy Schubert HT_PROTOTYPE(cached_sock_errs_map,
17402b15cb3dSCy Schubert 	     cached_sock_errs_entry,
17412b15cb3dSCy Schubert 	     node,
17422b15cb3dSCy Schubert 	     hash_cached_sock_errs,
17432b15cb3dSCy Schubert 	     eq_cached_sock_errs);
17442b15cb3dSCy Schubert 
17452b15cb3dSCy Schubert HT_GENERATE(cached_sock_errs_map,
17462b15cb3dSCy Schubert 	    cached_sock_errs_entry,
17472b15cb3dSCy Schubert 	    node,
17482b15cb3dSCy Schubert 	    hash_cached_sock_errs,
17492b15cb3dSCy Schubert 	    eq_cached_sock_errs,
17502b15cb3dSCy Schubert 	    0.5,
17512b15cb3dSCy Schubert 	    mm_malloc,
17522b15cb3dSCy Schubert 	    mm_realloc,
17532b15cb3dSCy Schubert 	    mm_free);
17542b15cb3dSCy Schubert 
17552b15cb3dSCy Schubert /** Equivalent to strerror, but for windows socket errors. */
17562b15cb3dSCy Schubert const char *
evutil_socket_error_to_string(int errcode)17572b15cb3dSCy Schubert evutil_socket_error_to_string(int errcode)
17582b15cb3dSCy Schubert {
17592b15cb3dSCy Schubert 	struct cached_sock_errs_entry *errs, *newerr, find;
17602b15cb3dSCy Schubert 	char *msg = NULL;
17612b15cb3dSCy Schubert 
17622b15cb3dSCy Schubert 	EVLOCK_LOCK(windows_socket_errors_lock_, 0);
17632b15cb3dSCy Schubert 
17642b15cb3dSCy Schubert 	find.code = errcode;
17652b15cb3dSCy Schubert 	errs = HT_FIND(cached_sock_errs_map, &windows_socket_errors, &find);
17662b15cb3dSCy Schubert 	if (errs) {
17672b15cb3dSCy Schubert 		msg = errs->msg;
17682b15cb3dSCy Schubert 		goto done;
17692b15cb3dSCy Schubert 	}
17702b15cb3dSCy Schubert 
1771*a466cc55SCy Schubert 	if (0 != FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
17722b15cb3dSCy Schubert 			       FORMAT_MESSAGE_IGNORE_INSERTS |
17732b15cb3dSCy Schubert 			       FORMAT_MESSAGE_ALLOCATE_BUFFER,
1774*a466cc55SCy Schubert 			       NULL, errcode, 0, (char *)&msg, 0, NULL))
17752b15cb3dSCy Schubert 		chomp (msg);	/* because message has trailing newline */
17762b15cb3dSCy Schubert 	else {
17772b15cb3dSCy Schubert 		size_t len = 50;
17782b15cb3dSCy Schubert 		/* use LocalAlloc because FormatMessage does */
17792b15cb3dSCy Schubert 		msg = LocalAlloc(LMEM_FIXED, len);
17802b15cb3dSCy Schubert 		if (!msg) {
17812b15cb3dSCy Schubert 			msg = (char *)"LocalAlloc failed during Winsock error";
17822b15cb3dSCy Schubert 			goto done;
17832b15cb3dSCy Schubert 		}
17842b15cb3dSCy Schubert 		evutil_snprintf(msg, len, "winsock error 0x%08x", errcode);
17852b15cb3dSCy Schubert 	}
17862b15cb3dSCy Schubert 
17872b15cb3dSCy Schubert 	newerr = (struct cached_sock_errs_entry *)
17882b15cb3dSCy Schubert 		mm_malloc(sizeof (struct cached_sock_errs_entry));
17892b15cb3dSCy Schubert 
17902b15cb3dSCy Schubert 	if (!newerr) {
17912b15cb3dSCy Schubert 		LocalFree(msg);
17922b15cb3dSCy Schubert 		msg = (char *)"malloc failed during Winsock error";
17932b15cb3dSCy Schubert 		goto done;
17942b15cb3dSCy Schubert 	}
17952b15cb3dSCy Schubert 
17962b15cb3dSCy Schubert 	newerr->code = errcode;
17972b15cb3dSCy Schubert 	newerr->msg = msg;
17982b15cb3dSCy Schubert 	HT_INSERT(cached_sock_errs_map, &windows_socket_errors, newerr);
17992b15cb3dSCy Schubert 
18002b15cb3dSCy Schubert  done:
18012b15cb3dSCy Schubert 	EVLOCK_UNLOCK(windows_socket_errors_lock_, 0);
18022b15cb3dSCy Schubert 
18032b15cb3dSCy Schubert 	return msg;
18042b15cb3dSCy Schubert }
18052b15cb3dSCy Schubert 
18062b15cb3dSCy Schubert #ifndef EVENT__DISABLE_THREAD_SUPPORT
18072b15cb3dSCy Schubert int
evutil_global_setup_locks_(const int enable_locks)18082b15cb3dSCy Schubert evutil_global_setup_locks_(const int enable_locks)
18092b15cb3dSCy Schubert {
18102b15cb3dSCy Schubert 	EVTHREAD_SETUP_GLOBAL_LOCK(windows_socket_errors_lock_, 0);
18112b15cb3dSCy Schubert 	return 0;
18122b15cb3dSCy Schubert }
18132b15cb3dSCy Schubert #endif
18142b15cb3dSCy Schubert 
18152b15cb3dSCy Schubert static void
evutil_free_sock_err_globals(void)18162b15cb3dSCy Schubert evutil_free_sock_err_globals(void)
18172b15cb3dSCy Schubert {
18182b15cb3dSCy Schubert 	struct cached_sock_errs_entry **errs, *tofree;
18192b15cb3dSCy Schubert 
18202b15cb3dSCy Schubert 	for (errs = HT_START(cached_sock_errs_map, &windows_socket_errors)
18212b15cb3dSCy Schubert 		     ; errs; ) {
18222b15cb3dSCy Schubert 		tofree = *errs;
18232b15cb3dSCy Schubert 		errs = HT_NEXT_RMV(cached_sock_errs_map,
18242b15cb3dSCy Schubert 				   &windows_socket_errors,
18252b15cb3dSCy Schubert 				   errs);
18262b15cb3dSCy Schubert 		LocalFree(tofree->msg);
18272b15cb3dSCy Schubert 		mm_free(tofree);
18282b15cb3dSCy Schubert 	}
18292b15cb3dSCy Schubert 
18302b15cb3dSCy Schubert 	HT_CLEAR(cached_sock_errs_map, &windows_socket_errors);
18312b15cb3dSCy Schubert 
18322b15cb3dSCy Schubert #ifndef EVENT__DISABLE_THREAD_SUPPORT
18332b15cb3dSCy Schubert 	if (windows_socket_errors_lock_ != NULL) {
18342b15cb3dSCy Schubert 		EVTHREAD_FREE_LOCK(windows_socket_errors_lock_, 0);
18352b15cb3dSCy Schubert 		windows_socket_errors_lock_ = NULL;
18362b15cb3dSCy Schubert 	}
18372b15cb3dSCy Schubert #endif
18382b15cb3dSCy Schubert }
18392b15cb3dSCy Schubert 
18402b15cb3dSCy Schubert #else
18412b15cb3dSCy Schubert 
18422b15cb3dSCy Schubert #ifndef EVENT__DISABLE_THREAD_SUPPORT
18432b15cb3dSCy Schubert int
evutil_global_setup_locks_(const int enable_locks)18442b15cb3dSCy Schubert evutil_global_setup_locks_(const int enable_locks)
18452b15cb3dSCy Schubert {
18462b15cb3dSCy Schubert 	return 0;
18472b15cb3dSCy Schubert }
18482b15cb3dSCy Schubert #endif
18492b15cb3dSCy Schubert 
18502b15cb3dSCy Schubert static void
evutil_free_sock_err_globals(void)18512b15cb3dSCy Schubert evutil_free_sock_err_globals(void)
18522b15cb3dSCy Schubert {
18532b15cb3dSCy Schubert }
18542b15cb3dSCy Schubert 
18552b15cb3dSCy Schubert #endif
18562b15cb3dSCy Schubert 
18572b15cb3dSCy Schubert int
evutil_snprintf(char * buf,size_t buflen,const char * format,...)18582b15cb3dSCy Schubert evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
18592b15cb3dSCy Schubert {
18602b15cb3dSCy Schubert 	int r;
18612b15cb3dSCy Schubert 	va_list ap;
18622b15cb3dSCy Schubert 	va_start(ap, format);
18632b15cb3dSCy Schubert 	r = evutil_vsnprintf(buf, buflen, format, ap);
18642b15cb3dSCy Schubert 	va_end(ap);
18652b15cb3dSCy Schubert 	return r;
18662b15cb3dSCy Schubert }
18672b15cb3dSCy Schubert 
18682b15cb3dSCy Schubert int
evutil_vsnprintf(char * buf,size_t buflen,const char * format,va_list ap)18692b15cb3dSCy Schubert evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
18702b15cb3dSCy Schubert {
18712b15cb3dSCy Schubert 	int r;
18722b15cb3dSCy Schubert 	if (!buflen)
18732b15cb3dSCy Schubert 		return 0;
18742b15cb3dSCy Schubert #if defined(_MSC_VER) || defined(_WIN32)
18752b15cb3dSCy Schubert 	r = _vsnprintf(buf, buflen, format, ap);
18762b15cb3dSCy Schubert 	if (r < 0)
18772b15cb3dSCy Schubert 		r = _vscprintf(format, ap);
18782b15cb3dSCy Schubert #elif defined(sgi)
18792b15cb3dSCy Schubert 	/* Make sure we always use the correct vsnprintf on IRIX */
18802b15cb3dSCy Schubert 	extern int      _xpg5_vsnprintf(char * __restrict,
18812b15cb3dSCy Schubert 		__SGI_LIBC_NAMESPACE_QUALIFIER size_t,
18822b15cb3dSCy Schubert 		const char * __restrict, /* va_list */ char *);
18832b15cb3dSCy Schubert 
18842b15cb3dSCy Schubert 	r = _xpg5_vsnprintf(buf, buflen, format, ap);
18852b15cb3dSCy Schubert #else
18862b15cb3dSCy Schubert 	r = vsnprintf(buf, buflen, format, ap);
18872b15cb3dSCy Schubert #endif
18882b15cb3dSCy Schubert 	buf[buflen-1] = '\0';
18892b15cb3dSCy Schubert 	return r;
18902b15cb3dSCy Schubert }
18912b15cb3dSCy Schubert 
18922b15cb3dSCy Schubert #define USE_INTERNAL_NTOP
18932b15cb3dSCy Schubert #define USE_INTERNAL_PTON
18942b15cb3dSCy Schubert 
18952b15cb3dSCy Schubert const char *
evutil_inet_ntop(int af,const void * src,char * dst,size_t len)18962b15cb3dSCy Schubert evutil_inet_ntop(int af, const void *src, char *dst, size_t len)
18972b15cb3dSCy Schubert {
18982b15cb3dSCy Schubert #if defined(EVENT__HAVE_INET_NTOP) && !defined(USE_INTERNAL_NTOP)
18992b15cb3dSCy Schubert 	return inet_ntop(af, src, dst, len);
19002b15cb3dSCy Schubert #else
19012b15cb3dSCy Schubert 	if (af == AF_INET) {
19022b15cb3dSCy Schubert 		const struct in_addr *in = src;
19032b15cb3dSCy Schubert 		const ev_uint32_t a = ntohl(in->s_addr);
19042b15cb3dSCy Schubert 		int r;
19052b15cb3dSCy Schubert 		r = evutil_snprintf(dst, len, "%d.%d.%d.%d",
19062b15cb3dSCy Schubert 		    (int)(ev_uint8_t)((a>>24)&0xff),
19072b15cb3dSCy Schubert 		    (int)(ev_uint8_t)((a>>16)&0xff),
19082b15cb3dSCy Schubert 		    (int)(ev_uint8_t)((a>>8 )&0xff),
19092b15cb3dSCy Schubert 		    (int)(ev_uint8_t)((a    )&0xff));
19102b15cb3dSCy Schubert 		if (r<0||(size_t)r>=len)
19112b15cb3dSCy Schubert 			return NULL;
19122b15cb3dSCy Schubert 		else
19132b15cb3dSCy Schubert 			return dst;
19142b15cb3dSCy Schubert #ifdef AF_INET6
19152b15cb3dSCy Schubert 	} else if (af == AF_INET6) {
19162b15cb3dSCy Schubert 		const struct in6_addr *addr = src;
19172b15cb3dSCy Schubert 		char buf[64], *cp;
19182b15cb3dSCy Schubert 		int longestGapLen = 0, longestGapPos = -1, i,
19192b15cb3dSCy Schubert 			curGapPos = -1, curGapLen = 0;
19202b15cb3dSCy Schubert 		ev_uint16_t words[8];
19212b15cb3dSCy Schubert 		for (i = 0; i < 8; ++i) {
19222b15cb3dSCy Schubert 			words[i] =
19232b15cb3dSCy Schubert 			    (((ev_uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
19242b15cb3dSCy Schubert 		}
19252b15cb3dSCy Schubert 		if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
19262b15cb3dSCy Schubert 		    words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
19272b15cb3dSCy Schubert 			(words[5] == 0xffff))) {
19282b15cb3dSCy Schubert 			/* This is an IPv4 address. */
19292b15cb3dSCy Schubert 			if (words[5] == 0) {
19302b15cb3dSCy Schubert 				evutil_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
19312b15cb3dSCy Schubert 				    addr->s6_addr[12], addr->s6_addr[13],
19322b15cb3dSCy Schubert 				    addr->s6_addr[14], addr->s6_addr[15]);
19332b15cb3dSCy Schubert 			} else {
19342b15cb3dSCy Schubert 				evutil_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
19352b15cb3dSCy Schubert 				    addr->s6_addr[12], addr->s6_addr[13],
19362b15cb3dSCy Schubert 				    addr->s6_addr[14], addr->s6_addr[15]);
19372b15cb3dSCy Schubert 			}
19382b15cb3dSCy Schubert 			if (strlen(buf) > len)
19392b15cb3dSCy Schubert 				return NULL;
19402b15cb3dSCy Schubert 			strlcpy(dst, buf, len);
19412b15cb3dSCy Schubert 			return dst;
19422b15cb3dSCy Schubert 		}
19432b15cb3dSCy Schubert 		i = 0;
19442b15cb3dSCy Schubert 		while (i < 8) {
19452b15cb3dSCy Schubert 			if (words[i] == 0) {
19462b15cb3dSCy Schubert 				curGapPos = i++;
19472b15cb3dSCy Schubert 				curGapLen = 1;
19482b15cb3dSCy Schubert 				while (i<8 && words[i] == 0) {
19492b15cb3dSCy Schubert 					++i; ++curGapLen;
19502b15cb3dSCy Schubert 				}
19512b15cb3dSCy Schubert 				if (curGapLen > longestGapLen) {
19522b15cb3dSCy Schubert 					longestGapPos = curGapPos;
19532b15cb3dSCy Schubert 					longestGapLen = curGapLen;
19542b15cb3dSCy Schubert 				}
19552b15cb3dSCy Schubert 			} else {
19562b15cb3dSCy Schubert 				++i;
19572b15cb3dSCy Schubert 			}
19582b15cb3dSCy Schubert 		}
19592b15cb3dSCy Schubert 		if (longestGapLen<=1)
19602b15cb3dSCy Schubert 			longestGapPos = -1;
19612b15cb3dSCy Schubert 
19622b15cb3dSCy Schubert 		cp = buf;
19632b15cb3dSCy Schubert 		for (i = 0; i < 8; ++i) {
19642b15cb3dSCy Schubert 			if (words[i] == 0 && longestGapPos == i) {
19652b15cb3dSCy Schubert 				if (i == 0)
19662b15cb3dSCy Schubert 					*cp++ = ':';
19672b15cb3dSCy Schubert 				*cp++ = ':';
19682b15cb3dSCy Schubert 				while (i < 8 && words[i] == 0)
19692b15cb3dSCy Schubert 					++i;
19702b15cb3dSCy Schubert 				--i; /* to compensate for loop increment. */
19712b15cb3dSCy Schubert 			} else {
19722b15cb3dSCy Schubert 				evutil_snprintf(cp,
19732b15cb3dSCy Schubert 								sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
19742b15cb3dSCy Schubert 				cp += strlen(cp);
19752b15cb3dSCy Schubert 				if (i != 7)
19762b15cb3dSCy Schubert 					*cp++ = ':';
19772b15cb3dSCy Schubert 			}
19782b15cb3dSCy Schubert 		}
19792b15cb3dSCy Schubert 		*cp = '\0';
19802b15cb3dSCy Schubert 		if (strlen(buf) > len)
19812b15cb3dSCy Schubert 			return NULL;
19822b15cb3dSCy Schubert 		strlcpy(dst, buf, len);
19832b15cb3dSCy Schubert 		return dst;
19842b15cb3dSCy Schubert #endif
19852b15cb3dSCy Schubert 	} else {
19862b15cb3dSCy Schubert 		return NULL;
19872b15cb3dSCy Schubert 	}
19882b15cb3dSCy Schubert #endif
19892b15cb3dSCy Schubert }
19902b15cb3dSCy Schubert 
19912b15cb3dSCy Schubert int
evutil_inet_pton_scope(int af,const char * src,void * dst,unsigned * indexp)1992*a466cc55SCy Schubert evutil_inet_pton_scope(int af, const char *src, void *dst, unsigned *indexp)
1993*a466cc55SCy Schubert {
1994*a466cc55SCy Schubert 	int r;
1995*a466cc55SCy Schubert 	unsigned if_index;
1996*a466cc55SCy Schubert 	char *check, *cp, *tmp_src;
1997*a466cc55SCy Schubert 
1998*a466cc55SCy Schubert 	*indexp = 0; /* Reasonable default */
1999*a466cc55SCy Schubert 
2000*a466cc55SCy Schubert 	/* Bail out if not IPv6 */
2001*a466cc55SCy Schubert 	if (af != AF_INET6)
2002*a466cc55SCy Schubert 		return evutil_inet_pton(af, src, dst);
2003*a466cc55SCy Schubert 
2004*a466cc55SCy Schubert 	cp = strchr(src, '%');
2005*a466cc55SCy Schubert 
2006*a466cc55SCy Schubert 	/* Bail out if no zone ID */
2007*a466cc55SCy Schubert 	if (cp == NULL)
2008*a466cc55SCy Schubert 		return evutil_inet_pton(af, src, dst);
2009*a466cc55SCy Schubert 
2010*a466cc55SCy Schubert 	if_index = if_nametoindex(cp + 1);
2011*a466cc55SCy Schubert 	if (if_index == 0) {
2012*a466cc55SCy Schubert 		/* Could be numeric */
2013*a466cc55SCy Schubert 		if_index = strtoul(cp + 1, &check, 10);
2014*a466cc55SCy Schubert 		if (check[0] != '\0')
2015*a466cc55SCy Schubert 			return 0;
2016*a466cc55SCy Schubert 	}
2017*a466cc55SCy Schubert 	*indexp = if_index;
2018*a466cc55SCy Schubert 	tmp_src = mm_strdup(src);
2019*a466cc55SCy Schubert 	cp = strchr(tmp_src, '%');
2020*a466cc55SCy Schubert 	*cp = '\0';
2021*a466cc55SCy Schubert 	r = evutil_inet_pton(af, tmp_src, dst);
2022*a466cc55SCy Schubert 	free(tmp_src);
2023*a466cc55SCy Schubert 	return r;
2024*a466cc55SCy Schubert }
2025*a466cc55SCy Schubert 
2026*a466cc55SCy Schubert int
evutil_inet_pton(int af,const char * src,void * dst)20272b15cb3dSCy Schubert evutil_inet_pton(int af, const char *src, void *dst)
20282b15cb3dSCy Schubert {
20292b15cb3dSCy Schubert #if defined(EVENT__HAVE_INET_PTON) && !defined(USE_INTERNAL_PTON)
20302b15cb3dSCy Schubert 	return inet_pton(af, src, dst);
20312b15cb3dSCy Schubert #else
20322b15cb3dSCy Schubert 	if (af == AF_INET) {
2033a25439b6SCy Schubert 		unsigned a,b,c,d;
20342b15cb3dSCy Schubert 		char more;
20352b15cb3dSCy Schubert 		struct in_addr *addr = dst;
2036a25439b6SCy Schubert 		if (sscanf(src, "%u.%u.%u.%u%c", &a,&b,&c,&d,&more) != 4)
20372b15cb3dSCy Schubert 			return 0;
2038a25439b6SCy Schubert 		if (a > 255) return 0;
2039a25439b6SCy Schubert 		if (b > 255) return 0;
2040a25439b6SCy Schubert 		if (c > 255) return 0;
2041a25439b6SCy Schubert 		if (d > 255) return 0;
20422b15cb3dSCy Schubert 		addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
20432b15cb3dSCy Schubert 		return 1;
20442b15cb3dSCy Schubert #ifdef AF_INET6
20452b15cb3dSCy Schubert 	} else if (af == AF_INET6) {
20462b15cb3dSCy Schubert 		struct in6_addr *out = dst;
20472b15cb3dSCy Schubert 		ev_uint16_t words[8];
20482b15cb3dSCy Schubert 		int gapPos = -1, i, setWords=0;
20492b15cb3dSCy Schubert 		const char *dot = strchr(src, '.');
20502b15cb3dSCy Schubert 		const char *eow; /* end of words. */
20512b15cb3dSCy Schubert 		if (dot == src)
20522b15cb3dSCy Schubert 			return 0;
20532b15cb3dSCy Schubert 		else if (!dot)
20542b15cb3dSCy Schubert 			eow = src+strlen(src);
20552b15cb3dSCy Schubert 		else {
2056a25439b6SCy Schubert 			unsigned byte1,byte2,byte3,byte4;
20572b15cb3dSCy Schubert 			char more;
20582b15cb3dSCy Schubert 			for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT_(*eow); --eow)
20592b15cb3dSCy Schubert 				;
20602b15cb3dSCy Schubert 			++eow;
20612b15cb3dSCy Schubert 
20622b15cb3dSCy Schubert 			/* We use "scanf" because some platform inet_aton()s are too lax
20632b15cb3dSCy Schubert 			 * about IPv4 addresses of the form "1.2.3" */
2064a25439b6SCy Schubert 			if (sscanf(eow, "%u.%u.%u.%u%c",
20652b15cb3dSCy Schubert 					   &byte1,&byte2,&byte3,&byte4,&more) != 4)
20662b15cb3dSCy Schubert 				return 0;
20672b15cb3dSCy Schubert 
2068a25439b6SCy Schubert 			if (byte1 > 255 ||
2069a25439b6SCy Schubert 			    byte2 > 255 ||
2070a25439b6SCy Schubert 			    byte3 > 255 ||
2071a25439b6SCy Schubert 			    byte4 > 255)
20722b15cb3dSCy Schubert 				return 0;
20732b15cb3dSCy Schubert 
20742b15cb3dSCy Schubert 			words[6] = (byte1<<8) | byte2;
20752b15cb3dSCy Schubert 			words[7] = (byte3<<8) | byte4;
20762b15cb3dSCy Schubert 			setWords += 2;
20772b15cb3dSCy Schubert 		}
20782b15cb3dSCy Schubert 
20792b15cb3dSCy Schubert 		i = 0;
20802b15cb3dSCy Schubert 		while (src < eow) {
20812b15cb3dSCy Schubert 			if (i > 7)
20822b15cb3dSCy Schubert 				return 0;
20832b15cb3dSCy Schubert 			if (EVUTIL_ISXDIGIT_(*src)) {
20842b15cb3dSCy Schubert 				char *next;
20852b15cb3dSCy Schubert 				long r = strtol(src, &next, 16);
20862b15cb3dSCy Schubert 				if (next > 4+src)
20872b15cb3dSCy Schubert 					return 0;
20882b15cb3dSCy Schubert 				if (next == src)
20892b15cb3dSCy Schubert 					return 0;
20902b15cb3dSCy Schubert 				if (r<0 || r>65536)
20912b15cb3dSCy Schubert 					return 0;
20922b15cb3dSCy Schubert 
20932b15cb3dSCy Schubert 				words[i++] = (ev_uint16_t)r;
20942b15cb3dSCy Schubert 				setWords++;
20952b15cb3dSCy Schubert 				src = next;
20962b15cb3dSCy Schubert 				if (*src != ':' && src != eow)
20972b15cb3dSCy Schubert 					return 0;
20982b15cb3dSCy Schubert 				++src;
20992b15cb3dSCy Schubert 			} else if (*src == ':' && i > 0 && gapPos==-1) {
21002b15cb3dSCy Schubert 				gapPos = i;
21012b15cb3dSCy Schubert 				++src;
21022b15cb3dSCy Schubert 			} else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
21032b15cb3dSCy Schubert 				gapPos = i;
21042b15cb3dSCy Schubert 				src += 2;
21052b15cb3dSCy Schubert 			} else {
21062b15cb3dSCy Schubert 				return 0;
21072b15cb3dSCy Schubert 			}
21082b15cb3dSCy Schubert 		}
21092b15cb3dSCy Schubert 
21102b15cb3dSCy Schubert 		if (setWords > 8 ||
21112b15cb3dSCy Schubert 			(setWords == 8 && gapPos != -1) ||
21122b15cb3dSCy Schubert 			(setWords < 8 && gapPos == -1))
21132b15cb3dSCy Schubert 			return 0;
21142b15cb3dSCy Schubert 
21152b15cb3dSCy Schubert 		if (gapPos >= 0) {
21162b15cb3dSCy Schubert 			int nToMove = setWords - (dot ? 2 : 0) - gapPos;
21172b15cb3dSCy Schubert 			int gapLen = 8 - setWords;
21182b15cb3dSCy Schubert 			/* assert(nToMove >= 0); */
21192b15cb3dSCy Schubert 			if (nToMove < 0)
21202b15cb3dSCy Schubert 				return -1; /* should be impossible */
21212b15cb3dSCy Schubert 			memmove(&words[gapPos+gapLen], &words[gapPos],
21222b15cb3dSCy Schubert 					sizeof(ev_uint16_t)*nToMove);
21232b15cb3dSCy Schubert 			memset(&words[gapPos], 0, sizeof(ev_uint16_t)*gapLen);
21242b15cb3dSCy Schubert 		}
21252b15cb3dSCy Schubert 		for (i = 0; i < 8; ++i) {
21262b15cb3dSCy Schubert 			out->s6_addr[2*i  ] = words[i] >> 8;
21272b15cb3dSCy Schubert 			out->s6_addr[2*i+1] = words[i] & 0xff;
21282b15cb3dSCy Schubert 		}
21292b15cb3dSCy Schubert 
21302b15cb3dSCy Schubert 		return 1;
21312b15cb3dSCy Schubert #endif
21322b15cb3dSCy Schubert 	} else {
21332b15cb3dSCy Schubert 		return -1;
21342b15cb3dSCy Schubert 	}
21352b15cb3dSCy Schubert #endif
21362b15cb3dSCy Schubert }
21372b15cb3dSCy Schubert 
21382b15cb3dSCy Schubert int
evutil_parse_sockaddr_port(const char * ip_as_string,struct sockaddr * out,int * outlen)21392b15cb3dSCy Schubert evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
21402b15cb3dSCy Schubert {
21412b15cb3dSCy Schubert 	int port;
2142*a466cc55SCy Schubert 	unsigned int if_index;
21432b15cb3dSCy Schubert 	char buf[128];
21442b15cb3dSCy Schubert 	const char *cp, *addr_part, *port_part;
21452b15cb3dSCy Schubert 	int is_ipv6;
21462b15cb3dSCy Schubert 	/* recognized formats are:
21472b15cb3dSCy Schubert 	 * [ipv6]:port
21482b15cb3dSCy Schubert 	 * ipv6
21492b15cb3dSCy Schubert 	 * [ipv6]
21502b15cb3dSCy Schubert 	 * ipv4:port
21512b15cb3dSCy Schubert 	 * ipv4
21522b15cb3dSCy Schubert 	 */
21532b15cb3dSCy Schubert 
21542b15cb3dSCy Schubert 	cp = strchr(ip_as_string, ':');
21552b15cb3dSCy Schubert 	if (*ip_as_string == '[') {
2156*a466cc55SCy Schubert 		size_t len;
21572b15cb3dSCy Schubert 		if (!(cp = strchr(ip_as_string, ']'))) {
21582b15cb3dSCy Schubert 			return -1;
21592b15cb3dSCy Schubert 		}
2160*a466cc55SCy Schubert 		len = ( cp-(ip_as_string + 1) );
2161*a466cc55SCy Schubert 		if (len > sizeof(buf)-1) {
21622b15cb3dSCy Schubert 			return -1;
21632b15cb3dSCy Schubert 		}
21642b15cb3dSCy Schubert 		memcpy(buf, ip_as_string+1, len);
21652b15cb3dSCy Schubert 		buf[len] = '\0';
21662b15cb3dSCy Schubert 		addr_part = buf;
21672b15cb3dSCy Schubert 		if (cp[1] == ':')
21682b15cb3dSCy Schubert 			port_part = cp+2;
21692b15cb3dSCy Schubert 		else
21702b15cb3dSCy Schubert 			port_part = NULL;
21712b15cb3dSCy Schubert 		is_ipv6 = 1;
21722b15cb3dSCy Schubert 	} else if (cp && strchr(cp+1, ':')) {
21732b15cb3dSCy Schubert 		is_ipv6 = 1;
21742b15cb3dSCy Schubert 		addr_part = ip_as_string;
21752b15cb3dSCy Schubert 		port_part = NULL;
21762b15cb3dSCy Schubert 	} else if (cp) {
21772b15cb3dSCy Schubert 		is_ipv6 = 0;
21782b15cb3dSCy Schubert 		if (cp - ip_as_string > (int)sizeof(buf)-1) {
21792b15cb3dSCy Schubert 			return -1;
21802b15cb3dSCy Schubert 		}
21812b15cb3dSCy Schubert 		memcpy(buf, ip_as_string, cp-ip_as_string);
21822b15cb3dSCy Schubert 		buf[cp-ip_as_string] = '\0';
21832b15cb3dSCy Schubert 		addr_part = buf;
21842b15cb3dSCy Schubert 		port_part = cp+1;
21852b15cb3dSCy Schubert 	} else {
21862b15cb3dSCy Schubert 		addr_part = ip_as_string;
21872b15cb3dSCy Schubert 		port_part = NULL;
21882b15cb3dSCy Schubert 		is_ipv6 = 0;
21892b15cb3dSCy Schubert 	}
21902b15cb3dSCy Schubert 
21912b15cb3dSCy Schubert 	if (port_part == NULL) {
21922b15cb3dSCy Schubert 		port = 0;
21932b15cb3dSCy Schubert 	} else {
21942b15cb3dSCy Schubert 		port = atoi(port_part);
21952b15cb3dSCy Schubert 		if (port <= 0 || port > 65535) {
21962b15cb3dSCy Schubert 			return -1;
21972b15cb3dSCy Schubert 		}
21982b15cb3dSCy Schubert 	}
21992b15cb3dSCy Schubert 
22002b15cb3dSCy Schubert 	if (!addr_part)
22012b15cb3dSCy Schubert 		return -1; /* Should be impossible. */
22022b15cb3dSCy Schubert #ifdef AF_INET6
22032b15cb3dSCy Schubert 	if (is_ipv6)
22042b15cb3dSCy Schubert 	{
22052b15cb3dSCy Schubert 		struct sockaddr_in6 sin6;
22062b15cb3dSCy Schubert 		memset(&sin6, 0, sizeof(sin6));
22072b15cb3dSCy Schubert #ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
22082b15cb3dSCy Schubert 		sin6.sin6_len = sizeof(sin6);
22092b15cb3dSCy Schubert #endif
22102b15cb3dSCy Schubert 		sin6.sin6_family = AF_INET6;
22112b15cb3dSCy Schubert 		sin6.sin6_port = htons(port);
2212*a466cc55SCy Schubert 		if (1 != evutil_inet_pton_scope(
2213*a466cc55SCy Schubert 			AF_INET6, addr_part, &sin6.sin6_addr, &if_index)) {
22142b15cb3dSCy Schubert 			return -1;
2215*a466cc55SCy Schubert 		}
22162b15cb3dSCy Schubert 		if ((int)sizeof(sin6) > *outlen)
22172b15cb3dSCy Schubert 			return -1;
2218*a466cc55SCy Schubert 		sin6.sin6_scope_id = if_index;
22192b15cb3dSCy Schubert 		memset(out, 0, *outlen);
22202b15cb3dSCy Schubert 		memcpy(out, &sin6, sizeof(sin6));
22212b15cb3dSCy Schubert 		*outlen = sizeof(sin6);
22222b15cb3dSCy Schubert 		return 0;
22232b15cb3dSCy Schubert 	}
22242b15cb3dSCy Schubert 	else
22252b15cb3dSCy Schubert #endif
22262b15cb3dSCy Schubert 	{
22272b15cb3dSCy Schubert 		struct sockaddr_in sin;
22282b15cb3dSCy Schubert 		memset(&sin, 0, sizeof(sin));
22292b15cb3dSCy Schubert #ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
22302b15cb3dSCy Schubert 		sin.sin_len = sizeof(sin);
22312b15cb3dSCy Schubert #endif
22322b15cb3dSCy Schubert 		sin.sin_family = AF_INET;
22332b15cb3dSCy Schubert 		sin.sin_port = htons(port);
22342b15cb3dSCy Schubert 		if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr))
22352b15cb3dSCy Schubert 			return -1;
22362b15cb3dSCy Schubert 		if ((int)sizeof(sin) > *outlen)
22372b15cb3dSCy Schubert 			return -1;
22382b15cb3dSCy Schubert 		memset(out, 0, *outlen);
22392b15cb3dSCy Schubert 		memcpy(out, &sin, sizeof(sin));
22402b15cb3dSCy Schubert 		*outlen = sizeof(sin);
22412b15cb3dSCy Schubert 		return 0;
22422b15cb3dSCy Schubert 	}
22432b15cb3dSCy Schubert }
22442b15cb3dSCy Schubert 
22452b15cb3dSCy Schubert const char *
evutil_format_sockaddr_port_(const struct sockaddr * sa,char * out,size_t outlen)22462b15cb3dSCy Schubert evutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen)
22472b15cb3dSCy Schubert {
22482b15cb3dSCy Schubert 	char b[128];
22492b15cb3dSCy Schubert 	const char *res=NULL;
22502b15cb3dSCy Schubert 	int port;
22512b15cb3dSCy Schubert 	if (sa->sa_family == AF_INET) {
22522b15cb3dSCy Schubert 		const struct sockaddr_in *sin = (const struct sockaddr_in*)sa;
22532b15cb3dSCy Schubert 		res = evutil_inet_ntop(AF_INET, &sin->sin_addr,b,sizeof(b));
22542b15cb3dSCy Schubert 		port = ntohs(sin->sin_port);
22552b15cb3dSCy Schubert 		if (res) {
22562b15cb3dSCy Schubert 			evutil_snprintf(out, outlen, "%s:%d", b, port);
22572b15cb3dSCy Schubert 			return out;
22582b15cb3dSCy Schubert 		}
22592b15cb3dSCy Schubert 	} else if (sa->sa_family == AF_INET6) {
22602b15cb3dSCy Schubert 		const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6*)sa;
22612b15cb3dSCy Schubert 		res = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr,b,sizeof(b));
22622b15cb3dSCy Schubert 		port = ntohs(sin6->sin6_port);
22632b15cb3dSCy Schubert 		if (res) {
22642b15cb3dSCy Schubert 			evutil_snprintf(out, outlen, "[%s]:%d", b, port);
22652b15cb3dSCy Schubert 			return out;
22662b15cb3dSCy Schubert 		}
22672b15cb3dSCy Schubert 	}
22682b15cb3dSCy Schubert 
22692b15cb3dSCy Schubert 	evutil_snprintf(out, outlen, "<addr with socktype %d>",
22702b15cb3dSCy Schubert 	    (int)sa->sa_family);
22712b15cb3dSCy Schubert 	return out;
22722b15cb3dSCy Schubert }
22732b15cb3dSCy Schubert 
22742b15cb3dSCy Schubert int
evutil_sockaddr_cmp(const struct sockaddr * sa1,const struct sockaddr * sa2,int include_port)22752b15cb3dSCy Schubert evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
22762b15cb3dSCy Schubert     int include_port)
22772b15cb3dSCy Schubert {
22782b15cb3dSCy Schubert 	int r;
22792b15cb3dSCy Schubert 	if (0 != (r = (sa1->sa_family - sa2->sa_family)))
22802b15cb3dSCy Schubert 		return r;
22812b15cb3dSCy Schubert 
22822b15cb3dSCy Schubert 	if (sa1->sa_family == AF_INET) {
22832b15cb3dSCy Schubert 		const struct sockaddr_in *sin1, *sin2;
22842b15cb3dSCy Schubert 		sin1 = (const struct sockaddr_in *)sa1;
22852b15cb3dSCy Schubert 		sin2 = (const struct sockaddr_in *)sa2;
22862b15cb3dSCy Schubert 		if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
22872b15cb3dSCy Schubert 			return -1;
22882b15cb3dSCy Schubert 		else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
22892b15cb3dSCy Schubert 			return 1;
22902b15cb3dSCy Schubert 		else if (include_port &&
22912b15cb3dSCy Schubert 		    (r = ((int)sin1->sin_port - (int)sin2->sin_port)))
22922b15cb3dSCy Schubert 			return r;
22932b15cb3dSCy Schubert 		else
22942b15cb3dSCy Schubert 			return 0;
22952b15cb3dSCy Schubert 	}
22962b15cb3dSCy Schubert #ifdef AF_INET6
22972b15cb3dSCy Schubert 	else if (sa1->sa_family == AF_INET6) {
22982b15cb3dSCy Schubert 		const struct sockaddr_in6 *sin1, *sin2;
22992b15cb3dSCy Schubert 		sin1 = (const struct sockaddr_in6 *)sa1;
23002b15cb3dSCy Schubert 		sin2 = (const struct sockaddr_in6 *)sa2;
23012b15cb3dSCy Schubert 		if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
23022b15cb3dSCy Schubert 			return r;
23032b15cb3dSCy Schubert 		else if (include_port &&
23042b15cb3dSCy Schubert 		    (r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
23052b15cb3dSCy Schubert 			return r;
23062b15cb3dSCy Schubert 		else
23072b15cb3dSCy Schubert 			return 0;
23082b15cb3dSCy Schubert 	}
23092b15cb3dSCy Schubert #endif
23102b15cb3dSCy Schubert 	return 1;
23112b15cb3dSCy Schubert }
23122b15cb3dSCy Schubert 
23132b15cb3dSCy Schubert /* Tables to implement ctypes-replacement EVUTIL_IS*() functions.  Each table
23142b15cb3dSCy Schubert  * has 256 bits to look up whether a character is in some set or not.  This
23152b15cb3dSCy Schubert  * fails on non-ASCII platforms, but so does every other place where we
23162b15cb3dSCy Schubert  * take a char and write it onto the network.
23172b15cb3dSCy Schubert  **/
23182b15cb3dSCy Schubert static const ev_uint32_t EVUTIL_ISALPHA_TABLE[8] =
23192b15cb3dSCy Schubert   { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
23202b15cb3dSCy Schubert static const ev_uint32_t EVUTIL_ISALNUM_TABLE[8] =
23212b15cb3dSCy Schubert   { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
23222b15cb3dSCy Schubert static const ev_uint32_t EVUTIL_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
23232b15cb3dSCy Schubert static const ev_uint32_t EVUTIL_ISXDIGIT_TABLE[8] =
23242b15cb3dSCy Schubert   { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
23252b15cb3dSCy Schubert static const ev_uint32_t EVUTIL_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
23262b15cb3dSCy Schubert static const ev_uint32_t EVUTIL_ISPRINT_TABLE[8] =
23272b15cb3dSCy Schubert   { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
23282b15cb3dSCy Schubert static const ev_uint32_t EVUTIL_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
23292b15cb3dSCy Schubert static const ev_uint32_t EVUTIL_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
23302b15cb3dSCy Schubert /* Upper-casing and lowercasing tables to map characters to upper/lowercase
23312b15cb3dSCy Schubert  * equivalents. */
23322b15cb3dSCy Schubert static const unsigned char EVUTIL_TOUPPER_TABLE[256] = {
23332b15cb3dSCy Schubert   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
23342b15cb3dSCy Schubert   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
23352b15cb3dSCy Schubert   32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
23362b15cb3dSCy Schubert   48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
23372b15cb3dSCy Schubert   64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
23382b15cb3dSCy Schubert   80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
23392b15cb3dSCy Schubert   96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
23402b15cb3dSCy Schubert   80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
23412b15cb3dSCy Schubert   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
23422b15cb3dSCy Schubert   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
23432b15cb3dSCy Schubert   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
23442b15cb3dSCy Schubert   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
23452b15cb3dSCy Schubert   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
23462b15cb3dSCy Schubert   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
23472b15cb3dSCy Schubert   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
23482b15cb3dSCy Schubert   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
23492b15cb3dSCy Schubert };
23502b15cb3dSCy Schubert static const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
23512b15cb3dSCy Schubert   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
23522b15cb3dSCy Schubert   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
23532b15cb3dSCy Schubert   32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
23542b15cb3dSCy Schubert   48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
23552b15cb3dSCy Schubert   64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
23562b15cb3dSCy Schubert   112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
23572b15cb3dSCy Schubert   96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
23582b15cb3dSCy Schubert   112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
23592b15cb3dSCy Schubert   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
23602b15cb3dSCy Schubert   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
23612b15cb3dSCy Schubert   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
23622b15cb3dSCy Schubert   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
23632b15cb3dSCy Schubert   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
23642b15cb3dSCy Schubert   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
23652b15cb3dSCy Schubert   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
23662b15cb3dSCy Schubert   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
23672b15cb3dSCy Schubert };
23682b15cb3dSCy Schubert 
23692b15cb3dSCy Schubert #define IMPL_CTYPE_FN(name)						\
23702b15cb3dSCy Schubert 	int EVUTIL_##name##_(char c) {					\
23712b15cb3dSCy Schubert 		ev_uint8_t u = c;					\
2372*a466cc55SCy Schubert 		return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1U << (u & 31))); \
23732b15cb3dSCy Schubert 	}
23742b15cb3dSCy Schubert IMPL_CTYPE_FN(ISALPHA)
IMPL_CTYPE_FN(ISALNUM)23752b15cb3dSCy Schubert IMPL_CTYPE_FN(ISALNUM)
23762b15cb3dSCy Schubert IMPL_CTYPE_FN(ISSPACE)
23772b15cb3dSCy Schubert IMPL_CTYPE_FN(ISDIGIT)
23782b15cb3dSCy Schubert IMPL_CTYPE_FN(ISXDIGIT)
23792b15cb3dSCy Schubert IMPL_CTYPE_FN(ISPRINT)
23802b15cb3dSCy Schubert IMPL_CTYPE_FN(ISLOWER)
23812b15cb3dSCy Schubert IMPL_CTYPE_FN(ISUPPER)
23822b15cb3dSCy Schubert 
23832b15cb3dSCy Schubert char EVUTIL_TOLOWER_(char c)
23842b15cb3dSCy Schubert {
23852b15cb3dSCy Schubert 	return ((char)EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]);
23862b15cb3dSCy Schubert }
EVUTIL_TOUPPER_(char c)23872b15cb3dSCy Schubert char EVUTIL_TOUPPER_(char c)
23882b15cb3dSCy Schubert {
23892b15cb3dSCy Schubert 	return ((char)EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]);
23902b15cb3dSCy Schubert }
23912b15cb3dSCy Schubert int
evutil_ascii_strcasecmp(const char * s1,const char * s2)23922b15cb3dSCy Schubert evutil_ascii_strcasecmp(const char *s1, const char *s2)
23932b15cb3dSCy Schubert {
23942b15cb3dSCy Schubert 	char c1, c2;
23952b15cb3dSCy Schubert 	while (1) {
23962b15cb3dSCy Schubert 		c1 = EVUTIL_TOLOWER_(*s1++);
23972b15cb3dSCy Schubert 		c2 = EVUTIL_TOLOWER_(*s2++);
23982b15cb3dSCy Schubert 		if (c1 < c2)
23992b15cb3dSCy Schubert 			return -1;
24002b15cb3dSCy Schubert 		else if (c1 > c2)
24012b15cb3dSCy Schubert 			return 1;
24022b15cb3dSCy Schubert 		else if (c1 == 0)
24032b15cb3dSCy Schubert 			return 0;
24042b15cb3dSCy Schubert 	}
24052b15cb3dSCy Schubert }
evutil_ascii_strncasecmp(const char * s1,const char * s2,size_t n)24062b15cb3dSCy Schubert int evutil_ascii_strncasecmp(const char *s1, const char *s2, size_t n)
24072b15cb3dSCy Schubert {
24082b15cb3dSCy Schubert 	char c1, c2;
24092b15cb3dSCy Schubert 	while (n--) {
24102b15cb3dSCy Schubert 		c1 = EVUTIL_TOLOWER_(*s1++);
24112b15cb3dSCy Schubert 		c2 = EVUTIL_TOLOWER_(*s2++);
24122b15cb3dSCy Schubert 		if (c1 < c2)
24132b15cb3dSCy Schubert 			return -1;
24142b15cb3dSCy Schubert 		else if (c1 > c2)
24152b15cb3dSCy Schubert 			return 1;
24162b15cb3dSCy Schubert 		else if (c1 == 0)
24172b15cb3dSCy Schubert 			return 0;
24182b15cb3dSCy Schubert 	}
24192b15cb3dSCy Schubert 	return 0;
24202b15cb3dSCy Schubert }
24212b15cb3dSCy Schubert 
24222b15cb3dSCy Schubert void
evutil_rtrim_lws_(char * str)24232b15cb3dSCy Schubert evutil_rtrim_lws_(char *str)
24242b15cb3dSCy Schubert {
24252b15cb3dSCy Schubert 	char *cp;
24262b15cb3dSCy Schubert 
24272b15cb3dSCy Schubert 	if (str == NULL)
24282b15cb3dSCy Schubert 		return;
24292b15cb3dSCy Schubert 
24302b15cb3dSCy Schubert 	if ((cp = strchr(str, '\0')) == NULL || (cp == str))
24312b15cb3dSCy Schubert 		return;
24322b15cb3dSCy Schubert 
24332b15cb3dSCy Schubert 	--cp;
24342b15cb3dSCy Schubert 
24352b15cb3dSCy Schubert 	while (*cp == ' ' || *cp == '\t') {
24362b15cb3dSCy Schubert 		*cp = '\0';
24372b15cb3dSCy Schubert 		if (cp == str)
24382b15cb3dSCy Schubert 			break;
24392b15cb3dSCy Schubert 		--cp;
24402b15cb3dSCy Schubert 	}
24412b15cb3dSCy Schubert }
24422b15cb3dSCy Schubert 
24432b15cb3dSCy Schubert static int
evutil_issetugid(void)24442b15cb3dSCy Schubert evutil_issetugid(void)
24452b15cb3dSCy Schubert {
24462b15cb3dSCy Schubert #ifdef EVENT__HAVE_ISSETUGID
24472b15cb3dSCy Schubert 	return issetugid();
24482b15cb3dSCy Schubert #else
24492b15cb3dSCy Schubert 
24502b15cb3dSCy Schubert #ifdef EVENT__HAVE_GETEUID
24512b15cb3dSCy Schubert 	if (getuid() != geteuid())
24522b15cb3dSCy Schubert 		return 1;
24532b15cb3dSCy Schubert #endif
24542b15cb3dSCy Schubert #ifdef EVENT__HAVE_GETEGID
24552b15cb3dSCy Schubert 	if (getgid() != getegid())
24562b15cb3dSCy Schubert 		return 1;
24572b15cb3dSCy Schubert #endif
24582b15cb3dSCy Schubert 	return 0;
24592b15cb3dSCy Schubert #endif
24602b15cb3dSCy Schubert }
24612b15cb3dSCy Schubert 
24622b15cb3dSCy Schubert const char *
evutil_getenv_(const char * varname)24632b15cb3dSCy Schubert evutil_getenv_(const char *varname)
24642b15cb3dSCy Schubert {
24652b15cb3dSCy Schubert 	if (evutil_issetugid())
24662b15cb3dSCy Schubert 		return NULL;
24672b15cb3dSCy Schubert 
24682b15cb3dSCy Schubert 	return getenv(varname);
24692b15cb3dSCy Schubert }
24702b15cb3dSCy Schubert 
24712b15cb3dSCy Schubert ev_uint32_t
evutil_weakrand_seed_(struct evutil_weakrand_state * state,ev_uint32_t seed)24722b15cb3dSCy Schubert evutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed)
24732b15cb3dSCy Schubert {
24742b15cb3dSCy Schubert 	if (seed == 0) {
24752b15cb3dSCy Schubert 		struct timeval tv;
24762b15cb3dSCy Schubert 		evutil_gettimeofday(&tv, NULL);
24772b15cb3dSCy Schubert 		seed = (ev_uint32_t)tv.tv_sec + (ev_uint32_t)tv.tv_usec;
24782b15cb3dSCy Schubert #ifdef _WIN32
24792b15cb3dSCy Schubert 		seed += (ev_uint32_t) _getpid();
24802b15cb3dSCy Schubert #else
24812b15cb3dSCy Schubert 		seed += (ev_uint32_t) getpid();
24822b15cb3dSCy Schubert #endif
24832b15cb3dSCy Schubert 	}
24842b15cb3dSCy Schubert 	state->seed = seed;
24852b15cb3dSCy Schubert 	return seed;
24862b15cb3dSCy Schubert }
24872b15cb3dSCy Schubert 
24882b15cb3dSCy Schubert ev_int32_t
evutil_weakrand_(struct evutil_weakrand_state * state)24892b15cb3dSCy Schubert evutil_weakrand_(struct evutil_weakrand_state *state)
24902b15cb3dSCy Schubert {
24912b15cb3dSCy Schubert 	/* This RNG implementation is a linear congruential generator, with
24922b15cb3dSCy Schubert 	 * modulus 2^31, multiplier 1103515245, and addend 12345.  It's also
24932b15cb3dSCy Schubert 	 * used by OpenBSD, and by Glibc's TYPE_0 RNG.
24942b15cb3dSCy Schubert 	 *
24952b15cb3dSCy Schubert 	 * The linear congruential generator is not an industrial-strength
24962b15cb3dSCy Schubert 	 * RNG!  It's fast, but it can have higher-order patterns.  Notably,
24972b15cb3dSCy Schubert 	 * the low bits tend to have periodicity.
24982b15cb3dSCy Schubert 	 */
24992b15cb3dSCy Schubert 	state->seed = ((state->seed) * 1103515245 + 12345) & 0x7fffffff;
25002b15cb3dSCy Schubert 	return (ev_int32_t)(state->seed);
25012b15cb3dSCy Schubert }
25022b15cb3dSCy Schubert 
25032b15cb3dSCy Schubert ev_int32_t
evutil_weakrand_range_(struct evutil_weakrand_state * state,ev_int32_t top)25042b15cb3dSCy Schubert evutil_weakrand_range_(struct evutil_weakrand_state *state, ev_int32_t top)
25052b15cb3dSCy Schubert {
25062b15cb3dSCy Schubert 	ev_int32_t divisor, result;
25072b15cb3dSCy Schubert 
25082b15cb3dSCy Schubert 	/* We can't just do weakrand() % top, since the low bits of the LCG
25092b15cb3dSCy Schubert 	 * are less random than the high ones.  (Specifically, since the LCG
25102b15cb3dSCy Schubert 	 * modulus is 2^N, every 2^m for m<N will divide the modulus, and so
25112b15cb3dSCy Schubert 	 * therefore the low m bits of the LCG will have period 2^m.) */
25122b15cb3dSCy Schubert 	divisor = EVUTIL_WEAKRAND_MAX / top;
25132b15cb3dSCy Schubert 	do {
25142b15cb3dSCy Schubert 		result = evutil_weakrand_(state) / divisor;
25152b15cb3dSCy Schubert 	} while (result >= top);
25162b15cb3dSCy Schubert 	return result;
25172b15cb3dSCy Schubert }
25182b15cb3dSCy Schubert 
25192b15cb3dSCy Schubert /**
25202b15cb3dSCy Schubert  * Volatile pointer to memset: we use this to keep the compiler from
25212b15cb3dSCy Schubert  * eliminating our call to memset.
25222b15cb3dSCy Schubert  */
25232b15cb3dSCy Schubert void * (*volatile evutil_memset_volatile_)(void *, int, size_t) = memset;
25242b15cb3dSCy Schubert 
25252b15cb3dSCy Schubert void
evutil_memclear_(void * mem,size_t len)25262b15cb3dSCy Schubert evutil_memclear_(void *mem, size_t len)
25272b15cb3dSCy Schubert {
25282b15cb3dSCy Schubert 	evutil_memset_volatile_(mem, 0, len);
25292b15cb3dSCy Schubert }
25302b15cb3dSCy Schubert 
25312b15cb3dSCy Schubert int
evutil_sockaddr_is_loopback_(const struct sockaddr * addr)25322b15cb3dSCy Schubert evutil_sockaddr_is_loopback_(const struct sockaddr *addr)
25332b15cb3dSCy Schubert {
25342b15cb3dSCy Schubert 	static const char LOOPBACK_S6[16] =
25352b15cb3dSCy Schubert 	    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
25362b15cb3dSCy Schubert 	if (addr->sa_family == AF_INET) {
25372b15cb3dSCy Schubert 		struct sockaddr_in *sin = (struct sockaddr_in *)addr;
25382b15cb3dSCy Schubert 		return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
25392b15cb3dSCy Schubert 	} else if (addr->sa_family == AF_INET6) {
25402b15cb3dSCy Schubert 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
25412b15cb3dSCy Schubert 		return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
25422b15cb3dSCy Schubert 	}
25432b15cb3dSCy Schubert 	return 0;
25442b15cb3dSCy Schubert }
25452b15cb3dSCy Schubert 
25462b15cb3dSCy Schubert int
evutil_hex_char_to_int_(char c)25472b15cb3dSCy Schubert evutil_hex_char_to_int_(char c)
25482b15cb3dSCy Schubert {
25492b15cb3dSCy Schubert 	switch(c)
25502b15cb3dSCy Schubert 	{
25512b15cb3dSCy Schubert 		case '0': return 0;
25522b15cb3dSCy Schubert 		case '1': return 1;
25532b15cb3dSCy Schubert 		case '2': return 2;
25542b15cb3dSCy Schubert 		case '3': return 3;
25552b15cb3dSCy Schubert 		case '4': return 4;
25562b15cb3dSCy Schubert 		case '5': return 5;
25572b15cb3dSCy Schubert 		case '6': return 6;
25582b15cb3dSCy Schubert 		case '7': return 7;
25592b15cb3dSCy Schubert 		case '8': return 8;
25602b15cb3dSCy Schubert 		case '9': return 9;
25612b15cb3dSCy Schubert 		case 'A': case 'a': return 10;
25622b15cb3dSCy Schubert 		case 'B': case 'b': return 11;
25632b15cb3dSCy Schubert 		case 'C': case 'c': return 12;
25642b15cb3dSCy Schubert 		case 'D': case 'd': return 13;
25652b15cb3dSCy Schubert 		case 'E': case 'e': return 14;
25662b15cb3dSCy Schubert 		case 'F': case 'f': return 15;
25672b15cb3dSCy Schubert 	}
25682b15cb3dSCy Schubert 	return -1;
25692b15cb3dSCy Schubert }
25702b15cb3dSCy Schubert 
25712b15cb3dSCy Schubert #ifdef _WIN32
2572a25439b6SCy Schubert HMODULE
evutil_load_windows_system_library_(const TCHAR * library_name)25732b15cb3dSCy Schubert evutil_load_windows_system_library_(const TCHAR *library_name)
25742b15cb3dSCy Schubert {
25752b15cb3dSCy Schubert   TCHAR path[MAX_PATH];
25762b15cb3dSCy Schubert   unsigned n;
25772b15cb3dSCy Schubert   n = GetSystemDirectory(path, MAX_PATH);
25782b15cb3dSCy Schubert   if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
25792b15cb3dSCy Schubert     return 0;
25802b15cb3dSCy Schubert   _tcscat(path, TEXT("\\"));
25812b15cb3dSCy Schubert   _tcscat(path, library_name);
25822b15cb3dSCy Schubert   return LoadLibrary(path);
25832b15cb3dSCy Schubert }
25842b15cb3dSCy Schubert #endif
25852b15cb3dSCy Schubert 
25862b15cb3dSCy Schubert /* Internal wrapper around 'socket' to provide Linux-style support for
25872b15cb3dSCy Schubert  * syscall-saving methods where available.
25882b15cb3dSCy Schubert  *
25892b15cb3dSCy Schubert  * In addition to regular socket behavior, you can use a bitwise or to set the
25902b15cb3dSCy Schubert  * flags EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'type' argument,
25912b15cb3dSCy Schubert  * to make the socket nonblocking or close-on-exec with as few syscalls as
25922b15cb3dSCy Schubert  * possible.
25932b15cb3dSCy Schubert  */
25942b15cb3dSCy Schubert evutil_socket_t
evutil_socket_(int domain,int type,int protocol)25952b15cb3dSCy Schubert evutil_socket_(int domain, int type, int protocol)
25962b15cb3dSCy Schubert {
25972b15cb3dSCy Schubert 	evutil_socket_t r;
25982b15cb3dSCy Schubert #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
25992b15cb3dSCy Schubert 	r = socket(domain, type, protocol);
26002b15cb3dSCy Schubert 	if (r >= 0)
26012b15cb3dSCy Schubert 		return r;
26022b15cb3dSCy Schubert 	else if ((type & (SOCK_NONBLOCK|SOCK_CLOEXEC)) == 0)
26032b15cb3dSCy Schubert 		return -1;
26042b15cb3dSCy Schubert #endif
26052b15cb3dSCy Schubert #define SOCKET_TYPE_MASK (~(EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC))
26062b15cb3dSCy Schubert 	r = socket(domain, type & SOCKET_TYPE_MASK, protocol);
26072b15cb3dSCy Schubert 	if (r < 0)
26082b15cb3dSCy Schubert 		return -1;
26092b15cb3dSCy Schubert 	if (type & EVUTIL_SOCK_NONBLOCK) {
26102b15cb3dSCy Schubert 		if (evutil_fast_socket_nonblocking(r) < 0) {
26112b15cb3dSCy Schubert 			evutil_closesocket(r);
26122b15cb3dSCy Schubert 			return -1;
26132b15cb3dSCy Schubert 		}
26142b15cb3dSCy Schubert 	}
26152b15cb3dSCy Schubert 	if (type & EVUTIL_SOCK_CLOEXEC) {
26162b15cb3dSCy Schubert 		if (evutil_fast_socket_closeonexec(r) < 0) {
26172b15cb3dSCy Schubert 			evutil_closesocket(r);
26182b15cb3dSCy Schubert 			return -1;
26192b15cb3dSCy Schubert 		}
26202b15cb3dSCy Schubert 	}
26212b15cb3dSCy Schubert 	return r;
26222b15cb3dSCy Schubert }
26232b15cb3dSCy Schubert 
26242b15cb3dSCy Schubert /* Internal wrapper around 'accept' or 'accept4' to provide Linux-style
26252b15cb3dSCy Schubert  * support for syscall-saving methods where available.
26262b15cb3dSCy Schubert  *
26272b15cb3dSCy Schubert  * In addition to regular accept behavior, you can set one or more of flags
26282b15cb3dSCy Schubert  * EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'flags' argument, to
26292b15cb3dSCy Schubert  * make the socket nonblocking or close-on-exec with as few syscalls as
26302b15cb3dSCy Schubert  * possible.
26312b15cb3dSCy Schubert  */
26322b15cb3dSCy Schubert evutil_socket_t
evutil_accept4_(evutil_socket_t sockfd,struct sockaddr * addr,ev_socklen_t * addrlen,int flags)26332b15cb3dSCy Schubert evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr,
26342b15cb3dSCy Schubert     ev_socklen_t *addrlen, int flags)
26352b15cb3dSCy Schubert {
26362b15cb3dSCy Schubert 	evutil_socket_t result;
26372b15cb3dSCy Schubert #if defined(EVENT__HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
26382b15cb3dSCy Schubert 	result = accept4(sockfd, addr, addrlen, flags);
26392b15cb3dSCy Schubert 	if (result >= 0 || (errno != EINVAL && errno != ENOSYS)) {
26402b15cb3dSCy Schubert 		/* A nonnegative result means that we succeeded, so return.
26412b15cb3dSCy Schubert 		 * Failing with EINVAL means that an option wasn't supported,
26422b15cb3dSCy Schubert 		 * and failing with ENOSYS means that the syscall wasn't
26432b15cb3dSCy Schubert 		 * there: in those cases we want to fall back.  Otherwise, we
26442b15cb3dSCy Schubert 		 * got a real error, and we should return. */
26452b15cb3dSCy Schubert 		return result;
26462b15cb3dSCy Schubert 	}
26472b15cb3dSCy Schubert #endif
26482b15cb3dSCy Schubert 	result = accept(sockfd, addr, addrlen);
26492b15cb3dSCy Schubert 	if (result < 0)
26502b15cb3dSCy Schubert 		return result;
26512b15cb3dSCy Schubert 
26522b15cb3dSCy Schubert 	if (flags & EVUTIL_SOCK_CLOEXEC) {
26532b15cb3dSCy Schubert 		if (evutil_fast_socket_closeonexec(result) < 0) {
26542b15cb3dSCy Schubert 			evutil_closesocket(result);
26552b15cb3dSCy Schubert 			return -1;
26562b15cb3dSCy Schubert 		}
26572b15cb3dSCy Schubert 	}
26582b15cb3dSCy Schubert 	if (flags & EVUTIL_SOCK_NONBLOCK) {
26592b15cb3dSCy Schubert 		if (evutil_fast_socket_nonblocking(result) < 0) {
26602b15cb3dSCy Schubert 			evutil_closesocket(result);
26612b15cb3dSCy Schubert 			return -1;
26622b15cb3dSCy Schubert 		}
26632b15cb3dSCy Schubert 	}
26642b15cb3dSCy Schubert 	return result;
26652b15cb3dSCy Schubert }
26662b15cb3dSCy Schubert 
26672b15cb3dSCy Schubert /* Internal function: Set fd[0] and fd[1] to a pair of fds such that writes on
2668*a466cc55SCy Schubert  * fd[1] get read from fd[0].  Make both fds nonblocking and close-on-exec.
26692b15cb3dSCy Schubert  * Return 0 on success, -1 on failure.
26702b15cb3dSCy Schubert  */
26712b15cb3dSCy Schubert int
evutil_make_internal_pipe_(evutil_socket_t fd[2])26722b15cb3dSCy Schubert evutil_make_internal_pipe_(evutil_socket_t fd[2])
26732b15cb3dSCy Schubert {
26742b15cb3dSCy Schubert 	/*
26752b15cb3dSCy Schubert 	  Making the second socket nonblocking is a bit subtle, given that we
26762b15cb3dSCy Schubert 	  ignore any EAGAIN returns when writing to it, and you don't usally
26772b15cb3dSCy Schubert 	  do that for a nonblocking socket. But if the kernel gives us EAGAIN,
26782b15cb3dSCy Schubert 	  then there's no need to add any more data to the buffer, since
26792b15cb3dSCy Schubert 	  the main thread is already either about to wake up and drain it,
26802b15cb3dSCy Schubert 	  or woken up and in the process of draining it.
26812b15cb3dSCy Schubert 	*/
26822b15cb3dSCy Schubert 
26832b15cb3dSCy Schubert #if defined(EVENT__HAVE_PIPE2)
26842b15cb3dSCy Schubert 	if (pipe2(fd, O_NONBLOCK|O_CLOEXEC) == 0)
26852b15cb3dSCy Schubert 		return 0;
26862b15cb3dSCy Schubert #endif
26872b15cb3dSCy Schubert #if defined(EVENT__HAVE_PIPE)
26882b15cb3dSCy Schubert 	if (pipe(fd) == 0) {
26892b15cb3dSCy Schubert 		if (evutil_fast_socket_nonblocking(fd[0]) < 0 ||
26902b15cb3dSCy Schubert 		    evutil_fast_socket_nonblocking(fd[1]) < 0 ||
26912b15cb3dSCy Schubert 		    evutil_fast_socket_closeonexec(fd[0]) < 0 ||
26922b15cb3dSCy Schubert 		    evutil_fast_socket_closeonexec(fd[1]) < 0) {
26932b15cb3dSCy Schubert 			close(fd[0]);
26942b15cb3dSCy Schubert 			close(fd[1]);
26952b15cb3dSCy Schubert 			fd[0] = fd[1] = -1;
26962b15cb3dSCy Schubert 			return -1;
26972b15cb3dSCy Schubert 		}
26982b15cb3dSCy Schubert 		return 0;
26992b15cb3dSCy Schubert 	} else {
27002b15cb3dSCy Schubert 		event_warn("%s: pipe", __func__);
27012b15cb3dSCy Schubert 	}
27022b15cb3dSCy Schubert #endif
27032b15cb3dSCy Schubert 
27042b15cb3dSCy Schubert #ifdef _WIN32
27052b15cb3dSCy Schubert #define LOCAL_SOCKETPAIR_AF AF_INET
27062b15cb3dSCy Schubert #else
27072b15cb3dSCy Schubert #define LOCAL_SOCKETPAIR_AF AF_UNIX
27082b15cb3dSCy Schubert #endif
27092b15cb3dSCy Schubert 	if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, fd) == 0) {
27102b15cb3dSCy Schubert 		if (evutil_fast_socket_nonblocking(fd[0]) < 0 ||
27112b15cb3dSCy Schubert 		    evutil_fast_socket_nonblocking(fd[1]) < 0 ||
27122b15cb3dSCy Schubert 		    evutil_fast_socket_closeonexec(fd[0]) < 0 ||
27132b15cb3dSCy Schubert 		    evutil_fast_socket_closeonexec(fd[1]) < 0) {
27142b15cb3dSCy Schubert 			evutil_closesocket(fd[0]);
27152b15cb3dSCy Schubert 			evutil_closesocket(fd[1]);
27162b15cb3dSCy Schubert 			fd[0] = fd[1] = -1;
27172b15cb3dSCy Schubert 			return -1;
27182b15cb3dSCy Schubert 		}
27192b15cb3dSCy Schubert 		return 0;
27202b15cb3dSCy Schubert 	}
27212b15cb3dSCy Schubert 	fd[0] = fd[1] = -1;
27222b15cb3dSCy Schubert 	return -1;
27232b15cb3dSCy Schubert }
27242b15cb3dSCy Schubert 
27252b15cb3dSCy Schubert /* Wrapper around eventfd on systems that provide it.  Unlike the system
27262b15cb3dSCy Schubert  * eventfd, it always supports EVUTIL_EFD_CLOEXEC and EVUTIL_EFD_NONBLOCK as
27272b15cb3dSCy Schubert  * flags.  Returns -1 on error or if eventfd is not supported.
27282b15cb3dSCy Schubert  */
27292b15cb3dSCy Schubert evutil_socket_t
evutil_eventfd_(unsigned initval,int flags)27302b15cb3dSCy Schubert evutil_eventfd_(unsigned initval, int flags)
27312b15cb3dSCy Schubert {
27322b15cb3dSCy Schubert #if defined(EVENT__HAVE_EVENTFD) && defined(EVENT__HAVE_SYS_EVENTFD_H)
27332b15cb3dSCy Schubert 	int r;
27342b15cb3dSCy Schubert #if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
27352b15cb3dSCy Schubert 	r = eventfd(initval, flags);
27362b15cb3dSCy Schubert 	if (r >= 0 || flags == 0)
27372b15cb3dSCy Schubert 		return r;
27382b15cb3dSCy Schubert #endif
27392b15cb3dSCy Schubert 	r = eventfd(initval, 0);
27402b15cb3dSCy Schubert 	if (r < 0)
27412b15cb3dSCy Schubert 		return r;
27422b15cb3dSCy Schubert 	if (flags & EVUTIL_EFD_CLOEXEC) {
27432b15cb3dSCy Schubert 		if (evutil_fast_socket_closeonexec(r) < 0) {
27442b15cb3dSCy Schubert 			evutil_closesocket(r);
27452b15cb3dSCy Schubert 			return -1;
27462b15cb3dSCy Schubert 		}
27472b15cb3dSCy Schubert 	}
27482b15cb3dSCy Schubert 	if (flags & EVUTIL_EFD_NONBLOCK) {
27492b15cb3dSCy Schubert 		if (evutil_fast_socket_nonblocking(r) < 0) {
27502b15cb3dSCy Schubert 			evutil_closesocket(r);
27512b15cb3dSCy Schubert 			return -1;
27522b15cb3dSCy Schubert 		}
27532b15cb3dSCy Schubert 	}
27542b15cb3dSCy Schubert 	return r;
27552b15cb3dSCy Schubert #else
27562b15cb3dSCy Schubert 	return -1;
27572b15cb3dSCy Schubert #endif
27582b15cb3dSCy Schubert }
27592b15cb3dSCy Schubert 
27602b15cb3dSCy Schubert void
evutil_free_globals_(void)27612b15cb3dSCy Schubert evutil_free_globals_(void)
27622b15cb3dSCy Schubert {
27632b15cb3dSCy Schubert 	evutil_free_secure_rng_globals_();
27642b15cb3dSCy Schubert 	evutil_free_sock_err_globals();
27652b15cb3dSCy Schubert }
2766