struct quic_fctl fc; /* stream flow control applied on sending */
uint64_t buf_in_flight; /* sum of currently allocated Tx buffer sizes */
struct list frms; /* list of STREAM frames ready for sent */
- struct quic_pacer pacer; /* engine used to pace emission */
- int paced_sent_ctr; /* counter for when emission is interrupted due to pacing */
+ union {
+ struct {
+ /* quic */
+ struct quic_pacer pacer; /* engine used to pace emission */
+ int paced_sent_ctr; /* counter for when emission is interrupted due to pacing */
+ };
+ /* qstrm */
+ struct buffer qstrm_buf;
+ };
} tx;
struct {
struct buffer qstrm_buf;
}
if (!conn_is_quic(conn)) {
+ qcc->tx.qstrm_buf = BUF_NULL;
+ b_alloc(&qcc->tx.qstrm_buf, DB_MUX_TX);
+ if (!b_size(&qcc->tx.qstrm_buf)) {
+ TRACE_ERROR("tx qstrm buf alloc failure", QMUX_EV_QCC_NEW);
+ goto err;
+ }
+
qcc->rx.qstrm_buf = BUF_NULL;
b_alloc(&qcc->rx.qstrm_buf, DB_MUX_RX);
if (!b_size(&qcc->rx.qstrm_buf)) {
struct connection *conn = qcc->conn;
struct quic_frame *frm, *frm_old;
struct quic_frame *split_frm, *orig_frm;
+ struct buffer *buf = &qcc->tx.qstrm_buf;
unsigned char *pos, *old, *end;
size_t ret;
TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn);
+
+ if (b_data(buf)) {
+ ret = conn->xprt->snd_buf(conn, conn->xprt_ctx, buf, b_data(buf), NULL, 0, 0);
+ if (!ret) {
+ TRACE_DEVEL("snd_buf interrupted", QMUX_EV_QCC_SEND, qcc->conn);
+ goto out;
+ }
+
+ if (ret != b_data(buf)) {
+ /* TODO */
+ ABORT_NOW();
+ }
+ }
+
+ b_reset(buf);
list_for_each_entry_safe(frm, frm_old, frms, list) {
loop:
split_frm = NULL;
- b_reset(&trash);
- old = pos = (unsigned char *)b_orig(&trash);
- end = (unsigned char *)b_wrap(&trash);
+ b_reset(buf);
+ old = pos = (unsigned char *)b_orig(buf);
+ end = (unsigned char *)b_wrap(buf);
BUG_ON(!frm);
TRACE_PRINTF(TRACE_LEVEL_DEVELOPER, QMUX_EV_QCC_SEND, qcc->conn, 0, 0, 0,
qc_build_frm(frm, &pos, end, NULL);
BUG_ON(pos - old > global.tune.bufsize);
BUG_ON(pos == old);
- b_add(&trash, pos - old);
+ b_add(buf, pos - old);
- ret = conn->xprt->snd_buf(conn, conn->xprt_ctx, &trash, b_data(&trash), NULL, 0, 0);
+ ret = conn->xprt->snd_buf(conn, conn->xprt_ctx, buf, b_data(buf), NULL, 0, 0);
if (!ret) {
TRACE_DEVEL("snd_buf interrupted", QMUX_EV_QCC_SEND, qcc->conn);
if (split_frm)
break;
}
- if (ret != b_data(&trash)) {
+ if (ret != b_data(buf)) {
/* TODO */
ABORT_NOW();
}
}
}
+ out:
if (conn->flags & CO_FL_ERROR) {
/* TODO */
//ABORT_NOW();