diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/connection.c | 11 | ||||
-rw-r--r-- | server/core.c | 57 |
2 files changed, 68 insertions, 0 deletions
diff --git a/server/connection.c b/server/connection.c index a7a51cf741..f32a1f3712 100644 --- a/server/connection.c +++ b/server/connection.c @@ -35,6 +35,7 @@ APR_HOOK_STRUCT( APR_HOOK_LINK(process_connection) APR_HOOK_LINK(pre_connection) APR_HOOK_LINK(pre_close_connection) + APR_HOOK_LINK(create_secondary_connection) ) AP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_connection, (apr_pool_t *p, server_rec *server, apr_socket_t *csd, long conn_id, void *sbh, apr_bucket_alloc_t *alloc), @@ -42,6 +43,9 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_connection, AP_IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED) AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c, void *csd),(c, csd),OK,DECLINED) AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_close_connection,(conn_rec *c),(c),OK,DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_secondary_connection, + (apr_pool_t *p, conn_rec *master, apr_bucket_alloc_t *alloc), + (p, master, alloc), NULL) AP_DECLARE(conn_rec *) ap_create_connection(apr_pool_t *p, server_rec *server, @@ -66,6 +70,13 @@ AP_DECLARE(conn_rec *) ap_create_connection(apr_pool_t *p, return c; } +AP_DECLARE(conn_rec *) ap_create_secondary_connection(apr_pool_t *p, + conn_rec *master, + apr_bucket_alloc_t *alloc) +{ + return ap_run_create_secondary_connection(p, master, alloc); +} + /* * More machine-dependent networking gooo... on some systems, * you've got to be *really* sure that all the packets are acknowledged diff --git a/server/core.c b/server/core.c index 1730ceee44..e3953f231a 100644 --- a/server/core.c +++ b/server/core.c @@ -147,6 +147,8 @@ typedef struct { struct ap_logconf log; } conn_log_config; +static apr_socket_t *dummy_socket; + static void *create_core_dir_config(apr_pool_t *a, char *dir) { core_dir_config *conf; @@ -5517,6 +5519,54 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *s, return c; } +static conn_rec *core_create_secondary_conn(apr_pool_t *ptrans, + conn_rec *master, + apr_bucket_alloc_t *alloc) +{ + apr_pool_t *pool; + conn_config_t *conn_config; + conn_rec *c = (conn_rec *) apr_pmemdup(ptrans, master, sizeof(*c)); + + /* Got a connection structure, so initialize what fields we can + * (the rest are zeroed out by pcalloc). + */ + apr_pool_create(&pool, ptrans); + apr_pool_tag(pool, "secondary_conn"); + + /* we copied everything, now replace what is different */ + c->master = master; + c->pool = pool; + c->bucket_alloc = alloc; + c->conn_config = ap_create_conn_config(pool); + c->notes = apr_table_make(pool, 5); + c->slaves = apr_array_make(pool, 20, sizeof(conn_slave_rec *)); + c->requests = apr_array_make(pool, 20, sizeof(request_rec *)); + c->input_filters = NULL; + c->output_filters = NULL; + c->filter_conn_ctx = NULL; + + /* prevent mpm_event from making wrong assumptions about this connection, + * like e.g. using its socket for an async read check. */ + c->clogging_input_filters = 1; + + c->log = NULL; + c->aborted = 0; + c->keepalives = 0; + + /* FIXME: mpms (and maybe other) parts think that there is always + * a socket for a connection. We cannot use the master socket for + * secondary connections, as this gets modified (closed?) when + * the secondary connection terminates. + * There seem to be some checks for c->master necessary in other + * places. + */ + conn_config = apr_pcalloc(pool, sizeof(*conn_config)); + conn_config->socket = dummy_socket; + ap_set_core_module_config(c->conn_config, conn_config); + + return c; +} + static int core_pre_connection(conn_rec *c, void *csd) { conn_config_t *conn_config; @@ -5670,6 +5720,11 @@ static void core_child_init(apr_pool_t *pchild, server_rec *s) */ proc.pid = getpid(); apr_random_after_fork(&proc); + + /* needed for secondary connections so people do not change the master + * connection socket. */ + apr_socket_create(&dummy_socket, APR_INET, SOCK_STREAM, + APR_PROTO_TCP, pchild); } static void core_optional_fn_retrieve(void) @@ -5905,6 +5960,8 @@ static void register_hooks(apr_pool_t *p) */ ap_hook_create_connection(core_create_conn, NULL, NULL, APR_HOOK_REALLY_LAST); + ap_hook_create_secondary_connection(core_create_secondary_conn, NULL, NULL, + APR_HOOK_REALLY_LAST); ap_hook_pre_connection(core_pre_connection, NULL, NULL, APR_HOOK_REALLY_LAST); |