@@ -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:: 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,13 @@ 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
+ }
512
+
503
513
/// Tracker policy for Announcements
504
514
#[ derive( Copy , Clone , Debug , PartialEq , Default , Constructor ) ]
505
515
pub struct AnnouncePolicy {
@@ -569,7 +579,7 @@ impl Tracker {
569
579
///
570
580
/// Will return a `databases::error::Error` if unable to connect to database. The `Tracker` is responsible for the persistence.
571
581
pub fn new (
572
- config : Arc < Configuration > ,
582
+ config : & Arc < Configuration > ,
573
583
stats_event_sender : Option < Box < dyn statistics:: EventSender > > ,
574
584
stats_repository : statistics:: Repo ,
575
585
) -> Result < Tracker , databases:: error:: Error > {
@@ -578,14 +588,22 @@ impl Tracker {
578
588
let mode = config. mode ;
579
589
580
590
Ok ( Tracker {
581
- config,
591
+ //config,
592
+ announce_policy : AnnouncePolicy :: new ( config. announce_interval , config. min_announce_interval ) ,
582
593
mode,
583
594
keys : tokio:: sync:: RwLock :: new ( std:: collections:: HashMap :: new ( ) ) ,
584
595
whitelist : tokio:: sync:: RwLock :: new ( std:: collections:: HashSet :: new ( ) ) ,
585
596
torrents : Arc :: new ( RepositoryAsyncSingle :: new ( ) ) ,
586
597
stats_event_sender,
587
598
stats_repository,
588
599
database,
600
+ external_ip : config. get_ext_ip ( ) ,
601
+ policy : TrackerPolicy :: new (
602
+ config. remove_peerless_torrents ,
603
+ config. max_peer_timeout ,
604
+ config. persistent_torrent_completed_stat ,
605
+ ) ,
606
+ on_reverse_proxy : config. on_reverse_proxy ,
589
607
} )
590
608
}
591
609
@@ -609,6 +627,19 @@ impl Tracker {
609
627
self . is_private ( )
610
628
}
611
629
630
+ /// Returns `true` is the tracker is in whitelisted mode.
631
+ pub fn is_behind_reverse_proxy ( & self ) -> bool {
632
+ self . on_reverse_proxy
633
+ }
634
+
635
+ pub fn get_announce_policy ( & self ) -> AnnouncePolicy {
636
+ self . announce_policy
637
+ }
638
+
639
+ pub fn get_maybe_external_ip ( & self ) -> Option < IpAddr > {
640
+ self . external_ip
641
+ }
642
+
612
643
/// It handles an announce request.
613
644
///
614
645
/// # Context: Tracker
@@ -630,16 +661,17 @@ impl Tracker {
630
661
// we are actually handling authentication at the handlers level. So I would extract that
631
662
// responsibility into another authentication service.
632
663
633
- peer. change_ip ( & assign_ip_address_to_peer ( remote_client_ip, self . config . get_ext_ip ( ) ) ) ;
664
+ debug ! ( "Before: {peer:?}" ) ;
665
+ peer. change_ip ( & assign_ip_address_to_peer ( remote_client_ip, self . external_ip ) ) ;
666
+ debug ! ( "After: {peer:?}" ) ;
634
667
668
+ // we should update the torrent and get the stats before we get the peer list.
635
669
let swarm_stats = self . update_torrent_with_peer_and_get_stats ( info_hash, peer) . await ;
636
670
637
671
let peers = self . get_torrent_peers_for_peer ( info_hash, peer) . await ;
638
672
639
- let policy = AnnouncePolicy :: new ( self . config . announce_interval , self . config . min_announce_interval ) ;
640
-
641
673
AnnounceData {
642
- policy,
674
+ policy : self . announce_policy ,
643
675
peers,
644
676
swarm_stats,
645
677
}
@@ -740,7 +772,7 @@ impl Tracker {
740
772
741
773
let ( stats, stats_updated) = self . torrents . update_torrent_with_peer_and_get_stats ( info_hash, peer) . await ;
742
774
743
- if self . config . persistent_torrent_completed_stat && stats_updated {
775
+ if self . policy . persistent_torrent_completed_stat && stats_updated {
744
776
let completed = stats. completed ;
745
777
let info_hash = * info_hash;
746
778
@@ -801,17 +833,17 @@ impl Tracker {
801
833
let mut torrents_lock = self . torrents . get_torrents_mut ( ) . await ;
802
834
803
835
// If we don't need to remove torrents we will use the faster iter
804
- if self . config . remove_peerless_torrents {
836
+ if self . policy . remove_peerless_torrents {
805
837
let mut cleaned_torrents_map: BTreeMap < InfoHash , torrent:: Entry > = BTreeMap :: new ( ) ;
806
838
807
839
for ( info_hash, torrent_entry) in & mut * torrents_lock {
808
- torrent_entry. remove_inactive_peers ( self . config . max_peer_timeout ) ;
840
+ torrent_entry. remove_inactive_peers ( self . policy . max_peer_timeout ) ;
809
841
810
842
if torrent_entry. peers . is_empty ( ) {
811
843
continue ;
812
844
}
813
845
814
- if self . config . persistent_torrent_completed_stat && torrent_entry. completed == 0 {
846
+ if self . policy . persistent_torrent_completed_stat && torrent_entry. completed == 0 {
815
847
continue ;
816
848
}
817
849
@@ -821,7 +853,7 @@ impl Tracker {
821
853
* torrents_lock = cleaned_torrents_map;
822
854
} else {
823
855
for torrent_entry in ( * torrents_lock) . values_mut ( ) {
824
- torrent_entry. remove_inactive_peers ( self . config . max_peer_timeout ) ;
856
+ torrent_entry. remove_inactive_peers ( self . policy . max_peer_timeout ) ;
825
857
}
826
858
}
827
859
}
@@ -1086,21 +1118,21 @@ mod tests {
1086
1118
use crate :: shared:: clock:: DurationSinceUnixEpoch ;
1087
1119
1088
1120
fn public_tracker ( ) -> Tracker {
1089
- tracker_factory ( configuration:: ephemeral_mode_public ( ) . into ( ) )
1121
+ tracker_factory ( & configuration:: ephemeral_mode_public ( ) . into ( ) )
1090
1122
}
1091
1123
1092
1124
fn private_tracker ( ) -> Tracker {
1093
- tracker_factory ( configuration:: ephemeral_mode_private ( ) . into ( ) )
1125
+ tracker_factory ( & configuration:: ephemeral_mode_private ( ) . into ( ) )
1094
1126
}
1095
1127
1096
1128
fn whitelisted_tracker ( ) -> Tracker {
1097
- tracker_factory ( configuration:: ephemeral_mode_whitelisted ( ) . into ( ) )
1129
+ tracker_factory ( & configuration:: ephemeral_mode_whitelisted ( ) . into ( ) )
1098
1130
}
1099
1131
1100
1132
pub fn tracker_persisting_torrents_in_database ( ) -> Tracker {
1101
1133
let mut configuration = configuration:: ephemeral ( ) ;
1102
1134
configuration. persistent_torrent_completed_stat = true ;
1103
- tracker_factory ( Arc :: new ( configuration) )
1135
+ tracker_factory ( & Arc :: new ( configuration) )
1104
1136
}
1105
1137
1106
1138
fn sample_info_hash ( ) -> InfoHash {
0 commit comments