xref: /webrtc/turn/src/proto/channum.rs (revision ffe74184)
1 #[cfg(test)]
2 mod channnum_test;
3 
4 use std::fmt;
5 use stun::attributes::*;
6 use stun::checks::*;
7 use stun::message::*;
8 
9 // 16 bits of uint + 16 bits of RFFU = 0.
10 const CHANNEL_NUMBER_SIZE: usize = 4;
11 
12 // See https://tools.ietf.org/html/rfc5766#section-11:
13 //
14 // 0x4000 through 0x7FFF: These values are the allowed channel
15 // numbers (16,383 possible values).
16 pub const MIN_CHANNEL_NUMBER: u16 = 0x4000;
17 pub const MAX_CHANNEL_NUMBER: u16 = 0x7FFF;
18 
19 // ChannelNumber represents CHANNEL-NUMBER attribute.
20 //
21 // The CHANNEL-NUMBER attribute contains the number of the channel.
22 //
23 // RFC 5766 Section 14.1
24 // encoded as uint16
25 #[derive(Default, Eq, PartialEq, Debug, Copy, Clone, Hash)]
26 pub struct ChannelNumber(pub u16);
27 
28 impl fmt::Display for ChannelNumber {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result29     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30         write!(f, "{}", self.0)
31     }
32 }
33 
34 impl Setter for ChannelNumber {
35     // AddTo adds CHANNEL-NUMBER to message.
add_to(&self, m: &mut Message) -> Result<(), stun::Error>36     fn add_to(&self, m: &mut Message) -> Result<(), stun::Error> {
37         let mut v = vec![0; CHANNEL_NUMBER_SIZE];
38         v[..2].copy_from_slice(&self.0.to_be_bytes());
39         // v[2:4] are zeroes (RFFU = 0)
40         m.add(ATTR_CHANNEL_NUMBER, &v);
41         Ok(())
42     }
43 }
44 
45 impl Getter for ChannelNumber {
46     // GetFrom decodes CHANNEL-NUMBER from message.
get_from(&mut self, m: &Message) -> Result<(), stun::Error>47     fn get_from(&mut self, m: &Message) -> Result<(), stun::Error> {
48         let v = m.get(ATTR_CHANNEL_NUMBER)?;
49 
50         check_size(ATTR_CHANNEL_NUMBER, v.len(), CHANNEL_NUMBER_SIZE)?;
51 
52         //_ = v[CHANNEL_NUMBER_SIZE-1] // asserting length
53         self.0 = u16::from_be_bytes([v[0], v[1]]);
54         // v[2:4] is RFFU and equals to 0.
55         Ok(())
56     }
57 }
58 
59 impl ChannelNumber {
60     // is_channel_number_valid returns true if c in [0x4000, 0x7FFF].
is_channel_number_valid(&self) -> bool61     fn is_channel_number_valid(&self) -> bool {
62         self.0 >= MIN_CHANNEL_NUMBER && self.0 <= MAX_CHANNEL_NUMBER
63     }
64 
65     // Valid returns true if channel number has correct value that complies RFC 5766 Section 11 range.
valid(&self) -> bool66     pub fn valid(&self) -> bool {
67         self.is_channel_number_valid()
68     }
69 }
70