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
LIST_APPEND(&qcc->opening_list, &qcs->el_opening);
}
+void qcc_show_quic(struct qcc *qcc);
+
#endif /* USE_QUIC */
#endif /* _HAPROXY_MUX_QUIC_H */
#include <import/eb64tree.h>
#include <haproxy/api.h>
+#include <haproxy/chunk.h>
#include <haproxy/connection.h>
#include <haproxy/dynbuf.h>
#include <haproxy/h3.h>
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;
.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 };
#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;
#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 {
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
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;
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");
}