ipc/chromium/src/third_party/libevent/evutil.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/third_party/libevent/evutil.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,2178 @@
     1.4 +/*
     1.5 + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
     1.6 + *
     1.7 + * Redistribution and use in source and binary forms, with or without
     1.8 + * modification, are permitted provided that the following conditions
     1.9 + * are met:
    1.10 + * 1. Redistributions of source code must retain the above copyright
    1.11 + *    notice, this list of conditions and the following disclaimer.
    1.12 + * 2. Redistributions in binary form must reproduce the above copyright
    1.13 + *    notice, this list of conditions and the following disclaimer in the
    1.14 + *    documentation and/or other materials provided with the distribution.
    1.15 + * 3. The name of the author may not be used to endorse or promote products
    1.16 + *    derived from this software without specific prior written permission.
    1.17 + *
    1.18 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    1.19 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    1.20 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    1.21 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    1.22 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1.23 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.24 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.25 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.26 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    1.27 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.28 + */
    1.29 +
    1.30 +#include "event2/event-config.h"
    1.31 +
    1.32 +#define _GNU_SOURCE
    1.33 +
    1.34 +#ifdef WIN32
    1.35 +#include <winsock2.h>
    1.36 +#include <ws2tcpip.h>
    1.37 +#define WIN32_LEAN_AND_MEAN
    1.38 +#include <windows.h>
    1.39 +#undef WIN32_LEAN_AND_MEAN
    1.40 +#include <io.h>
    1.41 +#include <tchar.h>
    1.42 +#endif
    1.43 +
    1.44 +#include <sys/types.h>
    1.45 +#ifdef _EVENT_HAVE_SYS_SOCKET_H
    1.46 +#include <sys/socket.h>
    1.47 +#endif
    1.48 +#ifdef _EVENT_HAVE_UNISTD_H
    1.49 +#include <unistd.h>
    1.50 +#endif
    1.51 +#ifdef _EVENT_HAVE_FCNTL_H
    1.52 +#include <fcntl.h>
    1.53 +#endif
    1.54 +#ifdef _EVENT_HAVE_STDLIB_H
    1.55 +#include <stdlib.h>
    1.56 +#endif
    1.57 +#include <errno.h>
    1.58 +#include <limits.h>
    1.59 +#include <stdio.h>
    1.60 +#include <string.h>
    1.61 +#ifdef _EVENT_HAVE_NETINET_IN_H
    1.62 +#include <netinet/in.h>
    1.63 +#endif
    1.64 +#ifdef _EVENT_HAVE_NETINET_IN6_H
    1.65 +#include <netinet/in6.h>
    1.66 +#endif
    1.67 +#ifdef _EVENT_HAVE_ARPA_INET_H
    1.68 +#include <arpa/inet.h>
    1.69 +#endif
    1.70 +
    1.71 +#ifndef _EVENT_HAVE_GETTIMEOFDAY
    1.72 +#include <sys/timeb.h>
    1.73 +#include <time.h>
    1.74 +#endif
    1.75 +#include <sys/stat.h>
    1.76 +
    1.77 +#include "event2/util.h"
    1.78 +#include "util-internal.h"
    1.79 +#include "log-internal.h"
    1.80 +#include "mm-internal.h"
    1.81 +
    1.82 +#include "strlcpy-internal.h"
    1.83 +#include "ipv6-internal.h"
    1.84 +
    1.85 +#ifdef WIN32
    1.86 +#define open _open
    1.87 +#define read _read
    1.88 +#define close _close
    1.89 +#define fstat _fstati64
    1.90 +#define stat _stati64
    1.91 +#define mode_t int
    1.92 +#endif
    1.93 +
    1.94 +int
    1.95 +evutil_open_closeonexec(const char *pathname, int flags, unsigned mode)
    1.96 +{
    1.97 +	int fd;
    1.98 +
    1.99 +#ifdef O_CLOEXEC
   1.100 +	flags |= O_CLOEXEC;
   1.101 +#endif
   1.102 +
   1.103 +	if (flags & O_CREAT)
   1.104 +		fd = open(pathname, flags, (mode_t)mode);
   1.105 +	else
   1.106 +		fd = open(pathname, flags);
   1.107 +	if (fd < 0)
   1.108 +		return -1;
   1.109 +
   1.110 +#if !defined(O_CLOEXEC) && defined(FD_CLOEXEC)
   1.111 +	if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
   1.112 +		return -1;
   1.113 +#endif
   1.114 +
   1.115 +	return fd;
   1.116 +}
   1.117 +
   1.118 +/**
   1.119 +   Read the contents of 'filename' into a newly allocated NUL-terminated
   1.120 +   string.  Set *content_out to hold this string, and *len_out to hold its
   1.121 +   length (not including the appended NUL).  If 'is_binary', open the file in
   1.122 +   binary mode.
   1.123 +
   1.124 +   Returns 0 on success, -1 if the open fails, and -2 for all other failures.
   1.125 +
   1.126 +   Used internally only; may go away in a future version.
   1.127 + */
   1.128 +int
   1.129 +evutil_read_file(const char *filename, char **content_out, size_t *len_out,
   1.130 +    int is_binary)
   1.131 +{
   1.132 +	int fd, r;
   1.133 +	struct stat st;
   1.134 +	char *mem;
   1.135 +	size_t read_so_far=0;
   1.136 +	int mode = O_RDONLY;
   1.137 +
   1.138 +	EVUTIL_ASSERT(content_out);
   1.139 +	EVUTIL_ASSERT(len_out);
   1.140 +	*content_out = NULL;
   1.141 +	*len_out = 0;
   1.142 +
   1.143 +#ifdef O_BINARY
   1.144 +	if (is_binary)
   1.145 +		mode |= O_BINARY;
   1.146 +#endif
   1.147 +
   1.148 +	fd = evutil_open_closeonexec(filename, mode, 0);
   1.149 +	if (fd < 0)
   1.150 +		return -1;
   1.151 +	if (fstat(fd, &st) || st.st_size < 0 ||
   1.152 +	    st.st_size > EV_SSIZE_MAX-1 ) {
   1.153 +		close(fd);
   1.154 +		return -2;
   1.155 +	}
   1.156 +	mem = mm_malloc((size_t)st.st_size + 1);
   1.157 +	if (!mem) {
   1.158 +		close(fd);
   1.159 +		return -2;
   1.160 +	}
   1.161 +	read_so_far = 0;
   1.162 +#ifdef WIN32
   1.163 +#define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x))
   1.164 +#else
   1.165 +#define N_TO_READ(x) (x)
   1.166 +#endif
   1.167 +	while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) {
   1.168 +		read_so_far += r;
   1.169 +		if (read_so_far >= (size_t)st.st_size)
   1.170 +			break;
   1.171 +		EVUTIL_ASSERT(read_so_far < (size_t)st.st_size);
   1.172 +	}
   1.173 +	close(fd);
   1.174 +	if (r < 0) {
   1.175 +		mm_free(mem);
   1.176 +		return -2;
   1.177 +	}
   1.178 +	mem[read_so_far] = 0;
   1.179 +
   1.180 +	*len_out = read_so_far;
   1.181 +	*content_out = mem;
   1.182 +	return 0;
   1.183 +}
   1.184 +
   1.185 +int
   1.186 +evutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
   1.187 +{
   1.188 +#ifndef WIN32
   1.189 +	return socketpair(family, type, protocol, fd);
   1.190 +#else
   1.191 +	return evutil_ersatz_socketpair(family, type, protocol, fd);
   1.192 +#endif
   1.193 +}
   1.194 +
   1.195 +int
   1.196 +evutil_ersatz_socketpair(int family, int type, int protocol,
   1.197 +    evutil_socket_t fd[2])
   1.198 +{
   1.199 +	/* This code is originally from Tor.  Used with permission. */
   1.200 +
   1.201 +	/* This socketpair does not work when localhost is down. So
   1.202 +	 * it's really not the same thing at all. But it's close enough
   1.203 +	 * for now, and really, when localhost is down sometimes, we
   1.204 +	 * have other problems too.
   1.205 +	 */
   1.206 +#ifdef WIN32
   1.207 +#define ERR(e) WSA##e
   1.208 +#else
   1.209 +#define ERR(e) e
   1.210 +#endif
   1.211 +	evutil_socket_t listener = -1;
   1.212 +	evutil_socket_t connector = -1;
   1.213 +	evutil_socket_t acceptor = -1;
   1.214 +	struct sockaddr_in listen_addr;
   1.215 +	struct sockaddr_in connect_addr;
   1.216 +	ev_socklen_t size;
   1.217 +	int saved_errno = -1;
   1.218 +
   1.219 +	if (protocol
   1.220 +		|| (family != AF_INET
   1.221 +#ifdef AF_UNIX
   1.222 +		    && family != AF_UNIX
   1.223 +#endif
   1.224 +		)) {
   1.225 +		EVUTIL_SET_SOCKET_ERROR(ERR(EAFNOSUPPORT));
   1.226 +		return -1;
   1.227 +	}
   1.228 +	if (!fd) {
   1.229 +		EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
   1.230 +		return -1;
   1.231 +	}
   1.232 +
   1.233 +	listener = socket(AF_INET, type, 0);
   1.234 +	if (listener < 0)
   1.235 +		return -1;
   1.236 +	memset(&listen_addr, 0, sizeof(listen_addr));
   1.237 +	listen_addr.sin_family = AF_INET;
   1.238 +	listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   1.239 +	listen_addr.sin_port = 0;	/* kernel chooses port.	 */
   1.240 +	if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
   1.241 +		== -1)
   1.242 +		goto tidy_up_and_fail;
   1.243 +	if (listen(listener, 1) == -1)
   1.244 +		goto tidy_up_and_fail;
   1.245 +
   1.246 +	connector = socket(AF_INET, type, 0);
   1.247 +	if (connector < 0)
   1.248 +		goto tidy_up_and_fail;
   1.249 +	/* We want to find out the port number to connect to.  */
   1.250 +	size = sizeof(connect_addr);
   1.251 +	if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
   1.252 +		goto tidy_up_and_fail;
   1.253 +	if (size != sizeof (connect_addr))
   1.254 +		goto abort_tidy_up_and_fail;
   1.255 +	if (connect(connector, (struct sockaddr *) &connect_addr,
   1.256 +				sizeof(connect_addr)) == -1)
   1.257 +		goto tidy_up_and_fail;
   1.258 +
   1.259 +	size = sizeof(listen_addr);
   1.260 +	acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
   1.261 +	if (acceptor < 0)
   1.262 +		goto tidy_up_and_fail;
   1.263 +	if (size != sizeof(listen_addr))
   1.264 +		goto abort_tidy_up_and_fail;
   1.265 +	evutil_closesocket(listener);
   1.266 +	/* Now check we are talking to ourself by matching port and host on the
   1.267 +	   two sockets.	 */
   1.268 +	if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
   1.269 +		goto tidy_up_and_fail;
   1.270 +	if (size != sizeof (connect_addr)
   1.271 +		|| listen_addr.sin_family != connect_addr.sin_family
   1.272 +		|| listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
   1.273 +		|| listen_addr.sin_port != connect_addr.sin_port)
   1.274 +		goto abort_tidy_up_and_fail;
   1.275 +	fd[0] = connector;
   1.276 +	fd[1] = acceptor;
   1.277 +
   1.278 +	return 0;
   1.279 +
   1.280 + abort_tidy_up_and_fail:
   1.281 +	saved_errno = ERR(ECONNABORTED);
   1.282 + tidy_up_and_fail:
   1.283 +	if (saved_errno < 0)
   1.284 +		saved_errno = EVUTIL_SOCKET_ERROR();
   1.285 +	if (listener != -1)
   1.286 +		evutil_closesocket(listener);
   1.287 +	if (connector != -1)
   1.288 +		evutil_closesocket(connector);
   1.289 +	if (acceptor != -1)
   1.290 +		evutil_closesocket(acceptor);
   1.291 +
   1.292 +	EVUTIL_SET_SOCKET_ERROR(saved_errno);
   1.293 +	return -1;
   1.294 +#undef ERR
   1.295 +}
   1.296 +
   1.297 +int
   1.298 +evutil_make_socket_nonblocking(evutil_socket_t fd)
   1.299 +{
   1.300 +#ifdef WIN32
   1.301 +	{
   1.302 +		u_long nonblocking = 1;
   1.303 +		if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) {
   1.304 +			event_sock_warn(fd, "fcntl(%d, F_GETFL)", (int)fd);
   1.305 +			return -1;
   1.306 +		}
   1.307 +	}
   1.308 +#else
   1.309 +	{
   1.310 +		int flags;
   1.311 +		if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
   1.312 +			event_warn("fcntl(%d, F_GETFL)", fd);
   1.313 +			return -1;
   1.314 +		}
   1.315 +		if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
   1.316 +			event_warn("fcntl(%d, F_SETFL)", fd);
   1.317 +			return -1;
   1.318 +		}
   1.319 +	}
   1.320 +#endif
   1.321 +	return 0;
   1.322 +}
   1.323 +
   1.324 +int
   1.325 +evutil_make_listen_socket_reuseable(evutil_socket_t sock)
   1.326 +{
   1.327 +#ifndef WIN32
   1.328 +	int one = 1;
   1.329 +	/* REUSEADDR on Unix means, "don't hang on to this address after the
   1.330 +	 * listener is closed."  On Windows, though, it means "don't keep other
   1.331 +	 * processes from binding to this address while we're using it. */
   1.332 +	return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
   1.333 +	    (ev_socklen_t)sizeof(one));
   1.334 +#else
   1.335 +	return 0;
   1.336 +#endif
   1.337 +}
   1.338 +
   1.339 +int
   1.340 +evutil_make_socket_closeonexec(evutil_socket_t fd)
   1.341 +{
   1.342 +#if !defined(WIN32) && defined(_EVENT_HAVE_SETFD)
   1.343 +	int flags;
   1.344 +	if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) {
   1.345 +		event_warn("fcntl(%d, F_GETFD)", fd);
   1.346 +		return -1;
   1.347 +	}
   1.348 +	if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
   1.349 +		event_warn("fcntl(%d, F_SETFD)", fd);
   1.350 +		return -1;
   1.351 +	}
   1.352 +#endif
   1.353 +	return 0;
   1.354 +}
   1.355 +
   1.356 +int
   1.357 +evutil_closesocket(evutil_socket_t sock)
   1.358 +{
   1.359 +#ifndef WIN32
   1.360 +	return close(sock);
   1.361 +#else
   1.362 +	return closesocket(sock);
   1.363 +#endif
   1.364 +}
   1.365 +
   1.366 +ev_int64_t
   1.367 +evutil_strtoll(const char *s, char **endptr, int base)
   1.368 +{
   1.369 +#ifdef _EVENT_HAVE_STRTOLL
   1.370 +	return (ev_int64_t)strtoll(s, endptr, base);
   1.371 +#elif _EVENT_SIZEOF_LONG == 8
   1.372 +	return (ev_int64_t)strtol(s, endptr, base);
   1.373 +#elif defined(WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
   1.374 +	/* XXXX on old versions of MS APIs, we only support base
   1.375 +	 * 10. */
   1.376 +	ev_int64_t r;
   1.377 +	if (base != 10)
   1.378 +		return 0;
   1.379 +	r = (ev_int64_t) _atoi64(s);
   1.380 +	while (isspace(*s))
   1.381 +		++s;
   1.382 +	if (*s == '-')
   1.383 +		++s;
   1.384 +	while (isdigit(*s))
   1.385 +		++s;
   1.386 +	if (endptr)
   1.387 +		*endptr = (char*) s;
   1.388 +	return r;
   1.389 +#elif defined(WIN32)
   1.390 +	return (ev_int64_t) _strtoi64(s, endptr, base);
   1.391 +#elif defined(_EVENT_SIZEOF_LONG_LONG) && _EVENT_SIZEOF_LONG_LONG == 8
   1.392 +	long long r;
   1.393 +	int n;
   1.394 +	if (base != 10 && base != 16)
   1.395 +		return 0;
   1.396 +	if (base == 10) {
   1.397 +		n = sscanf(s, "%lld", &r);
   1.398 +	} else {
   1.399 +		unsigned long long ru=0;
   1.400 +		n = sscanf(s, "%llx", &ru);
   1.401 +		if (ru > EV_INT64_MAX)
   1.402 +			return 0;
   1.403 +		r = (long long) ru;
   1.404 +	}
   1.405 +	if (n != 1)
   1.406 +		return 0;
   1.407 +	while (EVUTIL_ISSPACE(*s))
   1.408 +		++s;
   1.409 +	if (*s == '-')
   1.410 +		++s;
   1.411 +	if (base == 10) {
   1.412 +		while (EVUTIL_ISDIGIT(*s))
   1.413 +			++s;
   1.414 +	} else {
   1.415 +		while (EVUTIL_ISXDIGIT(*s))
   1.416 +			++s;
   1.417 +	}
   1.418 +	if (endptr)
   1.419 +		*endptr = (char*) s;
   1.420 +	return r;
   1.421 +#else
   1.422 +#error "I don't know how to parse 64-bit integers."
   1.423 +#endif
   1.424 +}
   1.425 +
   1.426 +#ifndef _EVENT_HAVE_GETTIMEOFDAY
   1.427 +/* No gettimeofday; this muse be windows. */
   1.428 +int
   1.429 +evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
   1.430 +{
   1.431 +	struct _timeb tb;
   1.432 +
   1.433 +	if (tv == NULL)
   1.434 +		return -1;
   1.435 +
   1.436 +	/* XXXX
   1.437 +	 * _ftime is not the greatest interface here; GetSystemTimeAsFileTime
   1.438 +	 * would give us better resolution, whereas something cobbled together
   1.439 +	 * with GetTickCount could maybe give us monotonic behavior.
   1.440 +	 *
   1.441 +	 * Either way, I think this value might be skewed to ignore the
   1.442 +	 * timezone, and just return local time.  That's not so good.
   1.443 +	 */
   1.444 +	_ftime(&tb);
   1.445 +	tv->tv_sec = (long) tb.time;
   1.446 +	tv->tv_usec = ((int) tb.millitm) * 1000;
   1.447 +	return 0;
   1.448 +}
   1.449 +#endif
   1.450 +
   1.451 +#ifdef WIN32
   1.452 +int
   1.453 +evutil_socket_geterror(evutil_socket_t sock)
   1.454 +{
   1.455 +	int optval, optvallen=sizeof(optval);
   1.456 +	int err = WSAGetLastError();
   1.457 +	if (err == WSAEWOULDBLOCK && sock >= 0) {
   1.458 +		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
   1.459 +					   &optvallen))
   1.460 +			return err;
   1.461 +		if (optval)
   1.462 +			return optval;
   1.463 +	}
   1.464 +	return err;
   1.465 +}
   1.466 +#endif
   1.467 +
   1.468 +/* XXX we should use an enum here. */
   1.469 +/* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
   1.470 +int
   1.471 +evutil_socket_connect(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen)
   1.472 +{
   1.473 +	int made_fd = 0;
   1.474 +
   1.475 +	if (*fd_ptr < 0) {
   1.476 +		if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
   1.477 +			goto err;
   1.478 +		made_fd = 1;
   1.479 +		if (evutil_make_socket_nonblocking(*fd_ptr) < 0) {
   1.480 +			goto err;
   1.481 +		}
   1.482 +	}
   1.483 +
   1.484 +	if (connect(*fd_ptr, sa, socklen) < 0) {
   1.485 +		int e = evutil_socket_geterror(*fd_ptr);
   1.486 +		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
   1.487 +			return 0;
   1.488 +		if (EVUTIL_ERR_CONNECT_REFUSED(e))
   1.489 +			return 2;
   1.490 +		goto err;
   1.491 +	} else {
   1.492 +		return 1;
   1.493 +	}
   1.494 +
   1.495 +err:
   1.496 +	if (made_fd) {
   1.497 +		evutil_closesocket(*fd_ptr);
   1.498 +		*fd_ptr = -1;
   1.499 +	}
   1.500 +	return -1;
   1.501 +}
   1.502 +
   1.503 +/* Check whether a socket on which we called connect() is done
   1.504 +   connecting. Return 1 for connected, 0 for not yet, -1 for error.  In the
   1.505 +   error case, set the current socket errno to the error that happened during
   1.506 +   the connect operation. */
   1.507 +int
   1.508 +evutil_socket_finished_connecting(evutil_socket_t fd)
   1.509 +{
   1.510 +	int e;
   1.511 +	ev_socklen_t elen = sizeof(e);
   1.512 +
   1.513 +	if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
   1.514 +		return -1;
   1.515 +
   1.516 +	if (e) {
   1.517 +		if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
   1.518 +			return 0;
   1.519 +		EVUTIL_SET_SOCKET_ERROR(e);
   1.520 +		return -1;
   1.521 +	}
   1.522 +
   1.523 +	return 1;
   1.524 +}
   1.525 +
   1.526 +#if (EVUTIL_AI_PASSIVE|EVUTIL_AI_CANONNAME|EVUTIL_AI_NUMERICHOST| \
   1.527 +     EVUTIL_AI_NUMERICSERV|EVUTIL_AI_V4MAPPED|EVUTIL_AI_ALL| \
   1.528 +     EVUTIL_AI_ADDRCONFIG) != \
   1.529 +    (EVUTIL_AI_PASSIVE^EVUTIL_AI_CANONNAME^EVUTIL_AI_NUMERICHOST^ \
   1.530 +     EVUTIL_AI_NUMERICSERV^EVUTIL_AI_V4MAPPED^EVUTIL_AI_ALL^ \
   1.531 +     EVUTIL_AI_ADDRCONFIG)
   1.532 +#error "Some of our EVUTIL_AI_* flags seem to overlap with system AI_* flags"
   1.533 +#endif
   1.534 +
   1.535 +/* We sometimes need to know whether we have an ipv4 address and whether we
   1.536 +   have an ipv6 address. If 'have_checked_interfaces', then we've already done
   1.537 +   the test.  If 'had_ipv4_address', then it turns out we had an ipv4 address.
   1.538 +   If 'had_ipv6_address', then it turns out we had an ipv6 address.   These are
   1.539 +   set by evutil_check_interfaces. */
   1.540 +static int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
   1.541 +
   1.542 +/* Macro: True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8
   1.543 + */
   1.544 +#define EVUTIL_V4ADDR_IS_LOCALHOST(addr) (((addr)>>24) == 127)
   1.545 +
   1.546 +/* Macro: True iff the IPv4 address 'addr', in host order, is a class D
   1.547 + * (multiclass) address.
   1.548 + */
   1.549 +#define EVUTIL_V4ADDR_IS_CLASSD(addr) ((((addr)>>24) & 0xf0) == 0xe0)
   1.550 +
   1.551 +/* Test whether we have an ipv4 interface and an ipv6 interface.  Return 0 if
   1.552 + * the test seemed successful. */
   1.553 +static int
   1.554 +evutil_check_interfaces(int force_recheck)
   1.555 +{
   1.556 +	const char ZEROES[] = "\x00\x00\x00\x00\x00\x00\x00\x00"
   1.557 +	    "\x00\x00\x00\x00\x00\x00\x00\x00";
   1.558 +	evutil_socket_t fd = -1;
   1.559 +	struct sockaddr_in sin, sin_out;
   1.560 +	struct sockaddr_in6 sin6, sin6_out;
   1.561 +	ev_socklen_t sin_out_len = sizeof(sin_out);
   1.562 +	ev_socklen_t sin6_out_len = sizeof(sin6_out);
   1.563 +	int r;
   1.564 +	char buf[128];
   1.565 +	if (have_checked_interfaces && !force_recheck)
   1.566 +		return 0;
   1.567 +
   1.568 +	/* To check whether we have an interface open for a given protocol, we
   1.569 +	 * try to make a UDP 'connection' to a remote host on the internet.
   1.570 +	 * We don't actually use it, so the address doesn't matter, but we
   1.571 +	 * want to pick one that keep us from using a host- or link-local
   1.572 +	 * interface. */
   1.573 +	memset(&sin, 0, sizeof(sin));
   1.574 +	sin.sin_family = AF_INET;
   1.575 +	sin.sin_port = htons(53);
   1.576 +	r = evutil_inet_pton(AF_INET, "18.244.0.188", &sin.sin_addr);
   1.577 +	EVUTIL_ASSERT(r);
   1.578 +
   1.579 +	memset(&sin6, 0, sizeof(sin6));
   1.580 +	sin6.sin6_family = AF_INET6;
   1.581 +	sin6.sin6_port = htons(53);
   1.582 +	r = evutil_inet_pton(AF_INET6, "2001:4860:b002::68", &sin6.sin6_addr);
   1.583 +	EVUTIL_ASSERT(r);
   1.584 +
   1.585 +	memset(&sin_out, 0, sizeof(sin_out));
   1.586 +	memset(&sin6_out, 0, sizeof(sin6_out));
   1.587 +
   1.588 +	/* XXX some errnos mean 'no address'; some mean 'not enough sockets'. */
   1.589 +	if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
   1.590 +	    connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
   1.591 +	    getsockname(fd, (struct sockaddr*)&sin_out, &sin_out_len) == 0) {
   1.592 +		/* We might have an IPv4 interface. */
   1.593 +		ev_uint32_t addr = ntohl(sin_out.sin_addr.s_addr);
   1.594 +		if (addr == 0 ||
   1.595 +		    EVUTIL_V4ADDR_IS_LOCALHOST(addr) ||
   1.596 +		    EVUTIL_V4ADDR_IS_CLASSD(addr)) {
   1.597 +			evutil_inet_ntop(AF_INET, &sin_out.sin_addr,
   1.598 +			    buf, sizeof(buf));
   1.599 +			/* This is a reserved, ipv4compat, ipv4map, loopback,
   1.600 +			 * link-local or unspecified address.  The host should
   1.601 +			 * never have given it to us; it could never connect
   1.602 +			 * to sin. */
   1.603 +			event_warnx("Got a strange local ipv4 address %s",buf);
   1.604 +		} else {
   1.605 +			event_debug(("Detected an IPv4 interface"));
   1.606 +			had_ipv4_address = 1;
   1.607 +		}
   1.608 +	}
   1.609 +	if (fd >= 0)
   1.610 +		evutil_closesocket(fd);
   1.611 +
   1.612 +	if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
   1.613 +	    connect(fd, (struct sockaddr*)&sin6, sizeof(sin6)) == 0 &&
   1.614 +	    getsockname(fd, (struct sockaddr*)&sin6_out, &sin6_out_len) == 0) {
   1.615 +		/* We might have an IPv6 interface. */
   1.616 +		const unsigned char *addr =
   1.617 +		    (unsigned char*)sin6_out.sin6_addr.s6_addr;
   1.618 +		if (!memcmp(addr, ZEROES, 8) ||
   1.619 +		    (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80)) {
   1.620 +			/* This is a reserved, ipv4compat, ipv4map, loopback,
   1.621 +			 * link-local or unspecified address.  The host should
   1.622 +			 * never have given it to us; it could never connect
   1.623 +			 * to sin6. */
   1.624 +			evutil_inet_ntop(AF_INET6, &sin6_out.sin6_addr,
   1.625 +			    buf, sizeof(buf));
   1.626 +			event_warnx("Got a strange local ipv6 address %s",buf);
   1.627 +		} else {
   1.628 +			event_debug(("Detected an IPv4 interface"));
   1.629 +			had_ipv6_address = 1;
   1.630 +		}
   1.631 +	}
   1.632 +
   1.633 +	if (fd >= 0)
   1.634 +		evutil_closesocket(fd);
   1.635 +
   1.636 +	return 0;
   1.637 +}
   1.638 +
   1.639 +/* Internal addrinfo flag.  This one is set when we allocate the addrinfo from
   1.640 + * inside libevent.  Otherwise, the built-in getaddrinfo() function allocated
   1.641 + * it, and we should trust what they said.
   1.642 + **/
   1.643 +#define EVUTIL_AI_LIBEVENT_ALLOCATED 0x80000000
   1.644 +
   1.645 +/* Helper: construct a new addrinfo containing the socket address in
   1.646 + * 'sa', which must be a sockaddr_in or a sockaddr_in6.  Take the
   1.647 + * socktype and protocol info from hints.  If they weren't set, then
   1.648 + * allocate both a TCP and a UDP addrinfo.
   1.649 + */
   1.650 +struct evutil_addrinfo *
   1.651 +evutil_new_addrinfo(struct sockaddr *sa, ev_socklen_t socklen,
   1.652 +    const struct evutil_addrinfo *hints)
   1.653 +{
   1.654 +	struct evutil_addrinfo *res;
   1.655 +	EVUTIL_ASSERT(hints);
   1.656 +
   1.657 +	if (hints->ai_socktype == 0 && hints->ai_protocol == 0) {
   1.658 +		/* Indecisive user! Give them a UDP and a TCP. */
   1.659 +		struct evutil_addrinfo *r1, *r2;
   1.660 +		struct evutil_addrinfo tmp;
   1.661 +		memcpy(&tmp, hints, sizeof(tmp));
   1.662 +		tmp.ai_socktype = SOCK_STREAM; tmp.ai_protocol = IPPROTO_TCP;
   1.663 +		r1 = evutil_new_addrinfo(sa, socklen, &tmp);
   1.664 +		if (!r1)
   1.665 +			return NULL;
   1.666 +		tmp.ai_socktype = SOCK_DGRAM; tmp.ai_protocol = IPPROTO_UDP;
   1.667 +		r2 = evutil_new_addrinfo(sa, socklen, &tmp);
   1.668 +		if (!r2) {
   1.669 +			evutil_freeaddrinfo(r1);
   1.670 +			return NULL;
   1.671 +		}
   1.672 +		r1->ai_next = r2;
   1.673 +		return r1;
   1.674 +	}
   1.675 +
   1.676 +	/* We're going to allocate extra space to hold the sockaddr. */
   1.677 +	res = mm_calloc(1,sizeof(struct evutil_addrinfo)+socklen);
   1.678 +	if (!res)
   1.679 +		return NULL;
   1.680 +	res->ai_addr = (struct sockaddr*)
   1.681 +	    (((char*)res) + sizeof(struct evutil_addrinfo));
   1.682 +	memcpy(res->ai_addr, sa, socklen);
   1.683 +	res->ai_addrlen = socklen;
   1.684 +	res->ai_family = sa->sa_family; /* Same or not? XXX */
   1.685 +	res->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
   1.686 +	res->ai_socktype = hints->ai_socktype;
   1.687 +	res->ai_protocol = hints->ai_protocol;
   1.688 +
   1.689 +	return res;
   1.690 +}
   1.691 +
   1.692 +/* Append the addrinfo 'append' to the end of 'first', and return the start of
   1.693 + * the list.  Either element can be NULL, in which case we return the element
   1.694 + * that is not NULL. */
   1.695 +struct evutil_addrinfo *
   1.696 +evutil_addrinfo_append(struct evutil_addrinfo *first,
   1.697 +    struct evutil_addrinfo *append)
   1.698 +{
   1.699 +	struct evutil_addrinfo *ai = first;
   1.700 +	if (!ai)
   1.701 +		return append;
   1.702 +	while (ai->ai_next)
   1.703 +		ai = ai->ai_next;
   1.704 +	ai->ai_next = append;
   1.705 +
   1.706 +	return first;
   1.707 +}
   1.708 +
   1.709 +static int
   1.710 +parse_numeric_servname(const char *servname)
   1.711 +{
   1.712 +	int n;
   1.713 +	char *endptr=NULL;
   1.714 +	n = (int) strtol(servname, &endptr, 10);
   1.715 +	if (n>=0 && n <= 65535 && servname[0] && endptr && !endptr[0])
   1.716 +		return n;
   1.717 +	else
   1.718 +		return -1;
   1.719 +}
   1.720 +
   1.721 +/** Parse a service name in 'servname', which can be a decimal port.
   1.722 + * Return the port number, or -1 on error.
   1.723 + */
   1.724 +static int
   1.725 +evutil_parse_servname(const char *servname, const char *protocol,
   1.726 +    const struct evutil_addrinfo *hints)
   1.727 +{
   1.728 +	int n = parse_numeric_servname(servname);
   1.729 +	if (n>=0)
   1.730 +		return n;
   1.731 +#if defined(_EVENT_HAVE_GETSERVBYNAME) || defined(WIN32)
   1.732 +	if (!(hints->ai_flags & EVUTIL_AI_NUMERICSERV)) {
   1.733 +		struct servent *ent = getservbyname(servname, protocol);
   1.734 +		if (ent) {
   1.735 +			return ntohs(ent->s_port);
   1.736 +		}
   1.737 +	}
   1.738 +#endif
   1.739 +	return -1;
   1.740 +}
   1.741 +
   1.742 +/* Return a string corresponding to a protocol number that we can pass to
   1.743 + * getservyname.  */
   1.744 +static const char *
   1.745 +evutil_unparse_protoname(int proto)
   1.746 +{
   1.747 +	switch (proto) {
   1.748 +	case 0:
   1.749 +		return NULL;
   1.750 +	case IPPROTO_TCP:
   1.751 +		return "tcp";
   1.752 +	case IPPROTO_UDP:
   1.753 +		return "udp";
   1.754 +#ifdef IPPROTO_SCTP
   1.755 +	case IPPROTO_SCTP:
   1.756 +		return "sctp";
   1.757 +#endif
   1.758 +	default:
   1.759 +#ifdef _EVENT_HAVE_GETPROTOBYNUMBER
   1.760 +		{
   1.761 +			struct protoent *ent = getprotobynumber(proto);
   1.762 +			if (ent)
   1.763 +				return ent->p_name;
   1.764 +		}
   1.765 +#endif
   1.766 +		return NULL;
   1.767 +	}
   1.768 +}
   1.769 +
   1.770 +static void
   1.771 +evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints)
   1.772 +{
   1.773 +	/* If we can guess the protocol from the socktype, do so. */
   1.774 +	if (!hints->ai_protocol && hints->ai_socktype) {
   1.775 +		if (hints->ai_socktype == SOCK_DGRAM)
   1.776 +			hints->ai_protocol = IPPROTO_UDP;
   1.777 +		else if (hints->ai_socktype == SOCK_STREAM)
   1.778 +			hints->ai_protocol = IPPROTO_TCP;
   1.779 +	}
   1.780 +
   1.781 +	/* Set the socktype if it isn't set. */
   1.782 +	if (!hints->ai_socktype && hints->ai_protocol) {
   1.783 +		if (hints->ai_protocol == IPPROTO_UDP)
   1.784 +			hints->ai_socktype = SOCK_DGRAM;
   1.785 +		else if (hints->ai_protocol == IPPROTO_TCP)
   1.786 +			hints->ai_socktype = SOCK_STREAM;
   1.787 +#ifdef IPPROTO_SCTP
   1.788 +		else if (hints->ai_protocol == IPPROTO_SCTP)
   1.789 +			hints->ai_socktype = SOCK_STREAM;
   1.790 +#endif
   1.791 +	}
   1.792 +}
   1.793 +
   1.794 +#if AF_UNSPEC != PF_UNSPEC
   1.795 +#error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC"
   1.796 +#endif
   1.797 +
   1.798 +/** Implements the part of looking up hosts by name that's common to both
   1.799 + * the blocking and nonblocking resolver:
   1.800 + *   - Adjust 'hints' to have a reasonable socktype and protocol.
   1.801 + *   - Look up the port based on 'servname', and store it in *portnum,
   1.802 + *   - Handle the nodename==NULL case
   1.803 + *   - Handle some invalid arguments cases.
   1.804 + *   - Handle the cases where nodename is an IPv4 or IPv6 address.
   1.805 + *
   1.806 + * If we need the resolver to look up the hostname, we return
   1.807 + * EVUTIL_EAI_NEED_RESOLVE.  Otherwise, we can completely implement
   1.808 + * getaddrinfo: we return 0 or an appropriate EVUTIL_EAI_* error, and
   1.809 + * set *res as getaddrinfo would.
   1.810 + */
   1.811 +int
   1.812 +evutil_getaddrinfo_common(const char *nodename, const char *servname,
   1.813 +    struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
   1.814 +{
   1.815 +	int port = 0;
   1.816 +	const char *pname;
   1.817 +
   1.818 +	if (nodename == NULL && servname == NULL)
   1.819 +		return EVUTIL_EAI_NONAME;
   1.820 +
   1.821 +	/* We only understand 3 families */
   1.822 +	if (hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET &&
   1.823 +	    hints->ai_family != PF_INET6)
   1.824 +		return EVUTIL_EAI_FAMILY;
   1.825 +
   1.826 +	evutil_getaddrinfo_infer_protocols(hints);
   1.827 +
   1.828 +	/* Look up the port number and protocol, if possible. */
   1.829 +	pname = evutil_unparse_protoname(hints->ai_protocol);
   1.830 +	if (servname) {
   1.831 +		/* XXXX We could look at the protocol we got back from
   1.832 +		 * getservbyname, but it doesn't seem too useful. */
   1.833 +		port = evutil_parse_servname(servname, pname, hints);
   1.834 +		if (port < 0) {
   1.835 +			return EVUTIL_EAI_NONAME;
   1.836 +		}
   1.837 +	}
   1.838 +
   1.839 +	/* If we have no node name, then we're supposed to bind to 'any' and
   1.840 +	 * connect to localhost. */
   1.841 +	if (nodename == NULL) {
   1.842 +		struct evutil_addrinfo *res4=NULL, *res6=NULL;
   1.843 +		if (hints->ai_family != PF_INET) { /* INET6 or UNSPEC. */
   1.844 +			struct sockaddr_in6 sin6;
   1.845 +			memset(&sin6, 0, sizeof(sin6));
   1.846 +			sin6.sin6_family = AF_INET6;
   1.847 +			sin6.sin6_port = htons(port);
   1.848 +			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
   1.849 +				/* Bind to :: */
   1.850 +			} else {
   1.851 +				/* connect to ::1 */
   1.852 +				sin6.sin6_addr.s6_addr[15] = 1;
   1.853 +			}
   1.854 +			res6 = evutil_new_addrinfo((struct sockaddr*)&sin6,
   1.855 +			    sizeof(sin6), hints);
   1.856 +			if (!res6)
   1.857 +				return EVUTIL_EAI_MEMORY;
   1.858 +		}
   1.859 +
   1.860 +		if (hints->ai_family != PF_INET6) { /* INET or UNSPEC */
   1.861 +			struct sockaddr_in sin;
   1.862 +			memset(&sin, 0, sizeof(sin));
   1.863 +			sin.sin_family = AF_INET;
   1.864 +			sin.sin_port = htons(port);
   1.865 +			if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
   1.866 +				/* Bind to 0.0.0.0 */
   1.867 +			} else {
   1.868 +				/* connect to 127.0.0.1 */
   1.869 +				sin.sin_addr.s_addr = htonl(0x7f000001);
   1.870 +			}
   1.871 +			res4 = evutil_new_addrinfo((struct sockaddr*)&sin,
   1.872 +			    sizeof(sin), hints);
   1.873 +			if (!res4) {
   1.874 +				if (res6)
   1.875 +					evutil_freeaddrinfo(res6);
   1.876 +				return EVUTIL_EAI_MEMORY;
   1.877 +			}
   1.878 +		}
   1.879 +		*res = evutil_addrinfo_append(res4, res6);
   1.880 +		return 0;
   1.881 +	}
   1.882 +
   1.883 +	/* If we can, we should try to parse the hostname without resolving
   1.884 +	 * it. */
   1.885 +	/* Try ipv6. */
   1.886 +	if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
   1.887 +		struct sockaddr_in6 sin6;
   1.888 +		memset(&sin6, 0, sizeof(sin6));
   1.889 +		if (1==evutil_inet_pton(AF_INET6, nodename, &sin6.sin6_addr)) {
   1.890 +			/* Got an ipv6 address. */
   1.891 +			sin6.sin6_family = AF_INET6;
   1.892 +			sin6.sin6_port = htons(port);
   1.893 +			*res = evutil_new_addrinfo((struct sockaddr*)&sin6,
   1.894 +			    sizeof(sin6), hints);
   1.895 +			if (!*res)
   1.896 +				return EVUTIL_EAI_MEMORY;
   1.897 +			return 0;
   1.898 +		}
   1.899 +	}
   1.900 +
   1.901 +	/* Try ipv4. */
   1.902 +	if (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC) {
   1.903 +		struct sockaddr_in sin;
   1.904 +		memset(&sin, 0, sizeof(sin));
   1.905 +		if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
   1.906 +			/* Got an ipv6 address. */
   1.907 +			sin.sin_family = AF_INET;
   1.908 +			sin.sin_port = htons(port);
   1.909 +			*res = evutil_new_addrinfo((struct sockaddr*)&sin,
   1.910 +			    sizeof(sin), hints);
   1.911 +			if (!*res)
   1.912 +				return EVUTIL_EAI_MEMORY;
   1.913 +			return 0;
   1.914 +		}
   1.915 +	}
   1.916 +
   1.917 +
   1.918 +	/* If we have reached this point, we definitely need to do a DNS
   1.919 +	 * lookup. */
   1.920 +	if ((hints->ai_flags & EVUTIL_AI_NUMERICHOST)) {
   1.921 +		/* If we're not allowed to do one, then say so. */
   1.922 +		return EVUTIL_EAI_NONAME;
   1.923 +	}
   1.924 +	*portnum = port;
   1.925 +	return EVUTIL_EAI_NEED_RESOLVE;
   1.926 +}
   1.927 +
   1.928 +#ifdef _EVENT_HAVE_GETADDRINFO
   1.929 +#define USE_NATIVE_GETADDRINFO
   1.930 +#endif
   1.931 +
   1.932 +#ifdef USE_NATIVE_GETADDRINFO
   1.933 +/* A mask of all the flags that we declare, so we can clear them before calling
   1.934 + * the native getaddrinfo */
   1.935 +static const unsigned int ALL_NONNATIVE_AI_FLAGS =
   1.936 +#ifndef AI_PASSIVE
   1.937 +    EVUTIL_AI_PASSIVE |
   1.938 +#endif
   1.939 +#ifndef AI_CANONNAME
   1.940 +    EVUTIL_AI_CANONNAME |
   1.941 +#endif
   1.942 +#ifndef AI_NUMERICHOST
   1.943 +    EVUTIL_AI_NUMERICHOST |
   1.944 +#endif
   1.945 +#ifndef AI_NUMERICSERV
   1.946 +    EVUTIL_AI_NUMERICSERV |
   1.947 +#endif
   1.948 +#ifndef AI_ADDRCONFIG
   1.949 +    EVUTIL_AI_ADDRCONFIG |
   1.950 +#endif
   1.951 +#ifndef AI_ALL
   1.952 +    EVUTIL_AI_ALL |
   1.953 +#endif
   1.954 +#ifndef AI_V4MAPPED
   1.955 +    EVUTIL_AI_V4MAPPED |
   1.956 +#endif
   1.957 +    EVUTIL_AI_LIBEVENT_ALLOCATED;
   1.958 +
   1.959 +static const unsigned int ALL_NATIVE_AI_FLAGS =
   1.960 +#ifdef AI_PASSIVE
   1.961 +    AI_PASSIVE |
   1.962 +#endif
   1.963 +#ifdef AI_CANONNAME
   1.964 +    AI_CANONNAME |
   1.965 +#endif
   1.966 +#ifdef AI_NUMERICHOST
   1.967 +    AI_NUMERICHOST |
   1.968 +#endif
   1.969 +#ifdef AI_NUMERICSERV
   1.970 +    AI_NUMERICSERV |
   1.971 +#endif
   1.972 +#ifdef AI_ADDRCONFIG
   1.973 +    AI_ADDRCONFIG |
   1.974 +#endif
   1.975 +#ifdef AI_ALL
   1.976 +    AI_ALL |
   1.977 +#endif
   1.978 +#ifdef AI_V4MAPPED
   1.979 +    AI_V4MAPPED |
   1.980 +#endif
   1.981 +    0;
   1.982 +#endif
   1.983 +
   1.984 +#ifndef USE_NATIVE_GETADDRINFO
   1.985 +/* Helper for systems with no getaddrinfo(): make one or more addrinfos out of
   1.986 + * a struct hostent.
   1.987 + */
   1.988 +static struct evutil_addrinfo *
   1.989 +addrinfo_from_hostent(const struct hostent *ent,
   1.990 +    int port, const struct evutil_addrinfo *hints)
   1.991 +{
   1.992 +	int i;
   1.993 +	struct sockaddr_in sin;
   1.994 +	struct sockaddr_in6 sin6;
   1.995 +	struct sockaddr *sa;
   1.996 +	int socklen;
   1.997 +	struct evutil_addrinfo *res=NULL, *ai;
   1.998 +	void *addrp;
   1.999 +
  1.1000 +	if (ent->h_addrtype == PF_INET) {
  1.1001 +		memset(&sin, 0, sizeof(sin));
  1.1002 +		sin.sin_family = AF_INET;
  1.1003 +		sin.sin_port = htons(port);
  1.1004 +		sa = (struct sockaddr *)&sin;
  1.1005 +		socklen = sizeof(struct sockaddr_in);
  1.1006 +		addrp = &sin.sin_addr;
  1.1007 +		if (ent->h_length != sizeof(sin.sin_addr)) {
  1.1008 +			event_warnx("Weird h_length from gethostbyname");
  1.1009 +			return NULL;
  1.1010 +		}
  1.1011 +	} else if (ent->h_addrtype == PF_INET6) {
  1.1012 +		memset(&sin6, 0, sizeof(sin6));
  1.1013 +		sin6.sin6_family = AF_INET6;
  1.1014 +		sin6.sin6_port = htons(port);
  1.1015 +		sa = (struct sockaddr *)&sin6;
  1.1016 +		socklen = sizeof(struct sockaddr_in);
  1.1017 +		addrp = &sin6.sin6_addr;
  1.1018 +		if (ent->h_length != sizeof(sin6.sin6_addr)) {
  1.1019 +			event_warnx("Weird h_length from gethostbyname");
  1.1020 +			return NULL;
  1.1021 +		}
  1.1022 +	} else
  1.1023 +		return NULL;
  1.1024 +
  1.1025 +	for (i = 0; ent->h_addr_list[i]; ++i) {
  1.1026 +		memcpy(addrp, ent->h_addr_list[i], ent->h_length);
  1.1027 +		ai = evutil_new_addrinfo(sa, socklen, hints);
  1.1028 +		if (!ai) {
  1.1029 +			evutil_freeaddrinfo(res);
  1.1030 +			return NULL;
  1.1031 +		}
  1.1032 +		res = evutil_addrinfo_append(res, ai);
  1.1033 +	}
  1.1034 +
  1.1035 +	if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) {
  1.1036 +		res->ai_canonname = mm_strdup(ent->h_name);
  1.1037 +		if (res->ai_canonname == NULL) {
  1.1038 +			evutil_freeaddrinfo(res);
  1.1039 +			return NULL;
  1.1040 +		}
  1.1041 +	}
  1.1042 +
  1.1043 +	return res;
  1.1044 +}
  1.1045 +#endif
  1.1046 +
  1.1047 +/* If the EVUTIL_AI_ADDRCONFIG flag is set on hints->ai_flags, and
  1.1048 + * hints->ai_family is PF_UNSPEC, then revise the value of hints->ai_family so
  1.1049 + * that we'll only get addresses we could maybe connect to.
  1.1050 + */
  1.1051 +void
  1.1052 +evutil_adjust_hints_for_addrconfig(struct evutil_addrinfo *hints)
  1.1053 +{
  1.1054 +	if (!(hints->ai_flags & EVUTIL_AI_ADDRCONFIG))
  1.1055 +		return;
  1.1056 +	if (hints->ai_family != PF_UNSPEC)
  1.1057 +		return;
  1.1058 +	if (!have_checked_interfaces)
  1.1059 +		evutil_check_interfaces(0);
  1.1060 +	if (had_ipv4_address && !had_ipv6_address) {
  1.1061 +		hints->ai_family = PF_INET;
  1.1062 +	} else if (!had_ipv4_address && had_ipv6_address) {
  1.1063 +		hints->ai_family = PF_INET6;
  1.1064 +	}
  1.1065 +}
  1.1066 +
  1.1067 +#ifdef USE_NATIVE_GETADDRINFO
  1.1068 +static int need_numeric_port_hack_=0;
  1.1069 +static int need_socktype_protocol_hack_=0;
  1.1070 +static int tested_for_getaddrinfo_hacks=0;
  1.1071 +
  1.1072 +/* Some older BSDs (like OpenBSD up to 4.6) used to believe that
  1.1073 +   giving a numeric port without giving an ai_socktype was verboten.
  1.1074 +   We test for this so we can apply an appropriate workaround.  If it
  1.1075 +   turns out that the bug is present, then:
  1.1076 +
  1.1077 +    - If nodename==NULL and servname is numeric, we build an answer
  1.1078 +      ourselves using evutil_getaddrinfo_common().
  1.1079 +
  1.1080 +    - If nodename!=NULL and servname is numeric, then we set
  1.1081 +      servname=NULL when calling getaddrinfo, and post-process the
  1.1082 +      result to set the ports on it.
  1.1083 +
  1.1084 +   We test for this bug at runtime, since otherwise we can't have the
  1.1085 +   same binary run on multiple BSD versions.
  1.1086 +
  1.1087 +   - Some versions of Solaris believe that it's nice to leave to protocol
  1.1088 +     field set to 0.  We test for this so we can apply an appropriate
  1.1089 +     workaround.
  1.1090 +*/
  1.1091 +static void
  1.1092 +test_for_getaddrinfo_hacks(void)
  1.1093 +{
  1.1094 +	int r, r2;
  1.1095 +	struct evutil_addrinfo *ai=NULL, *ai2=NULL;
  1.1096 +	struct evutil_addrinfo hints;
  1.1097 +
  1.1098 +	memset(&hints,0,sizeof(hints));
  1.1099 +	hints.ai_family = PF_UNSPEC;
  1.1100 +	hints.ai_flags =
  1.1101 +#ifdef AI_NUMERICHOST
  1.1102 +	    AI_NUMERICHOST |
  1.1103 +#endif
  1.1104 +#ifdef AI_NUMERICSERV
  1.1105 +	    AI_NUMERICSERV |
  1.1106 +#endif
  1.1107 +	    0;
  1.1108 +	r = getaddrinfo("1.2.3.4", "80", &hints, &ai);
  1.1109 +	hints.ai_socktype = SOCK_STREAM;
  1.1110 +	r2 = getaddrinfo("1.2.3.4", "80", &hints, &ai2);
  1.1111 +	if (r2 == 0 && r != 0) {
  1.1112 +		need_numeric_port_hack_=1;
  1.1113 +	}
  1.1114 +	if (ai2 && ai2->ai_protocol == 0) {
  1.1115 +		need_socktype_protocol_hack_=1;
  1.1116 +	}
  1.1117 +
  1.1118 +	if (ai)
  1.1119 +		freeaddrinfo(ai);
  1.1120 +	if (ai2)
  1.1121 +		freeaddrinfo(ai2);
  1.1122 +	tested_for_getaddrinfo_hacks=1;
  1.1123 +}
  1.1124 +
  1.1125 +static inline int
  1.1126 +need_numeric_port_hack(void)
  1.1127 +{
  1.1128 +	if (!tested_for_getaddrinfo_hacks)
  1.1129 +		test_for_getaddrinfo_hacks();
  1.1130 +	return need_numeric_port_hack_;
  1.1131 +}
  1.1132 +
  1.1133 +static inline int
  1.1134 +need_socktype_protocol_hack(void)
  1.1135 +{
  1.1136 +	if (!tested_for_getaddrinfo_hacks)
  1.1137 +		test_for_getaddrinfo_hacks();
  1.1138 +	return need_socktype_protocol_hack_;
  1.1139 +}
  1.1140 +
  1.1141 +static void
  1.1142 +apply_numeric_port_hack(int port, struct evutil_addrinfo **ai)
  1.1143 +{
  1.1144 +	/* Now we run through the list and set the ports on all of the
  1.1145 +	 * results where ports would make sense. */
  1.1146 +	for ( ; *ai; ai = &(*ai)->ai_next) {
  1.1147 +		struct sockaddr *sa = (*ai)->ai_addr;
  1.1148 +		if (sa && sa->sa_family == AF_INET) {
  1.1149 +			struct sockaddr_in *sin = (struct sockaddr_in*)sa;
  1.1150 +			sin->sin_port = htons(port);
  1.1151 +		} else if (sa && sa->sa_family == AF_INET6) {
  1.1152 +			struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
  1.1153 +			sin6->sin6_port = htons(port);
  1.1154 +		} else {
  1.1155 +			/* A numeric port makes no sense here; remove this one
  1.1156 +			 * from the list. */
  1.1157 +			struct evutil_addrinfo *victim = *ai;
  1.1158 +			*ai = victim->ai_next;
  1.1159 +			victim->ai_next = NULL;
  1.1160 +			freeaddrinfo(victim);
  1.1161 +		}
  1.1162 +	}
  1.1163 +}
  1.1164 +
  1.1165 +static int
  1.1166 +apply_socktype_protocol_hack(struct evutil_addrinfo *ai)
  1.1167 +{
  1.1168 +	struct evutil_addrinfo *ai_new;
  1.1169 +	for (; ai; ai = ai->ai_next) {
  1.1170 +		evutil_getaddrinfo_infer_protocols(ai);
  1.1171 +		if (ai->ai_socktype || ai->ai_protocol)
  1.1172 +			continue;
  1.1173 +		ai_new = mm_malloc(sizeof(*ai_new));
  1.1174 +		if (!ai_new)
  1.1175 +			return -1;
  1.1176 +		memcpy(ai_new, ai, sizeof(*ai_new));
  1.1177 +		ai->ai_socktype = SOCK_STREAM;
  1.1178 +		ai->ai_protocol = IPPROTO_TCP;
  1.1179 +		ai_new->ai_socktype = SOCK_DGRAM;
  1.1180 +		ai_new->ai_protocol = IPPROTO_UDP;
  1.1181 +
  1.1182 +		ai_new->ai_next = ai->ai_next;
  1.1183 +		ai->ai_next = ai_new;
  1.1184 +	}
  1.1185 +	return 0;
  1.1186 +}
  1.1187 +#endif
  1.1188 +
  1.1189 +int
  1.1190 +evutil_getaddrinfo(const char *nodename, const char *servname,
  1.1191 +    const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res)
  1.1192 +{
  1.1193 +#ifdef USE_NATIVE_GETADDRINFO
  1.1194 +	struct evutil_addrinfo hints;
  1.1195 +	int portnum=-1, need_np_hack, err;
  1.1196 +
  1.1197 +	if (hints_in) {
  1.1198 +		memcpy(&hints, hints_in, sizeof(hints));
  1.1199 +	} else {
  1.1200 +		memset(&hints, 0, sizeof(hints));
  1.1201 +		hints.ai_family = PF_UNSPEC;
  1.1202 +	}
  1.1203 +
  1.1204 +#ifndef AI_ADDRCONFIG
  1.1205 +	/* Not every system has AI_ADDRCONFIG, so fake it. */
  1.1206 +	if (hints.ai_family == PF_UNSPEC &&
  1.1207 +	    (hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
  1.1208 +		evutil_adjust_hints_for_addrconfig(&hints);
  1.1209 +	}
  1.1210 +#endif
  1.1211 +
  1.1212 +#ifndef AI_NUMERICSERV
  1.1213 +	/* Not every system has AI_NUMERICSERV, so fake it. */
  1.1214 +	if (hints.ai_flags & EVUTIL_AI_NUMERICSERV) {
  1.1215 +		if (servname && parse_numeric_servname(servname)<0)
  1.1216 +			return EVUTIL_EAI_NONAME;
  1.1217 +	}
  1.1218 +#endif
  1.1219 +
  1.1220 +	/* Enough operating systems handle enough common non-resolve
  1.1221 +	 * cases here weirdly enough that we are better off just
  1.1222 +	 * overriding them.  For example:
  1.1223 +	 *
  1.1224 +	 * - Windows doesn't like to infer the protocol from the
  1.1225 +	 *   socket type, or fill in socket or protocol types much at
  1.1226 +	 *   all.  It also seems to do its own broken implicit
  1.1227 +	 *   always-on version of AI_ADDRCONFIG that keeps it from
  1.1228 +	 *   ever resolving even a literal IPv6 address when
  1.1229 +	 *   ai_addrtype is PF_UNSPEC.
  1.1230 +	 */
  1.1231 +#ifdef WIN32
  1.1232 +	{
  1.1233 +		int tmp_port;
  1.1234 +		err = evutil_getaddrinfo_common(nodename,servname,&hints,
  1.1235 +		    res, &tmp_port);
  1.1236 +		if (err == 0 ||
  1.1237 +		    err == EVUTIL_EAI_MEMORY ||
  1.1238 +		    err == EVUTIL_EAI_NONAME)
  1.1239 +			return err;
  1.1240 +		/* If we make it here, the system getaddrinfo can
  1.1241 +		 * have a crack at it. */
  1.1242 +	}
  1.1243 +#endif
  1.1244 +
  1.1245 +	/* See documentation for need_numeric_port_hack above.*/
  1.1246 +	need_np_hack = need_numeric_port_hack() && servname && !hints.ai_socktype
  1.1247 +	    && ((portnum=parse_numeric_servname(servname)) >= 0);
  1.1248 +	if (need_np_hack) {
  1.1249 +		if (!nodename)
  1.1250 +			return evutil_getaddrinfo_common(
  1.1251 +				NULL,servname,&hints, res, &portnum);
  1.1252 +		servname = NULL;
  1.1253 +	}
  1.1254 +
  1.1255 +	if (need_socktype_protocol_hack()) {
  1.1256 +		evutil_getaddrinfo_infer_protocols(&hints);
  1.1257 +	}
  1.1258 +
  1.1259 +	/* Make sure that we didn't actually steal any AI_FLAGS values that
  1.1260 +	 * the system is using.  (This is a constant expression, and should ge
  1.1261 +	 * optimized out.)
  1.1262 +	 *
  1.1263 +	 * XXXX Turn this into a compile-time failure rather than a run-time
  1.1264 +	 * failure.
  1.1265 +	 */
  1.1266 +	EVUTIL_ASSERT((ALL_NONNATIVE_AI_FLAGS & ALL_NATIVE_AI_FLAGS) == 0);
  1.1267 +
  1.1268 +	/* Clear any flags that only libevent understands. */
  1.1269 +	hints.ai_flags &= ~ALL_NONNATIVE_AI_FLAGS;
  1.1270 +
  1.1271 +	err = getaddrinfo(nodename, servname, &hints, res);
  1.1272 +	if (need_np_hack)
  1.1273 +		apply_numeric_port_hack(portnum, res);
  1.1274 +
  1.1275 +	if (need_socktype_protocol_hack()) {
  1.1276 +		if (apply_socktype_protocol_hack(*res) < 0) {
  1.1277 +			evutil_freeaddrinfo(*res);
  1.1278 +			*res = NULL;
  1.1279 +			return EVUTIL_EAI_MEMORY;
  1.1280 +		}
  1.1281 +	}
  1.1282 +	return err;
  1.1283 +#else
  1.1284 +	int port=0, err;
  1.1285 +	struct hostent *ent = NULL;
  1.1286 +	struct evutil_addrinfo hints;
  1.1287 +
  1.1288 +	if (hints_in) {
  1.1289 +		memcpy(&hints, hints_in, sizeof(hints));
  1.1290 +	} else {
  1.1291 +		memset(&hints, 0, sizeof(hints));
  1.1292 +		hints.ai_family = PF_UNSPEC;
  1.1293 +	}
  1.1294 +
  1.1295 +	evutil_adjust_hints_for_addrconfig(&hints);
  1.1296 +
  1.1297 +	err = evutil_getaddrinfo_common(nodename, servname, &hints, res, &port);
  1.1298 +	if (err != EVUTIL_EAI_NEED_RESOLVE) {
  1.1299 +		/* We either succeeded or failed.  No need to continue */
  1.1300 +		return err;
  1.1301 +	}
  1.1302 +
  1.1303 +	err = 0;
  1.1304 +	/* Use any of the various gethostbyname_r variants as available. */
  1.1305 +	{
  1.1306 +#ifdef _EVENT_HAVE_GETHOSTBYNAME_R_6_ARG
  1.1307 +		/* This one is what glibc provides. */
  1.1308 +		char buf[2048];
  1.1309 +		struct hostent hostent;
  1.1310 +		int r;
  1.1311 +		r = gethostbyname_r(nodename, &hostent, buf, sizeof(buf), &ent,
  1.1312 +		    &err);
  1.1313 +#elif defined(_EVENT_HAVE_GETHOSTBYNAME_R_5_ARG)
  1.1314 +		char buf[2048];
  1.1315 +		struct hostent hostent;
  1.1316 +		ent = gethostbyname_r(nodename, &hostent, buf, sizeof(buf),
  1.1317 +		    &err);
  1.1318 +#elif defined(_EVENT_HAVE_GETHOSTBYNAME_R_3_ARG)
  1.1319 +		struct hostent_data data;
  1.1320 +		struct hostent hostent;
  1.1321 +		memset(&data, 0, sizeof(data));
  1.1322 +		err = gethostbyname_r(nodename, &hostent, &data);
  1.1323 +		ent = err ? NULL : &hostent;
  1.1324 +#else
  1.1325 +		/* fall back to gethostbyname. */
  1.1326 +		/* XXXX This needs a lock everywhere but Windows. */
  1.1327 +		ent = gethostbyname(nodename);
  1.1328 +#ifdef WIN32
  1.1329 +		err = WSAGetLastError();
  1.1330 +#else
  1.1331 +		err = h_errno;
  1.1332 +#endif
  1.1333 +#endif
  1.1334 +
  1.1335 +		/* Now we have either ent or err set. */
  1.1336 +		if (!ent) {
  1.1337 +			/* XXX is this right for windows ? */
  1.1338 +			switch (err) {
  1.1339 +			case TRY_AGAIN:
  1.1340 +				return EVUTIL_EAI_AGAIN;
  1.1341 +			case NO_RECOVERY:
  1.1342 +			default:
  1.1343 +				return EVUTIL_EAI_FAIL;
  1.1344 +			case HOST_NOT_FOUND:
  1.1345 +				return EVUTIL_EAI_NONAME;
  1.1346 +			case NO_ADDRESS:
  1.1347 +#if NO_DATA != NO_ADDRESS
  1.1348 +			case NO_DATA:
  1.1349 +#endif
  1.1350 +				return EVUTIL_EAI_NODATA;
  1.1351 +			}
  1.1352 +		}
  1.1353 +
  1.1354 +		if (ent->h_addrtype != hints.ai_family &&
  1.1355 +		    hints.ai_family != PF_UNSPEC) {
  1.1356 +			/* This wasn't the type we were hoping for.  Too bad
  1.1357 +			 * we never had a chance to ask gethostbyname for what
  1.1358 +			 * we wanted. */
  1.1359 +			return EVUTIL_EAI_NONAME;
  1.1360 +		}
  1.1361 +
  1.1362 +		/* Make sure we got _some_ answers. */
  1.1363 +		if (ent->h_length == 0)
  1.1364 +			return EVUTIL_EAI_NODATA;
  1.1365 +
  1.1366 +		/* If we got an address type we don't know how to make a
  1.1367 +		   sockaddr for, give up. */
  1.1368 +		if (ent->h_addrtype != PF_INET && ent->h_addrtype != PF_INET6)
  1.1369 +			return EVUTIL_EAI_FAMILY;
  1.1370 +
  1.1371 +		*res = addrinfo_from_hostent(ent, port, &hints);
  1.1372 +		if (! *res)
  1.1373 +			return EVUTIL_EAI_MEMORY;
  1.1374 +	}
  1.1375 +
  1.1376 +	return 0;
  1.1377 +#endif
  1.1378 +}
  1.1379 +
  1.1380 +void
  1.1381 +evutil_freeaddrinfo(struct evutil_addrinfo *ai)
  1.1382 +{
  1.1383 +#ifdef _EVENT_HAVE_GETADDRINFO
  1.1384 +	if (!(ai->ai_flags & EVUTIL_AI_LIBEVENT_ALLOCATED)) {
  1.1385 +		freeaddrinfo(ai);
  1.1386 +		return;
  1.1387 +	}
  1.1388 +#endif
  1.1389 +	while (ai) {
  1.1390 +		struct evutil_addrinfo *next = ai->ai_next;
  1.1391 +		if (ai->ai_canonname)
  1.1392 +			mm_free(ai->ai_canonname);
  1.1393 +		mm_free(ai);
  1.1394 +		ai = next;
  1.1395 +	}
  1.1396 +}
  1.1397 +
  1.1398 +static evdns_getaddrinfo_fn evdns_getaddrinfo_impl = NULL;
  1.1399 +
  1.1400 +void
  1.1401 +evutil_set_evdns_getaddrinfo_fn(evdns_getaddrinfo_fn fn)
  1.1402 +{
  1.1403 +	if (!evdns_getaddrinfo_impl)
  1.1404 +		evdns_getaddrinfo_impl = fn;
  1.1405 +}
  1.1406 +
  1.1407 +/* Internal helper function: act like evdns_getaddrinfo if dns_base is set;
  1.1408 + * otherwise do a blocking resolve and pass the result to the callback in the
  1.1409 + * way that evdns_getaddrinfo would.
  1.1410 + */
  1.1411 +int
  1.1412 +evutil_getaddrinfo_async(struct evdns_base *dns_base,
  1.1413 +    const char *nodename, const char *servname,
  1.1414 +    const struct evutil_addrinfo *hints_in,
  1.1415 +    void (*cb)(int, struct evutil_addrinfo *, void *), void *arg)
  1.1416 +{
  1.1417 +	if (dns_base && evdns_getaddrinfo_impl) {
  1.1418 +		evdns_getaddrinfo_impl(
  1.1419 +			dns_base, nodename, servname, hints_in, cb, arg);
  1.1420 +	} else {
  1.1421 +		struct evutil_addrinfo *ai=NULL;
  1.1422 +		int err;
  1.1423 +		err = evutil_getaddrinfo(nodename, servname, hints_in, &ai);
  1.1424 +		cb(err, ai, arg);
  1.1425 +	}
  1.1426 +	return 0;
  1.1427 +}
  1.1428 +
  1.1429 +const char *
  1.1430 +evutil_gai_strerror(int err)
  1.1431 +{
  1.1432 +	/* As a sneaky side-benefit, this case statement will get most
  1.1433 +	 * compilers to tell us if any of the error codes we defined
  1.1434 +	 * conflict with the platform's native error codes. */
  1.1435 +	switch (err) {
  1.1436 +	case EVUTIL_EAI_CANCEL:
  1.1437 +		return "Request canceled";
  1.1438 +	case 0:
  1.1439 +		return "No error";
  1.1440 +
  1.1441 +	case EVUTIL_EAI_ADDRFAMILY:
  1.1442 +		return "address family for nodename not supported";
  1.1443 +	case EVUTIL_EAI_AGAIN:
  1.1444 +		return "temporary failure in name resolution";
  1.1445 +	case EVUTIL_EAI_BADFLAGS:
  1.1446 +		return "invalid value for ai_flags";
  1.1447 +	case EVUTIL_EAI_FAIL:
  1.1448 +		return "non-recoverable failure in name resolution";
  1.1449 +	case EVUTIL_EAI_FAMILY:
  1.1450 +		return "ai_family not supported";
  1.1451 +	case EVUTIL_EAI_MEMORY:
  1.1452 +		return "memory allocation failure";
  1.1453 +	case EVUTIL_EAI_NODATA:
  1.1454 +		return "no address associated with nodename";
  1.1455 +	case EVUTIL_EAI_NONAME:
  1.1456 +		return "nodename nor servname provided, or not known";
  1.1457 +	case EVUTIL_EAI_SERVICE:
  1.1458 +		return "servname not supported for ai_socktype";
  1.1459 +	case EVUTIL_EAI_SOCKTYPE:
  1.1460 +		return "ai_socktype not supported";
  1.1461 +	case EVUTIL_EAI_SYSTEM:
  1.1462 +		return "system error";
  1.1463 +	default:
  1.1464 +#if defined(USE_NATIVE_GETADDRINFO) && defined(WIN32)
  1.1465 +		return gai_strerrorA(err);
  1.1466 +#elif defined(USE_NATIVE_GETADDRINFO)
  1.1467 +		return gai_strerror(err);
  1.1468 +#else
  1.1469 +		return "Unknown error code";
  1.1470 +#endif
  1.1471 +	}
  1.1472 +}
  1.1473 +
  1.1474 +#ifdef WIN32
  1.1475 +#define E(code, s) { code, (s " [" #code " ]") }
  1.1476 +static struct { int code; const char *msg; } windows_socket_errors[] = {
  1.1477 +  E(WSAEINTR, "Interrupted function call"),
  1.1478 +  E(WSAEACCES, "Permission denied"),
  1.1479 +  E(WSAEFAULT, "Bad address"),
  1.1480 +  E(WSAEINVAL, "Invalid argument"),
  1.1481 +  E(WSAEMFILE, "Too many open files"),
  1.1482 +  E(WSAEWOULDBLOCK,  "Resource temporarily unavailable"),
  1.1483 +  E(WSAEINPROGRESS, "Operation now in progress"),
  1.1484 +  E(WSAEALREADY, "Operation already in progress"),
  1.1485 +  E(WSAENOTSOCK, "Socket operation on nonsocket"),
  1.1486 +  E(WSAEDESTADDRREQ, "Destination address required"),
  1.1487 +  E(WSAEMSGSIZE, "Message too long"),
  1.1488 +  E(WSAEPROTOTYPE, "Protocol wrong for socket"),
  1.1489 +  E(WSAENOPROTOOPT, "Bad protocol option"),
  1.1490 +  E(WSAEPROTONOSUPPORT, "Protocol not supported"),
  1.1491 +  E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
  1.1492 +  /* What's the difference between NOTSUPP and NOSUPPORT? :) */
  1.1493 +  E(WSAEOPNOTSUPP, "Operation not supported"),
  1.1494 +  E(WSAEPFNOSUPPORT,  "Protocol family not supported"),
  1.1495 +  E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
  1.1496 +  E(WSAEADDRINUSE, "Address already in use"),
  1.1497 +  E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
  1.1498 +  E(WSAENETDOWN, "Network is down"),
  1.1499 +  E(WSAENETUNREACH, "Network is unreachable"),
  1.1500 +  E(WSAENETRESET, "Network dropped connection on reset"),
  1.1501 +  E(WSAECONNABORTED, "Software caused connection abort"),
  1.1502 +  E(WSAECONNRESET, "Connection reset by peer"),
  1.1503 +  E(WSAENOBUFS, "No buffer space available"),
  1.1504 +  E(WSAEISCONN, "Socket is already connected"),
  1.1505 +  E(WSAENOTCONN, "Socket is not connected"),
  1.1506 +  E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
  1.1507 +  E(WSAETIMEDOUT, "Connection timed out"),
  1.1508 +  E(WSAECONNREFUSED, "Connection refused"),
  1.1509 +  E(WSAEHOSTDOWN, "Host is down"),
  1.1510 +  E(WSAEHOSTUNREACH, "No route to host"),
  1.1511 +  E(WSAEPROCLIM, "Too many processes"),
  1.1512 +
  1.1513 +  /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
  1.1514 +  E(WSASYSNOTREADY, "Network subsystem is unavailable"),
  1.1515 +  E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
  1.1516 +  E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
  1.1517 +  E(WSAEDISCON, "Graceful shutdown now in progress"),
  1.1518 +#ifdef WSATYPE_NOT_FOUND
  1.1519 +  E(WSATYPE_NOT_FOUND, "Class type not found"),
  1.1520 +#endif
  1.1521 +  E(WSAHOST_NOT_FOUND, "Host not found"),
  1.1522 +  E(WSATRY_AGAIN, "Nonauthoritative host not found"),
  1.1523 +  E(WSANO_RECOVERY, "This is a nonrecoverable error"),
  1.1524 +  E(WSANO_DATA, "Valid name, no data record of requested type)"),
  1.1525 +
  1.1526 +  /* There are some more error codes whose numeric values are marked
  1.1527 +   * <b>OS dependent</b>. They start with WSA_, apparently for the same
  1.1528 +   * reason that practitioners of some craft traditions deliberately
  1.1529 +   * introduce imperfections into their baskets and rugs "to allow the
  1.1530 +   * evil spirits to escape."  If we catch them, then our binaries
  1.1531 +   * might not report consistent results across versions of Windows.
  1.1532 +   * Thus, I'm going to let them all fall through.
  1.1533 +   */
  1.1534 +  { -1, NULL },
  1.1535 +};
  1.1536 +#undef E
  1.1537 +/** Equivalent to strerror, but for windows socket errors. */
  1.1538 +const char *
  1.1539 +evutil_socket_error_to_string(int errcode)
  1.1540 +{
  1.1541 +  /* XXXX Is there really no built-in function to do this? */
  1.1542 +  int i;
  1.1543 +  for (i=0; windows_socket_errors[i].code >= 0; ++i) {
  1.1544 +    if (errcode == windows_socket_errors[i].code)
  1.1545 +      return windows_socket_errors[i].msg;
  1.1546 +  }
  1.1547 +  return strerror(errcode);
  1.1548 +}
  1.1549 +#endif
  1.1550 +
  1.1551 +int
  1.1552 +evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
  1.1553 +{
  1.1554 +	int r;
  1.1555 +	va_list ap;
  1.1556 +	va_start(ap, format);
  1.1557 +	r = evutil_vsnprintf(buf, buflen, format, ap);
  1.1558 +	va_end(ap);
  1.1559 +	return r;
  1.1560 +}
  1.1561 +
  1.1562 +int
  1.1563 +evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
  1.1564 +{
  1.1565 +	int r;
  1.1566 +	if (!buflen)
  1.1567 +		return 0;
  1.1568 +#ifdef _MSC_VER
  1.1569 +	r = _vsnprintf(buf, buflen, format, ap);
  1.1570 +	if (r < 0)
  1.1571 +		r = _vscprintf(format, ap);
  1.1572 +#elif defined(sgi)
  1.1573 +	/* Make sure we always use the correct vsnprintf on IRIX */
  1.1574 +	extern int      _xpg5_vsnprintf(char * __restrict,
  1.1575 +		__SGI_LIBC_NAMESPACE_QUALIFIER size_t,
  1.1576 +		const char * __restrict, /* va_list */ char *);
  1.1577 +
  1.1578 +	r = _xpg5_vsnprintf(buf, buflen, format, ap);
  1.1579 +#else
  1.1580 +	r = vsnprintf(buf, buflen, format, ap);
  1.1581 +#endif
  1.1582 +	buf[buflen-1] = '\0';
  1.1583 +	return r;
  1.1584 +}
  1.1585 +
  1.1586 +#define USE_INTERNAL_NTOP
  1.1587 +#define USE_INTERNAL_PTON
  1.1588 +
  1.1589 +const char *
  1.1590 +evutil_inet_ntop(int af, const void *src, char *dst, size_t len)
  1.1591 +{
  1.1592 +#if defined(_EVENT_HAVE_INET_NTOP) && !defined(USE_INTERNAL_NTOP)
  1.1593 +	return inet_ntop(af, src, dst, len);
  1.1594 +#else
  1.1595 +	if (af == AF_INET) {
  1.1596 +		const struct in_addr *in = src;
  1.1597 +		const ev_uint32_t a = ntohl(in->s_addr);
  1.1598 +		int r;
  1.1599 +		r = evutil_snprintf(dst, len, "%d.%d.%d.%d",
  1.1600 +		    (int)(ev_uint8_t)((a>>24)&0xff),
  1.1601 +		    (int)(ev_uint8_t)((a>>16)&0xff),
  1.1602 +		    (int)(ev_uint8_t)((a>>8 )&0xff),
  1.1603 +		    (int)(ev_uint8_t)((a    )&0xff));
  1.1604 +		if (r<0||(size_t)r>=len)
  1.1605 +			return NULL;
  1.1606 +		else
  1.1607 +			return dst;
  1.1608 +#ifdef AF_INET6
  1.1609 +	} else if (af == AF_INET6) {
  1.1610 +		const struct in6_addr *addr = src;
  1.1611 +		char buf[64], *cp;
  1.1612 +		int longestGapLen = 0, longestGapPos = -1, i,
  1.1613 +			curGapPos = -1, curGapLen = 0;
  1.1614 +		ev_uint16_t words[8];
  1.1615 +		for (i = 0; i < 8; ++i) {
  1.1616 +			words[i] =
  1.1617 +			    (((ev_uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
  1.1618 +		}
  1.1619 +		if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
  1.1620 +		    words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
  1.1621 +			(words[5] == 0xffff))) {
  1.1622 +			/* This is an IPv4 address. */
  1.1623 +			if (words[5] == 0) {
  1.1624 +				evutil_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
  1.1625 +				    addr->s6_addr[12], addr->s6_addr[13],
  1.1626 +				    addr->s6_addr[14], addr->s6_addr[15]);
  1.1627 +			} else {
  1.1628 +				evutil_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
  1.1629 +				    addr->s6_addr[12], addr->s6_addr[13],
  1.1630 +				    addr->s6_addr[14], addr->s6_addr[15]);
  1.1631 +			}
  1.1632 +			if (strlen(buf) > len)
  1.1633 +				return NULL;
  1.1634 +			strlcpy(dst, buf, len);
  1.1635 +			return dst;
  1.1636 +		}
  1.1637 +		i = 0;
  1.1638 +		while (i < 8) {
  1.1639 +			if (words[i] == 0) {
  1.1640 +				curGapPos = i++;
  1.1641 +				curGapLen = 1;
  1.1642 +				while (i<8 && words[i] == 0) {
  1.1643 +					++i; ++curGapLen;
  1.1644 +				}
  1.1645 +				if (curGapLen > longestGapLen) {
  1.1646 +					longestGapPos = curGapPos;
  1.1647 +					longestGapLen = curGapLen;
  1.1648 +				}
  1.1649 +			} else {
  1.1650 +				++i;
  1.1651 +			}
  1.1652 +		}
  1.1653 +		if (longestGapLen<=1)
  1.1654 +			longestGapPos = -1;
  1.1655 +
  1.1656 +		cp = buf;
  1.1657 +		for (i = 0; i < 8; ++i) {
  1.1658 +			if (words[i] == 0 && longestGapPos == i) {
  1.1659 +				if (i == 0)
  1.1660 +					*cp++ = ':';
  1.1661 +				*cp++ = ':';
  1.1662 +				while (i < 8 && words[i] == 0)
  1.1663 +					++i;
  1.1664 +				--i; /* to compensate for loop increment. */
  1.1665 +			} else {
  1.1666 +				evutil_snprintf(cp,
  1.1667 +								sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
  1.1668 +				cp += strlen(cp);
  1.1669 +				if (i != 7)
  1.1670 +					*cp++ = ':';
  1.1671 +			}
  1.1672 +		}
  1.1673 +		*cp = '\0';
  1.1674 +		if (strlen(buf) > len)
  1.1675 +			return NULL;
  1.1676 +		strlcpy(dst, buf, len);
  1.1677 +		return dst;
  1.1678 +#endif
  1.1679 +	} else {
  1.1680 +		return NULL;
  1.1681 +	}
  1.1682 +#endif
  1.1683 +}
  1.1684 +
  1.1685 +int
  1.1686 +evutil_inet_pton(int af, const char *src, void *dst)
  1.1687 +{
  1.1688 +#if defined(_EVENT_HAVE_INET_PTON) && !defined(USE_INTERNAL_PTON)
  1.1689 +	return inet_pton(af, src, dst);
  1.1690 +#else
  1.1691 +	if (af == AF_INET) {
  1.1692 +		int a,b,c,d;
  1.1693 +		char more;
  1.1694 +		struct in_addr *addr = dst;
  1.1695 +		if (sscanf(src, "%d.%d.%d.%d%c", &a,&b,&c,&d,&more) != 4)
  1.1696 +			return 0;
  1.1697 +		if (a < 0 || a > 255) return 0;
  1.1698 +		if (b < 0 || b > 255) return 0;
  1.1699 +		if (c < 0 || c > 255) return 0;
  1.1700 +		if (d < 0 || d > 255) return 0;
  1.1701 +		addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
  1.1702 +		return 1;
  1.1703 +#ifdef AF_INET6
  1.1704 +	} else if (af == AF_INET6) {
  1.1705 +		struct in6_addr *out = dst;
  1.1706 +		ev_uint16_t words[8];
  1.1707 +		int gapPos = -1, i, setWords=0;
  1.1708 +		const char *dot = strchr(src, '.');
  1.1709 +		const char *eow; /* end of words. */
  1.1710 +		if (dot == src)
  1.1711 +			return 0;
  1.1712 +		else if (!dot)
  1.1713 +			eow = src+strlen(src);
  1.1714 +		else {
  1.1715 +			int byte1,byte2,byte3,byte4;
  1.1716 +			char more;
  1.1717 +			for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT(*eow); --eow)
  1.1718 +				;
  1.1719 +			++eow;
  1.1720 +
  1.1721 +			/* We use "scanf" because some platform inet_aton()s are too lax
  1.1722 +			 * about IPv4 addresses of the form "1.2.3" */
  1.1723 +			if (sscanf(eow, "%d.%d.%d.%d%c",
  1.1724 +					   &byte1,&byte2,&byte3,&byte4,&more) != 4)
  1.1725 +				return 0;
  1.1726 +
  1.1727 +			if (byte1 > 255 || byte1 < 0 ||
  1.1728 +				byte2 > 255 || byte2 < 0 ||
  1.1729 +				byte3 > 255 || byte3 < 0 ||
  1.1730 +				byte4 > 255 || byte4 < 0)
  1.1731 +				return 0;
  1.1732 +
  1.1733 +			words[6] = (byte1<<8) | byte2;
  1.1734 +			words[7] = (byte3<<8) | byte4;
  1.1735 +			setWords += 2;
  1.1736 +		}
  1.1737 +
  1.1738 +		i = 0;
  1.1739 +		while (src < eow) {
  1.1740 +			if (i > 7)
  1.1741 +				return 0;
  1.1742 +			if (EVUTIL_ISXDIGIT(*src)) {
  1.1743 +				char *next;
  1.1744 +				long r = strtol(src, &next, 16);
  1.1745 +				if (next > 4+src)
  1.1746 +					return 0;
  1.1747 +				if (next == src)
  1.1748 +					return 0;
  1.1749 +				if (r<0 || r>65536)
  1.1750 +					return 0;
  1.1751 +
  1.1752 +				words[i++] = (ev_uint16_t)r;
  1.1753 +				setWords++;
  1.1754 +				src = next;
  1.1755 +				if (*src != ':' && src != eow)
  1.1756 +					return 0;
  1.1757 +				++src;
  1.1758 +			} else if (*src == ':' && i > 0 && gapPos==-1) {
  1.1759 +				gapPos = i;
  1.1760 +				++src;
  1.1761 +			} else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
  1.1762 +				gapPos = i;
  1.1763 +				src += 2;
  1.1764 +			} else {
  1.1765 +				return 0;
  1.1766 +			}
  1.1767 +		}
  1.1768 +
  1.1769 +		if (setWords > 8 ||
  1.1770 +			(setWords == 8 && gapPos != -1) ||
  1.1771 +			(setWords < 8 && gapPos == -1))
  1.1772 +			return 0;
  1.1773 +
  1.1774 +		if (gapPos >= 0) {
  1.1775 +			int nToMove = setWords - (dot ? 2 : 0) - gapPos;
  1.1776 +			int gapLen = 8 - setWords;
  1.1777 +			/* assert(nToMove >= 0); */
  1.1778 +			if (nToMove < 0)
  1.1779 +				return -1; /* should be impossible */
  1.1780 +			memmove(&words[gapPos+gapLen], &words[gapPos],
  1.1781 +					sizeof(ev_uint16_t)*nToMove);
  1.1782 +			memset(&words[gapPos], 0, sizeof(ev_uint16_t)*gapLen);
  1.1783 +		}
  1.1784 +		for (i = 0; i < 8; ++i) {
  1.1785 +			out->s6_addr[2*i  ] = words[i] >> 8;
  1.1786 +			out->s6_addr[2*i+1] = words[i] & 0xff;
  1.1787 +		}
  1.1788 +
  1.1789 +		return 1;
  1.1790 +#endif
  1.1791 +	} else {
  1.1792 +		return -1;
  1.1793 +	}
  1.1794 +#endif
  1.1795 +}
  1.1796 +
  1.1797 +int
  1.1798 +evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
  1.1799 +{
  1.1800 +	int port;
  1.1801 +	char buf[128];
  1.1802 +	const char *cp, *addr_part, *port_part;
  1.1803 +	int is_ipv6;
  1.1804 +	/* recognized formats are:
  1.1805 +	 * [ipv6]:port
  1.1806 +	 * ipv6
  1.1807 +	 * [ipv6]
  1.1808 +	 * ipv4:port
  1.1809 +	 * ipv4
  1.1810 +	 */
  1.1811 +
  1.1812 +	cp = strchr(ip_as_string, ':');
  1.1813 +	if (*ip_as_string == '[') {
  1.1814 +		int len;
  1.1815 +		if (!(cp = strchr(ip_as_string, ']'))) {
  1.1816 +			return -1;
  1.1817 +		}
  1.1818 +		len = (int) ( cp-(ip_as_string + 1) );
  1.1819 +		if (len > (int)sizeof(buf)-1) {
  1.1820 +			return -1;
  1.1821 +		}
  1.1822 +		memcpy(buf, ip_as_string+1, len);
  1.1823 +		buf[len] = '\0';
  1.1824 +		addr_part = buf;
  1.1825 +		if (cp[1] == ':')
  1.1826 +			port_part = cp+2;
  1.1827 +		else
  1.1828 +			port_part = NULL;
  1.1829 +		is_ipv6 = 1;
  1.1830 +	} else if (cp && strchr(cp+1, ':')) {
  1.1831 +		is_ipv6 = 1;
  1.1832 +		addr_part = ip_as_string;
  1.1833 +		port_part = NULL;
  1.1834 +	} else if (cp) {
  1.1835 +		is_ipv6 = 0;
  1.1836 +		if (cp - ip_as_string > (int)sizeof(buf)-1) {
  1.1837 +			return -1;
  1.1838 +		}
  1.1839 +		memcpy(buf, ip_as_string, cp-ip_as_string);
  1.1840 +		buf[cp-ip_as_string] = '\0';
  1.1841 +		addr_part = buf;
  1.1842 +		port_part = cp+1;
  1.1843 +	} else {
  1.1844 +		addr_part = ip_as_string;
  1.1845 +		port_part = NULL;
  1.1846 +		is_ipv6 = 0;
  1.1847 +	}
  1.1848 +
  1.1849 +	if (port_part == NULL) {
  1.1850 +		port = 0;
  1.1851 +	} else {
  1.1852 +		port = atoi(port_part);
  1.1853 +		if (port <= 0 || port > 65535) {
  1.1854 +			return -1;
  1.1855 +		}
  1.1856 +	}
  1.1857 +
  1.1858 +	if (!addr_part)
  1.1859 +		return -1; /* Should be impossible. */
  1.1860 +#ifdef AF_INET6
  1.1861 +	if (is_ipv6)
  1.1862 +	{
  1.1863 +		struct sockaddr_in6 sin6;
  1.1864 +		memset(&sin6, 0, sizeof(sin6));
  1.1865 +#ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
  1.1866 +		sin6.sin6_len = sizeof(sin6);
  1.1867 +#endif
  1.1868 +		sin6.sin6_family = AF_INET6;
  1.1869 +		sin6.sin6_port = htons(port);
  1.1870 +		if (1 != evutil_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr))
  1.1871 +			return -1;
  1.1872 +		if ((int)sizeof(sin6) > *outlen)
  1.1873 +			return -1;
  1.1874 +		memset(out, 0, *outlen);
  1.1875 +		memcpy(out, &sin6, sizeof(sin6));
  1.1876 +		*outlen = sizeof(sin6);
  1.1877 +		return 0;
  1.1878 +	}
  1.1879 +	else
  1.1880 +#endif
  1.1881 +	{
  1.1882 +		struct sockaddr_in sin;
  1.1883 +		memset(&sin, 0, sizeof(sin));
  1.1884 +#ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  1.1885 +		sin.sin_len = sizeof(sin);
  1.1886 +#endif
  1.1887 +		sin.sin_family = AF_INET;
  1.1888 +		sin.sin_port = htons(port);
  1.1889 +		if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr))
  1.1890 +			return -1;
  1.1891 +		if ((int)sizeof(sin) > *outlen)
  1.1892 +			return -1;
  1.1893 +		memset(out, 0, *outlen);
  1.1894 +		memcpy(out, &sin, sizeof(sin));
  1.1895 +		*outlen = sizeof(sin);
  1.1896 +		return 0;
  1.1897 +	}
  1.1898 +}
  1.1899 +
  1.1900 +const char *
  1.1901 +evutil_format_sockaddr_port(const struct sockaddr *sa, char *out, size_t outlen)
  1.1902 +{
  1.1903 +	char b[128];
  1.1904 +	const char *res=NULL;
  1.1905 +	int port;
  1.1906 +	if (sa->sa_family == AF_INET) {
  1.1907 +		const struct sockaddr_in *sin = (const struct sockaddr_in*)sa;
  1.1908 +		res = evutil_inet_ntop(AF_INET, &sin->sin_addr,b,sizeof(b));
  1.1909 +		port = ntohs(sin->sin_port);
  1.1910 +		if (res) {
  1.1911 +			evutil_snprintf(out, outlen, "%s:%d", b, port);
  1.1912 +			return out;
  1.1913 +		}
  1.1914 +	} else if (sa->sa_family == AF_INET6) {
  1.1915 +		const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6*)sa;
  1.1916 +		res = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr,b,sizeof(b));
  1.1917 +		port = ntohs(sin6->sin6_port);
  1.1918 +		if (res) {
  1.1919 +			evutil_snprintf(out, outlen, "[%s]:%d", b, port);
  1.1920 +			return out;
  1.1921 +		}
  1.1922 +	}
  1.1923 +
  1.1924 +	evutil_snprintf(out, outlen, "<addr with socktype %d>",
  1.1925 +	    (int)sa->sa_family);
  1.1926 +	return out;
  1.1927 +}
  1.1928 +
  1.1929 +int
  1.1930 +evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
  1.1931 +    int include_port)
  1.1932 +{
  1.1933 +	int r;
  1.1934 +	if (0 != (r = (sa1->sa_family - sa2->sa_family)))
  1.1935 +		return r;
  1.1936 +
  1.1937 +	if (sa1->sa_family == AF_INET) {
  1.1938 +		const struct sockaddr_in *sin1, *sin2;
  1.1939 +		sin1 = (const struct sockaddr_in *)sa1;
  1.1940 +		sin2 = (const struct sockaddr_in *)sa2;
  1.1941 +		if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
  1.1942 +			return -1;
  1.1943 +		else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
  1.1944 +			return 1;
  1.1945 +		else if (include_port &&
  1.1946 +		    (r = ((int)sin1->sin_port - (int)sin2->sin_port)))
  1.1947 +			return r;
  1.1948 +		else
  1.1949 +			return 0;
  1.1950 +	}
  1.1951 +#ifdef AF_INET6
  1.1952 +	else if (sa1->sa_family == AF_INET6) {
  1.1953 +		const struct sockaddr_in6 *sin1, *sin2;
  1.1954 +		sin1 = (const struct sockaddr_in6 *)sa1;
  1.1955 +		sin2 = (const struct sockaddr_in6 *)sa2;
  1.1956 +		if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
  1.1957 +			return r;
  1.1958 +		else if (include_port &&
  1.1959 +		    (r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
  1.1960 +			return r;
  1.1961 +		else
  1.1962 +			return 0;
  1.1963 +	}
  1.1964 +#endif
  1.1965 +	return 1;
  1.1966 +}
  1.1967 +
  1.1968 +/* Tables to implement ctypes-replacement EVUTIL_IS*() functions.  Each table
  1.1969 + * has 256 bits to look up whether a character is in some set or not.  This
  1.1970 + * fails on non-ASCII platforms, but so does every other place where we
  1.1971 + * take a char and write it onto the network.
  1.1972 + **/
  1.1973 +static const ev_uint32_t EVUTIL_ISALPHA_TABLE[8] =
  1.1974 +  { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
  1.1975 +static const ev_uint32_t EVUTIL_ISALNUM_TABLE[8] =
  1.1976 +  { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
  1.1977 +static const ev_uint32_t EVUTIL_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
  1.1978 +static const ev_uint32_t EVUTIL_ISXDIGIT_TABLE[8] =
  1.1979 +  { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
  1.1980 +static const ev_uint32_t EVUTIL_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
  1.1981 +static const ev_uint32_t EVUTIL_ISPRINT_TABLE[8] =
  1.1982 +  { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
  1.1983 +static const ev_uint32_t EVUTIL_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
  1.1984 +static const ev_uint32_t EVUTIL_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
  1.1985 +/* Upper-casing and lowercasing tables to map characters to upper/lowercase
  1.1986 + * equivalents. */
  1.1987 +static const unsigned char EVUTIL_TOUPPER_TABLE[256] = {
  1.1988 +  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
  1.1989 +  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
  1.1990 +  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
  1.1991 +  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
  1.1992 +  64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
  1.1993 +  80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
  1.1994 +  96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
  1.1995 +  80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
  1.1996 +  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
  1.1997 +  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
  1.1998 +  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  1.1999 +  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  1.2000 +  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  1.2001 +  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  1.2002 +  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  1.2003 +  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
  1.2004 +};
  1.2005 +static const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
  1.2006 +  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
  1.2007 +  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
  1.2008 +  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
  1.2009 +  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
  1.2010 +  64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
  1.2011 +  112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
  1.2012 +  96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
  1.2013 +  112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
  1.2014 +  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
  1.2015 +  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
  1.2016 +  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  1.2017 +  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  1.2018 +  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  1.2019 +  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  1.2020 +  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  1.2021 +  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
  1.2022 +};
  1.2023 +
  1.2024 +#define IMPL_CTYPE_FN(name)						\
  1.2025 +	int EVUTIL_##name(char c) {					\
  1.2026 +		ev_uint8_t u = c;					\
  1.2027 +		return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31))); \
  1.2028 +	}
  1.2029 +IMPL_CTYPE_FN(ISALPHA)
  1.2030 +IMPL_CTYPE_FN(ISALNUM)
  1.2031 +IMPL_CTYPE_FN(ISSPACE)
  1.2032 +IMPL_CTYPE_FN(ISDIGIT)
  1.2033 +IMPL_CTYPE_FN(ISXDIGIT)
  1.2034 +IMPL_CTYPE_FN(ISPRINT)
  1.2035 +IMPL_CTYPE_FN(ISLOWER)
  1.2036 +IMPL_CTYPE_FN(ISUPPER)
  1.2037 +
  1.2038 +char EVUTIL_TOLOWER(char c)
  1.2039 +{
  1.2040 +	return ((char)EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]);
  1.2041 +}
  1.2042 +char EVUTIL_TOUPPER(char c)
  1.2043 +{
  1.2044 +	return ((char)EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]);
  1.2045 +}
  1.2046 +int
  1.2047 +evutil_ascii_strcasecmp(const char *s1, const char *s2)
  1.2048 +{
  1.2049 +	char c1, c2;
  1.2050 +	while (1) {
  1.2051 +		c1 = EVUTIL_TOLOWER(*s1++);
  1.2052 +		c2 = EVUTIL_TOLOWER(*s2++);
  1.2053 +		if (c1 < c2)
  1.2054 +			return -1;
  1.2055 +		else if (c1 > c2)
  1.2056 +			return 1;
  1.2057 +		else if (c1 == 0)
  1.2058 +			return 0;
  1.2059 +	}
  1.2060 +}
  1.2061 +int evutil_ascii_strncasecmp(const char *s1, const char *s2, size_t n)
  1.2062 +{
  1.2063 +	char c1, c2;
  1.2064 +	while (n--) {
  1.2065 +		c1 = EVUTIL_TOLOWER(*s1++);
  1.2066 +		c2 = EVUTIL_TOLOWER(*s2++);
  1.2067 +		if (c1 < c2)
  1.2068 +			return -1;
  1.2069 +		else if (c1 > c2)
  1.2070 +			return 1;
  1.2071 +		else if (c1 == 0)
  1.2072 +			return 0;
  1.2073 +	}
  1.2074 +	return 0;
  1.2075 +}
  1.2076 +
  1.2077 +static int
  1.2078 +evutil_issetugid(void)
  1.2079 +{
  1.2080 +#ifdef _EVENT_HAVE_ISSETUGID
  1.2081 +	return issetugid();
  1.2082 +#else
  1.2083 +
  1.2084 +#ifdef _EVENT_HAVE_GETEUID
  1.2085 +	if (getuid() != geteuid())
  1.2086 +		return 1;
  1.2087 +#endif
  1.2088 +#ifdef _EVENT_HAVE_GETEGID
  1.2089 +	if (getgid() != getegid())
  1.2090 +		return 1;
  1.2091 +#endif
  1.2092 +	return 0;
  1.2093 +#endif
  1.2094 +}
  1.2095 +
  1.2096 +const char *
  1.2097 +evutil_getenv(const char *varname)
  1.2098 +{
  1.2099 +	if (evutil_issetugid())
  1.2100 +		return NULL;
  1.2101 +
  1.2102 +	return getenv(varname);
  1.2103 +}
  1.2104 +
  1.2105 +long
  1.2106 +_evutil_weakrand(void)
  1.2107 +{
  1.2108 +#ifdef WIN32
  1.2109 +	return rand();
  1.2110 +#else
  1.2111 +	return random();
  1.2112 +#endif
  1.2113 +}
  1.2114 +
  1.2115 +int
  1.2116 +evutil_sockaddr_is_loopback(const struct sockaddr *addr)
  1.2117 +{
  1.2118 +	static const char LOOPBACK_S6[16] =
  1.2119 +	    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
  1.2120 +	if (addr->sa_family == AF_INET) {
  1.2121 +		struct sockaddr_in *sin = (struct sockaddr_in *)addr;
  1.2122 +		return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
  1.2123 +	} else if (addr->sa_family == AF_INET6) {
  1.2124 +		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
  1.2125 +		return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
  1.2126 +	}
  1.2127 +	return 0;
  1.2128 +}
  1.2129 +
  1.2130 +#define MAX_SECONDS_IN_MSEC_LONG \
  1.2131 +	(((LONG_MAX) - 999) / 1000)
  1.2132 +
  1.2133 +long
  1.2134 +evutil_tv_to_msec(const struct timeval *tv)
  1.2135 +{
  1.2136 +	if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
  1.2137 +		return -1;
  1.2138 +
  1.2139 +	return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
  1.2140 +}
  1.2141 +
  1.2142 +int
  1.2143 +evutil_hex_char_to_int(char c)
  1.2144 +{
  1.2145 +	switch(c)
  1.2146 +	{
  1.2147 +		case '0': return 0;
  1.2148 +		case '1': return 1;
  1.2149 +		case '2': return 2;
  1.2150 +		case '3': return 3;
  1.2151 +		case '4': return 4;
  1.2152 +		case '5': return 5;
  1.2153 +		case '6': return 6;
  1.2154 +		case '7': return 7;
  1.2155 +		case '8': return 8;
  1.2156 +		case '9': return 9;
  1.2157 +		case 'A': case 'a': return 10;
  1.2158 +		case 'B': case 'b': return 11;
  1.2159 +		case 'C': case 'c': return 12;
  1.2160 +		case 'D': case 'd': return 13;
  1.2161 +		case 'E': case 'e': return 14;
  1.2162 +		case 'F': case 'f': return 15;
  1.2163 +	}
  1.2164 +	return -1;
  1.2165 +}
  1.2166 +
  1.2167 +#ifdef WIN32
  1.2168 +HANDLE
  1.2169 +evutil_load_windows_system_library(const TCHAR *library_name)
  1.2170 +{
  1.2171 +  TCHAR path[MAX_PATH];
  1.2172 +  unsigned n;
  1.2173 +  n = GetSystemDirectory(path, MAX_PATH);
  1.2174 +  if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
  1.2175 +    return 0;
  1.2176 +  _tcscat(path, TEXT("\\"));
  1.2177 +  _tcscat(path, library_name);
  1.2178 +  return LoadLibrary(path);
  1.2179 +}
  1.2180 +#endif
  1.2181 +

mercurial