diff --git a/packages/configuration/src/lib.rs b/packages/configuration/src/lib.rs index 1c097952..58de9458 100644 --- a/packages/configuration/src/lib.rs +++ b/packages/configuration/src/lib.rs @@ -387,26 +387,9 @@ pub struct HealthCheckApi { pub bind_address: String, } -/// Core configuration for the tracker. -#[allow(clippy::struct_excessive_bools)] -#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] -pub struct Configuration { - /// Logging level. Possible values are: `Off`, `Error`, `Warn`, `Info`, - /// `Debug` and `Trace`. Default is `Info`. - pub log_level: Option, - /// Tracker mode. See [`TrackerMode`] for more information. - pub mode: TrackerMode, - - // Database configuration - /// Database driver. Possible values are: `Sqlite3`, and `MySQL`. - pub db_driver: DatabaseDriver, - /// Database connection string. The format depends on the database driver. - /// For `Sqlite3`, the format is `path/to/database.db`, for example: - /// `./storage/tracker/lib/database/sqlite3.db`. - /// For `Mysql`, the format is `mysql://db_user:db_user_password:port/db_name`, for - /// example: `root:password@localhost:3306/torrust`. - pub db_path: String, - +/// Announce policy +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Copy)] +pub struct AnnouncePolicy { /// Interval in seconds that the client should wait between sending regular /// announce requests to the tracker. /// @@ -418,7 +401,8 @@ pub struct Configuration { /// client's initial request. It serves as a guideline for clients to know /// how often they should contact the tracker for updates on the peer list, /// while ensuring that the tracker is not overwhelmed with requests. - pub announce_interval: u32, + pub interval: u32, + /// Minimum announce interval. Clients must not reannounce more frequently /// than this. /// @@ -430,6 +414,42 @@ pub struct Configuration { /// value to prevent sending too many requests in a short period, which /// could lead to excessive load on the tracker or even getting banned by /// the tracker for not adhering to the rules. + pub interval_min: u32, +} + +impl Default for AnnouncePolicy { + fn default() -> Self { + Self { + interval: 120, + interval_min: 120, + } + } +} + +/// Core configuration for the tracker. +#[allow(clippy::struct_excessive_bools)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] +pub struct Configuration { + /// Logging level. Possible values are: `Off`, `Error`, `Warn`, `Info`, + /// `Debug` and `Trace`. Default is `Info`. + pub log_level: Option, + /// Tracker mode. See [`TrackerMode`] for more information. + pub mode: TrackerMode, + + // Database configuration + /// Database driver. Possible values are: `Sqlite3`, and `MySQL`. + pub db_driver: DatabaseDriver, + /// Database connection string. The format depends on the database driver. + /// For `Sqlite3`, the format is `path/to/database.db`, for example: + /// `./storage/tracker/lib/database/sqlite3.db`. + /// For `Mysql`, the format is `mysql://db_user:db_user_password:port/db_name`, for + /// example: `root:password@localhost:3306/torrust`. + pub db_path: String, + + /// See [`AnnouncePolicy::interval`] + pub announce_interval: u32, + + /// See [`AnnouncePolicy::interval_min`] pub min_announce_interval: u32, /// Weather the tracker is behind a reverse proxy or not. /// If the tracker is behind a reverse proxy, the `X-Forwarded-For` header @@ -516,13 +536,14 @@ impl From for Error { impl Default for Configuration { fn default() -> Self { + let announce_policy = AnnouncePolicy::default(); let mut configuration = Configuration { log_level: Option::from(String::from("info")), mode: TrackerMode::Public, db_driver: DatabaseDriver::Sqlite3, db_path: String::from("./storage/tracker/lib/database/sqlite3.db"), - announce_interval: 120, - min_announce_interval: 120, + announce_interval: announce_policy.interval, + min_announce_interval: announce_policy.interval_min, max_peer_timeout: 900, on_reverse_proxy: false, external_ip: Some(String::from("0.0.0.0")), diff --git a/src/servers/http/mod.rs b/src/servers/http/mod.rs index b2d232fc..e4e42b1c 100644 --- a/src/servers/http/mod.rs +++ b/src/servers/http/mod.rs @@ -152,7 +152,7 @@ //! 000000f0: 65 e //! ``` //! -//! Refer to the [`NonCompact`](crate::servers::http::v1::responses::announce::NonCompact) +//! Refer to the [`Normal`](crate::servers::http::v1::responses::announce::Normal) //! response for more information about the response. //! //! **Sample compact response** diff --git a/src/servers/http/v1/requests/announce.rs b/src/servers/http/v1/requests/announce.rs index 7f77f727..f65d2292 100644 --- a/src/servers/http/v1/requests/announce.rs +++ b/src/servers/http/v1/requests/announce.rs @@ -180,7 +180,7 @@ impl fmt::Display for Event { /// Depending on the value of this param, the tracker will return a different /// response: /// -/// - [`NonCompact`](crate::servers::http::v1::responses::announce::NonCompact) response. +/// - [`Normal`](crate::servers::http::v1::responses::announce::Normal) response. /// - [`Compact`](crate::servers::http::v1::responses::announce::Compact) response. /// /// Refer to [BEP 23. Tracker Returns Compact Peer Lists](https://www.bittorrent.org/beps/bep_0023.html) diff --git a/src/servers/http/v1/responses/announce.rs b/src/servers/http/v1/responses/announce.rs index 52155f17..b19a311d 100644 --- a/src/servers/http/v1/responses/announce.rs +++ b/src/servers/http/v1/responses/announce.rs @@ -9,6 +9,7 @@ use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; use serde::{self, Deserialize, Serialize}; use thiserror::Error; +use torrust_tracker_configuration::AnnouncePolicy; use torrust_tracker_contrib_bencode::{ben_bytes, ben_int, ben_list, ben_map, BMutAccess, BencodeMut}; use crate::core::{self, AnnounceData}; @@ -20,11 +21,14 @@ use crate::servers::http::v1::responses; /// /// ```rust /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +/// use torrust_tracker_configuration::AnnouncePolicy; /// use torrust_tracker::servers::http::v1::responses::announce::{Normal, NormalPeer}; /// /// let response = Normal { -/// interval: 111, -/// interval_min: 222, +/// policy: AnnouncePolicy { +/// interval: 111, +/// interval_min: 222, +/// }, /// complete: 333, /// incomplete: 444, /// peers: vec![ @@ -58,31 +62,8 @@ use crate::servers::http::v1::responses; /// for more information. #[derive(Serialize, Deserialize, Debug, PartialEq)] pub struct Normal { - /// Interval in seconds that the client should wait between sending regular - /// announce requests to the tracker. - /// - /// It's a **recommended** wait time between announcements. - /// - /// This is the standard amount of time that clients should wait between - /// sending consecutive announcements to the tracker. This value is set by - /// the tracker and is typically provided in the tracker's response to a - /// client's initial request. It serves as a guideline for clients to know - /// how often they should contact the tracker for updates on the peer list, - /// while ensuring that the tracker is not overwhelmed with requests. - pub interval: u32, - /// Minimum announce interval. Clients must not reannounce more frequently - /// than this. - /// - /// It establishes the shortest allowed wait time. - /// - /// This is an optional parameter in the protocol that the tracker may - /// provide in its response. It sets a lower limit on the frequency at which - /// clients are allowed to send announcements. Clients should respect this - /// value to prevent sending too many requests in a short period, which - /// could lead to excessive load on the tracker or even getting banned by - /// the tracker for not adhering to the rules. - #[serde(rename = "min interval")] - pub interval_min: u32, + /// Announce policy + pub policy: AnnouncePolicy, /// Number of peers with the entire file, i.e. seeders. pub complete: u32, /// Number of non-seeder peers, aka "leechers". @@ -152,8 +133,8 @@ impl Normal { (ben_map! { "complete" => ben_int!(i64::from(self.complete)), "incomplete" => ben_int!(i64::from(self.incomplete)), - "interval" => ben_int!(i64::from(self.interval)), - "min interval" => ben_int!(i64::from(self.interval_min)), + "interval" => ben_int!(i64::from(self.policy.interval)), + "min interval" => ben_int!(i64::from(self.policy.interval_min)), "peers" => peers_list.clone() }) .encode() @@ -175,8 +156,10 @@ impl From for Normal { .collect(); Self { - interval: domain_announce_response.interval, - interval_min: domain_announce_response.interval_min, + policy: AnnouncePolicy { + interval: domain_announce_response.interval, + interval_min: domain_announce_response.interval_min, + }, complete: domain_announce_response.swarm_stats.seeders, incomplete: domain_announce_response.swarm_stats.leechers, peers, @@ -192,11 +175,14 @@ impl From for Normal { /// /// ```rust /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +/// use torrust_tracker_configuration::AnnouncePolicy; /// use torrust_tracker::servers::http::v1::responses::announce::{Compact, CompactPeer}; /// /// let response = Compact { -/// interval: 111, -/// interval_min: 222, +/// policy: AnnouncePolicy { +/// interval: 111, +/// interval_min: 222, +/// }, /// complete: 333, /// incomplete: 444, /// peers: vec![ @@ -232,31 +218,8 @@ impl From for Normal { /// - [BEP 07: IPv6 Tracker Extension](https://www.bittorrent.org/beps/bep_0007.html) #[derive(Serialize, Deserialize, Debug, PartialEq)] pub struct Compact { - /// Interval in seconds that the client should wait between sending regular - /// announce requests to the tracker. - /// - /// It's a **recommended** wait time between announcements. - /// - /// This is the standard amount of time that clients should wait between - /// sending consecutive announcements to the tracker. This value is set by - /// the tracker and is typically provided in the tracker's response to a - /// client's initial request. It serves as a guideline for clients to know - /// how often they should contact the tracker for updates on the peer list, - /// while ensuring that the tracker is not overwhelmed with requests. - pub interval: u32, - /// Minimum announce interval. Clients must not reannounce more frequently - /// than this. - /// - /// It establishes the shortest allowed wait time. - /// - /// This is an optional parameter in the protocol that the tracker may - /// provide in its response. It sets a lower limit on the frequency at which - /// clients are allowed to send announcements. Clients should respect this - /// value to prevent sending too many requests in a short period, which - /// could lead to excessive load on the tracker or even getting banned by - /// the tracker for not adhering to the rules. - #[serde(rename = "min interval")] - pub interval_min: u32, + /// Announce policy + pub policy: AnnouncePolicy, /// Number of seeders, aka "completed". pub complete: u32, /// Number of non-seeder peers, aka "incomplete". @@ -335,8 +298,8 @@ impl Compact { let bytes = (ben_map! { "complete" => ben_int!(i64::from(self.complete)), "incomplete" => ben_int!(i64::from(self.incomplete)), - "interval" => ben_int!(i64::from(self.interval)), - "min interval" => ben_int!(i64::from(self.interval_min)), + "interval" => ben_int!(i64::from(self.policy.interval)), + "min interval" => ben_int!(i64::from(self.policy.interval_min)), "peers" => ben_bytes!(self.peers_v4_bytes()?), "peers6" => ben_bytes!(self.peers_v6_bytes()?) }) @@ -414,8 +377,10 @@ impl From for Compact { .collect(); Self { - interval: domain_announce_response.interval, - interval_min: domain_announce_response.interval_min, + policy: AnnouncePolicy { + interval: domain_announce_response.interval, + interval_min: domain_announce_response.interval_min, + }, complete: domain_announce_response.swarm_stats.seeders, incomplete: domain_announce_response.swarm_stats.leechers, peers, @@ -428,6 +393,8 @@ mod tests { use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + use torrust_tracker_configuration::AnnouncePolicy; + use super::{Normal, NormalPeer}; use crate::servers::http::v1::responses::announce::{Compact, CompactPeer}; @@ -446,8 +413,10 @@ mod tests { #[test] fn normal_announce_response_can_be_bencoded() { let response = Normal { - interval: 111, - interval_min: 222, + policy: AnnouncePolicy { + interval: 111, + interval_min: 222, + }, complete: 333, incomplete: 444, peers: vec![ @@ -480,8 +449,10 @@ mod tests { #[test] fn compact_announce_response_can_be_bencoded() { let response = Compact { - interval: 111, - interval_min: 222, + policy: AnnouncePolicy { + interval: 111, + interval_min: 222, + }, complete: 333, incomplete: 444, peers: vec![