]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-h2: add a trace context filling helper
authorWilly Tarreau <w@1wt.eu>
Tue, 6 Aug 2024 16:33:42 +0000 (18:33 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 7 Aug 2024 14:02:59 +0000 (16:02 +0200)
This helper is able to find a connection, a session, a stream, a
frontend or a backend from its args.

Note that this required to always make sure that h2s->sess is reset on
allocation because it's normally initialized later for backend streams,
and producing traces between the two could pre-fill a bad pointer in
the trace_ctx.

src/mux_h2.c

index 76c9b0805316fae4260c97361b9d29b5770f43a7..d8e185038826f29793bca25accf5dc5ff92fa185 100644 (file)
@@ -135,6 +135,9 @@ static void h2_trace(enum trace_level level, uint64_t mask, \
                      const struct ist where, const struct ist func,
                      const void *a1, const void *a2, const void *a3, const void *a4);
 
+static void h2_trace_fill_ctx(struct trace_ctx *ctx, const struct trace_source *src,
+                              const void *a1, const void *a2, const void *a3, const void *a4);
+
 /* The event representation is split like this :
  *   strm  - application layer
  *   h2s   - internal H2 stream
@@ -276,6 +279,7 @@ static struct trace_source trace_h2 __read_mostly = {
        .desc = "HTTP/2 multiplexer",
        .arg_def = TRC_ARG1_CONN,  // TRACE()'s first argument is always a connection
        .default_cb = h2_trace,
+       .fill_ctx = h2_trace_fill_ctx,
        .known_events = h2_trace_events,
        .lockon_args = h2_trace_lockon_args,
        .decoding = h2_trace_decoding,
@@ -611,6 +615,33 @@ static void h2_trace(enum trace_level level, uint64_t mask, const struct trace_s
        }
 }
 
+/* This fills the trace_ctx with extra info guessed from the args */
+static void h2_trace_fill_ctx(struct trace_ctx *ctx, const struct trace_source *src,
+                              const void *a1, const void *a2, const void *a3, const void *a4)
+{
+       const struct connection *conn = a1;
+       const struct h2c *h2c = conn ? conn->ctx : NULL;
+       const struct h2s *h2s    = a2;
+
+       if (!ctx->conn)
+               ctx->conn = conn;
+
+       if (h2c) {
+               if (!ctx->fe && !(h2c->flags & H2_CF_IS_BACK))
+                       ctx->fe = h2c->proxy;
+
+               if (!ctx->be && (h2c->flags & H2_CF_IS_BACK))
+                       ctx->be = h2c->proxy;
+       }
+
+       if (h2s) {
+               if (!ctx->sess)
+                       ctx->sess = h2s->sess;
+               if (!ctx->strm && h2s->sd && h2s_sc(h2s))
+                       ctx->strm = sc_strm(h2s_sc(h2s));
+       }
+}
+
 
 /* Detect a pending read0 for a H2 connection. It happens if a read0 was
  * already reported on a previous xprt->rcvbuf() AND a frame parser failed
@@ -1621,6 +1652,7 @@ static struct h2s *h2s_new(struct h2c *h2c, int id)
        h2s->shut_tl->context = h2s;
        LIST_INIT(&h2s->list);
        h2s->h2c       = h2c;
+       h2s->sess      = NULL;
        h2s->sd        = NULL;
        h2s->sws       = 0;
        h2s->flags     = H2_SF_NONE;