Proper p2p remote address detection when accepting conn

A receiving peer trusts the address advertised by a client.
However as we do not have external address detection (and there is
generally no very good way to do that), the address detected by
a peer is the loopback, which is useless. So we attempt to detect
these cases and use the IP detected by the TCP connection while
keeping the advertised port.
This commit is contained in:
Ignotus Peverell 2017-11-01 18:56:59 -04:00
parent de1cdddfb9
commit 362fbcf90f
No known key found for this signature in database
GPG key ID: 99CD25F39F8F8211
2 changed files with 28 additions and 5 deletions

View file

@ -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()
}

View file

@ -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,