@@ -457,52 +457,25 @@ async fn run_daemon(config_path: &std::path::Path) -> anyhow::Result<()> { |
| 457 | .map(|n| n.direction) | 457 | .map(|n| n.direction) |
| 458 | }; | 458 | }; |
| 459 | | 459 | |
| 460 | - // Check if we need to update our config due to direction change | 460 | + // NOTE: We no longer auto-correct direction based on peer claims. |
| | 461 | + // Direction changes are now handled explicitly via DirectionChange messages |
| | 462 | + // sent when the user changes direction in the GUI. |
| | 463 | + // This prevents the config from being overwritten on reconnect. |
| 461 | if let Some(peer_dir) = hello.my_direction_for_you { | 464 | if let Some(peer_dir) = hello.my_direction_for_you { |
| 462 | let new_dir = peer_dir.opposite(); | 465 | let new_dir = peer_dir.opposite(); |
| 463 | let existing = neighbors_for_accept | 466 | let existing = neighbors_for_accept |
| 464 | .iter() | 467 | .iter() |
| 465 | .find(|n| n.name == hello.machine_name); | 468 | .find(|n| n.name == hello.machine_name); |
| 466 | | 469 | |
| 467 | - let needs_update = match existing { | 470 | + if let Some(existing_neighbor) = existing { |
| 468 | - Some(n) => n.direction != new_dir, | 471 | + if existing_neighbor.direction != new_dir { |
| 469 | - None => true, // Peer not in our config - could add them | 472 | + // Just log the mismatch, don't auto-correct |
| 470 | - }; | 473 | + // The user should update both configs via the GUI |
| 471 | - | 474 | + tracing::warn!( |
| 472 | - if needs_update { | 475 | + "Direction mismatch for {}: our config says {:?}, peer claims {:?}. \ |
| 473 | - if let Some(existing_neighbor) = existing { | 476 | + Use the GUI to update directions on both machines.", |
| 474 | - info!( | | |
| 475 | - "Direction mismatch for {}: our config says {:?}, peer says we should be {:?}", | | |
| 476 | hello.machine_name, existing_neighbor.direction, new_dir | 477 | hello.machine_name, existing_neighbor.direction, new_dir |
| 477 | ); | 478 | ); |
| 478 | - | | |
| 479 | - // Load, update, and save config | | |
| 480 | - match Config::load(&config_path_for_accept) { | | |
| 481 | - Ok(mut cfg) => { | | |
| 482 | - // Find and update the neighbor's direction | | |
| 483 | - for neighbor in &mut cfg.machines.neighbors { | | |
| 484 | - if neighbor.name == hello.machine_name { | | |
| 485 | - info!("Updating {} direction: {:?} -> {:?}", | | |
| 486 | - neighbor.name, neighbor.direction, new_dir); | | |
| 487 | - neighbor.direction = new_dir; | | |
| 488 | - break; | | |
| 489 | - } | | |
| 490 | - } | | |
| 491 | - | | |
| 492 | - // Save updated config | | |
| 493 | - if let Err(e) = cfg.save(&config_path_for_accept) { | | |
| 494 | - tracing::error!("Failed to save updated config: {}", e); | | |
| 495 | - } else { | | |
| 496 | - info!("Config updated with new direction, signaling restart..."); | | |
| 497 | - let _ = restart_tx_for_accept.try_send( | | |
| 498 | - format!("Direction changed for {}", hello.machine_name) | | |
| 499 | - ); | | |
| 500 | - } | | |
| 501 | - } | | |
| 502 | - Err(e) => { | | |
| 503 | - tracing::error!("Failed to load config for update: {}", e); | | |
| 504 | - } | | |
| 505 | - } | | |
| 506 | } | 479 | } |
| 507 | } | 480 | } |
| 508 | } | 481 | } |
@@ -1399,6 +1372,63 @@ async fn run_daemon(config_path: &std::path::Path) -> anyhow::Result<()> { |
| 1399 | } | 1372 | } |
| 1400 | }); | 1373 | }); |
| 1401 | } | 1374 | } |
| | 1375 | + Message::DirectionChange(payload) => { |
| | 1376 | + // Peer is notifying us that they changed our relative direction |
| | 1377 | + // We need to update our config to store them in the opposite direction |
| | 1378 | + let new_dir_for_peer = payload.your_direction_from_me.opposite(); |
| | 1379 | + info!("Received DirectionChange: peer says we are {:?} from them, so we store them as {:?}", |
| | 1380 | + payload.your_direction_from_me, new_dir_for_peer); |
| | 1381 | + |
| | 1382 | + // Find the peer's name from config based on direction |
| | 1383 | + let peer_name = config.machines.neighbors |
| | 1384 | + .iter() |
| | 1385 | + .find(|n| n.direction == direction) |
| | 1386 | + .map(|n| n.name.clone()) |
| | 1387 | + .unwrap_or_else(|| "unknown".to_string()); |
| | 1388 | + |
| | 1389 | + // Load, update, and save config |
| | 1390 | + let config_path_clone = config_path.clone(); |
| | 1391 | + match Config::load(&config_path_clone) { |
| | 1392 | + Ok(mut cfg) => { |
| | 1393 | + let mut found = false; |
| | 1394 | + for neighbor in &mut cfg.machines.neighbors { |
| | 1395 | + if neighbor.name == peer_name { |
| | 1396 | + info!("DirectionChange: updating {} direction {:?} -> {:?}", |
| | 1397 | + neighbor.name, neighbor.direction, new_dir_for_peer); |
| | 1398 | + neighbor.direction = new_dir_for_peer; |
| | 1399 | + found = true; |
| | 1400 | + break; |
| | 1401 | + } |
| | 1402 | + } |
| | 1403 | + |
| | 1404 | + if found { |
| | 1405 | + if let Err(e) = cfg.save(&config_path_clone) { |
| | 1406 | + tracing::error!("DirectionChange: failed to save config: {}", e); |
| | 1407 | + let _ = peer.send(&Message::DirectionChangeAck { success: false }).await; |
| | 1408 | + } else { |
| | 1409 | + info!("DirectionChange: config updated, signaling restart"); |
| | 1410 | + let _ = peer.send(&Message::DirectionChangeAck { success: true }).await; |
| | 1411 | + // Signal restart to apply new edge barriers |
| | 1412 | + let _ = restart_tx.try_send(format!("Direction sync from {}", peer_name)); |
| | 1413 | + } |
| | 1414 | + } else { |
| | 1415 | + tracing::warn!("DirectionChange: peer {} not found in config", peer_name); |
| | 1416 | + let _ = peer.send(&Message::DirectionChangeAck { success: false }).await; |
| | 1417 | + } |
| | 1418 | + } |
| | 1419 | + Err(e) => { |
| | 1420 | + tracing::error!("DirectionChange: failed to load config: {}", e); |
| | 1421 | + let _ = peer.send(&Message::DirectionChangeAck { success: false }).await; |
| | 1422 | + } |
| | 1423 | + } |
| | 1424 | + } |
| | 1425 | + Message::DirectionChangeAck { success } => { |
| | 1426 | + if success { |
| | 1427 | + info!("DirectionChangeAck: peer acknowledged direction update"); |
| | 1428 | + } else { |
| | 1429 | + tracing::warn!("DirectionChangeAck: peer failed to update direction"); |
| | 1430 | + } |
| | 1431 | + } |
| 1402 | _ => { | 1432 | _ => { |
| 1403 | tracing::debug!("Unhandled message: {:?}", msg); | 1433 | tracing::debug!("Unhandled message: {:?}", msg); |
| 1404 | } | 1434 | } |
@@ -2153,6 +2183,8 @@ async fn run_daemon(config_path: &std::path::Path) -> anyhow::Result<()> { |
| 2153 | } | 2183 | } |
| 2154 | | 2184 | |
| 2155 | // Check for direction changes (requires restart for edge barriers) | 2185 | // Check for direction changes (requires restart for edge barriers) |
| | 2186 | + // Also send DirectionChange messages to notify peers |
| | 2187 | + let mut direction_changes: Vec<(String, Direction)> = Vec::new(); |
| 2156 | for new_neighbor in &new_config.machines.neighbors { | 2188 | for new_neighbor in &new_config.machines.neighbors { |
| 2157 | if let Some(old_neighbor) = config.machines.neighbors | 2189 | if let Some(old_neighbor) = config.machines.neighbors |
| 2158 | .iter() | 2190 | .iter() |
@@ -2164,6 +2196,36 @@ async fn run_daemon(config_path: &std::path::Path) -> anyhow::Result<()> { |
| 2164 | new_neighbor.name, old_neighbor.direction, new_neighbor.direction | 2196 | new_neighbor.name, old_neighbor.direction, new_neighbor.direction |
| 2165 | )); | 2197 | )); |
| 2166 | needs_restart = true; | 2198 | needs_restart = true; |
| | 2199 | + // Track this change to notify the peer |
| | 2200 | + direction_changes.push((new_neighbor.name.clone(), new_neighbor.direction)); |
| | 2201 | + } |
| | 2202 | + } |
| | 2203 | + } |
| | 2204 | + |
| | 2205 | + // Send DirectionChange messages to affected peers |
| | 2206 | + // We need to send on the OLD direction since that's where the peer is connected |
| | 2207 | + for (peer_name, new_direction) in &direction_changes { |
| | 2208 | + // Find the OLD direction for this peer from current config |
| | 2209 | + let old_direction = config.machines.neighbors |
| | 2210 | + .iter() |
| | 2211 | + .find(|n| &n.name == peer_name) |
| | 2212 | + .map(|n| n.direction); |
| | 2213 | + |
| | 2214 | + if let Some(old_dir) = old_direction { |
| | 2215 | + let mut peers_guard = peers.write().await; |
| | 2216 | + if let Some(peer) = peers_guard.get_mut(&old_dir) { |
| | 2217 | + info!("Sending DirectionChange to {}: you are now {:?} from me", |
| | 2218 | + peer_name, new_direction); |
| | 2219 | + let msg = Message::DirectionChange( |
| | 2220 | + hyprkvm_common::protocol::DirectionChangePayload { |
| | 2221 | + your_direction_from_me: *new_direction, |
| | 2222 | + } |
| | 2223 | + ); |
| | 2224 | + if let Err(e) = peer.send(&msg).await { |
| | 2225 | + tracing::warn!("Failed to send DirectionChange to {}: {}", peer_name, e); |
| | 2226 | + } |
| | 2227 | + } else { |
| | 2228 | + tracing::warn!("Peer {} not connected on {:?}", peer_name, old_dir); |
| 2167 | } | 2229 | } |
| 2168 | } | 2230 | } |
| 2169 | } | 2231 | } |