From 0a05e62c7fe5eb639d36a8f7f49e79b3d2e781fa Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Tue, 7 Apr 2026 21:37:10 +0400 Subject: [PATCH] feat: relay prints federation peering config on startup On startup, the relay detects its outbound IP (via UDP socket trick) and prints a ready-to-copy YAML snippet for other relays to federate: federation: to peer with this relay, add to peers config: - url: "193.180.213.68:4433" fingerprint: "a5d6:e3c6:..." Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/wzp-relay/src/main.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/crates/wzp-relay/src/main.rs b/crates/wzp-relay/src/main.rs index 1f73636..abc380b 100644 --- a/crates/wzp-relay/src/main.rs +++ b/crates/wzp-relay/src/main.rs @@ -184,6 +184,21 @@ async fn run_downstream( } } +/// Detect a non-loopback IP address from local interfaces. +/// Prefers public IPs over private (10.x, 172.16-31.x, 192.168.x). +fn detect_public_ip() -> Option { + use std::net::UdpSocket; + // Connect to a public address to find our outbound IP (doesn't actually send anything) + if let Ok(socket) = UdpSocket::bind("0.0.0.0:0") { + if socket.connect("8.8.8.8:80").is_ok() { + if let Ok(addr) = socket.local_addr() { + return Some(addr.ip().to_string()); + } + } + } + None +} + #[tokio::main] async fn main() -> anyhow::Result<()> { let config = parse_args(); @@ -243,6 +258,15 @@ async fn main() -> anyhow::Result<()> { let relay_fp = relay_seed.derive_identity().public_identity().fingerprint; info!(addr = %config.listen_addr, fingerprint = %relay_fp, "WarzonePhone relay starting"); + // Print federation hint with our public IP + listen port + let listen_port = config.listen_addr.port(); + let public_ip = detect_public_ip(); + if let Some(ip) = &public_ip { + info!("federation: to peer with this relay, add to peers config:"); + info!(" - url: \"{ip}:{listen_port}\""); + info!(" fingerprint: \"{relay_fp}\""); + } + let (server_config, _cert) = wzp_transport::server_config(); let endpoint = wzp_transport::create_endpoint(config.listen_addr, Some(server_config))?;