-
Notifications
You must be signed in to change notification settings - Fork 53
Expand file tree
/
Copy pathpeer.rs
More file actions
78 lines (68 loc) · 2.93 KB
/
peer.rs
File metadata and controls
78 lines (68 loc) · 2.93 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
76
77
78
use std::net::{IpAddr, SocketAddr};
use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes};
use serde;
use serde::{Serialize};
use crate::protocol::common::{NumberOfBytesDef, AnnounceEventDef};
use crate::protocol::utils::ser_instant;
use crate::http::AnnounceRequest;
use crate::PeerId;
#[derive(PartialEq, Eq, Debug, Clone, Serialize)]
pub struct TorrentPeer {
pub peer_id: PeerId,
pub peer_addr: SocketAddr,
#[serde(serialize_with = "ser_instant")]
pub updated: std::time::Instant,
#[serde(with = "NumberOfBytesDef")]
pub uploaded: NumberOfBytes,
#[serde(with = "NumberOfBytesDef")]
pub downloaded: NumberOfBytes,
#[serde(with = "NumberOfBytesDef")]
pub left: NumberOfBytes,
#[serde(with = "AnnounceEventDef")]
pub event: AnnounceEvent,
}
impl TorrentPeer {
pub fn from_udp_announce_request(announce_request: &aquatic_udp_protocol::AnnounceRequest, remote_ip: IpAddr, host_opt_ip: Option<IpAddr>) -> Self {
let peer_addr = TorrentPeer::peer_addr_from_ip_and_port_and_opt_host_ip(remote_ip, host_opt_ip, announce_request.port.0);
TorrentPeer {
peer_id: PeerId(announce_request.peer_id.0),
peer_addr,
updated: std::time::Instant::now(),
uploaded: announce_request.bytes_uploaded,
downloaded: announce_request.bytes_downloaded,
left: announce_request.bytes_left,
event: announce_request.event,
}
}
pub fn from_http_announce_request(announce_request: &AnnounceRequest, remote_ip: IpAddr, host_opt_ip: Option<IpAddr>) -> Self {
let peer_addr = TorrentPeer::peer_addr_from_ip_and_port_and_opt_host_ip(remote_ip, host_opt_ip, announce_request.port);
let event: AnnounceEvent = if let Some(event) = &announce_request.event {
match event.as_ref() {
"started" => AnnounceEvent::Started,
"stopped" => AnnounceEvent::Stopped,
"completed" => AnnounceEvent::Completed,
_ => AnnounceEvent::None
}
} else {
AnnounceEvent::None
};
TorrentPeer {
peer_id: announce_request.peer_id.clone(),
peer_addr,
updated: std::time::Instant::now(),
uploaded: NumberOfBytes(announce_request.uploaded as i64),
downloaded: NumberOfBytes(announce_request.downloaded as i64),
left: NumberOfBytes(announce_request.left as i64),
event,
}
}
// potentially substitute localhost ip with external ip
pub fn peer_addr_from_ip_and_port_and_opt_host_ip(remote_ip: IpAddr, host_opt_ip: Option<IpAddr>, port: u16) -> SocketAddr {
if remote_ip.is_loopback() && host_opt_ip.is_some() {
SocketAddr::new(host_opt_ip.unwrap(), port)
} else {
SocketAddr::new(remote_ip, port)
}
}
pub fn is_seeder(&self) -> bool { self.left.0 <= 0 && self.event != AnnounceEvent::Stopped }
}