Commit 13978f5c authored by Yann Ylavic's avatar Yann Ylavic
Browse files

Merge r1572630, r1572611, r1572967, r1573229 from trunk:

Redo what was reverted in r1572627.
Don't reuse a SSL backend connection whose SNI differs. PR 55782.
This may happen when ProxyPreserveHost is on and the proxy-worker
handles connections to different Hosts.


Follows up r1572606.
MMN minor bump required by proxy_conn_rec change.


mod_proxy: follows up r1572630.
Don't reuse a SSL backend connection with no SNI for a request requiring SNI.


mod_proxy: Add comment and avoid ternary operator as condition (no functional change).


Submitted by: ylavic
Reviewed by: ylavic, rpluem, wrowe


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1611813 13f79535-47bb-0310-9956-ffa450edef68
parent 01b9a3cd
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@
 * 20051115.32 (2.2.24) Add ap_get_exec_line
 * 20051115.33 (2.2.24) Add ap_pregsub_ex()
 * 20051115.34 (2.2.28) Add ap_copy_scoreboard_worker()
 * 20051115.35 (2.2.27) Add SSL reusable SNI to mod_proxy.h's proxy_conn_rec
 */

#define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */
@@ -159,7 +160,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20051115
#endif
#define MODULE_MAGIC_NUMBER_MINOR 34                    /* 0...n */
#define MODULE_MAGIC_NUMBER_MINOR 35                    /* 0...n */

/**
 * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
+1 −0
Original line number Diff line number Diff line
@@ -248,6 +248,7 @@ typedef struct {
    int          need_flush;/* Flag to decide whether we need to flush the
                             * filter chain or not */
    void         *forward;  /* opaque forward proxy data */
    const char   *ssl_hostname;/* Hostname (SNI) in use by SSL connection */
} proxy_conn_rec;

typedef struct {
+4 −17
Original line number Diff line number Diff line
@@ -2028,23 +2028,10 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
         * requested, such that mod_ssl can check if it is requested to do
         * so.
         */
        if (is_ssl) {
            const char *ssl_hostname;

            /*
             * In the case of ProxyPreserveHost on use the hostname of
             * the request if present otherwise use the one from the
             * backend request URI.
             */
            if ((conf->preserve_host != 0) && (r->hostname != NULL)) {
                ssl_hostname = r->hostname;
            }
            else {
                ssl_hostname = uri->hostname;
            }

            apr_table_set(backend->connection->notes, "proxy-request-hostname",
                          ssl_hostname);
        if (backend->ssl_hostname) {
            apr_table_setn(backend->connection->notes,
                           "proxy-request-hostname",
                           backend->ssl_hostname);
        }
    }

+33 −0
Original line number Diff line number Diff line
@@ -1698,6 +1698,7 @@ static void socket_cleanup(proxy_conn_rec *conn)
{
    conn->sock = NULL;
    conn->connection = NULL;
    conn->ssl_hostname = NULL;
    apr_pool_clear(conn->scpool);
}

@@ -2197,6 +2198,38 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
        return ap_proxyerror(r, HTTP_FORBIDDEN,
                             "Connect to remote machine blocked");
    }
    /*
     * When SSL is configured, determine the hostname (SNI) for the request
     * and save it in conn->ssl_hostname. Close any reused connection whose
     * SNI differs.
     */
    if (conn->is_ssl) {
        const char *ssl_hostname;
        /*
         * In the case of ProxyPreserveHost on use the hostname of
         * the request if present otherwise use the one from the
         * backend request URI.
         */
        if (conf->preserve_host) {
            ssl_hostname = r->hostname;
        }
        else {
            ssl_hostname = conn->hostname;
        }
        /*
         * Close if a SNI is in use but this request requires no or
         * a different one, or no SNI is in use but one is required.
         */
        if ((conn->ssl_hostname && (!ssl_hostname ||
                                    strcasecmp(conn->ssl_hostname,
                                               ssl_hostname) != 0)) ||
                (!conn->ssl_hostname && ssl_hostname && conn->sock)) {
            socket_cleanup(conn);
        }
        if (conn->ssl_hostname == NULL) {
            conn->ssl_hostname = apr_pstrdup(conn->scpool, ssl_hostname);
        }
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                 "proxy: connected %s to %s:%d", *url, conn->hostname,
                 conn->port);