mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-08 21:43:44 +02:00
Controller receives NETWORK_CONFIG_REQUEST packets!
This commit is contained in:
parent
459b195fa4
commit
aac20c67d2
2 changed files with 36 additions and 21 deletions
|
@ -36,6 +36,12 @@ impl<DatabaseImpl: Database> Controller<DatabaseImpl> {
|
||||||
have_revision: Option<u64>,
|
have_revision: Option<u64>,
|
||||||
have_timestamp: Option<u64>,
|
have_timestamp: Option<u64>,
|
||||||
) {
|
) {
|
||||||
|
println!(
|
||||||
|
"handle_network_config_request {} {} {}",
|
||||||
|
source.identity.to_string(),
|
||||||
|
source_path.endpoint.to_string(),
|
||||||
|
network_id.to_string()
|
||||||
|
);
|
||||||
if let Ok(Some(network)) = database.get_network(network_id).await {}
|
if let Ok(Some(network)) = database.get_network(network_id).await {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +81,8 @@ impl<DatabaseImpl: Database> InnerProtocol for Controller<DatabaseImpl> {
|
||||||
) -> PacketHandlerResult {
|
) -> PacketHandlerResult {
|
||||||
match verb {
|
match verb {
|
||||||
verbs::VL2_VERB_NETWORK_CONFIG_REQUEST => {
|
verbs::VL2_VERB_NETWORK_CONFIG_REQUEST => {
|
||||||
let mut cursor = 0;
|
let mut cursor = 1;
|
||||||
|
|
||||||
let network_id = payload.read_u64(&mut cursor);
|
let network_id = payload.read_u64(&mut cursor);
|
||||||
if network_id.is_err() {
|
if network_id.is_err() {
|
||||||
return PacketHandlerResult::Error;
|
return PacketHandlerResult::Error;
|
||||||
|
@ -85,7 +92,8 @@ impl<DatabaseImpl: Database> InnerProtocol for Controller<DatabaseImpl> {
|
||||||
return PacketHandlerResult::Error;
|
return PacketHandlerResult::Error;
|
||||||
}
|
}
|
||||||
let network_id = network_id.unwrap();
|
let network_id = network_id.unwrap();
|
||||||
let meta_data = if cursor < payload.len() {
|
|
||||||
|
let meta_data = if (cursor + 2) < payload.len() {
|
||||||
let meta_data_len = payload.read_u16(&mut cursor);
|
let meta_data_len = payload.read_u16(&mut cursor);
|
||||||
if meta_data_len.is_err() {
|
if meta_data_len.is_err() {
|
||||||
return PacketHandlerResult::Error;
|
return PacketHandlerResult::Error;
|
||||||
|
@ -102,7 +110,8 @@ impl<DatabaseImpl: Database> InnerProtocol for Controller<DatabaseImpl> {
|
||||||
} else {
|
} else {
|
||||||
Dictionary::new()
|
Dictionary::new()
|
||||||
};
|
};
|
||||||
let (have_revision, have_timestamp) = if cursor < payload.len() {
|
|
||||||
|
let (have_revision, have_timestamp) = if (cursor + 16) <= payload.len() {
|
||||||
let r = payload.read_u64(&mut cursor);
|
let r = payload.read_u64(&mut cursor);
|
||||||
let t = payload.read_u64(&mut cursor);
|
let t = payload.read_u64(&mut cursor);
|
||||||
if r.is_err() || t.is_err() {
|
if r.is_err() || t.is_err() {
|
||||||
|
|
|
@ -20,9 +20,14 @@ use crate::model::*;
|
||||||
|
|
||||||
const IDENTITY_SECRET_FILENAME: &'static str = "identity.secret";
|
const IDENTITY_SECRET_FILENAME: &'static str = "identity.secret";
|
||||||
|
|
||||||
|
/// An in-filesystem database that permits live editing.
|
||||||
|
///
|
||||||
|
/// A cache is maintained that contains the actual objects. When an object is live edited,
|
||||||
|
/// once it successfully reads and loads it is merged with the cached object and saved to
|
||||||
|
/// the cache. The cache will also contain any ephemeral data, generated data, etc.
|
||||||
pub struct FileDatabase {
|
pub struct FileDatabase {
|
||||||
base: PathBuf,
|
base_path: PathBuf,
|
||||||
cache: PathBuf,
|
cache_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn network_path(base: &PathBuf, network_id: NetworkId) -> PathBuf {
|
fn network_path(base: &PathBuf, network_id: NetworkId) -> PathBuf {
|
||||||
|
@ -38,7 +43,7 @@ impl FileDatabase {
|
||||||
let base: PathBuf = base_path.as_ref().into();
|
let base: PathBuf = base_path.as_ref().into();
|
||||||
let cache: PathBuf = base_path.as_ref().join("cache");
|
let cache: PathBuf = base_path.as_ref().join("cache");
|
||||||
let _ = fs::create_dir_all(&cache).await;
|
let _ = fs::create_dir_all(&cache).await;
|
||||||
Self { base, cache }
|
Self { base_path: base, cache_path: cache }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Merge an object with its cached instance and save the result to the 'cache' path.
|
/// Merge an object with its cached instance and save the result to the 'cache' path.
|
||||||
|
@ -65,7 +70,7 @@ impl FileDatabase {
|
||||||
|
|
||||||
impl NodeStorage for FileDatabase {
|
impl NodeStorage for FileDatabase {
|
||||||
fn load_node_identity(&self) -> Option<Identity> {
|
fn load_node_identity(&self) -> Option<Identity> {
|
||||||
let id_data = read_limit(self.base.join(IDENTITY_SECRET_FILENAME), 4096);
|
let id_data = read_limit(self.base_path.join(IDENTITY_SECRET_FILENAME), 4096);
|
||||||
if id_data.is_err() {
|
if id_data.is_err() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +84,7 @@ impl NodeStorage for FileDatabase {
|
||||||
fn save_node_identity(&self, id: &Identity) {
|
fn save_node_identity(&self, id: &Identity) {
|
||||||
assert!(id.secret.is_some());
|
assert!(id.secret.is_some());
|
||||||
let id_secret_str = id.to_secret_string();
|
let id_secret_str = id.to_secret_string();
|
||||||
let secret_path = self.base.join(IDENTITY_SECRET_FILENAME);
|
let secret_path = self.base_path.join(IDENTITY_SECRET_FILENAME);
|
||||||
assert!(std::fs::write(&secret_path, id_secret_str.as_bytes()).is_ok());
|
assert!(std::fs::write(&secret_path, id_secret_str.as_bytes()).is_ok());
|
||||||
assert!(fs_restrict_permissions(&secret_path));
|
assert!(fs_restrict_permissions(&secret_path));
|
||||||
}
|
}
|
||||||
|
@ -88,18 +93,18 @@ impl NodeStorage for FileDatabase {
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Database for FileDatabase {
|
impl Database for FileDatabase {
|
||||||
async fn get_network(&self, id: NetworkId) -> Result<Option<Network>, Box<dyn Error>> {
|
async fn get_network(&self, id: NetworkId) -> Result<Option<Network>, Box<dyn Error>> {
|
||||||
let r = fs::read(network_path(&self.base, id)).await;
|
let r = fs::read(network_path(&self.base_path, id)).await;
|
||||||
if let Ok(raw) = r {
|
if let Ok(raw) = r {
|
||||||
let r = serde_json::from_slice::<Network>(raw.as_slice());
|
let r = serde_json::from_slice::<Network>(raw.as_slice());
|
||||||
if let Ok(network) = r {
|
if let Ok(network) = r {
|
||||||
return Ok(Some(self.merge_with_cache(network_path(&self.cache, id), network).await?));
|
return Ok(Some(self.merge_with_cache(network_path(&self.cache_path, id), network).await?));
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(r.err().unwrap()));
|
return Err(Box::new(r.err().unwrap()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let e = r.unwrap_err();
|
let e = r.unwrap_err();
|
||||||
if matches!(e.kind(), ErrorKind::NotFound) {
|
if matches!(e.kind(), ErrorKind::NotFound) {
|
||||||
let _ = fs::remove_dir_all(self.cache.join(id.to_string())).await;
|
let _ = fs::remove_dir_all(self.cache_path.join(id.to_string())).await;
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(e));
|
return Err(Box::new(e));
|
||||||
|
@ -108,22 +113,22 @@ impl Database for FileDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn save_network(&self, obj: &Network) -> Result<(), Box<dyn Error>> {
|
async fn save_network(&self, obj: &Network) -> Result<(), Box<dyn Error>> {
|
||||||
let _ = fs::create_dir_all(self.base.join(obj.id.to_string())).await;
|
let _ = fs::create_dir_all(self.base_path.join(obj.id.to_string())).await;
|
||||||
let _ = fs::create_dir_all(self.cache.join(obj.id.to_string())).await;
|
let _ = fs::create_dir_all(self.cache_path.join(obj.id.to_string())).await;
|
||||||
|
|
||||||
let base_network_path = network_path(&self.base, obj.id);
|
let base_network_path = network_path(&self.base_path, obj.id);
|
||||||
if !fs::metadata(&base_network_path).await.is_ok() {
|
if !fs::metadata(&base_network_path).await.is_ok() {
|
||||||
fs::write(base_network_path, to_json_pretty(obj).as_bytes()).await?;
|
fs::write(base_network_path, to_json_pretty(obj).as_bytes()).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::write(network_path(&self.cache, obj.id), serde_json::to_vec(obj)?.as_slice()).await?;
|
fs::write(network_path(&self.cache_path, obj.id), serde_json::to_vec(obj)?.as_slice()).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn list_members(&self, network_id: NetworkId) -> Result<Vec<Address>, Box<dyn Error>> {
|
async fn list_members(&self, network_id: NetworkId) -> Result<Vec<Address>, Box<dyn Error>> {
|
||||||
let mut members = Vec::new();
|
let mut members = Vec::new();
|
||||||
let mut dir = fs::read_dir(self.base.join(network_id.to_string())).await?;
|
let mut dir = fs::read_dir(self.base_path.join(network_id.to_string())).await?;
|
||||||
while let Ok(Some(ent)) = dir.next_entry().await {
|
while let Ok(Some(ent)) = dir.next_entry().await {
|
||||||
let osname = ent.file_name();
|
let osname = ent.file_name();
|
||||||
let name = osname.to_string_lossy();
|
let name = osname.to_string_lossy();
|
||||||
|
@ -142,12 +147,13 @@ impl Database for FileDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_member(&self, network_id: NetworkId, node_id: Address) -> Result<Option<Member>, Box<dyn Error>> {
|
async fn get_member(&self, network_id: NetworkId, node_id: Address) -> Result<Option<Member>, Box<dyn Error>> {
|
||||||
let r = fs::read(member_path(&self.base, network_id, node_id)).await;
|
let r = fs::read(member_path(&self.base_path, network_id, node_id)).await;
|
||||||
if let Ok(raw) = r {
|
if let Ok(raw) = r {
|
||||||
let r = serde_json::from_slice::<Member>(raw.as_slice());
|
let r = serde_json::from_slice::<Member>(raw.as_slice());
|
||||||
if let Ok(member) = r {
|
if let Ok(member) = r {
|
||||||
return Ok(Some(
|
return Ok(Some(
|
||||||
self.merge_with_cache(member_path(&self.cache, network_id, node_id), member).await?,
|
self.merge_with_cache(member_path(&self.cache_path, network_id, node_id), member)
|
||||||
|
.await?,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(r.err().unwrap()));
|
return Err(Box::new(r.err().unwrap()));
|
||||||
|
@ -155,7 +161,7 @@ impl Database for FileDatabase {
|
||||||
} else {
|
} else {
|
||||||
let e = r.unwrap_err();
|
let e = r.unwrap_err();
|
||||||
if matches!(e.kind(), ErrorKind::NotFound) {
|
if matches!(e.kind(), ErrorKind::NotFound) {
|
||||||
let _ = fs::remove_file(member_path(&self.cache, network_id, node_id)).await;
|
let _ = fs::remove_file(member_path(&self.cache_path, network_id, node_id)).await;
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(e));
|
return Err(Box::new(e));
|
||||||
|
@ -164,13 +170,13 @@ impl Database for FileDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn save_member(&self, obj: &Member) -> Result<(), Box<dyn Error>> {
|
async fn save_member(&self, obj: &Member) -> Result<(), Box<dyn Error>> {
|
||||||
let base_member_path = member_path(&self.base, obj.network_id, obj.node_id);
|
let base_member_path = member_path(&self.base_path, obj.network_id, obj.node_id);
|
||||||
if !fs::metadata(&base_member_path).await.is_ok() {
|
if !fs::metadata(&base_member_path).await.is_ok() {
|
||||||
fs::write(base_member_path, to_json_pretty(obj).as_bytes()).await?;
|
fs::write(base_member_path, to_json_pretty(obj).as_bytes()).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::write(
|
fs::write(
|
||||||
member_path(&self.cache, obj.network_id, obj.node_id),
|
member_path(&self.cache_path, obj.network_id, obj.node_id),
|
||||||
serde_json::to_vec(obj)?.as_slice(),
|
serde_json::to_vec(obj)?.as_slice(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
Loading…
Add table
Reference in a new issue