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