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::{FragmentedPayload, PayloadLen, WindowSize};
283
284    use crate::internal::socket::accept_queue::{AcceptQueueChange, ListenerNotifier};
285
286    type Mutex<T> = netstack3_base::sync::Mutex<T, netstack3_base::sync::lock_impl::RawMutex>;
287
288    /// A circular buffer implementation.
289    ///
290    /// A [`RingBuffer`] holds a logically contiguous ring of memory in three
291    /// regions:
292    ///
293    /// - *readable*: memory is available for reading and not for writing,
294    /// - *writable*: memory that is available for writing and not for reading,
295    /// - *reserved*: memory that was read from and is no longer available
296    ///   for reading or for writing.
297    ///
298    /// Zero or more of these regions can be empty, and a region of memory can
299    /// transition from one to another in a few different ways:
300    ///
301    /// *Readable* memory, once read, becomes writable.
302    ///
303    /// *Writable* memory, once marked as such, becomes readable.
304    #[derive(Clone, PartialEq, Eq)]
305    pub struct RingBuffer {
306        pub(super) storage: Vec<u8>,
307        /// The index where the reader starts to read.
308        ///
309        /// Maintains the invariant that `head < storage.len()` by wrapping
310        /// around to 0 as needed.
311        pub(super) head: usize,
312        /// The amount of readable data in `storage`.
313        ///
314        /// Anything between [head, head+len) is readable. This will never exceed
315        /// `storage.len()`.
316        pub(super) len: usize,
317    }
318
319    impl Debug for RingBuffer {
320        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
321            let Self { storage, head, len } = self;
322            f.debug_struct("RingBuffer")
323                .field("storage (len, cap)", &(storage.len(), storage.capacity()))
324                .field("head", head)
325                .field("len", len)
326                .finish()
327        }
328    }
329
330    impl Default for RingBuffer {
331        fn default() -> Self {
332            Self::new(WindowSize::DEFAULT.into())
333        }
334    }
335
336    impl RingBuffer {
337        /// Creates a new `RingBuffer`.
338        pub fn new(capacity: usize) -> Self {
339            Self { storage: vec![0; capacity], head: 0, len: 0 }
340        }
341
342        /// Resets the buffer to be entirely unwritten.
343        pub fn reset(&mut self) {
344            let Self { storage: _, head, len } = self;
345            *head = 0;
346            *len = 0;
347        }
348
349        /// Calls `f` on the contiguous sequences from `start` up to `len` bytes.
350        fn with_readable<'a, F, R>(storage: &'a Vec<u8>, start: usize, len: usize, f: F) -> R
351        where
352            F: for<'b> FnOnce(&'b [&'a [u8]]) -> R,
353        {
354            // Don't read past the end of storage.
355            let end = start + len;
356            if end > storage.len() {
357                let first_part = &storage[start..storage.len()];
358                let second_part = &storage[0..len - first_part.len()];
359                f(&[first_part, second_part][..])
360            } else {
361                let all_bytes = &storage[start..end];
362                f(&[all_bytes][..])
363            }
364        }
365
366        /// Calls `f` with contiguous sequences of readable bytes in the buffer and
367        /// discards the amount of bytes returned by `f`.
368        ///
369        /// # Panics
370        ///
371        /// Panics if the closure wants to discard more bytes than possible, i.e.,
372        /// the value returned by `f` is greater than `self.len()`.
373        pub fn read_with<F>(&mut self, f: F) -> usize
374        where
375            F: for<'a, 'b> FnOnce(&'b [&'a [u8]]) -> usize,
376        {
377            let Self { storage, head, len } = self;
378            if storage.len() == 0 {
379                return f(&[&[]]);
380            }
381            let nread = RingBuffer::with_readable(storage, *head, *len, f);
382            assert!(nread <= *len);
383            *len -= nread;
384            *head = (*head + nread) % storage.len();
385            nread
386        }
387
388        /// Returns the writable regions of the [`RingBuffer`].
389        pub fn writable_regions(&mut self) -> impl IntoIterator<Item = &mut [u8]> {
390            let BufferLimits { capacity, len } = self.limits();
391            let available = capacity - len;
392            let Self { storage, head, len } = self;
393
394            let mut write_start = *head + *len;
395            if write_start >= storage.len() {
396                write_start -= storage.len()
397            }
398            let write_end = write_start + available;
399            if write_end <= storage.len() {
400                Either::Left([&mut self.storage[write_start..write_end]].into_iter())
401            } else {
402                let (b1, b2) = self.storage[..].split_at_mut(write_start);
403                let b2_len = b2.len();
404                Either::Right([b2, &mut b1[..(available - b2_len)]].into_iter())
405            }
406        }
407    }
408
409    impl Buffer for RingBuffer {
410        fn limits(&self) -> BufferLimits {
411            let Self { storage, len, head: _ } = self;
412            let capacity = storage.len();
413            BufferLimits { len: *len, capacity }
414        }
415
416        fn target_capacity(&self) -> usize {
417            let Self { storage, len: _, head: _ } = self;
418            storage.len()
419        }
420
421        fn request_capacity(&mut self, size: usize) {
422            unimplemented!("capacity request for {size} not supported")
423        }
424    }
425
426    impl ReceiveBuffer for RingBuffer {
427        fn write_at<P: Payload>(&mut self, offset: usize, data: &P) -> usize {
428            let BufferLimits { capacity, len } = self.limits();
429            let available = capacity - len;
430            let Self { storage, head, len } = self;
431            if storage.len() == 0 {
432                return 0;
433            }
434
435            if offset > available {
436                return 0;
437            }
438            let start_at = (*head + *len + offset) % storage.len();
439            let to_write = cmp::min(data.len(), available);
440            // Write the first part of the payload.
441            let first_len = cmp::min(to_write, storage.len() - start_at);
442            data.partial_copy(0, &mut storage[start_at..start_at + first_len]);
443            // If we have more to write, wrap around and start from the beginning
444            // of the storage.
445            if to_write > first_len {
446                data.partial_copy(first_len, &mut storage[0..to_write - first_len]);
447            }
448            to_write
449        }
450
451        fn make_readable(&mut self, count: usize, _has_outstanding: bool) {
452            let BufferLimits { capacity, len } = self.limits();
453            debug_assert!(count <= capacity - len);
454            self.len += count;
455        }
456    }
457
458    impl SendBuffer for RingBuffer {
459        type Payload<'a> = FragmentedPayload<'a, 2>;
460
461        fn mark_read(&mut self, count: usize) {
462            let Self { storage, head, len } = self;
463            assert!(count <= *len);
464            *len -= count;
465            *head = (*head + count) % storage.len();
466        }
467
468        fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
469        where
470            F: FnOnce(Self::Payload<'a>) -> R,
471        {
472            let Self { storage, head, len } = self;
473            if storage.len() == 0 {
474                return f(FragmentedPayload::new_empty());
475            }
476            assert!(offset <= *len);
477            RingBuffer::with_readable(
478                storage,
479                (*head + offset) % storage.len(),
480                *len - offset,
481                |readable| f(readable.iter().map(|x| *x).collect()),
482            )
483        }
484    }
485
486    impl RingBuffer {
487        /// Enqueues as much of `data` as possible to the end of the buffer.
488        ///
489        /// Returns the number of bytes actually queued.
490        pub(crate) fn enqueue_data(&mut self, data: &[u8]) -> usize {
491            let nwritten = self.write_at(0, &data);
492            self.make_readable(nwritten, false);
493            nwritten
494        }
495    }
496
497    impl Buffer for Arc<Mutex<RingBuffer>> {
498        fn limits(&self) -> BufferLimits {
499            self.lock().limits()
500        }
501
502        fn target_capacity(&self) -> usize {
503            self.lock().target_capacity()
504        }
505
506        fn request_capacity(&mut self, size: usize) {
507            self.lock().request_capacity(size)
508        }
509    }
510
511    impl ReceiveBuffer for Arc<Mutex<RingBuffer>> {
512        fn write_at<P: Payload>(&mut self, offset: usize, data: &P) -> usize {
513            self.lock().write_at(offset, data)
514        }
515
516        fn make_readable(&mut self, count: usize, has_outstanding: bool) {
517            self.lock().make_readable(count, has_outstanding)
518        }
519    }
520
521    /// An implementation of [`SendBuffer`] for tests.
522    #[derive(Debug, Default)]
523    pub struct TestSendBuffer {
524        fake_stream: Arc<Mutex<Vec<u8>>>,
525        ring: RingBuffer,
526    }
527
528    impl TestSendBuffer {
529        /// Creates a new `TestSendBuffer` with a backing shared vec and a
530        /// helper ring buffer.
531        pub fn new(fake_stream: Arc<Mutex<Vec<u8>>>, ring: RingBuffer) -> TestSendBuffer {
532            Self { fake_stream, ring }
533        }
534
535        /// Enqueues data into the buffer.
536        pub fn enqueue_data(&mut self, data: &[u8]) {
537            self.fake_stream.lock().extend_from_slice(data);
538        }
539    }
540
541    impl Buffer for TestSendBuffer {
542        fn limits(&self) -> BufferLimits {
543            let Self { fake_stream, ring } = self;
544            let BufferLimits { capacity: ring_capacity, len: ring_len } = ring.limits();
545            let guard = fake_stream.lock();
546            let len = ring_len + guard.len();
547            let capacity = ring_capacity + guard.capacity();
548            BufferLimits { len, capacity }
549        }
550
551        fn target_capacity(&self) -> usize {
552            let Self { fake_stream: _, ring } = self;
553            ring.target_capacity()
554        }
555
556        fn request_capacity(&mut self, size: usize) {
557            let Self { fake_stream: _, ring } = self;
558            ring.request_capacity(size)
559        }
560    }
561
562    impl SendBuffer for TestSendBuffer {
563        type Payload<'a> = FragmentedPayload<'a, 2>;
564
565        fn mark_read(&mut self, count: usize) {
566            let Self { fake_stream: _, ring } = self;
567            ring.mark_read(count)
568        }
569
570        fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
571        where
572            F: FnOnce(Self::Payload<'a>) -> R,
573        {
574            let Self { fake_stream, ring } = self;
575            let mut guard = fake_stream.lock();
576            if !guard.is_empty() {
577                // Pull from the fake stream into the ring if there is capacity.
578                let BufferLimits { capacity, len } = ring.limits();
579                let len = (capacity - len).min(guard.len());
580                let rest = guard.split_off(len);
581                let first = core::mem::replace(&mut *guard, rest);
582                assert_eq!(ring.enqueue_data(&first[..]), len);
583            }
584            ring.peek_with(offset, f)
585        }
586    }
587
588    fn arc_mutex_eq<T: PartialEq>(a: &Arc<Mutex<T>>, b: &Arc<Mutex<T>>) -> bool {
589        if Arc::ptr_eq(a, b) {
590            return true;
591        }
592        (&*a.lock()) == (&*b.lock())
593    }
594
595    /// A fake implementation of client-side TCP buffers.
596    #[derive(Clone, Debug, Default)]
597    pub struct ClientBuffers {
598        /// Receive buffer shared with core TCP implementation.
599        pub receive: Arc<Mutex<RingBuffer>>,
600        /// Send buffer shared with core TCP implementation.
601        pub send: Arc<Mutex<Vec<u8>>>,
602    }
603
604    impl PartialEq for ClientBuffers {
605        fn eq(&self, ClientBuffers { receive: other_receive, send: other_send }: &Self) -> bool {
606            let Self { receive, send } = self;
607            arc_mutex_eq(receive, other_receive) && arc_mutex_eq(send, other_send)
608        }
609    }
610
611    impl Eq for ClientBuffers {}
612
613    impl ClientBuffers {
614        /// Creates new a `ClientBuffers` with `buffer_sizes`.
615        pub fn new(buffer_sizes: BufferSizes) -> Self {
616            let BufferSizes { send, receive } = buffer_sizes;
617            Self {
618                receive: Arc::new(Mutex::new(RingBuffer::new(receive))),
619                send: Arc::new(Mutex::new(Vec::with_capacity(send))),
620            }
621        }
622    }
623
624    /// A fake implementation of bindings buffers for TCP.
625    #[derive(Debug, Clone, Eq, PartialEq)]
626    #[allow(missing_docs)]
627    pub enum ProvidedBuffers {
628        Buffers(WriteBackClientBuffers),
629        NoBuffers,
630    }
631
632    impl Default for ProvidedBuffers {
633        fn default() -> Self {
634            Self::NoBuffers
635        }
636    }
637
638    impl From<WriteBackClientBuffers> for ProvidedBuffers {
639        fn from(buffers: WriteBackClientBuffers) -> Self {
640            ProvidedBuffers::Buffers(buffers)
641        }
642    }
643
644    impl From<ProvidedBuffers> for WriteBackClientBuffers {
645        fn from(extra: ProvidedBuffers) -> Self {
646            match extra {
647                ProvidedBuffers::Buffers(buffers) => buffers,
648                ProvidedBuffers::NoBuffers => Default::default(),
649            }
650        }
651    }
652
653    impl From<ProvidedBuffers> for () {
654        fn from(_: ProvidedBuffers) -> Self {
655            ()
656        }
657    }
658
659    impl From<()> for ProvidedBuffers {
660        fn from(_: ()) -> Self {
661            Default::default()
662        }
663    }
664
665    /// The variant of [`ProvidedBuffers`] that provides observing the data
666    /// sent/received to TCP sockets.
667    #[derive(Debug, Default, Clone)]
668    pub struct WriteBackClientBuffers(pub Arc<Mutex<Option<ClientBuffers>>>);
669
670    impl PartialEq for WriteBackClientBuffers {
671        fn eq(&self, Self(other): &Self) -> bool {
672            let Self(this) = self;
673            arc_mutex_eq(this, other)
674        }
675    }
676
677    impl Eq for WriteBackClientBuffers {}
678
679    impl IntoBuffers<Arc<Mutex<RingBuffer>>, TestSendBuffer> for ProvidedBuffers {
680        fn into_buffers(
681            self,
682            buffer_sizes: BufferSizes,
683        ) -> (Arc<Mutex<RingBuffer>>, TestSendBuffer) {
684            let buffers = ClientBuffers::new(buffer_sizes);
685            if let ProvidedBuffers::Buffers(b) = self {
686                *b.0.as_ref().lock() = Some(buffers.clone());
687            }
688            let ClientBuffers { receive, send } = buffers;
689            (receive, TestSendBuffer::new(send, Default::default()))
690        }
691    }
692
693    impl ListenerNotifier for ProvidedBuffers {
694        fn accept_queue_changed(&mut self, _: AcceptQueueChange) {}
695    }
696
697    #[derive(Clone, Copy, Debug)]
698    pub struct RepeatingPayload {
699        len: usize,
700    }
701
702    impl RepeatingPayload {
703        const REPEATING_BYTE: u8 = 0xAA;
704    }
705
706    impl PayloadLen for RepeatingPayload {
707        fn len(&self) -> usize {
708            self.len
709        }
710    }
711
712    impl Payload for RepeatingPayload {
713        fn slice(self, range: Range<u32>) -> Self {
714            Self { len: usize::try_from(range.end - range.start).unwrap() }
715        }
716
717        fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
718            assert!(offset < self.len);
719            assert_eq!(dst.len() - offset, self.len);
720            dst.fill(Self::REPEATING_BYTE);
721        }
722
723        fn partial_copy_uninit(&self, offset: usize, dst: &mut [core::mem::MaybeUninit<u8>]) {
724            assert!(offset < self.len);
725            assert_eq!(dst.len() - offset, self.len);
726            dst.fill(core::mem::MaybeUninit::new(Self::REPEATING_BYTE));
727        }
728
729        fn new_empty() -> Self {
730            Self { len: 0 }
731        }
732    }
733
734    impl InnerPacketBuilder for RepeatingPayload {
735        fn bytes_len(&self) -> usize {
736            self.len
737        }
738
739        fn serialize(&self, buffer: &mut [u8]) {
740            buffer.fill(Self::REPEATING_BYTE)
741        }
742    }
743
744    /// A buffer that always has [`usize::MAX`] bytes available to write.
745    #[derive(Default, Debug, Eq, PartialEq)]
746    pub struct InfiniteSendBuffer;
747
748    impl InfiniteSendBuffer {
749        const LEN: usize = usize::MAX as usize;
750    }
751
752    impl Buffer for InfiniteSendBuffer {
753        fn limits(&self) -> BufferLimits {
754            BufferLimits { capacity: Self::LEN, len: Self::LEN }
755        }
756
757        fn target_capacity(&self) -> usize {
758            Self::LEN
759        }
760
761        fn request_capacity(&mut self, size: usize) {
762            unimplemented!("can't change capacity of infinite send buffer to {size}")
763        }
764    }
765
766    impl SendBuffer for InfiniteSendBuffer {
767        type Payload<'a> = RepeatingPayload;
768
769        fn mark_read(&mut self, _count: usize) {}
770
771        fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
772        where
773            F: FnOnce(Self::Payload<'a>) -> R,
774        {
775            f(RepeatingPayload { len: Self::LEN - offset })
776        }
777    }
778
779    /// A buffer that has a controllable amount of [`RepeatingPayload`] bytes
780    /// available to read.
781    #[derive(Default, Debug, Eq, PartialEq)]
782    pub struct RepeatingSendBuffer(usize);
783
784    impl RepeatingSendBuffer {
785        /// Creates a new buffer with the provided `length`.
786        pub fn new(length: usize) -> Self {
787            Self(length)
788        }
789    }
790
791    impl Buffer for RepeatingSendBuffer {
792        fn limits(&self) -> BufferLimits {
793            let Self(len) = self;
794            BufferLimits { capacity: usize::MAX, len: *len }
795        }
796
797        fn target_capacity(&self) -> usize {
798            usize::MAX
799        }
800
801        fn request_capacity(&mut self, size: usize) {
802            unimplemented!("can't change capacity of repeatable send buffer to {size}")
803        }
804    }
805
806    impl SendBuffer for RepeatingSendBuffer {
807        type Payload<'a> = RepeatingPayload;
808
809        fn mark_read(&mut self, count: usize) {
810            let Self(len) = self;
811            *len = *len - count;
812        }
813
814        fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
815        where
816            F: FnOnce(Self::Payload<'a>) -> R,
817        {
818            let Self(len) = self;
819            f(RepeatingPayload { len: *len - offset })
820        }
821    }
822}
823
824#[cfg(test)]
825mod test {
826    use alloc::vec;
827    use alloc::vec::Vec;
828
829    use netstack3_base::FragmentedPayload;
830    use proptest::strategy::{Just, Strategy};
831    use proptest::test_runner::Config;
832    use proptest::{prop_assert, prop_assert_eq, proptest};
833    use proptest_support::failed_seeds_no_std;
834    use test_case::test_case;
835    use testutil::RingBuffer;
836
837    use super::*;
838
839    fn contains_range(assembler: &Assembler, range: Range<SeqNum>) -> bool {
840        assembler.outstanding.iter().any(|r| r.start() == range.start && r.end() == range.end)
841    }
842
843    proptest! {
844        #![proptest_config(Config {
845            // Add all failed seeds here.
846            failure_persistence: failed_seeds_no_std!(
847                "cc f621ca7d3a2b108e0dc41f7169ad028f4329b79e90e73d5f68042519a9f63999",
848                "cc c449aebed201b4ec4f137f3c224f20325f4cfee0b7fd596d9285176b6d811aa9"
849            ),
850            ..Config::default()
851        })]
852
853        #[test]
854        fn ring_buffer_make_readable((mut rb, avail) in ring_buffer::with_written()) {
855            let old_storage = rb.storage.clone();
856            let old_head = rb.head;
857            let old_len = rb.limits().len;
858            rb.make_readable(avail, false);
859            // Assert that length is updated but everything else is unchanged.
860            let RingBuffer { storage, head, len } = rb;
861            prop_assert_eq!(len, old_len + avail);
862            prop_assert_eq!(head, old_head);
863            prop_assert_eq!(storage, old_storage);
864        }
865
866        #[test]
867        fn ring_buffer_write_at((mut rb, offset, data) in ring_buffer::with_offset_data()) {
868            let old_head = rb.head;
869            let old_len = rb.limits().len;
870            prop_assert_eq!(rb.write_at(offset, &&data[..]), data.len());
871            prop_assert_eq!(rb.head, old_head);
872            prop_assert_eq!(rb.limits().len, old_len);
873            for i in 0..data.len() {
874                let masked = (rb.head + rb.len + offset + i) % rb.storage.len();
875                // Make sure that data are written.
876                prop_assert_eq!(rb.storage[masked], data[i]);
877                rb.storage[masked] = 0;
878            }
879            // And the other parts of the storage are untouched.
880            prop_assert_eq!(&rb.storage, &vec![0; rb.storage.len()]);
881        }
882
883        #[test]
884        fn ring_buffer_read_with((mut rb, expected, consume) in ring_buffer::with_read_data()) {
885            prop_assert_eq!(rb.limits().len, expected.len());
886            let nread = rb.read_with(|readable| {
887                assert!(readable.len() == 1 || readable.len() == 2);
888                let got = readable.concat();
889                assert_eq!(got, expected);
890                consume
891            });
892            prop_assert_eq!(nread, consume);
893            prop_assert_eq!(rb.limits().len, expected.len() - consume);
894        }
895
896        #[test]
897        fn ring_buffer_mark_read((mut rb, readable) in ring_buffer::with_readable()) {
898            const BYTE_TO_WRITE: u8 = 0x42;
899            let written = rb.writable_regions().into_iter().fold(0, |acc, slice| {
900                slice.fill(BYTE_TO_WRITE);
901                acc + slice.len()
902            });
903            let old_storage = rb.storage.clone();
904            let old_head = rb.head;
905            let old_len = rb.limits().len;
906
907            rb.mark_read(readable);
908            let new_writable = rb.writable_regions().into_iter().fold(Vec::new(), |mut acc, slice| {
909                acc.extend_from_slice(slice);
910                acc
911            });
912            for (i, x) in new_writable.iter().enumerate().take(written) {
913                prop_assert_eq!(*x, BYTE_TO_WRITE, "i={}, rb={:?}", i, rb);
914            }
915            prop_assert!(new_writable.len() >= written);
916
917            let RingBuffer { storage, head, len } = rb;
918            prop_assert_eq!(len, old_len - readable);
919            prop_assert_eq!(head, (old_head + readable) % old_storage.len());
920            prop_assert_eq!(storage, old_storage);
921        }
922
923        #[test]
924        fn ring_buffer_peek_with((mut rb, expected, offset) in ring_buffer::with_read_data()) {
925            prop_assert_eq!(rb.limits().len, expected.len());
926            rb.peek_with(offset, |readable| {
927                prop_assert_eq!(readable.to_vec(), &expected[offset..]);
928                Ok(())
929            })?;
930            prop_assert_eq!(rb.limits().len, expected.len());
931        }
932
933        #[test]
934        fn ring_buffer_writable_regions(mut rb in ring_buffer::arb_ring_buffer()) {
935            const BYTE_TO_WRITE: u8 = 0x42;
936            let writable_len = rb.writable_regions().into_iter().fold(0, |acc, slice| {
937                slice.fill(BYTE_TO_WRITE);
938                acc + slice.len()
939            });
940            let BufferLimits {len, capacity} = rb.limits();
941            prop_assert_eq!(writable_len + len, capacity);
942            for i in 0..capacity {
943                let expected = if i < len {
944                    0
945                } else {
946                    BYTE_TO_WRITE
947                };
948                let idx = (rb.head + i) % rb.storage.len();
949                prop_assert_eq!(rb.storage[idx], expected);
950            }
951        }
952    }
953
954    #[test_case([Range { start: 0, end: 0 }]
955        => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(0), generation: 0 })]
956    #[test_case([Range { start: 0, end: 10 }]
957        => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(10), generation: 1 })]
958    #[test_case([Range{ start: 10, end: 15 }, Range { start: 5, end: 10 }]
959        => Assembler {
960            outstanding: [
961                SeqRange::new(SeqNum::new(5)..SeqNum::new(15), 2).unwrap()
962            ].into_iter().collect(),
963            nxt: SeqNum::new(0),
964            generation: 2,
965        })
966    ]
967    #[test_case([Range{ start: 10, end: 15 }, Range { start: 0, end: 5 }, Range { start: 5, end: 10 }]
968        => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(15), generation: 3 })]
969    #[test_case([Range{ start: 10, end: 15 }, Range { start: 5, end: 10 }, Range { start: 0, end: 5 }]
970        => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(15), generation: 3 })]
971    #[test_case([Range{ start: 10, end: 15 }, Range { start: 10, end: 15 }, Range { start: 11, end: 12 }]
972        => Assembler {
973             outstanding: [
974                SeqRange::new(SeqNum::new(10)..SeqNum::new(15), 3).unwrap()
975            ].into_iter().collect(),
976            nxt: SeqNum::new(0), generation: 3 })]
977    fn assembler_examples(ops: impl IntoIterator<Item = Range<u32>>) -> Assembler {
978        let mut assembler = Assembler::new(SeqNum::new(0));
979        for Range { start, end } in ops.into_iter() {
980            let _advanced = assembler.insert(SeqNum::new(start)..SeqNum::new(end));
981        }
982        assembler
983    }
984
985    #[test_case(&[] => Vec::<Range<u32>>::new(); "empty")]
986    #[test_case(&[1..2] => vec![1..2]; "single")]
987    #[test_case(&[1..2, 3..4] => vec![3..4, 1..2]; "latest first")]
988    #[test_case(&[1..2, 3..4, 5..6, 7..8, 9..10]
989        => vec![9..10, 7..8, 5..6, 3..4]; "max len")]
990    #[test_case(&[1..2, 3..4, 5..6, 7..8, 9..10, 6..7]
991        => vec![5..8, 9..10, 3..4, 1..2]; "gap fill")]
992    #[test_case(&[1..2, 3..4, 5..6, 7..8, 9..10, 1..8]
993        => vec![1..8, 9..10]; "large gap fill")]
994    fn assembler_sack_blocks(ops: &[Range<u32>]) -> Vec<Range<u32>> {
995        let mut assembler = Assembler::new(SeqNum::new(0));
996        for Range { start, end } in ops {
997            let _: usize = assembler.insert(SeqNum::new(*start)..SeqNum::new(*end));
998        }
999        assembler
1000            .sack_blocks(SackBlockSizeLimiters { timestamp_enabled: false })
1001            .try_iter()
1002            .map(|r| r.expect("invalid block").into_range_u32())
1003            .collect()
1004    }
1005
1006    #[test_case(false => vec![10..11, 7..8, 4..5, 1..2]; "4_blocks_with_timestamp_disabled")]
1007    #[test_case(true => vec![10..11, 7..8, 4..5]; "3_blocks_with_timestamp_disabled")]
1008    fn assembler_sack_blocks_with_timestamp(timestamp_enabled: bool) -> Vec<Range<u32>> {
1009        let mut assembler = Assembler::new(SeqNum::new(0));
1010        for Range { start, end } in [1..2, 4..5, 7..8, 10..11] {
1011            let _: usize = assembler.insert(SeqNum::new(start)..SeqNum::new(end));
1012        }
1013        assembler
1014            .sack_blocks(SackBlockSizeLimiters { timestamp_enabled })
1015            .try_iter()
1016            .map(|r| r.expect("invalid_block").into_range_u32())
1017            .collect()
1018    }
1019
1020    // Verify that the Assembler correctly limits the outstanding ranges.
1021    #[test]
1022    fn assembler_max_outstanding_ranges() {
1023        const MAX: usize = Assembler::MAX_NUM_OUTSTANDING_RANGES;
1024
1025        // Set up a 10 byte gap between every outstanding range.
1026        const PERIOD: u32 = 20;
1027        const LEN: u32 = 10;
1028        const OFFSET: u32 = 10;
1029        let nth_range = |n| {
1030            SeqNum::new(PERIOD * (n as u32) + OFFSET)
1031                ..SeqNum::new(PERIOD * (n as u32) + OFFSET + LEN)
1032        };
1033
1034        // Insert the maximum number of disjoint ranges into the assembler.
1035        let mut assembler = Assembler::new(SeqNum::new(0));
1036        for n in 0..MAX {
1037            assert_eq!(assembler.insert(nth_range(n)), 0);
1038        }
1039        assert_eq!(assembler.outstanding.len(), MAX);
1040        assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 1).start);
1041
1042        // If the new range is rightmost, it should be dropped.
1043        assert_eq!(assembler.insert(nth_range(MAX)), 0);
1044        assert_eq!(assembler.outstanding.len(), MAX);
1045        assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 1).start);
1046
1047        // If the new range makes data available, it should do so without
1048        // eviction.
1049        assert_eq!(assembler.insert(SeqNum::new(0)..SeqNum::new(1)), 1);
1050        assert_eq!(assembler.outstanding.len(), MAX);
1051        assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 1).start);
1052
1053        // If the new range is in the middle & disjoint from all existing ranges
1054        // it should be inserted and the rightmost range should be evicted.
1055        let middle_disjoint = SeqNum::new(PERIOD + 2)..SeqNum::new(PERIOD + OFFSET - 2);
1056        assert_eq!(assembler.insert(middle_disjoint.clone()), 0);
1057        assert_eq!(assembler.outstanding.len(), MAX);
1058        assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 2).start);
1059        assert!(contains_range(&assembler, middle_disjoint));
1060
1061        // If the new range extends an existing range, it should do so without
1062        // eviction.
1063        let extending_range1 = nth_range(10).end..nth_range(10).end + 1;
1064        assert_eq!(assembler.insert(extending_range1.clone()), 0);
1065        assert_eq!(assembler.outstanding.len(), MAX);
1066        assert!(contains_range(&assembler, nth_range(10).start..extending_range1.end));
1067
1068        // If the new range merges two existing ranges, it should do so without
1069        // eviction.
1070        let extending_range2 = extending_range1.start..nth_range(11).start;
1071        assert_eq!(assembler.insert(extending_range2), 0);
1072        assert_eq!(assembler.outstanding.len(), MAX - 1);
1073        assert!(contains_range(&assembler, nth_range(10).start..nth_range(11).end));
1074    }
1075
1076    #[test]
1077    // Regression test for https://fxbug.dev/42061342.
1078    fn ring_buffer_wrap_around() {
1079        const CAPACITY: usize = 16;
1080        let mut rb = RingBuffer::new(CAPACITY);
1081
1082        // Write more than half the buffer.
1083        const BUF_SIZE: usize = 10;
1084        assert_eq!(rb.enqueue_data(&[0xAA; BUF_SIZE]), BUF_SIZE);
1085        rb.peek_with(0, |payload| {
1086            assert_eq!(payload, FragmentedPayload::new_contiguous(&[0xAA; BUF_SIZE]))
1087        });
1088        rb.mark_read(BUF_SIZE);
1089
1090        // Write around the end of the buffer.
1091        assert_eq!(rb.enqueue_data(&[0xBB; BUF_SIZE]), BUF_SIZE);
1092        rb.peek_with(0, |payload| {
1093            assert_eq!(
1094                payload,
1095                FragmentedPayload::new([
1096                    &[0xBB; (CAPACITY - BUF_SIZE)],
1097                    &[0xBB; (BUF_SIZE * 2 - CAPACITY)]
1098                ])
1099            )
1100        });
1101        // Mark everything read, which should advance `head` around to the
1102        // beginning of the buffer.
1103        rb.mark_read(BUF_SIZE);
1104
1105        // Now make a contiguous sequence of bytes readable.
1106        assert_eq!(rb.enqueue_data(&[0xCC; BUF_SIZE]), BUF_SIZE);
1107        rb.peek_with(0, |payload| {
1108            assert_eq!(payload, FragmentedPayload::new_contiguous(&[0xCC; BUF_SIZE]))
1109        });
1110
1111        // Check that the unwritten bytes are left untouched. If `head` was
1112        // advanced improperly, this will crash.
1113        let read = rb.read_with(|segments| {
1114            assert_eq!(segments, [[0xCC; BUF_SIZE]]);
1115            BUF_SIZE
1116        });
1117        assert_eq!(read, BUF_SIZE);
1118    }
1119
1120    #[test]
1121    fn ring_buffer_example() {
1122        let mut rb = RingBuffer::new(16);
1123        assert_eq!(rb.write_at(5, &"World".as_bytes()), 5);
1124        assert_eq!(rb.write_at(0, &"Hello".as_bytes()), 5);
1125        rb.make_readable(10, false);
1126        assert_eq!(
1127            rb.read_with(|readable| {
1128                assert_eq!(readable, &["HelloWorld".as_bytes()]);
1129                5
1130            }),
1131            5
1132        );
1133        assert_eq!(
1134            rb.read_with(|readable| {
1135                assert_eq!(readable, &["World".as_bytes()]);
1136                readable[0].len()
1137            }),
1138            5
1139        );
1140        assert_eq!(rb.write_at(0, &"HelloWorld".as_bytes()), 10);
1141        rb.make_readable(10, false);
1142        assert_eq!(
1143            rb.read_with(|readable| {
1144                assert_eq!(readable, &["HelloW".as_bytes(), "orld".as_bytes()]);
1145                6
1146            }),
1147            6
1148        );
1149        assert_eq!(rb.limits().len, 4);
1150        assert_eq!(
1151            rb.read_with(|readable| {
1152                assert_eq!(readable, &["orld".as_bytes()]);
1153                4
1154            }),
1155            4
1156        );
1157        assert_eq!(rb.limits().len, 0);
1158
1159        assert_eq!(rb.enqueue_data("Hello".as_bytes()), 5);
1160        assert_eq!(rb.limits().len, 5);
1161
1162        rb.peek_with(3, |readable| {
1163            assert_eq!(readable.to_vec(), "lo".as_bytes());
1164        });
1165
1166        rb.mark_read(2);
1167
1168        rb.peek_with(0, |readable| {
1169            assert_eq!(readable.to_vec(), "llo".as_bytes());
1170        });
1171    }
1172
1173    mod ring_buffer {
1174        use super::*;
1175        // Use a small capacity so that we have a higher chance to exercise
1176        // wrapping around logic.
1177        const MAX_CAP: usize = 32;
1178
1179        fn arb_ring_buffer_args() -> impl Strategy<Value = (usize, usize, usize)> {
1180            // Use a small capacity so that we have a higher chance to exercise
1181            // wrapping around logic.
1182            (1..=MAX_CAP).prop_flat_map(|cap| {
1183                let max_len = cap;
1184                //  cap      head     len
1185                (Just(cap), 0..cap, 0..=max_len)
1186            })
1187        }
1188
1189        pub(super) fn arb_ring_buffer() -> impl Strategy<Value = RingBuffer> {
1190            arb_ring_buffer_args().prop_map(|(cap, head, len)| RingBuffer {
1191                storage: vec![0; cap],
1192                head,
1193                len,
1194            })
1195        }
1196
1197        /// A strategy for a [`RingBuffer`] and a valid length to mark read.
1198        pub(super) fn with_readable() -> impl Strategy<Value = (RingBuffer, usize)> {
1199            arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1200                (Just(RingBuffer { storage: vec![0; cap], head, len }), 0..=len)
1201            })
1202        }
1203
1204        /// A strategy for a [`RingBuffer`] and a valid length to make readable.
1205        pub(super) fn with_written() -> impl Strategy<Value = (RingBuffer, usize)> {
1206            arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1207                let rb = RingBuffer { storage: vec![0; cap], head, len };
1208                let max_written = cap - len;
1209                (Just(rb), 0..=max_written)
1210            })
1211        }
1212
1213        /// A strategy for a [`RingBuffer`], a valid offset and data to write.
1214        pub(super) fn with_offset_data() -> impl Strategy<Value = (RingBuffer, usize, Vec<u8>)> {
1215            arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1216                let writable_len = cap - len;
1217                (0..=writable_len).prop_flat_map(move |offset| {
1218                    (0..=writable_len - offset).prop_flat_map(move |data_len| {
1219                        (
1220                            Just(RingBuffer { storage: vec![0; cap], head, len }),
1221                            Just(offset),
1222                            proptest::collection::vec(1..=u8::MAX, data_len),
1223                        )
1224                    })
1225                })
1226            })
1227        }
1228
1229        /// A strategy for a [`RingBuffer`], its readable data, and how many
1230        /// bytes to consume.
1231        pub(super) fn with_read_data() -> impl Strategy<Value = (RingBuffer, Vec<u8>, usize)> {
1232            arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1233                proptest::collection::vec(1..=u8::MAX, len).prop_flat_map(move |data| {
1234                    // Fill the RingBuffer with the data.
1235                    let mut rb = RingBuffer { storage: vec![0; cap], head, len: 0 };
1236                    assert_eq!(rb.write_at(0, &&data[..]), len);
1237                    rb.make_readable(len, false);
1238                    (Just(rb), Just(data), 0..=len)
1239                })
1240            })
1241        }
1242    }
1243}