MINOR: quic: add MUX output for show quic
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 23 Feb 2024 16:32:14 +0000 (17:32 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 29 Feb 2024 09:03:36 +0000 (10:03 +0100)
Extend "show quic" to be able to dump MUX related information. This is
done via the new function qcc_show_quic(). This replaces the old streams
dumping list which was incomplete.

These info are displayed on full output or by specifying "mux" field.

doc/management.txt
include/haproxy/mux_quic.h
src/mux_quic.c
src/quic_cli.c

index 4efeb90..83c4c1d 100644 (file)
@@ -3076,8 +3076,8 @@ show quic [<format>] [<filter>]
   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" and
-  "cc".
+  to restrict output. Currently supported values are "tp", "sock", "pktns",
+  "cc" and "mux".
 
   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 da686c1..b1d2168 100644 (file)
@@ -115,6 +115,8 @@ static inline void qcs_wait_http_req(struct qcs *qcs)
        LIST_APPEND(&qcc->opening_list, &qcs->el_opening);
 }
 
+void qcc_show_quic(struct qcc *qcc);
+
 #endif /* USE_QUIC */
 
 #endif /* _HAPROXY_MUX_QUIC_H */
index 1d82b51..46e21b4 100644 (file)
@@ -3,6 +3,7 @@
 #include <import/eb64tree.h>
 
 #include <haproxy/api.h>
+#include <haproxy/chunk.h>
 #include <haproxy/connection.h>
 #include <haproxy/dynbuf.h>
 #include <haproxy/h3.h>
@@ -125,6 +126,9 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type)
        else if (quic_stream_is_local(qcc, id)) {
                qfctl_init(&qcs->tx.fc, qcc->rfctl.msd_uni_l);
        }
+       else {
+               qcs->tx.fc.off_real = 0;
+       }
 
        qcs->rx.ncbuf = NCBUF_NULL;
        qcs->rx.app_buf = BUF_NULL;
@@ -3185,6 +3189,27 @@ static const struct mux_ops qmux_ops = {
        .name = "QUIC",
 };
 
+void qcc_show_quic(struct qcc *qcc)
+{
+       struct eb64_node *node;
+       chunk_appendf(&trash, "  qcc=0x%p flags=0x%x sc=%llu hreq=%llu\n",
+                     qcc, qcc->flags, (ullong)qcc->nb_sc, (ullong)qcc->nb_hreq);
+
+       node = eb64_first(&qcc->streams_by_id);
+       while (node) {
+               struct qcs *qcs = eb64_entry(node, struct qcs, by_id);
+               chunk_appendf(&trash, "    qcs=0x%p id=%llu flags=0x%x st=%s",
+                             qcs, (ullong)qcs->id, qcs->flags,
+                             qcs_st_to_str(qcs->st));
+               if (!quic_stream_is_uni(qcs->id) || !quic_stream_is_local(qcc, qcs->id))
+                       chunk_appendf(&trash, " rxoff=%llu", (ullong)qcs->rx.offset);
+               if (!quic_stream_is_uni(qcs->id) || !quic_stream_is_remote(qcc, qcs->id))
+                       chunk_appendf(&trash, " txoff=%llu", (ullong)qcs->tx.fc.off_real);
+               chunk_appendf(&trash, "\n");
+               node = eb64_next(node);
+       }
+}
+
 static struct mux_proto_list mux_proto_quic =
   { .token = IST("quic"), .mode = PROTO_MODE_HTTP, .side = PROTO_SIDE_FE, .mux = &qmux_ops };
 
index 526acc6..49501d5 100644 (file)
@@ -3,9 +3,10 @@
 #include <haproxy/applet-t.h>
 #include <haproxy/cli.h>
 #include <haproxy/list.h>
-#include <haproxy/tools.h>
+#include <haproxy/mux_quic.h>
 #include <haproxy/quic_conn-t.h>
 #include <haproxy/quic_tp.h>
+#include <haproxy/tools.h>
 
 /* incremented by each "show quic". */
 unsigned int qc_epoch = 0;
@@ -21,8 +22,9 @@ enum quic_dump_format {
 #define QUIC_DUMP_FLD_SOCK  0x0002
 #define QUIC_DUMP_FLD_PKTNS 0x0004
 #define QUIC_DUMP_FLD_CC    0x0008
+#define QUIC_DUMP_FLD_MUX   0x0010
 /* Do not forget to update FLD_MASK when adding a new field. */
-#define QUIC_DUMP_FLD_MASK  0x000f
+#define QUIC_DUMP_FLD_MASK  0x001f
 
 /* appctx context used by "show quic" command */
 struct show_quic_ctx {
@@ -90,6 +92,9 @@ static int cli_parse_show_quic(char **args, char *payload, struct appctx *appctx
                        else if (isteq(field, ist("cc"))) {
                                ctx->fields |= QUIC_DUMP_FLD_CC;
                        }
+                       else if (isteq(field, ist("mux"))) {
+                               ctx->fields |= QUIC_DUMP_FLD_MUX;
+                       }
                        else {
                                /* Current argument is comma-separated so it is
                                 * interpreted as a field list but an unknown
@@ -202,10 +207,8 @@ static void dump_quic_oneline(struct show_quic_ctx *ctx, struct quic_conn *qc)
 static void dump_quic_full(struct show_quic_ctx *ctx, struct quic_conn *qc)
 {
        struct quic_pktns *pktns;
-       struct eb64_node *node;
-       struct qc_stream_desc *stream;
        char bufaddr[INET6_ADDRSTRLEN], bufport[6];
-       int expire, i, addnl;
+       int expire, addnl;
        unsigned char cid_len;
 
        addnl = 0;
@@ -351,23 +354,8 @@ static void dump_quic_full(struct show_quic_ctx *ctx, struct quic_conn *qc)
        if (addnl)
                chunk_appendf(&trash, "\n");
 
-       /* Streams */
-       node = eb64_first(&qc->streams_by_id);
-       i = 0;
-       while (node) {
-               stream = eb64_entry(node, struct qc_stream_desc, by_id);
-               node = eb64_next(node);
-
-               chunk_appendf(&trash, "  | stream=%-8llu", (unsigned long long)stream->by_id.key);
-               chunk_appendf(&trash, " off=%-8llu ack=%-8llu",
-                             (unsigned long long)stream->buf_offset,
-                             (unsigned long long)stream->ack_offset);
-
-               if (!(++i % 3)) {
-                       chunk_appendf(&trash, "\n");
-                       i = 0;
-               }
-       }
+       if (ctx->fields & QUIC_DUMP_FLD_MUX && qc->mux_state == QC_MUX_READY)
+               qcc_show_quic(qc->qcc);
 
        chunk_appendf(&trash, "\n");
 }