Skip to content

Commit 8826336

Browse files
committed
mod_proxy: Consistently close the socket on failure to reuse the connection.
proxy_connection_create() and ap_proxy_connect_backend() sometimes close the connection on failure, sometimes not. Always close it. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1912460 13f79535-47bb-0310-9956-ffa450edef68
1 parent 33c98b0 commit 8826336

File tree

1 file changed

+36
-33
lines changed

1 file changed

+36
-33
lines changed

modules/proxy/proxy_util.c

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,7 @@ static void socket_cleanup(proxy_conn_rec *conn)
15081508
conn->connection = NULL;
15091509
conn->ssl_hostname = NULL;
15101510
apr_pool_clear(conn->scpool);
1511+
conn->close = 0;
15111512
}
15121513

15131514
static void conn_cleanup(proxy_conn_rec *conn)
@@ -1525,6 +1526,7 @@ static void conn_cleanup(proxy_conn_rec *conn)
15251526

15261527
static apr_status_t conn_pool_cleanup(void *theworker)
15271528
{
1529+
/* Signal that the child is exiting */
15281530
((proxy_worker *)theworker)->cp = NULL;
15291531
return APR_SUCCESS;
15301532
}
@@ -1605,8 +1607,7 @@ PROXY_DECLARE(int) ap_proxy_connection_reusable(proxy_conn_rec *conn)
16051607

16061608
return !(conn->close
16071609
|| conn->forward
1608-
|| worker->s->disablereuse
1609-
|| !worker->s->is_address_reusable);
1610+
|| worker->s->disablereuse);
16101611
}
16111612

16121613
static proxy_conn_rec *connection_make(apr_pool_t *p, proxy_worker *worker)
@@ -1659,18 +1660,17 @@ static void connection_cleanup(void *theconn)
16591660
apr_pool_clear(p);
16601661
conn = connection_make(p, worker);
16611662
}
1662-
else if (conn->close
1663-
|| conn->forward
1663+
else if (!conn->sock
16641664
|| (conn->connection
16651665
&& conn->connection->keepalive == AP_CONN_CLOSE)
1666-
|| worker->s->disablereuse) {
1666+
|| !ap_proxy_connection_reusable(conn)) {
16671667
socket_cleanup(conn);
1668-
conn->close = 0;
16691668
}
16701669
else if (conn->is_ssl) {
1671-
/* Unbind/reset the SSL connection dir config (sslconn->dc) from
1672-
* r->per_dir_config, r will likely get destroyed before this proxy
1673-
* conn is reused.
1670+
/* The current ssl section/dir config of the conn is not necessarily
1671+
* the one it will be reused for, so while the conn is in the reslist
1672+
* reset its ssl config to the worker's, until a new user sets its own
1673+
* ssl config eventually in proxy_connection_create() and so on.
16741674
*/
16751675
ap_proxy_ssl_engine(conn->connection, worker->section_config, 1);
16761676
}
@@ -2822,7 +2822,6 @@ PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
28222822
(int)worker->s->port);
28232823

28242824
(*conn)->worker = worker;
2825-
(*conn)->close = 0;
28262825
(*conn)->inreslist = 0;
28272826

28282827
return OK;
@@ -3267,7 +3266,6 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
32673266
/* Close a possible existing socket if we are told to do so */
32683267
if (conn->close) {
32693268
socket_cleanup(conn);
3270-
conn->close = 0;
32713269
}
32723270

32733271
/*
@@ -4058,13 +4056,13 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
40584056
* e.g. for a timeout or bad status. We should respect this and should
40594057
* not continue with a connection via this worker even if we got one.
40604058
*/
4061-
if (rv == APR_SUCCESS) {
4062-
socket_cleanup(conn);
4063-
}
40644059
rv = APR_EINVAL;
40654060
}
4066-
4067-
return rv == APR_SUCCESS ? OK : DECLINED;
4061+
if (rv != APR_SUCCESS) {
4062+
socket_cleanup(conn);
4063+
return DECLINED;
4064+
}
4065+
return OK;
40684066
}
40694067

