X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jbsockets.c;h=a146c3c282fdabbecfbb7a4ed353a525f606a3fa;hp=b234b2059a13e1f2c1f2e699d240325e26f27de4;hb=bf3fead75da42fbe7ace1756596e5f9b740eb955;hpb=05dd2cc7b727e9600f3808d9156d94d1a3396155 diff --git a/jbsockets.c b/jbsockets.c index b234b205..a146c3c2 100644 --- a/jbsockets.c +++ b/jbsockets.c @@ -1,4 +1,4 @@ -const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.72 2010/02/15 15:14:10 fabiankeil Exp $"; +const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.85 2011/03/27 13:54:52 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jbsockets.c,v $ @@ -8,7 +8,7 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.72 2010/02/15 15:14:10 fabian * OS-independent. Contains #ifdefs to make this work * on many platforms. * - * Copyright : Written by and Copyright (C) 2001-2009 the + * Copyright : Written by and Copyright (C) 2001-2010 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -118,6 +118,11 @@ const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION; #define MAX_LISTEN_BACKLOG 128 +#ifdef HAVE_RFC2553 +static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client_state *csp); +#else +static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct client_state *csp); +#endif /********************************************************************* * @@ -130,15 +135,40 @@ const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION; * 1 : host = hostname to connect to * 2 : portnum = port to connent on (XXX: should be unsigned) * 3 : csp = Current client state (buffers, headers, etc...) - * Not modified, only used for source IP and ACL. * * Returns : JB_INVALID_SOCKET => failure, else it is the socket * file descriptor. * *********************************************************************/ +jb_socket connect_to(const char *host, int portnum, struct client_state *csp) +{ + jb_socket fd; + int forwarded_connect_retries = 0; + + do + { +#ifdef HAVE_RFC2553 + fd = rfc2553_connect_to(host, portnum, csp); +#else + fd = no_rfc2553_connect_to(host, portnum, csp); +#endif + if ((fd != JB_INVALID_SOCKET) || (errno != EINVAL)) + { + break; + } + forwarded_connect_retries++; + log_error(LOG_LEVEL_ERROR, + "Attempt %d of %d to connect to %s failed. Trying again.", + forwarded_connect_retries, csp->config->forwarded_connect_retries, host); + + } while (forwarded_connect_retries < csp->config->forwarded_connect_retries); + + return fd; +} + #ifdef HAVE_RFC2553 /* Getaddrinfo implementation */ -jb_socket connect_to(const char *host, int portnum, struct client_state *csp) +static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client_state *csp) { struct addrinfo hints, *result, *rp; char service[6]; @@ -146,9 +176,9 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp) jb_socket fd; fd_set wfds; struct timeval tv[1]; -#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) +#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) int flags; -#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */ +#endif int connect_failed; #ifdef FEATURE_ACL @@ -182,6 +212,14 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp) return(JB_INVALID_SOCKET); } + csp->http->host_ip_addr_str = malloc(NI_MAXHOST); + if (NULL == csp->http->host_ip_addr_str) + { + log_error(LOG_LEVEL_ERROR, + "Out of memory while getting the server IP address."); + return JB_INVALID_SOCKET; + } + for (rp = result; rp != NULL; rp = rp->ai_next) { @@ -199,22 +237,13 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp) } #endif /* def FEATURE_ACL */ - csp->http->host_ip_addr_str = malloc(NI_MAXHOST); - if (NULL == csp->http->host_ip_addr_str) - { - log_error(LOG_LEVEL_ERROR, - "Out of memory while getting the server IP address."); - return JB_INVALID_SOCKET; - } retval = getnameinfo(rp->ai_addr, rp->ai_addrlen, csp->http->host_ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); - if (!csp->http->host_ip_addr_str || retval) + if (retval) { log_error(LOG_LEVEL_ERROR, "Can not save csp->http->host_ip_addr_str: %s", - (csp->http->host_ip_addr_str) ? - gai_strerror(retval) : "Insufficient memory"); - freez(csp->http->host_ip_addr_str); + gai_strerror(retval)); continue; } @@ -292,21 +321,16 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp) if ((select((int)fd + 1, NULL, &wfds, NULL, tv) > 0) && FD_ISSET(fd, &wfds)) { - /* - * See Linux connect(2) man page for more info - * about connecting on non-blocking socket. - */ - int socket_in_error; - socklen_t optlen = sizeof(socket_in_error); - if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, &socket_in_error, &optlen)) + socklen_t optlen = sizeof(socket_error); + if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, &socket_error, &optlen)) { - if (!socket_in_error) + if (!socket_error) { /* Connection established, no need to try other addresses. */ break; } log_error(LOG_LEVEL_CONNECT, "Could not connect to [%s]:%s: %s.", - csp->http->host_ip_addr_str, service, strerror(socket_in_error)); + csp->http->host_ip_addr_str, service, strerror(socket_error)); } else { @@ -337,16 +361,16 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp) #else /* ndef HAVE_RFC2553 */ /* Pre-getaddrinfo implementation */ -jb_socket connect_to(const char *host, int portnum, struct client_state *csp) +static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct client_state *csp) { struct sockaddr_in inaddr; jb_socket fd; unsigned int addr; fd_set wfds; struct timeval tv[1]; -#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) +#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) int flags; -#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */ +#endif #ifdef FEATURE_ACL struct access_control_addr dst[1]; @@ -498,7 +522,7 @@ int write_socket(jb_socket fd, const char *buf, size_t len) return 1; } - log_error(LOG_LEVEL_LOG, "%N", len, buf); + log_error(LOG_LEVEL_WRITING, "to socket %d: %N", fd, len, buf); #if defined(_WIN32) return (send(fd, buf, (int)len, 0) != (int)len); @@ -511,7 +535,7 @@ int write_socket(jb_socket fd, const char *buf, size_t len) */ #define SOCKET_SEND_MAX 65000 { - int write_len = 0, send_len, send_rc = 0, i = 0; + int send_len, send_rc = 0, i = 0; while ((i < len) && (send_rc != -1)) { if ((i + SOCKET_SEND_MAX) > len) @@ -559,18 +583,27 @@ int write_socket(jb_socket fd, const char *buf, size_t len) *********************************************************************/ int read_socket(jb_socket fd, char *buf, int len) { + int ret; + if (len <= 0) { return(0); } #if defined(_WIN32) - return(recv(fd, buf, len, 0)); + ret = recv(fd, buf, len, 0); #elif defined(__BEOS__) || defined(AMIGA) || defined(__OS2__) - return(recv(fd, buf, (size_t)len, 0)); + ret = recv(fd, buf, (size_t)len, 0); #else - return((int)read(fd, buf, (size_t)len)); + ret = (int)read(fd, buf, (size_t)len); #endif + + if (ret > 0) + { + log_error(LOG_LEVEL_RECEIVED, "from socket %d: %N", fd, ret, buf); + } + + return ret; } @@ -1103,7 +1136,6 @@ unsigned long resolve_hostname_to_ip(const char *host) { struct sockaddr_in inaddr; struct hostent *hostp; - unsigned int dns_retries = 0; #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS) || defined(HAVE_GETHOSTBYNAME_R_3_ARGS) struct hostent result; #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS) @@ -1123,6 +1155,7 @@ unsigned long resolve_hostname_to_ip(const char *host) if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1) { + unsigned int dns_retries = 0; #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) while (gethostbyname_r(host, &result, hbuf, HOSTENT_BUFFER_SIZE, &hostp, &thd_err)