xref: /webrtc/stun/src/message.rs (revision e32feda5)
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