@@ -447,6 +447,7 @@ use std::time::Duration;
447
447
448
448
use derive_more:: Constructor ;
449
449
use futures:: future:: join_all;
450
+ use log:: debug;
450
451
use tokio:: sync:: mpsc:: error:: SendError ;
451
452
use torrust_tracker_configuration:: { AnnouncePolicy , Configuration } ;
452
453
use torrust_tracker_primitives:: TrackerMode ;
@@ -472,17 +473,19 @@ pub const TORRENT_PEERS_LIMIT: usize = 74;
472
473
/// Typically, the `Tracker` is used by a higher application service that handles
473
474
/// the network layer.
474
475
pub struct Tracker {
475
- /// `Tracker` configuration. See [`torrust-tracker-configuration`](torrust_tracker_configuration)
476
- pub config : Arc < Configuration > ,
476
+ announce_policy : AnnouncePolicy ,
477
477
/// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite)
478
478
/// or [`MySQL`](crate::core::databases::mysql)
479
479
pub database : Arc < Box < dyn Database > > ,
480
480
mode : TrackerMode ,
481
+ policy : TrackerPolicy ,
481
482
keys : tokio:: sync:: RwLock < std:: collections:: HashMap < Key , auth:: ExpiringKey > > ,
482
483
whitelist : tokio:: sync:: RwLock < std:: collections:: HashSet < InfoHash > > ,
483
484
pub torrents : Arc < RepositoryAsyncSingle > ,
484
485
stats_event_sender : Option < Box < dyn statistics:: EventSender > > ,
485
486
stats_repository : statistics:: Repo ,
487
+ external_ip : Option < IpAddr > ,
488
+ on_reverse_proxy : bool ,
486
489
}
487
490
488
491
/// Structure that holds general `Tracker` torrents metrics.
@@ -500,6 +503,12 @@ pub struct TorrentsMetrics {
500
503
pub torrents : u64 ,
501
504
}
502
505
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
+ }
503
512
/// Structure that holds the data returned by the `announce` request.
504
513
#[ derive( Clone , Debug , PartialEq , Constructor , Default ) ]
505
514
pub struct AnnounceData {
@@ -556,7 +565,7 @@ impl Tracker {
556
565
///
557
566
/// Will return a `databases::error::Error` if unable to connect to database. The `Tracker` is responsible for the persistence.
558
567
pub fn new (
559
- config : Arc < Configuration > ,
568
+ config : & Configuration ,
560
569
stats_event_sender : Option < Box < dyn statistics:: EventSender > > ,
561
570
stats_repository : statistics:: Repo ,
562
571
) -> Result < Tracker , databases:: error:: Error > {
@@ -565,14 +574,22 @@ impl Tracker {
565
574
let mode = config. mode ;
566
575
567
576
Ok ( Tracker {
568
- config,
577
+ //config,
578
+ announce_policy : AnnouncePolicy :: new ( config. announce_interval , config. min_announce_interval ) ,
569
579
mode,
570
580
keys : tokio:: sync:: RwLock :: new ( std:: collections:: HashMap :: new ( ) ) ,
571
581
whitelist : tokio:: sync:: RwLock :: new ( std:: collections:: HashSet :: new ( ) ) ,
572
582
torrents : Arc :: new ( RepositoryAsyncSingle :: new ( ) ) ,
573
583
stats_event_sender,
574
584
stats_repository,
575
585
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 ,
576
593
} )
577
594
}
578
595
@@ -596,6 +613,19 @@ impl Tracker {
596
613
self . is_private ( )
597
614
}
598
615
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
+
599
629
/// It handles an announce request.
600
630
///
601
631
/// # Context: Tracker
@@ -617,18 +647,19 @@ impl Tracker {
617
647
// we are actually handling authentication at the handlers level. So I would extract that
618
648
// responsibility into another authentication service.
619
649
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:?}" ) ;
621
653
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 ;
623
656
624
657
let peers = self . get_torrent_peers_for_peer ( info_hash, peer) . await ;
625
658
626
- let policy = AnnouncePolicy :: new ( self . config . announce_interval , self . config . min_announce_interval ) ;
627
-
628
659
AnnounceData {
629
660
peers,
630
- stats : swarm_stats ,
631
- policy,
661
+ stats,
662
+ policy : self . get_announce_policy ( ) ,
632
663
}
633
664
}
634
665
@@ -727,7 +758,7 @@ impl Tracker {
727
758
728
759
let ( stats, stats_updated) = self . torrents . update_torrent_with_peer_and_get_stats ( info_hash, peer) . await ;
729
760
730
- if self . config . persistent_torrent_completed_stat && stats_updated {
761
+ if self . policy . persistent_torrent_completed_stat && stats_updated {
731
762
let completed = stats. downloaded ;
732
763
let info_hash = * info_hash;
733
764
@@ -788,17 +819,17 @@ impl Tracker {
788
819
let mut torrents_lock = self . torrents . get_torrents_mut ( ) . await ;
789
820
790
821
// 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 {
792
823
let mut cleaned_torrents_map: BTreeMap < InfoHash , torrent:: Entry > = BTreeMap :: new ( ) ;
793
824
794
825
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 ) ;
796
827
797
828
if torrent_entry. peers . is_empty ( ) {
798
829
continue ;
799
830
}
800
831
801
- if self . config . persistent_torrent_completed_stat && torrent_entry. completed == 0 {
832
+ if self . policy . persistent_torrent_completed_stat && torrent_entry. completed == 0 {
802
833
continue ;
803
834
}
804
835
@@ -808,7 +839,7 @@ impl Tracker {
808
839
* torrents_lock = cleaned_torrents_map;
809
840
} else {
810
841
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 ) ;
812
843
}
813
844
}
814
845
}
@@ -1061,7 +1092,6 @@ mod tests {
1061
1092
1062
1093
use std:: net:: { IpAddr , Ipv4Addr , SocketAddr } ;
1063
1094
use std:: str:: FromStr ;
1064
- use std:: sync:: Arc ;
1065
1095
1066
1096
use aquatic_udp_protocol:: { AnnounceEvent , NumberOfBytes } ;
1067
1097
use torrust_tracker_test_helpers:: configuration;
@@ -1073,21 +1103,21 @@ mod tests {
1073
1103
use crate :: shared:: clock:: DurationSinceUnixEpoch ;
1074
1104
1075
1105
fn public_tracker ( ) -> Tracker {
1076
- tracker_factory ( configuration:: ephemeral_mode_public ( ) . into ( ) )
1106
+ tracker_factory ( & configuration:: ephemeral_mode_public ( ) )
1077
1107
}
1078
1108
1079
1109
fn private_tracker ( ) -> Tracker {
1080
- tracker_factory ( configuration:: ephemeral_mode_private ( ) . into ( ) )
1110
+ tracker_factory ( & configuration:: ephemeral_mode_private ( ) )
1081
1111
}
1082
1112
1083
1113
fn whitelisted_tracker ( ) -> Tracker {
1084
- tracker_factory ( configuration:: ephemeral_mode_whitelisted ( ) . into ( ) )
1114
+ tracker_factory ( & configuration:: ephemeral_mode_whitelisted ( ) )
1085
1115
}
1086
1116
1087
1117
pub fn tracker_persisting_torrents_in_database ( ) -> Tracker {
1088
1118
let mut configuration = configuration:: ephemeral ( ) ;
1089
1119
configuration. persistent_torrent_completed_stat = true ;
1090
- tracker_factory ( Arc :: new ( configuration) )
1120
+ tracker_factory ( & configuration)
1091
1121
}
1092
1122
1093
1123
fn sample_info_hash ( ) -> InfoHash {
0 commit comments