@@ -3,18 +3,12 @@ use std::collections::BTreeMap;
33use std:: net:: SocketAddr ;
44use std:: sync:: Arc ;
55
6- use aquatic_udp_protocol:: PeerId ;
76use torrust_tracker_primitives:: peer:: { self , Peer } ;
87use torrust_tracker_primitives:: DurationSinceUnixEpoch ;
98
10- // code-review: the current implementation uses the peer Id as the ``BTreeMap``
11- // key. That would allow adding two identical peers except for the Id.
12- // For example, two peers with the same socket address but a different peer Id
13- // would be allowed. That would lead to duplicated peers in the tracker responses.
14-
159#[ derive( Clone , Debug , Default , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
1610pub struct Swarm {
17- peers : BTreeMap < PeerId , Arc < Peer > > ,
11+ peers : BTreeMap < SocketAddr , Arc < Peer > > ,
1812}
1913
2014impl Swarm {
@@ -28,12 +22,12 @@ impl Swarm {
2822 self . peers . is_empty ( )
2923 }
3024
31- pub fn upsert ( & mut self , value : Arc < peer :: Peer > ) -> Option < Arc < peer :: Peer > > {
32- self . peers . insert ( value . peer_id , value )
25+ pub fn upsert ( & mut self , peer : Arc < Peer > ) -> Option < Arc < Peer > > {
26+ self . peers . insert ( peer . peer_addr , peer )
3327 }
3428
35- pub fn remove ( & mut self , key : & PeerId ) -> Option < Arc < peer :: Peer > > {
36- self . peers . remove ( key )
29+ pub fn remove ( & mut self , peer : & Peer ) -> Option < Arc < Peer > > {
30+ self . peers . remove ( & peer . peer_addr )
3731 }
3832
3933 pub fn remove_inactive_peers ( & mut self , current_cutoff : DurationSinceUnixEpoch ) {
@@ -42,12 +36,12 @@ impl Swarm {
4236 }
4337
4438 #[ must_use]
45- pub fn get ( & self , peer_id : & PeerId ) -> Option < & Arc < peer :: Peer > > {
46- self . peers . get ( peer_id )
39+ pub fn get ( & self , peer_addr : & SocketAddr ) -> Option < & Arc < Peer > > {
40+ self . peers . get ( peer_addr )
4741 }
4842
4943 #[ must_use]
50- pub fn get_all ( & self , limit : Option < usize > ) -> Vec < Arc < peer :: Peer > > {
44+ pub fn get_all ( & self , limit : Option < usize > ) -> Vec < Arc < Peer > > {
5145 match limit {
5246 Some ( limit) => self . peers . values ( ) . take ( limit) . cloned ( ) . collect ( ) ,
5347 None => self . peers . values ( ) . cloned ( ) . collect ( ) ,
@@ -151,7 +145,7 @@ mod tests {
151145
152146 swarm. upsert ( peer. into ( ) ) ;
153147
154- assert_eq ! ( swarm. get( & peer. peer_id ) , Some ( Arc :: new( peer) ) . as_ref( ) ) ;
148+ assert_eq ! ( swarm. get( & peer. peer_addr ) , Some ( Arc :: new( peer) ) . as_ref( ) ) ;
155149 }
156150
157151 #[ test]
@@ -173,7 +167,7 @@ mod tests {
173167
174168 swarm. upsert ( peer. into ( ) ) ;
175169
176- swarm. remove ( & peer. peer_id ) ;
170+ swarm. remove ( & peer) ;
177171
178172 assert ! ( swarm. is_empty( ) ) ;
179173 }
@@ -186,9 +180,9 @@ mod tests {
186180
187181 swarm. upsert ( peer. into ( ) ) ;
188182
189- swarm. remove ( & peer. peer_id ) ;
183+ swarm. remove ( & peer) ;
190184
191- assert_eq ! ( swarm. get( & peer. peer_id ) , None ) ;
185+ assert_eq ! ( swarm. get( & peer. peer_addr ) , None ) ;
192186 }
193187
194188 #[ test]
@@ -273,16 +267,42 @@ mod tests {
273267 }
274268
275269 #[ test]
276- fn allow_inserting_two_identical_peers_except_for_the_id ( ) {
270+ fn allow_inserting_two_identical_peers_except_for_the_socket_address ( ) {
277271 let mut swarm = Swarm :: default ( ) ;
278272
279- let peer1 = PeerBuilder :: default ( ) . with_peer_id ( & PeerId ( * b"-qB00000000000000001" ) ) . build ( ) ;
273+ let peer1 = PeerBuilder :: default ( )
274+ . with_peer_addr ( & SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 6969 ) )
275+ . build ( ) ;
280276 swarm. upsert ( peer1. into ( ) ) ;
281277
282- let peer2 = PeerBuilder :: default ( ) . with_peer_id ( & PeerId ( * b"-qB00000000000000002" ) ) . build ( ) ;
278+ let peer2 = PeerBuilder :: default ( )
279+ . with_peer_addr ( & SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 2 ) ) , 6969 ) )
280+ . build ( ) ;
283281 swarm. upsert ( peer2. into ( ) ) ;
284282
285283 assert_eq ! ( swarm. len( ) , 2 ) ;
286284 }
285+
286+ #[ test]
287+ fn not_allow_inserting_two_peers_with_different_peer_id_but_the_same_socket_address ( ) {
288+ let mut swarm = Swarm :: default ( ) ;
289+
290+ // When that happens the peer ID will be changed in the swarm.
291+ // In practice, it's like if the peer had changed its ID.
292+
293+ let peer1 = PeerBuilder :: default ( )
294+ . with_peer_id ( & PeerId ( * b"-qB00000000000000001" ) )
295+ . with_peer_addr ( & SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 6969 ) )
296+ . build ( ) ;
297+ swarm. upsert ( peer1. into ( ) ) ;
298+
299+ let peer2 = PeerBuilder :: default ( )
300+ . with_peer_id ( & PeerId ( * b"-qB00000000000000002" ) )
301+ . with_peer_addr ( & SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 6969 ) )
302+ . build ( ) ;
303+ swarm. upsert ( peer2. into ( ) ) ;
304+
305+ assert_eq ! ( swarm. len( ) , 1 ) ;
306+ }
287307 }
288308}
0 commit comments