diff --git a/include/proto/connection.h b/include/proto/connection.h index ff63e03cc..52b547c19 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -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; diff --git a/include/types/connection.h b/include/types/connection.h index 35ce1f5ab..5803c2c2e 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -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 */ diff --git a/src/session.c b/src/session.c index ba074c8cc..7c218bf80 100644 --- a/src/session.c +++ b/src/session.c @@ -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;