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.
82 lines
3.0 KiB
Rust
82 lines
3.0 KiB
Rust
#![recursion_limit = "512"]
|
|
use async_std::net::{IpAddr, UdpSocket};
|
|
use futures::select;
|
|
use futures::FutureExt;
|
|
use std::net::SocketAddr;
|
|
use std::pin::Pin;
|
|
use std::str::FromStr;
|
|
use std::time::{Duration, Instant};
|
|
use torment_dht::host_node::HostNode;
|
|
use torment_dht::krpc::{FromBencode, Message, ToBencode};
|
|
|
|
async fn recv_from(socket: &UdpSocket) -> std::io::Result<(Vec<u8>, SocketAddr)> {
|
|
let mut buffer = [0u8; 2048];
|
|
socket
|
|
.recv_from(&mut buffer)
|
|
.await
|
|
.map(|(len, addr)| (buffer[..len].to_vec(), addr))
|
|
}
|
|
|
|
#[async_std::main]
|
|
async fn main() {
|
|
let socket = UdpSocket::bind(SocketAddr::from_str("[::]:50002").unwrap())
|
|
.await
|
|
.unwrap();
|
|
let mut node = HostNode::new(Default::default(), Some(50002));
|
|
node.add_bootstrap(SocketAddr::from_str("67.215.246.10:6881").unwrap(), None);
|
|
node.add_bootstrap(
|
|
SocketAddr::from_str("[2001:41d0:c:5ac:5::1]:6881").unwrap(),
|
|
None,
|
|
);
|
|
|
|
let mut fut_holder = recv_from(&socket).fuse();
|
|
let mut socket_fut = unsafe { Pin::new_unchecked(&mut fut_holder) };
|
|
let mut fut_sleep_holder = async_std::task::sleep(Duration::from_secs(10)).fuse();
|
|
let mut event_fut = unsafe { Pin::new_unchecked(&mut fut_sleep_holder) };
|
|
|
|
loop {
|
|
while let Some((message, to)) = node.next() {
|
|
println!("| {} <= {:?}", to, message);
|
|
socket
|
|
.send_to(&message.to_bencode().unwrap(), to)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
select! {
|
|
res = socket_fut => {
|
|
if let Ok((msg, from)) = res {
|
|
let from = if let IpAddr::V6(ipv6) = from.ip() {
|
|
if let Some(ipv4) = ipv6.to_ipv4() {
|
|
SocketAddr::new(IpAddr::V4(ipv4), from.port())
|
|
} else {
|
|
from
|
|
}
|
|
} else {
|
|
from
|
|
};
|
|
|
|
match Message::from_bencode(&msg) {
|
|
Ok(msg) => {
|
|
println!("| {} => {:?}", from, msg);
|
|
node.process(msg, from);
|
|
},
|
|
Err(err) => eprintln!("{} => Failed parsing UDP message: {}", from, err),
|
|
}
|
|
}
|
|
|
|
fut_holder = recv_from(&socket).fuse();
|
|
socket_fut = unsafe { Pin::new_unchecked(&mut fut_holder) };
|
|
},
|
|
_ = event_fut => {
|
|
println!("| Housekeeping");
|
|
let instant = Instant::now();
|
|
node.housekeeping();
|
|
println!("| Housekeeping took {:?} (seen nodes: {}, table[ipv4={}, ipv6={}])", Instant::now() - instant, node.num_tracking_nodes(), node.num_ipv4_table_nodes(), node.num_ipv6_table_nodes());
|
|
fut_sleep_holder = async_std::task::sleep(Duration::from_secs(10)).fuse();
|
|
event_fut = unsafe { Pin::new_unchecked(&mut fut_sleep_holder) };
|
|
},
|
|
};
|
|
}
|
|
}
|