diff --git a/doc/management.txt b/doc/management.txt index 42cf2042bb..978b0482f4 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -2988,10 +2988,10 @@ show quic [] [all] Dump information on all active QUIC frontend connections. This command is restricted and can only be issued on sockets configured for levels "operator" or "admin". An optional format can be specified as first argument to control - the verbosity. Currently only supported value is "full" which is the default - if format is unspecified. By default, connections on closing or draining - state are not displayed. Use the extra argument "all" to include them in the - output. + the verbosity. Currently supported values are "oneline" which is the default + if format is unspecified or "full". By default, connections on closing or + draining state are not displayed. Use the extra argument "all" to include + them in the output. show servers conn [] Dump the current and idle connections state of the servers belonging to the diff --git a/src/quic_conn.c b/src/quic_conn.c index 1d43cd8d98..c3e0beccf6 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -8596,6 +8596,7 @@ void qc_finalize_affinity_rebind(struct quic_conn *qc) } enum quic_dump_format { + QUIC_DUMP_FMT_ONELINE, QUIC_DUMP_FMT_FULL, }; @@ -8621,12 +8622,16 @@ static int cli_parse_show_quic(char **args, char *payload, struct appctx *appctx ctx->epoch = _HA_ATOMIC_FETCH_ADD(&qc_epoch, 1); ctx->thr = 0; ctx->flags = 0; - ctx->format = QUIC_DUMP_FMT_FULL; + ctx->format = QUIC_DUMP_FMT_ONELINE; - if (strcmp(args[argc], "full") == 0) { + if (strcmp(args[argc], "oneline") == 0) { /* format already used as default value */ ++argc; } + else if (strcmp(args[argc], "full") == 0) { + ctx->format = QUIC_DUMP_FMT_FULL; + ++argc; + } while (*args[argc]) { if (strcmp(args[argc], "all") == 0) @@ -8640,6 +8645,54 @@ static int cli_parse_show_quic(char **args, char *payload, struct appctx *appctx return 0; } +/* Dump for "show quic" with "oneline" format. */ +static void dump_quic_oneline(struct show_quic_ctx *ctx, struct quic_conn *qc) +{ + char bufaddr[INET6_ADDRSTRLEN], bufport[6]; + unsigned char cid_len; + + chunk_appendf(&trash, "%p[%02u]/%-.12s ", qc, ctx->thr, + qc->li->bind_conf->frontend->id); + + /* State */ + if (qc->flags & QUIC_FL_CONN_CLOSING) + chunk_appendf(&trash, "CLOSE "); + else if (qc->flags & QUIC_FL_CONN_DRAINING) + chunk_appendf(&trash, "DRAIN "); + else if (qc->state < QUIC_HS_ST_COMPLETE) + chunk_appendf(&trash, "HDSHK "); + else + chunk_appendf(&trash, "ESTAB "); + + /* Bytes in flight / Lost packets */ + chunk_appendf(&trash, "%9llu %6llu %6llu ", + (ullong)qc->path->in_flight, + (ullong)qc->path->ifae_pkts, + (ullong)qc->path->loss.nb_lost_pkt); + + /* Socket */ + if (qc->local_addr.ss_family == AF_INET || + qc->local_addr.ss_family == AF_INET6) { + addr_to_str(&qc->peer_addr, bufaddr, sizeof(bufaddr)); + port_to_str(&qc->peer_addr, bufport, sizeof(bufport)); + chunk_appendf(&trash, "%15s:%s ", bufaddr, bufport); + + addr_to_str(&qc->local_addr, bufaddr, sizeof(bufaddr)); + port_to_str(&qc->local_addr, bufport, sizeof(bufport)); + chunk_appendf(&trash, "%15s:%s ", bufaddr, bufport); + } + + /* CIDs */ + for (cid_len = 0; cid_len < qc->scid.len; ++cid_len) + chunk_appendf(&trash, "%02x", qc->scid.data[cid_len]); + + chunk_appendf(&trash, " "); + for (cid_len = 0; cid_len < qc->dcid.len; ++cid_len) + chunk_appendf(&trash, "%02x", qc->dcid.data[cid_len]); + + chunk_appendf(&trash, "\n"); +} + /* Dump for "show quic" with "full" format. */ static void dump_quic_full(struct show_quic_ctx *ctx, struct quic_conn *qc) { @@ -8779,6 +8832,15 @@ static int cli_io_handler_dump_quic(struct appctx *appctx) else if (!ctx->bref.ref) { /* First invocation. */ ctx->bref.ref = ha_thread_ctx[ctx->thr].quic_conns.n; + + /* Print legend for oneline format. */ + if (ctx->format == QUIC_DUMP_FMT_ONELINE) { + chunk_appendf(&trash, "# conn/frontend state " + "in_flight infl_p lost_p " + "from to " + "local & remote CIDs\n"); + applet_putchk(appctx, &trash); + } } while (1) { @@ -8822,6 +8884,9 @@ static int cli_io_handler_dump_quic(struct appctx *appctx) case QUIC_DUMP_FMT_FULL: dump_quic_full(ctx, qc); break; + case QUIC_DUMP_FMT_ONELINE: + dump_quic_oneline(ctx, qc); + break; } if (applet_putchk(appctx, &trash) == -1) {