]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: streams: Always create a conn_stream in connect_server().
authorOlivier Houchard <ohouchard@haproxy.com>
Wed, 22 Jan 2020 16:34:54 +0000 (17:34 +0100)
committerOlivier Houchard <cognet@ci0.org>
Wed, 22 Jan 2020 17:55:59 +0000 (18:55 +0100)
In connect_server(), when creating a new connection for which we don't yet
know the mux (because it'll be decided by the ALPN), instead of associating
the connection to the stream_interface, always create a conn_stream. This way,
we have less special-casing needed. Store the conn_stream in conn->ctx,
so that we can reach the upper layers if needed.

include/proto/stream_interface.h
src/backend.c
src/stream_interface.c

index c0f88b265c59b74fe651549d80c72946f9ab84c3..d1e228b0927a1603f367d646a1fe4940c5255fb0 100644 (file)
@@ -172,7 +172,6 @@ static inline enum obj_type *si_detach_endpoint(struct stream_interface *si)
  */
 static inline void si_release_endpoint(struct stream_interface *si)
 {
-       struct connection *conn;
        struct conn_stream *cs;
        struct appctx *appctx;
 
@@ -189,10 +188,6 @@ static inline void si_release_endpoint(struct stream_interface *si)
                if (appctx->applet->release && !si_state_in(si->state, SI_SB_DIS|SI_SB_CLO))
                        appctx->applet->release(appctx);
                appctx_free(appctx);
-       } else if ((conn = objt_conn(si->end))) {
-               conn_stop_tracking(conn);
-               conn_full_close(conn);
-               conn_free(conn);
        }
        si_detach_endpoint(si);
 }
@@ -478,7 +473,7 @@ static inline int si_sync_recv(struct stream_interface *si)
                return 0;
 
        cs = objt_cs(si->end);
-       if (!cs)
+       if (!cs || !cs->conn->mux)
                return 0; // only conn_streams are supported
 
        if (si->wait_event.events & SUB_RETRY_RECV)
index 0a91a6875664c128299cd82be61f5a0b894beb84..4bb30adfb955bb242eae486bf01482a894244207 100644 (file)
@@ -1083,7 +1083,8 @@ static void assign_tproxy_address(struct stream *s)
  */
 static int conn_complete_server(struct connection *conn)
 {
-       struct stream *s = container_of(conn->ctx, struct stream, si[1].end);
+       struct conn_stream *cs = conn->ctx;
+       struct stream *s = si_strm((struct stream_interface *)cs->data);
 
        task_wakeup(s->task, TASK_WOKEN_IO);
        conn_clear_xprt_done_cb(conn);
@@ -1408,32 +1409,20 @@ int connect_server(struct stream *s)
                        return SF_ERR_INTERNAL;  /* how did we get there ? */
 
 #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
+               srv_cs = si_alloc_cs(&s->si[1], srv_conn);
+               if (!srv_cs) {
+                       conn_free(srv_conn);
+                       return SF_ERR_RESOURCE;
+               }
+               srv_conn->ctx = srv_cs;
                if (!srv ||
                    ((!(srv->ssl_ctx.alpn_str) && !(srv->ssl_ctx.npn_str)) ||
                    srv->mux_proto || s->be->mode != PR_MODE_HTTP))
 #endif
-               {
-                       srv_cs = objt_cs(s->si[1].end);
-                       if (!srv_cs || srv_cs->conn != srv_conn)
-                               srv_cs = si_alloc_cs(&s->si[1], srv_conn);
-                       if (!srv_cs) {
-                               conn_free(srv_conn);
-                               return SF_ERR_RESOURCE;
-                       }
                        init_mux = 1;
-               }
 #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
-               else {
-                       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
-                        * established, we have a chance to destroy it even
-                        * if it is no longer referenced in the session.
-                        */
-                       s->si[1].end = &srv_conn->obj_type;
+               else
                        conn_set_xprt_done_cb(srv_conn, conn_complete_server);
-               }
 
 #endif
                /* process the case where the server requires the PROXY protocol to be sent */
@@ -1978,10 +1967,6 @@ void back_handle_st_con(struct stream *s)
 
                if (conn->flags & CO_FL_ERROR)
                        goto fail;
-               si_detach_endpoint(&s->si[1]);
-               srv_cs = si_alloc_cs(&s->si[1], conn);
-               if (!srv_cs)
-                       goto fail;
                if (conn_install_mux_be(conn, srv_cs, s->sess) < 0)
                        goto fail;
                srv = objt_server(s->target);
@@ -1991,16 +1976,7 @@ void back_handle_st_con(struct stream *s)
                goto done;
 
        fail:
-               si_detach_endpoint(&s->si[1]);
-               if (srv_cs)
-                       cs_free(srv_cs);
-               /* kill the connection now */
-               conn_stop_tracking(conn);
-               conn_full_close(conn);
-               conn_free(conn);
-               conn = NULL;
-               /* Let process_stream know it went wrong */
-               s->si[1].flags |= SI_FL_ERR;
+               si_release_endpoint(&s->si[1]);
        }
 
  done:
index ba82cae94552b9dec040e1d2a16b9bca18246cee..e1c51f4d731e30c18344f2a397c5776f90120e95 100644 (file)
@@ -923,7 +923,7 @@ void si_sync_send(struct stream_interface *si)
                return;
 
        cs = objt_cs(si->end);
-       if (!cs)
+       if (!cs || !cs->conn->mux)
                return;
 
        si_cs_send(cs);