@@ -56,40 +56,62 @@ pub struct TcpListener {
5656 listeners : Vec < TokioTcpListener > ,
5757}
5858
59- #[ derive( Clone , Default ) ]
60- pub struct DialAddresses {
61- /// Listen addresses.
62- listen_addresses : Arc < Vec < SocketAddr > > ,
59+ /// Local addresses to use for outbound connections.
60+ #[ derive( Clone ) ]
61+ pub enum DialAddresses {
62+ /// Reuse port from listen addresses.
63+ Reuse {
64+ listen_addresses : Arc < Vec < SocketAddr > > ,
65+ } ,
66+ /// Do not reuse port.
67+ NoReuse ,
68+ }
69+
70+ impl Default for DialAddresses {
71+ fn default ( ) -> Self {
72+ DialAddresses :: NoReuse
73+ }
6374}
6475
6576impl DialAddresses {
6677 /// Get local dial address for an outbound connection.
67- pub ( super ) fn local_dial_address ( & self , remote_address : & IpAddr ) -> Option < SocketAddr > {
68- for address in self . listen_addresses . iter ( ) {
69- if remote_address. is_ipv4 ( ) == address. is_ipv4 ( )
70- && remote_address. is_loopback ( ) == address. ip ( ) . is_loopback ( )
71- {
72- if remote_address. is_ipv4 ( ) {
73- return Some ( SocketAddr :: new (
74- IpAddr :: V4 ( Ipv4Addr :: UNSPECIFIED ) ,
75- address. port ( ) ,
76- ) ) ;
77- } else {
78- return Some ( SocketAddr :: new (
79- IpAddr :: V6 ( Ipv6Addr :: UNSPECIFIED ) ,
80- address. port ( ) ,
81- ) ) ;
78+ pub ( super ) fn local_dial_address (
79+ & self ,
80+ remote_address : & IpAddr ,
81+ ) -> Result < Option < SocketAddr > , ( ) > {
82+ match self {
83+ DialAddresses :: Reuse { listen_addresses } => {
84+ for address in listen_addresses. iter ( ) {
85+ if remote_address. is_ipv4 ( ) == address. is_ipv4 ( )
86+ && remote_address. is_loopback ( ) == address. ip ( ) . is_loopback ( )
87+ {
88+ if remote_address. is_ipv4 ( ) {
89+ return Ok ( Some ( SocketAddr :: new (
90+ IpAddr :: V4 ( Ipv4Addr :: UNSPECIFIED ) ,
91+ address. port ( ) ,
92+ ) ) ) ;
93+ } else {
94+ return Ok ( Some ( SocketAddr :: new (
95+ IpAddr :: V6 ( Ipv6Addr :: UNSPECIFIED ) ,
96+ address. port ( ) ,
97+ ) ) ) ;
98+ }
99+ }
82100 }
101+
102+ Err ( ( ) )
83103 }
104+ DialAddresses :: NoReuse => Ok ( None ) ,
84105 }
85-
86- None
87106 }
88107}
89108
90109impl TcpListener {
91110 /// Create new [`TcpListener`]
92- pub fn new ( addresses : Vec < Multiaddr > ) -> ( Self , Vec < Multiaddr > , DialAddresses ) {
111+ pub fn new (
112+ addresses : Vec < Multiaddr > ,
113+ reuse_port : bool ,
114+ ) -> ( Self , Vec < Multiaddr > , DialAddresses ) {
93115 let ( listeners, listen_addresses) : ( _ , Vec < Vec < _ > > ) = addresses
94116 . into_iter ( )
95117 . filter_map ( |address| {
@@ -117,7 +139,9 @@ impl TcpListener {
117139 socket. set_nonblocking ( true ) . ok ( ) ?;
118140 socket. set_reuse_address ( true ) . ok ( ) ?;
119141 #[ cfg( unix) ]
120- socket. set_reuse_port ( true ) . ok ( ) ?;
142+ if reuse_port {
143+ socket. set_reuse_port ( true ) . ok ( ) ?;
144+ }
121145 socket. bind ( & address. into ( ) ) . ok ( ) ?;
122146 socket. listen ( 1024 ) . ok ( ) ?;
123147
@@ -176,14 +200,15 @@ impl TcpListener {
176200 . with ( Protocol :: Tcp ( address. port ( ) ) )
177201 } )
178202 . collect ( ) ;
179-
180- (
181- Self { listeners } ,
182- listen_multi_addresses,
183- DialAddresses {
203+ let dial_addresses = if reuse_port {
204+ DialAddresses :: Reuse {
184205 listen_addresses : Arc :: new ( listen_addresses) ,
185- } ,
186- )
206+ }
207+ } else {
208+ DialAddresses :: NoReuse
209+ } ;
210+
211+ ( Self { listeners } , listen_multi_addresses, dial_addresses)
187212 }
188213
189214 /// Extract socket address and `PeerId`, if found, from `address`.
@@ -319,7 +344,7 @@ mod tests {
319344
320345 #[ tokio:: test]
321346 async fn no_listeners ( ) {
322- let ( mut listener, _, _) = TcpListener :: new ( Vec :: new ( ) ) ;
347+ let ( mut listener, _, _) = TcpListener :: new ( Vec :: new ( ) , true ) ;
323348
324349 futures:: future:: poll_fn ( |cx| match listener. poll_next_unpin ( cx) {
325350 Poll :: Pending => Poll :: Ready ( ( ) ) ,
@@ -331,7 +356,7 @@ mod tests {
331356 #[ tokio:: test]
332357 async fn one_listener ( ) {
333358 let address: Multiaddr = "/ip6/::1/tcp/0" . parse ( ) . unwrap ( ) ;
334- let ( mut listener, listen_addresses, _) = TcpListener :: new ( vec ! [ address. clone( ) ] ) ;
359+ let ( mut listener, listen_addresses, _) = TcpListener :: new ( vec ! [ address. clone( ) ] , true ) ;
335360 let Some ( Protocol :: Tcp ( port) ) =
336361 listen_addresses. iter ( ) . next ( ) . unwrap ( ) . clone ( ) . iter ( ) . skip ( 1 ) . next ( )
337362 else {
@@ -348,7 +373,7 @@ mod tests {
348373 async fn two_listeners ( ) {
349374 let address1: Multiaddr = "/ip6/::1/tcp/0" . parse ( ) . unwrap ( ) ;
350375 let address2: Multiaddr = "/ip4/127.0.0.1/tcp/0" . parse ( ) . unwrap ( ) ;
351- let ( mut listener, listen_addresses, _) = TcpListener :: new ( vec ! [ address1, address2] ) ;
376+ let ( mut listener, listen_addresses, _) = TcpListener :: new ( vec ! [ address1, address2] , true ) ;
352377 let Some ( Protocol :: Tcp ( port1) ) =
353378 listen_addresses. iter ( ) . next ( ) . unwrap ( ) . clone ( ) . iter ( ) . skip ( 1 ) . next ( )
354379 else {
@@ -373,7 +398,7 @@ mod tests {
373398
374399 #[ tokio:: test]
375400 async fn local_dial_address ( ) {
376- let dial_addresses = DialAddresses {
401+ let dial_addresses = DialAddresses :: Reuse {
377402 listen_addresses : Arc :: new ( vec ! [
378403 "[2001:7d0:84aa:3900:2a5d:9e85::]:8888" . parse( ) . unwrap( ) ,
379404 "92.168.127.1:9999" . parse( ) . unwrap( ) ,
@@ -382,20 +407,26 @@ mod tests {
382407
383408 assert_eq ! (
384409 dial_addresses. local_dial_address( & IpAddr :: V4 ( Ipv4Addr :: new( 192 , 168 , 0 , 1 ) ) ) ,
385- Some ( SocketAddr :: new( IpAddr :: V4 ( Ipv4Addr :: UNSPECIFIED ) , 9999 ) )
410+ Ok ( Some ( SocketAddr :: new(
411+ IpAddr :: V4 ( Ipv4Addr :: UNSPECIFIED ) ,
412+ 9999
413+ ) ) ) ,
386414 ) ;
387415
388416 assert_eq ! (
389417 dial_addresses. local_dial_address( & IpAddr :: V6 ( Ipv6Addr :: new( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ) ) ,
390- Some ( SocketAddr :: new( IpAddr :: V6 ( Ipv6Addr :: UNSPECIFIED ) , 8888 ) )
418+ Ok ( Some ( SocketAddr :: new(
419+ IpAddr :: V6 ( Ipv6Addr :: UNSPECIFIED ) ,
420+ 8888
421+ ) ) ) ,
391422 ) ;
392423 }
393424
394425 #[ tokio:: test]
395426 async fn show_all_addresses ( ) {
396427 let address1: Multiaddr = "/ip6/::/tcp/0" . parse ( ) . unwrap ( ) ;
397428 let address2: Multiaddr = "/ip4/0.0.0.0/tcp/0" . parse ( ) . unwrap ( ) ;
398- let ( _, listen_addresses, _) = TcpListener :: new ( vec ! [ address1, address2] ) ;
429+ let ( _, listen_addresses, _) = TcpListener :: new ( vec ! [ address1, address2] , true ) ;
399430
400431 println ! ( "{listen_addresses:#?}" ) ;
401432 }
0 commit comments