From: Christopher Faulet Date: Wed, 19 Jan 2022 13:50:11 +0000 (+0100) Subject: MEDIUM: applet: Set the appctx owner during allocation X-Git-Tag: v2.6-dev6~107 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2479e5f7754c9b1dcfe32cba1ff3e72c94792415;p=thirdparty%2Fhaproxy.git MEDIUM: applet: Set the appctx owner during allocation The appctx owner is now always a conn-stream. Thus, it can be set during the appctx allocation. But, to do so, the conn-stream must be created first. It is not a problem on the server side because the conn-stream is created with the stream. On the client side, we must take care to create the conn-stream first. This change should ease other changes about the applets bootstrapping. --- diff --git a/include/haproxy/applet.h b/include/haproxy/applet.h index 97b9c347b4..97164ac30e 100644 --- a/include/haproxy/applet.h +++ b/include/haproxy/applet.h @@ -59,7 +59,7 @@ static inline void appctx_init(struct appctx *appctx) * appctx_free(). is assigned as the applet, but it can be NULL. The * applet's task is always created on the current thread. */ -static inline struct appctx *appctx_new(struct applet *applet) +static inline struct appctx *appctx_new(struct applet *applet, void *owner) { struct appctx *appctx; @@ -67,6 +67,7 @@ static inline struct appctx *appctx_new(struct applet *applet) if (likely(appctx != NULL)) { appctx->obj_type = OBJ_TYPE_APPCTX; appctx->applet = applet; + appctx->owner = owner; appctx_init(appctx); appctx->t = task_new_here(); if (unlikely(appctx->t == NULL)) { diff --git a/src/dns.c b/src/dns.c index 249db228f8..cd7780ce65 100644 --- a/src/dns.c +++ b/src/dns.c @@ -891,10 +891,15 @@ static struct appctx *dns_session_create(struct dns_session *ds) struct stream *s; struct applet *applet = &dns_session_applet; - appctx = appctx_new(applet); - if (!appctx) + cs = cs_new(); + if (!cs) { + ha_alert("out of memory in dns_session_create().\n"); goto out_close; + } + appctx = appctx_new(applet, cs); + if (!appctx) + goto out_free_cs; appctx->ctx.sft.ptr = (void *)ds; sess = session_new(ds->dss->srv->proxy, NULL, &appctx->obj_type); @@ -903,22 +908,16 @@ static struct appctx *dns_session_create(struct dns_session *ds) goto out_free_appctx; } - cs = cs_new(); - if (!cs) { - ha_alert("out of memory in dns_session_create().\n"); - goto out_free_sess; - } - cs_attach_endp(cs, &appctx->obj_type, appctx); - if ((s = stream_new(sess, cs, &BUF_NULL)) == NULL) { ha_alert("Failed to initialize stream in dns_session_create().\n"); - goto out_free_cs; + goto out_free_sess; } - s->target = &ds->dss->srv->obj_type; if (!sockaddr_alloc(&cs_si(s->csb)->dst, &ds->dss->srv->addr, sizeof(ds->dss->srv->addr))) goto out_free_strm; + + cs_attach_endp(cs, &appctx->obj_type, appctx); s->flags = SF_ASSIGNED|SF_ADDR_SET; cs_si(s->csb)->flags |= SI_FL_NOLINGER; @@ -938,12 +937,12 @@ static struct appctx *dns_session_create(struct dns_session *ds) out_free_strm: LIST_DELETE(&s->list); pool_free(pool_head_stream, s); - out_free_cs: - cs_free(cs); out_free_sess: session_free(sess); out_free_appctx: appctx_free(appctx); + out_free_cs: + cs_free(cs); out_close: return NULL; } diff --git a/src/flt_spoe.c b/src/flt_spoe.c index 5d0a535242..36b1f9ac7c 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -1991,9 +1991,13 @@ spoe_create_appctx(struct spoe_config *conf) struct conn_stream *cs; struct stream *strm; - if ((appctx = appctx_new(&spoe_applet)) == NULL) + cs = cs_new(); + if (!cs) goto out_error; + if ((appctx = appctx_new(&spoe_applet, cs)) == NULL) + goto out_free_cs; + appctx->ctx.spoe.ptr = pool_zalloc(pool_head_spoe_appctx); if (SPOE_APPCTX(appctx) == NULL) goto out_free_appctx; @@ -2024,14 +2028,10 @@ spoe_create_appctx(struct spoe_config *conf) if (!sess) goto out_free_spoe; - cs = cs_new(); - if (!cs) - goto out_free_sess; - cs_attach_endp(cs, &appctx->obj_type, appctx); - if ((strm = stream_new(sess, cs, &BUF_NULL)) == NULL) - goto out_free_cs; + goto out_free_sess; + cs_attach_endp(cs, &appctx->obj_type, appctx); stream_set_backend(strm, conf->agent->b.be); /* applet is waiting for data */ @@ -2050,8 +2050,6 @@ spoe_create_appctx(struct spoe_config *conf) return appctx; /* Error unrolling */ - out_free_cs: - cs_free(cs); out_free_sess: session_free(sess); out_free_spoe: @@ -2060,6 +2058,8 @@ spoe_create_appctx(struct spoe_config *conf) pool_free(pool_head_spoe_appctx, SPOE_APPCTX(appctx)); out_free_appctx: appctx_free(appctx); + out_free_cs: + cs_free(cs); out_error: return NULL; } diff --git a/src/hlua.c b/src/hlua.c index ecc0762013..270e3f6b2e 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -2944,11 +2944,17 @@ __LJMP static int hlua_socket_new(lua_State *L) lua_rawgeti(L, LUA_REGISTRYINDEX, class_socket_ref); lua_setmetatable(L, -2); + cs = cs_new(); + if (!cs) { + hlua_pusherror(L, "socket: out of memory"); + goto out_fail_conf; + } + /* Create the applet context */ - appctx = appctx_new(&update_applet); + appctx = appctx_new(&update_applet, cs); if (!appctx) { hlua_pusherror(L, "socket: out of memory"); - goto out_fail_conf; + goto out_fail_cs; } appctx->ctx.hlua_cosocket.connected = 0; @@ -2963,19 +2969,14 @@ __LJMP static int hlua_socket_new(lua_State *L) goto out_fail_appctx; } - cs = cs_new(); - if (!cs) { - hlua_pusherror(L, "socket: out of memory"); - goto out_fail_sess; - } - cs_attach_endp(cs, &appctx->obj_type, appctx); - strm = stream_new(sess, cs, &BUF_NULL); if (!strm) { hlua_pusherror(L, "socket: out of memory"); - goto out_fail_cs; + goto out_fail_sess; } + cs_attach_endp(cs, &appctx->obj_type, appctx); + /* Initialise cross reference between stream and Lua socket object. */ xref_create(&socket->xref, &appctx->ctx.hlua_cosocket.xref); @@ -2991,12 +2992,12 @@ __LJMP static int hlua_socket_new(lua_State *L) return 1; - out_fail_cs: - cs_free(cs); out_fail_sess: session_free(sess); out_fail_appctx: appctx_free(appctx); + out_fail_cs: + cs_free(cs); out_fail_conf: WILL_LJMP(lua_error(L)); return 0; diff --git a/src/http_client.c b/src/http_client.c index 33213a88f5..cf1165bb56 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -476,26 +476,27 @@ struct appctx *httpclient_start(struct httpclient *hc) goto out; } + cs = cs_new(); + if (!cs) { + ha_alert("httpclient: out of memory in %s:%d.\n", __FUNCTION__, __LINE__); + goto out; + } + /* The HTTP client will be created in the same thread as the caller, * avoiding threading issues */ - appctx = appctx_new(applet); + appctx = appctx_new(applet, cs); if (!appctx) - goto out; + goto out_free_cs; sess = session_new(httpclient_proxy, NULL, &appctx->obj_type); if (!sess) { ha_alert("httpclient: out of memory in %s:%d.\n", __FUNCTION__, __LINE__); goto out_free_appctx; } - cs = cs_new(); - if (!cs) { - ha_alert("httpclient: out of memory in %s:%d.\n", __FUNCTION__, __LINE__); - goto out_free_sess; - } - cs_attach_endp(cs, &appctx->obj_type, appctx); + if ((s = stream_new(sess, cs, &hc->req.buf)) == NULL) { ha_alert("httpclient: Failed to initialize stream %s:%d.\n", __FUNCTION__, __LINE__); - goto out_free_cs; + goto out_free_sess; } /* set the "timeout server" */ @@ -528,6 +529,7 @@ struct appctx *httpclient_start(struct httpclient *hc) break; } + cs_attach_endp(cs, &appctx->obj_type, appctx); s->flags |= SF_ASSIGNED|SF_ADDR_SET; cs_si(s->csb)->flags |= SI_FL_NOLINGER; s->res.flags |= CF_READ_DONTWAIT; @@ -550,12 +552,12 @@ struct appctx *httpclient_start(struct httpclient *hc) out_free_stream: LIST_DELETE(&s->list); pool_free(pool_head_stream, s); -out_free_cs: - cs_free(cs); out_free_sess: session_free(sess); out_free_appctx: appctx_free(appctx); +out_free_cs: + cs_free(cs); out: return NULL; diff --git a/src/peers.c b/src/peers.c index 413f594a25..e2bcee7c9f 100644 --- a/src/peers.c +++ b/src/peers.c @@ -3191,9 +3191,15 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer peer->last_hdshk = now_ms; s = NULL; - appctx = appctx_new(&peer_applet); - if (!appctx) + cs = cs_new(); + if (!cs) { + ha_alert("out of memory in peer_session_create().\n"); goto out_close; + } + + appctx = appctx_new(&peer_applet, cs); + if (!appctx) + goto out_free_cs; appctx->st0 = PEER_SESS_ST_CONNECT; appctx->ctx.peers.ptr = (void *)peer; @@ -3204,16 +3210,9 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer goto out_free_appctx; } - cs = cs_new(); - if (!cs) { - ha_alert("out of memory in peer_session_create().\n"); - goto out_free_sess; - } - cs_attach_endp(cs, &appctx->obj_type, appctx); - if ((s = stream_new(sess, cs, &BUF_NULL)) == NULL) { ha_alert("Failed to initialize stream in peer_session_create().\n"); - goto out_free_cs; + goto out_free_sess; } /* applet is waiting for data */ @@ -3224,6 +3223,8 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer s->target = peer_session_target(peer, s); if (!sockaddr_alloc(&(cs_si(s->csb)->dst), &peer->addr, sizeof(peer->addr))) goto out_free_strm; + + cs_attach_endp(cs, &appctx->obj_type, appctx); s->flags = SF_ASSIGNED|SF_ADDR_SET; cs_si(s->csb)->flags |= SI_FL_NOLINGER; @@ -3240,12 +3241,12 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer out_free_strm: LIST_DELETE(&s->list); pool_free(pool_head_stream, s); - out_free_cs: - cs_free(cs); out_free_sess: session_free(sess); out_free_appctx: appctx_free(appctx); + out_free_cs: + cs_free(cs); out_close: return NULL; } diff --git a/src/sink.c b/src/sink.c index eec8570f1c..16d3533593 100644 --- a/src/sink.c +++ b/src/sink.c @@ -643,9 +643,15 @@ 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; - appctx = appctx_new(applet); - if (!appctx) + cs = cs_new(); + if (!cs) { + ha_alert("out of memory in sink_forward_session_create"); goto out_close; + } + + appctx = appctx_new(applet, cs); + if (!appctx) + goto out_free_cs; appctx->ctx.sft.ptr = (void *)sft; @@ -655,22 +661,17 @@ static struct appctx *sink_forward_session_create(struct sink *sink, struct sink goto out_free_appctx; } - cs = cs_new(); - if (!cs) { - ha_alert("out of memory in sink_forward_session_create"); - goto out_free_sess; - } - cs_attach_endp(cs, &appctx->obj_type, appctx); - if ((s = stream_new(sess, cs, &BUF_NULL)) == NULL) { ha_alert("Failed to initialize stream in sink_forward_session_create().\n"); - goto out_free_cs; + goto out_free_sess; } s->target = &sft->srv->obj_type; if (!sockaddr_alloc(&cs_si(s->csb)->dst, &sft->srv->addr, sizeof(sft->srv->addr))) goto out_free_strm; + + cs_attach_endp(cs, &appctx->obj_type, appctx); s->flags = SF_ASSIGNED|SF_ADDR_SET; cs_si(s->csb)->flags |= SI_FL_NOLINGER; @@ -690,12 +691,12 @@ static struct appctx *sink_forward_session_create(struct sink *sink, struct sink out_free_strm: LIST_DELETE(&s->list); pool_free(pool_head_stream, s); - out_free_cs: - cs_free(cs); out_free_sess: session_free(sess); out_free_appctx: appctx_free(appctx); + out_free_cs: + cs_free(cs); out_close: return NULL; } diff --git a/src/stream_interface.c b/src/stream_interface.c index 703fd37d0c..f8f7794cee 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -339,7 +339,7 @@ struct appctx *si_register_handler(struct stream_interface *si, struct applet *a DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", app, si, si_task(si)); - appctx = appctx_new(app); + appctx = appctx_new(app, si->cs); if (!appctx) return NULL; cs_attach_endp(si->cs, &appctx->obj_type, appctx);