LCOV - code coverage report
Current view: top level - fuzz - jbsockets.c (source / functions) Hit Total Coverage
Test: trace.lcov_info_final Lines: 47 283 16.6 %
Date: 2021-02-22 04:51:02 Functions: 9 15 60.0 %

          Line data    Source code
       1             : /*********************************************************************
       2             :  *
       3             :  * File        :  $Source: /cvsroot/ijbswa/current/jbsockets.c,v $
       4             :  *
       5             :  * Purpose     :  Contains wrappers for system-specific sockets code,
       6             :  *                so that the rest of Privoxy can be more
       7             :  *                OS-independent.  Contains #ifdefs to make this work
       8             :  *                on many platforms.
       9             :  *
      10             :  * Copyright   :  Written by and Copyright (C) 2001-2017 the
      11             :  *                Privoxy team. https://www.privoxy.org/
      12             :  *
      13             :  *                Based on the Internet Junkbuster originally written
      14             :  *                by and Copyright (C) 1997 Anonymous Coders and
      15             :  *                Junkbusters Corporation.  http://www.junkbusters.com
      16             :  *
      17             :  *                This program is free software; you can redistribute it
      18             :  *                and/or modify it under the terms of the GNU General
      19             :  *                Public License as published by the Free Software
      20             :  *                Foundation; either version 2 of the License, or (at
      21             :  *                your option) any later version.
      22             :  *
      23             :  *                This program is distributed in the hope that it will
      24             :  *                be useful, but WITHOUT ANY WARRANTY; without even the
      25             :  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
      26             :  *                PARTICULAR PURPOSE.  See the GNU General Public
      27             :  *                License for more details.
      28             :  *
      29             :  *                The GNU General Public License should be included with
      30             :  *                this file.  If not, you can view it at
      31             :  *                http://www.gnu.org/copyleft/gpl.html
      32             :  *                or write to the Free Software Foundation, Inc., 59
      33             :  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
      34             :  *
      35             :  *********************************************************************/
      36             : 
      37             : 
      38             : #include "config.h"
      39             : 
      40             : #include <stdlib.h>
      41             : #include <stdio.h>
      42             : #include <string.h>
      43             : #include <errno.h>
      44             : #include <fcntl.h>
      45             : #include <sys/types.h>
      46             : 
      47             : #ifdef _WIN32
      48             : 
      49             : #ifndef STRICT
      50             : #define STRICT
      51             : #endif
      52             : #include <winsock2.h>
      53             : #include <windows.h>
      54             : #include <sys/timeb.h>
      55             : #include <io.h>
      56             : 
      57             : #else
      58             : 
      59             : #include <unistd.h>
      60             : #include <sys/time.h>
      61             : #include <netinet/in.h>
      62             : #include <linux/sockios.h>
      63             : #include <netdb.h>
      64             : #include <sys/socket.h>
      65             : 
      66             : #ifndef __BEOS__
      67             : #include <netinet/tcp.h>
      68             : #include <arpa/inet.h>
      69             : #else
      70             : #include <socket.h>
      71             : #endif
      72             : 
      73             : #endif
      74             : 
      75             : #ifdef HAVE_POLL
      76             : #ifdef __GLIBC__
      77             : #include <sys/poll.h>
      78             : #else
      79             : #include <poll.h>
      80             : #endif /* def __GLIBC__ */
      81             : #endif /* HAVE_POLL */
      82             : 
      83             : #include "project.h"
      84             : 
      85             : /* For mutex semaphores only */
      86             : #include "jcc.h"
      87             : 
      88             : #include "jbsockets.h"
      89             : #include "filters.h"
      90             : #include "errlog.h"
      91             : #include "miscutil.h"
      92             : 
      93             : /* Mac OSX doesn't define AI_NUMERICSESRV */
      94             : #ifndef AI_NUMERICSERV
      95             : #define AI_NUMERICSERV 0
      96             : #endif
      97             : 
      98             : /*
      99             :  * Maximum number of gethostbyname(_r) retries in case of
     100             :  * soft errors (TRY_AGAIN).
     101             :  * XXX: Does it make sense to make this a config option?
     102             :  */
     103             : #define MAX_DNS_RETRIES 10
     104             : 
     105             : #ifdef HAVE_RFC2553
     106             : static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client_state *csp);
     107             : #else
     108             : static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct client_state *csp);
     109             : #endif
     110             : 
     111             : /*********************************************************************
     112             :  *
     113             :  * Function    :  set_no_delay_flag
     114             :  *
     115             :  * Description :  Disables the Nagle algorithm (TCP send coalescence)
     116             :  *                for the given socket.
     117             :  *
     118             :  * Parameters  :
     119             :  *          1  :  fd = The file descriptor to operate on
     120             :  *
     121             :  * Returns     :  void
     122             :  *
     123             :  *********************************************************************/
     124           0 : static void set_no_delay_flag(int fd)
     125             : {
     126             : #ifdef TCP_NODELAY
     127           0 :    int mi = 1;
     128             : 
     129           0 :    if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &mi, sizeof(int)))
     130             :    {
     131           0 :       log_error(LOG_LEVEL_ERROR,
     132             :          "Failed to disable TCP coalescence for socket %d", fd);
     133             :    }
     134             : #else
     135             : #warning set_no_delay_flag() is a nop due to lack of TCP_NODELAY
     136             : #endif /* def TCP_NODELAY */
     137           0 : }
     138             : 
     139             : /*********************************************************************
     140             :  *
     141             :  * Function    :  connect_to
     142             :  *
     143             :  * Description :  Open a socket and connect to it.  Will check
     144             :  *                that this is allowed according to ACL.
     145             :  *
     146             :  * Parameters  :
     147             :  *          1  :  host = hostname to connect to
     148             :  *          2  :  portnum = port to connect to (XXX: should be unsigned)
     149             :  *          3  :  csp = Current client state (buffers, headers, etc...)
     150             :  *
     151             :  * Returns     :  JB_INVALID_SOCKET => failure, else it is the socket
     152             :  *                file descriptor.
     153             :  *
     154             :  *********************************************************************/
     155        6474 : jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
     156             : {
     157        6474 :    return 0; //stdein always.
     158             :    jb_socket fd;
     159             :    int forwarded_connect_retries = 0;
     160             : 
     161             :    do
     162             :    {
     163             :       /*
     164             :        * XXX: The whole errno overloading is ridiculous and should
     165             :        *      be replaced with something sane and thread safe
     166             :        */
     167             :       /* errno = 0;*/
     168             : #ifdef HAVE_RFC2553
     169             :       fd = rfc2553_connect_to(host, portnum, csp);
     170             : #else
     171             :       fd = no_rfc2553_connect_to(host, portnum, csp);
     172             : #endif
     173             :       if ((fd != JB_INVALID_SOCKET) || (errno == EINVAL)
     174             :          || (csp->fwd == NULL)
     175             :          || ((csp->fwd->forward_host == NULL) && (csp->fwd->type == SOCKS_NONE)))
     176             :       {
     177             :          break;
     178             :       }
     179             :       forwarded_connect_retries++;
     180             :       if (csp->config->forwarded_connect_retries != 0)
     181             :       {
     182             :          log_error(LOG_LEVEL_ERROR,
     183             :             "Attempt %d of %d to connect to %s failed. Trying again.",
     184             :             forwarded_connect_retries, csp->config->forwarded_connect_retries + 1, host);
     185             :       }
     186             : 
     187             :    } while (forwarded_connect_retries < csp->config->forwarded_connect_retries);
     188             : 
     189             :    return fd;
     190             : }
     191             : 
     192             : #ifdef HAVE_RFC2553
     193             : /* Getaddrinfo implementation */
     194           0 : static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client_state *csp)
     195             : {
     196             :    struct addrinfo hints, *result, *rp;
     197             :    char service[6];
     198             :    int retval;
     199             :    jb_socket fd;
     200             : #ifdef HAVE_POLL
     201             :    struct pollfd poll_fd[1];
     202             : #else
     203             :    fd_set wfds;
     204             :    struct timeval timeout;
     205             : #endif
     206             : #if !defined(_WIN32) && !defined(__BEOS__)
     207             :    int   flags;
     208             : #endif
     209             :    int connect_failed;
     210             :    /*
     211             :     * XXX: Initializing it here is only necessary
     212             :     *      because not all situations are properly
     213             :     *      covered yet.
     214             :     */
     215           0 :    int socket_error = 0;
     216             : 
     217             : #ifdef FEATURE_ACL
     218             :    struct access_control_addr dst[1];
     219             : #endif /* def FEATURE_ACL */
     220             : 
     221             :    /* Don't leak memory when retrying. */
     222           0 :    freez(csp->error_message);
     223           0 :    freez(csp->http->host_ip_addr_str);
     224             : 
     225           0 :    retval = snprintf(service, sizeof(service), "%d", portnum);
     226           0 :    if ((-1 == retval) || (sizeof(service) <= retval))
     227             :    {
     228           0 :       log_error(LOG_LEVEL_ERROR,
     229             :          "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",
     230             :          portnum);
     231           0 :       csp->error_message = strdup("Invalid port number");
     232           0 :       csp->http->host_ip_addr_str = strdup("unknown");
     233           0 :       return(JB_INVALID_SOCKET);
     234             :    }
     235             : 
     236           0 :    memset((char *)&hints, 0, sizeof(hints));
     237           0 :    hints.ai_family = AF_UNSPEC;
     238           0 :    hints.ai_socktype = SOCK_STREAM;
     239           0 :    hints.ai_flags = AI_NUMERICSERV; /* avoid service look-up */
     240             : #ifdef AI_ADDRCONFIG
     241           0 :    hints.ai_flags |= AI_ADDRCONFIG;
     242             : #endif
     243           0 :    if ((retval = getaddrinfo(host, service, &hints, &result)))
     244             :    {
     245           0 :       log_error(LOG_LEVEL_INFO,
     246             :          "Can not resolve %s: %s", host, gai_strerror(retval));
     247           0 :       csp->error_message = strdup(gai_strerror(retval));
     248           0 :       csp->http->host_ip_addr_str = strdup("unknown");
     249             :       /* XXX: Should find a better way to propagate this error. */
     250           0 :       errno = EINVAL;
     251           0 :       return(JB_INVALID_SOCKET);
     252             :    }
     253             : 
     254           0 :    csp->http->host_ip_addr_str = malloc_or_die(NI_MAXHOST);
     255             : 
     256           0 :    for (rp = result; rp != NULL; rp = rp->ai_next)
     257             :    {
     258             : 
     259             : #ifdef FEATURE_ACL
     260           0 :       memcpy(&dst->addr, rp->ai_addr, rp->ai_addrlen);
     261             : 
     262           0 :       if (block_acl(dst, csp))
     263             :       {
     264           0 :          socket_error = errno = EPERM;
     265           0 :          continue;
     266             :       }
     267             : #endif /* def FEATURE_ACL */
     268             : 
     269           0 :       retval = getnameinfo(rp->ai_addr, rp->ai_addrlen,
     270             :          csp->http->host_ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
     271           0 :       if (retval)
     272             :       {
     273           0 :          log_error(LOG_LEVEL_ERROR,
     274             :             "Failed to get the host name from the socket structure: %s",
     275             :             gai_strerror(retval));
     276           0 :          continue;
     277             :       }
     278             : 
     279           0 :       fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
     280             : #ifdef _WIN32
     281             :       if (fd == JB_INVALID_SOCKET)
     282             : #else
     283           0 :       if (fd < 0)
     284             : #endif
     285             :       {
     286           0 :          continue;
     287             :       }
     288             : 
     289             : #ifndef HAVE_POLL
     290             : #ifndef _WIN32
     291             :       if (fd >= FD_SETSIZE)
     292             :       {
     293             :          log_error(LOG_LEVEL_ERROR,
     294             :             "Server socket number too high to use select(): %d >= %d",
     295             :             fd, FD_SETSIZE);
     296             :          close_socket(fd);
     297             :          freeaddrinfo(result);
     298             :          return JB_INVALID_SOCKET;
     299             :       }
     300             : #endif
     301             : #endif
     302             : 
     303             : #ifdef FEATURE_EXTERNAL_FILTERS
     304           0 :       mark_socket_for_close_on_execute(fd);
     305             : #endif
     306             : 
     307           0 :       set_no_delay_flag(fd);
     308             : 
     309             : #if !defined(_WIN32) && !defined(__BEOS__)
     310           0 :       if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
     311             :       {
     312           0 :          flags |= O_NDELAY;
     313           0 :          fcntl(fd, F_SETFL, flags);
     314             :       }
     315             : #endif /* !defined(_WIN32) && !defined(__BEOS__) */
     316             : 
     317           0 :       connect_failed = 0;
     318           0 :       while (connect(fd, rp->ai_addr, rp->ai_addrlen) == JB_INVALID_SOCKET)
     319             :       {
     320             : #ifdef _WIN32
     321             :          if (errno == WSAEINPROGRESS)
     322             : #else /* ifndef _WIN32 */
     323           0 :          if (errno == EINPROGRESS)
     324             : #endif /* ndef _WIN32 */
     325             :          {
     326           0 :             break;
     327             :          }
     328             : 
     329           0 :          if (errno != EINTR)
     330             :          {
     331           0 :             socket_error = errno;
     332           0 :             close_socket(fd);
     333           0 :             connect_failed = 1;
     334           0 :             break;
     335             :          }
     336             :       }
     337           0 :       if (connect_failed)
     338             :       {
     339           0 :          continue;
     340             :       }
     341             : 
     342             : #if !defined(_WIN32) && !defined(__BEOS__)
     343           0 :       if (flags != -1)
     344             :       {
     345           0 :          flags &= ~O_NDELAY;
     346           0 :          fcntl(fd, F_SETFL, flags);
     347             :       }
     348             : #endif /* !defined(_WIN32) && !defined(__BEOS__) */
     349             : 
     350             : #ifdef HAVE_POLL
     351           0 :       poll_fd[0].fd = fd;
     352           0 :       poll_fd[0].events = POLLOUT;
     353             : 
     354           0 :       retval = poll(poll_fd, 1, 30000);
     355           0 :       if (retval == 0)
     356             :       {
     357           0 :          if (rp->ai_next != NULL)
     358             :          {
     359             :             /* Log this now as we'll try another address next */
     360           0 :             log_error(LOG_LEVEL_CONNECT,
     361             :                "Could not connect to [%s]:%s: Operation timed out.",
     362             :                csp->http->host_ip_addr_str, service);
     363             :          }
     364             :          else
     365             :          {
     366             :             /*
     367             :              * This is the last address, don't log this now
     368             :              * as it would result in a duplicated log message.
     369             :              */
     370           0 :             socket_error = ETIMEDOUT;
     371             :          }
     372             :       }
     373           0 :       else if (retval > 0)
     374             : #else
     375             :       /* wait for connection to complete */
     376             :       FD_ZERO(&wfds);
     377             :       FD_SET(fd, &wfds);
     378             : 
     379             :       memset(&timeout, 0, sizeof(timeout));
     380             :       timeout.tv_sec  = 30;
     381             : 
     382             :       /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Weird! */
     383             :       if ((select((int)fd + 1, NULL, &wfds, NULL, &timeout) > 0)
     384             :          && FD_ISSET(fd, &wfds))
     385             : #endif
     386             :       {
     387           0 :          socklen_t optlen = sizeof(socket_error);
     388           0 :          if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, &socket_error, &optlen))
     389             :          {
     390           0 :             if (!socket_error)
     391             :             {
     392             :                /* Connection established, no need to try other addresses. */
     393           0 :                break;
     394             :             }
     395           0 :             if (rp->ai_next != NULL)
     396             :             {
     397             :                /*
     398             :                 * There's another address we can try, so log that this
     399             :                 * one didn't work out. If the last one fails, too,
     400             :                 * it will get logged outside the loop body so we don't
     401             :                 * have to mention it here.
     402             :                 */
     403           0 :                log_error(LOG_LEVEL_CONNECT, "Could not connect to [%s]:%s: %s.",
     404             :                   csp->http->host_ip_addr_str, service, strerror(socket_error));
     405             :             }
     406             :          }
     407             :          else
     408             :          {
     409           0 :             socket_error = errno;
     410           0 :             log_error(LOG_LEVEL_ERROR, "Could not get the state of "
     411             :                "the connection to [%s]:%s: %s; dropping connection.",
     412           0 :                csp->http->host_ip_addr_str, service, strerror(errno));
     413             :          }
     414             :       }
     415             : 
     416             :       /* Connection failed, try next address */
     417           0 :       close_socket(fd);
     418             :    }
     419             : 
     420           0 :    freeaddrinfo(result);
     421           0 :    if (!rp)
     422             :    {
     423           0 :       log_error(LOG_LEVEL_CONNECT, "Could not connect to [%s]:%s: %s.",
     424             :          host, service, strerror(socket_error));
     425           0 :       csp->error_message = strdup(strerror(socket_error));
     426           0 :       return(JB_INVALID_SOCKET);
     427             :    }
     428           0 :    log_error(LOG_LEVEL_CONNECT, "Connected to %s[%s]:%s.",
     429             :       host, csp->http->host_ip_addr_str, service);
     430             : 
     431           0 :    return(fd);
     432             : 
     433             : }
     434             : 
     435             : #else /* ndef HAVE_RFC2553 */
     436             : /* Pre-getaddrinfo implementation */
     437             : 
     438             : static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct client_state *csp)
     439             : {
     440             :    struct sockaddr_in inaddr;
     441             :    jb_socket fd;
     442             :    unsigned int addr;
     443             : #ifdef HAVE_POLL
     444             :    struct pollfd poll_fd[1];
     445             : #else
     446             :    fd_set wfds;
     447             :    struct timeval tv[1];
     448             : #endif
     449             : #if !defined(_WIN32) && !defined(__BEOS__)
     450             :    int   flags;
     451             : #endif
     452             : 
     453             : #ifdef FEATURE_ACL
     454             :    struct access_control_addr dst[1];
     455             : #endif /* def FEATURE_ACL */
     456             : 
     457             :    /* Don't leak memory when retrying. */
     458             :    freez(csp->http->host_ip_addr_str);
     459             : 
     460             :    memset((char *)&inaddr, 0, sizeof inaddr);
     461             : 
     462             :    if ((addr = resolve_hostname_to_ip(host)) == INADDR_NONE)
     463             :    {
     464             :       csp->http->host_ip_addr_str = strdup("unknown");
     465             :       return(JB_INVALID_SOCKET);
     466             :    }
     467             : 
     468             : #ifdef FEATURE_ACL
     469             :    dst->addr = ntohl(addr);
     470             :    dst->port = portnum;
     471             : 
     472             :    if (block_acl(dst, csp))
     473             :    {
     474             :       errno = EPERM;
     475             :       return(JB_INVALID_SOCKET);
     476             :    }
     477             : #endif /* def FEATURE_ACL */
     478             : 
     479             :    inaddr.sin_addr.s_addr = addr;
     480             :    inaddr.sin_family      = AF_INET;
     481             :    csp->http->host_ip_addr_str = strdup(inet_ntoa(inaddr.sin_addr));
     482             : 
     483             : #ifndef _WIN32
     484             :    if (sizeof(inaddr.sin_port) == sizeof(short))
     485             : #endif /* ndef _WIN32 */
     486             :    {
     487             :       inaddr.sin_port = htons((unsigned short) portnum);
     488             :    }
     489             : #ifndef _WIN32
     490             :    else
     491             :    {
     492             :       inaddr.sin_port = htonl((unsigned long)portnum);
     493             :    }
     494             : #endif /* ndef _WIN32 */
     495             : 
     496             :    fd = socket(inaddr.sin_family, SOCK_STREAM, 0);
     497             : #ifdef _WIN32
     498             :    if (fd == JB_INVALID_SOCKET)
     499             : #else
     500             :    if (fd < 0)
     501             : #endif
     502             :    {
     503             :       return(JB_INVALID_SOCKET);
     504             :    }
     505             : 
     506             : #ifndef HAVE_POLL
     507             : #ifndef _WIN32
     508             :    if (fd >= FD_SETSIZE)
     509             :    {
     510             :       log_error(LOG_LEVEL_ERROR,
     511             :          "Server socket number too high to use select(): %d >= %d",
     512             :          fd, FD_SETSIZE);
     513             :       close_socket(fd);
     514             :       return JB_INVALID_SOCKET;
     515             :    }
     516             : #endif
     517             : #endif
     518             : 
     519             :    set_no_delay_flag(fd);
     520             : 
     521             : #if !defined(_WIN32) && !defined(__BEOS__)
     522             :    if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
     523             :    {
     524             :       flags |= O_NDELAY;
     525             :       fcntl(fd, F_SETFL, flags);
     526             : #ifdef FEATURE_EXTERNAL_FILTERS
     527             :       mark_socket_for_close_on_execute(fd);
     528             : #endif
     529             :    }
     530             : #endif /* !defined(_WIN32) && !defined(__BEOS__) */
     531             : 
     532             :    while (connect(fd, (struct sockaddr *) & inaddr, sizeof inaddr) == JB_INVALID_SOCKET)
     533             :    {
     534             : #ifdef _WIN32
     535             :       if (errno == WSAEINPROGRESS)
     536             : #else /* ifndef _WIN32 */
     537             :       if (errno == EINPROGRESS)
     538             : #endif /* ndef _WIN32 */
     539             :       {
     540             :          break;
     541             :       }
     542             : 
     543             :       if (errno != EINTR)
     544             :       {
     545             :          close_socket(fd);
     546             :          return(JB_INVALID_SOCKET);
     547             :       }
     548             :    }
     549             : 
     550             : #if !defined(_WIN32) && !defined(__BEOS__)
     551             :    if (flags != -1)
     552             :    {
     553             :       flags &= ~O_NDELAY;
     554             :       fcntl(fd, F_SETFL, flags);
     555             :    }
     556             : #endif /* !defined(_WIN32) && !defined(__BEOS__) */
     557             : 
     558             : #ifdef HAVE_POLL
     559             :    poll_fd[0].fd = fd;
     560             :    poll_fd[0].events = POLLOUT;
     561             : 
     562             :    if (poll(poll_fd, 1, 30000) <= 0)
     563             : #else
     564             :    /* wait for connection to complete */
     565             :    FD_ZERO(&wfds);
     566             :    FD_SET(fd, &wfds);
     567             : 
     568             :    tv->tv_sec  = 30;
     569             :    tv->tv_usec = 0;
     570             : 
     571             :    /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Weird! */
     572             :    if (select((int)fd + 1, NULL, &wfds, NULL, tv) <= 0)
     573             : #endif
     574             :    {
     575             :       close_socket(fd);
     576             :       return(JB_INVALID_SOCKET);
     577             :    }
     578             :    return(fd);
     579             : 
     580             : }
     581             : #endif /* ndef HAVE_RFC2553 */
     582             : 
     583             : 
     584             : /*********************************************************************
     585             :  *
     586             :  * Function    :  write_socket
     587             :  *
     588             :  * Description :  Write the contents of buf (for n bytes) to socket fd.
     589             :  *
     590             :  * Parameters  :
     591             :  *          1  :  fd = file descriptor (aka. handle) of socket to write to.
     592             :  *          2  :  buf = pointer to data to be written.
     593             :  *          3  :  len = length of data to be written to the socket "fd".
     594             :  *
     595             :  * Returns     :  0 on success (entire buffer sent).
     596             :  *                nonzero on error.
     597             :  *
     598             :  *********************************************************************/
     599       70270 : int write_socket(jb_socket fd, const char *buf, size_t len)
     600             : {
     601       70270 :    if (len == 0)
     602             :    {
     603        6594 :       return 0;
     604             :    }
     605             : 
     606             : #ifdef FUZZ
     607       63676 :    if (!daemon_mode && fd <= 3)
     608             :    {
     609       63676 :       log_error(LOG_LEVEL_WRITING, "Pretending to write to socket %d: %N", fd, len, buf);
     610       63676 :       return 0;
     611             :    }
     612             : #endif
     613             : 
     614           0 :    log_error(LOG_LEVEL_WRITING, "to socket %d: %N", fd, len, buf);
     615             : 
     616             : #if defined(_WIN32)
     617             :    return (send(fd, buf, (int)len, 0) != (int)len);
     618             : #elif defined(__BEOS__)
     619             :    return (send(fd, buf, len, 0) != len);
     620             : #else
     621           0 :    return (write(fd, buf, len) != len);
     622             : #endif
     623             : 
     624             : }
     625             : 
     626             : 
     627             : /*********************************************************************
     628             :  *
     629             :  * Function    :  write_socket_delayed
     630             :  *
     631             :  * Description :  Write the contents of buf (for n bytes) to
     632             :  *                socket fd, optionally delaying the operation.
     633             :  *
     634             :  * Parameters  :
     635             :  *          1  :  fd = File descriptor (aka. handle) of socket to write to.
     636             :  *          2  :  buf = Pointer to data to be written.
     637             :  *          3  :  len = Length of data to be written to the socket "fd".
     638             :  *          4  :  delay = Delay in milliseconds.
     639             :  *
     640             :  * Returns     :  0 on success (entire buffer sent).
     641             :  *                nonzero on error.
     642             :  *
     643             :  *********************************************************************/
     644       63046 : int write_socket_delayed(jb_socket fd, const char *buf, size_t len, unsigned int delay)
     645             : {
     646       63046 :    size_t i = 0;
     647             : 
     648       63046 :    if (delay == 0)
     649             :    {
     650       63046 :       return write_socket(fd, buf, len);
     651             :    }
     652             : 
     653           0 :    while (i < len)
     654             :    {
     655             :       size_t write_length;
     656             :       enum {MAX_WRITE_LENGTH = 10};
     657             : 
     658           0 :       if ((i + MAX_WRITE_LENGTH) > len)
     659             :       {
     660           0 :          write_length = len - i;
     661             :       }
     662             :       else
     663             :       {
     664           0 :          write_length = MAX_WRITE_LENGTH;
     665             :       }
     666             : 
     667           0 :       privoxy_millisleep(delay);
     668             : 
     669           0 :       if (write_socket(fd, buf + i, write_length) != 0)
     670             :       {
     671           0 :          return 1;
     672             :       }
     673           0 :       i += write_length;
     674             :    }
     675             : 
     676           0 :    return 0;
     677             : 
     678             : }
     679             : 
     680             : 
     681             : /*********************************************************************
     682             :  *
     683             :  * Function    :  read_socket
     684             :  *
     685             :  * Description :  Read from a TCP/IP socket in a platform independent way.
     686             :  *
     687             :  * Parameters  :
     688             :  *          1  :  fd = file descriptor of the socket to read
     689             :  *          2  :  buf = pointer to buffer where data will be written
     690             :  *                Must be >= len bytes long.
     691             :  *          3  :  len = maximum number of bytes to read
     692             :  *
     693             :  * Returns     :  On success, the number of bytes read is returned (zero
     694             :  *                indicates end of file), and the file position is advanced
     695             :  *                by this number.  It is not an error if this number is
     696             :  *                smaller than the number of bytes requested; this may hap-
     697             :  *                pen for example because fewer bytes are actually available
     698             :  *                right now (maybe because we were close to end-of-file, or
     699             :  *                because we are reading from a pipe, or from a terminal,
     700             :  *                or because read() was interrupted by a signal).  On error,
     701             :  *                -1 is returned, and errno is set appropriately.  In this
     702             :  *                case it is left unspecified whether the file position (if
     703             :  *                any) changes.
     704             :  *
     705             :  *********************************************************************/
     706       54272 : int read_socket(jb_socket fd, char *buf, int len)
     707             : {
     708       54272 :    int ret = 0;
     709       54272 :    int i = 0;
     710       54272 :         int c = 0;
     711       54272 :    if (len <= 0)
     712             :    {
     713           0 :       return(0);
     714             :    }
     715             : 
     716             : #if defined(_WIN32)
     717             :    ret = recv(fd, buf, len, 0);
     718             : #elif defined(__BEOS__)
     719             :    ret = recv(fd, buf, (size_t)len, 0);
     720             : #else
     721    30038243 :    while(i < len && (c = getchar_unlocked()) != EOF && c != 248 /*\xF8 */) buf[i++] = (unsigned char)c;
     722       54272 :    ret = i;
     723             : #endif
     724       54272 :    if (ret > 0)
     725             :    {
     726       53457 :       log_error(LOG_LEVEL_RECEIVED, "from socket %d: %N", fd, ret, buf);
     727             :    }
     728             : 
     729       54272 :    return ret;
     730             : }
     731             : 
     732             : 
     733             : /*********************************************************************
     734             :  *
     735             :  * Function    :  data_is_available
     736             :  *
     737             :  * Description :  Waits for data to arrive on a socket.
     738             :  *
     739             :  * Parameters  :
     740             :  *          1  :  fd = file descriptor of the socket to read
     741             :  *          2  :  seconds_to_wait = number of seconds after which we give up.
     742             :  *
     743             :  * Returns     :  TRUE if data arrived in time,
     744             :  *                FALSE otherwise.
     745             :  *
     746             :  *********************************************************************/
     747       60585 : int data_is_available(jb_socket fd, int seconds_to_wait)
     748             : {
     749             :    int n;
     750             :    char buf[10];
     751             : #ifdef HAVE_POLL
     752             :    struct pollfd poll_fd[1];
     753             : 
     754       60585 :    poll_fd[0].fd = fd;
     755       60585 :    poll_fd[0].events = POLLIN;
     756             : 
     757       60585 :    n = poll(poll_fd, 1, seconds_to_wait * 1000);
     758             : #else
     759             :    fd_set rfds;
     760             :    struct timeval timeout;
     761             : 
     762             :    memset(&timeout, 0, sizeof(timeout));
     763             :    timeout.tv_sec = seconds_to_wait;
     764             : 
     765             :    FD_ZERO(&rfds);
     766             :    FD_SET(fd, &rfds);
     767             : 
     768             :    n = select(fd+1, &rfds, NULL, NULL, &timeout);
     769             : #endif
     770             : 
     771             :    /*
     772             :     * XXX: Do we care about the different error conditions?
     773             :     */
     774       60585 :    return ((n == 1) && !feof_unlocked(stdin));
     775             : }
     776             : 
     777             : 
     778             : /*********************************************************************
     779             :  *
     780             :  * Function    :  close_socket
     781             :  *
     782             :  * Description :  Closes a TCP/IP socket
     783             :  *
     784             :  * Parameters  :
     785             :  *          1  :  fd = file descriptor of socket to be closed
     786             :  *
     787             :  * Returns     :  void
     788             :  *
     789             :  *********************************************************************/
     790        6474 : void close_socket(jb_socket fd)
     791             : {
     792        6474 : return;
     793             : #if defined(_WIN32) || defined(__BEOS__)
     794             :    closesocket(fd);
     795             : #else
     796             :    close(fd);
     797             : #endif
     798             : }
     799             : 
     800             : 
     801             : /*********************************************************************
     802             :  *
     803             :  * Function    :  drain_and_close_socket
     804             :  *
     805             :  * Description :  Closes a TCP/IP socket after draining unread data
     806             :  *
     807             :  * Parameters  :
     808             :  *          1  :  fd = file descriptor of the socket to be closed
     809             :  *
     810             :  * Returns     :  void
     811             :  *
     812             :  *********************************************************************/
     813        3098 : void drain_and_close_socket(jb_socket fd)
     814             : {
     815        3098 : return;
     816             : #ifdef FEATURE_CONNECTION_KEEP_ALIVE
     817             :    if (socket_is_still_alive(fd))
     818             : #endif
     819             :    {
     820             :       int bytes_drained_total = 0;
     821             :       int bytes_drained;
     822             : 
     823             : #ifdef HAVE_SHUTDOWN
     824             : /* Apparently Windows has shutdown() but not SHUT_WR. */
     825             : #ifndef SHUT_WR
     826             : #define SHUT_WR 1
     827             : #endif
     828             :       if (0 != shutdown(fd, SHUT_WR))
     829             :       {
     830             :          log_error(LOG_LEVEL_CONNECT, "Failed to shutdown socket %d: %E", fd);
     831             :       }
     832             : #endif
     833             : #define ARBITRARY_DRAIN_LIMIT 10000
     834             :       do
     835             :       {
     836             :          char drainage[500];
     837             : 
     838             :          if (!data_is_available(fd, 0))
     839             :          {
     840             :             /*
     841             :              * If there is no data available right now, don't try
     842             :              * to drain the socket as read_socket() could block.
     843             :              */
     844             :             break;
     845             :          }
     846             : 
     847             :          bytes_drained = read_socket(fd, drainage, sizeof(drainage));
     848             :          if (bytes_drained < 0)
     849             :          {
     850             :             log_error(LOG_LEVEL_CONNECT, "Failed to drain socket %d: %E", fd);
     851             :          }
     852             :          else if (bytes_drained > 0)
     853             :          {
     854             :             bytes_drained_total += bytes_drained;
     855             :             if (bytes_drained_total > ARBITRARY_DRAIN_LIMIT)
     856             :             {
     857             :                log_error(LOG_LEVEL_CONNECT, "Giving up draining socket %d", fd);
     858             :                break;
     859             :             }
     860             :          }
     861             :       } while (bytes_drained > 0);
     862             :       if (bytes_drained_total != 0)
     863             :       {
     864             :          log_error(LOG_LEVEL_CONNECT,
     865             :             "Drained %d bytes before closing socket %d", bytes_drained_total, fd);
     866             :       }
     867             :    }
     868             : 
     869             :    close_socket(fd);
     870             : 
     871             : }
     872             : 
     873             : 
     874             : /*********************************************************************
     875             :  *
     876             :  * Function    :  bind_port
     877             :  *
     878             :  * Description :  Call socket, set socket options, and listen.
     879             :  *                Called by listen_loop to "boot up" our proxy address.
     880             :  *
     881             :  * Parameters  :
     882             :  *          1  :  hostnam = TCP/IP address to bind/listen to
     883             :  *          2  :  portnum = port to listen on
     884             :  *          3  :  backlog = Listen backlog
     885             :  *          4  :  pfd = pointer used to return file descriptor.
     886             :  *
     887             :  * Returns     :  if success, returns 0 and sets *pfd.
     888             :  *                if failure, returns -3 if address is in use,
     889             :  *                                    -2 if address unresolvable,
     890             :  *                                    -1 otherwise
     891             :  *********************************************************************/
     892           0 : int bind_port(const char *hostnam, int portnum, int backlog, jb_socket *pfd)
     893             : {
     894             : #ifdef HAVE_RFC2553
     895             :    struct addrinfo hints;
     896             :    struct addrinfo *result, *rp;
     897             :    /*
     898             :     * XXX: portnum should be a string to allow symbolic service
     899             :     * names in the configuration file and to avoid the following
     900             :     * int2string.
     901             :     */
     902             :    char servnam[6];
     903             :    int retval;
     904             : #else
     905             :    struct sockaddr_in inaddr;
     906             : #endif /* def HAVE_RFC2553 */
     907             :    jb_socket fd;
     908             : #ifndef _WIN32
     909           0 :    int one = 1;
     910             : #endif /* ndef _WIN32 */
     911             : 
     912           0 :    *pfd = JB_INVALID_SOCKET;
     913             : 
     914             : #ifdef HAVE_RFC2553
     915           0 :    retval = snprintf(servnam, sizeof(servnam), "%d", portnum);
     916           0 :    if ((-1 == retval) || (sizeof(servnam) <= retval))
     917             :    {
     918           0 :       log_error(LOG_LEVEL_ERROR,
     919             :          "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",
     920             :          portnum);
     921           0 :       return -1;
     922             :    }
     923             : 
     924           0 :    memset(&hints, 0, sizeof(struct addrinfo));
     925           0 :    if (hostnam == NULL)
     926             :    {
     927             :       /*
     928             :        * XXX: This is a hack. The right thing to do
     929             :        * would be to bind to both AF_INET and AF_INET6.
     930             :        * This will also fail if there is no AF_INET
     931             :        * version available.
     932             :        */
     933           0 :       hints.ai_family = AF_INET;
     934             :    }
     935             :    else
     936             :    {
     937           0 :       hints.ai_family = AF_UNSPEC;
     938             :    }
     939           0 :    hints.ai_socktype = SOCK_STREAM;
     940           0 :    hints.ai_flags = AI_PASSIVE;
     941           0 :    hints.ai_protocol = 0; /* Really any stream protocol or TCP only */
     942           0 :    hints.ai_canonname = NULL;
     943           0 :    hints.ai_addr = NULL;
     944           0 :    hints.ai_next = NULL;
     945             : 
     946           0 :    if ((retval = getaddrinfo(hostnam, servnam, &hints, &result)))
     947             :    {
     948           0 :       log_error(LOG_LEVEL_ERROR,
     949             :          "Can not resolve %s: %s", hostnam, gai_strerror(retval));
     950           0 :       return -2;
     951             :    }
     952             : #else
     953             :    memset((char *)&inaddr, '\0', sizeof inaddr);
     954             : 
     955             :    inaddr.sin_family      = AF_INET;
     956             :    inaddr.sin_addr.s_addr = resolve_hostname_to_ip(hostnam);
     957             : 
     958             :    if (inaddr.sin_addr.s_addr == INADDR_NONE)
     959             :    {
     960             :       return(-2);
     961             :    }
     962             : 
     963             : #ifndef _WIN32
     964             :    if (sizeof(inaddr.sin_port) == sizeof(short))
     965             : #endif /* ndef _WIN32 */
     966             :    {
     967             :       inaddr.sin_port = htons((unsigned short) portnum);
     968             :    }
     969             : #ifndef _WIN32
     970             :    else
     971             :    {
     972             :       inaddr.sin_port = htonl((unsigned long) portnum);
     973             :    }
     974             : #endif /* ndef _WIN32 */
     975             : #endif /* def HAVE_RFC2553 */
     976             : 
     977             : #ifdef HAVE_RFC2553
     978           0 :    for (rp = result; rp != NULL; rp = rp->ai_next)
     979             :    {
     980           0 :       fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
     981             : #else
     982             :    fd = socket(AF_INET, SOCK_STREAM, 0);
     983             : #endif /* def HAVE_RFC2553 */
     984             : 
     985             : #ifdef _WIN32
     986             :    if (fd == JB_INVALID_SOCKET)
     987             : #else
     988           0 :    if (fd < 0)
     989             : #endif
     990             :    {
     991             : #ifdef HAVE_RFC2553
     992           0 :       continue;
     993             : #else
     994             :       return(-1);
     995             : #endif
     996             :    }
     997             : 
     998             : #ifdef FEATURE_EXTERNAL_FILTERS
     999           0 :    mark_socket_for_close_on_execute(fd);
    1000             : #endif
    1001             : 
    1002             : #ifndef _WIN32
    1003             :    /*
    1004             :     * This is not needed for Win32 - in fact, it stops
    1005             :     * duplicate instances of Privoxy from being caught.
    1006             :     *
    1007             :     * On UNIX, we assume the user is sensible enough not
    1008             :     * to start Privoxy multiple times on the same IP.
    1009             :     * Without this, stopping and restarting Privoxy
    1010             :     * from a script fails.
    1011             :     * Note: SO_REUSEADDR is meant to only take over
    1012             :     * sockets which are *not* in listen state in Linux,
    1013             :     * e.g. sockets in TIME_WAIT. YMMV.
    1014             :     */
    1015           0 :    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
    1016             : #endif /* ndef _WIN32 */
    1017             : 
    1018             : #ifdef IP_FREEBIND
    1019           0 :    setsockopt(fd, IPPROTO_IP, IP_FREEBIND, (char *)&one, sizeof(one));
    1020             : #endif
    1021             : 
    1022             : #ifdef HAVE_RFC2553
    1023           0 :    if (bind(fd, rp->ai_addr, rp->ai_addrlen) < 0)
    1024             : #else
    1025             :    if (bind(fd, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
    1026             : #endif
    1027             :    {
    1028             : #ifdef _WIN32
    1029             :       errno = WSAGetLastError();
    1030             :       if (errno == WSAEADDRINUSE)
    1031             : #else
    1032           0 :       if (errno == EADDRINUSE)
    1033             : #endif
    1034             :       {
    1035             : #ifdef HAVE_RFC2553
    1036           0 :          freeaddrinfo(result);
    1037             : #endif
    1038           0 :          close_socket(fd);
    1039           0 :          return(-3);
    1040             :       }
    1041             :       else
    1042             :       {
    1043           0 :          close_socket(fd);
    1044             : #ifndef HAVE_RFC2553
    1045             :          return(-1);
    1046             :       }
    1047             :    }
    1048             : #else
    1049             :       }
    1050             :    }
    1051             :    else
    1052             :    {
    1053             :       /* bind() succeeded, escape from for-loop */
    1054             :       /*
    1055             :        * XXX: Support multiple listening sockets (e.g. localhost
    1056             :        * resolves to AF_INET and AF_INET6, but only the first address
    1057             :        * is used
    1058             :        */
    1059           0 :       break;
    1060             :    }
    1061             :    }
    1062             : 
    1063           0 :    freeaddrinfo(result);
    1064           0 :    if (rp == NULL)
    1065             :    {
    1066             :       /* All bind()s failed */
    1067           0 :       return(-1);
    1068             :    }
    1069             : #endif /* ndef HAVE_RFC2553 */
    1070             : 
    1071           0 :    while (listen(fd, backlog) == -1)
    1072             :    {
    1073           0 :       if (errno != EINTR)
    1074             :       {
    1075           0 :          close_socket(fd);
    1076           0 :          return(-1);
    1077             :       }
    1078             :    }
    1079             : 
    1080           0 :    *pfd = fd;
    1081           0 :    return 0;
    1082             : 
    1083             : }
    1084             : 
    1085             : 
    1086             : /*********************************************************************
    1087             :  *
    1088             :  * Function    :  get_host_information
    1089             :  *
    1090             :  * Description :  Determines the IP address the client used to
    1091             :  *                reach us and the hostname associated with it.
    1092             :  *
    1093             :  *                XXX: Most of the code has been copy and pasted
    1094             :  *                from accept_connection() and not all of the
    1095             :  *                ifdefs paths have been tested afterwards.
    1096             :  *
    1097             :  * Parameters  :
    1098             :  *          1  :  afd = File descriptor returned from accept().
    1099             :  *          2  :  ip_address = Pointer to return the pointer to
    1100             :  *                             the ip address string.
    1101             :  *          3  :  port =       Pointer to return the pointer to
    1102             :  *                             the TCP port string.
    1103             :  *          4  :  hostname =   Pointer to return the pointer to
    1104             :  *                             the hostname or NULL if the caller
    1105             :  *                             isn't interested in it.
    1106             :  *
    1107             :  * Returns     :  void.
    1108             :  *
    1109             :  *********************************************************************/
    1110       19338 : void get_host_information(jb_socket afd, char **ip_address, char **port,
    1111             :                           char **hostname)
    1112             : {
    1113             : #ifdef HAVE_RFC2553
    1114             :    struct sockaddr_storage server;
    1115             :    int retval;
    1116             : #else
    1117             :    struct sockaddr_in server;
    1118             :    struct hostent *host = NULL;
    1119             : #endif /* HAVE_RFC2553 */
    1120             : #if defined(_WIN32)
    1121             :    /* according to accept_connection() this fixes a warning. */
    1122             :    int s_length, s_length_provided;
    1123             : #else
    1124             :    socklen_t s_length, s_length_provided;
    1125             : #endif
    1126             : #ifndef HAVE_RFC2553
    1127             : #if defined(HAVE_GETHOSTBYADDR_R_8_ARGS) ||  defined(HAVE_GETHOSTBYADDR_R_7_ARGS) || defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
    1128             :    struct hostent result;
    1129             : #if defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
    1130             :    struct hostent_data hdata;
    1131             : #else
    1132             :    char hbuf[HOSTENT_BUFFER_SIZE];
    1133             :    int thd_err;
    1134             : #endif /* def HAVE_GETHOSTBYADDR_R_5_ARGS */
    1135             : #endif /* def HAVE_GETHOSTBYADDR_R_(8|7|5)_ARGS */
    1136             : #endif /* ifndef HAVE_RFC2553 */
    1137       19338 :    s_length = s_length_provided = sizeof(server);
    1138             : 
    1139       19338 :    if (NULL != hostname)
    1140             :    {
    1141       19338 :       *hostname = NULL;
    1142             :    }
    1143       19338 :    *ip_address = NULL;
    1144       19338 :    *port = NULL;
    1145             : 
    1146       19338 :    if (!getsockname(afd, (struct sockaddr *) &server, &s_length))
    1147             :    {
    1148           0 :       if (s_length > s_length_provided)
    1149             :       {
    1150           0 :          log_error(LOG_LEVEL_ERROR, "getsockname() truncated server address");
    1151           0 :          return;
    1152             :       }
    1153             : /*
    1154             :  * XXX: Workaround for missing header on Windows when
    1155             :  *      configured with --disable-ipv6-support.
    1156             :  *      The proper fix is to not use NI_MAXSERV in
    1157             :  *      that case. It works by accident on other platforms
    1158             :  *      as <netdb.h> is included unconditionally there.
    1159             :  */
    1160             : #ifndef NI_MAXSERV
    1161             : #define NI_MAXSERV 32
    1162             : #endif
    1163           0 :       *port = malloc_or_die(NI_MAXSERV);
    1164             : 
    1165             : #ifdef HAVE_RFC2553
    1166           0 :       *ip_address = malloc_or_die(NI_MAXHOST);
    1167           0 :       retval = getnameinfo((struct sockaddr *) &server, s_length,
    1168             :          *ip_address, NI_MAXHOST, *port, NI_MAXSERV,
    1169             :          NI_NUMERICHOST|NI_NUMERICSERV);
    1170           0 :       if (retval)
    1171             :       {
    1172           0 :          log_error(LOG_LEVEL_ERROR,
    1173             :             "Unable to print my own IP address: %s", gai_strerror(retval));
    1174           0 :          freez(*ip_address);
    1175           0 :          freez(*port);
    1176           0 :          return;
    1177             :       }
    1178             : #else
    1179             :       *ip_address = strdup(inet_ntoa(server.sin_addr));
    1180             :       snprintf(*port, NI_MAXSERV, "%hu", ntohs(server.sin_port));
    1181             : #endif /* HAVE_RFC2553 */
    1182           0 :       if (NULL == hostname)
    1183             :       {
    1184             :          /*
    1185             :           * We're done here, the caller isn't
    1186             :           * interested in knowing the hostname.
    1187             :           */
    1188           0 :          return;
    1189             :       }
    1190             : 
    1191             : #ifdef HAVE_RFC2553
    1192           0 :       *hostname = malloc_or_die(NI_MAXHOST);
    1193           0 :       retval = getnameinfo((struct sockaddr *) &server, s_length,
    1194             :          *hostname, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
    1195           0 :       if (retval)
    1196             :       {
    1197           0 :          log_error(LOG_LEVEL_ERROR,
    1198             :             "Unable to resolve my own IP address: %s", gai_strerror(retval));
    1199           0 :          freez(*hostname);
    1200             :       }
    1201             : #else
    1202             : #if defined(HAVE_GETHOSTBYADDR_R_8_ARGS)
    1203             :       gethostbyaddr_r((const char *)&server.sin_addr,
    1204             :                       sizeof(server.sin_addr), AF_INET,
    1205             :                       &result, hbuf, HOSTENT_BUFFER_SIZE,
    1206             :                       &host, &thd_err);
    1207             : #elif defined(HAVE_GETHOSTBYADDR_R_7_ARGS)
    1208             :       host = gethostbyaddr_r((const char *)&server.sin_addr,
    1209             :                       sizeof(server.sin_addr), AF_INET,
    1210             :                       &result, hbuf, HOSTENT_BUFFER_SIZE, &thd_err);
    1211             : #elif defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
    1212             :       if (0 == gethostbyaddr_r((const char *)&server.sin_addr,
    1213             :                                sizeof(server.sin_addr), AF_INET,
    1214             :                                &result, &hdata))
    1215             :       {
    1216             :          host = &result;
    1217             :       }
    1218             :       else
    1219             :       {
    1220             :          host = NULL;
    1221             :       }
    1222             : #elif defined(MUTEX_LOCKS_AVAILABLE)
    1223             :       privoxy_mutex_lock(&resolver_mutex);
    1224             :       host = gethostbyaddr((const char *)&server.sin_addr,
    1225             :                            sizeof(server.sin_addr), AF_INET);
    1226             :       privoxy_mutex_unlock(&resolver_mutex);
    1227             : #else
    1228             :       host = gethostbyaddr((const char *)&server.sin_addr,
    1229             :                            sizeof(server.sin_addr), AF_INET);
    1230             : #endif
    1231             :       if (host == NULL)
    1232             :       {
    1233             :          log_error(LOG_LEVEL_ERROR, "Unable to get my own hostname: %E\n");
    1234             :       }
    1235             :       else
    1236             :       {
    1237             :          *hostname = strdup(host->h_name);
    1238             :       }
    1239             : #endif /* else def HAVE_RFC2553 */
    1240             :    }
    1241             : 
    1242       19338 :    return;
    1243             : }
    1244             : 
    1245             : 
    1246             : /*********************************************************************
    1247             :  *
    1248             :  * Function    :  accept_connection
    1249             :  *
    1250             :  * Description :  Accepts a connection on one of possibly multiple
    1251             :  *                sockets. The socket(s) to check must have been
    1252             :  *                created using bind_port().
    1253             :  *
    1254             :  * Parameters  :
    1255             :  *          1  :  csp = Client state, cfd, ip_addr_str, and
    1256             :  *                      ip_addr_long will be set by this routine.
    1257             :  *          2  :  fds = File descriptors returned from bind_port
    1258             :  *
    1259             :  * Returns     :  when a connection is accepted, it returns 1 (TRUE).
    1260             :  *                On an error it returns 0 (FALSE).
    1261             :  *
    1262             :  *********************************************************************/
    1263           0 : int accept_connection(struct client_state * csp, jb_socket fds[])
    1264             : {
    1265             : #ifdef HAVE_RFC2553
    1266             :    /* XXX: client is stored directly into csp->tcp_addr */
    1267             : #define client (csp->tcp_addr)
    1268             : #else
    1269             :    struct sockaddr_in client;
    1270             : #endif
    1271             :    jb_socket afd;
    1272             : #if defined(_WIN32)
    1273             :    /* Weirdness - fix a warning. */
    1274             :    int c_length;
    1275             : #else
    1276             :    socklen_t c_length;
    1277             : #endif
    1278             :    int retval;
    1279             :    int i;
    1280             :    int max_selected_socket;
    1281             : #ifdef HAVE_POLL
    1282             :    struct pollfd poll_fds[MAX_LISTENING_SOCKETS];
    1283             :    nfds_t polled_sockets;
    1284             : #else
    1285             :    fd_set selected_fds;
    1286             : #endif
    1287             :    jb_socket fd;
    1288             :    const char *host_addr;
    1289             :    size_t listen_addr_size;
    1290             : 
    1291           0 :    c_length = sizeof(client);
    1292             : 
    1293             : #ifdef HAVE_POLL
    1294           0 :    memset(poll_fds, 0, sizeof(poll_fds));
    1295           0 :    polled_sockets = 0;
    1296             : #else
    1297             :    /*
    1298             :     * Wait for a connection on any socket.
    1299             :     * Return immediately if no socket is listening.
    1300             :     * XXX: Why not treat this as fatal error?
    1301             :     */
    1302             :    FD_ZERO(&selected_fds);
    1303             : #endif
    1304           0 :    max_selected_socket = 0;
    1305           0 :    for (i = 0; i < MAX_LISTENING_SOCKETS; i++)
    1306             :    {
    1307           0 :       if (JB_INVALID_SOCKET != fds[i])
    1308             :       {
    1309             : #ifdef HAVE_POLL
    1310           0 :          poll_fds[i].fd = fds[i];
    1311           0 :          poll_fds[i].events = POLLIN;
    1312           0 :          polled_sockets++;
    1313             : #else
    1314             :          FD_SET(fds[i], &selected_fds);
    1315             : #endif
    1316           0 :          if (max_selected_socket < fds[i] + 1)
    1317             :          {
    1318           0 :             max_selected_socket = fds[i] + 1;
    1319             :          }
    1320             :       }
    1321             :    }
    1322           0 :    if (0 == max_selected_socket)
    1323             :    {
    1324           0 :       return 0;
    1325             :    }
    1326             :    do
    1327             :    {
    1328             : #ifdef HAVE_POLL
    1329           0 :       retval = poll(poll_fds, polled_sockets, -1);
    1330             : #else
    1331             :       retval = select(max_selected_socket, &selected_fds, NULL, NULL, NULL);
    1332             : #endif
    1333           0 :    } while (retval < 0 && errno == EINTR);
    1334           0 :    if (retval <= 0)
    1335             :    {
    1336           0 :       if (0 == retval)
    1337             :       {
    1338           0 :          log_error(LOG_LEVEL_ERROR,
    1339             :             "Waiting on new client failed because select(2) returned 0."
    1340             :             " This should not happen.");
    1341             :       }
    1342             :       else
    1343             :       {
    1344           0 :          log_error(LOG_LEVEL_ERROR,
    1345             :             "Waiting on new client failed because of problems in select(2): "
    1346           0 :             "%s.", strerror(errno));
    1347             :       }
    1348           0 :       return 0;
    1349             :    }
    1350             : #ifdef HAVE_POLL
    1351           0 :    for (i = 0; i < MAX_LISTENING_SOCKETS && (poll_fds[i].revents == 0); i++);
    1352             : #else
    1353             :    for (i = 0; i < MAX_LISTENING_SOCKETS && !FD_ISSET(fds[i], &selected_fds);
    1354             :          i++);
    1355             : #endif
    1356           0 :    if (i >= MAX_LISTENING_SOCKETS)
    1357             :    {
    1358           0 :       log_error(LOG_LEVEL_ERROR,
    1359             :          "select(2) reported connected clients (number = %u, "
    1360             :          "descriptor boundary = %u), but none found.",
    1361             :          retval, max_selected_socket);
    1362           0 :       return 0;
    1363             :    }
    1364           0 :    fd = fds[i];
    1365             : 
    1366             :    /* Accept selected connection */
    1367             : #ifdef _WIN32
    1368             :    afd = accept (fd, (struct sockaddr *) &client, &c_length);
    1369             :    if (afd == JB_INVALID_SOCKET)
    1370             :    {
    1371             :       return 0;
    1372             :    }
    1373             : #else
    1374             :    do
    1375             :    {
    1376           0 :       afd = accept (fd, (struct sockaddr *) &client, &c_length);
    1377           0 :    } while (afd < 0 && errno == EINTR);
    1378           0 :    if (afd < 0)
    1379             :    {
    1380           0 :       return 0;
    1381             :    }
    1382             : #endif
    1383             : 
    1384             : #ifdef SO_LINGER
    1385             :    {
    1386             :       struct linger linger_options;
    1387           0 :       linger_options.l_onoff  = 1;
    1388           0 :       linger_options.l_linger = 5;
    1389           0 :       if (0 != setsockopt(afd, SOL_SOCKET, SO_LINGER, &linger_options, sizeof(linger_options)))
    1390             :       {
    1391           0 :          log_error(LOG_LEVEL_ERROR, "Setting SO_LINGER on socket %d failed.", afd);
    1392             :       }
    1393             :    }
    1394             : #endif
    1395             : 
    1396             : #ifndef HAVE_POLL
    1397             : #ifndef _WIN32
    1398             :    if (afd >= FD_SETSIZE)
    1399             :    {
    1400             :       log_error(LOG_LEVEL_ERROR,
    1401             :          "Client socket number too high to use select(): %d >= %d",
    1402             :          afd, FD_SETSIZE);
    1403             :       close_socket(afd);
    1404             :       return 0;
    1405             :    }
    1406             : #endif
    1407             : #endif
    1408             : 
    1409             : #ifdef FEATURE_EXTERNAL_FILTERS
    1410           0 :    mark_socket_for_close_on_execute(afd);
    1411             : #endif
    1412             : 
    1413           0 :    set_no_delay_flag(afd);
    1414             : 
    1415           0 :    csp->cfd = afd;
    1416             : #ifdef HAVE_RFC2553
    1417           0 :    csp->ip_addr_str = malloc_or_die(NI_MAXHOST);
    1418           0 :    retval = getnameinfo((struct sockaddr *) &client, c_length,
    1419             :          csp->ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
    1420           0 :    if (!csp->ip_addr_str || retval)
    1421             :    {
    1422           0 :       log_error(LOG_LEVEL_ERROR, "Can not save csp->ip_addr_str: %s",
    1423           0 :          (csp->ip_addr_str) ? gai_strerror(retval) : "Insuffcient memory");
    1424           0 :       freez(csp->ip_addr_str);
    1425             :    }
    1426             : #undef client
    1427             : #else
    1428             :    csp->ip_addr_str  = strdup(inet_ntoa(client.sin_addr));
    1429             :    csp->ip_addr_long = ntohl(client.sin_addr.s_addr);
    1430             : #endif /* def HAVE_RFC2553 */
    1431             : 
    1432             :    /*
    1433             :     * Save the name and port of the accepting socket for later lookup.
    1434             :     *
    1435             :     * The string needs space for strlen(...) + 7 characters:
    1436             :     * strlen(haddr[i]) + 1 (':') + 5 (port digits) + 1 ('\0')
    1437             :     */
    1438           0 :    host_addr = (csp->config->haddr[i] != NULL) ? csp->config->haddr[i] : "";
    1439           0 :    listen_addr_size = strlen(host_addr) + 7;
    1440           0 :    csp->listen_addr_str = malloc_or_die(listen_addr_size);
    1441           0 :    retval = snprintf(csp->listen_addr_str, listen_addr_size,
    1442           0 :       "%s:%d", host_addr, csp->config->hport[i]);
    1443           0 :    if ((-1 == retval) || listen_addr_size <= retval)
    1444             :    {
    1445           0 :       log_error(LOG_LEVEL_ERROR,
    1446             :          "Server name (%s) and port number (%d) ASCII decimal representation"
    1447             :          "don't fit into %lu bytes",
    1448           0 :          host_addr, csp->config->hport[i], listen_addr_size);
    1449           0 :       return 0;
    1450             :    }
    1451             : 
    1452           0 :    return 1;
    1453             : 
    1454             : }
    1455             : 
    1456             : 
    1457             : /*********************************************************************
    1458             :  *
    1459             :  * Function    :  resolve_hostname_to_ip
    1460             :  *
    1461             :  * Description :  Resolve a hostname to an internet tcp/ip address.
    1462             :  *                NULL or an empty string resolve to INADDR_ANY.
    1463             :  *
    1464             :  * Parameters  :
    1465             :  *          1  :  host = hostname to resolve
    1466             :  *
    1467             :  * Returns     :  INADDR_NONE => failure, INADDR_ANY or tcp/ip address if successful.
    1468             :  *
    1469             :  *********************************************************************/
    1470           0 : unsigned long resolve_hostname_to_ip(const char *host)
    1471             : {
    1472             :    struct sockaddr_in inaddr;
    1473             :    struct hostent *hostp;
    1474             : #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS) || defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
    1475             :    struct hostent result;
    1476             : #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
    1477             :    char hbuf[HOSTENT_BUFFER_SIZE];
    1478             :    int thd_err;
    1479             : #else /* defined(HAVE_GETHOSTBYNAME_R_3_ARGS) */
    1480             :    struct hostent_data hdata;
    1481             : #endif /* def HAVE_GETHOSTBYNAME_R_(6|5)_ARGS */
    1482             : #endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
    1483             : 
    1484           0 :    if ((host == NULL) || (*host == '\0'))
    1485             :    {
    1486           0 :       return(INADDR_ANY);
    1487             :    }
    1488             : 
    1489           0 :    memset((char *) &inaddr, 0, sizeof inaddr);
    1490             : 
    1491           0 :    if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1)
    1492             :    {
    1493           0 :       unsigned int dns_retries = 0;
    1494             : #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS)
    1495           0 :       while (gethostbyname_r(host, &result, hbuf,
    1496             :                 HOSTENT_BUFFER_SIZE, &hostp, &thd_err)
    1497           0 :              && (thd_err == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
    1498             :       {
    1499           0 :          log_error(LOG_LEVEL_ERROR,
    1500             :             "Timeout #%u while trying to resolve %s. Trying again.",
    1501             :             dns_retries, host);
    1502             :       }
    1503             : #elif defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
    1504             :       while (NULL == (hostp = gethostbyname_r(host, &result,
    1505             :                                  hbuf, HOSTENT_BUFFER_SIZE, &thd_err))
    1506             :              && (thd_err == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
    1507             :       {
    1508             :          log_error(LOG_LEVEL_ERROR,
    1509             :             "Timeout #%u while trying to resolve %s. Trying again.",
    1510             :             dns_retries, host);
    1511             :       }
    1512             : #elif defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
    1513             :       /*
    1514             :        * XXX: Doesn't retry in case of soft errors.
    1515             :        * Does this gethostbyname_r version set h_errno?
    1516             :        */
    1517             :       if (0 == gethostbyname_r(host, &result, &hdata))
    1518             :       {
    1519             :          hostp = &result;
    1520             :       }
    1521             :       else
    1522             :       {
    1523             :          hostp = NULL;
    1524             :       }
    1525             : #elif defined(MUTEX_LOCKS_AVAILABLE)
    1526             :       privoxy_mutex_lock(&resolver_mutex);
    1527             :       while (NULL == (hostp = gethostbyname(host))
    1528             :              && (h_errno == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
    1529             :       {
    1530             :          log_error(LOG_LEVEL_ERROR,
    1531             :             "Timeout #%u while trying to resolve %s. Trying again.",
    1532             :             dns_retries, host);
    1533             :       }
    1534             :       privoxy_mutex_unlock(&resolver_mutex);
    1535             : #else
    1536             :       while (NULL == (hostp = gethostbyname(host))
    1537             :              && (h_errno == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
    1538             :       {
    1539             :          log_error(LOG_LEVEL_ERROR,
    1540             :             "Timeout #%u while trying to resolve %s. Trying again.",
    1541             :             dns_retries, host);
    1542             :       }
    1543             : #endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
    1544             :       /*
    1545             :        * On Mac OSX, if a domain exists but doesn't have a type A
    1546             :        * record associated with it, the h_addr member of the struct
    1547             :        * hostent returned by gethostbyname is NULL, even if h_length
    1548             :        * is 4. Therefore the second test below.
    1549             :        */
    1550           0 :       if (hostp == NULL || hostp->h_addr == NULL)
    1551             :       {
    1552           0 :          errno = EINVAL;
    1553           0 :          log_error(LOG_LEVEL_ERROR, "could not resolve hostname %s", host);
    1554           0 :          return(INADDR_NONE);
    1555             :       }
    1556           0 :       if (hostp->h_addrtype != AF_INET)
    1557             :       {
    1558             : #ifdef _WIN32
    1559             :          errno = WSAEPROTOTYPE;
    1560             : #else
    1561           0 :          errno = EPROTOTYPE;
    1562             : #endif
    1563           0 :          log_error(LOG_LEVEL_ERROR, "hostname %s resolves to unknown address type.", host);
    1564           0 :          return(INADDR_NONE);
    1565             :       }
    1566           0 :       memcpy((char *)&inaddr.sin_addr, (char *)hostp->h_addr, sizeof(inaddr.sin_addr));
    1567             :    }
    1568           0 :    return(inaddr.sin_addr.s_addr);
    1569             : 
    1570             : }
    1571             : 
    1572             : 
    1573             : /*********************************************************************
    1574             :  *
    1575             :  * Function    :  socket_is_still_alive
    1576             :  *
    1577             :  * Description :  Figures out whether or not a socket is still alive.
    1578             :  *
    1579             :  * Parameters  :
    1580             :  *          1  :  sfd = The socket to check.
    1581             :  *
    1582             :  * Returns     :  TRUE for yes, otherwise FALSE.
    1583             :  *
    1584             :  *********************************************************************/
    1585       48542 : int socket_is_still_alive(jb_socket sfd)
    1586             : {
    1587             :    char buf[10];
    1588             :    int no_data_waiting;
    1589             : #ifdef HAVE_POLL
    1590             :    int poll_result;
    1591             :    struct pollfd poll_fd[1];
    1592             : 
    1593       48542 :    memset(poll_fd, 0, sizeof(poll_fd));
    1594       48542 :    poll_fd[0].fd = sfd;
    1595       48542 :    poll_fd[0].events = POLLIN;
    1596             : 
    1597       48542 :    poll_result = poll(poll_fd, 1, 0);
    1598             : 
    1599       48542 :    if (-1 == poll_result)
    1600             :    {
    1601           0 :       log_error(LOG_LEVEL_CONNECT, "Polling socket %d failed.", sfd);
    1602           0 :       return FALSE;
    1603             :    }
    1604       48542 :    no_data_waiting = !(poll_fd[0].revents & POLLIN);
    1605             : #else
    1606             :    fd_set readable_fds;
    1607             :    struct timeval timeout;
    1608             :    int ret;
    1609             : 
    1610             :    memset(&timeout, '\0', sizeof(timeout));
    1611             :    FD_ZERO(&readable_fds);
    1612             :    FD_SET(sfd, &readable_fds);
    1613             : 
    1614             :    ret = select((int)sfd+1, &readable_fds, NULL, NULL, &timeout);
    1615             :    if (ret < 0)
    1616             :    {
    1617             :       log_error(LOG_LEVEL_CONNECT, "select() on socket %d failed: %E", sfd);
    1618             :       return FALSE;
    1619             :    }
    1620             :    no_data_waiting = !FD_ISSET(sfd, &readable_fds);
    1621             : #endif /* def HAVE_POLL */
    1622             : 
    1623       48542 :    return (no_data_waiting || !feof_unlocked(stdin));
    1624             : }
    1625             : 
    1626             : 
    1627             : #ifdef FEATURE_EXTERNAL_FILTERS
    1628             : /*********************************************************************
    1629             :  *
    1630             :  * Function    :  mark_socket_for_close_on_execute
    1631             :  *
    1632             :  * Description :  Marks a socket for close on execute.
    1633             :  *
    1634             :  *                Used so that external filters have no direct
    1635             :  *                access to sockets they shouldn't care about.
    1636             :  *
    1637             :  *                Not implemented for all platforms.
    1638             :  *
    1639             :  * Parameters  :
    1640             :  *          1  :  fd = The socket to mark
    1641             :  *
    1642             :  * Returns     :  void.
    1643             :  *
    1644             :  *********************************************************************/
    1645           0 : void mark_socket_for_close_on_execute(jb_socket fd)
    1646             : {
    1647             : #ifdef FEATURE_PTHREAD
    1648             :    int ret;
    1649             : 
    1650           0 :    ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
    1651             : 
    1652           0 :    if (ret == -1)
    1653             :    {
    1654           0 :       log_error(LOG_LEVEL_ERROR,
    1655             :          "fcntl(%d, F_SETFD, FD_CLOEXEC) failed", fd);
    1656             :    }
    1657             : #else
    1658             : #warning "Sockets will be visible to external filters"
    1659             : #endif
    1660           0 : }
    1661             : #endif /* def FEATURE_EXTERNAL_FILTERS */
    1662             : 
    1663             : /*
    1664             :   Local Variables:
    1665             :   tab-width: 3
    1666             :   end:
    1667             : */

Generated by: LCOV version 1.14