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
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![]
|
|
}
|
|
}
|