use super::{SessionMessageType, decode_optional_coords, encode_coords, encode_empty_coords};
use crate::NodeAddr;
use crate::protocol::ProtocolError;
use crate::tree::TreeCoordinate;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PathMtuNotification {
pub path_mtu: u16,
}
pub const PATH_MTU_NOTIFICATION_SIZE: usize = 2;
impl PathMtuNotification {
pub fn new(path_mtu: u16) -> Self {
Self { path_mtu }
}
pub fn encode(&self) -> Vec<u8> {
self.path_mtu.to_le_bytes().to_vec()
}
pub fn decode(body: &[u8]) -> Result<Self, ProtocolError> {
if body.len() < PATH_MTU_NOTIFICATION_SIZE {
return Err(ProtocolError::MessageTooShort {
expected: PATH_MTU_NOTIFICATION_SIZE,
got: body.len(),
});
}
Ok(Self {
path_mtu: u16::from_le_bytes([body[0], body[1]]),
})
}
}
#[derive(Clone, Debug)]
pub struct CoordsRequired {
pub dest_addr: NodeAddr,
pub reporter: NodeAddr,
}
pub const COORDS_REQUIRED_SIZE: usize = 34;
impl CoordsRequired {
pub fn new(dest_addr: NodeAddr, reporter: NodeAddr) -> Self {
Self {
dest_addr,
reporter,
}
}
pub fn encode(&self) -> Vec<u8> {
let body_len = 1 + 1 + 16 + 16; let mut buf = Vec::with_capacity(4 + body_len);
buf.push(0x00); buf.push(0x04); let payload_len = body_len as u16;
buf.extend_from_slice(&payload_len.to_le_bytes());
buf.push(SessionMessageType::CoordsRequired.to_byte());
buf.push(0x00); buf.extend_from_slice(self.dest_addr.as_bytes());
buf.extend_from_slice(self.reporter.as_bytes());
buf
}
pub fn decode(payload: &[u8]) -> Result<Self, ProtocolError> {
if payload.len() < 33 {
return Err(ProtocolError::MessageTooShort {
expected: 33,
got: payload.len(),
});
}
let mut dest_bytes = [0u8; 16];
dest_bytes.copy_from_slice(&payload[1..17]);
let mut reporter_bytes = [0u8; 16];
reporter_bytes.copy_from_slice(&payload[17..33]);
Ok(Self {
dest_addr: NodeAddr::from_bytes(dest_bytes),
reporter: NodeAddr::from_bytes(reporter_bytes),
})
}
}
#[derive(Clone, Debug)]
pub struct PathBroken {
pub dest_addr: NodeAddr,
pub reporter: NodeAddr,
pub last_known_coords: Option<TreeCoordinate>,
}
impl PathBroken {
pub fn new(dest_addr: NodeAddr, reporter: NodeAddr) -> Self {
Self {
dest_addr,
reporter,
last_known_coords: None,
}
}
pub fn with_last_coords(mut self, coords: TreeCoordinate) -> Self {
self.last_known_coords = Some(coords);
self
}
pub fn encode(&self) -> Vec<u8> {
let mut body = Vec::new();
body.push(SessionMessageType::PathBroken.to_byte());
body.push(0x00); body.extend_from_slice(self.dest_addr.as_bytes());
body.extend_from_slice(self.reporter.as_bytes());
if let Some(ref coords) = self.last_known_coords {
encode_coords(coords, &mut body);
} else {
encode_empty_coords(&mut body);
}
let payload_len = body.len() as u16;
let mut buf = Vec::with_capacity(4 + body.len());
buf.push(0x00); buf.push(0x04); buf.extend_from_slice(&payload_len.to_le_bytes());
buf.extend_from_slice(&body);
buf
}
pub fn decode(payload: &[u8]) -> Result<Self, ProtocolError> {
if payload.len() < 35 {
return Err(ProtocolError::MessageTooShort {
expected: 35,
got: payload.len(),
});
}
let mut dest_bytes = [0u8; 16];
dest_bytes.copy_from_slice(&payload[1..17]);
let mut reporter_bytes = [0u8; 16];
reporter_bytes.copy_from_slice(&payload[17..33]);
let (last_known_coords, _consumed) = decode_optional_coords(&payload[33..])?;
Ok(Self {
dest_addr: NodeAddr::from_bytes(dest_bytes),
reporter: NodeAddr::from_bytes(reporter_bytes),
last_known_coords,
})
}
}
#[derive(Clone, Debug)]
pub struct MtuExceeded {
pub dest_addr: NodeAddr,
pub reporter: NodeAddr,
pub mtu: u16,
}
pub const MTU_EXCEEDED_SIZE: usize = 36;
impl MtuExceeded {
pub fn new(dest_addr: NodeAddr, reporter: NodeAddr, mtu: u16) -> Self {
Self {
dest_addr,
reporter,
mtu,
}
}
pub fn encode(&self) -> Vec<u8> {
let body_len = MTU_EXCEEDED_SIZE; let mut buf = Vec::with_capacity(4 + body_len);
buf.push(0x00); buf.push(0x04); let payload_len = body_len as u16;
buf.extend_from_slice(&payload_len.to_le_bytes());
buf.push(SessionMessageType::MtuExceeded.to_byte());
buf.push(0x00); buf.extend_from_slice(self.dest_addr.as_bytes());
buf.extend_from_slice(self.reporter.as_bytes());
buf.extend_from_slice(&self.mtu.to_le_bytes());
buf
}
pub fn decode(payload: &[u8]) -> Result<Self, ProtocolError> {
if payload.len() < 35 {
return Err(ProtocolError::MessageTooShort {
expected: 35,
got: payload.len(),
});
}
let mut dest_bytes = [0u8; 16];
dest_bytes.copy_from_slice(&payload[1..17]);
let mut reporter_bytes = [0u8; 16];
reporter_bytes.copy_from_slice(&payload[17..33]);
let mtu = u16::from_le_bytes([payload[33], payload[34]]);
Ok(Self {
dest_addr: NodeAddr::from_bytes(dest_bytes),
reporter: NodeAddr::from_bytes(reporter_bytes),
mtu,
})
}
}