Feature Requests 3040263 :: Add "user.filter" to "Edit" menu
[privoxy.git] / jbsockets.c
1 const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.78 2010/07/26 11:28:11 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-2010 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 FEATURE_CONNECTION_KEEP_ALIVE
87 #ifdef HAVE_POLL
88 #ifdef __GLIBC__
89 #include <sys/poll.h>
90 #else
91 #include <poll.h>
92 #endif /* def __GLIBC__ */
93 #endif /* HAVE_POLL */
94 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
95
96 #include "project.h"
97
98 /* For mutex semaphores only */
99 #include "jcc.h"
100
101 #include "jbsockets.h"
102 #include "filters.h"
103 #include "errlog.h"
104
105 /* Mac OSX doesn't define AI_NUMERICSESRV */
106 #ifndef AI_NUMERICSERV
107 #define AI_NUMERICSERV 0
108 #endif
109
110 const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION;
111
112 /*
113  * Maximum number of gethostbyname(_r) retries in case of
114  * soft errors (TRY_AGAIN).
115  * XXX: Does it make sense to make this a config option?
116  */
117 #define MAX_DNS_RETRIES 10
118
119 #define MAX_LISTEN_BACKLOG 128
120
121
122 /*********************************************************************
123  *
124  * Function    :  connect_to
125  *
126  * Description :  Open a socket and connect to it.  Will check
127  *                that this is allowed according to ACL.
128  *
129  * Parameters  :
130  *          1  :  host = hostname to connect to
131  *          2  :  portnum = port to connent on (XXX: should be unsigned)
132  *          3  :  csp = Current client state (buffers, headers, etc...)
133  *                      Not modified, only used for source IP and ACL.
134  *
135  * Returns     :  JB_INVALID_SOCKET => failure, else it is the socket
136  *                file descriptor.
137  *
138  *********************************************************************/
139 #ifdef HAVE_RFC2553
140 /* Getaddrinfo implementation */
141 jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
142 {
143    struct addrinfo hints, *result, *rp;
144    char service[6];
145    int retval;
146    jb_socket fd;
147    fd_set wfds;
148    struct timeval tv[1];
149 #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
150    int   flags;
151 #endif
152    int connect_failed;
153
154 #ifdef FEATURE_ACL
155    struct access_control_addr dst[1];
156 #endif /* def FEATURE_ACL */
157
158    retval = snprintf(service, sizeof(service), "%d", portnum);
159    if ((-1 == retval) || (sizeof(service) <= retval))
160    {
161       log_error(LOG_LEVEL_ERROR,
162          "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",
163          portnum);
164       csp->http->host_ip_addr_str = strdup("unknown");
165       return(JB_INVALID_SOCKET);
166    }
167
168    memset((char *)&hints, 0, sizeof(hints));
169    hints.ai_family = AF_UNSPEC;
170    hints.ai_socktype = SOCK_STREAM;
171    hints.ai_flags = AI_NUMERICSERV; /* avoid service look-up */
172 #ifdef AI_ADDRCONFIG
173    hints.ai_flags |= AI_ADDRCONFIG;
174 #endif
175    if ((retval = getaddrinfo(host, service, &hints, &result)))
176    {
177       log_error(LOG_LEVEL_INFO,
178          "Can not resolve %s: %s", host, gai_strerror(retval));
179       /* XXX: Should find a better way to propagate this error. */
180       errno = EINVAL;
181       csp->http->host_ip_addr_str = strdup("unknown");
182       return(JB_INVALID_SOCKET);
183    }
184
185    for (rp = result; rp != NULL; rp = rp->ai_next)
186    {
187
188 #ifdef FEATURE_ACL
189       memcpy(&dst->addr, rp->ai_addr, rp->ai_addrlen);
190
191       if (block_acl(dst, csp))
192       {
193 #ifdef __OS2__
194          errno = SOCEPERM;
195 #else
196          errno = EPERM;
197 #endif
198          continue;
199       }
200 #endif /* def FEATURE_ACL */
201
202       csp->http->host_ip_addr_str = malloc(NI_MAXHOST);
203       if (NULL == csp->http->host_ip_addr_str)
204       {
205          log_error(LOG_LEVEL_ERROR,
206             "Out of memory while getting the server IP address.");
207          return JB_INVALID_SOCKET;
208       }
209       retval = getnameinfo(rp->ai_addr, rp->ai_addrlen,
210          csp->http->host_ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
211       if (!csp->http->host_ip_addr_str || retval)
212       {
213          log_error(LOG_LEVEL_ERROR,
214             "Can not save csp->http->host_ip_addr_str: %s",
215             (csp->http->host_ip_addr_str) ?
216             gai_strerror(retval) : "Insufficient memory");
217          freez(csp->http->host_ip_addr_str);
218          continue;
219       }
220
221 #ifdef _WIN32
222       if ((fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) ==
223             JB_INVALID_SOCKET)
224 #else
225       if ((fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0)
226 #endif
227       {
228          continue;
229       }
230
231 #ifdef TCP_NODELAY
232       {  /* turn off TCP coalescence */
233          int mi = 1;
234          setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &mi, sizeof (int));
235       }
236 #endif /* def TCP_NODELAY */
237
238 #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
239       if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
240       {
241          flags |= O_NDELAY;
242          fcntl(fd, F_SETFL, flags);
243       }
244 #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
245
246       connect_failed = 0;
247       while (connect(fd, rp->ai_addr, rp->ai_addrlen) == JB_INVALID_SOCKET)
248       {
249 #ifdef _WIN32
250          if (errno == WSAEINPROGRESS)
251 #elif __OS2__
252          if (sock_errno() == EINPROGRESS)
253 #else /* ifndef _WIN32 */
254          if (errno == EINPROGRESS)
255 #endif /* ndef _WIN32 || __OS2__ */
256          {
257             break;
258          }
259
260 #ifdef __OS2__
261          if (sock_errno() != EINTR)
262 #else
263          if (errno != EINTR)
264 #endif /* __OS2__ */
265          {
266             close_socket(fd);
267             connect_failed = 1;
268             break;
269          }
270       }
271       if (connect_failed)
272       {
273          continue;
274       }
275
276 #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
277       if (flags != -1)
278       {
279          flags &= ~O_NDELAY;
280          fcntl(fd, F_SETFL, flags);
281       }
282 #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
283
284       /* wait for connection to complete */
285       FD_ZERO(&wfds);
286       FD_SET(fd, &wfds);
287
288       tv->tv_sec  = 30;
289       tv->tv_usec = 0;
290
291       /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Wierd! */
292       if ((select((int)fd + 1, NULL, &wfds, NULL, tv) > 0)
293          && FD_ISSET(fd, &wfds))
294       {
295          /*
296           * See Linux connect(2) man page for more info
297           * about connecting on non-blocking socket.
298           */
299          int socket_in_error;
300          socklen_t optlen = sizeof(socket_in_error);
301          if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, &socket_in_error, &optlen))
302          {
303             if (!socket_in_error)
304             {
305                /* Connection established, no need to try other addresses. */
306                break;
307             }
308             log_error(LOG_LEVEL_CONNECT, "Could not connect to [%s]:%s: %s.",
309                csp->http->host_ip_addr_str, service, strerror(socket_in_error));
310          }
311          else
312          {
313             log_error(LOG_LEVEL_ERROR, "Could not get the state of "
314                "the connection to [%s]:%s: %s; dropping connection.",
315                csp->http->host_ip_addr_str, service, strerror(errno));
316          }
317       }
318
319       /* Connection failed, try next address */
320       close_socket(fd);
321    }
322
323    freeaddrinfo(result);
324    if (!rp)
325    {
326       log_error(LOG_LEVEL_CONNECT, "Could not connect to [%s]:%s.",
327          host, service);
328       return(JB_INVALID_SOCKET);
329    }
330    log_error(LOG_LEVEL_CONNECT, "Connected to %s[%s]:%s.",
331       host, csp->http->host_ip_addr_str, service);
332
333    return(fd);
334
335 }
336
337 #else /* ndef HAVE_RFC2553 */
338 /* Pre-getaddrinfo implementation */
339
340 jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
341 {
342    struct sockaddr_in inaddr;
343    jb_socket fd;
344    unsigned int addr;
345    fd_set wfds;
346    struct timeval tv[1];
347 #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
348    int   flags;
349 #endif
350
351 #ifdef FEATURE_ACL
352    struct access_control_addr dst[1];
353 #endif /* def FEATURE_ACL */
354
355    memset((char *)&inaddr, 0, sizeof inaddr);
356
357    if ((addr = resolve_hostname_to_ip(host)) == INADDR_NONE)
358    {
359       csp->http->host_ip_addr_str = strdup("unknown");
360       return(JB_INVALID_SOCKET);
361    }
362
363 #ifdef FEATURE_ACL
364    dst->addr = ntohl(addr);
365    dst->port = portnum;
366
367    if (block_acl(dst, csp))
368    {
369 #ifdef __OS2__
370       errno = SOCEPERM;
371 #else
372       errno = EPERM;
373 #endif
374       return(JB_INVALID_SOCKET);
375    }
376 #endif /* def FEATURE_ACL */
377
378    inaddr.sin_addr.s_addr = addr;
379    inaddr.sin_family      = AF_INET;
380    csp->http->host_ip_addr_str = strdup(inet_ntoa(inaddr.sin_addr));
381
382 #ifndef _WIN32
383    if (sizeof(inaddr.sin_port) == sizeof(short))
384 #endif /* ndef _WIN32 */
385    {
386       inaddr.sin_port = htons((unsigned short) portnum);
387    }
388 #ifndef _WIN32
389    else
390    {
391       inaddr.sin_port = htonl((unsigned long)portnum);
392    }
393 #endif /* ndef _WIN32 */
394
395 #ifdef _WIN32
396    if ((fd = socket(inaddr.sin_family, SOCK_STREAM, 0)) == JB_INVALID_SOCKET)
397 #else
398    if ((fd = socket(inaddr.sin_family, SOCK_STREAM, 0)) < 0)
399 #endif
400    {
401       return(JB_INVALID_SOCKET);
402    }
403
404 #ifdef TCP_NODELAY
405    {  /* turn off TCP coalescence */
406       int mi = 1;
407       setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &mi, sizeof (int));
408    }
409 #endif /* def TCP_NODELAY */
410
411 #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
412    if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
413    {
414       flags |= O_NDELAY;
415       fcntl(fd, F_SETFL, flags);
416    }
417 #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
418
419    while (connect(fd, (struct sockaddr *) & inaddr, sizeof inaddr) == JB_INVALID_SOCKET)
420    {
421 #ifdef _WIN32
422       if (errno == WSAEINPROGRESS)
423 #elif __OS2__ 
424       if (sock_errno() == EINPROGRESS)
425 #else /* ifndef _WIN32 */
426       if (errno == EINPROGRESS)
427 #endif /* ndef _WIN32 || __OS2__ */
428       {
429          break;
430       }
431
432 #ifdef __OS2__ 
433       if (sock_errno() != EINTR)
434 #else
435       if (errno != EINTR)
436 #endif /* __OS2__ */
437       {
438          close_socket(fd);
439          return(JB_INVALID_SOCKET);
440       }
441    }
442
443 #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
444    if (flags != -1)
445    {
446       flags &= ~O_NDELAY;
447       fcntl(fd, F_SETFL, flags);
448    }
449 #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
450
451    /* wait for connection to complete */
452    FD_ZERO(&wfds);
453    FD_SET(fd, &wfds);
454
455    tv->tv_sec  = 30;
456    tv->tv_usec = 0;
457
458    /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Wierd! */
459    if (select((int)fd + 1, NULL, &wfds, NULL, tv) <= 0)
460    {
461       close_socket(fd);
462       return(JB_INVALID_SOCKET);
463    }
464    return(fd);
465
466 }
467 #endif /* ndef HAVE_RFC2553 */
468
469
470 /*********************************************************************
471  *
472  * Function    :  write_socket
473  *
474  * Description :  Write the contents of buf (for n bytes) to socket fd.
475  *
476  * Parameters  :
477  *          1  :  fd = file descriptor (aka. handle) of socket to write to.
478  *          2  :  buf = pointer to data to be written.
479  *          3  :  len = length of data to be written to the socket "fd".
480  *
481  * Returns     :  0 on success (entire buffer sent).
482  *                nonzero on error.
483  *
484  *********************************************************************/
485 #ifdef AMIGA
486 int write_socket(jb_socket fd, const char *buf, ssize_t len)
487 #else
488 int write_socket(jb_socket fd, const char *buf, size_t len)
489 #endif
490 {
491    if (len == 0)
492    {
493       return 0;
494    }
495
496    if (len < 0) /* constant condition - size_t isn't ever negative */ 
497    {
498       return 1;
499    }
500
501    log_error(LOG_LEVEL_WRITING, "to socket %d: %N", fd, len, buf);
502
503 #if defined(_WIN32)
504    return (send(fd, buf, (int)len, 0) != (int)len);
505 #elif defined(__BEOS__) || defined(AMIGA)
506    return (send(fd, buf, len, 0) != len);
507 #elif defined(__OS2__)
508    /*
509     * Break the data up into SOCKET_SEND_MAX chunks for sending...
510     * OS/2 seemed to complain when the chunks were too large.
511     */
512 #define SOCKET_SEND_MAX 65000
513    {
514       int send_len, send_rc = 0, i = 0;
515       while ((i < len) && (send_rc != -1))
516       {
517          if ((i + SOCKET_SEND_MAX) > len)
518             send_len = len - i;
519          else
520             send_len = SOCKET_SEND_MAX;
521          send_rc = send(fd,(char*)buf + i, send_len, 0);
522          if (send_rc == -1)
523             return 1;
524          i = i + send_len;
525       }
526       return 0;
527    }
528 #else
529    return (write(fd, buf, len) != len);
530 #endif
531
532 }
533
534
535 /*********************************************************************
536  *
537  * Function    :  read_socket
538  *
539  * Description :  Read from a TCP/IP socket in a platform independent way.
540  *
541  * Parameters  :
542  *          1  :  fd = file descriptor of the socket to read
543  *          2  :  buf = pointer to buffer where data will be written
544  *                Must be >= len bytes long.
545  *          3  :  len = maximum number of bytes to read
546  *
547  * Returns     :  On success, the number of bytes read is returned (zero
548  *                indicates end of file), and the file position is advanced
549  *                by this number.  It is not an error if this number is
550  *                smaller than the number of bytes requested; this may hap-
551  *                pen for example because fewer bytes are actually available
552  *                right now (maybe because we were close to end-of-file, or
553  *                because we are reading from a pipe, or from a terminal,
554  *                or because read() was interrupted by a signal).  On error,
555  *                -1 is returned, and errno is set appropriately.  In this
556  *                case it is left unspecified whether the file position (if
557  *                any) changes.
558  *
559  *********************************************************************/
560 int read_socket(jb_socket fd, char *buf, int len)
561 {
562    int ret;
563
564    if (len <= 0)
565    {
566       return(0);
567    }
568
569 #if defined(_WIN32)
570    ret = recv(fd, buf, len, 0);
571 #elif defined(__BEOS__) || defined(AMIGA) || defined(__OS2__)
572    ret = recv(fd, buf, (size_t)len, 0);
573 #else
574    ret = (int)read(fd, buf, (size_t)len);
575 #endif
576
577    if (ret > 0)
578    {
579       log_error(LOG_LEVEL_RECEIVED, "from socket %d: %N", fd, ret, buf);
580    }
581
582    return ret;
583 }
584
585
586 /*********************************************************************
587  *
588  * Function    :  data_is_available
589  *
590  * Description :  Waits for data to arrive on a socket.
591  *
592  * Parameters  :
593  *          1  :  fd = file descriptor of the socket to read
594  *          2  :  seconds_to_wait = number of seconds after which we give up.
595  *
596  * Returns     :  TRUE if data arrived in time,
597  *                FALSE otherwise.
598  *
599  *********************************************************************/
600 int data_is_available(jb_socket fd, int seconds_to_wait)
601 {
602    char buf[10];
603    fd_set rfds;
604    struct timeval timeout;
605    int n;
606
607    memset(&timeout, 0, sizeof(timeout));
608    timeout.tv_sec = seconds_to_wait;
609
610 #ifdef __OS2__
611    /* Copy and pasted from jcc.c ... */
612    memset(&rfds, 0, sizeof(fd_set));
613 #else
614    FD_ZERO(&rfds);
615 #endif
616    FD_SET(fd, &rfds);
617
618    n = select(fd+1, &rfds, NULL, NULL, &timeout);
619
620    /*
621     * XXX: Do we care about the different error conditions?
622     */
623    return ((n == 1) && (1 == recv(fd, buf, 1, MSG_PEEK)));
624 }
625
626
627 /*********************************************************************
628  *
629  * Function    :  close_socket
630  *
631  * Description :  Closes a TCP/IP socket
632  *
633  * Parameters  :
634  *          1  :  fd = file descriptor of socket to be closed
635  *
636  * Returns     :  void
637  *
638  *********************************************************************/
639 void close_socket(jb_socket fd)
640 {
641 #if defined(_WIN32) || defined(__BEOS__)
642    closesocket(fd);
643 #elif defined(AMIGA)
644    CloseSocket(fd); 
645 #elif defined(__OS2__)
646    soclose(fd);
647 #else
648    close(fd);
649 #endif
650
651 }
652
653
654 /*********************************************************************
655  *
656  * Function    :  bind_port
657  *
658  * Description :  Call socket, set socket options, and listen.
659  *                Called by listen_loop to "boot up" our proxy address.
660  *
661  * Parameters  :
662  *          1  :  hostnam = TCP/IP address to bind/listen to
663  *          2  :  portnum = port to listen on
664  *          3  :  pfd = pointer used to return file descriptor.
665  *
666  * Returns     :  if success, returns 0 and sets *pfd.
667  *                if failure, returns -3 if address is in use,
668  *                                    -2 if address unresolvable,
669  *                                    -1 otherwise
670  *********************************************************************/
671 int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
672 {
673 #ifdef HAVE_RFC2553
674    struct addrinfo hints;
675    struct addrinfo *result, *rp;
676    /*
677     * XXX: portnum should be a string to allow symbolic service
678     * names in the configuration file and to avoid the following
679     * int2string.
680     */
681    char servnam[6];
682    int retval;
683 #else
684    struct sockaddr_in inaddr;
685 #endif /* def HAVE_RFC2553 */
686    jb_socket fd;
687 #ifndef _WIN32
688    int one = 1;
689 #endif /* ndef _WIN32 */
690
691    *pfd = JB_INVALID_SOCKET;
692
693 #ifdef HAVE_RFC2553
694    retval = snprintf(servnam, sizeof(servnam), "%d", portnum);
695    if ((-1 == retval) || (sizeof(servnam) <= retval))
696    {
697       log_error(LOG_LEVEL_ERROR,
698          "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",
699          portnum);
700       return -1;
701    }
702
703    memset(&hints, 0, sizeof(struct addrinfo));
704    if (hostnam == NULL)
705    {
706       /*
707        * XXX: This is a hack. The right thing to do
708        * would be to bind to both AF_INET and AF_INET6.
709        * This will also fail if there is no AF_INET
710        * version available.
711        */
712       hints.ai_family = AF_INET;
713    }
714    else
715    {
716       hints.ai_family = AF_UNSPEC;
717    }
718    hints.ai_socktype = SOCK_STREAM;
719    hints.ai_flags = AI_PASSIVE;
720 #ifdef AI_ADDRCONFIG
721    hints.ai_flags |= AI_ADDRCONFIG;
722 #endif
723    hints.ai_protocol = 0; /* Realy any stream protocol or TCP only */
724    hints.ai_canonname = NULL;
725    hints.ai_addr = NULL;
726    hints.ai_next = NULL;
727
728    if ((retval = getaddrinfo(hostnam, servnam, &hints, &result)))
729    {
730       log_error(LOG_LEVEL_ERROR,
731          "Can not resolve %s: %s", hostnam, gai_strerror(retval));
732       return -2;
733    }
734 #else
735    memset((char *)&inaddr, '\0', sizeof inaddr);
736
737    inaddr.sin_family      = AF_INET;
738    inaddr.sin_addr.s_addr = resolve_hostname_to_ip(hostnam);
739
740    if (inaddr.sin_addr.s_addr == INADDR_NONE)
741    {
742       return(-2);
743    }
744
745 #ifndef _WIN32
746    if (sizeof(inaddr.sin_port) == sizeof(short))
747 #endif /* ndef _WIN32 */
748    {
749       inaddr.sin_port = htons((unsigned short) portnum);
750    }
751 #ifndef _WIN32
752    else
753    {
754       inaddr.sin_port = htonl((unsigned long) portnum);
755    }
756 #endif /* ndef _WIN32 */
757 #endif /* def HAVE_RFC2553 */
758
759 #ifdef HAVE_RFC2553
760    for (rp = result; rp != NULL; rp = rp->ai_next)
761    {
762       fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
763 #else
764    fd = socket(AF_INET, SOCK_STREAM, 0);
765 #endif /* def HAVE_RFC2553 */
766
767 #ifdef _WIN32
768    if (fd == JB_INVALID_SOCKET)
769 #else
770    if (fd < 0)
771 #endif
772    {
773 #ifdef HAVE_RFC2553
774       continue;
775 #else
776       return(-1);
777 #endif
778    }
779
780 #ifndef _WIN32
781    /*
782     * This is not needed for Win32 - in fact, it stops
783     * duplicate instances of Privoxy from being caught.
784     *
785     * On UNIX, we assume the user is sensible enough not
786     * to start Privoxy multiple times on the same IP.
787     * Without this, stopping and restarting Privoxy
788     * from a script fails.
789     * Note: SO_REUSEADDR is meant to only take over
790     * sockets which are *not* in listen state in Linux,
791     * e.g. sockets in TIME_WAIT. YMMV.
792     */
793    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
794 #endif /* ndef _WIN32 */
795
796 #ifdef HAVE_RFC2553
797    if (bind(fd, rp->ai_addr, rp->ai_addrlen) < 0)
798 #else
799    if (bind(fd, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
800 #endif
801    {
802 #ifdef _WIN32
803       errno = WSAGetLastError();
804       if (errno == WSAEADDRINUSE)
805 #else
806       if (errno == EADDRINUSE)
807 #endif
808       {
809 #ifdef HAVE_RFC2553
810          freeaddrinfo(result);
811 #endif
812          close_socket(fd);
813          return(-3);
814       }
815       else
816       {
817          close_socket(fd);
818 #ifndef HAVE_RFC2553
819          return(-1);
820       }
821    }
822 #else
823       }
824    }
825    else
826    {
827       /* bind() succeeded, escape from for-loop */
828       /*
829        * XXX: Support multiple listening sockets (e.g. localhost
830        * resolves to AF_INET and AF_INET6, but only the first address
831        * is used
832        */
833       break;
834    }
835    }
836
837    freeaddrinfo(result);
838    if (rp == NULL)
839    {
840       /* All bind()s failed */
841       return(-1);
842    }
843 #endif /* ndef HAVE_RFC2553 */
844
845    while (listen(fd, MAX_LISTEN_BACKLOG) == -1)
846    {
847       if (errno != EINTR)
848       {
849          return(-1);
850       }
851    }
852
853    *pfd = fd;
854    return 0;
855
856 }
857
858
859 /*********************************************************************
860  *
861  * Function    :  get_host_information
862  *
863  * Description :  Determines the IP address the client used to
864  *                reach us and the hostname associated with it.
865  *
866  *                XXX: Most of the code has been copy and pasted
867  *                from accept_connection() and not all of the
868  *                ifdefs paths have been tested afterwards.
869  *
870  * Parameters  :
871  *          1  :  afd = File descriptor returned from accept().
872  *          2  :  ip_address = Pointer to return the pointer to
873  *                             the ip address string.
874  *          3  :  hostname =   Pointer to return the pointer to
875  *                             the hostname or NULL if the caller
876  *                             isn't interested in it.
877  *
878  * Returns     :  void.
879  *
880  *********************************************************************/
881 void get_host_information(jb_socket afd, char **ip_address, char **hostname)
882 {
883 #ifdef HAVE_RFC2553
884    struct sockaddr_storage server;
885    int retval;
886 #else
887    struct sockaddr_in server;
888    struct hostent *host = NULL;
889 #endif /* HAVE_RFC2553 */
890 #if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA)
891    /* according to accept_connection() this fixes a warning. */
892    int s_length, s_length_provided;
893 #else
894    socklen_t s_length, s_length_provided;
895 #endif
896 #ifndef HAVE_RFC2553
897 #if defined(HAVE_GETHOSTBYADDR_R_8_ARGS) ||  defined(HAVE_GETHOSTBYADDR_R_7_ARGS) || defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
898    struct hostent result;
899 #if defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
900    struct hostent_data hdata;
901 #else
902    char hbuf[HOSTENT_BUFFER_SIZE];
903    int thd_err;
904 #endif /* def HAVE_GETHOSTBYADDR_R_5_ARGS */
905 #endif /* def HAVE_GETHOSTBYADDR_R_(8|7|5)_ARGS */
906 #endif /* ifndef HAVE_RFC2553 */
907    s_length = s_length_provided = sizeof(server);
908
909    if (NULL != hostname)
910    {
911       *hostname = NULL;
912    }
913    *ip_address = NULL;
914
915    if (!getsockname(afd, (struct sockaddr *) &server, &s_length))
916    {
917       if (s_length > s_length_provided)
918       {
919          log_error(LOG_LEVEL_ERROR, "getsockname() truncated server address");
920          return;
921       }
922 #ifdef HAVE_RFC2553
923       *ip_address = malloc(NI_MAXHOST);
924       if (NULL == *ip_address)
925       {
926          log_error(LOG_LEVEL_ERROR,
927             "Out of memory while getting the client's IP address.");
928          return;
929       }
930       retval = getnameinfo((struct sockaddr *) &server, s_length,
931          *ip_address, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
932       if (retval)
933       {
934          log_error(LOG_LEVEL_ERROR,
935             "Unable to print my own IP address: %s", gai_strerror(retval));
936          freez(*ip_address);
937          return;
938       }
939 #else
940       *ip_address = strdup(inet_ntoa(server.sin_addr));
941 #endif /* HAVE_RFC2553 */
942       if (NULL == hostname)
943       {
944          /*
945           * We're done here, the caller isn't
946           * interested in knowing the hostname.
947           */
948          return;
949       }
950
951 #ifdef HAVE_RFC2553
952       *hostname = malloc(NI_MAXHOST);
953       if (NULL == *hostname)
954       {
955          log_error(LOG_LEVEL_ERROR,
956             "Out of memory while getting the client's hostname.");
957          return;
958       }
959       retval = getnameinfo((struct sockaddr *) &server, s_length,
960          *hostname, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
961       if (retval)
962       {
963          log_error(LOG_LEVEL_ERROR,
964             "Unable to resolve my own IP address: %s", gai_strerror(retval));
965          freez(*hostname);
966       }
967 #else
968 #if defined(HAVE_GETHOSTBYADDR_R_8_ARGS)
969       gethostbyaddr_r((const char *)&server.sin_addr,
970                       sizeof(server.sin_addr), AF_INET,
971                       &result, hbuf, HOSTENT_BUFFER_SIZE,
972                       &host, &thd_err);
973 #elif defined(HAVE_GETHOSTBYADDR_R_7_ARGS)
974       host = gethostbyaddr_r((const char *)&server.sin_addr,
975                       sizeof(server.sin_addr), AF_INET,
976                       &result, hbuf, HOSTENT_BUFFER_SIZE, &thd_err);
977 #elif defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
978       if (0 == gethostbyaddr_r((const char *)&server.sin_addr,
979                                sizeof(server.sin_addr), AF_INET,
980                                &result, &hdata))
981       {
982          host = &result;
983       }
984       else
985       {
986          host = NULL;
987       }
988 #elif defined(MUTEX_LOCKS_AVAILABLE)
989       privoxy_mutex_lock(&resolver_mutex);
990       host = gethostbyaddr((const char *)&server.sin_addr, 
991                            sizeof(server.sin_addr), AF_INET);
992       privoxy_mutex_unlock(&resolver_mutex);
993 #else
994       host = gethostbyaddr((const char *)&server.sin_addr, 
995                            sizeof(server.sin_addr), AF_INET);
996 #endif
997       if (host == NULL)
998       {
999          log_error(LOG_LEVEL_ERROR, "Unable to get my own hostname: %E\n");
1000       }
1001       else
1002       {
1003          *hostname = strdup(host->h_name);
1004       }
1005 #endif /* else def HAVE_RFC2553 */
1006    }
1007
1008    return;
1009 }
1010
1011
1012 /*********************************************************************
1013  *
1014  * Function    :  accept_connection
1015  *
1016  * Description :  Accepts a connection on a socket.  Socket must have
1017  *                been created using bind_port().
1018  *
1019  * Parameters  :
1020  *          1  :  csp = Client state, cfd, ip_addr_str, and 
1021  *                ip_addr_long will be set by this routine.
1022  *          2  :  fd  = file descriptor returned from bind_port
1023  *
1024  * Returns     :  when a connection is accepted, it returns 1 (TRUE).
1025  *                On an error it returns 0 (FALSE).
1026  *
1027  *********************************************************************/
1028 int accept_connection(struct client_state * csp, jb_socket fd)
1029 {
1030 #ifdef HAVE_RFC2553
1031    /* XXX: client is stored directly into csp->tcp_addr */
1032 #define client (csp->tcp_addr)
1033    int retval;
1034 #else
1035    struct sockaddr_in client;
1036 #endif
1037    jb_socket afd;
1038 #if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA)
1039    /* Wierdness - fix a warning. */
1040    int c_length;
1041 #else
1042    socklen_t c_length;
1043 #endif
1044
1045    c_length = sizeof(client);
1046
1047 #ifdef _WIN32
1048    afd = accept (fd, (struct sockaddr *) &client, &c_length);
1049    if (afd == JB_INVALID_SOCKET)
1050    {
1051       return 0;
1052    }
1053 #else
1054    do
1055    {
1056 #if defined(FEATURE_ACCEPT_FILTER) && defined(SO_ACCEPTFILTER)
1057       struct accept_filter_arg af_options;
1058       bzero(&af_options, sizeof(af_options));
1059       strlcpy(af_options.af_name, "httpready", sizeof(af_options.af_name));
1060       setsockopt(fd, SOL_SOCKET, SO_ACCEPTFILTER, &af_options, sizeof(af_options));
1061 #endif
1062       afd = accept (fd, (struct sockaddr *) &client, &c_length);
1063    } while (afd < 1 && errno == EINTR);
1064    if (afd < 0)
1065    {
1066       return 0;
1067    }
1068 #endif
1069
1070    csp->cfd = afd;
1071 #ifdef HAVE_RFC2553
1072    csp->ip_addr_str = malloc(NI_MAXHOST);
1073    if (NULL == csp->ip_addr_str)
1074    {
1075       log_error(LOG_LEVEL_ERROR,
1076          "Out of memory while getting the client's IP address.");
1077       return 0;
1078    }
1079    retval = getnameinfo((struct sockaddr *) &client, c_length,
1080          csp->ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1081    if (!csp->ip_addr_str || retval)
1082    {
1083       log_error(LOG_LEVEL_ERROR, "Can not save csp->ip_addr_str: %s",
1084             (csp->ip_addr_str) ? gai_strerror(retval) : "Insuffcient memory");
1085       freez(csp->ip_addr_str);
1086    }
1087 #undef client
1088 #else
1089    csp->ip_addr_str  = strdup(inet_ntoa(client.sin_addr));
1090    csp->ip_addr_long = ntohl(client.sin_addr.s_addr);
1091 #endif /* def HAVE_RFC2553 */
1092
1093    return 1;
1094
1095 }
1096
1097
1098 /*********************************************************************
1099  *
1100  * Function    :  resolve_hostname_to_ip
1101  *
1102  * Description :  Resolve a hostname to an internet tcp/ip address.
1103  *                NULL or an empty string resolve to INADDR_ANY.
1104  *
1105  * Parameters  :
1106  *          1  :  host = hostname to resolve
1107  *
1108  * Returns     :  INADDR_NONE => failure, INADDR_ANY or tcp/ip address if succesful.
1109  *
1110  *********************************************************************/
1111 unsigned long resolve_hostname_to_ip(const char *host)
1112 {
1113    struct sockaddr_in inaddr;
1114    struct hostent *hostp;
1115 #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS) || defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
1116    struct hostent result;
1117 #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
1118    char hbuf[HOSTENT_BUFFER_SIZE];
1119    int thd_err;
1120 #else /* defined(HAVE_GETHOSTBYNAME_R_3_ARGS) */
1121    struct hostent_data hdata;
1122 #endif /* def HAVE_GETHOSTBYNAME_R_(6|5)_ARGS */
1123 #endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
1124
1125    if ((host == NULL) || (*host == '\0'))
1126    {
1127       return(INADDR_ANY);
1128    }
1129
1130    memset((char *) &inaddr, 0, sizeof inaddr);
1131
1132    if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1)
1133    {
1134       unsigned int dns_retries = 0;
1135 #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS)
1136       while (gethostbyname_r(host, &result, hbuf,
1137                 HOSTENT_BUFFER_SIZE, &hostp, &thd_err)
1138              && (thd_err == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
1139       {   
1140          log_error(LOG_LEVEL_ERROR,
1141             "Timeout #%u while trying to resolve %s. Trying again.",
1142             dns_retries, host);
1143       }
1144 #elif defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
1145       while (NULL == (hostp = gethostbyname_r(host, &result,
1146                                  hbuf, HOSTENT_BUFFER_SIZE, &thd_err))
1147              && (thd_err == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
1148       {   
1149          log_error(LOG_LEVEL_ERROR,
1150             "Timeout #%u while trying to resolve %s. Trying again.",
1151             dns_retries, host);
1152       }
1153 #elif defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
1154       /*
1155        * XXX: Doesn't retry in case of soft errors.
1156        * Does this gethostbyname_r version set h_errno?
1157        */
1158       if (0 == gethostbyname_r(host, &result, &hdata))
1159       {
1160          hostp = &result;
1161       }
1162       else
1163       {
1164          hostp = NULL;
1165       }
1166 #elif defined(MUTEX_LOCKS_AVAILABLE)
1167       privoxy_mutex_lock(&resolver_mutex);
1168       while (NULL == (hostp = gethostbyname(host))
1169              && (h_errno == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
1170       {   
1171          log_error(LOG_LEVEL_ERROR,
1172             "Timeout #%u while trying to resolve %s. Trying again.",
1173             dns_retries, host);
1174       }
1175       privoxy_mutex_unlock(&resolver_mutex);
1176 #else
1177       while (NULL == (hostp = gethostbyname(host))
1178              && (h_errno == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
1179       {
1180          log_error(LOG_LEVEL_ERROR,
1181             "Timeout #%u while trying to resolve %s. Trying again.",
1182             dns_retries, host);
1183       }
1184 #endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
1185       /*
1186        * On Mac OSX, if a domain exists but doesn't have a type A
1187        * record associated with it, the h_addr member of the struct
1188        * hostent returned by gethostbyname is NULL, even if h_length
1189        * is 4. Therefore the second test below.
1190        */
1191       if (hostp == NULL || hostp->h_addr == NULL)
1192       {
1193          errno = EINVAL;
1194          log_error(LOG_LEVEL_ERROR, "could not resolve hostname %s", host);
1195          return(INADDR_NONE);
1196       }
1197       if (hostp->h_addrtype != AF_INET)
1198       {
1199 #ifdef _WIN32
1200          errno = WSAEPROTOTYPE;
1201 #else
1202          errno = EPROTOTYPE;
1203 #endif 
1204          log_error(LOG_LEVEL_ERROR, "hostname %s resolves to unknown address type.", host);
1205          return(INADDR_NONE);
1206       }
1207       memcpy(
1208          (char *) &inaddr.sin_addr,
1209          (char *) hostp->h_addr,
1210          sizeof(inaddr.sin_addr)
1211       );
1212    }
1213    return(inaddr.sin_addr.s_addr);
1214
1215 }
1216
1217
1218 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
1219 /*********************************************************************
1220  *
1221  * Function    :  socket_is_still_alive
1222  *
1223  * Description :  Figures out whether or not a socket is still alive.
1224  *
1225  * Parameters  :
1226  *          1  :  sfd = The socket to check.
1227  *
1228  * Returns     :  TRUE for yes, otherwise FALSE.
1229  *
1230  *********************************************************************/
1231 int socket_is_still_alive(jb_socket sfd)
1232 {
1233    char buf[10];
1234    int no_data_waiting;
1235
1236 #ifdef HAVE_POLL
1237    int poll_result;
1238    struct pollfd poll_fd[1];
1239
1240    memset(poll_fd, 0, sizeof(poll_fd));
1241    poll_fd[0].fd = sfd;
1242    poll_fd[0].events = POLLIN;
1243
1244    poll_result = poll(poll_fd, 1, 0);
1245
1246    if (-1 == poll_result)
1247    {
1248       log_error(LOG_LEVEL_CONNECT, "Polling socket %d failed.", sfd);
1249       return FALSE;
1250    }
1251    no_data_waiting = !(poll_fd[0].revents & POLLIN);
1252 #else
1253    fd_set readable_fds;
1254    struct timeval timeout;
1255    int ret;
1256
1257    memset(&timeout, '\0', sizeof(timeout));
1258    FD_ZERO(&readable_fds);
1259    FD_SET(sfd, &readable_fds);
1260
1261    ret = select((int)sfd+1, &readable_fds, NULL, NULL, &timeout);
1262    if (ret < 0)
1263    {
1264       log_error(LOG_LEVEL_CONNECT, "select() on socket %d failed: %E", sfd);
1265       return FALSE;
1266    }
1267    no_data_waiting = !FD_ISSET(sfd, &readable_fds);
1268 #endif /* def HAVE_POLL */
1269
1270    return (no_data_waiting || (1 == recv(sfd, buf, 1, MSG_PEEK)));
1271 }
1272 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
1273
1274
1275 /*
1276   Local Variables:
1277   tab-width: 3
1278   end:
1279 */