Skip to content

Commit e1d9aa4

Browse files
committed
refactor: [torrust#1326] extract bittorrent_udp_tracker_core::services::connect::ConnectService
1 parent ddfbcd2 commit e1d9aa4

File tree

8 files changed

+101
-46
lines changed

8 files changed

+101
-46
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515
callgrind.out
1616
codecov.json
1717
lcov.info
18-
perf.data*
18+
perf.data*
19+
rustc-ice-*.txt

cSpell.json

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
"routable",
137137
"rstest",
138138
"rusqlite",
139+
"rustc",
139140
"RUSTDOCFLAGS",
140141
"RUSTFLAGS",
141142
"rustfmt",

packages/udp-tracker-core/src/container.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use tokio::sync::RwLock;
88
use torrust_tracker_configuration::{Core, UdpTracker};
99

1010
use crate::services::banning::BanService;
11+
use crate::services::connect::ConnectService;
1112
use crate::{statistics, MAX_CONNECTION_ID_ERRORS_PER_IP};
1213

1314
pub struct UdpTrackerCoreContainer {
@@ -21,6 +22,7 @@ pub struct UdpTrackerCoreContainer {
2122
pub udp_core_stats_event_sender: Arc<Option<Box<dyn statistics::event::sender::Sender>>>,
2223
pub udp_core_stats_repository: Arc<statistics::repository::Repository>,
2324
pub ban_service: Arc<RwLock<BanService>>,
25+
pub connect_service: Arc<ConnectService>,
2426
}
2527

2628
impl UdpTrackerCoreContainer {
@@ -39,8 +41,8 @@ impl UdpTrackerCoreContainer {
3941
statistics::setup::factory(tracker_core_container.core_config.tracker_usage_statistics);
4042
let udp_core_stats_event_sender = Arc::new(udp_core_stats_event_sender);
4143
let udp_core_stats_repository = Arc::new(udp_core_stats_repository);
42-
4344
let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP)));
45+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender.clone()));
4446

4547
Arc::new(UdpTrackerCoreContainer {
4648
core_config: tracker_core_container.core_config.clone(),
@@ -52,6 +54,7 @@ impl UdpTrackerCoreContainer {
5254
udp_core_stats_event_sender: udp_core_stats_event_sender.clone(),
5355
udp_core_stats_repository: udp_core_stats_repository.clone(),
5456
ban_service: ban_service.clone(),
57+
connect_service: connect_service.clone(),
5558
})
5659
}
5760
}

packages/udp-tracker-core/src/services/connect.rs

+64-29
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,43 @@ use aquatic_udp_protocol::ConnectionId;
99
use crate::connection_cookie::{gen_remote_fingerprint, make};
1010
use crate::statistics;
1111

