@@ -6,11 +6,13 @@ pub use p2p_connection_outgoing_actions::*;
66
77mod p2p_connection_outgoing_reducer;
88
9+ use std:: net:: IpAddr ;
910#[ cfg( feature = "p2p-libp2p" ) ]
1011use std:: net:: SocketAddr ;
1112use std:: { fmt, str:: FromStr } ;
1213
1314use binprot_derive:: { BinProtRead , BinProtWrite } ;
15+ use multiaddr:: { Multiaddr , Protocol } ;
1416use serde:: { Deserialize , Serialize } ;
1517use thiserror:: Error ;
1618
@@ -44,6 +46,42 @@ pub struct P2pConnectionOutgoingInitLibp2pOpts {
4446 pub port : u16 ,
4547}
4648
49+ impl P2pConnectionOutgoingInitLibp2pOpts {
50+ /// If the current host is local and there is a better host among the `addrs`,
51+ /// replace the current one with the better one.
52+ pub fn update_host_if_needed < ' a > ( & mut self , mut addrs : impl Iterator < Item = & ' a Multiaddr > ) {
53+ fn is_local ( ip : impl Into < IpAddr > ) -> bool {
54+ match ip. into ( ) {
55+ IpAddr :: V4 ( ip) => ip. is_loopback ( ) || ip. is_private ( ) ,
56+ IpAddr :: V6 ( ip) => ip. is_loopback ( ) ,
57+ }
58+ }
59+
60+ // if current dial opts is not good enough
61+ let update = match & self . host {
62+ Host :: Domain ( _) => false ,
63+ Host :: Ipv4 ( ip) => is_local ( * ip) ,
64+ Host :: Ipv6 ( ip) => is_local ( * ip) ,
65+ } ;
66+ if update {
67+ // if new options is better
68+ let new = addrs. find_map ( |x| {
69+ x. iter ( ) . find_map ( |x| match x {
70+ Protocol :: Dns4 ( hostname) | Protocol :: Dns6 ( hostname) => {
71+ Some ( Host :: Domain ( hostname. into_owned ( ) ) )
72+ }
73+ Protocol :: Ip4 ( ip) if !is_local ( ip) => Some ( Host :: Ipv4 ( ip) ) ,
74+ Protocol :: Ip6 ( ip) if !is_local ( ip) => Some ( Host :: Ipv6 ( ip) ) ,
75+ _ => None ,
76+ } )
77+ } ) ;
78+ if let Some ( new) = new {
79+ self . host = new;
80+ }
81+ }
82+ }
83+ }
84+
4785pub ( crate ) mod libp2p_opts {
4886 use std:: net:: { IpAddr , SocketAddr } ;
4987
0 commit comments