LCOV - code coverage report
Current view: top level - ipc/chromium/src/third_party/libevent - evutil.c (source / functions) Hit Total Coverage
Test: output.info Lines: 22 955 2.3 %
Date: 2017-07-14 16:53:18 Functions: 6 74 8.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13