diff --git a/src/agent.rs b/src/agent.rs index bc38a4e..7062bf8 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -285,7 +285,7 @@ async fn handle_server_message(msg: ServerMessage, ygg_config_path: &str, no_res // Apply full configuration update to Yggdrasil match update_yggdrasil_config_full(ygg_config_path, &listen, &peers, &allowed_public_keys).await { - Ok(_) => { + Ok(true) => { info!("Configuration update successfully applied to {}", ygg_config_path); // Restart Yggdrasil service to apply updated configuration if !no_restart { @@ -296,6 +296,9 @@ async fn handle_server_message(msg: ServerMessage, ygg_config_path: &str, no_res info!("Skipping service restart (--no-restart flag set)"); } }, + Ok(false) => { + info!("Configuration unchanged, skipping restart"); + }, Err(e) => error!("Failed to update Yggdrasil config: {}", e), } } @@ -444,15 +447,29 @@ async fn update_yggdrasil_config_full( listen: &[String], peers: &[String], allowed_public_keys: &[String] -) -> Result<()> { +) -> Result { // Returns true if config was updated // Read current config let current_config = tokio::fs::read_to_string(config_path).await?; let mut config: serde_json::Value = serde_json::from_str(¤t_config)?; + // Check if config actually changed + let old_listen = config["Listen"].clone(); + let old_peers = config["Peers"].clone(); + let old_keys = config["AllowedPublicKeys"].clone(); + + let new_listen = serde_json::json!(listen); + let new_peers = serde_json::json!(peers); + let new_keys = serde_json::json!(allowed_public_keys); + + if old_listen == new_listen && old_peers == new_peers && old_keys == new_keys { + debug!("Configuration unchanged, skipping update"); + return Ok(false); + } + // Update listen, peers and allowed public keys - config["Listen"] = serde_json::json!(listen); - config["Peers"] = serde_json::json!(peers); - config["AllowedPublicKeys"] = serde_json::json!(allowed_public_keys); + config["Listen"] = new_listen; + config["Peers"] = new_peers; + config["AllowedPublicKeys"] = new_keys; // Write updated config back let updated_config = serde_json::to_string_pretty(&config)?; @@ -461,7 +478,7 @@ async fn update_yggdrasil_config_full( match tokio::fs::write(config_path, &updated_config).await { Ok(_) => { info!("Yggdrasil configuration fully updated in {}", config_path); - Ok(()) + Ok(true) } Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => { // Try with sudo if permission denied @@ -491,7 +508,7 @@ async fn update_yggdrasil_config_full( } info!("Yggdrasil configuration fully updated in {} with sudo", config_path); - Ok(()) + Ok(true) } Err(e) => Err(anyhow!("Failed to write configuration: {}", e)) } diff --git a/src/modules/websocket.rs b/src/modules/websocket.rs index 864e7b3..3dbb285 100644 --- a/src/modules/websocket.rs +++ b/src/modules/websocket.rs @@ -150,21 +150,32 @@ pub async fn handle_agent_socket( // Get current node information if let Some(current_node) = node_manager.get_node_by_id(id).await { - // Update node with new addresses - match node_manager.update_node( - id, - current_node.name.clone(), - current_node.listen.clone(), - addresses - ).await { - Ok(_) => { - info!("Updated addresses for node {}", id); - // Broadcast configuration update to all agents - crate::websocket_state::broadcast_configuration_update(&node_manager).await; - } - Err(e) => { - error!("Failed to update addresses for node {}: {}", id, e); + // Sort addresses for comparison to avoid false positives + let mut new_addresses = addresses.clone(); + new_addresses.sort(); + let mut current_addresses = current_node.addresses.clone(); + current_addresses.sort(); + + // Only update if addresses actually changed + if new_addresses != current_addresses { + // Update node with new addresses + match node_manager.update_node( + id, + current_node.name.clone(), + current_node.listen.clone(), + addresses + ).await { + Ok(_) => { + info!("Updated addresses for node {}", id); + // Broadcast configuration update to all agents + crate::websocket_state::broadcast_configuration_update(&node_manager).await; + } + Err(e) => { + error!("Failed to update addresses for node {}: {}", id, e); + } } + } else { + debug!("Address list unchanged for node {}, skipping update", id); } } else { warn!("Cannot update addresses for unknown node: {}", id);