]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: conn-stream: Be prepared to fail to attach a cs to a mux
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 31 Mar 2022 17:27:18 +0000 (19:27 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 13 Apr 2022 13:10:15 +0000 (15:10 +0200)
To be able to move wait_event from the stream-interface to the conn-stream,
we must be prepare to handle errors when a mux is attached to a conn-stream.
Indeed, the wait_event's tasklet will be allocated when both a mux and a
stream will be both attached to a stream. So, we must be prepared to handle
allocation errors.

include/haproxy/conn_stream.h
src/backend.c
src/conn_stream.c
src/mux_fcgi.c
src/mux_h1.c
src/mux_h2.c
src/mux_pt.c
src/tcpcheck.c

index 98921aae5892810f239b794e6472732198670272..441146989e61090cde467f10230b08ff21f9b72c 100644 (file)
@@ -46,7 +46,7 @@ struct conn_stream *cs_new_from_strm(struct stream *strm, unsigned int flags);
 struct conn_stream *cs_new_from_check(struct check *check, unsigned int flags);
 void cs_free(struct conn_stream *cs);
 
-void cs_attach_mux(struct conn_stream *cs, void *target, void *ctx);
+int cs_attach_mux(struct conn_stream *cs, void *target, void *ctx);
 void cs_attach_applet(struct conn_stream *cs, void *target, void *ctx);
 int cs_attach_strm(struct conn_stream *cs, struct stream *strm);
 
index ea27b8c4a0c223a140ecec1aecce64b21ef7d4cc..65ded4bd1c1199b1701a4bf19ef557c2660a4376 100644 (file)
@@ -1611,7 +1611,10 @@ skip_reuse:
                        return SF_ERR_INTERNAL;  /* how did we get there ? */
                }
 
-               cs_attach_mux(s->csb, NULL, srv_conn);
+               if (cs_attach_mux(s->csb, NULL, srv_conn) < 0) {
+                       conn_free(srv_conn);
+                       return SF_ERR_INTERNAL;  /* how did we get there ? */
+               }
                srv_conn->ctx = s->csb;
 
 #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
index 31979d881ea2b58367c69b88b7dc415b8e32c79a..b6329129165d0091901b8d910456350ed3256f84 100644 (file)
@@ -161,7 +161,7 @@ void cs_free(struct conn_stream *cs)
 
 
 /* Attaches a conn_stream to an mux endpoint and sets the endpoint ctx */
-void cs_attach_mux(struct conn_stream *cs, void *target, void *ctx)
+int cs_attach_mux(struct conn_stream *cs, void *target, void *ctx)
 {
        struct connection *conn = ctx;
 
@@ -177,6 +177,7 @@ void cs_attach_mux(struct conn_stream *cs, void *target, void *ctx)
        }
        else if (cs_check(cs))
                cs->data_cb = &check_conn_cb;
+       return 0;
 }
 
 /* Attaches a conn_stream to an applet endpoint and sets the endpoint ctx */
index d34b1c5ecc04077fdb62985a3b5a75e4a5b21caf..5996e7e22a7719067084093167f2502d09487ea4 100644 (file)
@@ -1134,7 +1134,8 @@ static struct fcgi_strm *fcgi_conn_stream_new(struct fcgi_conn *fconn, struct co
                TRACE_ERROR("fstream allocation failure", FCGI_EV_FSTRM_NEW|FCGI_EV_FSTRM_END|FCGI_EV_FSTRM_ERR, fconn->conn);
                goto out;
        }
-       cs_attach_mux(cs, fstrm, fconn->conn);
+       if (cs_attach_mux(cs, fstrm, fconn->conn) < 0)
+               goto out;
        fstrm->cs = cs;
        fstrm->endp = cs->endp;
        fstrm->sess = sess;
@@ -1145,6 +1146,7 @@ static struct fcgi_strm *fcgi_conn_stream_new(struct fcgi_conn *fconn, struct co
 
   out:
        TRACE_DEVEL("leaving on error", FCGI_EV_FSTRM_NEW|FCGI_EV_FSTRM_END|FCGI_EV_FSTRM_ERR, fconn->conn);
+       fcgi_strm_destroy(fstrm);
        return NULL;
 }
 
