stun_rs/
raw.rs

1use crate::common::{check_buffer_boundaries, padding};
2use crate::error::{StunError, StunErrorType};
3use crate::types::{MAGIC_COOKIE_SIZE, TRANSACTION_ID_SIZE};
4use crate::{Decode, MAGIC_COOKIE};
5use byteorder::{BigEndian, ByteOrder};
6use fallible_iterator::{FallibleIterator, IntoFallibleIterator};
7use std::convert::{TryFrom, TryInto};
8
9// Stun message format
10//       0                   1                   2                   3
11//       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
12//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
13//      |0 0|     STUN Message Type     |         Message Length        |
14//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
15//      |                         Magic Cookie                          |
16//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17//      |                                                               |
18//      |                     Transaction ID (96 bits)                  |
19//      |                                                               |
20//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21
22/// STUN message header size
23pub const MESSAGE_HEADER_SIZE: usize = 20;
24pub const ATTRIBUTE_HEADER_SIZE: usize = 4;
25
26/// The STUN message header
27#[derive(Debug)]
28pub struct MessageHeader<'a> {
29    /// The value of the most significant 2 bits
30    pub bits: u8,
31    /// Message type
32    pub msg_type: u16,
33    /// Message length
34    pub msg_length: u16,
35    /// Magic cookie
36    pub cookie: &'a [u8; MAGIC_COOKIE_SIZE],
37    /// Transaction Id
38    pub transaction_id: &'a [u8; TRANSACTION_ID_SIZE],
39}
40
41impl<'a> TryFrom<&'a [u8; MESSAGE_HEADER_SIZE]> for MessageHeader<'a> {
42    type Error = StunError;
43    fn try_from(buff: &'a [u8; MESSAGE_HEADER_SIZE]) -> Result<Self, Self::Error> {
44        let (attr, _) = MessageHeader::decode(buff)?;
45        Ok(attr)
46    }
47}
48
49impl PartialEq for MessageHeader<'_> {
50    fn eq(&self, other: &Self) -> bool {
51        self.msg_type == other.msg_type
52            && self.msg_length == other.msg_length
53            && self.cookie == other.cookie
54            && self.transaction_id == other.transaction_id
55    }
56}
57
58impl Eq for MessageHeader<'_> {}
59
60impl<'a> Decode<'a> for MessageHeader<'a> {
61    fn decode(buffer: &'a [u8]) -> Result<(Self, usize), StunError> {
62        check_buffer_boundaries(buffer, MESSAGE_HEADER_SIZE)?;
63
64        let msg_type = BigEndian::read_u16(&buffer[..2]);
65        let bits: u8 = (msg_type >> 14).try_into()?;
66
67        if bits != 0 {
68            // First two bits in the header are not 0
69            return Err(StunError::new(
70                StunErrorType::InvalidParam,
71                format!("Invalid STUN header bits: {:#02x}", bits),
72            ));
73        }
74
75        let msg_type = msg_type & 0x3FFF;
76        let msg_length = BigEndian::read_u16(&buffer[2..4]);
77
78        let cookie = <&[u8; MAGIC_COOKIE_SIZE]>::try_from(&buffer[4..8])?;
79
80        if cookie != MAGIC_COOKIE {
81            // Cookie in the header is not the STUN magic cookie.
82            return Err(StunError::new(
83                StunErrorType::InvalidParam,
84                format!("Invalid STUN cookie: {:?}", cookie),
85            ));
86        }
87
88        let transaction_id = <&[u8; TRANSACTION_ID_SIZE]>::try_from(&buffer[8..20])?;
89
90        Ok((
91            Self {
92                bits,
93                msg_type,
94                msg_length,
95                cookie,
96                transaction_id,
97            },
98            MESSAGE_HEADER_SIZE,
99        ))
100    }
101}
102
103#[derive(Debug)]
104pub struct RawMessage<'a> {
105    /// Message header
106    pub header: MessageHeader<'a>,
107    /// Attributes
108    pub attributes: &'a [u8],
109}
110
111impl PartialEq for RawMessage<'_> {
112    fn eq(&self, other: &Self) -> bool {
113        if self.header != other.header {
114            return false;
115        }
116
117        // Check raw attributes discarding padding
118        let attrs_1 = RawAttributes::from(self.attributes).into_fallible_iter();
119        let attrs_2 = RawAttributes::from(other.attributes).into_fallible_iter();
120
121        attrs_1
122            .into_fallible_iter()
123            .eq(attrs_2.into_fallible_iter())
124            .unwrap_or(false)
125    }
126}
127
128impl Eq for RawMessage<'_> {}
129
130impl<'a> Decode<'a> for RawMessage<'a> {
131    fn decode(buffer: &'a [u8]) -> Result<(Self, usize), StunError> {
132        let (header, _) = MessageHeader::decode(buffer)?;
133
134        let value_size: usize = MESSAGE_HEADER_SIZE + header.msg_length as usize;
135        check_buffer_boundaries(buffer, value_size)?;
136        let attributes = &buffer[MESSAGE_HEADER_SIZE..value_size];
137
138        Ok((Self { header, attributes }, value_size))
139    }
140}
141
142// Format of STUN Attributes:
143//      0                   1                   2                   3
144//      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
145//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
146//     |         Type                  |            Length             |
147//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
148//     |                         Value (variable)                ....
149//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
150#[derive(Debug, PartialEq, Eq)]
151pub struct RawAttribute<'a> {
152    /// Attribute type
153    pub attr_type: u16,
154    /// Attribute value of size equal to Length
155    pub value: &'a [u8],
156}
157
158impl<'a> Decode<'a> for RawAttribute<'a> {
159    fn decode(buffer: &'a [u8]) -> Result<(Self, usize), StunError> {
160        check_buffer_boundaries(buffer, 4)?;
161        let attr_type = BigEndian::read_u16(&buffer[..2]);
162        let attr_length = BigEndian::read_u16(&buffer[2..4]);
163
164        // required buffer size for value:
165        // 2 Bytes (Type) + 2 Bytes (Length) + Length value
166        let value_size: usize = 4 + attr_length as usize;
167
168        check_buffer_boundaries(buffer, value_size)?;
169
170        let value = &buffer[4..value_size];
171
172        Ok((Self { attr_type, value }, value_size))
173    }
174}
175
176#[derive(Debug, PartialEq, Eq)]
177pub struct RawAttributes<'a>(&'a [u8]);
178
179impl<'a> From<&'a [u8]> for RawAttributes<'a> {
180    fn from(buff: &'a [u8]) -> Self {
181        RawAttributes(buff)
182    }
183}
184
185#[derive(Debug, PartialEq, Eq)]
186pub struct RawAttributesIter<'a> {
187    buffer: &'a [u8],
188    pos: usize,
189}
190
191impl RawAttributesIter<'_> {
192    pub fn pos(&self) -> usize {
193        self.pos
194    }
195}
196impl<'a> FallibleIterator for RawAttributesIter<'a> {
197    type Item = RawAttribute<'a>;
198    type Error = StunError;
199
200    fn next(&mut self) -> Result<Option<Self::Item>, Self::Error> {
201        if self.pos == self.buffer.len() {
202            return Ok(None);
203        }
204
205        let (attr, value_size) = RawAttribute::decode(&self.buffer[self.pos..])?;
206        let size = value_size + padding(value_size);
207        self.pos += size;
208
209        (self.pos <= self.buffer.len())
210            .then_some(Some(attr))
211            .ok_or_else(|| {
212                StunError::new(
213                    StunErrorType::SmallBuffer,
214                    format!(
215                        "Next position ({}) > buffer size: {}",
216                        self.pos,
217                        self.buffer.len()
218                    ),
219                )
220            })
221    }
222}
223
224impl<'a> IntoFallibleIterator for RawAttributes<'a> {
225    type Item = RawAttribute<'a>;
226    type Error = StunError;
227    type IntoFallibleIter = RawAttributesIter<'a>;
228
229    fn into_fallible_iter(self) -> Self::IntoFallibleIter {
230        RawAttributesIter {
231            buffer: self.0,
232            pos: 0,
233        }
234    }
235}
236
237pub(crate) fn get_input_text(buffer: &[u8], attr_type: u16) -> Result<Vec<u8>, StunError> {
238    let (raw_msg, _) = RawMessage::decode(buffer)?;
239
240    // Parse raw attributes
241    let attributes = RawAttributes::from(raw_msg.attributes);
242    let mut iter = attributes.into_fallible_iter();
243    let mut pos = 0;
244    let mut len = None;
245
246    while let Some(raw_attr) = iter.next()? {
247        if attr_type == raw_attr.attr_type {
248            len = Some(iter.pos);
249            break;
250        } else {
251            pos = iter.pos;
252        }
253    }
254
255    let len: usize = len.ok_or_else(|| {
256        StunError::new(
257            StunErrorType::InvalidParam,
258            format!("Attribute type '{:#02x}' not found", attr_type),
259        )
260    })?;
261    let index = pos + MESSAGE_HEADER_SIZE;
262    check_buffer_boundaries(buffer, index)?;
263    let mut out = buffer[..index].to_vec();
264
265    BigEndian::write_u16(&mut out[2..4], len.try_into()?);
266
267    Ok(out)
268}
269
270#[cfg(test)]
271mod tests {
272    use super::*;
273    use crate::MAGIC_COOKIE;
274
275    #[test]
276    fn message_header() {
277        let header = [
278            0x80, 0x01, 0x00, 0x58, // Request type and message length
279            0x21, 0x12, 0xa4, 0x42, // Magic cookie
280            0xb7, 0xe7, 0xa7, 0x01, // }
281            0xbc, 0x34, 0xd6, 0x86, // }  Transaction ID
282            0xfa, 0x87, 0xdf, 0xae, // }
283        ];
284        // Heder bits are not 00
285        let error = MessageHeader::try_from(&header).expect_err("Error expected");
286        assert_eq!(error, StunErrorType::InvalidParam);
287
288        let header = [
289            0x80, 0x01, 0x00, 0x58, // Request type and message length
290            0x21, 0x12, 0xa4, 0x42, // Magic cookie
291            0xff, 0xff, 0xff, 0xff, // }
292            0xff, 0xff, 0xff, 0xff, // }  Transaction ID
293            0xff, 0xff, 0xff, 0xff, // }
294        ];
295        // Invalid MACIG COOKIE
296        let error = MessageHeader::try_from(&header).expect_err("Error expected");
297        assert_eq!(error, StunErrorType::InvalidParam);
298
299        let header = [
300            0x00, 0x01, 0x00, 0x58, // Request type and message length
301            0x21, 0x12, 0xa4, 0x42, // Magic cookie
302            0xb7, 0xe7, 0xa7, 0x01, // }
303            0xbc, 0x34, 0xd6, 0x86, // }  Transaction ID
304            0xfa, 0x87, 0xdf, 0xae, // }
305        ];
306        let header = MessageHeader::try_from(&header).expect("Can not get STUN header");
307        assert_eq!(header.bits, 0x00);
308        assert_eq!(header.msg_type, 0x01);
309        assert_eq!(header.msg_length, 0x58);
310        assert!(MAGIC_COOKIE.eq(header.cookie));
311        assert_eq!(
312            header.transaction_id,
313            &[0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae]
314        );
315    }
316
317    #[test]
318    fn test_decode_message() {
319        let buffer = [
320            0x03, 0x00, 0x00, 0x00, // Request type and message length (16 bytes)
321            0x21, 0x12, 0xA4, 0x42, // Magic cookie
322            0x01, 0x02, 0x03, 0x04, // }
323            0x05, 0x06, 0x07, 0x08, // } Transaction ID
324            0x09, 0x0A, 0x0B, 0x0C, // }
325        ];
326
327        let (_, size) = RawMessage::decode(&buffer).expect("Can not decode Stun Message");
328        assert_eq!(size, buffer.len());
329
330        let buffer = [
331            0x03, 0x00, 0x00, 0x10, // Request type and message length (16 bytes)
332            0x21, 0x12, 0xA4, 0x42, // Magic cookie
333            0x01, 0x02, 0x03, 0x04, // }
334            0x05, 0x06, 0x07, 0x08, // } Transaction ID
335            0x09, 0x0A, 0x0B, 0x0C, // }
336            0x00, 0x14, 0x00, 0x0B, // REALM attribute header
337            0x65, 0x78, 0x61, 0x6D, // }
338            0x70, 0x6c, 0x65, 0x2e, // }  Realm value (11 bytes) and padding (1 byte)
339            0x6f, 0x72, 0x67, 0x00, // }
340        ];
341
342        let (_, size) = RawMessage::decode(&buffer).expect("Can not decode Stun Message");
343        assert_eq!(size, buffer.len());
344    }
345
346    #[test]
347    fn test_decode_message_error() {
348        // Empty buffer
349        let buffer = [];
350        let result = RawMessage::decode(&buffer);
351        assert_eq!(
352            result.expect_err("Error expected"),
353            StunErrorType::SmallBuffer
354        );
355
356        // Stun header < 20 bytes
357        let buffer = [
358            0x03, 0x00, 0x00, 0x00, // Request type and message length (16 bytes)
359            0x21, 0x12, 0xA4, 0x42, // Magic cookie
360            0x01, 0x02, 0x03, 0x04, // }
361            0x05, 0x06, 0x07, 0x08, // } Transaction ID
362            0x09, 0x0A, 0x0B, // }
363        ];
364        let result = RawMessage::decode(&buffer);
365        assert_eq!(
366            result.expect_err("Error expected"),
367            StunErrorType::SmallBuffer
368        );
369
370        // Stun header = 20 bytes, Empty attributes but Length = 1
371        let buffer = [
372            0x03, 0x00, 0x00, 0x01, // Request type and message length (16 bytes)
373            0x21, 0x12, 0xA4, 0x42, // Magic cookie
374            0x01, 0x02, 0x03, 0x04, // }
375            0x05, 0x06, 0x07, 0x08, // } Transaction ID
376            0x09, 0x0A, 0x0B, 0x0C, // }
377        ];
378        let result = RawMessage::decode(&buffer);
379        assert_eq!(
380            result.expect_err("Error expected"),
381            StunErrorType::SmallBuffer
382        );
383    }
384
385    #[test]
386    fn decode() {
387        let buffer = [0x00, 0x01, 0x00, 0x00];
388        let (attr, size) = RawAttribute::decode(&buffer).expect("Can not decode attribute");
389        assert_eq!(size, 4);
390        assert_eq!(attr.attr_type, 1);
391        assert_eq!(attr.value.len(), 0);
392
393        let buffer = [0x00, 0x02, 0x00, 0x01, 0xff];
394        let (attr, size) = RawAttribute::decode(&buffer).expect("Can not decode attribute");
395        assert_eq!(size, 5);
396        assert_eq!(attr.attr_type, 2);
397        assert_eq!(attr.value.len(), 1);
398        assert_eq!(attr.value[0], 0xff);
399
400        let buffer = [
401            0x00, 0x01, 0x00, 0x14, 0x00, 0x02, 0x11, 0xfc, 25u8, 24u8, 23u8, 22u8, 21u8, 20u8,
402            19u8, 18u8, 17u8, 16u8, 15u8, 14u8, 13u8, 12u8, 11u8, 10u8,
403        ];
404        let value = [
405            0x00, 0x02, 0x11, 0xfc, 25u8, 24u8, 23u8, 22u8, 21u8, 20u8, 19u8, 18u8, 17u8, 16u8,
406            15u8, 14u8, 13u8, 12u8, 11u8, 10u8,
407        ];
408
409        let (attr, size) = RawAttribute::decode(&buffer).expect("Can not decode attribute");
410        assert_eq!(size, 24);
411        assert_eq!(attr.attr_type, 1);
412        assert_eq!(attr.value.len(), 20);
413        assert!(attr.value[..] == value[..]);
414    }
415
416    #[test]
417    fn decode_error() {
418        let buffer = [];
419        let result = RawAttribute::decode(&buffer);
420        assert_eq!(
421            result.expect_err("Error expected"),
422            StunErrorType::SmallBuffer
423        );
424
425        let buffer = [0x00, 0x01, 0x00, 0x01];
426        let result = RawAttribute::decode(&buffer);
427        assert_eq!(
428            result.expect_err("Error expected"),
429            StunErrorType::SmallBuffer
430        );
431
432        let buffer = [0x00, 0x01, 0x00, 0x02, 0x00];
433        let result = RawAttribute::decode(&buffer);
434        assert_eq!(
435            result.expect_err("Error expected"),
436            StunErrorType::SmallBuffer
437        );
438    }
439
440    #[test]
441    fn test_decode_raw_attributes() {
442        // Empty buffer
443        let buffer = [];
444        let raw_attr = RawAttributes::from(&buffer[..]);
445        // check debug is implemented
446        let _val = format!("{:?}", raw_attr);
447
448        let mut iter = raw_attr.into_fallible_iter();
449        // check debug is implemented
450        let _val = format!("{:?}", iter);
451
452        assert_eq!(iter.next(), Ok(None));
453
454        let buffer = [
455            0x00, 0x1e, 0x00, 0x20, // `USERHASH` attribute header
456            0x4A, 0x3C, 0xF3, 0x8F, // }
457            0xEF, 0x69, 0x92, 0xBD, // }
458            0xA9, 0x52, 0xC6, 0x78, // }
459            0x04, 0x17, 0xDA, 0x0F, // }  `Userhash` value (32 bytes)
460            0x24, 0x81, 0x94, 0x15, // }
461            0x56, 0x9E, 0x60, 0xB2, // }
462            0x05, 0xC4, 0x6E, 0x41, // }
463            0x40, 0x7F, 0x17, 0x04, // }
464            0x00, 0x15, 0x00, 0x29, // NONCE attribute header
465            0x6F, 0x62, 0x4D, 0x61, // }
466            0x74, 0x4A, 0x6F, 0x73, // }
467            0x32, 0x41, 0x41, 0x41, // }
468            0x43, 0x66, 0x2F, 0x2F, // }
469            0x34, 0x39, 0x39, 0x6B, // }  Nonce value and padding (3 bytes)
470            0x39, 0x35, 0x34, 0x64, // }
471            0x36, 0x4F, 0x4C, 0x33, // }
472            0x34, 0x6F, 0x4C, 0x39, // }
473            0x46, 0x53, 0x54, 0x76, // }
474            0x79, 0x36, 0x34, 0x73, // }
475            0x41, 0x00, 0x00, 0x00, // }
476            0x00, 0x14, 0x00, 0x0B, // REALM attribute header
477            0x65, 0x78, 0x61, 0x6D, // }
478            0x70, 0x6C, 0x65, 0x2E, // }  Realm value (11 bytes) and padding (1 byte)
479            0x6F, 0x72, 0x67, 0x00, // }
480            0x00, 0x1C, 0x00, 0x20, // MESSAGE-INTEGRITY-SHA256 attribute header
481            0xE4, 0x68, 0x6C, 0x8F, // }
482            0x0E, 0xDE, 0xB5, 0x90, // }
483            0x13, 0xE0, 0x70, 0x90, // }
484            0x01, 0x0A, 0x93, 0xEF, // }  HMAC-SHA256 value
485            0xCC, 0xBC, 0xCC, 0x54, // }
486            0x4C, 0x0A, 0x45, 0xD9, // }
487            0xF8, 0x30, 0xAA, 0x6D, // }
488            0x6F, 0x73, 0x5A, 0x01, // }
489        ];
490        let raw_attr = RawAttributes::from(&buffer[..]);
491        let mut iter = raw_attr.into_fallible_iter();
492
493        // Consume `UserHash`
494        let attr = iter
495            .next()
496            .expect("Unexpected error decoding raw attribute")
497            .expect("Expected UserHash attribute");
498        // Iterator must point to the next attribute
499        assert_eq!(iter.pos, 36);
500        assert_eq!(attr.value.len(), 32);
501
502        // Consume Nonce
503        let attr = iter
504            .next()
505            .expect("Unexpected error decoding raw attribute")
506            .expect("Expected Nonce attribute");
507        // Iterator must point to the next attribute
508        assert_eq!(iter.pos, 84);
509        assert_eq!(attr.value.len(), 41);
510
511        // Consume Realm
512        let attr = iter
513            .next()
514            .expect("Unexpected error decoding raw attribute")
515            .expect("Expected Realm attribute");
516        // Iterator must point to the next attribute
517        assert_eq!(iter.pos, 100);
518        assert_eq!(attr.value.len(), 11);
519
520        // Consume `MessageIntegrity`
521        let attr = iter
522            .next()
523            .expect("Unexpected error decoding raw attribute")
524            .expect("Expected MessageIntegrity attribute");
525        // Iterator must point to the next attribute
526        assert_eq!(iter.pos, 136);
527        assert_eq!(attr.value.len(), 32);
528
529        // No more attributes
530        assert_eq!(iter.next(), Ok(None));
531    }
532
533    #[test]
534    fn test_decode_raw_attributes_error() {
535        // Empty buffer
536        let buffer = [];
537        let raw_attr = RawAttributes::from(&buffer[..]);
538        let mut iter = raw_attr.into_fallible_iter();
539        assert_eq!(iter.next(), Ok(None));
540
541        let buffer = [0x00, 0x1e, 0x00, 0x20, 0x4A, 0x3C, 0xF3, 0x8F];
542        let raw_attr = RawAttributes::from(&buffer[..]);
543        let mut iter = raw_attr.into_fallible_iter();
544
545        assert_eq!(
546            iter.next().expect_err("Error expected"),
547            StunErrorType::SmallBuffer
548        );
549
550        let buffer = [
551            0x00, 0x1e, 0x00, 0x20, // `USERHASH` attribute header
552            0x4A, 0x3C, 0xF3, 0x8F, // }
553            0xEF, 0x69, 0x92, 0xBD, // }
554            0xA9, 0x52, 0xC6, 0x78, // }
555            0x04, 0x17, 0xDA, 0x0F, // }  `Userhash` value (32 bytes)
556            0x24, 0x81, 0x94, 0x15, // }
557            0x56, 0x9E, 0x60, 0xB2, // }
558            0x05, 0xC4, 0x6E, 0x41, // }
559            0x40, 0x7F, 0x17, 0x04, // }
560            0x00, 0x15, 0x00, 0x29, // NONCE attribute header
561            0x6F, 0x62, 0x4D, 0x61, // }
562            0x74, 0x4A, 0x6F, 0x73, // }
563            0x32, 0x41, 0x41, 0x41, // }
564            0x43, 0x66, 0x2F, 0x2F, // }
565            0x34, 0x39, 0x39, 0x6B, // }  Nonce value and padding (Miss 3 padding bytes)
566            0x39, 0x35, 0x34, 0x64, // }
567            0x36, 0x4F, 0x4C, 0x33, // }
568            0x34, 0x6F, 0x4C, 0x39, // }
569            0x46, 0x53, 0x54, 0x76, // }
570            0x79, 0x36, 0x34, 0x73, // }
571            0x41, // }
572        ];
573        let raw_attr = RawAttributes::from(&buffer[..]);
574        let mut iter = raw_attr.into_fallible_iter();
575
576        // Consume `UserHash`
577        iter.next()
578            .expect("Unexpected error decoding raw attribute")
579            .expect("Expected UserHash attribute");
580
581        // NONCE value misses last 3 bytes
582        assert_eq!(
583            iter.next().expect_err("Error expected"),
584            StunErrorType::SmallBuffer
585        );
586    }
587
588    #[test]
589    fn test_input_text() {
590        // Try with a attribute type that does not exist in the buffer
591        assert_eq!(
592            get_input_text(&stun_vectors::SAMPLE_IPV4_RESPONSE, 0x15).expect_err("Error expected"),
593            StunErrorType::InvalidParam
594        );
595        assert_eq!(
596            get_input_text(&stun_vectors::SAMPLE_IPV4_RESPONSE, 0x0b).expect_err("Error expected"),
597            StunErrorType::InvalidParam
598        );
599
600        let input = get_input_text(&stun_vectors::SAMPLE_IPV4_RESPONSE, 0x8022).unwrap();
601        assert_eq!(input.len(), 20);
602        assert_eq!(input[..4], [0x01, 0x01, 0x00, 0x10]);
603        assert_eq!(input[4..], stun_vectors::SAMPLE_IPV4_RESPONSE[4..20]);
604
605        let input = get_input_text(&stun_vectors::SAMPLE_IPV4_RESPONSE, 0x0020).unwrap();
606        assert_eq!(input.len(), 36);
607        assert_eq!(input[..4], [0x01, 0x01, 0x00, 0x1c]);
608        assert_eq!(input[4..], stun_vectors::SAMPLE_IPV4_RESPONSE[4..36]);
609
610        let input = get_input_text(&stun_vectors::SAMPLE_IPV4_RESPONSE, 0x0008).unwrap();
611        assert_eq!(input.len(), 48);
612        assert_eq!(input[..4], [0x01, 0x01, 0x00, 0x34]);
613        assert_eq!(input[4..], stun_vectors::SAMPLE_IPV4_RESPONSE[4..48]);
614
615        let input = get_input_text(&stun_vectors::SAMPLE_IPV4_RESPONSE, 0x8028).unwrap();
616        assert_eq!(input.len(), 72);
617        assert_eq!(input[..4], [0x01, 0x01, 0x00, 0x3c]);
618        assert_eq!(input[4..], stun_vectors::SAMPLE_IPV4_RESPONSE[4..72]);
619    }
620
621    #[test]
622    fn test_message_header() {
623        let (header, size) = MessageHeader::decode(&stun_vectors::SAMPLE_REQUEST)
624            .expect("Can not parse STUN header");
625        assert_eq!(size, MESSAGE_HEADER_SIZE);
626        assert_eq!(header.msg_type, 0x01);
627        assert_eq!(header.msg_length, 0x058);
628        assert_eq!(header.cookie, &[0x21, 0x12, 0xa4, 0x42]);
629        assert_eq!(
630            header.transaction_id,
631            &[0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae]
632        );
633
634        let _val = format!("{:?}", header);
635
636        let (header2, _size) = MessageHeader::decode(&stun_vectors::SAMPLE_REQUEST)
637            .expect("Can not parse STUN header");
638        assert_eq!(header, header2);
639
640        let (header3, size) = MessageHeader::decode(&stun_vectors::SAMPLE_REQUEST_LONG_TERM_AUTH)
641            .expect("Can not parse STUN header");
642        assert_eq!(size, MESSAGE_HEADER_SIZE);
643        assert_ne!(header3, header2);
644    }
645
646    #[test]
647    fn test_raw_messager() {
648        let (raw_msg1, size) =
649            RawMessage::decode(&stun_vectors::SAMPLE_REQUEST).expect("Can not parse STUN message");
650        assert_eq!(size, stun_vectors::SAMPLE_REQUEST.len());
651
652        let _val = format!("{:?}", raw_msg1);
653
654        let (raw_msg2, size) = RawMessage::decode(&stun_vectors::SAMPLE_REQUEST_LONG_TERM_AUTH)
655            .expect("Can not parse STUN message");
656        assert_eq!(size, stun_vectors::SAMPLE_REQUEST_LONG_TERM_AUTH.len());
657
658        assert_ne!(raw_msg1, raw_msg2);
659
660        let (raw_msg3, size) =
661            RawMessage::decode(&stun_vectors::SAMPLE_REQUEST).expect("Can not parse STUN message");
662        assert_eq!(size, stun_vectors::SAMPLE_REQUEST.len());
663
664        assert_eq!(raw_msg1, raw_msg3);
665
666        let mut buffer: [u8; 108] = [0x00; 108];
667        buffer.copy_from_slice(&stun_vectors::SAMPLE_REQUEST);
668        // Change padding values
669        buffer[73] = 0xa1;
670        buffer[74] = 0xff;
671        buffer[75] = 0xed;
672        let (raw_msg4, size) = RawMessage::decode(&buffer).expect("Can not parse STUN message");
673        assert_eq!(size, buffer.len());
674
675        // Padding are not taking into account for comparision
676        assert_eq!(raw_msg1, raw_msg4);
677    }
678}