struct {
uint64_t ms_bidi_init; /* max initial sub-ID of bidi stream allowed for the peer */
uint64_t ms_bidi; /* max sub-ID of bidi stream allowed for the peer */
+ uint64_t msd_bidi_l; /* initial max-stream-data on local streams */
+ uint64_t msd_bidi_r; /* initial max-stream-data on remote streams */
uint64_t cl_bidi_r; /* total count of closed remote bidi stream since last MAX_STREAMS emission */
} lfctl;
uint64_t offset; /* the current offset of received data */
struct buffer buf; /* receive buffer, always valid (buf_empty or real buffer) */
struct buffer app_buf; /* receive buffer used by conn_stream layer */
+ uint64_t msd; /* fctl bytes limit to enforce */
} rx;
struct {
uint64_t offset; /* last offset of data ready to be sent */
qcs->rx.offset = 0;
qcs->rx.frms = EB_ROOT_UNIQUE;
+ /* TODO use uni limit for unidirectional streams */
+ qcs->rx.msd = quic_stream_is_local(qcc, id) ? qcc->lfctl.msd_bidi_l :
+ qcc->lfctl.msd_bidi_r;
+
qcs->tx.buf = BUF_NULL;
qcs->tx.offset = 0;
qcs->tx.sent_offset = 0;
/* Last frame already handled for this stream. */
BUG_ON(qcs->flags & QC_SF_FIN_RECV);
+ /* TODO initial max-stream-data overflow. Implement FLOW_CONTROL_ERROR emission. */
+ BUG_ON(offset + len > qcs->rx.msd);
if (!qc_get_buf(qcs, &qcs->rx.buf)) {
/* TODO should mark qcs as full */
qcs->rx.offset += total;
+ /* TODO initial max-stream-data reached. Implement MAX_STREAM_DATA emission. */
+ BUG_ON(qcs->rx.offset == qcs->rx.msd);
+
if (fin)
qcs->flags |= QC_SF_FIN_RECV;
- out:
TRACE_LEAVE(QMUX_EV_QCC_RECV, qcc->conn);
return 0;
}
qcc->strms[QCS_SRV_UNI].tx.max_data = 0;
qcc->lfctl.ms_bidi = qcc->lfctl.ms_bidi_init = lparams->initial_max_streams_bidi;
+ qcc->lfctl.msd_bidi_l = lparams->initial_max_stream_data_bidi_local;
+ qcc->lfctl.msd_bidi_r = lparams->initial_max_stream_data_bidi_remote;
qcc->lfctl.cl_bidi_r = 0;
rparams = &conn->handle.qc->tx.params;