@@ -445,7 +445,9 @@ use std::panic::Location;
445
445
use std:: sync:: Arc ;
446
446
use std:: time:: Duration ;
447
447
448
+ use derive_more:: Constructor ;
448
449
use futures:: future:: join_all;
450
+ use log:: debug;
449
451
use tokio:: sync:: mpsc:: error:: SendError ;
450
452
use torrust_tracker_configuration:: Configuration ;
451
453
use torrust_tracker_primitives:: TrackerMode ;
@@ -471,17 +473,19 @@ pub const TORRENT_PEERS_LIMIT: usize = 74;
471
473
/// Typically, the `Tracker` is used by a higher application service that handles
472
474
/// the network layer.
473
475
pub struct Tracker {
474
- /// `Tracker` configuration. See [`torrust-tracker-configuration`](torrust_tracker_configuration)
475
- pub config : Arc < Configuration > ,
476
+ announce_policy : AnnouncePolicy ,
476
477
/// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite)
477
478
/// or [`MySQL`](crate::core::databases::mysql)
478
479
pub database : Arc < Box < dyn Database > > ,
479
480
mode : TrackerMode ,
481
+ policy : TrackerPolicy ,
480
482
keys : tokio:: sync:: RwLock < std:: collections:: HashMap < Key , auth:: ExpiringKey > > ,
481
483
whitelist : tokio:: sync:: RwLock < std:: collections:: HashSet < InfoHash > > ,
482
484
pub torrents : Arc < RepositoryAsyncSingle > ,
483
485
stats_event_sender : Option < Box < dyn statistics:: EventSender > > ,
484
486
stats_repository : statistics:: Repo ,
487
+ external_ip : Option < IpAddr > ,
488
+ on_reverse_proxy : bool ,
485
489
}
486
490
487
491
/// Structure that holds general `Tracker` torrents metrics.
@@ -499,21 +503,35 @@ pub struct TorrentsMetrics {
499
503
pub torrents : u64 ,
500
504
}
501
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
+
513
+ /// Tracker policy for Announcements
514
+ #[ derive( Copy , Clone , Debug , PartialEq , Default , Constructor ) ]
515
+ pub struct AnnouncePolicy {
516
+ /// The interval in seconds that the client should wait between sending
517
+ /// regular requests to the tracker.
518
+ /// Refer to [`announce_interval`](torrust_tracker_configuration::Configuration::announce_interval).
519
+ pub interval : u32 ,
520
+ /// The minimum announce interval in seconds that the client should wait.
521
+ /// Refer to [`min_announce_interval`](torrust_tracker_configuration::Configuration::min_announce_interval).
522
+ pub interval_min : u32 ,
523
+ }
524
+
502
525
/// Structure that holds the data returned by the `announce` request.
503
526
#[ derive( Debug , PartialEq , Default ) ]
504
527
pub struct AnnounceData {
528
+ /// Tracker policy for Announcements
529
+ pub policy : AnnouncePolicy ,
505
530
/// The list of peers that are downloading the same torrent.
506
531
/// It excludes the peer that made the request.
507
532
pub peers : Vec < Peer > ,
508
533
/// Swarm statistics
509
534
pub swarm_stats : SwarmStats ,
510
- /// The interval in seconds that the client should wait between sending
511
- /// regular requests to the tracker.
512
- /// Refer to [`announce_interval`](torrust_tracker_configuration::Configuration::announce_interval).
513
- pub interval : u32 ,
514
- /// The minimum announce interval in seconds that the client should wait.
515
- /// Refer to [`min_announce_interval`](torrust_tracker_configuration::Configuration::min_announce_interval).
516
- pub interval_min : u32 ,
517
535
}
518
536
519
537
/// Structure that holds the data returned by the `scrape` request.
@@ -561,7 +579,7 @@ impl Tracker {
561
579
///
562
580
/// Will return a `databases::error::Error` if unable to connect to database. The `Tracker` is responsible for the persistence.
563
581
pub fn new (
564
- config : Arc < Configuration > ,
582
+ config : & Arc < Configuration > ,
565
583
stats_event_sender : Option < Box < dyn statistics:: EventSender > > ,
566
584
stats_repository : statistics:: Repo ,
567
585
) -> Result < Tracker , databases:: error:: Error > {
@@ -570,14 +588,22 @@ impl Tracker {
570
588
let mode = config. mode ;
571
589
572
590
Ok ( Tracker {
573
- config,
591
+ //config,
592
+ announce_policy : AnnouncePolicy :: new ( config. announce_interval , config. min_announce_interval ) ,
574
593
mode,
575
594
keys : tokio:: sync:: RwLock :: new ( std:: collections:: HashMap :: new ( ) ) ,
576
595
whitelist : tokio:: sync:: RwLock :: new ( std:: collections:: HashSet :: new ( ) ) ,
577
596
torrents : Arc :: new ( RepositoryAsyncSingle :: new ( ) ) ,
578
597
stats_event_sender,
579
598
stats_repository,
580
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 ,
581
607
} )
582
608
}
583
609
@@ -601,6 +627,19 @@ impl Tracker {
601
627
self . is_private ( )
602
628
}
603
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
+
604
643
/// It handles an announce request.
605
644
///
606
645
/// # Context: Tracker
@@ -622,17 +661,19 @@ impl Tracker {
622
661
// we are actually handling authentication at the handlers level. So I would extract that
623
662
// responsibility into another authentication service.
624
663
625
- 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:?}" ) ;
626
667
668
+ // we should update the torrent and get the stats before we get the peer list.
627
669
let swarm_stats = self . update_torrent_with_peer_and_get_stats ( info_hash, peer) . await ;
628
670
629
671
let peers = self . get_torrent_peers_for_peer ( info_hash, peer) . await ;
630
672
631
673
AnnounceData {
674
+ policy : self . announce_policy ,
632
675
peers,
633
676
swarm_stats,
634
- interval : self . config . announce_interval ,
635
- interval_min : self . config . min_announce_interval ,
636
677
}
637
678
}
638
679
@@ -731,7 +772,7 @@ impl Tracker {
731
772
732
773
let ( stats, stats_updated) = self . torrents . update_torrent_with_peer_and_get_stats ( info_hash, peer) . await ;
733
774
734
- if self . config . persistent_torrent_completed_stat && stats_updated {
775
+ if self . policy . persistent_torrent_completed_stat && stats_updated {
735
776
let completed = stats. completed ;
736
777
let info_hash = * info_hash;
737
778
@@ -792,17 +833,17 @@ impl Tracker {
792
833
let mut torrents_lock = self . torrents . get_torrents_mut ( ) . await ;
793
834
794
835
// If we don't need to remove torrents we will use the faster iter
795
- if self . config . remove_peerless_torrents {
836
+ if self . policy . remove_peerless_torrents {
796
837
let mut cleaned_torrents_map: BTreeMap < InfoHash , torrent:: Entry > = BTreeMap :: new ( ) ;
797
838
798
839
for ( info_hash, torrent_entry) in & mut * torrents_lock {
799
- torrent_entry. remove_inactive_peers ( self . config . max_peer_timeout ) ;
840
+ torrent_entry. remove_inactive_peers ( self . policy . max_peer_timeout ) ;
800
841
801
842
if torrent_entry. peers . is_empty ( ) {
802
843
continue ;
803
844
}
804
845
805
- if self . config . persistent_torrent_completed_stat && torrent_entry. completed == 0 {
846
+ if self . policy . persistent_torrent_completed_stat && torrent_entry. completed == 0 {
806
847
continue ;
807
848
}
808
849
@@ -812,7 +853,7 @@ impl Tracker {
812
853
* torrents_lock = cleaned_torrents_map;
813
854
} else {
814
855
for torrent_entry in ( * torrents_lock) . values_mut ( ) {
815
- torrent_entry. remove_inactive_peers ( self . config . max_peer_timeout ) ;
856
+ torrent_entry. remove_inactive_peers ( self . policy . max_peer_timeout ) ;
816
857
}
817
858
}
818
859
}
@@ -1077,21 +1118,21 @@ mod tests {
1077
1118
use crate :: shared:: clock:: DurationSinceUnixEpoch ;
1078
1119
1079
1120
fn public_tracker ( ) -> Tracker {
1080
- tracker_factory ( configuration:: ephemeral_mode_public ( ) . into ( ) )
1121
+ tracker_factory ( & configuration:: ephemeral_mode_public ( ) . into ( ) )
1081
1122
}
1082
1123
1083
1124
fn private_tracker ( ) -> Tracker {
1084
- tracker_factory ( configuration:: ephemeral_mode_private ( ) . into ( ) )
1125
+ tracker_factory ( & configuration:: ephemeral_mode_private ( ) . into ( ) )
1085
1126
}
1086
1127
1087
1128
fn whitelisted_tracker ( ) -> Tracker {
1088
- tracker_factory ( configuration:: ephemeral_mode_whitelisted ( ) . into ( ) )
1129
+ tracker_factory ( & configuration:: ephemeral_mode_whitelisted ( ) . into ( ) )
1089
1130
}
1090
1131
1091
1132
pub fn tracker_persisting_torrents_in_database ( ) -> Tracker {
1092
1133
let mut configuration = configuration:: ephemeral ( ) ;
1093
1134
configuration. persistent_torrent_completed_stat = true ;
1094
- tracker_factory ( Arc :: new ( configuration) )
1135
+ tracker_factory ( & Arc :: new ( configuration) )
1095
1136
}
1096
1137
1097
1138
fn sample_info_hash ( ) -> InfoHash {
0 commit comments