stun_rs/attributes/turn/
reservation_token.rs

1use crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
2use crate::common::check_buffer_boundaries;
3use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
4use crate::StunError;
5use std::convert::TryFrom;
6
7const RESERVATION_TOKEN: u16 = 0x0022;
8const RESERVATION_TOKEN_SIZE: usize = 8;
9
10/// The `ReservationToken` attribute contains a token that uniquely
11/// identifies a relayed transport address being held in reserve by the
12/// server.  The server includes this attribute in a success response to
13/// tell the client about the token, and the client includes this
14/// attribute in a subsequent Allocate request to request the server use
15/// that relayed transport address for the allocation.
16/// # Examples
17///```rust
18/// # use stun_rs::attributes::turn::ReservationToken;
19/// let token = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
20/// let attr = ReservationToken::from(token);
21/// assert_eq!(token, attr.token());
22///```
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct ReservationToken([u8; RESERVATION_TOKEN_SIZE]);
25
26impl ReservationToken {
27    /// Returns the reservation token.
28    pub fn token(&self) -> &[u8] {
29        &self.0
30    }
31}
32
33impl AsRef<[u8]> for ReservationToken {
34    fn as_ref(&self) -> &[u8] {
35        &self.0[..]
36    }
37}
38
39impl From<&[u8; RESERVATION_TOKEN_SIZE]> for ReservationToken {
40    fn from(buff: &[u8; RESERVATION_TOKEN_SIZE]) -> Self {
41        Self(*buff)
42    }
43}
44
45impl From<[u8; RESERVATION_TOKEN_SIZE]> for ReservationToken {
46    fn from(buff: [u8; RESERVATION_TOKEN_SIZE]) -> Self {
47        Self(buff)
48    }
49}
50
51impl DecodeAttributeValue for ReservationToken {
52    fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
53        let raw_value = ctx.raw_value();
54        check_buffer_boundaries(raw_value, RESERVATION_TOKEN_SIZE)?;
55        let token =
56            <&[u8; RESERVATION_TOKEN_SIZE]>::try_from(&raw_value[..RESERVATION_TOKEN_SIZE])?;
57        Ok((ReservationToken::from(token), RESERVATION_TOKEN_SIZE))
58    }
59}
60
61impl EncodeAttributeValue for ReservationToken {
62    fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
63        let raw_value = ctx.raw_value_mut();
64        check_buffer_boundaries(raw_value, RESERVATION_TOKEN_SIZE)?;
65        raw_value[..RESERVATION_TOKEN_SIZE].clone_from_slice(&self.0);
66        Ok(RESERVATION_TOKEN_SIZE)
67    }
68}
69
70impl crate::attributes::AsVerifiable for ReservationToken {}
71
72stunt_attribute!(ReservationToken, RESERVATION_TOKEN);
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use crate::error::StunErrorType;
78    use crate::StunAttribute;
79
80    #[test]
81    fn constructor() {
82        let token = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
83        let attr = ReservationToken::from(token);
84        assert_eq!(attr.as_ref(), token);
85    }
86
87    #[test]
88    fn decode_reservation_token_constructor() {
89        let token = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
90        let attr = ReservationToken::from(token);
91        assert_eq!(token, attr.token());
92    }
93
94    #[test]
95    fn decode_reservation_token_value() {
96        let dummy_msg = [];
97        let buffer = [];
98        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
99        let result = ReservationToken::decode(ctx);
100        assert_eq!(
101            result.expect_err("Error expected"),
102            StunErrorType::SmallBuffer
103        );
104
105        let buffer = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
106        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
107        let result = ReservationToken::decode(ctx);
108        assert_eq!(
109            result.expect_err("Error expected"),
110            StunErrorType::SmallBuffer
111        );
112
113        let buffer = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
114        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
115        let (attr, size) = ReservationToken::decode(ctx).expect("Can not decode ReservationToken");
116        assert_eq!(size, 8);
117        assert_eq!(attr.token(), buffer);
118    }
119
120    #[test]
121    fn encode_reservation_token_value() {
122        let token = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
123        let attr = ReservationToken::from(token);
124        let dummy_msg = [];
125
126        let mut buffer = [];
127        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
128        let result = attr.encode(ctx);
129        assert_eq!(
130            result.expect_err("Error expected"),
131            StunErrorType::SmallBuffer
132        );
133
134        let mut buffer: [u8; 7] = [0xFF; 7];
135        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
136        let result = attr.encode(ctx);
137        assert_eq!(
138            result.expect_err("Error expected"),
139            StunErrorType::SmallBuffer
140        );
141
142        let mut buffer: [u8; 8] = [0xFF; 8];
143        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
144        let result = attr.encode(ctx);
145        assert_eq!(result, Ok(8));
146        assert_eq!(buffer, token);
147    }
148
149    #[test]
150    fn reservatiom_token_stunt_attribute() {
151        let token = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
152        let attr = StunAttribute::ReservationToken(ReservationToken::from(token));
153        assert!(attr.is_reservation_token());
154        assert!(attr.as_reservation_token().is_ok());
155        assert!(attr.as_unknown().is_err());
156
157        assert!(attr.attribute_type().is_comprehension_required());
158        assert!(!attr.attribute_type().is_comprehension_optional());
159
160        let dbg_fmt = format!("{:?}", attr);
161        assert_eq!(
162            "ReservationToken(ReservationToken([1, 2, 3, 4, 5, 6, 7, 8]))",
163            dbg_fmt
164        );
165    }
166}