forked from torrust/torrust-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.rs
More file actions
75 lines (61 loc) · 2.37 KB
/
server.rs
File metadata and controls
75 lines (61 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use std::io::Cursor;
use std::net::SocketAddr;
use std::sync::Arc;
use aquatic_udp_protocol::Response;
use log::{debug, info};
use tokio::net::UdpSocket;
use crate::tracker::tracker::TorrentTracker;
use crate::udp::{handle_packet, MAX_PACKET_SIZE};
pub struct UdpServer {
socket: Arc<UdpSocket>,
tracker: Arc<TorrentTracker>,
}
impl UdpServer {
pub async fn new(tracker: Arc<TorrentTracker>, bind_address: &str) -> tokio::io::Result<UdpServer> {
let socket = UdpSocket::bind(bind_address).await?;
Ok(UdpServer {
socket: Arc::new(socket),
tracker,
})
}
pub async fn start(&self) {
loop {
let mut data = [0; MAX_PACKET_SIZE];
let socket = self.socket.clone();
let tracker = self.tracker.clone();
tokio::select! {
_ = tokio::signal::ctrl_c() => {
info!("Stopping UDP server: {}..", socket.local_addr().unwrap());
break;
}
Ok((valid_bytes, remote_addr)) = socket.recv_from(&mut data) => {
let payload = data[..valid_bytes].to_vec();
debug!("Received {} bytes from {}", payload.len(), remote_addr);
debug!("{:?}", payload);
let response = handle_packet(remote_addr, payload, tracker).await;
UdpServer::send_response(socket, remote_addr, response).await;
}
}
}
}
async fn send_response(socket: Arc<UdpSocket>, remote_addr: SocketAddr, response: Response) {
debug!("sending response to: {:?}", &remote_addr);
let buffer = vec![0u8; MAX_PACKET_SIZE];
let mut cursor = Cursor::new(buffer);
match response.write(&mut cursor) {
Ok(_) => {
let position = cursor.position() as usize;
let inner = cursor.get_ref();
debug!("{:?}", &inner[..position]);
UdpServer::send_packet(socket, &remote_addr, &inner[..position]).await;
}
Err(_) => {
debug!("could not write response to bytes.");
}
}
}
async fn send_packet(socket: Arc<UdpSocket>, remote_addr: &SocketAddr, payload: &[u8]) {
// doesn't matter if it reaches or not
let _ = socket.send_to(payload, remote_addr).await;
}
}