Skip to content

Commit ce20db3

Browse files
sanityclaude
andauthored
fix: use Joiner enum to properly handle NAT peer address discovery (#2158)
Co-authored-by: Claude <[email protected]>
1 parent e2ffb94 commit ce20db3

File tree

5 files changed

+221
-47
lines changed

5 files changed

+221
-47
lines changed

crates/core/src/node/network_bridge/p2p_protoc.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use futures::FutureExt;
55
use futures::StreamExt;
66
use std::convert::Infallible;
77
use std::future::Future;
8-
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
8+
use std::net::{IpAddr, SocketAddr};
99
use std::pin::Pin;
1010
use std::time::Duration;
1111
use std::{
@@ -148,28 +148,34 @@ impl P2pConnManager {
148148
let gateways = config.get_gateways()?;
149149
let key_pair = config.key_pair.clone();
150150

151-
// Initialize our peer identity before any connection attempts so join requests can
152-
// reference the correct address.
153-
let advertised_addr = {
151+
// Initialize our peer identity.
152+
// - Gateways must know their public address upfront (required)
153+
// - Peers with configured public_address use that
154+
// - Peers behind NAT start with a placeholder (127.0.0.1) which will be updated
155+
// when they receive ObservedAddress from a gateway
156+
let advertised_addr = if config.is_gateway {
157+
// Gateways must have a public address configured
154158
let advertised_ip = config
155159
.peer_id
156160
.as_ref()
157161
.map(|peer| peer.addr.ip())
158162
.or(config.config.network_api.public_address)
159-
.unwrap_or_else(|| {
160-
if listener_ip.is_unspecified() {
161-
IpAddr::V4(Ipv4Addr::LOCALHOST)
162-
} else {
163-
listener_ip
164-
}
165-
});
163+
.expect("Gateway must have public_address configured");
166164
let advertised_port = config
167165
.peer_id
168166
.as_ref()
169167
.map(|peer| peer.addr.port())
170168
.or(config.config.network_api.public_port)
171169
.unwrap_or(listen_port);
172170
SocketAddr::new(advertised_ip, advertised_port)
171+
} else if let Some(public_addr) = config.config.network_api.public_address {
172+
// Non-gateway peer with explicitly configured public address
173+
let port = config.config.network_api.public_port.unwrap_or(listen_port);
174+
SocketAddr::new(public_addr, port)
175+
} else {
176+
// Non-gateway peer behind NAT: use placeholder address.
177+
// This will be updated when we receive ObservedAddress from gateway.
178+
SocketAddr::new(std::net::Ipv4Addr::new(127, 0, 0, 1).into(), listen_port)
173179
};
174180
bridge
175181
.op_manager

crates/core/src/node/p2p_impl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,15 @@ impl NodeP2P {
159159
.min(u8::MAX as usize) as u8;
160160
let target_connections = self.op_manager.ring.connection_manager.min_connections;
161161

162+
let is_gateway = self.op_manager.ring.connection_manager.is_gateway();
162163
let (tx, op, msg) = ConnectOp::initiate_join_request(
163164
joiner,
164165
query_target.clone(),
165166
ideal_location,
166167
ttl,
167168
target_connections,
168169
self.op_manager.connect_forward_estimator.clone(),
170+
is_gateway,
169171
);
170172

171173
tracing::debug!(

0 commit comments

Comments
 (0)