Skip to main content

gbps/
message.rs

1use crate::peer::Peer;
2use std::error::Error;
3use std::fmt::Debug;
4
5const MSG_TYPE_REQ: u8 = 0x80; // 0b1000000
6const MSG_TYPE_RESP: u8 = 0x00;
7const MASK_MSG_TYPE: u8 = 0x80; // 0b1000000
8
9/// The message type
10#[derive(Debug)]
11pub enum MessageType {
12    Request,
13    Response
14}
15
16/// A peer sampling protocol message
17#[derive(Debug)]
18pub struct Message {
19    /// Address of the sender
20    sender: String,
21    /// Type of the message
22    message_type: MessageType,
23    /// The view of the sender
24    view: Option<Vec<Peer>>,
25}
26
27impl Message {
28
29    /// Creates a new message of type [MessageType::Request] containing a view
30    pub fn new_request(sender: String, view: Option<Vec<Peer>>) -> Message {
31        Self::new(sender, MessageType::Request, view)
32    }
33
34    /// Creates a new message of type [MessageType::Response] containing a view
35    pub fn new_response(sender: String, view: Option<Vec<Peer>>) -> Message {
36        Self::new(sender, MessageType::Response, view)
37    }
38
39    fn new(sender: String, message_type: MessageType, view: Option<Vec<Peer>>) -> Message {
40        Message{
41            sender,
42            message_type,
43            view
44        }
45    }
46
47    /// Returns the message sender
48    pub fn sender(&self) -> &str {
49        &self.sender
50    }
51
52    /// Returns the message type
53    pub fn message_type(&self) -> &MessageType{
54        &self.message_type
55    }
56
57    /// Returns the view contained in the message
58    pub fn view(&self) -> &Option<Vec<Peer>> {
59        &self.view
60    }
61
62    /// Serializes the message to a vector of bytes
63    pub fn as_bytes(&self) -> Vec<u8> {
64        let mut buffer = vec![];
65        // first byte: message type
66        match self.message_type {
67            MessageType::Request => buffer.push(MSG_TYPE_REQ),
68            MessageType::Response => buffer.push(MSG_TYPE_RESP),
69        }
70        // sender
71        buffer.push(self.sender.as_bytes().len() as u8);
72        self.sender.as_bytes().iter().for_each(|byte| buffer.push(*byte));
73        // view
74        if let Some(peers) = &self.view {
75            // view size in number of peers
76            buffer.push(peers.len() as u8);
77            // rest of bytes: peers
78            peers.iter().map(|p| { p.as_bytes() }).for_each(|mut bytes| {
79                // length of peer data in bytes
80                buffer.push(bytes.len() as u8);
81                // peer data
82                buffer.append(&mut bytes);
83            });
84        }
85        else {
86            // empty set
87            buffer.push(0);
88        }
89        buffer
90    }
91
92    /// Deserializes a message from bytes
93    ///
94    /// # Arguments
95    ///
96    /// * `bytes` - A message serialized as bytes
97    pub fn from_bytes(bytes: &[u8]) -> Result<Message, Box<dyn Error>> {
98
99        // message type(1) + sender size(1) + one byte for sender(>=1) + view size(1)
100        if bytes.len() < 4 {
101            Err("invalid message")?
102        }
103
104        // message type
105        let message_type = match bytes[0] & MASK_MSG_TYPE {
106            MSG_TYPE_REQ => MessageType::Request,
107            MSG_TYPE_RESP => MessageType::Response,
108            _ => return Err("invalid message type")?,
109        };
110
111        // sender
112        let sender_size = bytes[1] as usize;
113        // message type(1) + sender size(1) + sender(sender_size) + view size(>=1)
114        if bytes.len() < 3 + sender_size {
115            Err("invalid message")?
116        }
117        let sender = String::from_utf8(bytes[2..2+sender_size].to_vec())?;
118
119        // view size
120        let view_size = bytes[2+sender_size];
121        // message type(1) + sender size(1) + sender(sender_size) + view size(2 * view_size)
122        if bytes.len() < (2 + sender_size + 2 * view_size as usize) {
123            Err("invalid message")?
124        }
125        if view_size > 0 {
126            let mut index = 3+sender_size;
127            let mut peers = vec![];
128            for _ in 0..view_size {
129                let peer_length = bytes[index] as usize;
130                // index + 1 + peer length
131                if bytes.len() < index + 1 + peer_length{
132                    return Err("invalid message")?;
133                }
134                let parsed_peer = Peer::from_bytes(&bytes[index+1..index+1+peer_length])?;
135                peers.push(parsed_peer);
136                index += peer_length + 1;
137            }
138            Ok(Message {
139                sender,
140                message_type,
141                view: Some(peers)
142            })
143        }
144        else {
145            Ok(Message {
146                sender,
147                message_type,
148                view: None
149            })
150        }
151    }
152}