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.
152 lines
5.2 KiB
Rust
152 lines
5.2 KiB
Rust
use bytes::BytesMut;
|
|
use polling::{Event, Poller};
|
|
use std::collections::HashMap;
|
|
use std::convert::TryInto;
|
|
use std::fs::File;
|
|
use std::io::{Read, Write};
|
|
use std::net::TcpStream;
|
|
use std::option::Option::Some;
|
|
use std::path::PathBuf;
|
|
use std::process::exit;
|
|
use std::result::Result::Ok;
|
|
use std::time::Duration;
|
|
use torment_core::infohash::v1::U160;
|
|
use torment_core::metainfo::Torrent;
|
|
use torment_core::peer_id;
|
|
use torment_manager::session_manager::SessionManager;
|
|
use torment_manager::torrent_manager::{TorrentManager, TorrentTarget};
|
|
use torment_peer::message::{Handshake, Message};
|
|
use torment_peer::PeerProtocol::TCP;
|
|
|
|
struct TcpState {
|
|
builder: BytesMut,
|
|
handshake: Option<Handshake>,
|
|
stream: TcpStream,
|
|
}
|
|
|
|
fn main() {
|
|
let mut session_manager = SessionManager::new();
|
|
|
|
let mut buffer = vec![];
|
|
File::open("/home/eater/Downloads/[Commie] Senyuu. - 23 [150B93D5].mkv.torrent")
|
|
.unwrap()
|
|
.read_to_end(&mut buffer)
|
|
.unwrap();
|
|
let torrent_manager = TorrentManager::from_torrent(
|
|
Torrent::from_bytes(
|
|
buffer,
|
|
Some("[Commie] Senyuu. - 23 [150B93D5].mkv".to_string()),
|
|
)
|
|
.unwrap(),
|
|
TorrentTarget {
|
|
path: PathBuf::from("/tmp"),
|
|
is_base_path: true,
|
|
},
|
|
None,
|
|
);
|
|
|
|
let peer_id = U160::from(peer_id(rand::random()));
|
|
let info_hash = torrent_manager.info_hash();
|
|
session_manager.add_torrent_manager(torrent_manager);
|
|
|
|
let mut tcp_stream_ktorrent = TcpStream::connect("127.0.0.1:6881").unwrap();
|
|
tcp_stream_ktorrent.set_nodelay(true).unwrap();
|
|
tcp_stream_ktorrent
|
|
.write_all(Handshake::new(peer_id, info_hash).to_bytes().as_ref())
|
|
.unwrap();
|
|
|
|
let mut tcp_stream_transmission = TcpStream::connect("192.168.188.100:51413").unwrap();
|
|
tcp_stream_transmission.set_nodelay(true).unwrap();
|
|
tcp_stream_transmission
|
|
.write_all(Handshake::new(peer_id, info_hash).to_bytes().as_ref())
|
|
.unwrap();
|
|
|
|
let mut buffer = vec![0u8; 4096 * 10];
|
|
let mut poller = Poller::new().unwrap();
|
|
poller.insert(&tcp_stream_ktorrent).unwrap();
|
|
poller.insert(&tcp_stream_transmission).unwrap();
|
|
poller.interest(&tcp_stream_ktorrent, Event::readable(0));
|
|
poller.interest(&tcp_stream_transmission, Event::readable(1));
|
|
|
|
let mut items = vec![
|
|
TcpState {
|
|
builder: Default::default(),
|
|
handshake: None,
|
|
stream: tcp_stream_ktorrent,
|
|
},
|
|
TcpState {
|
|
builder: Default::default(),
|
|
handshake: None,
|
|
stream: tcp_stream_transmission,
|
|
},
|
|
];
|
|
|
|
let mut peer_map: HashMap<(U160, U160), usize> = Default::default();
|
|
|
|
loop {
|
|
let mut events: Vec<Event> = vec![];
|
|
poller.wait(&mut events, Some(Duration::from_secs(10)));
|
|
|
|
for event in events {
|
|
println!("Event => {:?}", event);
|
|
if !event.readable {
|
|
continue;
|
|
}
|
|
|
|
let item = &mut items[event.key];
|
|
let packet = item.stream.read(&mut buffer).unwrap();
|
|
item.builder.extend_from_slice(&buffer[..packet]);
|
|
let handshake = if let Some(handshake) = &item.handshake {
|
|
handshake
|
|
} else {
|
|
if item.builder.len() >= 68 {
|
|
item.handshake =
|
|
Some(Handshake::from_bytes(item.builder.split_to(68).freeze()).unwrap());
|
|
let handshake = item.handshake.as_ref().unwrap();
|
|
println!("{} => {:?}", item.stream.peer_addr().unwrap(), handshake);
|
|
peer_map.insert((handshake.info_hash(), handshake.peer_id()), event.key);
|
|
session_manager.handshake(*handshake, item.stream.peer_addr().unwrap(), TCP);
|
|
handshake
|
|
} else {
|
|
continue;
|
|
}
|
|
};
|
|
|
|
while item.builder.len() >= 4 {
|
|
let len = u32::from_be_bytes(item.builder[..4].try_into().unwrap());
|
|
if len + 4 > item.builder.len() as u32 {
|
|
break;
|
|
}
|
|
|
|
if len == 0 {
|
|
item.builder.split_to(4);
|
|
continue;
|
|
}
|
|
|
|
let message_bytes = item.builder.split_to((4 + len) as usize).freeze();
|
|
let msg = Message::from_bytes(message_bytes.slice(4..)).unwrap();
|
|
println!("{} => {:?}", item.stream.peer_addr().unwrap(), msg);
|
|
if !session_manager.process(info_hash, handshake.peer_id(), msg) {
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
poller.interest(&item.stream, Event::readable(event.key));
|
|
}
|
|
|
|
while let Some(queued) = session_manager.next() {
|
|
if let Some(key) = peer_map.get(&(queued.info_hash, queued.peer_id)) {
|
|
let item = &mut items[*key];
|
|
println!("{} <= {:?}", queued.addr, queued.message);
|
|
|
|
item.stream
|
|
.write_all(&queued.message.to_length_prefixed_bytes())
|
|
.unwrap();
|
|
}
|
|
}
|
|
|
|
println!("=> Running house keeping");
|
|
session_manager.house_keeping();
|
|
}
|
|
}
|