Skip to content

Commit dee86be

Browse files
committed
Merge #644: udp: handle udp requests concurrently
72c8348 udp: handle udp requests concurrently (Cameron Garnham) Pull request description: Extracted from #557 Upgrades the udp implementation to handle requests concurrently, no timeout is needed as udp is non-blocking. Hard-coded limit of 50 concurrent requests. With trivial changes can make this limit configurable, however I don't think that it would really be much benefit for it, the main concern is memory usage, and since udp is no blocking each request should return very quickly, could set to 5000 and it should still be fine. ACKs for top commit: josecelano: ACK 72c8348 Tree-SHA512: 83c4d893d5a88a59655942dcafceed25ca3b620a73fbd70d43ade4684394348c170dbfa427dfb236bcb7a8175e307547c894ec79d3c0b992441e8aa1490885b8
2 parents 444c395 + 72c8348 commit dee86be

File tree

11 files changed

+207
-85
lines changed

11 files changed

+207
-85
lines changed

.github/workflows/coverage.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ jobs:
5555
name: Run Build Checks
5656
run: cargo check --tests --benches --examples --workspace --all-targets --all-features
5757

58+
# Run Test Locally:
59+
# RUSTFLAGS="-Z profile -C codegen-units=1 -C inline-threshold=0 -C link-dead-code -C overflow-checks=off -C panic=abort -Z panic_abort_tests" RUSTDOCFLAGS="-Z profile -C codegen-units=1 -C inline-threshold=0 -C link-dead-code -C overflow-checks=off -C panic=abort -Z panic_abort_tests" CARGO_INCREMENTAL="0" RUST_BACKTRACE=1 cargo test --tests --benches --examples --workspace --all-targets --all-features
60+
5861
- id: test
5962
name: Run Unit Tests
6063
run: cargo test --tests --benches --examples --workspace --all-targets --all-features

.vscode/settings.json

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
"[rust]": {
33
"editor.formatOnSave": true
44
},
5+
"[ignore]": { "rust-analyzer.cargo.extraEnv" : {
6+
"RUSTFLAGS": "-Z profile -C codegen-units=1 -C inline-threshold=0 -C link-dead-code -C overflow-checks=off -C panic=abort -Z panic_abort_tests",
7+
"RUSTDOCFLAGS": "-Z profile -C codegen-units=1 -C inline-threshold=0 -C link-dead-code -C overflow-checks=off -C panic=abort -Z panic_abort_tests",
8+
"CARGO_INCREMENTAL": "0",
9+
"RUST_BACKTRACE": "1"
10+
}},
511
"rust-analyzer.checkOnSave": true,
612
"rust-analyzer.check.command": "clippy",
713
"rust-analyzer.check.allTargets": true,

Cargo.lock

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ serde = { version = "1", features = ["derive"] }
5656
serde_bencode = "0"
5757
serde_bytes = "0"
5858
serde_json = "1"
59+
ringbuf = "0.4.0-rc.2"
5960
serde_with = "3"
6061
serde_repr = "0"
6162
tdyne-peer-id = "1"

cSpell.json

+2
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,10 @@
9494
"reannounce",
9595
"Registar",
9696
"repr",
97+
"reqs",
9798
"reqwest",
9899
"rerequests",
100+
"ringbuf",
99101
"rngs",
100102
"routable",
101103
"rusqlite",

src/servers/udp/handlers.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use log::{debug, info};
1111
use torrust_tracker_located_error::DynError;
1212

1313
use super::connection_cookie::{check, from_connection_id, into_connection_id, make};
14+
use super::UdpRequest;
1415
use crate::core::{statistics, ScrapeData, Tracker};
1516
use crate::servers::udp::error::Error;
1617
use crate::servers::udp::peer_builder;
@@ -27,10 +28,13 @@ use crate::shared::bit_torrent::info_hash::InfoHash;
2728
/// type.
2829
///
2930
/// It will return an `Error` response if the request is invalid.
30-
pub async fn handle_packet(remote_addr: SocketAddr, payload: Vec<u8>, tracker: &Tracker) -> Response {
31-
match Request::from_bytes(&payload[..payload.len()], MAX_SCRAPE_TORRENTS).map_err(|e| Error::InternalServer {
32-
message: format!("{e:?}"),
33-
location: Location::caller(),
31+
pub(crate) async fn handle_packet(udp_request: UdpRequest, tracker: &Arc<Tracker>) -> Response {
32+
debug!("Handling Packets: {udp_request:?}");
33+
match Request::from_bytes(&udp_request.payload[..udp_request.payload.len()], MAX_SCRAPE_TORRENTS).map_err(|e| {
34+
Error::InternalServer {
35+
message: format!("{e:?}"),
36+
location: Location::caller(),
37+
}
3438
}) {
3539
Ok(request) => {
3640
let transaction_id = match &request {
@@ -39,7 +43,7 @@ pub async fn handle_packet(remote_addr: SocketAddr, payload: Vec<u8>, tracker: &
3943
Request::Scrape(scrape_request) => scrape_request.transaction_id,
4044
};
4145

42-
match handle_request(request, remote_addr, tracker).await {
46+
match handle_request(request, udp_request.from, tracker).await {
4347
Ok(response) => response,
4448
Err(e) => handle_error(&e, transaction_id),
4549
}
@@ -60,6 +64,8 @@ pub async fn handle_packet(remote_addr: SocketAddr, payload: Vec<u8>, tracker: &
6064
///
6165
/// If a error happens in the `handle_request` function, it will just return the `ServerError`.
6266
pub async fn handle_request(request: Request, remote_addr: SocketAddr, tracker: &Tracker) -> Result<Response, Error> {
67+
debug!("Handling Request: {request:?} to: {remote_addr:?}");
68+
6369
match request {
6470
Request::Connect(connect_request) => handle_connect(remote_addr, &connect_request, tracker).await,
6571
Request::Announce(announce_request) => handle_announce(remote_addr, &announce_request, tracker).await,

src/servers/udp/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,9 @@
638638
//! documentation by [Arvid Norberg](https://github.com/arvidn) was very
639639
//! supportive in the development of this documentation. Some descriptions were
640640
//! taken from the [libtorrent](https://www.rasterbar.com/products/libtorrent/udp_tracker_protocol.html).
641+
642+
use std::net::SocketAddr;
643+
641644
pub mod connection_cookie;
642645
pub mod error;
643646
pub mod handlers;
@@ -652,3 +655,9 @@ pub type Port = u16;
652655
/// The transaction id. A random number generated byt the peer that is used to
653656
/// match requests and responses.
654657
pub type TransactionId = i64;
658+
659+
#[derive(Clone, Debug)]
660+
pub(crate) struct UdpRequest {
661+
payload: Vec<u8>,
662+
from: SocketAddr,
663+
}

0 commit comments

Comments
 (0)