stun_rs/attributes/turn/
requested_transport.rs1use crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
2use crate::common::check_buffer_boundaries;
3use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
4use crate::protocols::{ProtocolNumber, UDP};
5use crate::{Decode, Encode, StunError};
6
7const REQUESTED_TRANSPORT: u16 = 0x0019;
8const REQUESTED_TRANSPORT_SIZE: usize = 4;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct RequestedTrasport(ProtocolNumber);
28
29impl RequestedTrasport {
30 pub fn new(protocol: ProtocolNumber) -> Self {
39 Self(protocol)
40 }
41
42 pub fn protocol(&self) -> ProtocolNumber {
44 self.0
45 }
46}
47
48impl From<ProtocolNumber> for RequestedTrasport {
49 fn from(value: ProtocolNumber) -> Self {
50 RequestedTrasport(value)
51 }
52}
53
54impl Default for RequestedTrasport {
55 fn default() -> Self {
56 RequestedTrasport(UDP)
57 }
58}
59
60impl DecodeAttributeValue for RequestedTrasport {
61 fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
62 let raw_value = ctx.raw_value();
63 check_buffer_boundaries(raw_value, REQUESTED_TRANSPORT_SIZE)?;
64 Ok((
65 Self(ProtocolNumber::decode(raw_value)?.0),
66 REQUESTED_TRANSPORT_SIZE,
67 ))
68 }
69}
70
71impl EncodeAttributeValue for RequestedTrasport {
72 fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
73 let raw_value = ctx.raw_value_mut();
74 check_buffer_boundaries(raw_value, REQUESTED_TRANSPORT_SIZE)?;
75 let size = self.0.encode(raw_value)?;
76 debug_assert!(
77 size == 1,
78 "Unexpected size of type `ProtocolNumber`, {} != 1",
79 size
80 );
81 raw_value[size..REQUESTED_TRANSPORT_SIZE].fill(0x0);
83 Ok(REQUESTED_TRANSPORT_SIZE)
84 }
85}
86
87impl crate::attributes::AsVerifiable for RequestedTrasport {}
88
89stunt_attribute!(RequestedTrasport, REQUESTED_TRANSPORT);
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94 use crate::error::StunErrorType;
95 use crate::protocols;
96 use crate::StunAttribute;
97
98 #[test]
99 fn decode_requested_transport_constructor() {
100 let attr = RequestedTrasport::new(protocols::UDP);
101 assert_eq!(attr.protocol(), protocols::UDP);
102
103 let attr = RequestedTrasport::from(protocols::UDP);
104 assert_eq!(attr.protocol(), protocols::UDP);
105 }
106
107 #[test]
108 fn decode_requested_transport_value() {
109 let dummy_msg = [];
110 let buffer = [];
111 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
112 let result = RequestedTrasport::decode(ctx);
113 assert_eq!(
114 result.expect_err("Error expected"),
115 StunErrorType::SmallBuffer
116 );
117
118 let buffer = [0x11, 0x00, 0x00];
119 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
120 let result = RequestedTrasport::decode(ctx);
121 assert_eq!(
122 result.expect_err("Error expected"),
123 StunErrorType::SmallBuffer
124 );
125
126 let buffer = [0x11, 0x00, 0x00, 0x00];
127 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
128 let (attr, size) =
129 RequestedTrasport::decode(ctx).expect("Can not decode RequestedTrasport");
130 assert_eq!(size, 4);
131 assert_eq!(attr.protocol(), protocols::UDP);
132
133 let buffer = [0x06, 0x01, 0x02, 0x03];
135 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
136 let (attr, size) =
137 RequestedTrasport::decode(ctx).expect("Can not decode RequestedTrasport");
138 assert_eq!(size, 4);
139 assert_eq!(attr.protocol().as_u8(), 6);
140 }
141
142 #[test]
143 fn encode_requested_transport_value() {
144 let attr = RequestedTrasport::default();
145 let dummy_msg = [];
146
147 let mut buffer = [];
148 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
149 let result = attr.encode(ctx);
150 assert_eq!(
151 result.expect_err("Error expected"),
152 StunErrorType::SmallBuffer
153 );
154
155 let mut buffer: [u8; 3] = [0xFF; 3];
156 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
157 let result = attr.encode(ctx);
158 assert_eq!(
159 result.expect_err("Error expected"),
160 StunErrorType::SmallBuffer
161 );
162
163 let mut buffer: [u8; 4] = [0xFF; 4];
164 let attr = RequestedTrasport::new(protocols::UDP);
165 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
166 let result = attr.encode(ctx);
167 assert_eq!(result, Ok(4));
168 let expected_buffer = [0x11, 0x00, 0x00, 0x00];
169 assert_eq!(&buffer[..], &expected_buffer[..]);
170 }
171
172 #[test]
173 fn requested_transport_stunt_attribute() {
174 let attr = StunAttribute::RequestedTrasport(RequestedTrasport::from(protocols::UDP));
175 assert!(attr.is_requested_trasport());
176 assert!(attr.as_requested_trasport().is_ok());
177 assert!(attr.as_unknown().is_err());
178
179 assert!(attr.attribute_type().is_comprehension_required());
180 assert!(!attr.attribute_type().is_comprehension_optional());
181
182 let dbg_fmt = format!("{:?}", attr);
183 assert_eq!(
184 "RequestedTrasport(RequestedTrasport(ProtocolNumber(17)))",
185 dbg_fmt
186 );
187 }
188}