REORG: quic: move mux function outside of xprt

Move qcc_get_qcs() function from xprt_quic.c to mux_quic.c. This
function is used to retrieve the qcs instance from a qcc with a stream
id. This clearly belongs to the mux-quic layer.
This commit is contained in:
Amaury Denoyelle 2021-12-21 11:53:10 +01:00
parent 17a741693c
commit 8a5b27a9b9
3 changed files with 74 additions and 77 deletions

View File

@ -52,6 +52,8 @@ static inline int qcs_get_next_id(struct qcc *qcc, enum qcs_type type)
return (qcc->strms[type].nb_streams++ << QCS_ID_TYPE_SHIFT) | type;
}
struct eb64_node *qcc_get_qcs(struct qcc *qcc, uint64_t id);
#endif /* USE_QUIC */
#endif /* _HAPROXY_MUX_QUIC_H */

View File

@ -117,6 +117,78 @@ void qcs_notify_send(struct qcs *qcs)
}
}
/* Retrieve as an ebtree node the stream with <id> as ID, possibly allocates
* several streams, depending on the already open ones.
* Return this node if succeeded, NULL if not.
*/
struct eb64_node *qcc_get_qcs(struct qcc *qcc, uint64_t id)
{
unsigned int strm_type;
int64_t sub_id;
struct eb64_node *strm_node;
strm_type = id & QCS_ID_TYPE_MASK;
sub_id = id >> QCS_ID_TYPE_SHIFT;
strm_node = NULL;
if (qc_local_stream_id(qcc, id)) {
/* Local streams: this stream must be already opened. */
strm_node = eb64_lookup(&qcc->streams_by_id, id);
if (!strm_node) {
/* unknown stream id */
goto out;
}
}
else {
/* Remote streams. */
struct eb_root *strms;
uint64_t largest_id;
enum qcs_type qcs_type;
strms = &qcc->streams_by_id;
qcs_type = qcs_id_type(id);
if (sub_id + 1 > qcc->strms[qcs_type].max_streams) {
/* streams limit reached */
goto out;
}
/* Note: ->largest_id was initialized with (uint64_t)-1 as value, 0 being a
* correct value.
*/
largest_id = qcc->strms[qcs_type].largest_id;
if (sub_id > (int64_t)largest_id) {
/* RFC: "A stream ID that is used out of order results in all streams
* of that type with lower-numbered stream IDs also being opened".
* So, let's "open" these streams.
*/
int64_t i;
struct qcs *qcs;
qcs = NULL;
for (i = largest_id + 1; i <= sub_id; i++) {
uint64_t id = (i << QCS_ID_TYPE_SHIFT) | strm_type;
enum qcs_type type = id & QCS_ID_DIR_BIT ? QCS_CLT_UNI : QCS_CLT_BIDI;
qcs = qcs_new(qcc, id, type);
if (!qcs) {
/* allocation failure */
goto out;
}
qcc->strms[qcs_type].largest_id = i;
}
if (qcs)
strm_node = &qcs->by_id;
}
else {
strm_node = eb64_lookup(strms, id);
}
}
return strm_node;
out:
return NULL;
}
/* detachs the QUIC stream from its QCC and releases it to the QCS pool. */
static void qcs_destroy(struct qcs *qcs)
{

View File

@ -1949,83 +1949,6 @@ struct quic_rx_strm_frm *new_quic_rx_strm_frm(struct quic_stream *stream_frm,
return frm;
}
/* Retrieve as an ebtree node the stream with <id> as ID, possibly allocates
* several streams, depending on the already open ones.
* Return this node if succeeded, NULL if not.
*/
static struct eb64_node *qcc_get_qcs(struct qcc *qcc, uint64_t id)
{
unsigned int strm_type;
int64_t sub_id;
struct eb64_node *strm_node;
TRACE_ENTER(QUIC_EV_CONN_PSTRM, qcc->conn);
strm_type = id & QCS_ID_TYPE_MASK;
sub_id = id >> QCS_ID_TYPE_SHIFT;
strm_node = NULL;
if (qc_local_stream_id(qcc, id)) {
/* Local streams: this stream must be already opened. */
strm_node = eb64_lookup(&qcc->streams_by_id, id);
if (!strm_node) {
TRACE_PROTO("Unknown stream ID", QUIC_EV_CONN_PSTRM, qcc->conn);
goto out;
}
}
else {
/* Remote streams. */
struct eb_root *strms;
uint64_t largest_id;
enum qcs_type qcs_type;
strms = &qcc->streams_by_id;
qcs_type = qcs_id_type(id);
if (sub_id + 1 > qcc->strms[qcs_type].max_streams) {
TRACE_PROTO("Streams limit reached", QUIC_EV_CONN_PSTRM, qcc->conn);
goto out;
}
/* Note: ->largest_id was initialized with (uint64_t)-1 as value, 0 being a
* correct value.
*/
largest_id = qcc->strms[qcs_type].largest_id;
if (sub_id > (int64_t)largest_id) {
/* RFC: "A stream ID that is used out of order results in all streams
* of that type with lower-numbered stream IDs also being opened".
* So, let's "open" these streams.
*/
int64_t i;
struct qcs *qcs;
qcs = NULL;
for (i = largest_id + 1; i <= sub_id; i++) {
uint64_t id = (i << QCS_ID_TYPE_SHIFT) | strm_type;
enum qcs_type type = id & QCS_ID_DIR_BIT ? QCS_CLT_UNI : QCS_CLT_BIDI;
qcs = qcs_new(qcc, id, type);
if (!qcs) {
TRACE_PROTO("Could not allocate a new stream",
QUIC_EV_CONN_PSTRM, qcc->conn);
goto out;
}
qcc->strms[qcs_type].largest_id = i;
}
if (qcs)
strm_node = &qcs->by_id;
}
else {
strm_node = eb64_lookup(strms, id);
}
}
TRACE_LEAVE(QUIC_EV_CONN_PSTRM, qcc->conn);
return strm_node;
out:
TRACE_LEAVE(QUIC_EV_CONN_PSTRM, qcc->conn);
return NULL;
}
/* Copy as most as possible STREAM data from <strm_frm> into <strm> stream.
* Also update <strm_frm> frame to reflect the data which have been consumed.
*/