extern crate anyhow;
use crate::torrent::*;
use anyhow::{anyhow, Result};
use byteorder::{BigEndian, ReadBytesExt};
use std::io::Cursor;
use std::net::Ipv4Addr;
const PEER_SIZE: usize = 6;
type PeerId = u32;
#[derive(Clone)]
pub struct Peer {
pub id: PeerId,
pub ip: Ipv4Addr,
pub port: u16,
}
impl Peer {
pub fn new() -> Peer {
Peer {
id: 0,
ip: Ipv4Addr::new(1, 1, 1, 1),
port: 0,
}
}
pub fn get_id(&self) -> u32 {
self.id
}
pub fn get_ip(&self) -> Ipv4Addr {
self.ip
}
pub fn get_port(&self) -> u16 {
self.port
}
}
impl Torrent {
pub fn build_peers(&self, tracker_peers: Vec<u8>) -> Result<Vec<Peer>> {
if tracker_peers.len() % PEER_SIZE != 0 {
return Err(anyhow!("received invalid peers from tracker"));
}
let nb_peers = tracker_peers.len() / PEER_SIZE;
let mut peers: Vec<Peer> = vec![Peer::new(); nb_peers];
let mut port = vec![];
for i in 0..nb_peers {
peers[i].id = i as u32;
let offset = i * PEER_SIZE;
peers[i].ip = Ipv4Addr::new(
tracker_peers[offset],
tracker_peers[offset + 1],
tracker_peers[offset + 2],
tracker_peers[offset + 3],
);
port.push(tracker_peers[offset + 4]);
port.push(tracker_peers[offset + 5]);
let mut port_cursor = Cursor::new(port);
peers[i].port = port_cursor.read_u16::<BigEndian>()?;
port = vec![];
}
Ok(peers)
}
}