From: Christopher Faulet Date: Mon, 20 Apr 2026 16:33:36 +0000 (+0200) Subject: MINOR: stream: Add flags to identify the stream tansaction when allocated X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=9d459293410e6be285ca67144ad7c17fd4b35d6d;p=thirdparty%2Fhaproxy.git MINOR: stream: Add flags to identify the stream tansaction when allocated To be able to deal with different types of transaction for a stream, new stream flags was added to know the transaction type when allocated. For now only HTTP transactions can be allocated, so only SF_TXN_HTTP was introduced. The mask SF_TXN_MASK must be used to get the transaction type. The transaction type is set when it is allocated and removed when it is destroyed. --- diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index ecd31caae..7162dcead 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -90,6 +90,10 @@ #define SF_BC_MARK 0x01000000 /* need to set specific mark on backend/srv conn upon connect */ #define SF_BC_TOS 0x02000000 /* need to set specific tos on backend/srv conn upon connect */ #define SF_RULE_FYIELD 0x04000000 /* s->current_rule set because of forced yield */ +/* unused: 0x08000000 */ +#define SF_TXN_NONE 0x00000000 /* No transaction allocated */ +#define SF_TXN_HTTP 0x10000000 /* HTTP transaction allocated */ +#define SF_TXN_MASK 0x10000000 /* mask to get the transaction type */ /* This function is used to report flags in debugging tools. Please reflect * below any single-bit flag addition above in the same order via the diff --git a/src/debug.c b/src/debug.c index ce31711d3..50a8856dc 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1401,7 +1401,8 @@ static int debug_parse_cli_stream(char **args, char *payload, struct appctx *app } else if (isteq(name, ist("strm.x"))) { ptr = (!s || !may_access(s)) ? NULL : &s->conn_exp; size = sizeof(s->conn_exp); } else if (isteq(name, ist("txn.f"))) { - ptr = (!s || !may_access(s)) ? NULL : &s->txn.http->flags; size = sizeof(s->txn.http->flags); + ptr = (!s || !may_access(s) || (s->flags & SF_TXN_MASK) != SF_TXN_HTTP) ? NULL : &s->txn.http->flags; + size = sizeof(s->txn.http->flags); } else if (isteq(name, ist("req.f"))) { ptr = (!s || !may_access(s)) ? NULL : &s->req.flags; size = sizeof(s->req.flags); } else if (isteq(name, ist("res.f"))) { diff --git a/src/http_ana.c b/src/http_ana.c index aea92a9f7..9087dfa9e 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -5290,6 +5290,9 @@ struct http_txn *http_create_txn(struct stream *s) struct http_txn *txn; struct stconn *sc = s->scf; + if ((s->flags & SF_TXN_MASK) != SF_TXN_NONE) + return NULL; + txn = pool_alloc(pool_head_http_txn); if (!txn) return NULL; @@ -5318,6 +5321,8 @@ struct http_txn *http_create_txn(struct stream *s) txn->auth.method = HTTP_AUTH_UNKNOWN; + s->flags |= SF_TXN_HTTP; + /* here we don't want to re-initialize s->vars_txn and s->vars_reqres * variable lists, because they were already initialized upon stream * creation in stream_new(), and thus may already contain some variables @@ -5349,6 +5354,7 @@ void http_destroy_txn(struct stream *s) pool_free(pool_head_http_txn, txn); s->txn.http = NULL; + s->flags &= ~SF_TXN_MASK; } diff --git a/src/log.c b/src/log.c index be06ad060..ad435ddda 100644 --- a/src/log.c +++ b/src/log.c @@ -3959,7 +3959,7 @@ size_t sess_build_logline_orig(struct session *sess, struct stream *s, if (likely(s)) { be = s->be; - txn = s->txn.http; + txn = (((s->flags & SF_TXN_MASK) == SF_TXN_HTTP) ? s->txn.http : NULL); be_conn = sc_conn(s->scb); status = (txn ? txn->status : 0); s_flags = s->flags; diff --git a/src/stconn.c b/src/stconn.c index 2941c2d1e..c2f96a198 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -1488,7 +1488,7 @@ int sc_conn_send(struct stconn *sc) if (oc->flags & CF_STREAMER) send_flag |= CO_SFL_STREAMER; - if (s->txn.http && s->txn.http->flags & TX_L7_RETRY && !b_data(&s->txn.http->l7_buffer)) { + if ((s->flags & SF_TXN_MASK) == SF_TXN_HTTP && (s->txn.http->flags & TX_L7_RETRY) && !b_data(&s->txn.http->l7_buffer)) { /* If we want to be able to do L7 retries, copy * the data we're about to send, so that we are able * to resend them if needed diff --git a/src/stream.c b/src/stream.c index bb88c6288..cd271ff04 100644 --- a/src/stream.c +++ b/src/stream.c @@ -683,7 +683,7 @@ void stream_free(struct stream *s) hlua_ctx_destroy(s->hlua[1]); s->hlua[0] = s->hlua[1] = NULL; - if (s->txn.http) + if ((s->flags & SF_TXN_MASK) == SF_TXN_HTTP) http_destroy_txn(s); /* ensure the client-side transport layer is destroyed */ @@ -1299,7 +1299,7 @@ static int process_switching_rules(struct stream *s, struct channel *req, int an if (!(s->flags & SF_FINST_MASK)) s->flags |= SF_FINST_R; - if (s->txn.http) + if ((s->flags & SF_TXN_MASK) == SF_TXN_HTTP) s->txn.http->status = 500; s->req.analysers &= AN_REQ_FLT_END; s->req.analyse_exp = TICK_ETERNITY; @@ -1594,7 +1594,7 @@ int stream_set_http_mode(struct stream *s, const struct mux_proto_list *mux_prot s->req.analysers |= AN_REQ_WAIT_HTTP|AN_REQ_HTTP_PROCESS_FE; - if (unlikely(!s->txn.http && !http_create_txn(s))) + if (unlikely((s->flags & SF_TXN_MASK) != SF_TXN_HTTP && !http_create_txn(s))) return 0; conn = sc_conn(sc); @@ -1913,7 +1913,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) } /* this data may be no longer valid, clear it */ - if (s->txn.http) + if ((s->flags & SF_TXN_MASK) == SF_TXN_HTTP) memset(&s->txn.http->auth, 0, sizeof(s->txn.http->auth)); /* 1a: Check for low level timeouts if needed. We just set a flag on @@ -2774,7 +2774,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) stream_process_counters(s); - if (s->txn.http && s->txn.http->status) { + if ((s->flags & SF_TXN_MASK) == SF_TXN_HTTP && s->txn.http->status) { int n; n = s->txn.http->status / 100; @@ -3627,7 +3627,7 @@ static void __strm_dump_to_buffer(struct buffer *buf, const struct show_sess_ctx " age=%s)\n", human_time(ns_to_sec(now_ns) - ns_to_sec(request_ts), 1)); - if (strm->txn.http) { + if ((strm->flags & SF_TXN_MASK) == SF_TXN_HTTP) { chunk_appendf(buf, "%s txn=%p flags=0x%x meth=%d status=%d req.st=%s rsp.st=%s req.f=0x%02x rsp.f=0x%02x", pfx, strm->txn.http, strm->txn.http->flags, @@ -4237,7 +4237,9 @@ static int cli_io_handler_dump_sess(struct appctx *appctx) if (task_in_rq(curr_strm->task)) chunk_appendf(&trash, " run(nice=%d)", curr_strm->task->nice); - if ((ctx->flags & CLI_SHOWSESS_F_DUMP_URI) && curr_strm->txn.http && curr_strm->txn.http->uri) + if ((ctx->flags & CLI_SHOWSESS_F_DUMP_URI) && + (curr_strm->flags & SF_TXN_MASK) == SF_TXN_HTTP && + curr_strm->txn.http->uri) chunk_appendf(&trash, " uri=\"%s\"", HA_ANON_CLI(curr_strm->txn.http->uri));