-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(packet): clean up module structure
- Loading branch information
Showing
6 changed files
with
183 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
use super::Version; | ||
use crate::path::DataplanePathErrorKind; | ||
|
||
/// Errors raised when failing to decode a [`ScionPacket`] or its constituents. | ||
#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone, Copy)] | ||
pub enum DecodeError { | ||
#[error("cannot decode packet with unsupported header version {0:?}")] | ||
UnsupportedVersion(Version), | ||
#[error("header length factor is inconsistent with the SCION specification: {0}")] | ||
InvalidHeaderLength(u8), | ||
#[error("the provided bytes did not include the full packet")] | ||
PacketEmptyOrTruncated, | ||
#[error("the path type and length do not correspond")] | ||
InconsistentPathLength, | ||
#[error("attempted to decode the empty path type")] | ||
EmptyPath, | ||
#[error("invalid path header: {0}")] | ||
InvalidPath(DataplanePathErrorKind), | ||
} | ||
|
||
impl From<DataplanePathErrorKind> for DecodeError { | ||
fn from(value: DataplanePathErrorKind) -> Self { | ||
Self::InvalidPath(value) | ||
} | ||
} | ||
|
||
/// Errors raised when failing to encode a [`ScionPacket`]. | ||
#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone, Copy)] | ||
pub enum EncodeError { | ||
#[error("packet payload is too large")] | ||
PayloadTooLarge, | ||
#[error("packet header is too large")] | ||
HeaderTooLarge, | ||
#[error("header is not properly aligned")] | ||
MisalignedHeader, | ||
} | ||
|
||
/// Raised if the buffer does not have sufficient capacity for encoding the SCION headers. | ||
/// | ||
/// As the headers can be a maximum of 1020 bytes in length, it is advisable to have at | ||
/// least that amount of remaining space for encoding a [`ScionPacket`] (the payload is not | ||
/// written to the buffer). | ||
#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone, Copy, Default)] | ||
#[error("the provided buffer did not have sufficient size")] | ||
pub struct InadequateBufferSize; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
use bytes::{Buf, Bytes}; | ||
|
||
use super::{ | ||
AddressHeader, | ||
ByEndpoint, | ||
CommonHeader, | ||
DataplanePath, | ||
DecodeError, | ||
EncodeError, | ||
InadequateBufferSize, | ||
ScionHeaders, | ||
}; | ||
use crate::{ | ||
address::SocketAddr, | ||
path::Path, | ||
wire_encoding::{WireDecode, WireDecodeWithContext, WireEncode, WireEncodeVec}, | ||
}; | ||
|
||
/// A SCION network packet. | ||
#[derive(Debug, Clone)] | ||
pub struct ScionPacketRaw { | ||
/// Packet headers | ||
pub headers: ScionHeaders, | ||
/// The packet payload. | ||
pub payload: Bytes, | ||
} | ||
|
||
impl ScionPacketRaw { | ||
pub fn new( | ||
endhosts: &ByEndpoint<SocketAddr>, | ||
path: &Path, | ||
payload: Bytes, | ||
next_header: u8, | ||
) -> Result<Self, EncodeError> { | ||
let headers = ScionHeaders::new(endhosts, path, next_header, payload.len())?; | ||
|
||
Ok(Self { headers, payload }) | ||
} | ||
} | ||
|
||
impl WireEncodeVec for &ScionPacketRaw { | ||
type Error = InadequateBufferSize; | ||
|
||
fn encode_with(&self, buffer: &mut bytes::BytesMut) -> Result<Vec<Bytes>, Self::Error> { | ||
let mut bytes = self.headers.encode_with(buffer)?; | ||
bytes.push(self.payload.clone()); | ||
Ok(bytes) | ||
} | ||
|
||
fn total_length(&self) -> usize { | ||
self.headers.encoded_length() + self.payload.len() | ||
} | ||
} | ||
|
||
impl<T: Buf> WireDecode<T> for ScionPacketRaw { | ||
type Error = DecodeError; | ||
|
||
fn decode(data: &mut T) -> Result<Self, Self::Error> { | ||
let common_header = CommonHeader::decode(data)?; | ||
|
||
// Limit the data for headers to the length specified by the common header | ||
let mut header_data = data.take(common_header.remaining_header_length()); | ||
let address_header = | ||
AddressHeader::decode_with_context(&mut header_data, common_header.address_info)?; | ||
|
||
// The path requires a Bytes, if we were already parsing a Bytes, then this is just an | ||
// Arc increment, otherwise we copy the bytes needed for the path. | ||
let mut path_bytes = header_data.copy_to_bytes(header_data.remaining()); | ||
let context = (common_header.path_type, path_bytes.len()); | ||
let path_header = DataplanePath::decode_with_context(&mut path_bytes, context)?; | ||
|
||
if path_bytes.has_remaining() { | ||
Err(DecodeError::InconsistentPathLength) | ||
} else if data.remaining() < common_header.payload_size() { | ||
Err(DecodeError::PacketEmptyOrTruncated) | ||
} else { | ||
let payload = data.copy_to_bytes(common_header.payload_size()); | ||
Ok(Self { | ||
headers: ScionHeaders { | ||
common: common_header, | ||
address: address_header, | ||
path: path_header, | ||
}, | ||
payload, | ||
}) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.