xref: /webrtc/stun/src/textattrs.rs (revision 5d8fe953)
1 #[cfg(test)]
2 mod textattrs_test;
3 
4 use crate::attributes::*;
5 use crate::checks::*;
6 use crate::error::*;
7 use crate::message::*;
8 
9 use std::fmt;
10 
11 const MAX_USERNAME_B: usize = 513;
12 const MAX_REALM_B: usize = 763;
13 const MAX_SOFTWARE_B: usize = 763;
14 const MAX_NONCE_B: usize = 763;
15 
16 // Username represents USERNAME attribute.
17 //
18 // RFC 5389 Section 15.3
19 pub type Username = TextAttribute;
20 
21 // Realm represents REALM attribute.
22 //
23 // RFC 5389 Section 15.7
24 pub type Realm = TextAttribute;
25 
26 // Nonce represents NONCE attribute.
27 //
28 // RFC 5389 Section 15.8
29 pub type Nonce = TextAttribute;
30 
31 // Software is SOFTWARE attribute.
32 //
33 // RFC 5389 Section 15.10
34 pub type Software = TextAttribute;
35 
36 // TextAttribute is helper for adding and getting text attributes.
37 #[derive(Clone, Default)]
38 pub struct TextAttribute {
39     pub attr: AttrType,
40     pub text: String,
41 }
42 
43 impl fmt::Display for TextAttribute {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result44     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45         write!(f, "{}", self.text)
46     }
47 }
48 
49 impl Setter for TextAttribute {
50     // add_to_as adds attribute with type t to m, checking maximum length. If max_len
51     // is less than 0, no check is performed.
add_to(&self, m: &mut Message) -> Result<()>52     fn add_to(&self, m: &mut Message) -> Result<()> {
53         let text = self.text.as_bytes();
54         let max_len = match self.attr {
55             ATTR_USERNAME => MAX_USERNAME_B,
56             ATTR_REALM => MAX_REALM_B,
57             ATTR_SOFTWARE => MAX_SOFTWARE_B,
58             ATTR_NONCE => MAX_NONCE_B,
59             _ => return Err(Error::Other(format!("Unsupported AttrType {}", self.attr))),
60         };
61 
62         check_overflow(self.attr, text.len(), max_len)?;
63         m.add(self.attr, text);
64         Ok(())
65     }
66 }
67 
68 impl Getter for TextAttribute {
get_from(&mut self, m: &Message) -> Result<()>69     fn get_from(&mut self, m: &Message) -> Result<()> {
70         let attr = self.attr;
71         *self = TextAttribute::get_from_as(m, attr)?;
72         Ok(())
73     }
74 }
75 
76 impl TextAttribute {
new(attr: AttrType, text: String) -> Self77     pub fn new(attr: AttrType, text: String) -> Self {
78         TextAttribute { attr, text }
79     }
80 
81     // get_from_as gets t attribute from m and appends its value to reseted v.
get_from_as(m: &Message, attr: AttrType) -> Result<Self>82     pub fn get_from_as(m: &Message, attr: AttrType) -> Result<Self> {
83         match attr {
84             ATTR_USERNAME => {}
85             ATTR_REALM => {}
86             ATTR_SOFTWARE => {}
87             ATTR_NONCE => {}
88             _ => return Err(Error::Other(format!("Unsupported AttrType {attr}"))),
89         };
90 
91         let a = m.get(attr)?;
92         let text = String::from_utf8(a)?;
93         Ok(TextAttribute { attr, text })
94     }
95 }
96