MINOR: mux-quic: standardize h3 settings sending
Use same buffer management to send h3 settings as for streams. This
simplify the code maintenance with unused function removed.
diff --git a/src/h3.c b/src/h3.c
index 602627f..1469dfb 100644
--- a/src/h3.c
+++ b/src/h3.c
@@ -76,35 +76,6 @@
return b_make(b->area, b->size, b->head, b->data);
}
-static int qcs_buf_available(void *target)
-{
- struct h3_uqs *h3_uqs = target;
- struct qcs *qcs = h3_uqs->qcs;
-
- if ((qcs->flags & OUQS_SF_TXBUF_MALLOC) && b_alloc(&qcs->tx.buf)) {
- qcs->flags &= ~OUQS_SF_TXBUF_MALLOC;
- tasklet_wakeup(h3_uqs->wait_event.tasklet);
- return 1;
- }
-
- return 0;
-}
-
-static struct buffer *h3_uqs_get_buf(struct h3_uqs *h3_uqs)
-{
- struct buffer *buf = NULL;
- struct h3 *h3 = h3_uqs->qcs->qcc->ctx;
-
- if (likely(!LIST_INLIST(&h3->buf_wait.list)) &&
- unlikely((buf = b_alloc(&h3_uqs->qcs->tx.buf)) == NULL)) {
- h3->buf_wait.target = h3_uqs;
- h3->buf_wait.wakeup_cb = qcs_buf_available;
- LIST_APPEND(&th_ctx->buffer_wq, &h3->buf_wait.list);
- }
-
- return buf;
-}
-
/* Decode a h3 frame header made of two QUIC varints from <b> buffer.
* Returns the number of bytes consumed if there was enough data in <b>, 0 if not.
* Note that this function update <b> buffer to reflect the number of bytes consumed
@@ -342,24 +313,15 @@
return 1;
}
-int h3_txbuf_cpy(struct h3_uqs *h3_uqs, unsigned char *buf, size_t len)
+/* Returns buffer for data sending.
+ * May be NULL if the allocation failed.
+ */
+static struct buffer *mux_get_buf(struct qcs *qcs)
{
- struct buffer *res = &h3_uqs->qcs->tx.buf;
- struct qcc *qcc = h3_uqs->qcs->qcc;
- int ret;
-
- ret = 0;
- if (!h3_uqs_get_buf(h3_uqs)) {
- qcc->flags |= OUQS_SF_TXBUF_MALLOC;
- goto out;
- }
-
- ret = b_istput(res, ist2((char *)buf, len));
- if (unlikely(!ret))
- qcc->flags |= OUQS_SF_TXBUF_FULL;
+ if (!b_size(&qcs->tx.buf))
+ b_alloc(&qcs->tx.buf);
- out:
- return ret;
+ return &qcs->tx.buf;
}
/* Function used to emit stream data from <h3_uqs> control uni-stream */
@@ -368,14 +330,12 @@
int ret;
struct h3 *h3 = ctx;
unsigned char data[(2 + 3) * 2 * QUIC_VARINT_MAX_SIZE]; /* enough for 3 settings */
- unsigned char *pos, *end;
+ struct buffer pos, *res;
ret = 0;
- pos = data;
- end = pos + sizeof data;
+ pos = b_make((char *)data, sizeof(data), 0, 0);
if (!(h3->flags & H3_CF_SETTINGS_SENT)) {
struct qcs *qcs = h3_uqs->qcs;
- struct buffer *txbuf = &qcs->tx.buf;
size_t frm_len;
frm_len = quic_int_getsize(H3_SETTINGS_QPACK_MAX_TABLE_CAPACITY) +
@@ -387,46 +347,37 @@
quic_int_getsize(h3_settings_max_field_section_size);
}
- quic_enc_int(&pos, end, H3_UNI_STRM_TP_CONTROL_STREAM);
+ b_quic_enc_int(&pos, H3_UNI_STRM_TP_CONTROL_STREAM);
/* Build a SETTINGS frame */
- quic_enc_int(&pos, end, H3_FT_SETTINGS);
- quic_enc_int(&pos, end, frm_len);
- quic_enc_int(&pos, end, H3_SETTINGS_QPACK_MAX_TABLE_CAPACITY);
- quic_enc_int(&pos, end, h3_settings_qpack_max_table_capacity);
- quic_enc_int(&pos, end, H3_SETTINGS_QPACK_BLOCKED_STREAMS);
- quic_enc_int(&pos, end, h3_settings_qpack_blocked_streams);
+ b_quic_enc_int(&pos, H3_FT_SETTINGS);
+ b_quic_enc_int(&pos, frm_len);
+ b_quic_enc_int(&pos, H3_SETTINGS_QPACK_MAX_TABLE_CAPACITY);
+ b_quic_enc_int(&pos, h3_settings_qpack_max_table_capacity);
+ b_quic_enc_int(&pos, H3_SETTINGS_QPACK_BLOCKED_STREAMS);
+ b_quic_enc_int(&pos, h3_settings_qpack_blocked_streams);
if (h3_settings_max_field_section_size) {
- quic_enc_int(&pos, end, H3_SETTINGS_MAX_FIELD_SECTION_SIZE);
- quic_enc_int(&pos, end, h3_settings_max_field_section_size);
+ b_quic_enc_int(&pos, H3_SETTINGS_MAX_FIELD_SECTION_SIZE);
+ b_quic_enc_int(&pos, h3_settings_max_field_section_size);
}
- ret = h3_txbuf_cpy(h3_uqs, data, pos - data);
- if (ret < 0) {
- qc_error(qcs->qcc, H3_INTERNAL_ERROR);
- return ret;
+
+ res = mux_get_buf(qcs);
+ if (b_room(res) < b_data(&pos)) {
+ // TODO the mux should be put in blocked state, with
+ // the stream in state waiting for settings to be sent
+ ABORT_NOW();
}
+ ret = b_force_xfer(res, &pos, b_data(&pos));
if (ret > 0) {
h3->flags |= H3_CF_SETTINGS_SENT;
- luqs_snd_buf(h3_uqs->qcs, txbuf, b_data(&qcs->tx.buf), 0);
+ if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND))
+ tasklet_wakeup(qcs->qcc->wait_event.tasklet);
}
- if (b_data(&qcs->tx.buf))
- qcs->qcc->conn->mux->luqs_subscribe(qcs, SUB_RETRY_SEND, &h3->lctrl.wait_event);
}
return ret;
}
-/* Returns buffer for data sending.
- * May be NULL if the allocation failed.
- */
-static struct buffer *mux_get_buf(struct qcs *qcs)
-{
- if (!b_size(&qcs->tx.buf))
- b_alloc(&qcs->tx.buf);
-
- return &qcs->tx.buf;
-}
-
static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
{
struct buffer outbuf;