You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.2 KiB
Rust

#![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<u8>;
fn from_compact_contact<T: AsRef<[u8]>>(input: T) -> Result<Self, ParsingError>;
}
impl CompactContact for SocketAddr {
fn to_compact_contact(&self) -> Vec<u8> {
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<T: AsRef<[u8]>>(input: T) -> Result<Self, ParsingError> {
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<u8> {
let contact = self.contact.to_compact_contact();
let mut bytes = self.id.to_bytes().to_vec();
bytes.extend(contact);
bytes
}
pub fn from_bytes<T: AsRef<[u8]>>(input: T) -> Result<ContactInfo, ParsingError> {
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<SocketAddr>) {}
pub fn get_peers(&self, _info_hash: U160, _filter: LookupFilter) -> Vec<SocketAddr> {
vec![]
}
}