]> granicus.if.org Git - apache/commitdiff
Fix a couple of mod_proxy problems forwarding HTTP connections:
authorJeff Trawick <trawick@apache.org>
Fri, 4 Jan 2002 01:47:55 +0000 (01:47 +0000)
committerJeff Trawick <trawick@apache.org>
Fri, 4 Jan 2002 01:47:55 +0000 (01:47 +0000)
(1) PR #9190  It failed to connect to IPv6 hosts.
(2) It failed to connect when the first IP address returned by
    the resolver was unreachable but a secondary IP address was.

PR:    9190 (partly)

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@92727 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/proxy/proxy_http.c

diff --git a/CHANGES b/CHANGES
index 01dfbdd3924e80c51acd75470cc5a131addda65e..7d710a0eefeaad2454e0a11b5035890e7bc995b3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,11 @@
 Changes with Apache 2.0.30-dev
 
+  *) Fix a couple of mod_proxy problems forwarding HTTP connections:
+     (1) PR #9190  It failed to connect to IPv6 hosts.
+     (2) It failed to connect when the first IP address returned by 
+         the resolver was unreachable but a secondary IP address was.  
+     [Jeff Trawick]
+
   *) Fix the module identifer as shown in the docs for various core
      modules (e.g., the identifer for mod_log_config was previously
      listed as config_log_module).  PR #9338
index af5c8ce4b2acc266c54347fd613adac2e1616614..2fe038126b5af0361eb021b6beb4070b891eab18 100644 (file)
@@ -344,31 +344,6 @@ apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r,
         /* create a new socket */
         backend->connection = NULL;
 
-        /* see memory note above */
-        if ((rv = apr_socket_create(&p_conn->sock, APR_INET, SOCK_STREAM,
-                                    c->pool)) != APR_SUCCESS) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
-                         "proxy: error creating socket");
-            return HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-#if !defined(TPF) && !defined(BEOS)
-        if (conf->recv_buffer_size > 0 &&
-            (rv = apr_setsocketopt(p_conn->sock, APR_SO_RCVBUF,
-                                   conf->recv_buffer_size))) {
-            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
-                          "setsockopt(SO_RCVBUF): Failed to set "
-                          "ProxyReceiveBufferSize, using default");
-        }
-#endif
-
-        /* Set a timeout on the socket */
-        apr_setsocketopt(p_conn->sock, APR_SO_TIMEOUT,
-                         (int)(r->server->timeout * APR_USEC_PER_SEC));
-
-        ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
-                     "proxy: socket has been created");
-
         /*
          * At this point we have a list of one or more IP addresses of
          * the machine to connect to. If configured, reorder this
@@ -378,17 +353,50 @@ apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r,
          *
          * For now we do nothing, ie we get DNS round robin.
          * XXX FIXME
+         *
+         * We have to create a new socket each time through the loop because
+         *
+         *   (1) On most stacks, connect() fails with EINVAL or similar if
+         *       we previously failed connect() on the socket in the past
+         *   (2) The address family of the socket needs to match that of the
+         *       address we're trying to connect to.
          */
 
         /* try each IP address until we connect successfully */
         failed = 1;
         while (p_conn->addr) {
 
+            /* see memory note above */
+            if ((rv = apr_socket_create(&p_conn->sock, p_conn->addr->family,
+                                        SOCK_STREAM, c->pool)) != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
+                             "proxy: error creating socket");
+                return HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+#if !defined(TPF) && !defined(BEOS)
+            if (conf->recv_buffer_size > 0 &&
+                (rv = apr_setsocketopt(p_conn->sock, APR_SO_RCVBUF,
+                                       conf->recv_buffer_size))) {
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                              "setsockopt(SO_RCVBUF): Failed to set "
+                              "ProxyReceiveBufferSize, using default");
+            }
+#endif
+
+            /* Set a timeout on the socket */
+            apr_setsocketopt(p_conn->sock, APR_SO_TIMEOUT,
+                             (int)(r->server->timeout * APR_USEC_PER_SEC));
+
+            ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+                         "proxy: socket has been created");
+
             /* make the connection out of the socket */
             rv = apr_connect(p_conn->sock, p_conn->addr);
 
             /* if an error occurred, loop round and try again */
             if (rv != APR_SUCCESS) {
+                apr_socket_close(p_conn->sock);
                 ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                              "proxy: attempt to connect to %pI (%s) failed",
                              p_conn->addr, p_conn->name);
@@ -403,7 +411,6 @@ apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r,
 
         /* handle a permanent error from the above loop */
         if (failed) {
-            apr_socket_close(p_conn->sock);
             if (proxyname) {
                 return DECLINED;
             } else {
@@ -433,7 +440,8 @@ apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r,
         backend->port = p_conn->port;
 
         ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
-                     "proxy: connection complete");
+                     "proxy: connection complete to %pI (%s)",
+                     p_conn->addr, p_conn->name);
 
         /* set up the connection filters */
         ap_proxy_pre_http_connection(*origin);