Skip to main content

netstack3_tcp/
buffer.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Defines the buffer traits needed by the TCP implementation. The traits
6//! in this module provide a common interface for platform-specific buffers
7//! used by TCP.
8
9use netstack3_base::{Payload, SackBlocks, SeqNum};
10
11use arrayvec::ArrayVec;
12use core::fmt::Debug;
13use core::ops::Range;
14use packet::InnerPacketBuilder;
15
16use crate::internal::base::BufferSizes;
17use crate::internal::seq_ranges::{SeqRange, SeqRanges};
18
19/// Common super trait for both sending and receiving buffer.
20pub trait Buffer: Debug + Sized {
21    /// Returns information about the number of bytes in the buffer.
22    ///
23    /// Returns a [`BufferLimits`] instance with information about the number of
24    /// bytes in the buffer.
25    fn limits(&self) -> BufferLimits;
26
27    /// Gets the target size of the buffer, in bytes.
28    ///
29    /// The target capacity of the buffer is distinct from the actual capacity
30    /// ([`BufferLimits.capacity`], returned by [`Buffer::limits()`]) in that
31    /// the target capacity should remain fixed unless requested otherwise,
32    /// while the actual capacity can vary with usage.
33    ///
34    /// For fixed-size buffers this should return the same result as calling
35    /// `self.limits().capacity`. For buffer types that support resizing, the
36    /// returned value can be different but should not change unless a resize
37    /// was requested.
38    fn target_capacity(&self) -> usize;
39
40    /// Requests that the buffer be resized to hold the given number of bytes.
41    ///
42    /// Calling this method suggests to the buffer that it should alter its size.
43    /// Implementations are free to impose constraints or ignore requests
44    /// entirely.
45    fn request_capacity(&mut self, size: usize);
46}
47
48/// A buffer supporting TCP receiving operations.
49pub trait ReceiveBuffer: Buffer {
50    /// Writes `data` into the buffer at `offset`.
51    ///
52    /// Returns the number of bytes written.
53    fn write_at<P: Payload>(&mut self, offset: usize, data: &P) -> usize;
54
55    /// Marks `count` bytes available for the application to read.
56    ///
57    /// `has_outstanding` informs the buffer if any bytes past `count` may have
58    /// been populated by out of order segments.
59    ///
60    /// # Panics
61    ///
62    /// Panics if the caller attempts to make more bytes readable than the
63    /// buffer has capacity for. That is, this method panics if `self.len() +
64    /// count > self.cap()`
65    fn make_readable(&mut self, count: usize, has_outstanding: bool);
66}
67
68/// A buffer supporting TCP sending operations.
69pub trait SendBuffer: Buffer {
70    /// The payload type given to `peek_with`.
71    type Payload<'a>: InnerPacketBuilder + Payload + Debug + 'a;
72
73    /// Removes `count` bytes from the beginning of the buffer as already read.
74    ///
75    /// # Panics
76    ///
77    /// Panics if more bytes are marked as read than are available, i.e.,
78    /// `count > self.len`.
79    fn mark_read(&mut self, count: usize);
80
81    /// Calls `f` with contiguous sequences of readable bytes in the buffer
82    /// without advancing the reading pointer.
83    ///
84    /// # Panics
85    ///
86    /// Panics if more bytes are peeked than are available, i.e.,
87    /// `offset > self.len`
88    fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
89    where
90        F: FnOnce(Self::Payload<'a>) -> R;
91}
92
93/// Information about the number of bytes in a [`Buffer`].
94#[derive(Eq, PartialEq, Debug, Copy, Clone)]
95pub struct BufferLimits {
96    /// The total number of bytes that the buffer can hold.
97    pub capacity: usize,
98
99    /// The number of readable bytes that the buffer currently holds.
100    pub len: usize,
101}
102
103/// Assembler for out-of-order segment data.
104#[derive(Debug)]
105#[cfg_attr(test, derive(PartialEq, Eq))]
106pub(super) struct Assembler {
107    // `nxt` is the next sequence number to be expected. It should be before
108    // any sequnce number of the out-of-order sequence numbers we keep track
109    // of below.
110    nxt: SeqNum,
111    // Keeps track of the "age" of segments in the outstanding queue. Every time
112    // a segment is inserted, the generation increases. This allows
113    // RFC-compliant ordering of selective ACK blocks.
114    generation: usize,
115    // Holds all the sequence number ranges which we have already received.
116    // These ranges are sorted and should have a gap of at least 1 byte
117    // between any consecutive two. These ranges should only be after `nxt`.
118    // Each range is tagged with the generation that last modified it.
119    outstanding: SeqRanges<usize>,
120}
121
122impl Assembler {
123    /// The max number of outstanding ranges we'll track for the assembler.
124    ///
125    /// In order to preserve this limit, the assembler will evict the rightmost
126    /// range. Preserving the leftmost ranges is important because they will be
127    /// made available to the application first.
128    pub(crate) const MAX_NUM_OUTSTANDING_RANGES: usize = 64;
129
130    /// Creates a new assembler.
131    pub(super) fn new(nxt: SeqNum) -> Self {
132        Self { outstanding: SeqRanges::default(), generation: 0, nxt }
133    }
134
135    /// Returns the next sequence number expected to be received.
136    pub(super) fn nxt(&self) -> SeqNum {
137        self.nxt
138    }
139
140    /// Returns whether there are out-of-order segments waiting to be
141    /// acknowledged.
142    pub(super) fn has_out_of_order(&self) -> bool {
143        !self.outstanding.is_empty()
144    }
145
146    /// Inserts a received segment.
147    ///
148    /// The newly added segment will be merged with as many existing ones as
149    /// possible and `nxt` will be advanced to the highest ACK number possible.
150    ///
151    /// Returns number of bytes that should be available for the application
152    /// to consume.
153    ///
154    /// # Panics
155    ///
156    /// Panics if `start` is after `end` or if `start` is before `self.nxt`.
157    pub(super) fn insert(&mut self, Range { start, end }: Range<SeqNum>) -> usize {
158        assert!(!start.after(end));
159        assert!(!start.before(self.nxt));
160        if start == end {
161            return 0;
162        }
163
164        let Self { outstanding, nxt, generation } = self;
165        *generation = *generation + 1;
166        let _: bool = outstanding.insert(start..end, *generation);
167
168        if let Some(advanced) = outstanding.pop_front_if(|r| r.start() == *nxt) {
169            *nxt = advanced.end();
170            usize::try_from(advanced.len()).unwrap()
171        } else {
172            // Since we're not popping the front of `outstanding`, ensure the
173            // range we inserted above didn't extend beyond the limit.
174            if outstanding.len() > Self::MAX_NUM_OUTSTANDING_RANGES {
175                let _evicted: Option<SeqRange<usize>> = outstanding.pop_back();
176            }
177            0
178        }
179    }
180
181    pub(super) fn has_outstanding(&self) -> bool {
182        let Self { outstanding, nxt: _, generation: _ } = self;
183        !outstanding.is_empty()
184    }
185
186    /// Returns the current outstanding selective ack blocks in the assembler.
187    ///
188    /// The returned blocks are sorted according to [RFC 2018 section 4]:
189    ///
190    /// * The first SACK block (i.e., the one immediately following the kind and
191    ///   length fields in the option) MUST specify the contiguous block of data
192    ///   containing the segment which triggered this ACK. [...]
193    /// * The SACK option SHOULD be filled out by repeating the most recently
194    ///   reported SACK blocks [...]
195    ///
196    /// This is achieved by always returning the blocks that were most recently
197    /// changed by incoming segments.
198    ///
199    /// [RFC 2018 section 4]:
200    ///     https://datatracker.ietf.org/doc/html/rfc2018#section-4
201    pub(crate) fn sack_blocks(&self, size_limits: SackBlockSizeLimiters) -> SackBlocks {
202        let Self { nxt: _, generation: _, outstanding } = self;
203        // Fast exit, no outstanding blocks.
204        if outstanding.is_empty() {
205            return SackBlocks::default();
206        }
207
208        // Create a heap with storage to hold the maximum allowed number of
209        // blocks, but the number of blocks allowed for this connection may be
210        // lower based on the other TCP options in use.
211        let mut heap = ArrayVec::<&SeqRange<_>, { SackBlocks::MAX_BLOCKS }>::new();
212        let num_blocks_allowed = size_limits.num_blocks_allowed();
213
214        for block in outstanding.iter() {
215            if heap.len() >= num_blocks_allowed {
216                if heap.last().is_some_and(|l| l.meta() < block.meta()) {
217                    // New block is later than the earliest block in the heap.
218                    let _: Option<_> = heap.pop();
219                } else {
220                    // New block is earlier than the earliest block in the heap,
221                    // pass.
222                    continue;
223                }
224            }
225
226            heap.push(block);
227            // Sort heap larger generation to lower.
228            heap.sort_by(|a, b| b.meta().cmp(&a.meta()))
229        }
230
231        SackBlocks::from_iter(heap.into_iter().map(|block| block.to_sack_block()))
232    }
233}
234
235pub(crate) struct SackBlockSizeLimiters {
236    pub(crate) timestamp_enabled: bool,
237}
238
239impl SackBlockSizeLimiters {
240    fn num_blocks_allowed(&self) -> usize {
241        let Self { timestamp_enabled } = self;
242        if *timestamp_enabled {
243            SackBlocks::MAX_BLOCKS_WITH_TIMESTAMP
244        } else {
245            SackBlocks::MAX_BLOCKS
246        }
247    }
248}
249
250/// A conversion trait that converts the object that Bindings give us into a
251/// pair of receive and send buffers.
252pub trait IntoBuffers<R: ReceiveBuffer, S: SendBuffer> {
253    /// Converts to receive and send buffers.
254    fn into_buffers(self, buffer_sizes: BufferSizes) -> (R, S);
255}
256
257#[cfg(any(test, feature = "testutils"))]
258impl<R: Default + ReceiveBuffer, S: Default + SendBuffer> IntoBuffers<R, S> for () {
259    fn into_buffers(self, buffer_sizes: BufferSizes) -> (R, S) {
260        // Ignore buffer sizes since this is a test-only impl.
261        let BufferSizes { send: _, receive: _ } = buffer_sizes;
262        Default::default()
263    }
264}
265
266#[cfg(any(test, feature = "testutils"))]
267pub(crate) mod testutil {
268    use super::*;
269
270    use alloc::sync::Arc;
271    use alloc::vec;
272    use alloc::vec::Vec;
273    use core::cmp;
274
275    use either::Either;
276    use netstack3_base::sync::Mutex;
277    use netstack3_base::{FragmentedPayload, PayloadLen, WindowSize};
278
279    use crate::internal::socket::accept_queue::ListenerNotifier;
280
281    /// A circular buffer implementation.
282    ///
283    /// A [`RingBuffer`] holds a logically contiguous ring of memory in three
284    /// regions:
285    ///
286    /// - *readable*: memory is available for reading and not for writing,
287    /// - *writable*: memory that is available for writing and not for reading,
288    /// - *reserved*: memory that was read from and is no longer available
289    ///   for reading or for writing.
290    ///
291    /// Zero or more of these regions can be empty, and a region of memory can
292    /// transition from one to another in a few different ways:
293    ///
294    /// *Readable* memory, once read, becomes writable.
295    ///
296    /// *Writable* memory, once marked as such, becomes readable.
297    #[derive(Clone, PartialEq, Eq)]
298    pub struct RingBuffer {
299        pub(super) storage: Vec<u8>,
300        /// The index where the reader starts to read.
301        ///
302        /// Maintains the invariant that `head < storage.len()` by wrapping
303        /// around to 0 as needed.
304        pub(super) head: usize,
305        /// The amount of readable data in `storage`.
306        ///
307        /// Anything between [head, head+len) is readable. This will never exceed
308        /// `storage.len()`.
309        pub(super) len: usize,
310    }
311
312    impl Debug for RingBuffer {
313        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
314            let Self { storage, head, len } = self;
315            f.debug_struct("RingBuffer")
316                .field("storage (len, cap)", &(storage.len(), storage.capacity()))
317                .field("head", head)
318                .field("len", len)
319                .finish()
320        }
321    }
322
323    impl Default for RingBuffer {
324        fn default() -> Self {
325            Self::new(WindowSize::DEFAULT.into())
326        }
327    }
328
329    impl RingBuffer {
330        /// Creates a new `RingBuffer`.
331        pub fn new(capacity: usize) -> Self {
332            Self { storage: vec![0; capacity], head: 0, len: 0 }
333        }
334
335        /// Resets the buffer to be entirely unwritten.
336        pub fn reset(&mut self) {
337            let Self { storage: _, head, len } = self;
338            *head = 0;
339            *len = 0;
340        }
341
342        /// Calls `f` on the contiguous sequences from `start` up to `len` bytes.
343        fn with_readable<'a, F, R>(storage: &'a Vec<u8>, start: usize, len: usize, f: F) -> R
344        where
345            F: for<'b> FnOnce(&'b [&'a [u8]]) -> R,
346        {
347            // Don't read past the end of storage.
348            let end = start + len;
349            if end > storage.len() {
350                let first_part = &storage[start..storage.len()];
351                let second_part = &storage[0..len - first_part.len()];
352                f(&[first_part, second_part][..])
353            } else {
354                let all_bytes = &storage[start..end];
355                f(&[all_bytes][..])
356            }
357        }
358
359        /// Calls `f` with contiguous sequences of readable bytes in the buffer and
360        /// discards the amount of bytes returned by `f`.
361        ///
362        /// # Panics
363        ///
364        /// Panics if the closure wants to discard more bytes than possible, i.e.,
365        /// the value returned by `f` is greater than `self.len()`.
366        pub fn read_with<F>(&mut self, f: F) -> usize
367        where
368            F: for<'a, 'b> FnOnce(&'b [&'a [u8]]) -> usize,
369        {
370            let Self { storage, head, len } = self;
371            if storage.len() == 0 {
372                return f(&[&[]]);
373            }
374            let nread = RingBuffer::with_readable(storage, *head, *len, f);
375            assert!(nread <= *len);
376            *len -= nread;
377            *head = (*head + nread) % storage.len();
378            nread
379        }
380
381        /// Returns the writable regions of the [`RingBuffer`].
382        pub fn writable_regions(&mut self) -> impl IntoIterator<Item = &mut [u8]> {
383            let BufferLimits { capacity, len } = self.limits();
384            let available = capacity - len;
385            let Self { storage, head, len } = self;
386
387            let mut write_start = *head + *len;
388            if write_start >= storage.len() {
389                write_start -= storage.len()
390            }
391            let write_end = write_start + available;
392            if write_end <= storage.len() {
393                Either::Left([&mut self.storage[write_start..write_end]].into_iter())
394            } else {
395                let (b1, b2) = self.storage[..].split_at_mut(write_start);
396                let b2_len = b2.len();
397                Either::Right([b2, &mut b1[..(available - b2_len)]].into_iter())
398            }
399        }
400    }
401
402    impl Buffer for RingBuffer {
403        fn limits(&self) -> BufferLimits {
404            let Self { storage, len, head: _ } = self;
405            let capacity = storage.len();
406            BufferLimits { len: *len, capacity }
407        }
408
409        fn target_capacity(&self) -> usize {
410            let Self { storage, len: _, head: _ } = self;
411            storage.len()
412        }
413
414        fn request_capacity(&mut self, size: usize) {
415            unimplemented!("capacity request for {size} not supported")
416        }
417    }
418
419    impl ReceiveBuffer for RingBuffer {
420        fn write_at<P: Payload>(&mut self, offset: usize, data: &P) -> usize {
421            let BufferLimits { capacity, len } = self.limits();
422            let available = capacity - len;
423            let Self { storage, head, len } = self;
424            if storage.len() == 0 {
425                return 0;
426            }
427
428            if offset > available {
429                return 0;
430            }
431            let start_at = (*head + *len + offset) % storage.len();
432            let to_write = cmp::min(data.len(), available);
433            // Write the first part of the payload.
434            let first_len = cmp::min(to_write, storage.len() - start_at);
435            data.partial_copy(0, &mut storage[start_at..start_at + first_len]);
436            // If we have more to write, wrap around and start from the beginning
437            // of the storage.
438            if to_write > first_len {
439                data.partial_copy(first_len, &mut storage[0..to_write - first_len]);
440            }
441            to_write
442        }
443
444        fn make_readable(&mut self, count: usize, _has_outstanding: bool) {
445            let BufferLimits { capacity, len } = self.limits();
446            debug_assert!(count <= capacity - len);
447            self.len += count;
448        }
449    }
450
451    impl SendBuffer for RingBuffer {
452        type Payload<'a> = FragmentedPayload<'a, 2>;
453
454        fn mark_read(&mut self, count: usize) {
455            let Self { storage, head, len } = self;
456            assert!(count <= *len);
457            *len -= count;
458            *head = (*head + count) % storage.len();
459        }
460
461        fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
462        where
463            F: FnOnce(Self::Payload<'a>) -> R,
464        {
465            let Self { storage, head, len } = self;
466            if storage.len() == 0 {
467                return f(FragmentedPayload::new_empty());
468            }
469            assert!(offset <= *len);
470            RingBuffer::with_readable(
471                storage,
472                (*head + offset) % storage.len(),
473                *len - offset,
474                |readable| f(readable.iter().map(|x| *x).collect()),
475            )
476        }
477    }
478
479    impl RingBuffer {
480        /// Enqueues as much of `data` as possible to the end of the buffer.
481        ///
482        /// Returns the number of bytes actually queued.
483        pub(crate) fn enqueue_data(&mut self, data: &[u8]) -> usize {
484            let nwritten = self.write_at(0, &data);
485            self.make_readable(nwritten, false);
486            nwritten
487        }
488    }
489
490    impl Buffer for Arc<Mutex<RingBuffer>> {
491        fn limits(&self) -> BufferLimits {
492            self.lock().limits()
493        }
494
495        fn target_capacity(&self) -> usize {
496            self.lock().target_capacity()
497        }
498
499        fn request_capacity(&mut self, size: usize) {
500            self.lock().request_capacity(size)
501        }
502    }
503
504    impl ReceiveBuffer for Arc<Mutex<RingBuffer>> {
505        fn write_at<P: Payload>(&mut self, offset: usize, data: &P) -> usize {
506            self.lock().write_at(offset, data)
507        }
508
509        fn make_readable(&mut self, count: usize, has_outstanding: bool) {
510            self.lock().make_readable(count, has_outstanding)
511        }
512    }
513
514    /// An implementation of [`SendBuffer`] for tests.
515    #[derive(Debug, Default)]
516    pub struct TestSendBuffer {
517        fake_stream: Arc<Mutex<Vec<u8>>>,
518        ring: RingBuffer,
519    }
520
521    impl TestSendBuffer {
522        /// Creates a new `TestSendBuffer` with a backing shared vec and a
523        /// helper ring buffer.
524        pub fn new(fake_stream: Arc<Mutex<Vec<u8>>>, ring: RingBuffer) -> TestSendBuffer {
525            Self { fake_stream, ring }
526        }
527
528        /// Enqueues data into the buffer.
529        pub fn enqueue_data(&mut self, data: &[u8]) {
530            self.fake_stream.lock().extend_from_slice(data);
531        }
532    }
533
534    impl Buffer for TestSendBuffer {
535        fn limits(&self) -> BufferLimits {
536            let Self { fake_stream, ring } = self;
537            let BufferLimits { capacity: ring_capacity, len: ring_len } = ring.limits();
538            let guard = fake_stream.lock();
539            let len = ring_len + guard.len();
540            let capacity = ring_capacity + guard.capacity();
541            BufferLimits { len, capacity }
542        }
543
544        fn target_capacity(&self) -> usize {
545            let Self { fake_stream: _, ring } = self;
546            ring.target_capacity()
547        }
548
549        fn request_capacity(&mut self, size: usize) {
550            let Self { fake_stream: _, ring } = self;
551            ring.request_capacity(size)
552        }
553    }
554
555    impl SendBuffer for TestSendBuffer {
556        type Payload<'a> = FragmentedPayload<'a, 2>;
557
558        fn mark_read(&mut self, count: usize) {
559            let Self { fake_stream: _, ring } = self;
560            ring.mark_read(count)
561        }
562
563        fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
564        where
565            F: FnOnce(Self::Payload<'a>) -> R,
566        {
567            let Self { fake_stream, ring } = self;
568            let mut guard = fake_stream.lock();
569            if !guard.is_empty() {
570                // Pull from the fake stream into the ring if there is capacity.
571                let BufferLimits { capacity, len } = ring.limits();
572                let len = (capacity - len).min(guard.len());
573                let rest = guard.split_off(len);
574                let first = core::mem::replace(&mut *guard, rest);
575                assert_eq!(ring.enqueue_data(&first[..]), len);
576            }
577            ring.peek_with(offset, f)
578        }
579    }
580
581    fn arc_mutex_eq<T: PartialEq>(a: &Arc<Mutex<T>>, b: &Arc<Mutex<T>>) -> bool {
582        if Arc::ptr_eq(a, b) {
583            return true;
584        }
585        (&*a.lock()) == (&*b.lock())
586    }
587
588    /// A fake implementation of client-side TCP buffers.
589    #[derive(Clone, Debug, Default)]
590    pub struct ClientBuffers {
591        /// Receive buffer shared with core TCP implementation.
592        pub receive: Arc<Mutex<RingBuffer>>,
593        /// Send buffer shared with core TCP implementation.
594        pub send: Arc<Mutex<Vec<u8>>>,
595    }
596
597    impl PartialEq for ClientBuffers {
598        fn eq(&self, ClientBuffers { receive: other_receive, send: other_send }: &Self) -> bool {
599            let Self { receive, send } = self;
600            arc_mutex_eq(receive, other_receive) && arc_mutex_eq(send, other_send)
601        }
602    }
603
604    impl Eq for ClientBuffers {}
605
606    impl ClientBuffers {
607        /// Creates new a `ClientBuffers` with `buffer_sizes`.
608        pub fn new(buffer_sizes: BufferSizes) -> Self {
609            let BufferSizes { send, receive } = buffer_sizes;
610            Self {
611                receive: Arc::new(Mutex::new(RingBuffer::new(receive))),
612                send: Arc::new(Mutex::new(Vec::with_capacity(send))),
613            }
614        }
615    }
616
617    /// A fake implementation of bindings buffers for TCP.
618    #[derive(Debug, Clone, Eq, PartialEq)]
619    #[allow(missing_docs)]
620    pub enum ProvidedBuffers {
621        Buffers(WriteBackClientBuffers),
622        NoBuffers,
623    }
624
625    impl Default for ProvidedBuffers {
626        fn default() -> Self {
627            Self::NoBuffers
628        }
629    }
630
631    impl From<WriteBackClientBuffers> for ProvidedBuffers {
632        fn from(buffers: WriteBackClientBuffers) -> Self {
633            ProvidedBuffers::Buffers(buffers)
634        }
635    }
636
637    impl From<ProvidedBuffers> for WriteBackClientBuffers {
638        fn from(extra: ProvidedBuffers) -> Self {
639            match extra {
640                ProvidedBuffers::Buffers(buffers) => buffers,
641                ProvidedBuffers::NoBuffers => Default::default(),
642            }
643        }
644    }
645
646    impl From<ProvidedBuffers> for () {
647        fn from(_: ProvidedBuffers) -> Self {
648            ()
649        }
650    }
651
652    impl From<()> for ProvidedBuffers {
653        fn from(_: ()) -> Self {
654            Default::default()
655        }
656    }
657
658    /// The variant of [`ProvidedBuffers`] that provides observing the data
659    /// sent/received to TCP sockets.
660    #[derive(Debug, Default, Clone)]
661    pub struct WriteBackClientBuffers(pub Arc<Mutex<Option<ClientBuffers>>>);
662
663    impl PartialEq for WriteBackClientBuffers {
664        fn eq(&self, Self(other): &Self) -> bool {
665            let Self(this) = self;
666            arc_mutex_eq(this, other)
667        }
668    }
669
670    impl Eq for WriteBackClientBuffers {}
671
672    impl IntoBuffers<Arc<Mutex<RingBuffer>>, TestSendBuffer> for ProvidedBuffers {
673        fn into_buffers(
674            self,
675            buffer_sizes: BufferSizes,
676        ) -> (Arc<Mutex<RingBuffer>>, TestSendBuffer) {
677            let buffers = ClientBuffers::new(buffer_sizes);
678            if let ProvidedBuffers::Buffers(b) = self {
679                *b.0.as_ref().lock() = Some(buffers.clone());
680            }
681            let ClientBuffers { receive, send } = buffers;
682            (receive, TestSendBuffer::new(send, Default::default()))
683        }
684    }
685
686    impl ListenerNotifier for ProvidedBuffers {
687        fn new_incoming_connections(&mut self, _: usize) {}
688    }
689
690    #[derive(Debug)]
691    pub struct RepeatingPayload {
692        len: usize,
693    }
694
695    impl RepeatingPayload {
696        const REPEATING_BYTE: u8 = 0xAA;
697    }
698
699    impl PayloadLen for RepeatingPayload {
700        fn len(&self) -> usize {
701            self.len
702        }
703    }
704
705    impl Payload for RepeatingPayload {
706        fn slice(self, range: Range<u32>) -> Self {
707            Self { len: usize::try_from(range.end - range.start).unwrap() }
708        }
709
710        fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
711            assert!(offset < self.len);
712            assert_eq!(dst.len() - offset, self.len);
713            dst.fill(Self::REPEATING_BYTE);
714        }
715
716        fn partial_copy_uninit(&self, offset: usize, dst: &mut [core::mem::MaybeUninit<u8>]) {
717            assert!(offset < self.len);
718            assert_eq!(dst.len() - offset, self.len);
719            dst.fill(core::mem::MaybeUninit::new(Self::REPEATING_BYTE));
720        }
721
722        fn new_empty() -> Self {
723            Self { len: 0 }
724        }
725    }
726
727    impl InnerPacketBuilder for RepeatingPayload {
728        fn bytes_len(&self) -> usize {
729            self.len
730        }
731
732        fn serialize(&self, buffer: &mut [u8]) {
733            buffer.fill(Self::REPEATING_BYTE)
734        }
735    }
736
737    /// A buffer that always has [`usize::MAX`] bytes available to write.
738    #[derive(Default, Debug, Eq, PartialEq)]
739    pub struct InfiniteSendBuffer;
740
741    impl InfiniteSendBuffer {
742        const LEN: usize = usize::MAX as usize;
743    }
744
745    impl Buffer for InfiniteSendBuffer {
746        fn limits(&self) -> BufferLimits {
747            BufferLimits { capacity: Self::LEN, len: Self::LEN }
748        }
749
750        fn target_capacity(&self) -> usize {
751            Self::LEN
752        }
753
754        fn request_capacity(&mut self, size: usize) {
755            unimplemented!("can't change capacity of infinite send buffer to {size}")
756        }
757    }
758
759    impl SendBuffer for InfiniteSendBuffer {
760        type Payload<'a> = RepeatingPayload;
761
762        fn mark_read(&mut self, _count: usize) {}
763
764        fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
765        where
766            F: FnOnce(Self::Payload<'a>) -> R,
767        {
768            f(RepeatingPayload { len: Self::LEN - offset })
769        }
770    }
771
772    /// A buffer that has a controllable amount of [`RepeatingPayload`] bytes
773    /// available to read.
774    #[derive(Default, Debug, Eq, PartialEq)]
775    pub struct RepeatingSendBuffer(usize);
776
777    impl RepeatingSendBuffer {
778        /// Creates a new buffer with the provided `length`.
779        pub fn new(length: usize) -> Self {
780            Self(length)
781        }
782    }
783
784    impl Buffer for RepeatingSendBuffer {
785        fn limits(&self) -> BufferLimits {
786            let Self(len) = self;
787            BufferLimits { capacity: usize::MAX, len: *len }
788        }
789
790        fn target_capacity(&self) -> usize {
791            usize::MAX
792        }
793
794        fn request_capacity(&mut self, size: usize) {
795            unimplemented!("can't change capacity of repeatable send buffer to {size}")
796        }
797    }
798
799    impl SendBuffer for RepeatingSendBuffer {
800        type Payload<'a> = RepeatingPayload;
801
802        fn mark_read(&mut self, count: usize) {
803            let Self(len) = self;
804            *len = *len - count;
805        }
806
807        fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
808        where
809            F: FnOnce(Self::Payload<'a>) -> R,
810        {
811            let Self(len) = self;
812            f(RepeatingPayload { len: *len - offset })
813        }
814    }
815}
816
817#[cfg(test)]
818mod test {
819    use alloc::vec;
820    use alloc::vec::Vec;
821
822    use netstack3_base::FragmentedPayload;
823    use proptest::strategy::{Just, Strategy};
824    use proptest::test_runner::Config;
825    use proptest::{prop_assert, prop_assert_eq, proptest};
826    use proptest_support::failed_seeds_no_std;
827    use test_case::test_case;
828    use testutil::RingBuffer;
829
830    use super::*;
831
832    fn contains_range(assembler: &Assembler, range: Range<SeqNum>) -> bool {
833        assembler.outstanding.iter().any(|r| r.start() == range.start && r.end() == range.end)
834    }
835
836    proptest! {
837        #![proptest_config(Config {
838            // Add all failed seeds here.
839            failure_persistence: failed_seeds_no_std!(
840                "cc f621ca7d3a2b108e0dc41f7169ad028f4329b79e90e73d5f68042519a9f63999",
841                "cc c449aebed201b4ec4f137f3c224f20325f4cfee0b7fd596d9285176b6d811aa9"
842            ),
843            ..Config::default()
844        })]
845
846        #[test]
847        fn ring_buffer_make_readable((mut rb, avail) in ring_buffer::with_written()) {
848            let old_storage = rb.storage.clone();
849            let old_head = rb.head;
850            let old_len = rb.limits().len;
851            rb.make_readable(avail, false);
852            // Assert that length is updated but everything else is unchanged.
853            let RingBuffer { storage, head, len } = rb;
854            prop_assert_eq!(len, old_len + avail);
855            prop_assert_eq!(head, old_head);
856            prop_assert_eq!(storage, old_storage);
857        }
858
859        #[test]
860        fn ring_buffer_write_at((mut rb, offset, data) in ring_buffer::with_offset_data()) {
861            let old_head = rb.head;
862            let old_len = rb.limits().len;
863            prop_assert_eq!(rb.write_at(offset, &&data[..]), data.len());
864            prop_assert_eq!(rb.head, old_head);
865            prop_assert_eq!(rb.limits().len, old_len);
866            for i in 0..data.len() {
867                let masked = (rb.head + rb.len + offset + i) % rb.storage.len();
868                // Make sure that data are written.
869                prop_assert_eq!(rb.storage[masked], data[i]);
870                rb.storage[masked] = 0;
871            }
872            // And the other parts of the storage are untouched.
873            prop_assert_eq!(&rb.storage, &vec![0; rb.storage.len()]);
874        }
875
876        #[test]
877        fn ring_buffer_read_with((mut rb, expected, consume) in ring_buffer::with_read_data()) {
878            prop_assert_eq!(rb.limits().len, expected.len());
879            let nread = rb.read_with(|readable| {
880                assert!(readable.len() == 1 || readable.len() == 2);
881                let got = readable.concat();
882                assert_eq!(got, expected);
883                consume
884            });
885            prop_assert_eq!(nread, consume);
886            prop_assert_eq!(rb.limits().len, expected.len() - consume);
887        }
888
889        #[test]
890        fn ring_buffer_mark_read((mut rb, readable) in ring_buffer::with_readable()) {
891            const BYTE_TO_WRITE: u8 = 0x42;
892            let written = rb.writable_regions().into_iter().fold(0, |acc, slice| {
893                slice.fill(BYTE_TO_WRITE);
894                acc + slice.len()
895            });
896            let old_storage = rb.storage.clone();
897            let old_head = rb.head;
898            let old_len = rb.limits().len;
899
900            rb.mark_read(readable);
901            let new_writable = rb.writable_regions().into_iter().fold(Vec::new(), |mut acc, slice| {
902                acc.extend_from_slice(slice);
903                acc
904            });
905            for (i, x) in new_writable.iter().enumerate().take(written) {
906                prop_assert_eq!(*x, BYTE_TO_WRITE, "i={}, rb={:?}", i, rb);
907            }
908            prop_assert!(new_writable.len() >= written);
909
910            let RingBuffer { storage, head, len } = rb;
911            prop_assert_eq!(len, old_len - readable);
912            prop_assert_eq!(head, (old_head + readable) % old_storage.len());
913            prop_assert_eq!(storage, old_storage);
914        }
915
916        #[test]
917        fn ring_buffer_peek_with((mut rb, expected, offset) in ring_buffer::with_read_data()) {
918            prop_assert_eq!(rb.limits().len, expected.len());
919            rb.peek_with(offset, |readable| {
920                prop_assert_eq!(readable.to_vec(), &expected[offset..]);
921                Ok(())
922            })?;
923            prop_assert_eq!(rb.limits().len, expected.len());
924        }
925
926        #[test]
927        fn ring_buffer_writable_regions(mut rb in ring_buffer::arb_ring_buffer()) {
928            const BYTE_TO_WRITE: u8 = 0x42;
929            let writable_len = rb.writable_regions().into_iter().fold(0, |acc, slice| {
930                slice.fill(BYTE_TO_WRITE);
931                acc + slice.len()
932            });
933            let BufferLimits {len, capacity} = rb.limits();
934            prop_assert_eq!(writable_len + len, capacity);
935            for i in 0..capacity {
936                let expected = if i < len {
937                    0
938                } else {
939                    BYTE_TO_WRITE
940                };
941                let idx = (rb.head + i) % rb.storage.len();
942                prop_assert_eq!(rb.storage[idx], expected);
943            }
944        }
945    }
946
947    #[test_case([Range { start: 0, end: 0 }]
948        => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(0), generation: 0 })]
949    #[test_case([Range { start: 0, end: 10 }]
950        => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(10), generation: 1 })]
951    #[test_case([Range{ start: 10, end: 15 }, Range { start: 5, end: 10 }]
952        => Assembler {
953            outstanding: [
954                SeqRange::new(SeqNum::new(5)..SeqNum::new(15), 2).unwrap()
955            ].into_iter().collect(),
956            nxt: SeqNum::new(0),
957            generation: 2,
958        })
959    ]
960    #[test_case([Range{ start: 10, end: 15 }, Range { start: 0, end: 5 }, Range { start: 5, end: 10 }]
961        => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(15), generation: 3 })]
962    #[test_case([Range{ start: 10, end: 15 }, Range { start: 5, end: 10 }, Range { start: 0, end: 5 }]
963        => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(15), generation: 3 })]
964    #[test_case([Range{ start: 10, end: 15 }, Range { start: 10, end: 15 }, Range { start: 11, end: 12 }]
965        => Assembler {
966             outstanding: [
967                SeqRange::new(SeqNum::new(10)..SeqNum::new(15), 3).unwrap()
968            ].into_iter().collect(),
969            nxt: SeqNum::new(0), generation: 3 })]
970    fn assembler_examples(ops: impl IntoIterator<Item = Range<u32>>) -> Assembler {
971        let mut assembler = Assembler::new(SeqNum::new(0));
972        for Range { start, end } in ops.into_iter() {
973            let _advanced = assembler.insert(SeqNum::new(start)..SeqNum::new(end));
974        }
975        assembler
976    }
977
978    #[test_case(&[] => Vec::<Range<u32>>::new(); "empty")]
979    #[test_case(&[1..2] => vec![1..2]; "single")]
980    #[test_case(&[1..2, 3..4] => vec![3..4, 1..2]; "latest first")]
981    #[test_case(&[1..2, 3..4, 5..6, 7..8, 9..10]
982        => vec![9..10, 7..8, 5..6, 3..4]; "max len")]
983    #[test_case(&[1..2, 3..4, 5..6, 7..8, 9..10, 6..7]
984        => vec![5..8, 9..10, 3..4, 1..2]; "gap fill")]
985    #[test_case(&[1..2, 3..4, 5..6, 7..8, 9..10, 1..8]
986        => vec![1..8, 9..10]; "large gap fill")]
987    fn assembler_sack_blocks(ops: &[Range<u32>]) -> Vec<Range<u32>> {
988        let mut assembler = Assembler::new(SeqNum::new(0));
989        for Range { start, end } in ops {
990            let _: usize = assembler.insert(SeqNum::new(*start)..SeqNum::new(*end));
991        }
992        assembler
993            .sack_blocks(SackBlockSizeLimiters { timestamp_enabled: false })
994            .try_iter()
995            .map(|r| r.expect("invalid block").into_range_u32())
996            .collect()
997    }
998
999    #[test_case(false => vec![10..11, 7..8, 4..5, 1..2]; "4_blocks_with_timestamp_disabled")]
1000    #[test_case(true => vec![10..11, 7..8, 4..5]; "3_blocks_with_timestamp_disabled")]
1001    fn assembler_sack_blocks_with_timestamp(timestamp_enabled: bool) -> Vec<Range<u32>> {
1002        let mut assembler = Assembler::new(SeqNum::new(0));
1003        for Range { start, end } in [1..2, 4..5, 7..8, 10..11] {
1004            let _: usize = assembler.insert(SeqNum::new(start)..SeqNum::new(end));
1005        }
1006        assembler
1007            .sack_blocks(SackBlockSizeLimiters { timestamp_enabled })
1008            .try_iter()
1009            .map(|r| r.expect("invalid_block").into_range_u32())
1010            .collect()
1011    }
1012
1013    // Verify that the Assembler correctly limits the outstanding ranges.
1014    #[test]
1015    fn assembler_max_outstanding_ranges() {
1016        const MAX: usize = Assembler::MAX_NUM_OUTSTANDING_RANGES;
1017
1018        // Set up a 10 byte gap between every outstanding range.
1019        const PERIOD: u32 = 20;
1020        const LEN: u32 = 10;
1021        const OFFSET: u32 = 10;
1022        let nth_range = |n| {
1023            SeqNum::new(PERIOD * (n as u32) + OFFSET)
1024                ..SeqNum::new(PERIOD * (n as u32) + OFFSET + LEN)
1025        };
1026
1027        // Insert the maximum number of disjoint ranges into the assembler.
1028        let mut assembler = Assembler::new(SeqNum::new(0));
1029        for n in 0..MAX {
1030            assert_eq!(assembler.insert(nth_range(n)), 0);
1031        }
1032        assert_eq!(assembler.outstanding.len(), MAX);
1033        assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 1).start);
1034
1035        // If the new range is rightmost, it should be dropped.
1036        assert_eq!(assembler.insert(nth_range(MAX)), 0);
1037        assert_eq!(assembler.outstanding.len(), MAX);
1038        assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 1).start);
1039
1040        // If the new range makes data available, it should do so without
1041        // eviction.
1042        assert_eq!(assembler.insert(SeqNum::new(0)..SeqNum::new(1)), 1);
1043        assert_eq!(assembler.outstanding.len(), MAX);
1044        assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 1).start);
1045
1046        // If the new range is in the middle & disjoint from all existing ranges
1047        // it should be inserted and the rightmost range should be evicted.
1048        let middle_disjoint = SeqNum::new(PERIOD + 2)..SeqNum::new(PERIOD + OFFSET - 2);
1049        assert_eq!(assembler.insert(middle_disjoint.clone()), 0);
1050        assert_eq!(assembler.outstanding.len(), MAX);
1051        assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 2).start);
1052        assert!(contains_range(&assembler, middle_disjoint));
1053
1054        // If the new range extends an existing range, it should do so without
1055        // eviction.
1056        let extending_range1 = nth_range(10).end..nth_range(10).end + 1;
1057        assert_eq!(assembler.insert(extending_range1.clone()), 0);
1058        assert_eq!(assembler.outstanding.len(), MAX);
1059        assert!(contains_range(&assembler, nth_range(10).start..extending_range1.end));
1060
1061        // If the new range merges two existing ranges, it should do so without
1062        // eviction.
1063        let extending_range2 = extending_range1.start..nth_range(11).start;
1064        assert_eq!(assembler.insert(extending_range2), 0);
1065        assert_eq!(assembler.outstanding.len(), MAX - 1);
1066        assert!(contains_range(&assembler, nth_range(10).start..nth_range(11).end));
1067    }
1068
1069    #[test]
1070    // Regression test for https://fxbug.dev/42061342.
1071    fn ring_buffer_wrap_around() {
1072        const CAPACITY: usize = 16;
1073        let mut rb = RingBuffer::new(CAPACITY);
1074
1075        // Write more than half the buffer.
1076        const BUF_SIZE: usize = 10;
1077        assert_eq!(rb.enqueue_data(&[0xAA; BUF_SIZE]), BUF_SIZE);
1078        rb.peek_with(0, |payload| {
1079            assert_eq!(payload, FragmentedPayload::new_contiguous(&[0xAA; BUF_SIZE]))
1080        });
1081        rb.mark_read(BUF_SIZE);
1082
1083        // Write around the end of the buffer.
1084        assert_eq!(rb.enqueue_data(&[0xBB; BUF_SIZE]), BUF_SIZE);
1085        rb.peek_with(0, |payload| {
1086            assert_eq!(
1087                payload,
1088                FragmentedPayload::new([
1089                    &[0xBB; (CAPACITY - BUF_SIZE)],
1090                    &[0xBB; (BUF_SIZE * 2 - CAPACITY)]
1091                ])
1092            )
1093        });
1094        // Mark everything read, which should advance `head` around to the
1095        // beginning of the buffer.
1096        rb.mark_read(BUF_SIZE);
1097
1098        // Now make a contiguous sequence of bytes readable.
1099        assert_eq!(rb.enqueue_data(&[0xCC; BUF_SIZE]), BUF_SIZE);
1100        rb.peek_with(0, |payload| {
1101            assert_eq!(payload, FragmentedPayload::new_contiguous(&[0xCC; BUF_SIZE]))
1102        });
1103
1104        // Check that the unwritten bytes are left untouched. If `head` was
1105        // advanced improperly, this will crash.
1106        let read = rb.read_with(|segments| {
1107            assert_eq!(segments, [[0xCC; BUF_SIZE]]);
1108            BUF_SIZE
1109        });
1110        assert_eq!(read, BUF_SIZE);
1111    }
1112
1113    #[test]
1114    fn ring_buffer_example() {
1115        let mut rb = RingBuffer::new(16);
1116        assert_eq!(rb.write_at(5, &"World".as_bytes()), 5);
1117        assert_eq!(rb.write_at(0, &"Hello".as_bytes()), 5);
1118        rb.make_readable(10, false);
1119        assert_eq!(
1120            rb.read_with(|readable| {
1121                assert_eq!(readable, &["HelloWorld".as_bytes()]);
1122                5
1123            }),
1124            5
1125        );
1126        assert_eq!(
1127            rb.read_with(|readable| {
1128                assert_eq!(readable, &["World".as_bytes()]);
1129                readable[0].len()
1130            }),
1131            5
1132        );
1133        assert_eq!(rb.write_at(0, &"HelloWorld".as_bytes()), 10);
1134        rb.make_readable(10, false);
1135        assert_eq!(
1136            rb.read_with(|readable| {
1137                assert_eq!(readable, &["HelloW".as_bytes(), "orld".as_bytes()]);
1138                6
1139            }),
1140            6
1141        );
1142        assert_eq!(rb.limits().len, 4);
1143        assert_eq!(
1144            rb.read_with(|readable| {
1145                assert_eq!(readable, &["orld".as_bytes()]);
1146                4
1147            }),
1148            4
1149        );
1150        assert_eq!(rb.limits().len, 0);
1151
1152        assert_eq!(rb.enqueue_data("Hello".as_bytes()), 5);
1153        assert_eq!(rb.limits().len, 5);
1154
1155        rb.peek_with(3, |readable| {
1156            assert_eq!(readable.to_vec(), "lo".as_bytes());
1157        });
1158
1159        rb.mark_read(2);
1160
1161        rb.peek_with(0, |readable| {
1162            assert_eq!(readable.to_vec(), "llo".as_bytes());
1163        });
1164    }
1165
1166    mod ring_buffer {
1167        use super::*;
1168        // Use a small capacity so that we have a higher chance to exercise
1169        // wrapping around logic.
1170        const MAX_CAP: usize = 32;
1171
1172        fn arb_ring_buffer_args() -> impl Strategy<Value = (usize, usize, usize)> {
1173            // Use a small capacity so that we have a higher chance to exercise
1174            // wrapping around logic.
1175            (1..=MAX_CAP).prop_flat_map(|cap| {
1176                let max_len = cap;
1177                //  cap      head     len
1178                (Just(cap), 0..cap, 0..=max_len)
1179            })
1180        }
1181
1182        pub(super) fn arb_ring_buffer() -> impl Strategy<Value = RingBuffer> {
1183            arb_ring_buffer_args().prop_map(|(cap, head, len)| RingBuffer {
1184                storage: vec![0; cap],
1185                head,
1186                len,
1187            })
1188        }
1189
1190        /// A strategy for a [`RingBuffer`] and a valid length to mark read.
1191        pub(super) fn with_readable() -> impl Strategy<Value = (RingBuffer, usize)> {
1192            arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1193                (Just(RingBuffer { storage: vec![0; cap], head, len }), 0..=len)
1194            })
1195        }
1196
1197        /// A strategy for a [`RingBuffer`] and a valid length to make readable.
1198        pub(super) fn with_written() -> impl Strategy<Value = (RingBuffer, usize)> {
1199            arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1200                let rb = RingBuffer { storage: vec![0; cap], head, len };
1201                let max_written = cap - len;
1202                (Just(rb), 0..=max_written)
1203            })
1204        }
1205
1206        /// A strategy for a [`RingBuffer`], a valid offset and data to write.
1207        pub(super) fn with_offset_data() -> impl Strategy<Value = (RingBuffer, usize, Vec<u8>)> {
1208            arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1209                let writable_len = cap - len;
1210                (0..=writable_len).prop_flat_map(move |offset| {
1211                    (0..=writable_len - offset).prop_flat_map(move |data_len| {
1212                        (
1213                            Just(RingBuffer { storage: vec![0; cap], head, len }),
1214                            Just(offset),
1215                            proptest::collection::vec(1..=u8::MAX, data_len),
1216                        )
1217                    })
1218                })
1219            })
1220        }
1221
1222        /// A strategy for a [`RingBuffer`], its readable data, and how many
1223        /// bytes to consume.
1224        pub(super) fn with_read_data() -> impl Strategy<Value = (RingBuffer, Vec<u8>, usize)> {
1225            arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1226                proptest::collection::vec(1..=u8::MAX, len).prop_flat_map(move |data| {
1227                    // Fill the RingBuffer with the data.
1228                    let mut rb = RingBuffer { storage: vec![0; cap], head, len: 0 };
1229                    assert_eq!(rb.write_at(0, &&data[..]), len);
1230                    rb.make_readable(len, false);
1231                    (Just(rb), Just(data), 0..=len)
1232                })
1233            })
1234        }
1235    }
1236}