From bd3d3603923cc5a87a85aadef8bb7804e415f9e2 Mon Sep 17 00:00:00 2001 From: Bill Stoddard Date: Fri, 1 Feb 2002 22:16:31 +0000 Subject: [PATCH] Reintroduce the create_connection hook. This hook is required to enable modules to completely take over all network i/o from the core. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93171 13f79535-47bb-0310-9956-ffa450edef68 --- include/http_connection.h | 40 ++++++++++-------- modules/proxy/proxy_ftp.c | 8 ++-- modules/proxy/proxy_http.c | 6 +-- server/connection.c | 46 +++------------------ server/core.c | 44 ++++++++++++++++++++ server/mpm/beos/beos.c | 2 +- server/mpm/experimental/perchild/perchild.c | 2 +- server/mpm/mpmt_os2/mpmt_os2_child.c | 2 +- server/mpm/netware/mpm_netware.c | 4 +- server/mpm/perchild/perchild.c | 2 +- server/mpm/prefork/prefork.c | 2 +- server/mpm/winnt/mpm_winnt.c | 10 ++--- server/mpm/worker/worker.c | 2 +- 13 files changed, 92 insertions(+), 78 deletions(-) diff --git a/include/http_connection.h b/include/http_connection.h index 02cb5555b5..d676a9d2f8 100644 --- a/include/http_connection.h +++ b/include/http_connection.h @@ -65,20 +65,7 @@ extern "C" { /** * @package Apache connection library */ - #ifdef CORE_PRIVATE -/** - * Create a new connection. - * @param p Pool to allocate data structures out of - * @param server The server to create the connection for - * @param csd The socket to use for all communication with the client - * @param id ID of this connection; unique at any point in time. - * @param sbh Scoreboard handle - * @return new conn_rec, or NULL if the connection has already been reset - */ -AP_CORE_DECLARE(conn_rec *)ap_new_connection(apr_pool_t *ptrans, server_rec *server, - apr_socket_t *csd, long id, void *sbh); - /** * This is the protocol module driver. This calls all of the * pre-connection and connection hooks for all protocol modules. @@ -109,11 +96,28 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c); /* Hooks */ /** - * This hook is used to install the bottom most input and output - * filters (e.g., CORE_IN and CORE_OUT) used to interface to the - * network. This filter is a RUN_FIRST hook that runs right before - * the pre_connection filter. This filter hook can use vhost - * configuration to influence its operation. + * create_connection is a RUN_FIRST hook which allows modules to create + * connections. In general, you should not install filters with the + * create_connection hook. If you require vhost configuration information + * to make filter installation decisions, you must use the pre_connection + * or install_network_transport hook. This hook should close the connection + * if it encounters a fatal error condition. + * + * @param p The pool from which to allocate the connection record + * @param csd The socket that has been accepted + * @param conn_id A unique identifier for this connection. The ID only + * needs to be unique at that time, not forever. + * @param sbh A handle to scoreboard information for this connection. + * @return An allocated connection record or NULL. + */ +AP_DECLARE_HOOK(conn_rec *, create_connection, + (apr_pool_t *p, server_rec *server, apr_socket_t *csd, long conn_id, void *sbh)) + +/** + * install_transport_filters is a RUN_FIRST hook used to install the bottom + * most input and output network transport filters (e.g., CORE_IN and CORE_OUT) + * used to interface to the network. This hook can access vhost configuration. + * * @param c The socket to the client * @param csd Pointer to the client apr_socket_t struct. * @return OK or DECLINED diff --git a/modules/proxy/proxy_ftp.c b/modules/proxy/proxy_ftp.c index 208618f449..8a8439eb05 100644 --- a/modules/proxy/proxy_ftp.c +++ b/modules/proxy/proxy_ftp.c @@ -1017,10 +1017,10 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, } /* the socket is now open, create a new connection */ - origin = ap_new_connection(p, r->server, sock, r->connection->id, r->connection->sbh); + origin = ap_run_create_connection(p, r->server, sock, r->connection->id, r->connection->sbh); if (!origin) { /* - * the peer reset the connection already; ap_new_connection() closed + * the peer reset the connection already; ap_run_create_connection() closed * the socket */ ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server, @@ -1778,10 +1778,10 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, } /* the transfer socket is now open, create a new connection */ - data = ap_new_connection(p, r->server, data_sock, r->connection->id, r->connection->sbh); + data = ap_run_create_connection(p, r->server, data_sock, r->connection->id, r->connection->sbh); if (!data) { /* - * the peer reset the connection already; ap_new_connection() closed + * the peer reset the connection already; ap_run_create_connection() closed * the socket */ ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server, diff --git a/modules/proxy/proxy_http.c b/modules/proxy/proxy_http.c index ff69dd2988..b8eec52fc3 100644 --- a/modules/proxy/proxy_http.c +++ b/modules/proxy/proxy_http.c @@ -428,10 +428,10 @@ apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r, "proxy: socket is connected"); /* the socket is now open, create a new backend server connection */ - *origin = ap_new_connection(c->pool, r->server, p_conn->sock, - r->connection->id, r->connection->sbh); + *origin = ap_run_create_connection(c->pool, r->server, p_conn->sock, + r->connection->id, r->connection->sbh); if (!origin) { - /* the peer reset the connection already; ap_new_connection() + /* the peer reset the connection already; ap_run_create_connection() * closed the socket */ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, diff --git a/server/connection.c b/server/connection.c index 52ce3e97ab..48952a2628 100644 --- a/server/connection.c +++ b/server/connection.c @@ -75,16 +75,18 @@ #include "util_filter.h" APR_HOOK_STRUCT( - APR_HOOK_LINK(pre_connection) + APR_HOOK_LINK(create_connection) APR_HOOK_LINK(process_connection) APR_HOOK_LINK(install_transport_filters) + APR_HOOK_LINK(pre_connection) ) - -AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c),(c),OK,DECLINED) +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), + (p, server, csd, conn_id, sbh), NULL) AP_IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED) AP_IMPLEMENT_HOOK_RUN_FIRST(int, install_transport_filters, (conn_rec *c, apr_socket_t *csd),(c, csd), DECLINED) - +AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c),(c),OK,DECLINED) /* * More machine-dependent networking gooo... on some systems, * you've got to be *really* sure that all the packets are acknowledged @@ -231,40 +233,4 @@ AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c, apr_socket_t *csd) ap_run_process_connection(c); } } -AP_CORE_DECLARE(conn_rec *)ap_new_connection(apr_pool_t *ptrans, server_rec *server, - apr_socket_t *csd, long id, void *sbh) -{ - apr_status_t rv; - conn_rec *c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec)); - c->sbh = sbh; - (void) ap_update_child_status(c->sbh, SERVER_BUSY_READ, (request_rec *) NULL); - - /* Got a connection structure, so initialize what fields we can - * (the rest are zeroed out by pcalloc). - */ - c->conn_config=ap_create_conn_config(ptrans); - c->notes = apr_table_make(ptrans, 5); - - c->pool = ptrans; - if ((rv = apr_socket_addr_get(&c->local_addr, APR_LOCAL, csd)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, - "apr_socket_addr_get(APR_LOCAL)"); - apr_socket_close(csd); - return NULL; - } - apr_sockaddr_ip_get(&c->local_ip, c->local_addr); - if ((rv = apr_socket_addr_get(&c->remote_addr, APR_REMOTE, csd)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, - "apr_socket_addr_get(APR_REMOTE)"); - apr_socket_close(csd); - return NULL; - } - apr_sockaddr_ip_get(&c->remote_ip, c->remote_addr); - c->base_server = server; - - c->id = id; - return c; -} diff --git a/server/core.c b/server/core.c index c940130e11..4adfae074f 100644 --- a/server/core.c +++ b/server/core.c @@ -3614,7 +3614,43 @@ static int core_create_proxy_req(request_rec *r, request_rec *pr) { return core_create_req(pr); } +static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, + apr_socket_t *csd, long id, void *sbh) +{ + apr_status_t rv; + conn_rec *c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec)); + c->sbh = sbh; + (void) ap_update_child_status(c->sbh, SERVER_BUSY_READ, (request_rec *) NULL); + + /* Got a connection structure, so initialize what fields we can + * (the rest are zeroed out by pcalloc). + */ + c->conn_config=ap_create_conn_config(ptrans); + c->notes = apr_table_make(ptrans, 5); + + c->pool = ptrans; + if ((rv = apr_socket_addr_get(&c->local_addr, APR_LOCAL, csd)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, + "apr_socket_addr_get(APR_LOCAL)"); + apr_socket_close(csd); + return NULL; + } + apr_sockaddr_ip_get(&c->local_ip, c->local_addr); + if ((rv = apr_socket_addr_get(&c->remote_addr, APR_REMOTE, csd)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, + "apr_socket_addr_get(APR_REMOTE)"); + apr_socket_close(csd); + return NULL; + } + apr_sockaddr_ip_get(&c->remote_ip, c->remote_addr); + c->base_server = server; + + c->id = id; + return c; +} static int core_install_transport_filters(conn_rec *c, apr_socket_t *csd) { core_net_rec *net = apr_palloc(c->pool, sizeof(*net)); @@ -3640,8 +3676,14 @@ static int core_install_transport_filters(conn_rec *c, apr_socket_t *csd) static void register_hooks(apr_pool_t *p) { + /* create_connection and install_transport_filters are RUN_FIRST + * hooks that should always be APR_HOOK_REALLY_LAST to give other + * modules the opportunity to install alternate network transports + */ + ap_hook_create_connection(core_create_conn, NULL, NULL, APR_HOOK_REALLY_LAST); ap_hook_install_transport_filters(core_install_transport_filters, NULL, NULL, APR_HOOK_REALLY_LAST); + ap_hook_post_config(core_post_config,NULL,NULL,APR_HOOK_REALLY_FIRST); ap_hook_translate_name(ap_core_translate,NULL,NULL,APR_HOOK_REALLY_LAST); ap_hook_map_to_storage(core_map_to_storage,NULL,NULL,APR_HOOK_REALLY_LAST); @@ -3689,3 +3731,5 @@ AP_DECLARE_DATA module core_module = { core_cmds, /* command apr_table_t */ register_hooks /* register hooks */ }; + + diff --git a/server/mpm/beos/beos.c b/server/mpm/beos/beos.c index 1f6d015418..d9fc492ff5 100644 --- a/server/mpm/beos/beos.c +++ b/server/mpm/beos/beos.c @@ -346,7 +346,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num) } ap_create_sb_handle(&sbh, p, 0, my_child_num); - current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id, sbh); + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn, sock); diff --git a/server/mpm/experimental/perchild/perchild.c b/server/mpm/experimental/perchild/perchild.c index fe69695acc..b79852d18d 100644 --- a/server/mpm/experimental/perchild/perchild.c +++ b/server/mpm/experimental/perchild/perchild.c @@ -567,7 +567,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id) } ap_create_sb_handle(&sbh, p, conn_id / thread_limit, thread_num); - current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id, sbh); + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn, sock); ap_lingering_close(current_conn); diff --git a/server/mpm/mpmt_os2/mpmt_os2_child.c b/server/mpm/mpmt_os2/mpmt_os2_child.c index 20887377f6..47e01564c0 100644 --- a/server/mpm/mpmt_os2/mpmt_os2_child.c +++ b/server/mpm/mpmt_os2/mpmt_os2_child.c @@ -430,7 +430,7 @@ static void worker_main(void *vpArg) rc == 0 && rd.ulData != WORKTYPE_EXIT) { pconn = worker_args->pconn; ap_create_sb_handle(&sbh, pconn, child_slot, thread_slot); - current_conn = ap_new_connection(pconn, ap_server_conf, worker_args->conn_sd, conn_id, sbh); + current_conn = ap_run_create_connection(pconn, ap_server_conf, worker_args->conn_sd, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn, worker_args->conn_sd); diff --git a/server/mpm/netware/mpm_netware.c b/server/mpm/netware/mpm_netware.c index 06747531a1..c26299740a 100644 --- a/server/mpm/netware/mpm_netware.c +++ b/server/mpm/netware/mpm_netware.c @@ -525,8 +525,8 @@ got_listener: * We now have a connection, so set it up with the appropriate * socket options, file descriptors, and read/write buffers. */ - current_conn = ap_new_connection(ptrans, ap_server_conf, csd, - my_worker_num, sbh); + current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, + my_worker_num, sbh); if (current_conn) { ap_process_connection(current_conn, csd); ap_lingering_close(current_conn); diff --git a/server/mpm/perchild/perchild.c b/server/mpm/perchild/perchild.c index fe69695acc..b79852d18d 100644 --- a/server/mpm/perchild/perchild.c +++ b/server/mpm/perchild/perchild.c @@ -567,7 +567,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id) } ap_create_sb_handle(&sbh, p, conn_id / thread_limit, thread_num); - current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id, sbh); + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn, sock); ap_lingering_close(current_conn); diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index 78c47a0e9a..644f5ec17b 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -712,7 +712,7 @@ static void child_main(int child_num_arg) * socket options, file descriptors, and read/write buffers. */ - current_conn = ap_new_connection(ptrans, ap_server_conf, csd, my_child_num, sbh); + current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh); if (current_conn) { ap_process_connection(current_conn, csd); ap_lingering_close(current_conn); diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index fbbf1dec98..00d6c0aa78 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -897,7 +897,7 @@ static PCOMP_CONTEXT winnt_get_connection(PCOMP_CONTEXT pCompContext) * Main entry point for the worker threads. Worker threads block in * win*_get_connection() awaiting a connection to service. */ -static void worker_main(int thread_num) +static void worker_main(long thread_num) { static int requests_this_child = 0; PCOMP_CONTEXT context = NULL; @@ -941,8 +941,8 @@ static void worker_main(int thread_num) apr_os_sock_make(&context->sock, &sockinfo, context->ptrans); ap_create_sb_handle(&sbh, context->ptrans, 0, thread_num); - c = ap_new_connection(context->ptrans, ap_server_conf, context->sock, - thread_num, sbh); + c = ap_run_create_connection(context->ptrans, ap_server_conf, context->sock, + thread_num, sbh); if (c) { ap_process_connection(c, context->sock); @@ -953,7 +953,7 @@ static void worker_main(int thread_num) } } else { - /* ap_new_connection closes the socket on failure */ + /* ap_run_create_connection closes the socket on failure */ context->accept_socket = INVALID_SOCKET; } } @@ -1014,7 +1014,7 @@ static void child_main() "Child %d: exit_event_name = %s", my_pid, exit_event_name); /* Set up the scoreboard. */ ap_my_generation = atoi(getenv("AP_MY_GENERATION")); - ap_log_error(APLOG_MARK, APLOG_CRIT, APR_SUCCESS, ap_server_conf, + ap_log_error(APLOG_MARK, APLOG_CRIT, APR_SUCCESS, ap_server_conf, "getting listeners child_main", my_pid); get_listeners_from_parent(ap_server_conf); } diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index d3f95dfdf3..84a65b52f2 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -554,7 +554,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, return; } - current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id, sbh); + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn, sock); ap_lingering_close(current_conn); -- 2.40.0