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}