]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: connection: add a flag to hold the transport layer
authorWilly Tarreau <w@1wt.eu>
Fri, 12 Oct 2012 15:50:05 +0000 (17:50 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 12 Oct 2012 18:30:50 +0000 (20:30 +0200)
When we start logging SSL information, we need the SSL struct to be
present even past the conn_xprt_close() call. In order to achieve this,
we should use refcounting on the connection and the transport layer. At
the moment it's not worth using plain refcounting as only the logs require
this, so instead of real refcounting we just use a flag which will be set
by the log subsystem when SSL data need to be logged.

What happens then is that the xprt->close() call is ignored and the
transport layer is closed again during session_free(), after the log
line is emitted.

include/proto/connection.h
include/types/connection.h
src/session.c

index ff63e03ccad40407d4cb1e125cdf007eef8fb428..52b547c195daa8f3f0602e72bae89eb8dcae32e0 100644 (file)
@@ -46,11 +46,13 @@ static inline int conn_xprt_init(struct connection *conn)
 }
 
 /* Calls the close() function of the transport layer if any, and always unsets
- * the transport layer.
+ * the transport layer. However this is not done if the CO_FL_XPRT_TRACKED flag
+ * is set, which allows logs to take data from the transport layer very late if
+ * needed.
  */
 static inline void conn_xprt_close(struct connection *conn)
 {
-       if (conn->xprt) {
+       if (conn->xprt && !(conn->flags & CO_FL_XPRT_TRACKED)) {
                if (conn->xprt->close)
                        conn->xprt->close(conn);
                conn->xprt = NULL;
index 35ce1f5ab1ab05e1e00f65a0254e22c34ab09046..5803c2c2ec41102c83f6651e3cdc494840bb4600 100644 (file)
@@ -145,6 +145,12 @@ enum {
         * as DATA or SOCK on some implementations.
         */
        CO_FL_POLL_SOCK     = CO_FL_HANDSHAKE | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN,
+
+       /* This last flag indicates that the transport layer is used (for instance
+        * by logs) and must not be cleared yet. The last call to conn_xprt_close()
+        * must be done after clearing this flag.
+        */
+       CO_FL_XPRT_TRACKED  = 0x80000000,
 };
 
 /* target types */
index ba074c8cc39b74140c479ef7c9b5d8411871314a..7c218bf80315f77d108d98a4a9e301966000b170 100644 (file)
@@ -548,6 +548,10 @@ static void session_free(struct session *s)
 
        http_end_txn(s);
 
+       /* ensure the client-side transport layer is destroyed */
+       s->si[0].conn.flags &= ~CO_FL_XPRT_TRACKED;
+       conn_xprt_close(&s->si[0].conn);
+
        for (i = 0; i < s->store_count; i++) {
                if (!s->store[i].ts)
                        continue;