summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/connection.c11
-rw-r--r--server/core.c57
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);