ASF Bugzilla – Attachment 30889 Details for
Bug 39673
mod_proxy opens connections that disturb NTLM
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
mod_proxy one for one connection
httpd-2.4.x_mod_proxy_1for1_connection.patch (text/plain), 9.51 KB, created by
Yann Ylavic
on 2013-09-27 14:19:55 UTC
(
hide
)
Description:
mod_proxy one for one connection
Filename:
MIME Type:
Creator:
Yann Ylavic
Created:
2013-09-27 14:19:55 UTC
Size:
9.51 KB
patch
obsolete
>Index: modules/proxy/proxy_util.c >=================================================================== >--- modules/proxy/proxy_util.c (revision 1526505) >+++ modules/proxy/proxy_util.c (working copy) >@@ -1333,6 +1333,13 @@ static void init_conn_pool(apr_pool_t *p, proxy_wo > worker->cp = cp; > } > >+static void socket_cleanup(proxy_conn_rec *conn) >+{ >+ conn->sock = NULL; >+ conn->connection = NULL; >+ apr_pool_clear(conn->scpool); >+} >+ > static apr_status_t connection_cleanup(void *theconn) > { > proxy_conn_rec *conn = (proxy_conn_rec *)theconn; >@@ -1351,12 +1358,31 @@ static apr_status_t connection_cleanup(void *theco > conn->r = NULL; > } > >- /* Sanity check: Did we already return the pooled connection? */ >+ /* If the connection was not acquired from the reslist, it was from the >+ * optional function ap_proxy_acquire_connection_ex (1for1 connection), >+ * so it will be closed/freed with the client's connection pool. >+ * >+ * <sigh> >+ * The flag 'inreslist' has been hijacked (to preserve the 2.4.x API), it >+ * was originally used here to check a double-release of the connection, >+ * being unset when acquired and set when released (below). >+ * >+ * The check was broken (per se) since nothing can help when the same >+ * connection is released twice, the reslist might have destroy it the >+ * first time or else given it to another thread before the second time, >+ * it could also work sometimes... >+ * >+ * The flag is now misnamed, but still set/unset in the same place, so its >+ * value really is 0 here when the connection comes from the reslist (and >+ * should be put back there) and 1 when it comes from an optional call to >+ * ap_proxy_acquire_connection_ex (and must not hit the reslist now), hence >+ * the test below is misleading but valid... >+ * </sigh> >+ */ > if (conn->inreslist) { >- ap_log_perror(APLOG_MARK, APLOG_ERR, 0, conn->pool, APLOGNO(00923) >- "Pooled connection 0x%pp for worker %s has been" >- " already returned to the connection pool.", conn, >- worker->s->name); >+ if (conn->close) { >+ socket_cleanup(conn); >+ } > return APR_SUCCESS; > } > >@@ -1384,13 +1410,6 @@ static apr_status_t connection_cleanup(void *theco > return APR_SUCCESS; > } > >-static void socket_cleanup(proxy_conn_rec *conn) >-{ >- conn->sock = NULL; >- conn->connection = NULL; >- apr_pool_clear(conn->scpool); >-} >- > PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn, > request_rec *r) > { >@@ -1975,13 +1994,17 @@ PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr > return connected ? 0 : 1; > } > >-PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function, >- proxy_conn_rec **conn, >- proxy_worker *worker, >- server_rec *s) >+static int ap_proxy_acquire_connection_ex(const char *proxy_function, >+ proxy_conn_rec **conn, >+ proxy_worker *worker, >+ server_rec *s, >+ conn_rec *c) > { > apr_status_t rv; >+ int one4one = 0; > >+ *conn = NULL; >+ > if (!PROXY_WORKER_IS_USABLE(worker)) { > /* Retry the worker */ > ap_proxy_retry_worker(proxy_function, worker, s); >@@ -1994,6 +2017,17 @@ PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr > } > } > >+ if (c && worker->s->is_address_reusable && !worker->s->disablereuse) { >+ *conn = (proxy_conn_rec *)ap_get_module_config(c->conn_config, >+ &proxy_module); >+ if (!*conn) { >+ connection_constructor((void **)conn, worker, c->pool); >+ ap_set_module_config(c->conn_config, &proxy_module, *conn); >+ } >+ rv = APR_SUCCESS; >+ one4one = 1; >+ } >+ else > if (worker->s->hmax && worker->cp->res) { > rv = apr_reslist_acquire(worker->cp->res, (void **)conn); > } >@@ -2011,28 +2045,40 @@ PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr > > if (rv != APR_SUCCESS) { > ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00941) >- "%s: failed to acquire connection for (%s)", >- proxy_function, worker->s->hostname); >+ "%s: failed to acquire %sconnection for (%s)", >+ proxy_function, one4one ? "1for1 " : "", >+ worker->s->hostname); > return HTTP_SERVICE_UNAVAILABLE; > } > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00942) >- "%s: has acquired connection for (%s)", >- proxy_function, worker->s->hostname); >+ "%s: has acquired %sconnection for (%s)", >+ proxy_function, one4one ? "1for1 " : "", >+ worker->s->hostname); > > (*conn)->worker = worker; > (*conn)->close = 0; >- (*conn)->inreslist = 0; >+ (*conn)->inreslist = one4one; > > return OK; > } > >+PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function, >+ proxy_conn_rec **conn, >+ proxy_worker *worker, >+ server_rec *s) >+{ >+ return ap_proxy_acquire_connection_ex(proxy_function, conn, worker, s, >+ NULL); >+} >+ > PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function, > proxy_conn_rec *conn, > server_rec *s) > { > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00943) >- "%s: has released connection for (%s)", >- proxy_function, conn->worker->s->hostname); >+ "%s: has released %sconnection for (%s)", >+ proxy_function, conn->inreslist ? "1for1 " : "", >+ conn->worker->s->hostname); > connection_cleanup(conn); > > return OK; >@@ -3217,4 +3263,5 @@ void proxy_util_register_hooks(apr_pool_t *p) > { > APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker); > APR_REGISTER_OPTIONAL_FN(ap_proxy_clear_connection); >+ APR_REGISTER_OPTIONAL_FN(ap_proxy_acquire_connection_ex); > } >Index: modules/proxy/mod_proxy_http.c >=================================================================== >--- modules/proxy/mod_proxy_http.c (revision 1526505) >+++ modules/proxy/mod_proxy_http.c (working copy) >@@ -17,6 +17,7 @@ > /* HTTP routines for Apache proxy */ > > #include "mod_proxy.h" >+#include "proxy_util.h" /* ap_proxy_acquire_connection_ex() */ > #include "ap_regex.h" > > module AP_MODULE_DECLARE_DATA proxy_http_module; >@@ -24,6 +25,13 @@ module AP_MODULE_DECLARE_DATA proxy_http_module; > static int (*ap_proxy_clear_connection_fn)(request_rec *r, apr_table_t *headers) = > NULL; > >+static int (*ap_proxy_acquire_connection_ex_fn)(const char *proxy_function, >+ proxy_conn_rec **conn, >+ proxy_worker *worker, >+ server_rec *s, >+ conn_rec *c) >+ = NULL; >+ > static apr_status_t ap_proxy_http_cleanup(const char *scheme, > request_rec *r, > proxy_conn_rec *backend); >@@ -1902,9 +1910,17 @@ static int proxy_http_handler(request_rec *r, prox > > > /* create space for state information */ >- if ((status = ap_proxy_acquire_connection(proxy_function, &backend, >- worker, r->server)) != OK) >+ if (apr_table_get(r->subprocess_env, "proxy-1for1-connection")) { >+ status = ap_proxy_acquire_connection_ex_fn(proxy_function, &backend, >+ worker, r->server, c); >+ } >+ else { >+ status = ap_proxy_acquire_connection(proxy_function, &backend, >+ worker, r->server); >+ } >+ if (status != OK) { > goto cleanup; >+ } > > > backend->is_ssl = is_ssl; >@@ -2034,6 +2050,16 @@ static int proxy_http_post_config(apr_pool_t *pcon > } > } > >+ if (!ap_proxy_acquire_connection_ex_fn) { >+ ap_proxy_acquire_connection_ex_fn = >+ APR_RETRIEVE_OPTIONAL_FN(ap_proxy_acquire_connection_ex); >+ if (!ap_proxy_acquire_connection_ex_fn) { >+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO() >+ "mod_proxy must be loaded for mod_proxy_http"); >+ return !OK; >+ } >+ } >+ > return OK; > } > >Index: modules/proxy/proxy_util.h >=================================================================== >--- modules/proxy/proxy_util.h (revision 1526505) >+++ modules/proxy/proxy_util.h (working copy) >@@ -40,6 +40,14 @@ PROXY_DECLARE_DATA extern const apr_strmatch_patte > */ > void proxy_util_register_hooks(apr_pool_t *p); > >+/** >+ * Optional function to acquire a backend connection attached to the client's one >+ * when c is not NULL, otherwise it is ap_proxy_acquire_connection. >+ */ >+APR_DECLARE_OPTIONAL_FN(int, ap_proxy_acquire_connection_ex, >+ (const char *proxy_function, proxy_conn_rec **conn, >+ proxy_worker *worker, server_rec *s, conn_rec *c)); >+ > /** @} */ > > #endif /* PROXY_UTIL_H_ */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 39673
:
29994
|
30887
|
30888
|
30889
|
31751
|
31752
|
31753
|
31754
|
32040