Home | History | Annotate | Line # | Download | only in dist
evutil.c revision 1.1.1.3
      1      1.1    plunky /*	$NetBSD: evutil.c,v 1.1.1.3 2015/01/29 06:38:06 spz Exp $	*/
      2      1.1    plunky /*
      3  1.1.1.2  christos  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
      4      1.1    plunky  *
      5      1.1    plunky  * Redistribution and use in source and binary forms, with or without
      6      1.1    plunky  * modification, are permitted provided that the following conditions
      7      1.1    plunky  * are met:
      8      1.1    plunky  * 1. Redistributions of source code must retain the above copyright
      9      1.1    plunky  *    notice, this list of conditions and the following disclaimer.
     10      1.1    plunky  * 2. Redistributions in binary form must reproduce the above copyright
     11      1.1    plunky  *    notice, this list of conditions and the following disclaimer in the
     12      1.1    plunky  *    documentation and/or other materials provided with the distribution.
     13      1.1    plunky  * 3. The name of the author may not be used to endorse or promote products
     14      1.1    plunky  *    derived from this software without specific prior written permission.
     15      1.1    plunky  *
     16      1.1    plunky  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17      1.1    plunky  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18      1.1    plunky  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19      1.1    plunky  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20      1.1    plunky  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21      1.1    plunky  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22      1.1    plunky  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23      1.1    plunky  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24      1.1    plunky  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25      1.1    plunky  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26      1.1    plunky  */
     27  1.1.1.2  christos 
     28  1.1.1.2  christos #include "event2/event-config.h"
     29  1.1.1.2  christos #include <sys/cdefs.h>
     30  1.1.1.2  christos __RCSID("$NetBSD: evutil.c,v 1.1.1.3 2015/01/29 06:38:06 spz Exp $");
     31  1.1.1.2  christos 
     32  1.1.1.2  christos #define _GNU_SOURCE
     33      1.1    plunky 
     34      1.1    plunky #ifdef WIN32
     35      1.1    plunky #include <winsock2.h>
     36  1.1.1.2  christos #include <ws2tcpip.h>
     37      1.1    plunky #define WIN32_LEAN_AND_MEAN
     38      1.1    plunky #include <windows.h>
     39      1.1    plunky #undef WIN32_LEAN_AND_MEAN
     40  1.1.1.2  christos #include <io.h>
     41  1.1.1.2  christos #include <tchar.h>
     42      1.1    plunky #endif
     43      1.1    plunky 
     44      1.1    plunky #include <sys/types.h>
     45  1.1.1.2  christos #ifdef _EVENT_HAVE_SYS_SOCKET_H
     46      1.1    plunky #include <sys/socket.h>
     47      1.1    plunky #endif
     48  1.1.1.2  christos #ifdef _EVENT_HAVE_UNISTD_H
     49      1.1    plunky #include <unistd.h>
     50      1.1    plunky #endif
     51  1.1.1.2  christos #ifdef _EVENT_HAVE_FCNTL_H
     52      1.1    plunky #include <fcntl.h>
     53      1.1    plunky #endif
     54  1.1.1.2  christos #ifdef _EVENT_HAVE_STDLIB_H
     55      1.1    plunky #include <stdlib.h>
     56      1.1    plunky #endif
     57      1.1    plunky #include <errno.h>
     58  1.1.1.2  christos #include <limits.h>
     59  1.1.1.2  christos #include <stdio.h>
     60  1.1.1.2  christos #include <string.h>
     61  1.1.1.2  christos #ifdef _EVENT_HAVE_NETINET_IN_H
     62  1.1.1.2  christos #include <netinet/in.h>
     63  1.1.1.2  christos #endif
     64  1.1.1.2  christos #ifdef _EVENT_HAVE_NETINET_IN6_H
     65  1.1.1.2  christos #include <netinet/in6.h>
     66  1.1.1.2  christos #endif
     67  1.1.1.2  christos #ifdef _EVENT_HAVE_ARPA_INET_H
     68  1.1.1.2  christos #include <arpa/inet.h>
     69  1.1.1.2  christos #endif
     70  1.1.1.2  christos 
     71  1.1.1.2  christos #ifndef _EVENT_HAVE_GETTIMEOFDAY
     72      1.1    plunky #include <sys/timeb.h>
     73  1.1.1.2  christos #include <time.h>
     74      1.1    plunky #endif
     75  1.1.1.2  christos #include <sys/stat.h>
     76  1.1.1.2  christos 
     77  1.1.1.2  christos #include "event2/util.h"
     78  1.1.1.2  christos #include "util-internal.h"
     79  1.1.1.2  christos #include "log-internal.h"
     80  1.1.1.2  christos #include "mm-internal.h"
     81  1.1.1.2  christos 
     82  1.1.1.2  christos #include "strlcpy-internal.h"
     83  1.1.1.2  christos #include "ipv6-internal.h"
     84      1.1    plunky 
     85  1.1.1.2  christos #ifdef WIN32
     86  1.1.1.2  christos #define open _open
     87  1.1.1.2  christos #define read _read
     88  1.1.1.2  christos #define close _close
     89  1.1.1.2  christos #define fstat _fstati64
     90  1.1.1.2  christos #define stat _stati64
     91  1.1.1.2  christos #define mode_t int
     92  1.1.1.2  christos #endif
     93      1.1    plunky 
     94      1.1    plunky int
     95  1.1.1.2  christos evutil_open_closeonexec(const char *pathname, int flags, unsigned mode)
     96  1.1.1.2  christos {
     97  1.1.1.2  christos 	int fd;
     98  1.1.1.2  christos 
     99  1.1.1.2  christos #ifdef O_CLOEXEC
    100  1.1.1.2  christos 	flags |= O_CLOEXEC;
    101  1.1.1.2  christos #endif
    102  1.1.1.2  christos 
    103  1.1.1.2  christos 	if (flags & O_CREAT)
    104  1.1.1.2  christos 		fd = open(pathname, flags, (mode_t)mode);
    105  1.1.1.2  christos 	else
    106  1.1.1.2  christos 		fd = open(pathname, flags);
    107  1.1.1.2  christos 	if (fd < 0)
    108  1.1.1.2  christos 		return -1;
    109  1.1.1.2  christos 
    110  1.1.1.2  christos #if !defined(O_CLOEXEC) && defined(FD_CLOEXEC)
    111  1.1.1.2  christos 	if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
    112  1.1.1.2  christos 		return -1;
    113  1.1.1.2  christos #endif
    114  1.1.1.2  christos 
    115  1.1.1.2  christos 	return fd;
    116  1.1.1.2  christos }
    117  1.1.1.2  christos 
    118  1.1.1.2  christos /**
    119  1.1.1.2  christos    Read the contents of 'filename' into a newly allocated NUL-terminated
    120  1.1.1.2  christos    string.  Set *content_out to hold this string, and *len_out to hold its
    121  1.1.1.2  christos    length (not including the appended NUL).  If 'is_binary', open the file in
    122  1.1.1.2  christos    binary mode.
    123  1.1.1.2  christos 
    124  1.1.1.2  christos    Returns 0 on success, -1 if the open fails, and -2 for all other failures.
    125  1.1.1.2  christos 
    126  1.1.1.2  christos    Used internally only; may go away in a future version.
    127  1.1.1.2  christos  */
    128  1.1.1.2  christos int
    129  1.1.1.2  christos evutil_read_file(const char *filename, char **content_out, size_t *len_out,
    130  1.1.1.2  christos     int is_binary)
    131  1.1.1.2  christos {
    132  1.1.1.2  christos 	int fd, r;
    133  1.1.1.2  christos 	struct stat st;
    134  1.1.1.2  christos 	char *mem;
    135  1.1.1.2  christos 	size_t read_so_far=0;
    136  1.1.1.2  christos 	int mode = O_RDONLY;
    137  1.1.1.2  christos 
    138  1.1.1.2  christos 	EVUTIL_ASSERT(content_out);
    139  1.1.1.2  christos 	EVUTIL_ASSERT(len_out);
    140  1.1.1.2  christos 	*content_out = NULL;
    141  1.1.1.2  christos 	*len_out = 0;
    142  1.1.1.2  christos 
    143  1.1.1.2  christos #ifdef O_BINARY
    144  1.1.1.2  christos 	if (is_binary)
    145  1.1.1.2  christos 		mode |= O_BINARY;
    146  1.1.1.2  christos #endif
    147  1.1.1.2  christos 
    148  1.1.1.2  christos 	fd = evutil_open_closeonexec(filename, mode, 0);
    149  1.1.1.2  christos 	if (fd < 0)
    150  1.1.1.2  christos 		return -1;
    151  1.1.1.2  christos 	if (fstat(fd, &st) || st.st_size < 0 ||
    152  1.1.1.2  christos 	    st.st_size > EV_SSIZE_MAX-1 ) {
    153  1.1.1.2  christos 		close(fd);
    154  1.1.1.2  christos 		return -2;
    155  1.1.1.2  christos 	}
    156  1.1.1.2  christos 	mem = mm_malloc((size_t)st.st_size + 1);
    157  1.1.1.2  christos 	if (!mem) {
    158  1.1.1.2  christos 		close(fd);
    159  1.1.1.2  christos 		return -2;
    160  1.1.1.2  christos 	}
    161  1.1.1.2  christos 	read_so_far = 0;
    162  1.1.1.2  christos #ifdef WIN32
    163  1.1.1.2  christos #define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x))
    164  1.1.1.2  christos #else
    165  1.1.1.2  christos #define N_TO_READ(x) (x)
    166  1.1.1.2  christos #endif
    167  1.1.1.2  christos 	while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) {
    168  1.1.1.2  christos 		read_so_far += r;
    169  1.1.1.2  christos 		if (read_so_far >= (size_t)st.st_size)
    170  1.1.1.2  christos 			break;
    171  1.1.1.2  christos 		EVUTIL_ASSERT(read_so_far < (size_t)st.st_size);
    172  1.1.1.2  christos 	}
    173  1.1.1.2  christos 	close(fd);
    174  1.1.1.2  christos 	if (r < 0) {
    175  1.1.1.2  christos 		mm_free(mem);
    176  1.1.1.2  christos 		return -2;
    177  1.1.1.2  christos 	}
    178  1.1.1.2  christos 	mem[read_so_far] = 0;
    179  1.1.1.2  christos 
    180  1.1.1.2  christos 	*len_out = read_so_far;
    181  1.1.1.2  christos 	*content_out = mem;
    182  1.1.1.2  christos 	return 0;
    183  1.1.1.2  christos }
    184  1.1.1.2  christos 
    185  1.1.1.2  christos int
    186  1.1.1.2  christos evutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
    187      1.1    plunky {
    188      1.1    plunky #ifndef WIN32
    189      1.1    plunky 	return socketpair(family, type, protocol, fd);
    190      1.1    plunky #else
    191  1.1.1.2  christos 	return evutil_ersatz_socketpair(family, type, protocol, fd);
    192  1.1.1.2  christos #endif
    193  1.1.1.2  christos }
    194  1.1.1.2  christos 
    195  1.1.1.2  christos int
    196  1.1.1.2  christos evutil_ersatz_socketpair(int family, int type, int protocol,
    197  1.1.1.2  christos     evutil_socket_t fd[2])
    198  1.1.1.2  christos {
    199      1.1    plunky 	/* This code is originally from Tor.  Used with permission. */
    200      1.1    plunky 
    201      1.1    plunky 	/* This socketpair does not work when localhost is down. So
    202      1.1    plunky 	 * it's really not the same thing at all. But it's close enough
    203      1.1    plunky 	 * for now, and really, when localhost is down sometimes, we
    204      1.1    plunky 	 * have other problems too.
    205      1.1    plunky 	 */
    206  1.1.1.2  christos #ifdef WIN32
    207  1.1.1.2  christos #define ERR(e) WSA##e
    208  1.1.1.2  christos #else
    209  1.1.1.2  christos #define ERR(e) e
    210  1.1.1.2  christos #endif
    211  1.1.1.2  christos 	evutil_socket_t listener = -1;
    212  1.1.1.2  christos 	evutil_socket_t connector = -1;
    213  1.1.1.2  christos 	evutil_socket_t acceptor = -1;
    214      1.1    plunky 	struct sockaddr_in listen_addr;
    215      1.1    plunky 	struct sockaddr_in connect_addr;
    216  1.1.1.2  christos 	ev_socklen_t size;
    217      1.1    plunky 	int saved_errno = -1;
    218      1.1    plunky 
    219      1.1    plunky 	if (protocol
    220  1.1.1.2  christos 		|| (family != AF_INET
    221      1.1    plunky #ifdef AF_UNIX
    222  1.1.1.2  christos 		    && family != AF_UNIX
    223      1.1    plunky #endif
    224  1.1.1.2  christos 		)) {
    225  1.1.1.2  christos 		EVUTIL_SET_SOCKET_ERROR(ERR(EAFNOSUPPORT));
    226      1.1    plunky 		return -1;
    227      1.1    plunky 	}
    228      1.1    plunky 	if (!fd) {
    229  1.1.1.2  christos 		EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
    230      1.1    plunky 		return -1;
    231      1.1    plunky 	}
    232      1.1    plunky 
    233      1.1    plunky 	listener = socket(AF_INET, type, 0);
    234      1.1    plunky 	if (listener < 0)
    235      1.1    plunky 		return -1;
    236      1.1    plunky 	memset(&listen_addr, 0, sizeof(listen_addr));
    237      1.1    plunky 	listen_addr.sin_family = AF_INET;
    238      1.1    plunky 	listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    239      1.1    plunky 	listen_addr.sin_port = 0;	/* kernel chooses port.	 */
    240      1.1    plunky 	if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
    241      1.1    plunky 		== -1)
    242      1.1    plunky 		goto tidy_up_and_fail;
    243      1.1    plunky 	if (listen(listener, 1) == -1)
    244      1.1    plunky 		goto tidy_up_and_fail;
    245      1.1    plunky 
    246      1.1    plunky 	connector = socket(AF_INET, type, 0);
    247      1.1    plunky 	if (connector < 0)
    248      1.1    plunky 		goto tidy_up_and_fail;
    249      1.1    plunky 	/* We want to find out the port number to connect to.  */
    250      1.1    plunky 	size = sizeof(connect_addr);
    251      1.1    plunky 	if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
    252      1.1    plunky 		goto tidy_up_and_fail;
    253      1.1    plunky 	if (size != sizeof (connect_addr))
    254      1.1    plunky 		goto abort_tidy_up_and_fail;
    255      1.1    plunky 	if (connect(connector, (struct sockaddr *) &connect_addr,
    256      1.1    plunky 				sizeof(connect_addr)) == -1)
    257      1.1    plunky 		goto tidy_up_and_fail;
    258      1.1    plunky 
    259      1.1    plunky 	size = sizeof(listen_addr);
    260      1.1    plunky 	acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
    261      1.1    plunky 	if (acceptor < 0)
    262      1.1    plunky 		goto tidy_up_and_fail;
    263      1.1    plunky 	if (size != sizeof(listen_addr))
    264      1.1    plunky 		goto abort_tidy_up_and_fail;
    265      1.1    plunky 	/* Now check we are talking to ourself by matching port and host on the
    266      1.1    plunky 	   two sockets.	 */
    267      1.1    plunky 	if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
    268      1.1    plunky 		goto tidy_up_and_fail;
    269      1.1    plunky 	if (size != sizeof (connect_addr)
    270      1.1    plunky 		|| listen_addr.sin_family != connect_addr.sin_family
    271      1.1    plunky 		|| listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
    272      1.1    plunky 		|| listen_addr.sin_port != connect_addr.sin_port)
    273      1.1    plunky 		goto abort_tidy_up_and_fail;
    274  1.1.1.3       spz 	evutil_closesocket(listener);
    275      1.1    plunky 	fd[0] = connector;
    276      1.1    plunky 	fd[1] = acceptor;
    277      1.1    plunky 
    278      1.1    plunky 	return 0;
    279      1.1    plunky 
    280      1.1    plunky  abort_tidy_up_and_fail:
    281  1.1.1.2  christos 	saved_errno = ERR(ECONNABORTED);
    282      1.1    plunky  tidy_up_and_fail:
    283      1.1    plunky 	if (saved_errno < 0)
    284  1.1.1.2  christos 		saved_errno = EVUTIL_SOCKET_ERROR();
    285      1.1    plunky 	if (listener != -1)
    286  1.1.1.2  christos 		evutil_closesocket(listener);
    287      1.1    plunky 	if (connector != -1)
    288  1.1.1.2  christos 		evutil_closesocket(connector);
    289      1.1    plunky 	if (acceptor != -1)
    290  1.1.1.2  christos 		evutil_closesocket(acceptor);
    291      1.1    plunky 
    292      1.1    plunky 	EVUTIL_SET_SOCKET_ERROR(saved_errno);
    293      1.1    plunky 	return -1;
    294  1.1.1.2  christos #undef ERR
    295      1.1    plunky }
    296      1.1    plunky 
    297      1.1    plunky int
    298  1.1.1.2  christos evutil_make_socket_nonblocking(evutil_socket_t fd)
    299      1.1    plunky {
    300      1.1    plunky #ifdef WIN32
    301      1.1    plunky 	{
    302  1.1.1.2  christos 		u_long nonblocking = 1;
    303  1.1.1.2  christos 		if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) {
    304  1.1.1.2  christos 			event_sock_warn(fd, "fcntl(%d, F_GETFL)", (int)fd);
    305  1.1.1.2  christos 			return -1;
    306  1.1.1.2  christos 		}
    307      1.1    plunky 	}
    308      1.1    plunky #else
    309  1.1.1.2  christos 	{
    310  1.1.1.2  christos 		int flags;
    311  1.1.1.2  christos 		if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
    312  1.1.1.2  christos 			event_warn("fcntl(%d, F_GETFL)", fd);
    313  1.1.1.2  christos 			return -1;
    314  1.1.1.2  christos 		}
    315  1.1.1.2  christos 		if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
    316  1.1.1.2  christos 			event_warn("fcntl(%d, F_SETFL)", fd);
    317  1.1.1.2  christos 			return -1;
    318  1.1.1.2  christos 		}
    319  1.1.1.2  christos 	}
    320  1.1.1.2  christos #endif
    321  1.1.1.2  christos 	return 0;
    322  1.1.1.2  christos }
    323  1.1.1.2  christos 
    324  1.1.1.2  christos int
    325  1.1.1.2  christos evutil_make_listen_socket_reuseable(evutil_socket_t sock)
    326  1.1.1.2  christos {
    327  1.1.1.2  christos #ifndef WIN32
    328  1.1.1.2  christos 	int one = 1;
    329  1.1.1.2  christos 	/* REUSEADDR on Unix means, "don't hang on to this address after the
    330  1.1.1.2  christos 	 * listener is closed."  On Windows, though, it means "don't keep other
    331  1.1.1.2  christos 	 * processes from binding to this address while we're using it. */
    332  1.1.1.2  christos 	return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
    333  1.1.1.2  christos 	    (ev_socklen_t)sizeof(one));
    334  1.1.1.2  christos #else
    335  1.1.1.2  christos 	return 0;
    336  1.1.1.2  christos #endif
    337  1.1.1.2  christos }
    338  1.1.1.2  christos 
    339  1.1.1.2  christos int
    340  1.1.1.2  christos evutil_make_socket_closeonexec(evutil_socket_t fd)
    341  1.1.1.2  christos {
    342  1.1.1.2  christos #if !defined(WIN32) && defined(_EVENT_HAVE_SETFD)
    343  1.1.1.2  christos 	int flags;
    344  1.1.1.2  christos 	if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) {
    345  1.1.1.2  christos 		event_warn("fcntl(%d, F_GETFD)", fd);
    346      1.1    plunky 		return -1;
    347  1.1.1.2  christos 	}
    348  1.1.1.2  christos 	if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
    349  1.1.1.2  christos 		event_warn("fcntl(%d, F_SETFD)", fd);
    350  1.1.1.2  christos 		return -1;
    351  1.1.1.2  christos 	}
    352      1.1    plunky #endif
    353      1.1    plunky 	return 0;
    354      1.1    plunky }
    355      1.1    plunky 
    356  1.1.1.2  christos int
    357  1.1.1.2  christos evutil_closesocket(evutil_socket_t sock)
    358  1.1.1.2  christos {
    359  1.1.1.2  christos #ifndef WIN32
    360  1.1.1.2  christos 	return close(sock);
    361  1.1.1.2  christos #else
    362  1.1.1.2  christos 	return closesocket(sock);
    363  1.1.1.2  christos #endif
    364  1.1.1.2  christos }
    365  1.1.1.2  christos 
    366      1.1    plunky ev_int64_t
    367      1.1    plunky evutil_strtoll(const char *s, char **endptr, int base)
    368      1.1    plunky {
    369  1.1.1.2  christos #ifdef _EVENT_HAVE_STRTOLL
    370      1.1    plunky 	return (ev_int64_t)strtoll(s, endptr, base);
    371  1.1.1.2  christos #elif _EVENT_SIZEOF_LONG == 8
    372      1.1    plunky 	return (ev_int64_t)strtol(s, endptr, base);
    373      1.1    plunky #elif defined(WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
    374      1.1    plunky 	/* XXXX on old versions of MS APIs, we only support base
    375      1.1    plunky 	 * 10. */
    376      1.1    plunky 	ev_int64_t r;
    377      1.1    plunky 	if (base != 10)
    378      1.1    plunky 		return 0;
    379      1.1    plunky 	r = (ev_int64_t) _atoi64(s);
    380      1.1    plunky 	while (isspace(*s))
    381      1.1    plunky 		++s;
    382  1.1.1.2  christos 	if (*s == '-')
    383  1.1.1.2  christos 		++s;
    384      1.1    plunky 	while (isdigit(*s))
    385      1.1    plunky 		++s;
    386      1.1    plunky 	if (endptr)
    387      1.1    plunky 		*endptr = (char*) s;
    388      1.1    plunky 	return r;
    389      1.1    plunky #elif defined(WIN32)
    390      1.1    plunky 	return (ev_int64_t) _strtoi64(s, endptr, base);
    391  1.1.1.2  christos #elif defined(_EVENT_SIZEOF_LONG_LONG) && _EVENT_SIZEOF_LONG_LONG == 8
    392  1.1.1.2  christos 	long long r;
    393  1.1.1.2  christos 	int n;
    394  1.1.1.2  christos 	if (base != 10 && base != 16)
    395  1.1.1.2  christos 		return 0;
    396  1.1.1.2  christos 	if (base == 10) {
    397  1.1.1.2  christos 		n = sscanf(s, "%lld", &r);
    398  1.1.1.2  christos 	} else {
    399  1.1.1.2  christos 		unsigned long long ru=0;
    400  1.1.1.2  christos 		n = sscanf(s, "%llx", &ru);
    401  1.1.1.2  christos 		if (ru > EV_INT64_MAX)
    402  1.1.1.2  christos 			return 0;
    403  1.1.1.2  christos 		r = (long long) ru;
    404  1.1.1.2  christos 	}
    405  1.1.1.2  christos 	if (n != 1)
    406  1.1.1.2  christos 		return 0;
    407  1.1.1.2  christos 	while (EVUTIL_ISSPACE(*s))
    408  1.1.1.2  christos 		++s;
    409  1.1.1.2  christos 	if (*s == '-')
    410  1.1.1.2  christos 		++s;
    411  1.1.1.2  christos 	if (base == 10) {
    412  1.1.1.2  christos 		while (EVUTIL_ISDIGIT(*s))
    413  1.1.1.2  christos 			++s;
    414  1.1.1.2  christos 	} else {
    415  1.1.1.2  christos 		while (EVUTIL_ISXDIGIT(*s))
    416  1.1.1.2  christos 			++s;
    417  1.1.1.2  christos 	}
    418  1.1.1.2  christos 	if (endptr)
    419  1.1.1.2  christos 		*endptr = (char*) s;
    420  1.1.1.2  christos 	return r;
    421      1.1    plunky #else
    422      1.1    plunky #error "I don't know how to parse 64-bit integers."
    423      1.1    plunky #endif
    424      1.1    plunky }
    425      1.1    plunky 
    426      1.1    plunky #ifndef _EVENT_HAVE_GETTIMEOFDAY
    427  1.1.1.2  christos /* No gettimeofday; this muse be windows. */
    428      1.1    plunky int
    429      1.1    plunky evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
    430      1.1    plunky {
    431      1.1    plunky 	struct _timeb tb;
    432      1.1    plunky 
    433  1.1.1.2  christos 	if (tv == NULL)
    434      1.1    plunky 		return -1;
    435      1.1    plunky 
    436  1.1.1.2  christos 	/* XXXX
    437  1.1.1.2  christos 	 * _ftime is not the greatest interface here; GetSystemTimeAsFileTime
    438  1.1.1.2  christos 	 * would give us better resolution, whereas something cobbled together
    439  1.1.1.2  christos 	 * with GetTickCount could maybe give us monotonic behavior.
    440  1.1.1.2  christos 	 *
    441  1.1.1.2  christos 	 * Either way, I think this value might be skewed to ignore the
    442  1.1.1.2  christos 	 * timezone, and just return local time.  That's not so good.
    443  1.1.1.2  christos 	 */
    444      1.1    plunky 	_ftime(&tb);
    445      1.1    plunky 	tv->tv_sec = (long) tb.time;
    446      1.1    plunky 	tv->tv_usec = ((int) tb.millitm) * 1000;
    447      1.1    plunky 	return 0;
    448      1.1    plunky }
    449      1.1    plunky #endif
    450      1.1    plunky 
    451  1.1.1.2  christos #ifdef WIN32
    452  1.1.1.2  christos int
    453  1.1.1.2  christos evutil_socket_geterror(evutil_socket_t sock)
    454  1.1.1.2  christos {
    455  1.1.1.2  christos 	int optval, optvallen=sizeof(optval);
    456  1.1.1.2  christos 	int err = WSAGetLastError();
    457  1.1.1.2  christos 	if (err == WSAEWOULDBLOCK && sock >= 0) {
    458  1.1.1.2  christos 		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
    459  1.1.1.2  christos 					   &optvallen))
    460  1.1.1.2  christos 			return err;
    461  1.1.1.2  christos 		if (optval)
    462  1.1.1.2  christos 			return optval;
    463  1.1.1.2  christos 	}
    464  1.1.1.2  christos 	return err;
    465  1.1.1.2  christos }
    466  1.1.1.2  christos #endif
    467  1.1.1.2  christos 
    468  1.1.1.2  christos /* XXX we should use an enum here. */
    469  1.1.1.2  christos /* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
    470  1.1.1.2  christos int
    471  1.1.1.2  christos evutil_socket_connect(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen)
    472  1.1.1.2  christos {
    473  1.1.1.2  christos 	int made_fd = 0;
    474  1.1.1.2  christos 
    475  1.1.1.2  christos 	if (*fd_ptr < 0) {
    476  1.1.1.2  christos 		if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
    477  1.1.1.2  christos 			goto err;
    478  1.1.1.2  christos 		made_fd = 1;
    479  1.1.1.2  christos 		if (evutil_make_socket_nonblocking(*fd_ptr) < 0) {
    480  1.1.1.2  christos 			goto err;
    481  1.1.1.2  christos 		}
    482  1.1.1.2  christos 	}
    483  1.1.1.2  christos 
    484  1.1.1.2  christos 	if (connect(*fd_ptr, sa, socklen) < 0) {
    485  1.1.1.2  christos 		int e = evutil_socket_geterror(*fd_ptr);
    486  1.1.1.2  christos 		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
    487  1.1.1.2  christos 			return 0;
    488  1.1.1.2  christos 		if (EVUTIL_ERR_CONNECT_REFUSED(e))
    489  1.1.1.2  christos 			return 2;
    490  1.1.1.2  christos 		goto err;
    491  1.1.1.2  christos 	} else {
    492  1.1.1.2  christos 		return 1;
    493  1.1.1.2  christos 	}
    494  1.1.1.2  christos 
    495  1.1.1.2  christos err:
    496  1.1.1.2  christos 	if (made_fd) {
    497  1.1.1.2  christos 		evutil_closesocket(*fd_ptr);
    498  1.1.1.2  christos 		*fd_ptr = -1;
    499  1.1.1.2  christos 	}
    500  1.1.1.2  christos 	return -1;
    501  1.1.1.2  christos }
    502  1.1.1.2  christos 
    503  1.1.1.2  christos /* Check whether a socket on which we called connect() is done
    504  1.1.1.2  christos    connecting. Return 1 for connected, 0 for not yet, -1 for error.  In the
    505  1.1.1.2  christos    error case, set the current socket errno to the error that happened during
    506  1.1.1.2  christos    the connect operation. */
    507  1.1.1.2  christos int
    508  1.1.1.2  christos evutil_socket_finished_connecting(evutil_socket_t fd)
    509  1.1.1.2  christos {
    510  1.1.1.2  christos 	int e;
    511  1.1.1.2  christos 	ev_socklen_t elen = sizeof(e);
    512  1.1.1.2  christos 
    513  1.1.1.2  christos 	if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
    514  1.1.1.2  christos 		return -1;
    515  1.1.1.2  christos 
    516  1.1.1.2  christos 	if (e) {
    517  1.1.1.2  christos 		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
    518  1.1.1.2  christos 			return 0;
    519  1.1.1.2  christos 		EVUTIL_SET_SOCKET_ERROR(e);
    520  1.1.1.2  christos 		return -1;
    521  1.1.1.2  christos 	}
    522  1.1.1.2  christos 
    523  1.1.1.2  christos 	return 1;
    524  1.1.1.2  christos }
    525  1.1.1.2  christos 
    526  1.1.1.2  christos #if (EVUTIL_AI_PASSIVE|EVUTIL_AI_CANONNAME|EVUTIL_AI_NUMERICHOST| \
    527  1.1.1.2  christos      EVUTIL_AI_NUMERICSERV|EVUTIL_AI_V4MAPPED|EVUTIL_AI_ALL| \
    528  1.1.1.2  christos      EVUTIL_AI_ADDRCONFIG) != \
    529  1.1.1.2  christos     (EVUTIL_AI_PASSIVE^EVUTIL_AI_CANONNAME^EVUTIL_AI_NUMERICHOST^ \
    530  1.1.1.2  christos      EVUTIL_AI_NUMERICSERV^EVUTIL_AI_V4MAPPED^EVUTIL_AI_ALL^ \
    531  1.1.1.2  christos      EVUTIL_AI_ADDRCONFIG)
    532  1.1.1.2  christos #error "Some of our EVUTIL_AI_* flags seem to overlap with system AI_* flags"
    533  1.1.1.2  christos #endif
    534  1.1.1.2  christos 
    535  1.1.1.2  christos /* We sometimes need to know whether we have an ipv4 address and whether we
    536  1.1.1.2  christos    have an ipv6 address. If 'have_checked_interfaces', then we've already done
    537  1.1.1.2  christos    the test.  If 'had_ipv4_address', then it turns out we had an ipv4 address.
    538  1.1.1.2  christos    If 'had_ipv6_address', then it turns out we had an ipv6 address.   These are
    539  1.1.1.2  christos    set by evutil_check_interfaces. */
    540  1.1.1.2  christos static int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
    541  1.1.1.2  christos 
    542  1.1.1.2  christos /* Macro: True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8
    543  1.1.1.2  christos  */
    544  1.1.1.2  christos #define EVUTIL_V4ADDR_IS_LOCALHOST(addr) (((addr)>>24) == 127)
    545  1.1.1.2  christos 
    546  1.1.1.2  christos /* Macro: True iff the IPv4 address 'addr', in host order, is a class D
    547  1.1.1.2  christos  * (multiclass) address.
    548  1.1.1.2  christos  */
    549  1.1.1.2  christos #define EVUTIL_V4ADDR_IS_CLASSD(addr) ((((addr)>>24) & 0xf0) == 0xe0)
    550  1.1.1.2  christos 
    551  1.1.1.2  christos /* Test whether we have an ipv4 interface and an ipv6 interface.  Return 0 if
    552  1.1.1.2  christos  * the test seemed successful. */
    553  1.1.1.2  christos static int
    554  1.1.1.2  christos evutil_check_interfaces(int force_recheck)
    555  1.1.1.2  christos {
    556  1.1.1.2  christos 	const char ZEROES[] = "\x00\x00\x00\x00\x00\x00\x00\x00"
    557  1.1.1.2  christos 	    "\x00\x00\x00\x00\x00\x00\x00\x00";
    558  1.1.1.2  christos 	evutil_socket_t fd = -1;
    559  1.1.1.2  christos 	struct sockaddr_in sin, sin_out;
    560  1.1.1.2  christos 	struct sockaddr_in6 sin6, sin6_out;
    561  1.1.1.2  christos 	ev_socklen_t sin_out_len = sizeof(sin_out);
    562  1.1.1.2  christos 	ev_socklen_t sin6_out_len = sizeof(sin6_out);
    563  1.1.1.2  christos 	int r;
    564  1.1.1.2  christos 	char buf[128];
    565  1.1.1.2  christos 	if (have_checked_interfaces && !force_recheck)
    566  1.1.1.2  christos 		return 0;
    567  1.1.1.2  christos 
    568  1.1.1.2  christos 	/* To check whether we have an interface open for a given protocol, we
    569  1.1.1.2  christos 	 * try to make a UDP 'connection' to a remote host on the internet.
    570  1.1.1.2  christos 	 * We don't actually use it, so the address doesn't matter, but we
    571  1.1.1.2  christos 	 * want to pick one that keep us from using a host- or link-local
    572  1.1.1.2  christos 	 * interface. */
    573  1.1.1.2  christos 	memset(&sin, 0, sizeof(sin));
    574  1.1.1.2  christos 	sin.sin_family = AF_INET;
    575  1.1.1.2  christos 	sin.sin_port = htons(53);
    576  1.1.1.2  christos 	r = evutil_inet_pton(AF_INET, "18.244.0.188", &sin.sin_addr);
    577  1.1.1.2  christos 	EVUTIL_ASSERT(r);
    578  1.1.1.2  christos 
    579  1.1.1.2  christos 	memset(&sin6, 0, sizeof(sin6));
    580  1.1.1.2  christos 	sin6.sin6_family = AF_INET6;
    581  1.1.1.2  christos 	sin6.sin6_port = htons(53);
    582  1.1.1.2  christos 	r = evutil_inet_pton(AF_INET6, "2001:4860:b002::68", &sin6.sin6_addr);
    583  1.1.1.2  christos 	EVUTIL_ASSERT(r);
    584  1.1.1.2  christos 
    585  1.1.1.2  christos 	memset(&sin_out, 0, sizeof(sin_out));
    586  1.1.1.2  christos 	memset(&sin6_out, 0, sizeof(sin6_out));
    587  1.1.1.2  christos 
    588  1.1.1.2  christos 	/* XXX some errnos mean 'no address'; some mean 'not enough sockets'. */
    589  1.1.1.2  christos 	if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
    590  1.1.1.2  christos 	    connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
    591  1.1.1.2  christos 	    getsockname(fd, (struct sockaddr*)&sin_out, &sin_out_len) == 0) {
    592  1.1.1.2  christos 		/* We might have an IPv4 interface. */
    593  1.1.1.2  christos 		ev_uint32_t addr = ntohl(sin_out.sin_addr.s_addr);
    594  1.1.1.2  christos 		if (addr == 0 ||
    595  1.1.1.2  christos 		    EVUTIL_V4ADDR_IS_LOCALHOST(addr) ||
    596  1.1.1.2  christos 		    EVUTIL_V4ADDR_IS_CLASSD(addr)) {
    597  1.1.1.2  christos 			evutil_inet_ntop(AF_INET, &sin_out.sin_addr,
    598  1.1.1.2  christos 			    buf, sizeof(buf));
    599  1.1.1.2  christos 			/* This is a reserved, ipv4compat, ipv4map, loopback,
    600  1.1.1.2  christos 			 * link-local or unspecified address.  The host should
    601  1.1.1.2  christos 			 * never have given it to us; it could never connect
    602  1.1.1.2  christos 			 * to sin. */
    603  1.1.1.2  christos 			event_warnx("Got a strange local ipv4 address %s",buf);
    604  1.1.1.2  christos 		} else {
    605  1.1.1.2  christos 			event_debug(("Detected an IPv4 interface"));
    606  1.1.1.2  christos 			had_ipv4_address = 1;
    607  1.1.1.2  christos 		}
    608  1.1.1.2  christos 	}
    609  1.1.1.2  christos 	if (fd >= 0)
    610  1.1.1.2  christos 		evutil_closesocket(fd);
    611  1.1.1.2  christos 
    612  1.1.1.2  christos 	if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
    613  1.1.1.2  christos 	    connect(fd, (struct sockaddr*)&sin6, sizeof(sin6)) == 0 &&
    614  1.1.1.2  christos 	    getsockname(fd, (struct sockaddr*)&sin6_out, &sin6_out_len) == 0) {
    615  1.1.1.2  christos 		/* We might have an IPv6 interface. */
    616  1.1.1.2  christos 		const unsigned char *addr =
    617  1.1.1.2  christos 		    (unsigned char*)sin6_out.sin6_addr.s6_addr;
    618  1.1.1.2  christos 		if (!memcmp(addr, ZEROES, 8) ||
    619  1.1.1.2  christos 		    (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80)) {
    620  1.1.1.2  christos 			/* This is a reserved, ipv4compat, ipv4map, loopback,
    621  1.1.1.2  christos 			 * link-local or unspecified address.  The host should
    622  1.1.1.2  christos 			 * never have given it to us; it could never connect
    623  1.1.1.2  christos 			 * to sin6. */
    624  1.1.1.2  christos 			evutil_inet_ntop(AF_INET6, &sin6_out.sin6_addr,
    625  1.1.1.2  christos 			    buf, sizeof(buf));
    626  1.1.1.2  christos 			event_warnx("Got a strange local ipv6 address %s",buf);
    627  1.1.1.2  christos 		} else {
    628  1.1.1.2  christos 			event_debug(("Detected an IPv4 interface"));
    629  1.1.1.2  christos 			had_ipv6_address = 1;
    630  1.1.1.2  christos 		}
    631  1.1.1.2  christos 	}
    632  1.1.1.2  christos 
    633  1.1.1.2  christos 	if (fd >= 0)
    634  1.1.1.2  christos 		evutil_closesocket(fd);
    635  1.1.1.2  christos 
    636  1.1.1.2  christos 	return 0;
    637  1.1.1.2  christos }
    638  1.1.1.2  christos 
    639  1.1.1.2  christos /* Internal addrinfo flag.  This one is set when we allocate the addrinfo from
    640  1.1.1.2  christos  * inside libevent.  Otherwise, the built-in getaddrinfo() function allocated
    641  1.1.1.2  christos  * it, and we should trust what they said.
    642  1.1.1.2  christos  **/
    643  1.1.1.2  christos #define EVUTIL_AI_LIBEVENT_ALLOCATED 0x80000000
    644  1.1.1.2  christos 
    645  1.1.1.2  christos /* Helper: construct a new addrinfo containing the socket address in
    646  1.1.1.2  christos  * 'sa', which must be a sockaddr_in or a sockaddr_in6.  Take the
    647  1.1.1.2  christos  * socktype and protocol info from hints.  If they weren't set, then
    648  1.1.1.2  christos  * allocate both a TCP and a UDP addrinfo.
    649  1.1.1.2  christos  */
    650  1.1.1.2  christos struct evutil_addrinfo *
    651  1.1.1.2  christos evutil_new_addrinfo(struct sockaddr *sa, ev_socklen_t socklen,
    652  1.1.1.2  christos     const struct evutil_addrinfo *hints)
    653  1.1.1.2  christos {
    654  1.1.1.2  christos 	struct evutil_addrinfo *res;
    655  1.1.1.2  christos 	EVUTIL_ASSERT(hints);
    656  1.1.1.2  christos 
    657  1.1.1.2  christos 	if (hints->ai_socktype == 0 && hints->ai_protocol == 0) {
    658  1.1.1.2  christos 		/* Indecisive user! Give them a UDP and a TCP. */
    659  1.1.1.2  christos 		struct evutil_addrinfo *r1, *r2;
    660  1.1.1.2  christos 		struct evutil_addrinfo tmp;
    661  1.1.1.2  christos 		memcpy(&tmp, hints, sizeof(tmp));
    662  1.1.1.2  christos 		tmp.ai_socktype = SOCK_STREAM; tmp.ai_protocol = IPPROTO_TCP;
    663  1.1.1.2  christos 		r1 = evutil_new_addrinfo(sa, socklen, &tmp);
    664  1.1.1.2  christos 		if (!r1)
    665  1.1.1.2  christos 			return NULL;
    666  1.1.1.2  christos 		tmp.ai_socktype = SOCK_DGRAM; tmp.ai_protocol = IPPROTO_UDP;
    667  1.1.1.2  christos 		r2 = evutil_new_addrinfo(sa, socklen, &tmp);
    668  1.1.1.2  christos 		if (!r2) {
    669  1.1.1.2  christos 			evutil_freeaddrinfo(r1);
    670  1.1.1.2  christos 			return NULL;
    671  1.1.1.2  christos 		}
    672  1.1.1.2  christos 		r1->ai_next = r2;
    673  1.1.1.2  christos 		return r1;
    674  1.1.1.2  christos 	}
    675  1.1.1.2  christos 
    676  1.1.1.2  christos 	/* We're going to allocate extra space to hold the sockaddr. */
    677  1.1.1.2  christos 	res = mm_calloc(1,sizeof(struct evutil_addrinfo)+socklen);
    678  1.1.1.2  christos 	if (!res)
    679  1.1.1.2  christos 		return NULL;
    680  1.1.1.2  christos 	res->ai_addr = (struct sockaddr*)
    681  1.1.1.2  christos 	    (((char*)res) + sizeof(struct evutil_addrinfo));
    682  1.1.1.2  christos 	memcpy(res->ai_addr, sa, socklen);
    683  1.1.1.2  christos 	res->ai_addrlen = socklen;
    684  1.1.1.2  christos 	res->ai_family = sa->sa_family; /* Same or not? XXX */
    685  1.1.1.2  christos 	res->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
    686  1.1.1.2  christos 	res->ai_socktype = hints->ai_socktype;
    687  1.1.1.2  christos 	res->ai_protocol = hints->ai_protocol;
    688  1.1.1.2  christos 
    689  1.1.1.2  christos 	return res;
    690  1.1.1.2  christos }
    691  1.1.1.2  christos 
    692  1.1.1.2  christos /* Append the addrinfo 'append' to the end of 'first', and return the start of
    693  1.1.1.2  christos  * the list.  Either element can be NULL, in which case we return the element
    694  1.1.1.2  christos  * that is not NULL. */
    695  1.1.1.2  christos struct evutil_addrinfo *
    696  1.1.1.2  christos evutil_addrinfo_append(struct evutil_addrinfo *first,
    697  1.1.1.2  christos     struct evutil_addrinfo *append)
    698  1.1.1.2  christos {
    699  1.1.1.2  christos 	struct evutil_addrinfo *ai = first;
    700  1.1.1.2  christos 	if (!ai)
    701  1.1.1.2  christos 		return append;
    702  1.1.1.2  christos 	while (ai->ai_next)
    703  1.1.1.2  christos 		ai = ai->ai_next;
    704  1.1.1.2  christos 	ai->ai_next = append;
    705  1.1.1.2  christos 
    706  1.1.1.2  christos 	return first;
    707  1.1.1.2  christos }
    708  1.1.1.2  christos 
    709  1.1.1.2  christos static int
    710  1.1.1.2  christos parse_numeric_servname(const char *servname)
    711  1.1.1.2  christos {
    712  1.1.1.2  christos 	int n;
    713  1.1.1.2  christos 	char *endptr=NULL;
    714  1.1.1.2  christos 	n = (int) strtol(servname, &endptr, 10);
    715  1.1.1.2  christos 	if (n>=0 && n <= 65535 && servname[0] && endptr && !endptr[0])
    716  1.1.1.2  christos 		return n;
    717  1.1.1.2  christos 	else
    718  1.1.1.2  christos 		return -1;
    719  1.1.1.2  christos }
    720  1.1.1.2  christos 
    721  1.1.1.2  christos /** Parse a service name in 'servname', which can be a decimal port.
    722  1.1.1.2  christos  * Return the port number, or -1 on error.
    723  1.1.1.2  christos  */
    724  1.1.1.2  christos static int
    725  1.1.1.2  christos evutil_parse_servname(const char *servname, const char *protocol,
    726  1.1.1.2  christos     const struct evutil_addrinfo *hints)
    727  1.1.1.2  christos {
    728  1.1.1.2  christos 	int n = parse_numeric_servname(servname);
    729  1.1.1.2  christos 	if (n>=0)
    730  1.1.1.2  christos 		return n;
    731  1.1.1.2  christos #if defined(_EVENT_HAVE_GETSERVBYNAME) || defined(WIN32)
    732  1.1.1.2  christos 	if (!(hints->ai_flags & EVUTIL_AI_NUMERICSERV)) {
    733  1.1.1.2  christos 		struct servent *ent = getservbyname(servname, protocol);
    734  1.1.1.2  christos 		if (ent) {
    735  1.1.1.2  christos 			return ntohs(ent->s_port);
    736  1.1.1.2  christos 		}
    737  1.1.1.2  christos 	}
    738  1.1.1.2  christos #endif
    739  1.1.1.2  christos 	return -1;
    740  1.1.1.2  christos }
    741  1.1.1.2  christos 
    742  1.1.1.2  christos /* Return a string corresponding to a protocol number that we can pass to
    743  1.1.1.2  christos  * getservyname.  */
    744  1.1.1.2  christos static const char *
    745  1.1.1.2  christos evutil_unparse_protoname(int proto)
    746  1.1.1.2  christos {
    747  1.1.1.2  christos 	switch (proto) {
    748  1.1.1.2  christos 	case 0:
    749  1.1.1.2  christos 		return NULL;
    750  1.1.1.2  christos 	case IPPROTO_TCP:
    751  1.1.1.2  christos 		return "tcp";
    752  1.1.1.2  christos 	case IPPROTO_UDP:
    753  1.1.1.2  christos 		return "udp";
    754  1.1.1.2  christos #ifdef IPPROTO_SCTP
    755  1.1.1.2  christos 	case IPPROTO_SCTP:
    756  1.1.1.2  christos 		return "sctp";
    757  1.1.1.2  christos #endif
    758  1.1.1.2  christos 	default:
    759  1.1.1.2  christos #ifdef _EVENT_HAVE_GETPROTOBYNUMBER
    760  1.1.1.2  christos 		{
    761  1.1.1.2  christos 			struct protoent *ent = getprotobynumber(proto);
    762  1.1.1.2  christos 			if (ent)
    763  1.1.1.2  christos 				return ent->p_name;
    764  1.1.1.2  christos 		}
    765  1.1.1.2  christos #endif
    766  1.1.1.2  christos 		return NULL;
    767  1.1.1.2  christos 	}
    768  1.1.1.2  christos }
    769  1.1.1.2  christos 
    770  1.1.1.2  christos static void
    771  1.1.1.2  christos evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints)
    772  1.1.1.2  christos {
    773  1.1.1.2  christos 	/* If we can guess the protocol from the socktype, do so. */
    774  1.1.1.2  christos 	if (!hints->ai_protocol && hints->ai_socktype) {
    775  1.1.1.2  christos 		if (hints->ai_socktype == SOCK_DGRAM)
    776  1.1.1.2  christos 			hints->ai_protocol = IPPROTO_UDP;
    777  1.1.1.2  christos 		else if (hints->ai_socktype == SOCK_STREAM)
    778  1.1.1.2  christos 			hints->ai_protocol = IPPROTO_TCP;
    779  1.1.1.2  christos 	}
    780  1.1.1.2  christos 
    781  1.1.1.2  christos 	/* Set the socktype if it isn't set. */
    782  1.1.1.2  christos 	if (!hints->ai_socktype && hints->ai_protocol) {
    783  1.1.1.2  christos 		if (hints->ai_protocol == IPPROTO_UDP)
    784  1.1.1.2  christos 			hints->ai_socktype = SOCK_DGRAM;
    785  1.1.1.2  christos 		else if (hints->ai_protocol == IPPROTO_TCP)
    786  1.1.1.2  christos 			hints->ai_socktype = SOCK_STREAM;
    787  1.1.1.2  christos #ifdef IPPROTO_SCTP
    788  1.1.1.2  christos 		else if (hints->ai_protocol == IPPROTO_SCTP)
    789  1.1.1.2  christos 			hints->ai_socktype = SOCK_STREAM;
    790  1.1.1.2  christos #endif
    791  1.1.1.2  christos 	}
    792  1.1.1.2  christos }
    793  1.1.1.2  christos 
    794  1.1.1.2  christos #if AF_UNSPEC != PF_UNSPEC
    795  1.1.1.2  christos #error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC"
    796  1.1.1.2  christos #endif
    797  1.1.1.2  christos 
    798  1.1.1.2  christos /** Implements the part of looking up hosts by name that's common to both
    799  1.1.1.2  christos  * the blocking and nonblocking resolver:
    800  1.1.1.2  christos  *   - Adjust 'hints' to have a reasonable socktype and protocol.
    801  1.1.1.2  christos  *   - Look up the port based on 'servname', and store it in *portnum,
    802  1.1.1.2  christos  *   - Handle the nodename==NULL case
    803  1.1.1.2  christos  *   - Handle some invalid arguments cases.
    804  1.1.1.2  christos  *   - Handle the cases where nodename is an IPv4 or IPv6 address.
    805  1.1.1.2  christos  *
    806  1.1.1.2  christos  * If we need the resolver to look up the hostname, we return
    807  1.1.1.2  christos  * EVUTIL_EAI_NEED_RESOLVE.  Otherwise, we can completely implement
    808  1.1.1.2  christos  * getaddrinfo: we return 0 or an appropriate EVUTIL_EAI_* error, and
    809  1.1.1.2  christos  * set *res as getaddrinfo would.
    810  1.1.1.2  christos  */
    811  1.1.1.2  christos int
    812  1.1.1.2  christos evutil_getaddrinfo_common(const char *nodename, const char *servname,
    813  1.1.1.2  christos     struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
    814  1.1.1.2  christos {
    815  1.1.1.2  christos 	int port = 0;
    816  1.1.1.2  christos 	const char *pname;
    817  1.1.1.2  christos 
    818  1.1.1.2  christos 	if (nodename == NULL && servname == NULL)
    819  1.1.1.2  christos 		return EVUTIL_EAI_NONAME;
    820  1.1.1.2  christos 
    821  1.1.1.2  christos 	/* We only understand 3 families */
    822  1.1.1.2  christos 	if (hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET &&
    823  1.1.1.2  christos 	    hints->ai_family != PF_INET6)
    824  1.1.1.2  christos 		return EVUTIL_EAI_FAMILY;
    825  1.1.1.2  christos 
    826  1.1.1.2  christos 	evutil_getaddrinfo_infer_protocols(hints);
    827  1.1.1.2  christos 
    828  1.1.1.2  christos 	/* Look up the port number and protocol, if possible. */
    829  1.1.1.2  christos 	pname = evutil_unparse_protoname(hints->ai_protocol);
    830  1.1.1.2  christos 	if (servname) {
    831  1.1.1.2  christos 		/* XXXX We could look at the protocol we got back from
    832  1.1.1.2  christos 		 * getservbyname, but it doesn't seem too useful. */
    833  1.1.1.2  christos 		port = evutil_parse_servname(servname, pname, hints);
    834  1.1.1.2  christos 		if (port < 0) {
    835  1.1.1.2  christos 			return EVUTIL_EAI_NONAME;
    836  1.1.1.2  christos 		}
    837  1.1.1.2  christos 	}
    838  1.1.1.2  christos 
    839  1.1.1.2  christos 	/* If we have no node name, then we're supposed to bind to 'any' and
    840  1.1.1.2  christos 	 * connect to localhost. */
    841  1.1.1.2  christos 	if (nodename == NULL) {
    842  1.1.1.2  christos 		struct evutil_addrinfo *res4=NULL, *res6=NULL;
    843  1.1.1.2  christos 		if (hints->ai_family != PF_INET) { /* INET6 or UNSPEC. */
    844  1.1.1.2  christos 			struct sockaddr_in6 sin6;
    845  1.1.1.2  christos 			memset(&sin6, 0, sizeof(sin6));
    846  1.1.1.2  christos 			sin6.sin6_family = AF_INET6;
    847  1.1.1.2  christos 			sin6.sin6_port = htons(port);
    848  1.1.1.2  christos 			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
    849  1.1.1.2  christos 				/* Bind to :: */
    850  1.1.1.2  christos 			} else {
    851  1.1.1.2  christos 				/* connect to ::1 */
    852  1.1.1.2  christos 				sin6.sin6_addr.s6_addr[15] = 1;
    853  1.1.1.2  christos 			}
    854  1.1.1.2  christos 			res6 = evutil_new_addrinfo((struct sockaddr*)&sin6,
    855  1.1.1.2  christos 			    sizeof(sin6), hints);
    856  1.1.1.2  christos 			if (!res6)
    857  1.1.1.2  christos 				return EVUTIL_EAI_MEMORY;
    858  1.1.1.2  christos 		}
    859  1.1.1.2  christos 
    860  1.1.1.2  christos 		if (hints->ai_family != PF_INET6) { /* INET or UNSPEC */
    861  1.1.1.2  christos 			struct sockaddr_in sin;
    862  1.1.1.2  christos 			memset(&sin, 0, sizeof(sin));
    863  1.1.1.2  christos 			sin.sin_family = AF_INET;
    864  1.1.1.2  christos 			sin.sin_port = htons(port);
    865  1.1.1.2  christos 			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
    866  1.1.1.2  christos 				/* Bind to 0.0.0.0 */
    867  1.1.1.2  christos 			} else {
    868  1.1.1.2  christos 				/* connect to 127.0.0.1 */
    869  1.1.1.2  christos 				sin.sin_addr.s_addr = htonl(0x7f000001);
    870  1.1.1.2  christos 			}
    871  1.1.1.2  christos 			res4 = evutil_new_addrinfo((struct sockaddr*)&sin,
    872  1.1.1.2  christos 			    sizeof(sin), hints);
    873  1.1.1.2  christos 			if (!res4) {
    874  1.1.1.2  christos 				if (res6)
    875  1.1.1.2  christos 					evutil_freeaddrinfo(res6);
    876  1.1.1.2  christos 				return EVUTIL_EAI_MEMORY;
    877  1.1.1.2  christos 			}
    878  1.1.1.2  christos 		}
    879  1.1.1.2  christos 		*res = evutil_addrinfo_append(res4, res6);
    880  1.1.1.2  christos 		return 0;
    881  1.1.1.2  christos 	}
    882  1.1.1.2  christos 
    883  1.1.1.2  christos 	/* If we can, we should try to parse the hostname without resolving
    884  1.1.1.2  christos 	 * it. */
    885  1.1.1.2  christos 	/* Try ipv6. */
    886  1.1.1.2  christos 	if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
    887  1.1.1.2  christos 		struct sockaddr_in6 sin6;
    888  1.1.1.2  christos 		memset(&sin6, 0, sizeof(sin6));
    889  1.1.1.2  christos 		if (1==evutil_inet_pton(AF_INET6, nodename, &sin6.sin6_addr)) {
    890  1.1.1.2  christos 			/* Got an ipv6 address. */
    891  1.1.1.2  christos 			sin6.sin6_family = AF_INET6;
    892  1.1.1.2  christos 			sin6.sin6_port = htons(port);
    893  1.1.1.2  christos 			*res = evutil_new_addrinfo((struct sockaddr*)&sin6,
    894  1.1.1.2  christos 			    sizeof(sin6), hints);
    895  1.1.1.2  christos 			if (!*res)
    896  1.1.1.2  christos 				return EVUTIL_EAI_MEMORY;
    897  1.1.1.2  christos 			return 0;
    898  1.1.1.2  christos 		}
    899  1.1.1.2  christos 	}
    900  1.1.1.2  christos 
    901  1.1.1.2  christos 	/* Try ipv4. */
    902  1.1.1.2  christos 	if (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC) {
    903  1.1.1.2  christos 		struct sockaddr_in sin;
    904  1.1.1.2  christos 		memset(&sin, 0, sizeof(sin));
    905  1.1.1.2  christos 		if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
    906  1.1.1.2  christos 			/* Got an ipv6 address. */
    907  1.1.1.2  christos 			sin.sin_family = AF_INET;
    908  1.1.1.2  christos 			sin.sin_port = htons(port);
    909  1.1.1.2  christos 			*res = evutil_new_addrinfo((struct sockaddr*)&sin,
    910  1.1.1.2  christos 			    sizeof(sin), hints);
    911  1.1.1.2  christos 			if (!*res)
    912  1.1.1.2  christos 				return EVUTIL_EAI_MEMORY;
    913  1.1.1.2  christos 			return 0;
    914  1.1.1.2  christos 		}
    915  1.1.1.2  christos 	}
    916  1.1.1.2  christos 
    917  1.1.1.2  christos 
    918  1.1.1.2  christos 	/* If we have reached this point, we definitely need to do a DNS
    919  1.1.1.2  christos 	 * lookup. */
    920  1.1.1.2  christos 	if ((hints->ai_flags & EVUTIL_AI_NUMERICHOST)) {
    921  1.1.1.2  christos 		/* If we're not allowed to do one, then say so. */
    922  1.1.1.2  christos 		return EVUTIL_EAI_NONAME;
    923  1.1.1.2  christos 	}
    924  1.1.1.2  christos 	*portnum = port;
    925  1.1.1.2  christos 	return EVUTIL_EAI_NEED_RESOLVE;
    926  1.1.1.2  christos }
    927  1.1.1.2  christos 
    928  1.1.1.2  christos #ifdef _EVENT_HAVE_GETADDRINFO
    929  1.1.1.2  christos #define USE_NATIVE_GETADDRINFO
    930  1.1.1.2  christos #endif
    931  1.1.1.2  christos 
    932  1.1.1.2  christos #ifdef USE_NATIVE_GETADDRINFO
    933  1.1.1.2  christos /* A mask of all the flags that we declare, so we can clear them before calling
    934  1.1.1.2  christos  * the native getaddrinfo */
    935  1.1.1.2  christos static const unsigned int ALL_NONNATIVE_AI_FLAGS =
    936  1.1.1.2  christos #ifndef AI_PASSIVE
    937  1.1.1.2  christos     EVUTIL_AI_PASSIVE |
    938  1.1.1.2  christos #endif
    939  1.1.1.2  christos #ifndef AI_CANONNAME
    940  1.1.1.2  christos     EVUTIL_AI_CANONNAME |
    941  1.1.1.2  christos #endif
    942  1.1.1.2  christos #ifndef AI_NUMERICHOST
    943  1.1.1.2  christos     EVUTIL_AI_NUMERICHOST |
    944  1.1.1.2  christos #endif
    945  1.1.1.2  christos #ifndef AI_NUMERICSERV
    946  1.1.1.2  christos     EVUTIL_AI_NUMERICSERV |
    947  1.1.1.2  christos #endif
    948  1.1.1.2  christos #ifndef AI_ADDRCONFIG
    949  1.1.1.2  christos     EVUTIL_AI_ADDRCONFIG |
    950  1.1.1.2  christos #endif
    951  1.1.1.2  christos #ifndef AI_ALL
    952  1.1.1.2  christos     EVUTIL_AI_ALL |
    953  1.1.1.2  christos #endif
    954  1.1.1.2  christos #ifndef AI_V4MAPPED
    955  1.1.1.2  christos     EVUTIL_AI_V4MAPPED |
    956  1.1.1.2  christos #endif
    957  1.1.1.2  christos     EVUTIL_AI_LIBEVENT_ALLOCATED;
    958  1.1.1.2  christos 
    959  1.1.1.2  christos static const unsigned int ALL_NATIVE_AI_FLAGS =
    960  1.1.1.2  christos #ifdef AI_PASSIVE
    961  1.1.1.2  christos     AI_PASSIVE |
    962  1.1.1.2  christos #endif
    963  1.1.1.2  christos #ifdef AI_CANONNAME
    964  1.1.1.2  christos     AI_CANONNAME |
    965  1.1.1.2  christos #endif
    966  1.1.1.2  christos #ifdef AI_NUMERICHOST
    967  1.1.1.2  christos     AI_NUMERICHOST |
    968  1.1.1.2  christos #endif
    969  1.1.1.2  christos #ifdef AI_NUMERICSERV
    970  1.1.1.2  christos     AI_NUMERICSERV |
    971  1.1.1.2  christos #endif
    972  1.1.1.2  christos #ifdef AI_ADDRCONFIG
    973  1.1.1.2  christos     AI_ADDRCONFIG |
    974  1.1.1.2  christos #endif
    975  1.1.1.2  christos #ifdef AI_ALL
    976  1.1.1.2  christos     AI_ALL |
    977  1.1.1.2  christos #endif
    978  1.1.1.2  christos #ifdef AI_V4MAPPED
    979  1.1.1.2  christos     AI_V4MAPPED |
    980  1.1.1.2  christos #endif
    981  1.1.1.2  christos     0;
    982  1.1.1.2  christos #endif
    983  1.1.1.2  christos 
    984  1.1.1.2  christos #ifndef USE_NATIVE_GETADDRINFO
    985  1.1.1.2  christos /* Helper for systems with no getaddrinfo(): make one or more addrinfos out of
    986  1.1.1.2  christos  * a struct hostent.
    987  1.1.1.2  christos  */
    988  1.1.1.2  christos static struct evutil_addrinfo *
    989  1.1.1.2  christos addrinfo_from_hostent(const struct hostent *ent,
    990  1.1.1.2  christos     int port, const struct evutil_addrinfo *hints)
    991  1.1.1.2  christos {
    992  1.1.1.2  christos 	int i;
    993  1.1.1.2  christos 	struct sockaddr_in sin;
    994  1.1.1.2  christos 	struct sockaddr_in6 sin6;
    995  1.1.1.2  christos 	struct sockaddr *sa;
    996  1.1.1.2  christos 	int socklen;
    997  1.1.1.2  christos 	struct evutil_addrinfo *res=NULL, *ai;
    998  1.1.1.2  christos 	void *addrp;
    999  1.1.1.2  christos 
   1000  1.1.1.2  christos 	if (ent->h_addrtype == PF_INET) {
   1001  1.1.1.2  christos 		memset(&sin, 0, sizeof(sin));
   1002  1.1.1.2  christos 		sin.sin_family = AF_INET;
   1003  1.1.1.2  christos 		sin.sin_port = htons(port);
   1004  1.1.1.2  christos 		sa = (struct sockaddr *)&sin;
   1005  1.1.1.2  christos 		socklen = sizeof(struct sockaddr_in);
   1006  1.1.1.2  christos 		addrp = &sin.sin_addr;
   1007  1.1.1.2  christos 		if (ent->h_length != sizeof(sin.sin_addr)) {
   1008  1.1.1.2  christos 			event_warnx("Weird h_length from gethostbyname");
   1009  1.1.1.2  christos 			return NULL;
   1010  1.1.1.2  christos 		}
   1011  1.1.1.2  christos 	} else if (ent->h_addrtype == PF_INET6) {
   1012  1.1.1.2  christos 		memset(&sin6, 0, sizeof(sin6));
   1013  1.1.1.2  christos 		sin6.sin6_family = AF_INET6;
   1014  1.1.1.2  christos 		sin6.sin6_port = htons(port);
   1015  1.1.1.2  christos 		sa = (struct sockaddr *)&sin6;
   1016  1.1.1.2  christos 		socklen = sizeof(struct sockaddr_in);
   1017  1.1.1.2  christos 		addrp = &sin6.sin6_addr;
   1018  1.1.1.2  christos 		if (ent->h_length != sizeof(sin6.sin6_addr)) {
   1019  1.1.1.2  christos 			event_warnx("Weird h_length from gethostbyname");
   1020  1.1.1.2  christos 			return NULL;
   1021  1.1.1.2  christos 		}
   1022  1.1.1.2  christos 	} else
   1023  1.1.1.2  christos 		return NULL;
   1024  1.1.1.2  christos 
   1025  1.1.1.2  christos 	for (i = 0; ent->h_addr_list[i]; ++i) {
   1026  1.1.1.2  christos 		memcpy(addrp, ent->h_addr_list[i], ent->h_length);
   1027  1.1.1.2  christos 		ai = evutil_new_addrinfo(sa, socklen, hints);
   1028  1.1.1.2  christos 		if (!ai) {
   1029  1.1.1.2  christos 			evutil_freeaddrinfo(res);
   1030  1.1.1.2  christos 			return NULL;
   1031  1.1.1.2  christos 		}
   1032  1.1.1.2  christos 		res = evutil_addrinfo_append(res, ai);
   1033  1.1.1.2  christos 	}
   1034  1.1.1.2  christos 
   1035  1.1.1.2  christos 	if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) {
   1036  1.1.1.2  christos 		res->ai_canonname = mm_strdup(ent->h_name);
   1037  1.1.1.2  christos 		if (res->ai_canonname == NULL) {
   1038  1.1.1.2  christos 			evutil_freeaddrinfo(res);
   1039  1.1.1.2  christos 			return NULL;
   1040  1.1.1.2  christos 		}
   1041  1.1.1.2  christos 	}
   1042  1.1.1.2  christos 
   1043  1.1.1.2  christos 	return res;
   1044  1.1.1.2  christos }
   1045  1.1.1.2  christos #endif
   1046  1.1.1.2  christos 
   1047  1.1.1.2  christos /* If the EVUTIL_AI_ADDRCONFIG flag is set on hints->ai_flags, and
   1048  1.1.1.2  christos  * hints->ai_family is PF_UNSPEC, then revise the value of hints->ai_family so
   1049  1.1.1.2  christos  * that we'll only get addresses we could maybe connect to.
   1050  1.1.1.2  christos  */
   1051  1.1.1.2  christos void
   1052  1.1.1.2  christos evutil_adjust_hints_for_addrconfig(struct evutil_addrinfo *hints)
   1053  1.1.1.2  christos {
   1054  1.1.1.2  christos 	if (!(hints->ai_flags & EVUTIL_AI_ADDRCONFIG))
   1055  1.1.1.2  christos 		return;
   1056  1.1.1.2  christos 	if (hints->ai_family != PF_UNSPEC)
   1057  1.1.1.2  christos 		return;
   1058  1.1.1.2  christos 	if (!have_checked_interfaces)
   1059  1.1.1.2  christos 		evutil_check_interfaces(0);
   1060  1.1.1.2  christos 	if (had_ipv4_address && !had_ipv6_address) {
   1061  1.1.1.2  christos 		hints->ai_family = PF_INET;
   1062  1.1.1.2  christos 	} else if (!had_ipv4_address && had_ipv6_address) {
   1063  1.1.1.2  christos 		hints->ai_family = PF_INET6;
   1064  1.1.1.2  christos 	}
   1065  1.1.1.2  christos }
   1066  1.1.1.2  christos 
   1067  1.1.1.2  christos #ifdef USE_NATIVE_GETADDRINFO
   1068  1.1.1.2  christos static int need_numeric_port_hack_=0;
   1069  1.1.1.2  christos static int need_socktype_protocol_hack_=0;
   1070  1.1.1.2  christos static int tested_for_getaddrinfo_hacks=0;
   1071  1.1.1.2  christos 
   1072  1.1.1.2  christos /* Some older BSDs (like OpenBSD up to 4.6) used to believe that
   1073  1.1.1.2  christos    giving a numeric port without giving an ai_socktype was verboten.
   1074  1.1.1.2  christos    We test for this so we can apply an appropriate workaround.  If it
   1075  1.1.1.2  christos    turns out that the bug is present, then:
   1076  1.1.1.2  christos 
   1077  1.1.1.2  christos     - If nodename==NULL and servname is numeric, we build an answer
   1078  1.1.1.2  christos       ourselves using evutil_getaddrinfo_common().
   1079  1.1.1.2  christos 
   1080  1.1.1.2  christos     - If nodename!=NULL and servname is numeric, then we set
   1081  1.1.1.2  christos       servname=NULL when calling getaddrinfo, and post-process the
   1082  1.1.1.2  christos       result to set the ports on it.
   1083  1.1.1.2  christos 
   1084  1.1.1.2  christos    We test for this bug at runtime, since otherwise we can't have the
   1085  1.1.1.2  christos    same binary run on multiple BSD versions.
   1086  1.1.1.2  christos 
   1087  1.1.1.2  christos    - Some versions of Solaris believe that it's nice to leave to protocol
   1088  1.1.1.2  christos      field set to 0.  We test for this so we can apply an appropriate
   1089  1.1.1.2  christos      workaround.
   1090  1.1.1.2  christos */
   1091  1.1.1.2  christos static void
   1092  1.1.1.2  christos test_for_getaddrinfo_hacks(void)
   1093  1.1.1.2  christos {
   1094  1.1.1.2  christos 	int r, r2;
   1095  1.1.1.2  christos 	struct evutil_addrinfo *ai=NULL, *ai2=NULL;
   1096  1.1.1.2  christos 	struct evutil_addrinfo hints;
   1097  1.1.1.2  christos 
   1098  1.1.1.2  christos 	memset(&hints,0,sizeof(hints));
   1099  1.1.1.2  christos 	hints.ai_family = PF_UNSPEC;
   1100  1.1.1.2  christos 	hints.ai_flags =
   1101  1.1.1.2  christos #ifdef AI_NUMERICHOST
   1102  1.1.1.2  christos 	    AI_NUMERICHOST |
   1103  1.1.1.2  christos #endif
   1104  1.1.1.2  christos #ifdef AI_NUMERICSERV
   1105  1.1.1.2  christos 	    AI_NUMERICSERV |
   1106  1.1.1.2  christos #endif
   1107  1.1.1.2  christos 	    0;
   1108  1.1.1.2  christos 	r = getaddrinfo("1.2.3.4", "80", &hints, &ai);
   1109  1.1.1.2  christos 	hints.ai_socktype = SOCK_STREAM;
   1110  1.1.1.2  christos 	r2 = getaddrinfo("1.2.3.4", "80", &hints, &ai2);
   1111  1.1.1.2  christos 	if (r2 == 0 && r != 0) {
   1112  1.1.1.2  christos 		need_numeric_port_hack_=1;
   1113  1.1.1.2  christos 	}
   1114  1.1.1.2  christos 	if (ai2 && ai2->ai_protocol == 0) {
   1115  1.1.1.2  christos 		need_socktype_protocol_hack_=1;
   1116  1.1.1.2  christos 	}
   1117  1.1.1.2  christos 
   1118  1.1.1.2  christos 	if (ai)
   1119  1.1.1.2  christos 		freeaddrinfo(ai);
   1120  1.1.1.2  christos 	if (ai2)
   1121  1.1.1.2  christos 		freeaddrinfo(ai2);
   1122  1.1.1.2  christos 	tested_for_getaddrinfo_hacks=1;
   1123  1.1.1.2  christos }
   1124  1.1.1.2  christos 
   1125  1.1.1.2  christos static inline int
   1126  1.1.1.2  christos need_numeric_port_hack(void)
   1127  1.1.1.2  christos {
   1128  1.1.1.2  christos 	if (!tested_for_getaddrinfo_hacks)
   1129  1.1.1.2  christos 		test_for_getaddrinfo_hacks();
   1130  1.1.1.2  christos 	return need_numeric_port_hack_;
   1131  1.1.1.2  christos }
   1132  1.1.1.2  christos 
   1133  1.1.1.2  christos static inline int
   1134  1.1.1.2  christos need_socktype_protocol_hack(void)
   1135  1.1.1.2  christos {
   1136  1.1.1.2  christos 	if (!tested_for_getaddrinfo_hacks)
   1137  1.1.1.2  christos 		test_for_getaddrinfo_hacks();
   1138  1.1.1.2  christos 	return need_socktype_protocol_hack_;
   1139  1.1.1.2  christos }
   1140  1.1.1.2  christos 
   1141  1.1.1.2  christos static void
   1142  1.1.1.2  christos apply_numeric_port_hack(int port, struct evutil_addrinfo **ai)
   1143  1.1.1.2  christos {
   1144  1.1.1.2  christos 	/* Now we run through the list and set the ports on all of the
   1145  1.1.1.2  christos 	 * results where ports would make sense. */
   1146  1.1.1.2  christos 	for ( ; *ai; ai = &(*ai)->ai_next) {
   1147  1.1.1.2  christos 		struct sockaddr *sa = (*ai)->ai_addr;
   1148  1.1.1.2  christos 		if (sa && sa->sa_family == AF_INET) {
   1149  1.1.1.2  christos 			struct sockaddr_in *sin = (struct sockaddr_in*)sa;
   1150  1.1.1.2  christos 			sin->sin_port = htons(port);
   1151  1.1.1.2  christos 		} else if (sa && sa->sa_family == AF_INET6) {
   1152  1.1.1.2  christos 			struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
   1153  1.1.1.2  christos 			sin6->sin6_port = htons(port);
   1154  1.1.1.2  christos 		} else {
   1155  1.1.1.2  christos 			/* A numeric port makes no sense here; remove this one
   1156  1.1.1.2  christos 			 * from the list. */
   1157  1.1.1.2  christos 			struct evutil_addrinfo *victim = *ai;
   1158  1.1.1.2  christos 			*ai = victim->ai_next;
   1159  1.1.1.2  christos 			victim->ai_next = NULL;
   1160  1.1.1.2  christos 			freeaddrinfo(victim);
   1161  1.1.1.2  christos 		}
   1162  1.1.1.2  christos 	}
   1163  1.1.1.2  christos }
   1164  1.1.1.2  christos 
   1165  1.1.1.2  christos static int
   1166  1.1.1.2  christos apply_socktype_protocol_hack(struct evutil_addrinfo *ai)
   1167  1.1.1.2  christos {
   1168  1.1.1.2  christos 	struct evutil_addrinfo *ai_new;
   1169  1.1.1.2  christos 	for (; ai; ai = ai->ai_next) {
   1170  1.1.1.2  christos 		evutil_getaddrinfo_infer_protocols(ai);
   1171  1.1.1.2  christos 		if (ai->ai_socktype || ai->ai_protocol)
   1172  1.1.1.2  christos 			continue;
   1173  1.1.1.2  christos 		ai_new = mm_malloc(sizeof(*ai_new));
   1174  1.1.1.2  christos 		if (!ai_new)
   1175  1.1.1.2  christos 			return -1;
   1176  1.1.1.2  christos 		memcpy(ai_new, ai, sizeof(*ai_new));
   1177  1.1.1.2  christos 		ai->ai_socktype = SOCK_STREAM;
   1178  1.1.1.2  christos 		ai->ai_protocol = IPPROTO_TCP;
   1179  1.1.1.2  christos 		ai_new->ai_socktype = SOCK_DGRAM;
   1180  1.1.1.2  christos 		ai_new->ai_protocol = IPPROTO_UDP;
   1181  1.1.1.2  christos 
   1182  1.1.1.2  christos 		ai_new->ai_next = ai->ai_next;
   1183  1.1.1.2  christos 		ai->ai_next = ai_new;
   1184  1.1.1.2  christos 	}
   1185  1.1.1.2  christos 	return 0;
   1186  1.1.1.2  christos }
   1187  1.1.1.2  christos #endif
   1188  1.1.1.2  christos 
   1189  1.1.1.2  christos int
   1190  1.1.1.2  christos evutil_getaddrinfo(const char *nodename, const char *servname,
   1191  1.1.1.2  christos     const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res)
   1192  1.1.1.2  christos {
   1193  1.1.1.2  christos #ifdef USE_NATIVE_GETADDRINFO
   1194  1.1.1.2  christos 	struct evutil_addrinfo hints;
   1195  1.1.1.2  christos 	int portnum=-1, need_np_hack, err;
   1196  1.1.1.2  christos 
   1197  1.1.1.2  christos 	if (hints_in) {
   1198  1.1.1.2  christos 		memcpy(&hints, hints_in, sizeof(hints));
   1199  1.1.1.2  christos 	} else {
   1200  1.1.1.2  christos 		memset(&hints, 0, sizeof(hints));
   1201  1.1.1.2  christos 		hints.ai_family = PF_UNSPEC;
   1202  1.1.1.2  christos 	}
   1203  1.1.1.2  christos 
   1204  1.1.1.2  christos #ifndef AI_ADDRCONFIG
   1205  1.1.1.2  christos 	/* Not every system has AI_ADDRCONFIG, so fake it. */
   1206  1.1.1.2  christos 	if (hints.ai_family == PF_UNSPEC &&
   1207  1.1.1.2  christos 	    (hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
   1208  1.1.1.2  christos 		evutil_adjust_hints_for_addrconfig(&hints);
   1209  1.1.1.2  christos 	}
   1210  1.1.1.2  christos #endif
   1211  1.1.1.2  christos 
   1212  1.1.1.2  christos #ifndef AI_NUMERICSERV
   1213  1.1.1.2  christos 	/* Not every system has AI_NUMERICSERV, so fake it. */
   1214  1.1.1.2  christos 	if (hints.ai_flags & EVUTIL_AI_NUMERICSERV) {
   1215  1.1.1.2  christos 		if (servname && parse_numeric_servname(servname)<0)
   1216  1.1.1.2  christos 			return EVUTIL_EAI_NONAME;
   1217  1.1.1.2  christos 	}
   1218  1.1.1.2  christos #endif
   1219  1.1.1.2  christos 
   1220  1.1.1.2  christos 	/* Enough operating systems handle enough common non-resolve
   1221  1.1.1.2  christos 	 * cases here weirdly enough that we are better off just
   1222  1.1.1.2  christos 	 * overriding them.  For example:
   1223  1.1.1.2  christos 	 *
   1224  1.1.1.2  christos 	 * - Windows doesn't like to infer the protocol from the
   1225  1.1.1.2  christos 	 *   socket type, or fill in socket or protocol types much at
   1226  1.1.1.2  christos 	 *   all.  It also seems to do its own broken implicit
   1227  1.1.1.2  christos 	 *   always-on version of AI_ADDRCONFIG that keeps it from
   1228  1.1.1.2  christos 	 *   ever resolving even a literal IPv6 address when
   1229  1.1.1.2  christos 	 *   ai_addrtype is PF_UNSPEC.
   1230  1.1.1.2  christos 	 */
   1231  1.1.1.2  christos #ifdef WIN32
   1232  1.1.1.2  christos 	{
   1233  1.1.1.2  christos 		int tmp_port;
   1234  1.1.1.2  christos 		err = evutil_getaddrinfo_common(nodename,servname,&hints,
   1235  1.1.1.2  christos 		    res, &tmp_port);
   1236  1.1.1.2  christos 		if (err == 0 ||
   1237  1.1.1.2  christos 		    err == EVUTIL_EAI_MEMORY ||
   1238  1.1.1.2  christos 		    err == EVUTIL_EAI_NONAME)
   1239  1.1.1.2  christos 			return err;
   1240  1.1.1.2  christos 		/* If we make it here, the system getaddrinfo can
   1241  1.1.1.2  christos 		 * have a crack at it. */
   1242  1.1.1.2  christos 	}
   1243  1.1.1.2  christos #endif
   1244  1.1.1.2  christos 
   1245  1.1.1.2  christos 	/* See documentation for need_numeric_port_hack above.*/
   1246  1.1.1.2  christos 	need_np_hack = need_numeric_port_hack() && servname && !hints.ai_socktype
   1247  1.1.1.2  christos 	    && ((portnum=parse_numeric_servname(servname)) >= 0);
   1248  1.1.1.2  christos 	if (need_np_hack) {
   1249  1.1.1.2  christos 		if (!nodename)
   1250  1.1.1.2  christos 			return evutil_getaddrinfo_common(
   1251  1.1.1.2  christos 				NULL,servname,&hints, res, &portnum);
   1252  1.1.1.2  christos 		servname = NULL;
   1253  1.1.1.2  christos 	}
   1254  1.1.1.2  christos 
   1255  1.1.1.2  christos 	if (need_socktype_protocol_hack()) {
   1256  1.1.1.2  christos 		evutil_getaddrinfo_infer_protocols(&hints);
   1257  1.1.1.2  christos 	}
   1258  1.1.1.2  christos 
   1259  1.1.1.2  christos 	/* Make sure that we didn't actually steal any AI_FLAGS values that
   1260  1.1.1.2  christos 	 * the system is using.  (This is a constant expression, and should ge
   1261  1.1.1.2  christos 	 * optimized out.)
   1262  1.1.1.2  christos 	 *
   1263  1.1.1.2  christos 	 * XXXX Turn this into a compile-time failure rather than a run-time
   1264  1.1.1.2  christos 	 * failure.
   1265  1.1.1.2  christos 	 */
   1266  1.1.1.2  christos 	EVUTIL_ASSERT((ALL_NONNATIVE_AI_FLAGS & ALL_NATIVE_AI_FLAGS) == 0);
   1267  1.1.1.2  christos 
   1268  1.1.1.2  christos 	/* Clear any flags that only libevent understands. */
   1269  1.1.1.2  christos 	hints.ai_flags &= ~ALL_NONNATIVE_AI_FLAGS;
   1270  1.1.1.2  christos 
   1271  1.1.1.2  christos 	err = getaddrinfo(nodename, servname, &hints, res);
   1272  1.1.1.2  christos 	if (need_np_hack)
   1273  1.1.1.2  christos 		apply_numeric_port_hack(portnum, res);
   1274  1.1.1.2  christos 
   1275  1.1.1.2  christos 	if (need_socktype_protocol_hack()) {
   1276  1.1.1.2  christos 		if (apply_socktype_protocol_hack(*res) < 0) {
   1277  1.1.1.2  christos 			evutil_freeaddrinfo(*res);
   1278  1.1.1.2  christos 			*res = NULL;
   1279  1.1.1.2  christos 			return EVUTIL_EAI_MEMORY;
   1280  1.1.1.2  christos 		}
   1281  1.1.1.2  christos 	}
   1282  1.1.1.2  christos 	return err;
   1283  1.1.1.2  christos #else
   1284  1.1.1.2  christos 	int port=0, err;
   1285  1.1.1.2  christos 	struct hostent *ent = NULL;
   1286  1.1.1.2  christos 	struct evutil_addrinfo hints;
   1287  1.1.1.2  christos 
   1288  1.1.1.2  christos 	if (hints_in) {
   1289  1.1.1.2  christos 		memcpy(&hints, hints_in, sizeof(hints));
   1290  1.1.1.2  christos 	} else {
   1291  1.1.1.2  christos 		memset(&hints, 0, sizeof(hints));
   1292  1.1.1.2  christos 		hints.ai_family = PF_UNSPEC;
   1293  1.1.1.2  christos 	}
   1294  1.1.1.2  christos 
   1295  1.1.1.2  christos 	evutil_adjust_hints_for_addrconfig(&hints);
   1296  1.1.1.2  christos 
   1297  1.1.1.2  christos 	err = evutil_getaddrinfo_common(nodename, servname, &hints, res, &port);
   1298  1.1.1.2  christos 	if (err != EVUTIL_EAI_NEED_RESOLVE) {
   1299  1.1.1.2  christos 		/* We either succeeded or failed.  No need to continue */
   1300  1.1.1.2  christos 		return err;
   1301  1.1.1.2  christos 	}
   1302  1.1.1.2  christos 
   1303  1.1.1.2  christos 	err = 0;
   1304  1.1.1.2  christos 	/* Use any of the various gethostbyname_r variants as available. */
   1305  1.1.1.2  christos 	{
   1306  1.1.1.2  christos #ifdef _EVENT_HAVE_GETHOSTBYNAME_R_6_ARG
   1307  1.1.1.2  christos 		/* This one is what glibc provides. */
   1308  1.1.1.2  christos 		char buf[2048];
   1309  1.1.1.2  christos 		struct hostent hostent;
   1310  1.1.1.2  christos 		int r;
   1311  1.1.1.2  christos 		r = gethostbyname_r(nodename, &hostent, buf, sizeof(buf), &ent,
   1312  1.1.1.2  christos 		    &err);
   1313  1.1.1.2  christos #elif defined(_EVENT_HAVE_GETHOSTBYNAME_R_5_ARG)
   1314  1.1.1.2  christos 		char buf[2048];
   1315  1.1.1.2  christos 		struct hostent hostent;
   1316  1.1.1.2  christos 		ent = gethostbyname_r(nodename, &hostent, buf, sizeof(buf),
   1317  1.1.1.2  christos 		    &err);
   1318  1.1.1.2  christos #elif defined(_EVENT_HAVE_GETHOSTBYNAME_R_3_ARG)
   1319  1.1.1.2  christos 		struct hostent_data data;
   1320  1.1.1.2  christos 		struct hostent hostent;
   1321  1.1.1.2  christos 		memset(&data, 0, sizeof(data));
   1322  1.1.1.2  christos 		err = gethostbyname_r(nodename, &hostent, &data);
   1323  1.1.1.2  christos 		ent = err ? NULL : &hostent;
   1324  1.1.1.2  christos #else
   1325  1.1.1.2  christos 		/* fall back to gethostbyname. */
   1326  1.1.1.2  christos 		/* XXXX This needs a lock everywhere but Windows. */
   1327  1.1.1.2  christos 		ent = gethostbyname(nodename);
   1328  1.1.1.2  christos #ifdef WIN32
   1329  1.1.1.2  christos 		err = WSAGetLastError();
   1330  1.1.1.2  christos #else
   1331  1.1.1.2  christos 		err = h_errno;
   1332  1.1.1.2  christos #endif
   1333  1.1.1.2  christos #endif
   1334  1.1.1.2  christos 
   1335  1.1.1.2  christos 		/* Now we have either ent or err set. */
   1336  1.1.1.2  christos 		if (!ent) {
   1337  1.1.1.2  christos 			/* XXX is this right for windows ? */
   1338  1.1.1.2  christos 			switch (err) {
   1339  1.1.1.2  christos 			case TRY_AGAIN:
   1340  1.1.1.2  christos 				return EVUTIL_EAI_AGAIN;
   1341  1.1.1.2  christos 			case NO_RECOVERY:
   1342  1.1.1.2  christos 			default:
   1343  1.1.1.2  christos 				return EVUTIL_EAI_FAIL;
   1344  1.1.1.2  christos 			case HOST_NOT_FOUND:
   1345  1.1.1.2  christos 				return EVUTIL_EAI_NONAME;
   1346  1.1.1.2  christos 			case NO_ADDRESS:
   1347  1.1.1.2  christos #if NO_DATA != NO_ADDRESS
   1348  1.1.1.2  christos 			case NO_DATA:
   1349  1.1.1.2  christos #endif
   1350  1.1.1.2  christos 				return EVUTIL_EAI_NODATA;
   1351  1.1.1.2  christos 			}
   1352  1.1.1.2  christos 		}
   1353  1.1.1.2  christos 
   1354  1.1.1.2  christos 		if (ent->h_addrtype != hints.ai_family &&
   1355  1.1.1.2  christos 		    hints.ai_family != PF_UNSPEC) {
   1356  1.1.1.2  christos 			/* This wasn't the type we were hoping for.  Too bad
   1357  1.1.1.2  christos 			 * we never had a chance to ask gethostbyname for what
   1358  1.1.1.2  christos 			 * we wanted. */
   1359  1.1.1.2  christos 			return EVUTIL_EAI_NONAME;
   1360  1.1.1.2  christos 		}
   1361  1.1.1.2  christos 
   1362  1.1.1.2  christos 		/* Make sure we got _some_ answers. */
   1363  1.1.1.2  christos 		if (ent->h_length == 0)
   1364  1.1.1.2  christos 			return EVUTIL_EAI_NODATA;
   1365  1.1.1.2  christos 
   1366  1.1.1.2  christos 		/* If we got an address type we don't know how to make a
   1367  1.1.1.2  christos 		   sockaddr for, give up. */
   1368  1.1.1.2  christos 		if (ent->h_addrtype != PF_INET && ent->h_addrtype != PF_INET6)
   1369  1.1.1.2  christos 			return EVUTIL_EAI_FAMILY;
   1370  1.1.1.2  christos 
   1371  1.1.1.2  christos 		*res = addrinfo_from_hostent(ent, port, &hints);
   1372  1.1.1.2  christos 		if (! *res)
   1373  1.1.1.2  christos 			return EVUTIL_EAI_MEMORY;
   1374  1.1.1.2  christos 	}
   1375  1.1.1.2  christos 
   1376  1.1.1.2  christos 	return 0;
   1377  1.1.1.2  christos #endif
   1378  1.1.1.2  christos }
   1379  1.1.1.2  christos 
   1380  1.1.1.2  christos void
   1381  1.1.1.2  christos evutil_freeaddrinfo(struct evutil_addrinfo *ai)
   1382  1.1.1.2  christos {
   1383  1.1.1.2  christos #ifdef _EVENT_HAVE_GETADDRINFO
   1384  1.1.1.2  christos 	if (!(ai->ai_flags & EVUTIL_AI_LIBEVENT_ALLOCATED)) {
   1385  1.1.1.2  christos 		freeaddrinfo(ai);
   1386  1.1.1.2  christos 		return;
   1387  1.1.1.2  christos 	}
   1388  1.1.1.2  christos #endif
   1389  1.1.1.2  christos 	while (ai) {
   1390  1.1.1.2  christos 		struct evutil_addrinfo *next = ai->ai_next;
   1391  1.1.1.2  christos 		if (ai->ai_canonname)
   1392  1.1.1.2  christos 			mm_free(ai->ai_canonname);
   1393  1.1.1.2  christos 		mm_free(ai);
   1394  1.1.1.2  christos 		ai = next;
   1395  1.1.1.2  christos 	}
   1396  1.1.1.2  christos }
   1397  1.1.1.2  christos 
   1398  1.1.1.2  christos static evdns_getaddrinfo_fn evdns_getaddrinfo_impl = NULL;
   1399  1.1.1.2  christos 
   1400  1.1.1.2  christos void
   1401  1.1.1.2  christos evutil_set_evdns_getaddrinfo_fn(evdns_getaddrinfo_fn fn)
   1402  1.1.1.2  christos {
   1403  1.1.1.2  christos 	if (!evdns_getaddrinfo_impl)
   1404  1.1.1.2  christos 		evdns_getaddrinfo_impl = fn;
   1405  1.1.1.2  christos }
   1406  1.1.1.2  christos 
   1407  1.1.1.2  christos /* Internal helper function: act like evdns_getaddrinfo if dns_base is set;
   1408  1.1.1.2  christos  * otherwise do a blocking resolve and pass the result to the callback in the
   1409  1.1.1.2  christos  * way that evdns_getaddrinfo would.
   1410  1.1.1.2  christos  */
   1411  1.1.1.2  christos int
   1412  1.1.1.2  christos evutil_getaddrinfo_async(struct evdns_base *dns_base,
   1413  1.1.1.2  christos     const char *nodename, const char *servname,
   1414  1.1.1.2  christos     const struct evutil_addrinfo *hints_in,
   1415  1.1.1.2  christos     void (*cb)(int, struct evutil_addrinfo *, void *), void *arg)
   1416  1.1.1.2  christos {
   1417  1.1.1.2  christos 	if (dns_base && evdns_getaddrinfo_impl) {
   1418  1.1.1.2  christos 		evdns_getaddrinfo_impl(
   1419  1.1.1.2  christos 			dns_base, nodename, servname, hints_in, cb, arg);
   1420  1.1.1.2  christos 	} else {
   1421  1.1.1.2  christos 		struct evutil_addrinfo *ai=NULL;
   1422  1.1.1.2  christos 		int err;
   1423  1.1.1.2  christos 		err = evutil_getaddrinfo(nodename, servname, hints_in, &ai);
   1424  1.1.1.2  christos 		cb(err, ai, arg);
   1425  1.1.1.2  christos 	}
   1426  1.1.1.2  christos 	return 0;
   1427  1.1.1.2  christos }
   1428  1.1.1.2  christos 
   1429  1.1.1.2  christos const char *
   1430  1.1.1.2  christos evutil_gai_strerror(int err)
   1431  1.1.1.2  christos {
   1432  1.1.1.2  christos 	/* As a sneaky side-benefit, this case statement will get most
   1433  1.1.1.2  christos 	 * compilers to tell us if any of the error codes we defined
   1434  1.1.1.2  christos 	 * conflict with the platform's native error codes. */
   1435  1.1.1.2  christos 	switch (err) {
   1436  1.1.1.2  christos 	case EVUTIL_EAI_CANCEL:
   1437  1.1.1.2  christos 		return "Request canceled";
   1438  1.1.1.2  christos 	case 0:
   1439  1.1.1.2  christos 		return "No error";
   1440  1.1.1.2  christos 
   1441  1.1.1.2  christos 	case EVUTIL_EAI_ADDRFAMILY:
   1442  1.1.1.2  christos 		return "address family for nodename not supported";
   1443  1.1.1.2  christos 	case EVUTIL_EAI_AGAIN:
   1444  1.1.1.2  christos 		return "temporary failure in name resolution";
   1445  1.1.1.2  christos 	case EVUTIL_EAI_BADFLAGS:
   1446  1.1.1.2  christos 		return "invalid value for ai_flags";
   1447  1.1.1.2  christos 	case EVUTIL_EAI_FAIL:
   1448  1.1.1.2  christos 		return "non-recoverable failure in name resolution";
   1449  1.1.1.2  christos 	case EVUTIL_EAI_FAMILY:
   1450  1.1.1.2  christos 		return "ai_family not supported";
   1451  1.1.1.2  christos 	case EVUTIL_EAI_MEMORY:
   1452  1.1.1.2  christos 		return "memory allocation failure";
   1453  1.1.1.2  christos 	case EVUTIL_EAI_NODATA:
   1454  1.1.1.2  christos 		return "no address associated with nodename";
   1455  1.1.1.2  christos 	case EVUTIL_EAI_NONAME:
   1456  1.1.1.2  christos 		return "nodename nor servname provided, or not known";
   1457  1.1.1.2  christos 	case EVUTIL_EAI_SERVICE:
   1458  1.1.1.2  christos 		return "servname not supported for ai_socktype";
   1459  1.1.1.2  christos 	case EVUTIL_EAI_SOCKTYPE:
   1460  1.1.1.2  christos 		return "ai_socktype not supported";
   1461  1.1.1.2  christos 	case EVUTIL_EAI_SYSTEM:
   1462  1.1.1.2  christos 		return "system error";
   1463  1.1.1.2  christos 	default:
   1464  1.1.1.2  christos #if defined(USE_NATIVE_GETADDRINFO) && defined(WIN32)
   1465  1.1.1.2  christos 		return gai_strerrorA(err);
   1466  1.1.1.2  christos #elif defined(USE_NATIVE_GETADDRINFO)
   1467  1.1.1.2  christos 		return gai_strerror(err);
   1468  1.1.1.2  christos #else
   1469  1.1.1.2  christos 		return "Unknown error code";
   1470  1.1.1.2  christos #endif
   1471  1.1.1.2  christos 	}
   1472  1.1.1.2  christos }
   1473  1.1.1.2  christos 
   1474  1.1.1.2  christos #ifdef WIN32
   1475  1.1.1.2  christos #define E(code, s) { code, (s " [" #code " ]") }
   1476  1.1.1.2  christos static struct { int code; const char *msg; } windows_socket_errors[] = {
   1477  1.1.1.2  christos   E(WSAEINTR, "Interrupted function call"),
   1478  1.1.1.2  christos   E(WSAEACCES, "Permission denied"),
   1479  1.1.1.2  christos   E(WSAEFAULT, "Bad address"),
   1480  1.1.1.2  christos   E(WSAEINVAL, "Invalid argument"),
   1481  1.1.1.2  christos   E(WSAEMFILE, "Too many open files"),
   1482  1.1.1.2  christos   E(WSAEWOULDBLOCK,  "Resource temporarily unavailable"),
   1483  1.1.1.2  christos   E(WSAEINPROGRESS, "Operation now in progress"),
   1484  1.1.1.2  christos   E(WSAEALREADY, "Operation already in progress"),
   1485  1.1.1.2  christos   E(WSAENOTSOCK, "Socket operation on nonsocket"),
   1486  1.1.1.2  christos   E(WSAEDESTADDRREQ, "Destination address required"),
   1487  1.1.1.2  christos   E(WSAEMSGSIZE, "Message too long"),
   1488  1.1.1.2  christos   E(WSAEPROTOTYPE, "Protocol wrong for socket"),
   1489  1.1.1.2  christos   E(WSAENOPROTOOPT, "Bad protocol option"),
   1490  1.1.1.2  christos   E(WSAEPROTONOSUPPORT, "Protocol not supported"),
   1491  1.1.1.2  christos   E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
   1492  1.1.1.2  christos   /* What's the difference between NOTSUPP and NOSUPPORT? :) */
   1493  1.1.1.2  christos   E(WSAEOPNOTSUPP, "Operation not supported"),
   1494  1.1.1.2  christos   E(WSAEPFNOSUPPORT,  "Protocol family not supported"),
   1495  1.1.1.2  christos   E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
   1496  1.1.1.2  christos   E(WSAEADDRINUSE, "Address already in use"),
   1497  1.1.1.2  christos   E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
   1498  1.1.1.2  christos   E(WSAENETDOWN, "Network is down"),
   1499  1.1.1.2  christos   E(WSAENETUNREACH, "Network is unreachable"),
   1500  1.1.1.2  christos   E(WSAENETRESET, "Network dropped connection on reset"),
   1501  1.1.1.2  christos   E(WSAECONNABORTED, "Software caused connection abort"),
   1502  1.1.1.2  christos   E(WSAECONNRESET, "Connection reset by peer"),
   1503  1.1.1.2  christos   E(WSAENOBUFS, "No buffer space available"),
   1504  1.1.1.2  christos   E(WSAEISCONN, "Socket is already connected"),
   1505  1.1.1.2  christos   E(WSAENOTCONN, "Socket is not connected"),
   1506  1.1.1.2  christos   E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
   1507  1.1.1.2  christos   E(WSAETIMEDOUT, "Connection timed out"),
   1508  1.1.1.2  christos   E(WSAECONNREFUSED, "Connection refused"),
   1509  1.1.1.2  christos   E(WSAEHOSTDOWN, "Host is down"),
   1510  1.1.1.2  christos   E(WSAEHOSTUNREACH, "No route to host"),
   1511  1.1.1.2  christos   E(WSAEPROCLIM, "Too many processes"),
   1512  1.1.1.2  christos 
   1513  1.1.1.2  christos   /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
   1514  1.1.1.2  christos   E(WSASYSNOTREADY, "Network subsystem is unavailable"),
   1515  1.1.1.2  christos   E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
   1516  1.1.1.2  christos   E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
   1517  1.1.1.2  christos   E(WSAEDISCON, "Graceful shutdown now in progress"),
   1518  1.1.1.2  christos #ifdef WSATYPE_NOT_FOUND
   1519  1.1.1.2  christos   E(WSATYPE_NOT_FOUND, "Class type not found"),
   1520  1.1.1.2  christos #endif
   1521  1.1.1.2  christos   E(WSAHOST_NOT_FOUND, "Host not found"),
   1522  1.1.1.2  christos   E(WSATRY_AGAIN, "Nonauthoritative host not found"),
   1523  1.1.1.2  christos   E(WSANO_RECOVERY, "This is a nonrecoverable error"),
   1524  1.1.1.2  christos   E(WSANO_DATA, "Valid name, no data record of requested type)"),
   1525  1.1.1.2  christos 
   1526  1.1.1.2  christos   /* There are some more error codes whose numeric values are marked
   1527  1.1.1.2  christos    * <b>OS dependent</b>. They start with WSA_, apparently for the same
   1528  1.1.1.2  christos    * reason that practitioners of some craft traditions deliberately
   1529  1.1.1.2  christos    * introduce imperfections into their baskets and rugs "to allow the
   1530  1.1.1.2  christos    * evil spirits to escape."  If we catch them, then our binaries
   1531  1.1.1.2  christos    * might not report consistent results across versions of Windows.
   1532  1.1.1.2  christos    * Thus, I'm going to let them all fall through.
   1533  1.1.1.2  christos    */
   1534  1.1.1.2  christos   { -1, NULL },
   1535  1.1.1.2  christos };
   1536  1.1.1.2  christos #undef E
   1537  1.1.1.2  christos /** Equivalent to strerror, but for windows socket errors. */
   1538  1.1.1.2  christos const char *
   1539  1.1.1.2  christos evutil_socket_error_to_string(int errcode)
   1540  1.1.1.2  christos {
   1541  1.1.1.2  christos   /* XXXX Is there really no built-in function to do this? */
   1542  1.1.1.2  christos   int i;
   1543  1.1.1.2  christos   for (i=0; windows_socket_errors[i].code >= 0; ++i) {
   1544  1.1.1.2  christos     if (errcode == windows_socket_errors[i].code)
   1545  1.1.1.2  christos       return windows_socket_errors[i].msg;
   1546  1.1.1.2  christos   }
   1547  1.1.1.2  christos   return strerror(errcode);
   1548  1.1.1.2  christos }
   1549  1.1.1.2  christos #endif
   1550  1.1.1.2  christos 
   1551      1.1    plunky int
   1552      1.1    plunky evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
   1553      1.1    plunky {
   1554      1.1    plunky 	int r;
   1555      1.1    plunky 	va_list ap;
   1556      1.1    plunky 	va_start(ap, format);
   1557      1.1    plunky 	r = evutil_vsnprintf(buf, buflen, format, ap);
   1558      1.1    plunky 	va_end(ap);
   1559      1.1    plunky 	return r;
   1560      1.1    plunky }
   1561      1.1    plunky 
   1562      1.1    plunky int
   1563      1.1    plunky evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
   1564      1.1    plunky {
   1565  1.1.1.2  christos 	int r;
   1566  1.1.1.2  christos 	if (!buflen)
   1567  1.1.1.2  christos 		return 0;
   1568  1.1.1.3       spz #if defined(_MSC_VER) || defined(WIN32)
   1569  1.1.1.2  christos 	r = _vsnprintf(buf, buflen, format, ap);
   1570  1.1.1.2  christos 	if (r < 0)
   1571  1.1.1.2  christos 		r = _vscprintf(format, ap);
   1572  1.1.1.2  christos #elif defined(sgi)
   1573  1.1.1.2  christos 	/* Make sure we always use the correct vsnprintf on IRIX */
   1574  1.1.1.2  christos 	extern int      _xpg5_vsnprintf(char * __restrict,
   1575  1.1.1.2  christos 		__SGI_LIBC_NAMESPACE_QUALIFIER size_t,
   1576  1.1.1.2  christos 		const char * __restrict, /* va_list */ char *);
   1577  1.1.1.2  christos 
   1578  1.1.1.2  christos 	r = _xpg5_vsnprintf(buf, buflen, format, ap);
   1579      1.1    plunky #else
   1580  1.1.1.2  christos 	r = vsnprintf(buf, buflen, format, ap);
   1581  1.1.1.2  christos #endif
   1582      1.1    plunky 	buf[buflen-1] = '\0';
   1583      1.1    plunky 	return r;
   1584  1.1.1.2  christos }
   1585  1.1.1.2  christos 
   1586  1.1.1.2  christos #define USE_INTERNAL_NTOP
   1587  1.1.1.2  christos #define USE_INTERNAL_PTON
   1588  1.1.1.2  christos 
   1589  1.1.1.2  christos const char *
   1590  1.1.1.2  christos evutil_inet_ntop(int af, const void *src, char *dst, size_t len)
   1591  1.1.1.2  christos {
   1592  1.1.1.2  christos #if defined(_EVENT_HAVE_INET_NTOP) && !defined(USE_INTERNAL_NTOP)
   1593  1.1.1.2  christos 	return inet_ntop(af, src, dst, len);
   1594  1.1.1.2  christos #else
   1595  1.1.1.2  christos 	if (af == AF_INET) {
   1596  1.1.1.2  christos 		const struct in_addr *in = src;
   1597  1.1.1.2  christos 		const ev_uint32_t a = ntohl(in->s_addr);
   1598  1.1.1.2  christos 		int r;
   1599  1.1.1.2  christos 		r = evutil_snprintf(dst, len, "%d.%d.%d.%d",
   1600  1.1.1.2  christos 		    (int)(ev_uint8_t)((a>>24)&0xff),
   1601  1.1.1.2  christos 		    (int)(ev_uint8_t)((a>>16)&0xff),
   1602  1.1.1.2  christos 		    (int)(ev_uint8_t)((a>>8 )&0xff),
   1603  1.1.1.2  christos 		    (int)(ev_uint8_t)((a    )&0xff));
   1604  1.1.1.2  christos 		if (r<0||(size_t)r>=len)
   1605  1.1.1.2  christos 			return NULL;
   1606  1.1.1.2  christos 		else
   1607  1.1.1.2  christos 			return dst;
   1608  1.1.1.2  christos #ifdef AF_INET6
   1609  1.1.1.2  christos 	} else if (af == AF_INET6) {
   1610  1.1.1.2  christos 		const struct in6_addr *addr = src;
   1611  1.1.1.2  christos 		char buf[64], *cp;
   1612  1.1.1.2  christos 		int longestGapLen = 0, longestGapPos = -1, i,
   1613  1.1.1.2  christos 			curGapPos = -1, curGapLen = 0;
   1614  1.1.1.2  christos 		ev_uint16_t words[8];
   1615  1.1.1.2  christos 		for (i = 0; i < 8; ++i) {
   1616  1.1.1.2  christos 			words[i] =
   1617  1.1.1.2  christos 			    (((ev_uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
   1618  1.1.1.2  christos 		}
   1619  1.1.1.2  christos 		if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
   1620  1.1.1.2  christos 		    words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
   1621  1.1.1.2  christos 			(words[5] == 0xffff))) {
   1622  1.1.1.2  christos 			/* This is an IPv4 address. */
   1623  1.1.1.2  christos 			if (words[5] == 0) {
   1624  1.1.1.2  christos 				evutil_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
   1625  1.1.1.2  christos 				    addr->s6_addr[12], addr->s6_addr[13],
   1626  1.1.1.2  christos 				    addr->s6_addr[14], addr->s6_addr[15]);
   1627  1.1.1.2  christos 			} else {
   1628  1.1.1.2  christos 				evutil_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
   1629  1.1.1.2  christos 				    addr->s6_addr[12], addr->s6_addr[13],
   1630  1.1.1.2  christos 				    addr->s6_addr[14], addr->s6_addr[15]);
   1631  1.1.1.2  christos 			}
   1632  1.1.1.2  christos 			if (strlen(buf) > len)
   1633  1.1.1.2  christos 				return NULL;
   1634  1.1.1.2  christos 			strlcpy(dst, buf, len);
   1635  1.1.1.2  christos 			return dst;
   1636  1.1.1.2  christos 		}
   1637  1.1.1.2  christos 		i = 0;
   1638  1.1.1.2  christos 		while (i < 8) {
   1639  1.1.1.2  christos 			if (words[i] == 0) {
   1640  1.1.1.2  christos 				curGapPos = i++;
   1641  1.1.1.2  christos 				curGapLen = 1;
   1642  1.1.1.2  christos 				while (i<8 && words[i] == 0) {
   1643  1.1.1.2  christos 					++i; ++curGapLen;
   1644  1.1.1.2  christos 				}
   1645  1.1.1.2  christos 				if (curGapLen > longestGapLen) {
   1646  1.1.1.2  christos 					longestGapPos = curGapPos;
   1647  1.1.1.2  christos 					longestGapLen = curGapLen;
   1648  1.1.1.2  christos 				}
   1649  1.1.1.2  christos 			} else {
   1650  1.1.1.2  christos 				++i;
   1651  1.1.1.2  christos 			}
   1652  1.1.1.2  christos 		}
   1653  1.1.1.2  christos 		if (longestGapLen<=1)
   1654  1.1.1.2  christos 			longestGapPos = -1;
   1655  1.1.1.2  christos 
   1656  1.1.1.2  christos 		cp = buf;
   1657  1.1.1.2  christos 		for (i = 0; i < 8; ++i) {
   1658  1.1.1.2  christos 			if (words[i] == 0 && longestGapPos == i) {
   1659  1.1.1.2  christos 				if (i == 0)
   1660  1.1.1.2  christos 					*cp++ = ':';
   1661  1.1.1.2  christos 				*cp++ = ':';
   1662  1.1.1.2  christos 				while (i < 8 && words[i] == 0)
   1663  1.1.1.2  christos 					++i;
   1664  1.1.1.2  christos 				--i; /* to compensate for loop increment. */
   1665  1.1.1.2  christos 			} else {
   1666  1.1.1.2  christos 				evutil_snprintf(cp,
   1667  1.1.1.2  christos 								sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
   1668  1.1.1.2  christos 				cp += strlen(cp);
   1669  1.1.1.2  christos 				if (i != 7)
   1670  1.1.1.2  christos 					*cp++ = ':';
   1671  1.1.1.2  christos 			}
   1672  1.1.1.2  christos 		}
   1673  1.1.1.2  christos 		*cp = '\0';
   1674  1.1.1.2  christos 		if (strlen(buf) > len)
   1675  1.1.1.2  christos 			return NULL;
   1676  1.1.1.2  christos 		strlcpy(dst, buf, len);
   1677  1.1.1.2  christos 		return dst;
   1678  1.1.1.2  christos #endif
   1679  1.1.1.2  christos 	} else {
   1680  1.1.1.2  christos 		return NULL;
   1681  1.1.1.2  christos 	}
   1682  1.1.1.2  christos #endif
   1683  1.1.1.2  christos }
   1684  1.1.1.2  christos 
   1685  1.1.1.2  christos int
   1686  1.1.1.2  christos evutil_inet_pton(int af, const char *src, void *dst)
   1687  1.1.1.2  christos {
   1688  1.1.1.2  christos #if defined(_EVENT_HAVE_INET_PTON) && !defined(USE_INTERNAL_PTON)
   1689  1.1.1.2  christos 	return inet_pton(af, src, dst);
   1690  1.1.1.2  christos #else
   1691  1.1.1.2  christos 	if (af == AF_INET) {
   1692  1.1.1.2  christos 		int a,b,c,d;
   1693  1.1.1.2  christos 		char more;
   1694  1.1.1.2  christos 		struct in_addr *addr = dst;
   1695  1.1.1.2  christos 		if (sscanf(src, "%d.%d.%d.%d%c", &a,&b,&c,&d,&more) != 4)
   1696  1.1.1.2  christos 			return 0;
   1697  1.1.1.2  christos 		if (a < 0 || a > 255) return 0;
   1698  1.1.1.2  christos 		if (b < 0 || b > 255) return 0;
   1699  1.1.1.2  christos 		if (c < 0 || c > 255) return 0;
   1700  1.1.1.2  christos 		if (d < 0 || d > 255) return 0;
   1701  1.1.1.2  christos 		addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
   1702  1.1.1.2  christos 		return 1;
   1703  1.1.1.2  christos #ifdef AF_INET6
   1704  1.1.1.2  christos 	} else if (af == AF_INET6) {
   1705  1.1.1.2  christos 		struct in6_addr *out = dst;
   1706  1.1.1.2  christos 		ev_uint16_t words[8];
   1707  1.1.1.2  christos 		int gapPos = -1, i, setWords=0;
   1708  1.1.1.2  christos 		const char *dot = strchr(src, '.');
   1709  1.1.1.2  christos 		const char *eow; /* end of words. */
   1710  1.1.1.2  christos 		if (dot == src)
   1711  1.1.1.2  christos 			return 0;
   1712  1.1.1.2  christos 		else if (!dot)
   1713  1.1.1.2  christos 			eow = src+strlen(src);
   1714  1.1.1.2  christos 		else {
   1715  1.1.1.2  christos 			int byte1,byte2,byte3,byte4;
   1716  1.1.1.2  christos 			char more;
   1717  1.1.1.2  christos 			for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT(*eow); --eow)
   1718  1.1.1.2  christos 				;
   1719  1.1.1.2  christos 			++eow;
   1720  1.1.1.2  christos 
   1721  1.1.1.2  christos 			/* We use "scanf" because some platform inet_aton()s are too lax
   1722  1.1.1.2  christos 			 * about IPv4 addresses of the form "1.2.3" */
   1723  1.1.1.2  christos 			if (sscanf(eow, "%d.%d.%d.%d%c",
   1724  1.1.1.2  christos 					   &byte1,&byte2,&byte3,&byte4,&more) != 4)
   1725  1.1.1.2  christos 				return 0;
   1726  1.1.1.2  christos 
   1727  1.1.1.2  christos 			if (byte1 > 255 || byte1 < 0 ||
   1728  1.1.1.2  christos 				byte2 > 255 || byte2 < 0 ||
   1729  1.1.1.2  christos 				byte3 > 255 || byte3 < 0 ||
   1730  1.1.1.2  christos 				byte4 > 255 || byte4 < 0)
   1731  1.1.1.2  christos 				return 0;
   1732  1.1.1.2  christos 
   1733  1.1.1.2  christos 			words[6] = (byte1<<8) | byte2;
   1734  1.1.1.2  christos 			words[7] = (byte3<<8) | byte4;
   1735  1.1.1.2  christos 			setWords += 2;
   1736  1.1.1.2  christos 		}
   1737  1.1.1.2  christos 
   1738  1.1.1.2  christos 		i = 0;
   1739  1.1.1.2  christos 		while (src < eow) {
   1740  1.1.1.2  christos 			if (i > 7)
   1741  1.1.1.2  christos 				return 0;
   1742  1.1.1.2  christos 			if (EVUTIL_ISXDIGIT(*src)) {
   1743  1.1.1.2  christos 				char *next;
   1744  1.1.1.2  christos 				long r = strtol(src, &next, 16);
   1745  1.1.1.2  christos 				if (next > 4+src)
   1746  1.1.1.2  christos 					return 0;
   1747  1.1.1.2  christos 				if (next == src)
   1748  1.1.1.2  christos 					return 0;
   1749  1.1.1.2  christos 				if (r<0 || r>65536)
   1750  1.1.1.2  christos 					return 0;
   1751  1.1.1.2  christos 
   1752  1.1.1.2  christos 				words[i++] = (ev_uint16_t)r;
   1753  1.1.1.2  christos 				setWords++;
   1754  1.1.1.2  christos 				src = next;
   1755  1.1.1.2  christos 				if (*src != ':' && src != eow)
   1756  1.1.1.2  christos 					return 0;
   1757  1.1.1.2  christos 				++src;
   1758  1.1.1.2  christos 			} else if (*src == ':' && i > 0 && gapPos==-1) {
   1759  1.1.1.2  christos 				gapPos = i;
   1760  1.1.1.2  christos 				++src;
   1761  1.1.1.2  christos 			} else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
   1762  1.1.1.2  christos 				gapPos = i;
   1763  1.1.1.2  christos 				src += 2;
   1764  1.1.1.2  christos 			} else {
   1765  1.1.1.2  christos 				return 0;
   1766  1.1.1.2  christos 			}
   1767  1.1.1.2  christos 		}
   1768  1.1.1.2  christos 
   1769  1.1.1.2  christos 		if (setWords > 8 ||
   1770  1.1.1.2  christos 			(setWords == 8 && gapPos != -1) ||
   1771  1.1.1.2  christos 			(setWords < 8 && gapPos == -1))
   1772  1.1.1.2  christos 			return 0;
   1773  1.1.1.2  christos 
   1774  1.1.1.2  christos 		if (gapPos >= 0) {
   1775  1.1.1.2  christos 			int nToMove = setWords - (dot ? 2 : 0) - gapPos;
   1776  1.1.1.2  christos 			int gapLen = 8 - setWords;
   1777  1.1.1.2  christos 			/* assert(nToMove >= 0); */
   1778  1.1.1.2  christos 			if (nToMove < 0)
   1779  1.1.1.2  christos 				return -1; /* should be impossible */
   1780  1.1.1.2  christos 			memmove(&words[gapPos+gapLen], &words[gapPos],
   1781  1.1.1.2  christos 					sizeof(ev_uint16_t)*nToMove);
   1782  1.1.1.2  christos 			memset(&words[gapPos], 0, sizeof(ev_uint16_t)*gapLen);
   1783  1.1.1.2  christos 		}
   1784  1.1.1.2  christos 		for (i = 0; i < 8; ++i) {
   1785  1.1.1.2  christos 			out->s6_addr[2*i  ] = words[i] >> 8;
   1786  1.1.1.2  christos 			out->s6_addr[2*i+1] = words[i] & 0xff;
   1787  1.1.1.2  christos 		}
   1788  1.1.1.2  christos 
   1789  1.1.1.2  christos 		return 1;
   1790  1.1.1.2  christos #endif
   1791  1.1.1.2  christos 	} else {
   1792  1.1.1.2  christos 		return -1;
   1793  1.1.1.2  christos 	}
   1794  1.1.1.2  christos #endif
   1795  1.1.1.2  christos }
   1796  1.1.1.2  christos 
   1797  1.1.1.2  christos int
   1798  1.1.1.2  christos evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
   1799  1.1.1.2  christos {
   1800  1.1.1.2  christos 	int port;
   1801  1.1.1.2  christos 	char buf[128];
   1802  1.1.1.2  christos 	const char *cp, *addr_part, *port_part;
   1803  1.1.1.2  christos 	int is_ipv6;
   1804  1.1.1.2  christos 	/* recognized formats are:
   1805  1.1.1.2  christos 	 * [ipv6]:port
   1806  1.1.1.2  christos 	 * ipv6
   1807  1.1.1.2  christos 	 * [ipv6]
   1808  1.1.1.2  christos 	 * ipv4:port
   1809  1.1.1.2  christos 	 * ipv4
   1810  1.1.1.2  christos 	 */
   1811  1.1.1.2  christos 
   1812  1.1.1.2  christos 	cp = strchr(ip_as_string, ':');
   1813  1.1.1.2  christos 	if (*ip_as_string == '[') {
   1814  1.1.1.2  christos 		int len;
   1815  1.1.1.2  christos 		if (!(cp = strchr(ip_as_string, ']'))) {
   1816  1.1.1.2  christos 			return -1;
   1817  1.1.1.2  christos 		}
   1818  1.1.1.2  christos 		len = (int) ( cp-(ip_as_string + 1) );
   1819  1.1.1.2  christos 		if (len > (int)sizeof(buf)-1) {
   1820  1.1.1.2  christos 			return -1;
   1821  1.1.1.2  christos 		}
   1822  1.1.1.2  christos 		memcpy(buf, ip_as_string+1, len);
   1823  1.1.1.2  christos 		buf[len] = '\0';
   1824  1.1.1.2  christos 		addr_part = buf;
   1825  1.1.1.2  christos 		if (cp[1] == ':')
   1826  1.1.1.2  christos 			port_part = cp+2;
   1827  1.1.1.2  christos 		else
   1828  1.1.1.2  christos 			port_part = NULL;
   1829  1.1.1.2  christos 		is_ipv6 = 1;
   1830  1.1.1.2  christos 	} else if (cp && strchr(cp+1, ':')) {
   1831  1.1.1.2  christos 		is_ipv6 = 1;
   1832  1.1.1.2  christos 		addr_part = ip_as_string;
   1833  1.1.1.2  christos 		port_part = NULL;
   1834  1.1.1.2  christos 	} else if (cp) {
   1835  1.1.1.2  christos 		is_ipv6 = 0;
   1836  1.1.1.2  christos 		if (cp - ip_as_string > (int)sizeof(buf)-1) {
   1837  1.1.1.2  christos 			return -1;
   1838  1.1.1.2  christos 		}
   1839  1.1.1.2  christos 		memcpy(buf, ip_as_string, cp-ip_as_string);
   1840  1.1.1.2  christos 		buf[cp-ip_as_string] = '\0';
   1841  1.1.1.2  christos 		addr_part = buf;
   1842  1.1.1.2  christos 		port_part = cp+1;
   1843  1.1.1.2  christos 	} else {
   1844  1.1.1.2  christos 		addr_part = ip_as_string;
   1845  1.1.1.2  christos 		port_part = NULL;
   1846  1.1.1.2  christos 		is_ipv6 = 0;
   1847  1.1.1.2  christos 	}
   1848  1.1.1.2  christos 
   1849  1.1.1.2  christos 	if (port_part == NULL) {
   1850  1.1.1.2  christos 		port = 0;
   1851  1.1.1.2  christos 	} else {
   1852  1.1.1.2  christos 		port = atoi(port_part);
   1853  1.1.1.2  christos 		if (port <= 0 || port > 65535) {
   1854  1.1.1.2  christos 			return -1;
   1855  1.1.1.2  christos 		}
   1856  1.1.1.2  christos 	}
   1857  1.1.1.2  christos 
   1858  1.1.1.2  christos 	if (!addr_part)
   1859  1.1.1.2  christos 		return -1; /* Should be impossible. */
   1860  1.1.1.2  christos #ifdef AF_INET6
   1861  1.1.1.2  christos 	if (is_ipv6)
   1862  1.1.1.2  christos 	{
   1863  1.1.1.2  christos 		struct sockaddr_in6 sin6;
   1864  1.1.1.2  christos 		memset(&sin6, 0, sizeof(sin6));
   1865  1.1.1.2  christos #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
   1866  1.1.1.2  christos 		sin6.sin6_len = sizeof(sin6);
   1867  1.1.1.2  christos #endif
   1868  1.1.1.2  christos 		sin6.sin6_family = AF_INET6;
   1869  1.1.1.2  christos 		sin6.sin6_port = htons(port);
   1870  1.1.1.2  christos 		if (1 != evutil_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr))
   1871  1.1.1.2  christos 			return -1;
   1872  1.1.1.2  christos 		if ((int)sizeof(sin6) > *outlen)
   1873  1.1.1.2  christos 			return -1;
   1874  1.1.1.2  christos 		memset(out, 0, *outlen);
   1875  1.1.1.2  christos 		memcpy(out, &sin6, sizeof(sin6));
   1876  1.1.1.2  christos 		*outlen = sizeof(sin6);
   1877  1.1.1.2  christos 		return 0;
   1878  1.1.1.2  christos 	}
   1879  1.1.1.2  christos 	else
   1880  1.1.1.2  christos #endif
   1881  1.1.1.2  christos 	{
   1882  1.1.1.2  christos 		struct sockaddr_in sin;
   1883  1.1.1.2  christos 		memset(&sin, 0, sizeof(sin));
   1884  1.1.1.2  christos #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
   1885  1.1.1.2  christos 		sin.sin_len = sizeof(sin);
   1886  1.1.1.2  christos #endif
   1887  1.1.1.2  christos 		sin.sin_family = AF_INET;
   1888  1.1.1.2  christos 		sin.sin_port = htons(port);
   1889  1.1.1.2  christos 		if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr))
   1890  1.1.1.2  christos 			return -1;
   1891  1.1.1.2  christos 		if ((int)sizeof(sin) > *outlen)
   1892  1.1.1.2  christos 			return -1;
   1893  1.1.1.2  christos 		memset(out, 0, *outlen);
   1894  1.1.1.2  christos 		memcpy(out, &sin, sizeof(sin));
   1895  1.1.1.2  christos 		*outlen = sizeof(sin);
   1896  1.1.1.2  christos 		return 0;
   1897  1.1.1.2  christos 	}
   1898  1.1.1.2  christos }
   1899  1.1.1.2  christos 
   1900  1.1.1.2  christos const char *
   1901  1.1.1.2  christos evutil_format_sockaddr_port(const struct sockaddr *sa, char *out, size_t outlen)
   1902  1.1.1.2  christos {
   1903  1.1.1.2  christos 	char b[128];
   1904  1.1.1.2  christos 	const char *res=NULL;
   1905  1.1.1.2  christos 	int port;
   1906  1.1.1.2  christos 	if (sa->sa_family == AF_INET) {
   1907  1.1.1.2  christos 		const struct sockaddr_in *sin = (const struct sockaddr_in*)sa;
   1908  1.1.1.2  christos 		res = evutil_inet_ntop(AF_INET, &sin->sin_addr,b,sizeof(b));
   1909  1.1.1.2  christos 		port = ntohs(sin->sin_port);
   1910  1.1.1.2  christos 		if (res) {
   1911  1.1.1.2  christos 			evutil_snprintf(out, outlen, "%s:%d", b, port);
   1912  1.1.1.2  christos 			return out;
   1913  1.1.1.2  christos 		}
   1914  1.1.1.2  christos 	} else if (sa->sa_family == AF_INET6) {
   1915  1.1.1.2  christos 		const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6*)sa;
   1916  1.1.1.2  christos 		res = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr,b,sizeof(b));
   1917  1.1.1.2  christos 		port = ntohs(sin6->sin6_port);
   1918  1.1.1.2  christos 		if (res) {
   1919  1.1.1.2  christos 			evutil_snprintf(out, outlen, "[%s]:%d", b, port);
   1920  1.1.1.2  christos 			return out;
   1921  1.1.1.2  christos 		}
   1922  1.1.1.2  christos 	}
   1923  1.1.1.2  christos 
   1924  1.1.1.2  christos 	evutil_snprintf(out, outlen, "<addr with socktype %d>",
   1925  1.1.1.2  christos 	    (int)sa->sa_family);
   1926  1.1.1.2  christos 	return out;
   1927  1.1.1.2  christos }
   1928  1.1.1.2  christos 
   1929  1.1.1.2  christos int
   1930  1.1.1.2  christos evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
   1931  1.1.1.2  christos     int include_port)
   1932  1.1.1.2  christos {
   1933  1.1.1.2  christos 	int r;
   1934  1.1.1.2  christos 	if (0 != (r = (sa1->sa_family - sa2->sa_family)))
   1935  1.1.1.2  christos 		return r;
   1936  1.1.1.2  christos 
   1937  1.1.1.2  christos 	if (sa1->sa_family == AF_INET) {
   1938  1.1.1.2  christos 		const struct sockaddr_in *sin1, *sin2;
   1939  1.1.1.2  christos 		sin1 = (const struct sockaddr_in *)sa1;
   1940  1.1.1.2  christos 		sin2 = (const struct sockaddr_in *)sa2;
   1941  1.1.1.2  christos 		if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
   1942  1.1.1.2  christos 			return -1;
   1943  1.1.1.2  christos 		else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
   1944  1.1.1.2  christos 			return 1;
   1945  1.1.1.2  christos 		else if (include_port &&
   1946  1.1.1.2  christos 		    (r = ((int)sin1->sin_port - (int)sin2->sin_port)))
   1947  1.1.1.2  christos 			return r;
   1948  1.1.1.2  christos 		else
   1949  1.1.1.2  christos 			return 0;
   1950  1.1.1.2  christos 	}
   1951  1.1.1.2  christos #ifdef AF_INET6
   1952  1.1.1.2  christos 	else if (sa1->sa_family == AF_INET6) {
   1953  1.1.1.2  christos 		const struct sockaddr_in6 *sin1, *sin2;
   1954  1.1.1.2  christos 		sin1 = (const struct sockaddr_in6 *)sa1;
   1955  1.1.1.2  christos 		sin2 = (const struct sockaddr_in6 *)sa2;
   1956  1.1.1.2  christos 		if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
   1957  1.1.1.2  christos 			return r;
   1958  1.1.1.2  christos 		else if (include_port &&
   1959  1.1.1.2  christos 		    (r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
   1960  1.1.1.2  christos 			return r;
   1961  1.1.1.2  christos 		else
   1962  1.1.1.2  christos 			return 0;
   1963  1.1.1.2  christos 	}
   1964      1.1    plunky #endif
   1965  1.1.1.2  christos 	return 1;
   1966      1.1    plunky }
   1967  1.1.1.2  christos 
   1968  1.1.1.2  christos /* Tables to implement ctypes-replacement EVUTIL_IS*() functions.  Each table
   1969  1.1.1.2  christos  * has 256 bits to look up whether a character is in some set or not.  This
   1970  1.1.1.2  christos  * fails on non-ASCII platforms, but so does every other place where we
   1971  1.1.1.2  christos  * take a char and write it onto the network.
   1972  1.1.1.2  christos  **/
   1973  1.1.1.2  christos static const ev_uint32_t EVUTIL_ISALPHA_TABLE[8] =
   1974  1.1.1.2  christos   { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
   1975  1.1.1.2  christos static const ev_uint32_t EVUTIL_ISALNUM_TABLE[8] =
   1976  1.1.1.2  christos   { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
   1977  1.1.1.2  christos static const ev_uint32_t EVUTIL_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
   1978  1.1.1.2  christos static const ev_uint32_t EVUTIL_ISXDIGIT_TABLE[8] =
   1979  1.1.1.2  christos   { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
   1980  1.1.1.2  christos static const ev_uint32_t EVUTIL_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
   1981  1.1.1.2  christos static const ev_uint32_t EVUTIL_ISPRINT_TABLE[8] =
   1982  1.1.1.2  christos   { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
   1983  1.1.1.2  christos static const ev_uint32_t EVUTIL_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
   1984  1.1.1.2  christos static const ev_uint32_t EVUTIL_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
   1985  1.1.1.2  christos /* Upper-casing and lowercasing tables to map characters to upper/lowercase
   1986  1.1.1.2  christos  * equivalents. */
   1987  1.1.1.2  christos static const unsigned char EVUTIL_TOUPPER_TABLE[256] = {
   1988  1.1.1.2  christos   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
   1989  1.1.1.2  christos   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
   1990  1.1.1.2  christos   32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
   1991  1.1.1.2  christos   48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
   1992  1.1.1.2  christos   64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
   1993  1.1.1.2  christos   80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
   1994  1.1.1.2  christos   96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
   1995  1.1.1.2  christos   80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
   1996  1.1.1.2  christos   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
   1997  1.1.1.2  christos   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
   1998  1.1.1.2  christos   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
   1999  1.1.1.2  christos   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
   2000  1.1.1.2  christos   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
   2001  1.1.1.2  christos   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
   2002  1.1.1.2  christos   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
   2003  1.1.1.2  christos   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
   2004  1.1.1.2  christos };
   2005  1.1.1.2  christos static const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
   2006  1.1.1.2  christos   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
   2007  1.1.1.2  christos   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
   2008  1.1.1.2  christos   32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
   2009  1.1.1.2  christos   48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
   2010  1.1.1.2  christos   64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
   2011  1.1.1.2  christos   112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
   2012  1.1.1.2  christos   96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
   2013  1.1.1.2  christos   112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
   2014  1.1.1.2  christos   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
   2015  1.1.1.2  christos   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
   2016  1.1.1.2  christos   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
   2017  1.1.1.2  christos   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
   2018  1.1.1.2  christos   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
   2019  1.1.1.2  christos   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
   2020  1.1.1.2  christos   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
   2021  1.1.1.2  christos   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
   2022  1.1.1.2  christos };
   2023  1.1.1.2  christos 
   2024  1.1.1.2  christos #define IMPL_CTYPE_FN(name)						\
   2025  1.1.1.2  christos 	int EVUTIL_##name(char c) {					\
   2026  1.1.1.2  christos 		ev_uint8_t u = c;					\
   2027  1.1.1.2  christos 		return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31))); \
   2028  1.1.1.2  christos 	}
   2029  1.1.1.2  christos IMPL_CTYPE_FN(ISALPHA)
   2030  1.1.1.2  christos IMPL_CTYPE_FN(ISALNUM)
   2031  1.1.1.2  christos IMPL_CTYPE_FN(ISSPACE)
   2032  1.1.1.2  christos IMPL_CTYPE_FN(ISDIGIT)
   2033  1.1.1.2  christos IMPL_CTYPE_FN(ISXDIGIT)
   2034  1.1.1.2  christos IMPL_CTYPE_FN(ISPRINT)
   2035  1.1.1.2  christos IMPL_CTYPE_FN(ISLOWER)
   2036  1.1.1.2  christos IMPL_CTYPE_FN(ISUPPER)
   2037  1.1.1.2  christos 
   2038  1.1.1.2  christos char EVUTIL_TOLOWER(char c)
   2039  1.1.1.2  christos {
   2040  1.1.1.2  christos 	return ((char)EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]);
   2041  1.1.1.2  christos }
   2042  1.1.1.2  christos char EVUTIL_TOUPPER(char c)
   2043  1.1.1.2  christos {
   2044  1.1.1.2  christos 	return ((char)EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]);
   2045  1.1.1.2  christos }
   2046  1.1.1.2  christos int
   2047  1.1.1.2  christos evutil_ascii_strcasecmp(const char *s1, const char *s2)
   2048  1.1.1.2  christos {
   2049  1.1.1.2  christos 	char c1, c2;
   2050  1.1.1.2  christos 	while (1) {
   2051  1.1.1.2  christos 		c1 = EVUTIL_TOLOWER(*s1++);
   2052  1.1.1.2  christos 		c2 = EVUTIL_TOLOWER(*s2++);
   2053  1.1.1.2  christos 		if (c1 < c2)
   2054  1.1.1.2  christos 			return -1;
   2055  1.1.1.2  christos 		else if (c1 > c2)
   2056  1.1.1.2  christos 			return 1;
   2057  1.1.1.2  christos 		else if (c1 == 0)
   2058  1.1.1.2  christos 			return 0;
   2059  1.1.1.2  christos 	}
   2060  1.1.1.2  christos }
   2061  1.1.1.2  christos int evutil_ascii_strncasecmp(const char *s1, const char *s2, size_t n)
   2062  1.1.1.2  christos {
   2063  1.1.1.2  christos 	char c1, c2;
   2064  1.1.1.2  christos 	while (n--) {
   2065  1.1.1.2  christos 		c1 = EVUTIL_TOLOWER(*s1++);
   2066  1.1.1.2  christos 		c2 = EVUTIL_TOLOWER(*s2++);
   2067  1.1.1.2  christos 		if (c1 < c2)
   2068  1.1.1.2  christos 			return -1;
   2069  1.1.1.2  christos 		else if (c1 > c2)
   2070  1.1.1.2  christos 			return 1;
   2071  1.1.1.2  christos 		else if (c1 == 0)
   2072  1.1.1.2  christos 			return 0;
   2073  1.1.1.2  christos 	}
   2074  1.1.1.2  christos 	return 0;
   2075  1.1.1.2  christos }
   2076  1.1.1.2  christos 
   2077  1.1.1.2  christos static int
   2078  1.1.1.2  christos evutil_issetugid(void)
   2079  1.1.1.2  christos {
   2080  1.1.1.2  christos #ifdef _EVENT_HAVE_ISSETUGID
   2081  1.1.1.2  christos 	return issetugid();
   2082  1.1.1.2  christos #else
   2083  1.1.1.2  christos 
   2084  1.1.1.2  christos #ifdef _EVENT_HAVE_GETEUID
   2085  1.1.1.2  christos 	if (getuid() != geteuid())
   2086  1.1.1.2  christos 		return 1;
   2087  1.1.1.2  christos #endif
   2088  1.1.1.2  christos #ifdef _EVENT_HAVE_GETEGID
   2089  1.1.1.2  christos 	if (getgid() != getegid())
   2090  1.1.1.2  christos 		return 1;
   2091  1.1.1.2  christos #endif
   2092  1.1.1.2  christos 	return 0;
   2093  1.1.1.2  christos #endif
   2094  1.1.1.2  christos }
   2095  1.1.1.2  christos 
   2096  1.1.1.2  christos const char *
   2097  1.1.1.2  christos evutil_getenv(const char *varname)
   2098  1.1.1.2  christos {
   2099  1.1.1.2  christos 	if (evutil_issetugid())
   2100  1.1.1.2  christos 		return NULL;
   2101  1.1.1.2  christos 
   2102  1.1.1.2  christos 	return getenv(varname);
   2103  1.1.1.2  christos }
   2104  1.1.1.2  christos 
   2105  1.1.1.2  christos long
   2106  1.1.1.2  christos _evutil_weakrand(void)
   2107  1.1.1.2  christos {
   2108  1.1.1.2  christos #ifdef WIN32
   2109  1.1.1.2  christos 	return rand();
   2110  1.1.1.2  christos #else
   2111  1.1.1.2  christos 	return random();
   2112  1.1.1.2  christos #endif
   2113  1.1.1.2  christos }
   2114  1.1.1.2  christos 
   2115  1.1.1.3       spz /**
   2116  1.1.1.3       spz  * Volatile pointer to memset: we use this to keep the compiler from
   2117  1.1.1.3       spz  * eliminating our call to memset.
   2118  1.1.1.3       spz  */
   2119  1.1.1.3       spz void * (*volatile evutil_memset_volatile_)(void *, int, size_t) = memset;
   2120  1.1.1.3       spz 
   2121  1.1.1.3       spz void
   2122  1.1.1.3       spz evutil_memclear_(void *mem, size_t len)
   2123  1.1.1.3       spz {
   2124  1.1.1.3       spz 	evutil_memset_volatile_(mem, 0, len);
   2125  1.1.1.3       spz }
   2126  1.1.1.3       spz 
   2127  1.1.1.2  christos int
   2128  1.1.1.2  christos evutil_sockaddr_is_loopback(const struct sockaddr *addr)
   2129  1.1.1.2  christos {
   2130  1.1.1.2  christos 	static const char LOOPBACK_S6[16] =
   2131  1.1.1.2  christos 	    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
   2132  1.1.1.2  christos 	if (addr->sa_family == AF_INET) {
   2133  1.1.1.2  christos 		struct sockaddr_in *sin = (struct sockaddr_in *)addr;
   2134  1.1.1.2  christos 		return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
   2135  1.1.1.2  christos 	} else if (addr->sa_family == AF_INET6) {
   2136  1.1.1.2  christos 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
   2137  1.1.1.2  christos 		return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
   2138  1.1.1.2  christos 	}
   2139  1.1.1.2  christos 	return 0;
   2140  1.1.1.2  christos }
   2141  1.1.1.2  christos 
   2142  1.1.1.2  christos #define MAX_SECONDS_IN_MSEC_LONG \
   2143  1.1.1.2  christos 	(((LONG_MAX) - 999) / 1000)
   2144  1.1.1.2  christos 
   2145  1.1.1.2  christos long
   2146  1.1.1.2  christos evutil_tv_to_msec(const struct timeval *tv)
   2147  1.1.1.2  christos {
   2148  1.1.1.2  christos 	if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
   2149  1.1.1.2  christos 		return -1;
   2150  1.1.1.2  christos 
   2151  1.1.1.2  christos 	return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
   2152  1.1.1.2  christos }
   2153  1.1.1.2  christos 
   2154  1.1.1.2  christos int
   2155  1.1.1.2  christos evutil_hex_char_to_int(char c)
   2156  1.1.1.2  christos {
   2157  1.1.1.2  christos 	switch(c)
   2158  1.1.1.2  christos 	{
   2159  1.1.1.2  christos 		case '0': return 0;
   2160  1.1.1.2  christos 		case '1': return 1;
   2161  1.1.1.2  christos 		case '2': return 2;
   2162  1.1.1.2  christos 		case '3': return 3;
   2163  1.1.1.2  christos 		case '4': return 4;
   2164  1.1.1.2  christos 		case '5': return 5;
   2165  1.1.1.2  christos 		case '6': return 6;
   2166  1.1.1.2  christos 		case '7': return 7;
   2167  1.1.1.2  christos 		case '8': return 8;
   2168  1.1.1.2  christos 		case '9': return 9;
   2169  1.1.1.2  christos 		case 'A': case 'a': return 10;
   2170  1.1.1.2  christos 		case 'B': case 'b': return 11;
   2171  1.1.1.2  christos 		case 'C': case 'c': return 12;
   2172  1.1.1.2  christos 		case 'D': case 'd': return 13;
   2173  1.1.1.2  christos 		case 'E': case 'e': return 14;
   2174  1.1.1.2  christos 		case 'F': case 'f': return 15;
   2175  1.1.1.2  christos 	}
   2176  1.1.1.2  christos 	return -1;
   2177  1.1.1.2  christos }
   2178  1.1.1.2  christos 
   2179  1.1.1.2  christos #ifdef WIN32
   2180  1.1.1.2  christos HANDLE
   2181  1.1.1.2  christos evutil_load_windows_system_library(const TCHAR *library_name)
   2182  1.1.1.2  christos {
   2183  1.1.1.2  christos   TCHAR path[MAX_PATH];
   2184  1.1.1.2  christos   unsigned n;
   2185  1.1.1.2  christos   n = GetSystemDirectory(path, MAX_PATH);
   2186  1.1.1.2  christos   if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
   2187  1.1.1.2  christos     return 0;
   2188  1.1.1.2  christos   _tcscat(path, TEXT("\\"));
   2189  1.1.1.2  christos   _tcscat(path, library_name);
   2190  1.1.1.2  christos   return LoadLibrary(path);
   2191  1.1.1.2  christos }
   2192  1.1.1.2  christos #endif
   2193  1.1.1.2  christos 
   2194