use std::io::{self, Read, Write};
use crate::{
io::{ReadFrom, WriteTo},
net::SocketAddr,
stream::StreamNumber,
time::Time,
};
bitflags! {
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Services: u64 {
const NETWORK = 1;
const SSL = 1<<1;
const POW = 1<<2;
const DANDELION = 1<<3;
}
}
impl WriteTo for Services {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.bits().write_to(w)
}
}
impl ReadFrom for Services {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
let bits = u64::read_from(r)?;
Ok(Self::from_bits_retain(bits))
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct NetAddr {
time: Time,
stream_number: StreamNumber,
services: Services,
socket_addr: SocketAddr,
}
impl NetAddr {
pub fn new(
time: Time,
stream_number: StreamNumber,
services: Services,
socket_addr: SocketAddr,
) -> Self {
Self {
time,
stream_number,
services,
socket_addr,
}
}
pub fn time(&self) -> Time {
self.time
}
pub fn stream_number(&self) -> StreamNumber {
self.stream_number
}
pub fn services(&self) -> Services {
self.services
}
pub fn socket_addr(&self) -> &SocketAddr {
&self.socket_addr
}
}
impl WriteTo for NetAddr {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.time.write_to(w)?;
self.stream_number.as_u32().write_to(w)?;
self.services.write_to(w)?;
self.socket_addr.write_to(w)?;
Ok(())
}
}
impl ReadFrom for NetAddr {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self {
time: Time::read_from(r)?,
stream_number: u32::read_from(r)?.into(),
services: Services::read_from(r)?,
socket_addr: SocketAddr::read_from(r)?,
})
}
}
#[test]
fn test_net_addr_write_to() {
use std::net::{Ipv4Addr, SocketAddrV4};
let local_socket_addr = SocketAddr::Ipv4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8444));
let test = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
local_socket_addr,
);
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc, ];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_net_addr_read_from() {
use std::{
io::Cursor,
net::{Ipv4Addr, SocketAddrV4},
};
let local_socket_addr = SocketAddr::Ipv4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8444));
let mut bytes = Cursor::new(
[
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc, ]
.to_vec(),
);
let test = NetAddr::read_from(&mut bytes).unwrap();
let expected = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
local_socket_addr,
);
assert_eq!(test, expected);
}