1use crate::coding::varint_len;
5use crate::error::*;
6use crate::frame::{self, MAX_STREAMS_LIMIT};
7use crate::ranges::RangeSet;
8use std::collections::{BTreeMap, HashMap, VecDeque};
9use std::hash::{BuildHasherDefault, Hasher};
10
11#[derive(Default)]
14pub struct IdHasher(u64);
15
16impl Hasher for IdHasher {
17 fn finish(&self) -> u64 {
18 self.0
19 }
20 fn write(&mut self, bytes: &[u8]) {
21 for &b in bytes {
22 self.0 = (self.0.rotate_left(5) ^ b as u64).wrapping_mul(0x51_7cc1_b727_220a_95);
23 }
24 }
25 fn write_u64(&mut self, n: u64) {
26 self.0 = (n ^ (n >> 32)).wrapping_mul(0x9e37_79b9_7f4a_7c15);
27 }
28}
29
30pub type IdMap<V> = HashMap<u64, V, BuildHasherDefault<IdHasher>>;
31
32#[inline]
33pub fn is_bidi(id: u64) -> bool {
34 id & 2 == 0
35}
36#[inline]
37pub fn is_server_initiated(id: u64) -> bool {
38 id & 1 == 1
39}
40
41#[derive(Clone, Debug)]
43pub struct StreamConfig {
44 pub max_streams_bidi: u64,
45 pub max_streams_uni: u64,
46 pub stream_window_bidi_local: u64,
47 pub stream_window_bidi_remote: u64,
48 pub stream_window_uni: u64,
49 pub conn_window: u64,
50 pub send_buffer: u64,
52}
53
54#[derive(Clone, Copy, Debug, PartialEq, Eq)]
56pub enum Control {
57 MaxData,
58 MaxStreamData(u64),
59 MaxStreams(bool),
60 DataBlocked,
61 StreamDataBlocked(u64),
62 StreamsBlocked(bool),
63 ResetStream(u64),
64 StopSending(u64),
65}
66
67#[derive(Default)]
68pub struct SendStream {
69 buf: VecDeque<u8>,
70 base: u64,
72 sent: u64,
74 retransmit: RangeSet,
75 acked: RangeSet,
76 max_data: u64,
78 fin: bool,
79 fin_sent: bool,
80 fin_acked: bool,
81 reset: Option<(u64, u64)>,
82 reset_acked: bool,
83 stopped: Option<u64>,
84 blocked_at: Option<u64>,
85 want_writable: bool,
86 queued: bool,
87}
88
89impl SendStream {
90 fn end(&self) -> u64 {
91 self.base + self.buf.len() as u64
92 }
93 fn has_pending(&self) -> bool {
94 self.reset.is_none()
95 && (!self.retransmit.is_empty() || self.sent < self.end() || (self.fin && !self.fin_sent))
96 }
97 fn is_done(&self) -> bool {
98 if self.reset.is_some() {
99 return self.reset_acked;
100 }
101 self.fin_acked && self.buf.is_empty()
102 }
103}
104
105#[derive(Default)]
106pub struct RecvStream {
107 data: VecDeque<u8>,
108 read: u64,
110 ooo: BTreeMap<u64, Vec<u8>>,
111 max_data: u64,
112 window: u64,
113 highest: u64,
114 final_size: Option<u64>,
115 reset: Option<u64>,
116 reset_delivered: bool,
117 stop: Option<u64>,
118 fin_delivered: bool,
119 notified: bool,
120}
121
122impl RecvStream {
123 fn contiguous_end(&self) -> u64 {
124 self.read + self.data.len() as u64
125 }
126 fn is_done(&self) -> bool {
127 self.fin_delivered || self.reset_delivered || (self.stop.is_some() && self.final_size.is_some())
128 }
129 fn insert(&mut self, mut off: u64, mut d: &[u8]) {
131 let cend = self.contiguous_end();
132 if off < cend {
133 let skip = (cend - off).min(d.len() as u64) as usize;
134 d = &d[skip..];
135 off += skip as u64;
136 }
137 if d.is_empty() {
138 return;
139 }
140 if off == cend {
141 self.data.extend(d);
142 while let Some((&o, _)) = self.ooo.first_key_value() {
144 let end = self.contiguous_end();
145 if o > end {
146 break;
147 }
148 let chunk = self.ooo.pop_first().unwrap().1;
149 let skip = (end - o) as usize;
150 if skip < chunk.len() {
151 self.data.extend(&chunk[skip..]);
152 }
153 }
154 return;
155 }
156 let end = off + d.len() as u64;
158 let mut cur = off;
159 let mut pieces: Vec<(u64, u64)> = Vec::new();
160 let start_key = self.ooo.range(..off).next_back().map(|(&k, v)| (k, k + v.len() as u64));
161 if let Some((_, e)) = start_key {
162 if e > cur {
163 cur = e;
164 }
165 }
166 for (&k, v) in self.ooo.range(off..end) {
167 if k > cur {
168 pieces.push((cur, k));
169 }
170 cur = cur.max(k + v.len() as u64);
171 }
172 if cur < end {
173 pieces.push((cur, end));
174 }
175 for (s, e) in pieces {
176 let piece = &d[(s - off) as usize..(e - off) as usize];
177 let mut key = s;
180 let mut buf = match self.ooo.range(..s).next_back() {
181 Some((&k, v)) if k + v.len() as u64 == s => {
182 key = k;
183 let mut v = self.ooo.remove(&k).unwrap();
184 v.extend_from_slice(piece);
185 v
186 }
187 _ => piece.to_vec(),
188 };
189 if let Some(next) = self.ooo.remove(&e) {
190 buf.extend_from_slice(&next);
191 }
192 self.ooo.insert(key, buf);
193 }
194 }
195
196 fn gaps(&self) -> usize {
198 self.ooo.len()
199 }
200}
201
202pub const MAX_RECV_GAPS: usize = 1024;
208
209pub struct Stream {
210 pub send: Option<SendStream>,
211 pub recv: Option<RecvStream>,
212}
213
214#[derive(Debug, Clone, Copy, PartialEq, Eq)]
215pub enum StreamEvent {
216 Opened(u64),
217 Readable(u64),
218 Writable(u64),
219 Stopped(u64, u64),
220 Reset(u64, u64),
221 Available(bool),
222}
223
224pub struct Streams {
225 is_server: bool,
226 cfg: StreamConfig,
227 map: IdMap<Stream>,
228 next: [u64; 2],
230 peer_max: [u64; 2],
231 blocked_sent: [Option<u64>; 2],
232 remote_opened: [u64; 2],
234 local_max: [u64; 2],
235 remote_closed: [u64; 2],
236 peer_bidi_local: u64,
238 peer_bidi_remote: u64,
239 peer_uni: u64,
240 pub send_max_data: u64,
242 written: u64,
243 data_blocked_at: Option<u64>,
244 recv_max_data: u64,
246 recv_highest: u64,
247 recv_consumed: u64,
248 recv_gaps: usize,
250 send_queue: VecDeque<u64>,
251 pub control: VecDeque<Control>,
252 pub events: VecDeque<StreamEvent>,
253}
254
255#[inline]
257fn dir(id: u64) -> usize {
258 ((id >> 1) & 1) as usize
259}
260
261impl Streams {
262 pub fn new(is_server: bool, cfg: StreamConfig) -> Self {
263 Streams {
264 is_server,
265 map: IdMap::default(),
266 next: [0; 2],
267 peer_max: [0; 2],
268 blocked_sent: [None; 2],
269 remote_opened: [0; 2],
270 local_max: [cfg.max_streams_bidi, cfg.max_streams_uni],
271 remote_closed: [0; 2],
272 peer_bidi_local: 0,
273 peer_bidi_remote: 0,
274 peer_uni: 0,
275 send_max_data: 0,
276 written: 0,
277 data_blocked_at: None,
278 recv_max_data: cfg.conn_window,
279 recv_highest: 0,
280 recv_consumed: 0,
281 recv_gaps: 0,
282 send_queue: VecDeque::new(),
283 control: VecDeque::new(),
284 events: VecDeque::new(),
285 cfg,
286 }
287 }
288
289 pub fn set_peer_params(&mut self, p: &crate::params::TransportParams) {
291 self.peer_max = [p.initial_max_streams_bidi, p.initial_max_streams_uni];
292 self.peer_bidi_local = p.initial_max_stream_data_bidi_local;
293 self.peer_bidi_remote = p.initial_max_stream_data_bidi_remote;
294 self.peer_uni = p.initial_max_stream_data_uni;
295 self.send_max_data = p.initial_max_data;
296 }
297
298 fn local(&self, id: u64) -> bool {
299 is_server_initiated(id) == self.is_server
300 }
301
302 pub fn len(&self) -> usize {
303 self.map.len()
304 }
305 pub fn is_empty(&self) -> bool {
306 self.map.is_empty()
307 }
308
309 fn new_stream(&self, id: u64) -> Stream {
310 let local = self.local(id);
311 let bidi = is_bidi(id);
312 let send = if bidi || local {
313 let max = if !bidi {
315 self.peer_uni
316 } else if local {
317 self.peer_bidi_remote
318 } else {
319 self.peer_bidi_local
320 };
321 Some(SendStream { max_data: max, ..Default::default() })
322 } else {
323 None
324 };
325 let recv = if bidi || !local {
326 let w = if !bidi {
327 self.cfg.stream_window_uni
328 } else if local {
329 self.cfg.stream_window_bidi_local
330 } else {
331 self.cfg.stream_window_bidi_remote
332 };
333 Some(RecvStream { max_data: w, window: w, ..Default::default() })
334 } else {
335 None
336 };
337 Stream { send, recv }
338 }
339
340 pub fn open(&mut self, bidi: bool) -> Result<u64, StreamError> {
342 let d = (!bidi) as usize;
343 if self.next[d] >= self.peer_max[d] {
344 if self.blocked_sent[d] != Some(self.peer_max[d]) {
345 self.blocked_sent[d] = Some(self.peer_max[d]);
346 self.control.push_back(Control::StreamsBlocked(bidi));
347 }
348 return Err(StreamError::LimitReached);
349 }
350 let id = self.next[d] << 2 | (d as u64) << 1 | self.is_server as u64;
351 self.next[d] += 1;
352 let s = self.new_stream(id);
353 self.map.insert(id, s);
354 Ok(id)
355 }
356
357 fn get_or_open(&mut self, id: u64, ty: u64) -> Result<Option<&mut Stream>, TransportError> {
361 let d = dir(id);
362 let idx = id >> 2;
363 if self.local(id) {
364 if idx >= self.next[d] {
365 return Err(TransportError::frame(STREAM_STATE_ERROR, ty, "frame for a stream not yet opened"));
366 }
367 } else if idx >= self.remote_opened[d] {
368 if idx >= self.local_max[d] {
369 return Err(TransportError::frame(STREAM_LIMIT_ERROR, ty, "stream limit exceeded"));
370 }
371 for i in self.remote_opened[d]..=idx {
372 let sid = i << 2 | (d as u64) << 1 | (!self.is_server) as u64;
373 let s = self.new_stream(sid);
374 self.map.insert(sid, s);
375 self.events.push_back(StreamEvent::Opened(sid));
376 }
377 self.remote_opened[d] = idx + 1;
378 }
379 Ok(self.map.get_mut(&id))
380 }
381
382 pub fn on_stream(&mut self, id: u64, off: u64, data: &[u8], fin: bool) -> Result<(), TransportError> {
385 let ty = frame::STREAM;
386 if self.local(id) && !is_bidi(id) {
387 return Err(TransportError::frame(STREAM_STATE_ERROR, ty, "STREAM on a send-only stream"));
388 }
389 let conn_max = self.recv_max_data;
390 let mut conn_highest = self.recv_highest;
391 let mut gaps_total = self.recv_gaps;
392 let Some(s) = self.get_or_open(id, ty)? else { return Ok(()) };
393 let r = s.recv.as_mut().unwrap();
394 let end = off + data.len() as u64;
395 if end > r.max_data {
396 return Err(TransportError::frame(FLOW_CONTROL_ERROR, ty, "stream flow control exceeded"));
397 }
398 if let Some(fs) = r.final_size {
399 if end > fs || (fin && end != fs) {
400 return Err(TransportError::frame(FINAL_SIZE_ERROR, ty, "final size changed"));
401 }
402 }
403 if fin {
404 if end < r.highest {
405 return Err(TransportError::frame(FINAL_SIZE_ERROR, ty, "final size below received data"));
406 }
407 r.final_size = Some(end);
408 }
409 if end > r.highest {
410 conn_highest += end - r.highest;
411 if conn_highest > conn_max {
412 return Err(TransportError::frame(FLOW_CONTROL_ERROR, ty, "connection flow control exceeded"));
413 }
414 r.highest = end;
415 }
416 if r.reset.is_some() || r.stop.is_some() {
417 self.recv_highest = conn_highest;
418 return Ok(());
419 }
420 let before = r.contiguous_end();
421 let gaps_before = r.gaps();
422 r.insert(off, data);
423 gaps_total = gaps_total + r.gaps() - gaps_before;
424 if gaps_total > MAX_RECV_GAPS {
425 return Err(TransportError::frame(PROTOCOL_VIOLATION, ty, "too many out-of-order stream fragments"));
426 }
427 let readable = r.contiguous_end() > before || (r.final_size == Some(r.contiguous_end()) && !r.fin_delivered);
428 if readable && !r.notified {
429 r.notified = true;
430 self.events.push_back(StreamEvent::Readable(id));
431 }
432 self.recv_highest = conn_highest;
433 self.recv_gaps = gaps_total;
434 Ok(())
435 }
436
437 pub fn on_reset(&mut self, id: u64, code: u64, final_size: u64) -> Result<(), TransportError> {
438 let ty = frame::RESET_STREAM;
439 if self.local(id) && !is_bidi(id) {
440 return Err(TransportError::frame(STREAM_STATE_ERROR, ty, "RESET_STREAM on a send-only stream"));
441 }
442 let conn_max = self.recv_max_data;
443 let mut conn_highest = self.recv_highest;
444 let mut gaps_total = self.recv_gaps;
445 let Some(s) = self.get_or_open(id, ty)? else { return Ok(()) };
446 let r = s.recv.as_mut().unwrap();
447 if let Some(fs) = r.final_size {
448 if fs != final_size {
449 return Err(TransportError::frame(FINAL_SIZE_ERROR, ty, "final size changed"));
450 }
451 }
452 if final_size < r.highest {
453 return Err(TransportError::frame(FINAL_SIZE_ERROR, ty, "final size below received data"));
454 }
455 if final_size > r.max_data {
456 return Err(TransportError::frame(FLOW_CONTROL_ERROR, ty, "final size exceeds flow control"));
457 }
458 conn_highest += final_size - r.highest;
459 if conn_highest > conn_max {
460 return Err(TransportError::frame(FLOW_CONTROL_ERROR, ty, "connection flow control exceeded"));
461 }
462 r.highest = final_size;
463 r.final_size = Some(final_size);
464 let mut released = None;
465 if r.reset.is_none() && !r.fin_delivered {
466 r.reset = Some(code);
467 released = Some(final_size - r.read);
469 r.data.clear();
470 gaps_total -= r.gaps();
471 r.ooo.clear();
472 }
473 self.recv_highest = conn_highest;
474 self.recv_gaps = gaps_total;
475 if let Some(rel) = released {
476 self.recv_consumed += rel;
477 self.events.push_back(StreamEvent::Reset(id, code));
478 self.maybe_max_data();
479 }
480 self.maybe_remove(id);
481 Ok(())
482 }
483
484 pub fn on_stop_sending(&mut self, id: u64, code: u64) -> Result<(), TransportError> {
485 let ty = frame::STOP_SENDING;
486 if !self.local(id) && !is_bidi(id) {
487 return Err(TransportError::frame(STREAM_STATE_ERROR, ty, "STOP_SENDING on a receive-only stream"));
488 }
489 let Some(s) = self.get_or_open(id, ty)? else { return Ok(()) };
490 let snd = s.send.as_mut().unwrap();
491 if snd.stopped.is_some() {
492 return Ok(());
493 }
494 snd.stopped = Some(code);
495 let reset = snd.reset.is_none() && !(snd.fin && snd.fin_acked);
497 if reset {
498 snd.reset = Some((code, snd.end()));
499 snd.retransmit.clear();
500 }
501 self.events.push_back(StreamEvent::Stopped(id, code));
502 if reset {
503 self.control.push_back(Control::ResetStream(id));
504 }
505 Ok(())
506 }
507
508 pub fn on_max_stream_data(&mut self, id: u64, max: u64) -> Result<(), TransportError> {
509 let ty = frame::MAX_STREAM_DATA;
510 if !self.local(id) && !is_bidi(id) {
511 return Err(TransportError::frame(STREAM_STATE_ERROR, ty, "MAX_STREAM_DATA on a receive-only stream"));
512 }
513 let Some(s) = self.get_or_open(id, ty)? else { return Ok(()) };
514 let snd = s.send.as_mut().unwrap();
515 if max > snd.max_data {
516 snd.max_data = max;
517 if snd.want_writable {
518 snd.want_writable = false;
519 self.events.push_back(StreamEvent::Writable(id));
520 }
521 }
522 Ok(())
523 }
524
525 pub fn on_stream_data_blocked(&mut self, id: u64) -> Result<(), TransportError> {
526 let ty = frame::STREAM_DATA_BLOCKED;
527 if self.local(id) && !is_bidi(id) {
528 return Err(TransportError::frame(STREAM_STATE_ERROR, ty, "STREAM_DATA_BLOCKED on a send-only stream"));
529 }
530 self.get_or_open(id, ty)?;
531 Ok(())
532 }
533
534 pub fn on_max_data(&mut self, max: u64) {
535 if max > self.send_max_data {
536 self.send_max_data = max;
537 for (&id, s) in self.map.iter_mut() {
539 if let Some(snd) = s.send.as_mut() {
540 if snd.want_writable {
541 snd.want_writable = false;
542 self.events.push_back(StreamEvent::Writable(id));
543 }
544 }
545 }
546 }
547 }
548
549 pub fn on_max_streams(&mut self, bidi: bool, max: u64) {
550 let d = (!bidi) as usize;
551 if max > self.peer_max[d] {
552 let was_blocked = self.next[d] >= self.peer_max[d];
553 self.peer_max[d] = max;
554 if was_blocked {
555 self.events.push_back(StreamEvent::Available(bidi));
556 }
557 }
558 }
559
560 pub fn on_streams_blocked(&mut self, bidi: bool, limit: u64) {
561 let _ = (bidi, limit);
563 }
564
565 pub fn write(&mut self, id: u64, data: &[u8], fin: bool) -> Result<usize, StreamError> {
569 let conn_room = self.send_max_data - self.written;
570 let cap = self.cfg.send_buffer;
571 let s = self.map.get_mut(&id).ok_or(StreamError::UnknownStream)?;
572 let snd = s.send.as_mut().ok_or(StreamError::InvalidDirection)?;
573 if let Some(code) = snd.stopped {
574 return Err(StreamError::Stopped(code));
575 }
576 if snd.reset.is_some() || snd.fin {
577 return Err(StreamError::Finished);
578 }
579 let end = snd.end();
580 let stream_room = snd.max_data.saturating_sub(end);
581 let buf_room = cap.saturating_sub(snd.buf.len() as u64);
582 let n = (data.len() as u64).min(stream_room).min(conn_room).min(buf_room) as usize;
583 if n == 0 && !data.is_empty() {
584 snd.want_writable = true;
585 if stream_room == 0 && snd.blocked_at != Some(snd.max_data) {
586 snd.blocked_at = Some(snd.max_data);
587 self.control.push_back(Control::StreamDataBlocked(id));
588 }
589 if conn_room == 0 && self.data_blocked_at != Some(self.send_max_data) {
590 self.data_blocked_at = Some(self.send_max_data);
591 self.control.push_back(Control::DataBlocked);
592 }
593 return Err(StreamError::Blocked);
594 }
595 snd.buf.extend(&data[..n]);
596 self.written += n as u64;
597 if n < data.len() {
598 snd.want_writable = true;
599 } else if fin {
600 snd.fin = true;
601 }
602 if !snd.queued && snd.has_pending() {
603 snd.queued = true;
604 self.send_queue.push_back(id);
605 }
606 Ok(n)
607 }
608
609 pub fn read(&mut self, id: u64, out: &mut [u8]) -> Result<(usize, bool), StreamError> {
611 let s = self.map.get_mut(&id).ok_or(StreamError::UnknownStream)?;
612 let r = s.recv.as_mut().ok_or(StreamError::InvalidDirection)?;
613 if let Some(code) = r.reset {
614 r.reset_delivered = true;
615 self.maybe_remove(id);
616 return Err(StreamError::Reset(code));
617 }
618 let n = out.len().min(r.data.len());
619 let (a, b) = r.data.as_slices();
620 if n <= a.len() {
621 out[..n].copy_from_slice(&a[..n]);
622 } else {
623 out[..a.len()].copy_from_slice(a);
624 out[a.len()..n].copy_from_slice(&b[..n - a.len()]);
625 }
626 r.data.drain(..n);
627 r.read += n as u64;
628 let fin = r.data.is_empty() && r.final_size == Some(r.read);
629 if n == 0 && !fin {
630 r.notified = false;
631 return Err(StreamError::WouldBlock);
632 }
633 if r.data.is_empty() {
634 r.notified = false;
635 }
636 if r.final_size.is_none() && r.max_data - r.read < r.window / 2 {
638 r.max_data = r.read + r.window;
639 self.control.push_back(Control::MaxStreamData(id));
640 }
641 if fin {
642 r.fin_delivered = true;
643 }
644 self.recv_consumed += n as u64;
645 self.maybe_max_data();
646 if fin {
647 self.maybe_remove(id);
648 }
649 Ok((n, fin))
650 }
651
652 fn maybe_max_data(&mut self) {
653 if self.recv_max_data - self.recv_consumed < self.cfg.conn_window / 2 {
654 self.recv_max_data = self.recv_consumed + self.cfg.conn_window;
655 self.control.push_back(Control::MaxData);
656 }
657 }
658
659 pub fn reset(&mut self, id: u64, code: u64) -> Result<(), StreamError> {
661 let s = self.map.get_mut(&id).ok_or(StreamError::UnknownStream)?;
662 let snd = s.send.as_mut().ok_or(StreamError::InvalidDirection)?;
663 if snd.reset.is_some() || (snd.fin && snd.fin_acked) {
664 return Ok(());
665 }
666 snd.reset = Some((code, snd.end()));
667 snd.retransmit.clear();
668 self.control.push_back(Control::ResetStream(id));
669 Ok(())
670 }
671
672 pub fn stop(&mut self, id: u64, code: u64) -> Result<(), StreamError> {
674 let s = self.map.get_mut(&id).ok_or(StreamError::UnknownStream)?;
675 let r = s.recv.as_mut().ok_or(StreamError::InvalidDirection)?;
676 if r.stop.is_some() || r.reset.is_some() || r.fin_delivered {
677 return Ok(());
678 }
679 r.stop = Some(code);
680 let unread = r.data.len() as u64;
681 r.data.clear();
682 self.recv_gaps -= r.gaps();
683 r.ooo.clear();
684 r.read = r.highest;
685 self.recv_consumed += unread;
686 if r.final_size.is_none() {
687 self.control.push_back(Control::StopSending(id));
688 }
689 self.maybe_max_data();
690 self.maybe_remove(id);
691 Ok(())
692 }
693
694 pub fn has_pending_data(&self) -> bool {
697 !self.send_queue.is_empty()
698 }
699
700 pub fn write_frames(&mut self, out: &mut Vec<u8>, limit: usize, sent: &mut Vec<crate::recovery::SentFrame>) {
703 let mut rounds = self.send_queue.len();
704 while rounds > 0 && out.len() + 8 < limit {
705 rounds -= 1;
706 let Some(id) = self.send_queue.pop_front() else { break };
707 let Some(snd) = self.map.get_mut(&id).and_then(|s| s.send.as_mut()) else { continue };
708 snd.queued = false;
709 if !snd.has_pending() {
710 continue;
711 }
712 let room = limit - out.len();
713 let (off, avail, is_retx) = if let Some((s, e)) = snd.retransmit.first() {
714 (s, e - s, true)
715 } else {
716 (snd.sent, snd.end() - snd.sent, false)
717 };
718 let hdr = frame::stream_overhead(id, off, room);
719 if room <= hdr {
720 snd.queued = true;
721 self.send_queue.push_front(id);
722 break;
723 }
724 let len = avail.min((room - hdr) as u64) as usize;
725 let end = off + len as u64;
726 let fin = snd.fin && end == snd.end() && (!is_retx || snd.sent == snd.end());
727 if len == 0 && !fin {
728 continue;
729 }
730 frame::put_stream_header(out, id, off, len, fin);
731 let start = (off - snd.base) as usize;
732 copy_range(&snd.buf, start, len, out);
733 if is_retx {
734 snd.retransmit.remove(off, end);
735 } else {
736 snd.sent = end;
737 }
738 if fin {
739 snd.fin_sent = true;
740 }
741 sent.push(crate::recovery::SentFrame::Stream { id, off, len: len as u32, fin });
742 if snd.has_pending() {
743 snd.queued = true;
744 self.send_queue.push_back(id);
745 }
746 }
747 }
748
749 pub fn write_control(&mut self, c: Control, out: &mut Vec<u8>, limit: usize) -> Option<bool> {
751 let mut tmp = [0u64; 3];
752 let (ty, n) = match c {
753 Control::MaxData => {
754 tmp[0] = self.recv_max_data;
755 (frame::MAX_DATA, 1)
756 }
757 Control::MaxStreamData(id) => {
758 let r = self.map.get(&id).and_then(|s| s.recv.as_ref())?;
759 if r.final_size.is_some() || r.stop.is_some() {
760 return None;
761 }
762 tmp[0] = id;
763 tmp[1] = r.max_data;
764 (frame::MAX_STREAM_DATA, 2)
765 }
766 Control::MaxStreams(bidi) => {
767 tmp[0] = self.local_max[(!bidi) as usize];
768 (if bidi { frame::MAX_STREAMS_BIDI } else { frame::MAX_STREAMS_UNI }, 1)
769 }
770 Control::DataBlocked => {
771 if self.written < self.send_max_data {
772 return None;
773 }
774 tmp[0] = self.send_max_data;
775 (frame::DATA_BLOCKED, 1)
776 }
777 Control::StreamDataBlocked(id) => {
778 let snd = self.map.get(&id).and_then(|s| s.send.as_ref())?;
779 if snd.end() < snd.max_data || snd.reset.is_some() {
780 return None;
781 }
782 tmp[0] = id;
783 tmp[1] = snd.max_data;
784 (frame::STREAM_DATA_BLOCKED, 2)
785 }
786 Control::StreamsBlocked(bidi) => {
787 let d = (!bidi) as usize;
788 if self.next[d] < self.peer_max[d] {
789 return None;
790 }
791 tmp[0] = self.peer_max[d];
792 (if bidi { frame::STREAMS_BLOCKED_BIDI } else { frame::STREAMS_BLOCKED_UNI }, 1)
793 }
794 Control::ResetStream(id) => {
795 let snd = self.map.get(&id).and_then(|s| s.send.as_ref())?;
796 let (code, fs) = snd.reset?;
797 if snd.reset_acked {
798 return None;
799 }
800 tmp = [id, code, fs];
801 (frame::RESET_STREAM, 3)
802 }
803 Control::StopSending(id) => {
804 let r = self.map.get(&id).and_then(|s| s.recv.as_ref())?;
805 let code = r.stop?;
806 if r.final_size.is_some() {
807 return None;
808 }
809 tmp[0] = id;
810 tmp[1] = code;
811 (frame::STOP_SENDING, 2)
812 }
813 };
814 let size = 1 + tmp[..n].iter().map(|&v| varint_len(v)).sum::<usize>();
815 if out.len() + size > limit {
816 return Some(false);
817 }
818 frame::put_simple(out, ty, &tmp[..n]);
819 Some(true)
820 }
821
822 pub fn on_stream_acked(&mut self, id: u64, off: u64, len: u64, fin: bool) {
825 let Some(snd) = self.map.get_mut(&id).and_then(|s| s.send.as_mut()) else { return };
826 let lo = off.max(snd.base);
831 if off + len > lo {
832 snd.acked.insert(lo, off + len);
833 if let Some((s, e)) = snd.acked.first() {
835 if s <= snd.base && e > snd.base {
836 let n = (e - snd.base) as usize;
837 snd.buf.drain(..n.min(snd.buf.len()));
838 snd.base = e;
839 snd.acked.remove_below(e);
840 snd.retransmit.remove_below(e);
841 if snd.want_writable {
842 snd.want_writable = false;
843 self.events.push_back(StreamEvent::Writable(id));
844 }
845 }
846 }
847 }
848 if fin {
849 snd.fin_acked = true;
850 }
851 self.maybe_remove(id);
852 }
853
854 pub fn on_stream_lost(&mut self, id: u64, off: u64, len: u64, fin: bool) {
855 let Some(snd) = self.map.get_mut(&id).and_then(|s| s.send.as_mut()) else { return };
856 if snd.reset.is_some() {
857 return;
858 }
859 let end = off + len;
860 let lo = off.max(snd.base);
861 if end > lo {
862 snd.retransmit.insert(lo, end);
863 for (s, e) in snd.acked.clone().iter() {
865 snd.retransmit.remove(s, e);
866 }
867 }
868 if fin && !snd.fin_acked {
869 snd.fin_sent = false;
870 }
871 if !snd.queued && snd.has_pending() {
872 snd.queued = true;
873 self.send_queue.push_back(id);
874 }
875 }
876
877 pub fn on_reset_acked(&mut self, id: u64) {
878 if let Some(snd) = self.map.get_mut(&id).and_then(|s| s.send.as_mut()) {
879 snd.reset_acked = true;
880 }
881 self.maybe_remove(id);
882 }
883
884 fn maybe_remove(&mut self, id: u64) {
886 let Some(s) = self.map.get(&id) else { return };
887 let send_done = s.send.as_ref().is_none_or(|x| x.is_done());
888 let recv_done = s.recv.as_ref().is_none_or(|x| x.is_done());
889 if !(send_done && recv_done) {
890 return;
891 }
892 let s = self.map.remove(&id).unwrap();
893 if let Some(snd) = &s.send {
894 let _ = snd;
897 }
898 if !self.local(id) {
899 let d = dir(id);
900 self.remote_closed[d] += 1;
901 let max = if d == 0 { self.cfg.max_streams_bidi } else { self.cfg.max_streams_uni };
902 let new = (self.remote_closed[d] + max).min(MAX_STREAMS_LIMIT);
903 if new - self.local_max[d] >= (max / 2).max(1) {
904 self.local_max[d] = new;
905 self.control.push_back(Control::MaxStreams(d == 0));
906 }
907 }
908 }
909
910 pub fn contains(&self, id: u64) -> bool {
912 self.map.contains_key(&id)
913 }
914
915 pub fn unacked(&self, id: u64) -> Option<u64> {
917 self.map.get(&id)?.send.as_ref().map(|s| s.buf.len() as u64)
918 }
919
920 pub fn writable(&self, id: u64) -> Option<u64> {
922 let snd = self.map.get(&id)?.send.as_ref()?;
923 if snd.fin || snd.reset.is_some() {
924 return Some(0);
925 }
926 Some(
927 snd.max_data
928 .saturating_sub(snd.end())
929 .min(self.send_max_data - self.written)
930 .min(self.cfg.send_buffer.saturating_sub(snd.buf.len() as u64)),
931 )
932 }
933}
934
935fn copy_range(buf: &VecDeque<u8>, start: usize, len: usize, out: &mut Vec<u8>) {
937 let (a, b) = buf.as_slices();
938 if start < a.len() {
939 let n = (a.len() - start).min(len);
940 out.extend_from_slice(&a[start..start + n]);
941 out.extend_from_slice(&b[..len - n]);
942 } else {
943 let s = start - a.len();
944 out.extend_from_slice(&b[s..s + len]);
945 }
946}
947
948#[cfg(test)]
949mod tests {
950 use super::*;
951 use crate::params::TransportParams;
952
953 fn server() -> Streams {
954 let mut s = Streams::new(
955 true,
956 StreamConfig {
957 max_streams_bidi: 2,
958 max_streams_uni: 1,
959 stream_window_bidi_local: 100,
960 stream_window_bidi_remote: 100,
961 stream_window_uni: 100,
962 conn_window: 150,
963 send_buffer: 1000,
964 },
965 );
966 let p = TransportParams {
967 initial_max_data: 50,
968 initial_max_stream_data_bidi_local: 30,
969 initial_max_stream_data_bidi_remote: 30,
970 initial_max_stream_data_uni: 30,
971 initial_max_streams_bidi: 1,
972 initial_max_streams_uni: 1,
973 ..Default::default()
974 };
975 s.set_peer_params(&p);
976 s
977 }
978
979 #[test]
980 fn receive_side_enforcement() {
981 let mut s = server();
982 s.on_stream(0, 0, b"abc", false).unwrap();
984 assert_eq!(s.on_stream(8, 0, b"x", false).unwrap_err().code, STREAM_LIMIT_ERROR);
985 s.on_stream(4, 0, b"", false).unwrap();
987 assert_eq!(s.on_stream(0, 98, b"xyz", false).unwrap_err().code, FLOW_CONTROL_ERROR);
989 s.on_stream(0, 0, &[0; 100], false).unwrap();
991 assert_eq!(s.on_stream(4, 0, &[0; 51], false).unwrap_err().code, FLOW_CONTROL_ERROR);
992 let mut s = server();
994 s.on_stream(0, 0, b"hello", true).unwrap();
995 assert_eq!(s.on_stream(0, 0, b"hello!", false).unwrap_err().code, FINAL_SIZE_ERROR);
996 assert_eq!(s.on_stream(0, 0, b"hel", true).unwrap_err().code, FINAL_SIZE_ERROR);
997 assert_eq!(s.on_reset(0, 1, 4).unwrap_err().code, FINAL_SIZE_ERROR);
998 let mut s = server();
999 s.on_stream(0, 0, b"hello", false).unwrap();
1000 assert_eq!(s.on_stream(0, 0, b"he", true).unwrap_err().code, FINAL_SIZE_ERROR);
1001 let mut s = server();
1003 assert_eq!(s.on_stream(1, 0, b"x", false).unwrap_err().code, STREAM_STATE_ERROR);
1004 let uni = s.open(false).unwrap();
1005 assert_eq!(uni, 3);
1006 assert_eq!(s.on_stream(3, 0, b"x", false).unwrap_err().code, STREAM_STATE_ERROR);
1007 assert_eq!(s.on_stop_sending(2, 0).unwrap_err().code, STREAM_STATE_ERROR); assert_eq!(s.on_max_stream_data(2, 5).unwrap_err().code, STREAM_STATE_ERROR);
1009 }
1010
1011 #[test]
1012 fn reassembly_out_of_order_and_overlapping() {
1013 let mut s = server();
1014 s.on_stream(0, 6, b"ghij", false).unwrap();
1015 s.on_stream(0, 3, b"defgh", false).unwrap();
1016 s.on_stream(0, 8, b"ijkl", true).unwrap();
1017 let mut out = [0u8; 32];
1018 assert_eq!(s.read(0, &mut out), Err(StreamError::WouldBlock));
1019 s.on_stream(0, 0, b"abcd", false).unwrap();
1020 let (n, fin) = s.read(0, &mut out).unwrap();
1021 assert_eq!(&out[..n], b"abcdefghijkl");
1022 assert!(fin);
1023 assert_eq!(s.events.iter().filter(|e| matches!(e, StreamEvent::Readable(0))).count(), 1);
1024 }
1025
1026 fn wide() -> Streams {
1027 let w = 1 << 20;
1028 Streams::new(
1029 true,
1030 StreamConfig {
1031 max_streams_bidi: 4,
1032 max_streams_uni: 4,
1033 stream_window_bidi_local: w,
1034 stream_window_bidi_remote: w,
1035 stream_window_uni: w,
1036 conn_window: w,
1037 send_buffer: 1000,
1038 },
1039 )
1040 }
1041
1042 fn gaps(s: &Streams, id: u64) -> usize {
1043 s.map.get(&id).unwrap().recv.as_ref().unwrap().gaps()
1044 }
1045
1046 #[test]
1047 fn adjacent_out_of_order_chunks_merge_and_reassemble() {
1048 let data: Vec<u8> = (0..2000u32).map(|i| (i * 31 % 251) as u8).collect();
1052 let mut chunks = Vec::new();
1053 let mut off = 0usize;
1054 while off < data.len() {
1055 let end = (off + 1 + off % 7).min(data.len());
1056 chunks.push((off, end));
1057 off = end;
1058 }
1059 let mut st = wide();
1060 let odd = (1..chunks.len()).filter(|i| i % 2 == 1);
1061 let even = (1..chunks.len()).filter(|i| i % 2 == 0);
1062 for i in odd.chain(even).chain(1..chunks.len()) {
1063 let (a, b) = chunks[i];
1064 st.on_stream(0, a as u64, &data[a..b], b == data.len()).unwrap();
1065 assert!(gaps(&st, 0) <= chunks.len() / 2 + 1);
1066 }
1067 assert_eq!(gaps(&st, 0), 1, "everything after the first hole merged into one chunk");
1068 st.on_stream(0, 0, &data[..chunks[0].1], false).unwrap();
1069 let mut out = vec![0u8; 4096];
1070 let (n, fin) = st.read(0, &mut out).unwrap();
1071 assert_eq!(&out[..n], &data[..]);
1072 assert!(fin);
1073 }
1074
1075 #[test]
1076 fn too_many_out_of_order_gaps_is_an_error() {
1077 let mut st = wide();
1078 for i in 0..MAX_RECV_GAPS as u64 {
1079 st.on_stream(0, 2 + 2 * i, b"x", false).unwrap();
1080 }
1081 assert_eq!(gaps(&st, 0), MAX_RECV_GAPS);
1082 let e = st.on_stream(0, 2 + 2 * MAX_RECV_GAPS as u64, b"x", false).unwrap_err();
1083 assert_eq!(e.code, PROTOCOL_VIOLATION);
1084 }
1085
1086 #[test]
1089 fn out_of_order_gap_cap_is_per_connection() {
1090 let mut st = wide();
1091 let per = (MAX_RECV_GAPS / 4) as u64;
1092 for id in [0u64, 4, 8, 12] {
1093 for i in 0..per {
1094 st.on_stream(id, 2 + 2 * i, b"x", false).unwrap();
1095 }
1096 }
1097 assert_eq!(st.recv_gaps, MAX_RECV_GAPS);
1098 let e = st.on_stream(4, 2 + 2 * per, b"x", false).unwrap_err();
1099 assert_eq!(e.code, PROTOCOL_VIOLATION, "one more hole on any stream is over the connection's cap");
1100 let mut st = wide();
1101 for i in 0..per {
1102 st.on_stream(0, 2 + 2 * i, b"x", false).unwrap();
1103 }
1104 st.on_reset(0, 0, 2 + 2 * per).unwrap();
1105 assert_eq!(st.recv_gaps, 0, "a reset stream's holes no longer count");
1106 st.on_stream(4, 2, b"x", false).unwrap();
1108 st.on_stream(4, 4, b"x", false).unwrap();
1109 assert_eq!(st.recv_gaps, 2);
1110 st.on_stream(4, 3, b"x", false).unwrap();
1111 assert_eq!(st.recv_gaps, 1, "adjacent chunks merged into one hole");
1112 st.on_stream(4, 0, b"xx", false).unwrap();
1113 assert_eq!(st.recv_gaps, 0);
1114 }
1115
1116 #[test]
1117 fn send_side_credit_and_limits() {
1118 let mut s = server();
1119 let id = s.open(true).unwrap();
1120 assert_eq!(id, 1);
1121 assert_eq!(s.open(true), Err(StreamError::LimitReached));
1122 assert_eq!(s.control.back(), Some(&Control::StreamsBlocked(true)));
1123 assert_eq!(s.write(id, &[1; 100], false), Ok(30));
1125 assert_eq!(s.write(id, &[1; 1], false), Err(StreamError::Blocked));
1126 assert!(s.control.contains(&Control::StreamDataBlocked(id)));
1127 s.on_max_stream_data(id, 100).unwrap();
1128 assert_eq!(s.events.back(), Some(&StreamEvent::Writable(id)));
1129 assert_eq!(s.write(id, &[1; 100], false), Ok(20));
1131 assert!(s.write(id, &[1; 1], false).is_err());
1132 assert!(s.control.contains(&Control::DataBlocked));
1133 s.on_max_streams(true, 2);
1134 assert_eq!(s.events.back(), Some(&StreamEvent::Available(true)));
1135 let mut out = Vec::new();
1137 let mut sent = Vec::new();
1138 s.write_frames(&mut out, 1000, &mut sent);
1139 assert_eq!(sent, vec![crate::recovery::SentFrame::Stream { id, off: 0, len: 50, fin: false }]);
1140 s.on_stream_lost(id, 10, 20, false);
1141 out.clear();
1142 sent.clear();
1143 s.write_frames(&mut out, 1000, &mut sent);
1144 assert_eq!(sent, vec![crate::recovery::SentFrame::Stream { id, off: 10, len: 20, fin: false }]);
1145 s.on_stream_acked(id, 0, 50, false);
1146 assert_eq!(s.unacked(id), Some(0));
1147 s.on_stream_acked(id, 10, 20, false);
1150 s.on_max_data(1000);
1151 s.on_max_stream_data(id, 1000).unwrap();
1152 assert_eq!(s.write(id, &[2; 30], false), Ok(30));
1153 out.clear();
1154 sent.clear();
1155 s.write_frames(&mut out, 1000, &mut sent);
1156 s.on_stream_acked(id, 50, 30, false);
1157 assert_eq!(s.unacked(id), Some(0), "the buffer is released after a stale acknowledgement");
1158 }
1159
1160 #[test]
1161 fn peer_streams_raise_max_streams_when_closed() {
1162 let mut s = server();
1163 s.on_stream(0, 0, b"a", true).unwrap();
1164 let mut b = [0u8; 4];
1165 s.read(0, &mut b).unwrap();
1166 s.write(0, b"", true).unwrap();
1167 let mut out = Vec::new();
1168 let mut sent = Vec::new();
1169 s.write_frames(&mut out, 1000, &mut sent);
1170 s.on_stream_acked(0, 0, 0, true);
1171 assert!(!s.contains(0));
1172 assert!(s.control.contains(&Control::MaxStreams(true)));
1173 s.on_stream(8, 0, b"x", false).unwrap();
1175 }
1176}