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