rtc_stun/
textattrs.rs

1#[cfg(test)]
2mod textattrs_test;
3
4use crate::attributes::*;
5use crate::checks::*;
6use crate::message::*;
7use shared::error::*;
8
9use std::fmt;
10
11const MAX_USERNAME_B: usize = 513;
12const MAX_REALM_B: usize = 763;
13const MAX_SOFTWARE_B: usize = 763;
14const MAX_NONCE_B: usize = 763;
15
16// Username represents USERNAME attribute.
17//
18// RFC 5389 Section 15.3
19pub type Username = TextAttribute;
20
21// Realm represents REALM attribute.
22//
23// RFC 5389 Section 15.7
24pub type Realm = TextAttribute;
25
26// Nonce represents NONCE attribute.
27//
28// RFC 5389 Section 15.8
29pub type Nonce = TextAttribute;
30
31// Software is SOFTWARE attribute.
32//
33// RFC 5389 Section 15.10
34pub type Software = TextAttribute;
35
36// TextAttribute is helper for adding and getting text attributes.
37#[derive(Clone, Default)]
38pub struct TextAttribute {
39    pub attr: AttrType,
40    pub text: String,
41}
42
43impl fmt::Display for TextAttribute {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        write!(f, "{}", self.text)
46    }
47}
48
49impl 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.
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
68impl Getter for TextAttribute {
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
76impl TextAttribute {
77    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.
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}