Skip to content

Commit 7ea61fe

Browse files
Paul Cwolfsoftwaresystemsltd
andcommitted
fix: send discovery to configured peers directly (unicast)
Discovery previously only used UDP broadcast (255.255.255.255 and /24 subnet broadcast), which doesn't work across subnets or over WolfNet tunnels. Now also sends discovery messages directly to each configured peer's IP on the discovery port (8551), enabling cross-subnet and WolfNet peer discovery. Configured peers list: host:8550 → discovery sent to host:8551 Co-Authored-By: CodeWolf <paul@wolf.uk.com> Co-Authored-By: Wolf Software Systems Ltd <paul@wolf.uk.com>
1 parent bb8a3ac commit 7ea61fe

2 files changed

Lines changed: 30 additions & 5 deletions

File tree

wolfdisk/src/cluster/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ impl ClusterManager {
235235
self.node_id.clone(),
236236
self.config.node.bind.clone(),
237237
self.config.node.role,
238-
);
238+
).with_peers(self.config.cluster.peers.clone());
239239
discovery.start()?;
240240

241241
// Start a sync thread to copy discovered peers to our peer map

wolfdisk/src/network/discovery.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ pub struct Discovery {
5454
node_id: String,
5555
bind_address: String,
5656
role: DiscoveryRole,
57+
configured_peers: Vec<String>,
5758
peers: Arc<RwLock<HashMap<String, DiscoveredPeer>>>,
5859
is_leader: Arc<RwLock<bool>>,
5960
running: Arc<RwLock<bool>>,
@@ -66,12 +67,19 @@ impl Discovery {
6667
node_id,
6768
bind_address,
6869
role: role.into(),
70+
configured_peers: Vec::new(),
6971
peers: Arc::new(RwLock::new(HashMap::new())),
7072
is_leader: Arc::new(RwLock::new(false)),
7173
running: Arc::new(RwLock::new(false)),
7274
}
7375
}
7476

77+
/// Create with configured peers for direct unicast discovery
78+
pub fn with_peers(mut self, peers: Vec<String>) -> Self {
79+
self.configured_peers = peers;
80+
self
81+
}
82+
7583
/// Set leader status
7684
pub fn set_leader(&self, is_leader: bool) {
7785
*self.is_leader.write().unwrap() = is_leader;
@@ -100,9 +108,10 @@ impl Discovery {
100108
let role = self.role;
101109
let is_leader = Arc::clone(&self.is_leader);
102110
let running = Arc::clone(&self.running);
111+
let configured_peers = self.configured_peers.clone();
103112

104113
thread::spawn(move || {
105-
if let Err(e) = run_broadcaster(node_id, bind_address, role, is_leader, running) {
114+
if let Err(e) = run_broadcaster(node_id, bind_address, role, is_leader, running, configured_peers) {
106115
warn!("Discovery broadcaster error: {}", e);
107116
}
108117
});
@@ -177,16 +186,17 @@ fn run_broadcaster(
177186
role: DiscoveryRole,
178187
is_leader: Arc<RwLock<bool>>,
179188
running: Arc<RwLock<bool>>,
189+
configured_peers: Vec<String>,
180190
) -> std::io::Result<()> {
181191
// Create UDP socket for broadcasting
182192
let socket = UdpSocket::bind("0.0.0.0:0")?;
183193
socket.set_broadcast(true)?;
184-
194+
185195
// Broadcast destinations: 255.255.255.255 for LAN, plus subnet broadcast for WolfNet
186196
let mut broadcast_addrs: Vec<SocketAddr> = vec![
187197
format!("255.255.255.255:{}", DISCOVERY_PORT).parse().unwrap(),
188198
];
189-
199+
190200
// If bind address is on a specific IP (not 0.0.0.0), also broadcast to its /24 subnet
191201
// e.g. bind 10.10.10.3:8550 → broadcast to 10.10.10.255:8551
192202
if let Ok(bind_sock) = bind_address.parse::<SocketAddr>() {
@@ -202,7 +212,22 @@ fn run_broadcaster(
202212
}
203213
}
204214

205-
info!("Discovery broadcaster started for node {}", node_id);
215+
// Also send discovery directly to configured peers (unicast) — critical for
216+
// cross-subnet and WolfNet connectivity where broadcast doesn't work
217+
for peer in &configured_peers {
218+
// Peer address is host:port for the data port — discovery uses DISCOVERY_PORT
219+
if let Some(host) = peer.rsplit_once(':').map(|(h, _)| h) {
220+
let discovery_addr = format!("{}:{}", host, DISCOVERY_PORT);
221+
if let Ok(addr) = discovery_addr.parse::<SocketAddr>() {
222+
if !broadcast_addrs.contains(&addr) {
223+
broadcast_addrs.push(addr);
224+
info!("Added direct peer discovery target: {}", addr);
225+
}
226+
}
227+
}
228+
}
229+
230+
info!("Discovery broadcaster started for node {} ({} targets)", node_id, broadcast_addrs.len());
206231

207232
while *running.read().unwrap() {
208233
let is_server = matches!(role, DiscoveryRole::Server);

0 commit comments

Comments
 (0)