From: Amaury Denoyelle Date: Tue, 21 Dec 2021 10:53:10 +0000 (+0100) Subject: REORG: quic: move mux function outside of xprt X-Git-Tag: v2.6-dev1~246 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a5b27a9b93b5e08d349e497c0e799405548d6ef;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/include/haproxy/mux_quic.h b/include/haproxy/mux_quic.h index 8a4b7ee901..c3eee86e55 100644 --- a/include/haproxy/mux_quic.h +++ b/include/haproxy/mux_quic.h @@ -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 */ diff --git a/src/mux_quic.c b/src/mux_quic.c index f7c38c7460..4886971bc7 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -117,6 +117,78 @@ void qcs_notify_send(struct qcs *qcs) } } +/* Retrieve as an ebtree node the stream with 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) { diff --git a/src/xprt_quic.c b/src/xprt_quic.c index eec30a5038..86936bc167 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -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 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 into stream. * Also update frame to reflect the data which have been consumed. */