Return-Path: X-Original-To: apmail-httpd-dev-archive@www.apache.org Delivered-To: apmail-httpd-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 35F2210D50 for ; Tue, 7 Jan 2014 13:41:22 +0000 (UTC) Received: (qmail 72604 invoked by uid 500); 7 Jan 2014 13:41:15 -0000 Delivered-To: apmail-httpd-dev-archive@httpd.apache.org Received: (qmail 72483 invoked by uid 500); 7 Jan 2014 13:41:07 -0000 Mailing-List: contact dev-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list dev@httpd.apache.org Received: (qmail 72448 invoked by uid 99); 7 Jan 2014 13:41:04 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Jan 2014 13:41:04 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of ylavic.dev@gmail.com designates 209.85.223.170 as permitted sender) Received: from [209.85.223.170] (HELO mail-ie0-f170.google.com) (209.85.223.170) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Jan 2014 13:40:58 +0000 Received: by mail-ie0-f170.google.com with SMTP id qd12so352741ieb.1 for ; Tue, 07 Jan 2014 05:40:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=kBx8WYcUyZ2g1ZKbibFhigTSoUrTFHpAiFg47U7VcQc=; b=fgbKmuRjDj2ljoD6/ngTewp4h3o4slhTteQ8MeukQTtLn5I3CfNpB9rDHBgD6E18kv swYnMjCcsOjNG4jezExfIrLQG+yShmojWwIMSdWVuirGW2hKj967pnuDjoMoNmMGWPAM vkC0UEF8xF5EJUQZa+GTviaBguR1eJqDf4vU0Me9kpWAaKuhGmc45H8aouTnz5pczsoF hbWb5YHSwLQ+vnPlnQzqt7UzLPdNpjAmDecBN7Z5Skjhf+s/mlNdYGSnHHq1gkhB82Oq IWzDabj8H423I6R+/Z1LxTjGPpLKOtUFtCnXeozM3dTJ9XxQ17lrBcYAB/g8ZD2p5uXG W0dA== MIME-Version: 1.0 X-Received: by 10.42.65.73 with SMTP id k9mr27100863ici.44.1389102037906; Tue, 07 Jan 2014 05:40:37 -0800 (PST) Received: by 10.43.60.205 with HTTP; Tue, 7 Jan 2014 05:40:37 -0800 (PST) Date: Tue, 7 Jan 2014 14:40:37 +0100 Message-ID: Subject: Proxy SSL connections shutdown From: Yann Ylavic To: httpd Content-Type: multipart/alternative; boundary=90e6ba3fcd1786b9e504ef618563 X-Virus-Checked: Checked by ClamAV on apache.org --90e6ba3fcd1786b9e504ef618563 Content-Type: text/plain; charset=ISO-8859-1 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] --90e6ba3fcd1786b9e504ef618563 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Helo,

when mod_proxy terminates its b= ackend 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 d= o a (short) lingering close on the conn_rec when the pool is cleared/destro= yed.

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

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

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

Actually the patch does the lingering close only for=A0SSL con= nections (established), maybe it could be done for plain connections too (l= ike on the client side), and the cleanup be registered unconditionnaly.

Regards,
Yann.

Index: modules/proxy/proxy_util.c
=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- modules/proxy/proxy_util.c=A0= =A0=A0 (revision 1556194)
+++ modules/proxy/proxy_util.c=A0=A0=A0 (working copy)
@@ -2738,6 +2738,= 27 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const
=A0=A0=A0=A0 ret= urn connected ? OK : DECLINED;
=A0}
=A0
+static apr_status_t linge= ring_cleanup(void *theconn)
+{
+=A0=A0=A0 proxy_conn_rec *conn =3D (proxy_conn_rec *)theconn;
++=A0=A0=A0 if (conn->connection) {
+=A0=A0=A0=A0=A0=A0=A0 /* XXX: s= hould this really be limited to SSL */
+=A0=A0=A0=A0=A0=A0=A0 if (!conn-= >connection->aborted && conn->is_ssl) {
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 apr_table_setn(conn->connection->n= otes,
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 "short-lingering-close", "1");
+=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ap_lingering_close(conn->connection);
= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 conn->connection->aborted =3D 1; +=A0=A0=A0=A0=A0=A0=A0 }
+
+=A0=A0=A0=A0=A0=A0=A0 ap_log_cerror(APLOG= _MARK, APLOG_INFO, 0, conn->connection,
+=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "proxy: connection closed");=
+=A0=A0=A0 }
+
+=A0=A0=A0 return APR_SUCCESS;
+}
+
+
= =A0PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function= ,
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 proxy_conn_= rec *conn,
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 conn_rec *c,
@@ -2810,6 +2831,12 @@ PROXY_DECLARE(int) ap_proxy_conn= ection_create(cons
=A0=A0=A0=A0 }
=A0=A0=A0=A0 apr_socket_timeout_set(conn->sock, current_timeout);
=A0=
+=A0=A0=A0 /* Do a lingering close on the connection when needed.
+= =A0=A0=A0=A0 * (SSL connections for example need to be "Close Notify&q= uot;ed).
+=A0=A0=A0=A0 */
+=A0=A0=A0 apr_pool_cleanup_register(conn->scpool, conn, lingering_clean= up,
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0 apr_pool_cleanup_null);
+
=A0=A0=A0=A0 return O= K;
=A0}
=A0[EOS]
--90e6ba3fcd1786b9e504ef618563--