Skip to content

Commit 0eec5b7

Browse files
committed
refactor: [1373] include client's port in stats events when provided
1 parent ba6e9f9 commit 0eec5b7

File tree

5 files changed

+132
-68
lines changed

5 files changed

+132
-68
lines changed

packages/http-tracker-core/src/services/announce.rs

+27-21
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl AnnounceService {
7575

7676
self.authorize(announce_request.info_hash).await?;
7777

78-
let remote_client_ip = self.resolve_remote_client_ip(client_ip_sources)?;
78+
let (remote_client_ip, opt_remote_client_port) = self.resolve_remote_client_address(client_ip_sources)?;
7979

8080
let mut peer = peer_from_request(announce_request, &remote_client_ip);
8181

@@ -86,7 +86,8 @@ impl AnnounceService {
8686
.announce(&announce_request.info_hash, &mut peer, &remote_client_ip, &peers_wanted)
8787
.await?;
8888

89-
self.send_stats_event(remote_client_ip, *server_socket_addr).await;
89+
self.send_stats_event(remote_client_ip, opt_remote_client_port, *server_socket_addr)
90+
.await;
9091

9192
Ok(announce_data)
9293
}
@@ -108,11 +109,24 @@ impl AnnounceService {
108109
}
109110

110111
/// Resolves the client's real IP address considering proxy headers
111-
fn resolve_remote_client_ip(&self, client_ip_sources: &ClientIpSources) -> Result<IpAddr, PeerIpResolutionError> {
112-
match peer_ip_resolver::invoke(self.core_config.net.on_reverse_proxy, client_ip_sources) {
112+
fn resolve_remote_client_address(
113+
&self,
114+
client_ip_sources: &ClientIpSources,
115+
) -> Result<(IpAddr, Option<u16>), PeerIpResolutionError> {
116+
let ip = match peer_ip_resolver::invoke(self.core_config.net.on_reverse_proxy, client_ip_sources) {
113117
Ok(peer_ip) => Ok(peer_ip),
114118
Err(error) => Err(error),
115-
}
119+
}?;
120+
121+
let port = if client_ip_sources.connection_info_socket_address.is_some() {
122+
client_ip_sources
123+
.connection_info_socket_address
124+
.map(|socket_addr| socket_addr.port())
125+
} else {
126+
None
127+
};
128+
129+
Ok((ip, port))
116130
}
117131

118132
/// Determines how many peers the client wants in the response
@@ -123,14 +137,11 @@ impl AnnounceService {
123137
}
124138
}
125139

126-
async fn send_stats_event(&self, peer_ip: IpAddr, server_socket_addr: SocketAddr) {
140+
async fn send_stats_event(&self, peer_ip: IpAddr, opt_peer_ip_port: Option<u16>, server_socket_addr: SocketAddr) {
127141
if let Some(http_stats_event_sender) = self.opt_http_stats_event_sender.as_deref() {
128142
http_stats_event_sender
129143
.send_event(statistics::event::Event::TcpAnnounce {
130-
connection: statistics::event::ConnectionContext {
131-
client_ip_addr: peer_ip,
132-
server_socket_addr,
133-
},
144+
connection: statistics::event::ConnectionContext::new(peer_ip, opt_peer_ip_port, server_socket_addr),
134145
})
135146
.await;
136147
}
@@ -381,10 +392,7 @@ mod tests {
381392
http_stats_event_sender_mock
382393
.expect_send_event()
383394
.with(eq(statistics::event::Event::TcpAnnounce {
384-
connection: ConnectionContext {
385-
client_ip_addr: IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)),
386-
server_socket_addr,
387-
},
395+
connection: ConnectionContext::new(IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)), Some(8080), server_socket_addr),
388396
}))
389397
.times(1)
390398
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
@@ -440,10 +448,7 @@ mod tests {
440448
http_stats_event_sender_mock
441449
.expect_send_event()
442450
.with(eq(statistics::event::Event::TcpAnnounce {
443-
connection: ConnectionContext {
444-
client_ip_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
445-
server_socket_addr,
446-
},
451+
connection: ConnectionContext::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), Some(8080), server_socket_addr),
447452
}))
448453
.times(1)
449454
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
@@ -482,10 +487,11 @@ mod tests {
482487
http_stats_event_sender_mock
483488
.expect_send_event()
484489
.with(eq(statistics::event::Event::TcpAnnounce {
485-
connection: ConnectionContext {
486-
client_ip_addr: IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
490+
connection: ConnectionContext::new(
491+
IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
492+
Some(8080),
487493
server_socket_addr,
488-
},
494+
),
489495
}))
490496
.times(1)
491497
.returning(|_| Box::pin(future::ready(Some(Ok(())))));

packages/http-tracker-core/src/services/scrape.rs

+43-23
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,10 @@ impl ScrapeService {
8080
self.scrape_handler.scrape(&scrape_request.info_hashes).await?
8181
};
8282

83-
let remote_client_ip = self.resolve_remote_client_ip(client_ip_sources)?;
83+
let (remote_client_ip, opt_client_port) = self.resolve_remote_client_ip(client_ip_sources)?;
8484

85-
self.send_stats_event(remote_client_ip, *server_socket_addr).await;
85+
self.send_stats_event(remote_client_ip, opt_client_port, *server_socket_addr)
86+
.await;
8687

8788
Ok(scrape_data)
8889
}
@@ -100,18 +101,33 @@ impl ScrapeService {
100101
}
101102

