From: Nick Kew Date: Wed, 19 Aug 2009 23:55:14 +0000 (+0000) Subject: Don't require all listeners to be created equal ... X-Git-Tag: 2.3.3~386 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b102bce05cf95bfbc278cef95ea92e901bd2669e;p=thirdparty%2Fapache%2Fhttpd.git Don't require all listeners to be created equal ... git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@806010 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/ap_listen.h b/include/ap_listen.h index b623495ba1c..3c73043698b 100644 --- a/include/ap_listen.h +++ b/include/ap_listen.h @@ -34,6 +34,7 @@ extern "C" { #endif +typedef struct ap_slave_t ap_slave_t; typedef struct ap_listen_rec ap_listen_rec; typedef apr_status_t (*accept_function)(void **csd, ap_listen_rec *lr, apr_pool_t *ptrans); @@ -68,6 +69,8 @@ struct ap_listen_rec { * The default protocol for this listening socket. */ const char* protocol; + + ap_slave_t *slave; }; /** @@ -92,6 +95,7 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s); * Loop through the global ap_listen_rec list and close each of the sockets. */ AP_DECLARE_NONSTD(void) ap_close_listeners(void); +AP_DECLARE_NONSTD(int) ap_close_listeners_selected(ap_slave_t*); /* Although these functions are exported from libmain, they are not really * public functions. These functions are actually called while parsing the diff --git a/server/listen.c b/server/listen.c index 8361fb3c35d..4a237150656 100644 --- a/server/listen.c +++ b/server/listen.c @@ -234,7 +234,8 @@ static apr_status_t close_listeners_on_exec(void *v) } static const char *alloc_listener(process_rec *process, char *addr, - apr_port_t port, const char* proto) + apr_port_t port, const char* proto, + void *dummy) { ap_listen_rec **walk, *last; apr_status_t status; @@ -269,6 +270,9 @@ static const char *alloc_listener(process_rec *process, char *addr, } if (found_listener) { + if (ap_listeners->slave != dummy) { + return "Cannot define a slave on the same IP:port as a Listener"; + } return NULL; } @@ -326,6 +330,7 @@ static const char *alloc_listener(process_rec *process, char *addr, last->next = new; last = new; } + new->slave = dummy; } return NULL; @@ -581,6 +586,22 @@ AP_DECLARE_NONSTD(void) ap_close_listeners(void) lr->active = 0; } } +AP_DECLARE_NONSTD(int) ap_close_selected_listeners(ap_slave_t *slave) +{ + ap_listen_rec *lr; + int n = 0; + + for (lr = ap_listeners; lr; lr = lr->next) { + if (lr->slave != slave) { + apr_socket_close(lr->sd); + lr->active = 0; + } + else { + ++n; + } + } + return n; +} AP_DECLARE(void) ap_listen_pre_config(void) { @@ -589,7 +610,10 @@ AP_DECLARE(void) ap_listen_pre_config(void) ap_listenbacklog = DEFAULT_LISTENBACKLOG; } - +/* Hack: populate an extra field + * When this gets called from a Listen directive, dummy is null. + * So we can use non-null dummy to pass a data pointer without conflict + */ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, int argc, char *const argv[]) { @@ -636,7 +660,7 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, ap_str_tolower(proto); } - return alloc_listener(cmd->server->process, host, port, proto); + return alloc_listener(cmd->server->process, host, port, proto, dummy); } AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd,