turn_server/codec/message/attributes/mod.rs
1pub mod address;
2pub mod error;
3
4use std::{fmt::Debug, net::SocketAddr};
5
6use bytes::{Buf, BufMut};
7use num_enum::TryFromPrimitive;
8
9use super::{
10 Error,
11 attributes::{
12 address::{IpFamily, XAddress},
13 error::ErrorType,
14 },
15};
16
17/// STUN Attributes Registry
18///
19/// [RFC8126]: https://datatracker.ietf.org/doc/html/rfc8126
20/// [RFC5389]: https://datatracker.ietf.org/doc/html/rfc5389
21/// [RFC8489]: https://datatracker.ietf.org/doc/html/rfc8489
22///
23/// A STUN attribute type is a hex number in the range 0x0000-0xFFFF.
24/// STUN attribute types in the range 0x0000-0x7FFF are considered
25/// comprehension-required; STUN attribute types in the range
26/// 0x8000-0xFFFF are considered comprehension-optional. A STUN agent
27/// handles unknown comprehension-required and comprehension-optional
28/// attributes differently.
29///
30/// STUN attribute types in the first half of the comprehension-required
31/// range (0x0000-0x3FFF) and in the first half of the comprehension-
32/// optional range (0x8000-0xBFFF) are assigned by IETF Review [RFC8126].
33/// STUN attribute types in the second half of the comprehension-required
34/// range (0x4000-0x7FFF) and in the second half of the comprehension-
35/// optional range (0xC000-0xFFFF) are assigned by Expert Review
36/// [RFC8126]. The responsibility of the expert is to verify that the
37/// selected codepoint(s) are not in use and that the request is not for
38/// an abnormally large number of codepoints. Technical review of the
39/// extension itself is outside the scope of the designated expert
40/// responsibility.
41///
42/// IANA has updated the names for attributes 0x0002, 0x0004, 0x0005,
43/// 0x0007, and 0x000B as well as updated the reference from [RFC5389] to
44/// [RFC8489] for each the following STUN methods.
45///
46/// In addition, [RFC5389] introduced a mistake in the name of attribute
47/// 0x0003; [RFC5389] called it CHANGE-ADDRESS when it was actually
48/// previously called CHANGE-REQUEST. Thus, IANA has updated the
49/// description for 0x0003 to read "Reserved; was CHANGE-REQUEST prior to
50/// [RFC5389]".
51///
52/// Comprehension-required range (0x0000-0x7FFF):
53/// 0x0000: Reserved
54/// 0x0001: MAPPED-ADDRESS
55/// 0x0002: Reserved; was RESPONSE-ADDRESS prior to [RFC5389]
56/// 0x0003: Reserved; was CHANGE-REQUEST prior to [RFC5389]
57/// 0x0004: Reserved; was SOURCE-ADDRESS prior to [RFC5389]
58/// 0x0005: Reserved; was CHANGED-ADDRESS prior to [RFC5389]
59/// 0x0006: USERNAME
60/// 0x0007: Reserved; was PASSWORD prior to [RFC5389]
61/// 0x0008: MESSAGE-INTEGRITY
62/// 0x0009: ERROR-CODE
63/// 0x000A: UNKNOWN-ATTRIBUTES
64/// 0x000B: Reserved; was REFLECTED-FROM prior to [RFC5389]
65/// 0x0014: REALM
66/// 0x0015: NONCE
67/// 0x0020: XOR-MAPPED-ADDRESS
68///
69/// Comprehension-optional range (0x8000-0xFFFF)
70/// 0x8022: SOFTWARE
71/// 0x8023: ALTERNATE-SERVER
72/// 0x8028: FINGERPRINT
73///
74/// IANA has added the following attribute to the "STUN Attributes"
75/// registry:
76///
77/// Comprehension-required range (0x0000-0x7FFF):
78/// 0x001C: MESSAGE-INTEGRITY-SHA256
79/// 0x001D: PASSWORD-ALGORITHM
80/// 0x001E: USERHASH
81///
82/// Comprehension-optional range (0x8000-0xFFFF)
83/// 0x8002: PASSWORD-ALGORITHMS
84/// 0x8003: ALTERNATE-DOMAIN
85#[repr(u16)]
86#[derive(Default, Clone, Copy, PartialEq, Eq, Hash, Debug, TryFromPrimitive)]
87pub enum AttributeType {
88 #[default]
89 Unknown = 0x0000,
90 MappedAddress = 0x0001,
91 UserName = 0x0006,
92 MessageIntegrity = 0x0008,
93 ErrorCode = 0x0009,
94 ChannelNumber = 0x000C,
95 Lifetime = 0x000D,
96 XorPeerAddress = 0x0012,
97 Data = 0x0013,
98 Realm = 0x0014,
99 Nonce = 0x0015,
100 XorRelayedAddress = 0x0016,
101 RequestedAddressFamily = 0x0017,
102 EvenPort = 0x0018,
103 ReqeestedTransport = 0x0019,
104 DontFragment = 0x001A,
105 AccessToken = 0x001B,
106 MessageIntegritySha256 = 0x001C,
107 PasswordAlgorithm = 0x001D,
108 UserHash = 0x001E,
109 XorMappedAddress = 0x0020,
110 ReservationToken = 0x0022,
111 Priority = 0x0024,
112 UseCandidate = 0x0025,
113 Padding = 0x0026,
114 ResponsePort = 0x0027,
115 ConnectionId = 0x002A,
116 AdditionalAddressFamily = 0x8000,
117 AddressErrorCode = 0x8001,
118 PasswordAlgorithms = 0x8002,
119 AlternateDomain = 0x8003,
120 Icmp = 0x8004,
121 Software = 0x8022,
122 AlternateServer = 0x8023,
123 TransactionTransmitCounter = 0x8025,
124 CacheTimeout = 0x8027,
125 Fingerprint = 0x8028,
126 IceControlled = 0x8029,
127 IceControlling = 0x802A,
128 ResponseOrigin = 0x802B,
129 OtherAddress = 0x802C,
130 EcnCheck = 0x802D,
131 ThirdPartyAuathorization = 0x802E,
132 MobilityTicket = 0x8030,
133}
134
135/// dyn stun/turn message attribute.
136pub trait Attribute<'a> {
137 type Error: Debug;
138
139 /// current attribute inner type.
140 type Item;
141
142 /// current attribute type.
143 const TYPE: AttributeType;
144
145 /// write the current attribute to the bytesfer.
146 #[allow(unused_variables)]
147 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {}
148
149 /// convert bytesfer to current attribute.
150 fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error>;
151}
152
153/// [RFC8265]: https://datatracker.ietf.org/doc/html/rfc8265
154/// [RFC5389]: https://datatracker.ietf.org/doc/html/rfc5389
155/// [RFC3629]: https://datatracker.ietf.org/doc/html/rfc3629
156///
157/// The USERNAME attribute is used for message integrity. It identifies
158/// the username and password combination used in the message-integrity
159/// check.
160///
161/// The value of USERNAME is a variable-length value containing the
162/// authentication username. It MUST contain a UTF-8-encoded [RFC3629]
163/// sequence of fewer than 509 bytes and MUST have been processed using
164/// the OpaqueString profile [RFC8265]. A compliant implementation MUST
165/// be able to parse a UTF-8-encoded sequence of 763 or fewer octets to
166/// be compatible with [RFC5389].
167#[derive(Debug, Clone, Copy)]
168pub struct UserName;
169
170impl<'a> Attribute<'a> for UserName {
171 type Error = Error;
172 type Item = &'a str;
173
174 const TYPE: AttributeType = AttributeType::UserName;
175
176 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
177 bytes.put(value.as_bytes());
178 }
179
180 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
181 Ok(std::str::from_utf8(bytes)?)
182 }
183}
184
185/// The USERHASH attribute is used as a replacement for the USERNAME attribute
186/// when username anonymity is supported.
187///
188/// The value of USERHASH has a fixed length of 32 bytes. The username MUST have
189/// been processed using the OpaqueString profile [RFC8265], and the realm MUST
190/// have been processed using the OpaqueString profile [RFC8265] before hashing.
191///
192/// The following is the operation that the client will perform to hash the username:
193///
194/// userhash = SHA-256(OpaqueString(username) ":" OpaqueString(realm))
195#[derive(Debug, Clone, Copy)]
196pub struct UserHash;
197
198impl<'a> Attribute<'a> for UserHash {
199 type Error = Error;
200 type Item = &'a [u8];
201
202 const TYPE: AttributeType = AttributeType::UserHash;
203
204 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
205 bytes.put(value);
206 }
207
208 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
209 Ok(bytes)
210 }
211}
212
213/// The DATA attribute is present in all Send and Data indications. The
214/// value portion of this attribute is variable length and consists of
215/// the application data (that is, the data that would immediately follow
216/// the UDP header if the data was been sent directly between the client
217/// and the peer). If the length of this attribute is not a multiple of
218/// 4, then padding must be added after this attribute.
219#[derive(Debug, Clone, Copy)]
220pub struct Data;
221
222impl<'a> Attribute<'a> for Data {
223 type Error = Error;
224 type Item = &'a [u8];
225
226 const TYPE: AttributeType = AttributeType::Data;
227
228 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
229 bytes.put(value);
230 }
231
232 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
233 Ok(bytes)
234 }
235}
236
237/// [RFC3629]: https://datatracker.ietf.org/doc/html/rfc3629
238/// [RFC3261]: https://datatracker.ietf.org/doc/html/rfc3261
239/// [RFC8265]: https://datatracker.ietf.org/doc/html/rfc8265
240///
241/// The REALM attribute may be present in requests and responses. It
242/// contains text that meets the grammar for "realm-value" as described
243/// in [RFC3261] but without the double quotes and their surrounding
244/// whitespace. That is, it is an unquoted realm-value (and is therefore
245/// a sequence of qdtext or quoted-pair). It MUST be a UTF-8-encoded
246/// [RFC3629] sequence of fewer than 128 characters (which can be as long
247/// as 509 bytes when encoding them and as long as 763 bytes when
248/// decoding them) and MUST have been processed using the OpaqueString
249/// profile [RFC8265].
250///
251/// Presence of the REALM attribute in a request indicates that long-term
252/// credentials are being used for authentication. Presence in certain
253/// error responses indicates that the server wishes the client to use a
254/// long-term credential in that realm for authentication.
255#[derive(Debug, Clone, Copy)]
256pub struct Realm;
257
258impl<'a> Attribute<'a> for Realm {
259 type Error = Error;
260 type Item = &'a str;
261
262 const TYPE: AttributeType = AttributeType::Realm;
263
264 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
265 bytes.put(value.as_bytes());
266 }
267
268 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
269 Ok(std::str::from_utf8(bytes)?)
270 }
271}
272
273/// [RFC3261]: https://datatracker.ietf.org/doc/html/rfc3261
274/// [RFC7616]: https://datatracker.ietf.org/doc/html/rfc7616
275///
276/// The NONCE attribute may be present in requests and responses. It
277/// contains a sequence of qdtext or quoted-pair, which are defined in
278/// [RFC3261]. Note that this means that the NONCE attribute will not
279/// contain the actual surrounding quote characters. The NONCE attribute
280/// MUST be fewer than 128 characters (which can be as long as 509 bytes
281/// when encoding them and a long as 763 bytes when decoding them). See
282/// Section 5.4 of [RFC7616] for guidance on selection of nonce values in
283/// a server.
284#[derive(Debug, Clone, Copy)]
285pub struct Nonce;
286
287impl<'a> Attribute<'a> for Nonce {
288 type Error = Error;
289 type Item = &'a str;
290
291 const TYPE: AttributeType = AttributeType::Nonce;
292
293 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
294 bytes.put(value.as_bytes());
295 }
296
297 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
298 Ok(std::str::from_utf8(bytes)?)
299 }
300}
301
302/// [RFC3629]: https://datatracker.ietf.org/doc/html/rfc3629
303///
304/// The SOFTWARE attribute contains a textual description of the software
305/// being used by the agent sending the message. It is used by clients
306/// and servers. Its value SHOULD include manufacturer and version
307/// number. The attribute has no impact on operation of the protocol and
308/// serves only as a tool for diagnostic and debugging purposes. The
309/// value of SOFTWARE is variable length. It MUST be a UTF-8-encoded
310/// [RFC3629] sequence of fewer than 128 characters (which can be as long
311/// as 509 when encoding them and as long as 763 bytes when decoding
312/// them).
313#[derive(Debug, Clone, Copy)]
314pub struct Software;
315
316impl<'a> Attribute<'a> for Software {
317 type Error = Error;
318 type Item = &'a str;
319
320 const TYPE: AttributeType = AttributeType::Software;
321
322 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
323 bytes.put(value.as_bytes());
324 }
325
326 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
327 Ok(std::str::from_utf8(bytes)?)
328 }
329}
330
331/// [RFC2104]: https://datatracker.ietf.org/doc/html/rfc2104
332/// [RFC5769]: https://datatracker.ietf.org/doc/html/rfc5769
333///
334/// The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of
335/// the STUN message. The MESSAGE-INTEGRITY attribute can be present in
336/// any STUN message type. Since it uses the SHA-1 hash, the HMAC will
337/// be 20 bytes.
338///
339/// The key for the HMAC depends on which credential mechanism is in use.
340/// Section 9.1.1 defines the key for the short-term credential
341/// mechanism, and Section 9.2.2 defines the key for the long-term
342/// credential mechanism. Other credential mechanisms MUST define the
343/// key that is used for the HMAC.
344///
345/// The text used as input to HMAC is the STUN message, up to and
346/// including the attribute preceding the MESSAGE-INTEGRITY attribute.
347/// The Length field of the STUN message header is adjusted to point to
348/// the end of the MESSAGE-INTEGRITY attribute. The value of the
349/// MESSAGE-INTEGRITY attribute is set to a dummy value.
350///
351/// Once the computation is performed, the value of the MESSAGE-INTEGRITY
352/// attribute is filled in, and the value of the length in the STUN
353/// header is set to its correct value -- the length of the entire
354/// message. Similarly, when validating the MESSAGE-INTEGRITY, the
355/// Length field in the STUN header must be adjusted to point to the end
356/// of the MESSAGE-INTEGRITY attribute prior to calculating the HMAC over
357/// the STUN message, up to and including the attribute preceding the
358/// MESSAGE-INTEGRITY attribute. Such adjustment is necessary when
359/// attributes, such as FINGERPRINT and MESSAGE-INTEGRITY-SHA256, appear
360/// after MESSAGE-INTEGRITY. See also [RFC5769] for examples of such
361/// calculations.
362#[derive(Debug, Clone, Copy)]
363pub struct MessageIntegrity;
364
365impl<'a> Attribute<'a> for MessageIntegrity {
366 type Error = Error;
367 type Item = &'a [u8];
368
369 const TYPE: AttributeType = AttributeType::MessageIntegrity;
370
371 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
372 bytes.put(value);
373 }
374
375 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
376 Ok(bytes)
377 }
378}
379
380/// The MESSAGE-INTEGRITY-SHA256 attribute contains an HMAC-SHA256
381/// [RFC2104] of the STUN message. The MESSAGE-INTEGRITY-SHA256
382/// attribute can be present in any STUN message type. The MESSAGE-
383/// INTEGRITY-SHA256 attribute contains an initial portion of the HMAC-
384/// SHA-256 [RFC2104] of the STUN message. The value will be at most 32
385/// bytes, but it MUST be at least 16 bytes and MUST be a multiple of 4
386/// bytes. The value must be the full 32 bytes unless the STUN Usage
387/// explicitly specifies that truncation is allowed. STUN Usages may
388/// specify a minimum length longer than 16 bytes.
389///
390/// The key for the HMAC depends on which credential mechanism is in use.
391/// Section 9.1.1 defines the key for the short-term credential
392/// mechanism, and Section 9.2.2 defines the key for the long-term
393/// credential mechanism. Other credential mechanism MUST define the key
394/// that is used for the HMAC.
395///
396/// The text used as input to HMAC is the STUN message, up to and
397/// including the attribute preceding the MESSAGE-INTEGRITY-SHA256
398/// attribute. The Length field of the STUN message header is adjusted
399/// to point to the end of the MESSAGE-INTEGRITY-SHA256 attribute. The
400/// value of the MESSAGE-INTEGRITY-SHA256 attribute is set to a dummy
401/// value.
402///
403/// Once the computation is performed, the value of the MESSAGE-
404/// INTEGRITY-SHA256 attribute is filled in, and the value of the length
405/// in the STUN header is set to its correct value -- the length of the
406/// entire message. Similarly, when validating the MESSAGE-INTEGRITY-
407/// SHA256, the Length field in the STUN header must be adjusted to point
408/// to the end of the MESSAGE-INTEGRITY-SHA256 attribute prior to
409/// calculating the HMAC over the STUN message, up to and including the
410/// attribute preceding the MESSAGE-INTEGRITY-SHA256 attribute. Such
411/// adjustment is necessary when attributes, such as FINGERPRINT, appear
412/// after MESSAGE-INTEGRITY-SHA256. See also Appendix B.1 for examples
413/// of such calculations.
414#[derive(Debug, Clone, Copy)]
415pub struct MessageIntegritySha256;
416
417impl<'a> Attribute<'a> for MessageIntegritySha256 {
418 type Error = Error;
419 type Item = &'a [u8];
420
421 const TYPE: AttributeType = AttributeType::MessageIntegritySha256;
422
423 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
424 bytes.put(value);
425 }
426
427 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
428 Ok(bytes)
429 }
430}
431
432/// The PASSWORD-ALGORITHM attribute is present only in requests. It
433/// contains the algorithm that the server must use to derive a key from
434/// the long-term password.
435///
436/// The set of known algorithms is maintained by IANA. The initial set
437/// defined by this specification is found in Section 18.5.
438///
439/// The attribute contains an algorithm number and variable length
440/// parameters. The algorithm number is a 16-bit value as defined in
441/// Section 18.5. The parameters starts with the length (prior to
442/// padding) of the parameters as a 16-bit value, followed by the
443/// parameters that are specific to the algorithm. The parameters are
444/// padded to a 32-bit boundary, in the same manner as an attribute.
445/// Similarly, the padding bits MUST be set to zero on sending and MUST
446/// be ignored by the receiver.
447///
448/// 0 1 2 3
449/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
450/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
451/// | Algorithm | Algorithm Parameters Length |
452/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
453/// | Algorithm Parameters (variable)
454/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
455#[repr(u16)]
456#[derive(Debug, PartialEq, Eq, Clone, Copy)]
457pub enum PasswordAlgorithm {
458 Md5 = 0x0001,
459 Sha256 = 0x0002,
460}
461
462impl<'a> Attribute<'a> for PasswordAlgorithm {
463 type Error = Error;
464 type Item = Self;
465
466 const TYPE: AttributeType = AttributeType::PasswordAlgorithm;
467
468 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
469 bytes.put_u16(value as u16);
470 bytes.put_u16(0);
471 }
472
473 fn deserialize(mut bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
474 if bytes.len() < 4 {
475 return Err(Error::InvalidInput);
476 }
477
478 let ty = match bytes.get_u16() {
479 0x0001 => Self::Md5,
480 0x0002 => Self::Sha256,
481 _ => return Err(Error::InvalidInput),
482 };
483
484 // Ignore attribute value, as it does not exist currently
485 let size = bytes.get_u16();
486 bytes.advance(super::alignment_32(size as usize));
487
488 Ok(ty)
489 }
490}
491
492/// The PASSWORD-ALGORITHMS attribute may be present in requests and
493/// responses. It contains the list of algorithms that the server can
494/// use to derive the long-term password.
495///
496/// The set of known algorithms is maintained by IANA. The initial set
497/// defined by this specification is found in Section 18.5.
498///
499/// The attribute contains a list of algorithm numbers and variable
500/// length parameters. The algorithm number is a 16-bit value as defined
501/// in Section 18.5. The parameters start with the length (prior to
502/// padding) of the parameters as a 16-bit value, followed by the
503/// parameters that are specific to each algorithm. The parameters are
504/// padded to a 32-bit boundary, in the same manner as an attribute.
505pub struct PasswordAlgorithms;
506
507impl<'a> Attribute<'a> for PasswordAlgorithms {
508 type Error = Error;
509 type Item = Vec<PasswordAlgorithm>;
510
511 const TYPE: AttributeType = AttributeType::PasswordAlgorithms;
512
513 fn serialize<B: BufMut>(algorithms: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
514 for algorithm in algorithms {
515 PasswordAlgorithm::serialize(algorithm, bytes, transaction_id);
516 }
517 }
518
519 fn deserialize(mut bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
520 let mut algorithms = Vec::new();
521
522 loop {
523 if bytes.len() < 4 {
524 break;
525 }
526
527 let ty = match bytes.get_u16() {
528 0x0001 => PasswordAlgorithm::Md5,
529 0x0002 => PasswordAlgorithm::Sha256,
530 _ => break,
531 };
532
533 // Ignore attribute value, as it does not exist currently
534 let size = bytes.get_u16();
535 bytes.advance(super::alignment_32(size as usize));
536
537 algorithms.push(ty);
538 }
539
540 Ok(algorithms)
541 }
542}
543
544/// [RFC5389]: https://datatracker.ietf.org/doc/html/rfc5389
545///
546/// The XOR-PEER-ADDRESS specifies the address and port of the peer as
547/// seen from the TURN server. (For example, the peer's server-reflexive
548/// transport address if the peer is behind a NAT.) It is encoded in the
549/// same way as XOR-MAPPED-ADDRESS [RFC5389].
550#[derive(Debug, Clone, Copy)]
551pub struct XorPeerAddress;
552
553impl<'a> Attribute<'a> for XorPeerAddress {
554 type Error = Error;
555 type Item = SocketAddr;
556
557 const TYPE: AttributeType = AttributeType::XorPeerAddress;
558
559 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
560 XAddress::serialize(&value, transaction_id, bytes, true)
561 }
562
563 fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
564 XAddress::deserialize(bytes, transaction_id, true)
565 }
566}
567
568/// [RFC5389]: https://datatracker.ietf.org/doc/html/rfc5389
569///
570/// The XOR-RELAYED-ADDRESS is present in Allocate responses. It
571/// specifies the address and port that the server allocated to the
572/// client. It is encoded in the same way as XOR-MAPPED-ADDRESS
573/// [RFC5389].
574#[derive(Debug, Clone, Copy)]
575pub struct XorRelayedAddress;
576
577impl<'a> Attribute<'a> for XorRelayedAddress {
578 type Error = Error;
579 type Item = SocketAddr;
580
581 const TYPE: AttributeType = AttributeType::XorRelayedAddress;
582
583 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
584 XAddress::serialize(&value, transaction_id, bytes, true)
585 }
586
587 fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
588 XAddress::deserialize(bytes, transaction_id, true)
589 }
590}
591
592/// [RFC3489]: https://datatracker.ietf.org/doc/html/rfc3489
593///
594/// The XOR-MAPPED-ADDRESS attribute is identical to the MAPPED-ADDRESS
595/// attribute, except that the reflexive transport address is obfuscated
596/// through the XOR function.
597///
598/// The Family field represents the IP address family and is encoded
599/// identically to the Family field in MAPPED-ADDRESS.
600///
601/// X-Port is computed by XOR'ing the mapped port with the most
602/// significant 16 bits of the magic cookie. If the IP address family is
603/// IPv4, X-Address is computed by XOR'ing the mapped IP address with the
604/// magic cookie. If the IP address family is IPv6, X-Address is
605/// computed by XOR'ing the mapped IP address with the concatenation of
606/// the magic cookie and the 96-bit transaction ID. In all cases, the
607/// XOR operation works on its inputs in network byte order (that is, the
608/// order they will be encoded in the message).
609///
610/// The rules for encoding and processing the first 8 bits of the
611/// attribute's value, the rules for handling multiple occurrences of the
612/// attribute, and the rules for processing address families are the same
613/// as for MAPPED-ADDRESS.
614///
615/// Note: XOR-MAPPED-ADDRESS and MAPPED-ADDRESS differ only in their
616/// encoding of the transport address. The former encodes the transport
617/// address by XOR'ing it with the magic cookie. The latter encodes it
618/// directly in binary. [RFC3489] originally specified only MAPPED-
619/// ADDRESS. However, deployment experience found that some NATs rewrite
620/// the 32-bit binary payloads containing the NAT's public IP address,
621/// such as STUN's MAPPED-ADDRESS attribute, in the well-meaning but
622/// misguided attempt to provide a generic Application Layer Gateway
623/// (ALG) function. Such behavior interferes with the operation of STUN
624/// and also causes failure of STUN's message-integrity checking.
625#[derive(Debug, Clone, Copy)]
626pub struct XorMappedAddress;
627
628impl<'a> Attribute<'a> for XorMappedAddress {
629 type Error = Error;
630 type Item = SocketAddr;
631
632 const TYPE: AttributeType = AttributeType::XorMappedAddress;
633
634 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
635 XAddress::serialize(&value, transaction_id, bytes, true)
636 }
637
638 fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
639 XAddress::deserialize(bytes, transaction_id, true)
640 }
641}
642
643/// [RFC3489]: https://datatracker.ietf.org/doc/html/rfc3489
644///
645/// The MAPPED-ADDRESS attribute indicates a reflexive transport address
646/// of the client. It consists of an 8-bit address family and a 16-bit
647/// port, followed by a fixed-length value representing the IP address.
648/// If the address family is IPv4, the address MUST be 32 bits. If the
649/// address family is IPv6, the address MUST be 128 bits. All fields
650/// must be in network byte order.
651///
652/// The address family can take on the following values:
653///
654/// 0x01:IPv4
655/// 0x02:IPv6
656///
657/// The first 8 bits of the MAPPED-ADDRESS MUST be set to 0 and MUST be
658/// ignored by receivers. These bits are present for aligning parameters
659/// on natural 32-bit boundaries.
660///
661/// This attribute is used only by servers for achieving backwards
662/// compatibility with [RFC3489] clients.
663#[derive(Debug, Clone, Copy)]
664pub struct MappedAddress;
665
666impl<'a> Attribute<'a> for MappedAddress {
667 type Error = Error;
668 type Item = SocketAddr;
669
670 const TYPE: AttributeType = AttributeType::MappedAddress;
671
672 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
673 XAddress::serialize(&value, transaction_id, bytes, false)
674 }
675
676 fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
677 XAddress::deserialize(bytes, transaction_id, false)
678 }
679}
680
681/// The RESPONSE-ORIGIN attribute is inserted by the server and indicates
682/// the source IP address and port the response was sent from. It is
683/// useful for detecting double NAT configurations. It is only present
684/// in Binding Responses.
685#[derive(Debug, Clone, Copy)]
686pub struct ResponseOrigin;
687
688impl<'a> Attribute<'a> for ResponseOrigin {
689 type Error = Error;
690 type Item = SocketAddr;
691
692 const TYPE: AttributeType = AttributeType::ResponseOrigin;
693
694 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
695 XAddress::serialize(&value, transaction_id, bytes, false)
696 }
697
698 fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
699 XAddress::deserialize(bytes, transaction_id, false)
700 }
701}
702
703/// [RFC3629]: https://datatracker.ietf.org/doc/html/rfc3629
704/// [RFC7231]: https://datatracker.ietf.org/doc/html/rfc7231
705/// [RFC3261]: https://datatracker.ietf.org/doc/html/rfc3261
706/// [RFC3629]: https://datatracker.ietf.org/doc/html/rfc3629
707///
708/// The ERROR-CODE attribute is used in error response messages. It
709/// contains a numeric error code value in the range of 300 to 699 plus a
710/// textual reason phrase encoded in UTF-8 [RFC3629]; it is also
711/// consistent in its code assignments and semantics with SIP [RFC3261]
712/// and HTTP [RFC7231]. The reason phrase is meant for diagnostic
713/// purposes and can be anything appropriate for the error code.
714/// Recommended reason phrases for the defined error codes are included
715/// in the IANA registry for error codes. The reason phrase MUST be a
716/// UTF-8-encoded [RFC3629] sequence of fewer than 128 characters (which
717/// can be as long as 509 bytes when encoding them or 763 bytes when
718/// decoding them).
719///
720/// ```text
721/// 0 1 2 3
722/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
723/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
724/// | Reserved, should be 0 |Class| Number |
725/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
726/// | Reason Phrase (variable) ..
727/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
728///
729/// Figure 7: Format of ERROR-CODE Attribute
730/// ```
731///
732/// To facilitate processing, the class of the error code (the hundreds
733/// digit) is encoded separately from the rest of the code, as shown in
734/// Figure 7.
735///
736/// The Reserved bits SHOULD be 0 and are for alignment on 32-bit
737/// boundaries. Receivers MUST ignore these bits. The Class represents
738/// the hundreds digit of the error code. The value MUST be between 3
739/// and 6. The Number represents the binary encoding of the error code
740/// modulo 100, and its value MUST be between 0 and 99.
741#[derive(Debug, Clone, Copy)]
742pub struct ErrorCode<'a> {
743 pub code: u16,
744 pub message: &'a str,
745}
746
747impl<'a> Attribute<'a> for ErrorCode<'a> {
748 type Error = Error;
749 type Item = Self;
750
751 const TYPE: AttributeType = AttributeType::ErrorCode;
752
753 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
754 value.serialize(bytes);
755 }
756
757 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
758 Self::try_from(bytes)
759 }
760}
761
762impl From<ErrorType> for ErrorCode<'_> {
763 /// create error from error type.
764 ///
765 /// # Example
766 ///
767 /// ```no_run
768 /// use turn_server::codec::message::attributes::error::ErrorType;
769 ///
770 /// // Error::from(ErrorType::TryAlternate);
771 /// ```
772 fn from(value: ErrorType) -> Self {
773 Self {
774 code: value as u16,
775 message: value.into(),
776 }
777 }
778}
779
780impl ErrorCode<'_> {
781 /// encode the error type as bytes.
782 ///
783 /// # Test
784 ///
785 /// ```
786 /// use bytes::BytesMut;
787 /// use turn_server::codec::message::attributes::error::ErrorType;
788 /// use turn_server::codec::Error;
789 ///
790 /// let buffer = [
791 /// 0x00u8, 0x00, 0x03, 0x00, 0x54, 0x72, 0x79, 0x20, 0x41, 0x6c, 0x74,
792 /// 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65,
793 /// ];
794 ///
795 /// let mut buf = BytesMut::with_capacity(1280);
796 /// let error = turn_server::codec::message::attributes::ErrorCode::from(ErrorType::TryAlternate);
797 ///
798 /// error.serialize(&mut buf);
799 /// assert_eq!(&buf[..], &buffer);
800 /// ```
801 pub fn serialize<B: BufMut>(self, bytes: &mut B) {
802 bytes.put_u16(0x0000);
803 bytes.put_u16(self.code);
804 bytes.put(self.message.as_bytes());
805 }
806}
807
808impl<'a> TryFrom<&'a [u8]> for ErrorCode<'a> {
809 type Error = Error;
810
811 /// # Test
812 ///
813 /// ```
814 /// use std::convert::TryFrom;
815 /// use turn_server::codec::message::attributes::error::ErrorType;
816 /// use turn_server::codec::Error;
817 ///
818 /// let buffer = [
819 /// 0x00u8, 0x00, 0x03, 0x00, 0x54, 0x72, 0x79, 0x20, 0x41, 0x6c, 0x74,
820 /// 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65,
821 /// ];
822 ///
823 /// let error = turn_server::codec::message::attributes::ErrorCode::try_from(&buffer[..]).unwrap();
824 /// assert_eq!(error.code, ErrorType::TryAlternate as u16);
825 /// assert_eq!(error.message, "Try Alternate");
826 /// ```
827 fn try_from(packet: &'a [u8]) -> Result<Self, Self::Error> {
828 if packet.len() < 4 {
829 return Err(Error::InvalidInput);
830 }
831
832 if u16::from_be_bytes(packet[..2].try_into()?) != 0x0000 {
833 return Err(Error::InvalidInput);
834 }
835
836 Ok(Self {
837 code: u16::from_be_bytes(packet[2..4].try_into()?),
838 message: std::str::from_utf8(&packet[4..])?,
839 })
840 }
841}
842
843impl Eq for ErrorCode<'_> {}
844impl PartialEq for ErrorCode<'_> {
845 fn eq(&self, other: &Self) -> bool {
846 self.code == other.code
847 }
848}
849
850/// The LIFETIME attribute represents the duration for which the server
851/// will maintain an allocation in the absence of a refresh. The value
852/// portion of this attribute is 4-bytes long and consists of a 32-bit
853/// unsigned integral value representing the number of seconds remaining
854/// until expiration.
855#[derive(Debug, Clone, Copy)]
856pub struct Lifetime;
857
858impl<'a> Attribute<'a> for Lifetime {
859 type Error = Error;
860 type Item = u32;
861
862 const TYPE: AttributeType = AttributeType::Lifetime;
863
864 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
865 bytes.put_u32(value)
866 }
867
868 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
869 Ok(u32::from_be_bytes(bytes.try_into()?))
870 }
871}
872
873/// This attribute is used by the client to request a specific transport
874/// protocol for the allocated transport address.
875///
876/// The Protocol field specifies the desired protocol. The codepoints
877/// used in this field are taken from those allowed in the Protocol field
878/// in the IPv4 header and the NextHeader field in the IPv6 header
879/// [Protocol-Numbers]. This specification only allows the use of
880/// codepoint 17 (User Datagram Protocol).
881///
882/// The RFFU field MUST be set to zero on transmission and MUST be
883/// ignored on reception. It is reserved for future uses.
884#[repr(u32)]
885#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
886pub enum ReqeestedTransport {
887 Tcp = 0x06000000,
888 Udp = 0x11000000,
889}
890
891impl<'a> Attribute<'a> for ReqeestedTransport {
892 type Error = Error;
893 type Item = Self;
894
895 const TYPE: AttributeType = AttributeType::ReqeestedTransport;
896
897 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
898 bytes.put_u32(value as u32)
899 }
900
901 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
902 Self::try_from(u32::from_be_bytes(bytes.try_into()?)).map_err(|_| Error::InvalidInput)
903 }
904}
905
906/// [RFC1952]: https://datatracker.ietf.org/doc/html/rfc1952
907///
908/// The FINGERPRINT attribute MAY be present in all STUN messages.
909///
910/// The value of the attribute is computed as the CRC-32 of the STUN
911/// message up to (but excluding) the FINGERPRINT attribute itself,
912/// XOR'ed with the 32-bit value 0x5354554e. (The XOR operation ensures
913/// that the FINGERPRINT test will not report a false positive on a
914/// packet containing a CRC-32 generated by an application protocol.)
915///
916/// The 32-bit CRC is the one defined in ITU V.42, which has a generator
917/// polynomial of x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 +
918/// x^7 + x^5 + x^4 + x^2 + x + 1. See the sample code for the CRC-32 in
919/// Section 8 of [RFC1952].
920///
921/// When present, the FINGERPRINT attribute MUST be the last attribute in
922/// the message and thus will appear after MESSAGE-INTEGRITY and MESSAGE-
923/// INTEGRITY-SHA256.
924///
925/// The FINGERPRINT attribute can aid in distinguishing STUN packets from
926/// packets of other protocols. See Section 7.
927///
928/// As with MESSAGE-INTEGRITY and MESSAGE-INTEGRITY-SHA256, the CRC used
929/// in the FINGERPRINT attribute covers the Length field from the STUN
930/// message header. Therefore, prior to computation of the CRC, this
931/// value must be correct and include the CRC attribute as part of the
932/// message length. When using the FINGERPRINT attribute in a message,
933/// the attribute is first placed into the message with a dummy value;
934/// then, the CRC is computed, and the value of the attribute is updated.
935/// If the MESSAGE-INTEGRITY or MESSAGE-INTEGRITY-SHA256 attribute is
936/// also present, then it must be present with the correct message-
937/// integrity value before the CRC is computed, since the CRC is done
938/// over the value of the MESSAGE-INTEGRITY and MESSAGE-INTEGRITY-SHA256
939/// attributes as well.
940#[derive(Debug, Clone, Copy)]
941pub struct Fingerprint;
942
943impl<'a> Attribute<'a> for Fingerprint {
944 type Error = Error;
945 type Item = u32;
946
947 const TYPE: AttributeType = AttributeType::Fingerprint;
948
949 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
950 bytes.put_u32(value)
951 }
952
953 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
954 Ok(u32::from_be_bytes(bytes.try_into()?))
955 }
956}
957
958/// The CHANNEL-NUMBER attribute contains the number of the channel. The
959/// value portion of this attribute is 4 bytes long and consists of a
960/// 16-bit unsigned integer followed by a two-octet RFFU (Reserved For
961/// Future Use) field, which MUST be set to 0 on transmission and MUST be
962/// ignored on reception.
963#[derive(Debug, Clone, Copy)]
964pub struct ChannelNumber;
965
966impl<'a> Attribute<'a> for ChannelNumber {
967 type Error = Error;
968 type Item = u16;
969
970 const TYPE: AttributeType = AttributeType::ChannelNumber;
971
972 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
973 bytes.put_u16(value)
974 }
975
976 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
977 Ok(u16::from_be_bytes(bytes[..2].try_into()?))
978 }
979}
980
981/// The ICE-CONTROLLING attribute is present in a Binding request. The
982/// attribute indicates that the client believes it is currently in the
983/// controlling role. The content of the attribute is a 64-bit unsigned
984/// integer in network byte order, which contains a random number. As
985/// for the ICE-CONTROLLED attribute, the number is used for solving role
986/// conflicts. An agent MUST use the same number for all Binding
987/// requests, for all streams, within an ICE session, unless it has
988/// received a 487 response, in which case it MUST change the number.
989/// The agent MAY change the number when an ICE restart occurs.
990#[derive(Debug, Clone, Copy)]
991pub struct IceControlling;
992
993impl<'a> Attribute<'a> for IceControlling {
994 type Error = Error;
995 type Item = u64;
996
997 const TYPE: AttributeType = AttributeType::IceControlling;
998
999 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
1000 bytes.put_u64(value)
1001 }
1002
1003 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1004 Ok(u64::from_be_bytes(bytes.try_into()?))
1005 }
1006}
1007
1008/// The USE-CANDIDATE attribute indicates that the candidate pair
1009/// resulting from this check will be used for transmission of data. The
1010/// attribute has no content (the Length field of the attribute is zero);
1011/// it serves as a flag. It has an attribute value of 0x0025.
1012#[derive(Debug, Clone, Copy)]
1013pub struct UseCandidate;
1014
1015impl<'a> Attribute<'a> for UseCandidate {
1016 type Error = Error;
1017 type Item = ();
1018
1019 const TYPE: AttributeType = AttributeType::UseCandidate;
1020
1021 fn serialize<B: BufMut>(_: Self::Item, _: &mut B, _: &'a [u8]) {}
1022
1023 fn deserialize(_: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1024 Ok(())
1025 }
1026}
1027
1028/// The ICE-CONTROLLED attribute is present in a Binding request. The
1029/// attribute indicates that the client believes it is currently in the
1030/// controlled role. The content of the attribute is a 64-bit unsigned
1031/// integer in network byte order, which contains a random number. The
1032/// number is used for solving role conflicts, when it is referred to as
1033/// the "tiebreaker value". An ICE agent MUST use the same number for
1034/// all Binding requests, for all streams, within an ICE session, unless
1035/// it has received a 487 response, in which case it MUST change the
1036/// number. The agent MAY change the number when an ICE restart occurs.
1037#[derive(Debug, Clone, Copy)]
1038pub struct IceControlled;
1039
1040impl<'a> Attribute<'a> for IceControlled {
1041 type Error = Error;
1042 type Item = u64;
1043
1044 const TYPE: AttributeType = AttributeType::IceControlled;
1045
1046 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
1047 bytes.put_u64(value)
1048 }
1049
1050 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1051 Ok(u64::from_be_bytes(bytes.try_into()?))
1052 }
1053}
1054
1055/// The PRIORITY attribute indicates the priority that is to be
1056/// associated with a peer-reflexive candidate, if one will be discovered
1057/// by this check. It is a 32-bit unsigned integer and has an attribute
1058/// value of 0x0024.
1059#[derive(Debug, Clone, Copy)]
1060pub struct Priority;
1061
1062impl<'a> Attribute<'a> for Priority {
1063 type Error = Error;
1064 type Item = u32;
1065
1066 const TYPE: AttributeType = AttributeType::Priority;
1067
1068 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
1069 bytes.put_u32(value)
1070 }
1071
1072 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1073 Ok(u32::from_be_bytes(bytes.try_into()?))
1074 }
1075}
1076
1077/// The RESERVATION-TOKEN attribute contains a transaction_id that uniquely identifies a
1078/// relayed transport address being held in reserve by the server. The server
1079/// includes this attribute in a success response to tell the client about the
1080/// transaction_id, and the client includes this attribute in a subsequent Allocate
1081/// request to request the server use that relayed transport address for the
1082/// allocation.
1083///
1084/// The attribute value is 8 bytes and contains the transaction_id value.
1085#[derive(Debug, Clone, Copy)]
1086pub struct ReservationToken;
1087
1088impl<'a> Attribute<'a> for ReservationToken {
1089 type Error = Error;
1090 type Item = u64;
1091
1092 const TYPE: AttributeType = AttributeType::ReservationToken;
1093
1094 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
1095 bytes.put_u64(value)
1096 }
1097
1098 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1099 Ok(u64::from_be_bytes(bytes.try_into()?))
1100 }
1101}
1102
1103/// This attribute allows the client to request that the port in the relayed
1104/// transport address be even, and (optionally) that the server reserve the
1105/// next-higher port number. The value portion of this attribute is 1 byte
1106/// long.
1107#[derive(Debug, Clone, Copy)]
1108pub struct EvenPort;
1109
1110impl<'a> Attribute<'a> for EvenPort {
1111 type Error = Error;
1112 type Item = bool;
1113
1114 const TYPE: AttributeType = AttributeType::EvenPort;
1115
1116 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
1117 bytes.put_u8(if value { 0b10000000 } else { 0b00000000 })
1118 }
1119
1120 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1121 if bytes.is_empty() {
1122 return Err(Error::InvalidInput);
1123 }
1124
1125 Ok(bytes[0] == 0b10000000)
1126 }
1127}
1128
1129/// The REQUESTED-ADDRESS-FAMILY attribute is used by clients to request the
1130/// allocation of a specific address type from a server. The following is the
1131/// format of the REQUESTED-ADDRESS-FAMILY attribute. Note that TURN attributes
1132/// are TLV (Type-Length-Value) encoded, with a 16-bit type, a 16-bit length,
1133/// and a variable-length value.
1134#[derive(Debug, Clone, Copy)]
1135pub struct RequestedAddressFamily;
1136
1137impl<'a> Attribute<'a> for RequestedAddressFamily {
1138 type Error = Error;
1139 type Item = IpFamily;
1140
1141 const TYPE: AttributeType = AttributeType::RequestedAddressFamily;
1142
1143 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
1144 bytes.put_u8(value as u8)
1145 }
1146
1147 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1148 if bytes.is_empty() {
1149 return Err(Error::InvalidInput);
1150 }
1151
1152 IpFamily::try_from(bytes[0]).map_err(|_| Error::InvalidInput)
1153 }
1154}
1155
1156/// This attribute is used by clients to request the allocation of an IPv4 and
1157/// IPv6 address type from a server. It is encoded in the same way as the
1158/// REQUESTED-ADDRESS-FAMILY attribute; The ADDITIONAL-ADDRESS-FAMILY attribute
1159/// MAY be present in the Allocate request. The attribute value of 0x02 (IPv6
1160/// address) is the only valid value in Allocate request.
1161#[derive(Debug, Clone, Copy)]
1162pub struct AdditionalAddressFamily;
1163
1164impl<'a> Attribute<'a> for AdditionalAddressFamily {
1165 type Error = Error;
1166 type Item = IpFamily;
1167
1168 const TYPE: AttributeType = AttributeType::AdditionalAddressFamily;
1169
1170 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
1171 bytes.put_u8(value as u8)
1172 }
1173
1174 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1175 if bytes.is_empty() {
1176 return Err(Error::InvalidInput);
1177 }
1178
1179 IpFamily::try_from(bytes[0]).map_err(|_| Error::InvalidInput)
1180 }
1181}
1182
1183/// This attribute is used by the client to request that the server set the DF
1184/// (Don't Fragment) bit in the IP header when relaying the application data
1185/// onward to the peer and for determining the server capability in Allocate
1186/// requests. This attribute has no value part, and thus, the attribute length
1187/// field is 0.
1188#[derive(Debug, Clone, Copy)]
1189pub struct DontFragment;
1190
1191impl<'a> Attribute<'a> for DontFragment {
1192 type Error = Error;
1193 type Item = ();
1194
1195 const TYPE: AttributeType = AttributeType::DontFragment;
1196
1197 fn deserialize(_: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1198 Ok(())
1199 }
1200}
1201
1202/// This attribute is used by the STUN server to inform the client that
1203/// it supports third-party authorization. This attribute value contains
1204/// the STUN server name. The authorization server may have tie ups with
1205/// multiple STUN servers and vice versa, so the client MUST provide the
1206/// STUN server name to the authorization server so that it can select
1207/// the appropriate keying material to generate the self-contained transaction_id.
1208/// If the authorization server does not have tie up with the STUN
1209/// server, then it returns an error to the client. If the client does
1210/// not support or is not capable of doing third-party authorization,
1211/// then it defaults to first-party authentication. The
1212/// THIRD-PARTY-AUTHORIZATION attribute is a comprehension-optional
1213/// attribute (see Section 15 from [RFC5389]). If the client is able to
1214/// comprehend THIRD-PARTY-AUTHORIZATION, it MUST ensure that third-party
1215/// authorization takes precedence over first-party authentication (as
1216/// explained in Section 10 of [RFC5389]).
1217#[derive(Debug, Clone, Copy)]
1218pub struct ThirdPartyAuathorization;
1219
1220impl<'a> Attribute<'a> for ThirdPartyAuathorization {
1221 type Error = Error;
1222 type Item = &'a str;
1223
1224 const TYPE: AttributeType = AttributeType::ThirdPartyAuathorization;
1225
1226 fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
1227 bytes.put(value.as_bytes());
1228 }
1229
1230 fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
1231 Ok(std::str::from_utf8(bytes)?)
1232 }
1233}