From: Jim Jagielski Date: Mon, 12 Jan 2015 13:36:17 +0000 (+0000) Subject: Merge r1598946, r1602989 from trunk: X-Git-Tag: 2.4.11~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1c7176efd1d1fca7d0c970114cf9066e5ff29e9a;p=thirdparty%2Fapache%2Fhttpd.git Merge r1598946, r1602989 from trunk: Fix computation of the size of 'struct sockaddr_un' when passed to 'connect()'. Use the same logic as the one in ' in 'proxy_util.c'. mod_proxy: Don't limit the size of the connectable Unix Domain Socket paths. Since connect() to UDS path is used at several places, introduce ap_proxy_connect_uds() in proxy_util. Submitted by: jailletc36, ylavic Reviewed/backported by: jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1651081 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 324a86604ea..a7757b68533 100644 --- a/CHANGES +++ b/CHANGES @@ -238,6 +238,9 @@ Changes with Apache 2.4.10 *) mod_proxy_balancer: Correctly encode user provided data in management interface. PR 56532 [Maksymilian, ] + *) mod_proxy: Don't limit the size of the connectable Unix Domain Socket + paths. [Graham Dumpleton, Christophe Jaillet, Yann Ylavic] + *) mod_proxy_fcgi: Support iobuffersize parameter. [Jeff Trawick] *) event: Send the SSL close notify alert when the KeepAliveTimeout diff --git a/STATUS b/STATUS index f5d0093c609..4de2e7d181b 100644 --- a/STATUS +++ b/STATUS @@ -138,23 +138,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: 2.4.x patch: trunk works (modulo CHANGES) +1: ylavic, rjung, covener - * mod_proxy: Don't limit the size of the connectable Unix Domain Socket paths. - [Graham Dumpleton, Christophe Jaillet, Yann Ylavic] - trunk patch: http://svn.apache.org/r1598946 - http://svn.apache.org/r1602989 - 2.4.x patch: http://people.apache.org/~ylavic/httpd-2.4.x-ap_proxy_connect_uds.patch - (modulo CHANGES/MMN) - +1: ylavic, jim, covener - - * mod_proxy: Shutdown (eg. SSL close notify) the backend connection before closing. - trunk patch: http://svn.apache.org/r1601291 - http://svn.apache.org/r1601630 - 2.4.x patch: http://people.apache.org/~ylavic/httpd-2.4.x-proxy-SSL-shutdown.patch - (modulo CHANGES) - note: depends on ap_shutdown_conn() from r1601185 above. - +1: ylavic, rjung, covener - - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 7a278b9c227..633e0520518 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -434,6 +434,7 @@ * 20120211.36 (2.4.10-dev) Add ap_copy_scoreboard_worker() * 20120211.37 (2.4.11-dev) Add r->trailers_{in,out} * 20120211.38 (2.4.10-dev) Added ap_shutdown_conn(). + * 20120211.39 (2.4.10-dev) Add ap_proxy_connect_uds(). */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -441,7 +442,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120211 #endif -#define MODULE_MAGIC_NUMBER_MINOR 38 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 39 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 4ead22e7018..5b3473b0297 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -865,6 +865,17 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, proxy_conn_rec *conn, proxy_worker *worker, server_rec *s); + +/** + * Make a connection to a Unix Domain Socket (UDS) path + * @param sock UDS to connect + * @param uds_path UDS path to connect to + * @param p pool to make the sock addr + * @return APR_SUCCESS or error status + */ +PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(apr_socket_t *sock, + const char *uds_path, + apr_pool_t *p); /** * Make a connection record for backend connection * @param proxy_function calling proxy scheme (http, ajp, ...) diff --git a/modules/proxy/mod_proxy_fdpass.c b/modules/proxy/mod_proxy_fdpass.c index 26a7b13e53c..63cf469664c 100644 --- a/modules/proxy/mod_proxy_fdpass.c +++ b/modules/proxy/mod_proxy_fdpass.c @@ -24,12 +24,6 @@ #error This module only works on unix platforms with the correct OS support #endif -#include "apr_version.h" -#if APR_MAJOR_VERSION < 2 -/* for apr_wait_for_io_or_timeout */ -#include "apr_support.h" -#endif - #include "mod_proxy_fdpass.h" module AP_MODULE_DECLARE_DATA proxy_fdpass_module; @@ -54,54 +48,10 @@ static int proxy_fdpass_canon(request_rec *r, char *url) return OK; } -/* TODO: In APR 2.x: Extend apr_sockaddr_t to possibly be a path !!! */ -static apr_status_t socket_connect_un(apr_socket_t *sock, - struct sockaddr_un *sa) -{ - apr_status_t rv; - apr_os_sock_t rawsock; - apr_interval_time_t t; - - rv = apr_os_sock_get(&rawsock, sock); - if (rv != APR_SUCCESS) { - return rv; - } - - rv = apr_socket_timeout_get(sock, &t); - if (rv != APR_SUCCESS) { - return rv; - } - - do { - rv = connect(rawsock, (struct sockaddr*)sa, - sizeof(*sa) + strlen(sa->sun_path)); - } while (rv == -1 && errno == EINTR); - - if ((rv == -1) && (errno == EINPROGRESS || errno == EALREADY) - && (t > 0)) { -#if APR_MAJOR_VERSION < 2 - rv = apr_wait_for_io_or_timeout(NULL, sock, 0); -#else - rv = apr_socket_wait(sock, APR_WAIT_WRITE); -#endif - - if (rv != APR_SUCCESS) { - return rv; - } - } - - if (rv == -1 && errno != EISCONN) { - return errno; - } - - return APR_SUCCESS; -} - static apr_status_t get_socket_from_path(apr_pool_t *p, const char* path, apr_socket_t **out_sock) { - struct sockaddr_un sa; apr_socket_t *s; apr_status_t rv; *out_sock = NULL; @@ -112,10 +62,7 @@ static apr_status_t get_socket_from_path(apr_pool_t *p, return rv; } - sa.sun_family = AF_UNIX; - apr_cpystrn(sa.sun_path, path, sizeof(sa.sun_path)); - - rv = socket_connect_un(s, &sa); + rv = ap_proxy_connect_uds(s, path, p); if (rv != APR_SUCCESS) { return rv; } diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index d89f44be087..3e74ec9ce0b 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -2558,13 +2558,16 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend, #if APR_HAVE_SYS_UN_H -/* lifted from mod_proxy_fdpass.c; tweaked addrlen in connect() call */ -static apr_status_t socket_connect_un(apr_socket_t *sock, - struct sockaddr_un *sa) +/* TODO: In APR 2.x: Extend apr_sockaddr_t to possibly be a path !!! */ +PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(apr_socket_t *sock, + const char *uds_path, + apr_pool_t *p) { apr_status_t rv; apr_os_sock_t rawsock; apr_interval_time_t t; + struct sockaddr_un *sa; + apr_socklen_t addrlen, pathlen; rv = apr_os_sock_get(&rawsock, sock); if (rv != APR_SUCCESS) { @@ -2576,29 +2579,30 @@ static apr_status_t socket_connect_un(apr_socket_t *sock, return rv; } + pathlen = strlen(uds_path); + /* copy the UDS path (including NUL) to the sockaddr_un */ + addrlen = APR_OFFSETOF(struct sockaddr_un, sun_path) + pathlen; + sa = (struct sockaddr_un *)apr_palloc(p, addrlen + 1); + memcpy(sa->sun_path, uds_path, pathlen + 1); + sa->sun_family = AF_UNIX; + do { - const socklen_t addrlen = APR_OFFSETOF(struct sockaddr_un, sun_path) - + strlen(sa->sun_path) + 1; rv = connect(rawsock, (struct sockaddr*)sa, addrlen); - } while (rv == -1 && errno == EINTR); + } while (rv == -1 && (rv = errno) == EINTR); - if ((rv == -1) && (errno == EINPROGRESS || errno == EALREADY) - && (t > 0)) { + if (rv && rv != EISCONN) { + if ((rv == EINPROGRESS || rv == EALREADY) && (t > 0)) { #if APR_MAJOR_VERSION < 2 - rv = apr_wait_for_io_or_timeout(NULL, sock, 0); + rv = apr_wait_for_io_or_timeout(NULL, sock, 0); #else - rv = apr_socket_wait(sock, APR_WAIT_WRITE); + rv = apr_socket_wait(sock, APR_WAIT_WRITE); #endif - + } if (rv != APR_SUCCESS) { return rv; } } - if (rv == -1 && errno != EISCONN) { - return errno; - } - return APR_SUCCESS; } #endif @@ -2631,8 +2635,6 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, #if APR_HAVE_SYS_UN_H if (conn->uds_path) { - struct sockaddr_un sa; - rv = apr_socket_create(&newsock, AF_UNIX, SOCK_STREAM, 0, conn->scpool); if (rv != APR_SUCCESS) { @@ -2646,10 +2648,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, } conn->connection = NULL; - sa.sun_family = AF_UNIX; - apr_cpystrn(sa.sun_path, conn->uds_path, sizeof(sa.sun_path)); - - rv = socket_connect_un(newsock, &sa); + rv = ap_proxy_connect_uds(newsock, conn->uds_path, conn->scpool); if (rv != APR_SUCCESS) { apr_socket_close(newsock); ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02454)