MINOR: quic: add stream format for "show quic"

Add a new format for "show quic" command labelled as "stream". This is
an equivalent of "show sess", dedicated to the QUIC stack. Each active
QUIC streams are listed on a line with their related infos.

The main objective of this command is to ensure there is no freeze
streams remaining after a transfer.
This commit is contained in:
Amaury Denoyelle 2025-05-07 16:28:39 +02:00
parent 1ccede211c
commit cbadfa0163
2 changed files with 42 additions and 5 deletions

View File

@ -3274,11 +3274,11 @@ show quic [<format>] [<filter>]
An optional argument can be specified to control the verbosity. Its value can
be interpreted in different way. The first possibility is to used predefined
values, "oneline" for the default format and "full" to display all
information. Alternatively, a list of comma-delimited fields can be specified
to restrict output. Currently supported values are "tp", "sock", "pktns",
"cc" and "mux". Finally, "help" in the format will instead show a more
detailed help message.
values, "oneline" for the default format, "stream" to list every active
streams and "full" to display all information. Alternatively, a list of
comma-delimited fields can be specified to restrict output. Currently
supported values are "tp", "sock", "pktns", "cc" and "mux". Finally, "help"
in the format will instead show a more detailed help message.
The final argument is used to restrict or extend the connection list. By
default, connections on closing or draining state are not displayed. Use the

View File

@ -6,6 +6,7 @@
#include <haproxy/mux_quic.h>
#include <haproxy/quic_conn-t.h>
#include <haproxy/quic_tp.h>
#include <haproxy/quic_utils.h>
#include <haproxy/tools.h>
/* incremented by each "show quic". */
@ -15,6 +16,7 @@ enum quic_dump_format {
QUIC_DUMP_FMT_DEFAULT, /* value used if not explicitly specified. */
QUIC_DUMP_FMT_ONELINE,
QUIC_DUMP_FMT_STREAM,
QUIC_DUMP_FMT_CUST,
};
@ -70,6 +72,11 @@ static int cli_parse_show_quic(char **args, char *payload, struct appctx *appctx
ctx->format = QUIC_DUMP_FMT_ONELINE;
++argc;
}
else if (strcmp(args[argc], "stream") == 0) {
ctx->format = QUIC_DUMP_FMT_STREAM;
ctx->fields = QUIC_DUMP_FLD_MASK;
++argc;
}
else if (strcmp(args[argc], "full") == 0) {
ctx->format = QUIC_DUMP_FMT_CUST;
ctx->fields = QUIC_DUMP_FLD_MASK;
@ -80,6 +87,7 @@ static int cli_parse_show_quic(char **args, char *payload, struct appctx *appctx
"Usage: show quic [help|<format>] [<filter>]\n"
"Dumps information about QUIC connections. Available output formats:\n"
" oneline dump a single, netstat-like line per connection (default)\n"
" stream dump a list of streams, one per line, sorted by connection\n"
" full dump all known information about each connection\n"
" <levels>* only dump certain information, defined by a comma-delimited list\n"
" of levels among 'tp', 'sock', 'pktns', 'cc', or 'mux'\n"
@ -218,6 +226,31 @@ static void dump_quic_oneline(struct show_quic_ctx *ctx, struct quic_conn *qc)
chunk_appendf(&trash, "\n");
}
/* Dump for "show quic" with "stream" format. */
static void dump_quic_stream(struct show_quic_ctx *ctx, struct quic_conn *qc)
{
struct eb64_node *node;
struct qc_stream_desc *sd;
uint64_t id;
node = eb64_first(&qc->streams_by_id);
while (node) {
sd = eb_entry(node, struct qc_stream_desc, by_id);
id = sd->by_id.key;
if (quic_stream_is_uni(id)) {
node = eb64_next(node);
continue;
}
chunk_appendf(&trash, "%p.%04llu: 0x%02x", qc, (ullong)id, sd->flags);
bdata_ctr_print(&trash, &sd->data, " txb=");
chunk_appendf(&trash, "\n");
node = eb64_next(node);
}
}
/* Dump for "show quic" with "full" format. */
static void dump_quic_full(struct show_quic_ctx *ctx, struct quic_conn *qc)
{
@ -464,6 +497,10 @@ static int cli_io_handler_dump_quic(struct appctx *appctx)
dump_quic_oneline(ctx, qc);
break;
case QUIC_DUMP_FMT_STREAM:
dump_quic_stream(ctx, qc);
break;
case QUIC_DUMP_FMT_DEFAULT:
/* An explicit format must be returned by cli_show_quic_format(). */
ABORT_NOW();