ytls_extensions/
rec_size_limit.rs

1//! yTLS Extension (28) Record Size Limit Handling
2
3use crate::TlsExtError;
4
5/// Downstream Record Size Limit Processor
6pub trait ExtRecSizeLimitProcessor {
7    // Set the record size limit
8    fn record_size_limit(&mut self, _: u16) -> ();
9}
10
11/// TLS Server Name Indication (SNI) handling
12pub struct TlsExtRecSizeLim {}
13
14impl TlsExtRecSizeLim {
15    /// Check with the provided Processor whether
16    /// any of the Client Hello provided SNIs matches
17    #[inline]
18    pub fn client_rec_size_limit_cb<P: ExtRecSizeLimitProcessor>(
19        p: &mut P,
20        limit_raw: &[u8],
21    ) -> Result<(), TlsExtError> {
22        if limit_raw.len() < 2 {
23            return Err(TlsExtError::InvalidLength);
24        }
25        let rec_size_limit = u16::from_be_bytes([limit_raw[0], limit_raw[1]]);
26
27        p.record_size_limit(rec_size_limit);
28
29        Ok(())
30    }
31}
32
33#[cfg(test)]
34mod test {
35    use super::*;
36    use hex_literal::hex;
37    use rstest::rstest;
38
39    #[derive(Debug, Default, PartialEq)]
40    struct Tester {
41        seen: Vec<u16>,
42    }
43
44    impl ExtRecSizeLimitProcessor for Tester {
45        fn record_size_limit(&mut self, lim: u16) -> () {
46            self.seen.push(lim);
47        }
48    }
49
50    #[rstest]
51    #[case(
52        "4001",
53        Tester { seen: vec![16385] },
54        Ok(())
55    )]
56    #[case(
57        "40",
58        Tester { seen: vec![] },
59        Err(TlsExtError::InvalidLength)
60    )]
61    fn client_record_size_limit(
62        #[case] raw_t: &str,
63        #[case] expected_tester: Tester,
64        #[case] expected_res: Result<(), TlsExtError>,
65    ) {
66        let in_raw = hex::decode(raw_t).unwrap();
67        let mut tester = Tester::default();
68        let res = TlsExtRecSizeLim::client_rec_size_limit_cb(&mut tester, &in_raw);
69        assert_eq!(expected_tester, tester);
70        assert_eq!(expected_res, res);
71    }
72}