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 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 be interpreted in different way. The first possibility is to used predefined
values, "oneline" for the default format and "full" to display all values, "oneline" for the default format, "stream" to list every active
information. Alternatively, a list of comma-delimited fields can be specified streams and "full" to display all information. Alternatively, a list of
to restrict output. Currently supported values are "tp", "sock", "pktns", comma-delimited fields can be specified to restrict output. Currently
"cc" and "mux". Finally, "help" in the format will instead show a more supported values are "tp", "sock", "pktns", "cc" and "mux". Finally, "help"
detailed help message. in the format will instead show a more detailed help message.
The final argument is used to restrict or extend the connection list. By 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 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/mux_quic.h>
#include <haproxy/quic_conn-t.h> #include <haproxy/quic_conn-t.h>
#include <haproxy/quic_tp.h> #include <haproxy/quic_tp.h>
#include <haproxy/quic_utils.h>
#include <haproxy/tools.h> #include <haproxy/tools.h>
/* incremented by each "show quic". */ /* 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_DEFAULT, /* value used if not explicitly specified. */
QUIC_DUMP_FMT_ONELINE, QUIC_DUMP_FMT_ONELINE,
QUIC_DUMP_FMT_STREAM,
QUIC_DUMP_FMT_CUST, 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; ctx->format = QUIC_DUMP_FMT_ONELINE;
++argc; ++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) { else if (strcmp(args[argc], "full") == 0) {
ctx->format = QUIC_DUMP_FMT_CUST; ctx->format = QUIC_DUMP_FMT_CUST;
ctx->fields = QUIC_DUMP_FLD_MASK; 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" "Usage: show quic [help|<format>] [<filter>]\n"
"Dumps information about QUIC connections. Available output formats:\n" "Dumps information about QUIC connections. Available output formats:\n"
" oneline dump a single, netstat-like line per connection (default)\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" " full dump all known information about each connection\n"
" <levels>* only dump certain information, defined by a comma-delimited list\n" " <levels>* only dump certain information, defined by a comma-delimited list\n"
" of levels among 'tp', 'sock', 'pktns', 'cc', or 'mux'\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"); 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. */ /* Dump for "show quic" with "full" format. */
static void dump_quic_full(struct show_quic_ctx *ctx, struct quic_conn *qc) 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); dump_quic_oneline(ctx, qc);
break; break;
case QUIC_DUMP_FMT_STREAM:
dump_quic_stream(ctx, qc);
break;
case QUIC_DUMP_FMT_DEFAULT: case QUIC_DUMP_FMT_DEFAULT:
/* An explicit format must be returned by cli_show_quic_format(). */ /* An explicit format must be returned by cli_show_quic_format(). */
ABORT_NOW(); ABORT_NOW();