diff --git a/p2p/src/handshake.rs b/p2p/src/handshake.rs index 1829c8a50..1f355b231 100644 --- a/p2p/src/handshake.rs +++ b/p2p/src/handshake.rs @@ -124,11 +124,12 @@ impl Handshake { })); } } + // all good, keep peer info let peer_info = PeerInfo { capabilities: hand.capabilities, user_agent: hand.user_agent, - addr: hand.sender_addr.0, + addr: extract_ip(&hand.sender_addr.0, &conn), version: hand.version, total_difficulty: hand.total_difficulty, }; @@ -163,3 +164,27 @@ impl Handshake { nonce } } + +// Attempts to make a best guess at the correct remote IP by checking if the +// advertised address is the loopback and our TCP connection. Note that the +// port reported by the connection is always incorrect for receiving +// connections as it's dynamically allocated by the server. +fn extract_ip(advertised: &SocketAddr, conn: &TcpStream) -> SocketAddr { + match advertised { + &SocketAddr::V4(v4sock) => { + if v4sock.ip().is_loopback() { + if let Ok(addr) = conn.peer_addr() { + return SocketAddr::new(addr.ip(), advertised.port()); + } + } + } + &SocketAddr::V6(v6sock) => { + if v6sock.ip().is_loopback() { + if let Ok(addr) = conn.peer_addr() { + return SocketAddr::new(addr.ip(), advertised.port()); + } + } + } + } + advertised.clone() +} diff --git a/p2p/src/msg.rs b/p2p/src/msg.rs index 4a39a5d2c..41d50b77f 100644 --- a/p2p/src/msg.rs +++ b/p2p/src/msg.rs @@ -190,8 +190,7 @@ pub struct Hand { /// randomly generated for each handshake, helps detect self pub nonce: u64, /// total difficulty accumulated by the sender, used to check whether sync - /// may - /// be needed + /// may be needed pub total_difficulty: Difficulty, /// network address of the sender pub sender_addr: SockAddr, @@ -245,8 +244,7 @@ pub struct Shake { /// sender capabilities pub capabilities: Capabilities, /// total difficulty accumulated by the sender, used to check whether sync - /// may - /// be needed + /// may be needed pub total_difficulty: Difficulty, /// name of version of the software pub user_agent: String,