Skip to content

Commit 046ca86

Browse files
committed
Merge #273: Crate docs for servers::upd module
7014a46 docs: [#271] crate docs for servers::udp mod (Jose Celano) Pull request description: Documentation for the `crate::servers::udp` module. The UDP tracker. ACKs for top commit: josecelano: ACK 7014a46 Tree-SHA512: 6c39d30c4163e3fc64a102aefb2e51715ceb7fe967124cea39ee6b678244c0bbe944a94901f59fed8e90bc03b44bdfae38cf3a29b9cbe4dd339ac295844078d4
2 parents 6126679 + 7014a46 commit 046ca86

File tree

15 files changed

+886
-25
lines changed

15 files changed

+886
-25
lines changed

cSpell.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"words": [
33
"appuser",
4+
"Arvid",
45
"AUTOINCREMENT",
56
"automock",
67
"Avicora",
@@ -21,6 +22,7 @@
2122
"chrono",
2223
"clippy",
2324
"completei",
25+
"connectionless",
2426
"dockerhub",
2527
"downloadedi",
2628
"filesd",
@@ -47,6 +49,7 @@
4749
"nanos",
4850
"nextest",
4951
"nocapture",
52+
"Norberg",
5053
"numwant",
5154
"oneshot",
5255
"ostr",
@@ -59,6 +62,7 @@
5962
"reqwest",
6063
"rerequests",
6164
"rngs",
65+
"routable",
6266
"rusqlite",
6367
"rustfmt",
6468
"Rustls",
@@ -82,6 +86,7 @@
8286
"Vagaa",
8387
"Vuze",
8488
"whitespaces",
89+
"XBTT",
8590
"Xtorrent",
8691
"Xunlei",
8792
"xxxxxxxxxxxxxxxxxxxxd",

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,6 @@
428428
//! - [BEP 15](https://www.bittorrent.org/beps/bep_0015.html): UDP Tracker Protocol for `BitTorrent`
429429
//! - [BEP 23](https://www.bittorrent.org/beps/bep_0023.html): Tracker Returns Compact Peer Lists
430430
//! - [BEP 27](https://www.bittorrent.org/beps/bep_0027.html): Private Torrents
431-
//! - [BEP 41](https://www.bittorrent.org/beps/bep_0041.html): UDP Tracker Protocol Extensions
432431
//! - [BEP 48](https://www.bittorrent.org/beps/bep_0048.html): Tracker Protocol Extension: Scrape
433432
//!
434433
//! # Contributing

src/servers/http/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
//!
4444
//! Parameter | Type | Description | Required | Default | Example
4545
//! ---|---|---|---|---|---
46-
//! [`info_hash`](crate::servers::http::v1::requests::announce::Announce::info_hash) | percent encoded of 40-byte array | The `Info Hash` of the torrent. | Yes | No | `%81%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00`
46+
//! [`info_hash`](crate::servers::http::v1::requests::announce::Announce::info_hash) | percent encoded of 20-byte array | The `Info Hash` of the torrent. | Yes | No | `%81%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00`
4747
//! `peer_addr` | string |The IP address of the peer. | No | No | `2.137.87.41`
4848
//! [`downloaded`](crate::servers::http::v1::requests::announce::Announce::downloaded) | positive integer |The number of bytes downloaded by the peer. | No | `0` | `0`
4949
//! [`uploaded`](crate::servers::http::v1::requests::announce::Announce::uploaded) | positive integer | The number of bytes uploaded by the peer. | No | `0` | `0`
@@ -220,7 +220,7 @@
220220
//!
221221
//! Parameter | Type | Description | Required | Default | Example
222222
//! ---|---|---|---|---|---
223-
//! [`info_hash`](crate::servers::http::v1::requests::scrape::Scrape::info_hashes) | percent encoded of 40-byte array | The `Info Hash` of the torrent. | Yes | No | `%81%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00`
223+
//! [`info_hash`](crate::servers::http::v1::requests::scrape::Scrape::info_hashes) | percent encoded of 20-byte array | The `Info Hash` of the torrent. | Yes | No | `%81%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00`
224224
//!
225225
//! > **NOTICE**: you can scrape multiple torrents at the same time by passing
226226
//! multiple `info_hash` parameters.

src/servers/http/percent_encoding.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::shared::bit_torrent::info_hash::{ConversionError, InfoHash};
1919
use crate::tracker::peer::{self, IdConversionError};
2020

2121
/// Percent decodes a percent encoded infohash. Internally an
22-
/// [`InfoHash`](crate::shared::bit_torrent::info_hash::InfoHash) is a 40-byte array.
22+
/// [`InfoHash`](crate::shared::bit_torrent::info_hash::InfoHash) is a 20-byte array.
2323
///
2424
/// For example, given the infohash `3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0`,
2525
/// it's percent encoded representation is `%3B%24U%04%CF%5F%11%BB%DB%E1%20%1C%EAjk%F4Z%EE%1B%C0`.

src/servers/http/server.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ pub enum Error {
4444
Error(String), // todo: refactor to use thiserror and add more variants for specific errors.
4545
}
4646

47-
/// A stopped HTTP server.
47+
/// A HTTP server instance controller with no HTTP instance running.
4848
#[allow(clippy::module_name_repetitions)]
4949
pub type StoppedHttpServer<I> = HttpServer<Stopped<I>>;
5050

51-
/// A running HTTP server.
51+
/// A HTTP server instance controller with a running HTTP instance.
5252
#[allow(clippy::module_name_repetitions)]
5353
pub type RunningHttpServer<I> = HttpServer<Running<I>>;
5454

55-
/// A HTTP running server controller.
55+
/// A HTTP server instance controller.
5656
///
5757
/// It's responsible for:
5858
///
@@ -83,12 +83,14 @@ pub struct Stopped<I: HttpServerLauncher> {
8383

8484
/// A running HTTP server state.
8585
pub struct Running<I: HttpServerLauncher> {
86+
/// The address where the server is bound.
8687
pub bind_addr: SocketAddr,
8788
task_killer: tokio::sync::oneshot::Sender<u8>,
8889
task: tokio::task::JoinHandle<I>,
8990
}
9091

9192
impl<I: HttpServerLauncher + 'static> HttpServer<Stopped<I>> {
93+
/// It creates a new `HttpServer` controller in `stopped` state.
9294
pub fn new(cfg: torrust_tracker_configuration::HttpTracker, launcher: I) -> Self {
9395
Self {
9496
cfg,

src/servers/http/v1/requests/announce.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub struct Announce {
8888
/// Errors that can occur when parsing the `Announce` request.
8989
///
9090
/// The `info_hash` and `peer_id` query params are special because they contain
91-
/// binary data. The `info_hash` is a 40-byte SHA1 hash and the `peer_id` is a
91+
/// binary data. The `info_hash` is a 20-byte SHA1 hash and the `peer_id` is a
9292
/// 20-byte array.
9393
#[derive(Error, Debug)]
9494
pub enum ParseAnnounceQueryError {

src/servers/signals.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/// This module contains functions to handle signals.
1+
//! This module contains functions to handle signals.
22
use log::info;
33

44
/// Resolves on `ctrl_c` or the `terminate` signal.

src/servers/udp/connection_cookie.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,71 @@
1+
//! Logic for generating and verifying connection IDs.
2+
//!
3+
//! The UDP tracker requires the client to connect to the server before it can
4+
//! send any data. The server responds with a random 64-bit integer that the
5+
//! client must use to identify itself.
6+
//!
7+
//! This connection ID is used to avoid spoofing attacks. The client must send
8+
//! the connection ID in all requests to the server. The server will ignore any
9+
//! requests that do not contain the correct connection ID.
10+
//!
11+
//! The simplest way to implement this would be to generate a random number when
12+
//! the client connects and store it in a hash table. However, this would
13+
//! require the server to store a large number of connection IDs, which would be
14+
//! a waste of memory. Instead, the server generates a connection ID based on
15+
//! the client's IP address and the current time. This allows the server to
16+
//! verify the connection ID without storing it.
17+
//!
18+
//! This module implements this method of generating connection IDs. It's the
19+
//! most common way to generate connection IDs. The connection ID is generated
20+
//! using a time based algorithm and it is valid for a certain amount of time
21+
//! (usually two minutes). The connection ID is generated using the following:
22+
//!
23+
//! ```text
24+
//! connection ID = hash(client IP + current time slot + secret seed)
25+
//! ```
26+
//!
27+
//! Time slots are two minute intervals since the Unix epoch. The secret seed is
28+
//! a random number that is generated when the server starts. And the client IP
29+
//! is used in order generate a unique connection ID for each client.
30+
//!
31+
//! The BEP-15 recommends a two-minute time slot.
32+
//!
33+
//! ```text
34+
//! Timestamp (seconds from Unix epoch):
35+
//! |------------|------------|------------|------------|
36+
//! 0 120 240 360 480
37+
//! Time slots (two-minutes time extents from Unix epoch):
38+
//! |------------|------------|------------|------------|
39+
//! 0 1 2 3 4
40+
//! Peer connections:
41+
//! Peer A |-------------------------|
42+
//! Peer B |-------------------------|
43+
//! Peer C |------------------|
44+
//! Peer A connects at timestamp 120 slot 1 -> connection ID will be valid from timestamp 120 to 360
45+
//! Peer B connects at timestamp 240 slot 2 -> connection ID will be valid from timestamp 240 to 480
46+
//! Peer C connects at timestamp 180 slot 1 -> connection ID will be valid from timestamp 180 to 360
47+
//! ```
48+
//! > **NOTICE**: connection ID is always the same for a given peer
49+
//! (socket address) and time slot.
50+
//!
51+
//! > **NOTICE**: connection ID will be valid for two time extents, **not two
52+
//! minutes**. It'll be valid for the the current time extent and the next one.
53+
//!
54+
//! Refer to [`Connect`](crate::servers::udp#connect) for more information about
55+
//! the connection process.
56+
//!
57+
//! ## Advantages
58+
//!
59+
//! - It consumes less memory than storing a hash table of connection IDs.
60+
//! - It's easy to implement.
61+
//! - It's fast.
62+
//!
63+
//! ## Disadvantages
64+
//!
65+
//! - It's not very flexible. The connection ID is only valid for a certain
66+
//! amount of time.
67+
//! - It's not very accurate. The connection ID is valid for more than two
68+
//! minutes.
169
use std::net::SocketAddr;
270
use std::panic::Location;
371

@@ -12,16 +80,19 @@ pub type SinceUnixEpochTimeExtent = TimeExtent;
1280

1381
pub const COOKIE_LIFETIME: TimeExtent = TimeExtent::from_sec(2, &60);
1482

83+
/// Converts a connection ID into a connection cookie.
1584
#[must_use]
1685
pub fn from_connection_id(connection_id: &ConnectionId) -> Cookie {
1786
connection_id.0.to_le_bytes()
1887
}
1988

89+
/// Converts a connection cookie into a connection ID.
2090
#[must_use]
2191
pub fn into_connection_id(connection_cookie: &Cookie) -> ConnectionId {
2292
ConnectionId(i64::from_le_bytes(*connection_cookie))
2393
}
2494

95+
/// Generates a new connection cookie.
2596
#[must_use]
2697
pub fn make(remote_address: &SocketAddr) -> Cookie {
2798
let time_extent = cookie_builder::get_last_time_extent();
@@ -30,6 +101,8 @@ pub fn make(remote_address: &SocketAddr) -> Cookie {
30101
cookie_builder::build(remote_address, &time_extent)
31102
}
32103

104+
/// Checks if the supplied `connection_cookie` is valid.
105+
///
33106
/// # Panics
34107
///
35108
/// It would panic if the `COOKIE_LIFETIME` constant would be an unreasonably large number.

src/servers/udp/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
1+
//! Error types for the UDP server.
12
use std::panic::Location;
23

34
use thiserror::Error;
45
use torrust_tracker_located_error::LocatedError;
56

7+
/// Error returned by the UDP server.
68
#[derive(Error, Debug)]
79
pub enum Error {
10+
/// Error returned when the domain tracker returns an error.
811
#[error("tracker server error: {source}")]
912
TrackerError {
1013
source: LocatedError<'static, dyn std::error::Error + Send + Sync>,
1114
},
1215

16+
/// Error returned from a third-party library (aquatic_udp_protocol).
1317
#[error("internal server error: {message}, {location}")]
1418
InternalServer {
1519
location: &'static Location<'static>,
1620
message: String,
1721
},
1822

23+
/// Error returned when the connection id could not be verified.
1924
#[error("connection id could not be verified")]
2025
InvalidConnectionId { location: &'static Location<'static> },
2126

27+
/// Error returned when the request is invalid.
2228
#[error("bad request: {source}")]
2329
BadRequest {
2430
source: LocatedError<'static, dyn std::error::Error + Send + Sync>,

0 commit comments

Comments
 (0)