Turn server_proxy_connection_adder() into a nop if the client didn't request keep...
[privoxy.git] / jbsockets.c
index d6e55d4..1133708 100644 (file)
@@ -1,4 +1,4 @@
-const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.55 2009/05/10 10:12:30 fabiankeil Exp $";
+const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.59 2009/05/25 15:43:34 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jbsockets.c,v $
@@ -95,10 +95,8 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.55 2009/05/10 10:12:30 fabian
 
 #include "project.h"
 
-#ifdef FEATURE_PTHREAD
+/* For mutex semaphores only */
 #include "jcc.h"
-/* jcc.h is for mutex semaphores only */
-#endif /* def FEATURE_PTHREAD */
 
 #include "jbsockets.h"
 #include "filters.h"
@@ -276,31 +274,46 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
       tv->tv_usec = 0;
 
       /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Wierd! */
-      if (select((int)fd + 1, NULL, &wfds, NULL, tv) <= 0)
+      if ((select((int)fd + 1, NULL, &wfds, NULL, tv) > 0)
+         && FD_ISSET(fd, &wfds))
       {
-         close_socket(fd);
-         continue;
+         /*
+          * 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))
+         {
+            if (!socket_in_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));
+         }
+         else
+         {
+            log_error(LOG_LEVEL_ERROR, "Could not get the state of "
+               "the connection to [%s]:%s: %s; dropping connection.",
+               csp->http->host_ip_addr_str, service, strerror(errno));
+         }
       }
 
-      break; /* for; Connection established; don't try other addresses */
+      /* Connection failed, try next address */
+      close_socket(fd);
    }
 
    freeaddrinfo(result);
    if (!rp)
    {
-      log_error(LOG_LEVEL_INFO,
-         "Could not connect to TCP/[%s]:%s", host, service);
+      log_error(LOG_LEVEL_CONNECT, "Could not connect to [%s]:%s.",
+         host, service);
       return(JB_INVALID_SOCKET);
    }
-   /*
-    * XXX: Current connection verification (EINPROGRESS && select()
-    * for writing) is not sufficient. E.g. on Linux-2.6.27 with glibc-2.6
-    * select returns socket ready for writing, however subsequential
-    * write(2) fails with ENOCONNECT. Read Linux connect(2) man page
-    * about non-blocking sockets.
-    * Thus we can't log here that the socket is connected.
-    */
-   /* log_error(LOG_LEVEL_INFO, "Connected to TCP/[%s]:%s", host, service); */
+   log_error(LOG_LEVEL_CONNECT, "Connected to %s[%s]:%s.",
+      host, csp->http->host_ip_addr_str, service);
 
    return(fd);
 
@@ -932,7 +945,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **hostname)
       {
          host = NULL;
       }
-#elif FEATURE_PTHREAD
+#elif def MUTEX_LOCKS_AVAILABLE
       privoxy_mutex_lock(&resolver_mutex);
       host = gethostbyaddr((const char *)&server.sin_addr, 
                            sizeof(server.sin_addr), AF_INET);
@@ -1098,7 +1111,7 @@ unsigned long resolve_hostname_to_ip(const char *host)
       {
          hostp = NULL;
       }
-#elif FEATURE_PTHREAD
+#elif def MUTEX_LOCKS_AVAILABLE
       privoxy_mutex_lock(&resolver_mutex);
       while (NULL == (hostp = gethostbyname(host))
              && (h_errno == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))