From ec95d72c5aa71899d6a833aff6c580296bb0011f Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Mon, 16 Jun 2014 20:26:24 +0000 Subject: [PATCH] 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. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1602989 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 5 ++- include/ap_mmn.h | 3 +- modules/proxy/mod_proxy.h | 11 ++++++ modules/proxy/mod_proxy_fdpass.c | 57 +------------------------------- modules/proxy/proxy_util.c | 41 +++++++++++------------ 5 files changed, 38 insertions(+), 79 deletions(-) diff --git a/CHANGES b/CHANGES index 1224ad2ab8..7a76a10178 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_proxy: Don't limit the size of the connectable Unix Domain Socket + paths. [Christophe Jaillet, Yann Ylavic] + *) mod_ssl: dump SSL IO/state for the write side of the connection(s), like reads (level TRACE4). [Yann Ylavic] @@ -31,7 +34,7 @@ Changes with Apache 2.5.0 PR 56286 [Micha Lenk ] *) mod_proxy_fdpass: Fix computation of the size of 'struct sockaddr_un' - when passed to 'connec()'. + when passed to 'connect()'. [Graham Dumpleton ] *) mod_socache_shmcb: Correct counting of expirations for status display. diff --git a/include/ap_mmn.h b/include/ap_mmn.h index a75342a0ee..7c84de1188 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -461,6 +461,7 @@ Changes 3rd argument's type of ap_mpm_register_socket_callback and ap_mpm_register_socket_callback_timeout. + * 20140611.1 (2.5.0-dev) Add ap_proxy_connect_uds(). */ #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */ @@ -468,7 +469,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20140611 #endif -#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 1 /* 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 3e63e24560..b6aafd9246 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -874,6 +874,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 1e52d677a2..63cf469664 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,56 +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 !!! */ -/* XXX: The same function exists in proxy_util.c */ -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 { - 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); - - 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; @@ -114,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 8e2942f1a1..2e34bfa7f9 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -2550,13 +2550,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) { @@ -2568,29 +2571,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 @@ -2623,8 +2627,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) { @@ -2638,10 +2640,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) -- 2.40.0