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