forked from torrust/torrust-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbound_socket.rs
70 lines (56 loc) · 2.01 KB
/
bound_socket.rs
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
use std::fmt::Debug;
use std::net::SocketAddr;
use std::ops::Deref;
use url::Url;
use crate::servers::udp::UDP_TRACKER_LOG_TARGET;
/// Wrapper for Tokio [`UdpSocket`][`tokio::net::UdpSocket`] that is bound to a particular socket.
pub struct BoundSocket {
socket: tokio::net::UdpSocket,
}
impl BoundSocket {
/// # Errors
///
/// Will return an error if the socket can't be bound the the provided address.
pub async fn new(addr: SocketAddr) -> Result<Self, Box<std::io::Error>> {
let bind_addr = format!("udp://{addr}");
tracing::debug!(target: UDP_TRACKER_LOG_TARGET, bind_addr, "UdpSocket::new (binding)");
let socket = tokio::net::UdpSocket::bind(addr).await;
let socket = match socket {
Ok(socket) => socket,
Err(e) => Err(e)?,
};
let local_addr = format!("udp://{addr}");
tracing::debug!(target: UDP_TRACKER_LOG_TARGET, local_addr, "UdpSocket::new (bound)");
Ok(Self { socket })
}
/// # Panics
///
/// Will panic if the socket can't get the address it was bound to.
#[must_use]
pub fn address(&self) -> SocketAddr {
self.socket.local_addr().expect("it should get local address")
}
/// # Panics
///
/// Will panic if the address the socket was bound to is not a valid address
/// to be used in a URL.
#[must_use]
pub fn url(&self) -> Url {
Url::parse(&format!("udp://{}", self.address())).expect("UDP socket address should be valid")
}
}
impl Deref for BoundSocket {
type Target = tokio::net::UdpSocket;
fn deref(&self) -> &Self::Target {
&self.socket
}
}
impl Debug for BoundSocket {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let local_addr = match self.socket.local_addr() {
Ok(socket) => format!("Receiving From: {socket}"),
Err(err) => format!("Socket Broken: {err}"),
};
f.debug_struct("UdpSocket").field("addr", &local_addr).finish_non_exhaustive()
}
}