102103
/// Resolves the client's real IP address considering proxy headers.
103-
fn resolve_remote_client_ip(&self, client_ip_sources: &ClientIpSources) -> Result<IpAddr, PeerIpResolutionError> {
104-
peer_ip_resolver::invoke(self.core_config.net.on_reverse_proxy, client_ip_sources)
104+
fn resolve_remote_client_ip(
105+
&self,
106+
client_ip_sources: &ClientIpSources,
107+
) -> Result<(IpAddr, Option<u16>), PeerIpResolutionError> {
108+
let ip = peer_ip_resolver::invoke(self.core_config.net.on_reverse_proxy, client_ip_sources)?;
109+
110+
let port = if client_ip_sources.connection_info_socket_address.is_some() {
111+
client_ip_sources
112+
.connection_info_socket_address
113+
.map(|socket_addr| socket_addr.port())
114+
} else {
115+
None
116+
};
117+
118+
Ok((ip, port))
105119
}
106120

107-
async fn send_stats_event(&self, original_peer_ip: IpAddr, server_socket_addr: SocketAddr) {
121+
async fn send_stats_event(
122+
&self,
123+
original_peer_ip: IpAddr,
124+
opt_original_peer_port: Option<u16>,
125+
server_socket_addr: SocketAddr,
126+
) {
108127
if let Some(http_stats_event_sender) = self.opt_http_stats_event_sender.as_deref() {
109128
http_stats_event_sender
110129
.send_event(statistics::event::Event::TcpScrape {
111-
connection: ConnectionContext {
112-
client_ip_addr: original_peer_ip,
113-
server_socket_addr,
114-
},
130+
connection: ConnectionContext::new(original_peer_ip, opt_original_peer_port, server_socket_addr),
115131
})
116132
.await;
117133
}
@@ -336,10 +352,11 @@ mod tests {
336352
http_stats_event_sender_mock
337353
.expect_send_event()
338354
.with(eq(statistics::event::Event::TcpScrape {
339-
connection: ConnectionContext {
340-
client_ip_addr: IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)),
341-
server_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
342-
},
355+
connection: ConnectionContext::new(
356+
IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)),
357+
Some(8080),
358+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
359+
),
343360
}))
344361
.times(1)
345362
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
@@ -384,10 +401,11 @@ mod tests {
384401
http_stats_event_sender_mock
385402
.expect_send_event()
386403
.with(eq(statistics::event::Event::TcpScrape {
387-
connection: ConnectionContext {
388-
client_ip_addr: IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
404+
connection: ConnectionContext::new(
405+
IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
406+
Some(8080),
389407
server_socket_addr,
390-
},
408+
),
391409
}))
392410
.times(1)
393411
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
@@ -504,10 +522,11 @@ mod tests {
504522
http_stats_event_sender_mock
505523
.expect_send_event()
506524
.with(eq(statistics::event::Event::TcpScrape {
507-
connection: ConnectionContext {
508-
client_ip_addr: IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)),
509-
server_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
510-
},
525+
connection: ConnectionContext::new(
526+
IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)),
527+
Some(8080),
528+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
529+
),
511530
}))
512531
.times(1)
513532
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
@@ -552,10 +571,11 @@ mod tests {
552571
http_stats_event_sender_mock
553572
.expect_send_event()
554573
.with(eq(statistics::event::Event::TcpScrape {
555-
connection: ConnectionContext {
556-
client_ip_addr: IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
574+
connection: ConnectionContext::new(
575+
IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
576+
Some(8080),
557577
server_socket_addr,
558-
},
578+
),
559579
}))
560580
.times(1)
561581
.returning(|_| Box::pin(future::ready(Some(Ok(())))));

packages/http-tracker-core/src/statistics/event/handler.rs

+22-18
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ use crate::statistics::repository::Repository;
99
/// version of the event.
1010
pub async fn handle_event(event: Event, stats_repository: &Repository) {
1111
match event {
12-
Event::TcpAnnounce { connection } => match connection.client_ip_addr {
12+
Event::TcpAnnounce { connection } => match connection.client_ip_addr() {
1313
IpAddr::V4(_) => {
1414
stats_repository.increase_tcp4_announces().await;
1515
}
1616
IpAddr::V6(_) => {
1717
stats_repository.increase_tcp6_announces().await;
1818
}
1919
},
20-
Event::TcpScrape { connection } => match connection.client_ip_addr {
20+
Event::TcpScrape { connection } => match connection.client_ip_addr() {
2121
IpAddr::V4(_) => {
2222
stats_repository.increase_tcp4_scrapes().await;
2323
}
@@ -44,10 +44,11 @@ mod tests {
4444

4545
handle_event(
4646
Event::TcpAnnounce {
47-
connection: ConnectionContext {
48-
client_ip_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)),
49-
server_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
50-
},
47+
connection: ConnectionContext::new(
48+
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)),
49+
Some(8080),
50+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
51+
),
5152
},
5253
&stats_repository,
5354
)
@@ -64,10 +65,11 @@ mod tests {
6465

6566
handle_event(
6667
Event::TcpScrape {
67-
connection: ConnectionContext {
68-
client_ip_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)),
69-
server_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
70-
},
68+
connection: ConnectionContext::new(
69+
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)),
70+
Some(8080),
71+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
72+
),
7173
},
7274
&stats_repository,
7375
)
@@ -84,10 +86,11 @@ mod tests {
8486

8587
handle_event(
8688
Event::TcpAnnounce {
87-
connection: ConnectionContext {
88-
client_ip_addr: IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
89-
server_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
90-
},
89+
connection: ConnectionContext::new(
90+
IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
91+
Some(8080),
92+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
93+
),
9194
},
9295
&stats_repository,
9396
)
@@ -104,10 +107,11 @@ mod tests {
104107

105108
handle_event(
106109
Event::TcpScrape {
107-
connection: ConnectionContext {
108-
client_ip_addr: IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
109-
server_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
110-
},
110+
connection: ConnectionContext::new(
111+
IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)),
112+
Some(8080),
113+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
114+
),
111115
},
112116
&stats_repository,
113117
)

