1 #[cfg(test)] 2 mod message_test; 3 4 use crate::agent::*; 5 use crate::attributes::*; 6 use crate::error::*; 7 8 use rand::Rng; 9 use std::fmt; 10 use std::io::{Read, Write}; 11 12 // MAGIC_COOKIE is fixed value that aids in distinguishing STUN packets 13 // from packets of other protocols when STUN is multiplexed with those 14 // other protocols on the same Port. 15 // 16 // The magic cookie field MUST contain the fixed value 0x2112A442 in 17 // network byte order. 18 // 19 // Defined in "STUN Message Structure", section 6. 20 pub const MAGIC_COOKIE: u32 = 0x2112A442; 21 pub const ATTRIBUTE_HEADER_SIZE: usize = 4; 22 pub const MESSAGE_HEADER_SIZE: usize = 20; 23 24 // TRANSACTION_ID_SIZE is length of transaction id array (in bytes). 25 pub const TRANSACTION_ID_SIZE: usize = 12; // 96 bit 26 27 // Interfaces that are implemented by message attributes, shorthands for them, 28 // or helpers for message fields as type or transaction id. 29 pub trait Setter { 30 // Setter sets *Message attribute. 31 fn add_to(&self, m: &mut Message) -> Result<()>; 32 } 33 34 // Getter parses attribute from *Message. 35 pub trait Getter { 36 fn get_from(&mut self, m: &Message) -> Result<()>; 37 } 38 39 // Checker checks *Message attribute. 40 pub trait Checker { 41 fn check(&self, m: &Message) -> Result<()>; 42 } 43 44 // is_message returns true if b looks like STUN message. 45 // Useful for multiplexing. is_message does not guarantee 46 // that decoding will be successful. 47 pub fn is_message(b: &[u8]) -> bool { 48 b.len() >= MESSAGE_HEADER_SIZE && u32::from_be_bytes([b[4], b[5], b[6], b[7]]) == MAGIC_COOKIE 49 } 50 // Message represents a single STUN packet. It uses aggressive internal 51 // buffering to enable zero-allocation encoding and decoding, 52 // so there are some usage constraints: 53 // 54 // Message, its fields, results of m.Get or any attribute a.GetFrom 55 // are valid only until Message.Raw is not modified. 56 #[derive(Default, Debug, Clone)] 57 pub struct Message { 58 pub typ: MessageType, 59 pub length: u32, // len(Raw) not including header 60 pub transaction_id: TransactionId, 61 pub attributes: Attributes, 62 pub raw: Vec<u8>, 63 } 64 65 impl fmt::Display for Message { 66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 67 let t_id = base64::encode(self.transaction_id.0); 68 write!( 69 f, 70 "{} l={} attrs={} id={}", 71 self.typ, 72 self.length, 73 self.attributes.0.len(), 74 t_id 75 ) 76 } 77 } 78 79 // Equal returns true if Message b equals to m. 80 // Ignores m.Raw. 81 impl PartialEq for Message { 82 fn eq(&self, other: &Self) -> bool { 83 if self.typ != other.typ { 84 return false; 85 } 86 if self.transaction_id != other.transaction_id { 87 return false; 88 } 89 if self.length != other.length { 90 return false; 91 } 92 if self.attributes != other.attributes { 93 return false; 94 } 95 true 96 } 97 } 98 99 const DEFAULT_RAW_CAPACITY: usize = 120; 100 101 impl Setter for Message { 102 // add_to sets b.TransactionID to m.TransactionID. 103 // 104 // Implements Setter to aid in crafting responses. 105 fn add_to(&self, b: &mut Message) -> Result<()> { 106 b.transaction_id = self.transaction_id; 107 b.write_transaction_id(); 108 Ok(()) 109 } 110 } 111 112 impl Message { 113 // New returns *Message with pre-allocated Raw. 114 pub fn new() -> Self { 115 Message { 116 raw: { 117 let mut raw = Vec::with_capacity(DEFAULT_RAW_CAPACITY); 118 raw.extend_from_slice(&[0; MESSAGE_HEADER_SIZE]); 119 raw 120 }, 121 ..Default::default() 122 } 123 } 124 125 // marshal_binary implements the encoding.BinaryMarshaler interface. 126 pub fn marshal_binary(&self) -> Result<Vec<u8>> { 127 // We can't return m.Raw, allocation is expected by implicit interface 128 // contract induced by other implementations. 129 Ok(self.raw.clone()) 130 } 131 132 // unmarshal_binary implements the encoding.BinaryUnmarshaler interface. 133 pub fn unmarshal_binary(&mut self, data: &[u8]) -> Result<()> { 134 // We can't retain data, copy is expected by interface contract. 135 self.raw.clear(); 136 self.raw.extend_from_slice(data); 137 self.decode() 138 } 139 140 // NewTransactionID sets m.TransactionID to random value from crypto/rand 141 // and returns error if any. 142 pub fn new_transaction_id(&mut self) -> Result<()> { 143 rand::thread_rng().fill(&mut self.transaction_id.0); 144 self.write_transaction_id(); 145 Ok(()) 146 } 147 148 // Reset resets Message, attributes and underlying buffer length. 149 pub fn reset(&mut self) { 150 self.raw.clear(); 151 self.length = 0; 152 self.attributes.0.clear(); 153 } 154 155 // grow ensures that internal buffer has n length. 156 fn grow(&mut self, n: usize, resize: bool) { 157 if self.raw.len() >= n { 158 if resize { 159 self.raw.resize(n, 0); 160 } 161 return; 162 } 163 self.raw.extend_from_slice(&vec![0; n - self.raw.len()]); 164 } 165 166 // Add appends new attribute to message. Not goroutine-safe. 167 // 168 // Value of attribute is copied to internal buffer so 169 // it is safe to reuse v. 170 pub fn add(&mut self, t: AttrType, v: &[u8]) { 171 // Allocating buffer for TLV (type-length-value). 172 // T = t, L = len(v), V = v. 173 // m.Raw will look like: 174 // [0:20] <- message header 175 // [20:20+m.Length] <- existing message attributes 176 // [20+m.Length:20+m.Length+len(v) + 4] <- allocated buffer for new TLV 177 // [first:last] <- same as previous 178 // [0 1|2 3|4 4 + len(v)] <- mapping for allocated buffer 179 // T L V 180 let alloc_size = ATTRIBUTE_HEADER_SIZE + v.len(); // ~ len(TLV) = len(TL) + len(V) 181 let first = MESSAGE_HEADER_SIZE + self.length as usize; // first byte number 182 let mut last = first + alloc_size; // last byte number 183 self.grow(last, true); // growing cap(Raw) to fit TLV 184 self.length += alloc_size as u32; // rendering length change 185 186 // Encoding attribute TLV to allocated buffer. 187 let buf = &mut self.raw[first..last]; 188 buf[0..2].copy_from_slice(&t.value().to_be_bytes()); // T 189 buf[2..4].copy_from_slice(&(v.len() as u16).to_be_bytes()); // L 190 191 let value = &mut buf[ATTRIBUTE_HEADER_SIZE..]; 192 value.copy_from_slice(v); // V 193 194 let attr = RawAttribute { 195 typ: t, // T 196 length: v.len() as u16, // L 197 value: value.to_vec(), // V 198 }; 199 200 // Checking that attribute value needs padding. 201 if attr.length as usize % PADDING != 0 { 202 // Performing padding. 203 let bytes_to_add = nearest_padded_value_length(v.len()) - v.len(); 204 last += bytes_to_add; 205 self.grow(last, true); 206 // setting all padding bytes to zero 207 // to prevent data leak from previous 208 // data in next bytes_to_add bytes 209 let buf = &mut self.raw[last - bytes_to_add..last]; 210 for b in buf { 211 *b = 0; 212 } 213 self.length += bytes_to_add as u32; // rendering length change 214 } 215 self.attributes.0.push(attr); 216 self.write_length(); 217 } 218 219 // WriteLength writes m.Length to m.Raw. 220 pub fn write_length(&mut self) { 221 self.grow(4, false); 222 self.raw[2..4].copy_from_slice(&(self.length as u16).to_be_bytes()); 223 } 224 225 // WriteHeader writes header to underlying buffer. Not goroutine-safe. 226 pub fn write_header(&mut self) { 227 self.grow(MESSAGE_HEADER_SIZE, false); 228 229 self.write_type(); 230 self.write_length(); 231 self.raw[4..8].copy_from_slice(&MAGIC_COOKIE.to_be_bytes()); // magic cookie 232 self.raw[8..MESSAGE_HEADER_SIZE].copy_from_slice(&self.transaction_id.0); 233 // transaction ID 234 } 235 236 // WriteTransactionID writes m.TransactionID to m.Raw. 237 pub fn write_transaction_id(&mut self) { 238 self.raw[8..MESSAGE_HEADER_SIZE].copy_from_slice(&self.transaction_id.0); 239 // transaction ID 240 } 241 242 // WriteAttributes encodes all m.Attributes to m. 243 pub fn write_attributes(&mut self) { 244 let attributes: Vec<RawAttribute> = self.attributes.0.drain(..).collect(); 245 for a in &attributes { 246 self.add(a.typ, &a.value); 247 } 248 self.attributes = Attributes(attributes); 249 } 250 251 // WriteType writes m.Type to m.Raw. 252 pub fn write_type(&mut self) { 253 self.grow(2, false); 254 self.raw[..2].copy_from_slice(&self.typ.value().to_be_bytes()); // message type 255 } 256 257 // SetType sets m.Type and writes it to m.Raw. 258 pub fn set_type(&mut self, t: MessageType) { 259 self.typ = t; 260 self.write_type(); 261 } 262 263 // Encode re-encodes message into m.Raw. 264 pub fn encode(&mut self) { 265 self.raw.clear(); 266 self.write_header(); 267 self.length = 0; 268 self.write_attributes(); 269 } 270 271 // Decode decodes m.Raw into m. 272 pub fn decode(&mut self) -> Result<()> { 273 // decoding message header 274 let buf = &self.raw; 275 if buf.len() < MESSAGE_HEADER_SIZE { 276 return Err(Error::ErrUnexpectedHeaderEof); 277 } 278 279 let t = u16::from_be_bytes([buf[0], buf[1]]); // first 2 bytes 280 let size = u16::from_be_bytes([buf[2], buf[3]]) as usize; // second 2 bytes 281 let cookie = u32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]); // last 4 bytes 282 let full_size = MESSAGE_HEADER_SIZE + size; // len(m.Raw) 283 284 if cookie != MAGIC_COOKIE { 285 return Err(Error::Other(format!( 286 "{:x} is invalid magic cookie (should be {:x})", 287 cookie, MAGIC_COOKIE 288 ))); 289 } 290 if buf.len() < full_size { 291 return Err(Error::Other(format!( 292 "buffer length {} is less than {} (expected message size)", 293 buf.len(), 294 full_size 295 ))); 296 } 297 298 // saving header data 299 self.typ.read_value(t); 300 self.length = size as u32; 301 self.transaction_id 302 .0 303 .copy_from_slice(&buf[8..MESSAGE_HEADER_SIZE]); 304 305 self.attributes.0.clear(); 306 let mut offset = 0; 307 let mut b = &buf[MESSAGE_HEADER_SIZE..full_size]; 308 309 while offset < size { 310 // checking that we have enough bytes to read header 311 if b.len() < ATTRIBUTE_HEADER_SIZE { 312 return Err(Error::Other(format!( 313 "buffer length {} is less than {} (expected header size)", 314 b.len(), 315 ATTRIBUTE_HEADER_SIZE 316 ))); 317 } 318 319 let mut a = RawAttribute { 320 typ: compat_attr_type(u16::from_be_bytes([b[0], b[1]])), // first 2 bytes 321 length: u16::from_be_bytes([b[2], b[3]]), // second 2 bytes 322 ..Default::default() 323 }; 324 let a_l = a.length as usize; // attribute length 325 let a_buff_l = nearest_padded_value_length(a_l); // expected buffer length (with padding) 326 327 b = &b[ATTRIBUTE_HEADER_SIZE..]; // slicing again to simplify value read 328 offset += ATTRIBUTE_HEADER_SIZE; 329 if b.len() < a_buff_l { 330 // checking size 331 return Err(Error::Other(format!( 332 "buffer length {} is less than {} (expected value size for {})", 333 b.len(), 334 a_buff_l, 335 a.typ 336 ))); 337 } 338 a.value = b[..a_l].to_vec(); 339 offset += a_buff_l; 340 b = &b[a_buff_l..]; 341 342 self.attributes.0.push(a); 343 } 344 345 Ok(()) 346 } 347 348 // WriteTo implements WriterTo via calling Write(m.Raw) on w and returning 349 // call result. 350 pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> { 351 let n = writer.write(&self.raw)?; 352 Ok(n) 353 } 354 355 // ReadFrom implements ReaderFrom. Reads message from r into m.Raw, 356 // Decodes it and return error if any. If m.Raw is too small, will return 357 // ErrUnexpectedEOF, ErrUnexpectedHeaderEOF or *DecodeErr. 358 // 359 // Can return *DecodeErr while decoding too. 360 pub fn read_from<R: Read>(&mut self, reader: &mut R) -> Result<usize> { 361 let mut t_buf = vec![0; DEFAULT_RAW_CAPACITY]; 362 let n = reader.read(&mut t_buf)?; 363 self.raw = t_buf[..n].to_vec(); 364 self.decode()?; 365 Ok(n) 366 } 367 368 // Write decodes message and return error if any. 369 // 370 // Any error is unrecoverable, but message could be partially decoded. 371 pub fn write(&mut self, t_buf: &[u8]) -> Result<usize> { 372 self.raw.clear(); 373 self.raw.extend_from_slice(t_buf); 374 self.decode()?; 375 Ok(t_buf.len()) 376 } 377 378 // CloneTo clones m to b securing any further m mutations. 379 pub fn clone_to(&self, b: &mut Message) -> Result<()> { 380 b.raw.clear(); 381 b.raw.extend_from_slice(&self.raw); 382 b.decode() 383 } 384 385 // Contains return true if message contain t attribute. 386 pub fn contains(&self, t: AttrType) -> bool { 387 for a in &self.attributes.0 { 388 if a.typ == t { 389 return true; 390 } 391 } 392 false 393 } 394 395 // get returns byte slice that represents attribute value, 396 // if there is no attribute with such type, 397 // ErrAttributeNotFound is returned. 398 pub fn get(&self, t: AttrType) -> Result<Vec<u8>> { 399 let (v, ok) = self.attributes.get(t); 400 if ok { 401 Ok(v.value) 402 } else { 403 Err(Error::ErrAttributeNotFound) 404 } 405 } 406 407 // Build resets message and applies setters to it in batch, returning on 408 // first error. To prevent allocations, pass pointers to values. 409 // 410 // Example: 411 // var ( 412 // t = BindingRequest 413 // username = NewUsername("username") 414 // nonce = NewNonce("nonce") 415 // realm = NewRealm("example.org") 416 // ) 417 // m := new(Message) 418 // m.Build(t, username, nonce, realm) // 4 allocations 419 // m.Build(&t, &username, &nonce, &realm) // 0 allocations 420 // 421 // See BenchmarkBuildOverhead. 422 pub fn build(&mut self, setters: &[Box<dyn Setter>]) -> Result<()> { 423 self.reset(); 424 self.write_header(); 425 for s in setters { 426 s.add_to(self)?; 427 } 428 Ok(()) 429 } 430 431 // Check applies checkers to message in batch, returning on first error. 432 pub fn check<C: Checker>(&self, checkers: &[C]) -> Result<()> { 433 for c in checkers { 434 c.check(self)?; 435 } 436 Ok(()) 437 } 438 439 // Parse applies getters to message in batch, returning on first error. 440 pub fn parse<G: Getter>(&self, getters: &mut [G]) -> Result<()> { 441 for c in getters { 442 c.get_from(self)?; 443 } 444 Ok(()) 445 } 446 } 447 448 // MessageClass is 8-bit representation of 2-bit class of STUN Message Class. 449 #[derive(Default, PartialEq, Eq, Debug, Copy, Clone)] 450 pub struct MessageClass(u8); 451 452 // Possible values for message class in STUN Message Type. 453 pub const CLASS_REQUEST: MessageClass = MessageClass(0x00); // 0b00 454 pub const CLASS_INDICATION: MessageClass = MessageClass(0x01); // 0b01 455 pub const CLASS_SUCCESS_RESPONSE: MessageClass = MessageClass(0x02); // 0b10 456 pub const CLASS_ERROR_RESPONSE: MessageClass = MessageClass(0x03); // 0b11 457 458 impl fmt::Display for MessageClass { 459 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 460 let s = match *self { 461 CLASS_REQUEST => "request", 462 CLASS_INDICATION => "indication", 463 CLASS_SUCCESS_RESPONSE => "success response", 464 CLASS_ERROR_RESPONSE => "error response", 465 _ => "unknown message class", 466 }; 467 468 write!(f, "{}", s) 469 } 470 } 471 472 // Method is uint16 representation of 12-bit STUN method. 473 #[derive(Default, PartialEq, Eq, Debug, Copy, Clone)] 474 pub struct Method(u16); 475 476 // Possible methods for STUN Message. 477 pub const METHOD_BINDING: Method = Method(0x001); 478 pub const METHOD_ALLOCATE: Method = Method(0x003); 479 pub const METHOD_REFRESH: Method = Method(0x004); 480 pub const METHOD_SEND: Method = Method(0x006); 481 pub const METHOD_DATA: Method = Method(0x007); 482 pub const METHOD_CREATE_PERMISSION: Method = Method(0x008); 483 pub const METHOD_CHANNEL_BIND: Method = Method(0x009); 484 485 // Methods from RFC 6062. 486 pub const METHOD_CONNECT: Method = Method(0x000a); 487 pub const METHOD_CONNECTION_BIND: Method = Method(0x000b); 488 pub const METHOD_CONNECTION_ATTEMPT: Method = Method(0x000c); 489 490 impl fmt::Display for Method { 491 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 492 let unknown = format!("0x{:x}", self.0); 493 494 let s = match *self { 495 METHOD_BINDING => "Binding", 496 METHOD_ALLOCATE => "Allocate", 497 METHOD_REFRESH => "Refresh", 498 METHOD_SEND => "Send", 499 METHOD_DATA => "Data", 500 METHOD_CREATE_PERMISSION => "CreatePermission", 501 METHOD_CHANNEL_BIND => "ChannelBind", 502 503 // RFC 6062. 504 METHOD_CONNECT => "Connect", 505 METHOD_CONNECTION_BIND => "ConnectionBind", 506 METHOD_CONNECTION_ATTEMPT => "ConnectionAttempt", 507 _ => unknown.as_str(), 508 }; 509 510 write!(f, "{}", s) 511 } 512 } 513 514 // MessageType is STUN Message Type Field. 515 #[derive(Default, Debug, PartialEq, Eq, Clone, Copy)] 516 pub struct MessageType { 517 pub method: Method, // e.g. binding 518 pub class: MessageClass, // e.g. request 519 } 520 521 // Common STUN message types. 522 // Binding request message type. 523 pub const BINDING_REQUEST: MessageType = MessageType { 524 method: METHOD_BINDING, 525 class: CLASS_REQUEST, 526 }; 527 // Binding success response message type 528 pub const BINDING_SUCCESS: MessageType = MessageType { 529 method: METHOD_BINDING, 530 class: CLASS_SUCCESS_RESPONSE, 531 }; 532 // Binding error response message type. 533 pub const BINDING_ERROR: MessageType = MessageType { 534 method: METHOD_BINDING, 535 class: CLASS_ERROR_RESPONSE, 536 }; 537 538 impl fmt::Display for MessageType { 539 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 540 write!(f, "{} {}", self.method, self.class) 541 } 542 } 543 544 const METHOD_ABITS: u16 = 0xf; // 0b0000000000001111 545 const METHOD_BBITS: u16 = 0x70; // 0b0000000001110000 546 const METHOD_DBITS: u16 = 0xf80; // 0b0000111110000000 547 548 const METHOD_BSHIFT: u16 = 1; 549 const METHOD_DSHIFT: u16 = 2; 550 551 const FIRST_BIT: u16 = 0x1; 552 const SECOND_BIT: u16 = 0x2; 553 554 const C0BIT: u16 = FIRST_BIT; 555 const C1BIT: u16 = SECOND_BIT; 556 557 const CLASS_C0SHIFT: u16 = 4; 558 const CLASS_C1SHIFT: u16 = 7; 559 560 impl Setter for MessageType { 561 // add_to sets m type to t. 562 fn add_to(&self, m: &mut Message) -> Result<()> { 563 m.set_type(*self); 564 Ok(()) 565 } 566 } 567 568 impl MessageType { 569 // NewType returns new message type with provided method and class. 570 pub fn new(method: Method, class: MessageClass) -> Self { 571 MessageType { method, class } 572 } 573 574 // Value returns bit representation of messageType. 575 pub fn value(&self) -> u16 { 576 // 0 1 577 // 2 3 4 5 6 7 8 9 0 1 2 3 4 5 578 // +--+--+-+-+-+-+-+-+-+-+-+-+-+-+ 579 // |M |M |M|M|M|C|M|M|M|C|M|M|M|M| 580 // |11|10|9|8|7|1|6|5|4|0|3|2|1|0| 581 // +--+--+-+-+-+-+-+-+-+-+-+-+-+-+ 582 // Figure 3: Format of STUN Message Type Field 583 584 // Warning: Abandon all hope ye who enter here. 585 // Splitting M into A(M0-M3), B(M4-M6), D(M7-M11). 586 let method = self.method.0; 587 let a = method & METHOD_ABITS; // A = M * 0b0000000000001111 (right 4 bits) 588 let b = method & METHOD_BBITS; // B = M * 0b0000000001110000 (3 bits after A) 589 let d = method & METHOD_DBITS; // D = M * 0b0000111110000000 (5 bits after B) 590 591 // Shifting to add "holes" for C0 (at 4 bit) and C1 (8 bit). 592 let method = a + (b << METHOD_BSHIFT) + (d << METHOD_DSHIFT); 593 594 // C0 is zero bit of C, C1 is first bit. 595 // C0 = C * 0b01, C1 = (C * 0b10) >> 1 596 // Ct = C0 << 4 + C1 << 8. 597 // Optimizations: "((C * 0b10) >> 1) << 8" as "(C * 0b10) << 7" 598 // We need C0 shifted by 4, and C1 by 8 to fit "11" and "7" positions 599 // (see figure 3). 600 let c = self.class.0 as u16; 601 let c0 = (c & C0BIT) << CLASS_C0SHIFT; 602 let c1 = (c & C1BIT) << CLASS_C1SHIFT; 603 let class = c0 + c1; 604 605 method + class 606 } 607 608 // ReadValue decodes uint16 into MessageType. 609 pub fn read_value(&mut self, value: u16) { 610 // Decoding class. 611 // We are taking first bit from v >> 4 and second from v >> 7. 612 let c0 = (value >> CLASS_C0SHIFT) & C0BIT; 613 let c1 = (value >> CLASS_C1SHIFT) & C1BIT; 614 let class = c0 + c1; 615 self.class = MessageClass(class as u8); 616 617 // Decoding method. 618 let a = value & METHOD_ABITS; // A(M0-M3) 619 let b = (value >> METHOD_BSHIFT) & METHOD_BBITS; // B(M4-M6) 620 let d = (value >> METHOD_DSHIFT) & METHOD_DBITS; // D(M7-M11) 621 let m = a + b + d; 622 self.method = Method(m); 623 } 624 } 625