@@ -447,6 +447,7 @@ use std::time::Duration;
447447
448448use derive_more:: Constructor ;
449449use futures:: future:: join_all;
450+ use log:: debug;
450451use tokio:: sync:: mpsc:: error:: SendError ;
451452use torrust_tracker_configuration:: { AnnouncePolicy , Configuration } ;
452453use torrust_tracker_primitives:: TrackerMode ;
@@ -472,17 +473,19 @@ pub const TORRENT_PEERS_LIMIT: usize = 74;
472473/// Typically, the `Tracker` is used by a higher application service that handles
473474/// the network layer.
474475pub struct Tracker {
475- /// `Tracker` configuration. See [`torrust-tracker-configuration`](torrust_tracker_configuration)
476- pub config : Arc < Configuration > ,
476+ announce_policy : AnnouncePolicy ,
477477 /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite)
478478 /// or [`MySQL`](crate::core::databases::mysql)
479479 pub database : Arc < Box < dyn Database > > ,
480480 mode : TrackerMode ,
481+ policy : TrackerPolicy ,
481482 keys : tokio:: sync:: RwLock < std:: collections:: HashMap < Key , auth:: ExpiringKey > > ,
482483 whitelist : tokio:: sync:: RwLock < std:: collections:: HashSet < InfoHash > > ,
483484 pub torrents : Arc < RepositoryAsyncSingle > ,
484485 stats_event_sender : Option < Box < dyn statistics:: EventSender > > ,
485486 stats_repository : statistics:: Repo ,
487+ external_ip : Option < IpAddr > ,
488+ on_reverse_proxy : bool ,
486489}
487490
488491/// Structure that holds general `Tracker` torrents metrics.
@@ -500,6 +503,12 @@ pub struct TorrentsMetrics {
500503 pub torrents : u64 ,
501504}
502505
506+ #[ derive( Copy , Clone , Debug , PartialEq , Default , Constructor ) ]
507+ pub struct TrackerPolicy {
508+ pub remove_peerless_torrents : bool ,
509+ pub max_peer_timeout : u32 ,
510+ pub persistent_torrent_completed_stat : bool ,
511+ }
503512/// Structure that holds the data returned by the `announce` request.
504513#[ derive( Clone , Debug , PartialEq , Constructor , Default ) ]
505514pub struct AnnounceData {
@@ -556,7 +565,7 @@ impl Tracker {
556565 ///
557566 /// Will return a `databases::error::Error` if unable to connect to database. The `Tracker` is responsible for the persistence.
558567 pub fn new (
559- config : Arc < Configuration > ,
568+ config : & Configuration ,
560569 stats_event_sender : Option < Box < dyn statistics:: EventSender > > ,
561570 stats_repository : statistics:: Repo ,
562571 ) -> Result < Tracker , databases:: error:: Error > {
@@ -565,14 +574,22 @@ impl Tracker {
565574 let mode = config. mode ;
566575
567576 Ok ( Tracker {
568- config,
577+ //config,
578+ announce_policy : AnnouncePolicy :: new ( config. announce_interval , config. min_announce_interval ) ,
569579 mode,
570580 keys : tokio:: sync:: RwLock :: new ( std:: collections:: HashMap :: new ( ) ) ,
571581 whitelist : tokio:: sync:: RwLock :: new ( std:: collections:: HashSet :: new ( ) ) ,
572582 torrents : Arc :: new ( RepositoryAsyncSingle :: new ( ) ) ,
573583 stats_event_sender,
574584 stats_repository,
575585 database,
586+ external_ip : config. get_ext_ip ( ) ,
587+ policy : TrackerPolicy :: new (
588+ config. remove_peerless_torrents ,
589+ config. max_peer_timeout ,
590+ config. persistent_torrent_completed_stat ,
591+ ) ,
592+ on_reverse_proxy : config. on_reverse_proxy ,
576593 } )
577594 }
578595
@@ -596,6 +613,19 @@ impl Tracker {
596613 self . is_private ( )
597614 }
598615
616+ /// Returns `true` is the tracker is in whitelisted mode.
617+ pub fn is_behind_reverse_proxy ( & self ) -> bool {
618+ self . on_reverse_proxy
619+ }
620+
621+ pub fn get_announce_policy ( & self ) -> AnnouncePolicy {
622+ self . announce_policy
623+ }
624+
625+ pub fn get_maybe_external_ip ( & self ) -> Option < IpAddr > {
626+ self . external_ip
627+ }
628+
599629 /// It handles an announce request.
600630 ///
601631 /// # Context: Tracker
@@ -617,18 +647,19 @@ impl Tracker {
617647 // we are actually handling authentication at the handlers level. So I would extract that
618648 // responsibility into another authentication service.
619649
620- peer. change_ip ( & assign_ip_address_to_peer ( remote_client_ip, self . config . get_ext_ip ( ) ) ) ;
650+ debug ! ( "Before: {peer:?}" ) ;
651+ peer. change_ip ( & assign_ip_address_to_peer ( remote_client_ip, self . external_ip ) ) ;
652+ debug ! ( "After: {peer:?}" ) ;
621653
622- let swarm_stats = self . update_torrent_with_peer_and_get_stats ( info_hash, peer) . await ;
654+ // we should update the torrent and get the stats before we get the peer list.
655+ let stats = self . update_torrent_with_peer_and_get_stats ( info_hash, peer) . await ;
623656
624657 let peers = self . get_torrent_peers_for_peer ( info_hash, peer) . await ;
625658
626- let policy = AnnouncePolicy :: new ( self . config . announce_interval , self . config . min_announce_interval ) ;
627-
628659 AnnounceData {
629660 peers,
630- stats : swarm_stats ,
631- policy,
661+ stats,
662+ policy : self . get_announce_policy ( ) ,
632663 }
633664 }
634665
@@ -727,7 +758,7 @@ impl Tracker {
727758
728759 let ( stats, stats_updated) = self . torrents . update_torrent_with_peer_and_get_stats ( info_hash, peer) . await ;
729760
730- if self . config . persistent_torrent_completed_stat && stats_updated {
761+ if self . policy . persistent_torrent_completed_stat && stats_updated {
731762 let completed = stats. downloaded ;
732763 let info_hash = * info_hash;
733764
@@ -788,17 +819,17 @@ impl Tracker {
788819 let mut torrents_lock = self . torrents . get_torrents_mut ( ) . await ;
789820
790821 // If we don't need to remove torrents we will use the faster iter
791- if self . config . remove_peerless_torrents {
822+ if self . policy . remove_peerless_torrents {
792823 let mut cleaned_torrents_map: BTreeMap < InfoHash , torrent:: Entry > = BTreeMap :: new ( ) ;
793824
794825 for ( info_hash, torrent_entry) in & mut * torrents_lock {
795- torrent_entry. remove_inactive_peers ( self . config . max_peer_timeout ) ;
826+ torrent_entry. remove_inactive_peers ( self . policy . max_peer_timeout ) ;
796827
797828 if torrent_entry. peers . is_empty ( ) {
798829 continue ;
799830 }
800831
801- if self . config . persistent_torrent_completed_stat && torrent_entry. completed == 0 {
832+ if self . policy . persistent_torrent_completed_stat && torrent_entry. completed == 0 {
802833 continue ;
803834 }
804835
@@ -808,7 +839,7 @@ impl Tracker {
808839 * torrents_lock = cleaned_torrents_map;
809840 } else {
810841 for torrent_entry in ( * torrents_lock) . values_mut ( ) {
811- torrent_entry. remove_inactive_peers ( self . config . max_peer_timeout ) ;
842+ torrent_entry. remove_inactive_peers ( self . policy . max_peer_timeout ) ;
812843 }
813844 }
814845 }
@@ -1061,7 +1092,6 @@ mod tests {
10611092
10621093 use std:: net:: { IpAddr , Ipv4Addr , SocketAddr } ;
10631094 use std:: str:: FromStr ;
1064- use std:: sync:: Arc ;
10651095
10661096 use aquatic_udp_protocol:: { AnnounceEvent , NumberOfBytes } ;
10671097 use torrust_tracker_test_helpers:: configuration;
@@ -1073,21 +1103,21 @@ mod tests {
10731103 use crate :: shared:: clock:: DurationSinceUnixEpoch ;
10741104
10751105 fn public_tracker ( ) -> Tracker {
1076- tracker_factory ( configuration:: ephemeral_mode_public ( ) . into ( ) )
1106+ tracker_factory ( & configuration:: ephemeral_mode_public ( ) )
10771107 }
10781108
10791109 fn private_tracker ( ) -> Tracker {
1080- tracker_factory ( configuration:: ephemeral_mode_private ( ) . into ( ) )
1110+ tracker_factory ( & configuration:: ephemeral_mode_private ( ) )
10811111 }
10821112
10831113 fn whitelisted_tracker ( ) -> Tracker {
1084- tracker_factory ( configuration:: ephemeral_mode_whitelisted ( ) . into ( ) )
1114+ tracker_factory ( & configuration:: ephemeral_mode_whitelisted ( ) )
10851115 }
10861116
10871117 pub fn tracker_persisting_torrents_in_database ( ) -> Tracker {
10881118 let mut configuration = configuration:: ephemeral ( ) ;
10891119 configuration. persistent_torrent_completed_stat = true ;
1090- tracker_factory ( Arc :: new ( configuration) )
1120+ tracker_factory ( & configuration)
10911121 }
10921122
10931123 fn sample_info_hash ( ) -> InfoHash {
0 commit comments