#![allow(dead_code)] use crate::infohash::v1::U160; use crate::infohash::InfoHashCapable; use serde_derive::{Deserialize, Serialize}; use std::convert::TryInto; use std::fmt::{Display, Formatter}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; pub mod infohash; pub mod ip; pub mod metainfo; pub mod utils; pub trait CompactContact: Sized { fn to_compact_contact(&self) -> Vec; fn from_compact_contact>(input: T) -> Result; } impl CompactContact for SocketAddr { fn to_compact_contact(&self) -> Vec { match self.ip() { IpAddr::V4(ref v4) => { let mut compact = [0u8; 6]; compact[..4].copy_from_slice(&v4.octets()); compact[4..].copy_from_slice(&self.port().to_be_bytes()[..]); compact.to_vec() } IpAddr::V6(ref v6) => { let mut compact = [0u8; 18]; compact[..16].copy_from_slice(&v6.octets()); compact[16..].copy_from_slice(&self.port().to_be_bytes()); compact.to_vec() } } } fn from_compact_contact>(input: T) -> Result { let b = input.as_ref(); if b.len() == 6 { let ipv4: [u8; 4] = b[..4].try_into().unwrap(); Ok(SocketAddr::new( Ipv4Addr::from(ipv4).into(), u16::from_be_bytes(b[4..].try_into().unwrap()), )) } else if b.len() == 18 { let ipv6: [u8; 16] = b[..16].try_into().unwrap(); Ok(SocketAddr::new( Ipv6Addr::from(ipv6).into(), u16::from_be_bytes(b[16..].try_into().unwrap()), )) } else { Err(ParsingError) } } } #[derive(Debug)] pub struct ParsingError; impl std::error::Error for ParsingError {} impl Display for ParsingError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "there was a parsing error.") } } #[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)] pub struct ContactInfo { pub id: U160, pub contact: SocketAddr, } impl ContactInfo { pub fn to_bytes(&self) -> Vec { let contact = self.contact.to_compact_contact(); let mut bytes = self.id.to_bytes().to_vec(); bytes.extend(contact); bytes } pub fn from_bytes>(input: T) -> Result { let b = input.as_ref(); if b.len() == 26 || b.len() == 38 { Ok(ContactInfo { id: U160::from_bytes(&b[..20]).map_err(|_| ParsingError)?, contact: SocketAddr::from_compact_contact(&b[20..])?, }) } else { Err(ParsingError) } } } #[derive(Debug, Default)] pub struct PeerStorage {} #[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone)] pub enum LookupFilter { IPv6, IPv4, All, } impl PeerStorage { pub fn new() -> PeerStorage { PeerStorage {} } pub fn add_peers(&mut self, _info_hash: U160, _peers: Vec) {} pub fn get_peers(&self, _info_hash: U160, _filter: LookupFilter) -> Vec { vec![] } }