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.
This commit is contained in:
Christopher Faulet 2026-04-20 18:33:36 +02:00
parent 594753238c
commit 9d45929341
6 changed files with 23 additions and 10 deletions

View File

@ -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

View File

@ -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"))) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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));