Skip to main content

rtc_turn/proto/
channum.rs

1#[cfg(test)]
2mod channnum_test;
3
4use std::fmt;
5
6use stun::attributes::*;
7use stun::checks::*;
8use stun::message::*;
9
10use shared::error::Result;
11
12// 16 bits of uint + 16 bits of RFFU = 0.
13const CHANNEL_NUMBER_SIZE: usize = 4;
14
15// See https://tools.ietf.org/html/rfc5766#section-11:
16//
17// 0x4000 through 0x7FFF: These values are the allowed channel
18// numbers (16,383 possible values).
19/// The lowest channel number a client may bind.
20///
21/// The range is chosen so ChannelData can be told apart from STUN messages on the same port.
22pub const MIN_CHANNEL_NUMBER: u16 = 0x4000;
23/// The highest channel number a client may bind.
24pub const MAX_CHANNEL_NUMBER: u16 = 0x7FFF;
25
26/// `ChannelNumber` represents `CHANNEL-NUMBER` attribute. Encoded as `u16`.
27///
28/// The `CHANNEL-NUMBER` attribute contains the number of the channel.
29///
30/// [RFC 5766 Section 14.1](https://www.rfc-editor.org/rfc/rfc5766#section-14.1).
31#[derive(Default, Eq, PartialEq, Debug, Copy, Clone, Hash)]
32pub struct ChannelNumber(pub u16);
33
34impl fmt::Display for ChannelNumber {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        write!(f, "{}", self.0)
37    }
38}
39
40impl Setter for ChannelNumber {
41    /// Adds `CHANNEL-NUMBER` to message.
42    fn add_to(&self, m: &mut Message) -> Result<()> {
43        let mut v = vec![0; CHANNEL_NUMBER_SIZE];
44        v[..2].copy_from_slice(&self.0.to_be_bytes());
45        // v[2:4] are zeroes (RFFU = 0)
46        m.add(ATTR_CHANNEL_NUMBER, &v);
47        Ok(())
48    }
49}
50
51impl Getter for ChannelNumber {
52    /// Decodes `CHANNEL-NUMBER` from message.
53    fn get_from(&mut self, m: &Message) -> Result<()> {
54        let v = m.get(ATTR_CHANNEL_NUMBER)?;
55
56        check_size(ATTR_CHANNEL_NUMBER, v.len(), CHANNEL_NUMBER_SIZE)?;
57
58        //_ = v[CHANNEL_NUMBER_SIZE-1] // asserting length
59        self.0 = u16::from_be_bytes([v[0], v[1]]);
60        // v[2:4] is RFFU and equals to 0.
61        Ok(())
62    }
63}
64
65impl ChannelNumber {
66    /// Returns true if c in `[0x4000, 0x7FFF]`.
67    fn is_channel_number_valid(&self) -> bool {
68        self.0 >= MIN_CHANNEL_NUMBER && self.0 <= MAX_CHANNEL_NUMBER
69    }
70
71    /// returns `true` if channel number has correct value that complies
72    /// [RFC 5766 Section 11](https://www.rfc-editor.org/rfc/rfc5766#section-11) range.
73    pub fn valid(&self) -> bool {
74        self.is_channel_number_valid()
75    }
76}