]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: add stream format for "show quic"
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 7 May 2025 14:28:39 +0000 (16:28 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 13 May 2025 13:41:51 +0000 (15:41 +0200)
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.

doc/management.txt
src/quic_cli.c

index 8ce6dae888b5a0b136541cf148f647957f58d725..b5ee76a13e9ebad3ea4afc4e03d887c57e41bca7 100644 (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
index ffe25855ff2640e7acaf4f74c1a935551d011b9a..6e60eed8e019b8035525b612683fdefc313d3abe 100644 (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();