1use std::collections::VecDeque;
10
11use crate::crypto::Decryptor;
12use crate::loss::{LossList, Timing};
13use crate::packet::{Ack, AckStats, Control, ControlPacket, DataPacket, MAX_LOSS_ENTRIES};
14use crate::rtt::Rtt;
15use crate::seq::{Seq, TimestampExtender};
16
17pub const ACK_INTERVAL: i64 = 10_000;
19pub const LIGHT_ACK_PACKETS: u32 = 64;
21pub const KEEPALIVE_INTERVAL: i64 = 1_000_000;
23const DRIFT_WINDOW: u32 = 1000;
25const DRIFT_STEP: i64 = 5_000;
27const DRIFT_MAX: i64 = 500_000;
29const MAX_HOLD_BEYOND_LATENCY: i64 = 1_000_000;
32const ACKS_REMEMBERED: usize = 64;
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub struct Settings {
38 pub latency: i64,
40 pub buffer: usize,
42 pub peer_idle: i64,
44 pub max_payload: usize,
46}
47
48#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
50pub struct Stats {
51 pub received: u64,
53 pub received_bytes: u64,
55 pub retransmitted: u64,
57 pub duplicates: u64,
59 pub belated: u64,
61 pub lost: u64,
63 pub dropped: u64,
65 pub delivered: u64,
67 pub encrypted: u64,
69 pub decrypted: u64,
71 pub km_rejected: u64,
74 pub naks_sent: u64,
76 pub acks_sent: u64,
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq)]
82pub enum CloseReason {
83 Shutdown,
85 Timeout,
87}
88
89#[derive(Debug)]
90struct Slot {
91 deliver_at: i64,
92 payload: Vec<u8>,
93}
94
95#[derive(Debug, Default)]
97struct RateMeter {
98 since: i64,
99 packets: u32,
100 bytes: u64,
101 rate: (u32, u32),
102}
103
104impl RateMeter {
105 fn add(&mut self, now: i64, bytes: usize) {
106 let elapsed = now - self.since;
107 if elapsed >= 1_000_000 {
108 let per_s = |n: u64| u32::try_from(n * 1_000_000 / elapsed as u64).unwrap_or(u32::MAX);
109 self.rate = (per_s(u64::from(self.packets)), per_s(self.bytes));
110 self.since = now;
111 self.packets = 0;
112 self.bytes = 0;
113 }
114 self.packets = self.packets.saturating_add(1);
115 self.bytes = self.bytes.saturating_add(bytes as u64);
116 }
117}
118
119#[derive(Debug, Default)]
122struct PacketPairs {
123 last: Option<(Seq, i64)>,
124 gaps: VecDeque<i64>,
125}
126
127impl PacketPairs {
128 fn add(&mut self, seq: Seq, now: i64) {
129 if let Some((s, t)) = self.last
130 && s.next() == seq
131 {
132 if self.gaps.len() >= 16 {
133 self.gaps.pop_front();
134 }
135 self.gaps.push_back((now - t).max(1));
136 }
137 self.last = Some((seq, now));
138 }
139
140 fn capacity(&self) -> u32 {
143 if self.gaps.is_empty() {
144 return 1000;
145 }
146 let mut g: Vec<i64> = self.gaps.iter().copied().collect();
147 g.sort_unstable();
148 let median = g.get(g.len() / 2).copied().unwrap_or(1).max(1);
149 u32::try_from(1_000_000 / median).unwrap_or(u32::MAX)
150 }
151}
152
153#[derive(Debug, Default)]
156struct Drift {
157 offset: i64,
158 window_min: Option<i64>,
159 count: u32,
160}
161
162impl Drift {
163 fn sample(&mut self, lateness: i64) {
164 self.window_min = Some(self.window_min.map_or(lateness, |m| m.min(lateness)));
165 self.count += 1;
166 if self.count >= DRIFT_WINDOW {
167 let target = self.window_min.unwrap_or(self.offset);
168 self.offset = (self.offset + (target - self.offset).clamp(-DRIFT_STEP, DRIFT_STEP))
169 .clamp(-DRIFT_MAX, DRIFT_MAX);
170 self.window_min = None;
171 self.count = 0;
172 }
173 }
174}
175
176pub struct Receiver {
179 settings: Settings,
180 peer_socket: u32,
181 start: i64,
183 base: i64,
185 ts: TimestampExtender,
186 drift: Drift,
187 head: Seq,
190 buf: VecDeque<Option<Slot>>,
191 ack_pos: Seq,
193 loss: LossList,
194 rtt: Rtt,
195 next_ack_number: u32,
196 last_ack_sent: Seq,
197 last_full_ack: i64,
198 unanswered: VecDeque<(u32, i64)>,
199 since_ack: u32,
200 last_sent: i64,
201 last_received: i64,
202 now: i64,
204 rate: RateMeter,
205 pairs: PacketPairs,
206 stats: Stats,
207 closed: Option<CloseReason>,
208 send: VecDeque<Vec<u8>>,
210 deliver: VecDeque<Vec<u8>>,
211 crypto: Option<Decryptor>,
212 next_km: i64,
213}
214
215impl Receiver {
216 pub fn new(
219 settings: Settings,
220 now: i64,
221 peer_socket: u32,
222 initial_seq: Seq,
223 hs_timestamp: u32,
224 ) -> Self {
225 Self {
226 settings,
227 peer_socket,
228 start: now,
229 base: now - i64::from(hs_timestamp),
230 ts: TimestampExtender::starting_at(hs_timestamp),
231 drift: Drift::default(),
232 head: initial_seq,
233 buf: VecDeque::new(),
234 ack_pos: initial_seq,
235 loss: LossList::new(),
236 rtt: Rtt::new(),
237 next_ack_number: 1,
238 last_ack_sent: initial_seq,
239 last_full_ack: now,
240 unanswered: VecDeque::new(),
241 since_ack: 0,
242 last_sent: now,
243 last_received: now,
244 now,
245 rate: RateMeter {
246 since: now,
247 ..RateMeter::default()
248 },
249 pairs: PacketPairs::default(),
250 stats: Stats::default(),
251 closed: None,
252 send: VecDeque::new(),
253 deliver: VecDeque::new(),
254 crypto: None,
255 next_km: 0,
256 }
257 }
258
259 pub fn stats(&self) -> Stats {
261 self.stats
262 }
263
264 pub fn rtt(&self) -> &Rtt {
266 &self.rtt
267 }
268
269 pub fn latency(&self) -> i64 {
271 self.settings.latency
272 }
273
274 pub(crate) fn set_crypto(&mut self, crypto: Option<Decryptor>) {
275 self.crypto = crypto;
276 }
277
278 pub fn closed(&self) -> Option<CloseReason> {
280 self.closed
281 }
282
283 pub fn take_send(&mut self) -> Option<Vec<u8>> {
285 self.send.pop_front()
286 }
287
288 pub fn take_delivery(&mut self) -> Option<Vec<u8>> {
290 self.deliver.pop_front()
291 }
292
293 pub fn buffered(&self) -> usize {
295 self.buf.len()
296 }
297
298 fn queue(&mut self, now: i64, body: Control) {
299 let ts = (now - self.start) as u32;
300 let mut out = Vec::with_capacity(64);
301 ControlPacket::new(ts, self.peer_socket, body).encode(&mut out);
302 self.send.push_back(out);
303 self.last_sent = now;
304 }
305
306 pub fn on_data(&mut self, now: i64, p: &DataPacket) {
310 self.now = self.now.max(now);
311 if self.closed.is_some() {
312 return;
313 }
314 if (self.crypto.is_some() && !matches!(p.key, 1 | 2))
315 || (self.crypto.is_none() && p.key != 0)
316 {
317 self.stats.encrypted += 1;
319 return;
320 }
321 if p.payload.len() > self.settings.max_payload {
322 return;
323 }
324 self.stats.received += 1;
325 self.stats.received_bytes += p.payload.len() as u64;
326 if p.retransmitted {
327 self.stats.retransmitted += 1;
328 }
329 let distance = self.head.distance_to(p.seq);
331 if distance < 0 {
332 self.stats.belated += 1;
333 return;
334 }
335 if self.buf.get(distance as usize).is_some_and(Option::is_some) {
336 self.stats.duplicates += 1;
337 return;
338 }
339 let mut payload = p.payload.to_vec();
340 if let Some(crypto) = &mut self.crypto {
341 if crypto.decrypt(p.key, p.seq, &mut payload).is_err() {
342 self.stats.encrypted += 1;
343 return;
344 }
345 self.stats.decrypted += 1;
346 }
347 self.last_received = now;
348 let ext = self.ts.extend(p.timestamp);
349 if !p.retransmitted {
350 self.drift
351 .sample(now.saturating_sub(self.base.saturating_add(ext)));
352 self.rate.add(now, p.payload.len());
353 self.pairs.add(p.seq, now);
354 }
355 let deliver_at = self
356 .base
357 .saturating_add(self.drift.offset)
358 .saturating_add(ext)
359 .saturating_add(self.settings.latency)
360 .min(now.saturating_add(self.settings.latency + MAX_HOLD_BEYOND_LATENCY));
361
362 let mut d = self.head.distance_to(p.seq);
363 if d < 0 {
364 self.stats.belated += 1;
365 return;
366 }
367 if d as usize >= self.settings.buffer {
368 self.make_room(p.seq);
369 d = self.head.distance_to(p.seq);
370 }
371 let idx = d as usize;
372 let slot = Slot {
373 deliver_at,
374 payload,
375 };
376 if let Some(existing) = self.buf.get_mut(idx) {
377 if existing.is_some() {
378 self.stats.duplicates += 1;
379 return;
380 }
381 *existing = Some(slot);
382 self.loss.remove(p.seq);
383 } else {
384 if idx > self.buf.len() {
385 let first = self.head.add(self.buf.len() as u32);
387 let last = p.seq.prev();
388 self.stats.lost += first.distance_to(last) as u64 + 1;
389 self.loss.add(first, last, now, deliver_at);
390 self.stats.naks_sent += 1;
391 self.queue(now, Control::Nak(vec![(first, last)]));
392 self.buf.resize_with(idx, || None);
393 }
394 self.buf.push_back(Some(slot));
395 }
396 self.advance_ack_pos();
397 self.since_ack += 1;
398 if self.since_ack >= LIGHT_ACK_PACKETS && self.ack_pos != self.last_ack_sent {
399 self.light_ack(now);
400 }
401 self.nak_due(now);
402 self.release(now);
403 }
404
405 fn make_room(&mut self, seq: Seq) {
409 let d = self.head.distance_to(seq) as usize;
410 let excess = d + 1 - self.settings.buffer;
411 if excess > self.buf.len() {
412 self.flush();
413 self.head = seq;
414 self.loss.clear();
415 } else {
416 for _ in 0..excess {
417 self.pop_front();
418 }
419 self.loss.remove_before(self.head);
420 }
421 self.advance_ack_pos();
422 }
423
424 fn pop_front(&mut self) {
426 match self.buf.pop_front() {
427 Some(Some(slot)) => {
428 self.stats.delivered += 1;
429 self.deliver.push_back(slot.payload);
430 }
431 Some(None) => self.stats.dropped += 1,
432 None => {}
433 }
434 self.head = self.head.next();
435 }
436
437 fn flush(&mut self) {
439 while !self.buf.is_empty() {
440 self.pop_front();
441 }
442 self.loss.clear();
443 self.advance_ack_pos();
444 }
445
446 fn advance_ack_pos(&mut self) {
447 let mut i = self.head.distance_to(self.ack_pos).max(0) as usize;
448 while matches!(self.buf.get(i), Some(Some(_))) {
449 i += 1;
450 }
451 self.ack_pos = self.head.add(i as u32);
452 }
453
454 fn release(&mut self, now: i64) {
457 loop {
458 match self.buf.front() {
459 Some(Some(slot)) if slot.deliver_at <= now => self.pop_front(),
460 Some(None) => {
461 let due = self
462 .buf
463 .iter()
464 .position(Option::is_some)
465 .and_then(|i| Some((i, self.buf.get(i)?.as_ref()?.deliver_at)));
466 match due {
467 Some((i, at)) if at <= now => {
468 for _ in 0..i {
469 self.pop_front();
470 }
471 self.loss.remove_before(self.head);
472 self.advance_ack_pos();
473 }
474 _ => break,
475 }
476 }
477 _ => break,
478 }
479 }
480 }
481
482 fn timing(&self) -> Timing {
483 Timing {
484 rtt: self.rtt.rtt(),
485 retry: self.rtt.retry(),
486 }
487 }
488
489 fn nak_due(&mut self, now: i64) {
490 if self.loss.is_empty() {
491 return;
492 }
493 let ranges = self.loss.due(now, self.timing(), MAX_LOSS_ENTRIES / 2);
494 if !ranges.is_empty() {
495 self.stats.naks_sent += 1;
496 self.queue(now, Control::Nak(ranges));
497 }
498 }
499
500 fn light_ack(&mut self, now: i64) {
501 self.last_ack_sent = self.ack_pos;
502 self.since_ack = 0;
503 self.stats.acks_sent += 1;
504 let ack = Ack {
505 number: 0,
506 ack: self.ack_pos,
507 stats: None,
508 };
509 self.queue(now, Control::Ack(ack));
510 }
511
512 fn full_ack(&mut self, now: i64) {
513 let number = self.next_ack_number;
514 self.next_ack_number = self.next_ack_number.wrapping_add(1).max(1);
515 self.last_ack_sent = self.ack_pos;
516 self.last_full_ack = now;
517 self.since_ack = 0;
518 self.stats.acks_sent += 1;
519 if self.unanswered.len() >= ACKS_REMEMBERED {
520 self.unanswered.pop_front();
521 }
522 self.unanswered.push_back((number, now));
523 let clamp = |v: i64| u32::try_from(v.max(0)).unwrap_or(u32::MAX);
524 let free = self.settings.buffer.saturating_sub(self.buf.len());
525 let ack = Ack {
526 number,
527 ack: self.ack_pos,
528 stats: Some(AckStats {
529 rtt: clamp(self.rtt.rtt()),
530 rtt_var: clamp(self.rtt.var()),
531 buffer: u32::try_from(free).unwrap_or(u32::MAX),
532 rates: Some((self.rate.rate.0, self.pairs.capacity(), self.rate.rate.1)),
533 }),
534 };
535 self.queue(now, Control::Ack(ack));
536 }
537
538 pub fn on_control(&mut self, now: i64, c: &Control) {
543 self.now = self.now.max(now);
544 if self.closed.is_some() {
545 return;
546 }
547 if let Control::Other {
548 control_type: 0x7fff,
549 subtype: 3,
550 info: 0,
551 cif,
552 } = c
553 {
554 if now < self.next_km {
557 return;
558 }
559 self.next_km = now.saturating_add(100_000);
560 if self
561 .crypto
562 .as_mut()
563 .is_some_and(|crypto| crypto.refresh(cif).is_ok())
564 {
565 self.last_received = now;
566 self.queue(
567 now,
568 Control::Other {
569 control_type: 0x7fff,
570 subtype: 4,
571 info: 0,
572 cif: cif.clone(),
573 },
574 );
575 } else {
576 self.stats.km_rejected += 1;
577 }
578 return;
579 }
580 self.last_received = now;
581 match c {
582 Control::AckAck { number } => {
583 if let Some(i) = self.unanswered.iter().position(|(n, _)| n == number) {
584 if let Some((_, sent)) = self.unanswered.get(i).copied() {
585 self.rtt.sample(now - sent);
586 }
587 self.unanswered.drain(..=i);
588 }
589 }
590 Control::Shutdown => {
591 self.flush();
592 self.closed = Some(CloseReason::Shutdown);
593 }
594 Control::DropRequest { first, last, .. } => {
595 self.loss.remove_range(*first, *last);
597 }
598 _ => {}
599 }
600 }
601
602 pub fn on_timer(&mut self, now: i64) {
605 self.now = self.now.max(now);
606 if self.closed.is_some() {
607 return;
608 }
609 if now - self.last_received >= self.settings.peer_idle {
610 self.closed = Some(CloseReason::Timeout);
611 return;
612 }
613 self.release(now);
614 if self.ack_pos != self.last_ack_sent && now - self.last_full_ack >= ACK_INTERVAL {
615 self.full_ack(now);
616 }
617 self.nak_due(now);
618 if now - self.last_sent >= KEEPALIVE_INTERVAL {
619 self.queue(now, Control::KeepAlive);
620 }
621 }
622
623 pub fn next_timer(&self) -> i64 {
625 let mut t = self
626 .last_received
627 .saturating_add(self.settings.peer_idle)
628 .min(self.last_sent + KEEPALIVE_INTERVAL);
629 if self.ack_pos != self.last_ack_sent {
630 t = t.min(self.last_full_ack + ACK_INTERVAL);
631 }
632 if let Some(at) = self.loss.next_due(self.now, self.timing()) {
633 t = t.min(at);
634 }
635 if let Some(at) = self
636 .buf
637 .iter()
638 .find_map(|s| s.as_ref().map(|s| s.deliver_at))
639 {
640 t = t.min(at);
641 }
642 t
643 }
644
645 pub fn shutdown(&mut self, now: i64) {
647 self.queue(now, Control::Shutdown);
648 }
649}
650
651#[cfg(test)]
652mod tests {
653 use super::*;
654 use crate::packet::{Packet, Position};
655
656 const MS: i64 = 1000;
657 const LATENCY: i64 = 200 * MS;
658 const ISN: u32 = 1000;
659
660 fn settings() -> Settings {
661 Settings {
662 latency: LATENCY,
663 buffer: 64,
664 peer_idle: 5_000 * MS,
665 max_payload: 1456,
666 }
667 }
668
669 fn rx() -> Receiver {
672 Receiver::new(settings(), 0, 77, Seq::new(ISN), 0)
673 }
674
675 fn data(seq: u32, ts: u32, payload: &[u8]) -> DataPacket<'_> {
676 DataPacket {
677 seq: Seq::new(seq),
678 position: Position::Only,
679 in_order: false,
680 key: 0,
681 retransmitted: false,
682 message: 1,
683 timestamp: ts,
684 dest: 5,
685 payload,
686 }
687 }
688
689 fn sent(r: &mut Receiver) -> Vec<Control> {
690 std::iter::from_fn(|| r.take_send())
691 .map(|b| match Packet::parse(&b) {
692 Ok(Packet::Control(c)) => {
693 assert_eq!(c.dest, 77);
694 c.body
695 }
696 other => panic!("{other:?}"),
697 })
698 .collect()
699 }
700
701 fn delivered(r: &mut Receiver) -> Vec<Vec<u8>> {
702 std::iter::from_fn(|| r.take_delivery()).collect()
703 }
704
705 #[test]
706 fn delivers_in_order_at_timestamp_plus_latency() {
707 let mut r = rx();
708 r.on_data(10 * MS, &data(ISN, 10 * MS as u32, b"a"));
709 r.on_data(20 * MS, &data(ISN + 1, 20 * MS as u32, b"b"));
710 assert!(delivered(&mut r).is_empty());
711 assert_eq!(r.next_timer(), 10 * MS, "the first full ACK");
712 r.on_timer(10 * MS);
713 assert_eq!(r.next_timer(), 210 * MS);
714 r.on_timer(209 * MS);
715 assert!(delivered(&mut r).is_empty());
716 r.on_timer(210 * MS);
717 assert_eq!(delivered(&mut r), vec![b"a".to_vec()]);
718 r.on_timer(220 * MS);
719 assert_eq!(delivered(&mut r), vec![b"b".to_vec()]);
720 assert_eq!(r.stats().delivered, 2);
721 }
722
723 #[test]
724 fn a_gap_is_reported_at_once_and_filled_by_a_retransmission() {
725 let mut r = rx();
726 r.on_data(0, &data(ISN, 0, b"0"));
727 r.on_data(MS, &data(ISN + 3, MS as u32, b"3"));
728 let s = |v| Seq::new(v);
729 assert_eq!(
730 sent(&mut r),
731 vec![Control::Nak(vec![(s(ISN + 1), s(ISN + 2))])]
732 );
733 assert_eq!(r.stats().lost, 2);
734 let mut p = data(ISN + 1, 0, b"1");
735 p.retransmitted = true;
736 r.on_data(5 * MS, &p);
737 let mut p = data(ISN + 2, 0, b"2");
738 p.retransmitted = true;
739 r.on_data(6 * MS, &p);
740 r.on_timer(300 * MS);
741 assert_eq!(
742 delivered(&mut r),
743 [b"0", b"1", b"2", b"3"].map(|x| x.to_vec()).to_vec()
744 );
745 assert_eq!(r.stats().dropped, 0);
746 assert_eq!(r.stats().retransmitted, 2);
747 }
748
749 #[test]
750 fn a_missing_packet_is_skipped_when_the_next_is_due() {
751 let mut r = rx();
752 r.on_data(0, &data(ISN, 0, b"0"));
753 r.on_data(2 * MS, &data(ISN + 2, 2 * MS as u32, b"2"));
754 r.on_timer(200 * MS);
755 assert_eq!(delivered(&mut r), vec![b"0".to_vec()]);
756 r.on_timer(201 * MS);
757 assert!(delivered(&mut r).is_empty(), "waits for 1 until 2 is due");
758 r.on_timer(202 * MS);
759 assert_eq!(delivered(&mut r), vec![b"2".to_vec()]);
760 assert_eq!(r.stats().dropped, 1);
761 sent(&mut r);
763 r.on_timer(300 * MS);
764 let acks: Vec<_> = sent(&mut r)
765 .into_iter()
766 .filter_map(|c| match c {
767 Control::Ack(a) => Some(a.ack),
768 _ => None,
769 })
770 .collect();
771 assert_eq!(acks.last(), Some(&Seq::new(ISN + 3)));
772 let mut p = data(ISN + 1, 0, b"1");
774 p.retransmitted = true;
775 r.on_data(301 * MS, &p);
776 assert_eq!(r.stats().belated, 1);
777 assert!(delivered(&mut r).is_empty());
778 }
779
780 #[test]
781 fn acks_and_rtt_from_ackack() {
782 let mut r = rx();
783 r.on_data(0, &data(ISN, 0, b"0"));
784 r.on_timer(10 * MS);
785 let c = sent(&mut r);
786 let [Control::Ack(a)] = c.as_slice() else {
787 panic!("{c:?}");
788 };
789 assert_eq!(a.number, 1);
790 assert_eq!(a.ack, Seq::new(ISN + 1));
791 let st = a.stats.expect("full ACK");
792 assert_eq!((st.rtt, st.rtt_var), (100_000, 50_000));
793 assert_eq!(st.buffer, 63);
794 r.on_control(40 * MS, &Control::AckAck { number: 1 });
795 assert_eq!(r.rtt().rtt(), 30 * MS);
796 r.on_timer(50 * MS);
798 assert!(sent(&mut r).is_empty());
799 r.on_data(51 * MS, &data(ISN + 1, 51 * MS as u32, b"1"));
800 r.on_timer(60 * MS);
801 let c = sent(&mut r);
802 assert!(
803 matches!(c.as_slice(), [Control::Ack(a)] if a.number == 2 && a.stats.is_some_and(|s| s.rtt == 30_000)),
804 "{c:?}"
805 );
806 }
807
808 #[test]
809 fn light_ack_every_64_packets() {
810 let mut r = Receiver::new(
811 Settings {
812 buffer: 1000,
813 ..settings()
814 },
815 0,
816 77,
817 Seq::new(ISN),
818 0,
819 );
820 for i in 0..64 {
821 r.on_data(0, &data(ISN + i, 0, b"x"));
822 }
823 let c = sent(&mut r);
824 assert!(
825 matches!(c.as_slice(), [Control::Ack(Ack { number: 0, stats: None, ack })] if *ack == Seq::new(ISN + 64)),
826 "{c:?}"
827 );
828 }
829
830 #[test]
831 fn nak_again_after_a_round_trip_and_its_variance() {
832 let mut r = Receiver::new(
833 Settings {
834 latency: 2_000 * MS,
835 ..settings()
836 },
837 0,
838 77,
839 Seq::new(ISN),
840 0,
841 );
842 r.on_data(0, &data(ISN, 0, b"0"));
845 r.on_timer(10 * MS);
846 r.on_control(70 * MS, &Control::AckAck { number: 1 });
847 assert_eq!((r.rtt().rtt(), r.rtt().retry()), (60 * MS, 180 * MS));
848 sent(&mut r);
849 r.on_data(71 * MS, &data(ISN + 2, 71 * MS as u32, b"2"));
852 let naks = |c: Vec<Control>| c.iter().filter(|c| matches!(c, Control::Nak(_))).count();
853 assert_eq!(naks(sent(&mut r)), 1, "the immediate NAK");
854 assert_eq!(r.next_timer(), 251 * MS);
855 r.on_timer(250 * MS);
856 assert_eq!(naks(sent(&mut r)), 0);
857 r.on_timer(251 * MS);
858 assert_eq!(naks(sent(&mut r)), 1);
859 assert_eq!(r.next_timer(), 431 * MS);
860 }
861
862 #[test]
863 fn idle_timeout_and_keepalive() {
864 let mut r = rx();
865 assert_eq!(r.next_timer(), KEEPALIVE_INTERVAL);
866 r.on_timer(KEEPALIVE_INTERVAL);
867 assert_eq!(sent(&mut r), vec![Control::KeepAlive]);
868 r.on_control(4_000 * MS, &Control::KeepAlive);
869 r.on_timer(8_999 * MS);
870 assert_eq!(r.closed(), None);
871 r.on_timer(9_000 * MS);
872 assert_eq!(r.closed(), Some(CloseReason::Timeout));
873 }
874
875 #[test]
876 fn shutdown_delivers_what_is_held() {
877 let mut r = rx();
878 r.on_data(0, &data(ISN, 0, b"0"));
879 r.on_data(0, &data(ISN + 1, 0, b"1"));
880 r.on_control(MS, &Control::Shutdown);
881 assert_eq!(r.closed(), Some(CloseReason::Shutdown));
882 assert_eq!(delivered(&mut r).len(), 2);
883 }
884
885 #[test]
886 fn sequence_numbers_wrap() {
887 let mut r = Receiver::new(settings(), 0, 77, Seq::new(Seq::MAX - 1), 0);
888 for (i, s) in [Seq::MAX - 1, Seq::MAX, 0, 1].into_iter().enumerate() {
889 r.on_data(0, &data(s, i as u32, &[i as u8]));
890 }
891 r.on_timer(LATENCY + 10);
892 assert_eq!(delivered(&mut r), vec![vec![0], vec![1], vec![2], vec![3]]);
893 }
894
895 #[test]
896 fn timestamps_wrap() {
897 let hs = u32::MAX - 3_000;
899 let mut r = Receiver::new(settings(), 0, 77, Seq::new(ISN), hs);
900 r.on_data(2 * MS, &data(ISN, hs.wrapping_add(2_000), b"0"));
901 r.on_data(5 * MS, &data(ISN + 1, hs.wrapping_add(5_000), b"1"));
902 r.on_timer(LATENCY + 2 * MS);
903 assert_eq!(delivered(&mut r), vec![b"0".to_vec()]);
904 r.on_timer(LATENCY + 5 * MS);
905 assert_eq!(delivered(&mut r), vec![b"1".to_vec()]);
906 }
907
908 #[test]
909 fn a_full_buffer_delivers_early_and_a_huge_jump_starts_afresh() {
910 let mut r = rx();
911 for i in 0..64 {
912 r.on_data(0, &data(ISN + i, 0, b"x"));
913 }
914 r.on_data(0, &data(ISN + 64, 0, b"y"));
915 assert_eq!(delivered(&mut r).len(), 1, "the oldest made room");
916 assert_eq!(r.buffered(), 64);
917 r.on_data(0, &data(ISN + 1_000_000, 0, b"z"));
918 assert_eq!(delivered(&mut r).len(), 64, "everything held, at once");
919 assert_eq!(r.buffered(), 1);
920 assert_eq!(r.stats().lost, 0, "a jump is not a loss");
921 }
922
923 #[test]
924 fn encrypted_and_oversized_packets_are_refused() {
925 let mut r = rx();
926 let mut p = data(ISN, 0, b"x");
927 p.key = 1;
928 r.on_data(0, &p);
929 let big = vec![0u8; 1457];
930 r.on_data(0, &data(ISN, 0, &big));
931 assert_eq!(r.stats().encrypted, 1);
932 assert_eq!(r.stats().received, 0);
933 assert_eq!(r.buffered(), 0);
934 }
935
936 #[test]
937 fn a_far_future_timestamp_is_not_held_forever() {
938 let mut r = rx();
939 r.on_data(0, &data(ISN, 2_000_000_000, b"x"));
940 assert!(r.next_timer() <= LATENCY + MAX_HOLD_BEYOND_LATENCY);
941 }
942
943 #[test]
944 fn drift_follows_a_slow_sender_clock() {
945 let mut r = rx();
946 for i in 0..3000u32 {
949 let now = i64::from(i) * 4 * MS;
950 let ts = (now - now / 1000) as u32;
951 r.on_data(now, &data(ISN + i, ts, b"x"));
952 r.on_timer(now);
953 delivered(&mut r);
954 sent(&mut r);
955 }
956 assert!(r.drift.offset > 4 * MS, "{}", r.drift.offset);
959 assert!(r.drift.offset <= 12 * MS, "{}", r.drift.offset);
960 }
961
962 #[test]
963 fn drop_request_stops_naks() {
964 let mut r = rx();
965 r.on_data(0, &data(ISN, 0, b"0"));
966 r.on_data(0, &data(ISN + 5, 100 * MS as u32, b"5"));
967 sent(&mut r);
968 r.on_control(
969 MS,
970 &Control::DropRequest {
971 message: 0,
972 first: Seq::new(ISN + 1),
973 last: Seq::new(ISN + 4),
974 },
975 );
976 r.on_timer(150 * MS);
977 assert!(!sent(&mut r).iter().any(|c| matches!(c, Control::Nak(_))));
978 }
979}