Skip to main content

rtc_turn/proto/
chandata.rs

1#[cfg(test)]
2mod chandata_test;
3
4use super::channum::*;
5use shared::error::{Error, Result};
6
7const PADDING: usize = 4;
8
9fn nearest_padded_value_length(l: usize) -> usize {
10    let mut n = PADDING * (l / PADDING);
11    if n < l {
12        n += PADDING;
13    }
14    n
15}
16
17const CHANNEL_DATA_LENGTH_SIZE: usize = 2;
18const CHANNEL_DATA_NUMBER_SIZE: usize = CHANNEL_DATA_LENGTH_SIZE;
19const CHANNEL_DATA_HEADER_SIZE: usize = CHANNEL_DATA_LENGTH_SIZE + CHANNEL_DATA_NUMBER_SIZE;
20
21/// `ChannelData` represents the `ChannelData` Message defined in
22/// [RFC 5766 Section 11.4](https://www.rfc-editor.org/rfc/rfc5766#section-11.4).
23#[derive(Default, Debug)]
24pub struct ChannelData {
25    /// The relayed payload. May be a subslice of [`Self::raw`].
26    pub data: Vec<u8>, // can be subslice of Raw
27    /// The channel this data belongs to, which identifies the peer.
28    pub number: ChannelNumber,
29    /// The full encoded message, header included.
30    pub raw: Vec<u8>,
31}
32
33impl PartialEq for ChannelData {
34    fn eq(&self, other: &Self) -> bool {
35        self.data == other.data && self.number == other.number
36    }
37}
38
39impl ChannelData {
40    /// Resets length, [`Self::data`] and [`Self::raw`] length.
41    #[inline]
42    pub fn reset(&mut self) {
43        self.raw.clear();
44        self.data.clear();
45    }
46
47    /// Encodes this to [`Self::raw`].
48    pub fn encode(&mut self) {
49        self.raw.clear();
50        self.write_header();
51        self.raw.extend_from_slice(&self.data);
52        let padded = nearest_padded_value_length(self.raw.len());
53        let bytes_to_add = padded - self.raw.len();
54        if bytes_to_add > 0 {
55            self.raw.extend_from_slice(&vec![0; bytes_to_add]);
56        }
57    }
58
59    /// Decodes this from [`Self::raw`].
60    pub fn decode(&mut self) -> Result<()> {
61        let buf = &self.raw;
62        if buf.len() < CHANNEL_DATA_HEADER_SIZE {
63            return Err(Error::ErrUnexpectedEof);
64        }
65        let num = u16::from_be_bytes([buf[0], buf[1]]);
66        self.number = ChannelNumber(num);
67        if !self.number.valid() {
68            return Err(Error::ErrInvalidChannelNumber);
69        }
70        let l = u16::from_be_bytes([
71            buf[CHANNEL_DATA_NUMBER_SIZE],
72            buf[CHANNEL_DATA_NUMBER_SIZE + 1],
73        ]) as usize;
74        if l > buf[CHANNEL_DATA_HEADER_SIZE..].len() {
75            return Err(Error::ErrBadChannelDataLength);
76        }
77        self.data = buf[CHANNEL_DATA_HEADER_SIZE..CHANNEL_DATA_HEADER_SIZE + l].to_vec();
78
79        Ok(())
80    }
81
82    /// Writes channel number and length.
83    pub fn write_header(&mut self) {
84        if self.raw.len() < CHANNEL_DATA_HEADER_SIZE {
85            // Making WriteHeader call valid even when c.Raw
86            // is nil or len(c.Raw) is less than needed for header.
87            self.raw
88                .resize(self.raw.len() + CHANNEL_DATA_HEADER_SIZE, 0);
89        }
90        self.raw[..CHANNEL_DATA_NUMBER_SIZE].copy_from_slice(&self.number.0.to_be_bytes());
91        self.raw[CHANNEL_DATA_NUMBER_SIZE..CHANNEL_DATA_HEADER_SIZE]
92            .copy_from_slice(&(self.data.len() as u16).to_be_bytes());
93    }
94
95    /// Returns `true` if `buf` looks like the `ChannelData` Message.
96    pub fn is_channel_data(buf: &[u8]) -> bool {
97        if buf.len() < CHANNEL_DATA_HEADER_SIZE {
98            return false;
99        }
100
101        if u16::from_be_bytes([
102            buf[CHANNEL_DATA_NUMBER_SIZE],
103            buf[CHANNEL_DATA_NUMBER_SIZE + 1],
104        ]) > buf[CHANNEL_DATA_HEADER_SIZE..].len() as u16
105        {
106            return false;
107        }
108
109        // Quick check for channel number.
110        let num = ChannelNumber(u16::from_be_bytes([buf[0], buf[1]]));
111        num.valid()
112    }
113}