solana/sdk/src/packet.rs

153 lines
3.6 KiB
Rust
Raw Normal View History

use {
bincode::Result,
bitflags::bitflags,
serde::Serialize,
std::{
fmt, io,
net::{IpAddr, Ipv4Addr, SocketAddr},
},
2020-01-28 16:11:22 -08:00
};
2018-11-16 08:04:46 -08:00
/// Maximum over-the-wire size of a Transaction
2019-05-21 21:45:38 -07:00
/// 1280 is IPv6 minimum MTU
/// 40 bytes is the size of the IPv6 header
/// 8 bytes is the size of the fragment header
pub const PACKET_DATA_SIZE: usize = 1280 - 40 - 8;
bitflags! {
#[repr(C)]
pub struct PacketFlags: u8 {
const DISCARD = 0b00000001;
const FORWARDED = 0b00000010;
const REPAIR = 0b00000100;
const SIMPLE_VOTE_TX = 0b00001000;
const TRACER_TX = 0b00010000;
}
}
#[derive(Clone, Debug, PartialEq)]
#[repr(C)]
pub struct Meta {
pub size: usize,
pub addr: IpAddr,
pub port: u16,
pub flags: PacketFlags,
2021-12-16 06:47:55 -08:00
pub weight: u64,
}
#[derive(Clone)]
#[repr(C)]
pub struct Packet {
pub data: [u8; PACKET_DATA_SIZE],
pub meta: Meta,
}
impl Packet {
pub fn new(data: [u8; PACKET_DATA_SIZE], meta: Meta) -> Self {
Self { data, meta }
}
pub fn from_data<T: Serialize>(dest: Option<&SocketAddr>, data: T) -> Result<Self> {
let mut packet = Packet::default();
Self::populate_packet(&mut packet, dest, &data)?;
Ok(packet)
}
pub fn populate_packet<T: Serialize>(
packet: &mut Packet,
dest: Option<&SocketAddr>,
data: &T,
) -> Result<()> {
let mut wr = io::Cursor::new(&mut packet.data[..]);
bincode::serialize_into(&mut wr, data)?;
let len = wr.position() as usize;
packet.meta.size = len;
if let Some(dest) = dest {
packet.meta.set_addr(dest);
}
Ok(())
}
}
impl fmt::Debug for Packet {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Packet {{ size: {:?}, addr: {:?} }}",
self.meta.size,
self.meta.addr()
)
}
}
#[allow(clippy::uninit_assumed_init)]
impl Default for Packet {
fn default() -> Packet {
Packet {
data: unsafe { std::mem::MaybeUninit::uninit().assume_init() },
meta: Meta::default(),
}
}
}
impl PartialEq for Packet {
fn eq(&self, other: &Packet) -> bool {
let self_data: &[u8] = self.data.as_ref();
let other_data: &[u8] = other.data.as_ref();
2020-12-13 17:26:34 -08:00
self.meta == other.meta && self_data[..self.meta.size] == other_data[..self.meta.size]
}
}
impl Meta {
pub fn addr(&self) -> SocketAddr {
SocketAddr::new(self.addr, self.port)
}
pub fn set_addr(&mut self, socket_addr: &SocketAddr) {
self.addr = socket_addr.ip();
self.port = socket_addr.port();
}
#[inline]
pub fn discard(&self) -> bool {
self.flags.contains(PacketFlags::DISCARD)
}
#[inline]
pub fn set_discard(&mut self, discard: bool) {
self.flags.set(PacketFlags::DISCARD, discard);
}
#[inline]
pub fn forwarded(&self) -> bool {
self.flags.contains(PacketFlags::FORWARDED)
}
#[inline]
pub fn repair(&self) -> bool {
self.flags.contains(PacketFlags::REPAIR)
}
#[inline]
pub fn is_simple_vote_tx(&self) -> bool {
self.flags.contains(PacketFlags::SIMPLE_VOTE_TX)
}
#[inline]
pub fn is_tracer_tx(&self) -> bool {
self.flags.contains(PacketFlags::TRACER_TX)
}
}
impl Default for Meta {
fn default() -> Self {
Self {
size: 0,
addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
port: 0,
flags: PacketFlags::empty(),
2021-12-16 06:47:55 -08:00
weight: 0,
}
}
}