1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

* Do not reset the retry timeout if the worker is in error at this stage even

if the connection to the backend was successful. It was likely set into
   error by a different thread / process in parallel e.g. for a timeout or
   bad status. We should respect this and should not continue with a connection
   via this worker even if we got one.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1664709 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Ruediger Pluem
2015-03-06 19:31:42 +00:00
parent 551fe1294d
commit 6864b2c781
2 changed files with 41 additions and 23 deletions

View File

@@ -1,6 +1,9 @@
-*- coding: utf-8 -*- -*- coding: utf-8 -*-
Changes with Apache 2.5.0 Changes with Apache 2.5.0
*) mod_proxy: Fix a race condition that caused a failed worker to be retried
before the retry period is over. [Ruediger Pluem]
*) SECURITY: CVE-2015-0253 (cve.mitre.org) *) SECURITY: CVE-2015-0253 (cve.mitre.org)
core: Fix a crash introduced in with ErrorDocument 400 pointing core: Fix a crash introduced in with ErrorDocument 400 pointing
to a local URL-path with the INCLUDES filter active, introduced to a local URL-path with the INCLUDES filter active, introduced

View File

@@ -2887,33 +2887,48 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
connected = 1; connected = 1;
} }
/* if (PROXY_WORKER_IS_USABLE(worker)) {
* Put the entire worker to error state if /*
* the PROXY_WORKER_IGNORE_ERRORS flag is not set. * Put the entire worker to error state if
* Altrough some connections may be alive * the PROXY_WORKER_IGNORE_ERRORS flag is not set.
* no further connections to the worker could be made * Although some connections may be alive
*/ * no further connections to the worker could be made
if (!connected && PROXY_WORKER_IS_USABLE(worker) && */
!(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) { if (!connected) {
worker->s->error_time = apr_time_now(); if (!(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
worker->s->status |= PROXY_WORKER_IN_ERROR; worker->s->error_time = apr_time_now();
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00959) worker->s->status |= PROXY_WORKER_IN_ERROR;
"ap_proxy_connect_backend disabling worker for (%s) for %" ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00959)
APR_TIME_T_FMT "s", "ap_proxy_connect_backend disabling worker for (%s) for %"
worker->s->hostname, apr_time_sec(worker->s->retry)); APR_TIME_T_FMT "s",
worker->s->hostname, apr_time_sec(worker->s->retry));
}
}
else {
if (worker->s->retries) {
/*
* A worker came back. So here is where we need to
* either reset all params to initial conditions or
* apply some sort of aging
*/
}
worker->s->error_time = 0;
worker->s->retries = 0;
}
return connected ? OK : DECLINED;
} }
else { else {
if (worker->s->retries) { /*
/* * The worker is in error likely done by a different thread / process
* A worker came back. So here is where we need to * e.g. for a timeout or bad status. We should respect this and should
* either reset all params to initial conditions or * not continue with a connection via this worker even if we got one.
* apply some sort of aging */
*/ if (connected) {
apr_socket_close(conn->sock );
conn->sock = NULL;
} }
worker->s->error_time = 0; return DECLINED;
worker->s->retries = 0;
} }
return connected ? OK : DECLINED;
} }
static apr_status_t connection_shutdown(void *theconn) static apr_status_t connection_shutdown(void *theconn)