blob: 5f2e26245d83b1a8c4939f2e5c4d304667675450 [file] [log] [blame]
Amaury Denoyelle36d50bf2022-09-19 16:12:38 +02001#include <haproxy/qmux_trace.h>
2
3#include <import/ist.h>
4#include <haproxy/api.h>
5#include <haproxy/connection.h>
6#include <haproxy/chunk.h>
7#include <haproxy/mux_quic.h>
Amaury Denoyelle5c25dc52022-09-30 17:44:15 +02008#include <haproxy/quic_frame-t.h>
Amaury Denoyelle36d50bf2022-09-19 16:12:38 +02009
10/* trace source and events */
11static void qmux_trace(enum trace_level level, uint64_t mask,
12 const struct trace_source *src,
13 const struct ist where, const struct ist func,
14 const void *a1, const void *a2, const void *a3, const void *a4);
15
16static const struct name_desc qmux_trace_lockon_args[4] = {
17 /* arg1 */ { /* already used by the connection */ },
18 /* arg2 */ { .name="qcs", .desc="QUIC stream" },
19 /* arg3 */ { },
20 /* arg4 */ { }
21};
22
23static const struct name_desc qmux_trace_decoding[] = {
24#define QMUX_VERB_CLEAN 1
25 { .name="clean", .desc="only user-friendly stuff, generally suitable for level \"user\"" },
26#define QMUX_VERB_MINIMAL 2
27 { .name="minimal", .desc="report only qcc/qcs state and flags, no real decoding" },
28 { /* end */ }
29};
30
31struct trace_source trace_qmux = {
32 .name = IST("qmux"),
33 .desc = "QUIC multiplexer",
34 .arg_def = TRC_ARG1_CONN, /* TRACE()'s first argument is always a connection */
35 .default_cb = qmux_trace,
36 .known_events = qmux_trace_events,
37 .lockon_args = qmux_trace_lockon_args,
38 .decoding = qmux_trace_decoding,
39 .report_events = ~0, /* report everything by default */
40};
41
42
43static void qmux_trace_frm(const struct quic_frame *frm)
44{
45 switch (frm->type) {
46 case QUIC_FT_MAX_STREAMS_BIDI:
Frédéric Lécaille5a5d05c2022-10-14 22:10:50 +020047 chunk_appendf(&trace_buf, " max_streams=%llu",
48 (ullong)frm->max_streams_bidi.max_streams);
Amaury Denoyelle36d50bf2022-09-19 16:12:38 +020049 break;
50
51 case QUIC_FT_MAX_STREAMS_UNI:
Frédéric Lécaille5a5d05c2022-10-14 22:10:50 +020052 chunk_appendf(&trace_buf, " max_streams=%llu",
53 (ullong)frm->max_streams_uni.max_streams);
Amaury Denoyelle36d50bf2022-09-19 16:12:38 +020054 break;
55
56 default:
57 break;
58 }
59}
60
61/* quic-mux trace handler */
62static void qmux_trace(enum trace_level level, uint64_t mask,
63 const struct trace_source *src,
64 const struct ist where, const struct ist func,
65 const void *a1, const void *a2, const void *a3, const void *a4)
66{
67 const struct connection *conn = a1;
68 const struct qcc *qcc = conn ? conn->ctx : NULL;
69 const struct qcs *qcs = a2;
70
71 if (!qcc)
72 return;
73
74 if (src->verbosity > QMUX_VERB_CLEAN) {
75 chunk_appendf(&trace_buf, " : qcc=%p(F)", qcc);
76 if (qcc->conn->handle.qc)
77 chunk_appendf(&trace_buf, " qc=%p", qcc->conn->handle.qc);
78
79 if (qcs)
Frédéric Lécailleea492e32022-10-18 11:57:01 +020080 chunk_appendf(&trace_buf, " qcs=%p .id=%llu .st=%s",
81 qcs, (ullong)qcs->id,
Amaury Denoyelle36d50bf2022-09-19 16:12:38 +020082 qcs_st_to_str(qcs->st));
83
84 if (mask & QMUX_EV_QCC_NQCS) {
85 const uint64_t *id = a3;
Frédéric Lécailleea492e32022-10-18 11:57:01 +020086 chunk_appendf(&trace_buf, " id=%llu", (ullong)*id);
Amaury Denoyelle36d50bf2022-09-19 16:12:38 +020087 }
88
89 if (mask & QMUX_EV_SEND_FRM)
90 qmux_trace_frm(a3);
91
92 if (mask & QMUX_EV_QCS_XFER_DATA) {
93 const struct qcs_xfer_data_trace_arg *arg = a3;
Amaury Denoyelled6922d52022-09-30 18:03:03 +020094 chunk_appendf(&trace_buf, " prep=%lu xfer=%d",
Frédéric Lécailleea492e32022-10-18 11:57:01 +020095 (ulong)arg->prep, arg->xfer);
Amaury Denoyelle36d50bf2022-09-19 16:12:38 +020096 }
97
98 if (mask & QMUX_EV_QCS_BUILD_STRM) {
99 const struct qcs_build_stream_trace_arg *arg = a3;
Frédéric Lécailleea492e32022-10-18 11:57:01 +0200100 chunk_appendf(&trace_buf, " len=%lu fin=%d offset=%llu",
101 (ulong)arg->len, arg->fin, (ullong)arg->offset);
Amaury Denoyelle36d50bf2022-09-19 16:12:38 +0200102 }
103 }
104}
105
106
107/* register qmux traces */
108INITCALL1(STG_REGISTER, trace_register_source, TRACE_SOURCE);