stun_rs/attributes/stun/
software.rs

1const SOFTWARE: u16 = 0x8022;
2const MAX_ENCODED_SIZE: usize = 509;
3const MAX_DECODED_SIZE: usize = 763;
4
5crate::common::string_attribute!(
6    /// The [`Software`] attribute contains a textual description of the software
7    /// being used by the agent sending the message.  It is used by clients
8    /// and servers.  Its value SHOULD include manufacturer and version
9    /// number.  The attribute has no impact on operation of the protocol and
10    /// serves only as a tool for diagnostic and debugging purposes.
11    ///
12    /// # Examples
13    ///```rust
14    /// # use std::error::Error;
15    /// # use stun_rs::attributes::stun::Software;
16    /// #
17    /// # fn main() -> Result<(), Box<dyn Error>> {
18    /// let attr = Software::new("STUN test client")?;
19    /// assert_eq!(attr, "STUN test client");
20    /// #
21    /// #  Ok(())
22    /// # }
23    ///```
24    Software,
25    SOFTWARE,
26    MAX_ENCODED_SIZE,
27    MAX_DECODED_SIZE,
28);
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33    use crate::attributes::{
34        AttributeDecoderContext, AttributeEncoderContext, DecodeAttributeValue,
35        EncodeAttributeValue,
36    };
37    use crate::{StunAttribute, StunErrorType};
38    use std::convert::TryFrom;
39
40    #[test]
41    fn constructor() {
42        let name = String::from("Test Software v1.0");
43        let attr_1 = Software::try_from(&name).expect("Can not create Software attribute");
44        let attr_2 = Software::new(&name).expect("Can not create Software attribute");
45        let attr_3 = Software::try_from(name.as_str()).expect("Can not create Software attribute");
46        let attr_4 = Software::try_from(name.clone()).expect("Can not create Software attribute");
47
48        assert_eq!(attr_1, name);
49        assert_eq!(name, attr_1);
50        assert_eq!(name, attr_3);
51        assert_eq!(name, attr_4);
52        assert_eq!(attr_1, "Test Software v1.0");
53        assert_eq!("Test Software v1.0", attr_1);
54        assert_eq!(attr_1, attr_2);
55
56        let value: &String = attr_1.as_ref();
57        assert!(name.eq(value));
58
59        let value: &str = attr_1.as_ref();
60        assert!(name.eq(value));
61
62        let value = "x".repeat(MAX_ENCODED_SIZE);
63        let _result = Software::new(value.as_str()).expect("Can not create a Sofware attribute");
64
65        let value = "x".repeat(MAX_ENCODED_SIZE + 1);
66        let result = Software::new(value);
67        assert_eq!(
68            result.expect_err("Error expected"),
69            StunErrorType::ValueTooLong
70        );
71    }
72
73    #[test]
74    fn decode_software_value() {
75        let dummy_msg = [];
76        // Software: example.org
77        let value = "example";
78        let ctx = AttributeDecoderContext::new(None, &dummy_msg, value.as_bytes());
79
80        let (software, size) = Software::decode(ctx).expect("Can not decode Software");
81        assert_eq!(size, 7);
82        assert_eq!(software.as_str(), "example");
83
84        let value = "x".repeat(MAX_DECODED_SIZE);
85        let ctx = AttributeDecoderContext::new(None, &dummy_msg, value.as_bytes());
86        let (_nonce, size) = Software::decode(ctx).expect("Can not decode Software");
87        assert_eq!(size, MAX_DECODED_SIZE);
88
89        let value = "x".repeat(MAX_DECODED_SIZE + 1);
90        let ctx = AttributeDecoderContext::new(None, &dummy_msg, value.as_bytes());
91        assert_eq!(
92            Software::decode(ctx).expect_err("Error expected"),
93            StunErrorType::ValueTooLong
94        );
95    }
96
97    #[test]
98    fn encode_software_value() {
99        let dummy_msg: [u8; 0] = [0x0; 0];
100        let software =
101            Software::try_from("test software").expect("Can not create a Sofware attribute");
102
103        let mut buffer: [u8; 13] = [0x0; 13];
104        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
105        let result = software.encode(ctx);
106        assert_eq!(result, Ok(13));
107
108        let mut buffer: [u8; MAX_ENCODED_SIZE] = [0x0; MAX_ENCODED_SIZE];
109        let software = Software::try_from("x".repeat(MAX_ENCODED_SIZE))
110            .expect("Can not create a Sofware attribute");
111        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
112        let result = software.encode(ctx);
113        assert_eq!(result, Ok(MAX_ENCODED_SIZE));
114
115        let mut buffer: [u8; 12] = [0x0; 12];
116        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
117        let result = software.encode(ctx);
118        assert_eq!(
119            result.expect_err("Error expected"),
120            StunErrorType::SmallBuffer
121        );
122
123        let mut buffer: [u8; MAX_ENCODED_SIZE + 1] = [0x0; MAX_ENCODED_SIZE + 1];
124        let software = Software("x".repeat(MAX_ENCODED_SIZE + 1));
125        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
126        let result = software.encode(ctx);
127        assert_eq!(
128            result.expect_err("Error expected"),
129            StunErrorType::ValueTooLong
130        );
131    }
132
133    #[test]
134    fn software_stunt_attribute() {
135        let attr = StunAttribute::Software(
136            Software::new("test").expect("Can not create Software attribute"),
137        );
138        assert!(attr.is_software());
139        assert!(attr.as_software().is_ok());
140        assert!(attr.as_unknown().is_err());
141
142        assert!(!attr.attribute_type().is_comprehension_required());
143        assert!(attr.attribute_type().is_comprehension_optional());
144
145        let dbg_fmt = format!("{:?}", attr);
146        assert_eq!("Software(Software(\"test\"))", dbg_fmt);
147    }
148}