QCS_SRV_BIDI,
QCS_CLT_UNI,
QCS_SRV_UNI,
-
- /* Must be the last one */
- QCS_MAX_TYPES
};
enum qcc_app_st {
return global.tune.bufsize - NCB_RESERVED_SZ;
}
-/* Bit shift to get the stream sub ID for internal use which is obtained
- * shifting the stream IDs by this value, knowing that the
- * QCS_ID_TYPE_SHIFT less significant bits identify the stream ID
- * types (client initiated bidirectional, server initiated bidirectional,
- * client initiated unidirectional, server initiated bidirectional).
- * Note that there is no reference to such stream sub IDs in the RFC.
- */
#define QCS_ID_TYPE_MASK 0x3
-#define QCS_ID_TYPE_SHIFT 2
/* The less significant bit of a stream ID is set for a server initiated stream */
#define QCS_ID_SRV_INTIATOR_BIT 0x1
/* This bit is set for unidirectional streams */
/* RX buffer */
struct buffer buf;
struct list pkt_list;
- struct {
- /* Number of open or closed streams */
- uint64_t nb_streams;
- } strms[QCS_MAX_TYPES];
+
+ /* first unhandled streams ID, set by MUX after release */
+ uint64_t stream_max_uni;
+ uint64_t stream_max_bidi;
} rx;
struct {
struct quic_tls_kp prv_rx;
qcs_free(qcs);
}
- /* unsubscribe from all remaining qc_stream_desc */
if (conn) {
qc = conn->handle.qc;
+
+ /* unsubscribe from all remaining qc_stream_desc */
node = eb64_first(&qc->streams_by_id);
while (node) {
struct qc_stream_desc *stream = eb64_entry(node, struct qc_stream_desc, by_id);
qc_stream_desc_sub_room(stream, NULL);
node = eb64_next(node);
}
+
+ /* register streams IDs so that quic-conn layer can ignore already closed streams. */
+ qc->rx.stream_max_uni = qcc->largest_uni_r;
+ qc->rx.stream_max_bidi = qcc->largest_bidi_r;
}
tasklet_free(qcc->wait_event.tasklet);
struct sockaddr_storage *peer_addr,
int server, int token, void *owner)
{
- int i;
struct quic_conn *qc = NULL;
struct listener *l = server ? owner : NULL;
struct proxy *prx = l ? l->bind_conf->frontend : NULL;
qc->bytes.rx = 0;
memset(&qc->rx.params, 0, sizeof(qc->rx.params));
qc->rx.buf = b_make(qc->rx.buf.area, QUIC_CONN_RX_BUFSZ, 0, 0);
- for (i = 0; i < QCS_MAX_TYPES; i++)
- qc->rx.strms[i].nb_streams = 0;
+ qc->rx.stream_max_uni = qc->rx.stream_max_bidi = 0;
qc->nb_pkt_for_cc = 1;
qc->nb_pkt_since_cc = 0;
case QUIC_FT_STREAM_8 ... QUIC_FT_STREAM_F:
{
struct qf_stream *strm_frm = &frm->stream;
- unsigned nb_streams = qc->rx.strms[qcs_id_type(strm_frm->id)].nb_streams;
const char fin = frm->type & QUIC_STREAM_FRAME_TYPE_FIN_BIT;
+ const uint64_t max = quic_stream_is_uni(strm_frm->id) ?
+ qc->rx.stream_max_uni : qc->rx.stream_max_bidi;
/* The upper layer may not be allocated. */
if (qc->mux_state != QC_MUX_READY) {
- if ((strm_frm->id >> QCS_ID_TYPE_SHIFT) < nb_streams) {
+ if (strm_frm->id < max) {
TRACE_DATA("Already closed stream", QUIC_EV_CONN_PRSHPKT, qc);
}
else {
else {
stream->by_id.key = id;
eb64_insert(&qc->streams_by_id, &stream->by_id);
- qc->rx.strms[type].nb_streams++;
}
stream->qc = qc;