Fix a denial of service attack against mod_reqtimeout.
[Stefan Fritsch]
+ *) mod_proxy: Release the backend connection as soon as EOS is detected,
+ so the backend isn't forced to wait for the client to eventually
+ acknowledge the data. [Graham Leggett]
+
*) mod_proxy: Optimise ProxyPass within a Location so that it is stored
per-directory, and chosen during the location walk. Make ProxyPass
work correctly from within a LocationMatch. [Graham Leggett]
#if APR_HAS_THREADS
char inreslist; /* connection in apr_reslist? */
#endif
+ int cleaned:1; /* connection cleaned? */
} proxy_conn_rec;
typedef struct {
/* found the last brigade? */
if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
+
/* signal that we must leave */
finish = TRUE;
+
+ /* make sure we release the backend connection as soon
+ * as we know we are done, so that the backend isn't
+ * left waiting for a slow client to eventually
+ * acknowledge the data.
+ */
+ ap_proxy_release_connection(backend->worker->scheme,
+ backend, r->server);
+
}
/* try send what we read */
ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, r->server,
"proxy: header only");
+ /* make sure we release the backend connection as soon
+ * as we know we are done, so that the backend isn't
+ * left waiting for a slow client to eventually
+ * acknowledge the data.
+ */
+ ap_proxy_release_connection(backend->worker->scheme,
+ backend, r->server);
+
/* Pass EOS bucket down the filter chain. */
e = apr_bucket_eos_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
proxy_conn_rec *conn,
server_rec *s)
{
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "proxy: %s: has released connection for (%s)",
- proxy_function, conn->worker->hostname);
- connection_cleanup(conn);
+ if (!conn->cleaned) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "proxy: %s: has released connection for (%s)",
+ proxy_function, conn->worker->hostname);
+ connection_cleanup(conn);
+ conn->cleaned = 1;
+ }
return OK;
}