12-
/// # Panics
12+
/// The `ConnectService` is responsible for handling the `connect` requests.
1313
///
14-
/// IT will panic if there was an error making the connection cookie.
15-
pub async fn handle_connect(
16-
remote_addr: SocketAddr,
17-
opt_udp_stats_event_sender: &Arc<Option<Box<dyn statistics::event::sender::Sender>>>,
18-
cookie_issue_time: f64,
19-
) -> ConnectionId {
20-
let connection_id = make(gen_remote_fingerprint(&remote_addr), cookie_issue_time).expect("it should be a normal value");
21-
22-
if let Some(udp_stats_event_sender) = opt_udp_stats_event_sender.as_deref() {
23-
match remote_addr {
24-
SocketAddr::V4(_) => {
25-
udp_stats_event_sender.send_event(statistics::event::Event::Udp4Connect).await;
26-
}
27-
SocketAddr::V6(_) => {
28-
udp_stats_event_sender.send_event(statistics::event::Event::Udp6Connect).await;
29-
}
14+
/// It is responsible for generating the connection cookie and sending the
15+
/// appropriate statistics events.
16+
pub struct ConnectService {
17+
pub opt_udp_core_stats_event_sender: Arc<Option<Box<dyn statistics::event::sender::Sender>>>,
18+
}
19+
20+
impl ConnectService {
21+
#[must_use]
22+
pub fn new(opt_udp_core_stats_event_sender: Arc<Option<Box<dyn statistics::event::sender::Sender>>>) -> Self {
23+
Self {
24+
opt_udp_core_stats_event_sender,
3025
}
3126
}
3227

33-
connection_id
28+
/// Handles a `connect` request.
29+
///
30+
/// # Panics
31+
///
32+
/// It will panic if there was an error making the connection cookie.
33+
pub async fn handle_connect(&self, remote_addr: SocketAddr, cookie_issue_time: f64) -> ConnectionId {
34+
let connection_id = make(gen_remote_fingerprint(&remote_addr), cookie_issue_time).expect("it should be a normal value");
35+
36+
if let Some(udp_stats_event_sender) = self.opt_udp_core_stats_event_sender.as_deref() {
37+
match remote_addr {
38+
SocketAddr::V4(_) => {
39+
udp_stats_event_sender.send_event(statistics::event::Event::Udp4Connect).await;
40+
}
41+
SocketAddr::V6(_) => {
42+
udp_stats_event_sender.send_event(statistics::event::Event::Udp6Connect).await;
43+
}
44+
}
45+
}
46+
47+
connection_id
48+
}
3449
}
3550

3651
#[cfg(test)]
@@ -44,10 +59,10 @@ mod tests {
4459
use mockall::predicate::eq;
4560

4661
use crate::connection_cookie::make;
47-
use crate::services::connect::handle_connect;
62+
use crate::services::connect::ConnectService;
4863
use crate::services::tests::{
4964
sample_ipv4_remote_addr, sample_ipv4_remote_addr_fingerprint, sample_ipv4_socket_address, sample_ipv6_remote_addr,
50-
sample_ipv6_remote_addr_fingerprint, sample_issue_time, MockUdpStatsEventSender,
65+
sample_ipv6_remote_addr_fingerprint, sample_issue_time, MockUdpCoreStatsEventSender,
5166
};
5267
use crate::statistics;
5368

@@ -56,7 +71,11 @@ mod tests {
5671
let (udp_core_stats_event_sender, _udp_core_stats_repository) = statistics::setup::factory(false);
5772
let udp_core_stats_event_sender = Arc::new(udp_core_stats_event_sender);
5873

59-
let response = handle_connect(sample_ipv4_remote_addr(), &udp_core_stats_event_sender, sample_issue_time()).await;
74+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender));
75+
76+
let response = connect_service
77+
.handle_connect(sample_ipv4_remote_addr(), sample_issue_time())
78+
.await;
6079

6180
assert_eq!(
6281
response,
@@ -69,7 +88,11 @@ mod tests {
6988
let (udp_core_stats_event_sender, _udp_core_stats_repository) = statistics::setup::factory(false);
7089
let udp_core_stats_event_sender = Arc::new(udp_core_stats_event_sender);
7190

72-
let response = handle_connect(sample_ipv4_remote_addr(), &udp_core_stats_event_sender, sample_issue_time()).await;
91+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender));
92+
93+
let response = connect_service
94+
.handle_connect(sample_ipv4_remote_addr(), sample_issue_time())
95+
.await;
7396

7497
assert_eq!(
7598
response,
@@ -82,7 +105,11 @@ mod tests {
82105
let (udp_core_stats_event_sender, _udp_core_stats_repository) = statistics::setup::factory(false);
83106
let udp_core_stats_event_sender = Arc::new(udp_core_stats_event_sender);
84107

85-
let response = handle_connect(sample_ipv6_remote_addr(), &udp_core_stats_event_sender, sample_issue_time()).await;
108+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender));
109+
110+
let response = connect_service
111+
.handle_connect(sample_ipv6_remote_addr(), sample_issue_time())
112+
.await;
86113

87114
assert_eq!(
88115
response,
@@ -92,32 +119,40 @@ mod tests {
92119

93120
#[tokio::test]
94121
async fn it_should_send_the_upd4_connect_event_when_a_client_tries_to_connect_using_a_ip4_socket_address() {
95-
let mut udp_stats_event_sender_mock = MockUdpStatsEventSender::new();
122+
let mut udp_stats_event_sender_mock = MockUdpCoreStatsEventSender::new();
96123
udp_stats_event_sender_mock
97124
.expect_send_event()
98125
.with(eq(statistics::event::Event::Udp4Connect))
99126
.times(1)
100127
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
101-
let udp_stats_event_sender: Arc<Option<Box<dyn statistics::event::sender::Sender>>> =
128+
let opt_udp_stats_event_sender: Arc<Option<Box<dyn statistics::event::sender::Sender>>> =
102129
Arc::new(Some(Box::new(udp_stats_event_sender_mock)));
103130

104131
let client_socket_address = sample_ipv4_socket_address();
105132

106-
handle_connect(client_socket_address, &udp_stats_event_sender, sample_issue_time()).await;
133+
let connect_service = Arc::new(ConnectService::new(opt_udp_stats_event_sender));
134+
135+
connect_service
136+
.handle_connect(client_socket_address, sample_issue_time())
137+
.await;
107138
}
108139

109140
#[tokio::test]
110141
async fn it_should_send_the_upd6_connect_event_when_a_client_tries_to_connect_using_a_ip6_socket_address() {
111-
let mut udp_stats_event_sender_mock = MockUdpStatsEventSender::new();
142+
let mut udp_stats_event_sender_mock = MockUdpCoreStatsEventSender::new();
112143
udp_stats_event_sender_mock
113144
.expect_send_event()
114145
.with(eq(statistics::event::Event::Udp6Connect))
115146
.times(1)
116147
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
117-
let udp_stats_event_sender: Arc<Option<Box<dyn statistics::event::sender::Sender>>> =
148+
let opt_udp_stats_event_sender: Arc<Option<Box<dyn statistics::event::sender::Sender>>> =
118149
Arc::new(Some(Box::new(udp_stats_event_sender_mock)));
119150

120-
handle_connect(sample_ipv6_remote_addr(), &udp_stats_event_sender, sample_issue_time()).await;
151+
let connect_service = Arc::new(ConnectService::new(opt_udp_stats_event_sender));
152+
153+
connect_service
154+
.handle_connect(sample_ipv6_remote_addr(), sample_issue_time())
155+
.await;
121156
}
122157
}
123158
}

packages/udp-tracker-core/src/services/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ pub(crate) mod tests {
4444
}
4545

4646
mock! {
47-
pub(crate) UdpStatsEventSender {}
48-
impl statistics::event::sender::Sender for UdpStatsEventSender {
47+
pub(crate) UdpCoreStatsEventSender {}
48+
impl statistics::event::sender::Sender for UdpCoreStatsEventSender {
4949
fn send_event(&self, event: statistics::event::Event) -> BoxFuture<'static,Option<Result<(),SendError<statistics::event::Event> > > > ;
5050
}
5151
}

packages/udp-tracker-server/src/handlers/connect.rs

+20-9
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ use std::net::{IpAddr, SocketAddr};
33
use std::sync::Arc;
44

55
use aquatic_udp_protocol::{ConnectRequest, ConnectResponse, ConnectionId, Response};
6-
use bittorrent_udp_tracker_core::{services, statistics as core_statistics};
6+
use bittorrent_udp_tracker_core::services::connect::ConnectService;
77
use tracing::{instrument, Level};
88

99
use crate::statistics as server_statistics;
1010
use crate::statistics::event::UdpResponseKind;
1111

1212
/// It handles the `Connect` request.
13-
#[instrument(fields(transaction_id), skip(opt_udp_core_stats_event_sender, opt_udp_server_stats_event_sender), ret(level = Level::TRACE))]
13+
#[instrument(fields(transaction_id), skip(connect_service, opt_udp_server_stats_event_sender), ret(level = Level::TRACE))]
1414
pub async fn handle_connect(
1515
remote_addr: SocketAddr,
1616
request: &ConnectRequest,
17-
opt_udp_core_stats_event_sender: &Arc<Option<Box<dyn core_statistics::event::sender::Sender>>>,
17+
connect_service: &Arc<ConnectService>,
1818
opt_udp_server_stats_event_sender: &Arc<Option<Box<dyn server_statistics::event::sender::Sender>>>,
1919
cookie_issue_time: f64,
2020
) -> Response {
@@ -40,7 +40,7 @@ pub async fn handle_connect(
4040
}
4141
}
4242

43-
let connection_id = services::connect::handle_connect(remote_addr, opt_udp_core_stats_event_sender, cookie_issue_time).await;
43+
let connection_id = connect_service.handle_connect(remote_addr, cookie_issue_time).await;
4444

4545
build_response(*request, connection_id)
4646
}
@@ -64,6 +64,7 @@ mod tests {
6464

6565
use aquatic_udp_protocol::{ConnectRequest, ConnectResponse, Response, TransactionId};
6666
use bittorrent_udp_tracker_core::connection_cookie::make;
67+
use bittorrent_udp_tracker_core::services::connect::ConnectService;
6768
use bittorrent_udp_tracker_core::statistics as core_statistics;
6869
use mockall::predicate::eq;
6970

@@ -94,10 +95,12 @@ mod tests {
9495
transaction_id: TransactionId(0i32.into()),
9596
};
9697

98+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender));
99+
97100
let response = handle_connect(
98101
sample_ipv4_remote_addr(),
99102
&request,
100-
&udp_core_stats_event_sender,
103+
&connect_service,
101104
&udp_server_stats_event_sender,
102105
sample_issue_time(),
103106
)
@@ -125,10 +128,12 @@ mod tests {
125128
transaction_id: TransactionId(0i32.into()),
126129
};
127130

131+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender));
132+
128133
let response = handle_connect(
129134
sample_ipv4_remote_addr(),
130135
&request,
131-
&udp_core_stats_event_sender,
136+
&connect_service,
132137
&udp_server_stats_event_sender,
133138
sample_issue_time(),
134139
)
@@ -156,10 +161,12 @@ mod tests {
156161
transaction_id: TransactionId(0i32.into()),
157162
};
158163