index bbdddf9a4e5bbcc26ce938fbef9383ed7ecf6579..d7fd3da8f8da62f28d384fee0b4d50491868182f 100644 (file)
@@ -814,7 +814,8 @@ static struct h1s *h1c_frt_stream_new(struct h1c *h1c, struct conn_stream *cs, s
                goto fail;
 
        if (cs) {
-               cs_attach_mux(cs, h1s, h1c->conn);
+               if (cs_attach_mux(cs, h1s, h1c->conn) < 0)
+                       goto fail;
                h1s->cs = cs;
                h1s->endp = cs->endp;
        }
@@ -853,7 +854,9 @@ static struct h1s *h1c_bck_stream_new(struct h1c *h1c, struct conn_stream *cs, s
        if (!h1s)
                goto fail;
 
-       cs_attach_mux(cs, h1s, h1c->conn);
+       if (cs_attach_mux(cs, h1s, h1c->conn) < 0)
+               goto fail;
+
        h1s->flags |= H1S_F_RX_BLK;
        h1s->cs = cs;
        h1s->endp = cs->endp;
@@ -872,6 +875,7 @@ static struct h1s *h1c_bck_stream_new(struct h1c *h1c, struct conn_stream *cs, s
 
   fail:
        TRACE_DEVEL("leaving on error", H1_EV_STRM_NEW|H1_EV_STRM_ERR, h1c->conn);
+       pool_free(pool_head_h1s, h1s);
        return NULL;
 }
 
index b161278b5fed671b40608591f1e02088a5a7b38c..d39de940941100bf95c32bb5ed854374bc00acbb 100644 (file)
@@ -1675,7 +1675,11 @@ static struct h2s *h2c_bck_stream_new(struct h2c *h2c, struct conn_stream *cs, s
        if (!h2s)
                goto out;
 
-       cs_attach_mux(cs, h2s, h2c->conn);
+       if (cs_attach_mux(cs, h2s, h2c->conn) < 0) {
+               h2s_destroy(h2s);
+               h2s = NULL;
+               goto out;
+       }
        h2s->cs = cs;
        h2s->endp = cs->endp;
        h2s->sess = sess;
index 2b1c30d6618e444bd7a520fe9321925f3350912e..97b3b835da0942edfcff8db040303b8291f2fd29 100644 (file)
@@ -315,7 +315,8 @@ static int mux_pt_init(struct connection *conn, struct proxy *prx, struct sessio
                TRACE_POINT(PT_EV_STRM_NEW, conn, cs);
        }
        else {
-               cs_attach_mux(cs, ctx, conn);
+               if (cs_attach_mux(cs, ctx, conn) < 0)
+                       goto fail_free_ctx;
                ctx->endp = cs->endp;
        }
        conn->ctx = ctx;
@@ -385,7 +386,8 @@ static int mux_pt_attach(struct connection *conn, struct conn_stream *cs, struct
        TRACE_ENTER(PT_EV_STRM_NEW, conn);
        if (ctx->wait_event.events)
                conn->xprt->unsubscribe(ctx->conn, conn->xprt_ctx, SUB_RETRY_RECV, &ctx->wait_event);
-       cs_attach_mux(cs, ctx, conn);
+       if (cs_attach_mux(cs, ctx, conn) < 0)
+               return -1;
        ctx->cs = cs;
        ctx->endp = cs->endp;
        ctx->endp->flags |= CS_EP_RCV_MORE;
index 930735b70d851f91a6b52841426dd3dea4865511..0ac825e0601296e90e5947962f4955c3421cbe1f 100644 (file)
@@ -1101,7 +1101,13 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
                TRACE_ERROR("conn-stream allocation error", CHK_EV_TCPCHK_CONN|CHK_EV_TCPCHK_ERR, check);
                goto out;
        }
-       cs_attach_mux(check->cs, NULL, conn);
+       if (cs_attach_mux(check->cs, NULL, conn) < 0) {
+               TRACE_ERROR("mux attach error", CHK_EV_TCPCHK_CONN|CHK_EV_TCPCHK_ERR, check);
+               conn_free(conn);
+               conn = NULL;
+               status = SF_ERR_RESOURCE;
+               goto fail_check;
+       }
        conn->ctx = check->cs;
        tasklet_set_tid(check->wait_list.tasklet, tid);
        conn_set_owner(conn, check->sess, NULL);