Skip to content

Commit bf23479

Browse files
committed
feat: [#508] add health check for UDP tracker
Using the `connect` UDP request. If the UDP trackers replies to a connection request we assume is healthy.
1 parent 2a05590 commit bf23479

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

src/servers/health_check_api/handlers.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use std::net::SocketAddr;
22
use std::sync::Arc;
33

4+
use aquatic_udp_protocol::{ConnectRequest, Response, TransactionId};
45
use axum::extract::State;
56
use axum::Json;
67
use torrust_tracker_configuration::Configuration;
78

89
use super::resources::Report;
910
use super::responses;
11+
use crate::shared::bit_torrent::udp::client::new_udp_tracker_client_connected;
1012

1113
/// If port 0 is specified in the configuration the OS will automatically
1214
/// assign a free port. But we do now know in from the configuration.
@@ -23,6 +25,8 @@ pub(crate) async fn health_check_handler(State(config): State<Arc<Configuration>
2325
// running service, after starting it as we do for testing with ephemeral
2426
// configurations.
2527

28+
// Health check for API
29+
2630
if config.http_api.enabled {
2731
let addr: SocketAddr = config.http_api.bind_address.parse().expect("invalid socket address for API");
2832

@@ -35,6 +39,8 @@ pub(crate) async fn health_check_handler(State(config): State<Arc<Configuration>
3539
}
3640
}
3741

42+
// Health check for HTTP Trackers
43+
3844
for http_tracker_config in &config.http_trackers {
3945
if !http_tracker_config.enabled {
4046
continue;
@@ -56,7 +62,22 @@ pub(crate) async fn health_check_handler(State(config): State<Arc<Configuration>
5662
}
5763
}
5864

59-
// todo: for all UDP Trackers, if enabled, check if is healthy
65+
// Health check for UDP Trackers
66+
67+
for udp_tracker_config in &config.udp_trackers {
68+
if !udp_tracker_config.enabled {
69+
continue;
70+
}
71+
72+
let addr: SocketAddr = udp_tracker_config
73+
.bind_address
74+
.parse()
75+
.expect("invalid socket address for UDP tracker");
76+
77+
if addr.port() != UNKNOWN_PORT && !can_connect_to_udp_tracker(&addr.to_string()).await {
78+
return responses::error(format!("UDP Tracker is not healthy. Can't connect to: {addr}"));
79+
}
80+
}
6081

6182
responses::ok()
6283
}
@@ -67,3 +88,18 @@ async fn get_req_is_ok(url: &str) -> bool {
6788
Err(_err) => false,
6889
}
6990
}
91+
92+
/// Tries to connect to an UDP tracker. It returns true if it succeeded.
93+
async fn can_connect_to_udp_tracker(url: &str) -> bool {
94+
let client = new_udp_tracker_client_connected(url).await;
95+
96+
let connect_request = ConnectRequest {
97+
transaction_id: TransactionId(123),
98+
};
99+
100+
client.send(connect_request.into()).await;
101+
102+
let response = client.receive().await;
103+
104+
matches!(response, Response::Connect(_connect_response))
105+
}

0 commit comments

Comments
 (0)