packages/http-tracker-core/src/statistics/event/mod.rs

+35-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,39 @@ pub enum Event {
1313

1414
#[derive(Debug, PartialEq, Eq)]
1515
pub struct ConnectionContext {
16-
pub client_ip_addr: IpAddr,
17-
pub server_socket_addr: SocketAddr,
16+
client: ClientConnectionContext,
17+
server: ServerConnectionContext,
18+
}
19+
20+
impl ConnectionContext {
21+
#[must_use]
22+
pub fn new(client_ip_addr: IpAddr, opt_client_port: Option<u16>, server_socket_addr: SocketAddr) -> Self {
23+
Self {
24+
client: ClientConnectionContext {
25+
ip_addr: client_ip_addr,
26+
port: opt_client_port,
27+
},
28+
server: ServerConnectionContext {
29+
socket_addr: server_socket_addr,
30+
},
31+
}
32+
}
33+
34+
#[must_use]
35+
pub fn client_ip_addr(&self) -> IpAddr {
36+
self.client.ip_addr
37+
}
38+
}
39+
40+
#[derive(Debug, PartialEq, Eq)]
41+
pub struct ClientConnectionContext {
42+
ip_addr: IpAddr,
43+
44+
/// It's provided if you use the `torrust-axum-http-tracker-server` crate.
45+
port: Option<u16>,
46+
}
47+
48+
#[derive(Debug, PartialEq, Eq)]
49+
pub struct ServerConnectionContext {
50+
socket_addr: SocketAddr,
1851
}

packages/http-tracker-core/src/statistics/keeper.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,11 @@ mod tests {
7474

7575
let result = event_sender
7676
.send_event(Event::TcpAnnounce {
77-
connection: ConnectionContext {
78-
client_ip_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)),
79-
server_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
80-
},
77+
connection: ConnectionContext::new(
78+
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)),
79+
Some(8080),
80+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7070),
81+
),
8182
})
8283
.await;
8384

0 commit comments

Comments
 (0)