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}