48f43c922b7819fb0ca428662be4b4929763b9fb
[privoxy.git] / jbsockets.c
1 const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.134 2015/11/06 13:37: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
1225    c_length = sizeof(client);
1226
1227    /*
1228     * Wait for a connection on any socket.
1229     * Return immediately if no socket is listening.
1230     * XXX: Why not treat this as fatal error?
1231     */
1232    FD_ZERO(&selected_fds);
1233    max_selected_socket = 0;
1234    for (i = 0; i < MAX_LISTENING_SOCKETS; i++)
1235    {
1236       if (JB_INVALID_SOCKET != fds[i])
1237       {
1238          FD_SET(fds[i], &selected_fds);
1239          if (max_selected_socket < fds[i] + 1)
1240          {
1241             max_selected_socket = fds[i] + 1;
1242          }
1243       }
1244    }
1245    if (0 == max_selected_socket)
1246    {
1247       return 0;
1248    }
1249    do
1250    {
1251       retval = select(max_selected_socket, &selected_fds, NULL, NULL, NULL);
1252    } while (retval < 0 && errno == EINTR);
1253    if (retval <= 0)
1254    {
1255       if (0 == retval)
1256       {
1257          log_error(LOG_LEVEL_ERROR,
1258             "Waiting on new client failed because select(2) returned 0."
1259             " This should not happen.");
1260       }
1261       else
1262       {
1263          log_error(LOG_LEVEL_ERROR,
1264             "Waiting on new client failed because of problems in select(2): "
1265             "%s.", strerror(errno));
1266       }
1267       return 0;
1268    }
1269    for (i = 0; i < MAX_LISTENING_SOCKETS && !FD_ISSET(fds[i], &selected_fds);
1270          i++);
1271    if (i >= MAX_LISTENING_SOCKETS)
1272    {
1273       log_error(LOG_LEVEL_ERROR,
1274          "select(2) reported connected clients (number = %u, "
1275          "descriptor boundary = %u), but none found.",
1276          retval, max_selected_socket);
1277       return 0;
1278    }
1279    fd = fds[i];
1280
1281    /* Accept selected connection */
1282 #ifdef _WIN32
1283    afd = accept (fd, (struct sockaddr *) &client, &c_length);
1284    if (afd == JB_INVALID_SOCKET)
1285    {
1286       return 0;
1287    }
1288 #else
1289    do
1290    {
1291 #if defined(FEATURE_ACCEPT_FILTER) && defined(SO_ACCEPTFILTER)
1292       struct accept_filter_arg af_options;
1293       bzero(&af_options, sizeof(af_options));
1294       strlcpy(af_options.af_name, "httpready", sizeof(af_options.af_name));
1295       setsockopt(fd, SOL_SOCKET, SO_ACCEPTFILTER, &af_options, sizeof(af_options));
1296 #endif
1297       afd = accept (fd, (struct sockaddr *) &client, &c_length);
1298    } while (afd < 0 && errno == EINTR);
1299    if (afd < 0)
1300    {
1301       return 0;
1302    }
1303 #endif
1304
1305 #ifdef SO_LINGER
1306    {
1307       struct linger linger_options;
1308       linger_options.l_onoff  = 1;
1309       linger_options.l_linger = 5;
1310       if (0 != setsockopt(afd, SOL_SOCKET, SO_LINGER, &linger_options, sizeof(linger_options)))
1311       {
1312          log_error(LOG_LEVEL_ERROR, "Setting SO_LINGER on socket %d failed.", afd);
1313       }
1314    }
1315 #endif
1316
1317 #ifndef _WIN32
1318    if (afd >= FD_SETSIZE)
1319    {
1320       log_error(LOG_LEVEL_ERROR,
1321          "Client socket number too high to use select(): %d >= %d",
1322          afd, FD_SETSIZE);
1323       close_socket(afd);
1324       return 0;
1325    }
1326 #endif
1327
1328 #ifdef FEATURE_EXTERNAL_FILTERS
1329    mark_socket_for_close_on_execute(afd);
1330 #endif
1331
1332    set_no_delay_flag(afd);
1333
1334    csp->cfd = afd;
1335 #ifdef HAVE_RFC2553
1336    csp->ip_addr_str = malloc_or_die(NI_MAXHOST);
1337    retval = getnameinfo((struct sockaddr *) &client, c_length,
1338          csp->ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1339    if (!csp->ip_addr_str || retval)
1340    {
1341       log_error(LOG_LEVEL_ERROR, "Can not save csp->ip_addr_str: %s",
1342          (csp->ip_addr_str) ? gai_strerror(retval) : "Insuffcient memory");
1343       freez(csp->ip_addr_str);
1344    }
1345 #undef client
1346 #else
1347    csp->ip_addr_str  = strdup(inet_ntoa(client.sin_addr));
1348    csp->ip_addr_long = ntohl(client.sin_addr.s_addr);
1349 #endif /* def HAVE_RFC2553 */
1350
1351    return 1;
1352
1353 }
1354
1355
1356 /*********************************************************************
1357  *
1358  * Function    :  resolve_hostname_to_ip
1359  *
1360  * Description :  Resolve a hostname to an internet tcp/ip address.
1361  *                NULL or an empty string resolve to INADDR_ANY.
1362  *
1363  * Parameters  :
1364  *          1  :  host = hostname to resolve
1365  *
1366  * Returns     :  INADDR_NONE => failure, INADDR_ANY or tcp/ip address if successful.
1367  *
1368  *********************************************************************/
1369 unsigned long resolve_hostname_to_ip(const char *host)
1370 {
1371    struct sockaddr_in inaddr;
1372    struct hostent *hostp;
1373 #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS) || defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
1374    struct hostent result;
1375 #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
1376    char hbuf[HOSTENT_BUFFER_SIZE];
1377    int thd_err;
1378 #else /* defined(HAVE_GETHOSTBYNAME_R_3_ARGS) */
1379    struct hostent_data hdata;
1380 #endif /* def HAVE_GETHOSTBYNAME_R_(6|5)_ARGS */
1381 #endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
1382
1383    if ((host == NULL) || (*host == '\0'))
1384    {
1385       return(INADDR_ANY);
1386    }
1387
1388    memset((char *) &inaddr, 0, sizeof inaddr);
1389
1390    if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1)
1391    {
1392       unsigned int dns_retries = 0;
1393 #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS)
1394       while (gethostbyname_r(host, &result, hbuf,
1395                 HOSTENT_BUFFER_SIZE, &hostp, &thd_err)
1396              && (thd_err == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
1397       {
1398          log_error(LOG_LEVEL_ERROR,
1399             "Timeout #%u while trying to resolve %s. Trying again.",
1400             dns_retries, host);
1401       }
1402 #elif defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
1403       while (NULL == (hostp = gethostbyname_r(host, &result,
1404                                  hbuf, HOSTENT_BUFFER_SIZE, &thd_err))
1405              && (thd_err == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
1406       {
1407          log_error(LOG_LEVEL_ERROR,
1408             "Timeout #%u while trying to resolve %s. Trying again.",
1409             dns_retries, host);
1410       }
1411 #elif defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
1412       /*
1413        * XXX: Doesn't retry in case of soft errors.
1414        * Does this gethostbyname_r version set h_errno?
1415        */
1416       if (0 == gethostbyname_r(host, &result, &hdata))
1417       {
1418          hostp = &result;
1419       }
1420       else
1421       {
1422          hostp = NULL;
1423       }
1424 #elif defined(MUTEX_LOCKS_AVAILABLE)
1425       privoxy_mutex_lock(&resolver_mutex);
1426       while (NULL == (hostp = gethostbyname(host))
1427              && (h_errno == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
1428       {
1429          log_error(LOG_LEVEL_ERROR,
1430             "Timeout #%u while trying to resolve %s. Trying again.",
1431             dns_retries, host);
1432       }
1433       privoxy_mutex_unlock(&resolver_mutex);
1434 #else
1435       while (NULL == (hostp = gethostbyname(host))
1436              && (h_errno == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
1437       {
1438          log_error(LOG_LEVEL_ERROR,
1439             "Timeout #%u while trying to resolve %s. Trying again.",
1440             dns_retries, host);
1441       }
1442 #endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
1443       /*
1444        * On Mac OSX, if a domain exists but doesn't have a type A
1445        * record associated with it, the h_addr member of the struct
1446        * hostent returned by gethostbyname is NULL, even if h_length
1447        * is 4. Therefore the second test below.
1448        */
1449       if (hostp == NULL || hostp->h_addr == NULL)
1450       {
1451          errno = EINVAL;
1452          log_error(LOG_LEVEL_ERROR, "could not resolve hostname %s", host);
1453          return(INADDR_NONE);
1454       }
1455       if (hostp->h_addrtype != AF_INET)
1456       {
1457 #ifdef _WIN32
1458          errno = WSAEPROTOTYPE;
1459 #else
1460          errno = EPROTOTYPE;
1461 #endif
1462          log_error(LOG_LEVEL_ERROR, "hostname %s resolves to unknown address type.", host);
1463          return(INADDR_NONE);
1464       }
1465       memcpy((char *)&inaddr.sin_addr, (char *)hostp->h_addr, sizeof(inaddr.sin_addr));
1466    }
1467    return(inaddr.sin_addr.s_addr);
1468
1469 }
1470
1471
1472 /*********************************************************************
1473  *
1474  * Function    :  socket_is_still_alive
1475  *
1476  * Description :  Figures out whether or not a socket is still alive.
1477  *
1478  * Parameters  :
1479  *          1  :  sfd = The socket to check.
1480  *
1481  * Returns     :  TRUE for yes, otherwise FALSE.
1482  *
1483  *********************************************************************/
1484 int socket_is_still_alive(jb_socket sfd)
1485 {
1486    char buf[10];
1487    int no_data_waiting;
1488
1489 #ifdef HAVE_POLL
1490    int poll_result;
1491    struct pollfd poll_fd[1];
1492
1493    memset(poll_fd, 0, sizeof(poll_fd));
1494    poll_fd[0].fd = sfd;
1495    poll_fd[0].events = POLLIN;
1496
1497    poll_result = poll(poll_fd, 1, 0);
1498
1499    if (-1 == poll_result)
1500    {
1501       log_error(LOG_LEVEL_CONNECT, "Polling socket %d failed.", sfd);
1502       return FALSE;
1503    }
1504    no_data_waiting = !(poll_fd[0].revents & POLLIN);
1505 #else
1506    fd_set readable_fds;
1507    struct timeval timeout;
1508    int ret;
1509
1510    memset(&timeout, '\0', sizeof(timeout));
1511    FD_ZERO(&readable_fds);
1512    FD_SET(sfd, &readable_fds);
1513
1514    ret = select((int)sfd+1, &readable_fds, NULL, NULL, &timeout);
1515    if (ret < 0)
1516    {
1517       log_error(LOG_LEVEL_CONNECT, "select() on socket %d failed: %E", sfd);
1518       return FALSE;
1519    }
1520    no_data_waiting = !FD_ISSET(sfd, &readable_fds);
1521 #endif /* def HAVE_POLL */
1522
1523    return (no_data_waiting || (1 == recv(sfd, buf, 1, MSG_PEEK)));
1524 }
1525
1526
1527 #ifdef FEATURE_EXTERNAL_FILTERS
1528 /*********************************************************************
1529  *
1530  * Function    :  mark_socket_for_close_on_execute
1531  *
1532  * Description :  Marks a socket for close on execute.
1533  *
1534  *                Used so that external filters have no direct
1535  *                access to sockets they shouldn't care about.
1536  *
1537  *                Not implemented for all platforms.
1538  *
1539  * Parameters  :
1540  *          1  :  fd = The socket to mark
1541  *
1542  * Returns     :  void.
1543  *
1544  *********************************************************************/
1545 void mark_socket_for_close_on_execute(jb_socket fd)
1546 {
1547 #ifdef FEATURE_PTHREAD
1548    int ret;
1549
1550    ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
1551
1552    if (ret == -1)
1553    {
1554       log_error(LOG_LEVEL_ERROR,
1555          "fcntl(%d, F_SETFD, FD_CLOEXEC) failed", fd);
1556    }
1557 #else
1558 #warning "Sockets will be visible to external filters"
1559 #endif
1560 }
1561 #endif /* def FEATURE_EXTERNAL_FILTERS */
1562
1563 /*
1564   Local Variables:
1565   tab-width: 3
1566   end:
1567 */