From: Willy Tarreau Date: Wed, 19 Dec 2018 13:36:29 +0000 (+0100) Subject: MINOR: connection: remove an unwelcome dependency on struct stream X-Git-Tag: v1.9.0~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=94031d30d71eea0fcb4e7a29388e62ee151a7ddf;p=thirdparty%2Fhaproxy.git MINOR: connection: remove an unwelcome dependency on struct stream There was a reference to struct stream in conn_free() for the case where we're freeing a connection that doesn't have a mux attached. For now we know it's always a stream, and we only need to do it to put a NULL in s->si[1].end. Let's do it better by storing the pointer to si[1].end in the context and specifying that this pointer is always nulled if the mux is null. This way it allows a connection to detach itself from wherever it's being used. Maybe we could even get rid of the condition on the mux. --- diff --git a/include/proto/connection.h b/include/proto/connection.h index 441b51df00..a7b596a50f 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -669,15 +669,14 @@ static inline void conn_free(struct connection *conn) sess->resp_conns--; LIST_DEL(&conn->session_list); } - /* If we temporarily stored the connection as the stream_interface's - * end point, remove it. + + /* By convention we always place a NULL where the ctx points to if the + * mux is null. It may have been used to store the connection as a + * stream_interface's end point for example. */ - if (conn->ctx != NULL && conn->mux == NULL) { - struct stream *s = conn->ctx; + if (conn->ctx != NULL && conn->mux == NULL) + *(void **)conn->ctx = NULL; - if (objt_conn(s->si[1].end) == conn) - s->si[1].end = NULL; - } /* The connection is currently in the server's idle list, so tell it * there's one less connection available in that list. */ diff --git a/src/backend.c b/src/backend.c index 237668cc43..2407f8a32e 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1052,12 +1052,13 @@ static void assign_tproxy_address(struct stream *s) #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation) /* * Pick the right mux once the connection is established, we should now have - * an alpn if available, so we are now able to choose. + * an alpn if available, so we are now able to choose. In this specific case + * the connection's context is &si[i].end. */ static int conn_complete_server(struct connection *conn) { struct conn_stream *cs = NULL; - struct stream *s = conn->ctx; + struct stream *s = container_of(conn->ctx, struct stream, si[1].end); struct server *srv; task_wakeup(s->task, TASK_WOKEN_IO); @@ -1066,8 +1067,6 @@ static int conn_complete_server(struct connection *conn) if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED)))) conn->flags |= CO_FL_CONNECTED; - if (!s) - goto fail; if (conn->flags & CO_FL_ERROR) goto fail; si_detach_endpoint(&s->si[1]); @@ -1338,7 +1337,7 @@ int connect_server(struct stream *s) } #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation) else { - srv_conn->ctx = s; + srv_conn->ctx = &s->si[1].end; /* Store the connection into the stream interface, * while we still don't have a mux, so that if the * stream is destroyed before the connection is