MEDIUM: mux-quic/xprt_qstrm: implement QMux record emission

This patch implements emission of the new Record layer for QMux frames.
This handles mux-quic and xprt_qstrm layers as this is performed
similarly in both cases.

Currently, the simplest approach has been prefered : each frame is
encoded in its own record. This is not the most efficient in size but it
is extremely simple to implement for a first interop testing.
This commit is contained in:
Amaury Denoyelle 2026-04-08 10:33:10 +02:00
parent 792e055c7c
commit a993f0c503
2 changed files with 16 additions and 5 deletions

View File

@ -242,6 +242,8 @@ int qcc_qstrm_send_frames(struct qcc *qcc, struct list *frms)
struct buffer *buf = &qcc->tx.qstrm_buf;
unsigned char *pos, *old, *end;
size_t ret;
/* Record size field length */
const int lensz = quic_int_getsize(quic_int_cap_length(b_size(buf)));
TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn);
@ -258,12 +260,12 @@ int qcc_qstrm_send_frames(struct qcc *qcc, struct list *frms)
}
}
b_reset(buf);
list_for_each_entry_safe(frm, frm_old, frms, list) {
loop:
split_frm = next_frm = NULL;
b_reset(buf);
old = pos = (unsigned char *)b_orig(buf);
/* Reserve 4 bytes for the record header. */
old = pos = (unsigned char *)b_orig(buf) + lensz;
end = (unsigned char *)b_wrap(buf);
BUG_ON(!frm);
@ -292,6 +294,10 @@ int qcc_qstrm_send_frames(struct qcc *qcc, struct list *frms)
qc_build_frm(frm, &pos, end, NULL);
BUG_ON(pos - old > global.tune.bufsize);
BUG_ON(pos == old);
/* Encode record header and save built payload. */
ret = b_quic_enc_int(buf, pos - old, lensz);
BUG_ON(!ret);
b_add(buf, pos - old);
ret = conn->xprt->snd_buf(conn, conn->xprt_ctx, buf, b_data(buf), NULL, 0, 0);

View File

@ -125,7 +125,7 @@ int conn_send_qstrm(struct connection *conn, struct xprt_qstrm_ctx *ctx, int fla
struct buffer *buf = &ctx->txbuf;
unsigned char *pos, *old, *end;
size_t sent;
int ret;
int ret, lensz;
if (!conn_ctrl_ready(conn))
goto fail;
@ -136,12 +136,17 @@ int conn_send_qstrm(struct connection *conn, struct xprt_qstrm_ctx *ctx, int fla
/* Small buf is sufficient for our transport parameters. */
if (!b_size(buf) && !b_alloc_small(buf))
goto fail;
/* Record size field length */
lensz = quic_int_getsize(quic_int_cap_length(b_size(buf)));
if (!b_data(buf)) {
old = pos = (unsigned char *)b_orig(buf);
old = pos = (unsigned char *)b_orig(buf) + lensz;
end = (unsigned char *)b_wrap(buf);
ret = qc_build_frm(&frm, &pos, end, NULL);
BUG_ON(!ret);
BUG_ON(!ret); /* should never fail */
ret = b_quic_enc_int(buf, pos - old, lensz);
BUG_ON(!ret); /* should never fail */
b_add(buf, pos - old);
}