diff options
author | Jim Jagielski <jim@apache.org> | 2014-06-03 15:07:29 +0200 |
---|---|---|
committer | Jim Jagielski <jim@apache.org> | 2014-06-03 15:07:29 +0200 |
commit | c539206da2d9e8d5d964e84c7497886c74f1a7f9 (patch) | |
tree | bf2d70a0adc86d730f516e93485c6ad913c03783 /server/mpm_unix.c | |
parent | mod_proxy_http: avoid (unlikely) access to freed memory. (diff) | |
download | apache2-c539206da2d9e8d5d964e84c7497886c74f1a7f9.tar.xz apache2-c539206da2d9e8d5d964e84c7497886c74f1a7f9.zip |
Optimize w/ duplicated listeners and use of SO_REUSEPORT
where available.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1599531 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/mpm_unix.c')
-rw-r--r-- | server/mpm_unix.c | 151 |
1 files changed, 77 insertions, 74 deletions
diff --git a/server/mpm_unix.c b/server/mpm_unix.c index 0000cb6672..97e3e65dff 100644 --- a/server/mpm_unix.c +++ b/server/mpm_unix.c @@ -615,6 +615,7 @@ static apr_status_t dummy_connection(ap_pod_t *pod) apr_pool_t *p; apr_size_t len; ap_listen_rec *lp; + int i; /* create a temporary pool for the socket. pconf stays around too long */ rv = apr_pool_create(&p, pod->p); @@ -626,87 +627,89 @@ static apr_status_t dummy_connection(ap_pod_t *pod) * plain-HTTP, not SSL; using an SSL port would either be * expensive to do correctly (performing a complete SSL handshake) * or cause log spam by doing incorrectly (simply sending EOF). */ - lp = ap_listeners; - while (lp && lp->protocol && strcasecmp(lp->protocol, "http") != 0) { - lp = lp->next; - } - if (!lp) { - lp = ap_listeners; - } + for (i = 0; i < num_buckets; i++) { + lp = mpm_listen[i]; + while (lp && lp->protocol && strcasecmp(lp->protocol, "http") != 0) { + lp = lp->next; + } + if (!lp) { + lp = mpm_listen[i]; + } - rv = apr_socket_create(&sock, lp->bind_addr->family, SOCK_STREAM, 0, p); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00054) - "get socket to connect to listener"); - apr_pool_destroy(p); - return rv; - } + rv = apr_socket_create(&sock, lp->bind_addr->family, SOCK_STREAM, 0, p); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00054) + "get socket to connect to listener"); + apr_pool_destroy(p); + return rv; + } - /* on some platforms (e.g., FreeBSD), the kernel won't accept many - * queued connections before it starts blocking local connects... - * we need to keep from blocking too long and instead return an error, - * because the MPM won't want to hold up a graceful restart for a - * long time - */ - rv = apr_socket_timeout_set(sock, apr_time_from_sec(3)); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00055) - "set timeout on socket to connect to listener"); - apr_socket_close(sock); - apr_pool_destroy(p); - return rv; - } + /* on some platforms (e.g., FreeBSD), the kernel won't accept many + * queued connections before it starts blocking local connects... + * we need to keep from blocking too long and instead return an error, + * because the MPM won't want to hold up a graceful restart for a + * long time + */ + rv = apr_socket_timeout_set(sock, apr_time_from_sec(3)); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00055) + "set timeout on socket to connect to listener"); + apr_socket_close(sock); + apr_pool_destroy(p); + return rv; + } - rv = apr_socket_connect(sock, lp->bind_addr); - if (rv != APR_SUCCESS) { - int log_level = APLOG_WARNING; - - if (APR_STATUS_IS_TIMEUP(rv)) { - /* probably some server processes bailed out already and there - * is nobody around to call accept and clear out the kernel - * connection queue; usually this is not worth logging - */ - log_level = APLOG_DEBUG; + rv = apr_socket_connect(sock, lp->bind_addr); + if (rv != APR_SUCCESS) { + int log_level = APLOG_WARNING; + + if (APR_STATUS_IS_TIMEUP(rv)) { + /* probably some server processes bailed out already and there + * is nobody around to call accept and clear out the kernel + * connection queue; usually this is not worth logging + */ + log_level = APLOG_DEBUG; + } + + ap_log_error(APLOG_MARK, log_level, rv, ap_server_conf, APLOGNO(00056) + "connect to listener on %pI", lp->bind_addr); + apr_pool_destroy(p); + return rv; } - ap_log_error(APLOG_MARK, log_level, rv, ap_server_conf, APLOGNO(00056) - "connect to listener on %pI", lp->bind_addr); - apr_pool_destroy(p); - return rv; - } + if (lp->protocol && strcasecmp(lp->protocol, "https") == 0) { + /* Send a TLS 1.0 close_notify alert. This is perhaps the + * "least wrong" way to open and cleanly terminate an SSL + * connection. It should "work" without noisy error logs if + * the server actually expects SSLv3/TLSv1. With + * SSLv23_server_method() OpenSSL's SSL_accept() fails + * ungracefully on receipt of this message, since it requires + * an 11-byte ClientHello message and this is too short. */ + static const unsigned char tls10_close_notify[7] = { + '\x15', /* TLSPlainText.type = Alert (21) */ + '\x03', '\x01', /* TLSPlainText.version = {3, 1} */ + '\x00', '\x02', /* TLSPlainText.length = 2 */ + '\x01', /* Alert.level = warning (1) */ + '\x00' /* Alert.description = close_notify (0) */ + }; + data = (const char *)tls10_close_notify; + len = sizeof(tls10_close_notify); + } + else /* ... XXX other request types here? */ { + /* Create an HTTP request string. We include a User-Agent so + * that adminstrators can track down the cause of the + * odd-looking requests in their logs. A complete request is + * used since kernel-level filtering may require that much + * data before returning from accept(). */ + data = apr_pstrcat(p, "OPTIONS * HTTP/1.0\r\nUser-Agent: ", + ap_get_server_description(), + " (internal dummy connection)\r\n\r\n", NULL); + len = strlen(data); + } - if (lp->protocol && strcasecmp(lp->protocol, "https") == 0) { - /* Send a TLS 1.0 close_notify alert. This is perhaps the - * "least wrong" way to open and cleanly terminate an SSL - * connection. It should "work" without noisy error logs if - * the server actually expects SSLv3/TLSv1. With - * SSLv23_server_method() OpenSSL's SSL_accept() fails - * ungracefully on receipt of this message, since it requires - * an 11-byte ClientHello message and this is too short. */ - static const unsigned char tls10_close_notify[7] = { - '\x15', /* TLSPlainText.type = Alert (21) */ - '\x03', '\x01', /* TLSPlainText.version = {3, 1} */ - '\x00', '\x02', /* TLSPlainText.length = 2 */ - '\x01', /* Alert.level = warning (1) */ - '\x00' /* Alert.description = close_notify (0) */ - }; - data = (const char *)tls10_close_notify; - len = sizeof(tls10_close_notify); - } - else /* ... XXX other request types here? */ { - /* Create an HTTP request string. We include a User-Agent so - * that adminstrators can track down the cause of the - * odd-looking requests in their logs. A complete request is - * used since kernel-level filtering may require that much - * data before returning from accept(). */ - data = apr_pstrcat(p, "OPTIONS * HTTP/1.0\r\nUser-Agent: ", - ap_get_server_description(), - " (internal dummy connection)\r\n\r\n", NULL); - len = strlen(data); + apr_socket_send(sock, data, &len); + apr_socket_close(sock); } - - apr_socket_send(sock, data, &len); - apr_socket_close(sock); apr_pool_destroy(p); return rv; |