You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Yann Ylavic <yl...@gmail.com> on 2014/01/07 14:40:37 UTC

Proxy SSL connections shutdown

Helo,

when mod_proxy terminates its backend connections (by clearing the scpool),
it does not send/ack any "Close Notify" to the backend, leaving the
negociated session possibly in an undefined state (is it?) on the backend.

The following patch will register a cleanup on the scpool to do a (short)
lingering close on the conn_rec when the pool is cleared/destroyed.

The lingering close will cause mod_ssl's flush/shutdown filters to run and
the remaining SSL data to be read from peer, including "Close Notify" and
ack, before the socket is closed.

Since mod_proxy does not reuse sessions either, maybe the sessions could be
invalidated before/with? "Close Notify", but I don't know if I can/how to
do that with OpenSSL.

Consideration is that the close may now take longer time (up to 2s with
"short-lingering-close" set), occur on reslist maintenance or before the
response is sent to the client when the backend's connection is not to be
kept alive.

Actually the patch does the lingering close only for SSL connections
(established), maybe it could be done for plain connections too (like on
the client side), and the cleanup be registered unconditionnaly.

Regards,
Yann.

Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c    (revision 1556194)
+++ modules/proxy/proxy_util.c    (working copy)
@@ -2738,6 +2738,27 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const
     return connected ? OK : DECLINED;
 }

+static apr_status_t lingering_cleanup(void *theconn)
+{
+    proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
+
+    if (conn->connection) {
+        /* XXX: should this really be limited to SSL */
+        if (!conn->connection->aborted && conn->is_ssl) {
+            apr_table_setn(conn->connection->notes,
+                           "short-lingering-close", "1");
+            ap_lingering_close(conn->connection);
+            conn->connection->aborted = 1;
+        }
+
+        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, conn->connection,
+                      "proxy: connection closed");
+    }
+
+    return APR_SUCCESS;
+}
+
+
 PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
                                               proxy_conn_rec *conn,
                                               conn_rec *c,
@@ -2810,6 +2831,12 @@ PROXY_DECLARE(int) ap_proxy_connection_create(cons
     }
     apr_socket_timeout_set(conn->sock, current_timeout);

+    /* Do a lingering close on the connection when needed.
+     * (SSL connections for example need to be "Close Notify"ed).
+     */
+    apr_pool_cleanup_register(conn->scpool, conn, lingering_cleanup,
+                              apr_pool_cleanup_null);
+
     return OK;
 }
 [EOS]