diff --git a/controller/src/controller.rs b/controller/src/controller.rs index ed5ab0b5d..d38f8d572 100644 --- a/controller/src/controller.rs +++ b/controller/src/controller.rs @@ -62,16 +62,9 @@ impl Controller { /// won't actually do anything. The reference the handler holds is weak to prevent /// a circular reference, so if the VL1Service is dropped this must be called again to /// tell the controller handler about a new instance. - pub fn set_service(&self, service: &Arc>) { + pub async fn set_service(&self, service: &Arc>) { *self.service.write().unwrap() = Arc::downgrade(service); - } - /// Start a change watcher to respond to changes detected by the database. - /// - /// This should only be called once, though multiple calls won't do anything but create - /// unnecessary async tasks. If the database being used does not support changes, this - /// does nothing. - pub async fn start_change_watcher(&self) { if let Some(cw) = self.database.changes().await.map(|mut ch| { let self2 = self.self_ref.upgrade().unwrap(); self.runtime.spawn(async move { @@ -89,6 +82,7 @@ impl Controller { } } + /// Compose and send network configuration packet. fn send_network_config( &self, peer: &Peer, @@ -142,9 +136,14 @@ impl Controller { } } + /// Called when the DB informs us of a change. async fn handle_change_notification(self: Arc, _change: Change) {} - async fn handle_network_config_request( + /// Attempt to create a network configuration and return the result. + /// + /// An error is only returned if a database or other unusual error occurs. Otherwise a rejection + /// reason is returned with None or an acceptance reason with a network configuration is returned. + async fn get_network_config( self: &Arc, source_identity: &Identity, network_id: NetworkId, @@ -335,12 +334,12 @@ impl InnerProtocol for Controller { let node_fingerprint = Blob::from(peer.identity.fingerprint); let now = ms_since_epoch(); - let result = match self2.handle_network_config_request(&peer.identity, network_id, now).await { + let (result, config) = match self2.get_network_config(&peer.identity, network_id, now).await { Result::Ok((result, Some(config))) => { self2.send_network_config(peer.as_ref(), &config, Some(message_id)); - result + (result, Some(config)) } - Result::Ok((result, None)) => result, + Result::Ok((result, None)) => (result, None), Result::Err(_) => { // TODO: log invalid request or internal error return; @@ -363,6 +362,7 @@ impl InnerProtocol for Controller { source_remote_endpoint, source_hops, result, + config, }) .await; }), diff --git a/controller/src/main.rs b/controller/src/main.rs index 32efb8375..8ccc90f39 100644 --- a/controller/src/main.rs +++ b/controller/src/main.rs @@ -34,8 +34,7 @@ async fn run(database: Arc, runtime: &Runtime) -> i32 { let svc = svc.unwrap(); svc.node().init_default_roots(); - handler.set_service(&svc); - handler.start_change_watcher().await; + handler.set_service(&svc).await; // Wait for kill signal on Unix-like platforms. #[cfg(unix)] @@ -49,6 +48,13 @@ async fn run(database: Arc, runtime: &Runtime) -> i32 { } } + #[cfg(windows)] + { + // TODO: if anyone wants to use this on Windows you'll need to make it a service or wait + // for a stop signal or soemthing here. + todo!(); + } + println!("Terminate signal received, shutting down..."); exitcode::OK } else { diff --git a/controller/src/model/mod.rs b/controller/src/model/mod.rs index d869c7b8d..f96ee3ab2 100644 --- a/controller/src/model/mod.rs +++ b/controller/src/model/mod.rs @@ -11,7 +11,7 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; use zerotier_network_hypervisor::vl1::{Address, Endpoint}; -use zerotier_network_hypervisor::vl2::NetworkId; +use zerotier_network_hypervisor::vl2::{NetworkConfig, NetworkId}; use zerotier_utils::blob::Blob; /// A complete network with all member configuration information for import/export or blob storage. @@ -111,6 +111,8 @@ pub struct RequestLogItem { pub source_hops: u8, #[serde(rename = "r")] pub result: AuthorizationResult, + #[serde(rename = "nc")] + pub config: Option, } impl ToString for RequestLogItem {