webrtc_turn/proto/
evenport.rs

1#[cfg(test)]
2mod evenport_test;
3
4use stun::attributes::*;
5use stun::checks::*;
6use stun::message::*;
7
8use util::Error;
9
10use std::fmt;
11
12// EvenPort represents EVEN-PORT attribute.
13//
14// This attribute allows the client to request that the port in the
15// relayed transport address be even, and (optionally) that the server
16// reserve the next-higher port number.
17//
18// RFC 5766 Section 14.6
19#[derive(Default, Debug, PartialEq)]
20pub struct EvenPort {
21    // reserve_port means that the server is requested to reserve
22    // the next-higher port number (on the same IP address)
23    // for a subsequent allocation.
24    reserve_port: bool,
25}
26
27impl fmt::Display for EvenPort {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        if self.reserve_port {
30            write!(f, "reserve: true")
31        } else {
32            write!(f, "reserve: false")
33        }
34    }
35}
36
37const EVEN_PORT_SIZE: usize = 1;
38const FIRST_BIT_SET: u8 = 0b10000000; //FIXME? (1 << 8) - 1;
39
40impl Setter for EvenPort {
41    // AddTo adds EVEN-PORT to message.
42    fn add_to(&self, m: &mut Message) -> Result<(), Error> {
43        let mut v = vec![0; EVEN_PORT_SIZE];
44        if self.reserve_port {
45            // Set first bit to 1.
46            v[0] = FIRST_BIT_SET;
47        }
48        m.add(ATTR_EVEN_PORT, &v);
49        Ok(())
50    }
51}
52
53impl Getter for EvenPort {
54    // GetFrom decodes EVEN-PORT from message.
55    fn get_from(&mut self, m: &Message) -> Result<(), Error> {
56        let v = m.get(ATTR_EVEN_PORT)?;
57
58        check_size(ATTR_EVEN_PORT, v.len(), EVEN_PORT_SIZE)?;
59
60        if v[0] & FIRST_BIT_SET > 0 {
61            self.reserve_port = true;
62        }
63        Ok(())
64    }
65}