diff --git a/include/haproxy/conn_stream.h b/include/haproxy/conn_stream.h index cb7c4cbea..638b0cf2d 100644 --- a/include/haproxy/conn_stream.h +++ b/include/haproxy/conn_stream.h @@ -37,7 +37,7 @@ struct check; struct cs_endpoint *cs_endpoint_new(); void cs_endpoint_free(struct cs_endpoint *endp); -struct conn_stream *cs_new(); +struct conn_stream *cs_new(struct cs_endpoint *endp); void cs_free(struct conn_stream *cs); void cs_attach_endp_mux(struct conn_stream *cs, void *endp, void *ctx); void cs_attach_endp_app(struct conn_stream *cs, void *endp, void *ctx); diff --git a/include/haproxy/mux_quic.h b/include/haproxy/mux_quic.h index ec3270d7b..aab468752 100644 --- a/include/haproxy/mux_quic.h +++ b/include/haproxy/mux_quic.h @@ -107,9 +107,19 @@ static inline struct qc_stream_desc *qcc_get_stream(struct qcc *qcc, uint64_t id static inline struct conn_stream *qc_attach_cs(struct qcs *qcs, struct buffer *buf) { - struct conn_stream *cs = cs_new(); - if (!cs) + struct cs_endpoint *endp; + struct conn_stream *cs; + + endp = cs_endpoint_new(); + if (!endp) return NULL; + endp->target = qcs; + endp->ctx = qcs->qcc->conn; + cs = cs_new(endp); + if (!cs) { + cs_endpoint_free(endp); + return NULL; + } cs_attach_endp_mux(cs, qcs, qcs->qcc->conn); qcs->cs = cs; stream_new(qcs->qcc->conn->owner, cs, buf); diff --git a/src/check.c b/src/check.c index 7e6430f05..b26e7b9b2 100644 --- a/src/check.c +++ b/src/check.c @@ -1391,7 +1391,7 @@ int start_check_task(struct check *check, int mininter, if (check->type == PR_O2_EXT_CHK) t = task_new_on(0); else { - check->cs = cs_new(); + check->cs = cs_new(NULL); if (!check->cs) goto fail_alloc_cs; if (cs_attach_app(check->cs, &check->obj_type) < 0) diff --git a/src/conn_stream.c b/src/conn_stream.c index 0335cbb63..5b8177484 100644 --- a/src/conn_stream.c +++ b/src/conn_stream.c @@ -46,10 +46,9 @@ void cs_endpoint_free(struct cs_endpoint *endp) /* Tries to allocate a new conn_stream and initialize its main fields. On * failure, nothing is allocated and NULL is returned. */ -struct conn_stream *cs_new() +struct conn_stream *cs_new(struct cs_endpoint *endp) { struct conn_stream *cs; - struct cs_endpoint *endp; cs = pool_alloc(pool_head_connstream); @@ -62,9 +61,11 @@ struct conn_stream *cs_new() cs->si = NULL; cs->data_cb = NULL; - endp = cs_endpoint_new(); - if (unlikely(!endp)) - goto alloc_error; + if (!endp) { + endp = cs_endpoint_new(); + if (unlikely(!endp)) + goto alloc_error; + } cs->endp = endp; return cs; diff --git a/src/dns.c b/src/dns.c index b13206deb..461e3c723 100644 --- a/src/dns.c +++ b/src/dns.c @@ -891,7 +891,7 @@ static struct appctx *dns_session_create(struct dns_session *ds) struct stream *s; struct applet *applet = &dns_session_applet; - cs = cs_new(); + cs = cs_new(NULL); if (!cs) { ha_alert("out of memory in dns_session_create().\n"); goto out_close; diff --git a/src/flt_spoe.c b/src/flt_spoe.c index a3713cf63..e8daf1be1 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -1991,7 +1991,7 @@ spoe_create_appctx(struct spoe_config *conf) struct conn_stream *cs; struct stream *strm; - cs = cs_new(); + cs = cs_new(NULL); if (!cs) goto out_error; diff --git a/src/hlua.c b/src/hlua.c index 179b8f232..3f9b123b2 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -2944,7 +2944,7 @@ __LJMP static int hlua_socket_new(lua_State *L) lua_rawgeti(L, LUA_REGISTRYINDEX, class_socket_ref); lua_setmetatable(L, -2); - cs = cs_new(); + cs = cs_new(NULL); if (!cs) { hlua_pusherror(L, "socket: out of memory"); goto out_fail_conf; diff --git a/src/http_client.c b/src/http_client.c index 22a13b1cb..dd2748207 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -476,7 +476,7 @@ struct appctx *httpclient_start(struct httpclient *hc) goto out; } - cs = cs_new(); + cs = cs_new(NULL); if (!cs) { ha_alert("httpclient: out of memory in %s:%d.\n", __FUNCTION__, __LINE__); goto out; diff --git a/src/mux_h1.c b/src/mux_h1.c index 82470bc2e..669b41105 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -716,23 +716,31 @@ static inline size_t h1s_data_pending(const struct h1s *h1s) static struct conn_stream *h1s_new_cs(struct h1s *h1s, struct buffer *input) { struct h1c *h1c = h1s->h1c; + struct cs_endpoint *endp; struct conn_stream *cs; TRACE_ENTER(H1_EV_STRM_NEW, h1c->conn, h1s); - cs = cs_new(); + endp = cs_endpoint_new(); + if (!endp) { + TRACE_ERROR("CS endp allocation failure", H1_EV_STRM_NEW|H1_EV_STRM_END|H1_EV_STRM_ERR, h1c->conn, h1s); + goto err; + } + endp->target = h1s; + endp->ctx = h1c->conn; + if (h1s->flags & H1S_F_NOT_FIRST) + endp->flags |= CS_EP_NOT_FIRST; + if (h1s->req.flags & H1_MF_UPG_WEBSOCKET) + endp->flags |= CS_EP_WEBSOCKET; + + cs = cs_new(endp); if (!cs) { TRACE_ERROR("CS allocation failure", H1_EV_STRM_NEW|H1_EV_STRM_END|H1_EV_STRM_ERR, h1c->conn, h1s); + cs_endpoint_free(endp); goto err; } cs_attach_endp_mux(cs, h1s, h1c->conn); h1s->cs = cs; - if (h1s->flags & H1S_F_NOT_FIRST) - cs->endp->flags |= CS_EP_NOT_FIRST; - - if (h1s->req.flags & H1_MF_UPG_WEBSOCKET) - cs->endp->flags |= CS_EP_WEBSOCKET; - if (!stream_new(h1c->conn->owner, cs, input)) { TRACE_DEVEL("leaving on stream creation failure", H1_EV_STRM_NEW|H1_EV_STRM_END|H1_EV_STRM_ERR, h1c->conn, h1s); goto err_cs; diff --git a/src/mux_h2.c b/src/mux_h2.c index 82196e95f..98a837d42 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -1590,6 +1590,7 @@ static struct h2s *h2s_new(struct h2c *h2c, int id) static struct h2s *h2c_frt_stream_new(struct h2c *h2c, int id, struct buffer *input, uint32_t flags) { struct session *sess = h2c->conn->owner; + struct cs_endpoint *endp; struct conn_stream *cs; struct h2s *h2s; @@ -1602,19 +1603,26 @@ static struct h2s *h2c_frt_stream_new(struct h2c *h2c, int id, struct buffer *in if (!h2s) goto out; - cs = cs_new(); - if (!cs) + endp = cs_endpoint_new(); + if (!endp) goto out_close; - cs->endp->flags |= CS_EP_NOT_FIRST; - cs_attach_endp_mux(cs, h2s, h2c->conn); - h2s->cs = cs; - h2c->nb_cs++; - + endp->target = h2s; + endp->ctx = h2c->conn; + endp->flags |= CS_EP_NOT_FIRST; /* FIXME wrong analogy between ext-connect and websocket, this need to * be refine. */ if (flags & H2_SF_EXT_CONNECT_RCVD) - cs->endp->flags |= CS_EP_WEBSOCKET; + endp->flags |= CS_EP_WEBSOCKET; + + cs = cs_new(endp); + if (!cs) { + cs_endpoint_free(endp); + goto out_close; + } + cs_attach_endp_mux(cs, h2s, h2c->conn); + h2s->cs = cs; + h2c->nb_cs++; /* The stream will record the request's accept date (which is either the * end of the connection's or the date immediately after the previous diff --git a/src/mux_pt.c b/src/mux_pt.c index 198c41a32..e49898e2e 100644 --- a/src/mux_pt.c +++ b/src/mux_pt.c @@ -272,6 +272,7 @@ struct task *mux_pt_io_cb(struct task *t, void *tctx, unsigned int status) static int mux_pt_init(struct connection *conn, struct proxy *prx, struct session *sess, struct buffer *input) { + struct cs_endpoint *endp; struct conn_stream *cs = conn->ctx; struct mux_pt_ctx *ctx = pool_alloc(pool_head_pt_ctx); @@ -291,9 +292,15 @@ static int mux_pt_init(struct connection *conn, struct proxy *prx, struct sessio ctx->conn = conn; if (!cs) { - cs = cs_new(); + endp = cs_endpoint_new(); + if (!endp) + goto fail_free_ctx; + endp->target = ctx; + endp->ctx = conn; + cs = cs_new(endp); if (!cs) { TRACE_ERROR("CS allocation failure", PT_EV_STRM_NEW|PT_EV_STRM_END|PT_EV_STRM_ERR, conn); + cs_endpoint_free(endp); goto fail_free_ctx; } cs_attach_endp_mux(cs, ctx, conn); diff --git a/src/peers.c b/src/peers.c index d82e562af..b88f4ec05 100644 --- a/src/peers.c +++ b/src/peers.c @@ -3191,7 +3191,7 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer peer->last_hdshk = now_ms; s = NULL; - cs = cs_new(); + cs = cs_new(NULL); if (!cs) { ha_alert("out of memory in peer_session_create().\n"); goto out_close; diff --git a/src/sink.c b/src/sink.c index 87f076bd4..d704042d1 100644 --- a/src/sink.c +++ b/src/sink.c @@ -643,7 +643,7 @@ static struct appctx *sink_forward_session_create(struct sink *sink, struct sink if (sft->srv->log_proto == SRV_LOG_PROTO_OCTET_COUNTING) applet = &sink_forward_oc_applet; - cs = cs_new(); + cs = cs_new(NULL); if (!cs) { ha_alert("out of memory in sink_forward_session_create"); goto out_close; diff --git a/src/stream.c b/src/stream.c index 868a3f0cf..e30027c52 100644 --- a/src/stream.c +++ b/src/stream.c @@ -443,7 +443,7 @@ struct stream *stream_new(struct session *sess, struct conn_stream *cs, struct b s->flags |= SF_HTX; s->csf = cs; - s->csb = cs_new(); + s->csb = cs_new(NULL); if (!s->csb) goto out_fail_alloc_csb;