turn_server/codec/message/attributes/error.rs
1use num_enum::TryFromPrimitive;
2
3/// The following error codes, along with their recommended reason
4/// phrases, are defined:
5///
6/// 300 Try Alternate: The client should contact an alternate server for
7/// this request. This error response MUST only be sent if the
8/// request included either a USERNAME or USERHASH attribute and a
9/// valid MESSAGE-INTEGRITY or MESSAGE-INTEGRITY-SHA256 attribute;
10/// otherwise, it MUST NOT be sent and error code 400 (Bad Request)
11/// is suggested. This error response MUST be protected with the
12/// MESSAGE-INTEGRITY or MESSAGE-INTEGRITY-SHA256 attribute, and
13/// receivers MUST validate the MESSAGE-INTEGRITY or MESSAGE-
14/// INTEGRITY-SHA256 of this response before redirecting themselves
15/// to an alternate server.
16/// Note: Failure to generate and validate message integrity for a
17/// 300 response allows an on-path attacker to falsify a 300
18/// response thus causing subsequent STUN messages to be sent to a
19/// victim.
20///
21/// 400 Bad Request: The request was malformed. The client SHOULD NOT
22/// retry the request without modification from the previous
23/// attempt. The server may not be able to generate a valid
24/// MESSAGE-INTEGRITY or MESSAGE-INTEGRITY-SHA256 for this error, so
25/// the client MUST NOT expect a valid MESSAGE-INTEGRITY or MESSAGE-
26/// INTEGRITY-SHA256 attribute on this response.
27///
28/// 401 Unauthenticated: The request did not contain the correct
29/// credentials to proceed. The client should retry the request
30/// with proper credentials.
31///
32/// 420 Unknown Attribute: The server received a STUN packet containing
33/// a comprehension-required attribute that it did not understand.
34/// The server MUST put this unknown attribute in the UNKNOWN-
35/// ATTRIBUTE attribute of its error response.
36///
37/// 438 Stale Nonce: The NONCE used by the client was no longer valid.
38/// The client should retry, using the NONCE provided in the
39/// response.
40///
41/// 500 Server Error: The server has suffered a temporary error. The
42/// client should try again.
43const fn errno(code: u16) -> u16 {
44 ((code / 100) << 8) | (code % 100)
45}
46
47#[repr(u16)]
48#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, TryFromPrimitive)]
49pub enum ErrorType {
50 TryAlternate = errno(300),
51 BadRequest = errno(400),
52 Unauthorized = errno(401),
53 Forbidden = errno(403),
54 UnknownAttribute = errno(420),
55 AllocationMismatch = errno(437),
56 StaleNonce = errno(438),
57 AddressFamilyNotSupported = errno(440),
58 WrongCredentials = errno(441),
59 UnsupportedTransportAddress = errno(442),
60 PeerAddressFamilyMismatch = errno(443),
61 AllocationQuotaReached = errno(486),
62 ServerError = errno(500),
63 InsufficientCapacity = errno(508),
64}
65
66impl From<ErrorType> for &'static str {
67 /// # Test
68 ///
69 /// ```
70 /// use std::convert::Into;
71 /// use turn_server::codec::message::attributes::error::ErrorType;
72 /// use turn_server::codec::Error;
73 ///
74 /// let err: &'static str = ErrorType::TryAlternate.into();
75 /// assert_eq!(err, "Try Alternate");
76 /// ```
77 #[rustfmt::skip]
78 fn from(val: ErrorType) -> Self {
79 match val {
80 ErrorType::TryAlternate => "Try Alternate",
81 ErrorType::BadRequest => "Bad Request",
82 ErrorType::Unauthorized => "Unauthorized",
83 ErrorType::Forbidden => "Forbidden",
84 ErrorType::UnknownAttribute => "Unknown Attribute",
85 ErrorType::AllocationMismatch => "Allocation Mismatch",
86 ErrorType::StaleNonce => "Stale Nonce",
87 ErrorType::AddressFamilyNotSupported => "Address Family not Supported",
88 ErrorType::WrongCredentials => "Wrong Credentials",
89 ErrorType::UnsupportedTransportAddress => "Unsupported Transport Address",
90 ErrorType::AllocationQuotaReached => "Allocation Quota Reached",
91 ErrorType::ServerError => "Server Error",
92 ErrorType::InsufficientCapacity => "Insufficient Capacity",
93 ErrorType::PeerAddressFamilyMismatch => "Peer Address Family Mismatch",
94 }
95 }
96}