ASF Bugzilla – Attachment 32040 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]
Handle aside connections in mod_proxy (trunk)
httpd-trunk-mod_proxy_aside6.patch (text/plain), 11.89 KB, created by
jkaluza
on 2014-09-22 07:49:03 UTC
(
hide
)
Description:
Handle aside connections in mod_proxy (trunk)
Filename:
MIME Type:
Creator:
jkaluza
Created:
2014-09-22 07:49:03 UTC
Size:
11.89 KB
patch
obsolete
>Index: modules/proxy/mod_proxy.h >=================================================================== >--- modules/proxy/mod_proxy.h (revision 1624217) >+++ modules/proxy/mod_proxy.h (working copy) >@@ -234,6 +234,9 @@ > apr_array_header_t* cookie_domains; > } proxy_req_conf; > >+/* Opaque aside connection record */ >+typedef struct ap_proxy_aside_rec ap_proxy_aside_rec; >+ > typedef struct { > conn_rec *connection; > request_rec *r; /* Request record of the backend request >@@ -255,6 +258,7 @@ > unsigned int inreslist:1; /* connection in apr_reslist? */ > const char *uds_path; /* Unix domain socket path */ > const char *ssl_hostname;/* Hostname (SNI) in use by SSL connection */ >+ ap_proxy_aside_rec *aside; /* Aside context */ > } proxy_conn_rec; > > typedef struct { >@@ -868,7 +872,43 @@ > proxy_conn_rec **conn, > proxy_worker *worker, > server_rec *s); >+ > /** >+ * Function types usable by ap_proxy_acquire_connection_ex(). >+ */ >+typedef apr_status_t (*ap_proxy_acquire_fn)(void *baton, proxy_conn_rec **conn, >+ proxy_worker *worker, >+ server_rec *s); >+typedef apr_status_t (*ap_proxy_release_fn)(void *baton, proxy_conn_rec *conn); >+ >+/** >+ * Acquire a connection using the given @acquire function and register >+ * a @release callback for it on cleanup, or use the worker connection >+ * pool if the associated @baton is NULL. >+ * @param proxy_function calling proxy scheme (http, ajp, ...) >+ * @param conn acquired connection >+ * @param worker worker used for obtaining connection >+ * @param s current server record >+ * @param baton associated baton (or conn_rec if @acquire is NULL) >+ * @param acquire function (if not NULL) used to acquire aside connections, >+ * given @baton, @conn, @worker, and @s >+ * @param release function (if not NULL) used to release acquired connection, >+ * given @baton, @conn, @worker, and @s, as callback >+ * @return OK or HTTP_XXX error >+ * @note If the connection limit has been reached, the function will >+ * block until a connection becomes available or the timeout has >+ * elapsed. >+ * @note If the given @baton is not NULL and @acquire is NULL, the baton is >+ * considered to be a conn_rec to which the connection is attached (by worker). >+ */ >+PROXY_DECLARE(int) ap_proxy_acquire_connection_ex(const char *proxy_function, >+ proxy_conn_rec **conn, >+ proxy_worker *worker, >+ server_rec *s, void *baton, >+ ap_proxy_acquire_fn acquire, >+ ap_proxy_release_fn release); >+ >+/** > * Release a connection back to worker connection pool > * @param proxy_function calling proxy scheme (http, ajp, ...) > * @param conn acquired connection >Index: modules/proxy/mod_proxy_ajp.c >=================================================================== >--- modules/proxy/mod_proxy_ajp.c (revision 1624217) >+++ modules/proxy/mod_proxy_ajp.c (working copy) >@@ -730,6 +730,12 @@ > ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00895) "serving URL %s", url); > > /* create space for state information */ >+ if (apr_table_get(r->subprocess_env, "proxy-aside-c")) { >+ status = ap_proxy_acquire_connection_ex(scheme, &backend, worker, >+ r->server, r->connection, >+ NULL, NULL); >+ } >+ else > status = ap_proxy_acquire_connection(scheme, &backend, worker, > r->server); > if (status != OK) { >Index: modules/proxy/mod_proxy_http.c >=================================================================== >--- modules/proxy/mod_proxy_http.c (revision 1624217) >+++ modules/proxy/mod_proxy_http.c (working copy) >@@ -1962,8 +1962,16 @@ > > > /* 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-aside-c")) { >+ status = ap_proxy_acquire_connection_ex(proxy_function, &backend, >+ worker, r->server, c, >+ NULL, NULL); >+ } >+ else { >+ status = ap_proxy_acquire_connection(proxy_function, &backend, >+ worker, r->server); >+ } >+ if (status != OK) > goto cleanup; > > >Index: modules/proxy/proxy_util.c >=================================================================== >--- modules/proxy/proxy_util.c (revision 1624217) >+++ modules/proxy/proxy_util.c (working copy) >@@ -72,6 +72,13 @@ > {0x0, '\0', NULL} > }; > >+/* Opaque aside connection record */ >+struct ap_proxy_aside_rec { >+ void *baton; >+ ap_proxy_release_fn release; >+ apr_time_t expiry; /* idle connection expiry */ >+}; >+ > /* Global balancer counter */ > int PROXY_DECLARE_DATA proxy_lb_workers = 0; > static int lb_workers_limit = 0; >@@ -1351,6 +1358,14 @@ > return ! (conn->close || !worker->s->is_address_reusable || worker->s->disablereuse); > } > >+static void socket_cleanup(proxy_conn_rec *conn) >+{ >+ conn->sock = NULL; >+ conn->connection = NULL; >+ conn->ssl_hostname = NULL; >+ apr_pool_clear(conn->scpool); >+} >+ > static apr_status_t connection_cleanup(void *theconn) > { > proxy_conn_rec *conn = (proxy_conn_rec *)theconn; >@@ -1378,6 +1393,21 @@ > return APR_SUCCESS; > } > >+ /* If the connection is aside (not acquired from the reslist), >+ * let it be released by the callback if any, or live with its >+ * parent pool otherwise (still ensuring it is closed if asked to). >+ */ >+ if (conn->aside) { >+ if (conn->close) { >+ socket_cleanup(conn); >+ conn->close = 0; >+ } >+ if (conn->aside->release) { >+ conn->aside->release(conn->aside->baton, conn); >+ } >+ return APR_SUCCESS; >+ } >+ > /* determine if the connection need to be closed */ > if (!ap_proxy_connection_reusable(conn)) { > apr_pool_t *p = conn->pool; >@@ -1402,14 +1432,6 @@ > return APR_SUCCESS; > } > >-static void socket_cleanup(proxy_conn_rec *conn) >-{ >- conn->sock = NULL; >- conn->connection = NULL; >- conn->ssl_hostname = NULL; >- apr_pool_clear(conn->scpool); >-} >- > PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn, > request_rec *r) > { >@@ -2151,11 +2173,61 @@ > 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) >+/* For the given conn_rec (baton), handle a connection per worker */ >+static apr_status_t proxy_acquire_from_c(void *baton, proxy_conn_rec **conn, >+ proxy_worker *worker, server_rec *s) > { >+ apr_hash_t *conns; >+ ap_proxy_aside_rec *aside; >+ conn_rec *c = baton; >+ >+ conns = ap_get_module_config(c->conn_config, &proxy_module); >+ if (!conns) { >+ conns = apr_hash_make(c->pool); >+ ap_set_module_config(c->conn_config, &proxy_module, conns); >+ *conn = NULL; >+ } >+ else { >+ *conn = apr_hash_get(conns, &worker->s, sizeof worker->s); >+ } >+ if (!*conn) { >+ connection_constructor((void **)conn, worker, c->pool); >+ apr_hash_set(conns, &worker->s, sizeof worker->s, *conn); >+ aside = apr_pcalloc((*conn)->pool, sizeof *aside); >+ (*conn)->aside = aside; >+ } >+ else { >+ aside = (*conn)->aside; >+ if (aside->expiry) { >+ if (apr_time_now() >= aside->expiry) { >+ socket_cleanup(*conn); >+ } >+ aside->expiry = 0; >+ } >+ } >+ >+ return APR_SUCCESS; >+} >+ >+static apr_status_t proxy_release_to_c(void *baton, proxy_conn_rec *conn) >+{ >+ if (conn->worker->s->ttl) { >+ conn->aside->expiry = apr_time_now() + >+ apr_time_from_sec(conn->worker->s->ttl); >+ } >+ else { >+ conn->aside->expiry = 0; >+ } >+ return APR_SUCCESS; >+} >+ >+PROXY_DECLARE(int) ap_proxy_acquire_connection_ex(const char *proxy_function, >+ proxy_conn_rec **conn, >+ proxy_worker *worker, >+ server_rec *s, void *baton, >+ ap_proxy_acquire_fn acquire, >+ ap_proxy_release_fn release) >+{ > apr_status_t rv; > > if (!PROXY_WORKER_IS_USABLE(worker)) { >@@ -2170,7 +2242,37 @@ > } > } > >- if (worker->s->hmax && worker->cp->res) { >+ /* Aside connection case, use the given functions. >+ * When a baton is given with no acquire function, it is >+ * assumed to be a conn_rec (to acquire from), hence the >+ * corresponding functions are installed. >+ */ >+ if (acquire || (baton && (acquire = proxy_acquire_from_c) >+ && (release = proxy_release_to_c))) { >+ rv = acquire(baton, conn, worker, s); >+ if (rv == APR_SUCCESS) { >+ if (!(*conn)->aside) { >+ (*conn)->aside = apr_pcalloc((*conn)->pool, >+ sizeof *(*conn)->aside); >+ } >+ (*conn)->aside->release = release; >+ (*conn)->aside->baton = baton; >+ } >+ else if (rv != APR_NOTFOUND) { >+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO() >+ "%s: failed to acquire aside connection for (%s)", >+ proxy_function, worker->s->hostname); >+ return HTTP_SERVICE_UNAVAILABLE; >+ } >+ } >+ else { >+ rv = APR_NOTFOUND; >+ } >+ >+ if (rv == APR_SUCCESS) { >+ /* got/use aside connection */ >+ } >+ else if (worker->s->hmax && worker->cp->res) { > rv = apr_reslist_acquire(worker->cp->res, (void **)conn); > } > else { >@@ -2192,8 +2294,9 @@ > 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, (*conn)->aside ? "aside " : "", >+ worker->s->hostname); > > (*conn)->worker = worker; > (*conn)->close = 0; >@@ -2202,13 +2305,23 @@ > 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, NULL, 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->aside ? "aside " : "", >+ conn->worker->s->hostname); > connection_cleanup(conn); > > return OK;
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