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