use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use crate::encryption::PubKeyPair;
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Layer3SocketAddr {
addr: Layer3Addr,
port: u16,
}
impl Layer3SocketAddr {
pub fn from_layer3_addr(addr: Layer3Addr, port: u16) -> Self {
Self { addr, port }
}
pub fn as_socket_addr(&self) -> SocketAddr {
SocketAddr::new(self.addr.as_ipaddr(), self.port)
}
pub fn as_ipaddr(&self) -> IpAddr {
self.addr.as_ipaddr()
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Layer3Addr {
V4([u8; 4]),
V6([u16; 8]),
}
impl Layer3Addr {
pub fn as_ipaddr(&self) -> IpAddr {
match self {
Self::V4(addr) => IpAddr::V4(Ipv4Addr::new(addr[0], addr[1], addr[2], addr[3])),
Self::V6(addr) => IpAddr::V6(Ipv6Addr::new(
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7],
)),
}
}
pub fn from_ipaddr(ipaddr: &IpAddr) -> Self {
match ipaddr {
IpAddr::V4(addr) => Self::V4(addr.octets()),
IpAddr::V6(addr) => {
let octets = addr.octets();
let mut addr: [u16; 8] = [0; 8];
let mut index: u8 = 0;
for i in &mut addr {
*i = (octets[index as usize] as u16) | (octets[index as usize + 1] as u16);
index += 2;
}
Self::V6(addr)
}
}
}
pub fn to_socket_addr(&self, port: u16) -> SocketAddr {
SocketAddr::new(self.as_ipaddr(), port)
}
}
#[test]
pub fn back_and_forth() {
let ipv6addr = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
let layer3addr = Layer3Addr::from_ipaddr(&ipv6addr);
let newipaddr = layer3addr.as_ipaddr();
assert_eq!(ipv6addr, newipaddr);
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialOrd, Ord)]
pub struct ArtificePeer {
global_peer_hash: String,
addr: Layer3SocketAddr,
routable: bool,
pubkey: PubKeyPair,
peer_hash: String,
}
impl PartialEq for ArtificePeer {
fn eq(&self, other: &Self) -> bool {
self.global_peer_hash == other.global_peer_hash
&& self.pubkey == other.pubkey
&& self.peer_hash == other.peer_hash
}
}
impl ArtificePeer {
pub fn new(
peer_hash: String,
global_peer_hash: String,
addr: Layer3SocketAddr,
pubkey: PubKeyPair,
) -> Self {
let routable = addr.as_ipaddr().is_global();
Self {
global_peer_hash,
addr,
routable,
pubkey,
peer_hash,
}
}
pub fn global_peer_hash(&self) -> String {
self.global_peer_hash.clone()
}
pub fn pubkeypair(&self) -> PubKeyPair {
self.pubkey.clone()
}
pub fn peer_hash(&self) -> String {
self.peer_hash.clone()
}
pub fn socket_addr(&self) -> std::net::SocketAddr {
self.addr.as_socket_addr()
}
}
pub trait PeerList {
fn get_peer(global_hash: &str) -> Option<ArtificePeer>;
}