LCOV - code coverage report
Current view: top level - lib/net - socket.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 93 187 49.7 %
Date: 2021-11-24 03:28:48 Functions: 18 24 75.0 %

          Line data    Source code
       1             : /* Copyright (c) 2003-2004, Roger Dingledine
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : /**
       7             :  * \file socket.c
       8             :  * \brief Compatibility and utility functions for working with network
       9             :  *    sockets.
      10             :  **/
      11             : 
      12             : #include "lib/net/socket.h"
      13             : #include "lib/net/socketpair.h"
      14             : #include "lib/net/address.h"
      15             : #include "lib/cc/compat_compiler.h"
      16             : #include "lib/err/torerr.h"
      17             : #include "lib/lock/compat_mutex.h"
      18             : #include "lib/log/log.h"
      19             : #include "lib/log/util_bug.h"
      20             : 
      21             : #ifdef _WIN32
      22             : #include <winsock2.h>
      23             : #include <windows.h>
      24             : #endif
      25             : #ifdef HAVE_UNISTD_H
      26             : #include <unistd.h>
      27             : #endif
      28             : #ifdef HAVE_FCNTL_H
      29             : #include <fcntl.h>
      30             : #endif
      31             : #include <stddef.h>
      32             : #include <string.h>
      33             : #ifdef __FreeBSD__
      34             : #include <sys/sysctl.h>
      35             : #endif
      36             : 
      37             : /** Called before we make any calls to network-related functions.
      38             :  * (Some operating systems require their network libraries to be
      39             :  * initialized.) */
      40             : int
      41        5560 : network_init(void)
      42             : {
      43             : #ifdef _WIN32
      44             :   /* This silly exercise is necessary before windows will allow
      45             :    * gethostbyname to work. */
      46             :   WSADATA WSAData;
      47             :   int r;
      48             :   r = WSAStartup(0x101,&WSAData);
      49             :   if (r) {
      50             :     log_warn(LD_NET,"Error initializing windows network layer: code was %d",r);
      51             :     return -1;
      52             :   }
      53             :   if (sizeof(SOCKET) != sizeof(tor_socket_t)) {
      54             :     log_warn(LD_BUG,"The tor_socket_t type does not match SOCKET in size; Tor "
      55             :              "might not work. (Sizes are %d and %d respectively.)",
      56             :              (int)sizeof(tor_socket_t), (int)sizeof(SOCKET));
      57             :   }
      58             :   /* WSAData.iMaxSockets might show the max sockets we're allowed to use.
      59             :    * We might use it to complain if we're trying to be a server but have
      60             :    * too few sockets available. */
      61             : #endif /* defined(_WIN32) */
      62        5560 :   return 0;
      63             : }
      64             : 
      65             : /**
      66             :  * Warn the user if any system network parameters should be changed.
      67             :  */
      68             : void
      69         558 : check_network_configuration(bool server_mode)
      70             : {
      71             : #ifdef __FreeBSD__
      72             :   if (server_mode) {
      73             :     int random_id_state;
      74             :     size_t state_size = sizeof(random_id_state);
      75             : 
      76             :     if (sysctlbyname("net.inet.ip.random_id", &random_id_state,
      77             :                      &state_size, NULL, 0)) {
      78             :       log_warn(LD_CONFIG,
      79             :                "Failed to figure out if IP ids are randomized.");
      80             :     } else if (random_id_state == 0) {
      81             :       log_warn(LD_CONFIG, "Looks like IP ids are not randomized. "
      82             :                "Please consider setting the net.inet.ip.random_id sysctl, "
      83             :                "so your relay makes it harder to figure out how busy it is.");
      84             :     }
      85             :   }
      86             : #else /* !defined(__FreeBSD__) */
      87         558 :   (void) server_mode;
      88             : #endif /* defined(__FreeBSD__) */
      89         558 : }
      90             : 
      91             : /* When set_max_file_sockets() is called, update this with the max file
      92             :  * descriptor value so we can use it to check the limit when opening a new
      93             :  * socket. Default value is what Debian sets as the default hard limit. */
      94             : static int max_sockets = 1024;
      95             : 
      96             : /** Return the maximum number of allowed sockets. */
      97             : int
      98           1 : get_max_sockets(void)
      99             : {
     100           1 :   return max_sockets;
     101             : }
     102             : 
     103             : /** Set the maximum number of allowed sockets to <b>n</b> */
     104             : void
     105           8 : set_max_sockets(int n)
     106             : {
     107           8 :   max_sockets = n;
     108           8 : }
     109             : 
     110             : #undef DEBUG_SOCKET_COUNTING
     111             : #ifdef DEBUG_SOCKET_COUNTING
     112             : #include "lib/container/bitarray.h"
     113             : 
     114             : /** A bitarray of all fds that should be passed to tor_socket_close(). Only
     115             :  * used if DEBUG_SOCKET_COUNTING is defined. */
     116             : static bitarray_t *open_sockets = NULL;
     117             : /** The size of <b>open_sockets</b>, in bits. */
     118             : static int max_socket = -1;
     119             : #endif /* defined(DEBUG_SOCKET_COUNTING) */
     120             : 
     121             : /** Count of number of sockets currently open.  (Undercounts sockets opened by
     122             :  * eventdns and libevent.) */
     123             : static int n_sockets_open = 0;
     124             : 
     125             : /** Mutex to protect open_sockets, max_socket, and n_sockets_open. */
     126             : static tor_mutex_t *socket_accounting_mutex = NULL;
     127             : 
     128             : /** Helper: acquire the socket accounting lock. */
     129             : static inline void
     130         103 : socket_accounting_lock(void)
     131             : {
     132         103 :   if (PREDICT_UNLIKELY(!socket_accounting_mutex))
     133          19 :     socket_accounting_mutex = tor_mutex_new();
     134         103 :   tor_mutex_acquire(socket_accounting_mutex);
     135         103 : }
     136             : 
     137             : /** Helper: release the socket accounting lock. */
     138             : static inline void
     139         103 : socket_accounting_unlock(void)
     140             : {
     141         103 :   tor_mutex_release(socket_accounting_mutex);
     142         103 : }
     143             : 
     144             : /** As close(), but guaranteed to work for sockets across platforms (including
     145             :  * Windows, where close()ing a socket doesn't work.  Returns 0 on success and
     146             :  * the socket error code on failure. */
     147             : int
     148          34 : tor_close_socket_simple(tor_socket_t s)
     149             : {
     150          34 :   int r = 0;
     151             : 
     152             :   /* On Windows, you have to call close() on fds returned by open(),
     153             :   * and closesocket() on fds returned by socket().  On Unix, everything
     154             :   * gets close()'d.  We abstract this difference by always using
     155             :   * tor_close_socket to close sockets, and always using close() on
     156             :   * files.
     157             :   */
     158             :   #if defined(_WIN32)
     159             :     r = closesocket(s);
     160             :   #else
     161          34 :     r = close(s);
     162             :   #endif
     163             : 
     164          34 :   if (r != 0) {
     165           5 :     int err = tor_socket_errno(-1);
     166           5 :     log_info(LD_NET, "Close returned an error: %s", tor_socket_strerror(err));
     167           5 :     return err;
     168             :   }
     169             : 
     170             :   return r;
     171             : }
     172             : 
     173             : /** @{ */
     174             : #ifdef DEBUG_SOCKET_COUNTING
     175             : /** Helper: if DEBUG_SOCKET_COUNTING is enabled, remember that <b>s</b> is
     176             :  * now an open socket. */
     177             : static inline void
     178             : mark_socket_open(tor_socket_t s)
     179             : {
     180             :   /* XXXX This bitarray business will NOT work on windows: sockets aren't
     181             :      small ints there. */
     182             :   if (s > max_socket) {
     183             :     if (max_socket == -1) {
     184             :       open_sockets = bitarray_init_zero(s+128);
     185             :       max_socket = s+128;
     186             :     } else {
     187             :       open_sockets = bitarray_expand(open_sockets, max_socket, s+128);
     188             :       max_socket = s+128;
     189             :     }
     190             :   }
     191             :   if (bitarray_is_set(open_sockets, s)) {
     192             :     log_warn(LD_BUG, "I thought that %d was already open, but socket() just "
     193             :              "gave it to me!", s);
     194             :   }
     195             :   bitarray_set(open_sockets, s);
     196             : }
     197             : static inline void
     198             : mark_socket_closed(tor_socket_t s)
     199             : {
     200             :   if (s > max_socket || ! bitarray_is_set(open_sockets, s)) {
     201             :     log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_"
     202             :              "socket(), or that was already closed or something.", s);
     203             :   } else {
     204             :     tor_assert(open_sockets && s <= max_socket);
     205             :     bitarray_clear(open_sockets, s);
     206             :   }
     207             : }
     208             : #else /* !defined(DEBUG_SOCKET_COUNTING) */
     209             : #define mark_socket_open(s) ((void) (s))
     210             : #define mark_socket_closed(s) ((void) (s))
     211             : #endif /* defined(DEBUG_SOCKET_COUNTING) */
     212             : /** @} */
     213             : 
     214             : /** As tor_close_socket_simple(), but keeps track of the number
     215             :  * of open sockets. Returns 0 on success, -1 on failure. */
     216          32 : MOCK_IMPL(int,
     217             : tor_close_socket,(tor_socket_t s))
     218             : {
     219          32 :   int r = tor_close_socket_simple(s);
     220             : 
     221          32 :   socket_accounting_lock();
     222          32 :   mark_socket_closed(s);
     223          32 :   if (r == 0) {
     224          27 :     --n_sockets_open;
     225             :   } else {
     226             : #ifdef _WIN32
     227             :     if (r != WSAENOTSOCK)
     228             :       --n_sockets_open;
     229             : #else
     230           5 :     if (r != EBADF)
     231             :       --n_sockets_open; // LCOV_EXCL_LINE -- EIO and EINTR too hard to force.
     232             : #endif /* defined(_WIN32) */
     233             :     r = -1;
     234             :   }
     235             : 
     236          32 :   tor_assert_nonfatal(n_sockets_open >= 0);
     237          32 :   socket_accounting_unlock();
     238          32 :   return r;
     239             : }
     240             : 
     241             : /** As socket(), but counts the number of open sockets. */
     242          19 : MOCK_IMPL(tor_socket_t,
     243             : tor_open_socket,(int domain, int type, int protocol))
     244             : {
     245          19 :   return tor_open_socket_with_extensions(domain, type, protocol, 1, 0);
     246             : }
     247             : 
     248             : /** Mockable wrapper for connect(). */
     249          17 : MOCK_IMPL(tor_socket_t,
     250             : tor_connect_socket,(tor_socket_t sock, const struct sockaddr *address,
     251             :                      socklen_t address_len))
     252             : {
     253          17 :   return connect(sock,address,address_len);
     254             : }
     255             : 
     256             : /** As socket(), but creates a nonblocking socket and
     257             :  * counts the number of open sockets. */
     258             : tor_socket_t
     259           2 : tor_open_socket_nonblocking(int domain, int type, int protocol)
     260             : {
     261           2 :   return tor_open_socket_with_extensions(domain, type, protocol, 1, 1);
     262             : }
     263             : 
     264             : /** As socket(), but counts the number of open sockets and handles
     265             :  * socket creation with either of SOCK_CLOEXEC and SOCK_NONBLOCK specified.
     266             :  * <b>cloexec</b> and <b>nonblock</b> should be either 0 or 1 to indicate
     267             :  * if the corresponding extension should be used.*/
     268             : tor_socket_t
     269          25 : tor_open_socket_with_extensions(int domain, int type, int protocol,
     270             :                                 int cloexec, int nonblock)
     271             : {
     272          25 :   tor_socket_t s;
     273             : 
     274             :   /* We are about to create a new file descriptor so make sure we have
     275             :    * enough of them. */
     276          25 :   if (get_n_open_sockets() >= max_sockets - 1) {
     277             : #ifdef _WIN32
     278             :     WSASetLastError(WSAEMFILE);
     279             : #else
     280           0 :     errno = EMFILE;
     281             : #endif
     282           0 :     return TOR_INVALID_SOCKET;
     283             :   }
     284             : 
     285             : #if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
     286          25 :   int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
     287          25 :                   (nonblock ? SOCK_NONBLOCK : 0);
     288          25 :   s = socket(domain, type|ext_flags, protocol);
     289          25 :   if (SOCKET_OK(s))
     290          25 :     goto socket_ok;
     291             :   /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
     292             :    * even though we were built on a system with SOCK_CLOEXEC and SOCK_NONBLOCK
     293             :    * support, we are running on one without. */
     294           0 :   if (errno != EINVAL)
     295             :     return s;
     296             : #endif /* defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) */
     297             : 
     298           0 :   s = socket(domain, type, protocol);
     299           0 :   if (! SOCKET_OK(s))
     300             :     return s;
     301             : 
     302             : #if defined(FD_CLOEXEC)
     303           0 :   if (cloexec) {
     304           0 :     if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
     305           0 :       log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno));
     306           0 :       tor_close_socket_simple(s);
     307           0 :       return TOR_INVALID_SOCKET;
     308             :     }
     309             :   }
     310             : #else /* !defined(FD_CLOEXEC) */
     311             :   (void)cloexec;
     312             : #endif /* defined(FD_CLOEXEC) */
     313             : 
     314           0 :   if (nonblock) {
     315           0 :     if (set_socket_nonblocking(s) == -1) {
     316           0 :       tor_close_socket_simple(s);
     317           0 :       return TOR_INVALID_SOCKET;
     318             :     }
     319             :   }
     320             : 
     321           0 :   goto socket_ok; /* So that socket_ok will not be unused. */
     322             : 
     323          25 :  socket_ok:
     324          25 :   tor_take_socket_ownership(s);
     325          25 :   return s;
     326             : }
     327             : 
     328             : /**
     329             :  * For socket accounting: remember that we are the owner of the socket
     330             :  * <b>s</b>. This will prevent us from overallocating sockets, and prevent us
     331             :  * from asserting later when we close the socket <b>s</b>.
     332             :  */
     333             : void
     334          25 : tor_take_socket_ownership(tor_socket_t s)
     335             : {
     336          25 :   socket_accounting_lock();
     337          25 :   ++n_sockets_open;
     338          25 :   mark_socket_open(s);
     339          25 :   socket_accounting_unlock();
     340          25 : }
     341             : 
     342             : /**
     343             :  * For socket accounting: declare that we are no longer the owner of the
     344             :  * socket <b>s</b>. This will prevent us from overallocating sockets, and
     345             :  * prevent us from asserting later when we close the socket <b>s</b>.
     346             :  */
     347             : void
     348           0 : tor_release_socket_ownership(tor_socket_t s)
     349             : {
     350           0 :   socket_accounting_lock();
     351           0 :   --n_sockets_open;
     352           0 :   mark_socket_closed(s);
     353           0 :   socket_accounting_unlock();
     354           0 : }
     355             : 
     356             : /** As accept(), but counts the number of open sockets. */
     357             : tor_socket_t
     358           0 : tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len)
     359             : {
     360           0 :   return tor_accept_socket_with_extensions(sockfd, addr, len, 1, 0);
     361             : }
     362             : 
     363             : /** As accept(), but returns a nonblocking socket and
     364             :  * counts the number of open sockets. */
     365             : tor_socket_t
     366           0 : tor_accept_socket_nonblocking(tor_socket_t sockfd, struct sockaddr *addr,
     367             :                               socklen_t *len)
     368             : {
     369           0 :   return tor_accept_socket_with_extensions(sockfd, addr, len, 1, 1);
     370             : }
     371             : 
     372             : /** As accept(), but counts the number of open sockets and handles
     373             :  * socket creation with either of SOCK_CLOEXEC and SOCK_NONBLOCK specified.
     374             :  * <b>cloexec</b> and <b>nonblock</b> should be either 0 or 1 to indicate
     375             :  * if the corresponding extension should be used.*/
     376             : tor_socket_t
     377           0 : tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr,
     378             :                                  socklen_t *len, int cloexec, int nonblock)
     379             : {
     380           0 :   tor_socket_t s;
     381             : 
     382             :   /* We are about to create a new file descriptor so make sure we have
     383             :    * enough of them. */
     384           0 :   if (get_n_open_sockets() >= max_sockets - 1) {
     385             : #ifdef _WIN32
     386             :     WSASetLastError(WSAEMFILE);
     387             : #else
     388           0 :     errno = EMFILE;
     389             : #endif
     390           0 :     return TOR_INVALID_SOCKET;
     391             :   }
     392             : 
     393             : #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) \
     394             :   && defined(SOCK_NONBLOCK)
     395           0 :   int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
     396           0 :                   (nonblock ? SOCK_NONBLOCK : 0);
     397           0 :   s = accept4(sockfd, addr, len, ext_flags);
     398           0 :   if (SOCKET_OK(s))
     399           0 :     goto socket_ok;
     400             :   /* If we got an error, see if it is ENOSYS. ENOSYS indicates that,
     401             :    * even though we were built on a system with accept4 support, we
     402             :    * are running on one without. Also, check for EINVAL, which indicates that
     403             :    * we are missing SOCK_CLOEXEC/SOCK_NONBLOCK support. */
     404           0 :   if (errno != EINVAL && errno != ENOSYS)
     405             :     return s;
     406             : #endif /* defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) ... */
     407             : 
     408           0 :   s = accept(sockfd, addr, len);
     409           0 :   if (!SOCKET_OK(s))
     410             :     return s;
     411             : 
     412             : #if defined(FD_CLOEXEC)
     413           0 :   if (cloexec) {
     414           0 :     if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
     415           0 :       log_warn(LD_NET, "Couldn't set FD_CLOEXEC: %s", strerror(errno));
     416           0 :       tor_close_socket_simple(s);
     417           0 :       return TOR_INVALID_SOCKET;
     418             :     }
     419             :   }
     420             : #else /* !defined(FD_CLOEXEC) */
     421             :   (void)cloexec;
     422             : #endif /* defined(FD_CLOEXEC) */
     423             : 
     424           0 :   if (nonblock) {
     425           0 :     if (set_socket_nonblocking(s) == -1) {
     426           0 :       tor_close_socket_simple(s);
     427           0 :       return TOR_INVALID_SOCKET;
     428             :     }
     429             :   }
     430             : 
     431           0 :   goto socket_ok; /* So that socket_ok will not be unused. */
     432             : 
     433           0 :  socket_ok:
     434           0 :   tor_take_socket_ownership(s);
     435           0 :   return s;
     436             : }
     437             : 
     438             : /** Return the number of sockets we currently have opened. */
     439             : int
     440          44 : get_n_open_sockets(void)
     441             : {
     442          44 :   int n;
     443          44 :   socket_accounting_lock();
     444          44 :   n = n_sockets_open;
     445          44 :   socket_accounting_unlock();
     446          44 :   return n;
     447             : }
     448             : 
     449             : /**
     450             :  * Allocate a pair of connected sockets.  (Like socketpair(family,
     451             :  * type,protocol,fd), but works on systems that don't have
     452             :  * socketpair.)
     453             :  *
     454             :  * Currently, only (AF_UNIX, SOCK_STREAM, 0) sockets are supported.
     455             :  *
     456             :  * Note that on systems without socketpair, this call will fail if
     457             :  * localhost is inaccessible (for example, if the networking
     458             :  * stack is down). And even if it succeeds, the socket pair will not
     459             :  * be able to read while localhost is down later (the socket pair may
     460             :  * even close, depending on OS-specific timeouts). The socket pair
     461             :  * should work on IPv4-only, IPv6-only, and dual-stack systems, as long
     462             :  * as they have the standard localhost addresses.
     463             :  *
     464             :  * Returns 0 on success and -errno on failure; do not rely on the value
     465             :  * of errno or WSAGetLastError().
     466             :  **/
     467             : /* It would be nicer just to set errno, but that won't work for windows. */
     468             : int
     469           2 : tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
     470             : {
     471           2 :   int r;
     472             : //don't use win32 socketpairs (they are always bad)
     473             : #if defined(HAVE_SOCKETPAIR) && !defined(_WIN32)
     474             : 
     475             : #ifdef SOCK_CLOEXEC
     476           2 :   r = socketpair(family, type|SOCK_CLOEXEC, protocol, fd);
     477           2 :   if (r == 0)
     478           2 :     goto sockets_ok;
     479             :   /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
     480             :    * even though we were built on a system with SOCK_CLOEXEC support, we
     481             :    * are running on one without. */
     482           0 :   if (errno != EINVAL)
     483           0 :     return -errno;
     484             : #endif /* defined(SOCK_CLOEXEC) */
     485             : 
     486           0 :   r = socketpair(family, type, protocol, fd);
     487           0 :   if (r < 0)
     488           0 :     return -errno;
     489             : #else /* !(defined(HAVE_SOCKETPAIR) && !defined(_WIN32)) */
     490             :   r = tor_ersatz_socketpair(family, type, protocol, fd);
     491             :   if (r < 0)
     492             :     return -r;
     493             : #endif /* defined(HAVE_SOCKETPAIR) && !defined(_WIN32) */
     494             : 
     495             : #if defined(FD_CLOEXEC)
     496           0 :   if (SOCKET_OK(fd[0])) {
     497           0 :     r = fcntl(fd[0], F_SETFD, FD_CLOEXEC);
     498           0 :     if (r == -1) {
     499           0 :       close(fd[0]);
     500           0 :       close(fd[1]);
     501           0 :       return -errno;
     502             :     }
     503             :   }
     504           0 :   if (SOCKET_OK(fd[1])) {
     505           0 :     r = fcntl(fd[1], F_SETFD, FD_CLOEXEC);
     506           0 :     if (r == -1) {
     507           0 :       close(fd[0]);
     508           0 :       close(fd[1]);
     509           0 :       return -errno;
     510             :     }
     511             :   }
     512             : #endif /* defined(FD_CLOEXEC) */
     513           0 :   goto sockets_ok; /* So that sockets_ok will not be unused. */
     514             : 
     515           2 :  sockets_ok:
     516           2 :   socket_accounting_lock();
     517           2 :   if (SOCKET_OK(fd[0])) {
     518           2 :     ++n_sockets_open;
     519           2 :     mark_socket_open(fd[0]);
     520             :   }
     521           2 :   if (SOCKET_OK(fd[1])) {
     522           2 :     ++n_sockets_open;
     523           2 :     mark_socket_open(fd[1]);
     524             :   }
     525           2 :   socket_accounting_unlock();
     526             : 
     527           2 :   return 0;
     528             : }
     529             : 
     530             : /** Mockable wrapper for getsockname(). */
     531           9 : MOCK_IMPL(int,
     532             : tor_getsockname,(tor_socket_t sock, struct sockaddr *address,
     533             :                  socklen_t *address_len))
     534             : {
     535           9 :    return getsockname(sock, address, address_len);
     536             : }
     537             : 
     538             : /**
     539             :  * Find the local address associated with the socket <b>sock</b>, and
     540             :  * place it in *<b>addr_out</b>.  Return 0 on success, -1 on failure.
     541             :  *
     542             :  * (As tor_getsockname, but instead places the result in a tor_addr_t.) */
     543             : int
     544          11 : tor_addr_from_getsockname(struct tor_addr_t *addr_out, tor_socket_t sock)
     545             : {
     546          11 :   struct sockaddr_storage ss;
     547          11 :   socklen_t ss_len = sizeof(ss);
     548          11 :   memset(&ss, 0, sizeof(ss));
     549             : 
     550          11 :   if (tor_getsockname(sock, (struct sockaddr *) &ss, &ss_len) < 0)
     551             :     return -1;
     552             : 
     553          11 :   return tor_addr_from_sockaddr(addr_out, (struct sockaddr *)&ss, NULL);
     554             : }
     555             : 
     556             : /** Turn <b>socket</b> into a nonblocking socket. Return 0 on success, -1
     557             :  * on failure.
     558             :  */
     559             : int
     560           5 : set_socket_nonblocking(tor_socket_t sock)
     561             : {
     562             : #if defined(_WIN32)
     563             :   unsigned long nonblocking = 1;
     564             :   ioctlsocket(sock, FIONBIO, (unsigned long*) &nonblocking);
     565             : #else
     566           5 :   int flags;
     567             : 
     568           5 :   flags = fcntl(sock, F_GETFL, 0);
     569           5 :   if (flags == -1) {
     570           0 :     log_warn(LD_NET, "Couldn't get file status flags: %s", strerror(errno));
     571           0 :     return -1;
     572             :   }
     573           5 :   flags |= O_NONBLOCK;
     574           5 :   if (fcntl(sock, F_SETFL, flags) == -1) {
     575           0 :     log_warn(LD_NET, "Couldn't set file status flags: %s", strerror(errno));
     576           0 :     return -1;
     577             :   }
     578             : #endif /* defined(_WIN32) */
     579             : 
     580             :   return 0;
     581             : }
     582             : 
     583             : /** Read from <b>sock</b> to <b>buf</b>, until we get <b>count</b> bytes or
     584             :  * reach the end of the file.  Return the number of bytes read, or -1 on
     585             :  * error. Only use if fd is a blocking fd. */
     586             : ssize_t
     587           0 : read_all_from_socket(tor_socket_t sock, char *buf, size_t count)
     588             : {
     589           0 :   size_t numread = 0;
     590           0 :   ssize_t result;
     591             : 
     592           0 :   if (count > SIZE_T_CEILING || count > SSIZE_MAX) {
     593           0 :     errno = EINVAL;
     594           0 :     return -1;
     595             :   }
     596             : 
     597           0 :   while (numread < count) {
     598           0 :     result = tor_socket_recv(sock, buf+numread, count-numread, 0);
     599           0 :     if (result<0)
     600             :       return -1;
     601           0 :     else if (result == 0)
     602             :       break;
     603           0 :     numread += result;
     604             :   }
     605           0 :   return (ssize_t)numread;
     606             : }
     607             : 
     608             : /** Write <b>count</b> bytes from <b>buf</b> to <b>sock</b>. Return the number
     609             :  * of bytes written, or -1 on error.  Only use if fd is a blocking fd.  */
     610             : ssize_t
     611           0 : write_all_to_socket(tor_socket_t fd, const char *buf, size_t count)
     612             : {
     613           0 :   size_t written = 0;
     614           0 :   ssize_t result;
     615           0 :   raw_assert(count < SSIZE_MAX);
     616             : 
     617           0 :   while (written != count) {
     618           0 :     result = tor_socket_send(fd, buf+written, count-written, 0);
     619           0 :     if (result<0)
     620             :       return -1;
     621           0 :     written += result;
     622             :   }
     623           0 :   return (ssize_t)count;
     624             : }
     625             : 
     626             : /**
     627             :  * On Windows, WSAEWOULDBLOCK is not always correct: when you see it,
     628             :  * you need to ask the socket for its actual errno.  Also, you need to
     629             :  * get your errors from WSAGetLastError, not errno.  (If you supply a
     630             :  * socket of -1, we check WSAGetLastError, but don't correct
     631             :  * WSAEWOULDBLOCKs.)
     632             :  *
     633             :  * The upshot of all of this is that when a socket call fails, you
     634             :  * should call tor_socket_errno <em>at most once</em> on the failing
     635             :  * socket to get the error.
     636             :  */
     637             : #if defined(_WIN32)
     638             : int
     639             : tor_socket_errno(tor_socket_t sock)
     640             : {
     641             :   int optval, optvallen=sizeof(optval);
     642             :   int err = WSAGetLastError();
     643             :   if (err == WSAEWOULDBLOCK && SOCKET_OK(sock)) {
     644             :     if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval, &optvallen))
     645             :       return err;
     646             :     if (optval)
     647             :       return optval;
     648             :   }
     649             :   return err;
     650             : }
     651             : #endif /* defined(_WIN32) */
     652             : 
     653             : #if defined(_WIN32)
     654             : #define E(code, s) { code, (s " [" #code " ]") }
     655             : struct { int code; const char *msg; } windows_socket_errors[] = {
     656             :   E(WSAEINTR, "Interrupted function call"),
     657             :   E(WSAEACCES, "Permission denied"),
     658             :   E(WSAEFAULT, "Bad address"),
     659             :   E(WSAEINVAL, "Invalid argument"),
     660             :   E(WSAEMFILE, "Too many open files"),
     661             :   E(WSAEWOULDBLOCK,  "Resource temporarily unavailable"),
     662             :   E(WSAEINPROGRESS, "Operation now in progress"),
     663             :   E(WSAEALREADY, "Operation already in progress"),
     664             :   E(WSAENOTSOCK, "Socket operation on nonsocket"),
     665             :   E(WSAEDESTADDRREQ, "Destination address required"),
     666             :   E(WSAEMSGSIZE, "Message too long"),
     667             :   E(WSAEPROTOTYPE, "Protocol wrong for socket"),
     668             :   E(WSAENOPROTOOPT, "Bad protocol option"),
     669             :   E(WSAEPROTONOSUPPORT, "Protocol not supported"),
     670             :   E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
     671             :   /* What's the difference between NOTSUPP and NOSUPPORT? :) */
     672             :   E(WSAEOPNOTSUPP, "Operation not supported"),
     673             :   E(WSAEPFNOSUPPORT,  "Protocol family not supported"),
     674             :   E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
     675             :   E(WSAEADDRINUSE, "Address already in use"),
     676             :   E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
     677             :   E(WSAENETDOWN, "Network is down"),
     678             :   E(WSAENETUNREACH, "Network is unreachable"),
     679             :   E(WSAENETRESET, "Network dropped connection on reset"),
     680             :   E(WSAECONNABORTED, "Software caused connection abort"),
     681             :   E(WSAECONNRESET, "Connection reset by peer"),
     682             :   E(WSAENOBUFS, "No buffer space available"),
     683             :   E(WSAEISCONN, "Socket is already connected"),
     684             :   E(WSAENOTCONN, "Socket is not connected"),
     685             :   E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
     686             :   E(WSAETIMEDOUT, "Connection timed out"),
     687             :   E(WSAECONNREFUSED, "Connection refused"),
     688             :   E(WSAEHOSTDOWN, "Host is down"),
     689             :   E(WSAEHOSTUNREACH, "No route to host"),
     690             :   E(WSAEPROCLIM, "Too many processes"),
     691             :   /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
     692             :   E(WSASYSNOTREADY, "Network subsystem is unavailable"),
     693             :   E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
     694             :   E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
     695             :   E(WSAEDISCON, "Graceful shutdown now in progress"),
     696             : #ifdef WSATYPE_NOT_FOUND
     697             :   E(WSATYPE_NOT_FOUND, "Class type not found"),
     698             : #endif
     699             :   E(WSAHOST_NOT_FOUND, "Host not found"),
     700             :   E(WSATRY_AGAIN, "Nonauthoritative host not found"),
     701             :   E(WSANO_RECOVERY, "This is a nonrecoverable error"),
     702             :   E(WSANO_DATA, "Valid name, no data record of requested type)"),
     703             : 
     704             :   /* There are some more error codes whose numeric values are marked
     705             :    * <b>OS dependent</b>. They start with WSA_, apparently for the same
     706             :    * reason that practitioners of some craft traditions deliberately
     707             :    * introduce imperfections into their baskets and rugs "to allow the
     708             :    * evil spirits to escape."  If we catch them, then our binaries
     709             :    * might not report consistent results across versions of Windows.
     710             :    * Thus, I'm going to let them all fall through.
     711             :    */
     712             :   { -1, NULL },
     713             : };
     714             : /** There does not seem to be a strerror equivalent for Winsock errors.
     715             :  * Naturally, we have to roll our own.
     716             :  */
     717             : const char *
     718             : tor_socket_strerror(int e)
     719             : {
     720             :   int i;
     721             :   for (i=0; windows_socket_errors[i].code >= 0; ++i) {
     722             :     if (e == windows_socket_errors[i].code)
     723             :       return windows_socket_errors[i].msg;
     724             :   }
     725             :   return strerror(e);
     726             : }
     727             : #endif /* defined(_WIN32) */

Generated by: LCOV version 1.14