]> granicus.if.org Git - apache/commitdiff
for proxy CONNECT handling:
authorJeff Trawick <trawick@apache.org>
Fri, 4 Jan 2002 18:32:48 +0000 (18:32 +0000)
committerJeff Trawick <trawick@apache.org>
Fri, 4 Jan 2002 18:32:48 +0000 (18:32 +0000)
  don't hard-code the address family of the target; respect
  what the resolver told us

  get a new socket each time we try to connect to one of the
  target addresses as reported by the resolver; you can't
  portably attempt to connect more than once on the same
  socket

this is the same fix committed to proxy http support yesterday

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

CHANGES
modules/proxy/proxy_connect.c

diff --git a/CHANGES b/CHANGES
index 7d710a0eefeaad2454e0a11b5035890e7bc995b3..d08149f02a299dbb8cc648e28b553302fc93726b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,9 @@
 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 
+  *) Fix a couple of mod_proxy problems forwarding HTTP connections
+     and handling CONNECT:
+     (1) PR #9190  Proxy failed to connect to IPv6 hosts.
+     (2) Proxy failed to connect when the first IP address returned by 
          the resolver was unreachable but a secondary IP address was.  
      [Jeff Trawick]
 
index 2b4df9f968ee75fa0ffa8b732d717bbc590b25f8..a317fed4c7a1e05aa8050a5a852c4440d3d6e2e0 100644 (file)
@@ -216,16 +216,6 @@ int ap_proxy_connect_handler(request_rec *r, proxy_server_conf *conf,
                              connectname, NULL));
     }
 
-    /* create a new socket */
-    if ((rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) {
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
-            "proxy: error creating socket");
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    /* Set a timeout on the socket */
-    apr_setsocketopt(sock, APR_SO_TIMEOUT, (int)(r->server->timeout * APR_USEC_PER_SEC));
-
        /*
         * At this point we have a list of one or more IP addresses of
         * the machine to connect to. If configured, reorder this
@@ -235,19 +225,36 @@ int ap_proxy_connect_handler(request_rec *r, proxy_server_conf *conf,
          *
          * 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 */
     {
        int failed = 1;
        while (connect_addr) {
 
+            /* create a new socket */
+            if ((rv = apr_socket_create(&sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) {
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                              "proxy: error creating socket");
+                return HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            /* Set a timeout on the socket */
+            apr_setsocketopt(sock, APR_SO_TIMEOUT, (int)(r->server->timeout * APR_USEC_PER_SEC));
+
            /* make the connection out of the socket */
            rv = apr_connect(sock, connect_addr);
 
            /* if an error occurred, loop round and try again */
             if (rv != APR_SUCCESS) {
+                apr_socket_close(sock);
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                             "proxy: CONNECT: attempt to connect to %pI (%s) failed", connect_addr, connectname);
                connect_addr = connect_addr->next;
@@ -261,7 +268,6 @@ int ap_proxy_connect_handler(request_rec *r, proxy_server_conf *conf,
 
        /* handle a permanent error from the above loop */
        if (failed) {
-           apr_socket_close(sock);
            if (proxyname) {
                return DECLINED;
            }