pub struct Stream { /* private fields */ }std only.Expand description
Stream - multiplexed data channel within a session
Implementations§
Source§impl Stream
impl Stream
Sourcepub fn reset_rto(&self)
pub fn reset_rto(&self)
Reset the RTT estimator (Phase 4 / QUIC §9.4): a migration path switch lands on a different network, so the old RTT must not carry over. A poisoned lock is recovered by taking the inner value — the RTO is a heuristic.
Sourcepub async fn state(&self) -> StreamState
pub async fn state(&self) -> StreamState
Get current state
Sourcepub fn set_priority(&self, priority: u32)
pub fn set_priority(&self, priority: u32)
Set priority
Sourcepub fn peer_send_window(&self) -> u32
pub fn peer_send_window(&self) -> u32
Bytes the peer currently allows us to send.
Sourcepub fn try_consume_send_window(&self, n: u32) -> bool
pub fn try_consume_send_window(&self, n: u32) -> bool
Atomically reserve n bytes from the peer’s send window.
Returns true if the reservation succeeded (and the window
was decremented); false if the window doesn’t have enough
capacity — caller must wait for a WINDOW_UPDATE.
Sourcepub fn apply_peer_window_update(&self, credit: u32)
pub fn apply_peer_window_update(&self, credit: u32)
Process an inbound WINDOW_UPDATE from the peer. The payload is a
relative credit — the number of bytes the peer’s application just
consumed and is therefore newly willing to receive. We add it to the
send window (saturating at MAX_SEND_WINDOW so a misbehaving peer’s
inflated credit cannot overflow the counter).
Relative credit (vs. an absolute window) is what makes flow control
correct for a session of any length: the sender’s window is
initial + Σ credit_granted − Σ bytes_sent = initial + consumed − sent, so the receiver’s outstanding (unconsumed) bytes sent − consumed
are bounded by initial. An absolute u32 window could not express this
for sessions exceeding 4 GiB and over-committed the receiver’s buffer.
Sourcepub fn local_recv_window(&self) -> u32
pub fn local_recv_window(&self) -> u32
Bytes the local side has granted the peer.
Sourcepub fn record_app_consumed(&self, n: u32) -> Option<u32>
pub fn record_app_consumed(&self, n: u32) -> Option<u32>
Record that the application has actually consumed n bytes from this
stream (called by the receive delivery task on real drainage, not
on routing). Accumulates the consumed bytes and, once the unreported
total crosses half the initial window, returns Some(credit) — the
relative credit to advertise in a WINDOW_UPDATE (the peer adds
it to its send window). The half-window threshold trades update frequency
against peer stalls.
Sourcepub fn stage_window_update_credit(&self, credit: u32)
pub fn stage_window_update_credit(&self, credit: u32)
Stage relative flow-control credit to be flushed by the send loop.
Called by the receive delivery task after it credits real app
consumption. Credits accumulate additively (saturating at
u32::MAX) rather than overwriting, so several grants landing between
two send-loop flushes are summed instead of lost — the send loop is the
single emitter (epoch-safe), and it may run arbitrarily after a grant.
Sourcepub fn take_pending_window_update(&self) -> Option<u32>
pub fn take_pending_window_update(&self) -> Option<u32>
Take all staged credit (swaps the slot back to 0). The send loop calls
this each drain pass and emits one WINDOW_UPDATE carrying the summed
credit if Some.
Sourcepub async fn send_reliable(
&self,
data: Bytes,
) -> Result<SequenceNumber, CoreError>
pub async fn send_reliable( &self, data: Bytes, ) -> Result<SequenceNumber, CoreError>
Queue data for sending with reliability.
Returns the gap-free stream_offset assigned to this chunk (the reassembly
/ SACK key). The wire packet number is assigned later, at send time, by the
data pump (① — Phase 4). Fails closed with CoreError::StreamError once the
u32 offset space is exhausted (T4.5) — the acquired backpressure permit is
released on that path so the semaphore accounting stays correct.
Sourcepub async fn send_unreliable(&self, data: Bytes)
pub async fn send_unreliable(&self, data: Bytes)
Queue data for unreliable sending. Fire-and-forget; the wire packet number is assigned at send time by the data pump (① — Phase 4).
Sourcepub async fn poll_send(&self, cwnd_budget: u64) -> Option<OutboundSegment>
pub async fn poll_send(&self, cwnd_budget: u64) -> Option<OutboundSegment>
Get the next segment to (re)transmit, or None if nothing is due.
cwnd_budget is how many bytes of new data the congestion window
currently permits. Retransmissions ignore it — loss recovery must always
proceed — but a first transmission is withheld (None) when it would
exceed the budget, so the next drain resumes once ACKs free the window.
Pass u64::MAX to disable the limit.
Sourcepub async fn ack(&self, stream_offset: SequenceNumber) -> Option<(Instant, u64)>
pub async fn ack(&self, stream_offset: SequenceNumber) -> Option<(Instant, u64)>
Mark a sequence number as acknowledged. Returns the timestamp when the packet was originally sent and its size, if found.
Sourcepub async fn mark_unsent(&self, stream_offset: SequenceNumber)
pub async fn mark_unsent(&self, stream_offset: SequenceNumber)
Reset a still-buffered reliable segment’s send timestamp so the next
poll_send re-offers it immediately (as an unsent
segment) rather than waiting a full RTO for the retransmit pass. Used
when a send attempt failed after poll_send had already stamped
sent_at — the bytes never reached the wire, so the segment must not be
treated as in-flight. No-op if the segment was already acknowledged and
removed.
Sourcepub async fn received_sack(&self, ack_delay_us: u32) -> Option<Sack>
pub async fn received_sack(&self, ack_delay_us: u32) -> Option<Sack>
Build a Sack describing exactly the reliable-data sequences this stream
currently holds, derived from the reorder state (single source of truth):
the contiguous delivered run [0, recv_sequence-1] as one range, plus one
range per out-of-order island still buffered in recv_buffer. Returns
None if nothing has been received yet.
Because the SACK is derived from what the reorder buffer actually holds, the
receiver never SACKs a sequence it has dropped (the SACK-without-data hazard
of a separate received-set). ack_delay_us: the caller’s measured value, or
— when 0 — a coarse now − last_data_recv_at so the on-wire field is
populated. The range set is capped to crate::transport::sack::MAX_SACK_RANGES
by Sack::from_inclusive_ranges so it always decodes at the peer.
Sourcepub async fn on_sack(&self, sack: &Sack) -> SackResult
pub async fn on_sack(&self, sack: &Sack) -> SackResult
Process a received SACK, retiring every buffered reliable segment whose
gap-free stream_offset the SACK covers (A.5; the SACK ranges are over
stream_offset, not the control-frame-holed wire sequence). Returns a
SackResult listing the newly-retired segments so the caller can feed
congestion control / the RTT estimator per segment.
RTT is sampled here (Karn’s algorithm) only for segments that were never
retransmitted (retries == 0); RetiredSegment::was_retransmit marks the
rest so the caller does not double-count or use an ambiguous sample.
This is a cumulative retire: a SACK re-acks every still-buffered offset it covers, so a lost ACK no longer strands a segment — the next SACK retires it. No loss detection / fast-retransmit here — that is L1-B.
Sourcepub async fn accept_in_order(
&self,
sequence: SequenceNumber,
payloads: Vec<Bytes>,
) -> Vec<Bytes>
pub async fn accept_in_order( &self, sequence: SequenceNumber, payloads: Vec<Bytes>, ) -> Vec<Bytes>
Accept reliable data payloads carried at sequence and return the
contiguous in-order run now deliverable to the application, in ascending
order. The returned Vec is empty when this is a future hole (buffered for
later), a duplicate, or refused for capacity.
payloads is normally one element (a single RELIABLE frame); a COALESCED
bundle passes its sub-payloads so the whole bundle occupies one cursor
position. This is the single source of truth for receive ordering: the
live data pump routes every reliable app payload through here so the app
sees the reliable stream strictly in sequence order even over a
reordering (UDP) path. Out-of-order segments are held in recv_buffer
(bounded by MAX_RECV_REORDER); the data-arrival instant is stamped for
the SACK ack_delay_us.
Sourcepub fn recv_reorder_bytes(&self) -> usize
pub fn recv_reorder_bytes(&self) -> usize
Total payload bytes currently held in the out-of-order reorder buffer (H-3). Bounded
by MAX_RECV_REORDER_BYTES; exposed so the byte bound is observable/testable.
Sourcepub async fn on_receive(&self, sequence: SequenceNumber, data: Bytes)
pub async fn on_receive(&self, sequence: SequenceNumber, data: Bytes)
Pull-API adapter over accept_in_order: buffer a
single reliable payload for in-order reassembly and push the released run
into recv_ready for recv / try_recv.
(Not used by the live session pump, which consumes the returned run
directly; retained for the pull-style read API.)
Sourcepub async fn recv(&self) -> Option<Bytes>
pub async fn recv(&self) -> Option<Bytes>
Read data from the stream (async, waits if no data available)
Sourcepub async fn on_remote_finish(&self)
pub async fn on_remote_finish(&self)
Mark remote side as finished
Sourcepub async fn pending_send_count(&self) -> usize
pub async fn pending_send_count(&self) -> usize
Get number of pending send chunks
Sourcepub async fn pending_recv_count(&self) -> usize
pub async fn pending_recv_count(&self) -> usize
Get number of pending receive chunks