1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use stringprep::saslprep;
pub use super::errors::{IntegrityKeyGenerationError, MessageDecodeError, MessageEncodeError};
use crate::definitions::StunTransactionId;
use crate::header::StunHeader;
use crate::header::{StunMessageClass, StunMessageMethod};
use crate::StunAttribute;
use super::message::StunMessage;
impl StunMessage {
pub fn new(method: StunMessageMethod, class: StunMessageClass) -> Self {
let header = StunHeader::new(method, class, None);
Self {
header,
attributes: Vec::new(),
}
}
pub fn create_request() -> Self {
Self::default().set_message_class(StunMessageClass::Request)
}
pub fn create_success_response() -> Self {
Self::default().set_message_class(StunMessageClass::SuccessResponse)
}
pub fn create_error_response() -> Self {
Self::default().set_message_class(StunMessageClass::ErrorResponse)
}
pub fn create_indication() -> Self {
Self::default().set_message_class(StunMessageClass::Indication)
}
pub fn set_transaction_id(mut self, transaction_id: StunTransactionId) -> Self {
self.header.transaction_id = transaction_id;
self
}
pub fn set_message_class(mut self, class: StunMessageClass) -> Self {
self.header.message_class = class;
self
}
pub fn set_message_method(mut self, method: StunMessageMethod) -> Self {
self.header.message_method = method;
self
}
pub fn get_header(&self) -> &StunHeader {
&self.header
}
pub fn get_attributes(&self) -> &Vec<StunAttribute> {
&self.attributes
}
pub fn add_attribute(mut self, attr: StunAttribute) -> Self {
self.attributes.push(attr);
self
}
pub fn add_fingerprint(mut self) -> Self {
self.attributes
.push(StunAttribute::Fingerprint { value: 0 });
self
}
pub fn add_message_integrity(mut self) -> Self {
self.attributes
.push(StunAttribute::MessageIntegrity { key: Vec::new() });
self
}
pub fn add_long_term_credential_message_integrity(
mut self,
username: &str,
realm: &str,
) -> Result<Self, stringprep::Error> {
self.attributes.push(StunAttribute::Username {
value: saslprep(username)?.to_string(),
});
self.attributes.push(StunAttribute::Realm {
value: saslprep(realm)?.to_string(),
});
Ok(self.add_message_integrity())
}
}
impl std::default::Default for StunMessage {
fn default() -> Self {
Self::new(StunMessageMethod::BindingRequest, StunMessageClass::Request)
}
}