haproxy/src/qmux_trace.c
Amaury Denoyelle 3fe3251593 MEDIUM: mux-quic: simplify sending API
The previous commit was a major rework for QUIC MUX sending process.
Following this, this patch cleans up a few elements that remains but can
be removed as they are duplicated.

Of notable changes, offset fields from QCS and QCC are removed. They are
both equivalent to flow control soft offsets.

A new function qcs_prep_bytes() is implemented. Its purpose is to return
the count of prepared data bytes not yet sent. It also replaces
qcs_need_sending().
2024-01-31 16:28:54 +01:00

115 lines
3.4 KiB
C

#include <haproxy/qmux_trace.h>
#include <import/ist.h>
#include <haproxy/api.h>
#include <haproxy/connection.h>
#include <haproxy/chunk.h>
#include <haproxy/mux_quic.h>
#include <haproxy/quic_frame-t.h>
/* trace source and events */
static void qmux_trace(enum trace_level level, uint64_t mask,
const struct trace_source *src,
const struct ist where, const struct ist func,
const void *a1, const void *a2, const void *a3, const void *a4);
static const struct name_desc qmux_trace_lockon_args[4] = {
/* arg1 */ { /* already used by the connection */ },
/* arg2 */ { .name="qcs", .desc="QUIC stream" },
/* arg3 */ { },
/* arg4 */ { }
};
static const struct name_desc qmux_trace_decoding[] = {
#define QMUX_VERB_CLEAN 1
{ .name="clean", .desc="only user-friendly stuff, generally suitable for level \"user\"" },
#define QMUX_VERB_MINIMAL 2
{ .name="minimal", .desc="report only qcc/qcs state and flags, no real decoding" },
{ /* end */ }
};
struct trace_source trace_qmux = {
.name = IST("qmux"),
.desc = "QUIC multiplexer",
.arg_def = TRC_ARG1_CONN, /* TRACE()'s first argument is always a connection */
.default_cb = qmux_trace,
.known_events = qmux_trace_events,
.lockon_args = qmux_trace_lockon_args,
.decoding = qmux_trace_decoding,
.report_events = ~0, /* report everything by default */
};
static void qmux_trace_frm(const struct quic_frame *frm)
{
switch (frm->type) {
case QUIC_FT_MAX_STREAMS_BIDI:
chunk_appendf(&trace_buf, " max_streams=%llu",
(ullong)frm->max_streams_bidi.max_streams);
break;
case QUIC_FT_MAX_STREAMS_UNI:
chunk_appendf(&trace_buf, " max_streams=%llu",
(ullong)frm->max_streams_uni.max_streams);
break;
default:
break;
}
}
/* quic-mux trace handler */
static void qmux_trace(enum trace_level level, uint64_t mask,
const struct trace_source *src,
const struct ist where, const struct ist func,
const void *a1, const void *a2, const void *a3, const void *a4)
{
const struct connection *conn = a1;
const struct qcc *qcc = conn ? conn->ctx : NULL;
const struct qcs *qcs = a2;
if (!qcc)
return;
if (src->verbosity > QMUX_VERB_CLEAN) {
chunk_appendf(&trace_buf, " : qcc=%p(F)", qcc);
if (qcc->conn->handle.qc)
chunk_appendf(&trace_buf, " qc=%p", qcc->conn->handle.qc);
chunk_appendf(&trace_buf, " md=%llu/%llu",
(ullong)qcc->tx.fc.limit, (ullong)qcc->tx.fc.off_real);
if (qcs) {
chunk_appendf(&trace_buf, " qcs=%p .id=%llu .st=%s",
qcs, (ullong)qcs->id,
qcs_st_to_str(qcs->st));
chunk_appendf(&trace_buf, " msd=%llu/%llu",
(ullong)qcs->tx.fc.limit, (ullong)qcs->tx.fc.off_real);
}
if (mask & QMUX_EV_QCC_NQCS) {
const uint64_t *id = a3;
chunk_appendf(&trace_buf, " id=%llu", (ullong)*id);
}
if (mask & QMUX_EV_SEND_FRM)
qmux_trace_frm(a3);
if (mask & QMUX_EV_QCS_XFER_DATA) {
const struct qcs_xfer_data_trace_arg *arg = a3;
chunk_appendf(&trace_buf, " prep=%lu xfer=%d",
(ulong)arg->prep, arg->xfer);
}
if (mask & QMUX_EV_QCS_BUILD_STRM) {
const struct qcs_build_stream_trace_arg *arg = a3;
chunk_appendf(&trace_buf, " len=%lu fin=%d offset=%llu",
(ulong)arg->len, arg->fin, (ullong)arg->offset);
}
}
}
/* register qmux traces */
INITCALL1(STG_REGISTER, trace_register_source, TRACE_SOURCE);