From: Jeff Trawick Date: Fri, 4 Jan 2002 18:32:48 +0000 (+0000) Subject: for proxy CONNECT handling: X-Git-Tag: 2.0.30~29 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9757a232c4c72ae61db06ef106642456168cac26;p=apache for proxy CONNECT handling: 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 --- diff --git a/CHANGES b/CHANGES index 7d710a0eef..d08149f02a 100644 --- 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] diff --git a/modules/proxy/proxy_connect.c b/modules/proxy/proxy_connect.c index 2b4df9f968..a317fed4c7 100644 --- a/modules/proxy/proxy_connect.c +++ b/modules/proxy/proxy_connect.c @@ -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; }