from the connection pool twice. This causes this connection to be present
in the connection pool twice. Thus it may be used by different threads
at the same time which causes many troubles (segfaults in this case).
Furthermore implement a logic to prevent double releases to the connection
pool if they are triggered by buggy code and log an error message in this
case.
- mod_proxy_http.c: remove double calls to ap_proxy_http_cleanup
- proxy_util.c: Add logic to prevent double releases of a
connection to the connection pool.
PR: 38793
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@394088
13f79535-47bb-0310-9956-
ffa450edef68
Changes with Apache 2.3.0
[Remove entries to the current 2.0 and 2.2 section below, when backported]
+ *) mod_proxy: Do not release connections from connection pool twice.
+ PR 38793. [Ruediger Pluem, matthias <mk-asf gigacodes.de>]
+
*) core: Prevent reading uninitialized memory while reading a line of
protocol input. PR 39282. [Davi Arnaut <davi haxent.com.br>]
* cache_server_conf (minor)
* 20060110.2 (2.3.0-dev) flush_packets and flush_wait members added to
* proxy_server (minor)
+ * 20060110.3 (2.3.0-dev) added inreslist member to proxy_conn_rec (minor)
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20060110
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 3 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
int close_on_recycle; /* Close the connection when returning to pool */
proxy_worker *worker; /* Connection pool this connection belogns to */
void *data; /* per scheme connection data */
+#if APR_HAS_THREADS
+ int inreslist; /* connection in apr_reslist? */
+#endif
} proxy_conn_rec;
typedef struct {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"proxy: error reading status line from remote "
"server %s", backend->hostname);
- ap_proxy_http_cleanup(NULL, r, backend);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
"Error reading from remote server");
}
* if the status line was > 8192 bytes
*/
else if ((buffer[5] != '1') || (len >= sizeof(buffer)-1)) {
- ap_proxy_http_cleanup(NULL, r, backend);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
apr_pstrcat(p, "Corrupt status line returned by remote "
"server: ", buffer, NULL));
if (!worker->cp)
return APR_SUCCESS;
- /* deterimine if the connection need to be closed */
+#if APR_HAS_THREADS
+ /* Sanity check: Did we already return the pooled connection? */
+ if (conn->inreslist) {
+ ap_log_perror(APLOG_MARK, APLOG_ERR, 0, conn->pool,
+ "proxy: Pooled connection 0x%pp for worker %s has been"
+ " already returned to the connection pool.", conn,
+ worker->name);
+ return APR_SUCCESS;
+ }
+#endif
+
+ /* determine if the connection need to be closed */
if (conn->close_on_recycle || conn->close) {
apr_pool_t *p = conn->pool;
apr_pool_clear(conn->pool);
}
#if APR_HAS_THREADS
if (worker->hmax && worker->cp->res) {
+ conn->inreslist = 1;
apr_reslist_release(worker->cp->res, (void *)conn);
}
else
conn->pool = ctx;
conn->worker = worker;
+ conn->inreslist = 1;
*resource = conn;
return APR_SUCCESS;
(*conn)->worker = worker;
(*conn)->close = 0;
(*conn)->close_on_recycle = 0;
+ (*conn)->inreslist = 0;
return OK;
}