164+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender));
165+
159166
let response = handle_connect(
160167
sample_ipv6_remote_addr(),
161168
&request,
162-
&udp_core_stats_event_sender,
169+
&connect_service,
163170
&udp_server_stats_event_sender,
164171
sample_issue_time(),
165172
)
@@ -198,10 +205,12 @@ mod tests {
198205

199206
let client_socket_address = sample_ipv4_socket_address();
200207

208+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender));
209+
201210
handle_connect(
202211
client_socket_address,
203212
&sample_connect_request(),
204-
&udp_core_stats_event_sender,
213+
&connect_service,
205214
&udp_server_stats_event_sender,
206215
sample_issue_time(),
207216
)
@@ -230,10 +239,12 @@ mod tests {
230239
let udp_server_stats_event_sender: Arc<Option<Box<dyn server_statistics::event::sender::Sender>>> =
231240
Arc::new(Some(Box::new(udp_server_stats_event_sender_mock)));
232241

242+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender));
243+
233244
handle_connect(
234245
sample_ipv6_remote_addr(),
235246
&sample_connect_request(),
236-
&udp_core_stats_event_sender,
247+
&connect_service,
237248
&udp_server_stats_event_sender,
238249
sample_issue_time(),
239250
)

packages/udp-tracker-server/src/handlers/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ pub async fn handle_request(
147147
Request::Connect(connect_request) => Ok(handle_connect(
148148
remote_addr,
149149
&connect_request,
150-
&udp_tracker_core_container.udp_core_stats_event_sender,
150+
&udp_tracker_core_container.connect_service,
151151
&udp_tracker_server_container.udp_server_stats_event_sender,
152152
cookie_time_values.issue_time,
153153
)

src/container.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use bittorrent_tracker_core::whitelist::manager::WhitelistManager;
1717
use bittorrent_tracker_core::whitelist::repository::in_memory::InMemoryWhitelist;
1818
use bittorrent_udp_tracker_core::container::UdpTrackerCoreContainer;
1919
use bittorrent_udp_tracker_core::services::banning::BanService;
20+
use bittorrent_udp_tracker_core::services::connect::ConnectService;
2021
use bittorrent_udp_tracker_core::{self, MAX_CONNECTION_ID_ERRORS_PER_IP};
2122
use tokio::sync::RwLock;
2223
use torrust_rest_tracker_api_core::container::TrackerHttpApiCoreContainer;
@@ -40,9 +41,10 @@ pub struct AppContainer {
4041
pub torrents_manager: Arc<TorrentsManager>,
4142

4243
// UDP Tracker Core Services
43-
pub ban_service: Arc<RwLock<BanService>>,
4444
pub udp_core_stats_event_sender: Arc<Option<Box<dyn bittorrent_udp_tracker_core::statistics::event::sender::Sender>>>,
4545
pub udp_core_stats_repository: Arc<bittorrent_udp_tracker_core::statistics::repository::Repository>,
46+
pub ban_service: Arc<RwLock<BanService>>,
47+
pub connect_service: Arc<bittorrent_udp_tracker_core::services::connect::ConnectService>,
4648

4749
// HTTP Tracker Core Services
4850
pub http_stats_event_sender: Arc<Option<Box<dyn bittorrent_http_tracker_core::statistics::event::sender::Sender>>>,
@@ -86,8 +88,8 @@ impl AppContainer {
8688
bittorrent_udp_tracker_core::statistics::setup::factory(configuration.core.tracker_usage_statistics);
8789
let udp_core_stats_event_sender = Arc::new(udp_core_stats_event_sender);
8890
let udp_core_stats_repository = Arc::new(udp_core_stats_repository);
89-
9091
let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP)));
92+
let connect_service = Arc::new(ConnectService::new(udp_core_stats_event_sender.clone()));
9193

9294
// UDP Tracker Server Services
9395
let (udp_server_stats_event_sender, udp_server_stats_repository) =
@@ -111,9 +113,10 @@ impl AppContainer {
111113
torrents_manager: tracker_core_container.torrents_manager,
112114

113115
// UDP Tracker Core Services
114-
ban_service,
115116
udp_core_stats_event_sender,
116117
udp_core_stats_repository,
118+
ban_service,
119+
connect_service,
117120

118121
// HTTP Tracker Core Services
119122
http_stats_event_sender,
@@ -156,6 +159,7 @@ impl AppContainer {
156159
udp_core_stats_event_sender: self.udp_core_stats_event_sender.clone(),
157160
udp_core_stats_repository: self.udp_core_stats_repository.clone(),
158161
ban_service: self.ban_service.clone(),
162+
connect_service: self.connect_service.clone(),
159163
}
160164
}
161165

0 commit comments

Comments
 (0)