From: Paul Querna Date: Thu, 5 May 2005 23:07:54 +0000 (+0000) Subject: Initial work to determine the protocol of a socket, before it is accept()'ed. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cbbb82463bb63012dfb44070be594283c625bd5f;p=thirdparty%2Fapache%2Fhttpd.git Initial work to determine the protocol of a socket, before it is accept()'ed. If we can determine the protocol at startup when we allocate the socket, the correct Accept Filters can be applied. Currently we blindly apply the http accept filter. * server/core.c: Add 'Protocol' to the core module config * server/core.c: Add ap_{set,get}_server_protocol API. * server/listen.c: Attempt to inherit protocols from Listener Records to Server configs. I do not like the current code, but it works. * server/listen.c: The 'Listen' directive can now optionally take a protocol arg * include/{ap_listen.h,http_core.h}: Add Protocol to respective structures. * include/ap_mmn.h: Minor MMN Bump for the new interfacces. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/listen-protocol@168459 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/ap_listen.h b/include/ap_listen.h index 7f456c569d5..d98949f3792 100644 --- a/include/ap_listen.h +++ b/include/ap_listen.h @@ -53,7 +53,10 @@ struct ap_listen_rec { * Is this socket currently active */ int active; -/* more stuff here, like which protocol is bound to the port */ + /** + * The default protocol for this listening socket. + */ + const char* protocol; }; /** @@ -82,7 +85,8 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s); * called. */ AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg); -AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, const char *ips); +AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, + int argc, char *const argv[]); AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy, const char *arg); AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, @@ -92,8 +96,8 @@ AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, #define LISTEN_COMMANDS \ AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \ "Maximum length of the queue of pending connections, as used by listen(2)"), \ -AP_INIT_TAKE1("Listen", ap_set_listener, NULL, RSRC_CONF, \ - "A port number or a numeric IP address and a port number"), \ +AP_INIT_TAKE_ARGV("Listen", ap_set_listener, NULL, RSRC_CONF, \ + "A port number or a numeric IP address and a port number, and an optional protocol"), \ AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \ "Send buffer size in bytes"), \ AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \ diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 96245efe0d0..f6e3c722087 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -95,6 +95,7 @@ * 20050305.0 (2.1.4-dev) added pid and generation fields to worker_score * 20050305.1 (2.1.5-dev) added ap_vhost_iterate_given_conn. * 20050305.2 (2.1.5-dev) added AP_INIT_TAKE_ARGV. + * 20050305.3 (2.1.5-dev) added Protocol Framework. */ #define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */ @@ -102,7 +103,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20050305 #endif -#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 3 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/http_core.h b/include/http_core.h index f20e8a80767..0578611a0be 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -545,6 +545,8 @@ typedef struct { /* recursion backstopper */ int redirect_limit; /* maximum number of internal redirects */ int subreq_limit; /* maximum nesting level of subrequests */ + + const char* protocol; } core_server_config; /* for AddOutputFiltersByType in core.c */ @@ -570,6 +572,8 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *b); #endif /* CORE_PRIVATE */ +AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s); +AP_DECLARE(void) ap_set_server_protocol(server_rec* s, const char* proto); /* ---------------------------------------------------------------------- * diff --git a/server/core.c b/server/core.c index b0e14c4224b..01ccd5106af 100644 --- a/server/core.c +++ b/server/core.c @@ -460,6 +460,8 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s) conf->redirect_limit = 0; /* 0 == unset */ conf->subreq_limit = 0; + conf->protocol = NULL; + return (void *)conf; } @@ -480,6 +482,10 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) conf->ap_document_root = base->ap_document_root; } + if (!conf->protocol) { + conf->protocol = base->protocol; + } + conf->sec_dir = apr_array_append(p, base->sec_dir, virt->sec_dir); conf->sec_url = apr_array_append(p, base->sec_url, virt->sec_url); @@ -490,7 +496,6 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) conf->subreq_limit = virt->subreq_limit ? virt->subreq_limit : base->subreq_limit; - return conf; } @@ -2182,6 +2187,39 @@ static const char *set_server_alias(cmd_parms *cmd, void *dummy, return NULL; } +AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s) +{ + core_server_config *conf = ap_get_module_config(s->module_config, + &core_module); + return conf->protocol; +} + +AP_DECLARE(void) ap_set_server_protocol(server_rec* s, const char* proto) +{ + core_server_config *conf = ap_get_module_config(s->module_config, + &core_module); + conf->protocol = proto; +} + +static const char *set_protocol(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + core_server_config *conf = ap_get_module_config(cmd->server->module_config, + &core_module); + char* proto; + + if (err != NULL) { + return err; + } + + proto = apr_pstrdup(cmd->pool, arg); + ap_str_tolower(proto); + conf->protocol = proto; + + return NULL; +} + static const char *set_server_string_slot(cmd_parms *cmd, void *dummy, const char *arg) { @@ -3120,6 +3158,8 @@ AP_INIT_TAKE1("EnableSendfile", set_enable_sendfile, NULL, OR_FILEINFO, /* Old server config file commands */ +AP_INIT_TAKE1("Protocol", set_protocol, NULL, RSRC_CONF, + "Set the Protocol for httpd to use."), AP_INIT_TAKE1("Port", ap_set_deprecated, NULL, RSRC_CONF, "Port was replaced with Listen in Apache 2.0"), AP_INIT_TAKE1("HostnameLookups", set_hostname_lookups, NULL, diff --git a/server/listen.c b/server/listen.c index 64b75054841..7adbef5cd0b 100644 --- a/server/listen.c +++ b/server/listen.c @@ -24,6 +24,7 @@ #include "ap_config.h" #include "httpd.h" #include "http_config.h" +#include "http_core.h" #include "ap_listen.h" #include "http_log.h" #include "mpm.h" @@ -218,7 +219,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) +static const char *alloc_listener(process_rec *process, char *addr, + apr_port_t port, const char* proto) { ap_listen_rec **walk, *last; apr_status_t status; @@ -279,6 +281,7 @@ static const char *alloc_listener(process_rec *process, char *addr, apr_port_t p new->active = 0; new->next = 0; new->bind_addr = sa; + new->protocol = apr_pstrdup(process->pool, proto); /* Go to the next sockaddr. */ sa = sa->next; @@ -451,8 +454,42 @@ static int open_listeners(apr_pool_t *pool) AP_DECLARE(int) ap_setup_listeners(server_rec *s) { + server_rec *ls; + server_addr_rec *addr; ap_listen_rec *lr; int num_listeners = 0; + const char* proto; + int nfound; + + for (ls = s; ls; ls = ls->next) { + proto = ap_get_server_protocol(ls); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,"%s proto: %s", ls->server_hostname, proto); + if (!proto) { + nfound = 1; + /* No protocol was set for this vhost, + * use the default for this listener. + */ + for (addr = ls->addrs; addr && nfound; addr = addr->next) { + for (lr = ap_listeners; lr; lr = lr->next) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,"%s compare proto: %s %d = %d", ls->server_hostname, lr->protocol, +addr->host_port, lr->bind_addr->port); + if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) && + lr->bind_addr->port == addr->host_port) { + ap_set_server_protocol(ls, lr->protocol); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,"%s match proto: %s", ls->server_hostname, lr->protocol); + nfound = 0; + break; + } + } + } + + if (nfound) { + /* TODO: set protocol defaults per-Port, eg 25=smtp */ + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,"%s dproto: http", ls->server_hostname); + ap_set_server_protocol(ls, "http"); + } + } + } if (open_listeners(s->process->pool)) { return 0; @@ -474,9 +511,9 @@ AP_DECLARE(void) ap_listen_pre_config(void) AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, - const char *ips) + int argc, char *const argv[]) { - char *host, *scope_id; + char *host, *scope_id, *proto; apr_port_t port; apr_status_t rv; const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); @@ -485,7 +522,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, return err; } - rv = apr_parse_addr_port(&host, &scope_id, &port, ips, cmd->pool); + if (argc < 1 || argc > 2) { + return "Listen requires 1 or 2 arguments."; + } + + rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool); if (rv != APR_SUCCESS) { return "Invalid address or port"; } @@ -503,7 +544,15 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, return "Port must be specified"; } - return alloc_listener(cmd->server->process, host, port); + if (argc != 2) { + proto = "http"; + } + else { + proto = apr_pstrdup(cmd->pool, argv[1]); + ap_str_tolower(proto); + } + + return alloc_listener(cmd->server->process, host, port, proto); } AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd,