X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jbsockets.c;h=556c927b1a5c1bf89370c04b7c0d5979ba2525d1;hp=3c43c1777773965b66e29be44e95f2f5cc43f065;hb=7649305de5e3751c37b0f09a17801dbb29737d45;hpb=c374b4059fb38a0555f9eb7f6b15a42fc7045df1 diff --git a/jbsockets.c b/jbsockets.c index 3c43c177..556c927b 100644 --- a/jbsockets.c +++ b/jbsockets.c @@ -1,4 +1,3 @@ -const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.143 2017/06/04 14:37:05 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jbsockets.c,v $ @@ -9,7 +8,7 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.143 2017/06/04 14:37:05 fabia * on many platforms. * * Copyright : Written by and Copyright (C) 2001-2017 the - * Privoxy team. http://www.privoxy.org/ + * Privoxy team. https://www.privoxy.org/ * * Based on the Internet Junkbuster originally written * by and Copyright (C) 1997 Anonymous Coders and @@ -107,8 +106,6 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.143 2017/06/04 14:37:05 fabia #define AI_NUMERICSERV 0 #endif -const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION; - /* * Maximum number of gethostbyname(_r) retries in case of * soft errors (TRY_AGAIN). @@ -116,8 +113,6 @@ const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION; */ #define MAX_DNS_RETRIES 10 -#define MAX_LISTEN_BACKLOG 128 - #ifdef HAVE_RFC2553 static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client_state *csp); #else @@ -128,7 +123,8 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli * * Function : set_no_delay_flag * - * Description : Disables TCP coalescence for the given socket. + * Description : Disables the Nagle algorithm (TCP send coalescence) + * for the given socket. * * Parameters : * 1 : fd = The file descriptor to operate on @@ -217,12 +213,12 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client fd_set wfds; struct timeval timeout; #endif -#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) +#if !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) int flags; #endif int connect_failed; /* - * XXX: Initializeing it here is only necessary + * XXX: Initializing it here is only necessary * because not all situations are properly * covered yet. */ @@ -324,13 +320,13 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client set_no_delay_flag(fd); -#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) +#if !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) if ((flags = fcntl(fd, F_GETFL, 0)) != -1) { flags |= O_NDELAY; fcntl(fd, F_SETFL, flags); } -#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */ +#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) */ connect_failed = 0; while (connect(fd, rp->ai_addr, rp->ai_addrlen) == JB_INVALID_SOCKET) @@ -361,19 +357,38 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client continue; } -#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) +#if !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) if (flags != -1) { flags &= ~O_NDELAY; fcntl(fd, F_SETFL, flags); } -#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */ +#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) */ #ifdef HAVE_POLL poll_fd[0].fd = fd; poll_fd[0].events = POLLOUT; - if (poll(poll_fd, 1, 30000) > 0) + retval = poll(poll_fd, 1, 30000); + if (retval == 0) + { + if (rp->ai_next != NULL) + { + /* Log this now as we'll try another address next */ + log_error(LOG_LEVEL_CONNECT, + "Could not connect to [%s]:%s: Operation timed out.", + csp->http->host_ip_addr_str, service); + } + else + { + /* + * This is the last address, don't log this now + * as it would result in a duplicated log message. + */ + socket_error = ETIMEDOUT; + } + } + else if (retval > 0) #else /* wait for connection to complete */ FD_ZERO(&wfds); @@ -449,7 +464,7 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli fd_set wfds; struct timeval tv[1]; #endif -#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) +#if !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) int flags; #endif @@ -525,7 +540,7 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli set_no_delay_flag(fd); -#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) +#if !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) if ((flags = fcntl(fd, F_GETFL, 0)) != -1) { flags |= O_NDELAY; @@ -534,7 +549,7 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli mark_socket_for_close_on_execute(fd); #endif } -#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */ +#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) */ while (connect(fd, (struct sockaddr *) & inaddr, sizeof inaddr) == JB_INVALID_SOCKET) { @@ -560,13 +575,13 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli } } -#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) +#if !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) if (flags != -1) { flags &= ~O_NDELAY; fcntl(fd, F_SETFL, flags); } -#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */ +#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) */ #ifdef HAVE_POLL poll_fd[0].fd = fd; @@ -609,11 +624,7 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli * nonzero on error. * *********************************************************************/ -#ifdef AMIGA -int write_socket(jb_socket fd, const char *buf, ssize_t len) -#else int write_socket(jb_socket fd, const char *buf, size_t len) -#endif { if (len == 0) { @@ -632,7 +643,7 @@ int write_socket(jb_socket fd, const char *buf, size_t len) #if defined(_WIN32) return (send(fd, buf, (int)len, 0) != (int)len); -#elif defined(__BEOS__) || defined(AMIGA) +#elif defined(__BEOS__) return (send(fd, buf, len, 0) != len); #elif defined(__OS2__) /* @@ -662,6 +673,60 @@ int write_socket(jb_socket fd, const char *buf, size_t len) } +/********************************************************************* + * + * Function : write_socket_delayed + * + * Description : Write the contents of buf (for n bytes) to + * socket fd, optionally delaying the operation. + * + * Parameters : + * 1 : fd = File descriptor (aka. handle) of socket to write to. + * 2 : buf = Pointer to data to be written. + * 3 : len = Length of data to be written to the socket "fd". + * 4 : delay = Delay in milliseconds. + * + * Returns : 0 on success (entire buffer sent). + * nonzero on error. + * + *********************************************************************/ +int write_socket_delayed(jb_socket fd, const char *buf, size_t len, unsigned int delay) +{ + size_t i = 0; + + if (delay == 0) + { + return write_socket(fd, buf, len); + } + + while (i < len) + { + size_t write_length; + enum {MAX_WRITE_LENGTH = 10}; + + if ((i + MAX_WRITE_LENGTH) > len) + { + write_length = len - i; + } + else + { + write_length = MAX_WRITE_LENGTH; + } + + privoxy_millisleep(delay); + + if (write_socket(fd, buf + i, write_length) != 0) + { + return 1; + } + i += write_length; + } + + return 0; + +} + + /********************************************************************* * * Function : read_socket @@ -698,7 +763,7 @@ int read_socket(jb_socket fd, char *buf, int len) #if defined(_WIN32) ret = recv(fd, buf, len, 0); -#elif defined(__BEOS__) || defined(AMIGA) || defined(__OS2__) +#elif defined(__BEOS__) || defined(__OS2__) ret = recv(fd, buf, (size_t)len, 0); #else ret = (int)read(fd, buf, (size_t)len); @@ -779,8 +844,6 @@ void close_socket(jb_socket fd) { #if defined(_WIN32) || defined(__BEOS__) closesocket(fd); -#elif defined(AMIGA) - CloseSocket(fd); #elif defined(__OS2__) soclose(fd); #else @@ -871,14 +934,15 @@ void drain_and_close_socket(jb_socket fd) * Parameters : * 1 : hostnam = TCP/IP address to bind/listen to * 2 : portnum = port to listen on - * 3 : pfd = pointer used to return file descriptor. + * 3 : backlog = Listen backlog + * 4 : pfd = pointer used to return file descriptor. * * Returns : if success, returns 0 and sets *pfd. * if failure, returns -3 if address is in use, * -2 if address unresolvable, * -1 otherwise *********************************************************************/ -int bind_port(const char *hostnam, int portnum, jb_socket *pfd) +int bind_port(const char *hostnam, int portnum, int backlog, jb_socket *pfd) { #ifdef HAVE_RFC2553 struct addrinfo hints; @@ -1004,6 +1068,10 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); #endif /* ndef _WIN32 */ +#ifdef IP_FREEBIND + setsockopt(fd, IPPROTO_IP, IP_FREEBIND, (char *)&one, sizeof(one)); +#endif + #ifdef HAVE_RFC2553 if (bind(fd, rp->ai_addr, rp->ai_addrlen) < 0) #else @@ -1053,7 +1121,7 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) } #endif /* ndef HAVE_RFC2553 */ - while (listen(fd, MAX_LISTEN_BACKLOG) == -1) + while (listen(fd, backlog) == -1) { if (errno != EINTR) { @@ -1102,7 +1170,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **port, struct sockaddr_in server; struct hostent *host = NULL; #endif /* HAVE_RFC2553 */ -#if defined(_WIN32) || defined(__OS2__) || defined(AMIGA) +#if defined(_WIN32) || defined(__OS2__) /* according to accept_connection() this fixes a warning. */ int s_length, s_length_provided; #else @@ -1254,8 +1322,8 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) struct sockaddr_in client; #endif jb_socket afd; -#if defined(_WIN32) || defined(__OS2__) || defined(AMIGA) - /* Wierdness - fix a warning. */ +#if defined(_WIN32) || defined(__OS2__) + /* Weirdness - fix a warning. */ int c_length; #else socklen_t c_length; @@ -1358,12 +1426,6 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) #else do { -#if defined(FEATURE_ACCEPT_FILTER) && defined(SO_ACCEPTFILTER) - struct accept_filter_arg af_options; - bzero(&af_options, sizeof(af_options)); - strlcpy(af_options.af_name, "httpready", sizeof(af_options.af_name)); - setsockopt(fd, SOL_SOCKET, SO_ACCEPTFILTER, &af_options, sizeof(af_options)); -#endif afd = accept (fd, (struct sockaddr *) &client, &c_length); } while (afd < 0 && errno == EINTR); if (afd < 0)