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