stun_coder/attribute/attribute.rs
1use std::net::SocketAddr;
2
3/// [STUN message attribute](https://tools.ietf.org/html/rfc5389#section-15)
4///
5/// After the STUN header are zero or more attributes. Each attribute
6/// MUST be TLV encoded, with a 16-bit type, 16-bit length, and value.
7/// Each STUN attribute MUST end on a 32-bit boundary. As mentioned
8/// above, all fields in an attribute are transmitted most significant
9/// bit first.
10/// The value in the length field MUST contain the length of the Value
11/// part of the attribute, prior to padding, measured in bytes. Since
12/// STUN aligns attributes on 32-bit boundaries, attributes whose content
13/// is not a multiple of 4 bytes are padded with 1, 2, or 3 bytes of
14/// padding so that its value contains a multiple of 4 bytes. The
15/// padding bits are ignored, and may be any value.
16///
17/// Any attribute type MAY appear more than once in a STUN message.
18/// Unless specified otherwise, the order of appearance is significant:
19/// only the first occurrence needs to be processed by a receiver, and
20/// any duplicates MAY be ignored by a receiver.
21///
22/// To allow future revisions of this specification to add new attributes
23/// if needed, the attribute space is divided into two ranges.
24/// Attributes with type values between 0x0000 and 0x7FFF are
25/// comprehension-required attributes, which means that the STUN agent
26/// cannot successfully process the message unless it understands the
27/// attribute. Attributes with type values between 0x8000 and 0xFFFF are
28/// comprehension-optional attributes, which means that those attributes
29/// can be ignored by the STUN agent if it does not understand them.
30///
31/// The set of STUN attribute types is maintained by IANA. The initial
32/// set defined by this specification is found in [Section 18.2](https://tools.ietf.org/html/rfc5389#section-18.2).
33///
34/// The rest of this section describes the format of the various
35/// attributes defined in this specification.
36
37#[derive(Debug, Clone)]
38pub enum StunAttribute {
39 /// [RFC5389: MAPPED-ADDRESS](https://tools.ietf.org/html/rfc5389#section-15.1)
40 ///
41 /// The MAPPED-ADDRESS attribute indicates a reflexive transport address
42 /// of the client. It consists of an 8-bit address family and a 16-bit
43 /// port, followed by a fixed-length value representing the IP address.
44 /// If the address family is IPv4, the address MUST be 32 bits. If the
45 /// address family is IPv6, the address MUST be 128 bits. All fields
46 /// must be in network byte order.
47 ///
48 /// This attribute is used only by servers for achieving backwards
49 /// compatibility with [RFC3489](https://tools.ietf.org/html/rfc3489) clients.
50 MappedAddress {
51 /// Reflexive transport address of the client.
52 socket_addr: SocketAddr,
53 },
54 /// [RFC5389: XOR-MAPPED-ADDRESS](https://tools.ietf.org/html/rfc5389#section-15.2)
55 ///
56 /// The XOR-MAPPED-ADDRESS attribute is identical to the MAPPED-ADDRESS
57 /// attribute, except that the reflexive transport address is obfuscated
58 /// through the XOR function.
59 ///
60 /// Note: XOR-MAPPED-ADDRESS and MAPPED-ADDRESS differ only in their
61 /// encoding of the transport address. The former encodes the transport
62 /// address by exclusive-or'ing it with the magic cookie. The latter
63 /// encodes it directly in binary. [RFC 3489](https://tools.ietf.org/html/rfc3489) originally specified only
64 /// MAPPED-ADDRESS. However, deployment experience found that some NATs
65 /// rewrite the 32-bit binary payloads containing the NAT's public IP
66 /// address, such as STUN's MAPPED-ADDRESS attribute, in the well-meaning
67 /// but misguided attempt at providing a generic ALG function. Such
68 /// behavior interferes with the operation of STUN and also causes
69 /// failure of STUN's message-integrity checking.
70 XorMappedAddress {
71 /// Reflexive transport address of the client.
72 socket_addr: SocketAddr,
73 },
74 /// [RFC5389: USERNAME](https://tools.ietf.org/html/rfc5389#section-15.3)
75 ///
76 /// The USERNAME attribute is used for message integrity. It identifies
77 /// the username and password combination used in the message-integrity
78 /// check.
79 ///
80 /// The value of USERNAME is a variable-length value. It MUST contain a
81 /// UTF-8 [RFC3629](https://tools.ietf.org/html/rfc3629) encoded sequence of less than 513 bytes, and MUST
82 /// have been processed using SASLprep [RFC4013](https://tools.ietf.org/html/rfc4013).
83 Username {
84 /// The username and password combination used in the message-integrity check.
85 value: String,
86 },
87 /// [RFC5389: MESSAGE-INTEGRITY](https://tools.ietf.org/html/rfc5389#section-15.4)
88 ///
89 /// The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104](https://datatracker.ietf.org/doc/html/rfc2104) of
90 /// the STUN message. The MESSAGE-INTEGRITY attribute can be present in
91 /// any STUN message type. Since it uses the SHA1 hash, the HMAC will be
92 /// 20 bytes. The text used as input to HMAC is the STUN message,
93 /// including the header, up to and including the attribute preceding the
94 /// MESSAGE-INTEGRITY attribute. With the exception of the FINGERPRINT
95 /// attribute, which appears after MESSAGE-INTEGRITY, agents MUST ignore
96 /// all other attributes that follow MESSAGE-INTEGRITY.
97 ///
98 /// The key for the HMAC depends on whether long-term or short-term
99 /// credentials are in use. For long-term credentials, the key is 16
100 /// bytes:
101 ///```text
102 /// key = MD5(username ":" realm ":" SASLprep(password))
103 ///```
104 /// That is, the 16-byte key is formed by taking the MD5 hash of the
105 /// result of concatenating the following five fields: (1) the username,
106 /// with any quotes and trailing nulls removed, as taken from the
107 /// USERNAME attribute (in which case SASLprep has already been applied);
108 /// (2) a single colon; (3) the realm, with any quotes and trailing nulls
109 /// removed; (4) a single colon; and (5) the password, with any trailing
110 /// nulls removed and after processing using SASLprep. For example, if
111 /// the username was 'user', the realm was 'realm', and the password was
112 /// 'pass', then the 16-byte HMAC key would be the result of performing
113 /// an MD5 hash on the string 'user:realm:pass', the resulting hash being
114 /// 0x8493fbc53ba582fb4c044c456bdc40eb.
115 ///
116 /// For short-term credentials:
117 ///```text
118 /// key = SASLprep(password)
119 ///```
120 /// where MD5 is defined in [RFC 1321](https://tools.ietf.org/html/rfc1321) and SASLprep() is defined
121 /// in [RFC 4013](https://tools.ietf.org/html/rfc4013).
122 ///
123 /// The structure of the key when used with long-term credentials
124 /// facilitates deployment in systems that also utilize SIP. Typically,
125 /// SIP systems utilizing SIP's digest authentication mechanism do not
126 /// actually store the password in the database. Rather, they store a
127 /// value called H(A1), which is equal to the key defined above.
128 ///
129 /// Based on the rules above, the hash used to construct MESSAGE-
130 /// INTEGRITY includes the length field from the STUN message header.
131 /// Prior to performing the hash, the MESSAGE-INTEGRITY attribute MUST be
132 /// inserted into the message (with dummy content). The length MUST then
133 /// be set to point to the length of the message up to, and including,
134 /// the MESSAGE-INTEGRITY attribute itself, but excluding any attributes
135 /// after it. Once the computation is performed, the value of the
136 /// MESSAGE-INTEGRITY attribute can be filled in, and the value of the
137 /// length in the STUN header can be set to its correct value -- the
138 /// length of the entire message. Similarly, when validating the
139 /// MESSAGE-INTEGRITY, the length field should be adjusted to point to
140 /// the end of the MESSAGE-INTEGRITY attribute prior to calculating the
141 /// HMAC. Such adjustment is necessary when attributes, such as
142 /// FINGERPRINT, appear after MESSAGE-INTEGRITY.
143 MessageIntegrity {
144 /// HMAC-SHA1 ([RFC2104](https://tools.ietf.org/html/rfc2104)) of the STUN message.
145 key: Vec<u8>,
146 },
147 /// [RFC5389: FINGERPRINT](https://tools.ietf.org/html/rfc5389#section-15.5)
148 ///
149 /// The FINGERPRINT attribute MAY be present in all STUN messages. The
150 /// value of the attribute is computed as the CRC-32 of the STUN message
151 /// up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
152 /// the 32-bit value 0x5354554e (the XOR helps in cases where an
153 /// application packet is also using CRC-32 in it). The 32-bit CRC is
154 /// the one defined in [ITU V.42](https://tools.ietf.org/html/rfc5389#ref-ITU.V42.2002), which has a generator
155 /// polynomial of x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1.
156 /// When present, the FINGERPRINT attribute MUST be the last attribute in
157 /// the message, and thus will appear after MESSAGE-INTEGRITY.
158 ///
159 /// The FINGERPRINT attribute can aid in distinguishing STUN packets from
160 /// packets of other protocols. See [Section 8](https://tools.ietf.org/html/rfc5389#section-8).
161 ///
162 /// As with MESSAGE-INTEGRITY, the CRC used in the FINGERPRINT attribute
163 /// covers the length field from the STUN message header. Therefore,
164 /// this value must be correct and include the CRC attribute as part of
165 /// the message length, prior to computation of the CRC. When using the
166 /// FINGERPRINT attribute in a message, the attribute is first placed
167 /// into the message with a dummy value, then the CRC is computed, and
168 /// then the value of the attribute is updated. If the MESSAGE-INTEGRITY
169 /// attribute is also present, then it must be present with the correct
170 /// message-integrity value before the CRC is computed, since the CRC is
171 /// done over the value of the MESSAGE-INTEGRITY attribute as well.
172 Fingerprint {
173 /// CRC-32 of the STUN message up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with the 32-bit value 0x5354554e
174 value: u32,
175 },
176 /// [RFC5389: ERROR-CODE](https://tools.ietf.org/html/rfc5389#section-15.6)
177 ///
178 /// The ERROR-CODE attribute is used in error response messages. It
179 /// contains a numeric error code value in the range of 300 to 699 plus a
180 /// textual reason phrase encoded in UTF-8 [RFC3629](https://tools.ietf.org/html/rfc3629), and is consistent
181 /// in its code assignments and semantics with SIP [RFC3261](https://tools.ietf.org/html/rfc3261) and HTTP
182 /// [RFC2616](https://tools.ietf.org/html/rfc2616). The reason phrase is meant for user consumption, and can
183 /// be anything appropriate for the error code. Recommended reason
184 /// phrases for the defined error codes are included in the IANA registry
185 /// for error codes. The reason phrase MUST be a UTF-8 [RFC3629](https://tools.ietf.org/html/rfc3629) encoded
186 /// sequence of less than 128 characters (which can be as long as 763
187 /// bytes).
188 ErrorCode {
189 /// Error class
190 class: u8,
191 /// Error number
192 number: u8,
193 /// Reason phrase
194 reason: String,
195 },
196 /// [RFC5389: REALM](https://tools.ietf.org/html/rfc5389#section-15.7)
197 ///
198 /// The REALM attribute may be present in requests and responses. It
199 /// contains text that meets the grammar for "realm-value" as described
200 /// in [RFC3261](https://tools.ietf.org/html/rfc3261) but without the double quotes and their
201 /// surrounding whitespace. That is, it is an unquoted realm-value (and
202 /// is therefore a sequence of qdtext or quoted-pair). It MUST be a
203 /// UTF-8 [RFC3629](https://tools.ietf.org/html/rfc3629) encoded sequence of less than 128 characters (which
204 /// can be as long as 763 bytes), and MUST have been processed using
205 /// SASLprep [RFC 4013](https://tools.ietf.org/html/rfc4013).
206 ///
207 /// Presence of the REALM attribute in a request indicates that long-term
208 /// credentials are being used for authentication. Presence in certain
209 /// error responses indicates that the server wishes the client to use a
210 /// long-term credential for authentication.
211 Realm {
212 /// Text that meets the grammar for "realm-value" as described in [RFC 3261](https://tools.ietf.org/html/rfc3261) but without the double quotes and their surrounding whitespace.
213 value: String,
214 },
215 /// [RFC5389: NONCE](https://tools.ietf.org/html/rfc5389#section-15.8)
216 /// The NONCE attribute may be present in requests and responses. It
217 /// contains a sequence of qdtext or quoted-pair, which are defined in
218 /// [RFC3261](https://tools.ietf.org/html/rfc3261). Note that this means that the NONCE attribute
219 /// will not contain actual quote characters. See [RFC2617](https://tools.ietf.org/html/rfc2617),
220 /// [Section 4.3](https://tools.ietf.org/html/rfc2617#section-4.3), for guidance on selection of nonce values in a server.
221 ///
222 /// It MUST be less than 128 characters (which can be as long as 763
223 /// bytes).
224 Nonce {
225 /// Sequence of qdtext or quoted-pair, which are defined in [RFC 3261](https://tools.ietf.org/html/rfc3261).
226 value: String,
227 },
228 /// [RFC5389: UNKNOWN-ATTRIBUTES](https://tools.ietf.org/html/rfc5389#section-15.9)
229 ///
230 /// The UNKNOWN-ATTRIBUTES attribute is present only in an error response
231 /// when the response code in the ERROR-CODE attribute is 420.
232 ///
233 /// The attribute contains a list of 16-bit values, each of which
234 /// represents an attribute type that was not understood by the server.
235 UnknownAttributes {
236 /// List of 16-bit values, each of which represents an attribute type that was not understood by the server.
237 types: Vec<u16>,
238 },
239 /// [RFC5389: SOFTWARE](https://tools.ietf.org/html/rfc5389#section-15.10)
240 /// The SOFTWARE attribute contains a textual description of the software
241 /// being used by the agent sending the message. It is used by clients
242 /// and servers. Its value SHOULD include manufacturer and version
243 /// number. The attribute has no impact on operation of the protocol,
244 /// and serves only as a tool for diagnostic and debugging purposes. The
245 /// value of SOFTWARE is variable length. It MUST be a UTF-8 [RFC3629](https://tools.ietf.org/html/rfc3629)
246 /// encoded sequence of less than 128 characters (which can be as long as
247 /// 763 bytes).
248 Software {
249 /// Textual description of the software being used by the agent sending the message.
250 description: String,
251 },
252 /// [RFC5389: ALTERNATE-SERVER](https://tools.ietf.org/html/rfc5389#section-15.11)
253 ///
254 /// The alternate server represents an alternate transport address
255 /// identifying a different STUN server that the STUN client should try.
256 ///
257 /// It is encoded in the same way as MAPPED-ADDRESS, and thus refers to a
258 /// single server by IP address. The IP address family MUST be identical
259 /// to that of the source IP address of the request.
260 AlternateServer {
261 /// Alternate transport address identifying a different STUN server that the STUN client should try.
262 socket_addr: SocketAddr,
263 },
264 /// [RFC8445: PRIORITY](https://tools.ietf.org/html/rfc8445#section-7.1.1)
265 ///
266 /// The PRIORITY attribute MUST be included in a Binding request and be
267 /// set to the value computed by the algorithm in [Section 5.1.2](https://tools.ietf.org/html/rfc8445#section-5.1.2) for the
268 /// local candidate, but with the candidate type preference of peer-
269 /// reflexive candidates.
270 Priority {
271 /// Value computed by the algorithm in [Section 5.1.2 of RFC8445](https://tools.ietf.org/html/rfc8445#section-5.1.2) for the local candidate, but with the candidate type preference of peer-reflexive candidates.
272 value: u32,
273 },
274 /// [RFC8445: USE-CANDIDATE](https://tools.ietf.org/html/rfc8445#section-7.1.2)
275 ///
276 /// The controlling agent MUST include the USE-CANDIDATE attribute in
277 /// order to nominate a candidate pair ([Section 8.1.1](https://tools.ietf.org/html/rfc8445#section-8.1.1)). The controlled
278 /// agent MUST NOT include the USE-CANDIDATE attribute in a Binding
279 /// request.
280 UseCandidate,
281 /// [RFC8445: ICE-CONTROLLED](https://tools.ietf.org/html/rfc8445#section-7.1.3)
282 ///
283 /// The controlled agent MUST include the ICE-CONTROLLED attribute in a Binding request.
284 ///
285 /// The content of either attribute is used as tiebreaker values when an
286 /// ICE role conflict occurs ([Section 7.3.1.1](https://tools.ietf.org/html/rfc8445#section-7.3.1.1)).
287 IceControlled {
288 /// Tiebreaker value used for ICE role conflict resolution defined in [Section 7.3.1.1 of RFC8445](https://tools.ietf.org/html/rfc8445#section-7.3.1.1)
289 tie_breaker: u64,
290 },
291 /// [RFC8445: ICE-CONTROLLING](https://tools.ietf.org/html/rfc8445#section-7.1.3)
292 ///
293 /// The controlling agent MUST include the ICE-CONTROLLING attribute in a
294 /// Binding request.
295 ///
296 /// The content of either attribute is used as tiebreaker values when an
297 /// ICE role conflict occurs ([Section 7.3.1.1](https://tools.ietf.org/html/rfc8445#section-7.3.1.1)).
298 IceControlling {
299 /// Tiebreaker value used for ICE role conflict resolution defined in [Section 7.3.1.1 of RFC8445](https://tools.ietf.org/html/rfc8445#section-7.3.1.1)
300 tie_breaker: u64,
301 },
302}