From fc932346a2c6a162ad3f6056ac12a00e1b5c561c Mon Sep 17 00:00:00 2001 From: Chip Senkbeil Date: Fri, 14 Jul 2023 02:25:35 -0500 Subject: [PATCH] Still unfinished --- Cargo.lock | 1 + distant-net/Cargo.toml | 1 + distant-net/src/common/version.rs | 41 ++++++++++++++----------------- distant-net/src/manager.rs | 9 +++++++ distant-ssh2/src/lib.rs | 5 ---- src/cli/commands/server.rs | 8 +++++- src/cli/common/client.rs | 4 ++- src/cli/common/manager.rs | 7 +++++- 8 files changed, 46 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64ab77c..573882b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -931,6 +931,7 @@ dependencies = [ "async-trait", "bytes", "chacha20poly1305", + "const-str", "derive_more", "distant-auth", "dyn-clone", diff --git a/distant-net/Cargo.toml b/distant-net/Cargo.toml index 040e745..98a95ef 100644 --- a/distant-net/Cargo.toml +++ b/distant-net/Cargo.toml @@ -15,6 +15,7 @@ license = "MIT OR Apache-2.0" async-trait = "0.1.68" bytes = "1.4.0" chacha20poly1305 = "0.10.1" +const-str = "0.5.6" derive_more = { version = "0.99.17", default-features = false, features = ["as_mut", "as_ref", "deref", "deref_mut", "display", "from", "error", "into", "into_iterator", "is_variant", "try_into"] } distant-auth = { version = "=0.20.0-alpha.12", path = "../distant-auth" } dyn-clone = "1.0.11" diff --git a/distant-net/src/common/version.rs b/distant-net/src/common/version.rs index b9f9cae..5a2358f 100644 --- a/distant-net/src/common/version.rs +++ b/distant-net/src/common/version.rs @@ -1,11 +1,12 @@ -use semver::{Comparator, Op, Prerelease, Version as SemVer, VersionReq}; +use semver::{Comparator, Op, Prerelease, Version as SemVer}; use std::fmt; /// Represents a version and compatibility rules. #[derive(Clone, Debug)] pub struct Version { inner: SemVer, - rules: VersionReq, + lower: Comparator, + upper: Comparator, } impl Version { @@ -44,38 +45,34 @@ impl Version { /// assert!(!a.is_compatible_with(&b)); /// assert!(!b.is_compatible_with(&a)); /// ``` - pub fn new(major: u64, minor: u64, patch: u64) -> Self { + pub const fn new(major: u64, minor: u64, patch: u64) -> Self { Self { inner: SemVer::new(major, minor, patch), - rules: VersionReq { - comparators: vec![ - Comparator { - op: Op::GreaterEq, - major, - minor: Some(minor), - patch: Some(patch), - pre: Prerelease::EMPTY, - }, - Comparator { - op: Op::Less, - major: if major == 0 { 0 } else { major + 1 }, - minor: if major == 0 { Some(minor + 1) } else { None }, - patch: None, - pre: Prerelease::EMPTY, - }, - ], + lower: Comparator { + op: Op::GreaterEq, + major, + minor: Some(minor), + patch: Some(patch), + pre: Prerelease::EMPTY, + }, + upper: Comparator { + op: Op::Less, + major: if major == 0 { 0 } else { major + 1 }, + minor: if major == 0 { Some(minor + 1) } else { None }, + patch: None, + pre: Prerelease::EMPTY, }, } } /// Returns true if this version is compatible with another version. pub fn is_compatible_with(&self, other: &Self) -> bool { - self.rules.matches(&other.inner) + self.lower.matches(&other.inner) && self.upper.matches(&other.inner) } /// Converts from a collection of bytes into a version using the byte form major/minor/patch /// using big endian. - pub fn from_be_bytes(bytes: [u8; 24]) -> Self { + pub const fn from_be_bytes(bytes: [u8; 24]) -> Self { Self::new( u64::from_be_bytes([ bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], diff --git a/distant-net/src/manager.rs b/distant-net/src/manager.rs index 6a9bf19..0201d71 100644 --- a/distant-net/src/manager.rs +++ b/distant-net/src/manager.rs @@ -5,3 +5,12 @@ mod server; pub use client::*; pub use data::*; pub use server::*; + +use crate::common::Version; + +/// Represents the version associated with the manager's protocol. +pub const PROTOCOL_VERSION: Version = Version::new( + const_str::parse!(env!("CARGO_PKG_VERSION_MAJOR"), u64), + const_str::parse!(env!("CARGO_PKG_VERSION_MINOR"), u64), + const_str::parse!(env!("CARGO_PKG_VERSION_PATCH"), u64), +); diff --git a/distant-ssh2/src/lib.rs b/distant-ssh2/src/lib.rs index 78a24ee..94381eb 100644 --- a/distant-ssh2/src/lib.rs +++ b/distant-ssh2/src/lib.rs @@ -762,11 +762,6 @@ impl Ssh { .auth_handler(DummyAuthHandler) .config(ClientConfig::default().with_maximum_silence_duration()) .connector(t1) - .version(Version::new( - PROTOCOL_VERSION.major, - PROTOCOL_VERSION.minor, - PROTOCOL_VERSION.patch, - )) .connect() .await?; Ok((client, server)) diff --git a/src/cli/commands/server.rs b/src/cli/commands/server.rs index 81f1d1b..d3d3740 100644 --- a/src/cli/commands/server.rs +++ b/src/cli/commands/server.rs @@ -2,8 +2,9 @@ use std::io::{self, Read, Write}; use anyhow::Context; use distant_core::net::auth::Verifier; -use distant_core::net::common::{Host, SecretKey32}; +use distant_core::net::common::{Host, SecretKey32, Version}; use distant_core::net::server::{Server, ServerConfig as NetServerConfig}; +use distant_core::protocol::PROTOCOL_VERSION; use distant_core::DistantSingleKeyCredentials; use distant_local::{Config as LocalConfig, WatchConfig as LocalWatchConfig}; use log::*; @@ -159,6 +160,11 @@ async fn async_run(cmd: ServerSubcommand, _is_forked: bool) -> CliResult { }) .handler(handler) .verifier(Verifier::static_key(key.clone())) + .version(Version::new( + PROTOCOL_VERSION.major, + PROTOCOL_VERSION.minor, + PROTOCOL_VERSION.patch, + )) .start(addr, port) .await .with_context(|| format!("Failed to start server @ {addr} with {port}"))?; diff --git a/src/cli/common/client.rs b/src/cli/common/client.rs index 73dd481..3f590cf 100644 --- a/src/cli/common/client.rs +++ b/src/cli/common/client.rs @@ -7,7 +7,7 @@ use distant_core::net::auth::{ AuthHandler, AuthMethodHandler, PromptAuthMethodHandler, SingleAuthHandler, }; use distant_core::net::client::{Client as NetClient, ClientConfig, ReconnectStrategy}; -use distant_core::net::manager::ManagerClient; +use distant_core::net::manager::{ManagerClient, PROTOCOL_VERSION}; use log::*; use crate::cli::common::{MsgReceiver, MsgSender}; @@ -71,6 +71,7 @@ impl Client { }, ..Default::default() }) + .version(PROTOCOL_VERSION) .connect() .await { @@ -113,6 +114,7 @@ impl Client { }, ..Default::default() }) + .version(PROTOCOL_VERSION) .connect() .await { diff --git a/src/cli/common/manager.rs b/src/cli/common/manager.rs index 5aa4e25..de3c928 100644 --- a/src/cli/common/manager.rs +++ b/src/cli/common/manager.rs @@ -1,6 +1,6 @@ use anyhow::Context; use distant_core::net::auth::Verifier; -use distant_core::net::manager::{Config as ManagerConfig, ManagerServer}; +use distant_core::net::manager::{Config as ManagerConfig, ManagerServer, PROTOCOL_VERSION}; use distant_core::net::server::ServerRef; use log::*; @@ -18,6 +18,9 @@ impl Manager { pub async fn listen(self) -> anyhow::Result { let user = self.config.user; + // Version we'll use to report compatibility in talking to the manager + let version = PROTOCOL_VERSION; + #[cfg(unix)] { use distant_core::net::common::UnixSocketListener; @@ -38,6 +41,7 @@ impl Manager { let server = ManagerServer::new(self.config) .verifier(Verifier::none()) + .version(version) .start( UnixSocketListener::bind_with_permissions(socket_path, self.access.into_mode()) .await?, @@ -59,6 +63,7 @@ impl Manager { let server = ManagerServer::new(self.config) .verifier(Verifier::none()) + .version(version) .start(WindowsPipeListener::bind_local(pipe_name)?) .with_context(|| format!("Failed to start manager at pipe {pipe_name:?}"))?;