1#[cfg(test)]
2mod message_test;
3
4use crate::attributes::*;
5use shared::error::*;
6
7use base64::prelude::*;
8use rand::Rng;
9use std::fmt;
10use std::io::{Read, Write};
11
12pub const MAGIC_COOKIE: u32 = 0x2112A442;
21pub const ATTRIBUTE_HEADER_SIZE: usize = 4;
22pub const MESSAGE_HEADER_SIZE: usize = 20;
23
24pub const TRANSACTION_ID_SIZE: usize = 12; #[derive(PartialEq, Eq, Hash, Copy, Clone, Default, Debug)]
28pub struct TransactionId(pub [u8; TRANSACTION_ID_SIZE]);
29
30impl TransactionId {
31 pub fn new() -> Self {
34 let mut b = TransactionId([0u8; TRANSACTION_ID_SIZE]);
35 rand::thread_rng().fill(&mut b.0);
36 b
37 }
38}
39
40impl Setter for TransactionId {
41 fn add_to(&self, m: &mut Message) -> Result<()> {
42 m.transaction_id = *self;
43 m.write_transaction_id();
44 Ok(())
45 }
46}
47
48pub trait Setter {
51 fn add_to(&self, m: &mut Message) -> Result<()>;
53}
54
55pub trait Getter {
57 fn get_from(&mut self, m: &Message) -> Result<()>;
58}
59
60pub trait Checker {
62 fn check(&self, m: &Message) -> Result<()>;
63}
64
65pub fn is_message(b: &[u8]) -> bool {
69 b.len() >= MESSAGE_HEADER_SIZE && u32::from_be_bytes([b[4], b[5], b[6], b[7]]) == MAGIC_COOKIE
70}
71#[derive(Default, Debug, Clone)]
78pub struct Message {
79 pub typ: MessageType,
80 pub length: u32, pub transaction_id: TransactionId,
82 pub attributes: Attributes,
83 pub raw: Vec<u8>,
84}
85
86impl fmt::Display for Message {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 let t_id = BASE64_STANDARD.encode(self.transaction_id.0);
89 write!(
90 f,
91 "{} l={} attrs={} id={}",
92 self.typ,
93 self.length,
94 self.attributes.0.len(),
95 t_id
96 )
97 }
98}
99
100impl PartialEq for Message {
103 fn eq(&self, other: &Self) -> bool {
104 if self.typ != other.typ {
105 return false;
106 }
107 if self.transaction_id != other.transaction_id {
108 return false;
109 }
110 if self.length != other.length {
111 return false;
112 }
113 if self.attributes != other.attributes {
114 return false;
115 }
116 true
117 }
118}
119
120const DEFAULT_RAW_CAPACITY: usize = 120;
121
122impl Setter for Message {
123 fn add_to(&self, b: &mut Message) -> Result<()> {
127 b.transaction_id = self.transaction_id;
128 b.write_transaction_id();
129 Ok(())
130 }
131}
132
133impl Message {
134 pub fn new() -> Self {
136 Message {
137 raw: {
138 let mut raw = Vec::with_capacity(DEFAULT_RAW_CAPACITY);
139 raw.extend_from_slice(&[0; MESSAGE_HEADER_SIZE]);
140 raw
141 },
142 ..Default::default()
143 }
144 }
145
146 pub fn marshal_binary(&self) -> Result<Vec<u8>> {
148 Ok(self.raw.clone())
151 }
152
153 pub fn unmarshal_binary(&mut self, data: &[u8]) -> Result<()> {
155 self.raw.clear();
157 self.raw.extend_from_slice(data);
158 self.decode()
159 }
160
161 pub fn new_transaction_id(&mut self) -> Result<()> {
164 rand::thread_rng().fill(&mut self.transaction_id.0);
165 self.write_transaction_id();
166 Ok(())
167 }
168
169 pub fn reset(&mut self) {
171 self.raw.clear();
172 self.length = 0;
173 self.attributes.0.clear();
174 }
175
176 fn grow(&mut self, n: usize, resize: bool) {
178 if self.raw.len() >= n {
179 if resize {
180 self.raw.resize(n, 0);
181 }
182 return;
183 }
184 self.raw.extend_from_slice(&vec![0; n - self.raw.len()]);
185 }
186
187 pub fn add(&mut self, t: AttrType, v: &[u8]) {
192 let alloc_size = ATTRIBUTE_HEADER_SIZE + v.len(); let first = MESSAGE_HEADER_SIZE + self.length as usize; let mut last = first + alloc_size; self.grow(last, true); self.length += alloc_size as u32; let buf = &mut self.raw[first..last];
209 buf[0..2].copy_from_slice(&t.value().to_be_bytes()); buf[2..4].copy_from_slice(&(v.len() as u16).to_be_bytes()); let value = &mut buf[ATTRIBUTE_HEADER_SIZE..];
213 value.copy_from_slice(v); let attr = RawAttribute {
216 typ: t, length: v.len() as u16, value: value.to_vec(), };
220
221 if attr.length as usize % PADDING != 0 {
223 let bytes_to_add = nearest_padded_value_length(v.len()) - v.len();
225 last += bytes_to_add;
226 self.grow(last, true);
227 let buf = &mut self.raw[last - bytes_to_add..last];
231 for b in buf {
232 *b = 0;
233 }
234 self.length += bytes_to_add as u32; }
236 self.attributes.0.push(attr);
237 self.write_length();
238 }
239
240 pub fn write_length(&mut self) {
242 self.grow(4, false);
243 self.raw[2..4].copy_from_slice(&(self.length as u16).to_be_bytes());
244 }
245
246 pub fn write_header(&mut self) {
248 self.grow(MESSAGE_HEADER_SIZE, false);
249
250 self.write_type();
251 self.write_length();
252 self.raw[4..8].copy_from_slice(&MAGIC_COOKIE.to_be_bytes()); self.raw[8..MESSAGE_HEADER_SIZE].copy_from_slice(&self.transaction_id.0);
254 }
256
257 pub fn write_transaction_id(&mut self) {
259 self.raw[8..MESSAGE_HEADER_SIZE].copy_from_slice(&self.transaction_id.0);
260 }
262
263 pub fn write_attributes(&mut self) {
265 let attributes: Vec<RawAttribute> = self.attributes.0.drain(..).collect();
266 for a in &attributes {
267 self.add(a.typ, &a.value);
268 }
269 self.attributes = Attributes(attributes);
270 }
271
272 pub fn write_type(&mut self) {
274 self.grow(2, false);
275 self.raw[..2].copy_from_slice(&self.typ.value().to_be_bytes()); }
277
278 pub fn set_type(&mut self, t: MessageType) {
280 self.typ = t;
281 self.write_type();
282 }
283
284 pub fn encode(&mut self) {
286 self.raw.clear();
287 self.write_header();
288 self.length = 0;
289 self.write_attributes();
290 }
291
292 pub fn decode(&mut self) -> Result<()> {
294 let buf = &self.raw;
296 if buf.len() < MESSAGE_HEADER_SIZE {
297 return Err(Error::ErrUnexpectedHeaderEof);
298 }
299
300 let t = u16::from_be_bytes([buf[0], buf[1]]); let size = u16::from_be_bytes([buf[2], buf[3]]) as usize; let cookie = u32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]); let full_size = MESSAGE_HEADER_SIZE + size; if cookie != MAGIC_COOKIE {
306 return Err(Error::Other(format!(
307 "{cookie:x} is invalid magic cookie (should be {MAGIC_COOKIE:x})"
308 )));
309 }
310 if buf.len() < full_size {
311 return Err(Error::Other(format!(
312 "buffer length {} is less than {} (expected message size)",
313 buf.len(),
314 full_size
315 )));
316 }
317
318 self.typ.read_value(t);
320 self.length = size as u32;
321 self.transaction_id
322 .0
323 .copy_from_slice(&buf[8..MESSAGE_HEADER_SIZE]);
324
325 self.attributes.0.clear();
326 let mut offset = 0;
327 let mut b = &buf[MESSAGE_HEADER_SIZE..full_size];
328
329 while offset < size {
330 if b.len() < ATTRIBUTE_HEADER_SIZE {
332 return Err(Error::Other(format!(
333 "buffer length {} is less than {} (expected header size)",
334 b.len(),
335 ATTRIBUTE_HEADER_SIZE
336 )));
337 }
338
339 let mut a = RawAttribute {
340 typ: compat_attr_type(u16::from_be_bytes([b[0], b[1]])), length: u16::from_be_bytes([b[2], b[3]]), ..Default::default()
343 };
344 let a_l = a.length as usize; let a_buff_l = nearest_padded_value_length(a_l); b = &b[ATTRIBUTE_HEADER_SIZE..]; offset += ATTRIBUTE_HEADER_SIZE;
349 if b.len() < a_buff_l {
350 return Err(Error::Other(format!(
352 "buffer length {} is less than {} (expected value size for {})",
353 b.len(),
354 a_buff_l,
355 a.typ
356 )));
357 }
358 a.value = b[..a_l].to_vec();
359 offset += a_buff_l;
360 b = &b[a_buff_l..];
361
362 self.attributes.0.push(a);
363 }
364
365 Ok(())
366 }
367
368 pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> {
371 let n = writer.write(&self.raw)?;
372 Ok(n)
373 }
374
375 pub fn read_from<R: Read>(&mut self, reader: &mut R) -> Result<usize> {
381 let mut t_buf = vec![0; DEFAULT_RAW_CAPACITY];
382 let n = reader.read(&mut t_buf)?;
383 self.raw = t_buf[..n].to_vec();
384 self.decode()?;
385 Ok(n)
386 }
387
388 pub fn write(&mut self, t_buf: &[u8]) -> Result<usize> {
392 self.raw.clear();
393 self.raw.extend_from_slice(t_buf);
394 self.decode()?;
395 Ok(t_buf.len())
396 }
397
398 pub fn clone_to(&self, b: &mut Message) -> Result<()> {
400 b.raw.clear();
401 b.raw.extend_from_slice(&self.raw);
402 b.decode()
403 }
404
405 pub fn contains(&self, t: AttrType) -> bool {
407 for a in &self.attributes.0 {
408 if a.typ == t {
409 return true;
410 }
411 }
412 false
413 }
414
415 pub fn get(&self, t: AttrType) -> Result<Vec<u8>> {
419 let (v, ok) = self.attributes.get(t);
420 if ok {
421 Ok(v.value)
422 } else {
423 Err(Error::ErrAttributeNotFound)
424 }
425 }
426
427 pub fn build(&mut self, setters: &[Box<dyn Setter>]) -> Result<()> {
443 self.reset();
444 self.write_header();
445 for s in setters {
446 s.add_to(self)?;
447 }
448 Ok(())
449 }
450
451 pub fn check<C: Checker>(&self, checkers: &[C]) -> Result<()> {
453 for c in checkers {
454 c.check(self)?;
455 }
456 Ok(())
457 }
458
459 pub fn parse<G: Getter>(&self, getters: &mut [G]) -> Result<()> {
461 for c in getters {
462 c.get_from(self)?;
463 }
464 Ok(())
465 }
466}
467
468#[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
470pub struct MessageClass(u8);
471
472pub const CLASS_REQUEST: MessageClass = MessageClass(0x00); pub const CLASS_INDICATION: MessageClass = MessageClass(0x01); pub const CLASS_SUCCESS_RESPONSE: MessageClass = MessageClass(0x02); pub const CLASS_ERROR_RESPONSE: MessageClass = MessageClass(0x03); impl fmt::Display for MessageClass {
479 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
480 let s = match *self {
481 CLASS_REQUEST => "request",
482 CLASS_INDICATION => "indication",
483 CLASS_SUCCESS_RESPONSE => "success response",
484 CLASS_ERROR_RESPONSE => "error response",
485 _ => "unknown message class",
486 };
487
488 write!(f, "{s}")
489 }
490}
491
492#[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
494pub struct Method(u16);
495
496pub const METHOD_BINDING: Method = Method(0x001);
498pub const METHOD_ALLOCATE: Method = Method(0x003);
499pub const METHOD_REFRESH: Method = Method(0x004);
500pub const METHOD_SEND: Method = Method(0x006);
501pub const METHOD_DATA: Method = Method(0x007);
502pub const METHOD_CREATE_PERMISSION: Method = Method(0x008);
503pub const METHOD_CHANNEL_BIND: Method = Method(0x009);
504
505pub const METHOD_CONNECT: Method = Method(0x000a);
507pub const METHOD_CONNECTION_BIND: Method = Method(0x000b);
508pub const METHOD_CONNECTION_ATTEMPT: Method = Method(0x000c);
509
510impl fmt::Display for Method {
511 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
512 let unknown = format!("0x{:x}", self.0);
513
514 let s = match *self {
515 METHOD_BINDING => "Binding",
516 METHOD_ALLOCATE => "Allocate",
517 METHOD_REFRESH => "Refresh",
518 METHOD_SEND => "Send",
519 METHOD_DATA => "Data",
520 METHOD_CREATE_PERMISSION => "CreatePermission",
521 METHOD_CHANNEL_BIND => "ChannelBind",
522
523 METHOD_CONNECT => "Connect",
525 METHOD_CONNECTION_BIND => "ConnectionBind",
526 METHOD_CONNECTION_ATTEMPT => "ConnectionAttempt",
527 _ => unknown.as_str(),
528 };
529
530 write!(f, "{s}")
531 }
532}
533
534#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
536pub struct MessageType {
537 pub method: Method, pub class: MessageClass, }
540
541pub const BINDING_REQUEST: MessageType = MessageType {
544 method: METHOD_BINDING,
545 class: CLASS_REQUEST,
546};
547pub const BINDING_SUCCESS: MessageType = MessageType {
549 method: METHOD_BINDING,
550 class: CLASS_SUCCESS_RESPONSE,
551};
552pub const BINDING_ERROR: MessageType = MessageType {
554 method: METHOD_BINDING,
555 class: CLASS_ERROR_RESPONSE,
556};
557
558impl fmt::Display for MessageType {
559 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
560 write!(f, "{} {}", self.method, self.class)
561 }
562}
563
564const METHOD_ABITS: u16 = 0xf; const METHOD_BBITS: u16 = 0x70; const METHOD_DBITS: u16 = 0xf80; const METHOD_BSHIFT: u16 = 1;
569const METHOD_DSHIFT: u16 = 2;
570
571const FIRST_BIT: u16 = 0x1;
572const SECOND_BIT: u16 = 0x2;
573
574const C0BIT: u16 = FIRST_BIT;
575const C1BIT: u16 = SECOND_BIT;
576
577const CLASS_C0SHIFT: u16 = 4;
578const CLASS_C1SHIFT: u16 = 7;
579
580impl Setter for MessageType {
581 fn add_to(&self, m: &mut Message) -> Result<()> {
583 m.set_type(*self);
584 Ok(())
585 }
586}
587
588impl MessageType {
589 pub fn new(method: Method, class: MessageClass) -> Self {
591 MessageType { method, class }
592 }
593
594 pub fn value(&self) -> u16 {
596 let method = self.method.0;
607 let a = method & METHOD_ABITS; let b = method & METHOD_BBITS; let d = method & METHOD_DBITS; let method = a + (b << METHOD_BSHIFT) + (d << METHOD_DSHIFT);
613
614 let c = self.class.0 as u16;
621 let c0 = (c & C0BIT) << CLASS_C0SHIFT;
622 let c1 = (c & C1BIT) << CLASS_C1SHIFT;
623 let class = c0 + c1;
624
625 method + class
626 }
627
628 pub fn read_value(&mut self, value: u16) {
630 let c0 = (value >> CLASS_C0SHIFT) & C0BIT;
633 let c1 = (value >> CLASS_C1SHIFT) & C1BIT;
634 let class = c0 + c1;
635 self.class = MessageClass(class as u8);
636
637 let a = value & METHOD_ABITS; let b = (value >> METHOD_BSHIFT) & METHOD_BBITS; let d = (value >> METHOD_DSHIFT) & METHOD_DBITS; let m = a + b + d;
642 self.method = Method(m);
643 }
644}