Our Info: display peer-observed external address
Store the external address reported by peers via your_observed_addr in initial exchange. Display it in Our Info panel with NAT classification. Replaces reliance on iroh's pkarr/STUN for external address discovery while keeping clear_address_lookup() (no dns.iroh.link publishing). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d1036a2d7d
commit
ffb13d6791
2 changed files with 34 additions and 2 deletions
|
|
@ -613,6 +613,8 @@ pub struct ConnectionManager {
|
||||||
activity_log: Arc<std::sync::Mutex<ActivityLog>>,
|
activity_log: Arc<std::sync::Mutex<ActivityLog>>,
|
||||||
/// UPnP external address (prepended to self-reported addresses in anchor registration)
|
/// UPnP external address (prepended to self-reported addresses in anchor registration)
|
||||||
upnp_external_addr: Option<SocketAddr>,
|
upnp_external_addr: Option<SocketAddr>,
|
||||||
|
/// External address as observed by peers (from initial exchange your_observed_addr)
|
||||||
|
pub observed_external_addr: std::sync::Mutex<Option<SocketAddr>>,
|
||||||
/// Stable bind address (from --bind flag), used for anchor advertised address
|
/// Stable bind address (from --bind flag), used for anchor advertised address
|
||||||
bind_addr: Option<SocketAddr>,
|
bind_addr: Option<SocketAddr>,
|
||||||
/// Our detected NAT type (from STUN probing on startup)
|
/// Our detected NAT type (from STUN probing on startup)
|
||||||
|
|
@ -684,6 +686,7 @@ impl ConnectionManager {
|
||||||
recovery_tx: None,
|
recovery_tx: None,
|
||||||
activity_log,
|
activity_log,
|
||||||
upnp_external_addr,
|
upnp_external_addr,
|
||||||
|
observed_external_addr: std::sync::Mutex::new(None),
|
||||||
bind_addr,
|
bind_addr,
|
||||||
nat_type,
|
nat_type,
|
||||||
nat_mapping,
|
nat_mapping,
|
||||||
|
|
@ -1597,9 +1600,12 @@ impl ConnectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log observed address (STUN-like feedback)
|
// Store observed address (STUN-like feedback from peer)
|
||||||
if let Some(ref observed) = their_payload.your_observed_addr {
|
if let Some(ref observed) = their_payload.your_observed_addr {
|
||||||
info!(observed_addr = %observed, reporter = hex::encode(remote_node_id), "Peer reports our address as");
|
info!(observed_addr = %observed, reporter = hex::encode(remote_node_id), "Peer reports our address as");
|
||||||
|
if let Ok(addr) = observed.parse::<std::net::SocketAddr>() {
|
||||||
|
*self.observed_external_addr.lock().unwrap() = Some(addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store peer's NAT type
|
// Store peer's NAT type
|
||||||
|
|
@ -6709,6 +6715,9 @@ pub enum ConnCommand {
|
||||||
GetUpnpExternalAddr {
|
GetUpnpExternalAddr {
|
||||||
reply: oneshot::Sender<Option<SocketAddr>>,
|
reply: oneshot::Sender<Option<SocketAddr>>,
|
||||||
},
|
},
|
||||||
|
GetObservedExternalAddr {
|
||||||
|
reply: oneshot::Sender<Option<SocketAddr>>,
|
||||||
|
},
|
||||||
TouchSessionIfExists {
|
TouchSessionIfExists {
|
||||||
peer: NodeId,
|
peer: NodeId,
|
||||||
},
|
},
|
||||||
|
|
@ -7204,6 +7213,12 @@ impl ConnHandle {
|
||||||
rx.await.ok().flatten()
|
rx.await.ok().flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn observed_external_addr(&self) -> Option<SocketAddr> {
|
||||||
|
let (tx, rx) = oneshot::channel();
|
||||||
|
let _ = self.tx.send(ConnCommand::GetObservedExternalAddr { reply: tx }).await;
|
||||||
|
rx.await.ok().flatten()
|
||||||
|
}
|
||||||
|
|
||||||
/// Touch session last_active (fire-and-forget, no-op if not a session peer).
|
/// Touch session last_active (fire-and-forget, no-op if not a session peer).
|
||||||
pub fn touch_session_if_exists(&self, peer: &NodeId) {
|
pub fn touch_session_if_exists(&self, peer: &NodeId) {
|
||||||
let _ = self.tx.try_send(ConnCommand::TouchSessionIfExists { peer: *peer });
|
let _ = self.tx.try_send(ConnCommand::TouchSessionIfExists { peer: *peer });
|
||||||
|
|
@ -8119,6 +8134,10 @@ impl ConnectionActor {
|
||||||
let cm = self.cm.lock().await;
|
let cm = self.cm.lock().await;
|
||||||
let _ = reply.send(cm.upnp_external_addr);
|
let _ = reply.send(cm.upnp_external_addr);
|
||||||
}
|
}
|
||||||
|
ConnCommand::GetObservedExternalAddr { reply } => {
|
||||||
|
let cm = self.cm.lock().await;
|
||||||
|
let _ = reply.send(*cm.observed_external_addr.lock().unwrap());
|
||||||
|
}
|
||||||
ConnCommand::TouchSessionIfExists { peer } => {
|
ConnCommand::TouchSessionIfExists { peer } => {
|
||||||
let mut cm = self.cm.lock().await;
|
let mut cm = self.cm.lock().await;
|
||||||
if let Some(session) = cm.sessions.get_mut(&peer) {
|
if let Some(session) = cm.sessions.get_mut(&peer) {
|
||||||
|
|
|
||||||
|
|
@ -1870,7 +1870,7 @@ async fn get_our_info(state: State<'_, AppNode>) -> Result<OurInfoDto, String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add iroh-discovered addresses not already listed (STUN-observed externals)
|
// Add iroh-discovered addresses not already listed
|
||||||
for sock in net.endpoint_addr().ip_addrs() {
|
for sock in net.endpoint_addr().ip_addrs() {
|
||||||
if sock.ip().is_loopback() || sock.ip().is_unspecified() { continue; }
|
if sock.ip().is_loopback() || sock.ip().is_unspecified() { continue; }
|
||||||
let s = sock.to_string();
|
let s = sock.to_string();
|
||||||
|
|
@ -1885,6 +1885,19 @@ async fn get_our_info(state: State<'_, AppNode>) -> Result<OurInfoDto, String> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add peer-observed external address (from anchor's your_observed_addr)
|
||||||
|
if let Some(observed) = net.conn_handle().observed_external_addr().await {
|
||||||
|
let s = observed.to_string();
|
||||||
|
if !addresses.iter().any(|a| a.addr == s) {
|
||||||
|
let family = if observed.ip().is_ipv4() { "IPv4" } else { "IPv6" };
|
||||||
|
addresses.insert(0, AddressInfoDto {
|
||||||
|
addr: s,
|
||||||
|
family: family.to_string(),
|
||||||
|
status: classify_addr(&observed, &nat_type, has_upnp, bind_addr.is_some(), true),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(OurInfoDto {
|
Ok(OurInfoDto {
|
||||||
node_id: hex::encode(net.node_id_bytes()),
|
node_id: hex::encode(net.node_id_bytes()),
|
||||||
addresses,
|
addresses,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue