MINOR: quic: New quic_cstream object implementation
Add new quic_cstream struct definition to implement the CRYPTO data stream.
This is a simplication of the qcs object (QUIC streams) for the CRYPTO data
without any information about the flow control. They are not attached to any
tree, but to a QUIC encryption level, one by encryption level except for
the early data encryption level (for 0RTT). A stream descriptor is also allocated
for each CRYPTO data stream.
Must be backported to 2.6
(cherry picked from commit 7e3f7c47e9
)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
This commit is contained in:
parent
2f824716d3
commit
6b84c17d99
@ -510,6 +510,21 @@ struct q_buf {
|
||||
struct list pkts;
|
||||
};
|
||||
|
||||
/* Crypto data stream (one by encryption level) */
|
||||
struct quic_cstream {
|
||||
struct {
|
||||
uint64_t offset; /* absolute current base offset of ncbuf */
|
||||
struct ncbuf ncbuf; /* receive buffer - can handle out-of-order offset frames */
|
||||
} rx;
|
||||
struct {
|
||||
uint64_t offset; /* last offset of data ready to be sent */
|
||||
uint64_t sent_offset; /* last offset sent by transport layer */
|
||||
struct buffer buf; /* transmit buffer before sending via xprt */
|
||||
} tx;
|
||||
|
||||
struct qc_stream_desc *desc;
|
||||
};
|
||||
|
||||
struct quic_enc_level {
|
||||
enum ssl_encryption_level_t level;
|
||||
struct quic_tls_ctx tls_ctx;
|
||||
@ -536,6 +551,8 @@ struct quic_enc_level {
|
||||
uint64_t offset;
|
||||
} crypto;
|
||||
} tx;
|
||||
/* Crypto data stream */
|
||||
struct quic_cstream *cstream;
|
||||
struct quic_pktns *pktns;
|
||||
};
|
||||
|
||||
|
@ -210,6 +210,7 @@ DECLARE_POOL(pool_head_quic_rx_packet, "quic_rx_packet", sizeof(struct quic_rx_p
|
||||
DECLARE_POOL(pool_head_quic_tx_packet, "quic_tx_packet", sizeof(struct quic_tx_packet));
|
||||
DECLARE_STATIC_POOL(pool_head_quic_rx_crypto_frm, "quic_rx_crypto_frm", sizeof(struct quic_rx_crypto_frm));
|
||||
DECLARE_STATIC_POOL(pool_head_quic_crypto_buf, "quic_crypto_buf", sizeof(struct quic_crypto_buf));
|
||||
DECLARE_STATIC_POOL(pool_head_quic_cstream, "quic_cstream", sizeof(struct quic_cstream));
|
||||
DECLARE_POOL(pool_head_quic_frame, "quic_frame", sizeof(struct quic_frame));
|
||||
DECLARE_STATIC_POOL(pool_head_quic_arng, "quic_arng", sizeof(struct quic_arng_node));
|
||||
|
||||
@ -4396,6 +4397,55 @@ struct task *quic_conn_io_cb(struct task *t, void *context, unsigned int state)
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Release the memory allocated for <cs> CRYPTO stream */
|
||||
void quic_cstream_free(struct quic_cstream *cs)
|
||||
{
|
||||
if (!cs) {
|
||||
/* This is the case for ORTT encryption level */
|
||||
return;
|
||||
}
|
||||
|
||||
qc_stream_desc_release(cs->desc);
|
||||
pool_free(pool_head_quic_cstream, cs);
|
||||
}
|
||||
|
||||
/* Allocate a new QUIC stream for <qc>.
|
||||
* Return it if succeeded, NULL if not.
|
||||
*/
|
||||
struct quic_cstream *quic_cstream_new(struct quic_conn *qc)
|
||||
{
|
||||
struct quic_cstream *cs, *ret_cs = NULL;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_LPKT, qc);
|
||||
cs = pool_alloc(pool_head_quic_cstream);
|
||||
if (!cs) {
|
||||
TRACE_ERROR("crypto stream allocation failed", QUIC_EV_CONN_INIT, qc);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
cs->rx.offset = 0;
|
||||
cs->rx.ncbuf = NCBUF_NULL;
|
||||
cs->rx.offset = 0;
|
||||
|
||||
cs->tx.offset = 0;
|
||||
cs->tx.sent_offset = 0;
|
||||
cs->tx.buf = BUF_NULL;
|
||||
cs->desc = qc_stream_desc_new((uint64_t)-1, -1, cs, qc);
|
||||
if (!cs->desc) {
|
||||
TRACE_ERROR("crypto stream allocation failed", QUIC_EV_CONN_INIT, qc);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret_cs = cs;
|
||||
leave:
|
||||
TRACE_LEAVE(QUIC_EV_CONN_LPKT, qc);
|
||||
return ret_cs;
|
||||
|
||||
err:
|
||||
pool_free(pool_head_quic_cstream, cs);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Uninitialize <qel> QUIC encryption level. Never fails. */
|
||||
static void quic_conn_enc_level_uninit(struct quic_conn *qc, struct quic_enc_level *qel)
|
||||
{
|
||||
@ -4410,6 +4460,7 @@ static void quic_conn_enc_level_uninit(struct quic_conn *qc, struct quic_enc_lev
|
||||
}
|
||||
}
|
||||
ha_free(&qel->tx.crypto.bufs);
|
||||
quic_cstream_free(qel->cstream);
|
||||
|
||||
TRACE_LEAVE(QUIC_EV_CONN_CLOSE, qc);
|
||||
}
|
||||
@ -4453,6 +4504,14 @@ static int quic_conn_enc_level_init(struct quic_conn *qc,
|
||||
|
||||
qel->tx.crypto.sz = 0;
|
||||
qel->tx.crypto.offset = 0;
|
||||
/* No CRYPTO data for early data TLS encryption level */
|
||||
if (level == QUIC_TLS_ENC_LEVEL_EARLY_DATA)
|
||||
qel->cstream = NULL;
|
||||
else {
|
||||
qel->cstream = quic_cstream_new(qc);
|
||||
if (!qel->cstream)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
leave:
|
||||
|
@ -18,7 +18,8 @@ DECLARE_STATIC_POOL(pool_head_quic_stream_buf, "qc_stream_buf",
|
||||
|
||||
|
||||
/* Allocate a new stream descriptor with id <id>. The caller is responsible to
|
||||
* store the stream in the appropriate tree.
|
||||
* store the stream in the appropriate tree. -1 special value must be used for
|
||||
* a CRYPTO data stream, the type being ignored.
|
||||
*
|
||||
* Returns the newly allocated instance on success or else NULL.
|
||||
*/
|
||||
@ -31,9 +32,14 @@ struct qc_stream_desc *qc_stream_desc_new(uint64_t id, enum qcs_type type, void
|
||||
if (!stream)
|
||||
return NULL;
|
||||
|
||||
stream->by_id.key = id;
|
||||
eb64_insert(&qc->streams_by_id, &stream->by_id);
|
||||
qc->rx.strms[type].nb_streams++;
|
||||
if (id == (uint64_t)-1) {
|
||||
stream->by_id.key = (uint64_t)-1;
|
||||
}
|
||||
else {
|
||||
stream->by_id.key = id;
|
||||
eb64_insert(&qc->streams_by_id, &stream->by_id);
|
||||
qc->rx.strms[type].nb_streams++;
|
||||
}
|
||||
stream->qc = qc;
|
||||
|
||||
stream->buf = NULL;
|
||||
@ -195,7 +201,8 @@ void qc_stream_desc_free(struct qc_stream_desc *stream, int closing)
|
||||
qc_release_frm(qc, frm);
|
||||
}
|
||||
|
||||
eb64_delete(&stream->by_id);
|
||||
if (stream->by_id.key != (uint64_t)-1)
|
||||
eb64_delete(&stream->by_id);
|
||||
pool_free(pool_head_quic_stream_desc, stream);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user