stun_rs/attributes/turn/
data.rs

1use crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
2use crate::common::check_buffer_boundaries;
3use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
4use crate::StunError;
5use std::ops::Deref;
6use std::sync::Arc;
7
8pub const DATA: u16 = 0x0013;
9
10/// The `DATA` attribute is present in all Send indications.  If the `ICMP`
11/// attribute is not present in a Data indication, it contains a DATA
12/// attribute.  The value portion of this attribute is variable length
13/// and consists of the application data (that is, the data that would
14/// immediately follow the `UDP` header if the data was sent directly
15/// between the client and the peer).  The application data is equivalent
16/// to the *`UDP` user data* and does not include the *surplus area*
17/// defined in Section 4 of
18/// [`UDP-OPT`](https://datatracker.ietf.org/doc/html/rfc8656#ref-UDP-OPT).
19///
20/// # Examples
21///```rust
22/// # use stun_rs::attributes::turn::Data;
23/// let raw_data = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05];
24/// let attr = Data::new(raw_data);
25/// assert_eq!(raw_data, attr.as_bytes());
26///```
27#[derive(Debug, Default, Clone, PartialEq, Eq)]
28pub struct Data(Arc<Vec<u8>>);
29
30impl Data {
31    /// Creates a new `Data` attribute
32    pub fn new<T>(buffer: T) -> Self
33    where
34        T: AsRef<[u8]>,
35    {
36        Self(Arc::new(buffer.as_ref().to_vec()))
37    }
38
39    /// Gets the data carried by this attribute
40    pub fn as_bytes(&self) -> &[u8] {
41        &self.0
42    }
43}
44
45impl Deref for Data {
46    type Target = [u8];
47
48    fn deref(&self) -> &[u8] {
49        &self.0
50    }
51}
52
53impl AsRef<[u8]> for Data {
54    fn as_ref(&self) -> &[u8] {
55        &self.0
56    }
57}
58
59impl From<&[u8]> for Data {
60    fn from(buff: &[u8]) -> Self {
61        Data::new(buff)
62    }
63}
64
65impl From<Vec<u8>> for Data {
66    fn from(buff: Vec<u8>) -> Self {
67        Self(Arc::new(buff))
68    }
69}
70
71impl DecodeAttributeValue for Data {
72    fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
73        let raw_value = ctx.raw_value();
74        Ok((Self(Arc::new(raw_value.to_vec())), raw_value.len()))
75    }
76}
77
78impl EncodeAttributeValue for Data {
79    fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
80        let size = self.0.len();
81        let raw_value = ctx.raw_value_mut();
82        check_buffer_boundaries(raw_value, size)?;
83        raw_value[..size].clone_from_slice(&self.0);
84        Ok(size)
85    }
86}
87
88impl crate::attributes::AsVerifiable for Data {}
89
90stunt_attribute!(Data, DATA);
91
92#[cfg(test)]
93mod tests {
94    use super::*;
95    use crate::StunAttribute;
96    use crate::StunErrorType;
97
98    #[test]
99    fn test_data() {
100        let buffer = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05];
101        let attr = Data::new(buffer);
102        // Check deref
103        let slice: &[u8] = &attr;
104        assert_eq!(slice, attr.as_bytes());
105
106        let attr_1 = Data::from(slice);
107        let attr_2 = Data::from(slice.to_vec());
108        assert_eq!(attr_1, attr_2);
109    }
110
111    #[test]
112    fn decode_data_value() {
113        let dummy_msg = [];
114
115        let buffer = [
116            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
117        ];
118        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
119
120        let (data, size) = Data::decode(ctx).expect("Can not decode REALM");
121        assert_eq!(size, 12);
122        assert_eq!(data.as_ref(), buffer);
123    }
124
125    #[test]
126    fn encode_data_value() {
127        let dummy_msg: [u8; 0] = [0x0; 0];
128        let mut buffer: [u8; 12] = [0x0; 12];
129
130        let raw_data = [
131            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
132        ];
133        let data = Data::new(raw_data);
134        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
135        let result = data.encode(ctx);
136        assert_eq!(result, Ok(12));
137        assert_eq!(data.as_ref(), raw_data);
138    }
139
140    #[test]
141    fn encode_data_value_error() {
142        let dummy_msg: [u8; 0] = [0x0; 0];
143        let mut buffer: [u8; 11] = [0x0; 11];
144
145        let raw_data = [
146            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
147        ];
148        let data = Data::new(raw_data);
149        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
150        let result = data.encode(ctx);
151
152        assert_eq!(
153            result.expect_err("Error expected"),
154            StunErrorType::SmallBuffer
155        );
156    }
157
158    #[test]
159    fn data_stunt_attribute() {
160        let attr = StunAttribute::Data(Data::new([]));
161        assert!(attr.is_data());
162        assert!(attr.as_data().is_ok());
163        assert!(attr.as_error_code().is_err());
164
165        assert!(attr.attribute_type().is_comprehension_required());
166        assert!(!attr.attribute_type().is_comprehension_optional());
167
168        let dbg_fmt = format!("{:?}", attr);
169        assert_eq!("Data(Data([]))", dbg_fmt);
170    }
171}