@@ -13,6 +13,7 @@ use std::sync::Arc;
1313
1414use bittorrent_http_tracker_protocol:: v1:: requests:: announce:: { peer_from_request, Announce } ;
1515use bittorrent_http_tracker_protocol:: v1:: services:: peer_ip_resolver:: { self , ClientIpSources , PeerIpResolutionError } ;
16+ use bittorrent_primitives:: info_hash:: InfoHash ;
1617use bittorrent_tracker_core:: announce_handler:: { AnnounceHandler , PeersWanted } ;
1718use bittorrent_tracker_core:: authentication:: service:: AuthenticationService ;
1819use bittorrent_tracker_core:: authentication:: { self , Key } ;
@@ -23,56 +24,6 @@ use torrust_tracker_primitives::core::AnnounceData;
2324
2425use crate :: statistics;
2526
26- /// Errors related to announce requests.
27- #[ derive( thiserror:: Error , Debug , Clone ) ]
28- pub enum HttpAnnounceError {
29- #[ error( "Error resolving peer IP: {source}" ) ]
30- PeerIpResolutionError { source : PeerIpResolutionError } ,
31-
32- #[ error( "Tracker core error: {source}" ) ]
33- TrackerCoreError { source : TrackerCoreError } ,
34- }
35-
36- impl From < PeerIpResolutionError > for HttpAnnounceError {
37- fn from ( peer_ip_resolution_error : PeerIpResolutionError ) -> Self {
38- Self :: PeerIpResolutionError {
39- source : peer_ip_resolution_error,
40- }
41- }
42- }
43-
44- impl From < TrackerCoreError > for HttpAnnounceError {
45- fn from ( tracker_core_error : TrackerCoreError ) -> Self {
46- Self :: TrackerCoreError {
47- source : tracker_core_error,
48- }
49- }
50- }
51-
52- impl From < AnnounceError > for HttpAnnounceError {
53- fn from ( announce_error : AnnounceError ) -> Self {
54- Self :: TrackerCoreError {
55- source : announce_error. into ( ) ,
56- }
57- }
58- }
59-
60- impl From < WhitelistError > for HttpAnnounceError {
61- fn from ( whitelist_error : WhitelistError ) -> Self {
62- Self :: TrackerCoreError {
63- source : whitelist_error. into ( ) ,
64- }
65- }
66- }
67-
68- impl From < authentication:: key:: Error > for HttpAnnounceError {
69- fn from ( whitelist_error : authentication:: key:: Error ) -> Self {
70- Self :: TrackerCoreError {
71- source : whitelist_error. into ( ) ,
72- }
73- }
74- }
75-
7627/// The HTTP tracker `announce` service.
7728///
7829/// The service sends an statistics event that increments:
@@ -123,50 +74,61 @@ impl AnnounceService {
12374 client_ip_sources : & ClientIpSources ,
12475 maybe_key : Option < Key > ,
12576 ) -> Result < AnnounceData , HttpAnnounceError > {
126- // Authentication
127- if self . core_config . private {
128- match maybe_key {
129- Some ( key) => match self . authentication_service . authenticate ( & key) . await {
130- Ok ( ( ) ) => ( ) ,
131- Err ( error) => return Err ( error. into ( ) ) ,
132- } ,
133- None => {
134- return Err ( authentication:: key:: Error :: MissingAuthKey {
135- location : Location :: caller ( ) ,
136- }
137- . into ( ) )
138- }
139- }
140- }
141-
142- // Authorization
143- match self . whitelist_authorization . authorize ( & announce_request. info_hash ) . await {
144- Ok ( ( ) ) => ( ) ,
145- Err ( error) => return Err ( error. into ( ) ) ,
146- }
77+ self . authenticate ( maybe_key) . await ?;
14778
148- let peer_ip = match peer_ip_resolver:: invoke ( self . core_config . net . on_reverse_proxy , client_ip_sources) {
149- Ok ( peer_ip) => peer_ip,
150- Err ( error) => return Err ( error. into ( ) ) ,
151- } ;
79+ self . authorize ( announce_request. info_hash ) . await ?;
15280
153- let mut peer = peer_from_request ( announce_request , & peer_ip ) ;
81+ let remote_client_ip = self . resolve_remote_client_ip ( client_ip_sources ) ? ;
15482
155- let peers_wanted = match announce_request. numwant {
156- Some ( numwant) => PeersWanted :: only ( numwant) ,
157- None => PeersWanted :: AsManyAsPossible ,
158- } ;
83+ let mut peer = peer_from_request ( announce_request, & remote_client_ip) ;
15984
160- let original_peer_ip = peer . peer_addr . ip ( ) ;
85+ let peers_wanted = Self :: peers_wanted ( announce_request ) ;
16186
162- // The tracker could change the original peer ip
16387 let announce_data = self
16488 . announce_handler
165- . announce ( & announce_request. info_hash , & mut peer, & original_peer_ip , & peers_wanted)
89+ . announce ( & announce_request. info_hash , & mut peer, & remote_client_ip , & peers_wanted)
16690 . await ?;
16791
92+ self . send_stats_event ( remote_client_ip) . await ;
93+
94+ Ok ( announce_data)
95+ }
96+
97+ async fn authenticate ( & self , maybe_key : Option < Key > ) -> Result < ( ) , authentication:: key:: Error > {
98+ if self . core_config . private {
99+ let key = maybe_key. ok_or ( authentication:: key:: Error :: MissingAuthKey {
100+ location : Location :: caller ( ) ,
101+ } ) ?;
102+
103+ self . authentication_service . authenticate ( & key) . await ?;
104+ }
105+
106+ Ok ( ( ) )
107+ }
108+
109+ async fn authorize ( & self , info_hash : InfoHash ) -> Result < ( ) , WhitelistError > {
110+ self . whitelist_authorization . authorize ( & info_hash) . await
111+ }
112+
113+ /// Resolves the client's real IP address considering proxy headers
114+ fn resolve_remote_client_ip ( & self , client_ip_sources : & ClientIpSources ) -> Result < IpAddr , PeerIpResolutionError > {
115+ match peer_ip_resolver:: invoke ( self . core_config . net . on_reverse_proxy , client_ip_sources) {
116+ Ok ( peer_ip) => Ok ( peer_ip) ,
117+ Err ( error) => Err ( error) ,
118+ }
119+ }
120+
121+ /// Determines how many peers the client wants in the response
122+ fn peers_wanted ( announce_request : & Announce ) -> PeersWanted {
123+ match announce_request. numwant {
124+ Some ( numwant) => PeersWanted :: only ( numwant) ,
125+ None => PeersWanted :: AsManyAsPossible ,
126+ }
127+ }
128+
129+ async fn send_stats_event ( & self , peer_ip : IpAddr ) {
168130 if let Some ( http_stats_event_sender) = self . opt_http_stats_event_sender . as_deref ( ) {
169- match original_peer_ip {
131+ match peer_ip {
170132 IpAddr :: V4 ( _) => {
171133 http_stats_event_sender
172134 . send_event ( statistics:: event:: Event :: Tcp4Announce )
@@ -179,8 +141,56 @@ impl AnnounceService {
179141 }
180142 }
181143 }
144+ }
145+ }
182146
183- Ok ( announce_data)
147+ /// Errors related to announce requests.
148+ #[ derive( thiserror:: Error , Debug , Clone ) ]
149+ pub enum HttpAnnounceError {
150+ #[ error( "Error resolving peer IP: {source}" ) ]
151+ PeerIpResolutionError { source : PeerIpResolutionError } ,
152+
153+ #[ error( "Tracker core error: {source}" ) ]
154+ TrackerCoreError { source : TrackerCoreError } ,
155+ }
156+
157+ impl From < PeerIpResolutionError > for HttpAnnounceError {
158+ fn from ( peer_ip_resolution_error : PeerIpResolutionError ) -> Self {
159+ Self :: PeerIpResolutionError {
160+ source : peer_ip_resolution_error,
161+ }
162+ }
163+ }
164+
165+ impl From < TrackerCoreError > for HttpAnnounceError {
166+ fn from ( tracker_core_error : TrackerCoreError ) -> Self {
167+ Self :: TrackerCoreError {
168+ source : tracker_core_error,
169+ }
170+ }
171+ }
172+
173+ impl From < AnnounceError > for HttpAnnounceError {
174+ fn from ( announce_error : AnnounceError ) -> Self {
175+ Self :: TrackerCoreError {
176+ source : announce_error. into ( ) ,
177+ }
178+ }
179+ }
180+
181+ impl From < WhitelistError > for HttpAnnounceError {
182+ fn from ( whitelist_error : WhitelistError ) -> Self {
183+ Self :: TrackerCoreError {
184+ source : whitelist_error. into ( ) ,
185+ }
186+ }
187+ }
188+
189+ impl From < authentication:: key:: Error > for HttpAnnounceError {
190+ fn from ( whitelist_error : authentication:: key:: Error ) -> Self {
191+ Self :: TrackerCoreError {
192+ source : whitelist_error. into ( ) ,
193+ }
184194 }
185195}
186196
0 commit comments