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