40704068
static apr_status_t connection_shutdown(void *theconn)
@@ -4101,9 +4099,9 @@ static int proxy_connection_create(const char *proxy_function,
41014099
ap_conf_vector_t *per_dir_config = (r) ? r->per_dir_config
41024100
: conn->worker->section_config;
41034101
apr_sockaddr_t *backend_addr = conn->addr;
4104-
int rc;
41054102
apr_interval_time_t current_timeout;
41064103
apr_bucket_alloc_t *bucket_alloc;
4104+
int rc = OK;
41074105

41084106
if (conn->connection) {
41094107
if (conn->is_ssl) {
@@ -4115,27 +4113,27 @@ static int proxy_connection_create(const char *proxy_function,
41154113
return OK;
41164114
}
41174115

4118-
bucket_alloc = apr_bucket_alloc_create(conn->scpool);
4119-
conn->tmp_bb = apr_brigade_create(conn->scpool, bucket_alloc);
4120-
/*
4121-
* The socket is now open, create a new backend server connection
4122-
*/
4123-
conn->connection = ap_run_create_connection(conn->scpool, s, conn->sock,
4124-
0, NULL,
4125-
bucket_alloc);
4126-
4116+
if (conn->sock) {
4117+
bucket_alloc = apr_bucket_alloc_create(conn->scpool);
4118+
conn->tmp_bb = apr_brigade_create(conn->scpool, bucket_alloc);
4119+
/*
4120+
* The socket is now open, create a new backend server connection
4121+
*/
4122+
conn->connection = ap_run_create_connection(conn->scpool, s, conn->sock,
4123+
0, NULL, bucket_alloc);
4124+
}
41274125
if (!conn->connection) {
41284126
/*
41294127
* the peer reset the connection already; ap_run_create_connection()
41304128
* closed the socket
41314129
*/
41324130
ap_log_error(APLOG_MARK, APLOG_ERR, 0,
41334131
s, APLOGNO(00960) "%s: an error occurred creating a "
4134-
"new connection to %pI (%s)", proxy_function,
4135-
backend_addr, conn->hostname);
4136-
/* XXX: Will be closed when proxy_conn is closed */
4137-
socket_cleanup(conn);
4138-
return HTTP_INTERNAL_SERVER_ERROR;
4132+
"new connection to %pI (%s)%s",
4133+
proxy_function, backend_addr, conn->hostname,
4134+
conn->sock ? "" : " (not connected)");
4135+
rc = HTTP_INTERNAL_SERVER_ERROR;
4136+
goto cleanup;
41394137
}
41404138

41414139
/* For ssl connection to backend */
@@ -4145,7 +4143,8 @@ static int proxy_connection_create(const char *proxy_function,
41454143
s, APLOGNO(00961) "%s: failed to enable ssl support "
41464144
"for %pI (%s)", proxy_function,
41474145
backend_addr, conn->hostname);
4148-
return HTTP_INTERNAL_SERVER_ERROR;
4146+
rc = HTTP_INTERNAL_SERVER_ERROR;
4147+
goto cleanup;
41494148
}
41504149
if (conn->ssl_hostname) {
41514150
/* Set a note on the connection about what CN is requested,
@@ -4180,7 +4179,7 @@ static int proxy_connection_create(const char *proxy_function,
41804179
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00963)
41814180
"%s: pre_connection setup failed (%d)",
41824181
proxy_function, rc);
4183-
return rc;
4182+
goto cleanup;
41844183
}
41854184
apr_socket_timeout_set(conn->sock, current_timeout);
41864185

@@ -4190,6 +4189,10 @@ static int proxy_connection_create(const char *proxy_function,
41904189
apr_pool_pre_cleanup_register(conn->scpool, conn, connection_shutdown);
41914190

41924191
return OK;
4192+
4193+
cleanup:
4194+
socket_cleanup(conn);
4195+
return rc;
41934196
}
41944197

41954198
PROXY_DECLARE(int) ap_proxy_connection_create_ex(const char *proxy_function,

0 commit comments

Comments
 (0)