xref: /webrtc/stun/src/error_code.rs (revision d65e701f)
1 use crate::attributes::*;
2 use crate::checks::*;
3 use crate::errors::*;
4 use crate::message::*;
5 
6 use util::Error;
7 
8 use std::collections::HashMap;
9 use std::fmt;
10 
11 // ErrorCodeAttribute represents ERROR-CODE attribute.
12 //
13 // RFC 5389 Section 15.6
14 pub struct ErrorCodeAttribute {
15     pub code: ErrorCode,
16     pub reason: Vec<u8>,
17 }
18 
19 impl fmt::Display for ErrorCodeAttribute {
20     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21         let reason = match String::from_utf8(self.reason.clone()) {
22             Ok(reason) => reason,
23             Err(_) => return Err(fmt::Error {}),
24         };
25 
26         write!(f, "{}: {}", self.code.0, reason)
27     }
28 }
29 
30 // constants for ERROR-CODE encoding.
31 const ERROR_CODE_CLASS_BYTE: usize = 2;
32 const ERROR_CODE_NUMBER_BYTE: usize = 3;
33 const ERROR_CODE_REASON_START: usize = 4;
34 const ERROR_CODE_REASON_MAX_B: usize = 763;
35 const ERROR_CODE_MODULO: u16 = 100;
36 
37 impl ErrorCodeAttribute {
38     // AddTo adds ERROR-CODE to m.
39     pub fn add_to(&self, _m: &Message) -> Result<(), Error> {
40         check_overflow(
41             ATTR_ERROR_CODE,
42             self.reason.len() + ERROR_CODE_REASON_START,
43             ERROR_CODE_REASON_MAX_B + ERROR_CODE_REASON_START,
44         )?;
45 
46         let mut value: Vec<u8> = Vec::with_capacity(ERROR_CODE_REASON_MAX_B);
47 
48         let number = (self.code.0 % ERROR_CODE_MODULO) as u8; // error code modulo 100
49         let class = (self.code.0 / ERROR_CODE_MODULO) as u8; // hundred digit
50         value.extend_from_slice(&[0, 0]);
51         value.push(class); // [ERROR_CODE_CLASS_BYTE]
52         value.push(number); //[ERROR_CODE_NUMBER_BYTE] =
53         value.extend_from_slice(&self.reason); //[ERROR_CODE_REASON_START:]
54 
55         //TODO: m.Add(AttrErrorCode, value)
56 
57         Ok(())
58     }
59 
60     // GetFrom decodes ERROR-CODE from m. Reason is valid until m.Raw is valid.
61     pub fn get_from(&mut self, _m: &Message) -> Result<(), Error> {
62         let v = vec![]; //TODO: m.Get(AttrErrorCode)?;
63 
64         if v.len() < ERROR_CODE_REASON_START {
65             return Err(ERR_UNEXPECTED_EOF.clone());
66         }
67 
68         let class = v[ERROR_CODE_CLASS_BYTE] as u16;
69         let number = v[ERROR_CODE_NUMBER_BYTE] as u16;
70         let code = class * ERROR_CODE_MODULO + number;
71         self.code = ErrorCode(code);
72         self.reason = v[ERROR_CODE_REASON_START..].to_vec();
73 
74         Ok(())
75     }
76 }
77 
78 // ErrorCode is code for ERROR-CODE attribute.
79 #[derive(PartialEq, Eq, Hash, Copy, Clone)]
80 pub struct ErrorCode(u16);
81 
82 impl ErrorCode {
83     // AddTo adds ERROR-CODE with default reason to m. If there
84     // is no default reason, returns ErrNoDefaultReason.
85     pub fn add_to(&self, m: &Message) -> Result<(), Error> {
86         if let Some(reason) = ERROR_REASONS.get(self) {
87             let a = ErrorCodeAttribute {
88                 code: *self,
89                 reason: reason.clone(),
90             };
91             a.add_to(m)
92         } else {
93             Err(ERR_NO_DEFAULT_REASON.clone())
94         }
95     }
96 }
97 
98 // Possible error codes.
99 pub const CODE_TRY_ALTERNATE: ErrorCode = ErrorCode(300);
100 pub const CODE_BAD_REQUEST: ErrorCode = ErrorCode(400);
101 pub const CODE_UNAUTHORIZED: ErrorCode = ErrorCode(401);
102 pub const CODE_UNKNOWN_ATTRIBUTE: ErrorCode = ErrorCode(420);
103 pub const CODE_STALE_NONCE: ErrorCode = ErrorCode(438);
104 pub const CODE_ROLE_CONFLICT: ErrorCode = ErrorCode(487);
105 pub const CODE_SERVER_ERROR: ErrorCode = ErrorCode(500);
106 
107 // DEPRECATED constants.
108 // DEPRECATED, use CODE_UNAUTHORIZED.
109 pub const CODE_UNAUTHORISED: ErrorCode = CODE_UNAUTHORIZED;
110 
111 // Error codes from RFC 5766.
112 //
113 // RFC 5766 Section 15
114 pub const CODE_FORBIDDEN: ErrorCode = ErrorCode(403); // Forbidden
115 pub const CODE_ALLOC_MISMATCH: ErrorCode = ErrorCode(437); // Allocation Mismatch
116 pub const CODE_WRONG_CREDENTIALS: ErrorCode = ErrorCode(441); // Wrong Credentials
117 pub const CODE_UNSUPPORTED_TRANS_PROTO: ErrorCode = ErrorCode(442); // Unsupported Transport Protocol
118 pub const CODE_ALLOC_QUOTA_REACHED: ErrorCode = ErrorCode(486); // Allocation Quota Reached
119 pub const CODE_INSUFFICIENT_CAPACITY: ErrorCode = ErrorCode(508); // Insufficient Capacity
120 
121 // Error codes from RFC 6062.
122 //
123 // RFC 6062 Section 6.3
124 pub const CODE_CONN_ALREADY_EXISTS: ErrorCode = ErrorCode(446);
125 pub const CODE_CONN_TIMEOUT_OR_FAILURE: ErrorCode = ErrorCode(447);
126 
127 // Error codes from RFC 6156.
128 //
129 // RFC 6156 Section 10.2
130 pub const CODE_ADDR_FAMILY_NOT_SUPPORTED: ErrorCode = ErrorCode(440); // Address Family not Supported
131 pub const CODE_PEER_ADDR_FAMILY_MISMATCH: ErrorCode = ErrorCode(443); // Peer Address Family Mismatch
132 
133 lazy_static! {
134     pub static ref ERROR_REASONS:HashMap<ErrorCode, Vec<u8>> =
135         [
136             (CODE_TRY_ALTERNATE,     b"Try Alternate".to_vec()),
137             (CODE_BAD_REQUEST,       b"Bad Request".to_vec()),
138             (CODE_UNAUTHORIZED,     b"Unauthorized".to_vec()),
139             (CODE_UNKNOWN_ATTRIBUTE, b"Unknown Attribute".to_vec()),
140             (CODE_STALE_NONCE,       b"Stale Nonce".to_vec()),
141             (CODE_SERVER_ERROR,      b"Server Error".to_vec()),
142             (CODE_ROLE_CONFLICT,     b"Role Conflict".to_vec()),
143 
144             // RFC 5766.
145             (CODE_FORBIDDEN,             b"Forbidden".to_vec()),
146             (CODE_ALLOC_MISMATCH,         b"Allocation Mismatch".to_vec()),
147             (CODE_WRONG_CREDENTIALS,      b"Wrong Credentials".to_vec()),
148             (CODE_UNSUPPORTED_TRANS_PROTO, b"Unsupported Transport Protocol".to_vec()),
149             (CODE_ALLOC_QUOTA_REACHED,     b"Allocation Quota Reached".to_vec()),
150             (CODE_INSUFFICIENT_CAPACITY,  b"Insufficient Capacity".to_vec()),
151 
152             // RFC 6062.
153             (CODE_CONN_ALREADY_EXISTS,    b"Connection Already Exists".to_vec()),
154             (CODE_CONN_TIMEOUT_OR_FAILURE, b"Connection Timeout or Failure".to_vec()),
155 
156             // RFC 6156.
157             (CODE_ADDR_FAMILY_NOT_SUPPORTED, b"Address Family not Supported".to_vec()),
158             (CODE_PEER_ADDR_FAMILY_MISMATCH, b"Peer Address Family Mismatch".to_vec()),
159         ].iter().cloned().collect();
160 
161 }
162