s2n_quic_core/xdp/
bpf.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use s2n_codec::{DecoderBufferMut as Inner, DecoderError, DecoderValue, DecoderValueMut};
5
6/// A BPF-aware version of [`s2n_codec::DecoderBufferMut`]
7///
8/// The Linux BPF verifier requires that every pointer be checked against the `end` pointer. This
9/// means that it struggles with regular Rust slices that use `ptr + len` instead of `ptr + end`.
10pub struct DecoderBufferMut<'a> {
11    buffer: Inner<'a>,
12    end: *mut u8,
13}
14
15impl<'a> DecoderBufferMut<'a> {
16    /// Creates a new DecoderBufferMut.
17    ///
18    /// # Safety
19    ///
20    /// The `start` and `end` pointers must be a valid range of bytes, ideally directly coming
21    /// from the BPF/XDP context argument.
22    #[inline]
23    pub unsafe fn new(start: *mut u8, end: *mut u8) -> Self {
24        let len = end as usize - start as usize;
25        let data = core::slice::from_raw_parts_mut(start, len);
26        let buffer = Inner::new(data);
27        Self { buffer, end }
28    }
29
30    /// Validates that the starting pointer is still within the bounds of the end pointer
31    #[inline]
32    fn new_checked(buffer: Inner<'a>, end: *mut u8) -> Result<Self, DecoderError> {
33        // The Linux BPF verifier needs to prove that no pointers go beyond the "end" pointer
34        if buffer.as_less_safe_slice().as_ptr() > end {
35            return Err(DecoderError::UnexpectedEof(0));
36        }
37
38        Ok(Self { buffer, end })
39    }
40
41    /// Decodes a T from the buffer, if possible
42    #[inline]
43    pub fn decode<T: DecoderValueMut<'a>>(self) -> Result<(T, Self), DecoderError> {
44        let end = self.end;
45        let (v, buffer) = self.buffer.decode()?;
46        let buffer = Self::new_checked(buffer, end)?;
47        Ok((v, buffer))
48    }
49
50    /// Decodes a slice of bytes with the given len, if possible
51    #[inline]
52    pub fn decode_slice(self, len: usize) -> Result<(Self, Self), DecoderError> {
53        let end = self.end;
54        let (slice, buffer) = self.buffer.decode_slice(len)?;
55        let slice = Self::new_checked(slice, end)?;
56        let buffer = Self::new_checked(buffer, end)?;
57        Ok((slice, buffer))
58    }
59
60    #[inline]
61    pub fn into_less_safe_slice(self) -> &'a mut [u8] {
62        self.buffer.into_less_safe_slice()
63    }
64
65    #[inline]
66    pub fn len(&self) -> usize {
67        self.buffer.len()
68    }
69
70    #[inline]
71    pub fn is_empty(&self) -> bool {
72        self.buffer.is_empty()
73    }
74}
75
76/// A generic interface over a decoder buffer
77pub trait Decoder<'a>: Sized {
78    fn decode<T: DecoderValue<'a> + DecoderValueMut<'a>>(
79        self,
80    ) -> core::result::Result<(T, Self), DecoderError>;
81    fn decode_slice(self, len: usize) -> core::result::Result<(Self, Self), DecoderError>;
82}
83
84impl<'a> Decoder<'a> for DecoderBufferMut<'a> {
85    #[inline]
86    fn decode<T: DecoderValue<'a> + DecoderValueMut<'a>>(
87        self,
88    ) -> core::result::Result<(T, Self), DecoderError> {
89        Self::decode(self)
90    }
91
92    #[inline]
93    fn decode_slice(self, len: usize) -> core::result::Result<(Self, Self), DecoderError> {
94        Self::decode_slice(self, len)
95    }
96}
97
98impl<'a> Decoder<'a> for s2n_codec::DecoderBuffer<'a> {
99    #[inline]
100    fn decode<T: DecoderValue<'a> + DecoderValueMut<'a>>(
101        self,
102    ) -> core::result::Result<(T, Self), DecoderError> {
103        Self::decode(self)
104    }
105
106    #[inline]
107    fn decode_slice(self, len: usize) -> core::result::Result<(Self, Self), DecoderError> {
108        Self::decode_slice(self, len)
109    }
110}
111
112impl<'a> Decoder<'a> for s2n_codec::DecoderBufferMut<'a> {
113    #[inline]
114    fn decode<T: DecoderValue<'a> + DecoderValueMut<'a>>(
115        self,
116    ) -> core::result::Result<(T, Self), DecoderError> {
117        Self::decode(self)
118    }
119
120    #[inline]
121    fn decode_slice(self, len: usize) -> core::result::Result<(Self, Self), DecoderError> {
122        Self::decode_slice(self, len)
123    }
124}