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