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