2021-12-03 09:00:31 -08:00
|
|
|
use {
|
|
|
|
bincode::Result,
|
2022-01-02 09:10:32 -08:00
|
|
|
bitflags::bitflags,
|
2021-12-03 09:00:31 -08:00
|
|
|
serde::Serialize,
|
|
|
|
std::{
|
|
|
|
fmt, io,
|
2022-01-02 08:13:57 -08:00
|
|
|
net::{IpAddr, Ipv4Addr, SocketAddr},
|
2021-12-03 09:00:31 -08:00
|
|
|
},
|
2020-01-28 16:11:22 -08:00
|
|
|
};
|
2019-10-17 10:37:30 -07: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;
|
2019-10-17 10:37:30 -07:00
|
|
|
|
2022-01-02 09:10:32 -08:00
|
|
|
bitflags! {
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct PacketFlags: u8 {
|
2022-05-23 08:48:59 -07:00
|
|
|
const DISCARD = 0b0000_0001;
|
|
|
|
const FORWARDED = 0b0000_0010;
|
|
|
|
const REPAIR = 0b0000_0100;
|
|
|
|
const SIMPLE_VOTE_TX = 0b0000_1000;
|
|
|
|
const TRACER_TX = 0b0001_0000;
|
2022-01-02 09:10:32 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-04 19:50:56 -07:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
2019-10-17 10:37:30 -07:00
|
|
|
#[repr(C)]
|
|
|
|
pub struct Meta {
|
|
|
|
pub size: usize,
|
2022-01-02 08:13:57 -08:00
|
|
|
pub addr: IpAddr,
|
2019-10-17 10:37:30 -07:00
|
|
|
pub port: u16,
|
2022-01-02 09:10:32 -08:00
|
|
|
pub flags: PacketFlags,
|
2022-03-15 16:44:53 -07:00
|
|
|
pub sender_stake: u64,
|
2019-10-17 10:37:30 -07:00
|
|
|
}
|
|
|
|
|
2022-05-04 19:50:56 -07:00
|
|
|
#[derive(Clone, Eq)]
|
2019-10-17 10:37:30 -07:00
|
|
|
#[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 }
|
|
|
|
}
|
2019-11-14 10:24:53 -08:00
|
|
|
|
2021-04-12 23:28:08 -07:00
|
|
|
pub fn from_data<T: Serialize>(dest: Option<&SocketAddr>, data: T) -> Result<Self> {
|
2020-11-08 07:10:03 -08:00
|
|
|
let mut packet = Packet::default();
|
2021-04-12 23:28:08 -07:00
|
|
|
Self::populate_packet(&mut packet, dest, &data)?;
|
2020-11-08 07:10:03 -08:00
|
|
|
Ok(packet)
|
2019-11-14 10:24:53 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2022-05-23 08:48:59 -07:00
|
|
|
packet.meta.set_socket_addr(dest);
|
2019-11-14 10:24:53 -08:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2019-10-17 10:37:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Packet {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"Packet {{ size: {:?}, addr: {:?} }}",
|
|
|
|
self.meta.size,
|
2022-05-23 08:48:59 -07:00
|
|
|
self.meta.socket_addr()
|
2019-10-17 10:37:30 -07:00
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 07:31:47 -07:00
|
|
|
#[allow(clippy::uninit_assumed_init)]
|
2019-10-17 10:37:30 -07:00
|
|
|
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]
|
2019-10-17 10:37:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Meta {
|
2022-05-23 08:48:59 -07:00
|
|
|
pub fn socket_addr(&self) -> SocketAddr {
|
2022-01-02 08:13:57 -08:00
|
|
|
SocketAddr::new(self.addr, self.port)
|
|
|
|
}
|
|
|
|
|
2022-05-23 08:48:59 -07:00
|
|
|
pub fn set_socket_addr(&mut self, socket_addr: &SocketAddr) {
|
2022-01-02 08:13:57 -08:00
|
|
|
self.addr = socket_addr.ip();
|
|
|
|
self.port = socket_addr.port();
|
2019-10-17 10:37:30 -07:00
|
|
|
}
|
2022-01-02 09:10:32 -08:00
|
|
|
|
|
|
|
#[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)
|
|
|
|
}
|
2022-01-02 08:13:57 -08:00
|
|
|
}
|
2019-10-17 10:37:30 -07:00
|
|
|
|
2022-01-02 08:13:57 -08:00
|
|
|
impl Default for Meta {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
size: 0,
|
|
|
|
addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
|
|
|
port: 0,
|
2022-01-02 09:10:32 -08:00
|
|
|
flags: PacketFlags::empty(),
|
2022-03-15 16:44:53 -07:00
|
|
|
sender_stake: 0,
|
2019-10-17 10:37:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|