From 065aef9c2a6f77936258a54c5d06f83c7f8e5fec Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 18 Jan 2023 14:35:41 +0100 Subject: [PATCH 001/203] Protocol internal reorg --- commons/zenoh-codec/src/transport/join.rs | 4 +- commons/zenoh-codec/src/zenoh/data.rs | 4 +- commons/zenoh-codec/src/zenoh/declare.rs | 5 +- commons/zenoh-codec/src/zenoh/query.rs | 4 +- commons/zenoh-protocol/src/core/endpoint.rs | 11 +- commons/zenoh-protocol/src/core/mod.rs | 246 ++++--------------- commons/zenoh-protocol/src/core/wire_expr.rs | 8 +- commons/zenoh-protocol/src/transport/join.rs | 7 +- commons/zenoh-protocol/src/transport/mod.rs | 54 +++- commons/zenoh-protocol/src/zenoh/data.rs | 41 +++- commons/zenoh-protocol/src/zenoh/declare.rs | 33 ++- commons/zenoh-protocol/src/zenoh/mod.rs | 4 +- commons/zenoh-protocol/src/zenoh/query.rs | 37 ++- io/zenoh-transport/src/primitives/mod.rs | 7 +- io/zenoh-transport/src/primitives/mux.rs | 12 +- zenoh/src/admin.rs | 4 +- zenoh/src/net/routing/face.rs | 7 +- zenoh/src/net/routing/pubsub.rs | 6 +- zenoh/src/net/routing/queries.rs | 4 +- zenoh/src/net/routing/resource.rs | 4 +- zenoh/src/net/runtime/adminspace.rs | 10 +- zenoh/src/net/tests/tables.rs | 10 +- zenoh/src/prelude.rs | 4 +- zenoh/src/query.rs | 4 +- zenoh/src/session.rs | 5 +- zenoh/src/subscriber.rs | 4 +- 26 files changed, 268 insertions(+), 271 deletions(-) diff --git a/commons/zenoh-codec/src/transport/join.rs b/commons/zenoh-codec/src/transport/join.rs index 6f91dea4d8..d2fdecd1ce 100644 --- a/commons/zenoh-codec/src/transport/join.rs +++ b/commons/zenoh-codec/src/transport/join.rs @@ -20,9 +20,9 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{ConduitSn, ConduitSnList, Priority, WhatAmI, ZInt, ZenohId}, + core::{Priority, WhatAmI, ZInt, ZenohId}, defaults::SEQ_NUM_RES, - transport::{tmsg, Join}, + transport::{tmsg, ConduitSn, ConduitSnList, Join}, }; impl WCodec<&Join, &mut W> for Zenoh060 diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index 446f92a5a4..239b70718e 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -23,8 +23,8 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{CongestionControl, Encoding, SampleKind, WireExpr, ZInt, ZenohId}, - zenoh::{zmsg, Data, DataInfo, ReplierInfo, ReplyContext}, + core::{CongestionControl, Encoding, WireExpr, ZInt, ZenohId}, + zenoh::{zmsg, Data, DataInfo, ReplierInfo, ReplyContext, SampleKind}, }; // ReplyContext diff --git a/commons/zenoh-codec/src/zenoh/declare.rs b/commons/zenoh-codec/src/zenoh/declare.rs index 23088ddd07..95ff17de02 100644 --- a/commons/zenoh-codec/src/zenoh/declare.rs +++ b/commons/zenoh-codec/src/zenoh/declare.rs @@ -19,10 +19,11 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{QueryableInfo, Reliability, SubInfo, SubMode, WireExpr, ZInt}, + core::{Reliability, WireExpr, ZInt}, zenoh::{ zmsg, Declaration, Declare, ForgetPublisher, ForgetQueryable, ForgetResource, - ForgetSubscriber, Publisher, Queryable, Resource, Subscriber, + ForgetSubscriber, Publisher, Queryable, QueryableInfo, Resource, SubInfo, SubMode, + Subscriber, }, }; diff --git a/commons/zenoh-codec/src/zenoh/query.rs b/commons/zenoh-codec/src/zenoh/query.rs index 543858decf..6a854fc104 100644 --- a/commons/zenoh-codec/src/zenoh/query.rs +++ b/commons/zenoh-codec/src/zenoh/query.rs @@ -20,8 +20,8 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{ConsolidationMode, QueryTarget, WireExpr, ZInt}, - zenoh::{zmsg, DataInfo, Query, QueryBody}, + core::{WireExpr, ZInt}, + zenoh::{zmsg, ConsolidationMode, DataInfo, Query, QueryBody, QueryTarget}, }; // QueryTarget diff --git a/commons/zenoh-protocol/src/core/endpoint.rs b/commons/zenoh-protocol/src/core/endpoint.rs index cc56ffb85b..84a6cb5251 100644 --- a/commons/zenoh-protocol/src/core/endpoint.rs +++ b/commons/zenoh-protocol/src/core/endpoint.rs @@ -12,7 +12,6 @@ // ZettaScale Zenoh Team, // use super::locator::*; -use crate::core::split_once; use core::{convert::TryFrom, fmt, str::FromStr}; use zenoh_core::{zerror, Error as ZError, Result as ZResult}; @@ -23,6 +22,16 @@ pub const LIST_SEPARATOR: char = ';'; pub const FIELD_SEPARATOR: char = '='; pub const CONFIG_SEPARATOR: char = '#'; +fn split_once(s: &str, c: char) -> (&str, &str) { + match s.find(c) { + Some(index) => { + let (l, r) = s.split_at(index); + (l, &r[1..]) + } + None => (s, ""), + } +} + // Parsing functions pub(super) fn protocol(s: &str) -> &str { let pdix = s.find(PROTO_SEPARATOR).unwrap_or(s.len()); diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index 737136d788..376c889256 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -36,27 +36,21 @@ pub type AtomicZInt = AtomicU64; pub type NonZeroZInt = NonZeroU64; pub const ZINT_MAX_BYTES: usize = 10; -// WhatAmI values -pub type WhatAmI = whatami::WhatAmI; - /// Constants and helpers for zenoh `whatami` flags. pub mod whatami; - -/// A numerical Id mapped to a key expression. -pub type ExprId = ZInt; - -pub const EMPTY_EXPR_ID: ExprId = 0; +pub use whatami::*; pub mod wire_expr; -pub use wire_expr::WireExpr; +pub use wire_expr::*; mod encoding; pub use encoding::{Encoding, KnownEncoding}; pub mod locator; -pub use locator::Locator; +pub use locator::*; + pub mod endpoint; -pub use endpoint::EndPoint; +pub use endpoint::*; #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -65,43 +59,6 @@ pub struct Property { pub value: Vec, } -/// The kind of a `Sample`. -#[repr(u8)] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum SampleKind { - /// if the `Sample` was issued by a `put` operation. - Put = 0, - /// if the `Sample` was issued by a `delete` operation. - Delete = 1, -} - -impl Default for SampleKind { - fn default() -> Self { - SampleKind::Put - } -} - -impl fmt::Display for SampleKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - SampleKind::Put => write!(f, "PUT"), - SampleKind::Delete => write!(f, "DELETE"), - } - } -} - -impl TryFrom for SampleKind { - type Error = ZInt; - fn try_from(kind: ZInt) -> Result { - match kind { - 0 => Ok(SampleKind::Put), - 1 => Ok(SampleKind::Delete), - _ => Err(kind), - } - } -} - /// The global unique id of a zenoh peer. #[derive(Clone, Copy, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -294,6 +251,42 @@ impl<'de> serde::Deserialize<'de> for ZenohId { } } +/// The kind of congestion control. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[repr(u8)] +pub enum CongestionControl { + Block, + Drop, +} + +impl Default for CongestionControl { + fn default() -> CongestionControl { + CongestionControl::Drop + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[repr(u8)] +pub enum Reliability { + BestEffort, + Reliable, +} + +impl Default for Reliability { + fn default() -> Reliability { + Reliability::BestEffort + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct Channel { + pub priority: Priority, + pub reliability: Reliability, +} + #[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u8)] @@ -345,160 +338,3 @@ impl TryFrom for Priority { } } } - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[repr(u8)] -pub enum Reliability { - BestEffort, - Reliable, -} - -impl Default for Reliability { - fn default() -> Reliability { - Reliability::BestEffort - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct Channel { - pub priority: Priority, - pub reliability: Reliability, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum ConduitSnList { - Plain(ConduitSn), - QoS(Box<[ConduitSn; Priority::NUM]>), -} - -impl fmt::Display for ConduitSnList { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "[ ")?; - match self { - ConduitSnList::Plain(sn) => { - write!( - f, - "{:?} {{ reliable: {}, best effort: {} }}", - Priority::default(), - sn.reliable, - sn.best_effort - )?; - } - ConduitSnList::QoS(ref sns) => { - for (prio, sn) in sns.iter().enumerate() { - let p: Priority = (prio as u8).try_into().unwrap(); - write!( - f, - "{:?} {{ reliable: {}, best effort: {} }}", - p, sn.reliable, sn.best_effort - )?; - if p != Priority::Background { - write!(f, ", ")?; - } - } - } - } - write!(f, " ]") - } -} - -/// The kind of reliability. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct ConduitSn { - pub reliable: ZInt, - pub best_effort: ZInt, -} - -/// The kind of congestion control. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[repr(u8)] -pub enum CongestionControl { - Block, - Drop, -} - -impl Default for CongestionControl { - fn default() -> CongestionControl { - CongestionControl::Drop - } -} - -/// The subscription mode. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[repr(u8)] -pub enum SubMode { - Push, - Pull, -} - -impl Default for SubMode { - #[inline] - fn default() -> Self { - SubMode::Push - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Default)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct SubInfo { - pub reliability: Reliability, - pub mode: SubMode, -} - -#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct QueryableInfo { - pub complete: ZInt, // Default 0: incomplete - pub distance: ZInt, // Default 0: no distance -} - -/// The kind of consolidation. -#[derive(Debug, Clone, PartialEq, Eq, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum ConsolidationMode { - /// No consolidation applied: multiple samples may be received for the same key-timestamp. - None, - /// Monotonic consolidation immediately forwards samples, except if one with an equal or more recent timestamp - /// has already been sent with the same key. - /// - /// This optimizes latency while potentially reducing bandwidth. - /// - /// Note that this doesn't cause re-ordering, but drops the samples for which a more recent timestamp has already - /// been observed with the same key. - Monotonic, - /// Holds back samples to only send the set of samples that had the highest timestamp for their key. - Latest, -} - -/// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum QueryTarget { - BestMatching, - All, - AllComplete, - #[cfg(feature = "complete_n")] - Complete(ZInt), -} - -impl Default for QueryTarget { - fn default() -> Self { - QueryTarget::BestMatching - } -} - -pub(crate) fn split_once(s: &str, c: char) -> (&str, &str) { - match s.find(c) { - Some(index) => { - let (l, r) = s.split_at(index); - (l, &r[1..]) - } - None => (s, ""), - } -} diff --git a/commons/zenoh-protocol/src/core/wire_expr.rs b/commons/zenoh-protocol/src/core/wire_expr.rs index c8024bd0b0..9f90251f94 100644 --- a/commons/zenoh-protocol/src/core/wire_expr.rs +++ b/commons/zenoh-protocol/src/core/wire_expr.rs @@ -13,13 +13,17 @@ // //! This module defines the wire representation of Key Expressions. -use crate::core::ExprId; +use crate::core::ZInt; use alloc::borrow::Cow; use core::{convert::TryInto, fmt}; use zenoh_core::{bail, Result as ZResult}; +/// A numerical Id mapped to a key expression. +pub type ExprId = ZInt; +pub const EMPTY_EXPR_ID: ExprId = 0; + /// A zenoh **resource** is represented by a pair composed by a **key** and a -/// **value**, such as, ```(/car/telemetry/speed, 320)```. A **resource key** +/// **value**, such as, ```(car/telemetry/speed, 320)```. A **resource key** /// is an arbitrary array of characters, with the exclusion of the symbols /// ```*```, ```**```, ```?```, ```[```, ```]```, and ```#```, /// which have special meaning in the context of zenoh. diff --git a/commons/zenoh-protocol/src/transport/join.rs b/commons/zenoh-protocol/src/transport/join.rs index 522f1f2a6e..9c9ac701a2 100644 --- a/commons/zenoh-protocol/src/transport/join.rs +++ b/commons/zenoh-protocol/src/transport/join.rs @@ -11,7 +11,10 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{ConduitSnList, WhatAmI, ZInt, ZenohId}; +use crate::{ + core::{WhatAmI, ZInt, ZenohId}, + transport::ConduitSnList, +}; use core::time::Duration; /// # Join message @@ -75,7 +78,7 @@ impl Join { impl Join { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::{ConduitSn, Priority}; + use crate::{core::Priority, transport::ConduitSn}; use rand::Rng; let mut rng = rand::thread_rng(); diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index fcb0c3d17a..7a8e14e4c2 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -20,10 +20,10 @@ mod open; use crate::{ common::Attachment, - core::{Channel, ConduitSnList, WhatAmI, ZInt, ZenohId}, + core::{Channel, Priority, WhatAmI, ZInt, ZenohId}, }; pub use close::*; -use core::time::Duration; +use core::{convert::TryInto, fmt, time::Duration}; pub use frame::*; pub use init::*; pub use join::*; @@ -31,9 +31,55 @@ pub use keepalive::*; pub use open::*; use zenoh_buffers::ZSlice; +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ConduitSnList { + Plain(ConduitSn), + QoS(Box<[ConduitSn; Priority::NUM]>), +} + +impl fmt::Display for ConduitSnList { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "[ ")?; + match self { + ConduitSnList::Plain(sn) => { + write!( + f, + "{:?} {{ reliable: {}, best effort: {} }}", + Priority::default(), + sn.reliable, + sn.best_effort + )?; + } + ConduitSnList::QoS(ref sns) => { + for (prio, sn) in sns.iter().enumerate() { + let p: Priority = (prio as u8).try_into().unwrap(); + write!( + f, + "{:?} {{ reliable: {}, best effort: {} }}", + p, sn.reliable, sn.best_effort + )?; + if p != Priority::Background { + write!(f, ", ")?; + } + } + } + } + write!(f, " ]") + } +} + +/// The kind of reliability. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct ConduitSn { + pub reliable: ZInt, + pub best_effort: ZInt, +} + pub mod tmsg { - use crate::common::imsg; - use crate::core::{Priority, ZInt}; + use super::Priority; + use crate::{common::imsg, core::ZInt}; // Transport message IDs -- Re-export of some of the Inner Message IDs pub mod id { diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs index b687272001..57914bd6f4 100644 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ b/commons/zenoh-protocol/src/zenoh/data.rs @@ -11,9 +11,47 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{CongestionControl, Encoding, SampleKind, Timestamp, WireExpr, ZInt, ZenohId}; +use crate::core::{CongestionControl, Encoding, Timestamp, WireExpr, ZInt, ZenohId}; +use core::{convert::TryFrom, fmt}; use zenoh_buffers::ZBuf; +/// The kind of a `Sample`. +#[repr(u8)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum SampleKind { + /// if the `Sample` was issued by a `put` operation. + Put = 0, + /// if the `Sample` was issued by a `delete` operation. + Delete = 1, +} + +impl Default for SampleKind { + fn default() -> Self { + SampleKind::Put + } +} + +impl fmt::Display for SampleKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + SampleKind::Put => write!(f, "PUT"), + SampleKind::Delete => write!(f, "DELETE"), + } + } +} + +impl TryFrom for SampleKind { + type Error = ZInt; + fn try_from(kind: ZInt) -> Result { + match kind { + 0 => Ok(SampleKind::Put), + 1 => Ok(SampleKind::Delete), + _ => Err(kind), + } + } +} + /// # ReplyContext decorator /// /// ```text @@ -128,7 +166,6 @@ pub struct DataInfo { impl DataInfo { #[cfg(feature = "test")] pub fn rand() -> Self { - use core::convert::TryFrom; use rand::Rng; let mut rng = rand::thread_rng(); diff --git a/commons/zenoh-protocol/src/zenoh/declare.rs b/commons/zenoh-protocol/src/zenoh/declare.rs index ee9ce159f5..2131c24933 100644 --- a/commons/zenoh-protocol/src/zenoh/declare.rs +++ b/commons/zenoh-protocol/src/zenoh/declare.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{QueryableInfo, SubInfo, WireExpr, ZInt}; +use crate::core::{Reliability, WireExpr, ZInt}; /// ```text /// 7 6 5 4 3 2 1 0 @@ -183,6 +183,29 @@ impl ForgetPublisher { } } +/// The subscription mode. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[repr(u8)] +pub enum SubMode { + Push, + Pull, +} + +impl Default for SubMode { + #[inline] + fn default() -> Self { + SubMode::Push + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct SubInfo { + pub reliability: Reliability, + pub mode: SubMode, +} + /// ```text /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ @@ -203,7 +226,6 @@ pub struct Subscriber { impl Subscriber { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::{Reliability, SubMode}; use rand::Rng; let mut rng = rand::thread_rng(); @@ -248,6 +270,13 @@ impl ForgetSubscriber { } } +#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct QueryableInfo { + pub complete: ZInt, // Default 0: incomplete + pub distance: ZInt, // Default 0: no distance +} + /// ```text /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index 43e47cb010..78f2ffa224 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -21,9 +21,7 @@ mod unit; use crate::{ common::Attachment, - core::{ - Channel, CongestionControl, ConsolidationMode, QueryTarget, Reliability, WireExpr, ZInt, - }, + core::{Channel, CongestionControl, Reliability, WireExpr, ZInt}, }; use core::fmt; pub use data::*; diff --git a/commons/zenoh-protocol/src/zenoh/query.rs b/commons/zenoh-protocol/src/zenoh/query.rs index 01a3056cad..d144e8b69c 100644 --- a/commons/zenoh-protocol/src/zenoh/query.rs +++ b/commons/zenoh-protocol/src/zenoh/query.rs @@ -12,11 +12,46 @@ // ZettaScale Zenoh Team, // use crate::{ - core::{ConsolidationMode, QueryTarget, WireExpr, ZInt}, + core::{WireExpr, ZInt}, zenoh::DataInfo, }; use zenoh_buffers::ZBuf; +/// The kind of consolidation. +#[derive(Debug, Clone, PartialEq, Eq, Copy)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ConsolidationMode { + /// No consolidation applied: multiple samples may be received for the same key-timestamp. + None, + /// Monotonic consolidation immediately forwards samples, except if one with an equal or more recent timestamp + /// has already been sent with the same key. + /// + /// This optimizes latency while potentially reducing bandwidth. + /// + /// Note that this doesn't cause re-ordering, but drops the samples for which a more recent timestamp has already + /// been observed with the same key. + Monotonic, + /// Holds back samples to only send the set of samples that had the highest timestamp for their key. + Latest, +} + +/// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum QueryTarget { + BestMatching, + All, + AllComplete, + #[cfg(feature = "complete_n")] + Complete(ZInt), +} + +impl Default for QueryTarget { + fn default() -> Self { + QueryTarget::BestMatching + } +} + /// # QueryBody /// /// QueryBody data structure is optionally included in Query messages diff --git a/io/zenoh-transport/src/primitives/mod.rs b/io/zenoh-transport/src/primitives/mod.rs index 44e0d7423d..cb8866134d 100644 --- a/io/zenoh-transport/src/primitives/mod.rs +++ b/io/zenoh-transport/src/primitives/mod.rs @@ -18,11 +18,10 @@ pub use demux::*; pub use mux::*; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{ - Channel, CongestionControl, ConsolidationMode, QueryTarget, QueryableInfo, SubInfo, - WireExpr, ZInt, ZenohId, + core::{Channel, CongestionControl, WireExpr, ZInt, ZenohId}, + zenoh::{ + ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo, }, - zenoh::{DataInfo, QueryBody, RoutingContext}, }; pub trait Primitives: Send + Sync { diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index 351ce05b0d..107a83ca75 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -15,14 +15,12 @@ use super::super::TransportUnicast; use super::Primitives; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{ - Channel, CongestionControl, ConsolidationMode, QueryTarget, QueryableInfo, SubInfo, - WireExpr, ZInt, ZenohId, - }, + core::{Channel, CongestionControl, WireExpr, ZInt, ZenohId}, zenoh::{ - zmsg, DataInfo, Declaration, ForgetPublisher, ForgetQueryable, ForgetResource, - ForgetSubscriber, Publisher, QueryBody, Queryable, ReplierInfo, ReplyContext, Resource, - RoutingContext, Subscriber, ZenohMessage, + zmsg, ConsolidationMode, DataInfo, Declaration, ForgetPublisher, ForgetQueryable, + ForgetResource, ForgetSubscriber, Publisher, QueryBody, QueryTarget, Queryable, + QueryableInfo, ReplierInfo, ReplyContext, Resource, RoutingContext, SubInfo, Subscriber, + ZenohMessage, }, }; diff --git a/zenoh/src/admin.rs b/zenoh/src/admin.rs index a10af7b5d2..5d1f6c95c0 100644 --- a/zenoh/src/admin.rs +++ b/zenoh/src/admin.rs @@ -25,8 +25,8 @@ use crate::{ }; use zenoh_core::SyncResolve; use zenoh_protocol::{ - core::{Encoding, KnownEncoding, SampleKind, WireExpr}, - zenoh::{DataInfo, ZenohMessage}, + core::{Encoding, KnownEncoding, WireExpr}, + zenoh::{DataInfo, SampleKind, ZenohMessage}, }; use zenoh_transport::{TransportEventHandler, TransportPeerEventHandler}; diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index 5409639cde..1e323c04cc 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -18,11 +18,10 @@ use std::sync::Arc; use std::sync::RwLock; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{ - Channel, CongestionControl, ConsolidationMode, QueryTarget, QueryableInfo, SubInfo, - WhatAmI, WireExpr, ZInt, ZenohId, + core::{Channel, CongestionControl, WhatAmI, WireExpr, ZInt, ZenohId}, + zenoh::{ + ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo, }, - zenoh::{DataInfo, QueryBody, RoutingContext}, }; use zenoh_transport::Primitives; diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index 2d7503ec33..786e7aabf5 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -25,10 +25,10 @@ use zenoh_buffers::ZBuf; use zenoh_core::zread; use zenoh_protocol::{ core::{ - key_expr::OwnedKeyExpr, Channel, CongestionControl, Priority, Reliability, SubInfo, - SubMode, WhatAmI, WireExpr, ZInt, ZenohId, + key_expr::OwnedKeyExpr, Channel, CongestionControl, Priority, Reliability, WhatAmI, + WireExpr, ZInt, ZenohId, }, - zenoh::{DataInfo, RoutingContext}, + zenoh::{DataInfo, RoutingContext, SubInfo, SubMode}, }; use zenoh_sync::get_mut_unchecked; diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 5cb66bb9b4..16f2584a32 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -30,9 +30,9 @@ use zenoh_buffers::ZBuf; use zenoh_protocol::{ core::{ key_expr::include::{Includer, DEFAULT_INCLUDER}, - ConsolidationMode, QueryTarget, QueryableInfo, WhatAmI, WireExpr, ZInt, ZenohId, + WhatAmI, WireExpr, ZInt, ZenohId, }, - zenoh::{DataInfo, QueryBody, RoutingContext}, + zenoh::{ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext}, }; use zenoh_sync::get_mut_unchecked; use zenoh_util::Timed; diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index 993d96f3c2..58950f3651 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -20,8 +20,8 @@ use std::hash::{Hash, Hasher}; use std::sync::{Arc, Weak}; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{key_expr::keyexpr, QueryableInfo, SubInfo, WireExpr, ZInt, ZenohId}, - zenoh::{DataInfo, RoutingContext}, + core::{key_expr::keyexpr, WireExpr, ZInt, ZenohId}, + zenoh::{DataInfo, QueryableInfo, RoutingContext, SubInfo}, }; use zenoh_sync::get_mut_unchecked; diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 66a371f3f4..cc043fdb10 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -28,11 +28,13 @@ use zenoh_config::WhatAmI; use zenoh_core::Result as ZResult; use zenoh_protocol::{ core::{ - key_expr::OwnedKeyExpr, Channel, CongestionControl, ConsolidationMode, Encoding, - KnownEncoding, QueryTarget, QueryableInfo, SampleKind, SubInfo, WireExpr, ZInt, ZenohId, - EMPTY_EXPR_ID, + key_expr::OwnedKeyExpr, Channel, CongestionControl, Encoding, KnownEncoding, WireExpr, + ZInt, ZenohId, EMPTY_EXPR_ID, + }, + zenoh::{ + ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, + SampleKind, SubInfo, }, - zenoh::{DataInfo, QueryBody, RoutingContext}, }; use zenoh_transport::{Primitives, TransportUnicast}; diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index 1ca396cfa1..ab62fbba87 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -21,11 +21,13 @@ use zenoh_config::ZN_QUERIES_DEFAULT_TIMEOUT_DEFAULT; use zenoh_core::zlock; use zenoh_protocol::{ core::{ - key_expr::keyexpr, Channel, CongestionControl, ConsolidationMode, QueryTarget, - QueryableInfo, Reliability, SubInfo, SubMode, WhatAmI, WireExpr, ZInt, ZenohId, - EMPTY_EXPR_ID, + key_expr::keyexpr, Channel, CongestionControl, Reliability, WhatAmI, WireExpr, ZInt, + ZenohId, EMPTY_EXPR_ID, + }, + zenoh::{ + ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, + SubInfo, SubMode, }, - zenoh::{DataInfo, QueryBody, RoutingContext}, }; use zenoh_transport::{DummyPrimitives, Primitives}; diff --git a/zenoh/src/prelude.rs b/zenoh/src/prelude.rs index b30f64b39d..dc6decff43 100644 --- a/zenoh/src/prelude.rs +++ b/zenoh/src/prelude.rs @@ -47,10 +47,10 @@ pub(crate) mod common { pub(crate) use crate::sample::Locality; pub use crate::sample::Sample; - pub use zenoh_protocol::core::SampleKind; + pub use zenoh_protocol::zenoh::{ConsolidationMode, SampleKind}; pub use crate::publication::Priority; - pub use zenoh_protocol::core::{CongestionControl, ConsolidationMode, Reliability}; + pub use zenoh_protocol::core::{CongestionControl, Reliability}; /// A [`Locator`] contains a choice of protocol, an address and port, as well as optional additional properties to work with. pub use zenoh_protocol::core::Locator; diff --git a/zenoh/src/query.rs b/zenoh/src/query.rs index 78a3f2b451..6ad6f46b21 100644 --- a/zenoh/src/query.rs +++ b/zenoh/src/query.rs @@ -24,10 +24,10 @@ use zenoh_core::zresult::ZResult; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; /// The [`Queryable`](crate::queryable::Queryable)s that should be target of a [`get`](Session::get). -pub use zenoh_protocol::core::QueryTarget; +pub use zenoh_protocol::zenoh::QueryTarget; /// The kind of consolidation. -pub use zenoh_protocol::core::ConsolidationMode; +pub use zenoh_protocol::zenoh::ConsolidationMode; /// The operation: either manual or automatic. #[derive(Clone, Copy, Debug, PartialEq, Eq)] diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 892935fa79..a2af191c50 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -56,10 +56,9 @@ use zenoh_core::{ use zenoh_protocol::{ core::{ key_expr::{keyexpr, OwnedKeyExpr}, - AtomicZInt, Channel, CongestionControl, ExprId, QueryTarget, QueryableInfo, SubInfo, - WireExpr, ZInt, ZenohId, EMPTY_EXPR_ID, + AtomicZInt, Channel, CongestionControl, ExprId, WireExpr, ZInt, ZenohId, EMPTY_EXPR_ID, }, - zenoh::{DataInfo, QueryBody, RoutingContext}, + zenoh::{DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo}, }; use zenoh_util::core::AsyncResolve; diff --git a/zenoh/src/subscriber.rs b/zenoh/src/subscriber.rs index 7156454a03..bb4c44623e 100644 --- a/zenoh/src/subscriber.rs +++ b/zenoh/src/subscriber.rs @@ -23,10 +23,10 @@ use std::future::Ready; use std::ops::{Deref, DerefMut}; use std::sync::Arc; use zenoh_core::{AsyncResolve, Resolvable, Resolve, SyncResolve}; -use zenoh_protocol::core::SubInfo; +use zenoh_protocol::zenoh::SubInfo; /// The subscription mode. -pub use zenoh_protocol::core::SubMode; +pub use zenoh_protocol::zenoh::SubMode; /// The kind of reliability. pub use zenoh_protocol::core::Reliability; From a99843b9da8f22a75e702eeb484b6c056a497a32 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 18 Jan 2023 14:53:13 +0100 Subject: [PATCH 002/203] Fix wrong imports --- io/zenoh-transport/src/common/conduit.rs | 5 ++++- io/zenoh-transport/src/multicast/establishment.rs | 5 ++++- io/zenoh-transport/src/multicast/link.rs | 12 +++++++----- io/zenoh-transport/src/multicast/transport.rs | 4 ++-- io/zenoh-transport/src/unicast/transport.rs | 4 ++-- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/io/zenoh-transport/src/common/conduit.rs b/io/zenoh-transport/src/common/conduit.rs index a91d93c4e6..77a76da70e 100644 --- a/io/zenoh-transport/src/common/conduit.rs +++ b/io/zenoh-transport/src/common/conduit.rs @@ -16,7 +16,10 @@ use super::seq_num::{SeqNum, SeqNumGenerator}; use std::sync::{Arc, Mutex}; use zenoh_core::zlock; use zenoh_core::zresult::ZResult; -use zenoh_protocol::core::{ConduitSn, Reliability, ZInt}; +use zenoh_protocol::{ + core::{Reliability, ZInt}, + transport::ConduitSn, +}; #[derive(Debug)] pub(crate) struct TransportChannelTx { diff --git a/io/zenoh-transport/src/multicast/establishment.rs b/io/zenoh-transport/src/multicast/establishment.rs index 88e5153493..b8c1c1c0ef 100644 --- a/io/zenoh-transport/src/multicast/establishment.rs +++ b/io/zenoh-transport/src/multicast/establishment.rs @@ -18,7 +18,10 @@ use std::sync::Arc; use zenoh_core::Result as ZResult; use zenoh_core::{zasynclock, zlock}; use zenoh_link::LinkMulticast; -use zenoh_protocol::core::{ConduitSn, ConduitSnList, Priority}; +use zenoh_protocol::{ + core::Priority, + transport::{ConduitSn, ConduitSnList}, +}; pub(crate) async fn open_link( manager: &TransportManager, diff --git a/io/zenoh-transport/src/multicast/link.rs b/io/zenoh-transport/src/multicast/link.rs index 542982ad2a..680dc2b7a7 100644 --- a/io/zenoh-transport/src/multicast/link.rs +++ b/io/zenoh-transport/src/multicast/link.rs @@ -22,16 +22,18 @@ use crate::common::pipeline::{ use async_std::prelude::FutureExt; use async_std::task; use async_std::task::JoinHandle; -use std::convert::TryInto; -use std::sync::Arc; -use std::time::{Duration, Instant}; +use std::{ + convert::TryInto, + sync::Arc, + time::{Duration, Instant}, +}; use zenoh_buffers::reader::{HasReader, Reader}; use zenoh_codec::{RCodec, Zenoh060}; use zenoh_core::{bail, zerror, zlock, Result as ZResult}; use zenoh_link::{LinkMulticast, Locator}; use zenoh_protocol::{ - core::{ConduitSn, ConduitSnList, Priority, WhatAmI, ZInt, ZenohId}, - transport::TransportMessage, + core::{Priority, WhatAmI, ZInt, ZenohId}, + transport::{ConduitSn, ConduitSnList, TransportMessage}, }; use zenoh_sync::RecyclingObjectPool; use zenoh_sync::Signal; diff --git a/io/zenoh-transport/src/multicast/transport.rs b/io/zenoh-transport/src/multicast/transport.rs index 1b0bd078dd..7016bbdb7b 100644 --- a/io/zenoh-transport/src/multicast/transport.rs +++ b/io/zenoh-transport/src/multicast/transport.rs @@ -30,8 +30,8 @@ use std::{ use zenoh_core::{bail, zread, zwrite, Result as ZResult}; use zenoh_link::{Link, LinkMulticast, Locator}; use zenoh_protocol::{ - core::{ConduitSnList, Priority, WhatAmI, ZInt, ZenohId}, - transport::{tmsg, Join, TransportMessage}, + core::{Priority, WhatAmI, ZInt, ZenohId}, + transport::{tmsg, ConduitSnList, Join, TransportMessage}, zenoh::ZenohMessage, }; use zenoh_util::{Timed, TimedEvent, TimedHandle, Timer}; diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index d25ec94550..cbdd421a8c 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -22,8 +22,8 @@ use std::time::Duration; use zenoh_core::{bail, zasynclock, zerror, zread, zwrite, Result as ZResult}; use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ - core::{ConduitSn, Priority, WhatAmI, ZInt, ZenohId}, - transport::TransportMessage, + core::{Priority, WhatAmI, ZInt, ZenohId}, + transport::{ConduitSn, TransportMessage}, zenoh::ZenohMessage, }; From 9d808dc27e67cada5ac1a15436ee600d6e067774 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 19 Jan 2023 20:36:55 +0100 Subject: [PATCH 003/203] Adding extensions. Missing tests. --- commons/zenoh-codec/src/common/extension.rs | 188 ++++++++++++++++++ commons/zenoh-codec/src/common/mod.rs | 1 + .../zenoh-protocol/src/common/extension.rs | 107 ++++++++++ commons/zenoh-protocol/src/common/mod.rs | 10 +- commons/zenoh-protocol/src/lib.rs | 76 +++++++ 5 files changed, 378 insertions(+), 4 deletions(-) create mode 100644 commons/zenoh-codec/src/common/extension.rs create mode 100644 commons/zenoh-protocol/src/common/extension.rs diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs new file mode 100644 index 0000000000..f953e3d460 --- /dev/null +++ b/commons/zenoh-codec/src/common/extension.rs @@ -0,0 +1,188 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh060, Zenoh060Condition}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, + ZBuf, +}; +use zenoh_protocol::{ + common::{iext, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtZInt, ZExtensionBody}, + core::ZInt, +}; + +impl WCodec<&ZExtUnit<{ ID }>, &mut W> for Zenoh060Condition +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, _x: &ZExtUnit<{ ID }>) -> Self::Output { + let mut header: u8 = ID | iext::ENC_UNIT; + if self.condition { + header |= iext::FLAG_Z; + } + self.codec.write(&mut *writer, header)?; + Ok(()) + } +} + +impl RCodec, &mut R> for Zenoh060 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result, Self::Error> { + let header: u8 = self.read(&mut *reader)?; + + if (header & iext::ID_MASK != ID) || (header & iext::ENC_MASK != iext::ENC_UNIT) { + return Err(DidntRead); + } + + Ok(ZExtUnit::new()) + } +} + +impl WCodec<&ZExtZInt<{ ID }>, &mut W> for Zenoh060Condition +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ZExtZInt<{ ID }>) -> Self::Output { + let mut header: u8 = ID | iext::ENC_ZINT; + if self.condition { + header |= iext::FLAG_Z; + } + self.codec.write(&mut *writer, header)?; + self.codec.write(&mut *writer, x.value)?; + Ok(()) + } +} + +impl RCodec, &mut R> for Zenoh060 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result, Self::Error> { + let header: u8 = self.read(&mut *reader)?; + + if (header & iext::ID_MASK != ID) || (header & iext::ENC_MASK != iext::ENC_ZINT) { + return Err(DidntRead); + } + + let value: ZInt = self.read(&mut *reader)?; + + Ok(ZExtZInt::new(value)) + } +} + +impl WCodec<&ZExtZBuf<{ ID }>, &mut W> for Zenoh060Condition +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ZExtZBuf<{ ID }>) -> Self::Output { + let mut header: u8 = ID | iext::ENC_ZINT; + if self.condition { + header |= iext::FLAG_Z; + } + self.codec.write(&mut *writer, header)?; + self.codec.write(&mut *writer, &x.value)?; + Ok(()) + } +} + +impl RCodec, &mut R> for Zenoh060 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result, Self::Error> { + let header: u8 = self.read(&mut *reader)?; + + if (header & iext::ID_MASK != ID) || (header & iext::ENC_MASK != iext::ENC_ZINT) { + return Err(DidntRead); + } + + let value: ZBuf = self.read(&mut *reader)?; + + Ok(ZExtZBuf::new(value)) + } +} + +impl WCodec<&ZExtUnknown, &mut W> for Zenoh060Condition +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ZExtUnknown) -> Self::Output { + let mut header: u8 = x.id; + if self.condition { + header |= iext::FLAG_Z; + } + match &x.body { + ZExtensionBody::Unit => { + header |= iext::ENC_UNIT; + self.codec.write(&mut *writer, header)? + } + ZExtensionBody::ZInt(zint) => { + header |= iext::ENC_ZINT; + self.codec.write(&mut *writer, header)?; + self.codec.write(&mut *writer, zint)? + } + ZExtensionBody::ZBuf(zbuf) => { + header |= iext::ENC_ZBUF; + self.codec.write(&mut *writer, header)?; + self.codec.write(&mut *writer, zbuf)? + } + } + Ok(()) + } +} + +impl RCodec for Zenoh060 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + + let body = match header & iext::ENC_MASK { + iext::ENC_UNIT => ZExtensionBody::Unit, + iext::ENC_ZINT => { + let zint: ZInt = self.read(&mut *reader)?; + ZExtensionBody::ZInt(zint) + } + iext::ENC_ZBUF => { + let zbuf: ZBuf = self.read(&mut *reader)?; + ZExtensionBody::ZBuf(zbuf) + } + _ => return Err(DidntRead), + }; + + Ok(ZExtUnknown { + id: header & iext::ID_MASK, + body, + }) + } +} diff --git a/commons/zenoh-codec/src/common/mod.rs b/commons/zenoh-codec/src/common/mod.rs index d3a6051bb2..f51eef0674 100644 --- a/commons/zenoh-codec/src/common/mod.rs +++ b/commons/zenoh-codec/src/common/mod.rs @@ -13,3 +13,4 @@ // mod attachment; mod priority; +mod extension; diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs new file mode 100644 index 0000000000..aa617aba26 --- /dev/null +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -0,0 +1,107 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::core::ZInt; +use zenoh_buffers::ZBuf; + +/// # Zenoh extensions +/// +/// A zenoh extension is encoded as TLV (Type, Length, Value). +/// Zenoh extensions with unknown IDs (i.e., type) can be skipped by reading the length and +/// not decoding the body (i.e. value). In case the zenoh extension is unknown, it is +/// still possible to forward it to the next hops, which in turn may be able to understand it. +/// This results in the capability of introducing new extensions in an already running system +/// without requiring the redeployment of the totality of infrastructure nodes. +/// +/// The zenoh extension wire format is the following: +/// +/// ```text +/// Header flags: +/// - X: Reserved +/// - F: Forward If F==1 then the extension needs to be forwarded. (*) +/// - Z: More If Z==1 then another extension will follow. +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|ENC| ID | +/// +-+-+-+---------+ +/// % length % -- If ENC == ZInt || ENC == ZBuf +/// +---------------+ +/// ~ [u8] ~ -- If ENC == ZBuf +/// +---------------+ +/// ``` +/// +/// Encoding: +/// - 0b00: Unit +/// - 0b01: ZInt +/// - 0b10: ZBuf +/// - 0b11: Reserved +/// +/// (*) If the zenoh extension is not understood, then it SHOULD NOT be dropped and it +/// SHOULD be forwarded to the next hops. +/// +pub mod iext { + pub const ID_BITS: u8 = 5; + pub const ID_MASK: u8 = !(u8::MAX << ID_BITS); + + pub const ENC_UNIT: u8 = 0b00 << ID_BITS; + pub const ENC_ZINT: u8 = 0b01 << ID_BITS; + pub const ENC_ZBUF: u8 = 0b10 << ID_BITS; + pub const ENC_MASK: u8 = 0b11 << ID_BITS; + + pub const FLAG_Z: u8 = 1 << 7; +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ZExtUnit; + +impl ZExtUnit<{ ID }> { + pub fn new() -> Self { + Self + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ZExtZInt { + pub value: ZInt, +} + +impl ZExtZInt<{ ID }> { + pub fn new(value: ZInt) -> Self { + Self { value } + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ZExtZBuf { + pub value: ZBuf, +} + +impl ZExtZBuf<{ ID }> { + pub fn new(value: ZBuf) -> Self { + Self { value } + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ZExtUnknown { + pub id: u8, + pub body: ZExtensionBody, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum ZExtensionBody { + Unit, + ZInt(ZInt), + ZBuf(ZBuf), +} diff --git a/commons/zenoh-protocol/src/common/mod.rs b/commons/zenoh-protocol/src/common/mod.rs index 41487e59fa..c4eff8a27d 100644 --- a/commons/zenoh-protocol/src/common/mod.rs +++ b/commons/zenoh-protocol/src/common/mod.rs @@ -13,6 +13,8 @@ // pub mod attachment; pub use attachment::*; +pub mod extension; +pub use extension::*; /*************************************/ /* IDS */ @@ -54,19 +56,19 @@ pub mod imsg { pub const HEADER_BITS: u8 = 5; pub const HEADER_MASK: u8 = !(0xff << HEADER_BITS); - pub fn mid(header: u8) -> u8 { + pub const fn mid(header: u8) -> u8 { header & HEADER_MASK } - pub fn flags(header: u8) -> u8 { + pub const fn flags(header: u8) -> u8 { header & !HEADER_MASK } - pub fn has_flag(byte: u8, flag: u8) -> bool { + pub const fn has_flag(byte: u8, flag: u8) -> bool { byte & flag != 0 } - pub fn has_option(options: ZInt, flag: ZInt) -> bool { + pub const fn has_option(options: ZInt, flag: ZInt) -> bool { options & flag != 0 } } diff --git a/commons/zenoh-protocol/src/lib.rs b/commons/zenoh-protocol/src/lib.rs index 9235c875bf..450508843d 100644 --- a/commons/zenoh-protocol/src/lib.rs +++ b/commons/zenoh-protocol/src/lib.rs @@ -26,3 +26,79 @@ pub mod defaults; pub mod scouting; pub mod transport; pub mod zenoh; + +// Zenoh protocol uses the following conventions for message definition and representation. +// +// +// # Single byte field +// +// A fixed size field of 8 bits. +// +// ```text +// 7 6 5 4 3 2 1 0 +// +-+-+-+-+-+-+-+-+ +// | u8 | +// +---------------+ +// ``` +// +// +// # Variable length field +// +// The field size depends on the element definition and/or actual encoding. An example of variable +// lenght element is an array of bytes (e.g., a payload or a string). +// +// ```text +// 7 6 5 4 3 2 1 0 +// +-+-+-+-+-+-+-+-+ +// ~ element ~ +// +---------------+ +// ``` +// +// +// # ZInt field +// +// A ZInt is a specialized variable lenght field that is used to encode an unsigned integer. +// +// ```text +// 7 6 5 4 3 2 1 0 +// +-+-+-+-+-+-+-+-+ +// % zint % +// +---------------+ +// ``` +// +// +// # Array field +// +// An array contains a fixed number of elements whose number is known a priori or indicated by +// another field. Each element can be either a single byte field or a variable legnth field. +// +// ```text +// 7 6 5 4 3 2 1 0 +// +-+-+-+-+-+-+-+-+ +// ~ [element] ~ +// +---------------+ +// ``` +// +// +// # Vector field +// +// A vector contains a variable number of elements and is represented as follows: +// +// ```text +// 7 6 5 4 3 2 1 0 +// +-+-+-+-+-+-+-+-+ +// ~ ~ +// +---------------+ +// ``` +// +// A vector field is always expanded as follows: +// +// ```text +// 7 6 5 4 3 2 1 0 +// +-+-+-+-+-+-+-+-+ +// % num % +// +---------------+ +// ~ [element] ~ +// +---------------+ +// ``` +// From 8e5472bacae34de5f5e967bb7cbe4199a32317ec Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 20 Jan 2023 17:48:32 +0100 Subject: [PATCH 004/203] Extensions codec test --- Cargo.lock | 9 +- Cargo.toml | 2 +- commons/zenoh-codec/src/common/extension.rs | 85 ++++++++++--------- commons/zenoh-codec/tests/codec.rs | 31 +++++++ .../zenoh-protocol/src/common/extension.rs | 44 +++++++++- 5 files changed, 125 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71149ab5be..c126013226 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2466,9 +2466,9 @@ checksum = "56770675ebc04927ded3e60633437841581c285dc6236109ea25fbf3beb7b59e" [[package]] name = "rsa" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" +checksum = "b5f00ae0c56ed2d34b86fc8f1c02e809dd455382de72e1dd08f7d1ced356bf59" dependencies = [ "byteorder", "digest 0.10.6", @@ -2480,7 +2480,6 @@ dependencies = [ "pkcs8", "rand_core 0.6.4", "signature", - "smallvec", "subtle", "zeroize", ] @@ -2841,9 +2840,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" dependencies = [ "digest 0.10.6", "rand_core 0.6.4", diff --git a/Cargo.toml b/Cargo.toml index 943a56120f..72af05315c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ rand_chacha = "0.3.1" rcgen = "0.10.0" regex = "1.7.0" ringbuffer-spsc = "0.1.8" -rsa = "0.7.2" +rsa = "0.8.0" rustc_version = "0.4.0" rustls = "0.20.6" rustls-native-certs = "0.6.2" diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index f953e3d460..31c44e642f 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -11,74 +11,76 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Condition}; +use crate::{RCodec, WCodec, Zenoh060}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, ZBuf, }; use zenoh_protocol::{ - common::{iext, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtZInt, ZExtensionBody}, + common::{iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtZInt, ZExtensionBody}, core::ZInt, }; -impl WCodec<&ZExtUnit<{ ID }>, &mut W> for Zenoh060Condition +impl WCodec<(&ZExtUnit<{ ID }>, bool), &mut W> for Zenoh060 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, _x: &ZExtUnit<{ ID }>) -> Self::Output { + fn write(self, writer: &mut W, x: (&ZExtUnit<{ ID }>, bool)) -> Self::Output { + let (_x, more) = x; let mut header: u8 = ID | iext::ENC_UNIT; - if self.condition { + if more { header |= iext::FLAG_Z; } - self.codec.write(&mut *writer, header)?; + self.write(&mut *writer, header)?; Ok(()) } } -impl RCodec, &mut R> for Zenoh060 +impl RCodec<(ZExtUnit<{ ID }>, bool), &mut R> for Zenoh060 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result, Self::Error> { + fn read(self, reader: &mut R) -> Result<(ZExtUnit<{ ID }>, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; if (header & iext::ID_MASK != ID) || (header & iext::ENC_MASK != iext::ENC_UNIT) { return Err(DidntRead); } - Ok(ZExtUnit::new()) + Ok((ZExtUnit::new(), has_flag(header, iext::FLAG_Z))) } } -impl WCodec<&ZExtZInt<{ ID }>, &mut W> for Zenoh060Condition +impl WCodec<(&ZExtZInt<{ ID }>, bool), &mut W> for Zenoh060 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &ZExtZInt<{ ID }>) -> Self::Output { + fn write(self, writer: &mut W, x: (&ZExtZInt<{ ID }>, bool)) -> Self::Output { + let (x, more) = x; let mut header: u8 = ID | iext::ENC_ZINT; - if self.condition { + if more { header |= iext::FLAG_Z; } - self.codec.write(&mut *writer, header)?; - self.codec.write(&mut *writer, x.value)?; + self.write(&mut *writer, header)?; + self.write(&mut *writer, x.value)?; Ok(()) } } -impl RCodec, &mut R> for Zenoh060 +impl RCodec<(ZExtZInt<{ ID }>, bool), &mut R> for Zenoh060 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result, Self::Error> { + fn read(self, reader: &mut R) -> Result<(ZExtZInt<{ ID }>, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; if (header & iext::ID_MASK != ID) || (header & iext::ENC_MASK != iext::ENC_ZINT) { @@ -87,34 +89,35 @@ where let value: ZInt = self.read(&mut *reader)?; - Ok(ZExtZInt::new(value)) + Ok((ZExtZInt::new(value), has_flag(header, iext::FLAG_Z))) } } -impl WCodec<&ZExtZBuf<{ ID }>, &mut W> for Zenoh060Condition +impl WCodec<(&ZExtZBuf<{ ID }>, bool), &mut W> for Zenoh060 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &ZExtZBuf<{ ID }>) -> Self::Output { + fn write(self, writer: &mut W, x: (&ZExtZBuf<{ ID }>, bool)) -> Self::Output { + let (x, more) = x; let mut header: u8 = ID | iext::ENC_ZINT; - if self.condition { + if more { header |= iext::FLAG_Z; } - self.codec.write(&mut *writer, header)?; - self.codec.write(&mut *writer, &x.value)?; + self.write(&mut *writer, header)?; + self.write(&mut *writer, &x.value)?; Ok(()) } } -impl RCodec, &mut R> for Zenoh060 +impl RCodec<(ZExtZBuf<{ ID }>, bool), &mut R> for Zenoh060 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result, Self::Error> { + fn read(self, reader: &mut R) -> Result<(ZExtZBuf<{ ID }>, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; if (header & iext::ID_MASK != ID) || (header & iext::ENC_MASK != iext::ENC_ZINT) { @@ -123,48 +126,49 @@ where let value: ZBuf = self.read(&mut *reader)?; - Ok(ZExtZBuf::new(value)) + Ok((ZExtZBuf::new(value), has_flag(header, iext::FLAG_Z))) } } -impl WCodec<&ZExtUnknown, &mut W> for Zenoh060Condition +impl WCodec<(&ZExtUnknown, bool), &mut W> for Zenoh060 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &ZExtUnknown) -> Self::Output { + fn write(self, writer: &mut W, x: (&ZExtUnknown, bool)) -> Self::Output { + let (x, more) = x; let mut header: u8 = x.id; - if self.condition { + if more { header |= iext::FLAG_Z; } match &x.body { ZExtensionBody::Unit => { header |= iext::ENC_UNIT; - self.codec.write(&mut *writer, header)? + self.write(&mut *writer, header)? } ZExtensionBody::ZInt(zint) => { header |= iext::ENC_ZINT; - self.codec.write(&mut *writer, header)?; - self.codec.write(&mut *writer, zint)? + self.write(&mut *writer, header)?; + self.write(&mut *writer, zint)? } ZExtensionBody::ZBuf(zbuf) => { header |= iext::ENC_ZBUF; - self.codec.write(&mut *writer, header)?; - self.codec.write(&mut *writer, zbuf)? + self.write(&mut *writer, header)?; + self.write(&mut *writer, zbuf)? } } Ok(()) } } -impl RCodec for Zenoh060 +impl RCodec<(ZExtUnknown, bool), &mut R> for Zenoh060 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result<(ZExtUnknown, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; let body = match header & iext::ENC_MASK { @@ -180,9 +184,12 @@ where _ => return Err(DidntRead), }; - Ok(ZExtUnknown { - id: header & iext::ID_MASK, - body, - }) + Ok(( + ZExtUnknown { + id: header & iext::ID_MASK, + body, + }, + has_flag(header, iext::FLAG_Z), + )) } } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index d0034b6851..dcc478aba8 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -173,6 +173,37 @@ fn codec_attachment() { run!(Attachment, Attachment::rand()); } +#[test] +fn codec_extension() { + macro_rules! run_extension { + ($ext:ty) => { + let codec = Zenoh060::default(); + let mut buff = ZBuf::default(); + for _ in 0..NUM_ITER { + let more: bool = thread_rng().gen(); + + let x: (&$ext, bool) = (&<$ext>::rand(), more); + + buff.clear(); + let mut writer = buff.writer(); + codec.write(&mut writer, x).unwrap(); + + let mut reader = buff.reader(); + let y: ($ext, bool) = codec.read(&mut reader).unwrap(); + assert!(!reader.can_read()); + + assert_eq!(x.0, &y.0); + assert_eq!(more, y.1); + } + }; + } + + run_extension!(ZExtUnit<0>); + run_extension!(ZExtZInt<1>); + run_extension!(ZExtZBuf<2>); + run_extension!(ZExtUnknown); +} + // Scouting #[test] fn codec_hello() { diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index aa617aba26..0ea9575974 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -62,13 +62,18 @@ pub mod iext { pub const FLAG_Z: u8 = 1 << 7; } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct ZExtUnit; impl ZExtUnit<{ ID }> { pub fn new() -> Self { Self } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + Self::new() + } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -80,6 +85,15 @@ impl ZExtZInt<{ ID }> { pub fn new(value: ZInt) -> Self { Self { value } } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let value: ZInt = rng.gen(); + Self { value } + } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -91,6 +105,15 @@ impl ZExtZBuf<{ ID }> { pub fn new(value: ZBuf) -> Self { Self { value } } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let value = ZBuf::rand(rng.gen_range(8..=64)); + Self { value } + } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -105,3 +128,22 @@ pub enum ZExtensionBody { ZInt(ZInt), ZBuf(ZBuf), } + +impl ZExtUnknown { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::{seq::SliceRandom, Rng}; + + let mut rng = rand::thread_rng(); + let id: u8 = rng.gen_range(0x00..=iext::ID_MASK); + let body = [ + ZExtensionBody::Unit, + ZExtensionBody::ZInt(rng.gen()), + ZExtensionBody::ZBuf(ZBuf::rand(rng.gen_range(8..=64))), + ] + .choose(&mut rng) + .unwrap() + .clone(); + Self { id, body } + } +} From 59cbe911239f26edc0644cd212a094b01a04db73 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 20 Jan 2023 18:09:00 +0100 Subject: [PATCH 005/203] Extensions codec test improved --- commons/zenoh-codec/tests/codec.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index dcc478aba8..81c4880609 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -175,20 +175,19 @@ fn codec_attachment() { #[test] fn codec_extension() { - macro_rules! run_extension { - ($ext:ty) => { + macro_rules! run_extension_single { + ($ext:ty, $buff:expr) => { let codec = Zenoh060::default(); - let mut buff = ZBuf::default(); for _ in 0..NUM_ITER { let more: bool = thread_rng().gen(); let x: (&$ext, bool) = (&<$ext>::rand(), more); - buff.clear(); - let mut writer = buff.writer(); + $buff.clear(); + let mut writer = $buff.writer(); codec.write(&mut writer, x).unwrap(); - let mut reader = buff.reader(); + let mut reader = $buff.reader(); let y: ($ext, bool) = codec.read(&mut reader).unwrap(); assert!(!reader.can_read()); @@ -198,6 +197,22 @@ fn codec_extension() { }; } + macro_rules! run_extension { + ($type:ty) => { + println!("Vec: codec {}", std::any::type_name::<$type>()); + let mut buff = vec![]; + run_extension_single!($type, buff); + + println!("BBuf: codec {}", std::any::type_name::<$type>()); + let mut buff = BBuf::with_capacity(u16::MAX as usize); + run_extension_single!($type, buff); + + println!("ZBuf: codec {}", std::any::type_name::<$type>()); + let mut buff = ZBuf::default(); + run_extension_single!($type, buff); + }; + } + run_extension!(ZExtUnit<0>); run_extension!(ZExtZInt<1>); run_extension!(ZExtZBuf<2>); From 938044562475d19df84ec9fe8101144084be5e06 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 20 Jan 2023 18:24:16 +0100 Subject: [PATCH 006/203] Extensions codec test improved --- commons/zenoh-codec/tests/codec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 81c4880609..6aaca0ac47 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -192,7 +192,7 @@ fn codec_extension() { assert!(!reader.can_read()); assert_eq!(x.0, &y.0); - assert_eq!(more, y.1); + assert_eq!(x.1, y.1); } }; } From 7bb1d4a81bb30a1889d007615e35f8b91b60f297 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 20 Jan 2023 18:33:26 +0100 Subject: [PATCH 007/203] Revert to RSA 0.7.2 --- Cargo.lock | 9 +++++---- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c126013226..71149ab5be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2466,9 +2466,9 @@ checksum = "56770675ebc04927ded3e60633437841581c285dc6236109ea25fbf3beb7b59e" [[package]] name = "rsa" -version = "0.8.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5f00ae0c56ed2d34b86fc8f1c02e809dd455382de72e1dd08f7d1ced356bf59" +checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" dependencies = [ "byteorder", "digest 0.10.6", @@ -2480,6 +2480,7 @@ dependencies = [ "pkcs8", "rand_core 0.6.4", "signature", + "smallvec", "subtle", "zeroize", ] @@ -2840,9 +2841,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ "digest 0.10.6", "rand_core 0.6.4", diff --git a/Cargo.toml b/Cargo.toml index 72af05315c..943a56120f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ rand_chacha = "0.3.1" rcgen = "0.10.0" regex = "1.7.0" ringbuffer-spsc = "0.1.8" -rsa = "0.8.0" +rsa = "0.7.2" rustc_version = "0.4.0" rustls = "0.20.6" rustls-native-certs = "0.6.2" From 5864bfaf7b26a24a7c2b2941b1a10c15c7f0b52f Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 30 Jan 2023 14:34:45 +0100 Subject: [PATCH 008/203] Fix code fmt --- commons/zenoh-codec/src/common/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/zenoh-codec/src/common/mod.rs b/commons/zenoh-codec/src/common/mod.rs index f51eef0674..3fc68df66c 100644 --- a/commons/zenoh-codec/src/common/mod.rs +++ b/commons/zenoh-codec/src/common/mod.rs @@ -12,5 +12,5 @@ // ZettaScale Zenoh Team, // mod attachment; -mod priority; mod extension; +mod priority; From 9f6fc8146021869db9dc9f1326b3085d4510cd42 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 1 Feb 2023 10:38:06 +0100 Subject: [PATCH 009/203] New 0.8.0 scouting --- Cargo.lock | 8 + commons/zenoh-codec/Cargo.toml | 2 + commons/zenoh-codec/benches/codec.rs | 18 +- commons/zenoh-codec/src/common/attachment.rs | 16 +- commons/zenoh-codec/src/common/extension.rs | 18 +- commons/zenoh-codec/src/common/priority.rs | 10 +- commons/zenoh-codec/src/core/encoding.rs | 6 +- commons/zenoh-codec/src/core/endpoint.rs | 10 +- commons/zenoh-codec/src/core/keyexpr.rs | 6 +- commons/zenoh-codec/src/core/locator.rs | 10 +- commons/zenoh-codec/src/core/mod.rs | 18 +- commons/zenoh-codec/src/core/property.rs | 10 +- commons/zenoh-codec/src/core/timestamp.rs | 6 +- commons/zenoh-codec/src/core/zbuf.rs | 24 +- commons/zenoh-codec/src/core/zenohid.rs | 6 +- commons/zenoh-codec/src/core/zint.rs | 12 +- commons/zenoh-codec/src/core/zslice.rs | 6 +- commons/zenoh-codec/src/lib.rs | 26 +- commons/zenoh-codec/src/scouting/hello.rs | 55 ++- commons/zenoh-codec/src/scouting/mod.rs | 8 +- commons/zenoh-codec/src/scouting/scout.rs | 43 ++- commons/zenoh-codec/src/transport/close.rs | 10 +- commons/zenoh-codec/src/transport/frame.rs | 20 +- commons/zenoh-codec/src/transport/init.rs | 31 +- commons/zenoh-codec/src/transport/join.rs | 18 +- .../zenoh-codec/src/transport/keepalive.rs | 10 +- commons/zenoh-codec/src/transport/mod.rs | 8 +- commons/zenoh-codec/src/transport/open.rs | 18 +- commons/zenoh-codec/src/zenoh/data.rs | 30 +- commons/zenoh-codec/src/zenoh/declare.rs | 102 ++--- commons/zenoh-codec/src/zenoh/linkstate.rs | 21 +- commons/zenoh-codec/src/zenoh/mod.rs | 18 +- commons/zenoh-codec/src/zenoh/pull.rs | 12 +- commons/zenoh-codec/src/zenoh/query.rs | 24 +- commons/zenoh-codec/src/zenoh/routing.rs | 10 +- commons/zenoh-codec/src/zenoh/unit.rs | 12 +- commons/zenoh-codec/tests/codec.rs | 21 +- commons/zenoh-config/src/defaults.rs | 12 +- commons/zenoh-config/src/lib.rs | 12 +- commons/zenoh-protocol/Cargo.toml | 1 + commons/zenoh-protocol/src/core/mod.rs | 6 +- commons/zenoh-protocol/src/core/whatami.rs | 361 ++++++++++-------- commons/zenoh-protocol/src/defaults.rs | 7 - commons/zenoh-protocol/src/lib.rs | 3 + commons/zenoh-protocol/src/scouting/hello.rs | 99 +++-- commons/zenoh-protocol/src/scouting/mod.rs | 30 +- commons/zenoh-protocol/src/scouting/scout.rs | 66 +++- io/zenoh-link-commons/src/lib.rs | 10 +- io/zenoh-transport/src/common/batch.rs | 10 +- .../src/common/defragmentation.rs | 4 +- io/zenoh-transport/src/common/pipeline.rs | 8 +- io/zenoh-transport/src/manager.rs | 3 +- io/zenoh-transport/src/multicast/link.rs | 4 +- .../unicast/establishment/accept/init_ack.rs | 8 +- .../unicast/establishment/accept/open_syn.rs | 8 +- .../establishment/authenticator/pubkey.rs | 28 +- .../establishment/authenticator/shm.rs | 22 +- .../authenticator/userpassword.rs | 22 +- .../src/unicast/establishment/cookie.rs | 27 +- .../src/unicast/establishment/properties.rs | 6 +- io/zenoh-transport/src/unicast/link.rs | 6 +- zenoh/src/net/runtime/orchestrator.rs | 43 +-- 62 files changed, 805 insertions(+), 684 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 979ae78882..208b1a0166 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -643,6 +643,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +[[package]] +name = "const-str" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5bc011a04793b8ce7bca0efd59e3697c2061760df6efbb8c895e8a81548db67" + [[package]] name = "const_fn" version = "0.4.9" @@ -3836,6 +3842,7 @@ version = "0.7.0-rc" dependencies = [ "criterion", "rand 0.8.5", + "serde", "uhlc", "uuid", "zenoh-buffers", @@ -4183,6 +4190,7 @@ dependencies = [ name = "zenoh-protocol" version = "0.7.0-rc" dependencies = [ + "const-str", "defmt", "hex", "lazy_static", diff --git a/commons/zenoh-codec/Cargo.toml b/commons/zenoh-codec/Cargo.toml index 53878efc9a..161780ce32 100644 --- a/commons/zenoh-codec/Cargo.toml +++ b/commons/zenoh-codec/Cargo.toml @@ -31,6 +31,7 @@ description = "Internal crate for zenoh." [features] default = ["std"] std = [ + "serde/std", "uhlc/std", "zenoh-protocol/std" ] @@ -46,6 +47,7 @@ defmt = [ ] [dependencies] +serde = { workspace = true, features = ["alloc"] } uhlc = { workspace = true } zenoh-buffers = { path = "../zenoh-buffers/", default-features = false } zenoh-protocol = { path = "../zenoh-protocol/", default-features = false } diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 895e357cbe..755e7838c3 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -31,7 +31,7 @@ use zenoh_protocol::{ fn criterion_benchmark(c: &mut Criterion) { // ZInt Vec let mut buff = vec![]; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); c.bench_function("ZInt Vec", |b| { b.iter(|| { buff.clear(); @@ -44,7 +44,7 @@ fn criterion_benchmark(c: &mut Criterion) { // ZInt BBuf let mut buff = BBuf::with_capacity(BATCH_SIZE as usize); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); c.bench_function("ZInt BBuf", |b| { b.iter(|| { buff.clear(); @@ -57,7 +57,7 @@ fn criterion_benchmark(c: &mut Criterion) { // ZInt ZBuf let mut buff = ZBuf::default(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); c.bench_function("ZInt ZBuf", |b| { b.iter(|| { buff.clear(); @@ -70,7 +70,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Batch BBuf Write let mut buff = BBuf::with_capacity(u16::MAX as usize); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let frame = FrameHeader { channel: Channel::default(), @@ -107,7 +107,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Batch ZSlice Read NoAlloc let mut buff = BBuf::with_capacity(u16::MAX as usize); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let frame = FrameHeader { channel: Channel::default(), @@ -139,7 +139,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Batch ZSlice Read NoAlloc let mut buff = BBuf::with_capacity(u16::MAX as usize); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let frame = FrameHeader { channel: Channel::default(), @@ -177,7 +177,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Fragmentation ZBuf Write let mut buff = ZBuf::default(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let data = Data { key: 0.into(), @@ -195,7 +195,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Fragmentation ZBuf Read let mut buff = vec![]; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let data = Data { key: 0.into(), @@ -225,7 +225,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Fragmentation ZSlice ZBuf Read let mut buff = vec![]; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let data = Data { key: 0.into(), diff --git a/commons/zenoh-codec/src/common/attachment.rs b/commons/zenoh-codec/src/common/attachment.rs index 73139c5d1f..14b598aa39 100644 --- a/commons/zenoh-codec/src/common/attachment.rs +++ b/commons/zenoh-codec/src/common/attachment.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -22,9 +22,9 @@ use zenoh_protocol::{ transport::tmsg, }; #[cfg(feature = "shared-memory")] -use {crate::Zenoh060Condition, core::any::TypeId, zenoh_shm::SharedMemoryBufInfoSerialized}; +use {crate::Zenoh080Condition, core::any::TypeId, zenoh_shm::SharedMemoryBufInfoSerialized}; -impl WCodec<&Attachment, &mut W> for Zenoh060 +impl WCodec<&Attachment, &mut W> for Zenoh080 where W: Writer, { @@ -51,7 +51,7 @@ where // Body #[cfg(feature = "shared-memory")] { - let codec = Zenoh060Condition::new(imsg::has_flag(header, tmsg::flag::Z)); + let codec = Zenoh080Condition::new(imsg::has_flag(header, tmsg::flag::Z)); codec.write(&mut *writer, &x.buffer) } #[cfg(not(feature = "shared-memory"))] @@ -61,14 +61,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -76,7 +76,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -90,7 +90,7 @@ where let buffer: ZBuf = { #[cfg(feature = "shared-memory")] { - let codec = Zenoh060Condition::new(imsg::has_flag(self.header, tmsg::flag::Z)); + let codec = Zenoh080Condition::new(imsg::has_flag(self.header, tmsg::flag::Z)); codec.read(&mut *reader)? } #[cfg(not(feature = "shared-memory"))] diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 31c44e642f..619cba888d 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -22,7 +22,7 @@ use zenoh_protocol::{ core::ZInt, }; -impl WCodec<(&ZExtUnit<{ ID }>, bool), &mut W> for Zenoh060 +impl WCodec<(&ZExtUnit<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, { @@ -39,7 +39,7 @@ where } } -impl RCodec<(ZExtUnit<{ ID }>, bool), &mut R> for Zenoh060 +impl RCodec<(ZExtUnit<{ ID }>, bool), &mut R> for Zenoh080 where R: Reader, { @@ -56,7 +56,7 @@ where } } -impl WCodec<(&ZExtZInt<{ ID }>, bool), &mut W> for Zenoh060 +impl WCodec<(&ZExtZInt<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, { @@ -74,7 +74,7 @@ where } } -impl RCodec<(ZExtZInt<{ ID }>, bool), &mut R> for Zenoh060 +impl RCodec<(ZExtZInt<{ ID }>, bool), &mut R> for Zenoh080 where R: Reader, { @@ -93,7 +93,7 @@ where } } -impl WCodec<(&ZExtZBuf<{ ID }>, bool), &mut W> for Zenoh060 +impl WCodec<(&ZExtZBuf<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, { @@ -111,7 +111,7 @@ where } } -impl RCodec<(ZExtZBuf<{ ID }>, bool), &mut R> for Zenoh060 +impl RCodec<(ZExtZBuf<{ ID }>, bool), &mut R> for Zenoh080 where R: Reader, { @@ -130,7 +130,7 @@ where } } -impl WCodec<(&ZExtUnknown, bool), &mut W> for Zenoh060 +impl WCodec<(&ZExtUnknown, bool), &mut W> for Zenoh080 where W: Writer, { @@ -162,7 +162,7 @@ where } } -impl RCodec<(ZExtUnknown, bool), &mut R> for Zenoh060 +impl RCodec<(ZExtUnknown, bool), &mut R> for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/common/priority.rs b/commons/zenoh-codec/src/common/priority.rs index 5cd075ee6f..f0ea255465 100644 --- a/commons/zenoh-codec/src/common/priority.rs +++ b/commons/zenoh-codec/src/common/priority.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use core::convert::TryInto; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{common::imsg, core::Priority, transport::tmsg}; -impl WCodec<&Priority, &mut W> for Zenoh060 +impl WCodec<&Priority, &mut W> for Zenoh080 where W: Writer, { @@ -33,14 +33,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -48,7 +48,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { diff --git a/commons/zenoh-codec/src/core/encoding.rs b/commons/zenoh-codec/src/core/encoding.rs index f450835b6c..0e991e5528 100644 --- a/commons/zenoh-codec/src/core/encoding.rs +++ b/commons/zenoh-codec/src/core/encoding.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use alloc::string::String; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::{Encoding, ZInt}; -impl WCodec<&Encoding, &mut W> for Zenoh060 +impl WCodec<&Encoding, &mut W> for Zenoh080 where W: Writer, { @@ -32,7 +32,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/core/endpoint.rs b/commons/zenoh-codec/src/core/endpoint.rs index dfcca79e4e..0d0dd1e80e 100644 --- a/commons/zenoh-codec/src/core/endpoint.rs +++ b/commons/zenoh-codec/src/core/endpoint.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use alloc::{string::String, vec::Vec}; use core::convert::TryFrom; use zenoh_buffers::{ @@ -20,7 +20,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::EndPoint; -impl WCodec<&EndPoint, &mut W> for Zenoh060 +impl WCodec<&EndPoint, &mut W> for Zenoh080 where W: Writer, { @@ -31,7 +31,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -43,7 +43,7 @@ where } } -impl WCodec<&[EndPoint], &mut W> for Zenoh060 +impl WCodec<&[EndPoint], &mut W> for Zenoh080 where W: Writer, { @@ -58,7 +58,7 @@ where } } -impl RCodec, &mut R> for Zenoh060 +impl RCodec, &mut R> for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/core/keyexpr.rs b/commons/zenoh-codec/src/core/keyexpr.rs index b10adf6872..97f5c34e7a 100644 --- a/commons/zenoh-codec/src/core/keyexpr.rs +++ b/commons/zenoh-codec/src/core/keyexpr.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Condition}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition}; use alloc::string::String; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::{WireExpr, ZInt}; -impl WCodec<&WireExpr<'_>, &mut W> for Zenoh060 +impl WCodec<&WireExpr<'_>, &mut W> for Zenoh080 where W: Writer, { @@ -34,7 +34,7 @@ where } } -impl RCodec, &mut R> for Zenoh060Condition +impl RCodec, &mut R> for Zenoh080Condition where R: Reader, { diff --git a/commons/zenoh-codec/src/core/locator.rs b/commons/zenoh-codec/src/core/locator.rs index 0b3b17f335..d5daab0916 100644 --- a/commons/zenoh-codec/src/core/locator.rs +++ b/commons/zenoh-codec/src/core/locator.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use alloc::{string::String, vec::Vec}; use core::convert::TryFrom; use zenoh_buffers::{ @@ -20,7 +20,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::Locator; -impl WCodec<&Locator, &mut W> for Zenoh060 +impl WCodec<&Locator, &mut W> for Zenoh080 where W: Writer, { @@ -31,7 +31,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -43,7 +43,7 @@ where } } -impl WCodec<&[Locator], &mut W> for Zenoh060 +impl WCodec<&[Locator], &mut W> for Zenoh080 where W: Writer, { @@ -58,7 +58,7 @@ where } } -impl RCodec, &mut R> for Zenoh060 +impl RCodec, &mut R> for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/core/mod.rs b/commons/zenoh-codec/src/core/mod.rs index 76b2f9c857..ea4b01776c 100644 --- a/commons/zenoh-codec/src/core/mod.rs +++ b/commons/zenoh-codec/src/core/mod.rs @@ -22,7 +22,7 @@ mod zenohid; mod zint; mod zslice; -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use alloc::{string::String, vec::Vec}; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -30,7 +30,7 @@ use zenoh_buffers::{ }; // u8 -impl WCodec for Zenoh060 +impl WCodec for Zenoh080 where W: Writer, { @@ -41,7 +41,7 @@ where } } -impl WCodec<&u8, &mut W> for Zenoh060 +impl WCodec<&u8, &mut W> for Zenoh080 where W: Writer, { @@ -52,7 +52,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -64,7 +64,7 @@ where } // &[u8] / Vec -impl WCodec<&[u8], &mut W> for Zenoh060 +impl WCodec<&[u8], &mut W> for Zenoh080 where W: Writer, { @@ -80,7 +80,7 @@ where } } -impl RCodec, &mut R> for Zenoh060 +impl RCodec, &mut R> for Zenoh080 where R: Reader, { @@ -98,7 +98,7 @@ where } // &str / String -impl WCodec<&str, &mut W> for Zenoh060 +impl WCodec<&str, &mut W> for Zenoh080 where W: Writer, { @@ -109,7 +109,7 @@ where } } -impl WCodec<&String, &mut W> for Zenoh060 +impl WCodec<&String, &mut W> for Zenoh080 where W: Writer, { @@ -120,7 +120,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/core/property.rs b/commons/zenoh-codec/src/core/property.rs index 902b800401..ef713a2f9f 100644 --- a/commons/zenoh-codec/src/core/property.rs +++ b/commons/zenoh-codec/src/core/property.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::{Property, ZInt}; -impl WCodec<&Property, &mut W> for Zenoh060 +impl WCodec<&Property, &mut W> for Zenoh080 where W: Writer, { @@ -32,7 +32,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -46,7 +46,7 @@ where } } -impl WCodec<&[Property], &mut W> for Zenoh060 +impl WCodec<&[Property], &mut W> for Zenoh080 where W: Writer, { @@ -62,7 +62,7 @@ where } } -impl RCodec, &mut R> for Zenoh060 +impl RCodec, &mut R> for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/core/timestamp.rs b/commons/zenoh-codec/src/core/timestamp.rs index b50f90352f..6bdd2c1f76 100644 --- a/commons/zenoh-codec/src/core/timestamp.rs +++ b/commons/zenoh-codec/src/core/timestamp.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use core::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::{Timestamp, ZenohId}; -impl WCodec<&Timestamp, &mut W> for Zenoh060 +impl WCodec<&Timestamp, &mut W> for Zenoh080 where W: Writer, { @@ -32,7 +32,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index 42e1169049..ffea9128f4 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -19,12 +19,12 @@ use zenoh_buffers::{ }; #[cfg(feature = "shared-memory")] use { - crate::Zenoh060Condition, core::any::TypeId, zenoh_buffers::ZSlice, + crate::Zenoh080Condition, core::any::TypeId, zenoh_buffers::ZSlice, zenoh_shm::SharedMemoryBufInfoSerialized, }; // ZBuf flat -impl WCodec<&ZBuf, &mut W> for Zenoh060 +impl WCodec<&ZBuf, &mut W> for Zenoh080 where W: Writer, { @@ -39,7 +39,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -56,12 +56,12 @@ where // ZBuf sliced #[cfg(feature = "shared-memory")] #[derive(Default)] -struct Zenoh060Sliced { - codec: Zenoh060, +struct Zenoh080Sliced { + codec: Zenoh080, } #[cfg(feature = "shared-memory")] -impl WCodec<&ZBuf, &mut W> for Zenoh060Sliced +impl WCodec<&ZBuf, &mut W> for Zenoh080Sliced where W: Writer, { @@ -86,7 +86,7 @@ where } #[cfg(feature = "shared-memory")] -impl RCodec for Zenoh060Sliced +impl RCodec for Zenoh080Sliced where R: Reader, { @@ -116,7 +116,7 @@ where } #[cfg(feature = "shared-memory")] -impl WCodec<&ZBuf, &mut W> for Zenoh060Condition +impl WCodec<&ZBuf, &mut W> for Zenoh080Condition where W: Writer, { @@ -126,7 +126,7 @@ where let is_sliced = self.condition; if is_sliced { - let codec = Zenoh060Sliced::default(); + let codec = Zenoh080Sliced::default(); codec.write(&mut *writer, x) } else { self.codec.write(&mut *writer, x) @@ -135,7 +135,7 @@ where } #[cfg(feature = "shared-memory")] -impl RCodec for Zenoh060Condition +impl RCodec for Zenoh080Condition where R: Reader, { @@ -145,7 +145,7 @@ where let is_sliced = self.condition; if is_sliced { - let codec = Zenoh060Sliced::default(); + let codec = Zenoh080Sliced::default(); codec.read(&mut *reader) } else { self.codec.read(&mut *reader) diff --git a/commons/zenoh-codec/src/core/zenohid.rs b/commons/zenoh-codec/src/core/zenohid.rs index abc686b81e..a0e8596a71 100644 --- a/commons/zenoh-codec/src/core/zenohid.rs +++ b/commons/zenoh-codec/src/core/zenohid.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use core::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::ZenohId; -impl WCodec<&ZenohId, &mut W> for Zenoh060 +impl WCodec<&ZenohId, &mut W> for Zenoh080 where W: Writer, { @@ -30,7 +30,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index c1570ea61d..7d93298289 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use core::convert::TryInto; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -21,7 +21,7 @@ use zenoh_buffers::{ const VLE_LEN: usize = 10; // ZInt -impl WCodec for Zenoh060 +impl WCodec for Zenoh080 where W: Writer, { @@ -43,7 +43,7 @@ where } } -impl WCodec<&u64, &mut W> for Zenoh060 +impl WCodec<&u64, &mut W> for Zenoh080 where W: Writer, { @@ -54,7 +54,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -82,7 +82,7 @@ where } // usize -impl WCodec for Zenoh060 +impl WCodec for Zenoh080 where W: Writer, { @@ -94,7 +94,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/core/zslice.rs b/commons/zenoh-codec/src/core/zslice.rs index 65e5118ae3..2aa30ae615 100644 --- a/commons/zenoh-codec/src/core/zslice.rs +++ b/commons/zenoh-codec/src/core/zslice.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060}; +use crate::{RCodec, WCodec, Zenoh080}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -24,7 +24,7 @@ pub(crate) mod kind { pub(crate) const SHM_INFO: u8 = 1; } -impl WCodec<&ZSlice, &mut W> for Zenoh060 +impl WCodec<&ZSlice, &mut W> for Zenoh080 where W: Writer, { @@ -37,7 +37,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 833d9f7413..63b263184b 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -34,51 +34,51 @@ pub trait RCodec { #[derive(Clone, Copy, Default)] #[non_exhaustive] -pub struct Zenoh060; +pub struct Zenoh080; #[derive(Clone, Copy, Default)] #[non_exhaustive] -pub struct Zenoh060Header { +pub struct Zenoh080Header { pub header: u8, - pub codec: Zenoh060, + pub codec: Zenoh080, } #[derive(Clone, Copy, Default)] #[non_exhaustive] -pub struct Zenoh060Condition { +pub struct Zenoh080Condition { pub condition: bool, - pub codec: Zenoh060, + pub codec: Zenoh080, } -impl Zenoh060Condition { +impl Zenoh080Condition { pub const fn new(condition: bool) -> Self { Self { condition, - codec: Zenoh060, + codec: Zenoh080, } } } #[derive(Clone, Copy, Default)] #[non_exhaustive] -pub struct Zenoh060Reliability { +pub struct Zenoh080Reliability { pub reliability: Reliability, - pub codec: Zenoh060, + pub codec: Zenoh080, } -impl Zenoh060Reliability { +impl Zenoh080Reliability { pub const fn new(reliability: Reliability) -> Self { Self { reliability, - codec: Zenoh060, + codec: Zenoh080, } } } #[derive(Clone, Default)] #[non_exhaustive] -pub struct Zenoh060HeaderReplyContext { +pub struct Zenoh080HeaderReplyContext { pub header: u8, pub reply_context: Option, - pub codec: Zenoh060, + pub codec: Zenoh080, } diff --git a/commons/zenoh-codec/src/scouting/hello.rs b/commons/zenoh-codec/src/scouting/hello.rs index f87820c2ed..640f9fee2e 100644 --- a/commons/zenoh-codec/src/scouting/hello.rs +++ b/commons/zenoh-codec/src/scouting/hello.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use alloc::{vec, vec::Vec}; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,12 +19,12 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{Locator, WhatAmI, ZInt, ZenohId}, + core::{Locator, WhatAmI, ZenohId}, scouting::Hello, transport::tmsg, }; -impl WCodec<&Hello, &mut W> for Zenoh060 +impl WCodec<&Hello, &mut W> for Zenoh080 where W: Writer, { @@ -33,40 +33,36 @@ where fn write(self, writer: &mut W, x: &Hello) -> Self::Output { // Header let mut header = tmsg::id::HELLO; - if x.zid.is_some() { - header |= tmsg::flag::I - } - if x.whatami != WhatAmI::Router { - header |= tmsg::flag::W; - } if !x.locators.is_empty() { header |= tmsg::flag::L; } self.write(&mut *writer, header)?; // Body - if let Some(zid) = x.zid.as_ref() { - self.write(&mut *writer, zid)?; - } - if x.whatami != WhatAmI::Router { - let wai: ZInt = x.whatami.into(); - self.write(&mut *writer, wai)?; - } + self.write(&mut *writer, x.version)?; + let whatami: u8 = match x.whatami { + WhatAmI::Router => 0b00, + WhatAmI::Peer => 0b01, + WhatAmI::Client => 0b10, + }; + self.write(&mut *writer, whatami)?; + self.write(&mut *writer, &x.zid)?; if !x.locators.is_empty() { self.write(&mut *writer, x.locators.as_slice())?; } + Ok(()) } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -74,7 +70,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -85,18 +81,16 @@ where return Err(DidntRead); } - let zid = if imsg::has_flag(self.header, tmsg::flag::I) { - let zid: ZenohId = self.codec.read(&mut *reader)?; - Some(zid) - } else { - None - }; - let whatami = if imsg::has_flag(self.header, tmsg::flag::W) { - let wai: ZInt = self.codec.read(&mut *reader)?; - WhatAmI::try_from(wai).ok_or(DidntRead)? - } else { - WhatAmI::Router + let version: u8 = self.codec.read(&mut *reader)?; + let flags: u8 = self.codec.read(&mut *reader)?; + let whatami = match flags & 0b11 { + 0b00 => WhatAmI::Router, + 0b01 => WhatAmI::Peer, + 0b10 => WhatAmI::Client, + _ => return Err(DidntRead), }; + + let zid: ZenohId = self.codec.read(&mut *reader)?; let locators = if imsg::has_flag(self.header, tmsg::flag::L) { let locs: Vec = self.codec.read(&mut *reader)?; locs @@ -105,6 +99,7 @@ where }; Ok(Hello { + version, zid, whatami, locators, diff --git a/commons/zenoh-codec/src/scouting/mod.rs b/commons/zenoh-codec/src/scouting/mod.rs index d715541488..a33f0ed377 100644 --- a/commons/zenoh-codec/src/scouting/mod.rs +++ b/commons/zenoh-codec/src/scouting/mod.rs @@ -14,7 +14,7 @@ mod hello; mod scout; -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -24,7 +24,7 @@ use zenoh_protocol::{ scouting::{ScoutingBody, ScoutingMessage}, }; -impl WCodec<&ScoutingMessage, &mut W> for Zenoh060 +impl WCodec<&ScoutingMessage, &mut W> for Zenoh080 where W: Writer, { @@ -42,14 +42,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh060Header { + let mut codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; diff --git a/commons/zenoh-codec/src/scouting/scout.rs b/commons/zenoh-codec/src/scouting/scout.rs index 133c97a19b..d9f4c2f17e 100644 --- a/commons/zenoh-codec/src/scouting/scout.rs +++ b/commons/zenoh-codec/src/scouting/scout.rs @@ -11,19 +11,20 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use core::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ common::imsg, - core::{whatami::WhatAmIMatcher, ZInt}, + core::{whatami::WhatAmIMatcher, ZenohId}, scouting::Scout, transport::tmsg, }; -impl WCodec<&Scout, &mut W> for Zenoh060 +impl WCodec<&Scout, &mut W> for Zenoh080 where W: Writer, { @@ -32,33 +33,30 @@ where fn write(self, writer: &mut W, x: &Scout) -> Self::Output { // Header let mut header = tmsg::id::SCOUT; - if x.zid_request { + if x.zid.is_some() { header |= tmsg::flag::I; } - if x.what.is_some() { - header |= tmsg::flag::W; - } self.write(&mut *writer, header)?; // Body - match x.what { - Some(w) => { - let w: ZInt = w.into(); - self.write(&mut *writer, w) - } - None => Ok(()), + self.write(&mut *writer, x.version)?; + let what: u8 = x.what.into(); + self.write(&mut *writer, what & 0b111)?; + if let Some(zid) = x.zid.as_ref() { + self.write(&mut *writer, zid)?; } + Ok(()) } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -66,7 +64,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -77,13 +75,16 @@ where return Err(DidntRead); } - let zid_request = imsg::has_flag(self.header, tmsg::flag::I); - let what = if imsg::has_flag(self.header, tmsg::flag::W) { - let wai: ZInt = self.codec.read(reader)?; - WhatAmIMatcher::try_from(wai) + let version: u8 = self.codec.read(&mut *reader)?; + let flags: u8 = self.codec.read(&mut *reader)?; + let what = WhatAmIMatcher::try_from(flags & 0b111).map_err(|_| DidntRead)?; + let zid = if imsg::has_flag(self.header, tmsg::flag::I) { + let zid: ZenohId = self.codec.read(&mut *reader)?; + Some(zid) } else { None }; - Ok(Scout { what, zid_request }) + + Ok(Scout { version, what, zid }) } } diff --git a/commons/zenoh-codec/src/transport/close.rs b/commons/zenoh-codec/src/transport/close.rs index 00eb780f6d..4fedb655f9 100644 --- a/commons/zenoh-codec/src/transport/close.rs +++ b/commons/zenoh-codec/src/transport/close.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -22,7 +22,7 @@ use zenoh_protocol::{ transport::{tmsg, Close}, }; -impl WCodec<&Close, &mut W> for Zenoh060 +impl WCodec<&Close, &mut W> for Zenoh080 where W: Writer, { @@ -48,14 +48,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -63,7 +63,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index d884b65686..7112ca0a86 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header, Zenoh060Reliability}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Reliability}; use alloc::vec::Vec; use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, @@ -25,7 +25,7 @@ use zenoh_protocol::{ }; // FrameHeader -impl WCodec<&FrameHeader, &mut W> for Zenoh060 +impl WCodec<&FrameHeader, &mut W> for Zenoh080 where W: Writer, { @@ -61,14 +61,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -76,7 +76,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -120,7 +120,7 @@ where } // Frame -impl WCodec<&Frame, &mut W> for Zenoh060 +impl WCodec<&Frame, &mut W> for Zenoh080 where W: Writer, { @@ -158,14 +158,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader + BacktrackableReader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -173,7 +173,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader + BacktrackableReader, { @@ -184,7 +184,7 @@ where let payload = match header.kind { FrameKind::Messages => { - let rcode = Zenoh060Reliability { + let rcode = Zenoh080Reliability { reliability: header.channel.reliability, ..Default::default() }; diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index ede8b61c23..3cdc69e752 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -11,7 +11,8 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use core::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -25,7 +26,7 @@ use zenoh_protocol::{ }; // InitSyn -impl WCodec<&InitSyn, &mut W> for Zenoh060 +impl WCodec<&InitSyn, &mut W> for Zenoh080 where W: Writer, { @@ -59,7 +60,7 @@ where self.write(&mut *writer, options(x))?; } self.write(&mut *writer, x.version)?; - let wai: ZInt = x.whatami.into(); + let wai: u8 = x.whatami.into(); self.write(&mut *writer, wai)?; self.write(&mut *writer, &x.zid)?; if imsg::has_flag(header, tmsg::flag::S) { @@ -69,14 +70,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -84,7 +85,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -101,8 +102,8 @@ where 0 }; let version: u8 = self.codec.read(&mut *reader)?; - let wai: ZInt = self.codec.read(&mut *reader)?; - let whatami = WhatAmI::try_from(wai).ok_or(DidntRead)?; + let wai: u8 = self.codec.read(&mut *reader)?; + let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; let zid: ZenohId = self.codec.read(&mut *reader)?; let sn_resolution: ZInt = if imsg::has_flag(self.header, tmsg::flag::S) { self.codec.read(&mut *reader)? @@ -122,7 +123,7 @@ where } // InitAck -impl WCodec<&InitAck, &mut W> for Zenoh060 +impl WCodec<&InitAck, &mut W> for Zenoh080 where W: Writer, { @@ -156,7 +157,7 @@ where if has_options(x) { self.write(&mut *writer, options(x))?; } - let wai: ZInt = x.whatami.into(); + let wai: u8 = x.whatami.into(); self.write(&mut *writer, wai)?; self.write(&mut *writer, &x.zid)?; if let Some(snr) = x.sn_resolution { @@ -167,14 +168,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -182,7 +183,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -198,8 +199,8 @@ where } else { 0 }; - let wai: ZInt = self.codec.read(&mut *reader)?; - let whatami = WhatAmI::try_from(wai).ok_or(DidntRead)?; + let wai: u8 = self.codec.read(&mut *reader)?; + let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; let zid: ZenohId = self.codec.read(&mut *reader)?; let sn_resolution = if imsg::has_flag(self.header, tmsg::flag::S) { let snr: ZInt = self.codec.read(&mut *reader)?; diff --git a/commons/zenoh-codec/src/transport/join.rs b/commons/zenoh-codec/src/transport/join.rs index d2fdecd1ce..0211d25369 100644 --- a/commons/zenoh-codec/src/transport/join.rs +++ b/commons/zenoh-codec/src/transport/join.rs @@ -11,9 +11,9 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use alloc::boxed::Box; -use core::time::Duration; +use core::{convert::TryFrom, time::Duration}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -25,7 +25,7 @@ use zenoh_protocol::{ transport::{tmsg, ConduitSn, ConduitSnList, Join}, }; -impl WCodec<&Join, &mut W> for Zenoh060 +impl WCodec<&Join, &mut W> for Zenoh080 where W: Writer, { @@ -59,7 +59,7 @@ where // Body self.write(&mut *writer, x.version)?; - let wai: ZInt = x.whatami.into(); + let wai: u8 = x.whatami.into(); self.write(&mut *writer, wai)?; self.write(&mut *writer, &x.zid)?; if imsg::has_flag(header, tmsg::flag::T1) { @@ -87,14 +87,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -102,7 +102,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -119,8 +119,8 @@ where 0 }; let version: u8 = self.codec.read(&mut *reader)?; - let wai: ZInt = self.codec.read(&mut *reader)?; - let whatami = WhatAmI::try_from(wai).ok_or(DidntRead)?; + let wai: u8 = self.codec.read(&mut *reader)?; + let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; let zid: ZenohId = self.codec.read(&mut *reader)?; let lease: ZInt = self.codec.read(&mut *reader)?; let lease = if imsg::has_flag(self.header, tmsg::flag::T1) { diff --git a/commons/zenoh-codec/src/transport/keepalive.rs b/commons/zenoh-codec/src/transport/keepalive.rs index bbb9c0c1ae..7685b2ade4 100644 --- a/commons/zenoh-codec/src/transport/keepalive.rs +++ b/commons/zenoh-codec/src/transport/keepalive.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -22,7 +22,7 @@ use zenoh_protocol::{ transport::{tmsg, KeepAlive}, }; -impl WCodec<&KeepAlive, &mut W> for Zenoh060 +impl WCodec<&KeepAlive, &mut W> for Zenoh080 where W: Writer, { @@ -44,14 +44,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -59,7 +59,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index b33a7cb8cb..05337472aa 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -18,7 +18,7 @@ mod join; mod keepalive; mod open; -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -29,7 +29,7 @@ use zenoh_protocol::{ }; // TransportMessage -impl WCodec<&TransportMessage, &mut W> for Zenoh060 +impl WCodec<&TransportMessage, &mut W> for Zenoh080 where W: Writer, { @@ -52,14 +52,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader + BacktrackableReader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh060Header { + let mut codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index dd80f99800..a027e6e6b3 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use core::time::Duration; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -25,7 +25,7 @@ use zenoh_protocol::{ }; // OpenSyn -impl WCodec<&OpenSyn, &mut W> for Zenoh060 +impl WCodec<&OpenSyn, &mut W> for Zenoh080 where W: Writer, { @@ -51,14 +51,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -66,7 +66,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -95,7 +95,7 @@ where } // OpenAck -impl WCodec<&OpenAck, &mut W> for Zenoh060 +impl WCodec<&OpenAck, &mut W> for Zenoh080 where W: Writer, { @@ -122,14 +122,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -137,7 +137,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index 239b70718e..8e0e6253b7 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{ - RCodec, WCodec, Zenoh060, Zenoh060Condition, Zenoh060Header, Zenoh060HeaderReplyContext, + RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header, Zenoh080HeaderReplyContext, }; use core::convert::TryInto; use uhlc::Timestamp; @@ -28,7 +28,7 @@ use zenoh_protocol::{ }; // ReplyContext -impl WCodec<&ReplyContext, &mut W> for Zenoh060 +impl WCodec<&ReplyContext, &mut W> for Zenoh080 where W: Writer, { @@ -51,14 +51,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -66,7 +66,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -89,7 +89,7 @@ where } // DataInfo -impl WCodec<&DataInfo, &mut W> for Zenoh060 +impl WCodec<&DataInfo, &mut W> for Zenoh080 where W: Writer, { @@ -139,7 +139,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -178,7 +178,7 @@ where } // Data -impl WCodec<&Data, &mut W> for Zenoh060 +impl WCodec<&Data, &mut W> for Zenoh080 where W: Writer, { @@ -218,7 +218,7 @@ where #[cfg(feature = "shared-memory")] { - let codec = Zenoh060Condition::new(sliced); + let codec = Zenoh080Condition::new(sliced); codec.write(&mut *writer, &x.payload)?; } @@ -231,19 +231,19 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh060HeaderReplyContext { + let mut codec = Zenoh080HeaderReplyContext { header: self.read(&mut *reader)?, ..Default::default() }; if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { - let hodec = Zenoh060Header { + let hodec = Zenoh080Header { header: codec.header, ..Default::default() }; @@ -254,7 +254,7 @@ where } } -impl RCodec for Zenoh060HeaderReplyContext +impl RCodec for Zenoh080HeaderReplyContext where R: Reader, { @@ -271,7 +271,7 @@ where CongestionControl::Block }; - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; @@ -294,7 +294,7 @@ where let payload: ZBuf = { #[cfg(feature = "shared-memory")] { - let codec = Zenoh060Condition::new(is_sliced); + let codec = Zenoh080Condition::new(is_sliced); codec.read(&mut *reader)? } #[cfg(not(feature = "shared-memory"))] diff --git a/commons/zenoh-codec/src/zenoh/declare.rs b/commons/zenoh-codec/src/zenoh/declare.rs index 95ff17de02..bb30f9733f 100644 --- a/commons/zenoh-codec/src/zenoh/declare.rs +++ b/commons/zenoh-codec/src/zenoh/declare.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Condition, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -28,7 +28,7 @@ use zenoh_protocol::{ }; // Declaration -impl WCodec<&Declaration, &mut W> for Zenoh060 +impl WCodec<&Declaration, &mut W> for Zenoh080 where W: Writer, { @@ -50,7 +50,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -59,7 +59,7 @@ where fn read(self, reader: &mut R) -> Result { use super::zmsg::declaration::id::*; - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -81,7 +81,7 @@ where } // Declare -impl WCodec<&Declare, &mut W> for Zenoh060 +impl WCodec<&Declare, &mut W> for Zenoh080 where W: Writer, { @@ -102,14 +102,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -117,7 +117,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -140,7 +140,7 @@ where } // Resource -impl WCodec<&Resource, &mut W> for Zenoh060 +impl WCodec<&Resource, &mut W> for Zenoh080 where W: Writer, { @@ -162,14 +162,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -177,7 +177,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -189,7 +189,7 @@ where } let expr_id: ZInt = self.codec.read(&mut *reader)?; - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; @@ -200,7 +200,7 @@ where } // ForgetResource -impl WCodec<&ForgetResource, &mut W> for Zenoh060 +impl WCodec<&ForgetResource, &mut W> for Zenoh080 where W: Writer, { @@ -218,14 +218,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -233,7 +233,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -251,7 +251,7 @@ where } // Publisher -impl WCodec<&Publisher, &mut W> for Zenoh060 +impl WCodec<&Publisher, &mut W> for Zenoh080 where W: Writer, { @@ -272,14 +272,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -287,7 +287,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -298,7 +298,7 @@ where return Err(DidntRead); } - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; @@ -309,7 +309,7 @@ where } // ForgetPublisher -impl WCodec<&ForgetPublisher, &mut W> for Zenoh060 +impl WCodec<&ForgetPublisher, &mut W> for Zenoh080 where W: Writer, { @@ -330,14 +330,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -345,7 +345,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -356,7 +356,7 @@ where return Err(DidntRead); } - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; @@ -367,7 +367,7 @@ where } // SubMode -impl WCodec<&SubMode, &mut W> for Zenoh060 +impl WCodec<&SubMode, &mut W> for Zenoh080 where W: Writer, { @@ -387,7 +387,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -407,7 +407,7 @@ where } // Subscriber -impl WCodec<&Subscriber, &mut W> for Zenoh060 +impl WCodec<&Subscriber, &mut W> for Zenoh080 where W: Writer, { @@ -437,14 +437,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -452,7 +452,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -469,7 +469,7 @@ where Reliability::BestEffort }; - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; @@ -489,7 +489,7 @@ where } // ForgetSubscriber -impl WCodec<&ForgetSubscriber, &mut W> for Zenoh060 +impl WCodec<&ForgetSubscriber, &mut W> for Zenoh080 where W: Writer, { @@ -510,14 +510,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -525,7 +525,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -536,7 +536,7 @@ where return Err(DidntRead); } - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; @@ -547,7 +547,7 @@ where } // QueryableInfo -impl WCodec<&QueryableInfo, &mut W> for Zenoh060 +impl WCodec<&QueryableInfo, &mut W> for Zenoh080 where W: Writer, { @@ -561,7 +561,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -576,7 +576,7 @@ where } // Queryable -impl WCodec<&Queryable, &mut W> for Zenoh060 +impl WCodec<&Queryable, &mut W> for Zenoh080 where W: Writer, { @@ -603,14 +603,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -618,7 +618,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -629,7 +629,7 @@ where return Err(DidntRead); } - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; @@ -646,7 +646,7 @@ where } // ForgetQueryable -impl WCodec<&ForgetQueryable, &mut W> for Zenoh060 +impl WCodec<&ForgetQueryable, &mut W> for Zenoh080 where W: Writer, { @@ -667,14 +667,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -682,7 +682,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -693,7 +693,7 @@ where return Err(DidntRead); } - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; diff --git a/commons/zenoh-codec/src/zenoh/linkstate.rs b/commons/zenoh-codec/src/zenoh/linkstate.rs index 6437beacd3..200ca2a41a 100644 --- a/commons/zenoh-codec/src/zenoh/linkstate.rs +++ b/commons/zenoh-codec/src/zenoh/linkstate.rs @@ -11,8 +11,9 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use alloc::vec::Vec; +use core::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -24,7 +25,7 @@ use zenoh_protocol::{ }; // LinkState -impl WCodec<&LinkState, &mut W> for Zenoh060 +impl WCodec<&LinkState, &mut W> for Zenoh080 where W: Writer, { @@ -51,7 +52,7 @@ where self.write(&mut *writer, zid)?; } if let Some(wai) = x.whatami { - let wai: ZInt = wai.into(); + let wai: u8 = wai.into(); self.write(&mut *writer, wai)?; } if let Some(locators) = x.locators.as_ref() { @@ -66,7 +67,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -83,8 +84,8 @@ where None }; let whatami = if imsg::has_option(options, zmsg::link_state::WAI) { - let wai: ZInt = self.read(&mut *reader)?; - Some(WhatAmI::try_from(wai).ok_or(DidntRead)?) + let wai: u8 = self.read(&mut *reader)?; + Some(WhatAmI::try_from(wai).map_err(|_| DidntRead)?) } else { None }; @@ -113,7 +114,7 @@ where } // LinkStateList -impl WCodec<&LinkStateList, &mut W> for Zenoh060 +impl WCodec<&LinkStateList, &mut W> for Zenoh080 where W: Writer, { @@ -134,14 +135,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -149,7 +150,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { diff --git a/commons/zenoh-codec/src/zenoh/mod.rs b/commons/zenoh-codec/src/zenoh/mod.rs index 875724be76..ade67584ce 100644 --- a/commons/zenoh-codec/src/zenoh/mod.rs +++ b/commons/zenoh-codec/src/zenoh/mod.rs @@ -20,7 +20,7 @@ mod routing; mod unit; use crate::{ - RCodec, WCodec, Zenoh060, Zenoh060Header, Zenoh060HeaderReplyContext, Zenoh060Reliability, + RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080HeaderReplyContext, Zenoh080Reliability, }; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -32,7 +32,7 @@ use zenoh_protocol::{ zenoh::{zmsg, ReplyContext, RoutingContext, ZenohBody, ZenohMessage}, }; -impl WCodec<&ZenohMessage, &mut W> for Zenoh060 +impl WCodec<&ZenohMessage, &mut W> for Zenoh080 where W: Writer, { @@ -60,14 +60,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Reliability { + let codec = Zenoh080Reliability { reliability: Reliability::default(), ..Default::default() }; @@ -75,14 +75,14 @@ where } } -impl RCodec for Zenoh060Reliability +impl RCodec for Zenoh080Reliability where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh060Header { + let mut codec = Zenoh080Header { header: self.codec.read(&mut *reader)?, ..Default::default() }; @@ -112,7 +112,7 @@ where let body = match imsg::mid(codec.header) { zmsg::id::REPLY_CONTEXT => { let rc: ReplyContext = codec.read(&mut *reader)?; - let rodec = Zenoh060HeaderReplyContext { + let rodec = Zenoh080HeaderReplyContext { header: self.codec.read(&mut *reader)?, reply_context: Some(rc), ..Default::default() @@ -124,14 +124,14 @@ where } } zmsg::id::DATA => { - let rodec = Zenoh060HeaderReplyContext { + let rodec = Zenoh080HeaderReplyContext { header: codec.header, ..Default::default() }; ZenohBody::Data(rodec.read(&mut *reader)?) } zmsg::id::UNIT => { - let rodec = Zenoh060HeaderReplyContext { + let rodec = Zenoh080HeaderReplyContext { header: codec.header, ..Default::default() }; diff --git a/commons/zenoh-codec/src/zenoh/pull.rs b/commons/zenoh-codec/src/zenoh/pull.rs index 5893213106..f827675ea2 100644 --- a/commons/zenoh-codec/src/zenoh/pull.rs +++ b/commons/zenoh-codec/src/zenoh/pull.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Condition, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -22,7 +22,7 @@ use zenoh_protocol::{ zenoh::{zmsg, Pull}, }; -impl WCodec<&Pull, &mut W> for Zenoh060 +impl WCodec<&Pull, &mut W> for Zenoh080 where W: Writer, { @@ -53,14 +53,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -68,7 +68,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -79,7 +79,7 @@ where return Err(DidntRead); } - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; diff --git a/commons/zenoh-codec/src/zenoh/query.rs b/commons/zenoh-codec/src/zenoh/query.rs index 6a854fc104..e545f2aec5 100644 --- a/commons/zenoh-codec/src/zenoh/query.rs +++ b/commons/zenoh-codec/src/zenoh/query.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Condition, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; use alloc::string::String; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -25,7 +25,7 @@ use zenoh_protocol::{ }; // QueryTarget -impl WCodec<&QueryTarget, &mut W> for Zenoh060 +impl WCodec<&QueryTarget, &mut W> for Zenoh080 where W: Writer, { @@ -47,7 +47,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -71,7 +71,7 @@ where } // ConsolidationMode -impl WCodec<&ConsolidationMode, &mut W> for Zenoh060 +impl WCodec<&ConsolidationMode, &mut W> for Zenoh080 where W: Writer, { @@ -88,7 +88,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -107,7 +107,7 @@ where } // QueryBody -impl WCodec<&QueryBody, &mut W> for Zenoh060 +impl WCodec<&QueryBody, &mut W> for Zenoh080 where W: Writer, { @@ -120,7 +120,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -134,7 +134,7 @@ where } // Query -impl WCodec<&Query, &mut W> for Zenoh060 +impl WCodec<&Query, &mut W> for Zenoh080 where W: Writer, { @@ -170,14 +170,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -185,7 +185,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { @@ -196,7 +196,7 @@ where return Err(DidntRead); } - let ccond = Zenoh060Condition { + let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; diff --git a/commons/zenoh-codec/src/zenoh/routing.rs b/commons/zenoh-codec/src/zenoh/routing.rs index f50ae4e642..4bc89a68fc 100644 --- a/commons/zenoh-codec/src/zenoh/routing.rs +++ b/commons/zenoh-codec/src/zenoh/routing.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -22,7 +22,7 @@ use zenoh_protocol::{ zenoh::{zmsg, RoutingContext}, }; -impl WCodec<&RoutingContext, &mut W> for Zenoh060 +impl WCodec<&RoutingContext, &mut W> for Zenoh080 where W: Writer, { @@ -39,14 +39,14 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh060Header { + let codec = Zenoh080Header { header: self.read(&mut *reader)?, ..Default::default() }; @@ -54,7 +54,7 @@ where } } -impl RCodec for Zenoh060Header +impl RCodec for Zenoh080Header where R: Reader, { diff --git a/commons/zenoh-codec/src/zenoh/unit.rs b/commons/zenoh-codec/src/zenoh/unit.rs index 236159fe4d..25e322336a 100644 --- a/commons/zenoh-codec/src/zenoh/unit.rs +++ b/commons/zenoh-codec/src/zenoh/unit.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh060, Zenoh060Header, Zenoh060HeaderReplyContext}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080HeaderReplyContext}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -22,7 +22,7 @@ use zenoh_protocol::{ zenoh::{zmsg, Unit}, }; -impl WCodec<&Unit, &mut W> for Zenoh060 +impl WCodec<&Unit, &mut W> for Zenoh080 where W: Writer, { @@ -45,19 +45,19 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh060HeaderReplyContext { + let mut codec = Zenoh080HeaderReplyContext { header: self.read(&mut *reader)?, ..Default::default() }; if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { - let hodec = Zenoh060Header { + let hodec = Zenoh080Header { header: codec.header, ..Default::default() }; @@ -68,7 +68,7 @@ where } } -impl RCodec for Zenoh060HeaderReplyContext +impl RCodec for Zenoh080HeaderReplyContext where R: Reader, { diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 6aaca0ac47..59fe9d8c93 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -107,7 +107,7 @@ macro_rules! run_buffers { macro_rules! run { ($type:ty, $rand:expr) => { - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); run_buffers!($type, $rand, codec, codec); }; ($type:ty, $rand:expr, $wcode:block, $rcode:block) => { @@ -177,7 +177,7 @@ fn codec_attachment() { fn codec_extension() { macro_rules! run_extension_single { ($ext:ty, $buff:expr) => { - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); for _ in 0..NUM_ITER { let more: bool = thread_rng().gen(); @@ -221,15 +221,16 @@ fn codec_extension() { // Scouting #[test] -fn codec_hello() { - run!(Hello, Hello::rand()); +fn codec_scout() { + run!(Scout, Scout::rand()); } #[test] -fn codec_scout() { - run!(Scout, Scout::rand()); +fn codec_hello() { + run!(Hello, Hello::rand()); } + #[test] fn codec_scouting() { run!(ScoutingMessage, ScoutingMessage::rand()); @@ -391,8 +392,8 @@ fn codec_zenoh() { x.channel.reliability = Reliability::Reliable; x }, - { Zenoh060::default() }, - { Zenoh060Reliability::new(Reliability::Reliable) } + { Zenoh080::default() }, + { Zenoh080Reliability::new(Reliability::Reliable) } ); run!( ZenohMessage, @@ -401,7 +402,7 @@ fn codec_zenoh() { x.channel.reliability = Reliability::BestEffort; x }, - { Zenoh060::default() }, - { Zenoh060Reliability::new(Reliability::BestEffort) } + { Zenoh080::default() }, + { Zenoh080Reliability::new(Reliability::BestEffort) } ); } diff --git a/commons/zenoh-config/src/defaults.rs b/commons/zenoh-config/src/defaults.rs index dc14fbf3e2..e8758803b9 100644 --- a/commons/zenoh-config/src/defaults.rs +++ b/commons/zenoh-config/src/defaults.rs @@ -41,11 +41,11 @@ pub mod scouting { pub const interface: &str = "auto"; pub mod autoconnect { pub const router: &crate::WhatAmIMatcher = // "" - &crate::WhatAmIMatcher(unsafe { std::num::NonZeroU8::new_unchecked(128) }); + &crate::WhatAmIMatcher::empty(); pub const peer: &crate::WhatAmIMatcher = // "router|peer" - &crate::WhatAmIMatcher(unsafe { std::num::NonZeroU8::new_unchecked(131) }); + &crate::WhatAmIMatcher::empty().router().peer(); pub const client: &crate::WhatAmIMatcher = // "router|peer" - &crate::WhatAmIMatcher(unsafe { std::num::NonZeroU8::new_unchecked(131) }); + &crate::WhatAmIMatcher::empty().router().peer(); mode_accessor!(crate::WhatAmIMatcher); } pub mod listen { @@ -60,11 +60,11 @@ pub mod scouting { pub const multihop: bool = false; pub mod autoconnect { pub const router: &crate::WhatAmIMatcher = // "" - &crate::WhatAmIMatcher(unsafe { std::num::NonZeroU8::new_unchecked(128) }); + &crate::WhatAmIMatcher::empty(); pub const peer: &crate::WhatAmIMatcher = // "router|peer" - &crate::WhatAmIMatcher(unsafe { std::num::NonZeroU8::new_unchecked(131) }); + &crate::WhatAmIMatcher::empty().router().peer(); pub const client: &crate::WhatAmIMatcher = // "router|peer" - &crate::WhatAmIMatcher(unsafe { std::num::NonZeroU8::new_unchecked(131) }); + &crate::WhatAmIMatcher::empty().router().peer(); mode_accessor!(crate::WhatAmIMatcher); } } diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 28acb61bad..319b27aa1c 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -19,6 +19,8 @@ use serde::{ Deserialize, Serialize, }; use serde_json::Value; +#[allow(unused_imports)] +use std::convert::TryFrom; // This is a false positive from the rust analyser use std::{ any::Any, collections::HashMap, @@ -387,15 +389,15 @@ fn config_deser() { assert_eq!(*config.scouting().multicast().enabled(), Some(false)); assert_eq!( config.scouting().multicast().autoconnect().router(), - Some(&WhatAmIMatcher::try_from(131).unwrap()) + Some(&WhatAmIMatcher::empty().router().peer()) ); assert_eq!( config.scouting().multicast().autoconnect().peer(), - Some(&WhatAmIMatcher::try_from(131).unwrap()) + Some(&WhatAmIMatcher::empty().router().peer()) ); assert_eq!( config.scouting().multicast().autoconnect().client(), - Some(&WhatAmIMatcher::try_from(131).unwrap()) + Some(&WhatAmIMatcher::empty().router().peer()) ); let config = Config::from_deserializer( &mut json5::Deserializer::from_str( @@ -414,11 +416,11 @@ fn config_deser() { assert_eq!(*config.scouting().multicast().enabled(), Some(false)); assert_eq!( config.scouting().multicast().autoconnect().router(), - Some(&WhatAmIMatcher::try_from(128).unwrap()) + Some(&WhatAmIMatcher::empty()) ); assert_eq!( config.scouting().multicast().autoconnect().peer(), - Some(&WhatAmIMatcher::try_from(131).unwrap()) + Some(&WhatAmIMatcher::empty().router().peer()) ); assert_eq!(config.scouting().multicast().autoconnect().client(), None); let config = Config::from_deserializer( diff --git a/commons/zenoh-protocol/Cargo.toml b/commons/zenoh-protocol/Cargo.toml index 6e7b8cd4eb..62ec7a4995 100644 --- a/commons/zenoh-protocol/Cargo.toml +++ b/commons/zenoh-protocol/Cargo.toml @@ -40,6 +40,7 @@ complete_n = [] defmt = ["dep:defmt", "uhlc/defmt", "zenoh-buffers/defmt"] [dependencies] +const-str = "0.5.3" defmt = { workspace = true, optional = true } hex = { workspace = true, features = ["alloc"] } rand = { workspace = true, features = ["alloc", "getrandom"], optional = true } diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index 711b8b2820..b7f94861d5 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -31,15 +31,15 @@ pub use uhlc::{Timestamp, NTP64}; use uuid::Uuid; use zenoh_result::{bail, zerror}; -/// The unique Id of the [`HLC`](uhlc::HLC) that generated the concerned [`Timestamp`]. -pub type TimestampId = uhlc::ID; - /// A zenoh integer. pub type ZInt = u64; pub type ZiInt = i64; pub type NonZeroZInt = NonZeroU64; pub const ZINT_MAX_BYTES: usize = 10; +/// The unique Id of the [`HLC`](uhlc::HLC) that generated the concerned [`Timestamp`]. +pub type TimestampId = uhlc::ID; + /// Constants and helpers for zenoh `whatami` flags. pub mod whatami; pub use whatami::*; diff --git a/commons/zenoh-protocol/src/core/whatami.rs b/commons/zenoh-protocol/src/core/whatami.rs index 3fae5fac4b..34455b2a6c 100644 --- a/commons/zenoh-protocol/src/core/whatami.rs +++ b/commons/zenoh-protocol/src/core/whatami.rs @@ -11,34 +11,36 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::ZInt; use alloc::string::String; -use core::{convert::TryInto, fmt, num::NonZeroU8, ops::BitOr, str::FromStr}; +use core::{convert::TryFrom, fmt, num::NonZeroU8, ops::BitOr, str::FromStr}; use zenoh_result::{bail, ZError}; +const WAI_STR_R: &str = "router"; +const WAI_STR_P: &str = "peer"; +const WAI_STR_C: &str = "client"; + #[repr(u8)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum WhatAmI { - Router = 1, - Peer = 1 << 1, - Client = 1 << 2, + Router = 0b001, + Peer = 0b010, + Client = 0b100, } -impl FromStr for WhatAmI { - type Err = ZError; +impl WhatAmI { + const U8_R: u8 = WhatAmI::Router as u8; + const U8_P: u8 = WhatAmI::Peer as u8; + const U8_C: u8 = WhatAmI::Client as u8; - fn from_str(s: &str) -> Result { - match s { - "router" => Ok(WhatAmI::Router), - "peer" => Ok(WhatAmI::Peer), - "client" => Ok(WhatAmI::Client), - _ => bail!("{} is not a valid WhatAmI value. Valid values are: [\"router\", \"peer\", \"client\"].", s), + pub const fn to_str(self) -> &'static str { + match self { + WhatAmI::Router => WAI_STR_R, + WhatAmI::Peer => WAI_STR_P, + WhatAmI::Client => WAI_STR_C, } } -} -impl WhatAmI { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::prelude::SliceRandom; @@ -48,24 +50,32 @@ impl WhatAmI { .choose(&mut rng) .unwrap() } +} - pub fn to_str(self) -> &'static str { - match self { - WhatAmI::Router => "router", - WhatAmI::Peer => "peer", - WhatAmI::Client => "client", +impl TryFrom for WhatAmI { + type Error = (); + + fn try_from(v: u8) -> Result { + match v { + Self::U8_R => Ok(WhatAmI::Router), + Self::U8_P => Ok(WhatAmI::Peer), + Self::U8_C => Ok(WhatAmI::Client), + _ => Err(()), } } +} - pub fn try_from(value: ZInt) -> Option { - const CLIENT: ZInt = WhatAmI::Client as ZInt; - const ROUTER: ZInt = WhatAmI::Router as ZInt; - const PEER: ZInt = WhatAmI::Peer as ZInt; - match value { - CLIENT => Some(WhatAmI::Client), - ROUTER => Some(WhatAmI::Router), - PEER => Some(WhatAmI::Peer), - _ => None, +impl FromStr for WhatAmI { + type Err = ZError; + + fn from_str(s: &str) -> Result { + match s { + WAI_STR_R => Ok(WhatAmI::Router), + WAI_STR_P => Ok(WhatAmI::Peer), + WAI_STR_C => Ok(WhatAmI::Client), + _ => bail!( + "{s} is not a valid WhatAmI value. Valid values are: {WAI_STR_R}, {WAI_STR_P}, {WAI_STR_C}." + ), } } } @@ -76,6 +86,176 @@ impl fmt::Display for WhatAmI { } } +impl From for u8 { + fn from(w: WhatAmI) -> Self { + w as u8 + } +} + +#[repr(transparent)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct WhatAmIMatcher(NonZeroU8); + +impl WhatAmIMatcher { + // We use the 7th bit for detecting whether the WhatAmIMatcher is non-zero + const U8_0: u8 = 1 << 7; + const U8_R: u8 = Self::U8_0 | WhatAmI::U8_R; + const U8_P: u8 = Self::U8_0 | WhatAmI::U8_P; + const U8_C: u8 = Self::U8_0 | WhatAmI::U8_C; + const U8_R_P: u8 = Self::U8_0 | WhatAmI::U8_R | WhatAmI::U8_P; + const U8_P_C: u8 = Self::U8_0 | WhatAmI::U8_P | WhatAmI::U8_C; + const U8_R_C: u8 = Self::U8_0 | WhatAmI::U8_R | WhatAmI::U8_C; + const U8_R_P_C: u8 = Self::U8_0 | WhatAmI::U8_R | WhatAmI::U8_P | WhatAmI::U8_C; + + pub const fn empty() -> Self { + Self(unsafe { NonZeroU8::new_unchecked(Self::U8_0) }) + } + + pub const fn router(self) -> Self { + Self(unsafe { NonZeroU8::new_unchecked(self.0.get() | Self::U8_R) }) + } + + pub const fn peer(self) -> Self { + Self(unsafe { NonZeroU8::new_unchecked(self.0.get() | Self::U8_P) }) + } + + pub const fn client(self) -> Self { + Self(unsafe { NonZeroU8::new_unchecked(self.0.get() | Self::U8_C) }) + } + + pub const fn is_empty(&self) -> bool { + self.0.get() == Self::U8_0 + } + + pub const fn matches(&self, w: WhatAmI) -> bool { + (self.0.get() & w as u8) != 0 + } + + pub const fn to_str(self) -> &'static str { + match self.0.get() { + Self::U8_0 => "", + Self::U8_R => WAI_STR_R, + Self::U8_P => WAI_STR_P, + Self::U8_C => WAI_STR_C, + Self::U8_R_P => const_str::concat!(WAI_STR_R, "|", WAI_STR_P), + Self::U8_R_C => const_str::concat!(WAI_STR_R, "|", WAI_STR_C), + Self::U8_P_C => const_str::concat!(WAI_STR_P, "|", WAI_STR_C), + Self::U8_R_P_C => const_str::concat!(WAI_STR_R, "|", WAI_STR_P, "|", WAI_STR_C), + _ => unreachable!(), + } + } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let mut waim = WhatAmIMatcher::empty(); + if rng.gen_bool(0.5) { + waim = waim.router(); + } + if rng.gen_bool(0.5) { + waim = waim.peer(); + } + if rng.gen_bool(0.5) { + waim = waim.client(); + } + waim + } +} + +impl TryFrom for WhatAmIMatcher { + type Error = (); + + fn try_from(v: u8) -> Result { + const MIN: u8 = 0; + const MAX: u8 = WhatAmI::U8_R | WhatAmI::U8_P | WhatAmI::U8_C; + + if (MIN..=MAX).contains(&v) { + Ok(WhatAmIMatcher(unsafe { + NonZeroU8::new_unchecked(Self::U8_0 | v) + })) + } else { + Err(()) + } + } +} + +impl FromStr for WhatAmIMatcher { + type Err = (); + + fn from_str(s: &str) -> Result { + let mut inner = 0; + for s in s.split('|') { + match s.trim() { + "" => {} + WAI_STR_R => inner |= WhatAmI::U8_R, + WAI_STR_P => inner |= WhatAmI::U8_P, + WAI_STR_C => inner |= WhatAmI::U8_C, + _ => return Err(()), + } + } + Self::try_from(inner) + } +} + +impl fmt::Display for WhatAmIMatcher { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.to_str()) + } +} + +impl From for u8 { + fn from(w: WhatAmIMatcher) -> u8 { + w.0.get() + } +} + +impl BitOr for WhatAmIMatcher +where + NonZeroU8: BitOr, +{ + type Output = Self; + + fn bitor(self, rhs: T) -> Self::Output { + WhatAmIMatcher(self.0 | rhs) + } +} + +impl BitOr for WhatAmIMatcher { + type Output = Self; + + fn bitor(self, rhs: WhatAmI) -> Self::Output { + self | rhs as u8 + } +} + +impl BitOr for WhatAmIMatcher { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self::Output { + self | rhs.0 + } +} + +impl BitOr for WhatAmI { + type Output = WhatAmIMatcher; + + fn bitor(self, rhs: Self) -> Self::Output { + WhatAmIMatcher(unsafe { + NonZeroU8::new_unchecked(self as u8 | rhs as u8 | WhatAmIMatcher::U8_0) + }) + } +} + +impl From for WhatAmIMatcher { + fn from(w: WhatAmI) -> Self { + WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(w as u8 | WhatAmIMatcher::U8_0) }) + } +} + +// Serde impl serde::Serialize for WhatAmI { fn serialize(&self, serializer: S) -> Result where @@ -123,80 +303,6 @@ impl<'de> serde::Deserialize<'de> for WhatAmI { } } -impl From for ZInt { - fn from(w: WhatAmI) -> Self { - w as ZInt - } -} - -#[repr(transparent)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct WhatAmIMatcher(pub NonZeroU8); - -impl WhatAmIMatcher { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(rng.gen_range(128..136)) }) - } - - pub fn try_from>(i: T) -> Option { - let i = i.try_into().ok()?; - if 127 < i && i < 136 { - Some(WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(i) })) - } else { - None - } - } - - pub fn is_empty(self) -> bool { - self.0.get() == 128 - } - - pub fn empty() -> Self { - WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(128) }) - } - - pub fn matches(self, w: WhatAmI) -> bool { - (self.0.get() & w as u8) != 0 - } - - pub fn to_str(self) -> &'static str { - match self.0.get() { - 128 => "", - 129 => "router", - 130 => "peer", - 132 => "client", - 131 => "router|peer", - 134 => "client|peer", - 133 => "client|router", - 135 => "client|router|peer", - _ => "invalid_matcher", - } - } -} - -impl FromStr for WhatAmIMatcher { - type Err = (); - - fn from_str(s: &str) -> Result { - let mut inner = 128; - for s in s.split('|') { - match s.trim() { - "" => {} - "router" => inner |= WhatAmI::Router as u8, - "client" => inner |= WhatAmI::Client as u8, - "peer" => inner |= WhatAmI::Peer as u8, - _ => return Err(()), - } - } - Self::try_from(inner).ok_or(()) - } -} - impl serde::Serialize for WhatAmIMatcher { fn serialize(&self, serializer: S) -> Result where @@ -245,52 +351,3 @@ impl<'de> serde::Deserialize<'de> for WhatAmIMatcher { deserializer.deserialize_str(WhatAmIMatcherVisitor) } } - -impl fmt::Display for WhatAmIMatcher { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.to_str()) - } -} - -impl From for ZInt { - fn from(w: WhatAmIMatcher) -> ZInt { - w.0.get() as ZInt - } -} - -impl BitOr for WhatAmIMatcher -where - NonZeroU8: BitOr, -{ - type Output = Self; - fn bitor(self, rhs: T) -> Self::Output { - WhatAmIMatcher(self.0 | rhs) - } -} - -impl BitOr for WhatAmIMatcher { - type Output = Self; - fn bitor(self, rhs: WhatAmI) -> Self::Output { - self | rhs as u8 - } -} - -impl BitOr for WhatAmIMatcher { - type Output = Self; - fn bitor(self, rhs: Self) -> Self::Output { - self | rhs.0 - } -} - -impl BitOr for WhatAmI { - type Output = WhatAmIMatcher; - fn bitor(self, rhs: Self) -> Self::Output { - WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(self as u8 | rhs as u8 | 128) }) - } -} - -impl From for WhatAmIMatcher { - fn from(w: WhatAmI) -> Self { - WhatAmIMatcher(unsafe { NonZeroU8::new_unchecked(w as u8 | 128) }) - } -} diff --git a/commons/zenoh-protocol/src/defaults.rs b/commons/zenoh-protocol/src/defaults.rs index 30cf243fde..b8bc3f9c14 100644 --- a/commons/zenoh-protocol/src/defaults.rs +++ b/commons/zenoh-protocol/src/defaults.rs @@ -13,13 +13,6 @@ // use super::core::ZInt; -// Zenoh version -// 7 6 5 4 3 2 1 0 -// +-+-+-+-+-+-+-+-+ -// | v_maj | v_min | -// +-------+-------+ -pub const VERSION: u8 = 0x07; - // The default sequence number resolution takes 4 bytes on the wire. // Given the VLE encoding of ZInt, 4 bytes result in 28 useful bits. // 2^28 = 268_435_456 => Max Seq Num = 268_435_455 diff --git a/commons/zenoh-protocol/src/lib.rs b/commons/zenoh-protocol/src/lib.rs index 450508843d..21983384be 100644 --- a/commons/zenoh-protocol/src/lib.rs +++ b/commons/zenoh-protocol/src/lib.rs @@ -27,6 +27,9 @@ pub mod scouting; pub mod transport; pub mod zenoh; +// Zenoh version +pub const VERSION: u8 = 0x08; + // Zenoh protocol uses the following conventions for message definition and representation. // // diff --git a/commons/zenoh-protocol/src/scouting/hello.rs b/commons/zenoh-protocol/src/scouting/hello.rs index 315055f44e..1311e834a4 100644 --- a/commons/zenoh-protocol/src/scouting/hello.rs +++ b/commons/zenoh-protocol/src/scouting/hello.rs @@ -17,41 +17,88 @@ use core::fmt; /// # Hello message /// +/// The [`Hello`] message is used to advertise the locators a zenoh node is reachable at. +/// The [`Hello`] message SHOULD be sent in a unicast fashion in response to a [`super::Scout`] +/// message as shown below: +/// /// ```text -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. +/// A B C +/// | SCOUT | | +/// |------------------>| | +/// | \---------------------------->| +/// | | | +/// | HELLO | | +/// |<------------------| | +/// | | HELLO | +/// |<--------------------------------------| +/// | | | +/// ``` +/// +/// Moreover, a [`Hello`] message MAY be sent in the network in a multicast +/// fashion to advertise the presence of zenoh node. The advertisement operation MAY be performed +/// periodically as shown below: +/// +///```text +/// A B C +/// | HELLO | | +/// |------------------>| | +/// | \---------------------------->| +/// | | | +/// ~ ... ~ ... ~ +/// | | | +/// | HELLO | | +/// |------------------>| | +/// | \---------------------------->| +/// | | | +/// ~ ... ~ ... ~ +/// | | | +/// ``` +/// +/// Examples of locators included in the [`Hello`] message are: +/// +/// ```text +/// udp/192.168.1.1:7447 +/// tcp/192.168.1.1:7447 +/// udp/224.0.0.224:7447 +/// tcp/localhost:7447 +/// ``` /// -/// The HELLO message is sent in any of the following three cases: -/// 1) in response to a SCOUT message; -/// 2) to (periodically) advertise (e.g., on multicast) the Peer and the locators it is reachable at; -/// 3) in a already established transport to update the corresponding peer on the new capabilities -/// (i.e., whatmai) and/or new set of locators (i.e., added or deleted). -/// Locators are expressed as: -/// -/// udp/192.168.0.2:1234 -/// tcp/192.168.0.2:1234 -/// udp/239.255.255.123:5555 -/// +/// The [`Hello`] message structure is defined as follows: +/// +/// ```text +/// Header flags: +/// - L: Locators If L==1 then the list of locators is present, else the src address is the locator +/// - X: Reserved +/// - Z: Extensions If Z==1 then zenoh extensions will follow. /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |L|W|I| HELLO | -/// +-+-+-+-+-------+ -/// ~ peer-id ~ if I==1 +/// |Z|X|L| HELLO | +/// +-+-+-+---------+ +/// | version | /// +---------------+ -/// ~ whatami ~ if W==1 -- Otherwise it is from a Router +/// |X|X|X|X|X|X|wai| (*) +/// +-+-+-+-+-+-+-+-+ +/// ~ ~ -- ZenohID /// +---------------+ -/// ~ [Locators] ~ if L==1 -- Otherwise src-address is the locator +/// ~ ~ if Flag(L)==1 -- List of locators /// +---------------+ +/// +/// (*) WhatAmI. It indicates the role of the zenoh node sending the HELLO message. +/// The valid WhatAmI values are: +/// - 0b00: Router +/// - 0b01: Peer +/// - 0b10: Client +/// - 0b11: Reserved /// ``` +/// #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub struct Hello { - pub zid: Option, + pub version: u8, pub whatami: WhatAmI, + pub zid: ZenohId, pub locators: Vec, } @@ -73,11 +120,8 @@ impl Hello { let mut rng = rand::thread_rng(); - let zid = if rng.gen_bool(0.5) { - Some(ZenohId::default()) - } else { - None - }; + let version: u8 = rng.gen(); + let zid = ZenohId::default(); let whatami = WhatAmI::rand(); let locators = if rng.gen_bool(0.5) { Vec::from_iter((1..5).into_iter().map(|_| Locator::rand())) @@ -85,6 +129,7 @@ impl Hello { vec![] }; Self { + version, zid, whatami, locators, diff --git a/commons/zenoh-protocol/src/scouting/mod.rs b/commons/zenoh-protocol/src/scouting/mod.rs index 4053522542..0853e3c6f2 100644 --- a/commons/zenoh-protocol/src/scouting/mod.rs +++ b/commons/zenoh-protocol/src/scouting/mod.rs @@ -41,12 +41,13 @@ pub struct ScoutingMessage { impl ScoutingMessage { pub fn make_scout( - what: Option, - zid_request: bool, + what: WhatAmIMatcher, + zid: Option, attachment: Option, ) -> ScoutingMessage { + let version = crate::VERSION; ScoutingMessage { - body: ScoutingBody::Scout(Scout { what, zid_request }), + body: ScoutingBody::Scout(Scout { version, what, zid }), attachment, #[cfg(feature = "stats")] size: None, @@ -54,18 +55,17 @@ impl ScoutingMessage { } pub fn make_hello( - zid: Option, - whatami: Option, - locators: Option>, + whatami: WhatAmI, + zid: ZenohId, + locators: Vec, attachment: Option, ) -> ScoutingMessage { - let whatami = whatami.unwrap_or(WhatAmI::Router); - let locators = locators.unwrap_or_default(); - + let version = crate::VERSION; ScoutingMessage { body: ScoutingBody::Hello(Hello { - zid, + version, whatami, + zid, locators, }), attachment, @@ -80,15 +80,11 @@ impl ScoutingMessage { let mut rng = rand::thread_rng(); - let attachment = if rng.gen_bool(0.5) { - Some(Attachment::rand()) - } else { - None - }; + let attachment = rng.gen_bool(0.5).then_some(Attachment::rand()); let body = match rng.gen_range(0..2) { - 0 => ScoutingBody::Hello(Hello::rand()), - 1 => ScoutingBody::Scout(Scout::rand()), + 0 => ScoutingBody::Scout(Scout::rand()), + 1 => ScoutingBody::Hello(Hello::rand()), _ => unreachable!(), }; diff --git a/commons/zenoh-protocol/src/scouting/scout.rs b/commons/zenoh-protocol/src/scouting/scout.rs index 1ac36cbd93..8e3ee18ee5 100644 --- a/commons/zenoh-protocol/src/scouting/scout.rs +++ b/commons/zenoh-protocol/src/scouting/scout.rs @@ -11,31 +11,62 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::whatami::WhatAmIMatcher; +use crate::core::{whatami::WhatAmIMatcher, ZenohId}; /// # Scout message /// +/// The [`Scout`] message MAY be sent at any point in time to discover the available zenoh nodes in the +/// network. The [`Scout`] message SHOULD be sent in a multicast or broadcast fashion. Upon receiving a +/// [`Scout`] message, a zenoh node MUST first verify whether the matching criteria are satisfied, then +/// it SHOULD reply with a [`super::Hello`] message in a unicast fashion including all the requested +/// information. +/// +/// The scouting message flow is the following: +/// /// ```text -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. +/// A B C +/// | SCOUT | | +/// |------------------>| | +/// | \---------------------------->| +/// | | | +/// | HELLO | | +/// |<------------------| | +/// | | HELLO | +/// |<--------------------------------------| +/// | | | +/// ``` +/// +/// The SCOUT message structure is defined as follows: /// -/// The SCOUT message can be sent at any point in time to solicit HELLO messages from matching parties. +/// ```text +/// Header flags: +/// - I: ZenohID If I==1 then the ZenohID of the scouter is present. +/// - X: Reserved +/// - Z: Extensions If Z==1 then zenoh extensions will follow. /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |X|W|I| SCOUT | -/// +-+-+-+-+-------+ -/// ~ what ~ if W==1 -- Otherwise implicitly scouting for Routers +/// |Z|X|I| SCOUT | +/// +-+-+-+---------+ +/// | version | +/// +---------------+ +/// |X|X|X|X|X| what| (*) +/// +-+-+-+-+-+-+-+-+ +/// ~ ~ if Flag(I)==1 -- ZenohID /// +---------------+ +/// +/// (*) What. It indicates a bitmap of WhatAmI interests. +/// The valid bitflags are: +/// - 0b001: Router +/// - 0b010: Peer +/// - 0b100: Client /// ``` #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Scout { - pub what: Option, - pub zid_request: bool, + pub version: u8, + pub what: WhatAmIMatcher, + pub zid: Option, } impl Scout { @@ -45,12 +76,9 @@ impl Scout { let mut rng = rand::thread_rng(); - let what = if rng.gen_bool(0.5) { - Some(WhatAmIMatcher::rand()) - } else { - None - }; - let zid_request = rng.gen_bool(0.5); - Self { what, zid_request } + let version: u8 = rng.gen(); + let what = WhatAmIMatcher::rand(); + let zid = rng.gen_bool(0.5).then_some(ZenohId::rand()); + Self { version, what, zid } } } diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index 524ca9a82a..51a4f1417c 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -33,7 +33,7 @@ use zenoh_buffers::{ writer::{HasWriter, Writer}, }; use zenoh_cfg_properties::Properties; -use zenoh_codec::{RCodec, WCodec, Zenoh060}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_protocol::{ core::{EndPoint, Locator}, transport::TransportMessage, @@ -155,7 +155,7 @@ impl LinkUnicast { // Create the buffer for serializing the message let mut buff = vec![]; let mut writer = buff.writer(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); // Reserve 16 bits to write the length if self.is_streamed() { @@ -201,7 +201,7 @@ impl LinkUnicast { }; let mut reader = buffer.reader(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut messages: Vec = Vec::with_capacity(1); while reader.can_read() { @@ -293,7 +293,7 @@ impl LinkMulticast { // Create the buffer for serializing the message let mut buff = vec![]; let mut writer = buff.writer(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); codec .write(&mut writer, msg) .map_err(|_| zerror!("Encoding error on link: {}", self))?; @@ -311,7 +311,7 @@ impl LinkMulticast { buffer.truncate(n); let mut reader = buffer.reader(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut messages: Vec = Vec::with_capacity(1); while reader.can_read() { diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 081557a919..b5ad3aee5e 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ writer::{BacktrackableWriter, DidntWrite, HasWriter, Writer}, BBuf, ZBufReader, }; -use zenoh_codec::{WCodec, Zenoh060}; +use zenoh_codec::{WCodec, Zenoh080}; use zenoh_protocol::{ core::{Channel, Reliability, ZInt}, transport::{FrameHeader, FrameKind, TransportMessage}, @@ -194,7 +194,7 @@ impl Encode<&TransportMessage> for &mut WBatch { let mut writer = self.buffer.writer(); let mark = writer.mark(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); codec.write(&mut writer, message).map_err(|e| { // Revert the write operation writer.rewind(mark); @@ -239,7 +239,7 @@ impl Encode<&ZenohMessage> for &mut WBatch { let mut writer = self.buffer.writer(); let mark = writer.mark(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); codec.write(&mut writer, message).map_err(|_| { // Revert the write operation writer.rewind(mark); @@ -263,7 +263,7 @@ impl Encode<(&ZenohMessage, Channel, ZInt)> for &mut WBatch { let mut writer = self.buffer.writer(); let mark = writer.mark(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); // Write the frame header let frame = FrameHeader { channel, @@ -308,7 +308,7 @@ impl Encode<(&mut ZBufReader<'_>, Channel, ZInt)> for &mut WBatch { let (reader, channel, sn) = message; let mut writer = self.buffer.writer(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); // Mark the buffer for the writing operation let mark = writer.mark(); diff --git a/io/zenoh-transport/src/common/defragmentation.rs b/io/zenoh-transport/src/common/defragmentation.rs index 67b6577440..c059f98a5c 100644 --- a/io/zenoh-transport/src/common/defragmentation.rs +++ b/io/zenoh-transport/src/common/defragmentation.rs @@ -13,7 +13,7 @@ // use super::seq_num::SeqNum; use zenoh_buffers::{reader::HasReader, SplitBuffer, ZBuf, ZSlice}; -use zenoh_codec::{RCodec, Zenoh060Reliability}; +use zenoh_codec::{RCodec, Zenoh080Reliability}; use zenoh_protocol::{ core::{Reliability, ZInt}, zenoh::ZenohMessage, @@ -87,7 +87,7 @@ impl DefragBuffer { #[inline(always)] pub(crate) fn defragment(&mut self) -> Option { let mut reader = self.buffer.reader(); - let rcodec = Zenoh060Reliability::new(self.reliability); + let rcodec = Zenoh080Reliability::new(self.reliability); let res: Option = rcodec.read(&mut reader).ok(); self.clear(); res diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index d6da78b587..8217c5530d 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -28,7 +28,7 @@ use zenoh_buffers::{ writer::HasWriter, ZBuf, }; -use zenoh_codec::{WCodec, Zenoh060}; +use zenoh_codec::{WCodec, Zenoh080}; use zenoh_config::QueueSizeConf; use zenoh_core::zlock; use zenoh_protocol::{ @@ -211,7 +211,7 @@ impl StageIn { self.fragbuf.clear(); let mut writer = self.fragbuf.writer(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); codec.write(&mut writer, &*msg).unwrap(); // Fragment the whole message @@ -696,7 +696,7 @@ mod tests { reader::{DidntRead, HasReader}, ZBuf, }; - use zenoh_codec::{RCodec, Zenoh060}; + use zenoh_codec::{RCodec, Zenoh080}; use zenoh_protocol::{ core::{Channel, CongestionControl, Priority, Reliability, ZInt}, defaults::{BATCH_SIZE, SEQ_NUM_RES}, @@ -764,7 +764,7 @@ mod tests { let bytes = batch.as_bytes(); // Deserialize the messages let mut reader = bytes.reader(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); loop { let res: Result = codec.read(&mut reader); diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index a1a125a969..436ffebce1 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -34,7 +34,8 @@ use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::NewLinkChannelSender; use zenoh_protocol::{ core::{EndPoint, Locator, Priority, WhatAmI, ZInt, ZenohId}, - defaults::{BATCH_SIZE, SEQ_NUM_RES, VERSION}, + defaults::{BATCH_SIZE, SEQ_NUM_RES}, + VERSION, }; use zenoh_result::{bail, ZResult}; #[cfg(feature = "shared-memory")] diff --git a/io/zenoh-transport/src/multicast/link.rs b/io/zenoh-transport/src/multicast/link.rs index f89f2dd7ad..c02d5fc65c 100644 --- a/io/zenoh-transport/src/multicast/link.rs +++ b/io/zenoh-transport/src/multicast/link.rs @@ -28,7 +28,7 @@ use std::{ time::{Duration, Instant}, }; use zenoh_buffers::reader::{HasReader, Reader}; -use zenoh_codec::{RCodec, Zenoh060}; +use zenoh_codec::{RCodec, Zenoh080}; use zenoh_core::zlock; use zenoh_link::{LinkMulticast, Locator}; use zenoh_protocol::{ @@ -351,7 +351,7 @@ async fn rx_task( } // The codec - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); // The pool of buffers let mtu = link.get_mtu() as usize; diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs index 12d4d4c403..7e45ce6616 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs @@ -14,14 +14,14 @@ use super::{init_syn, AResult}; use crate::{ unicast::establishment::{ - authenticator::AuthenticatedPeerLink, Cookie, EstablishmentProperties, Zenoh060Cookie, + authenticator::AuthenticatedPeerLink, Cookie, EstablishmentProperties, Zenoh080Cookie, }, TransportManager, }; use rand::Rng; use std::convert::TryFrom; use zenoh_buffers::{writer::HasWriter, ZSlice}; -use zenoh_codec::{WCodec, Zenoh060}; +use zenoh_codec::{WCodec, Zenoh080}; use zenoh_core::{zasynclock, zasyncread}; use zenoh_crypto::hmac; use zenoh_link::LinkUnicast; @@ -111,10 +111,10 @@ pub(super) async fn send( let mut encrypted = vec![]; let mut writer = encrypted.writer(); - let mut codec = Zenoh060Cookie { + let mut codec = Zenoh080Cookie { prng: &mut *zasynclock!(manager.prng), cipher: &manager.cipher, - codec: Zenoh060::default(), + codec: Zenoh080::default(), }; codec.write(&mut writer, &cookie).map_err(|_| { ( diff --git a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs b/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs index 4f07cebaad..8c091c99c8 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs @@ -16,10 +16,10 @@ use super::super::{ {Cookie, EstablishmentProperties}, }; use super::AResult; -use crate::{unicast::establishment::cookie::Zenoh060Cookie, TransportManager}; +use crate::{unicast::establishment::cookie::Zenoh080Cookie, TransportManager}; use std::{convert::TryFrom, time::Duration}; use zenoh_buffers::reader::HasReader; -use zenoh_codec::{RCodec, Zenoh060}; +use zenoh_codec::{RCodec, Zenoh080}; use zenoh_core::{zasynclock, zasyncread}; use zenoh_crypto::hmac; use zenoh_link::LinkUnicast; @@ -98,10 +98,10 @@ pub(super) async fn recv( // Decrypt the cookie with the cyper let mut reader = encrypted.reader(); - let mut codec = Zenoh060Cookie { + let mut codec = Zenoh080Cookie { prng: &mut *zasynclock!(manager.prng), cipher: &manager.cipher, - codec: Zenoh060::default(), + codec: Zenoh080::default(), }; let mut cookie: Cookie = codec.read(&mut reader).map_err(|_| { ( diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs index 3dd29c7c06..33fe848985 100644 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs @@ -29,7 +29,7 @@ use zenoh_buffers::{ writer::{DidntWrite, HasWriter, Writer}, }; use zenoh_cfg_properties::config::ZN_AUTH_RSA_KEY_SIZE_DEFAULT; -use zenoh_codec::{RCodec, WCodec, Zenoh060}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_config::Config; use zenoh_core::{zasynclock, zparse}; use zenoh_crypto::PseudoRng; @@ -92,7 +92,7 @@ impl From for ZPrivateKey { } } -impl WCodec<&ZPublicKey, &mut W> for Zenoh060 +impl WCodec<&ZPublicKey, &mut W> for Zenoh080 where W: Writer, { @@ -105,7 +105,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -138,7 +138,7 @@ struct InitSynProperty { alice_pubkey: ZPublicKey, } -impl WCodec<&InitSynProperty, &mut W> for Zenoh060 +impl WCodec<&InitSynProperty, &mut W> for Zenoh080 where W: Writer, { @@ -151,7 +151,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -183,7 +183,7 @@ struct InitAckProperty { nonce_encrypted_with_alice_pubkey: Vec, } -impl WCodec<&InitAckProperty, &mut W> for Zenoh060 +impl WCodec<&InitAckProperty, &mut W> for Zenoh080 where W: Writer, { @@ -196,7 +196,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -225,7 +225,7 @@ struct OpenSynProperty { nonce_encrypted_with_bob_pubkey: Vec, } -impl WCodec<&OpenSynProperty, &mut W> for Zenoh060 +impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 where W: Writer, { @@ -237,7 +237,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -395,7 +395,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { }; let mut wbuf = vec![]; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut writer = wbuf.writer(); codec .write(&mut writer, &init_syn_property) @@ -415,7 +415,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { Some(pk) => { // Decode the multilink attachment let mut reader = pk.reader(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { zerror!( @@ -465,7 +465,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { } // Create the InitAck attachment - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut wbuf = vec![]; let mut writer = wbuf.writer(); @@ -532,7 +532,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { None => return Ok(None), }; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut reader = pk.reader(); let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { @@ -580,7 +580,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { ) -> ZResult>> { match property { (Some(att), Some(cke)) => { - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut reader = att.reader(); let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs b/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs index e950bf2fa6..a2e9a39e0a 100644 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs @@ -26,7 +26,7 @@ use zenoh_buffers::{ writer::{DidntWrite, HasWriter, Writer}, ZSlice, }; -use zenoh_codec::{RCodec, WCodec, Zenoh060}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_config::Config; use zenoh_crypto::PseudoRng; use zenoh_protocol::core::{ZInt, ZenohId}; @@ -56,7 +56,7 @@ struct InitSynProperty { shm: ZSlice, } -impl WCodec<&InitSynProperty, &mut W> for Zenoh060 +impl WCodec<&InitSynProperty, &mut W> for Zenoh080 where W: Writer, { @@ -69,7 +69,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -100,7 +100,7 @@ struct InitAckProperty { shm: ZSlice, } -impl WCodec<&InitAckProperty, &mut W> for Zenoh060 +impl WCodec<&InitAckProperty, &mut W> for Zenoh080 where W: Writer, { @@ -113,7 +113,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -141,7 +141,7 @@ struct OpenSynProperty { challenge: ZInt, } -impl WCodec<&OpenSynProperty, &mut W> for Zenoh060 +impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 where W: Writer, { @@ -153,7 +153,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -245,7 +245,7 @@ impl PeerAuthenticatorTrait for SharedMemoryAuthenticator { shm: self.buffer.info.serialize().unwrap().into(), }; let mut buff = vec![]; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut writer = buff.writer(); codec @@ -269,7 +269,7 @@ impl PeerAuthenticatorTrait for SharedMemoryAuthenticator { } }; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut reader = buffer.reader(); let mut init_syn_property: InitSynProperty = codec @@ -336,7 +336,7 @@ impl PeerAuthenticatorTrait for SharedMemoryAuthenticator { } }; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut reader = buffer.reader(); let mut init_ack_property: InitAckProperty = codec @@ -401,7 +401,7 @@ impl PeerAuthenticatorTrait for SharedMemoryAuthenticator { } }; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut reader = buffer.reader(); let open_syn_property: OpenSynProperty = codec diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs b/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs index 17cec02bab..0649e2ad28 100644 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs +++ b/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs @@ -26,7 +26,7 @@ use zenoh_buffers::{ writer::{DidntWrite, HasWriter, Writer}, }; use zenoh_cfg_properties::Properties; -use zenoh_codec::{RCodec, WCodec, Zenoh060}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_config::Config; use zenoh_core::{zasynclock, zasyncread, zasyncwrite}; use zenoh_crypto::hmac; @@ -66,7 +66,7 @@ struct InitSynProperty { version: ZInt, } -impl WCodec<&InitSynProperty, &mut W> for Zenoh060 +impl WCodec<&InitSynProperty, &mut W> for Zenoh080 where W: Writer, { @@ -78,7 +78,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -103,7 +103,7 @@ struct InitAckProperty { nonce: ZInt, } -impl WCodec<&InitAckProperty, &mut W> for Zenoh060 +impl WCodec<&InitAckProperty, &mut W> for Zenoh080 where W: Writer, { @@ -115,7 +115,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -143,7 +143,7 @@ struct OpenSynProperty { hmac: Vec, } -impl WCodec<&OpenSynProperty, &mut W> for Zenoh060 +impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 where W: Writer, { @@ -156,7 +156,7 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { @@ -273,7 +273,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { version: USRPWD_VERSION, }; let mut wbuf = vec![]; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut writer = wbuf.writer(); codec .write(&mut writer, &init_syn_property) @@ -296,7 +296,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { ) })?; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut reader = p.reader(); let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { @@ -343,7 +343,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { ) })?; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut reader = p.reader(); let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { @@ -386,7 +386,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { ) })?; - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let mut reader = a.reader(); let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 30503830a1..f64c462280 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -12,11 +12,12 @@ // ZettaScale Zenoh Team, // use super::properties::EstablishmentProperties; +use std::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, HasReader, Reader}, writer::{DidntWrite, HasWriter, Writer}, }; -use zenoh_codec::{RCodec, WCodec, Zenoh060}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_protocol::core::{Property, WhatAmI, ZInt, ZenohId}; @@ -30,14 +31,14 @@ pub struct Cookie { pub properties: EstablishmentProperties, } -impl WCodec<&Cookie, &mut W> for Zenoh060 +impl WCodec<&Cookie, &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Cookie) -> Self::Output { - let wai: ZInt = x.whatami.into(); + let wai: u8 = x.whatami.into(); self.write(&mut *writer, wai)?; self.write(&mut *writer, &x.zid)?; self.write(&mut *writer, x.sn_resolution)?; @@ -50,15 +51,15 @@ where } } -impl RCodec for Zenoh060 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let wai: ZInt = self.read(&mut *reader)?; - let whatami = WhatAmI::try_from(wai).ok_or(DidntRead)?; + let wai: u8 = self.read(&mut *reader)?; + let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; let zid: ZenohId = self.read(&mut *reader)?; let sn_resolution: ZInt = self.read(&mut *reader)?; let is_qos: u8 = self.read(&mut *reader)?; @@ -83,13 +84,13 @@ where } } -pub(super) struct Zenoh060Cookie<'a> { +pub(super) struct Zenoh080Cookie<'a> { pub(super) cipher: &'a BlockCipher, pub(super) prng: &'a mut PseudoRng, - pub(super) codec: Zenoh060, + pub(super) codec: Zenoh080, } -impl WCodec<&Cookie, &mut W> for &mut Zenoh060Cookie<'_> +impl WCodec<&Cookie, &mut W> for &mut Zenoh080Cookie<'_> where W: Writer, { @@ -108,7 +109,7 @@ where } } -impl RCodec for &mut Zenoh060Cookie<'_> +impl RCodec for &mut Zenoh080Cookie<'_> where R: Reader, { @@ -182,7 +183,7 @@ mod tests { }; } - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); run!(Cookie, Cookie::rand(), codec); let mut prng = PseudoRng::from_entropy(); @@ -190,10 +191,10 @@ mod tests { prng.fill(&mut key[..]); let cipher = BlockCipher::new(key); - let mut codec = Zenoh060Cookie { + let mut codec = Zenoh080Cookie { prng: &mut prng, cipher: &cipher, - codec: Zenoh060::default(), + codec: Zenoh080::default(), }; run!(Cookie, Cookie::rand(), codec); diff --git a/io/zenoh-transport/src/unicast/establishment/properties.rs b/io/zenoh-transport/src/unicast/establishment/properties.rs index 31af09c9c0..67e6d2d1f3 100644 --- a/io/zenoh-transport/src/unicast/establishment/properties.rs +++ b/io/zenoh-transport/src/unicast/establishment/properties.rs @@ -16,7 +16,7 @@ use std::{ ops::{Deref, DerefMut}, }; use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZBuf}; -use zenoh_codec::{RCodec, WCodec, Zenoh060}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_protocol::{ common::Attachment, core::{Property, ZInt}, @@ -71,7 +71,7 @@ impl TryFrom<&EstablishmentProperties> for Attachment { let mut zbuf = ZBuf::default(); let mut writer = zbuf.writer(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); codec .write(&mut writer, eps.0.as_slice()) @@ -100,7 +100,7 @@ impl TryFrom<&Attachment> for EstablishmentProperties { fn try_from(att: &Attachment) -> Result { let mut reader = att.buffer.reader(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let ps: Vec = codec.read(&mut reader).map_err(|_| zerror!(""))?; EstablishmentProperties::try_from(ps) diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/link.rs index 6528b14839..8761e88364 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/link.rs @@ -27,7 +27,7 @@ use std::sync::Arc; use std::time::Duration; use zenoh_buffers::reader::{HasReader, Reader}; use zenoh_buffers::ZSlice; -use zenoh_codec::{RCodec, Zenoh060}; +use zenoh_codec::{RCodec, Zenoh080}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::transport::TransportMessage; use zenoh_result::{bail, zerror, ZResult}; @@ -257,7 +257,7 @@ async fn rx_task_stream( Ok(Action::Stop) } - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); // The pool of buffers let mtu = link.get_mtu() as usize; @@ -326,7 +326,7 @@ async fn rx_task_dgram( Ok(Action::Stop) } - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); // The pool of buffers let mtu = link.get_mtu() as usize; diff --git a/zenoh/src/net/runtime/orchestrator.rs b/zenoh/src/net/runtime/orchestrator.rs index 6b5a935b8b..fd90d7f484 100644 --- a/zenoh/src/net/runtime/orchestrator.rs +++ b/zenoh/src/net/runtime/orchestrator.rs @@ -20,7 +20,7 @@ use std::net::{IpAddr, Ipv6Addr, SocketAddr}; use std::time::Duration; use zenoh_buffers::reader::DidntRead; use zenoh_buffers::{reader::HasReader, writer::HasWriter}; -use zenoh_codec::{RCodec, WCodec, Zenoh060}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_config::{unwrap_or_default, EndPoint, ModeDependent}; use zenoh_link::Locator; use zenoh_protocol::{ @@ -485,10 +485,10 @@ impl Runtime { let send = async { let mut delay = SCOUT_INITIAL_PERIOD; - let scout = ScoutingMessage::make_scout(Some(matcher), true, None); + let scout = ScoutingMessage::make_scout(matcher, None, None); let mut wbuf = vec![]; let mut writer = wbuf.writer(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); codec.write(&mut writer, &scout).unwrap(); loop { @@ -530,7 +530,7 @@ impl Runtime { match socket.recv_from(&mut buf).await { Ok((n, peer)) => { let mut reader = buf.as_slice()[..n].reader(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let res: Result = codec.read(&mut reader); if let Ok(msg) = res { log::trace!("Received {:?} from {}", msg.body, peer); @@ -642,17 +642,10 @@ impl Runtime { addr: &SocketAddr, ) { Runtime::scout(ucast_sockets, what, addr, move |hello| async move { - match &hello.zid { - Some(zid) => { - if !hello.locators.is_empty() { - self.connect_peer(zid, &hello.locators).await - } else { - log::warn!("Received Hello with no locators: {:?}", hello); - } - } - None => { - log::warn!("Received Hello with no zid: {:?}", hello); - } + if !hello.locators.is_empty() { + self.connect_peer(&hello.zid, &hello.locators).await + } else { + log::warn!("Received Hello with no locators: {:?}", hello); } Loop::Continue }) @@ -697,29 +690,21 @@ impl Runtime { } let mut reader = buf.as_slice()[..n].reader(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); let res: Result = codec.read(&mut reader); if let Ok(msg) = res { log::trace!("Received {:?} from {}", msg.body, peer); - if let ScoutingBody::Scout(Scout { - what, zid_request, .. - }) = &msg.body - { - let what = what.or(Some(WhatAmI::Router.into())).unwrap(); + if let ScoutingBody::Scout(Scout { what, .. }) = &msg.body { if what.matches(self.whatami) { let mut wbuf = vec![]; let mut writer = wbuf.writer(); - let codec = Zenoh060::default(); + let codec = Zenoh080::default(); - let zid = if *zid_request { - Some(self.manager().zid()) - } else { - None - }; + let zid = self.manager().zid(); let hello = ScoutingMessage::make_hello( + self.whatami, zid, - Some(self.whatami), - Some(self.get_locators()), + self.get_locators(), None, ); let socket = get_best_match(&peer.ip(), ucast_sockets).unwrap(); From afb02d88755cfc487911990c2cb925bcdb73a254 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 1 Feb 2023 11:33:21 +0100 Subject: [PATCH 010/203] Fix code fmt --- commons/zenoh-codec/tests/codec.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 59fe9d8c93..0e7347a8ed 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -230,7 +230,6 @@ fn codec_hello() { run!(Hello, Hello::rand()); } - #[test] fn codec_scouting() { run!(ScoutingMessage, ScoutingMessage::rand()); From d27354d381ca506e045190b978ae56346ee22437 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 1 Feb 2023 12:44:11 +0100 Subject: [PATCH 011/203] Fix zenoh-protocol no_std --- Cargo.lock | 34 +++++++++++++++++----- Cargo.toml | 1 + commons/zenoh-protocol/Cargo.toml | 2 +- commons/zenoh-protocol/src/core/whatami.rs | 9 +++--- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 208b1a0166..e2862fce21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -643,18 +643,32 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" -[[package]] -name = "const-str" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5bc011a04793b8ce7bca0efd59e3697c2061760df6efbb8c895e8a81548db67" - [[package]] name = "const_fn" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" +[[package]] +name = "const_format" +version = "0.2.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7309d9b4d3d2c0641e018d449232f2e28f1b22933c137f157d3dbc14228b8c0e" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f47bf7270cf70d370f8f98c1abb6d2d4cf60a6845d30e05bfb90c6568650" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -3354,6 +3368,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "universal-hash" version = "0.4.1" @@ -4190,7 +4210,7 @@ dependencies = [ name = "zenoh-protocol" version = "0.7.0-rc" dependencies = [ - "const-str", + "const_format", "defmt", "hex", "lazy_static", diff --git a/Cargo.toml b/Cargo.toml index 365612ef3d..6cc98d303e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,6 +77,7 @@ async-trait = "0.1.60" base64 = "0.21.0" bincode = "1.3.3" clap = "3.2.23" +const_format = { version = "0.2.30", default-features = false } crc = "3.0.0" criterion = "0.4.0" defmt = { version = "0.3.2", features = ["alloc"] } diff --git a/commons/zenoh-protocol/Cargo.toml b/commons/zenoh-protocol/Cargo.toml index 62ec7a4995..3878d797ee 100644 --- a/commons/zenoh-protocol/Cargo.toml +++ b/commons/zenoh-protocol/Cargo.toml @@ -40,7 +40,7 @@ complete_n = [] defmt = ["dep:defmt", "uhlc/defmt", "zenoh-buffers/defmt"] [dependencies] -const-str = "0.5.3" +const_format = { workspace = true } defmt = { workspace = true, optional = true } hex = { workspace = true, features = ["alloc"] } rand = { workspace = true, features = ["alloc", "getrandom"], optional = true } diff --git a/commons/zenoh-protocol/src/core/whatami.rs b/commons/zenoh-protocol/src/core/whatami.rs index 34455b2a6c..2dcc422789 100644 --- a/commons/zenoh-protocol/src/core/whatami.rs +++ b/commons/zenoh-protocol/src/core/whatami.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use alloc::string::String; +use const_format::formatcp; use core::{convert::TryFrom, fmt, num::NonZeroU8, ops::BitOr, str::FromStr}; use zenoh_result::{bail, ZError}; @@ -138,10 +139,10 @@ impl WhatAmIMatcher { Self::U8_R => WAI_STR_R, Self::U8_P => WAI_STR_P, Self::U8_C => WAI_STR_C, - Self::U8_R_P => const_str::concat!(WAI_STR_R, "|", WAI_STR_P), - Self::U8_R_C => const_str::concat!(WAI_STR_R, "|", WAI_STR_C), - Self::U8_P_C => const_str::concat!(WAI_STR_P, "|", WAI_STR_C), - Self::U8_R_P_C => const_str::concat!(WAI_STR_R, "|", WAI_STR_P, "|", WAI_STR_C), + Self::U8_R_P => formatcp!("{}|{}", WAI_STR_R, WAI_STR_P), + Self::U8_R_C => formatcp!("{}|{}", WAI_STR_R, WAI_STR_C), + Self::U8_P_C => formatcp!("{}|{}", WAI_STR_P, WAI_STR_C), + Self::U8_R_P_C => formatcp!("{}|{}|{}", WAI_STR_R, WAI_STR_P, WAI_STR_C), _ => unreachable!(), } } From 5bf94a6e65a28c3261f0c0a2e4255cefdf2d8387 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 3 Feb 2023 09:25:06 +0100 Subject: [PATCH 012/203] Cleanup. New Init message. --- commons/zenoh-codec/src/common/attachment.rs | 81 ++--- commons/zenoh-codec/src/common/extension.rs | 126 ++++++- commons/zenoh-codec/src/common/mod.rs | 2 +- commons/zenoh-codec/src/common/priority.rs | 7 +- commons/zenoh-codec/src/core/mod.rs | 37 +++ commons/zenoh-codec/src/lib.rs | 11 +- commons/zenoh-codec/src/scouting/hello.rs | 31 +- commons/zenoh-codec/src/scouting/mod.rs | 27 +- commons/zenoh-codec/src/scouting/scout.rs | 32 +- commons/zenoh-codec/src/transport/close.rs | 52 ++- commons/zenoh-codec/src/transport/frame.rs | 265 +++++++-------- commons/zenoh-codec/src/transport/init.rs | 311 ++++++++++++------ commons/zenoh-codec/src/transport/join.rs | 199 ++++++----- .../zenoh-codec/src/transport/keepalive.rs | 50 +-- commons/zenoh-codec/src/transport/mod.rs | 39 +-- commons/zenoh-codec/src/transport/open.rs | 144 ++++---- commons/zenoh-codec/src/zenoh/data.rs | 14 +- commons/zenoh-codec/src/zenoh/declare.rs | 69 ++-- commons/zenoh-codec/src/zenoh/linkstate.rs | 7 +- commons/zenoh-codec/src/zenoh/mod.rs | 6 +- commons/zenoh-codec/src/zenoh/pull.rs | 7 +- commons/zenoh-codec/src/zenoh/query.rs | 7 +- commons/zenoh-codec/src/zenoh/routing.rs | 7 +- commons/zenoh-codec/src/zenoh/unit.rs | 5 +- .../zenoh-protocol/src/common/extension.rs | 30 +- commons/zenoh-protocol/src/common/mod.rs | 13 - commons/zenoh-protocol/src/defaults.rs | 16 +- commons/zenoh-protocol/src/scouting/hello.rs | 6 + commons/zenoh-protocol/src/scouting/mod.rs | 21 +- commons/zenoh-protocol/src/scouting/scout.rs | 6 + commons/zenoh-protocol/src/transport/close.rs | 91 +++-- commons/zenoh-protocol/src/transport/init.rs | 231 ++++++++++--- commons/zenoh-protocol/src/transport/mod.rs | 138 ++------ commons/zenoh-protocol/src/transport/open.rs | 50 ++- 34 files changed, 1247 insertions(+), 891 deletions(-) diff --git a/commons/zenoh-codec/src/common/attachment.rs b/commons/zenoh-codec/src/common/attachment.rs index 14b598aa39..eb554efda6 100644 --- a/commons/zenoh-codec/src/common/attachment.rs +++ b/commons/zenoh-codec/src/common/attachment.rs @@ -35,29 +35,30 @@ where #[allow(unused_mut)] // mut required with #[cfg(feature = "shared-memory")] let mut header = tmsg::id::ATTACHMENT; - #[cfg(feature = "shared-memory")] - { - let has_shminfo = x - .buffer - .zslices() - .any(|s| s.buf.as_any().type_id() == TypeId::of::()); - if has_shminfo { - header |= tmsg::flag::Z; - } - } + // #[cfg(feature = "shared-memory")] + // { + // let has_shminfo = x + // .buffer + // .zslices() + // .any(|s| s.buf.as_any().type_id() == TypeId::of::()); + // if has_shminfo { + // header |= tmsg::flag::Z; + // } + // } - self.write(&mut *writer, header)?; + // self.write(&mut *writer, header)?; - // Body - #[cfg(feature = "shared-memory")] - { - let codec = Zenoh080Condition::new(imsg::has_flag(header, tmsg::flag::Z)); - codec.write(&mut *writer, &x.buffer) - } - #[cfg(not(feature = "shared-memory"))] - { - self.write(&mut *writer, &x.buffer) - } + // // Body + // #[cfg(feature = "shared-memory")] + // { + // let codec = Zenoh080Condition::new(imsg::has_flag(header, tmsg::flag::Z)); + // codec.write(&mut *writer, &x.buffer) + // } + // #[cfg(not(feature = "shared-memory"))] + // { + // self.write(&mut *writer, &x.buffer) + // } + Err(DidntWrite) } } @@ -68,10 +69,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -83,22 +83,23 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != imsg::id::ATTACHMENT { - return Err(DidntRead); - } + // if imsg::mid(self.header) != imsg::id::ATTACHMENT { + // return Err(DidntRead); + // } - let buffer: ZBuf = { - #[cfg(feature = "shared-memory")] - { - let codec = Zenoh080Condition::new(imsg::has_flag(self.header, tmsg::flag::Z)); - codec.read(&mut *reader)? - } - #[cfg(not(feature = "shared-memory"))] - { - self.codec.read(&mut *reader)? - } - }; + // let buffer: ZBuf = { + // #[cfg(feature = "shared-memory")] + // { + // let codec = Zenoh080Condition::new(imsg::has_flag(self.header, tmsg::flag::Z)); + // codec.read(&mut *reader)? + // } + // #[cfg(not(feature = "shared-memory"))] + // { + // self.codec.read(&mut *reader)? + // } + // }; - Ok(Attachment { buffer }) + // Ok(Attachment { buffer }) + Err(DidntRead) } } diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 619cba888d..25f2322fbe 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -11,14 +11,16 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, - ZBuf, + ZBuf, ZSlice, }; use zenoh_protocol::{ - common::{iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtZInt, ZExtensionBody}, + common::{ + iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtZInt, ZExtZSlice, ZExtensionBody, + }, core::ZInt, }; @@ -47,12 +49,23 @@ where fn read(self, reader: &mut R) -> Result<(ZExtUnit<{ ID }>, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(&mut *reader) + } +} - if (header & iext::ID_MASK != ID) || (header & iext::ENC_MASK != iext::ENC_UNIT) { +impl RCodec<(ZExtUnit<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, _reader: &mut R) -> Result<(ZExtUnit<{ ID }>, bool), Self::Error> { + if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_UNIT) { return Err(DidntRead); } - Ok((ZExtUnit::new(), has_flag(header, iext::FLAG_Z))) + Ok((ZExtUnit::new(), has_flag(self.header, iext::FLAG_Z))) } } @@ -82,14 +95,73 @@ where fn read(self, reader: &mut R) -> Result<(ZExtZInt<{ ID }>, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(&mut *reader) + } +} + +impl RCodec<(ZExtZInt<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ZExtZInt<{ ID }>, bool), Self::Error> { + if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZINT) { + return Err(DidntRead); + } + + let value: ZInt = self.codec.read(&mut *reader)?; + + Ok((ZExtZInt::new(value), has_flag(self.header, iext::FLAG_Z))) + } +} + +impl WCodec<(&ZExtZSlice<{ ID }>, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ZExtZSlice<{ ID }>, bool)) -> Self::Output { + let (x, more) = x; + let mut header: u8 = ID | iext::ENC_ZINT; + if more { + header |= iext::FLAG_Z; + } + self.write(&mut *writer, header)?; + self.write(&mut *writer, &x.value)?; + Ok(()) + } +} + +impl RCodec<(ZExtZSlice<{ ID }>, bool), &mut R> for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ZExtZSlice<{ ID }>, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(&mut *reader) + } +} + +impl RCodec<(ZExtZSlice<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; - if (header & iext::ID_MASK != ID) || (header & iext::ENC_MASK != iext::ENC_ZINT) { + fn read(self, reader: &mut R) -> Result<(ZExtZSlice<{ ID }>, bool), Self::Error> { + if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZINT) { return Err(DidntRead); } - let value: ZInt = self.read(&mut *reader)?; + let value: ZSlice = self.codec.read(&mut *reader)?; - Ok((ZExtZInt::new(value), has_flag(header, iext::FLAG_Z))) + Ok((ZExtZSlice::new(value), has_flag(self.header, iext::FLAG_Z))) } } @@ -119,14 +191,25 @@ where fn read(self, reader: &mut R) -> Result<(ZExtZBuf<{ ID }>, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(&mut *reader) + } +} - if (header & iext::ID_MASK != ID) || (header & iext::ENC_MASK != iext::ENC_ZINT) { +impl RCodec<(ZExtZBuf<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ZExtZBuf<{ ID }>, bool), Self::Error> { + if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZINT) { return Err(DidntRead); } - let value: ZBuf = self.read(&mut *reader)?; + let value: ZBuf = self.codec.read(&mut *reader)?; - Ok((ZExtZBuf::new(value), has_flag(header, iext::FLAG_Z))) + Ok((ZExtZBuf::new(value), has_flag(self.header, iext::FLAG_Z))) } } @@ -170,15 +253,26 @@ where fn read(self, reader: &mut R) -> Result<(ZExtUnknown, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(&mut *reader) + } +} + +impl RCodec<(ZExtUnknown, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; - let body = match header & iext::ENC_MASK { + fn read(self, reader: &mut R) -> Result<(ZExtUnknown, bool), Self::Error> { + let body = match self.header & iext::ENC_MASK { iext::ENC_UNIT => ZExtensionBody::Unit, iext::ENC_ZINT => { - let zint: ZInt = self.read(&mut *reader)?; + let zint: ZInt = self.codec.read(&mut *reader)?; ZExtensionBody::ZInt(zint) } iext::ENC_ZBUF => { - let zbuf: ZBuf = self.read(&mut *reader)?; + let zbuf: ZBuf = self.codec.read(&mut *reader)?; ZExtensionBody::ZBuf(zbuf) } _ => return Err(DidntRead), @@ -186,10 +280,10 @@ where Ok(( ZExtUnknown { - id: header & iext::ID_MASK, + id: self.header & iext::ID_MASK, body, }, - has_flag(header, iext::FLAG_Z), + has_flag(self.header, iext::FLAG_Z), )) } } diff --git a/commons/zenoh-codec/src/common/mod.rs b/commons/zenoh-codec/src/common/mod.rs index 3fc68df66c..3777e5a775 100644 --- a/commons/zenoh-codec/src/common/mod.rs +++ b/commons/zenoh-codec/src/common/mod.rs @@ -12,5 +12,5 @@ // ZettaScale Zenoh Team, // mod attachment; -mod extension; +pub mod extension; mod priority; diff --git a/commons/zenoh-codec/src/common/priority.rs b/commons/zenoh-codec/src/common/priority.rs index f0ea255465..d9909c4b5e 100644 --- a/commons/zenoh-codec/src/common/priority.rs +++ b/commons/zenoh-codec/src/common/priority.rs @@ -40,10 +40,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } diff --git a/commons/zenoh-codec/src/core/mod.rs b/commons/zenoh-codec/src/core/mod.rs index ea4b01776c..1753e48fb3 100644 --- a/commons/zenoh-codec/src/core/mod.rs +++ b/commons/zenoh-codec/src/core/mod.rs @@ -63,6 +63,43 @@ where } } +// u16 +impl WCodec for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: u16) -> Self::Output { + let x = x.to_le_bytes(); + writer.write_exact(x.as_slice()) + } +} + +impl WCodec<&u16, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &u16) -> Self::Output { + self.write(writer, *x) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let mut x = [0u8; 2]; + reader.read_exact(&mut x)?; + Ok(u16::from_le_bytes(x)) + } +} + // &[u8] / Vec impl WCodec<&[u8], &mut W> for Zenoh080 where diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 63b263184b..45ff4d04dc 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -36,13 +36,22 @@ pub trait RCodec { #[non_exhaustive] pub struct Zenoh080; -#[derive(Clone, Copy, Default)] +#[derive(Clone, Copy)] #[non_exhaustive] pub struct Zenoh080Header { pub header: u8, pub codec: Zenoh080, } +impl Zenoh080Header { + pub const fn new(header: u8) -> Self { + Self { + header, + codec: Zenoh080, + } + } +} + #[derive(Clone, Copy, Default)] #[non_exhaustive] pub struct Zenoh080Condition { diff --git a/commons/zenoh-codec/src/scouting/hello.rs b/commons/zenoh-codec/src/scouting/hello.rs index 640f9fee2e..d87bb7d34a 100644 --- a/commons/zenoh-codec/src/scouting/hello.rs +++ b/commons/zenoh-codec/src/scouting/hello.rs @@ -18,10 +18,12 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::imsg, + common::{imsg, ZExtUnknown}, core::{Locator, WhatAmI, ZenohId}, - scouting::Hello, - transport::tmsg, + scouting::{ + hello::{flag, Hello}, + id, + }, }; impl WCodec<&Hello, &mut W> for Zenoh080 @@ -32,9 +34,9 @@ where fn write(self, writer: &mut W, x: &Hello) -> Self::Output { // Header - let mut header = tmsg::id::HELLO; + let mut header = id::HELLO; if !x.locators.is_empty() { - header |= tmsg::flag::L; + header |= flag::L; } self.write(&mut *writer, header)?; @@ -62,10 +64,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -77,10 +78,11 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != imsg::id::HELLO { + if imsg::mid(self.header) != id::HELLO { return Err(DidntRead); } + // Body let version: u8 = self.codec.read(&mut *reader)?; let flags: u8 = self.codec.read(&mut *reader)?; let whatami = match flags & 0b11 { @@ -91,13 +93,20 @@ where }; let zid: ZenohId = self.codec.read(&mut *reader)?; - let locators = if imsg::has_flag(self.header, tmsg::flag::L) { + let locators = if imsg::has_flag(self.header, flag::L) { let locs: Vec = self.codec.read(&mut *reader)?; locs } else { vec![] }; + // Extensions + let mut has_extensions = imsg::has_flag(self.header, flag::Z); + while has_extensions { + let (_, more): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + has_extensions = more; + } + Ok(Hello { version, zid, diff --git a/commons/zenoh-codec/src/scouting/mod.rs b/commons/zenoh-codec/src/scouting/mod.rs index a33f0ed377..c914a35532 100644 --- a/commons/zenoh-codec/src/scouting/mod.rs +++ b/commons/zenoh-codec/src/scouting/mod.rs @@ -20,8 +20,8 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, Attachment}, - scouting::{ScoutingBody, ScoutingMessage}, + common::imsg, + scouting::{id, ScoutingBody, ScoutingMessage}, }; impl WCodec<&ScoutingMessage, &mut W> for Zenoh080 @@ -31,10 +31,6 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &ScoutingMessage) -> Self::Output { - if let Some(a) = x.attachment.as_ref() { - self.write(&mut *writer, a)?; - } - match &x.body { ScoutingBody::Scout(s) => self.write(&mut *writer, s), ScoutingBody::Hello(h) => self.write(&mut *writer, h), @@ -49,23 +45,14 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); - let attachment = if imsg::mid(codec.header) == imsg::id::ATTACHMENT { - let a: Attachment = codec.read(&mut *reader)?; - codec.header = self.read(&mut *reader)?; - Some(a) - } else { - None - }; let body = match imsg::mid(codec.header) { - imsg::id::SCOUT => ScoutingBody::Scout(codec.read(&mut *reader)?), - imsg::id::HELLO => ScoutingBody::Hello(codec.read(&mut *reader)?), + id::SCOUT => ScoutingBody::Scout(codec.read(&mut *reader)?), + id::HELLO => ScoutingBody::Hello(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; - Ok(ScoutingMessage { body, attachment }) + Ok(ScoutingMessage { body }) } } diff --git a/commons/zenoh-codec/src/scouting/scout.rs b/commons/zenoh-codec/src/scouting/scout.rs index d9f4c2f17e..616c5f88d6 100644 --- a/commons/zenoh-codec/src/scouting/scout.rs +++ b/commons/zenoh-codec/src/scouting/scout.rs @@ -18,10 +18,12 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::imsg, + common::{imsg, ZExtUnknown}, core::{whatami::WhatAmIMatcher, ZenohId}, - scouting::Scout, - transport::tmsg, + scouting::{ + id, + scout::{flag, Scout}, + }, }; impl WCodec<&Scout, &mut W> for Zenoh080 @@ -32,9 +34,9 @@ where fn write(self, writer: &mut W, x: &Scout) -> Self::Output { // Header - let mut header = tmsg::id::SCOUT; + let mut header = id::SCOUT; if x.zid.is_some() { - header |= tmsg::flag::I; + header |= flag::I; } self.write(&mut *writer, header)?; @@ -45,6 +47,7 @@ where if let Some(zid) = x.zid.as_ref() { self.write(&mut *writer, zid)?; } + Ok(()) } } @@ -56,10 +59,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -71,20 +73,28 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != imsg::id::SCOUT { + if imsg::mid(self.header) != id::SCOUT { return Err(DidntRead); } + // Body let version: u8 = self.codec.read(&mut *reader)?; let flags: u8 = self.codec.read(&mut *reader)?; let what = WhatAmIMatcher::try_from(flags & 0b111).map_err(|_| DidntRead)?; - let zid = if imsg::has_flag(self.header, tmsg::flag::I) { + let zid = if imsg::has_flag(self.header, flag::I) { let zid: ZenohId = self.codec.read(&mut *reader)?; Some(zid) } else { None }; + // Extensions + let mut has_extensions = imsg::has_flag(self.header, flag::Z); + while has_extensions { + let (_, more): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + has_extensions = more; + } + Ok(Scout { version, what, zid }) } } diff --git a/commons/zenoh-codec/src/transport/close.rs b/commons/zenoh-codec/src/transport/close.rs index 4fedb655f9..73b9193cf3 100644 --- a/commons/zenoh-codec/src/transport/close.rs +++ b/commons/zenoh-codec/src/transport/close.rs @@ -17,9 +17,11 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::imsg, - core::ZenohId, - transport::{tmsg, Close}, + common::{imsg, ZExtUnknown}, + transport::{ + close::{flag, Close}, + id, + }, }; impl WCodec<&Close, &mut W> for Zenoh080 @@ -30,20 +32,15 @@ where fn write(self, writer: &mut W, x: &Close) -> Self::Output { // Header - let mut header = tmsg::id::CLOSE; - if x.zid.is_some() { - header |= tmsg::flag::I; - } - if x.link_only { - header |= tmsg::flag::K; + let mut header = id::CLOSE; + if x.session { + header |= flag::S; } self.write(&mut *writer, header)?; // Body - if let Some(p) = x.zid.as_ref() { - self.write(&mut *writer, p)?; - } self.write(&mut *writer, x.reason)?; + Ok(()) } } @@ -55,10 +52,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -70,23 +66,21 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != tmsg::id::CLOSE { + if imsg::mid(self.header) != id::CLOSE { return Err(DidntRead); } + let session = imsg::has_flag(self.header, flag::S); - let link_only = imsg::has_flag(self.header, tmsg::flag::K); - let zid = if imsg::has_flag(self.header, tmsg::flag::I) { - let zid: ZenohId = self.codec.read(&mut *reader)?; - Some(zid) - } else { - None - }; + // Body let reason: u8 = self.codec.read(&mut *reader)?; - Ok(Close { - zid, - reason, - link_only, - }) + // Extensions + let mut has_extensions = imsg::has_flag(self.header, flag::Z); + while has_extensions { + let (_, more): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + has_extensions = more; + } + + Ok(Close { reason, session }) } } diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 7112ca0a86..b0c008cc44 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -32,32 +32,33 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &FrameHeader) -> Self::Output { - // Decorator - if x.channel.priority != Priority::default() { - self.write(&mut *writer, &x.channel.priority)?; - } - - // Header - let mut header = tmsg::id::FRAME; - if let Reliability::Reliable = x.channel.reliability { - header |= tmsg::flag::R; - } - match x.kind { - FrameKind::Messages => {} - FrameKind::SomeFragment => { - header |= tmsg::flag::F; - } - FrameKind::LastFragment => { - header |= tmsg::flag::F; - header |= tmsg::flag::E; - } - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, x.sn)?; - - Ok(()) + // // Decorator + // if x.channel.priority != Priority::default() { + // self.write(&mut *writer, &x.channel.priority)?; + // } + + // // Header + // let mut header = tmsg::id::FRAME; + // if let Reliability::Reliable = x.channel.reliability { + // header |= tmsg::flag::R; + // } + // match x.kind { + // FrameKind::Messages => {} + // FrameKind::SomeFragment => { + // header |= tmsg::flag::F; + // } + // FrameKind::LastFragment => { + // header |= tmsg::flag::F; + // header |= tmsg::flag::E; + // } + // } + // self.write(&mut *writer, header)?; + + // // Body + // self.write(&mut *writer, x.sn)?; + + // Ok(()) + Err(DidntWrite) } } @@ -68,10 +69,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -83,39 +83,40 @@ where type Error = DidntRead; fn read(mut self, reader: &mut R) -> Result { - let mut priority = Priority::default(); - if imsg::mid(self.header) == tmsg::id::PRIORITY { - // Decode priority - priority = self.read(&mut *reader)?; - // Read next header - self.header = self.codec.read(&mut *reader)?; - } - - if imsg::mid(self.header) != tmsg::id::FRAME { - return Err(DidntRead); - } - - let reliability = match imsg::has_flag(self.header, tmsg::flag::R) { - true => Reliability::Reliable, - false => Reliability::BestEffort, - }; - let channel = Channel { - priority, - reliability, - }; - let sn: ZInt = self.codec.read(&mut *reader)?; - - let kind = if imsg::has_flag(self.header, tmsg::flag::F) { - if imsg::has_flag(self.header, tmsg::flag::E) { - FrameKind::LastFragment - } else { - FrameKind::SomeFragment - } - } else { - FrameKind::Messages - }; - - Ok(FrameHeader { channel, sn, kind }) + // let mut priority = Priority::default(); + // if imsg::mid(self.header) == tmsg::id::PRIORITY { + // // Decode priority + // priority = self.read(&mut *reader)?; + // // Read next header + // self.header = self.codec.read(&mut *reader)?; + // } + + // if imsg::mid(self.header) != tmsg::id::FRAME { + // return Err(DidntRead); + // } + + // let reliability = match imsg::has_flag(self.header, tmsg::flag::R) { + // true => Reliability::Reliable, + // false => Reliability::BestEffort, + // }; + // let channel = Channel { + // priority, + // reliability, + // }; + // let sn: ZInt = self.codec.read(&mut *reader)?; + + // let kind = if imsg::has_flag(self.header, tmsg::flag::F) { + // if imsg::has_flag(self.header, tmsg::flag::E) { + // FrameKind::LastFragment + // } else { + // FrameKind::SomeFragment + // } + // } else { + // FrameKind::Messages + // }; + + // Ok(FrameHeader { channel, sn, kind }) + Err(DidntRead) } } @@ -127,34 +128,35 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Frame) -> Self::Output { - // Header - let kind = match &x.payload { - FramePayload::Fragment { is_final, .. } => { - if *is_final { - FrameKind::LastFragment - } else { - FrameKind::SomeFragment - } - } - FramePayload::Messages { .. } => FrameKind::Messages, - }; - let header = FrameHeader { - channel: x.channel, - sn: x.sn, - kind, - }; - self.write(&mut *writer, &header)?; - - // Body - match &x.payload { - FramePayload::Fragment { buffer, .. } => writer.write_zslice(buffer)?, - FramePayload::Messages { messages } => { - for m in messages.iter() { - self.write(&mut *writer, m)?; - } - } - } - Ok(()) + // // Header + // let kind = match &x.payload { + // FramePayload::Fragment { is_final, .. } => { + // if *is_final { + // FrameKind::LastFragment + // } else { + // FrameKind::SomeFragment + // } + // } + // FramePayload::Messages { .. } => FrameKind::Messages, + // }; + // let header = FrameHeader { + // channel: x.channel, + // sn: x.sn, + // kind, + // }; + // self.write(&mut *writer, &header)?; + + // // Body + // match &x.payload { + // FramePayload::Fragment { buffer, .. } => writer.write_zslice(buffer)?, + // FramePayload::Messages { messages } => { + // for m in messages.iter() { + // self.write(&mut *writer, m)?; + // } + // } + // } + // Ok(()) + Err(DidntWrite) } } @@ -165,10 +167,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); codec.read(reader) } } @@ -180,42 +180,43 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let header: FrameHeader = self.read(&mut *reader)?; - - let payload = match header.kind { - FrameKind::Messages => { - let rcode = Zenoh080Reliability { - reliability: header.channel.reliability, - ..Default::default() - }; - - let mut messages: Vec = Vec::with_capacity(1); - while reader.can_read() { - let mark = reader.mark(); - let res: Result = rcode.read(&mut *reader); - match res { - Ok(m) => messages.push(m), - Err(_) => { - reader.rewind(mark); - break; - } - } - } - FramePayload::Messages { messages } - } - FrameKind::SomeFragment | FrameKind::LastFragment => { - // A fragmented frame is not supposed to be followed by - // any other frame in the same batch. Read all the bytes. - let buffer = reader.read_zslice(reader.remaining())?; - let is_final = header.kind == FrameKind::LastFragment; - FramePayload::Fragment { buffer, is_final } - } - }; - - Ok(Frame { - channel: header.channel, - sn: header.sn, - payload, - }) + // let header: FrameHeader = self.read(&mut *reader)?; + + // let payload = match header.kind { + // FrameKind::Messages => { + // let rcode = Zenoh080Reliability { + // reliability: header.channel.reliability, + // ..Default::default() + // }; + + // let mut messages: Vec = Vec::with_capacity(1); + // while reader.can_read() { + // let mark = reader.mark(); + // let res: Result = rcode.read(&mut *reader); + // match res { + // Ok(m) => messages.push(m), + // Err(_) => { + // reader.rewind(mark); + // break; + // } + // } + // } + // FramePayload::Messages { messages } + // } + // FrameKind::SomeFragment | FrameKind::LastFragment => { + // // A fragmented frame is not supposed to be followed by + // // any other frame in the same batch. Read all the bytes. + // let buffer = reader.read_zslice(reader.remaining())?; + // let is_final = header.kind == FrameKind::LastFragment; + // FramePayload::Fragment { buffer, is_final } + // } + // }; + + // Ok(Frame { + // channel: header.channel, + // sn: header.sn, + // payload, + // }) + Err(DidntRead) } } diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index 3cdc69e752..e4ad6beb68 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -19,10 +19,12 @@ use zenoh_buffers::{ ZSlice, }; use zenoh_protocol::{ - common::imsg, - core::{WhatAmI, ZInt, ZenohId}, - defaults::SEQ_NUM_RES, - transport::{tmsg, InitAck, InitSyn}, + common::{imsg, ZExtUnknown}, + core::{WhatAmI, ZenohId}, + transport::{ + id, + init::{ext, flag, InitAck, InitSyn, Resolution}, + }, }; // InitSyn @@ -33,39 +35,55 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &InitSyn) -> Self::Output { - fn has_options(x: &InitSyn) -> bool { - x.is_qos - } - - fn options(x: &InitSyn) -> ZInt { - let mut options = 0; - if x.is_qos { - options |= tmsg::init_options::QOS; - } - options - } - // Header - let mut header = tmsg::id::INIT; - if x.sn_resolution != SEQ_NUM_RES { - header |= tmsg::flag::S; + let mut header = id::INIT; + if x.resolution != Resolution::default() || x.batch_size != u16::MAX { + header |= flag::S; } - if has_options(x) { - header |= tmsg::flag::O; + let has_extensions = x.qos.is_some() || x.shm.is_some() || x.auth.is_some(); + if has_extensions { + header |= flag::Z; } self.write(&mut *writer, header)?; // Body - if has_options(x) { - self.write(&mut *writer, options(x))?; - } self.write(&mut *writer, x.version)?; - let wai: u8 = x.whatami.into(); - self.write(&mut *writer, wai)?; - self.write(&mut *writer, &x.zid)?; - if imsg::has_flag(header, tmsg::flag::S) { - self.write(&mut *writer, x.sn_resolution)?; + + let whatami: u8 = match x.whatami { + WhatAmI::Router => 0b00, + WhatAmI::Peer => 0b01, + WhatAmI::Client => 0b10, + }; + let zid_len = match x.zid.size() { + s if (1..=ZenohId::MAX_SIZE).contains(&s) => s as u8, + _ => return Err(DidntWrite), + }; + let flags = ((zid_len - 1) << 4) | whatami; + self.write(&mut *writer, flags)?; + + writer.write_exact(x.zid.as_slice())?; + + if imsg::has_flag(header, flag::S) { + self.write(&mut *writer, x.resolution.as_u8())?; + self.write(&mut *writer, x.batch_size)?; + } + + // Extensions + if let Some(qos) = x.qos.as_ref() { + let has_more = x.shm.is_some() || x.auth.is_some(); + self.write(&mut *writer, (qos, has_more))?; + } + + if let Some(shm) = x.shm.as_ref() { + let has_more = x.auth.is_some(); + self.write(&mut *writer, (shm, has_more))?; + } + + if let Some(auth) = x.auth.as_ref() { + let has_more = false; + self.write(&mut *writer, (auth, has_more))?; } + Ok(()) } } @@ -77,10 +95,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); codec.read(reader) } } @@ -92,32 +108,75 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != tmsg::id::INIT || imsg::has_flag(self.header, tmsg::flag::A) { + if imsg::mid(self.header) != id::INIT || imsg::has_flag(self.header, flag::A) { return Err(DidntRead); } - let options: ZInt = if imsg::has_flag(self.header, tmsg::flag::O) { - self.codec.read(&mut *reader)? - } else { - 0 - }; + // Body let version: u8 = self.codec.read(&mut *reader)?; - let wai: u8 = self.codec.read(&mut *reader)?; - let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; - let zid: ZenohId = self.codec.read(&mut *reader)?; - let sn_resolution: ZInt = if imsg::has_flag(self.header, tmsg::flag::S) { - self.codec.read(&mut *reader)? - } else { - SEQ_NUM_RES + + let flags: u8 = self.codec.read(&mut *reader)?; + let whatami = match flags & 0b11 { + 0b00 => WhatAmI::Router, + 0b01 => WhatAmI::Peer, + 0b10 => WhatAmI::Client, + _ => return Err(DidntRead), }; - let is_qos = imsg::has_option(options, tmsg::init_options::QOS); + let size = 1 + ((flags >> 4) as usize); + + let mut id = [0; ZenohId::MAX_SIZE]; + reader.read_exact(&mut id[..size])?; + let zid = ZenohId::try_from(&id[..size]).map_err(|_| DidntRead)?; + + let mut resolution = Resolution::default(); + let mut batch_size = u16::MAX; + if imsg::has_flag(self.header, flag::S) { + let flags: u8 = self.codec.read(&mut *reader)?; + resolution = Resolution::from(flags & 0b00111111); + batch_size = self.codec.read(&mut *reader)?; + } + + // Extensions + let mut qos = None; + let mut shm = None; + let mut auth = None; + + let mut has_more = imsg::has_flag(self.header, flag::Z); + while has_more { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QoS::ID => { + let (q, more): (ext::QoS, bool) = eodec.read(&mut *reader)?; + qos = Some(q); + has_more = more; + } + ext::Shm::ID => { + let (s, more): (ext::Shm, bool) = eodec.read(&mut *reader)?; + shm = Some(s); + has_more = more; + } + ext::Auth::ID => { + let (a, more): (ext::Auth, bool) = eodec.read(&mut *reader)?; + auth = Some(a); + has_more = more; + } + _ => { + let (_, more): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_more = more; + } + } + } Ok(InitSyn { version, whatami, zid, - sn_resolution, - is_qos, + resolution, + batch_size, + qos, + shm, + auth, }) } } @@ -130,40 +189,57 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &InitAck) -> Self::Output { - fn has_options(x: &InitAck) -> bool { - x.is_qos - } - - fn options(x: &InitAck) -> ZInt { - let mut options = 0; - if x.is_qos { - options |= tmsg::init_options::QOS; - } - options - } - // Header - let mut header = tmsg::id::INIT; - header |= tmsg::flag::A; - if x.sn_resolution.is_some() { - header |= tmsg::flag::S; + let mut header = id::INIT | flag::A; + if x.resolution != Resolution::default() || x.batch_size != u16::MAX { + header |= flag::S; } - if has_options(x) { - header |= tmsg::flag::O; + let has_extensions = x.qos.is_some() || x.shm.is_some() || x.auth.is_some(); + if has_extensions { + header |= flag::Z; } self.write(&mut *writer, header)?; // Body - if has_options(x) { - self.write(&mut *writer, options(x))?; - } - let wai: u8 = x.whatami.into(); - self.write(&mut *writer, wai)?; - self.write(&mut *writer, &x.zid)?; - if let Some(snr) = x.sn_resolution { - self.write(&mut *writer, snr)?; + self.write(&mut *writer, x.version)?; + + let whatami: u8 = match x.whatami { + WhatAmI::Router => 0b00, + WhatAmI::Peer => 0b01, + WhatAmI::Client => 0b10, + }; + let zid_len = match x.zid.size() { + s if (1..=ZenohId::MAX_SIZE).contains(&s) => s as u8, + _ => return Err(DidntWrite), + }; + let flags = ((zid_len - 1) << 4) | whatami; + self.write(&mut *writer, flags)?; + + writer.write_exact(x.zid.as_slice())?; + + if imsg::has_flag(header, flag::S) { + self.write(&mut *writer, x.resolution.as_u8())?; + self.write(&mut *writer, x.batch_size)?; } + self.write(&mut *writer, &x.cookie)?; + + // Extensions + if let Some(qos) = x.qos.as_ref() { + let has_more = x.shm.is_some() || x.auth.is_some(); + self.write(&mut *writer, (qos, has_more))?; + } + + if let Some(shm) = x.shm.as_ref() { + let has_more = x.auth.is_some(); + self.write(&mut *writer, (shm, has_more))?; + } + + if let Some(auth) = x.auth.as_ref() { + let has_more = false; + self.write(&mut *writer, (auth, has_more))?; + } + Ok(()) } } @@ -175,10 +251,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); codec.read(reader) } } @@ -190,33 +264,78 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != imsg::id::INIT || !imsg::has_flag(self.header, tmsg::flag::A) { + if imsg::mid(self.header) != id::INIT || !imsg::has_flag(self.header, flag::A) { return Err(DidntRead); } - let options: ZInt = if imsg::has_flag(self.header, tmsg::flag::O) { - self.codec.read(&mut *reader)? - } else { - 0 - }; - let wai: u8 = self.codec.read(&mut *reader)?; - let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; - let zid: ZenohId = self.codec.read(&mut *reader)?; - let sn_resolution = if imsg::has_flag(self.header, tmsg::flag::S) { - let snr: ZInt = self.codec.read(&mut *reader)?; - Some(snr) - } else { - None + // Body + let version: u8 = self.codec.read(&mut *reader)?; + + let flags: u8 = self.codec.read(&mut *reader)?; + let whatami = match flags & 0b11 { + 0b00 => WhatAmI::Router, + 0b01 => WhatAmI::Peer, + 0b10 => WhatAmI::Client, + _ => return Err(DidntRead), }; - let is_qos = imsg::has_option(options, tmsg::init_options::QOS); + let size = 1 + ((flags >> 4) as usize); + + let mut id = [0; ZenohId::MAX_SIZE]; + reader.read_exact(&mut id[..size])?; + let zid = ZenohId::try_from(&id[..size]).map_err(|_| DidntRead)?; + + let mut resolution = Resolution::default(); + let mut batch_size = u16::MAX; + if imsg::has_flag(self.header, flag::S) { + let flags: u8 = self.codec.read(&mut *reader)?; + resolution = Resolution::from(flags & 0b00111111); + batch_size = self.codec.read(&mut *reader)?; + } + let cookie: ZSlice = self.codec.read(&mut *reader)?; + // Extensions + let mut qos = None; + let mut shm = None; + let mut auth = None; + + let mut has_more = imsg::has_flag(self.header, flag::Z); + while has_more { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QoS::ID => { + let (q, more): (ext::QoS, bool) = eodec.read(&mut *reader)?; + qos = Some(q); + has_more = more; + } + ext::Shm::ID => { + let (s, more): (ext::Shm, bool) = eodec.read(&mut *reader)?; + shm = Some(s); + has_more = more; + } + ext::Auth::ID => { + let (a, more): (ext::Auth, bool) = eodec.read(&mut *reader)?; + auth = Some(a); + has_more = more; + } + _ => { + let (_, more): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_more = more; + } + } + } + Ok(InitAck { + version, whatami, zid, - sn_resolution, - is_qos, + resolution, + batch_size, cookie, + qos, + shm, + auth, }) } } diff --git a/commons/zenoh-codec/src/transport/join.rs b/commons/zenoh-codec/src/transport/join.rs index 0211d25369..9c2d3ce8b5 100644 --- a/commons/zenoh-codec/src/transport/join.rs +++ b/commons/zenoh-codec/src/transport/join.rs @@ -21,7 +21,6 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, core::{Priority, WhatAmI, ZInt, ZenohId}, - defaults::SEQ_NUM_RES, transport::{tmsg, ConduitSn, ConduitSnList, Join}, }; @@ -32,58 +31,59 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Join) -> Self::Output { - fn options(x: &Join) -> ZInt { - let mut options = 0; - if x.is_qos() { - options |= tmsg::join_options::QOS; - } - options - } + // fn options(x: &Join) -> ZInt { + // let mut options = 0; + // if x.is_qos() { + // options |= tmsg::join_options::QOS; + // } + // options + // } - // Header - let mut header = tmsg::id::JOIN; - if x.lease.as_millis() % 1_000 == 0 { - header |= tmsg::flag::T1; - } - if x.sn_resolution != SEQ_NUM_RES { - header |= tmsg::flag::S; - } - let opts = options(x); - if opts != 0 { - header |= tmsg::flag::O; - } - self.write(&mut *writer, header)?; - if opts != 0 { - self.write(&mut *writer, options(x))?; - } + // // Header + // let mut header = tmsg::id::JOIN; + // if x.lease.as_millis() % 1_000 == 0 { + // header |= tmsg::flag::T1; + // } + // if x.sn_resolution != SEQ_NUM_RES { + // header |= tmsg::flag::S; + // } + // let opts = options(x); + // if opts != 0 { + // header |= tmsg::flag::O; + // } + // self.write(&mut *writer, header)?; + // if opts != 0 { + // self.write(&mut *writer, options(x))?; + // } - // Body - self.write(&mut *writer, x.version)?; - let wai: u8 = x.whatami.into(); - self.write(&mut *writer, wai)?; - self.write(&mut *writer, &x.zid)?; - if imsg::has_flag(header, tmsg::flag::T1) { - self.write(&mut *writer, x.lease.as_secs() as ZInt)?; - } else { - self.write(&mut *writer, x.lease.as_millis() as ZInt)?; - } - if imsg::has_flag(header, tmsg::flag::S) { - self.write(&mut *writer, x.sn_resolution)?; - } - match &x.next_sns { - ConduitSnList::Plain(sn) => { - self.write(&mut *writer, sn.reliable)?; - self.write(&mut *writer, sn.best_effort)?; - } - ConduitSnList::QoS(sns) => { - for sn in sns.iter() { - self.write(&mut *writer, sn.reliable)?; - self.write(&mut *writer, sn.best_effort)?; - } - } - } - // true - Ok(()) + // // Body + // self.write(&mut *writer, x.version)?; + // let wai: u8 = x.whatami.into(); + // self.write(&mut *writer, wai)?; + // self.write(&mut *writer, &x.zid)?; + // if imsg::has_flag(header, tmsg::flag::T1) { + // self.write(&mut *writer, x.lease.as_secs() as ZInt)?; + // } else { + // self.write(&mut *writer, x.lease.as_millis() as ZInt)?; + // } + // if imsg::has_flag(header, tmsg::flag::S) { + // self.write(&mut *writer, x.sn_resolution)?; + // } + // match &x.next_sns { + // ConduitSnList::Plain(sn) => { + // self.write(&mut *writer, sn.reliable)?; + // self.write(&mut *writer, sn.best_effort)?; + // } + // ConduitSnList::QoS(sns) => { + // for sn in sns.iter() { + // self.write(&mut *writer, sn.reliable)?; + // self.write(&mut *writer, sn.best_effort)?; + // } + // } + // } + // // true + // Ok(()) + Err(DidntWrite) } } @@ -94,10 +94,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); codec.read(reader) } } @@ -109,52 +107,53 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != tmsg::id::JOIN { - return Err(DidntRead); - } + // if imsg::mid(self.header) != tmsg::id::JOIN { + // return Err(DidntRead); + // } - let options: ZInt = if imsg::has_flag(self.header, tmsg::flag::O) { - self.codec.read(&mut *reader)? - } else { - 0 - }; - let version: u8 = self.codec.read(&mut *reader)?; - let wai: u8 = self.codec.read(&mut *reader)?; - let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; - let zid: ZenohId = self.codec.read(&mut *reader)?; - let lease: ZInt = self.codec.read(&mut *reader)?; - let lease = if imsg::has_flag(self.header, tmsg::flag::T1) { - Duration::from_secs(lease) - } else { - Duration::from_millis(lease) - }; - let sn_resolution: ZInt = if imsg::has_flag(self.header, tmsg::flag::S) { - self.codec.read(&mut *reader)? - } else { - SEQ_NUM_RES - }; - let is_qos = imsg::has_option(options, tmsg::init_options::QOS); - let next_sns = if is_qos { - let mut sns = Box::new([ConduitSn::default(); Priority::NUM]); - for i in 0..Priority::NUM { - sns[i].reliable = self.codec.read(&mut *reader)?; - sns[i].best_effort = self.codec.read(&mut *reader)?; - } - ConduitSnList::QoS(sns) - } else { - ConduitSnList::Plain(ConduitSn { - reliable: self.codec.read(&mut *reader)?, - best_effort: self.codec.read(&mut *reader)?, - }) - }; + // let options: ZInt = if imsg::has_flag(self.header, tmsg::flag::O) { + // self.codec.read(&mut *reader)? + // } else { + // 0 + // }; + // let version: u8 = self.codec.read(&mut *reader)?; + // let wai: u8 = self.codec.read(&mut *reader)?; + // let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; + // let zid: ZenohId = self.codec.read(&mut *reader)?; + // let lease: ZInt = self.codec.read(&mut *reader)?; + // let lease = if imsg::has_flag(self.header, tmsg::flag::T1) { + // Duration::from_secs(lease) + // } else { + // Duration::from_millis(lease) + // }; + // let sn_resolution: ZInt = if imsg::has_flag(self.header, tmsg::flag::S) { + // self.codec.read(&mut *reader)? + // } else { + // SEQ_NUM_RES + // }; + // let is_qos = imsg::has_option(options, tmsg::init_options::QOS); + // let next_sns = if is_qos { + // let mut sns = Box::new([ConduitSn::default(); Priority::NUM]); + // for i in 0..Priority::NUM { + // sns[i].reliable = self.codec.read(&mut *reader)?; + // sns[i].best_effort = self.codec.read(&mut *reader)?; + // } + // ConduitSnList::QoS(sns) + // } else { + // ConduitSnList::Plain(ConduitSn { + // reliable: self.codec.read(&mut *reader)?, + // best_effort: self.codec.read(&mut *reader)?, + // }) + // }; - Ok(Join { - version, - whatami, - zid, - lease, - sn_resolution, - next_sns, - }) + // Ok(Join { + // version, + // whatami, + // zid, + // lease, + // sn_resolution, + // next_sns, + // }) + Err(DidntRead) } } diff --git a/commons/zenoh-codec/src/transport/keepalive.rs b/commons/zenoh-codec/src/transport/keepalive.rs index 7685b2ade4..ff70e5ed62 100644 --- a/commons/zenoh-codec/src/transport/keepalive.rs +++ b/commons/zenoh-codec/src/transport/keepalive.rs @@ -29,18 +29,19 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &KeepAlive) -> Self::Output { - // Header - let mut header = tmsg::id::KEEP_ALIVE; - if x.zid.is_some() { - header |= tmsg::flag::I; - } - self.write(&mut *writer, header)?; + // // Header + // let mut header = tmsg::id::KEEP_ALIVE; + // if x.zid.is_some() { + // header |= tmsg::flag::I; + // } + // self.write(&mut *writer, header)?; - // Body - if let Some(p) = x.zid.as_ref() { - self.write(&mut *writer, p)?; - } - Ok(()) + // // Body + // if let Some(p) = x.zid.as_ref() { + // self.write(&mut *writer, p)?; + // } + // Ok(()) + Err(DidntWrite) } } @@ -51,10 +52,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); codec.read(reader) } } @@ -66,17 +65,18 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != tmsg::id::KEEP_ALIVE { - return Err(DidntRead); - } + // if imsg::mid(self.header) != tmsg::id::KEEP_ALIVE { + // return Err(DidntRead); + // } - let zid = if imsg::has_flag(self.header, tmsg::flag::I) { - let zid: ZenohId = self.codec.read(&mut *reader)?; - Some(zid) - } else { - None - }; + // let zid = if imsg::has_flag(self.header, tmsg::flag::I) { + // let zid: ZenohId = self.codec.read(&mut *reader)?; + // Some(zid) + // } else { + // None + // }; - Ok(KeepAlive { zid }) + // Ok(KeepAlive { zid }) + Err(DidntRead) } } diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index 05337472aa..e066529424 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -23,10 +23,7 @@ use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_protocol::{ - common::{imsg, Attachment}, - transport::*, -}; +use zenoh_protocol::{common::imsg, transport::*}; // TransportMessage impl WCodec<&TransportMessage, &mut W> for Zenoh080 @@ -36,9 +33,6 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &TransportMessage) -> Self::Output { - if let Some(a) = x.attachment.as_ref() { - self.write(&mut *writer, a)?; - } match &x.body { TransportBody::InitSyn(b) => self.write(&mut *writer, b), TransportBody::InitAck(b) => self.write(&mut *writer, b), @@ -59,38 +53,31 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; - let mut attachment: Option = None; - if imsg::mid(codec.header) == tmsg::id::ATTACHMENT { - let a: Attachment = codec.read(&mut *reader)?; - attachment = Some(a); - codec.header = self.read(&mut *reader)?; - } + let header: u8 = self.read(&mut *reader)?; + + let mut codec = Zenoh080Header::new(header); let body = match imsg::mid(codec.header) { - tmsg::id::INIT => { - if !imsg::has_flag(codec.header, tmsg::flag::A) { + id::INIT => { + if !imsg::has_flag(codec.header, zenoh_protocol::transport::init::flag::A) { TransportBody::InitSyn(codec.read(&mut *reader)?) } else { TransportBody::InitAck(codec.read(&mut *reader)?) } } - tmsg::id::OPEN => { - if !imsg::has_flag(codec.header, tmsg::flag::A) { + id::OPEN => { + if !imsg::has_flag(codec.header, zenoh_protocol::transport::open::flag::A) { TransportBody::OpenSyn(codec.read(&mut *reader)?) } else { TransportBody::OpenAck(codec.read(&mut *reader)?) } } - tmsg::id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), - tmsg::id::CLOSE => TransportBody::Close(codec.read(&mut *reader)?), - tmsg::id::KEEP_ALIVE => TransportBody::KeepAlive(codec.read(&mut *reader)?), - tmsg::id::PRIORITY | tmsg::id::FRAME => TransportBody::Frame(codec.read(&mut *reader)?), + id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), + id::CLOSE => TransportBody::Close(codec.read(&mut *reader)?), + id::KEEP_ALIVE => TransportBody::KeepAlive(codec.read(&mut *reader)?), + id::FRAME => TransportBody::Frame(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; - Ok(TransportMessage { body, attachment }) + Ok(TransportMessage { body }) } } diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index a027e6e6b3..c6193052df 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -32,22 +32,23 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &OpenSyn) -> Self::Output { - // Header - let mut header = tmsg::id::OPEN; - if x.lease.as_millis() % 1_000 == 0 { - header |= tmsg::flag::T2; - } - self.write(&mut *writer, header)?; - - // Body - if imsg::has_flag(header, tmsg::flag::T2) { - self.write(&mut *writer, x.lease.as_secs() as ZInt)?; - } else { - self.write(&mut *writer, x.lease.as_millis() as ZInt)?; - } - self.write(&mut *writer, x.initial_sn)?; - self.write(&mut *writer, &x.cookie)?; - Ok(()) + // // Header + // let mut header = tmsg::id::OPEN; + // if x.lease.as_millis() % 1_000 == 0 { + // header |= tmsg::flag::T2; + // } + // self.write(&mut *writer, header)?; + + // // Body + // if imsg::has_flag(header, tmsg::flag::T2) { + // self.write(&mut *writer, x.lease.as_secs() as ZInt)?; + // } else { + // self.write(&mut *writer, x.lease.as_millis() as ZInt)?; + // } + // self.write(&mut *writer, x.initial_sn)?; + // self.write(&mut *writer, &x.cookie)?; + // Ok(()) + Err(DidntWrite) } } @@ -58,10 +59,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); codec.read(reader) } } @@ -73,24 +72,25 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != imsg::id::OPEN || imsg::has_flag(self.header, tmsg::flag::A) { - return Err(DidntRead); - } - - let lease: ZInt = self.codec.read(&mut *reader)?; - let lease = if imsg::has_flag(self.header, tmsg::flag::T2) { - Duration::from_secs(lease) - } else { - Duration::from_millis(lease) - }; - let initial_sn: ZInt = self.codec.read(&mut *reader)?; - let cookie: ZSlice = self.codec.read(&mut *reader)?; - - Ok(OpenSyn { - lease, - initial_sn, - cookie, - }) + // if imsg::mid(self.header) != imsg::id::OPEN || imsg::has_flag(self.header, tmsg::flag::A) { + // return Err(DidntRead); + // } + + // let lease: ZInt = self.codec.read(&mut *reader)?; + // let lease = if imsg::has_flag(self.header, tmsg::flag::T2) { + // Duration::from_secs(lease) + // } else { + // Duration::from_millis(lease) + // }; + // let initial_sn: ZInt = self.codec.read(&mut *reader)?; + // let cookie: ZSlice = self.codec.read(&mut *reader)?; + + // Ok(OpenSyn { + // lease, + // initial_sn, + // cookie, + // }) + Err(DidntRead) } } @@ -102,23 +102,24 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &OpenAck) -> Self::Output { - // Header - let mut header = tmsg::id::OPEN; - header |= tmsg::flag::A; - // Verify that the timeout is expressed in seconds, i.e. subsec part is 0. - if x.lease.subsec_nanos() == 0 { - header |= tmsg::flag::T2; - } - self.write(&mut *writer, header)?; - - // Body - if imsg::has_flag(header, tmsg::flag::T2) { - self.write(&mut *writer, x.lease.as_secs() as ZInt)?; - } else { - self.write(&mut *writer, x.lease.as_millis() as ZInt)?; - } - self.write(&mut *writer, x.initial_sn)?; - Ok(()) + // // Header + // let mut header = tmsg::id::OPEN; + // header |= tmsg::flag::A; + // // Verify that the timeout is expressed in seconds, i.e. subsec part is 0. + // if x.lease.subsec_nanos() == 0 { + // header |= tmsg::flag::T2; + // } + // self.write(&mut *writer, header)?; + + // // Body + // if imsg::has_flag(header, tmsg::flag::T2) { + // self.write(&mut *writer, x.lease.as_secs() as ZInt)?; + // } else { + // self.write(&mut *writer, x.lease.as_millis() as ZInt)?; + // } + // self.write(&mut *writer, x.initial_sn)?; + // Ok(()) + Err(DidntWrite) } } @@ -129,10 +130,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); codec.read(reader) } } @@ -144,18 +143,19 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != tmsg::id::OPEN || !imsg::has_flag(self.header, tmsg::flag::A) { - return Err(DidntRead); - } - - let lease: ZInt = self.codec.read(&mut *reader)?; - let lease = if imsg::has_flag(self.header, tmsg::flag::T2) { - Duration::from_secs(lease) - } else { - Duration::from_millis(lease) - }; - let initial_sn: ZInt = self.codec.read(&mut *reader)?; - - Ok(OpenAck { lease, initial_sn }) + // if imsg::mid(self.header) != tmsg::id::OPEN || !imsg::has_flag(self.header, tmsg::flag::A) { + // return Err(DidntRead); + // } + + // let lease: ZInt = self.codec.read(&mut *reader)?; + // let lease = if imsg::has_flag(self.header, tmsg::flag::T2) { + // Duration::from_secs(lease) + // } else { + // Duration::from_millis(lease) + // }; + // let initial_sn: ZInt = self.codec.read(&mut *reader)?; + + // Ok(OpenAck { lease, initial_sn }) + Err(DidntRead) } } diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index 8e0e6253b7..bc72744b38 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -58,10 +58,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -243,10 +242,9 @@ where ..Default::default() }; if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { - let hodec = Zenoh080Header { - header: codec.header, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let hodec = Zenoh080Header::new(header); + codec.reply_context = Some(hodec.read(&mut *reader)?); codec.header = self.read(&mut *reader)?; } diff --git a/commons/zenoh-codec/src/zenoh/declare.rs b/commons/zenoh-codec/src/zenoh/declare.rs index bb30f9733f..806c0b925c 100644 --- a/commons/zenoh-codec/src/zenoh/declare.rs +++ b/commons/zenoh-codec/src/zenoh/declare.rs @@ -59,10 +59,8 @@ where fn read(self, reader: &mut R) -> Result { use super::zmsg::declaration::id::*; - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); let d = match imsg::mid(codec.header) { RESOURCE => Declaration::Resource(codec.read(&mut *reader)?), @@ -109,10 +107,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -169,10 +166,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -225,10 +221,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -279,10 +274,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -337,10 +331,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -444,10 +437,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -517,10 +509,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -610,10 +601,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } @@ -674,10 +664,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } diff --git a/commons/zenoh-codec/src/zenoh/linkstate.rs b/commons/zenoh-codec/src/zenoh/linkstate.rs index 200ca2a41a..3d7e3fdb92 100644 --- a/commons/zenoh-codec/src/zenoh/linkstate.rs +++ b/commons/zenoh-codec/src/zenoh/linkstate.rs @@ -142,10 +142,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } diff --git a/commons/zenoh-codec/src/zenoh/mod.rs b/commons/zenoh-codec/src/zenoh/mod.rs index ade67584ce..c0f8ab2a34 100644 --- a/commons/zenoh-codec/src/zenoh/mod.rs +++ b/commons/zenoh-codec/src/zenoh/mod.rs @@ -82,10 +82,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh080Header { - header: self.codec.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.codec.read(&mut *reader)?; + let mut codec = Zenoh080Header::new(header); let attachment = if imsg::mid(codec.header) == imsg::id::ATTACHMENT { let a: Attachment = codec.read(&mut *reader)?; diff --git a/commons/zenoh-codec/src/zenoh/pull.rs b/commons/zenoh-codec/src/zenoh/pull.rs index f827675ea2..3172ca83da 100644 --- a/commons/zenoh-codec/src/zenoh/pull.rs +++ b/commons/zenoh-codec/src/zenoh/pull.rs @@ -60,10 +60,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } diff --git a/commons/zenoh-codec/src/zenoh/query.rs b/commons/zenoh-codec/src/zenoh/query.rs index e545f2aec5..af295dcc79 100644 --- a/commons/zenoh-codec/src/zenoh/query.rs +++ b/commons/zenoh-codec/src/zenoh/query.rs @@ -177,10 +177,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } diff --git a/commons/zenoh-codec/src/zenoh/routing.rs b/commons/zenoh-codec/src/zenoh/routing.rs index 4bc89a68fc..26648b91f8 100644 --- a/commons/zenoh-codec/src/zenoh/routing.rs +++ b/commons/zenoh-codec/src/zenoh/routing.rs @@ -46,10 +46,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Header { - header: self.read(&mut *reader)?, - ..Default::default() - }; + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) } } diff --git a/commons/zenoh-codec/src/zenoh/unit.rs b/commons/zenoh-codec/src/zenoh/unit.rs index 25e322336a..b23779f57a 100644 --- a/commons/zenoh-codec/src/zenoh/unit.rs +++ b/commons/zenoh-codec/src/zenoh/unit.rs @@ -57,10 +57,7 @@ where ..Default::default() }; if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { - let hodec = Zenoh080Header { - header: codec.header, - ..Default::default() - }; + let hodec = Zenoh080Header::new(codec.header); codec.reply_context = Some(hodec.read(&mut *reader)?); codec.header = self.read(&mut *reader)?; } diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index 0ea9575974..04a50c61b7 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use crate::core::ZInt; -use zenoh_buffers::ZBuf; +use zenoh_buffers::{ZBuf, ZSlice}; /// # Zenoh extensions /// @@ -66,6 +66,8 @@ pub mod iext { pub struct ZExtUnit; impl ZExtUnit<{ ID }> { + pub const ID: u8 = ID; + pub fn new() -> Self { Self } @@ -82,6 +84,8 @@ pub struct ZExtZInt { } impl ZExtZInt<{ ID }> { + pub const ID: u8 = ID; + pub fn new(value: ZInt) -> Self { Self { value } } @@ -96,12 +100,36 @@ impl ZExtZInt<{ ID }> { } } +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ZExtZSlice { + pub value: ZSlice, +} + +impl ZExtZSlice<{ ID }> { + pub const ID: u8 = ID; + + pub fn new(value: ZSlice) -> Self { + Self { value } + } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let value = ZSlice::rand(rng.gen_range(8..=64)); + Self { value } + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct ZExtZBuf { pub value: ZBuf, } impl ZExtZBuf<{ ID }> { + pub const ID: u8 = ID; + pub fn new(value: ZBuf) -> Self { Self { value } } diff --git a/commons/zenoh-protocol/src/common/mod.rs b/commons/zenoh-protocol/src/common/mod.rs index c4eff8a27d..416ebd346e 100644 --- a/commons/zenoh-protocol/src/common/mod.rs +++ b/commons/zenoh-protocol/src/common/mod.rs @@ -24,19 +24,6 @@ pub mod imsg { use crate::core::ZInt; pub mod id { - // Transport Messages - pub const JOIN: u8 = 0x00; // For multicast communications only - pub const SCOUT: u8 = 0x01; - pub const HELLO: u8 = 0x02; - pub const INIT: u8 = 0x03; // For unicast communications only - pub const OPEN: u8 = 0x04; // For unicast communications only - pub const CLOSE: u8 = 0x05; - pub const SYNC: u8 = 0x06; - pub const ACK_NACK: u8 = 0x07; - pub const KEEP_ALIVE: u8 = 0x08; - pub const PING_PONG: u8 = 0x09; - pub const FRAME: u8 = 0x0a; - // Zenoh Messages pub const DECLARE: u8 = 0x0b; pub const DATA: u8 = 0x0c; diff --git a/commons/zenoh-protocol/src/defaults.rs b/commons/zenoh-protocol/src/defaults.rs index b8bc3f9c14..5ec71fc454 100644 --- a/commons/zenoh-protocol/src/defaults.rs +++ b/commons/zenoh-protocol/src/defaults.rs @@ -11,12 +11,18 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::core::ZInt; +#[repr(u8)] +// The value represents the 2-bit encoded value +pub enum Bits { + U8 = 0b00, + U16 = 0b01, + U32 = 0b10, + U64 = 0b11, +} -// The default sequence number resolution takes 4 bytes on the wire. -// Given the VLE encoding of ZInt, 4 bytes result in 28 useful bits. -// 2^28 = 268_435_456 => Max Seq Num = 268_435_455 -pub const SEQ_NUM_RES: ZInt = 268_435_456; +pub const FRAME_SN_RESOLUTION: Bits = Bits::U64; +pub const REQUEST_ID_RESOLUTION: Bits = Bits::U64; +pub const KEYEXPR_ID_RESOLUTION: Bits = Bits::U64; /// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length /// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. diff --git a/commons/zenoh-protocol/src/scouting/hello.rs b/commons/zenoh-protocol/src/scouting/hello.rs index 1311e834a4..557e0b577b 100644 --- a/commons/zenoh-protocol/src/scouting/hello.rs +++ b/commons/zenoh-protocol/src/scouting/hello.rs @@ -92,6 +92,12 @@ use core::fmt; /// - 0b11: Reserved /// ``` /// +pub mod flag { + pub const L: u8 = 1 << 5; // 0x20 Locators if L==1 then the list of locators is present, else the src address is the locator + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/commons/zenoh-protocol/src/scouting/mod.rs b/commons/zenoh-protocol/src/scouting/mod.rs index 0853e3c6f2..2fd560abaa 100644 --- a/commons/zenoh-protocol/src/scouting/mod.rs +++ b/commons/zenoh-protocol/src/scouting/mod.rs @@ -11,16 +11,22 @@ // Contributors: // ZettaScale Zenoh Team, // -mod hello; -mod scout; +pub mod hello; +pub mod scout; use crate::{ common::Attachment, core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}, }; use alloc::vec::Vec; -pub use hello::*; -pub use scout::*; +pub use hello::Hello; +pub use scout::Scout; + +pub mod id { + // Scouting Messages + pub const SCOUT: u8 = 0x01; + pub const HELLO: u8 = 0x02; +} // Zenoh messages at scouting level #[derive(Debug, Clone, PartialEq, Eq)] @@ -34,7 +40,6 @@ pub enum ScoutingBody { #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ScoutingMessage { pub body: ScoutingBody, - pub attachment: Option, #[cfg(feature = "stats")] pub size: Option, } @@ -48,7 +53,6 @@ impl ScoutingMessage { let version = crate::VERSION; ScoutingMessage { body: ScoutingBody::Scout(Scout { version, what, zid }), - attachment, #[cfg(feature = "stats")] size: None, } @@ -68,7 +72,6 @@ impl ScoutingMessage { zid, locators, }), - attachment, #[cfg(feature = "stats")] size: None, } @@ -80,14 +83,12 @@ impl ScoutingMessage { let mut rng = rand::thread_rng(); - let attachment = rng.gen_bool(0.5).then_some(Attachment::rand()); - let body = match rng.gen_range(0..2) { 0 => ScoutingBody::Scout(Scout::rand()), 1 => ScoutingBody::Hello(Hello::rand()), _ => unreachable!(), }; - Self { body, attachment } + Self { body } } } diff --git a/commons/zenoh-protocol/src/scouting/scout.rs b/commons/zenoh-protocol/src/scouting/scout.rs index 8e3ee18ee5..5bc51f491e 100644 --- a/commons/zenoh-protocol/src/scouting/scout.rs +++ b/commons/zenoh-protocol/src/scouting/scout.rs @@ -61,6 +61,12 @@ use crate::core::{whatami::WhatAmIMatcher, ZenohId}; /// - 0b010: Peer /// - 0b100: Client /// ``` +pub mod flag { + pub const I: u8 = 1 << 5; // 0x20 ZenohID if I==1 then the PeerID is requested or present + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Scout { diff --git a/commons/zenoh-protocol/src/transport/close.rs b/commons/zenoh-protocol/src/transport/close.rs index b188430959..cc3b1f5223 100644 --- a/commons/zenoh-protocol/src/transport/close.rs +++ b/commons/zenoh-protocol/src/transport/close.rs @@ -11,41 +11,79 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::ZenohId; /// # Close message /// +/// The [`Close`] message is sent in any of the following two cases: +/// 1) in response to an INIT or OPEN message which are not accepted; +/// 2) at any time to arbitrarly close the transport with the corresponding zenoh node. +/// +/// The [`Close`] message flow is the following: +/// /// ```text -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. +/// A B +/// | CLOSE | +/// |------------------>| +/// | | +/// ``` /// -/// The CLOSE message is sent in any of the following two cases: -/// 1) in response to an OPEN message which is not accepted; -/// 2) at any time to arbitrarly close the transport with the corresponding peer. +/// The [`Close`] message structure is defined as follows: +/// +/// ```text +/// Flags: +/// - S: Session close If S==1 close the whole session, close only the link otherwise +/// - X: Reserved +/// - Z: Extensions If Z==1 then zenoh extensions will follow. /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |X|K|I| CLOSE | -/// +-+-+-+-+-------+ -/// ~ peer_id ~ if I==1 -- PID of the target peer. -/// +---------------+ +/// |Z|X|S| CLOSE | +/// +-+-+-+---------+ /// | reason | /// +---------------+ -/// -/// - if K==0 then close the whole zenoh transport. -/// - if K==1 then close the transport link the CLOSE message was sent on (e.g., TCP socket) but -/// keep the whole transport open. NOTE: the transport will be automatically closed when -/// the transport's lease period expires. +/// ~ [CloseExts] ~ if Flag(Z)==1 +/// +---------------+ /// ``` +/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length +/// in bytes of the message, resulting in the maximum length of a message being 65535 bytes. +/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve +/// the boundary of the serialized messages. The length is encoded as little-endian. +/// In any case, the length of a message must not exceed 65535 bytes. +/// + +pub mod flag { + pub const S: u8 = 1 << 5; // 0x20 Session close if S==1 close the whole session, close only the link otherwise + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +// Reason for the Close message +pub mod reason { + pub const GENERIC: u8 = 0x00; + pub const UNSUPPORTED: u8 = 0x01; + pub const INVALID: u8 = 0x02; + pub const MAX_SESSIONS: u8 = 0x03; + pub const MAX_LINKS: u8 = 0x04; + pub const EXPIRED: u8 = 0x05; +} + +pub fn reason_to_str(reason: u8) -> &'static str { + match reason { + reason::GENERIC => "GENERIC", + reason::UNSUPPORTED => "UNSUPPORTED", + reason::INVALID => "INVALID", + reason::MAX_SESSIONS => "MAX_SESSIONS", + reason::MAX_LINKS => "MAX_LINKS", + reason::EXPIRED => "EXPIRED", + _ => "UNKNOWN", + } +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Close { - pub zid: Option, pub reason: u8, - pub link_only: bool, + pub session: bool, } impl Close { @@ -55,18 +93,9 @@ impl Close { let mut rng = rand::thread_rng(); - let zid = if rng.gen_bool(0.5) { - Some(ZenohId::default()) - } else { - None - }; let reason: u8 = rng.gen(); - let link_only = rng.gen_bool(0.5); + let session = rng.gen_bool(0.5); - Self { - zid, - reason, - link_only, - } + Self { reason, session } } } diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index 2fa7cc63b4..26b50d3faf 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -11,59 +11,188 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{WhatAmI, ZInt, ZenohId}; +use crate::core::{WhatAmI, ZenohId}; use zenoh_buffers::ZSlice; /// # Init message /// +/// The INIT message is sent on a specific Locator to initiate a transport with the zenoh node +/// associated with that Locator. The initiator MUST send an INIT message with the A flag set to 0. +/// If the corresponding zenohd node deems appropriate to accept the INIT message, the corresponding +/// peer MUST reply with an INIT message with the A flag set to 1. Alternatively, it MAY reply with +/// a [`super::Close`] message. For convenience, we call [`InitSyn`] and [`InitAck`] an INIT message +/// when the A flag is set to 0 and 1, respectively. +/// +/// The [`InitSyn`]/[`InitAck`] message flow is the following: +/// /// ```text -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. +/// A B +/// | INIT SYN | +/// |------------------>| +/// | | +/// | INIT ACK | +/// |<------------------| +/// | | +/// ``` +/// +/// The INIT message structure is defined as follows: /// -/// The INIT message is sent on a specific Locator to initiate a transport with the peer associated -/// with that Locator. The initiator MUST send an INIT message with the A flag set to 0. If the -/// corresponding peer deems appropriate to initialize a transport with the initiator, the corresponding -/// peer MUST reply with an INIT message with the A flag set to 1. +/// ```text +/// Flags: +/// - A: Ack If A==0 then the message is an InitSyn else it is an InitAck +/// - S: Size params If S==1 then size parameters are exchanged +/// - Z: Extensions If Z==1 then zenoh extensions will follow. /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |O|S|A| INIT | -/// +-+-+-+-+-------+ -/// ~ |Q~ if O==1 +/// |Z|S|A| INIT | +/// +-+-+-+---------+ +/// | version | /// +---------------+ -/// | v_maj | v_min | if A==0 -- Protocol Version VMaj.VMin -/// +-------+-------+ -/// ~ whatami ~ -- Client, Router, Peer or a combination of them +/// |zid_len|x|x|wai| (#)(*) +/// +-----+-----+---+ +/// ~ [u8] ~ -- ZenohID of the sender of the INIT message /// +---------------+ -/// ~ peer_id ~ -- PID of the sender of the INIT message +/// |x|x|kid|rid|fsn| \ -- SN/ID resolution (+) +/// +---------------+ | if Flag(S)==1 +/// | u16 | | -- Batch Size ($) +/// | | / /// +---------------+ -/// ~ sn_resolution ~ if S==1 -- the sequence number resolution(*) +/// ~ ~ -- if Flag(A)==1 -- Cookie /// +---------------+ -/// ~ cookie ~ if A==1 +/// ~ [InitExts] ~ -- if Flag(Z)==1 /// +---------------+ /// -/// (*) if A==0 and S==0 then 2^28 is assumed. -/// if A==1 and S==0 then the agreed resolution is the one communicated by the initiator. +/// If A==1 and S==0 then size parameters are (ie. S flag) are accepted. +/// +/// (*) WhatAmI. It indicates the role of the zenoh node sending the INIT message. +/// The valid WhatAmI values are: +/// - 0b00: Router +/// - 0b01: Peer +/// - 0b10: Client +/// - 0b11: Reserved +/// +/// (#) ZID length. It indicates how many bytes are used for the ZenohID bytes. +/// A ZenohID is minimum 1 byte and maximum 16 bytes. Therefore, the actual lenght is computed as: +/// real_zid_len := 1 + zid_len +/// +/// (+) Sequence Number/ID resolution. It indicates the resolution and consequently the wire overhead +/// of various SN and ID in Zenoh. +/// - fsn: frame/fragment sequence number resolution. Used in Frame/Fragment messages. +/// - rid: request ID resolution. Used in Request/Response messages. +/// - kid: key expression ID resolution. Used in Push/Request/Response messages. +/// The valid SN/ID resolution values are: +/// - 0b00: 8 bits +/// - 0b01: 16 bits +/// - 0b10: 32 bits +/// - 0b11: 64 bits /// -/// - if Q==1 then the initiator/responder support QoS. +/// ($) Batch Size. It indicates the maximum size of a batch the sender of the INIT message is willing +/// to accept when reading from the network. +/// +/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length +/// in bytes of the message, resulting in the maximum length of a message being 65535 bytes. +/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve +/// the boundary of the serialized messages. The length is encoded as little-endian. +/// In any case, the length of a message must not exceed 65535 bytes. /// ``` +/// + +pub mod flag { + pub const A: u8 = 1 << 5; // 0x20 Ack if A==0 then the message is an InitSyn else it is an InitAck + pub const S: u8 = 1 << 6; // 0x40 Size params if S==1 then size parameters are exchanged + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +#[repr(u8)] +// The value represents the 2-bit encoded value +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Bits { + U8 = 0b00, + U16 = 0b01, + U32 = 0b10, + U64 = 0b11, +} + +#[repr(u8)] +// The value indicates the bit offest +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Field { + FrameSN = 0, + RequestID = 2, + KeyExprID = 4, +} + +#[repr(transparent)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Resolution(u8); + +impl Resolution { + pub const fn as_u8(&self) -> u8 { + self.0 + } + + pub const fn get(&self, field: Field) -> Bits { + let value = (self.0 >> (field as u8)) & 0b11; + unsafe { core::mem::transmute(value) } + } + + pub fn set(&mut self, field: Field, bits: Bits) { + self.0 &= !(0b11 << field as u8); // Clear bits + self.0 |= (bits as u8) << (field as u8); // Set bits + } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let v: u8 = rng.gen(); + Self(v & 0b00111111) + } +} + +impl Default for Resolution { + fn default() -> Self { + let frame_sn = Bits::U64 as u8; + let request_id = (Bits::U64 as u8) << 2; + let keyexpr_id = (Bits::U64 as u8) << 4; + Self(frame_sn | request_id | keyexpr_id) + } +} + +impl From for Resolution { + fn from(v: u8) -> Self { + Self(v) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct InitSyn { pub version: u8, pub whatami: WhatAmI, pub zid: ZenohId, - pub sn_resolution: ZInt, - pub is_qos: bool, + pub resolution: Resolution, + pub batch_size: u16, + pub qos: Option, + pub shm: Option, + pub auth: Option, +} + +// Extensions +pub mod ext { + use crate::common::{ZExtUnit, ZExtZSlice}; + + pub type QoS = ZExtUnit<0x01>; + pub type Shm = ZExtZSlice<0x02>; + pub type Auth = ZExtZSlice<0x03>; } impl InitSyn { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::defaults::SEQ_NUM_RES; + use crate::common::{ZExtUnit, ZExtZSlice}; use rand::Rng; let mut rng = rand::thread_rng(); @@ -71,19 +200,21 @@ impl InitSyn { let version: u8 = rng.gen(); let whatami = WhatAmI::rand(); let zid = ZenohId::default(); - let sn_resolution = if rng.gen_bool(0.5) { - rng.gen() - } else { - SEQ_NUM_RES - }; - let is_qos = rng.gen_bool(0.5); + let resolution = Resolution::rand(); + let batch_size: u16 = rng.gen(); + let qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); + let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); Self { version, whatami, zid, - sn_resolution, - is_qos, + resolution, + batch_size, + qos, + shm, + auth, } } } @@ -91,39 +222,49 @@ impl InitSyn { #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct InitAck { + pub version: u8, pub whatami: WhatAmI, pub zid: ZenohId, - pub sn_resolution: Option, - pub is_qos: bool, + pub resolution: Resolution, + pub batch_size: u16, pub cookie: ZSlice, + pub qos: Option, + pub shm: Option, + pub auth: Option, } impl InitAck { #[cfg(feature = "test")] pub fn rand() -> Self { + use crate::common::{ZExtUnit, ZExtZSlice}; use rand::Rng; - const MIN: usize = 32; - const MAX: usize = 1_024; - let mut rng = rand::thread_rng(); + let version: u8 = rng.gen(); let whatami = WhatAmI::rand(); let zid = ZenohId::default(); - let sn_resolution = if rng.gen_bool(0.5) { - Some(rng.gen()) + let resolution = if rng.gen_bool(0.5) { + Resolution::default() } else { - None + Resolution::rand() }; - let is_qos = rng.gen_bool(0.5); - let cookie = ZSlice::rand(rng.gen_range(MIN..=MAX)); + let batch_size: u16 = rng.gen(); + let cookie = ZSlice::rand(64); + let qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); + let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); Self { + version, whatami, zid, - sn_resolution, - is_qos, + resolution, + batch_size, cookie, + qos, + shm, + auth, } } } diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 7a8e14e4c2..7170cbcdd8 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -11,26 +11,36 @@ // Contributors: // ZettaScale Zenoh Team, // -mod close; -mod frame; -mod init; -mod join; -mod keepalive; -mod open; +pub mod close; +pub mod frame; +pub mod init; +pub mod join; +pub mod keepalive; +pub mod open; use crate::{ common::Attachment, core::{Channel, Priority, WhatAmI, ZInt, ZenohId}, }; -pub use close::*; +pub use close::Close; use core::{convert::TryInto, fmt, time::Duration}; pub use frame::*; -pub use init::*; +pub use init::{InitAck, InitSyn}; pub use join::*; pub use keepalive::*; pub use open::*; use zenoh_buffers::ZSlice; +pub mod id { + pub const JOIN: u8 = 0x01; // For multicast communications only + pub const INIT: u8 = 0x02; // For unicast communications only + pub const OPEN: u8 = 0x03; // For unicast communications only + pub const CLOSE: u8 = 0x04; + pub const KEEP_ALIVE: u8 = 0x05; + pub const FRAME: u8 = 0x06; + pub const FRAGMENT: u8 = 0x07; +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ConduitSnList { @@ -79,86 +89,17 @@ pub struct ConduitSn { pub mod tmsg { use super::Priority; - use crate::{common::imsg, core::ZInt}; + use crate::common::imsg; // Transport message IDs -- Re-export of some of the Inner Message IDs pub mod id { use super::imsg; - // Messages - pub const SCOUT: u8 = imsg::id::SCOUT; - pub const HELLO: u8 = imsg::id::HELLO; - pub const INIT: u8 = imsg::id::INIT; - pub const OPEN: u8 = imsg::id::OPEN; - pub const CLOSE: u8 = imsg::id::CLOSE; - pub const SYNC: u8 = imsg::id::SYNC; - pub const ACK_NACK: u8 = imsg::id::ACK_NACK; - pub const KEEP_ALIVE: u8 = imsg::id::KEEP_ALIVE; - pub const PING_PONG: u8 = imsg::id::PING_PONG; - pub const FRAME: u8 = imsg::id::FRAME; - pub const JOIN: u8 = imsg::id::JOIN; - // Message decorators pub const PRIORITY: u8 = imsg::id::PRIORITY; pub const ATTACHMENT: u8 = imsg::id::ATTACHMENT; } - // Transport message flags - pub mod flag { - pub const A: u8 = 1 << 5; // 0x20 Ack if A==1 then the message is an acknowledgment - pub const C: u8 = 1 << 6; // 0x40 Count if C==1 then number of unacknowledged messages is present - pub const E: u8 = 1 << 7; // 0x80 End if E==1 then it is the last FRAME fragment - pub const F: u8 = 1 << 6; // 0x40 Fragment if F==1 then the FRAME is a fragment - pub const I: u8 = 1 << 5; // 0x20 PeerID if I==1 then the PeerID is requested or present - pub const K: u8 = 1 << 6; // 0x40 CloseLink if K==1 then close the transport link only - pub const L: u8 = 1 << 7; // 0x80 Locators if L==1 then Locators are present - pub const M: u8 = 1 << 5; // 0x20 Mask if M==1 then a Mask is present - pub const O: u8 = 1 << 7; // 0x80 Options if O==1 then Options are present - pub const P: u8 = 1 << 5; // 0x20 PingOrPong if P==1 then the message is Ping, otherwise is Pong - pub const R: u8 = 1 << 5; // 0x20 Reliable if R==1 then it concerns the reliable channel, best-effort otherwise - pub const S: u8 = 1 << 6; // 0x40 SN Resolution if S==1 then the SN Resolution is present - pub const T1: u8 = 1 << 5; // 0x20 TimeRes if U==1 then the time resolution is in seconds - pub const T2: u8 = 1 << 6; // 0x40 TimeRes if T==1 then the time resolution is in seconds - pub const W: u8 = 1 << 6; // 0x40 WhatAmI if W==1 then WhatAmI is indicated - pub const Z: u8 = 1 << 5; // 0x20 MixedSlices if Z==1 then the payload contains a mix of raw and shm_info payload - - pub const X: u8 = 0; // Unused flags are set to zero - } - - pub mod init_options { - use super::ZInt; - - pub const QOS: ZInt = 1 << 0; // 0x01 QoS if PRIORITY==1 then the transport supports QoS - } - - pub mod join_options { - use super::ZInt; - - pub const QOS: ZInt = 1 << 0; // 0x01 QoS if PRIORITY==1 then the transport supports QoS - } - - // Reason for the Close message - pub mod close_reason { - pub const GENERIC: u8 = 0x00; - pub const UNSUPPORTED: u8 = 0x01; - pub const INVALID: u8 = 0x02; - pub const MAX_SESSIONS: u8 = 0x03; - pub const MAX_LINKS: u8 = 0x04; - pub const EXPIRED: u8 = 0x05; - } - - pub fn close_reason_to_str(reason: u8) -> &'static str { - match reason { - close_reason::GENERIC => "GENERIC", - close_reason::UNSUPPORTED => "UNSUPPORTED", - close_reason::INVALID => "INVALID", - close_reason::MAX_SESSIONS => "MAX_SESSIONS", - close_reason::MAX_LINKS => "MAX_LINKS", - close_reason::EXPIRED => "EXPIRED", - _ => "UNKNOWN", - } - } - pub mod conduit { use super::{imsg, Priority}; @@ -191,7 +132,6 @@ pub enum TransportBody { #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct TransportMessage { pub body: TransportBody, - pub attachment: Option, #[cfg(feature = "stats")] pub size: Option, } @@ -206,14 +146,7 @@ impl TransportMessage { attachment: Option, ) -> TransportMessage { TransportMessage { - body: TransportBody::InitSyn(InitSyn { - version, - whatami, - zid, - sn_resolution, - is_qos, - }), - attachment, + body: TransportBody::InitSyn(InitSyn::rand()), // @TODO #[cfg(feature = "stats")] size: None, } @@ -228,14 +161,7 @@ impl TransportMessage { attachment: Option, ) -> TransportMessage { TransportMessage { - body: TransportBody::InitAck(InitAck { - whatami, - zid, - sn_resolution, - is_qos, - cookie, - }), - attachment, + body: TransportBody::InitAck(InitAck::rand()), // @TODO #[cfg(feature = "stats")] size: None, } @@ -253,7 +179,6 @@ impl TransportMessage { initial_sn, cookie, }), - attachment, #[cfg(feature = "stats")] size: None, } @@ -266,7 +191,6 @@ impl TransportMessage { ) -> TransportMessage { TransportMessage { body: TransportBody::OpenAck(OpenAck { lease, initial_sn }), - attachment, #[cfg(feature = "stats")] size: None, } @@ -290,7 +214,6 @@ impl TransportMessage { sn_resolution, next_sns, }), - attachment, #[cfg(feature = "stats")] size: None, } @@ -299,16 +222,11 @@ impl TransportMessage { pub fn make_close( zid: Option, reason: u8, - link_only: bool, + session: bool, attachment: Option, ) -> TransportMessage { TransportMessage { - body: TransportBody::Close(Close { - zid, - reason, - link_only, - }), - attachment, + body: TransportBody::Close(Close { reason, session }), #[cfg(feature = "stats")] size: None, } @@ -320,7 +238,6 @@ impl TransportMessage { ) -> TransportMessage { TransportMessage { body: TransportBody::KeepAlive(KeepAlive { zid }), - attachment, #[cfg(feature = "stats")] size: None, } @@ -338,7 +255,6 @@ impl TransportMessage { sn, payload, }), - attachment, #[cfg(feature = "stats")] size: None, } @@ -350,12 +266,6 @@ impl TransportMessage { let mut rng = rand::thread_rng(); - let attachment = if rng.gen_bool(0.5) { - Some(Attachment::rand()) - } else { - None - }; - let body = match rng.gen_range(0..8) { 0 => TransportBody::InitSyn(InitSyn::rand()), 1 => TransportBody::InitAck(InitAck::rand()), @@ -368,6 +278,6 @@ impl TransportMessage { _ => unreachable!(), }; - Self { body, attachment } + Self { body } } } diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 9d8f6aa8e0..149d30e2e5 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -17,31 +17,49 @@ use zenoh_buffers::ZSlice; /// # Open message /// -/// ```text -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. +/// After having succesfully complete the [`super::InitSyn`]-[`super::InitAck`] message exchange, +/// the OPEN message is sent on a link to finalize the initialization of the link and +/// associated transport with a zenoh node. +/// For convenience, we call [`OpenSyn`] and [`OpenAck`] an OPEN message with the A flag +/// is set to 0 and 1, respectively. /// -/// The OPEN message is sent on a link to finally open an initialized transport with the peer. +/// ```text +/// Flags: +/// - A: Ack If A==0 then the message is an OpenSyn else it is an OpenAck +/// - T: Lease period if T==1 then the lease period is in seconds else in milliseconds +/// - Z: Extensions If Z==1 then zenoh extensions will follow. /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |X|T|A| OPEN | -/// +-+-+-+-+-------+ -/// ~ lease ~ -- Lease period of the sender of the OPEN message(*) +/// |Z|T|A| OPEN | +/// +-+-+-+---------+ +/// % lease % -- Lease period of the sender of the OPEN message +/// +---------------+ +/// % initial_sn % -- Initial SN proposed by the sender of the OPEN(*) /// +---------------+ -/// ~ initial_sn ~ -- Initial SN proposed by the sender of the OPEN(**) +/// ~ ~ if Flag(A)==0 (**) -- Cookie /// +---------------+ -/// ~ cookie ~ if A==0(***) +/// ~ [OpenExts] ~ if Flag(Z)==1 /// +---------------+ /// -/// (*) if T==1 then the lease period is expressed in seconds, otherwise in milliseconds -/// (**) the initial sequence number MUST be compatible with the sequence number resolution agreed in the -/// InitSyn/InitAck message exchange -/// (***) the cookie MUST be the same received in the INIT message with A==1 from the corresponding peer +/// (*) The initial sequence number MUST be compatible with the sequence number resolution agreed in the +/// [`super::InitSyn`]-[`super::InitAck`] message exchange +/// (**) The cookie MUST be the same received in the [`super::InitAck`]from the corresponding zenoh node /// ``` +/// +/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length +/// in bytes of the message, resulting in the maximum length of a message being 65535 bytes. +/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve +/// the boundary of the serialized messages. The length is encoded as little-endian. +/// In any case, the length of a message must not exceed 65535 bytes. +/// + +pub mod flag { + pub const A: u8 = 1 << 5; // 0x20 Ack if A==0 then the message is an InitSyn else it is an InitAck + pub const S: u8 = 1 << 6; // 0x40 Size params if S==1 then size parameters are exchanged + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct OpenSyn { From 1b20767d65d1978cd6bf3f784035af530ce01ed5 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 3 Feb 2023 17:47:29 +0100 Subject: [PATCH 013/203] Scout, Hello, Init, Open, KeepAlive rework. Incomplete Frame. --- Cargo.lock | 1 + commons/zenoh-codec/src/core/zenohid.rs | 33 +++- commons/zenoh-codec/src/lib.rs | 16 ++ commons/zenoh-codec/src/scouting/hello.rs | 18 +- commons/zenoh-codec/src/scouting/scout.rs | 25 ++- commons/zenoh-codec/src/transport/init.rs | 37 ++-- .../zenoh-codec/src/transport/keepalive.rs | 40 ++-- commons/zenoh-codec/src/transport/open.rs | 137 +++++++------- commons/zenoh-protocol/Cargo.toml | 1 + commons/zenoh-protocol/src/scouting/hello.rs | 4 +- commons/zenoh-protocol/src/scouting/scout.rs | 14 +- commons/zenoh-protocol/src/transport/frame.rs | 171 ++++++++---------- commons/zenoh-protocol/src/transport/init.rs | 2 +- .../zenoh-protocol/src/transport/keepalive.rs | 81 ++++++--- commons/zenoh-protocol/src/transport/mod.rs | 2 +- commons/zenoh-protocol/src/transport/open.rs | 16 +- 16 files changed, 332 insertions(+), 266 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e2862fce21..d9deeb664e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4219,6 +4219,7 @@ dependencies = [ "uhlc", "uuid", "zenoh-buffers", + "zenoh-collections", "zenoh-protocol", "zenoh-result", ] diff --git a/commons/zenoh-codec/src/core/zenohid.rs b/commons/zenoh-codec/src/core/zenohid.rs index a0e8596a71..f9d1c24a75 100644 --- a/commons/zenoh-codec/src/core/zenohid.rs +++ b/commons/zenoh-codec/src/core/zenohid.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Length}; use core::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -41,9 +41,38 @@ where if size > ZenohId::MAX_SIZE { return Err(DidntRead); } - let mut id = [0; ZenohId::MAX_SIZE]; reader.read_exact(&mut id[..size])?; ZenohId::try_from(&id[..size]).map_err(|_| DidntRead) } } + +impl WCodec<&ZenohId, &mut W> for Zenoh080Length +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ZenohId) -> Self::Output { + if self.length > ZenohId::MAX_SIZE { + return Err(DidntWrite); + } + writer.write_exact(x.as_slice()) + } +} + +impl RCodec for Zenoh080Length +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if self.length > ZenohId::MAX_SIZE { + return Err(DidntRead); + } + let mut id = [0; ZenohId::MAX_SIZE]; + reader.read_exact(&mut id[..self.length])?; + ZenohId::try_from(&id[..self.length]).map_err(|_| DidntRead) + } +} diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 45ff4d04dc..630253c60b 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -68,6 +68,22 @@ impl Zenoh080Condition { } } +#[derive(Clone, Copy, Default)] +#[non_exhaustive] +pub struct Zenoh080Length { + pub length: usize, + pub codec: Zenoh080, +} + +impl Zenoh080Length { + pub const fn new(length: usize) -> Self { + Self { + length, + codec: Zenoh080, + } + } +} + #[derive(Clone, Copy, Default)] #[non_exhaustive] pub struct Zenoh080Reliability { diff --git a/commons/zenoh-codec/src/scouting/hello.rs b/commons/zenoh-codec/src/scouting/hello.rs index d87bb7d34a..7bfd09a969 100644 --- a/commons/zenoh-codec/src/scouting/hello.rs +++ b/commons/zenoh-codec/src/scouting/hello.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; use alloc::{vec, vec::Vec}; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -42,13 +42,20 @@ where // Body self.write(&mut *writer, x.version)?; + + let mut flags: u8 = 0; let whatami: u8 = match x.whatami { WhatAmI::Router => 0b00, WhatAmI::Peer => 0b01, WhatAmI::Client => 0b10, }; - self.write(&mut *writer, whatami)?; - self.write(&mut *writer, &x.zid)?; + flags |= whatami & 0b11; + flags |= ((x.zid.size() - 1) as u8) << 4; + self.write(&mut *writer, flags)?; + + let lodec = Zenoh080Length::new(x.zid.size()); + lodec.write(&mut *writer, &x.zid)?; + if !x.locators.is_empty() { self.write(&mut *writer, x.locators.as_slice())?; } @@ -66,7 +73,6 @@ where fn read(self, reader: &mut R) -> Result { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); - codec.read(reader) } } @@ -91,8 +97,10 @@ where 0b10 => WhatAmI::Client, _ => return Err(DidntRead), }; + let length = 1 + ((flags >> 4) as usize); + let lodec = Zenoh080Length::new(length); + let zid: ZenohId = lodec.read(&mut *reader)?; - let zid: ZenohId = self.codec.read(&mut *reader)?; let locators = if imsg::has_flag(self.header, flag::L) { let locs: Vec = self.codec.read(&mut *reader)?; locs diff --git a/commons/zenoh-codec/src/scouting/scout.rs b/commons/zenoh-codec/src/scouting/scout.rs index 616c5f88d6..f86fcd0060 100644 --- a/commons/zenoh-codec/src/scouting/scout.rs +++ b/commons/zenoh-codec/src/scouting/scout.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; use core::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -34,18 +34,23 @@ where fn write(self, writer: &mut W, x: &Scout) -> Self::Output { // Header - let mut header = id::SCOUT; - if x.zid.is_some() { - header |= flag::I; - } + let header = id::SCOUT; self.write(&mut *writer, header)?; // Body self.write(&mut *writer, x.version)?; + + let mut flags: u8 = 0; let what: u8 = x.what.into(); - self.write(&mut *writer, what & 0b111)?; + flags |= what & 0b111; + if let Some(zid) = x.zid.as_ref() { + flags |= (((zid.size() - 1) as u8) << 4) | flag::I; + }; + self.write(&mut *writer, flags)?; + if let Some(zid) = x.zid.as_ref() { - self.write(&mut *writer, zid)?; + let lodec = Zenoh080Length::new(zid.size()); + lodec.write(&mut *writer, zid)?; } Ok(()) @@ -81,8 +86,10 @@ where let version: u8 = self.codec.read(&mut *reader)?; let flags: u8 = self.codec.read(&mut *reader)?; let what = WhatAmIMatcher::try_from(flags & 0b111).map_err(|_| DidntRead)?; - let zid = if imsg::has_flag(self.header, flag::I) { - let zid: ZenohId = self.codec.read(&mut *reader)?; + let zid = if imsg::has_flag(flags, flag::I) { + let length = 1 + ((flags >> 4) as usize); + let lodec = Zenoh080Length::new(length); + let zid: ZenohId = lodec.read(&mut *reader)?; Some(zid) } else { None diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index e4ad6beb68..468aa15025 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -11,8 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; -use core::convert::TryFrom; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -54,14 +53,11 @@ where WhatAmI::Peer => 0b01, WhatAmI::Client => 0b10, }; - let zid_len = match x.zid.size() { - s if (1..=ZenohId::MAX_SIZE).contains(&s) => s as u8, - _ => return Err(DidntWrite), - }; - let flags = ((zid_len - 1) << 4) | whatami; + let flags = ((x.zid.size() as u8 - 1) << 4) | whatami; self.write(&mut *writer, flags)?; - writer.write_exact(x.zid.as_slice())?; + let lodec = Zenoh080Length::new(x.zid.size()); + lodec.write(&mut *writer, &x.zid)?; if imsg::has_flag(header, flag::S) { self.write(&mut *writer, x.resolution.as_u8())?; @@ -122,11 +118,9 @@ where 0b10 => WhatAmI::Client, _ => return Err(DidntRead), }; - let size = 1 + ((flags >> 4) as usize); - - let mut id = [0; ZenohId::MAX_SIZE]; - reader.read_exact(&mut id[..size])?; - let zid = ZenohId::try_from(&id[..size]).map_err(|_| DidntRead)?; + let length = 1 + ((flags >> 4) as usize); + let lodec = Zenoh080Length::new(length); + let zid: ZenohId = lodec.read(&mut *reader)?; let mut resolution = Resolution::default(); let mut batch_size = u16::MAX; @@ -208,14 +202,11 @@ where WhatAmI::Peer => 0b01, WhatAmI::Client => 0b10, }; - let zid_len = match x.zid.size() { - s if (1..=ZenohId::MAX_SIZE).contains(&s) => s as u8, - _ => return Err(DidntWrite), - }; - let flags = ((zid_len - 1) << 4) | whatami; + let flags = ((x.zid.size() as u8 - 1) << 4) | whatami; self.write(&mut *writer, flags)?; - writer.write_exact(x.zid.as_slice())?; + let lodec = Zenoh080Length::new(x.zid.size()); + lodec.write(&mut *writer, &x.zid)?; if imsg::has_flag(header, flag::S) { self.write(&mut *writer, x.resolution.as_u8())?; @@ -278,11 +269,9 @@ where 0b10 => WhatAmI::Client, _ => return Err(DidntRead), }; - let size = 1 + ((flags >> 4) as usize); - - let mut id = [0; ZenohId::MAX_SIZE]; - reader.read_exact(&mut id[..size])?; - let zid = ZenohId::try_from(&id[..size]).map_err(|_| DidntRead)?; + let length = 1 + ((flags >> 4) as usize); + let lodec = Zenoh080Length::new(length); + let zid: ZenohId = lodec.read(&mut *reader)?; let mut resolution = Resolution::default(); let mut batch_size = u16::MAX; diff --git a/commons/zenoh-codec/src/transport/keepalive.rs b/commons/zenoh-codec/src/transport/keepalive.rs index ff70e5ed62..045dc03fa4 100644 --- a/commons/zenoh-codec/src/transport/keepalive.rs +++ b/commons/zenoh-codec/src/transport/keepalive.rs @@ -18,8 +18,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::ZenohId, - transport::{tmsg, KeepAlive}, + transport::{id, KeepAlive}, }; impl WCodec<&KeepAlive, &mut W> for Zenoh080 @@ -28,20 +27,11 @@ where { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &KeepAlive) -> Self::Output { - // // Header - // let mut header = tmsg::id::KEEP_ALIVE; - // if x.zid.is_some() { - // header |= tmsg::flag::I; - // } - // self.write(&mut *writer, header)?; - - // // Body - // if let Some(p) = x.zid.as_ref() { - // self.write(&mut *writer, p)?; - // } - // Ok(()) - Err(DidntWrite) + fn write(self, writer: &mut W, _x: &KeepAlive) -> Self::Output { + // Header + let header = id::KEEP_ALIVE; + self.write(&mut *writer, header)?; + Ok(()) } } @@ -64,19 +54,11 @@ where { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { - // if imsg::mid(self.header) != tmsg::id::KEEP_ALIVE { - // return Err(DidntRead); - // } - - // let zid = if imsg::has_flag(self.header, tmsg::flag::I) { - // let zid: ZenohId = self.codec.read(&mut *reader)?; - // Some(zid) - // } else { - // None - // }; + fn read(self, _reader: &mut R) -> Result { + if imsg::mid(self.header) != id::KEEP_ALIVE { + return Err(DidntRead); + } - // Ok(KeepAlive { zid }) - Err(DidntRead) + Ok(KeepAlive) } } diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index c6193052df..951862e4e0 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -21,7 +21,10 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, core::ZInt, - transport::{tmsg, OpenAck, OpenSyn}, + transport::{ + id, + open::{flag, OpenAck, OpenSyn}, + }, }; // OpenSyn @@ -32,23 +35,22 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &OpenSyn) -> Self::Output { - // // Header - // let mut header = tmsg::id::OPEN; - // if x.lease.as_millis() % 1_000 == 0 { - // header |= tmsg::flag::T2; - // } - // self.write(&mut *writer, header)?; - - // // Body - // if imsg::has_flag(header, tmsg::flag::T2) { - // self.write(&mut *writer, x.lease.as_secs() as ZInt)?; - // } else { - // self.write(&mut *writer, x.lease.as_millis() as ZInt)?; - // } - // self.write(&mut *writer, x.initial_sn)?; - // self.write(&mut *writer, &x.cookie)?; - // Ok(()) - Err(DidntWrite) + // Header + let mut header = id::OPEN; + if x.lease.as_millis() % 1_000 == 0 { + header |= flag::T; + } + self.write(&mut *writer, header)?; + + // Body + if imsg::has_flag(header, flag::T) { + self.write(&mut *writer, x.lease.as_secs() as ZInt)?; + } else { + self.write(&mut *writer, x.lease.as_millis() as ZInt)?; + } + self.write(&mut *writer, x.initial_sn)?; + self.write(&mut *writer, &x.cookie)?; + Ok(()) } } @@ -72,25 +74,24 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - // if imsg::mid(self.header) != imsg::id::OPEN || imsg::has_flag(self.header, tmsg::flag::A) { - // return Err(DidntRead); - // } - - // let lease: ZInt = self.codec.read(&mut *reader)?; - // let lease = if imsg::has_flag(self.header, tmsg::flag::T2) { - // Duration::from_secs(lease) - // } else { - // Duration::from_millis(lease) - // }; - // let initial_sn: ZInt = self.codec.read(&mut *reader)?; - // let cookie: ZSlice = self.codec.read(&mut *reader)?; - - // Ok(OpenSyn { - // lease, - // initial_sn, - // cookie, - // }) - Err(DidntRead) + if imsg::mid(self.header) != id::OPEN || imsg::has_flag(self.header, flag::A) { + return Err(DidntRead); + } + + let lease: ZInt = self.codec.read(&mut *reader)?; + let lease = if imsg::has_flag(self.header, flag::T) { + Duration::from_secs(lease) + } else { + Duration::from_millis(lease) + }; + let initial_sn: ZInt = self.codec.read(&mut *reader)?; + let cookie: ZSlice = self.codec.read(&mut *reader)?; + + Ok(OpenSyn { + lease, + initial_sn, + cookie, + }) } } @@ -102,24 +103,23 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &OpenAck) -> Self::Output { - // // Header - // let mut header = tmsg::id::OPEN; - // header |= tmsg::flag::A; - // // Verify that the timeout is expressed in seconds, i.e. subsec part is 0. - // if x.lease.subsec_nanos() == 0 { - // header |= tmsg::flag::T2; - // } - // self.write(&mut *writer, header)?; - - // // Body - // if imsg::has_flag(header, tmsg::flag::T2) { - // self.write(&mut *writer, x.lease.as_secs() as ZInt)?; - // } else { - // self.write(&mut *writer, x.lease.as_millis() as ZInt)?; - // } - // self.write(&mut *writer, x.initial_sn)?; - // Ok(()) - Err(DidntWrite) + // Header + let mut header = id::OPEN; + header |= flag::A; + // Verify that the timeout is expressed in seconds, i.e. subsec part is 0. + if x.lease.subsec_nanos() == 0 { + header |= flag::T; + } + self.write(&mut *writer, header)?; + + // Body + if imsg::has_flag(header, flag::T) { + self.write(&mut *writer, x.lease.as_secs() as ZInt)?; + } else { + self.write(&mut *writer, x.lease.as_millis() as ZInt)?; + } + self.write(&mut *writer, x.initial_sn)?; + Ok(()) } } @@ -143,19 +143,18 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - // if imsg::mid(self.header) != tmsg::id::OPEN || !imsg::has_flag(self.header, tmsg::flag::A) { - // return Err(DidntRead); - // } - - // let lease: ZInt = self.codec.read(&mut *reader)?; - // let lease = if imsg::has_flag(self.header, tmsg::flag::T2) { - // Duration::from_secs(lease) - // } else { - // Duration::from_millis(lease) - // }; - // let initial_sn: ZInt = self.codec.read(&mut *reader)?; - - // Ok(OpenAck { lease, initial_sn }) - Err(DidntRead) + if imsg::mid(self.header) != id::OPEN || !imsg::has_flag(self.header, flag::A) { + return Err(DidntRead); + } + + let lease: ZInt = self.codec.read(&mut *reader)?; + let lease = if imsg::has_flag(self.header, flag::T) { + Duration::from_secs(lease) + } else { + Duration::from_millis(lease) + }; + let initial_sn: ZInt = self.codec.read(&mut *reader)?; + + Ok(OpenAck { lease, initial_sn }) } } diff --git a/commons/zenoh-protocol/Cargo.toml b/commons/zenoh-protocol/Cargo.toml index 3878d797ee..18ab488b29 100644 --- a/commons/zenoh-protocol/Cargo.toml +++ b/commons/zenoh-protocol/Cargo.toml @@ -48,6 +48,7 @@ serde = { workspace = true, features = ["alloc"] } uhlc = { workspace = true } uuid = { workspace = true } # Needs a getrandom::getrandom() custom implementation on embedded (in root crate) zenoh-buffers = { path = "../zenoh-buffers/", default-features = false } +zenoh-collections = { path = "../zenoh-collections/", default-features = false } zenoh-result = { path = "../zenoh-result/", default-features = false } # INFO: May cause problems when testing no_std stuff. Check this tool: https://docs.rs/crate/cargo-no-dev-deps/0.1.0 diff --git a/commons/zenoh-protocol/src/scouting/hello.rs b/commons/zenoh-protocol/src/scouting/hello.rs index 557e0b577b..92799c7cf4 100644 --- a/commons/zenoh-protocol/src/scouting/hello.rs +++ b/commons/zenoh-protocol/src/scouting/hello.rs @@ -77,9 +77,9 @@ use core::fmt; /// +-+-+-+---------+ /// | version | /// +---------------+ -/// |X|X|X|X|X|X|wai| (*) +/// |zid_len|X|X|wai| (*) /// +-+-+-+-+-+-+-+-+ -/// ~ ~ -- ZenohID +/// ~ [u8] ~ -- ZenohID /// +---------------+ /// ~ ~ if Flag(L)==1 -- List of locators /// +---------------+ diff --git a/commons/zenoh-protocol/src/scouting/scout.rs b/commons/zenoh-protocol/src/scouting/scout.rs index 5bc51f491e..4ef1205b21 100644 --- a/commons/zenoh-protocol/src/scouting/scout.rs +++ b/commons/zenoh-protocol/src/scouting/scout.rs @@ -40,21 +40,25 @@ use crate::core::{whatami::WhatAmIMatcher, ZenohId}; /// /// ```text /// Header flags: -/// - I: ZenohID If I==1 then the ZenohID of the scouter is present. +/// - X: Reserved /// - X: Reserved /// - Z: Extensions If Z==1 then zenoh extensions will follow. /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|X|I| SCOUT | +/// |Z|X|X| SCOUT | /// +-+-+-+---------+ /// | version | /// +---------------+ -/// |X|X|X|X|X| what| (*) +/// |zid_len|I| what| (#)(*) /// +-+-+-+-+-+-+-+-+ -/// ~ ~ if Flag(I)==1 -- ZenohID +/// ~ [u8] ~ if Flag(I)==1 -- ZenohID /// +---------------+ /// +/// (#) ZID length. If Flag(I)==1 it indicates how many bytes are used for the ZenohID bytes. +/// A ZenohID is minimum 1 byte and maximum 16 bytes. Therefore, the actual lenght is computed as: +/// real_zid_len := 1 + zid_len +/// /// (*) What. It indicates a bitmap of WhatAmI interests. /// The valid bitflags are: /// - 0b001: Router @@ -62,7 +66,7 @@ use crate::core::{whatami::WhatAmIMatcher, ZenohId}; /// - 0b100: Client /// ``` pub mod flag { - pub const I: u8 = 1 << 5; // 0x20 ZenohID if I==1 then the PeerID is requested or present + pub const I: u8 = 1 << 3; // 0x04 ZenohID if I==1 then the ZenohID is present // pub const X: u8 = 1 << 6; // 0x40 Reserved pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow } diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 039a3ce32a..a24b3988ea 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -12,80 +12,73 @@ // ZettaScale Zenoh Team, // use crate::{ - core::{Channel, ZInt}, + core::{Channel, Reliability, ZInt}, zenoh::ZenohMessage, }; use alloc::vec::Vec; use zenoh_buffers::ZSlice; +use zenoh_collections::SingleOrVec; /// # Frame message /// +/// The [`Frame`] message is used to transmit one ore more complete serialized +/// [`crate::net::protocol::message::ZenohMessage`]. I.e., the total length of the +/// serialized [`crate::net::protocol::message::ZenohMessage`] (s) MUST be smaller +/// than the maximum batch size (i.e. 2^16-1) and the link MTU. +/// The [`Frame`] message is used as means to aggreate multiple +/// [`crate::net::protocol::message::ZenohMessage`] in a single atomic message that +/// goes on the wire. By doing so, many small messages can be batched together and +/// share common information like the sequence number. +/// +/// The [`Frame`] message flow is the following: +/// /// ```text -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. +/// A B +/// | FRAME | +/// |------------------>| +/// | | +/// ``` +/// +/// The [`Frame`] message structure is defined as follows: +/// +/// ```text +/// Flags: +/// - R: Reliable If R==1 it concerns the reliable channel, else the best-effort channel +/// - X: Reserved +/// - Z: Extensions If Z==1 then zenoh extensions will follow. /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |E|F|R| FRAME | -/// +-+-+-+-+-------+ -/// ~ SN ~ +/// |Z|X|R| FRAME | +/// +-+-+-+---------+ +/// % seq num % /// +---------------+ -/// ~ FramePayload ~ -- if F==1 then the payload is a fragment of a single Zenoh Message, a list of complete Zenoh Messages otherwise. +/// ~ [FrameExts] ~ if Flag(Z)==1 /// +---------------+ +/// ~ [NetworkMsg] ~ +/// +---------------+ +/// ``` /// -/// - if R==1 then the FRAME is sent on the reliable channel, best-effort otherwise. -/// - if F==1 then the FRAME is a fragment. -/// - if E==1 then the FRAME is the last fragment. E==1 is valid iff F==1. +/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length +/// in bytes of the message, resulting in the maximum length of a message being 65535 bytes. +/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve +/// the boundary of the serialized messages. The length is encoded as little-endian. +/// In any case, the length of a message must not exceed 65535 bytes. /// -/// NOTE: Only one bit would be sufficient to signal fragmentation in a IP-like fashion as follows: -/// - if F==1 then this FRAME is a fragment and more fragment will follow; -/// - if F==0 then the message is the last fragment if SN-1 had F==1, -/// otherwise it's a non-fragmented message. -/// However, this would require to always perform a two-steps de-serialization: first -/// de-serialize the FRAME and then the Payload. This is due to the fact the F==0 is ambigous -/// w.r.t. detecting if the FRAME is a fragment or not before SN re-ordering has occured. -/// By using the F bit to only signal whether the FRAME is fragmented or not, it allows to -/// de-serialize the payload in one single pass when F==0 since no re-ordering needs to take -/// place at this stage. Then, the F bit is used to detect the last fragment during re-ordering. -/// ``` #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Frame { - pub channel: Channel, + pub reliability: Reliability, pub sn: ZInt, - pub payload: FramePayload, + pub qos: ext::QoS, + pub payload: SingleOrVec<()>, } -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum FramePayload { - /// ```text - /// The Payload of a fragmented Frame. - /// - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// ~ payload bytes ~ - /// +---------------+ - /// ``` - Fragment { buffer: ZSlice, is_final: bool }, - /// ```text - /// The Payload of a batched Frame. - /// - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// ~ ZenohMessage ~ - /// +---------------+ - /// ~ ... ~ - Additional complete Zenoh messages. - /// +---------------+ - /// - /// NOTE: A batched Frame must contain at least one complete Zenoh message. - /// There is no upper limit to the number of Zenoh messages that can - /// be batched together in the same frame. - /// ``` - Messages { messages: Vec }, +// Extensions +pub mod ext { + use crate::common::ZExtZInt; + + pub type QoS = ZExtZInt<0x01>; } impl Frame { @@ -114,47 +107,40 @@ impl Frame { reliability, }; let sn: ZInt = rng.gen(); - let payload = if rng.gen_bool(0.5) { - FramePayload::Fragment { - buffer: ZSlice::rand(rng.gen_range(MIN..=MAX)), - is_final: rng.gen_bool(0.5), - } - } else { - let n = rng.gen_range(1..16); - let messages = (0..n) - .map(|_| { - let mut m = ZenohMessage::rand(); - m.channel = channel; - m - }) - .collect::>(); - FramePayload::Messages { messages } - }; + // let payload = if rng.gen_bool(0.5) { + // FramePayload::Fragment { + // buffer: ZSlice::rand(rng.gen_range(MIN..=MAX)), + // is_final: rng.gen_bool(0.5), + // } + // } else { + // let n = rng.gen_range(1..16); + // let messages = (0..n) + // .map(|_| { + // let mut m = ZenohMessage::rand(); + // m.channel = channel; + // m + // }) + // .collect::>(); + // FramePayload::Messages { messages } + // }; - Frame { - channel, - sn, - payload, - } + // Frame { + // channel, + // sn, + // payload, + // } + panic!() } } // FrameHeader -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[repr(u8)] -pub enum FrameKind { - Messages, - SomeFragment, - LastFragment, -} #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FrameHeader { - pub channel: Channel, + pub reliability: Reliability, pub sn: ZInt, - pub kind: FrameKind, + pub qos: ext::QoS, } impl FrameHeader { @@ -180,14 +166,15 @@ impl FrameHeader { reliability, }; let sn: ZInt = rng.gen(); - let kind = *[ - FrameKind::Messages, - FrameKind::SomeFragment, - FrameKind::LastFragment, - ] - .choose(&mut rng) - .unwrap(); + // let kind = *[ + // FrameKind::Messages, + // FrameKind::SomeFragment, + // FrameKind::LastFragment, + // ] + // .choose(&mut rng) + // .unwrap(); - FrameHeader { channel, sn, kind } + // FrameHeader { channel, sn, kind } + panic!(); } } diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index 26b50d3faf..ae1c45bf74 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -50,7 +50,7 @@ use zenoh_buffers::ZSlice; /// | version | /// +---------------+ /// |zid_len|x|x|wai| (#)(*) -/// +-----+-----+---+ +/// +-------+-+-+---+ /// ~ [u8] ~ -- ZenohID of the sender of the INIT message /// +---------------+ /// |x|x|kid|rid|fsn| \ -- SN/ID resolution (+) diff --git a/commons/zenoh-protocol/src/transport/keepalive.rs b/commons/zenoh-protocol/src/transport/keepalive.rs index 17126ee0e4..bfed3612aa 100644 --- a/commons/zenoh-protocol/src/transport/keepalive.rs +++ b/commons/zenoh-protocol/src/transport/keepalive.rs @@ -11,46 +11,77 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::ZenohId; /// # KeepAlive message /// +/// The [`KeepAlive`] message SHOULD be sent periodically to avoid the expiration of the +/// link lease period. A [`KeepAlive`] message MAY NOT be sent on the link if some other +/// data has been transmitted on the same link during the last keep alive interval. +/// +/// The [`KeepAlive`] message flow is the following: +/// /// ```text -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. +/// A B +/// | KEEP ALIVE | +/// |------------------>| +/// | | +/// ~ ... ~ +/// | | +/// | KEEP ALIVE | +/// |<------------------| +/// | | +/// | KEEP ALIVE | +/// |------------------>| +/// | | +/// ~ ... ~ +/// | | +/// | KEEP ALIVE | +/// |<------------------| +/// | | +/// ~ ... ~ +/// | | +/// | KEEP ALIVE | +/// |------------------>| +/// | | +/// ~ ... ~ +/// | | +/// ``` +/// +/// NOTE: In order to consider eventual packet loss, transmission latency and jitter, the time +/// interval between two subsequent [`KeepAlive`] messages SHOULD be set to one fourth of +/// the lease time. This is in-line with the ITU-T G.8013/Y.1731 specification on continous +/// connectivity check which considers a link as failed when no messages are received in +/// 3.5 times the target keep alive interval. /// -/// The KEEP_ALIVE message can be sent periodically to avoid the expiration of the transport lease -/// period in case there are no messages to be sent. +/// The [`KeepAlive`] message structure is defined as follows: +/// +/// ```text +/// Flags: +/// - X: Reserved +/// - X: Reserved +/// - Z: Extensions If Z==1 then zenoh extensions will follow. /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |X|X|I| K_ALIVE | -/// +-+-+-+-+-------+ -/// ~ zenoh_id ~ if I==1 -- Zenoh ID of the KEEP_ALIVE sender. +/// |Z|X|X| KALIVE | +/// +-+-+-+---------+ +/// ~ [KAliveExts] ~ if Flag(Z)==1 /// +---------------+ /// ``` +/// +/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length +/// in bytes of the message, resulting in the maximum length of a message being 65535 bytes. +/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve +/// the boundary of the serialized messages. The length is encoded as little-endian. +/// In any case, the length of a message must not exceed 65535 bytes. +/// #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct KeepAlive { - pub zid: Option, -} +pub struct KeepAlive; impl KeepAlive { #[cfg(feature = "test")] pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let zid = if rng.gen_bool(0.5) { - Some(ZenohId::default()) - } else { - None - }; - - Self { zid } + Self } } diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 7170cbcdd8..aa472a7d58 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -237,7 +237,7 @@ impl TransportMessage { attachment: Option, ) -> TransportMessage { TransportMessage { - body: TransportBody::KeepAlive(KeepAlive { zid }), + body: TransportBody::KeepAlive(KeepAlive), #[cfg(feature = "stats")] size: None, } diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 149d30e2e5..1b20172e90 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -23,6 +23,18 @@ use zenoh_buffers::ZSlice; /// For convenience, we call [`OpenSyn`] and [`OpenAck`] an OPEN message with the A flag /// is set to 0 and 1, respectively. /// +/// The [`OpenSyn`]/[`OpenAck`] message flow is the following: +/// +/// ```text +/// A B +/// | OPEN SYN | +/// |------------------>| +/// | | +/// | OPEN ACK | +/// |<------------------| +/// | | +/// ``` +/// /// ```text /// Flags: /// - A: Ack If A==0 then the message is an OpenSyn else it is an OpenAck @@ -37,7 +49,7 @@ use zenoh_buffers::ZSlice; /// +---------------+ /// % initial_sn % -- Initial SN proposed by the sender of the OPEN(*) /// +---------------+ -/// ~ ~ if Flag(A)==0 (**) -- Cookie +/// ~ ~ if Flag(A)==0 (**) -- Cookie /// +---------------+ /// ~ [OpenExts] ~ if Flag(Z)==1 /// +---------------+ @@ -56,7 +68,7 @@ use zenoh_buffers::ZSlice; pub mod flag { pub const A: u8 = 1 << 5; // 0x20 Ack if A==0 then the message is an InitSyn else it is an InitAck - pub const S: u8 = 1 << 6; // 0x40 Size params if S==1 then size parameters are exchanged + pub const T: u8 = 1 << 6; // 0x40 Lease period if T==1 then the lease period is in seconds else in milliseconds pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow } From 9c6546e2f26afe62bf3964b9af05be96b8811c88 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 7 Feb 2023 18:21:51 +0100 Subject: [PATCH 014/203] Frame message --- Cargo.lock | 1 + commons/zenoh-codec/Cargo.toml | 1 + commons/zenoh-codec/benches/codec.rs | 16 +- commons/zenoh-codec/src/transport/frame.rs | 277 +++++++++--------- commons/zenoh-codec/src/transport/init.rs | 6 +- commons/zenoh-codec/src/transport/join.rs | 2 +- commons/zenoh-codec/src/transport/mod.rs | 2 +- .../zenoh-protocol/src/common/extension.rs | 12 +- commons/zenoh-protocol/src/scouting/mod.rs | 64 ++-- commons/zenoh-protocol/src/transport/frame.rs | 154 ++++++---- commons/zenoh-protocol/src/transport/init.rs | 10 +- commons/zenoh-protocol/src/transport/mod.rs | 204 +++---------- 12 files changed, 338 insertions(+), 411 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9deeb664e..edb08c22e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3866,6 +3866,7 @@ dependencies = [ "uhlc", "uuid", "zenoh-buffers", + "zenoh-collections", "zenoh-protocol", "zenoh-shm", ] diff --git a/commons/zenoh-codec/Cargo.toml b/commons/zenoh-codec/Cargo.toml index 161780ce32..63ed5e1662 100644 --- a/commons/zenoh-codec/Cargo.toml +++ b/commons/zenoh-codec/Cargo.toml @@ -50,6 +50,7 @@ defmt = [ serde = { workspace = true, features = ["alloc"] } uhlc = { workspace = true } zenoh-buffers = { path = "../zenoh-buffers/", default-features = false } +zenoh-collections = { path = "../zenoh-collections/", default-features = false } zenoh-protocol = { path = "../zenoh-protocol/", default-features = false } zenoh-shm = { path = "../zenoh-shm/", optional = true } diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 755e7838c3..9bc1203a99 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -22,9 +22,9 @@ use zenoh_buffers::{ }; use zenoh_codec::*; use zenoh_protocol::{ - core::{Channel, CongestionControl, ZInt}, + core::{CongestionControl, Reliability, ZInt}, defaults::BATCH_SIZE, - transport::{Frame, FrameHeader, FrameKind}, + transport::{Frame, FrameHeader}, zenoh::Data, }; @@ -73,9 +73,9 @@ fn criterion_benchmark(c: &mut Criterion) { let codec = Zenoh080::default(); let frame = FrameHeader { - channel: Channel::default(), + reliability: Reliability::default(), sn: ZInt::MIN, - kind: FrameKind::Messages, + qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; let data = Data { @@ -110,9 +110,9 @@ fn criterion_benchmark(c: &mut Criterion) { let codec = Zenoh080::default(); let frame = FrameHeader { - channel: Channel::default(), + reliability: Reliability::default(), sn: ZInt::MIN, - kind: FrameKind::Messages, + qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; let data = Data { @@ -142,9 +142,9 @@ fn criterion_benchmark(c: &mut Criterion) { let codec = Zenoh080::default(); let frame = FrameHeader { - channel: Channel::default(), + reliability: Reliability::default(), sn: ZInt::MIN, - kind: FrameKind::Messages, + qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; let data = Data { diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index b0c008cc44..5ae85e81ea 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -12,18 +12,64 @@ // ZettaScale Zenoh Team, // use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Reliability}; -use alloc::vec::Vec; use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, writer::{DidntWrite, Writer}, }; +use zenoh_collections::SingleOrVec; use zenoh_protocol::{ - common::imsg, - core::{Channel, Priority, Reliability, ZInt}, - transport::{tmsg, Frame, FrameHeader, FrameKind, FramePayload}, + common::{imsg, ZExtUnknown, ZExtZInt}, + core::{Reliability, ZInt}, + transport::{ + frame::{ext, flag, Frame, FrameHeader}, + id, + }, zenoh::ZenohMessage, }; +// Extensions: QoS +impl WCodec<(&ext::QoS, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::QoS, bool)) -> Self::Output { + let (ext, more) = x; + self.write(&mut *writer, (&ext.inner, more)) + } +} + +impl RCodec<(ext::QoS, bool), &mut R> for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec<(ext::QoS, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { + if imsg::mid(self.header) != ext::QOS { + return Err(DidntRead); + } + + let (inner, more): (ZExtZInt<{ ext::QOS }>, bool) = self.read(&mut *reader)?; + Ok((ext::QoS { inner }, more)) + } +} + // FrameHeader impl WCodec<&FrameHeader, &mut W> for Zenoh080 where @@ -32,33 +78,25 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &FrameHeader) -> Self::Output { - // // Decorator - // if x.channel.priority != Priority::default() { - // self.write(&mut *writer, &x.channel.priority)?; - // } - - // // Header - // let mut header = tmsg::id::FRAME; - // if let Reliability::Reliable = x.channel.reliability { - // header |= tmsg::flag::R; - // } - // match x.kind { - // FrameKind::Messages => {} - // FrameKind::SomeFragment => { - // header |= tmsg::flag::F; - // } - // FrameKind::LastFragment => { - // header |= tmsg::flag::F; - // header |= tmsg::flag::E; - // } - // } - // self.write(&mut *writer, header)?; - - // // Body - // self.write(&mut *writer, x.sn)?; - - // Ok(()) - Err(DidntWrite) + // Header + let mut header = id::FRAME; + if let Reliability::Reliable = x.reliability { + header |= flag::R; + } + if x.qos != ext::QoS::default() { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.sn)?; + + // Extensions + if x.qos != ext::QoS::default() { + self.write(&mut *writer, (&x.qos.inner, false))?; + } + + Ok(()) } } @@ -71,7 +109,6 @@ where fn read(self, reader: &mut R) -> Result { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); - codec.read(reader) } } @@ -82,41 +119,42 @@ where { type Error = DidntRead; - fn read(mut self, reader: &mut R) -> Result { - // let mut priority = Priority::default(); - // if imsg::mid(self.header) == tmsg::id::PRIORITY { - // // Decode priority - // priority = self.read(&mut *reader)?; - // // Read next header - // self.header = self.codec.read(&mut *reader)?; - // } - - // if imsg::mid(self.header) != tmsg::id::FRAME { - // return Err(DidntRead); - // } - - // let reliability = match imsg::has_flag(self.header, tmsg::flag::R) { - // true => Reliability::Reliable, - // false => Reliability::BestEffort, - // }; - // let channel = Channel { - // priority, - // reliability, - // }; - // let sn: ZInt = self.codec.read(&mut *reader)?; - - // let kind = if imsg::has_flag(self.header, tmsg::flag::F) { - // if imsg::has_flag(self.header, tmsg::flag::E) { - // FrameKind::LastFragment - // } else { - // FrameKind::SomeFragment - // } - // } else { - // FrameKind::Messages - // }; - - // Ok(FrameHeader { channel, sn, kind }) - Err(DidntRead) + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::FRAME { + return Err(DidntRead); + } + + let reliability = match imsg::has_flag(self.header, flag::R) { + true => Reliability::Reliable, + false => Reliability::BestEffort, + }; + let sn: ZInt = self.codec.read(&mut *reader)?; + + // Extensions + let mut qos = ext::QoS::default(); + + let mut has_more = imsg::has_flag(self.header, flag::Z); + while has_more { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QOS => { + let (q, more): (ext::QoS, bool) = eodec.read(&mut *reader)?; + qos = q; + has_more = more; + } + _ => { + let (_, more): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_more = more; + } + } + } + + Ok(FrameHeader { + reliability, + sn, + qos, + }) } } @@ -128,35 +166,22 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Frame) -> Self::Output { - // // Header - // let kind = match &x.payload { - // FramePayload::Fragment { is_final, .. } => { - // if *is_final { - // FrameKind::LastFragment - // } else { - // FrameKind::SomeFragment - // } - // } - // FramePayload::Messages { .. } => FrameKind::Messages, - // }; - // let header = FrameHeader { - // channel: x.channel, - // sn: x.sn, - // kind, - // }; - // self.write(&mut *writer, &header)?; - - // // Body - // match &x.payload { - // FramePayload::Fragment { buffer, .. } => writer.write_zslice(buffer)?, - // FramePayload::Messages { messages } => { - // for m in messages.iter() { - // self.write(&mut *writer, m)?; - // } - // } - // } - // Ok(()) - Err(DidntWrite) + // Header + let header = FrameHeader { + reliability: x.reliability, + sn: x.sn, + qos: x.qos, + }; + self.write(&mut *writer, &header)?; + + dbg!("A"); + + // Body + for m in x.payload.as_ref() { + self.write(&mut *writer, m)?; + } + + Ok(()) } } @@ -180,43 +205,27 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - // let header: FrameHeader = self.read(&mut *reader)?; - - // let payload = match header.kind { - // FrameKind::Messages => { - // let rcode = Zenoh080Reliability { - // reliability: header.channel.reliability, - // ..Default::default() - // }; - - // let mut messages: Vec = Vec::with_capacity(1); - // while reader.can_read() { - // let mark = reader.mark(); - // let res: Result = rcode.read(&mut *reader); - // match res { - // Ok(m) => messages.push(m), - // Err(_) => { - // reader.rewind(mark); - // break; - // } - // } - // } - // FramePayload::Messages { messages } - // } - // FrameKind::SomeFragment | FrameKind::LastFragment => { - // // A fragmented frame is not supposed to be followed by - // // any other frame in the same batch. Read all the bytes. - // let buffer = reader.read_zslice(reader.remaining())?; - // let is_final = header.kind == FrameKind::LastFragment; - // FramePayload::Fragment { buffer, is_final } - // } - // }; - - // Ok(Frame { - // channel: header.channel, - // sn: header.sn, - // payload, - // }) - Err(DidntRead) + let header: FrameHeader = self.read(&mut *reader)?; + + let rcode = Zenoh080Reliability::new(header.reliability); + let mut payload = SingleOrVec::default(); + while reader.can_read() { + let mark = reader.mark(); + let res: Result = rcode.read(&mut *reader); + match res { + Ok(m) => payload.push(m), + Err(_) => { + reader.rewind(mark); + break; + } + } + } + + Ok(Frame { + reliability: header.reliability, + sn: header.sn, + qos: header.qos, + payload, + }) } } diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index 468aa15025..b190531874 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -293,17 +293,17 @@ where let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { - ext::QoS::ID => { + ext::QOS => { let (q, more): (ext::QoS, bool) = eodec.read(&mut *reader)?; qos = Some(q); has_more = more; } - ext::Shm::ID => { + ext::SHM => { let (s, more): (ext::Shm, bool) = eodec.read(&mut *reader)?; shm = Some(s); has_more = more; } - ext::Auth::ID => { + ext::AUTH => { let (a, more): (ext::Auth, bool) = eodec.read(&mut *reader)?; auth = Some(a); has_more = more; diff --git a/commons/zenoh-codec/src/transport/join.rs b/commons/zenoh-codec/src/transport/join.rs index 9c2d3ce8b5..cb992214ca 100644 --- a/commons/zenoh-codec/src/transport/join.rs +++ b/commons/zenoh-codec/src/transport/join.rs @@ -21,7 +21,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, core::{Priority, WhatAmI, ZInt, ZenohId}, - transport::{tmsg, ConduitSn, ConduitSnList, Join}, + transport::{ConduitSn, ConduitSnList, Join}, }; impl WCodec<&Join, &mut W> for Zenoh080 diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index e066529424..e7aa2f6be4 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -55,7 +55,7 @@ where fn read(self, reader: &mut R) -> Result { let header: u8 = self.read(&mut *reader)?; - let mut codec = Zenoh080Header::new(header); + let codec = Zenoh080Header::new(header); let body = match imsg::mid(codec.header) { id::INIT => { if !imsg::has_flag(codec.header, zenoh_protocol::transport::init::flag::A) { diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index 04a50c61b7..d5e620c6df 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -62,7 +62,7 @@ pub mod iext { pub const FLAG_Z: u8 = 1 << 7; } -#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub struct ZExtUnit; impl ZExtUnit<{ ID }> { @@ -78,7 +78,7 @@ impl ZExtUnit<{ ID }> { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ZExtZInt { pub value: ZInt, } @@ -100,7 +100,7 @@ impl ZExtZInt<{ ID }> { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ZExtZSlice { pub value: ZSlice, } @@ -122,7 +122,7 @@ impl ZExtZSlice<{ ID }> { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ZExtZBuf { pub value: ZBuf, } @@ -144,13 +144,13 @@ impl ZExtZBuf<{ ID }> { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ZExtUnknown { pub id: u8, pub body: ZExtensionBody, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum ZExtensionBody { Unit, ZInt(ZInt), diff --git a/commons/zenoh-protocol/src/scouting/mod.rs b/commons/zenoh-protocol/src/scouting/mod.rs index 2fd560abaa..e43323339a 100644 --- a/commons/zenoh-protocol/src/scouting/mod.rs +++ b/commons/zenoh-protocol/src/scouting/mod.rs @@ -14,11 +14,6 @@ pub mod hello; pub mod scout; -use crate::{ - common::Attachment, - core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}, -}; -use alloc::vec::Vec; pub use hello::Hello; pub use scout::Scout; @@ -45,50 +40,39 @@ pub struct ScoutingMessage { } impl ScoutingMessage { - pub fn make_scout( - what: WhatAmIMatcher, - zid: Option, - attachment: Option, - ) -> ScoutingMessage { - let version = crate::VERSION; - ScoutingMessage { - body: ScoutingBody::Scout(Scout { version, what, zid }), - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_hello( - whatami: WhatAmI, - zid: ZenohId, - locators: Vec, - attachment: Option, - ) -> ScoutingMessage { - let version = crate::VERSION; - ScoutingMessage { - body: ScoutingBody::Hello(Hello { - version, - whatami, - zid, - locators, - }), - #[cfg(feature = "stats")] - size: None, - } - } - #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; let mut rng = rand::thread_rng(); - let body = match rng.gen_range(0..2) { + match rng.gen_range(0..2) { 0 => ScoutingBody::Scout(Scout::rand()), 1 => ScoutingBody::Hello(Hello::rand()), _ => unreachable!(), - }; + } + .into() + } +} + +impl From for ScoutingMessage { + fn from(body: ScoutingBody) -> Self { + Self { + body, + #[cfg(feature = "stats")] + size: None, + } + } +} + +impl From for ScoutingMessage { + fn from(scout: Scout) -> Self { + ScoutingBody::Scout(scout).into() + } +} - Self { body } +impl From for ScoutingMessage { + fn from(hello: Hello) -> Self { + ScoutingBody::Hello(hello).into() } } diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index a24b3988ea..fe2c2a0d40 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -12,11 +12,9 @@ // ZettaScale Zenoh Team, // use crate::{ - core::{Channel, Reliability, ZInt}, + core::{Reliability, ZInt}, zenoh::ZenohMessage, }; -use alloc::vec::Vec; -use zenoh_buffers::ZSlice; use zenoh_collections::SingleOrVec; /// # Frame message @@ -65,32 +63,96 @@ use zenoh_collections::SingleOrVec; /// the boundary of the serialized messages. The length is encoded as little-endian. /// In any case, the length of a message must not exceed 65535 bytes. /// +pub mod flag { + pub const R: u8 = 1 << 5; // 0x20 Reliable if R==1 then the frame is reliable + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Frame { pub reliability: Reliability, pub sn: ZInt, pub qos: ext::QoS, - pub payload: SingleOrVec<()>, + pub payload: SingleOrVec, } // Extensions pub mod ext { - use crate::common::ZExtZInt; + use crate::core::ZInt; + use crate::{common::ZExtZInt, core::Priority}; + + pub const QOS: u8 = 0x01; + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|0_1| QoS | + /// +-+-+-+---------+ + /// % reserved|prio % + /// +---------------+ + #[repr(transparent)] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub struct QoS { + pub inner: ZExtZInt, + } + + impl QoS { + pub fn new(priority: Priority) -> Self { + Self { + inner: ZExtZInt::new(priority as ZInt), + } + } - pub type QoS = ZExtZInt<0x01>; + pub fn priority(&self) -> Priority { + // Safety: a unit test below checks the validity of the following unsafe code + unsafe { core::mem::transmute((self.inner.value & 0b111) as u8) } + } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + Self { + inner: ZExtZInt::rand(), + } + } + } + + impl Default for QoS { + fn default() -> Self { + Self::new(Priority::default()) + } + } + + mod tests { + #[test] + fn priority() { + use crate::{core::Priority, transport::frame::ext::QoS}; + + let ps = [ + Priority::Control, + Priority::RealTime, + Priority::InteractiveHigh, + Priority::InteractiveLow, + Priority::DataHigh, + Priority::Data, + Priority::DataLow, + Priority::Background, + ]; + for p in ps.iter() { + let q = QoS::new(*p); + assert_eq!(q.priority(), *p); + } + } + } } impl Frame { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::{Priority, Reliability}; + use crate::core::Priority; use core::convert::TryInto; use rand::Rng; - const MIN: usize = 1; - const MAX: usize = 1_024; - let mut rng = rand::thread_rng(); let priority: Priority = rng @@ -102,39 +164,26 @@ impl Frame { } else { Reliability::BestEffort }; - let channel = Channel { - priority, - reliability, - }; let sn: ZInt = rng.gen(); - // let payload = if rng.gen_bool(0.5) { - // FramePayload::Fragment { - // buffer: ZSlice::rand(rng.gen_range(MIN..=MAX)), - // is_final: rng.gen_bool(0.5), - // } - // } else { - // let n = rng.gen_range(1..16); - // let messages = (0..n) - // .map(|_| { - // let mut m = ZenohMessage::rand(); - // m.channel = channel; - // m - // }) - // .collect::>(); - // FramePayload::Messages { messages } - // }; - - // Frame { - // channel, - // sn, - // payload, - // } - panic!() + let qos = ext::QoS::rand(); + let mut payload = SingleOrVec::default(); + for _ in 0..rng.gen_range(1..4) { + let mut m = ZenohMessage::rand(); + m.channel.reliability = reliability; + m.channel.priority = priority; + payload.push(m); + } + + Frame { + reliability, + sn, + qos, + payload, + } } } // FrameHeader - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FrameHeader { @@ -146,35 +195,22 @@ pub struct FrameHeader { impl FrameHeader { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::{Priority, Reliability}; - use core::convert::TryInto; - use rand::{seq::SliceRandom, Rng}; + use rand::Rng; let mut rng = rand::thread_rng(); - let priority: Priority = rng - .gen_range(Priority::MAX as u8..=Priority::MIN as u8) - .try_into() - .unwrap(); let reliability = if rng.gen_bool(0.5) { Reliability::Reliable } else { Reliability::BestEffort }; - let channel = Channel { - priority, - reliability, - }; let sn: ZInt = rng.gen(); - // let kind = *[ - // FrameKind::Messages, - // FrameKind::SomeFragment, - // FrameKind::LastFragment, - // ] - // .choose(&mut rng) - // .unwrap(); - - // FrameHeader { channel, sn, kind } - panic!(); + let qos = ext::QoS::rand(); + + FrameHeader { + reliability, + sn, + qos, + } } } diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index ae1c45bf74..d54ca15dc9 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -184,9 +184,13 @@ pub struct InitSyn { pub mod ext { use crate::common::{ZExtUnit, ZExtZSlice}; - pub type QoS = ZExtUnit<0x01>; - pub type Shm = ZExtZSlice<0x02>; - pub type Auth = ZExtZSlice<0x03>; + pub const QOS: u8 = 0x01; + pub const SHM: u8 = 0x02; + pub const AUTH: u8 = 0x03; + + pub type QoS = ZExtUnit; + pub type Shm = ZExtZSlice; + pub type Auth = ZExtZSlice; } impl InitSyn { diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index aa472a7d58..3c715b5126 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -18,18 +18,14 @@ pub mod join; pub mod keepalive; pub mod open; -use crate::{ - common::Attachment, - core::{Channel, Priority, WhatAmI, ZInt, ZenohId}, -}; +use crate::core::{Priority, ZInt}; pub use close::Close; -use core::{convert::TryInto, fmt, time::Duration}; +use core::{convert::TryInto, fmt}; pub use frame::*; pub use init::{InitAck, InitSyn}; pub use join::*; pub use keepalive::*; pub use open::*; -use zenoh_buffers::ZSlice; pub mod id { pub const JOIN: u8 = 0x01; // For multicast communications only @@ -87,33 +83,6 @@ pub struct ConduitSn { pub best_effort: ZInt, } -pub mod tmsg { - use super::Priority; - use crate::common::imsg; - - // Transport message IDs -- Re-export of some of the Inner Message IDs - pub mod id { - use super::imsg; - - // Message decorators - pub const PRIORITY: u8 = imsg::id::PRIORITY; - pub const ATTACHMENT: u8 = imsg::id::ATTACHMENT; - } - - pub mod conduit { - use super::{imsg, Priority}; - - pub const CONTROL: u8 = (Priority::Control as u8) << imsg::HEADER_BITS; - pub const REAL_TIME: u8 = (Priority::RealTime as u8) << imsg::HEADER_BITS; - pub const INTERACTIVE_HIGH: u8 = (Priority::InteractiveHigh as u8) << imsg::HEADER_BITS; - pub const INTERACTIVE_LOW: u8 = (Priority::InteractiveLow as u8) << imsg::HEADER_BITS; - pub const DATA_HIGH: u8 = (Priority::DataHigh as u8) << imsg::HEADER_BITS; - pub const DATA: u8 = (Priority::Data as u8) << imsg::HEADER_BITS; - pub const DATA_LOW: u8 = (Priority::DataLow as u8) << imsg::HEADER_BITS; - pub const BACKGROUND: u8 = (Priority::Background as u8) << imsg::HEADER_BITS; - } -} - // Zenoh messages at zenoh-transport level #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -137,129 +106,6 @@ pub struct TransportMessage { } impl TransportMessage { - pub fn make_init_syn( - version: u8, - whatami: WhatAmI, - zid: ZenohId, - sn_resolution: ZInt, - is_qos: bool, - attachment: Option, - ) -> TransportMessage { - TransportMessage { - body: TransportBody::InitSyn(InitSyn::rand()), // @TODO - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_init_ack( - whatami: WhatAmI, - zid: ZenohId, - sn_resolution: Option, - is_qos: bool, - cookie: ZSlice, - attachment: Option, - ) -> TransportMessage { - TransportMessage { - body: TransportBody::InitAck(InitAck::rand()), // @TODO - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_open_syn( - lease: Duration, - initial_sn: ZInt, - cookie: ZSlice, - attachment: Option, - ) -> TransportMessage { - TransportMessage { - body: TransportBody::OpenSyn(OpenSyn { - lease, - initial_sn, - cookie, - }), - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_open_ack( - lease: Duration, - initial_sn: ZInt, - attachment: Option, - ) -> TransportMessage { - TransportMessage { - body: TransportBody::OpenAck(OpenAck { lease, initial_sn }), - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_join( - version: u8, - whatami: WhatAmI, - zid: ZenohId, - lease: Duration, - sn_resolution: ZInt, - next_sns: ConduitSnList, - attachment: Option, - ) -> TransportMessage { - TransportMessage { - body: TransportBody::Join(Join { - version, - whatami, - zid, - lease, - sn_resolution, - next_sns, - }), - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_close( - zid: Option, - reason: u8, - session: bool, - attachment: Option, - ) -> TransportMessage { - TransportMessage { - body: TransportBody::Close(Close { reason, session }), - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_keep_alive( - zid: Option, - attachment: Option, - ) -> TransportMessage { - TransportMessage { - body: TransportBody::KeepAlive(KeepAlive), - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_frame( - channel: Channel, - sn: ZInt, - payload: FramePayload, - attachment: Option, - ) -> TransportMessage { - TransportMessage { - body: TransportBody::Frame(Frame { - channel, - sn, - payload, - }), - #[cfg(feature = "stats")] - size: None, - } - } - #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; @@ -281,3 +127,49 @@ impl TransportMessage { Self { body } } } + +impl From for TransportMessage { + fn from(body: TransportBody) -> Self { + Self { + body, + #[cfg(feature = "stats")] + size: None, + } + } +} + +impl From for TransportMessage { + fn from(init_syn: InitSyn) -> Self { + TransportBody::InitSyn(init_syn).into() + } +} + +impl From for TransportMessage { + fn from(init_ack: InitAck) -> Self { + TransportBody::InitAck(init_ack).into() + } +} + +impl From for TransportMessage { + fn from(open_syn: OpenSyn) -> Self { + TransportBody::OpenSyn(open_syn).into() + } +} + +impl From for TransportMessage { + fn from(open_ack: OpenAck) -> Self { + TransportBody::OpenAck(open_ack).into() + } +} + +impl From for TransportMessage { + fn from(close: Close) -> Self { + TransportBody::Close(close).into() + } +} + +impl From for TransportMessage { + fn from(keep_alive: KeepAlive) -> Self { + TransportBody::KeepAlive(keep_alive).into() + } +} From efebb276a479c8019235611ee688ef25ae987847 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 7 Feb 2023 18:51:58 +0100 Subject: [PATCH 015/203] Fragment message --- commons/zenoh-codec/src/common/attachment.rs | 9 +- commons/zenoh-codec/src/common/priority.rs | 4 +- commons/zenoh-codec/src/transport/fragment.rs | 171 ++++++++++++++++++ commons/zenoh-codec/src/transport/frame.rs | 2 - commons/zenoh-codec/src/transport/mod.rs | 2 + commons/zenoh-codec/tests/codec.rs | 10 + .../zenoh-protocol/src/transport/fragment.rs | 140 ++++++++++++++ commons/zenoh-protocol/src/transport/mod.rs | 26 ++- 8 files changed, 349 insertions(+), 15 deletions(-) create mode 100644 commons/zenoh-codec/src/transport/fragment.rs create mode 100644 commons/zenoh-protocol/src/transport/fragment.rs diff --git a/commons/zenoh-codec/src/common/attachment.rs b/commons/zenoh-codec/src/common/attachment.rs index eb554efda6..3a44edb532 100644 --- a/commons/zenoh-codec/src/common/attachment.rs +++ b/commons/zenoh-codec/src/common/attachment.rs @@ -17,10 +17,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, ZBuf, }; -use zenoh_protocol::{ - common::{imsg, Attachment}, - transport::tmsg, -}; +use zenoh_protocol::common::{imsg, Attachment}; #[cfg(feature = "shared-memory")] use {crate::Zenoh080Condition, core::any::TypeId, zenoh_shm::SharedMemoryBufInfoSerialized}; @@ -32,8 +29,8 @@ where fn write(self, writer: &mut W, x: &Attachment) -> Self::Output { // Header - #[allow(unused_mut)] // mut required with #[cfg(feature = "shared-memory")] - let mut header = tmsg::id::ATTACHMENT; + // #[allow(unused_mut)] // mut required with #[cfg(feature = "shared-memory")] + // let mut header = tmsg::id::ATTACHMENT; // #[cfg(feature = "shared-memory")] // { diff --git a/commons/zenoh-codec/src/common/priority.rs b/commons/zenoh-codec/src/common/priority.rs index d9909c4b5e..bd3f5857ba 100644 --- a/commons/zenoh-codec/src/common/priority.rs +++ b/commons/zenoh-codec/src/common/priority.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_protocol::{common::imsg, core::Priority, transport::tmsg}; +use zenoh_protocol::{common::imsg, core::Priority}; impl WCodec<&Priority, &mut W> for Zenoh080 where @@ -27,7 +27,7 @@ where fn write(self, writer: &mut W, x: &Priority) -> Self::Output { // Header - let header = tmsg::id::PRIORITY | ((*x as u8) << imsg::HEADER_BITS); + let header = imsg::id::PRIORITY | ((*x as u8) << imsg::HEADER_BITS); self.write(&mut *writer, header)?; Ok(()) } diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs new file mode 100644 index 0000000000..be3895e573 --- /dev/null +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -0,0 +1,171 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{BacktrackableReader, DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{imsg, ZExtUnknown}, + core::{Reliability, ZInt}, + transport::{ + fragment::{ext, flag, Fragment, FragmentHeader}, + id, + }, +}; + +// FragmentHeader +impl WCodec<&FragmentHeader, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &FragmentHeader) -> Self::Output { + // Header + let mut header = id::FRAGMENT; + if let Reliability::Reliable = x.reliability { + header |= flag::R; + } + if x.qos != ext::QoS::default() { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.sn)?; + + // Extensions + if x.qos != ext::QoS::default() { + self.write(&mut *writer, (&x.qos.inner, false))?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::FRAGMENT { + return Err(DidntRead); + } + + let reliability = match imsg::has_flag(self.header, flag::R) { + true => Reliability::Reliable, + false => Reliability::BestEffort, + }; + let sn: ZInt = self.codec.read(&mut *reader)?; + + // Extensions + let mut qos = ext::QoS::default(); + + let mut has_more = imsg::has_flag(self.header, flag::Z); + while has_more { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QOS => { + let (q, more): (ext::QoS, bool) = eodec.read(&mut *reader)?; + qos = q; + has_more = more; + } + _ => { + let (_, more): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_more = more; + } + } + } + + Ok(FragmentHeader { + reliability, + sn, + qos, + }) + } +} + +// Fragment +impl WCodec<&Fragment, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Fragment) -> Self::Output { + // Header + let header = FragmentHeader { + reliability: x.reliability, + sn: x.sn, + qos: x.qos, + }; + self.write(&mut *writer, &header)?; + + // Body + for m in x.payload.as_ref() { + self.write(&mut *writer, m)?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader + BacktrackableReader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader + BacktrackableReader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: FragmentHeader = self.read(&mut *reader)?; + let payload = reader.read_zslice(reader.remaining())?; + + Ok(Fragment { + reliability: header.reliability, + sn: header.sn, + qos: header.qos, + payload, + }) + } +} diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 5ae85e81ea..427e832cea 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -174,8 +174,6 @@ where }; self.write(&mut *writer, &header)?; - dbg!("A"); - // Body for m in x.payload.as_ref() { self.write(&mut *writer, m)?; diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index e7aa2f6be4..4684d789c0 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // mod close; +mod fragment; mod frame; mod init; mod join; @@ -42,6 +43,7 @@ where TransportBody::Close(b) => self.write(&mut *writer, b), TransportBody::KeepAlive(b) => self.write(&mut *writer, b), TransportBody::Frame(b) => self.write(&mut *writer, b), + TransportBody::Fragment(b) => self.write(&mut *writer, b), } } } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 0e7347a8ed..b77c09165d 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -281,6 +281,16 @@ fn codec_frame() { run!(Frame, Frame::rand()); } +#[test] +fn codec_fragment_header() { + run!(FragmentHeader, FragmentHeader::rand()); +} + +#[test] +fn codec_fragment() { + run!(Fragment, Fragment::rand()); +} + #[test] fn codec_transport() { run!(TransportMessage, TransportMessage::rand()); diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs new file mode 100644 index 0000000000..5764c03d85 --- /dev/null +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -0,0 +1,140 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::core::{Reliability, ZInt}; +use zenoh_buffers::ZSlice; + +/// # Fragment message +/// +/// The [`Fragment`] message is used to transmit on the wire large [`crate::zenoh::ZenohMessage`] +/// that require fragmentation because they are larger thatn the maximum batch size +/// (i.e. 2^16-1) and/or the link MTU. +/// +/// The [`Fragment`] message flow is the following: +/// +/// ```text +/// A B +/// | FRAGMENT(MORE) | +/// |------------------>| +/// | FRAGMENT(MORE) | +/// |------------------>| +/// | FRAGMENT(MORE) | +/// |------------------>| +/// | FRAGMENT | +/// |------------------>| +/// | | +/// ``` +/// +/// The [`Fragment`] message structure is defined as follows: +/// +/// ```text +/// Flags: +/// - R: Reliable If R==1 it concerns the reliable channel, else the best-effort channel +/// - M: More If M==1 then other fragments will follow +/// - Z: Extensions If Z==1 then zenoh extensions will follow. +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|R| FRAGMENT| +/// +-+-+-+---------+ +/// % seq num % +/// +---------------+ +/// ~ [FragExts] ~ if Flag(Z)==1 +/// +---------------+ +/// ~ [u8] ~ +/// +---------------+ +/// ``` +/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length +/// in bytes of the message, resulting in the maximum length of a message being 65535 bytes. +/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve +/// the boundary of the serialized messages. The length is encoded as little-endian. +/// In any case, the length of a message must not exceed 65535 bytes. +/// +pub mod flag { + pub const R: u8 = 1 << 5; // 0x20 Reliable if R==1 then the frame is reliable + pub const M: u8 = 1 << 6; // 0x40 More if M==1 then another fragment will follow + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct Fragment { + pub reliability: Reliability, + pub sn: ZInt, + pub qos: ext::QoS, + pub payload: ZSlice, +} + +// Extensions +pub mod ext { + pub const QOS: u8 = crate::transport::frame::ext::QOS; + + pub type QoS = crate::transport::frame::ext::QoS; +} + +impl Fragment { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let reliability = if rng.gen_bool(0.5) { + Reliability::Reliable + } else { + Reliability::BestEffort + }; + let sn: ZInt = rng.gen(); + let qos = ext::QoS::rand(); + let payload = ZSlice::rand(rng.gen_range(8..128)); + + Fragment { + reliability, + sn, + qos, + payload, + } + } +} + +// FragmentHeader +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct FragmentHeader { + pub reliability: Reliability, + pub sn: ZInt, + pub qos: ext::QoS, +} + +impl FragmentHeader { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let reliability = if rng.gen_bool(0.5) { + Reliability::Reliable + } else { + Reliability::BestEffort + }; + let sn: ZInt = rng.gen(); + let qos = ext::QoS::rand(); + + FragmentHeader { + reliability, + sn, + qos, + } + } +} diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 3c715b5126..2110a7b678 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // pub mod close; +pub mod fragment; pub mod frame; pub mod init; pub mod join; @@ -21,11 +22,12 @@ pub mod open; use crate::core::{Priority, ZInt}; pub use close::Close; use core::{convert::TryInto, fmt}; -pub use frame::*; +pub use fragment::{Fragment, FragmentHeader}; +pub use frame::{Frame, FrameHeader}; pub use init::{InitAck, InitSyn}; -pub use join::*; -pub use keepalive::*; -pub use open::*; +pub use join::Join; +pub use keepalive::KeepAlive; +pub use open::{OpenAck, OpenSyn}; pub mod id { pub const JOIN: u8 = 0x01; // For multicast communications only @@ -95,6 +97,7 @@ pub enum TransportBody { Close(Close), KeepAlive(KeepAlive), Frame(Frame), + Fragment(Fragment), } #[derive(Debug, Clone, PartialEq, Eq)] @@ -112,7 +115,7 @@ impl TransportMessage { let mut rng = rand::thread_rng(); - let body = match rng.gen_range(0..8) { + let body = match rng.gen_range(0..9) { 0 => TransportBody::InitSyn(InitSyn::rand()), 1 => TransportBody::InitAck(InitAck::rand()), 2 => TransportBody::OpenSyn(OpenSyn::rand()), @@ -121,6 +124,7 @@ impl TransportMessage { 5 => TransportBody::Close(Close::rand()), 6 => TransportBody::KeepAlive(KeepAlive::rand()), 7 => TransportBody::Frame(Frame::rand()), + 8 => TransportBody::Fragment(Fragment::rand()), _ => unreachable!(), }; @@ -173,3 +177,15 @@ impl From for TransportMessage { TransportBody::KeepAlive(keep_alive).into() } } + +impl From for TransportMessage { + fn from(frame: Frame) -> Self { + TransportBody::Frame(frame).into() + } +} + +impl From for TransportMessage { + fn from(fragment: Fragment) -> Self { + TransportBody::Fragment(fragment).into() + } +} From 5b39936b1d556fac505f162607a3d595239cbdf1 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 10:54:10 +0100 Subject: [PATCH 016/203] Protocol refinement --- commons/zenoh-codec/src/transport/close.rs | 8 +- commons/zenoh-codec/src/transport/fragment.rs | 19 ++-- commons/zenoh-codec/src/transport/frame.rs | 12 +-- commons/zenoh-codec/src/transport/init.rs | 20 ++--- .../zenoh-codec/src/transport/keepalive.rs | 16 +++- commons/zenoh-codec/src/transport/open.rs | 87 ++++++++++++++++++- .../zenoh-protocol/src/common/extension.rs | 4 +- commons/zenoh-protocol/src/core/mod.rs | 10 +++ commons/zenoh-protocol/src/defaults.rs | 15 +--- .../zenoh-protocol/src/transport/fragment.rs | 6 ++ commons/zenoh-protocol/src/transport/init.rs | 19 ++++ commons/zenoh-protocol/src/transport/join.rs | 2 +- .../zenoh-protocol/src/transport/keepalive.rs | 6 ++ commons/zenoh-protocol/src/transport/open.rs | 39 ++++++++- io/zenoh-transport/src/manager.rs | 12 +-- 15 files changed, 218 insertions(+), 57 deletions(-) diff --git a/commons/zenoh-codec/src/transport/close.rs b/commons/zenoh-codec/src/transport/close.rs index 73b9193cf3..e0edff6f16 100644 --- a/commons/zenoh-codec/src/transport/close.rs +++ b/commons/zenoh-codec/src/transport/close.rs @@ -75,10 +75,10 @@ where let reason: u8 = self.codec.read(&mut *reader)?; // Extensions - let mut has_extensions = imsg::has_flag(self.header, flag::Z); - while has_extensions { - let (_, more): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - has_extensions = more; + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let (_, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + has_ext = ext; } Ok(Close { reason, session }) diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index be3895e573..0713ce11d1 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -38,6 +38,9 @@ where if let Reliability::Reliable = x.reliability { header |= flag::R; } + if x.more { + header |= flag::M; + } if x.qos != ext::QoS::default() { header |= flag::Z; } @@ -83,30 +86,32 @@ where true => Reliability::Reliable, false => Reliability::BestEffort, }; + let more = imsg::has_flag(self.header, flag::M); let sn: ZInt = self.codec.read(&mut *reader)?; // Extensions let mut qos = ext::QoS::default(); - let mut has_more = imsg::has_flag(self.header, flag::Z); - while has_more { + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { ext::QOS => { - let (q, more): (ext::QoS, bool) = eodec.read(&mut *reader)?; + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; qos = q; - has_more = more; + has_ext = ext; } _ => { - let (_, more): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - has_more = more; + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; } } } Ok(FragmentHeader { reliability, + more, sn, qos, }) @@ -124,6 +129,7 @@ where // Header let header = FragmentHeader { reliability: x.reliability, + more: x.more, sn: x.sn, qos: x.qos, }; @@ -163,6 +169,7 @@ where Ok(Fragment { reliability: header.reliability, + more: header.more, sn: header.sn, qos: header.qos, payload, diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 427e832cea..896c0bfa71 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -133,19 +133,19 @@ where // Extensions let mut qos = ext::QoS::default(); - let mut has_more = imsg::has_flag(self.header, flag::Z); - while has_more { + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { ext::QOS => { - let (q, more): (ext::QoS, bool) = eodec.read(&mut *reader)?; + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; qos = q; - has_more = more; + has_ext = ext; } _ => { - let (_, more): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - has_more = more; + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; } } } diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index b190531874..0a2be473fb 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -288,29 +288,29 @@ where let mut shm = None; let mut auth = None; - let mut has_more = imsg::has_flag(self.header, flag::Z); - while has_more { + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { ext::QOS => { - let (q, more): (ext::QoS, bool) = eodec.read(&mut *reader)?; + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; qos = Some(q); - has_more = more; + has_ext = ext; } ext::SHM => { - let (s, more): (ext::Shm, bool) = eodec.read(&mut *reader)?; + let (s, ext): (ext::Shm, bool) = eodec.read(&mut *reader)?; shm = Some(s); - has_more = more; + has_ext = ext; } ext::AUTH => { - let (a, more): (ext::Auth, bool) = eodec.read(&mut *reader)?; + let (a, ext): (ext::Auth, bool) = eodec.read(&mut *reader)?; auth = Some(a); - has_more = more; + has_ext = ext; } _ => { - let (_, more): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - has_more = more; + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; } } } diff --git a/commons/zenoh-codec/src/transport/keepalive.rs b/commons/zenoh-codec/src/transport/keepalive.rs index 045dc03fa4..4b342f0d25 100644 --- a/commons/zenoh-codec/src/transport/keepalive.rs +++ b/commons/zenoh-codec/src/transport/keepalive.rs @@ -17,8 +17,11 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::imsg, - transport::{id, KeepAlive}, + common::{imsg, ZExtUnknown}, + transport::{ + id, + keepalive::{flag, KeepAlive}, + }, }; impl WCodec<&KeepAlive, &mut W> for Zenoh080 @@ -54,11 +57,18 @@ where { type Error = DidntRead; - fn read(self, _reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result { if imsg::mid(self.header) != id::KEEP_ALIVE { return Err(DidntRead); } + // Extensions + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let (_, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + has_ext = ext; + } + Ok(KeepAlive) } } diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index 951862e4e0..ea2e9156be 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -19,11 +19,11 @@ use zenoh_buffers::{ ZSlice, }; use zenoh_protocol::{ - common::imsg, + common::{imsg, ZExtUnknown}, core::ZInt, transport::{ id, - open::{flag, OpenAck, OpenSyn}, + open::{ext, flag, OpenAck, OpenSyn}, }, }; @@ -40,6 +40,10 @@ where if x.lease.as_millis() % 1_000 == 0 { header |= flag::T; } + let has_extensions = x.shm.is_some() || x.auth.is_some(); + if has_extensions { + header |= flag::Z; + } self.write(&mut *writer, header)?; // Body @@ -50,6 +54,18 @@ where } self.write(&mut *writer, x.initial_sn)?; self.write(&mut *writer, &x.cookie)?; + + // Extensions + if let Some(shm) = x.shm.as_ref() { + let has_more = x.auth.is_some(); + self.write(&mut *writer, (shm, has_more))?; + } + + if let Some(auth) = x.auth.as_ref() { + let has_more = false; + self.write(&mut *writer, (auth, has_more))?; + } + Ok(()) } } @@ -78,6 +94,7 @@ where return Err(DidntRead); } + // Body let lease: ZInt = self.codec.read(&mut *reader)?; let lease = if imsg::has_flag(self.header, flag::T) { Duration::from_secs(lease) @@ -87,10 +104,38 @@ where let initial_sn: ZInt = self.codec.read(&mut *reader)?; let cookie: ZSlice = self.codec.read(&mut *reader)?; + // Extensions + let mut shm = None; + let mut auth = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::SHM => { + let (s, ext): (ext::Shm, bool) = eodec.read(&mut *reader)?; + shm = Some(s); + has_ext = ext; + } + ext::AUTH => { + let (a, ext): (ext::Auth, bool) = eodec.read(&mut *reader)?; + auth = Some(a); + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + Ok(OpenSyn { lease, initial_sn, cookie, + shm, + auth, }) } } @@ -110,6 +155,10 @@ where if x.lease.subsec_nanos() == 0 { header |= flag::T; } + let has_extensions = x.auth.is_some(); + if has_extensions { + header |= flag::Z; + } self.write(&mut *writer, header)?; // Body @@ -119,6 +168,13 @@ where self.write(&mut *writer, x.lease.as_millis() as ZInt)?; } self.write(&mut *writer, x.initial_sn)?; + + // Extensions + if let Some(auth) = x.auth.as_ref() { + let has_more = false; + self.write(&mut *writer, (auth, has_more))?; + } + Ok(()) } } @@ -147,6 +203,7 @@ where return Err(DidntRead); } + // Body let lease: ZInt = self.codec.read(&mut *reader)?; let lease = if imsg::has_flag(self.header, flag::T) { Duration::from_secs(lease) @@ -155,6 +212,30 @@ where }; let initial_sn: ZInt = self.codec.read(&mut *reader)?; - Ok(OpenAck { lease, initial_sn }) + // Extensions + let mut auth = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::AUTH => { + let (a, ext): (ext::Auth, bool) = eodec.read(&mut *reader)?; + auth = Some(a); + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + Ok(OpenAck { + lease, + initial_sn, + auth, + }) } } diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index d5e620c6df..dd4c919afe 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -27,8 +27,8 @@ use zenoh_buffers::{ZBuf, ZSlice}; /// /// ```text /// Header flags: -/// - X: Reserved -/// - F: Forward If F==1 then the extension needs to be forwarded. (*) +/// - E |: Encoding The encoding of the extension +/// - E/ /// - Z: More If Z==1 then another extension will follow. /// /// 7 6 5 4 3 2 1 0 diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index b7f94861d5..b7f8d97c62 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -56,6 +56,16 @@ pub use locator::*; pub mod endpoint; pub use endpoint::*; +#[repr(u8)] +// The value represents the 2-bit encoded value +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Bits { + U8 = 0b00, + U16 = 0b01, + U32 = 0b10, + U64 = 0b11, +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Property { diff --git a/commons/zenoh-protocol/src/defaults.rs b/commons/zenoh-protocol/src/defaults.rs index 5ec71fc454..43e58f5604 100644 --- a/commons/zenoh-protocol/src/defaults.rs +++ b/commons/zenoh-protocol/src/defaults.rs @@ -11,18 +11,11 @@ // Contributors: // ZettaScale Zenoh Team, // -#[repr(u8)] -// The value represents the 2-bit encoded value -pub enum Bits { - U8 = 0b00, - U16 = 0b01, - U32 = 0b10, - U64 = 0b11, -} +use crate::core::Bits; -pub const FRAME_SN_RESOLUTION: Bits = Bits::U64; -pub const REQUEST_ID_RESOLUTION: Bits = Bits::U64; -pub const KEYEXPR_ID_RESOLUTION: Bits = Bits::U64; +pub const FRAME_SN_RESOLUTION: Bits = Bits::U32; +pub const REQUEST_ID_RESOLUTION: Bits = Bits::U32; +pub const KEYEXPR_ID_RESOLUTION: Bits = Bits::U32; /// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length /// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs index 5764c03d85..077974549b 100644 --- a/commons/zenoh-protocol/src/transport/fragment.rs +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -70,6 +70,7 @@ pub mod flag { #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Fragment { pub reliability: Reliability, + pub more: bool, pub sn: ZInt, pub qos: ext::QoS, pub payload: ZSlice, @@ -94,6 +95,7 @@ impl Fragment { } else { Reliability::BestEffort }; + let more = rng.gen_bool(0.5); let sn: ZInt = rng.gen(); let qos = ext::QoS::rand(); let payload = ZSlice::rand(rng.gen_range(8..128)); @@ -101,6 +103,7 @@ impl Fragment { Fragment { reliability, sn, + more, qos, payload, } @@ -112,6 +115,7 @@ impl Fragment { #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FragmentHeader { pub reliability: Reliability, + pub more: bool, pub sn: ZInt, pub qos: ext::QoS, } @@ -128,11 +132,13 @@ impl FragmentHeader { } else { Reliability::BestEffort }; + let more = rng.gen_bool(0.5); let sn: ZInt = rng.gen(); let qos = ext::QoS::rand(); FragmentHeader { reliability, + more, sn, qos, } diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index d54ca15dc9..a17f371e11 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -176,6 +176,7 @@ pub struct InitSyn { pub resolution: Resolution, pub batch_size: u16, pub qos: Option, + #[cfg(feature = "shared-memory")] pub shm: Option, pub auth: Option, } @@ -185,11 +186,24 @@ pub mod ext { use crate::common::{ZExtUnit, ZExtZSlice}; pub const QOS: u8 = 0x01; + #[cfg(feature = "shared-memory")] pub const SHM: u8 = 0x02; pub const AUTH: u8 = 0x03; + /// # QoS extension + /// + /// Indicates wether the Zenoh nodes support QoS or not pub type QoS = ZExtUnit; + + /// # Shm extension + /// + /// Used as challenge for probing shared memory capabilities + #[cfg(feature = "shared-memory")] pub type Shm = ZExtZSlice; + + /// # Auth extension + /// + /// Used as challenge for probing authentication rights pub type Auth = ZExtZSlice; } @@ -207,6 +221,7 @@ impl InitSyn { let resolution = Resolution::rand(); let batch_size: u16 = rng.gen(); let qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); + #[cfg(feature = "shared-memory")] let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); @@ -217,6 +232,7 @@ impl InitSyn { resolution, batch_size, qos, + #[cfg(feature = "shared-memory")] shm, auth, } @@ -233,6 +249,7 @@ pub struct InitAck { pub batch_size: u16, pub cookie: ZSlice, pub qos: Option, + #[cfg(feature = "shared-memory")] pub shm: Option, pub auth: Option, } @@ -256,6 +273,7 @@ impl InitAck { let batch_size: u16 = rng.gen(); let cookie = ZSlice::rand(64); let qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); + #[cfg(feature = "shared-memory")] let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); @@ -267,6 +285,7 @@ impl InitAck { batch_size, cookie, qos, + #[cfg(feature = "shared-memory")] shm, auth, } diff --git a/commons/zenoh-protocol/src/transport/join.rs b/commons/zenoh-protocol/src/transport/join.rs index 9c9ac701a2..2f4d8ab6d0 100644 --- a/commons/zenoh-protocol/src/transport/join.rs +++ b/commons/zenoh-protocol/src/transport/join.rs @@ -38,7 +38,7 @@ use core::time::Duration; /// +-------+-------+ /// ~ whatami ~ -- Router, Peer or a combination of them /// +---------------+ -/// ~ peer_id ~ -- PID of the sender of the JOIN message +/// ~ node_id ~ -- PID of the sender of the JOIN message /// +---------------+ /// ~ lease ~ -- Lease period of the sender of the JOIN message(*) /// +---------------+ diff --git a/commons/zenoh-protocol/src/transport/keepalive.rs b/commons/zenoh-protocol/src/transport/keepalive.rs index bfed3612aa..8432fa5342 100644 --- a/commons/zenoh-protocol/src/transport/keepalive.rs +++ b/commons/zenoh-protocol/src/transport/keepalive.rs @@ -75,6 +75,12 @@ /// the boundary of the serialized messages. The length is encoded as little-endian. /// In any case, the length of a message must not exceed 65535 bytes. /// +pub mod flag { + // pub const X: u8 = 1 << 5; // 0x20 Reserved + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct KeepAlive; diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 1b20172e90..83a230d4f6 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -78,11 +78,35 @@ pub struct OpenSyn { pub lease: Duration, pub initial_sn: ZInt, pub cookie: ZSlice, + #[cfg(feature = "shared-memory")] + pub shm: Option, + pub auth: Option, +} + +// Extensions +pub mod ext { + use crate::common::ZExtZSlice; + + #[cfg(feature = "shared-memory")] + pub const SHM: u8 = 0x02; + pub const AUTH: u8 = 0x03; + + /// # Shm extension + /// + /// Used as challenge for probing shared memory capabilities + #[cfg(feature = "shared-memory")] + pub type Shm = ZExtZSlice; + + /// # Auth extension + /// + /// Used as challenge for probing authentication rights + pub type Auth = ZExtZSlice; } impl OpenSyn { #[cfg(feature = "test")] pub fn rand() -> Self { + use crate::common::ZExtZSlice; use rand::Rng; const MIN: usize = 32; @@ -98,10 +122,16 @@ impl OpenSyn { let initial_sn: ZInt = rng.gen(); let cookie = ZSlice::rand(rng.gen_range(MIN..=MAX)); + #[cfg(feature = "shared-memory")] + let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); Self { lease, initial_sn, cookie, + #[cfg(feature = "shared-memory")] + shm, + auth, } } } @@ -111,11 +141,13 @@ impl OpenSyn { pub struct OpenAck { pub lease: Duration, pub initial_sn: ZInt, + pub auth: Option, } impl OpenAck { #[cfg(feature = "test")] pub fn rand() -> Self { + use crate::common::ZExtZSlice; use rand::Rng; let mut rng = rand::thread_rng(); @@ -127,6 +159,11 @@ impl OpenAck { }; let initial_sn: ZInt = rng.gen(); - Self { lease, initial_sn } + let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + Self { + lease, + initial_sn, + auth, + } } } diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index 436ffebce1..ba91c7e83a 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -24,8 +24,6 @@ use async_std::sync::Mutex as AsyncMutex; use rand::{RngCore, SeedableRng}; use std::collections::HashMap; use std::sync::Arc; -#[cfg(feature = "shared-memory")] -use std::sync::RwLock; use std::time::Duration; use zenoh_cfg_properties::{config::*, Properties}; use zenoh_config::{Config, QueueConf, QueueSizeConf}; @@ -34,12 +32,10 @@ use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::NewLinkChannelSender; use zenoh_protocol::{ core::{EndPoint, Locator, Priority, WhatAmI, ZInt, ZenohId}, - defaults::{BATCH_SIZE, SEQ_NUM_RES}, + defaults::{BATCH_SIZE, FRAME_SN_RESOLUTION}, VERSION, }; use zenoh_result::{bail, ZResult}; -#[cfg(feature = "shared-memory")] -use zenoh_shm::SharedMemoryReader; /// # Examples /// ``` @@ -292,7 +288,7 @@ impl Default for TransportManagerBuilder { version: VERSION, zid: ZenohId::rand(), whatami: ZN_MODE_DEFAULT.parse().unwrap(), - sn_resolution: SEQ_NUM_RES, + sn_resolution: FRAME_SN_RESOLUTION as ZInt, batch_size: BATCH_SIZE, queue_size: queue.size, queue_backoff: Duration::from_nanos(backoff), @@ -342,8 +338,6 @@ pub struct TransportManager { pub(crate) state: Arc, pub(crate) prng: Arc>, pub(crate) cipher: Arc, - #[cfg(feature = "shared-memory")] - pub(crate) shmr: Arc>, pub(crate) locator_inspector: zenoh_link::LocatorInspector, pub(crate) new_unicast_link_sender: NewLinkChannelSender, pub(crate) tx_executor: TransportExecutor, @@ -366,8 +360,6 @@ impl TransportManager { state: Arc::new(params.state), prng: Arc::new(AsyncMutex::new(prng)), cipher: Arc::new(cipher), - #[cfg(feature = "shared-memory")] - shmr: Arc::new(RwLock::new(SharedMemoryReader::new())), locator_inspector: Default::default(), new_unicast_link_sender, tx_executor: TransportExecutor::new(tx_threads), From 0915cbd5ef0fecbbc5598d21517da1802b522c35 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 11:23:37 +0100 Subject: [PATCH 017/203] Fix Batch and Pipeline --- commons/zenoh-protocol/src/core/mod.rs | 11 ++++++++ commons/zenoh-protocol/src/transport/init.rs | 20 +-------------- commons/zenoh-protocol/src/transport/open.rs | 5 ---- commons/zenoh-protocol/src/zenoh/mod.rs | 6 +---- io/zenoh-transport/src/common/batch.rs | 25 +++++++++++-------- io/zenoh-transport/src/common/pipeline.rs | 24 ++++++++---------- io/zenoh-transport/src/multicast/manager.rs | 2 +- io/zenoh-transport/src/multicast/mod.rs | 2 +- io/zenoh-transport/src/multicast/transport.rs | 2 +- .../unicast/establishment/accept/init_ack.rs | 14 +++++------ .../unicast/establishment/accept/init_syn.rs | 12 ++++----- .../src/unicast/establishment/accept/mod.rs | 14 +++++------ .../unicast/establishment/accept/open_ack.rs | 2 +- .../unicast/establishment/accept/open_syn.rs | 24 +++++++++--------- .../unicast/establishment/open/init_ack.rs | 22 ++++++++-------- .../unicast/establishment/open/init_syn.rs | 10 ++++---- .../src/unicast/establishment/open/mod.rs | 10 ++++---- .../unicast/establishment/open/open_ack.rs | 14 +++++------ .../unicast/establishment/open/open_syn.rs | 2 +- io/zenoh-transport/src/unicast/manager.rs | 2 +- io/zenoh-transport/src/unicast/mod.rs | 8 +++--- io/zenoh-transport/src/unicast/rx.rs | 2 +- 22 files changed, 109 insertions(+), 124 deletions(-) diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index b7f8d97c62..518bb97001 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -66,6 +66,17 @@ pub enum Bits { U64 = 0b11, } +impl Bits { + pub fn mask(&self) -> ZInt { + match self { + Bits::U8 => u8::MAX as ZInt, + Bits::U16 => u16::MAX as ZInt, + Bits::U32 => u32::MAX as ZInt, + Bits::U64 => u64::MAX as ZInt, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Property { diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index a17f371e11..b08d08580f 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{WhatAmI, ZenohId}; +use crate::core::{Bits, WhatAmI, ZenohId}; use zenoh_buffers::ZSlice; /// # Init message @@ -104,16 +104,6 @@ pub mod flag { pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow } -#[repr(u8)] -// The value represents the 2-bit encoded value -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Bits { - U8 = 0b00, - U16 = 0b01, - U32 = 0b10, - U64 = 0b11, -} - #[repr(u8)] // The value indicates the bit offest #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -176,7 +166,6 @@ pub struct InitSyn { pub resolution: Resolution, pub batch_size: u16, pub qos: Option, - #[cfg(feature = "shared-memory")] pub shm: Option, pub auth: Option, } @@ -186,7 +175,6 @@ pub mod ext { use crate::common::{ZExtUnit, ZExtZSlice}; pub const QOS: u8 = 0x01; - #[cfg(feature = "shared-memory")] pub const SHM: u8 = 0x02; pub const AUTH: u8 = 0x03; @@ -198,7 +186,6 @@ pub mod ext { /// # Shm extension /// /// Used as challenge for probing shared memory capabilities - #[cfg(feature = "shared-memory")] pub type Shm = ZExtZSlice; /// # Auth extension @@ -221,7 +208,6 @@ impl InitSyn { let resolution = Resolution::rand(); let batch_size: u16 = rng.gen(); let qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - #[cfg(feature = "shared-memory")] let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); @@ -232,7 +218,6 @@ impl InitSyn { resolution, batch_size, qos, - #[cfg(feature = "shared-memory")] shm, auth, } @@ -249,7 +234,6 @@ pub struct InitAck { pub batch_size: u16, pub cookie: ZSlice, pub qos: Option, - #[cfg(feature = "shared-memory")] pub shm: Option, pub auth: Option, } @@ -273,7 +257,6 @@ impl InitAck { let batch_size: u16 = rng.gen(); let cookie = ZSlice::rand(64); let qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - #[cfg(feature = "shared-memory")] let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); @@ -285,7 +268,6 @@ impl InitAck { batch_size, cookie, qos, - #[cfg(feature = "shared-memory")] shm, auth, } diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 83a230d4f6..4ba6537d1f 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -78,7 +78,6 @@ pub struct OpenSyn { pub lease: Duration, pub initial_sn: ZInt, pub cookie: ZSlice, - #[cfg(feature = "shared-memory")] pub shm: Option, pub auth: Option, } @@ -87,14 +86,12 @@ pub struct OpenSyn { pub mod ext { use crate::common::ZExtZSlice; - #[cfg(feature = "shared-memory")] pub const SHM: u8 = 0x02; pub const AUTH: u8 = 0x03; /// # Shm extension /// /// Used as challenge for probing shared memory capabilities - #[cfg(feature = "shared-memory")] pub type Shm = ZExtZSlice; /// # Auth extension @@ -122,14 +119,12 @@ impl OpenSyn { let initial_sn: ZInt = rng.gen(); let cookie = ZSlice::rand(rng.gen_range(MIN..=MAX)); - #[cfg(feature = "shared-memory")] let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); Self { lease, initial_sn, cookie, - #[cfg(feature = "shared-memory")] shm, auth, } diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index 41895981ba..6db0d360fe 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -394,11 +394,7 @@ impl ZenohMessage { let mut rng = rand::thread_rng(); - let attachment = if rng.gen_bool(0.5) { - Some(Attachment::rand()) - } else { - None - }; + let attachment = None; let routing_context = if rng.gen_bool(0.5) { Some(RoutingContext::rand()) diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index b5ad3aee5e..7ee6fed361 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -20,7 +20,11 @@ use zenoh_buffers::{ use zenoh_codec::{WCodec, Zenoh080}; use zenoh_protocol::{ core::{Channel, Reliability, ZInt}, - transport::{FrameHeader, FrameKind, TransportMessage}, + transport::{ + fragment::{self, FragmentHeader}, + frame::{self, FrameHeader}, + TransportMessage, + }, zenoh::ZenohMessage, }; @@ -266,9 +270,9 @@ impl Encode<(&ZenohMessage, Channel, ZInt)> for &mut WBatch { let codec = Zenoh080::default(); // Write the frame header let frame = FrameHeader { - channel, + reliability: channel.reliability, sn, - kind: FrameKind::Messages, + qos: frame::ext::QoS::new(channel.priority), }; codec.write(&mut writer, &frame).map_err(|e| { // Revert the write operation @@ -282,7 +286,7 @@ impl Encode<(&ZenohMessage, Channel, ZInt)> for &mut WBatch { e })?; // Update the frame - self.current_frame = match frame.channel.reliability { + self.current_frame = match frame.reliability { Reliability::Reliable => { self.latest_sn.reliable = Some(sn); CurrentFrame::Reliable @@ -314,10 +318,11 @@ impl Encode<(&mut ZBufReader<'_>, Channel, ZInt)> for &mut WBatch { let mark = writer.mark(); // Serialize first assuming is some fragment - let mut frame = FrameHeader { - channel, + let mut frame = FragmentHeader { + reliability: channel.reliability, + more: true, sn, - kind: FrameKind::SomeFragment, + qos: fragment::ext::QoS::new(channel.priority), }; // Write the frame header codec.write(&mut writer, &frame).map_err(|e| { @@ -331,7 +336,7 @@ impl Encode<(&mut ZBufReader<'_>, Channel, ZInt)> for &mut WBatch { // Revert the buffer writer.rewind(mark); // It is really the finally fragment, reserialize the header - frame.kind = FrameKind::LastFragment; + frame.more = false; // Write the frame header codec.write(&mut writer, &frame).map_err(|e| { // Revert the write operation @@ -355,7 +360,7 @@ mod tests { use zenoh_buffers::ZBuf; use zenoh_protocol::{ core::{Channel, CongestionControl, Priority, Reliability}, - transport::TransportMessage, + transport::{KeepAlive, TransportMessage}, zenoh::ZenohMessage, }; @@ -363,7 +368,7 @@ mod tests { fn serialization_batch() { let mut batch = WBatch::new(u16::MAX, true); - let tmsg = TransportMessage::make_keep_alive(None, None); + let tmsg: TransportMessage = KeepAlive.into(); let mut zmsg = ZenohMessage::make_data( 0.into(), ZBuf::from(vec![0u8; 8]), diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 8217c5530d..8bc07cc1d2 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -699,8 +699,8 @@ mod tests { use zenoh_codec::{RCodec, Zenoh080}; use zenoh_protocol::{ core::{Channel, CongestionControl, Priority, Reliability, ZInt}, - defaults::{BATCH_SIZE, SEQ_NUM_RES}, - transport::{Frame, FramePayload, TransportBody}, + defaults::{BATCH_SIZE, FRAME_SN_RESOLUTION}, + transport::{Fragment, Frame, TransportBody}, zenoh::ZenohMessage, }; @@ -771,17 +771,15 @@ mod tests { match res { Ok(msg) => { match msg.body { - TransportBody::Frame(Frame { payload, .. }) => match payload { - FramePayload::Messages { messages } => { - msgs += messages.len(); - } - FramePayload::Fragment { is_final, .. } => { - fragments += 1; - if is_final { - msgs += 1; - } + TransportBody::Frame(Frame { payload, .. }) => { + msgs += payload.len() + } + TransportBody::Fragment(Fragment { more, .. }) => { + fragments += 1; + if !more { + msgs += 1; } - }, + } _ => { msgs += 1; } @@ -802,7 +800,7 @@ mod tests { } // Pipeline conduits - let tct = TransportConduitTx::make(SEQ_NUM_RES).unwrap(); + let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION.mask()).unwrap(); let conduits = vec![tct]; // Total amount of bytes to send in each test diff --git a/io/zenoh-transport/src/multicast/manager.rs b/io/zenoh-transport/src/multicast/manager.rs index 99e4ae12c5..6557713fe8 100644 --- a/io/zenoh-transport/src/multicast/manager.rs +++ b/io/zenoh-transport/src/multicast/manager.rs @@ -142,7 +142,7 @@ impl TransportManager { .map(|(_, v)| v) .collect::>>(); for tm in tm_guard.drain(..) { - let _ = tm.close(tmsg::close_reason::GENERIC).await; + let _ = tm.close(close::reason::GENERIC).await; } } diff --git a/io/zenoh-transport/src/multicast/mod.rs b/io/zenoh-transport/src/multicast/mod.rs index 7774e77253..02f1b42180 100644 --- a/io/zenoh-transport/src/multicast/mod.rs +++ b/io/zenoh-transport/src/multicast/mod.rs @@ -128,7 +128,7 @@ impl TransportMulticast { pub async fn close(&self) -> ZResult<()> { // Return Ok if the transport has already been closed match self.get_transport() { - Ok(transport) => transport.close(tmsg::close_reason::GENERIC).await, + Ok(transport) => transport.close(close::reason::GENERIC).await, Err(_) => Ok(()), } } diff --git a/io/zenoh-transport/src/multicast/transport.rs b/io/zenoh-transport/src/multicast/transport.rs index 8e9a4def94..9ac18b4f9e 100644 --- a/io/zenoh-transport/src/multicast/transport.rs +++ b/io/zenoh-transport/src/multicast/transport.rs @@ -78,7 +78,7 @@ impl Timed for TransportMulticastPeerLeaseTimer { if !is_active { let _ = self .transport - .del_peer(&self.locator, tmsg::close_reason::EXPIRED); + .del_peer(&self.locator, close::reason::EXPIRED); } } } diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs index 7e45ce6616..10d84dad4e 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs @@ -79,7 +79,7 @@ pub(super) async fn send( .map(|x| x.value), ) .await - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + .map_err(|e| (e, Some(close::reason::INVALID)))?; // Add attachment property if available if let Some(att) = att.take() { ps_attachment @@ -87,7 +87,7 @@ pub(super) async fn send( key: pa.id().into(), value: att, }) - .map_err(|e| (e, Some(tmsg::close_reason::UNSUPPORTED)))?; + .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; } // Add state in the cookie if avaiable if let Some(cke) = cke.take() { @@ -96,7 +96,7 @@ pub(super) async fn send( key: pa.id().into(), value: cke, }) - .map_err(|e| (e, Some(tmsg::close_reason::UNSUPPORTED)))?; + .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; } } cookie.properties = ps_cookie; @@ -104,8 +104,8 @@ pub(super) async fn send( let attachment: Option = if ps_attachment.is_empty() { None } else { - let att = Attachment::try_from(&ps_attachment) - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + let att = + Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; Some(att) }; @@ -119,7 +119,7 @@ pub(super) async fn send( codec.write(&mut writer, &cookie).map_err(|_| { ( zerror!("Encoding cookie failed").into(), - Some(tmsg::close_reason::INVALID), + Some(close::reason::INVALID), ) })?; @@ -141,7 +141,7 @@ pub(super) async fn send( let _ = link .write_transport_message(&message) .await - .map_err(|e| (e, Some(tmsg::close_reason::GENERIC)))?; + .map_err(|e| (e, Some(close::reason::GENERIC)))?; let output = Output { cookie_hash }; Ok(output) diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs index 90fd0447e5..111174555e 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs @@ -44,14 +44,14 @@ pub(super) async fn recv( let mut messages = link .read_transport_message() .await - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + .map_err(|e| (e, Some(close::reason::INVALID)))?; if messages.len() != 1 { let e = zerror!( "Received multiple messages instead of a single InitSyn on {}: {:?}", link, messages, ); - return Err((e.into(), Some(tmsg::close_reason::INVALID))); + return Err((e.into(), Some(close::reason::INVALID))); } let mut msg = messages.remove(0); @@ -63,7 +63,7 @@ pub(super) async fn recv( link, msg.body ); - return Err((e.into(), Some(tmsg::close_reason::INVALID))); + return Err((e.into(), Some(close::reason::INVALID))); } }; @@ -77,7 +77,7 @@ pub(super) async fn recv( zid, init_syn.zid ); - return Err((e.into(), Some(tmsg::close_reason::INVALID))); + return Err((e.into(), Some(close::reason::INVALID))); } } None => auth_link.peer_id = Some(init_syn.zid), @@ -90,13 +90,13 @@ pub(super) async fn recv( link, init_syn.zid ); - return Err((e.into(), Some(tmsg::close_reason::INVALID))); + return Err((e.into(), Some(close::reason::INVALID))); } // Validate the InitSyn with the peer authenticators let init_syn_properties: EstablishmentProperties = match msg.attachment.take() { Some(att) => EstablishmentProperties::try_from(&att) - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?, + .map_err(|e| (e, Some(close::reason::INVALID)))?, None => EstablishmentProperties::new(), }; diff --git a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs index b004e08148..7e1a70ce0a 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs @@ -62,7 +62,7 @@ pub(crate) async fn accept_link( }; let transport = step!(transport_init(manager, input) .await - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))); + .map_err(|e| (e, Some(close::reason::INVALID)))); // OPEN handshake macro_rules! step { @@ -71,7 +71,7 @@ pub(crate) async fn accept_link( Ok(output) => output, Err((e, reason)) => { match reason { - Some(tmsg::close_reason::MAX_LINKS) => log::debug!("{}", e), + Some(close::reason::MAX_LINKS) => log::debug!("{}", e), _ => log::error!("{}", e), } if let Ok(ll) = transport.get_links() { @@ -89,14 +89,14 @@ pub(crate) async fn accept_link( // Add the link to the transport step!(step!(transport .get_inner() - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))) + .map_err(|e| (e, Some(close::reason::INVALID)))) .add_link(link.clone(), LinkUnicastDirection::Inbound) - .map_err(|e| (e, Some(tmsg::close_reason::MAX_LINKS)))); + .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); // Sync the RX sequence number let _ = step!(transport .get_inner() - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))) + .map_err(|e| (e, Some(close::reason::INVALID)))) .sync(output.initial_sn) .await; @@ -104,7 +104,7 @@ pub(crate) async fn accept_link( let initial_sn = step!(transport .get_inner() - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))) + .map_err(|e| (e, Some(close::reason::INVALID)))) .config .initial_sn_tx; let input = open_ack::Input { @@ -120,7 +120,7 @@ pub(crate) async fn accept_link( }; step!(transport_finalize(link, manager, input) .await - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))); + .map_err(|e| (e, Some(close::reason::INVALID)))); Ok(()) } diff --git a/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs index 47955c1be4..806c088bc7 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs @@ -47,7 +47,7 @@ pub(super) async fn send( let _ = link .write_transport_message(&message) .await - .map_err(|e| (e, Some(tmsg::close_reason::GENERIC)))?; + .map_err(|e| (e, Some(close::reason::GENERIC)))?; Ok(()) } diff --git a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs b/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs index 8c091c99c8..7f45d502e8 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs @@ -53,14 +53,14 @@ pub(super) async fn recv( let mut messages = link .read_transport_message() .await - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + .map_err(|e| (e, Some(close::reason::INVALID)))?; if messages.len() != 1 { let e = zerror!( "Received multiple messages instead of a single OpenSyn on {}: {:?}", link, messages ); - return Err((e.into(), Some(tmsg::close_reason::INVALID))); + return Err((e.into(), Some(close::reason::INVALID))); } let mut msg = messages.remove(0); @@ -69,11 +69,11 @@ pub(super) async fn recv( TransportBody::Close(Close { reason, .. }) => { let e = zerror!( "Received a close message (reason {}) instead of an OpenSyn on: {:?}", - tmsg::close_reason_to_str(reason), + close::reason_to_str(reason), link, ); match reason { - tmsg::close_reason::MAX_LINKS => log::debug!("{}", e), + close::reason::MAX_LINKS => log::debug!("{}", e), _ => log::error!("{}", e), } return Err((e.into(), None)); @@ -85,7 +85,7 @@ pub(super) async fn recv( msg.body ); log::error!("{}", e); - return Err((e.into(), Some(tmsg::close_reason::INVALID))); + return Err((e.into(), Some(close::reason::INVALID))); } }; let encrypted = open_syn.cookie.to_vec(); @@ -93,7 +93,7 @@ pub(super) async fn recv( // Verify that the cookie is the one we sent if input.cookie_hash != hmac::digest(&encrypted) { let e = zerror!("Rejecting OpenSyn on: {}. Unkwown cookie.", link); - return Err((e.into(), Some(tmsg::close_reason::INVALID))); + return Err((e.into(), Some(close::reason::INVALID))); } // Decrypt the cookie with the cyper @@ -106,14 +106,14 @@ pub(super) async fn recv( let mut cookie: Cookie = codec.read(&mut reader).map_err(|_| { ( zerror!("Decoding cookie failed").into(), - Some(tmsg::close_reason::INVALID), + Some(close::reason::INVALID), ) })?; // Validate with the peer authenticators let mut open_syn_properties: EstablishmentProperties = match msg.attachment.take() { Some(att) => EstablishmentProperties::try_from(&att) - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?, + .map_err(|e| (e, Some(close::reason::INVALID)))?, None => EstablishmentProperties::new(), }; @@ -145,22 +145,22 @@ pub(super) async fn recv( } } - let mut att = att.map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + let mut att = att.map_err(|e| (e, Some(close::reason::INVALID)))?; if let Some(att) = att.take() { ps_attachment .insert(Property { key: pa.id().into(), value: att, }) - .map_err(|e| (e, Some(tmsg::close_reason::UNSUPPORTED)))?; + .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; } } let open_ack_attachment = if ps_attachment.is_empty() { None } else { - let att = Attachment::try_from(&ps_attachment) - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + let att = + Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; Some(att) }; diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs index 9d0d020ebe..f397575ae5 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs @@ -52,7 +52,7 @@ pub(super) async fn recv( let mut messages = link .read_transport_message() .await - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + .map_err(|e| (e, Some(close::reason::INVALID)))?; if messages.len() != 1 { return Err(( zerror!( @@ -61,7 +61,7 @@ pub(super) async fn recv( messages, ) .into(), - Some(tmsg::close_reason::INVALID), + Some(close::reason::INVALID), )); } @@ -71,11 +71,11 @@ pub(super) async fn recv( TransportBody::Close(Close { reason, .. }) => { let e = zerror!( "Received a close message (reason {}) in response to an InitSyn on: {}", - tmsg::close_reason_to_str(reason), + close::reason_to_str(reason), link, ); match reason { - tmsg::close_reason::MAX_LINKS => log::debug!("{}", e), + close::reason::MAX_LINKS => log::debug!("{}", e), _ => log::error!("{}", e), } return Err((e.into(), None)); @@ -87,7 +87,7 @@ pub(super) async fn recv( msg.body ); log::error!("{}", e); - return Err((e.into(), Some(tmsg::close_reason::INVALID))); + return Err((e.into(), Some(close::reason::INVALID))); } }; @@ -101,7 +101,7 @@ pub(super) async fn recv( sn_resolution ) .into(), - Some(tmsg::close_reason::INVALID), + Some(close::reason::INVALID), )); } sn_resolution @@ -114,7 +114,7 @@ pub(super) async fn recv( let mut init_ack_properties = match msg.attachment.take() { Some(att) => EstablishmentProperties::try_from(&att) - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?, + .map_err(|e| (e, Some(close::reason::INVALID)))?, None => EstablishmentProperties::new(), }; @@ -151,22 +151,22 @@ pub(super) async fn recv( }; } - let mut att = att.map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + let mut att = att.map_err(|e| (e, Some(close::reason::INVALID)))?; if let Some(att) = att.take() { ps_attachment .insert(Property { key: pa.id().into(), value: att, }) - .map_err(|e| (e, Some(tmsg::close_reason::UNSUPPORTED)))?; + .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; } } let open_syn_attachment = if ps_attachment.is_empty() { None } else { - let att = Attachment::try_from(&ps_attachment) - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + let att = + Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; Some(att) }; diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs b/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs index f69e324a95..4c6d16911d 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs @@ -40,14 +40,14 @@ pub(super) async fn send( let mut att = pa .get_init_syn_properties(auth_link, &manager.config.zid) .await - .map_err(|e| (e, Some(tmsg::close_reason::UNSUPPORTED)))?; + .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; if let Some(att) = att.take() { ps_attachment .insert(Property { key: pa.id().into(), value: att, }) - .map_err(|e| (e, Some(tmsg::close_reason::UNSUPPORTED)))?; + .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; } } @@ -55,8 +55,8 @@ pub(super) async fn send( let init_syn_attachment = if ps_attachment.is_empty() { None } else { - let att = Attachment::try_from(&ps_attachment) - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + let att = + Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; Some(att) }; @@ -71,7 +71,7 @@ pub(super) async fn send( let _ = link .write_transport_message(&message) .await - .map_err(|e| (e, Some(tmsg::close_reason::GENERIC)))?; + .map_err(|e| (e, Some(close::reason::GENERIC)))?; let output = Output; Ok(output) diff --git a/io/zenoh-transport/src/unicast/establishment/open/mod.rs b/io/zenoh-transport/src/unicast/establishment/open/mod.rs index 77d4581a68..7f2d8a61ed 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/mod.rs @@ -53,7 +53,7 @@ pub(crate) async fn open_link( match $s { Ok(output) => output, Err(e) => { - close_link(link, manager, auth_link, Some(tmsg::close_reason::INVALID)).await; + close_link(link, manager, auth_link, Some(close::reason::INVALID)).await; return Err(e); } } @@ -90,7 +90,7 @@ pub(crate) async fn open_link( let initial_sn = step!(transport .get_inner() - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))) + .map_err(|e| (e, Some(close::reason::INVALID)))) .config .initial_sn_tx; let input = open_syn::Input { @@ -105,14 +105,14 @@ pub(crate) async fn open_link( // Add the link to the transport step!(step!(transport .get_inner() - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))) + .map_err(|e| (e, Some(close::reason::INVALID)))) .add_link(link.clone(), LinkUnicastDirection::Outbound) - .map_err(|e| (e, Some(tmsg::close_reason::MAX_LINKS)))); + .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); // Sync the RX sequence number let _ = step!(transport .get_inner() - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))) + .map_err(|e| (e, Some(close::reason::INVALID)))) .sync(output.initial_sn) .await; diff --git a/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs b/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs index 793785c793..ad0a602318 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs @@ -41,7 +41,7 @@ pub(super) async fn recv( let mut messages = link .read_transport_message() .await - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + .map_err(|e| (e, Some(close::reason::INVALID)))?; if messages.len() != 1 { return Err(( zerror!( @@ -50,7 +50,7 @@ pub(super) async fn recv( messages, ) .into(), - Some(tmsg::close_reason::INVALID), + Some(close::reason::INVALID), )); } @@ -60,11 +60,11 @@ pub(super) async fn recv( TransportBody::Close(Close { reason, .. }) => { let e = zerror!( "Received a close message (reason {}) in response to an OpenSyn on: {:?}", - tmsg::close_reason_to_str(reason), + close::reason_to_str(reason), link, ); match reason { - tmsg::close_reason::MAX_LINKS => log::debug!("{}", e), + close::reason::MAX_LINKS => log::debug!("{}", e), _ => log::error!("{}", e), } return Err((e.into(), None)); @@ -76,13 +76,13 @@ pub(super) async fn recv( msg.body ); log::error!("{}", e); - return Err((e.into(), Some(tmsg::close_reason::INVALID))); + return Err((e.into(), Some(close::reason::INVALID))); } }; let mut opean_ack_properties = match msg.attachment.take() { Some(att) => EstablishmentProperties::try_from(&att) - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?, + .map_err(|e| (e, Some(close::reason::INVALID)))?, None => EstablishmentProperties::new(), }; for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { @@ -92,7 +92,7 @@ pub(super) async fn recv( opean_ack_properties.remove(pa.id().into()).map(|x| x.value), ) .await - .map_err(|e| (e, Some(tmsg::close_reason::INVALID)))?; + .map_err(|e| (e, Some(close::reason::INVALID)))?; } let output = Output { diff --git a/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs b/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs index 62a9f14bd6..d76cb1109a 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs @@ -43,7 +43,7 @@ pub(super) async fn send( let _ = link .write_transport_message(&message) .await - .map_err(|e| (e, Some(tmsg::close_reason::GENERIC)))?; + .map_err(|e| (e, Some(close::reason::GENERIC)))?; let output = Output; Ok(output) diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 3e6d988dab..48fc69e9c4 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -268,7 +268,7 @@ impl TransportManager { .map(|(_, v)| v) .collect::>>(); for tu in tu_guard.drain(..) { - let _ = tu.close(tmsg::close_reason::GENERIC).await; + let _ = tu.close(close::reason::GENERIC).await; } } diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 5ef13e698f..3c33fec7af 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -29,7 +29,7 @@ use transport::TransportUnicastInner; use zenoh_link::Link; use zenoh_protocol::{ core::{WhatAmI, ZInt, ZenohId}, - transport::tmsg, + transport::close, zenoh::ZenohMessage, }; use zenoh_result::{zerror, ZResult}; @@ -178,9 +178,7 @@ impl TransportUnicast { .into_iter() .find(|l| l.get_src() == &link.src && l.get_dst() == &link.dst) .ok_or_else(|| zerror!("Invalid link"))?; - transport - .close_link(&link, tmsg::close_reason::GENERIC) - .await?; + transport.close_link(&link, close::reason::GENERIC).await?; Ok(()) } @@ -188,7 +186,7 @@ impl TransportUnicast { pub async fn close(&self) -> ZResult<()> { // Return Ok if the transport has already been closed match self.get_inner() { - Ok(transport) => transport.close(tmsg::close_reason::GENERIC).await, + Ok(transport) => transport.close(close::reason::GENERIC).await, Err(_) => Ok(()), } } diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index 6a57c804be..db000804ed 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -94,7 +94,7 @@ impl TransportUnicastInner { "Received an invalid Close on link {} from peer {} with reason: {}. Ignoring.", link, zid, - tmsg::close_reason_to_str(reason), + close::reason_to_str(reason), ); return Ok(()); } From 992f2102a2aac2c419c27ca798af8bd57f216ad9 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 11:39:14 +0100 Subject: [PATCH 018/203] Remove attachment from zenoh-protocol and zenoh-codec --- commons/zenoh-codec/src/common/attachment.rs | 102 ------------------ commons/zenoh-codec/src/common/mod.rs | 1 - commons/zenoh-codec/src/zenoh/mod.rs | 13 +-- commons/zenoh-codec/tests/codec.rs | 5 - .../zenoh-protocol/src/common/attachment.rs | 57 ---------- commons/zenoh-protocol/src/common/mod.rs | 2 - commons/zenoh-protocol/src/zenoh/mod.rs | 31 +----- io/zenoh-transport/src/multicast/rx.rs | 10 +- .../unicast/establishment/accept/init_ack.rs | 1 - .../src/unicast/establishment/properties.rs | 5 +- 10 files changed, 13 insertions(+), 214 deletions(-) delete mode 100644 commons/zenoh-codec/src/common/attachment.rs delete mode 100644 commons/zenoh-protocol/src/common/attachment.rs diff --git a/commons/zenoh-codec/src/common/attachment.rs b/commons/zenoh-codec/src/common/attachment.rs deleted file mode 100644 index 3a44edb532..0000000000 --- a/commons/zenoh-codec/src/common/attachment.rs +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, - ZBuf, -}; -use zenoh_protocol::common::{imsg, Attachment}; -#[cfg(feature = "shared-memory")] -use {crate::Zenoh080Condition, core::any::TypeId, zenoh_shm::SharedMemoryBufInfoSerialized}; - -impl WCodec<&Attachment, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Attachment) -> Self::Output { - // Header - // #[allow(unused_mut)] // mut required with #[cfg(feature = "shared-memory")] - // let mut header = tmsg::id::ATTACHMENT; - - // #[cfg(feature = "shared-memory")] - // { - // let has_shminfo = x - // .buffer - // .zslices() - // .any(|s| s.buf.as_any().type_id() == TypeId::of::()); - // if has_shminfo { - // header |= tmsg::flag::Z; - // } - // } - - // self.write(&mut *writer, header)?; - - // // Body - // #[cfg(feature = "shared-memory")] - // { - // let codec = Zenoh080Condition::new(imsg::has_flag(header, tmsg::flag::Z)); - // codec.write(&mut *writer, &x.buffer) - // } - // #[cfg(not(feature = "shared-memory"))] - // { - // self.write(&mut *writer, &x.buffer) - // } - Err(DidntWrite) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - // if imsg::mid(self.header) != imsg::id::ATTACHMENT { - // return Err(DidntRead); - // } - - // let buffer: ZBuf = { - // #[cfg(feature = "shared-memory")] - // { - // let codec = Zenoh080Condition::new(imsg::has_flag(self.header, tmsg::flag::Z)); - // codec.read(&mut *reader)? - // } - // #[cfg(not(feature = "shared-memory"))] - // { - // self.codec.read(&mut *reader)? - // } - // }; - - // Ok(Attachment { buffer }) - Err(DidntRead) - } -} diff --git a/commons/zenoh-codec/src/common/mod.rs b/commons/zenoh-codec/src/common/mod.rs index 3777e5a775..898140f7fe 100644 --- a/commons/zenoh-codec/src/common/mod.rs +++ b/commons/zenoh-codec/src/common/mod.rs @@ -11,6 +11,5 @@ // Contributors: // ZettaScale Zenoh Team, // -mod attachment; pub mod extension; mod priority; diff --git a/commons/zenoh-codec/src/zenoh/mod.rs b/commons/zenoh-codec/src/zenoh/mod.rs index c0f8ab2a34..f0bdabba7f 100644 --- a/commons/zenoh-codec/src/zenoh/mod.rs +++ b/commons/zenoh-codec/src/zenoh/mod.rs @@ -27,7 +27,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, Attachment}, + common::imsg, core::{Channel, Priority, Reliability}, zenoh::{zmsg, ReplyContext, RoutingContext, ZenohBody, ZenohMessage}, }; @@ -39,9 +39,6 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &ZenohMessage) -> Self::Output { - if let Some(a) = x.attachment.as_ref() { - self.write(&mut *writer, a)?; - } if let Some(r) = x.routing_context.as_ref() { self.write(&mut *writer, r)?; } @@ -85,13 +82,6 @@ where let header: u8 = self.codec.read(&mut *reader)?; let mut codec = Zenoh080Header::new(header); - let attachment = if imsg::mid(codec.header) == imsg::id::ATTACHMENT { - let a: Attachment = codec.read(&mut *reader)?; - codec.header = self.codec.read(&mut *reader)?; - Some(a) - } else { - None - }; let routing_context = if imsg::mid(codec.header) == zmsg::id::ROUTING_CONTEXT { let r: RoutingContext = codec.read(&mut *reader)?; codec.header = self.codec.read(&mut *reader)?; @@ -144,7 +134,6 @@ where Ok(ZenohMessage { body, - attachment, channel: Channel { priority, reliability: self.reliability, diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index b77c09165d..7c28f09ac6 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -168,11 +168,6 @@ fn codec_encoding() { } // Common -#[test] -fn codec_attachment() { - run!(Attachment, Attachment::rand()); -} - #[test] fn codec_extension() { macro_rules! run_extension_single { diff --git a/commons/zenoh-protocol/src/common/attachment.rs b/commons/zenoh-protocol/src/common/attachment.rs deleted file mode 100644 index 251bdf5a6e..0000000000 --- a/commons/zenoh-protocol/src/common/attachment.rs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use zenoh_buffers::ZBuf; - -/// # Attachment decorator -/// -/// ```text -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. -/// -/// The Attachment can decorate any message (i.e., TransportMessage and ZenohMessage) and it allows to -/// append to the message any additional information. Since the information contained in the -/// Attachement is relevant only to the layer that provided them (e.g., Transport, Zenoh, User) it -/// is the duty of that layer to serialize and de-serialize the attachment whenever deemed necessary. -/// The attachement always contains serialized properties. -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |X|X|Z| ATTCH | -/// +-+-+-+---------+ -/// ~ Attachment ~ -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct Attachment { - pub buffer: ZBuf, -} - -impl Attachment { - pub fn new(buffer: ZBuf) -> Self { - Self { buffer } - } - - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - Self { - buffer: ZBuf::rand(rand::thread_rng().gen_range(1..128)), - } - } -} diff --git a/commons/zenoh-protocol/src/common/mod.rs b/commons/zenoh-protocol/src/common/mod.rs index 416ebd346e..d5887112cb 100644 --- a/commons/zenoh-protocol/src/common/mod.rs +++ b/commons/zenoh-protocol/src/common/mod.rs @@ -11,8 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -pub mod attachment; -pub use attachment::*; pub mod extension; pub use extension::*; diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index 6db0d360fe..04b92ca85f 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -19,10 +19,7 @@ mod query; mod routing; mod unit; -use crate::{ - common::Attachment, - core::{Channel, CongestionControl, Reliability, WireExpr, ZInt}, -}; +use crate::core::{Channel, CongestionControl, Reliability, WireExpr, ZInt}; use alloc::{string::String, vec::Vec}; use core::fmt; pub use data::*; @@ -55,7 +52,6 @@ pub mod zmsg { // Message decorators pub const PRIORITY: u8 = imsg::id::PRIORITY; pub const REPLY_CONTEXT: u8 = imsg::id::REPLY_CONTEXT; - pub const ATTACHMENT: u8 = imsg::id::ATTACHMENT; pub const ROUTING_CONTEXT: u8 = imsg::id::ROUTING_CONTEXT; } @@ -208,7 +204,6 @@ pub struct ZenohMessage { pub body: ZenohBody, pub channel: Channel, pub routing_context: Option, - pub attachment: Option, #[cfg(feature = "stats")] pub size: Option, } @@ -217,13 +212,11 @@ impl ZenohMessage { pub fn make_declare( declarations: Vec, routing_context: Option, - attachment: Option, ) -> ZenohMessage { ZenohMessage { body: ZenohBody::Declare(Declare { declarations }), channel: zmsg::default_channel::DECLARE, routing_context, - attachment, #[cfg(feature = "stats")] size: None, } @@ -239,7 +232,6 @@ impl ZenohMessage { data_info: Option, routing_context: Option, reply_context: Option, - attachment: Option, ) -> ZenohMessage { ZenohMessage { body: ZenohBody::Data(Data { @@ -251,7 +243,6 @@ impl ZenohMessage { }), channel, routing_context, - attachment, #[cfg(feature = "stats")] size: None, } @@ -261,7 +252,6 @@ impl ZenohMessage { channel: Channel, congestion_control: CongestionControl, reply_context: Option, - attachment: Option, ) -> ZenohMessage { ZenohMessage { body: ZenohBody::Unit(Unit { @@ -270,7 +260,6 @@ impl ZenohMessage { }), channel, routing_context: None, - attachment, #[cfg(feature = "stats")] size: None, } @@ -281,7 +270,6 @@ impl ZenohMessage { key: WireExpr<'static>, pull_id: ZInt, max_samples: Option, - attachment: Option, ) -> ZenohMessage { ZenohMessage { body: ZenohBody::Pull(Pull { @@ -292,7 +280,6 @@ impl ZenohMessage { }), channel: zmsg::default_channel::PULL, routing_context: None, - attachment, #[cfg(feature = "stats")] size: None, } @@ -308,7 +295,6 @@ impl ZenohMessage { consolidation: ConsolidationMode, body: Option, routing_context: Option, - attachment: Option, ) -> ZenohMessage { ZenohMessage { body: ZenohBody::Query(Query { @@ -321,21 +307,17 @@ impl ZenohMessage { }), channel: zmsg::default_channel::QUERY, routing_context, - attachment, #[cfg(feature = "stats")] size: None, } } - pub fn make_link_state_list( - link_states: Vec, - attachment: Option, - ) -> ZenohMessage { + pub fn make_link_state_list(link_states: Vec) -> ZenohMessage { ZenohMessage { body: ZenohBody::LinkStateList(LinkStateList { link_states }), channel: zmsg::default_channel::LINK_STATE_LIST, routing_context: None, - attachment, + #[cfg(feature = "stats")] size: None, } @@ -370,8 +352,8 @@ impl fmt::Debug for ZenohMessage { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "{:?} {:?} {:?} {:?}", - self.body, self.channel, self.routing_context, self.attachment + "{:?} {:?} {:?}", + self.body, self.channel, self.routing_context )?; #[cfg(feature = "stats")] write!(f, " {:?}", self.size)?; @@ -394,8 +376,6 @@ impl ZenohMessage { let mut rng = rand::thread_rng(); - let attachment = None; - let routing_context = if rng.gen_bool(0.5) { Some(RoutingContext::rand()) } else { @@ -429,7 +409,6 @@ impl ZenohMessage { body, channel, routing_context, - attachment, } } } diff --git a/io/zenoh-transport/src/multicast/rx.rs b/io/zenoh-transport/src/multicast/rx.rs index 21c54d3a21..c6e4facde6 100644 --- a/io/zenoh-transport/src/multicast/rx.rs +++ b/io/zenoh-transport/src/multicast/rx.rs @@ -205,20 +205,22 @@ impl TransportMulticastInner { match msg.body { TransportBody::Frame(Frame { - channel, + reliability, sn, payload, + qos, }) => { + let priority = qos.priority(); let c = if self.is_qos() { - &peer.conduit_rx[channel.priority as usize] - } else if channel.priority == Priority::default() { + &peer.conduit_rx[priority as usize] + } else if priority == Priority::default() { &peer.conduit_rx[0] } else { bail!( "Transport {}: {}. Unknown conduit {:?} from {}.", self.manager.config.zid, self.locator, - channel.priority, + priority, peer.locator ); }; diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs index 10d84dad4e..30ee96679e 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs @@ -26,7 +26,6 @@ use zenoh_core::{zasynclock, zasyncread}; use zenoh_crypto::hmac; use zenoh_link::LinkUnicast; use zenoh_protocol::{ - common::Attachment, core::Property, transport::{tmsg, TransportMessage}, }; diff --git a/io/zenoh-transport/src/unicast/establishment/properties.rs b/io/zenoh-transport/src/unicast/establishment/properties.rs index 67e6d2d1f3..b8dcbff511 100644 --- a/io/zenoh-transport/src/unicast/establishment/properties.rs +++ b/io/zenoh-transport/src/unicast/establishment/properties.rs @@ -17,10 +17,7 @@ use std::{ }; use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZBuf}; use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_protocol::{ - common::Attachment, - core::{Property, ZInt}, -}; +use zenoh_protocol::core::{Property, ZInt}; use zenoh_result::{bail, zerror, Error as ZError, ZResult}; #[derive(Clone, Debug, PartialEq, Eq)] From 6ef98b648e9d028fe426fd6992748cc8c288d78a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 11:45:09 +0100 Subject: [PATCH 019/203] Remove attachment from Batch and Pipeline --- commons/zenoh-protocol/src/core/mod.rs | 2 +- io/zenoh-transport/src/common/batch.rs | 1 - io/zenoh-transport/src/common/pipeline.rs | 10 ++-------- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index 518bb97001..a68e1e332d 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -67,7 +67,7 @@ pub enum Bits { } impl Bits { - pub fn mask(&self) -> ZInt { + pub const fn mask(&self) -> ZInt { match self { Bits::U8 => u8::MAX as ZInt, Bits::U16 => u16::MAX as ZInt, diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 7ee6fed361..238a281294 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -380,7 +380,6 @@ mod tests { None, None, None, - None, ); let mut tmsgs_in = vec![]; diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 8bc07cc1d2..b995d1e67b 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -723,7 +723,6 @@ mod tests { let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let channel = Channel { priority: Priority::Control, reliability: Reliability::Reliable, @@ -738,7 +737,6 @@ mod tests { data_info, routing_context, reply_context, - attachment, ); println!( @@ -857,7 +855,6 @@ mod tests { let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let message = ZenohMessage::make_data( key, @@ -867,7 +864,6 @@ mod tests { data_info, routing_context, reply_context, - attachment, ); // The last push should block since there shouldn't any more batches @@ -888,7 +884,7 @@ mod tests { } // Pipeline - let tct = TransportConduitTx::make(SEQ_NUM_RES).unwrap(); + let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION.mask()).unwrap(); let conduits = vec![tct]; let (producer, mut consumer) = TransmissionPipeline::make(TransmissionPipelineConf::default(), conduits.as_slice()); @@ -940,7 +936,7 @@ mod tests { #[ignore] fn tx_pipeline_thr() { // Queue - let tct = TransportConduitTx::make(SEQ_NUM_RES).unwrap(); + let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION.mask()).unwrap(); let conduits = vec![tct]; let (producer, mut consumer) = TransmissionPipeline::make(CONFIG, conduits.as_slice()); let count = Arc::new(AtomicUsize::new(0)); @@ -967,7 +963,6 @@ mod tests { let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let message = ZenohMessage::make_data( key, @@ -977,7 +972,6 @@ mod tests { data_info, routing_context, reply_context, - attachment, ); let duration = Duration::from_millis(5_500); From c7c0187c679c73118f16ae769d17d6f2e6621a62 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 11:53:00 +0100 Subject: [PATCH 020/203] Remove attachment from primitives --- commons/zenoh-protocol/src/transport/mod.rs | 6 +++ io/zenoh-transport/src/multicast/link.rs | 23 +++++------ io/zenoh-transport/src/primitives/mux.rs | 45 +++++++++------------ io/zenoh-transport/src/shm.rs | 26 ++---------- 4 files changed, 39 insertions(+), 61 deletions(-) diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 2110a7b678..e3300cfab2 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -166,6 +166,12 @@ impl From for TransportMessage { } } +impl From for TransportMessage { + fn from(join: Join) -> Self { + TransportBody::Join(join).into() + } +} + impl From for TransportMessage { fn from(close: Close) -> Self { TransportBody::Close(close).into() diff --git a/io/zenoh-transport/src/multicast/link.rs b/io/zenoh-transport/src/multicast/link.rs index c02d5fc65c..1928e94ec6 100644 --- a/io/zenoh-transport/src/multicast/link.rs +++ b/io/zenoh-transport/src/multicast/link.rs @@ -33,7 +33,7 @@ use zenoh_core::zlock; use zenoh_link::{LinkMulticast, Locator}; use zenoh_protocol::{ core::{Priority, WhatAmI, ZInt, ZenohId}, - transport::{ConduitSn, ConduitSnList, TransportMessage}, + transport::{ConduitSn, ConduitSnList, Join, KeepAlive, TransportMessage}, }; use zenoh_result::{bail, zerror, ZResult}; use zenoh_sync::RecyclingObjectPool; @@ -252,7 +252,6 @@ async fn tx_task( pipeline.refill(batch, priority); } Action::Join => { - let attachment = None; let next_sns = last_sns .iter() .map(|c| ConduitSn { @@ -267,15 +266,15 @@ async fn tx_task( assert_eq!(next_sns.len(), 1); ConduitSnList::Plain(next_sns[0]) }; - let message = TransportMessage::make_join( - config.version, - config.whatami, - config.zid, - config.lease, - config.sn_resolution, + let message: TransportMessage = Join { + version: config.version, + whatami: config.whatami, + zid: config.zid, + lease: config.lease, + sn_resolution: config.sn_resolution, next_sns, - attachment, - ); + } + .into(); #[allow(unused_variables)] // Used when stats feature is enabled let n = link.write_transport_message(&message).await?; @@ -288,9 +287,7 @@ async fn tx_task( last_join = Instant::now(); } Action::KeepAlive => { - let zid = Some(config.zid); - let attachment = None; - let message = TransportMessage::make_keep_alive(zid, attachment); + let message: TransportMessage = KeepAlive.into(); #[allow(unused_variables)] // Used when stats feature is enabled let n = link.write_transport_message(&message).await?; diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index 107a83ca75..965ca33b26 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -43,7 +43,7 @@ impl Primitives for Mux { let decls = vec![d]; let _ = self .handler - .handle_message(ZenohMessage::make_declare(decls, None, None)); + .handle_message(ZenohMessage::make_declare(decls, None)); } fn forget_resource(&self, expr_id: ZInt) { @@ -51,7 +51,7 @@ impl Primitives for Mux { let decls = vec![d]; let _ = self .handler - .handle_message(ZenohMessage::make_declare(decls, None, None)); + .handle_message(ZenohMessage::make_declare(decls, None)); } fn decl_subscriber( @@ -65,9 +65,9 @@ impl Primitives for Mux { info: sub_info.clone(), }); let decls = vec![d]; - let _ = - self.handler - .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); + let _ = self + .handler + .handle_message(ZenohMessage::make_declare(decls, routing_context)); } fn forget_subscriber(&self, key_expr: &WireExpr, routing_context: Option) { @@ -75,9 +75,9 @@ impl Primitives for Mux { key: key_expr.to_owned(), }); let decls = vec![d]; - let _ = - self.handler - .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); + let _ = self + .handler + .handle_message(ZenohMessage::make_declare(decls, routing_context)); } fn decl_publisher(&self, key_expr: &WireExpr, routing_context: Option) { @@ -85,9 +85,9 @@ impl Primitives for Mux { key: key_expr.to_owned(), }); let decls = vec![d]; - let _ = - self.handler - .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); + let _ = self + .handler + .handle_message(ZenohMessage::make_declare(decls, routing_context)); } fn forget_publisher(&self, key_expr: &WireExpr, routing_context: Option) { @@ -95,9 +95,9 @@ impl Primitives for Mux { key: key_expr.to_owned(), }); let decls = vec![d]; - let _ = - self.handler - .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); + let _ = self + .handler + .handle_message(ZenohMessage::make_declare(decls, routing_context)); } fn decl_queryable( @@ -111,9 +111,9 @@ impl Primitives for Mux { info: qabl_info.clone(), }); let decls = vec![d]; - let _ = - self.handler - .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); + let _ = self + .handler + .handle_message(ZenohMessage::make_declare(decls, routing_context)); } fn forget_queryable(&self, key_expr: &WireExpr, routing_context: Option) { @@ -121,9 +121,9 @@ impl Primitives for Mux { key: key_expr.to_owned(), }); let decls = vec![d]; - let _ = - self.handler - .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); + let _ = self + .handler + .handle_message(ZenohMessage::make_declare(decls, routing_context)); } fn send_data( @@ -143,7 +143,6 @@ impl Primitives for Mux { data_info, routing_context, None, - None, )); } @@ -170,7 +169,6 @@ impl Primitives for Mux { consolidation, body, routing_context, - None, )); } @@ -190,7 +188,6 @@ impl Primitives for Mux { data_info, None, Some(ReplyContext::new(qid, Some(ReplierInfo { id: replier_id }))), - None, )); } @@ -199,7 +196,6 @@ impl Primitives for Mux { zmsg::default_channel::REPLY, zmsg::default_congestion_control::REPLY, Some(ReplyContext::new(qid, None)), - None, )); } @@ -215,7 +211,6 @@ impl Primitives for Mux { key_expr.to_owned(), pull_id, *max_samples, - None, )); } diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index bdc1804f40..fc62871daf 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -121,10 +121,6 @@ pub fn map_zmsg_to_shmbuf( ) -> ZResult { let mut res = false; - if let Some(attachment) = msg.attachment.as_mut() { - res = map_zbuf_to_shmbuf(&mut attachment.buffer, shmr)?; - } - if let ZenohBody::Data(Data { payload, data_info, .. }) = &mut msg.body @@ -145,10 +141,6 @@ pub fn map_zmsg_to_shmbuf( pub fn map_zmsg_to_shminfo(msg: &mut ZenohMessage) -> ZResult { let mut res = false; - if let Some(attachment) = msg.attachment.as_mut() { - res = map_zbuf_to_shminfo(&mut attachment.buffer)?; - } - if let ZenohBody::Data(Data { payload, data_info, .. }) = &mut msg.body @@ -171,22 +163,10 @@ pub fn map_zmsg_to_shminfo(msg: &mut ZenohMessage) -> ZResult { // #[cfg(feature = "shared-memory")] // impl TransportMessage { // pub(crate) fn map_to_shmbuf(&mut self, shmr: Arc>) -> ZResult { -// let mut res = false; - -// if let Some(attachment) = self.attachment.as_mut() { -// res = attachment.buffer.map_to_shmbuf(shmr)?; -// } - -// Ok(res) +// Ok(false) // } - +// // pub(crate) fn map_to_shminfo(&mut self) -> ZResult { -// let mut res = false; - -// if let Some(attachment) = self.attachment.as_mut() { -// res = attachment.buffer.map_to_shminfo()?; -// } - -// Ok(res) +// Ok(false) // } // } From 4905c6bba7cdde9503b16d35f6651aab86fcf102 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 12:13:23 +0100 Subject: [PATCH 021/203] Remove multicast --- io/zenoh-transport/src/lib.rs | 39 -- io/zenoh-transport/src/manager.rs | 28 -- .../src/multicast/establishment.rs | 87 ---- io/zenoh-transport/src/multicast/link.rs | 392 --------------- io/zenoh-transport/src/multicast/manager.rs | 235 --------- io/zenoh-transport/src/multicast/mod.rs | 191 ------- io/zenoh-transport/src/multicast/rx.rs | 251 ---------- io/zenoh-transport/src/multicast/transport.rs | 464 ------------------ io/zenoh-transport/src/multicast/tx.rs | 91 ---- io/zenoh-transport/tests/endpoints.rs | 11 +- .../tests/multicast_transport.rs | 338 ------------- .../tests/unicast_authenticator.rs | 18 +- .../tests/unicast_concurrent.rs | 15 +- io/zenoh-transport/tests/unicast_conduits.rs | 20 +- .../tests/unicast_defragmentation.rs | 2 - .../tests/unicast_intermittent.rs | 27 +- io/zenoh-transport/tests/unicast_openclose.rs | 18 +- io/zenoh-transport/tests/unicast_shm.rs | 14 +- .../tests/unicast_simultaneous.rs | 9 - io/zenoh-transport/tests/unicast_transport.rs | 16 - zenoh/src/net/runtime/mod.rs | 8 - 21 files changed, 13 insertions(+), 2261 deletions(-) delete mode 100644 io/zenoh-transport/src/multicast/establishment.rs delete mode 100644 io/zenoh-transport/src/multicast/link.rs delete mode 100644 io/zenoh-transport/src/multicast/manager.rs delete mode 100644 io/zenoh-transport/src/multicast/mod.rs delete mode 100644 io/zenoh-transport/src/multicast/rx.rs delete mode 100644 io/zenoh-transport/src/multicast/transport.rs delete mode 100644 io/zenoh-transport/src/multicast/tx.rs delete mode 100644 io/zenoh-transport/tests/multicast_transport.rs diff --git a/io/zenoh-transport/src/lib.rs b/io/zenoh-transport/src/lib.rs index d2e20b423a..ef103c0d9f 100644 --- a/io/zenoh-transport/src/lib.rs +++ b/io/zenoh-transport/src/lib.rs @@ -19,14 +19,12 @@ //! [Click here for Zenoh's documentation](../zenoh/index.html) mod common; mod manager; -mod multicast; mod primitives; #[cfg(feature = "shared-memory")] mod shm; pub mod unicast; pub use manager::*; -pub use multicast::*; pub use primitives::*; use serde::Serialize; use std::any::Any; @@ -46,11 +44,6 @@ pub trait TransportEventHandler: Send + Sync { peer: TransportPeer, transport: TransportUnicast, ) -> ZResult>; - - fn new_multicast( - &self, - transport: TransportMulticast, - ) -> ZResult>; } #[derive(Default)] @@ -64,38 +57,6 @@ impl TransportEventHandler for DummyTransportEventHandler { ) -> ZResult> { Ok(Arc::new(DummyTransportPeerEventHandler::default())) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - Ok(Arc::new(DummyTransportMulticastEventHandler::default())) - } -} - -/*************************************/ -/* MULTICAST */ -/*************************************/ -pub trait TransportMulticastEventHandler: Send + Sync { - fn new_peer(&self, peer: TransportPeer) -> ZResult>; - fn closing(&self); - fn closed(&self); - fn as_any(&self) -> &dyn Any; -} - -// Define an empty TransportCallback for the listener transport -#[derive(Default)] -pub struct DummyTransportMulticastEventHandler; - -impl TransportMulticastEventHandler for DummyTransportMulticastEventHandler { - fn new_peer(&self, _peer: TransportPeer) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) - } - fn closing(&self) {} - fn closed(&self) {} - fn as_any(&self) -> &dyn Any { - self - } } /*************************************/ diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index ba91c7e83a..39f5de2d49 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -11,10 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::multicast::manager::{ - TransportManagerBuilderMulticast, TransportManagerConfigMulticast, - TransportManagerStateMulticast, -}; use super::unicast::manager::{ TransportManagerBuilderUnicast, TransportManagerConfigUnicast, TransportManagerStateUnicast, }; @@ -56,12 +52,6 @@ use zenoh_result::{bail, ZResult}; /// ) -> ZResult> { /// Ok(Arc::new(DummyTransportPeerEventHandler::default())) /// } -/// -/// fn new_multicast(&self, -/// _transport: TransportMulticast -/// ) -> ZResult> { -/// Ok(Arc::new(DummyTransportMulticastEventHandler::default())) -/// } /// } /// /// // Create the default TransportManager @@ -99,7 +89,6 @@ pub struct TransportManagerConfig { pub defrag_buff_size: usize, pub link_rx_buffer_size: usize, pub unicast: TransportManagerConfigUnicast, - pub multicast: TransportManagerConfigMulticast, pub endpoint: HashMap, pub handler: Arc, pub tx_threads: usize, @@ -107,7 +96,6 @@ pub struct TransportManagerConfig { pub struct TransportManagerState { pub unicast: TransportManagerStateUnicast, - pub multicast: TransportManagerStateMulticast, } pub struct TransportManagerParams { @@ -126,7 +114,6 @@ pub struct TransportManagerBuilder { defrag_buff_size: usize, link_rx_buffer_size: usize, unicast: TransportManagerBuilderUnicast, - multicast: TransportManagerBuilderMulticast, endpoint: HashMap, tx_threads: usize, } @@ -182,11 +169,6 @@ impl TransportManagerBuilder { self } - pub fn multicast(mut self, multicast: TransportManagerBuilderMulticast) -> Self { - self.multicast = multicast; - self - } - pub fn tx_threads(mut self, num: usize) -> Self { self.tx_threads = num; self @@ -229,18 +211,12 @@ impl TransportManagerBuilder { .from_config(config) .await?, ); - self = self.multicast( - TransportManagerBuilderMulticast::default() - .from_config(config) - .await?, - ); Ok(self) } pub fn build(self, handler: Arc) -> ZResult { let unicast = self.unicast.build()?; - let multicast = self.multicast.build()?; let mut queue_size = [0; Priority::NUM]; queue_size[Priority::Control as usize] = *self.queue_size.control(); @@ -263,7 +239,6 @@ impl TransportManagerBuilder { defrag_buff_size: self.defrag_buff_size, link_rx_buffer_size: self.link_rx_buffer_size, unicast: unicast.config, - multicast: multicast.config, endpoint: self.endpoint, handler, tx_threads: self.tx_threads, @@ -271,7 +246,6 @@ impl TransportManagerBuilder { let state = TransportManagerState { unicast: unicast.state, - multicast: multicast.state, }; let params = TransportManagerParams { config, state }; @@ -296,7 +270,6 @@ impl Default for TransportManagerBuilder { link_rx_buffer_size: zparse!(ZN_LINK_RX_BUFF_SIZE_DEFAULT).unwrap(), endpoint: HashMap::new(), unicast: TransportManagerBuilderUnicast::default(), - multicast: TransportManagerBuilderMulticast::default(), tx_threads: 1, } } @@ -389,7 +362,6 @@ impl TransportManager { pub async fn close(&self) { log::trace!("TransportManager::clear())"); self.close_unicast().await; - self.close_multicast().await; self.tx_executor.stop().await; } diff --git a/io/zenoh-transport/src/multicast/establishment.rs b/io/zenoh-transport/src/multicast/establishment.rs deleted file mode 100644 index fd8a40ee80..0000000000 --- a/io/zenoh-transport/src/multicast/establishment.rs +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::multicast::{TransportMulticast, TransportMulticastConfig, TransportMulticastInner}; -use crate::TransportManager; -use rand::Rng; -use std::sync::Arc; -use zenoh_core::{zasynclock, zlock}; -use zenoh_link::LinkMulticast; -use zenoh_protocol::{ - core::Priority, - transport::{ConduitSn, ConduitSnList}, -}; -use zenoh_result::ZResult; - -pub(crate) async fn open_link( - manager: &TransportManager, - link: LinkMulticast, -) -> ZResult { - // Create and configure the multicast transport - let mut prng = zasynclock!(manager.prng); - - macro_rules! zgen_conduit_sn { - () => { - ConduitSn { - reliable: prng.gen_range(0..manager.config.sn_resolution), - best_effort: prng.gen_range(0..manager.config.sn_resolution), - } - }; - } - - let locator = link.get_dst(); - let initial_sns = if manager.config.multicast.is_qos { - let mut initial_sns = [ConduitSn::default(); Priority::NUM]; - for isn in initial_sns.iter_mut() { - *isn = zgen_conduit_sn!(); - } - ConduitSnList::QoS(initial_sns.into()) - } else { - ConduitSnList::Plain(zgen_conduit_sn!()) - }; - let config = TransportMulticastConfig { - manager: manager.clone(), - initial_sns, - link: link.clone(), - }; - let ti = Arc::new(TransportMulticastInner::make(config)?); - - // Store the active transport - let transport: TransportMulticast = (&ti).into(); - zlock!(manager.state.multicast.transports).insert(locator.to_owned(), ti.clone()); - - // Notify the transport event handler - let batch_size = manager.config.batch_size.min(link.get_mtu()); - ti.start_tx(batch_size).map_err(|e| { - zlock!(manager.state.multicast.transports).remove(locator); - let _ = ti.stop_tx(); - e - })?; - let callback = manager - .config - .handler - .new_multicast(transport.clone()) - .map_err(|e| { - zlock!(manager.state.multicast.transports).remove(locator); - let _ = ti.stop_tx(); - e - })?; - ti.set_callback(callback); - ti.start_rx().map_err(|e| { - zlock!(manager.state.multicast.transports).remove(locator); - let _ = ti.stop_rx(); - e - })?; - - Ok(transport) -} diff --git a/io/zenoh-transport/src/multicast/link.rs b/io/zenoh-transport/src/multicast/link.rs deleted file mode 100644 index 1928e94ec6..0000000000 --- a/io/zenoh-transport/src/multicast/link.rs +++ /dev/null @@ -1,392 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::common::{conduit::TransportConduitTx, pipeline::TransmissionPipeline}; -use super::transport::TransportMulticastInner; -#[cfg(feature = "stats")] -use super::TransportMulticastStatsAtomic; -use crate::common::batch::WBatch; -use crate::common::pipeline::{ - TransmissionPipelineConf, TransmissionPipelineConsumer, TransmissionPipelineProducer, -}; -use async_std::prelude::FutureExt; -use async_std::task; -use async_std::task::JoinHandle; -use std::{ - convert::TryInto, - sync::Arc, - time::{Duration, Instant}, -}; -use zenoh_buffers::reader::{HasReader, Reader}; -use zenoh_codec::{RCodec, Zenoh080}; -use zenoh_core::zlock; -use zenoh_link::{LinkMulticast, Locator}; -use zenoh_protocol::{ - core::{Priority, WhatAmI, ZInt, ZenohId}, - transport::{ConduitSn, ConduitSnList, Join, KeepAlive, TransportMessage}, -}; -use zenoh_result::{bail, zerror, ZResult}; -use zenoh_sync::RecyclingObjectPool; -use zenoh_sync::Signal; - -pub(super) struct TransportLinkMulticastConfig { - pub(super) version: u8, - pub(super) zid: ZenohId, - pub(super) whatami: WhatAmI, - pub(super) lease: Duration, - pub(super) keep_alive: usize, - pub(super) join_interval: Duration, - pub(super) sn_resolution: ZInt, - pub(super) batch_size: u16, -} - -#[derive(Clone)] -pub(super) struct TransportLinkMulticast { - // The underlying link - pub(super) link: LinkMulticast, - // The transmission pipeline - pub(super) pipeline: Option, - // The transport this link is associated to - transport: TransportMulticastInner, - // The signals to stop TX/RX tasks - handle_tx: Option>>, - signal_rx: Signal, - handle_rx: Option>>, -} - -impl TransportLinkMulticast { - pub(super) fn new( - transport: TransportMulticastInner, - link: LinkMulticast, - ) -> TransportLinkMulticast { - TransportLinkMulticast { - transport, - link, - pipeline: None, - handle_tx: None, - signal_rx: Signal::new(), - handle_rx: None, - } - } -} - -impl TransportLinkMulticast { - pub(super) fn start_tx( - &mut self, - config: TransportLinkMulticastConfig, - conduit_tx: Arc<[TransportConduitTx]>, - ) { - let initial_sns: Vec = conduit_tx - .iter() - .map(|x| ConduitSn { - reliable: zlock!(x.reliable).sn.now(), - best_effort: zlock!(x.best_effort).sn.now(), - }) - .collect(); - - if self.handle_tx.is_none() { - let tpc = TransmissionPipelineConf { - is_streamed: false, - batch_size: config.batch_size.min(self.link.get_mtu()), - queue_size: self.transport.manager.config.queue_size, - backoff: self.transport.manager.config.queue_backoff, - }; - // The pipeline - let (producer, consumer) = TransmissionPipeline::make(tpc, &conduit_tx); - self.pipeline = Some(producer); - - // Spawn the TX task - let c_link = self.link.clone(); - let c_transport = self.transport.clone(); - let handle = task::spawn(async move { - let res = tx_task( - consumer, - c_link.clone(), - config, - initial_sns, - #[cfg(feature = "stats")] - c_transport.stats.clone(), - ) - .await; - if let Err(e) = res { - log::debug!("{}", e); - // Spawn a task to avoid a deadlock waiting for this same task - // to finish in the close() joining its handle - task::spawn(async move { c_transport.delete().await }); - } - }); - self.handle_tx = Some(Arc::new(handle)); - } - } - - pub(super) fn stop_tx(&mut self) { - if let Some(pipeline) = self.pipeline.as_ref() { - pipeline.disable(); - } - } - - pub(super) fn start_rx(&mut self) { - if self.handle_rx.is_none() { - // Spawn the RX task - let c_link = self.link.clone(); - let c_transport = self.transport.clone(); - let c_signal = self.signal_rx.clone(); - let c_rx_buffer_size = self.transport.manager.config.link_rx_buffer_size; - - let handle = task::spawn(async move { - // Start the consume task - let res = rx_task( - c_link.clone(), - c_transport.clone(), - c_signal.clone(), - c_rx_buffer_size, - ) - .await; - c_signal.trigger(); - if let Err(e) = res { - log::debug!("{}", e); - // Spawn a task to avoid a deadlock waiting for this same task - // to finish in the close() joining its handle - task::spawn(async move { c_transport.delete().await }); - } - }); - self.handle_rx = Some(Arc::new(handle)); - } - } - - pub(super) fn stop_rx(&mut self) { - self.signal_rx.trigger(); - } - - pub(super) async fn close(mut self) -> ZResult<()> { - log::trace!("{}: closing", self.link); - self.stop_rx(); - if let Some(handle) = self.handle_rx.take() { - // It is safe to unwrap the Arc since we have the ownership of the whole link - let handle_rx = Arc::try_unwrap(handle).unwrap(); - handle_rx.await; - } - - self.stop_tx(); - if let Some(handle) = self.handle_tx.take() { - // It is safe to unwrap the Arc since we have the ownership of the whole link - let handle_tx = Arc::try_unwrap(handle).unwrap(); - handle_tx.await; - } - - self.link.close().await - } -} - -/*************************************/ -/* TASKS */ -/*************************************/ -async fn tx_task( - mut pipeline: TransmissionPipelineConsumer, - link: LinkMulticast, - config: TransportLinkMulticastConfig, - mut last_sns: Vec, - #[cfg(feature = "stats")] stats: Arc, -) -> ZResult<()> { - enum Action { - Pull((WBatch, usize)), - Join, - KeepAlive, - Stop, - } - - async fn pull(pipeline: &mut TransmissionPipelineConsumer, keep_alive: Duration) -> Action { - match pipeline.pull().timeout(keep_alive).await { - Ok(res) => match res { - Some(sb) => Action::Pull(sb), - None => Action::Stop, - }, - Err(_) => Action::KeepAlive, - } - } - - async fn join(last_join: Instant, join_interval: Duration) -> Action { - let now = Instant::now(); - let target = last_join + join_interval; - if now < target { - let left = target - now; - task::sleep(left).await; - } - Action::Join - } - - let keep_alive = config.join_interval / config.keep_alive as u32; - let mut last_join = Instant::now().checked_sub(config.join_interval).unwrap(); - loop { - match pull(&mut pipeline, keep_alive) - .race(join(last_join, config.join_interval)) - .await - { - Action::Pull((batch, priority)) => { - // Send the buffer on the link - let bytes = batch.as_bytes(); - link.write_all(bytes).await?; - // Keep track of next SNs - if let Some(sn) = batch.latest_sn.reliable { - last_sns[priority].reliable = sn; - } - if let Some(sn) = batch.latest_sn.best_effort { - last_sns[priority].best_effort = sn; - } - #[cfg(feature = "stats")] - { - stats.inc_tx_t_msgs(batch.stats.t_msgs); - stats.inc_tx_bytes(bytes.len()); - } - // Reinsert the batch into the queue - pipeline.refill(batch, priority); - } - Action::Join => { - let next_sns = last_sns - .iter() - .map(|c| ConduitSn { - reliable: (1 + c.reliable) % config.sn_resolution, - best_effort: (1 + c.best_effort) % config.sn_resolution, - }) - .collect::>(); - let next_sns = if next_sns.len() == Priority::NUM { - let tmp: [ConduitSn; Priority::NUM] = next_sns.try_into().unwrap(); - ConduitSnList::QoS(tmp.into()) - } else { - assert_eq!(next_sns.len(), 1); - ConduitSnList::Plain(next_sns[0]) - }; - let message: TransportMessage = Join { - version: config.version, - whatami: config.whatami, - zid: config.zid, - lease: config.lease, - sn_resolution: config.sn_resolution, - next_sns, - } - .into(); - - #[allow(unused_variables)] // Used when stats feature is enabled - let n = link.write_transport_message(&message).await?; - #[cfg(feature = "stats")] - { - stats.inc_tx_t_msgs(1); - stats.inc_tx_bytes(n); - } - - last_join = Instant::now(); - } - Action::KeepAlive => { - let message: TransportMessage = KeepAlive.into(); - - #[allow(unused_variables)] // Used when stats feature is enabled - let n = link.write_transport_message(&message).await?; - #[cfg(feature = "stats")] - { - stats.inc_tx_t_msgs(1); - stats.inc_tx_bytes(n); - } - } - Action::Stop => { - // Drain the transmission pipeline and write remaining bytes on the wire - let mut batches = pipeline.drain(); - for (b, _) in batches.drain(..) { - link.write_all(b.as_bytes()) - .timeout(config.join_interval) - .await - .map_err(|_| { - zerror!( - "{}: flush failed after {} ms", - link, - config.join_interval.as_millis() - ) - })??; - - #[cfg(feature = "stats")] - { - stats.inc_tx_t_msgs(b.stats.t_msgs); - stats.inc_tx_bytes(b.len() as usize); - } - } - break; - } - } - } - - Ok(()) -} - -async fn rx_task( - link: LinkMulticast, - transport: TransportMulticastInner, - signal: Signal, - rx_buffer_size: usize, -) -> ZResult<()> { - enum Action { - Read((usize, Locator)), - Stop, - } - - async fn read(link: &LinkMulticast, buffer: &mut [u8]) -> ZResult { - let (n, loc) = link.read(buffer).await?; - Ok(Action::Read((n, loc.into_owned()))) - } - - async fn stop(signal: Signal) -> ZResult { - signal.wait().await; - Ok(Action::Stop) - } - - // The codec - let codec = Zenoh080::default(); - - // The pool of buffers - let mtu = link.get_mtu() as usize; - let mut n = rx_buffer_size / mtu; - if rx_buffer_size % mtu != 0 { - n += 1; - } - let pool = RecyclingObjectPool::new(n, || vec![0_u8; mtu].into_boxed_slice()); - while !signal.is_triggered() { - // Retrieve one buffer - let mut buffer = pool.try_take().unwrap_or_else(|| pool.alloc()); - // Async read from the underlying link - let action = read(&link, &mut buffer).race(stop(signal.clone())).await?; - match action { - Action::Read((n, loc)) => { - if n == 0 { - // Reading 0 bytes means error - bail!("{}: zero bytes reading", link); - } - - #[cfg(feature = "stats")] - transport.stats.inc_rx_bytes(n); - - // Deserialize all the messages from the current ZBuf - let mut reader = buffer[0..n].reader(); - while reader.can_read() { - let msg: TransportMessage = codec - .read(&mut reader) - .map_err(|_| zerror!("{}: decoding error", link))?; - - #[cfg(feature = "stats")] - transport.stats.inc_rx_t_msgs(1); - - transport.receive_message(msg, &loc)? - } - } - Action::Stop => break, - } - } - Ok(()) -} diff --git a/io/zenoh-transport/src/multicast/manager.rs b/io/zenoh-transport/src/multicast/manager.rs deleted file mode 100644 index 6557713fe8..0000000000 --- a/io/zenoh-transport/src/multicast/manager.rs +++ /dev/null @@ -1,235 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::multicast::transport::TransportMulticastInner; -use crate::multicast::TransportMulticast; -use crate::TransportManager; -use std::collections::HashMap; -use std::sync::{Arc, Mutex}; -use std::time::Duration; -use zenoh_config::{Config, ZN_LINK_KEEP_ALIVE_DEFAULT, ZN_LINK_LEASE_DEFAULT}; -use zenoh_core::{zlock, zparse}; -use zenoh_link::*; -use zenoh_protocol::{core::locator::LocatorProtocol, transport::tmsg}; -use zenoh_result::{bail, zerror, ZResult}; - -pub struct TransportManagerConfigMulticast { - pub lease: Duration, - pub keep_alive: usize, - pub join_interval: Duration, - pub max_sessions: usize, - pub is_qos: bool, -} - -pub struct TransportManagerBuilderMulticast { - lease: Duration, - keep_alive: usize, - join_interval: Duration, - max_sessions: usize, - is_qos: bool, -} - -pub struct TransportManagerStateMulticast { - // Established listeners - pub(super) protocols: Arc>>, - // Established transports - pub(super) transports: Arc>>>, -} - -pub struct TransportManagerParamsMulticast { - pub config: TransportManagerConfigMulticast, - pub state: TransportManagerStateMulticast, -} - -impl TransportManagerBuilderMulticast { - pub fn lease(mut self, lease: Duration) -> Self { - self.lease = lease; - self - } - - pub fn keep_alive(mut self, keep_alive: usize) -> Self { - self.keep_alive = keep_alive; - self - } - - pub fn join_interval(mut self, join_interval: Duration) -> Self { - self.join_interval = join_interval; - self - } - - pub fn max_sessions(mut self, max_sessions: usize) -> Self { - self.max_sessions = max_sessions; - self - } - - pub fn qos(mut self, is_qos: bool) -> Self { - self.is_qos = is_qos; - self - } - - pub async fn from_config( - mut self, - config: &Config, - ) -> ZResult { - self = self.lease(Duration::from_millis( - config.transport().link().tx().lease().unwrap(), - )); - self = self.keep_alive(config.transport().link().tx().keep_alive().unwrap()); - self = self.join_interval(Duration::from_millis( - config.transport().multicast().join_interval().unwrap(), - )); - self = self.max_sessions(config.transport().multicast().max_sessions().unwrap()); - self = self.qos(*config.transport().qos().enabled()); - - Ok(self) - } - - pub fn build(self) -> ZResult { - let config = TransportManagerConfigMulticast { - lease: self.lease, - keep_alive: self.keep_alive, - join_interval: self.join_interval, - max_sessions: self.max_sessions, - is_qos: self.is_qos, - }; - - let state = TransportManagerStateMulticast { - protocols: Arc::new(Mutex::new(HashMap::new())), - transports: Arc::new(Mutex::new(HashMap::new())), - }; - - let params = TransportManagerParamsMulticast { config, state }; - - Ok(params) - } -} - -impl Default for TransportManagerBuilderMulticast { - fn default() -> TransportManagerBuilderMulticast { - let tmb = TransportManagerBuilderMulticast { - lease: Duration::from_millis(zparse!(ZN_LINK_LEASE_DEFAULT).unwrap()), - keep_alive: zparse!(ZN_LINK_KEEP_ALIVE_DEFAULT).unwrap(), - join_interval: Duration::from_millis(0), - max_sessions: 0, - is_qos: false, - }; - async_std::task::block_on(tmb.from_config(&Config::default())).unwrap() - } -} - -impl TransportManager { - pub fn config_multicast() -> TransportManagerBuilderMulticast { - TransportManagerBuilderMulticast::default() - } - - pub async fn close_multicast(&self) { - log::trace!("TransportManagerMulticast::clear())"); - - zlock!(self.state.multicast.protocols).clear(); - - let mut tm_guard = zlock!(self.state.multicast.transports) - .drain() - .map(|(_, v)| v) - .collect::>>(); - for tm in tm_guard.drain(..) { - let _ = tm.close(close::reason::GENERIC).await; - } - } - - /*************************************/ - /* LINK MANAGER */ - /*************************************/ - fn new_link_manager_multicast( - &self, - protocol: &LocatorProtocol, - ) -> ZResult { - let mut w_guard = zlock!(self.state.multicast.protocols); - match w_guard.get(protocol) { - Some(lm) => Ok(lm.clone()), - None => { - let lm = LinkManagerBuilderMulticast::make(protocol)?; - w_guard.insert(protocol.to_owned(), lm.clone()); - Ok(lm) - } - } - } - - fn del_link_manager_multicast(&self, protocol: &LocatorProtocol) -> ZResult<()> { - match zlock!(self.state.multicast.protocols).remove(protocol) { - Some(_) => Ok(()), - None => bail!( - "Can not delete the link manager for protocol ({}) because it has not been found.", - protocol - ), - } - } - - /*************************************/ - /* TRANSPORT */ - /*************************************/ - pub async fn open_transport_multicast( - &self, - mut endpoint: EndPoint, - ) -> ZResult { - if !self - .locator_inspector - .is_multicast(&endpoint.to_locator()) - .await? - { - bail!( - "Can not open a multicast transport with a unicast unicast: {}.", - endpoint - ) - } - - // Automatically create a new link manager for the protocol if it does not exist - let manager = self.new_link_manager_multicast(endpoint.protocol().as_str())?; - // Fill and merge the endpoint configuration - if let Some(config) = self.config.endpoint.get(endpoint.protocol().as_str()) { - endpoint.config_mut().extend(config.iter())?; - } - - // Open the link - let link = manager.new_link(&endpoint).await?; - super::establishment::open_link(self, link).await - } - - pub fn get_transport_multicast(&self, locator: &Locator) -> Option { - zlock!(self.state.multicast.transports) - .get(locator) - .map(|t| t.into()) - } - - pub fn get_transports_multicast(&self) -> Vec { - zlock!(self.state.multicast.transports) - .values() - .map(|t| t.into()) - .collect() - } - - pub(super) fn del_transport_multicast(&self, locator: &Locator) -> ZResult<()> { - let mut guard = zlock!(self.state.multicast.transports); - let res = guard.remove(locator); - - let proto = locator.protocol(); - if !guard.iter().any(|(l, _)| l.protocol() == proto) { - let _ = self.del_link_manager_multicast(proto.as_str()); - } - - res.map(|_| ()).ok_or_else(|| { - let e = zerror!("Can not delete the transport for locator: {}", locator); - log::trace!("{}", e); - e.into() - }) - } -} diff --git a/io/zenoh-transport/src/multicast/mod.rs b/io/zenoh-transport/src/multicast/mod.rs deleted file mode 100644 index 02f1b42180..0000000000 --- a/io/zenoh-transport/src/multicast/mod.rs +++ /dev/null @@ -1,191 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// pub(crate) mod authenticator; -pub(crate) mod establishment; -pub(crate) mod link; -pub(crate) mod manager; -pub(crate) mod rx; -pub(crate) mod transport; -pub(crate) mod tx; - -use super::common; -#[cfg(feature = "stats")] -use super::common::stats::stats_struct; -use crate::{TransportMulticastEventHandler, TransportPeer}; -pub use manager::*; -use std::{ - fmt, - sync::{Arc, Weak}, -}; -use transport::{TransportMulticastConfig, TransportMulticastInner}; -use zenoh_core::zread; -use zenoh_link::Link; -use zenoh_protocol::{core::ZInt, transport::tmsg, zenoh::ZenohMessage}; -use zenoh_result::{zerror, ZResult}; - -/*************************************/ -/* STATS */ -/*************************************/ -#[cfg(feature = "stats")] -use serde::{Deserialize, Serialize}; -#[cfg(feature = "stats")] -use std::sync::atomic::{AtomicUsize, Ordering}; -#[cfg(feature = "stats")] -stats_struct! { - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct TransportMulticastStats { - pub tx_t_msgs, - pub tx_z_msgs, - pub tx_z_dropped, - pub tx_z_data_msgs, - pub tx_z_data_payload_bytes, - pub tx_z_data_reply_msgs, - pub tx_z_data_reply_payload_bytes, - pub tx_z_pull_msgs, - pub tx_z_query_msgs, - pub tx_z_declare_msgs, - pub tx_z_linkstate_msgs, - pub tx_z_unit_msgs, - pub tx_z_unit_reply_msgs, - pub tx_bytes, - pub rx_t_msgs, - pub rx_z_msgs, - pub rx_z_data_msgs, - pub rx_z_data_payload_bytes, - pub rx_z_data_reply_msgs, - pub rx_z_data_reply_payload_bytes, - pub rx_z_pull_msgs, - pub rx_z_query_msgs, - pub rx_z_declare_msgs, - pub rx_z_linkstate_msgs, - pub rx_z_unit_msgs, - pub rx_z_unit_reply_msgs, - pub rx_bytes, - } -} - -/*************************************/ -/* TRANSPORT MULTICAST */ -/*************************************/ -#[derive(Clone)] -pub struct TransportMulticast(Weak); - -impl TransportMulticast { - #[inline(always)] - fn get_transport(&self) -> ZResult> { - self.0 - .upgrade() - .ok_or_else(|| zerror!("Transport multicast closed").into()) - } - - #[inline(always)] - pub fn get_sn_resolution(&self) -> ZResult { - let transport = self.get_transport()?; - Ok(transport.get_sn_resolution()) - } - - #[inline(always)] - pub fn is_shm(&self) -> ZResult { - let transport = self.get_transport()?; - Ok(transport.is_shm()) - } - - #[inline(always)] - pub fn is_qos(&self) -> ZResult { - let transport = self.get_transport()?; - Ok(transport.is_qos()) - } - - #[inline(always)] - pub fn get_callback(&self) -> ZResult>> { - let transport = self.get_transport()?; - Ok(transport.get_callback()) - } - - #[inline(always)] - pub fn get_link(&self) -> ZResult { - let transport = self.get_transport()?; - Ok(transport.get_link().into()) - } - - #[inline(always)] - pub fn get_peers(&self) -> ZResult> { - let transport = self.get_transport()?; - Ok(transport.get_peers()) - } - - #[inline(always)] - pub async fn close(&self) -> ZResult<()> { - // Return Ok if the transport has already been closed - match self.get_transport() { - Ok(transport) => transport.close(close::reason::GENERIC).await, - Err(_) => Ok(()), - } - } - - #[inline(always)] - pub fn schedule(&self, message: ZenohMessage) -> ZResult<()> { - let transport = self.get_transport()?; - transport.schedule(message); - Ok(()) - } - - #[inline(always)] - pub fn handle_message(&self, message: ZenohMessage) -> ZResult<()> { - self.schedule(message) - } - - #[cfg(feature = "stats")] - pub fn get_stats(&self) -> ZResult { - Ok(self.get_transport()?.stats.snapshot()) - } -} - -impl From<&Arc> for TransportMulticast { - fn from(s: &Arc) -> TransportMulticast { - TransportMulticast(Arc::downgrade(s)) - } -} - -impl Eq for TransportMulticast {} - -impl PartialEq for TransportMulticast { - fn eq(&self, other: &Self) -> bool { - Weak::ptr_eq(&self.0, &other.0) - } -} - -impl fmt::Debug for TransportMulticast { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.get_transport() { - Ok(transport) => { - let peers: String = zread!(transport.peers) - .iter() - .map(|(l, p)| { - format!("(locator: {}, zid: {}, whatami: {})", l, p.zid, p.whatami) - }) - .collect(); - - f.debug_struct("Transport Multicast") - .field("sn_resolution", &transport.get_sn_resolution()) - .field("is_qos", &transport.is_qos()) - .field("is_shm", &transport.is_shm()) - .field("peers", &peers) - .finish() - } - Err(e) => { - write!(f, "{e}") - } - } - } -} diff --git a/io/zenoh-transport/src/multicast/rx.rs b/io/zenoh-transport/src/multicast/rx.rs deleted file mode 100644 index c6e4facde6..0000000000 --- a/io/zenoh-transport/src/multicast/rx.rs +++ /dev/null @@ -1,251 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::common::conduit::TransportChannelRx; -use super::transport::{TransportMulticastInner, TransportMulticastPeer}; -use std::sync::MutexGuard; -use zenoh_core::{zlock, zread}; -#[cfg(feature = "stats")] -use zenoh_protocol::zenoh::ZenohBody; -use zenoh_protocol::{ - core::{Locator, Priority, Reliability, ZInt}, - transport::{Frame, FramePayload, Join, TransportBody, TransportMessage}, - zenoh::ZenohMessage, -}; -use zenoh_result::{bail, zerror, ZResult}; - -/*************************************/ -/* TRANSPORT RX */ -/*************************************/ -//noinspection ALL -impl TransportMulticastInner { - fn trigger_callback( - &self, - #[allow(unused_mut)] // shared-memory feature requires mut - mut msg: ZenohMessage, - peer: &TransportMulticastPeer, - ) -> ZResult<()> { - #[cfg(feature = "stats")] - { - use zenoh_buffers::SplitBuffer; - self.stats.inc_rx_z_msgs(1); - match &msg.body { - ZenohBody::Data(data) => match data.reply_context { - Some(_) => { - self.stats.inc_rx_z_data_reply_msgs(1); - self.stats - .inc_rx_z_data_reply_payload_bytes(data.payload.len()); - } - None => { - self.stats.inc_rx_z_data_msgs(1); - self.stats.inc_rx_z_data_payload_bytes(data.payload.len()); - } - }, - ZenohBody::Unit(unit) => match unit.reply_context { - Some(_) => self.stats.inc_rx_z_unit_reply_msgs(1), - None => self.stats.inc_rx_z_unit_msgs(1), - }, - ZenohBody::Pull(_) => self.stats.inc_rx_z_pull_msgs(1), - ZenohBody::Query(_) => self.stats.inc_rx_z_query_msgs(1), - ZenohBody::Declare(_) => self.stats.inc_rx_z_declare_msgs(1), - ZenohBody::LinkStateList(_) => self.stats.inc_rx_z_linkstate_msgs(1), - } - } - - #[cfg(feature = "shared-memory")] - { - let _ = crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.shmr)?; - } - - peer.handler.handle_message(msg) - } - - fn handle_frame( - &self, - sn: ZInt, - payload: FramePayload, - mut guard: MutexGuard<'_, TransportChannelRx>, - peer: &TransportMulticastPeer, - ) -> ZResult<()> { - let precedes = guard.sn.precedes(sn)?; - if !precedes { - log::debug!( - "Transport: {}. Frame with invalid SN dropped: {}. Expected: {}.", - self.manager.config.zid, - sn, - guard.sn.get() - ); - // Drop the fragments if needed - if !guard.defrag.is_empty() { - guard.defrag.clear(); - } - // Keep reading - return Ok(()); - } - - // Set will always return OK because we have already checked - // with precedes() that the sn has the right resolution - let _ = guard.sn.set(sn); - match payload { - FramePayload::Fragment { buffer, is_final } => { - if guard.defrag.is_empty() { - let _ = guard.defrag.sync(sn); - } - guard.defrag.push(sn, buffer)?; - if is_final { - // When shared-memory feature is disabled, msg does not need to be mutable - let msg = guard.defrag.defragment().ok_or_else(|| { - zerror!( - "Transport {}: {}. Defragmentation error.", - self.manager.config.zid, - self.locator - ) - })?; - self.trigger_callback(msg, peer) - } else { - Ok(()) - } - } - FramePayload::Messages { mut messages } => { - for msg in messages.drain(..) { - self.trigger_callback(msg, peer)?; - } - Ok(()) - } - } - } - - pub(super) fn handle_join_from_peer( - &self, - join: Join, - peer: &TransportMulticastPeer, - ) -> ZResult<()> { - // Check if parameters are ok - if join.version != peer.version - || join.zid != peer.zid - || join.whatami != peer.whatami - || join.sn_resolution != peer.sn_resolution - || join.lease != peer.lease - || join.is_qos() != peer.is_qos() - { - let e = format!( - "Ingoring Join on {} of peer: {}. Inconsistent parameters. Version", - peer.locator, peer.zid, - ); - log::debug!("{}", e); - bail!("{}", e); - } - - Ok(()) - } - - pub(super) fn handle_join_from_unknown(&self, join: Join, locator: &Locator) -> ZResult<()> { - if zread!(self.peers).len() >= self.manager.config.multicast.max_sessions { - log::debug!( - "Ingoring Join on {} from peer: {}. Max sessions reached: {}.", - locator, - join.zid, - self.manager.config.multicast.max_sessions, - ); - return Ok(()); - } - - if join.version != self.manager.config.version { - log::debug!( - "Ingoring Join on {} from peer: {}. Unsupported version: {}. Expected: {}.", - locator, - join.zid, - join.version, - self.manager.config.version, - ); - return Ok(()); - } - - if join.sn_resolution > self.manager.config.sn_resolution { - log::debug!( - "Ingoring Join on {} from peer: {}. Unsupported SN resolution: {}. Expected: <= {}.", - locator, - join.zid, - join.sn_resolution, - self.manager.config.sn_resolution, - ); - return Ok(()); - } - - if !self.manager.config.multicast.is_qos && join.is_qos() { - log::debug!( - "Ingoring Join on {} from peer: {}. QoS is not supported.", - locator, - join.zid, - ); - return Ok(()); - } - - let _ = self.new_peer(locator, join); - - Ok(()) - } - - pub(super) fn receive_message(&self, msg: TransportMessage, locator: &Locator) -> ZResult<()> { - // Process the received message - let r_guard = zread!(self.peers); - match r_guard.get(locator) { - Some(peer) => { - peer.active(); - - match msg.body { - TransportBody::Frame(Frame { - reliability, - sn, - payload, - qos, - }) => { - let priority = qos.priority(); - let c = if self.is_qos() { - &peer.conduit_rx[priority as usize] - } else if priority == Priority::default() { - &peer.conduit_rx[0] - } else { - bail!( - "Transport {}: {}. Unknown conduit {:?} from {}.", - self.manager.config.zid, - self.locator, - priority, - peer.locator - ); - }; - - let guard = match channel.reliability { - Reliability::Reliable => zlock!(c.reliable), - Reliability::BestEffort => zlock!(c.best_effort), - }; - self.handle_frame(sn, payload, guard, peer) - } - TransportBody::Join(join) => self.handle_join_from_peer(join, peer), - TransportBody::Close(close) => { - drop(r_guard); - self.del_peer(locator, close.reason) - } - _ => Ok(()), - } - } - None => { - drop(r_guard); - match msg.body { - TransportBody::Join(join) => self.handle_join_from_unknown(join, locator), - _ => Ok(()), - } - } - } - } -} diff --git a/io/zenoh-transport/src/multicast/transport.rs b/io/zenoh-transport/src/multicast/transport.rs deleted file mode 100644 index 9ac18b4f9e..0000000000 --- a/io/zenoh-transport/src/multicast/transport.rs +++ /dev/null @@ -1,464 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::common::conduit::{TransportConduitRx, TransportConduitTx}; -use super::link::{TransportLinkMulticast, TransportLinkMulticastConfig}; -#[cfg(feature = "stats")] -use super::TransportMulticastStatsAtomic; -use crate::{ - TransportManager, TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, -}; -use async_trait::async_trait; -use std::{ - collections::HashMap, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, RwLock, - }, - time::Duration, -}; -use zenoh_core::{zread, zwrite}; -use zenoh_link::{Link, LinkMulticast, Locator}; -use zenoh_protocol::{ - core::{Priority, WhatAmI, ZInt, ZenohId}, - transport::{tmsg, ConduitSnList, Join, TransportMessage}, - zenoh::ZenohMessage, -}; -use zenoh_result::{bail, ZResult}; -use zenoh_util::{Timed, TimedEvent, TimedHandle, Timer}; - -/*************************************/ -/* TRANSPORT */ -/*************************************/ -#[derive(Clone)] -pub(super) struct TransportMulticastPeer { - pub(super) version: u8, - pub(super) locator: Locator, - pub(super) zid: ZenohId, - pub(super) whatami: WhatAmI, - pub(super) sn_resolution: ZInt, - pub(super) lease: Duration, - pub(super) whatchdog: Arc, - pub(super) handle: TimedHandle, - pub(super) conduit_rx: Box<[TransportConduitRx]>, - pub(super) handler: Arc, -} - -impl TransportMulticastPeer { - pub(super) fn active(&self) { - self.whatchdog.store(true, Ordering::Release); - } - - pub(super) fn is_qos(&self) -> bool { - self.conduit_rx.len() == Priority::NUM - } -} - -#[derive(Clone)] -pub(super) struct TransportMulticastPeerLeaseTimer { - pub(super) whatchdog: Arc, - locator: Locator, - transport: TransportMulticastInner, -} - -#[async_trait] -impl Timed for TransportMulticastPeerLeaseTimer { - async fn run(&mut self) { - let is_active = self.whatchdog.swap(false, Ordering::AcqRel); - if !is_active { - let _ = self - .transport - .del_peer(&self.locator, close::reason::EXPIRED); - } - } -} - -#[derive(Clone)] -pub(crate) struct TransportMulticastInner { - // The manager this channel is associated to - pub(super) manager: TransportManager, - // The multicast locator - pub(super) locator: Locator, - // Tx conduits - pub(super) conduit_tx: Arc<[TransportConduitTx]>, - // Remote peers - pub(super) peers: Arc>>, - // The multicast link - pub(super) link: Arc>>, - // The callback - pub(super) callback: Arc>>>, - // The timer for peer leases - pub(super) timer: Arc, - // Transport statistics - #[cfg(feature = "stats")] - pub(super) stats: Arc, -} - -pub(crate) struct TransportMulticastConfig { - pub(crate) manager: TransportManager, - pub(crate) initial_sns: ConduitSnList, - pub(crate) link: LinkMulticast, -} - -impl TransportMulticastInner { - pub(super) fn make(config: TransportMulticastConfig) -> ZResult { - let mut conduit_tx = vec![]; - - match config.initial_sns { - ConduitSnList::Plain(sn) => { - let tct = TransportConduitTx::make(config.manager.config.sn_resolution)?; - tct.sync(sn)?; - conduit_tx.push(tct); - } - ConduitSnList::QoS(sns) => { - for (_, sn) in sns.iter().enumerate() { - let tct = TransportConduitTx::make(config.manager.config.sn_resolution)?; - tct.sync(*sn)?; - conduit_tx.push(tct); - } - } - } - - let ti = TransportMulticastInner { - manager: config.manager, - locator: config.link.get_dst().to_owned(), - conduit_tx: conduit_tx.into_boxed_slice().into(), - peers: Arc::new(RwLock::new(HashMap::new())), - link: Arc::new(RwLock::new(None)), - callback: Arc::new(RwLock::new(None)), - timer: Arc::new(Timer::new(false)), - #[cfg(feature = "stats")] - stats: Arc::new(TransportMulticastStatsAtomic::default()), - }; - - let mut w_guard = zwrite!(ti.link); - *w_guard = Some(TransportLinkMulticast::new(ti.clone(), config.link)); - drop(w_guard); - - Ok(ti) - } - - pub(super) fn set_callback(&self, callback: Arc) { - let mut guard = zwrite!(self.callback); - *guard = Some(callback); - } - - /*************************************/ - /* ACCESSORS */ - /*************************************/ - pub(crate) fn get_sn_resolution(&self) -> ZInt { - self.manager.config.sn_resolution - } - - pub(crate) fn is_qos(&self) -> bool { - self.conduit_tx.len() > 1 - } - - pub(crate) fn is_shm(&self) -> bool { - false - } - - pub(crate) fn get_callback(&self) -> Option> { - zread!(self.callback).clone() - } - - pub(crate) fn get_link(&self) -> LinkMulticast { - zread!(self.link).as_ref().unwrap().link.clone() - } - - /*************************************/ - /* TERMINATION */ - /*************************************/ - pub(super) async fn delete(&self) -> ZResult<()> { - log::debug!("Closing multicast transport on {}", self.locator); - - // Notify the callback that we are going to close the transport - let callback = zwrite!(self.callback).take(); - if let Some(cb) = callback.as_ref() { - cb.closing(); - } - - // Delete the transport on the manager - let _ = self.manager.del_transport_multicast(&self.locator); - - // Close all the links - let mut link = zwrite!(self.link).take(); - if let Some(l) = link.take() { - let _ = l.close().await; - } - - // Notify the callback that we have closed the transport - if let Some(cb) = callback.as_ref() { - cb.closed(); - } - - Ok(()) - } - - pub(crate) async fn close(&self, reason: u8) -> ZResult<()> { - log::trace!( - "Closing multicast transport of peer {}: {}", - self.manager.config.zid, - self.locator - ); - - let pipeline = zread!(self.link) - .as_ref() - .unwrap() - .pipeline - .as_ref() - .unwrap() - .clone(); - - // Close message to be sent on all the links - let peer_id = Some(self.manager.zid()); - let reason_id = reason; - // link_only should always be false for user-triggered close. However, in case of - // multiple links, it is safer to close all the links first. When no links are left, - // the transport is then considered closed. - let link_only = true; - let attachment = None; // No attachment here - let msg = TransportMessage::make_close(peer_id, reason_id, link_only, attachment); - - pipeline.push_transport_message(msg, Priority::Background); - - // Terminate and clean up the transport - self.delete().await - } - - /*************************************/ - /* SCHEDULE AND SEND TX */ - /*************************************/ - /// Schedule a Zenoh message on the transmission queue - #[allow(unused_mut)] // Required with "shared-memory" feature - pub(crate) fn schedule(&self, mut msg: ZenohMessage) { - // Multicast transports do not support SHM for the time being - #[cfg(feature = "shared-memory")] - { - let res = crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.shmr); - if let Err(e) = res { - log::trace!("Failed SHM conversion: {}", e); - return; - } - } - self.schedule_first_fit(msg); - } - - /*************************************/ - /* LINK */ - /*************************************/ - pub(super) fn start_tx(&self, batch_size: u16) -> ZResult<()> { - let mut guard = zwrite!(self.link); - match guard.as_mut() { - Some(l) => { - assert!(!self.conduit_tx.is_empty()); - let config = TransportLinkMulticastConfig { - version: self.manager.config.version, - zid: self.manager.config.zid, - whatami: self.manager.config.whatami, - lease: self.manager.config.multicast.lease, - keep_alive: self.manager.config.multicast.keep_alive, - join_interval: self.manager.config.multicast.join_interval, - sn_resolution: self.manager.config.sn_resolution, - batch_size, - }; - l.start_tx(config, self.conduit_tx.clone()); - Ok(()) - } - None => { - bail!( - "Can not start multicast Link TX of peer {}: {}", - self.manager.config.zid, - self.locator - ) - } - } - } - - pub(super) fn stop_tx(&self) -> ZResult<()> { - let mut guard = zwrite!(self.link); - match guard.as_mut() { - Some(l) => { - l.stop_tx(); - Ok(()) - } - None => { - bail!( - "Can not stop multicast Link TX of peer {}: {}", - self.manager.config.zid, - self.locator - ) - } - } - } - - pub(super) fn start_rx(&self) -> ZResult<()> { - let mut guard = zwrite!(self.link); - match guard.as_mut() { - Some(l) => { - l.start_rx(); - Ok(()) - } - None => { - bail!( - "Can not start multicast Link RX of peer {}: {}", - self.manager.config.zid, - self.locator - ) - } - } - } - - pub(super) fn stop_rx(&self) -> ZResult<()> { - let mut guard = zwrite!(self.link); - match guard.as_mut() { - Some(l) => { - l.stop_rx(); - Ok(()) - } - None => { - bail!( - "Can not stop multicast Link RX of peer {}: {}", - self.manager.config.zid, - self.locator - ) - } - } - } - - /*************************************/ - /* PEER */ - /*************************************/ - pub(super) fn new_peer(&self, locator: &Locator, join: Join) -> ZResult<()> { - let mut link = Link::from(self.get_link()); - link.dst = locator.clone(); - - let peer = TransportPeer { - zid: join.zid, - whatami: join.whatami, - is_qos: join.is_qos(), - is_shm: self.is_shm(), - links: vec![link], - }; - - let handler = match zread!(self.callback).as_ref() { - Some(cb) => cb.new_peer(peer.clone())?, - None => return Ok(()), - }; - - let conduit_rx = match join.next_sns { - ConduitSnList::Plain(sn) => { - let tcr = TransportConduitRx::make( - join.sn_resolution, - self.manager.config.defrag_buff_size, - )?; - tcr.sync(sn)?; - vec![tcr] - } - ConduitSnList::QoS(ref sns) => { - let mut tcrs = Vec::with_capacity(sns.len()); - for (_, sn) in sns.iter().enumerate() { - let tcr = TransportConduitRx::make( - join.sn_resolution, - self.manager.config.defrag_buff_size, - )?; - tcr.sync(*sn)?; - tcrs.push(tcr); - } - tcrs - } - } - .into_boxed_slice(); - - // Create lease event - let whatchdog = Arc::new(AtomicBool::new(false)); - let event = TransportMulticastPeerLeaseTimer { - whatchdog: whatchdog.clone(), - locator: locator.clone(), - transport: self.clone(), - }; - let event = TimedEvent::periodic(join.lease, event); - let handle = event.get_handle(); - - // Store the new peer - let peer = TransportMulticastPeer { - version: join.version, - locator: locator.clone(), - zid: peer.zid, - whatami: peer.whatami, - sn_resolution: join.sn_resolution, - lease: join.lease, - whatchdog, - handle, - conduit_rx, - handler, - }; - { - zwrite!(self.peers).insert(locator.clone(), peer); - } - - // Add the event to the timer - self.timer.add(event); - - log::debug!( - "New transport joined on {}: zid {}, whatami {}, sn resolution {}, locator {}, qos {}, initial sn: {}", - self.locator, - join.zid, - join.whatami, - join.sn_resolution, - locator, - join.is_qos(), - join.next_sns, - ); - - Ok(()) - } - - pub(super) fn del_peer(&self, locator: &Locator, reason: u8) -> ZResult<()> { - let mut guard = zwrite!(self.peers); - if let Some(peer) = guard.remove(locator) { - log::debug!( - "Peer {}/{}/{} has left multicast {} with reason: {}", - peer.zid, - peer.whatami, - locator, - self.locator, - reason - ); - peer.handle.clone().defuse(); - - peer.handler.closing(); - drop(guard); - peer.handler.closed(); - } - Ok(()) - } - - pub(super) fn get_peers(&self) -> Vec { - zread!(self.peers) - .values() - .map(|p| { - let mut link = Link::from(self.get_link()); - link.dst = p.locator.clone(); - - TransportPeer { - zid: p.zid, - whatami: p.whatami, - is_qos: p.is_qos(), - is_shm: self.is_shm(), - links: vec![link], - } - }) - .collect() - } -} diff --git a/io/zenoh-transport/src/multicast/tx.rs b/io/zenoh-transport/src/multicast/tx.rs deleted file mode 100644 index 28bca36d4b..0000000000 --- a/io/zenoh-transport/src/multicast/tx.rs +++ /dev/null @@ -1,91 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::transport::TransportMulticastInner; -use zenoh_core::zread; -#[cfg(feature = "stats")] -use zenoh_protocol::zenoh::ZenohBody; -use zenoh_protocol::zenoh::ZenohMessage; - -//noinspection ALL -impl TransportMulticastInner { - fn schedule_on_link(&self, msg: ZenohMessage) -> bool { - macro_rules! zpush { - ($guard:expr, $pipeline:expr, $msg:expr) => { - // Drop the guard before the push_zenoh_message since - // the link could be congested and this operation could - // block for fairly long time - let pl = $pipeline.clone(); - drop($guard); - return pl.push_zenoh_message($msg); - }; - } - - let guard = zread!(self.link); - match guard.as_ref() { - Some(l) => { - if let Some(pl) = l.pipeline.as_ref() { - zpush!(guard, pl, msg); - } - } - None => { - log::trace!( - "Message dropped because the transport has no links: {}", - msg - ); - } - } - - false - } - - #[allow(clippy::let_and_return)] // When feature "stats" is not enabled - #[inline(always)] - pub(super) fn schedule_first_fit(&self, msg: ZenohMessage) -> bool { - #[cfg(feature = "stats")] - use zenoh_buffers::SplitBuffer; - #[cfg(feature = "stats")] - match &msg.body { - ZenohBody::Data(data) => match data.reply_context { - Some(_) => { - self.stats.inc_tx_z_data_reply_msgs(1); - self.stats - .inc_tx_z_data_reply_payload_bytes(data.payload.len()); - } - None => { - self.stats.inc_tx_z_data_msgs(1); - self.stats.inc_tx_z_data_payload_bytes(data.payload.len()); - } - }, - ZenohBody::Unit(unit) => match unit.reply_context { - Some(_) => self.stats.inc_tx_z_unit_reply_msgs(1), - None => self.stats.inc_tx_z_unit_msgs(1), - }, - ZenohBody::Pull(_) => self.stats.inc_tx_z_pull_msgs(1), - ZenohBody::Query(_) => self.stats.inc_tx_z_query_msgs(1), - ZenohBody::Declare(_) => self.stats.inc_tx_z_declare_msgs(1), - ZenohBody::LinkStateList(_) => self.stats.inc_tx_z_linkstate_msgs(1), - } - - let res = self.schedule_on_link(msg); - - #[cfg(feature = "stats")] - if res { - self.stats.inc_tx_z_msgs(1); - } else { - self.stats.inc_tx_z_dropped(1); - } - - res - } -} diff --git a/io/zenoh-transport/tests/endpoints.rs b/io/zenoh-transport/tests/endpoints.rs index ebe61f9feb..e921e96338 100644 --- a/io/zenoh-transport/tests/endpoints.rs +++ b/io/zenoh-transport/tests/endpoints.rs @@ -21,8 +21,8 @@ use zenoh_protocol::{ }; use zenoh_result::ZResult; use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportMulticast, TransportMulticastEventHandler, - TransportPeer, TransportPeerEventHandler, TransportUnicast, + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, }; const TIMEOUT: Duration = Duration::from_secs(60); @@ -49,13 +49,6 @@ impl TransportEventHandler for SH { let arc = Arc::new(SC::default()); Ok(arc) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } // Transport Callback for the router diff --git a/io/zenoh-transport/tests/multicast_transport.rs b/io/zenoh-transport/tests/multicast_transport.rs deleted file mode 100644 index cbc1738f8a..0000000000 --- a/io/zenoh-transport/tests/multicast_transport.rs +++ /dev/null @@ -1,338 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// - -// Restricting to macos by default because of no IPv6 support -// on GitHub CI actions on Linux and Windows. -#[cfg(target_os = "macos")] -mod tests { - use async_std::prelude::FutureExt; - use async_std::task; - use std::any::Any; - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::sync::Arc; - use std::time::Duration; - use zenoh_buffers::ZBuf; - use zenoh_cfg_properties::config::*; - use zenoh_core::zasync_executor_init; - use zenoh_link::Link; - use zenoh_protocol::{ - core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, - zenoh::ZenohMessage, - }; - use zenoh_result::ZResult; - use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportMulticast, - TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, - }; - - const TIMEOUT: Duration = Duration::from_secs(60); - const SLEEP: Duration = Duration::from_secs(1); - const SLEEP_COUNT: Duration = Duration::from_millis(10); - - const MSG_COUNT: usize = 1_000; - const MSG_SIZE_NOFRAG: [usize; 1] = [1_024]; - - macro_rules! ztimeout { - ($f:expr) => { - $f.timeout(TIMEOUT).await.unwrap() - }; - } - - // Transport Handler for the peer02 - struct SHPeer { - count: Arc, - } - - impl Default for SHPeer { - fn default() -> Self { - Self { - count: Arc::new(AtomicUsize::new(0)), - } - } - } - - impl SHPeer { - fn get_count(&self) -> usize { - self.count.load(Ordering::SeqCst) - } - } - - impl TransportEventHandler for SHPeer { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - panic!(); - } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - let arc = Arc::new(SCPeer::new(self.count.clone())); - Ok(arc) - } - } - - // Transport Callback for the peer02 - pub struct SCPeer { - count: Arc, - } - - impl SCPeer { - pub fn new(count: Arc) -> Self { - Self { count } - } - } - - impl TransportMulticastEventHandler for SCPeer { - fn new_peer(&self, _peer: TransportPeer) -> ZResult> { - Ok(Arc::new(SCPeer { - count: self.count.clone(), - })) - } - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } - } - - impl TransportPeerEventHandler for SCPeer { - fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { - self.count.fetch_add(1, Ordering::SeqCst); - Ok(()) - } - - fn new_link(&self, _link: Link) {} - fn del_link(&self, _link: Link) {} - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } - } - - struct TransportMulticastPeer { - manager: TransportManager, - handler: Arc, - transport: TransportMulticast, - } - - async fn open_transport( - endpoint: &EndPoint, - ) -> (TransportMulticastPeer, TransportMulticastPeer) { - use std::convert::TryFrom; - // Define peer01 and peer02 IDs - let peer01_id = ZenohId::try_from([1]).unwrap(); - let peer02_id = ZenohId::try_from([2]).unwrap(); - - // Create the peer01 transport manager - let peer01_handler = Arc::new(SHPeer::default()); - let peer01_manager = TransportManager::builder() - .zid(peer01_id) - .whatami(WhatAmI::Peer) - .build(peer01_handler.clone()) - .unwrap(); - - // Create the peer02 transport manager - let peer02_handler = Arc::new(SHPeer::default()); - let peer02_manager = TransportManager::builder() - .whatami(WhatAmI::Peer) - .zid(peer02_id) - .build(peer02_handler.clone()) - .unwrap(); - - // Create an empty transport with the peer01 - // Open transport -> This should be accepted - println!("Opening transport with {endpoint}"); - let _ = ztimeout!(peer01_manager.open_transport_multicast(endpoint.clone())).unwrap(); - assert!(peer01_manager - .get_transport_multicast(&endpoint.to_locator()) - .is_some()); - println!("\t{:?}", peer01_manager.get_transports_multicast()); - - println!("Opening transport with {endpoint}"); - let _ = ztimeout!(peer02_manager.open_transport_multicast(endpoint.clone())).unwrap(); - assert!(peer02_manager - .get_transport_multicast(&endpoint.to_locator()) - .is_some()); - println!("\t{:?}", peer02_manager.get_transports_multicast()); - - // Wait to for peer 01 and 02 to join each other - let peer01_transport = peer01_manager - .get_transport_multicast(&endpoint.to_locator()) - .unwrap(); - ztimeout!(async { - while peer01_transport.get_peers().unwrap().is_empty() { - task::sleep(SLEEP_COUNT).await; - } - }); - - let peer02_transport = peer02_manager - .get_transport_multicast(&endpoint.to_locator()) - .unwrap(); - ztimeout!(async { - while peer02_transport.get_peers().unwrap().is_empty() { - task::sleep(SLEEP_COUNT).await; - } - }); - - ( - TransportMulticastPeer { - manager: peer01_manager, - handler: peer01_handler, - transport: peer01_transport, - }, - TransportMulticastPeer { - manager: peer02_manager, - handler: peer02_handler, - transport: peer02_transport, - }, - ) - } - - async fn close_transport( - peer01: TransportMulticastPeer, - peer02: TransportMulticastPeer, - endpoint: &EndPoint, - ) { - // Close the peer01 transport - println!("Closing transport with {endpoint}"); - ztimeout!(peer01.transport.close()).unwrap(); - assert!(peer01.manager.get_transports_multicast().is_empty()); - assert!(peer02.transport.get_peers().unwrap().is_empty()); - - // Close the peer02 transport - println!("Closing transport with {endpoint}"); - ztimeout!(peer02.transport.close()).unwrap(); - assert!(peer02.manager.get_transports_multicast().is_empty()); - - // Wait a little bit - task::sleep(SLEEP).await; - } - - async fn test_transport( - peer01: &TransportMulticastPeer, - peer02: &TransportMulticastPeer, - channel: Channel, - msg_size: usize, - ) { - // Create the message to send - let key = "test".into(); - let payload = ZBuf::from(vec![0_u8; msg_size]); - let data_info = None; - let routing_context = None; - let reply_context = None; - let attachment = None; - let message = ZenohMessage::make_data( - key, - payload, - channel, - CongestionControl::Block, - data_info, - routing_context, - reply_context, - attachment, - ); - - println!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); - for _ in 0..MSG_COUNT { - peer01.transport.schedule(message.clone()).unwrap(); - } - - match channel.reliability { - Reliability::Reliable => { - ztimeout!(async { - while peer02.handler.get_count() != MSG_COUNT { - task::sleep(SLEEP_COUNT).await; - } - }); - } - Reliability::BestEffort => { - ztimeout!(async { - while peer02.handler.get_count() == 0 { - task::sleep(SLEEP_COUNT).await; - } - }); - } - }; - - // Wait a little bit - task::sleep(SLEEP).await; - } - - async fn run_single(endpoint: &EndPoint, channel: Channel, msg_size: usize) { - let (peer01, peer02) = open_transport(endpoint).await; - test_transport(&peer01, &peer02, channel, msg_size).await; - - #[cfg(feature = "stats")] - { - let stats = peer01.transport.get_stats().unwrap(); - println!("\tPeer 01: {:?}", stats); - let stats = peer02.transport.get_stats().unwrap(); - println!("\tPeer 02: {:?}", stats); - } - - close_transport(peer01, peer02, endpoint).await; - } - - async fn run(endpoints: &[EndPoint], channel: &[Channel], msg_size: &[usize]) { - for e in endpoints.iter() { - for ch in channel.iter() { - for ms in msg_size.iter() { - run_single(e, *ch, *ms).await; - } - } - } - } - - #[cfg(feature = "transport_udp")] - #[test] - fn transport_multicast_udp_only() { - env_logger::init(); - - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locator - let endpoints: Vec = vec![ - format!("udp/{ZN_MULTICAST_IPV4_ADDRESS_DEFAULT}") - .parse() - .unwrap(), - // Disabling by default because of no IPv6 support - // on GitHub CI actions. - // format!("udp/{}", ZN_MULTICAST_IPV6_ADDRESS_DEFAULT) - // .parse() - // .unwrap(), - ]; - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(run(&endpoints, &channel, &MSG_SIZE_NOFRAG)); - } -} diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index f963834a84..de657a6668 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -31,8 +31,8 @@ use zenoh_transport::unicast::establishment::authenticator::SharedMemoryAuthenti #[cfg(feature = "auth_usrpwd")] use zenoh_transport::unicast::establishment::authenticator::UserPasswordAuthenticator; use zenoh_transport::{ - DummyTransportPeerEventHandler, TransportEventHandler, TransportMulticast, - TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, + DummyTransportPeerEventHandler, TransportEventHandler, TransportPeer, + TransportPeerEventHandler, TransportUnicast, }; const TIMEOUT: Duration = Duration::from_secs(60); @@ -61,13 +61,6 @@ impl TransportEventHandler for SHRouterAuthenticator { ) -> ZResult> { Ok(Arc::new(MHRouterAuthenticator::new())) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } struct MHRouterAuthenticator; @@ -104,13 +97,6 @@ impl TransportEventHandler for SHClientAuthenticator { ) -> ZResult> { Ok(Arc::new(DummyTransportPeerEventHandler::default())) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } #[cfg(feature = "auth_pubkey")] diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index fd449f5d90..e2207e33af 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -28,8 +28,8 @@ use zenoh_protocol::{ }; use zenoh_result::ZResult; use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportMulticast, TransportMulticastEventHandler, - TransportPeer, TransportPeerEventHandler, TransportUnicast, + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, }; const MSG_COUNT: usize = 1_000; @@ -69,13 +69,6 @@ impl TransportEventHandler for SHPeer { let mh = Arc::new(MHPeer::new(self.count.clone())); Ok(mh) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } struct MHPeer { @@ -194,7 +187,6 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec, endpoint02: Vec, endpoint02: Vec, endpoint02: Vec ZResult> { - panic!(); - } } // Transport Callback for the router @@ -139,13 +132,6 @@ impl TransportEventHandler for SHClient { ) -> ZResult> { Ok(Arc::new(SCClient::default())) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } // Transport Callback for the client @@ -272,7 +258,6 @@ async fn single_run( let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let message = ZenohMessage::make_data( key, payload, @@ -281,7 +266,6 @@ async fn single_run( data_info, routing_context, reply_context, - attachment, ); println!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index 6381d3025f..59e2c6d8aa 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -71,7 +71,6 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let message = ZenohMessage::make_data( key, payload, @@ -80,7 +79,6 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { data_info, routing_context, reply_context, - attachment, ); println!( diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index 8d98e3f3e2..7fa1a6569c 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -29,8 +29,8 @@ use zenoh_protocol::{ }; use zenoh_result::ZResult; use zenoh_transport::{ - DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportMulticast, - TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, + DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportPeer, + TransportPeerEventHandler, TransportUnicast, }; const MSG_SIZE: usize = 8; @@ -56,13 +56,6 @@ impl TransportEventHandler for SHRouterIntermittent { ) -> ZResult> { Ok(Arc::new(DummyTransportPeerEventHandler::default())) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } // Transport Handler for the intermittent clients @@ -77,13 +70,6 @@ impl TransportEventHandler for SHClientIntermittent { ) -> ZResult> { Ok(Arc::new(DummyTransportPeerEventHandler::default())) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } // Transport Handler for the stable client @@ -105,13 +91,6 @@ impl TransportEventHandler for SHClientStable { ) -> ZResult> { Ok(Arc::new(SCClient::new(self.counter.clone()))) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } // Transport Callback for the client @@ -276,7 +255,6 @@ async fn transport_intermittent(endpoint: &EndPoint) { let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let message = ZenohMessage::make_data( key, @@ -286,7 +264,6 @@ async fn transport_intermittent(endpoint: &EndPoint) { data_info, routing_context, reply_context, - attachment, ); let mut ticks: Vec = (0..=MSG_COUNT).step_by(MSG_COUNT / 10).collect(); diff --git a/io/zenoh-transport/tests/unicast_openclose.rs b/io/zenoh-transport/tests/unicast_openclose.rs index 773fb6168c..0d3494e8bf 100644 --- a/io/zenoh-transport/tests/unicast_openclose.rs +++ b/io/zenoh-transport/tests/unicast_openclose.rs @@ -18,8 +18,8 @@ use zenoh_link::EndPoint; use zenoh_protocol::core::{WhatAmI, ZenohId}; use zenoh_result::ZResult; use zenoh_transport::{ - DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportMulticast, - TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, + DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportPeer, + TransportPeerEventHandler, TransportUnicast, }; const TIMEOUT: Duration = Duration::from_secs(60); @@ -43,13 +43,6 @@ impl TransportEventHandler for SHRouterOpenClose { ) -> ZResult> { Ok(Arc::new(DummyTransportPeerEventHandler::default())) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } // Transport Handler for the client @@ -69,13 +62,6 @@ impl TransportEventHandler for SHClientOpenClose { ) -> ZResult> { Ok(Arc::new(DummyTransportPeerEventHandler::default())) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } async fn openclose_transport(endpoint: &EndPoint) { diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index 56f039ee04..ba16b1558e 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -36,8 +36,7 @@ mod tests { use zenoh_shm::SharedMemoryManager; use zenoh_transport::{ unicast::establishment::authenticator::SharedMemoryAuthenticator, TransportEventHandler, - TransportManager, TransportMulticast, TransportMulticastEventHandler, TransportPeer, - TransportPeerEventHandler, TransportUnicast, + TransportManager, TransportPeer, TransportPeerEventHandler, TransportUnicast, }; const TIMEOUT: Duration = Duration::from_secs(60); @@ -81,13 +80,6 @@ mod tests { let arc = Arc::new(SCPeer::new(self.count.clone(), self.is_shm)); Ok(arc) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } // Transport Callback for the peer @@ -231,7 +223,6 @@ mod tests { let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let message = ZenohMessage::make_data( key, @@ -241,7 +232,6 @@ mod tests { data_info, routing_context, reply_context, - attachment, ); peer_shm02_transport.schedule(message.clone()).unwrap(); @@ -284,7 +274,6 @@ mod tests { let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let message = ZenohMessage::make_data( key, @@ -294,7 +283,6 @@ mod tests { data_info, routing_context, reply_context, - attachment, ); peer_net01_transport.schedule(message.clone()).unwrap(); diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index 2ceef02955..7ae5ece988 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -81,7 +81,6 @@ mod tests { let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let message = ZenohMessage::make_data( key, @@ -91,7 +90,6 @@ mod tests { data_info, routing_context, reply_context, - attachment, ); println!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); @@ -103,13 +101,6 @@ mod tests { let mh = Arc::new(MHPeer::new(self.count.clone())); Ok(mh) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } struct MHPeer { diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 59a07a0754..2004abb6f9 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -249,13 +249,6 @@ impl TransportEventHandler for SHRouter { let arc = Arc::new(SCRouter::new(self.count.clone())); Ok(arc) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } // Transport Callback for the router @@ -297,13 +290,6 @@ impl TransportEventHandler for SHClient { ) -> ZResult> { Ok(Arc::new(SCClient::default())) } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - panic!(); - } } // Transport Callback for the client @@ -436,7 +422,6 @@ async fn test_transport( let data_info = None; let routing_context = None; let reply_context = None; - let attachment = None; let message = ZenohMessage::make_data( key, payload, @@ -445,7 +430,6 @@ async fn test_transport( data_info, routing_context, reply_context, - attachment, ); println!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index b55a74b40a..6024601bf3 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -242,14 +242,6 @@ impl TransportEventHandler for RuntimeTransportEventHandler { None => bail!("Runtime not yet ready!"), } } - - fn new_multicast( - &self, - _transport: TransportMulticast, - ) -> ZResult> { - // @TODO - unimplemented!(); - } } pub(super) struct RuntimeSession { From 44d7ad31d7958bb4c065afccd9b2a79912a75833 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 14:31:14 +0100 Subject: [PATCH 022/203] Incomplete reworking on transport --- .../src/unicast/establishment/accept/mod.rs | 2 +- .../src/unicast/establishment/cookie.rs | 22 +-- .../src/unicast/establishment/mod.rs | 15 +- .../src/unicast/establishment/open/mod.rs | 2 +- io/zenoh-transport/src/unicast/link.rs | 6 +- io/zenoh-transport/src/unicast/manager.rs | 50 +----- io/zenoh-transport/src/unicast/mod.rs | 2 + io/zenoh-transport/src/unicast/rx.rs | 156 ++++++++++-------- io/zenoh-transport/src/unicast/transport.rs | 48 +++--- 9 files changed, 139 insertions(+), 164 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs index 7e1a70ce0a..f434ca9f20 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs @@ -22,7 +22,7 @@ use crate::unicast::establishment::{ }; use crate::TransportManager; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; -use zenoh_protocol::transport::tmsg; +use zenoh_protocol::transport::close; use zenoh_result::ZResult; pub(super) type AError = (zenoh_result::Error, Option); diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index f64c462280..17eedf8381 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::properties::EstablishmentProperties; +// use super::properties::EstablishmentProperties; use std::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, HasReader, Reader}, @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_crypto::{BlockCipher, PseudoRng}; -use zenoh_protocol::core::{Property, WhatAmI, ZInt, ZenohId}; +use zenoh_protocol::core::{WhatAmI, ZInt, ZenohId}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct Cookie { @@ -28,7 +28,7 @@ pub struct Cookie { pub sn_resolution: ZInt, pub is_qos: bool, pub nonce: ZInt, - pub properties: EstablishmentProperties, + // pub properties: EstablishmentProperties, // @TODO } impl WCodec<&Cookie, &mut W> for Zenoh080 @@ -45,7 +45,7 @@ where let is_qos = u8::from(x.is_qos); self.write(&mut *writer, is_qos)?; self.write(&mut *writer, x.nonce)?; - self.write(&mut *writer, x.properties.as_slice())?; + // self.write(&mut *writer, x.properties.as_slice())?; Ok(()) } @@ -65,11 +65,11 @@ where let is_qos: u8 = self.read(&mut *reader)?; let is_qos = is_qos == 1; let nonce: ZInt = self.read(&mut *reader)?; - let mut ps: Vec = self.read(&mut *reader)?; - let mut properties = EstablishmentProperties::new(); - for p in ps.drain(..) { - properties.insert(p).map_err(|_| DidntRead)?; - } + // let mut ps: Vec = self.read(&mut *reader)?; + // let mut properties = EstablishmentProperties::new(); + // for p in ps.drain(..) { + // properties.insert(p).map_err(|_| DidntRead)?; + // } let cookie = Cookie { whatami, @@ -77,7 +77,7 @@ where sn_resolution, is_qos, nonce, - properties, + // properties, }; Ok(cookie) @@ -139,7 +139,7 @@ impl Cookie { sn_resolution: rng.gen(), is_qos: rng.gen_bool(0.5), nonce: rng.gen(), - properties: EstablishmentProperties::rand(), + // properties: EstablishmentProperties::rand(), } } } diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 187666c71f..bac955c155 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -15,20 +15,20 @@ pub(crate) mod accept; pub mod authenticator; pub(super) mod cookie; pub(crate) mod open; -pub(super) mod properties; +// pub(super) mod properties; use super::super::TransportManager; use super::{TransportConfigUnicast, TransportPeer, TransportUnicast}; use authenticator::AuthenticatedPeerLink; use cookie::*; -use properties::*; +// use properties::*; use rand::Rng; use std::time::Duration; use zenoh_core::{zasynclock, zasyncread}; use zenoh_link::{Link, LinkUnicast}; use zenoh_protocol::{ core::{WhatAmI, ZInt, ZenohId}, - transport::TransportMessage, + transport::{Close, TransportMessage}, }; use zenoh_result::ZResult; @@ -40,10 +40,11 @@ pub(super) async fn close_link( ) { if let Some(reason) = reason.take() { // Build the close message - let peer_id = Some(manager.config.zid); - let link_only = true; - let attachment = None; - let message = TransportMessage::make_close(peer_id, reason, link_only, attachment); + let message: TransportMessage = Close { + reason, + session: false, + } + .into(); // Send the close message on the link let _ = link.write_transport_message(&message).await; } diff --git a/io/zenoh-transport/src/unicast/establishment/open/mod.rs b/io/zenoh-transport/src/unicast/establishment/open/mod.rs index 7f2d8a61ed..6367658a0d 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/mod.rs @@ -20,7 +20,7 @@ use super::authenticator::AuthenticatedPeerLink; use crate::unicast::establishment::{close_link, transport_finalize, InputFinalize, InputInit}; use crate::{TransportManager, TransportUnicast}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; -use zenoh_protocol::transport::tmsg; +use zenoh_protocol::transport::close; use zenoh_result::ZResult; type OError = (zenoh_result::Error, Option); diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/link.rs index 8761e88364..60a22ac0e8 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/link.rs @@ -29,7 +29,7 @@ use zenoh_buffers::reader::{HasReader, Reader}; use zenoh_buffers::ZSlice; use zenoh_codec::{RCodec, Zenoh080}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; -use zenoh_protocol::transport::TransportMessage; +use zenoh_protocol::transport::{KeepAlive, TransportMessage}; use zenoh_result::{bail, zerror, ZResult}; use zenoh_sync::{RecyclingObjectPool, Signal}; @@ -198,9 +198,7 @@ async fn tx_task( None => break, }, Err(_) => { - let zid = None; - let attachment = None; - let message = TransportMessage::make_keep_alive(zid, attachment); + let message: TransportMessage = KeepAlive.into(); #[allow(unused_variables)] // Used when stats feature is enabled let n = link.write_transport_message(&message).await?; diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 48fc69e9c4..b46427dd9d 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -29,7 +29,7 @@ use zenoh_core::{zasynclock, zasyncread, zasyncwrite, zlock, zparse}; use zenoh_link::*; use zenoh_protocol::{ core::{locator::LocatorProtocol, ZenohId}, - transport::tmsg, + transport::close, }; use zenoh_result::{bail, zerror, ZResult}; @@ -53,8 +53,6 @@ pub struct TransportManagerStateUnicast { pub(super) incoming: Arc>, // Active peer authenticators pub(super) peer_authenticator: Arc>>, - // Active link authenticators - pub(super) link_authenticator: Arc>>, // Established listeners pub(super) protocols: Arc>>, // Established transports @@ -82,7 +80,6 @@ pub struct TransportManagerBuilderUnicast { #[cfg(feature = "shared-memory")] pub(super) is_shm: bool, pub(super) peer_authenticator: HashSet, - pub(super) link_authenticator: HashSet, } impl TransportManagerBuilderUnicast { @@ -121,11 +118,6 @@ impl TransportManagerBuilderUnicast { self } - pub fn link_authenticator(mut self, link_authenticator: HashSet) -> Self { - self.link_authenticator = link_authenticator; - self - } - pub fn qos(mut self, is_qos: bool) -> Self { self.is_qos = is_qos; self @@ -155,7 +147,6 @@ impl TransportManagerBuilderUnicast { self = self.shm(*config.transport().shared_memory().enabled()); } self = self.peer_authenticator(PeerAuthenticator::from_config(config).await?); - self = self.link_authenticator(LinkAuthenticator::from_config(config).await?); Ok(self) } @@ -202,7 +193,6 @@ impl TransportManagerBuilderUnicast { incoming: Arc::new(AsyncMutex::new(0)), protocols: Arc::new(Mutex::new(HashMap::new())), transports: Arc::new(Mutex::new(HashMap::new())), - link_authenticator: Arc::new(AsyncRwLock::new(self.link_authenticator)), peer_authenticator: Arc::new(AsyncRwLock::new(self.peer_authenticator)), }; @@ -225,7 +215,6 @@ impl Default for TransportManagerBuilderUnicast { #[cfg(feature = "shared-memory")] is_shm: zparse!(ZN_SHM_DEFAULT).unwrap(), peer_authenticator: HashSet::new(), - link_authenticator: HashSet::new(), } } } @@ -241,13 +230,8 @@ impl TransportManager { pub async fn close_unicast(&self) { log::trace!("TransportManagerUnicast::clear())"); - let mut la_guard = zasyncwrite!(self.state.unicast.link_authenticator); let mut pa_guard = zasyncwrite!(self.state.unicast.peer_authenticator); - for la in la_guard.drain() { - la.close().await; - } - for pa in pa_guard.drain() { pa.close().await; } @@ -526,43 +510,13 @@ impl TransportManager { *guard += 1; drop(guard); - let mut peer_id: Option = None; - let peer_link = Link::from(&link); - for la in zasyncread!(self.state.unicast.link_authenticator).iter() { - let res = la.handle_new_link(&peer_link).await; - match res { - Ok(zid) => { - // Check that all the peer authenticators, eventually return the same ZenohId - if let Some(zid1) = peer_id.as_ref() { - if let Some(zid2) = zid.as_ref() { - if zid1 != zid2 { - log::debug!("Ambigous PeerID identification for link: {}", link); - let _ = link.close().await; - let mut guard = zasynclock!(self.state.unicast.incoming); - *guard -= 1; - return; - } - } - } else { - peer_id = zid; - } - } - Err(e) => { - log::debug!("{}", e); - let mut guard = zasynclock!(self.state.unicast.incoming); - *guard -= 1; - return; - } - } - } - // Spawn a task to accept the link let c_manager = self.clone(); task::spawn(async move { let mut auth_link = AuthenticatedPeerLink { src: link.get_src().to_owned(), dst: link.get_dst().to_owned(), - peer_id, + peer_id: None, }; if let Err(e) = diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 3c33fec7af..6abe17e79a 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -15,6 +15,8 @@ pub mod establishment; pub(crate) mod link; pub(crate) mod manager; pub(crate) mod rx; +#[cfg(feature = "shared-memory")] +pub(crate) mod shm; pub(crate) mod transport; pub(crate) mod tx; diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index db000804ed..9caadd164a 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -17,13 +17,15 @@ use async_std::task; use std::sync::MutexGuard; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; +use zenoh_buffers::ZSlice; +use zenoh_collections::SingleOrVec; use zenoh_core::{zlock, zread}; use zenoh_link::LinkUnicast; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::{ - core::{Priority, Reliability, ZInt, ZenohId}, - transport::{tmsg, Close, Frame, FramePayload, KeepAlive, TransportBody, TransportMessage}, + core::{Priority, Reliability, ZInt}, + transport::{Close, Fragment, Frame, KeepAlive, TransportBody, TransportMessage}, zenoh::ZenohMessage, }; use zenoh_result::{bail, zerror, ZResult}; @@ -65,10 +67,10 @@ impl TransportUnicastInner { let callback = zread!(self.callback).clone(); if let Some(callback) = callback.as_ref() { - #[cfg(feature = "shared-memory")] - { - crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.config.manager.shmr)?; - } + // #[cfg(feature = "shared-memory")] + // { + // crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.config.manager.shmr)?; + // } @TODO callback.handle_message(msg) } else { log::debug!( @@ -80,26 +82,7 @@ impl TransportUnicastInner { } } - fn handle_close( - &self, - link: &LinkUnicast, - zid: Option, - reason: u8, - link_only: bool, - ) -> ZResult<()> { - // Check if the PID is correct when provided - if let Some(zid) = zid { - if zid != self.config.zid { - log::debug!( - "Received an invalid Close on link {} from peer {} with reason: {}. Ignoring.", - link, - zid, - close::reason_to_str(reason), - ); - return Ok(()); - } - } - + fn handle_close(&self, link: &LinkUnicast, reason: u8, session: bool) -> ZResult<()> { // Stop now rx and tx tasks before doing the proper cleanup let _ = self.stop_rx(link); let _ = self.stop_tx(link); @@ -110,10 +93,10 @@ impl TransportUnicastInner { // Spawn a task to avoid a deadlock waiting for this same task // to finish in the link close() joining the rx handle task::spawn(async move { - if link_only { - let _ = c_transport.del_link(&c_link).await; - } else { + if session { let _ = c_transport.delete().await; + } else { + let _ = c_transport.del_link(&c_link).await; } }); @@ -121,11 +104,40 @@ impl TransportUnicastInner { } fn handle_frame( + &self, + payload: SingleOrVec, + mut guard: MutexGuard<'_, TransportChannelRx>, + ) -> ZResult<()> { + for msg in payload.into_iter() { + self.trigger_callback(msg)?; + } + Ok(()) + } + + fn handle_fragment( &self, sn: ZInt, - payload: FramePayload, + more: bool, + payload: ZSlice, mut guard: MutexGuard<'_, TransportChannelRx>, ) -> ZResult<()> { + if guard.defrag.is_empty() { + let _ = guard.defrag.sync(sn); + } + guard.defrag.push(sn, payload)?; + if !more { + // When shared-memory feature is disabled, msg does not need to be mutable + let msg = guard + .defrag + .defragment() + .ok_or_else(|| zerror!("Transport: {}. Defragmentation error.", self.config.zid))?; + return self.trigger_callback(msg); + } + + Ok(()) + } + + fn verify_sn(&self, sn: ZInt, guard: &mut MutexGuard<'_, TransportChannelRx>) -> ZResult<()> { let precedes = guard.sn.precedes(sn)?; if !precedes { log::debug!( @@ -145,29 +157,8 @@ impl TransportUnicastInner { // Set will always return OK because we have already checked // with precedes() that the sn has the right resolution let _ = guard.sn.set(sn); - match payload { - FramePayload::Fragment { buffer, is_final } => { - if guard.defrag.is_empty() { - let _ = guard.defrag.sync(sn); - } - guard.defrag.push(sn, buffer)?; - if is_final { - // When shared-memory feature is disabled, msg does not need to be mutable - let msg = guard.defrag.defragment().ok_or_else(|| { - zerror!("Transport: {}. Defragmentation error.", self.config.zid) - })?; - self.trigger_callback(msg) - } else { - Ok(()) - } - } - FramePayload::Messages { mut messages } => { - for msg in messages.drain(..) { - self.trigger_callback(msg)?; - } - Ok(()) - } - } + + Ok(()) } pub(super) fn receive_message(&self, msg: TransportMessage, link: &LinkUnicast) -> ZResult<()> { @@ -175,34 +166,63 @@ impl TransportUnicastInner { // Process the received message match msg.body { TransportBody::Frame(Frame { - channel, + reliability, sn, payload, + qos, }) => { + let priority = qos.priority(); let c = if self.is_qos() { - &self.conduit_rx[channel.priority as usize] - } else if channel.priority == Priority::default() { + &self.conduit_rx[priority as usize] + } else if priority == Priority::default() { &self.conduit_rx[0] } else { bail!( "Transport: {}. Unknown conduit: {:?}.", self.config.zid, - channel.priority + priority ); }; - match channel.reliability { - Reliability::Reliable => self.handle_frame(sn, payload, zlock!(c.reliable)), - Reliability::BestEffort => { - self.handle_frame(sn, payload, zlock!(c.best_effort)) - } - } + let mut guard = match reliability { + Reliability::Reliable => zlock!(c.reliable), + Reliability::BestEffort => zlock!(c.best_effort), + }; + + self.verify_sn(sn, &mut guard)?; + self.handle_frame(payload, guard) + } + TransportBody::Fragment(Fragment { + reliability, + more, + sn, + payload, + qos, + }) => { + let priority = qos.priority(); + let c = if self.is_qos() { + &self.conduit_rx[priority as usize] + } else if priority == Priority::default() { + &self.conduit_rx[0] + } else { + bail!( + "Transport: {}. Unknown conduit: {:?}.", + self.config.zid, + priority + ); + }; + + let mut guard = match reliability { + Reliability::Reliable => zlock!(c.reliable), + Reliability::BestEffort => zlock!(c.best_effort), + }; + + self.verify_sn(sn, &mut guard)?; + self.handle_fragment(sn, more, payload, guard) + } + TransportBody::Close(Close { reason, session }) => { + self.handle_close(link, reason, session) } - TransportBody::Close(Close { - zid, - reason, - link_only, - }) => self.handle_close(link, zid, reason, link_only), TransportBody::KeepAlive(KeepAlive { .. }) => Ok(()), _ => { log::debug!( diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index aeb6058d6b..1488ff164e 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -23,7 +23,7 @@ use zenoh_core::{zasynclock, zread, zwrite}; use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ core::{Priority, WhatAmI, ZInt, ZenohId}, - transport::{ConduitSn, TransportMessage}, + transport::{Close, ConduitSn, TransportMessage}, zenoh::ZenohMessage, }; use zenoh_result::{bail, zerror, ZResult}; @@ -398,11 +398,11 @@ impl TransportUnicastInner { if let Some(p) = pipeline.take() { // Close message to be sent on the target link - let peer_id = Some(self.config.manager.zid()); - let reason_id = reason; - let link_only = true; // This is should always be true when closing a link - let attachment = None; // No attachment here - let msg = TransportMessage::make_close(peer_id, reason_id, link_only, attachment); + let msg: TransportMessage = Close { + reason, + session: false, + } + .into(); p.push_transport_message(msg, Priority::Background); } @@ -420,14 +420,14 @@ impl TransportUnicastInner { .collect::>(); for p in pipelines.drain(..) { // Close message to be sent on all the links - let peer_id = Some(self.config.manager.zid()); - let reason_id = reason; - // link_only should always be false for user-triggered close. However, in case of + // session should always be true for user-triggered close. However, in case of // multiple links, it is safer to close all the links first. When no links are left, // the transport is then considered closed. - let link_only = true; - let attachment = None; // No attachment here - let msg = TransportMessage::make_close(peer_id, reason_id, link_only, attachment); + let msg: TransportMessage = Close { + reason, + session: false, + } + .into(); p.push_transport_message(msg, Priority::Background); } @@ -440,18 +440,18 @@ impl TransportUnicastInner { /*************************************/ /// Schedule a Zenoh message on the transmission queue pub(crate) fn schedule(&self, #[allow(unused_mut)] mut message: ZenohMessage) -> bool { - #[cfg(feature = "shared-memory")] - { - let res = if self.config.is_shm { - crate::shm::map_zmsg_to_shminfo(&mut message) - } else { - crate::shm::map_zmsg_to_shmbuf(&mut message, &self.config.manager.shmr) - }; - if let Err(e) = res { - log::trace!("Failed SHM conversion: {}", e); - return false; - } - } + // #[cfg(feature = "shared-memory")] + // { + // let res = if self.config.is_shm { + // crate::shm::map_zmsg_to_shminfo(&mut message) + // } else { + // crate::shm::map_zmsg_to_shmbuf(&mut message, &self.config.manager.shmr) + // }; + // if let Err(e) = res { + // log::trace!("Failed SHM conversion: {}", e); + // return false; + // } + // } // @TODO self.schedule_first_fit(message) } From 1efbcfcdfb0698df8e35ba54e64df4994e131d34 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 17:57:51 +0100 Subject: [PATCH 023/203] Working non-fragemted transport. Fragmentation not working. --- commons/zenoh-codec/src/transport/init.rs | 4 +- commons/zenoh-protocol/src/common/mod.rs | 1 - commons/zenoh-protocol/src/core/mod.rs | 22 +-- commons/zenoh-protocol/src/transport/init.rs | 55 +----- io/zenoh-transport/src/manager.rs | 32 +-- .../unicast/establishment/accept/init_ack.rs | 158 ++++++++------- .../unicast/establishment/accept/init_syn.rs | 67 +++---- .../src/unicast/establishment/accept/mod.rs | 16 +- .../unicast/establishment/accept/open_ack.rs | 15 +- .../unicast/establishment/accept/open_syn.rs | 139 +++++++------ .../src/unicast/establishment/cookie.rs | 34 ++-- .../src/unicast/establishment/mod.rs | 16 +- .../unicast/establishment/open/init_ack.rs | 185 +++++++++--------- .../unicast/establishment/open/init_syn.rs | 81 ++++---- .../src/unicast/establishment/open/mod.rs | 16 +- .../unicast/establishment/open/open_ack.rs | 61 +++--- .../unicast/establishment/open/open_syn.rs | 28 ++- io/zenoh-transport/src/unicast/manager.rs | 8 +- io/zenoh-transport/src/unicast/rx.rs | 10 +- .../tests/unicast_simultaneous.rs | 4 +- io/zenoh-transport/tests/unicast_transport.rs | 11 +- zenoh/src/admin.rs | 7 - zenoh/src/net/routing/network.rs | 2 +- 23 files changed, 445 insertions(+), 527 deletions(-) diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index 0a2be473fb..e47d429615 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -19,10 +19,10 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{imsg, ZExtUnknown}, - core::{WhatAmI, ZenohId}, + core::{Resolution, WhatAmI, ZenohId}, transport::{ id, - init::{ext, flag, InitAck, InitSyn, Resolution}, + init::{ext, flag, InitAck, InitSyn}, }, }; diff --git a/commons/zenoh-protocol/src/common/mod.rs b/commons/zenoh-protocol/src/common/mod.rs index d5887112cb..f236a1a075 100644 --- a/commons/zenoh-protocol/src/common/mod.rs +++ b/commons/zenoh-protocol/src/common/mod.rs @@ -34,7 +34,6 @@ pub mod imsg { pub const PRIORITY: u8 = 0x1c; pub const ROUTING_CONTEXT: u8 = 0x1d; pub const REPLY_CONTEXT: u8 = 0x1e; - pub const ATTACHMENT: u8 = 0x1f; } // Header mask diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index a68e1e332d..1617237399 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -56,26 +56,8 @@ pub use locator::*; pub mod endpoint; pub use endpoint::*; -#[repr(u8)] -// The value represents the 2-bit encoded value -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Bits { - U8 = 0b00, - U16 = 0b01, - U32 = 0b10, - U64 = 0b11, -} - -impl Bits { - pub const fn mask(&self) -> ZInt { - match self { - Bits::U8 => u8::MAX as ZInt, - Bits::U16 => u16::MAX as ZInt, - Bits::U32 => u32::MAX as ZInt, - Bits::U64 => u64::MAX as ZInt, - } - } -} +pub mod resolution; +pub use resolution::*; #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index b08d08580f..456d453628 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{Bits, WhatAmI, ZenohId}; +use crate::core::{Resolution, WhatAmI, ZenohId}; use zenoh_buffers::ZSlice; /// # Init message @@ -104,59 +104,6 @@ pub mod flag { pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow } -#[repr(u8)] -// The value indicates the bit offest -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Field { - FrameSN = 0, - RequestID = 2, - KeyExprID = 4, -} - -#[repr(transparent)] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Resolution(u8); - -impl Resolution { - pub const fn as_u8(&self) -> u8 { - self.0 - } - - pub const fn get(&self, field: Field) -> Bits { - let value = (self.0 >> (field as u8)) & 0b11; - unsafe { core::mem::transmute(value) } - } - - pub fn set(&mut self, field: Field, bits: Bits) { - self.0 &= !(0b11 << field as u8); // Clear bits - self.0 |= (bits as u8) << (field as u8); // Set bits - } - - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - let v: u8 = rng.gen(); - Self(v & 0b00111111) - } -} - -impl Default for Resolution { - fn default() -> Self { - let frame_sn = Bits::U64 as u8; - let request_id = (Bits::U64 as u8) << 2; - let keyexpr_id = (Bits::U64 as u8) << 4; - Self(frame_sn | request_id | keyexpr_id) - } -} - -impl From for Resolution { - fn from(v: u8) -> Self { - Self(v) - } -} - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct InitSyn { diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index 39f5de2d49..463e73bec0 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -27,8 +27,8 @@ use zenoh_core::zparse; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::NewLinkChannelSender; use zenoh_protocol::{ - core::{EndPoint, Locator, Priority, WhatAmI, ZInt, ZenohId}, - defaults::{BATCH_SIZE, FRAME_SN_RESOLUTION}, + core::{EndPoint, Locator, Priority, Resolution, WhatAmI, ZenohId}, + defaults::BATCH_SIZE, VERSION, }; use zenoh_result::{bail, ZResult}; @@ -82,7 +82,7 @@ pub struct TransportManagerConfig { pub version: u8, pub zid: ZenohId, pub whatami: WhatAmI, - pub sn_resolution: ZInt, + pub resolution: Resolution, pub batch_size: u16, pub queue_size: [usize; Priority::NUM], pub queue_backoff: Duration, @@ -107,7 +107,7 @@ pub struct TransportManagerBuilder { version: u8, zid: ZenohId, whatami: WhatAmI, - sn_resolution: ZInt, + resolution: Resolution, batch_size: u16, queue_size: QueueSizeConf, queue_backoff: Duration, @@ -129,8 +129,8 @@ impl TransportManagerBuilder { self } - pub fn sn_resolution(mut self, sn_resolution: ZInt) -> Self { - self.sn_resolution = sn_resolution; + pub fn resolution(mut self, resolution: Resolution) -> Self { + self.resolution = resolution; self } @@ -180,14 +180,14 @@ impl TransportManagerBuilder { self = self.whatami(*v); } - self = self.sn_resolution( - config - .transport() - .link() - .tx() - .sequence_number_resolution() - .unwrap(), - ); + // self = self.resolution( + // config + // .transport() + // .link() + // .tx() + // .sequence_number_resolution() + // .unwrap(), + // ); // @TODO self = self.batch_size(config.transport().link().tx().batch_size().unwrap()); self = self.defrag_buff_size(config.transport().link().rx().max_message_size().unwrap()); self = self.link_rx_buffer_size(config.transport().link().rx().buffer_size().unwrap()); @@ -232,7 +232,7 @@ impl TransportManagerBuilder { version: self.version, zid: self.zid, whatami: self.whatami, - sn_resolution: self.sn_resolution, + resolution: self.resolution, batch_size: self.batch_size, queue_size, queue_backoff: self.queue_backoff, @@ -262,7 +262,7 @@ impl Default for TransportManagerBuilder { version: VERSION, zid: ZenohId::rand(), whatami: ZN_MODE_DEFAULT.parse().unwrap(), - sn_resolution: FRAME_SN_RESOLUTION as ZInt, + resolution: Resolution::default(), batch_size: BATCH_SIZE, queue_size: queue.size, queue_backoff: Duration::from_nanos(backoff), diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs index 30ee96679e..372fe4db18 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs @@ -13,99 +13,96 @@ // use super::{init_syn, AResult}; use crate::{ - unicast::establishment::{ - authenticator::AuthenticatedPeerLink, Cookie, EstablishmentProperties, Zenoh080Cookie, - }, + unicast::establishment::{Cookie, Zenoh080Cookie}, TransportManager, }; use rand::Rng; -use std::convert::TryFrom; use zenoh_buffers::{writer::HasWriter, ZSlice}; use zenoh_codec::{WCodec, Zenoh080}; -use zenoh_core::{zasynclock, zasyncread}; -use zenoh_crypto::hmac; +use zenoh_core::zasynclock; use zenoh_link::LinkUnicast; use zenoh_protocol::{ - core::Property, - transport::{tmsg, TransportMessage}, + core::{Field, Resolution, ZInt}, + transport::{close, InitAck, TransportMessage}, }; use zenoh_result::zerror; // Send an InitAck pub(super) struct Output { - pub(super) cookie_hash: Vec, + pub(super) nonce: ZInt, } pub(super) async fn send( link: &LinkUnicast, manager: &TransportManager, - auth_link: &AuthenticatedPeerLink, - mut input: init_syn::Output, + input: init_syn::Output, ) -> AResult { - // Compute the minimum SN Resolution - let agreed_sn_resolution = manager.config.sn_resolution.min(input.sn_resolution); + // Build the attachment from the authenticators + // let mut ps_attachment = EstablishmentProperties::new(); + // let mut ps_cookie = EstablishmentProperties::new(); + // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { + // let (mut att, mut cke) = pa + // .handle_init_syn( + // auth_link, + // &cookie, + // input + // .init_syn_properties + // .remove(pa.id().into()) + // .map(|x| x.value), + // ) + // .await + // .map_err(|e| (e, Some(close::reason::INVALID)))?; + // // Add attachment property if available + // if let Some(att) = att.take() { + // ps_attachment + // .insert(Property { + // key: pa.id().into(), + // value: att, + // }) + // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; + // } + // // Add state in the cookie if avaiable + // if let Some(cke) = cke.take() { + // ps_cookie + // .insert(Property { + // key: pa.id().into(), + // value: cke, + // }) + // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; + // } + // } + // cookie.properties = ps_cookie; + + // let attachment: Option = if ps_attachment.is_empty() { + // None + // } else { + // let att = + // Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; + // Some(att) + // }; @TODO + + // Compute the minimum SN resolution + let resolution = { + let i_fsn_res = input.resolution.get(Field::FrameSN); + let m_fsn_res = manager.config.resolution.get(Field::FrameSN); - // Build the fields for the InitAck message - let whatami = manager.config.whatami; - let azid = manager.config.zid; - let sn_resolution = if agreed_sn_resolution == input.sn_resolution { - None - } else { - Some(agreed_sn_resolution) + let mut res = Resolution::default(); + res.set(Field::FrameSN, i_fsn_res.min(m_fsn_res)); + res }; + // Compute the minimum batch size + let batch_size = input.batch_size.min(manager.config.batch_size); + // Create the cookie - let mut cookie = Cookie { + let nonce: ZInt = zasynclock!(manager.prng).gen(); + let cookie = Cookie { whatami: input.whatami, zid: input.zid, - sn_resolution: agreed_sn_resolution, - is_qos: input.is_qos, - nonce: zasynclock!(manager.prng).gen_range(0..agreed_sn_resolution), - properties: EstablishmentProperties::new(), - }; - - // Build the attachment from the authenticators - let mut ps_attachment = EstablishmentProperties::new(); - let mut ps_cookie = EstablishmentProperties::new(); - for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - let (mut att, mut cke) = pa - .handle_init_syn( - auth_link, - &cookie, - input - .init_syn_properties - .remove(pa.id().into()) - .map(|x| x.value), - ) - .await - .map_err(|e| (e, Some(close::reason::INVALID)))?; - // Add attachment property if available - if let Some(att) = att.take() { - ps_attachment - .insert(Property { - key: pa.id().into(), - value: att, - }) - .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - } - // Add state in the cookie if avaiable - if let Some(cke) = cke.take() { - ps_cookie - .insert(Property { - key: pa.id().into(), - value: cke, - }) - .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - } - } - cookie.properties = ps_cookie; - - let attachment: Option = if ps_attachment.is_empty() { - None - } else { - let att = - Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; - Some(att) + resolution, + batch_size, + nonce, + // properties: EstablishmentProperties::new(), }; let mut encrypted = vec![]; @@ -122,19 +119,20 @@ pub(super) async fn send( ) })?; - // Compute the cookie hash - let cookie_hash = hmac::digest(&encrypted); - // Send the cookie let cookie: ZSlice = encrypted.into(); - let message = TransportMessage::make_init_ack( - whatami, - azid, - sn_resolution, - input.is_qos, + let message: TransportMessage = InitAck { + version: manager.config.version, + whatami: manager.config.whatami, + zid: manager.config.zid, + resolution, + batch_size: manager.config.batch_size, cookie, - attachment, - ); + qos: None, // @TODO + shm: None, // @TODO + auth: None, // @TODO + } + .into(); // Send the message on the link let _ = link @@ -142,6 +140,6 @@ pub(super) async fn send( .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = Output { cookie_hash }; + let output = Output { nonce }; Ok(output) } diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs index 111174555e..1bc029472d 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs @@ -1,5 +1,3 @@ -use std::convert::TryFrom; - // // Copyright (c) 2022 ZettaScale Technology // @@ -13,13 +11,12 @@ use std::convert::TryFrom; // Contributors: // ZettaScale Zenoh Team, // -use super::super::{AuthenticatedPeerLink, EstablishmentProperties}; use super::AResult; use crate::TransportManager; use zenoh_link::LinkUnicast; use zenoh_protocol::{ - core::{WhatAmI, ZInt, ZenohId}, - transport::{tmsg, TransportBody}, + core::{Resolution, WhatAmI, ZenohId}, + transport::{close, TransportBody}, }; use zenoh_result::zerror; @@ -31,15 +28,10 @@ use zenoh_result::zerror; pub(super) struct Output { pub(super) whatami: WhatAmI, pub(super) zid: ZenohId, - pub(super) sn_resolution: ZInt, - pub(super) is_qos: bool, - pub(super) init_syn_properties: EstablishmentProperties, + pub(super) resolution: Resolution, + pub(super) batch_size: u16, } -pub(super) async fn recv( - link: &LinkUnicast, - manager: &TransportManager, - auth_link: &mut AuthenticatedPeerLink, -) -> AResult { +pub(super) async fn recv(link: &LinkUnicast, manager: &TransportManager) -> AResult { // Wait to read an InitSyn let mut messages = link .read_transport_message() @@ -54,7 +46,7 @@ pub(super) async fn recv( return Err((e.into(), Some(close::reason::INVALID))); } - let mut msg = messages.remove(0); + let msg = messages.remove(0); let init_syn = match msg.body { TransportBody::InitSyn(init_syn) => init_syn, _ => { @@ -67,21 +59,21 @@ pub(super) async fn recv( } }; - // Check the peer id associate to the authenticated link - match auth_link.peer_id { - Some(zid) => { - if zid != init_syn.zid { - let e = zerror!( - "Inconsistent ZenohId in InitSyn on {}: {:?} {:?}", - link, - zid, - init_syn.zid - ); - return Err((e.into(), Some(close::reason::INVALID))); - } - } - None => auth_link.peer_id = Some(init_syn.zid), - } + // // Check the peer id associate to the authenticated link + // match auth_link.peer_id { + // Some(zid) => { + // if zid != init_syn.zid { + // let e = zerror!( + // "Inconsistent ZenohId in InitSyn on {}: {:?} {:?}", + // link, + // zid, + // init_syn.zid + // ); + // return Err((e.into(), Some(close::reason::INVALID))); + // } + // } + // None => auth_link.peer_id = Some(init_syn.zid), + // } // Check if the version is supported if init_syn.version != manager.config.version { @@ -93,19 +85,18 @@ pub(super) async fn recv( return Err((e.into(), Some(close::reason::INVALID))); } - // Validate the InitSyn with the peer authenticators - let init_syn_properties: EstablishmentProperties = match msg.attachment.take() { - Some(att) => EstablishmentProperties::try_from(&att) - .map_err(|e| (e, Some(close::reason::INVALID)))?, - None => EstablishmentProperties::new(), - }; + // // Validate the InitSyn with the peer authenticators + // let init_syn_properties: EstablishmentProperties = match msg.attachment.take() { + // Some(att) => EstablishmentProperties::try_from(&att) + // .map_err(|e| (e, Some(close::reason::INVALID)))?, + // None => EstablishmentProperties::new(), + // }; let output = Output { whatami: init_syn.whatami, zid: init_syn.zid, - sn_resolution: init_syn.sn_resolution, - is_qos: init_syn.is_qos, - init_syn_properties, + resolution: init_syn.resolution, + batch_size: init_syn.batch_size, }; Ok(output) } diff --git a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs index f434ca9f20..3d9e6356ef 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs @@ -47,18 +47,17 @@ pub(crate) async fn accept_link( }; } - let output = step!(init_syn::recv(link, manager, auth_link).await); - let output = step!(init_ack::send(link, manager, auth_link, output).await); - let output = step!(open_syn::recv(link, manager, auth_link, output).await); + let output = step!(init_syn::recv(link, manager).await); + let output = step!(init_ack::send(link, manager, output).await); + let output = step!(open_syn::recv(link, manager, output).await); // Initialize the transport let zid = output.cookie.zid; let input = super::InputInit { zid: output.cookie.zid, whatami: output.cookie.whatami, - sn_resolution: output.cookie.sn_resolution, - is_shm: output.is_shm, - is_qos: output.cookie.is_qos, + resolution: output.cookie.resolution, + batch_size: output.cookie.batch_size, }; let transport = step!(transport_init(manager, input) .await @@ -107,10 +106,7 @@ pub(crate) async fn accept_link( .map_err(|e| (e, Some(close::reason::INVALID)))) .config .initial_sn_tx; - let input = open_ack::Input { - initial_sn, - attachment: output.open_ack_attachment, - }; + let input = open_ack::Input { initial_sn }; let lease = output.lease; step!(open_ack::send(link, manager, auth_link, input).await); diff --git a/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs index 806c088bc7..fe28417228 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs @@ -16,9 +16,8 @@ use super::AResult; use crate::TransportManager; use zenoh_link::LinkUnicast; use zenoh_protocol::{ - common::Attachment, core::ZInt, - transport::{tmsg, TransportMessage}, + transport::{close, OpenAck, TransportMessage}, }; /*************************************/ @@ -27,7 +26,6 @@ use zenoh_protocol::{ // Send an OpenAck pub(super) struct Input { pub(super) initial_sn: ZInt, - pub(super) attachment: Option, } pub(super) async fn send( @@ -37,11 +35,12 @@ pub(super) async fn send( input: Input, ) -> AResult<()> { // Build OpenAck message - let message = TransportMessage::make_open_ack( - manager.config.unicast.lease, - input.initial_sn, - input.attachment, - ); + let message: TransportMessage = OpenAck { + lease: manager.config.unicast.lease, + initial_sn: input.initial_sn, + auth: None, // @TODO + } + .into(); // Send the message on the let _ = link diff --git a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs b/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs index 7f45d502e8..63211024ff 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs @@ -11,22 +11,22 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::super::{ - authenticator::AuthenticatedPeerLink, - {Cookie, EstablishmentProperties}, -}; use super::AResult; -use crate::{unicast::establishment::cookie::Zenoh080Cookie, TransportManager}; -use std::{convert::TryFrom, time::Duration}; +use crate::{ + unicast::establishment::cookie::{Cookie, Zenoh080Cookie}, + TransportManager, +}; +use std::time::Duration; use zenoh_buffers::reader::HasReader; use zenoh_codec::{RCodec, Zenoh080}; -use zenoh_core::{zasynclock, zasyncread}; -use zenoh_crypto::hmac; +use zenoh_core::zasynclock; use zenoh_link::LinkUnicast; use zenoh_protocol::{ - common::Attachment, - core::{Property, ZInt}, - transport::{tmsg, Close, TransportBody}, + core::ZInt, + transport::{ + close::{self, Close}, + TransportBody, + }, }; use zenoh_result::zerror; @@ -39,14 +39,11 @@ pub(super) struct Output { pub(super) cookie: Cookie, pub(super) initial_sn: ZInt, pub(super) lease: Duration, - pub(super) is_shm: bool, - pub(super) open_ack_attachment: Option, } #[allow(unused_mut)] pub(super) async fn recv( link: &LinkUnicast, manager: &TransportManager, - auth_link: &AuthenticatedPeerLink, input: super::init_ack::Output, ) -> AResult { // Wait to read an OpenSyn @@ -90,13 +87,7 @@ pub(super) async fn recv( }; let encrypted = open_syn.cookie.to_vec(); - // Verify that the cookie is the one we sent - if input.cookie_hash != hmac::digest(&encrypted) { - let e = zerror!("Rejecting OpenSyn on: {}. Unkwown cookie.", link); - return Err((e.into(), Some(close::reason::INVALID))); - } - - // Decrypt the cookie with the cyper + // Decrypt the cookie with the cipher let mut reader = encrypted.reader(); let mut codec = Zenoh080Cookie { prng: &mut *zasynclock!(manager.prng), @@ -110,66 +101,70 @@ pub(super) async fn recv( ) })?; - // Validate with the peer authenticators - let mut open_syn_properties: EstablishmentProperties = match msg.attachment.take() { - Some(att) => EstablishmentProperties::try_from(&att) - .map_err(|e| (e, Some(close::reason::INVALID)))?, - None => EstablishmentProperties::new(), - }; + // Verify that the cookie is the one we sent + if input.nonce != cookie.nonce { + let e = zerror!("Rejecting OpenSyn on: {}. Unkwown cookie.", link); + return Err((e.into(), Some(close::reason::INVALID))); + } - let mut is_shm = false; - let mut ps_attachment = EstablishmentProperties::new(); - for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - let po = open_syn_properties.remove(pa.id().into()).map(|x| x.value); - let pc = cookie.properties.remove(pa.id().into()).map(|x| x.value); - let mut att = pa.handle_open_syn(auth_link, &cookie, (po, pc)).await; + // // Validate with the peer authenticators + // let mut open_syn_properties: EstablishmentProperties = match msg.attachment.take() { + // Some(att) => EstablishmentProperties::try_from(&att) + // .map_err(|e| (e, Some(close::reason::INVALID)))?, + // None => EstablishmentProperties::new(), + // }; - #[cfg(feature = "shared-memory")] - { - if pa.id() == super::super::authenticator::PeerAuthenticatorId::Shm { - // Check if SHM has been validated from the other side - att = match att { - Ok(att) => { - is_shm = true; - Ok(att) - } - Err(e) => { - if e.is::() { - is_shm = false; - Ok(None) - } else { - Err(e) - } - } - }; - } - } + // let mut is_shm = false; + // let mut ps_attachment = EstablishmentProperties::new(); + // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { + // let po = open_syn_properties.remove(pa.id().into()).map(|x| x.value); + // let pc = cookie.properties.remove(pa.id().into()).map(|x| x.value); + // let mut att = pa.handle_open_syn(auth_link, &cookie, (po, pc)).await; - let mut att = att.map_err(|e| (e, Some(close::reason::INVALID)))?; - if let Some(att) = att.take() { - ps_attachment - .insert(Property { - key: pa.id().into(), - value: att, - }) - .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - } - } + // #[cfg(feature = "shared-memory")] + // { + // if pa.id() == super::super::authenticator::PeerAuthenticatorId::Shm { + // // Check if SHM has been validated from the other side + // att = match att { + // Ok(att) => { + // is_shm = true; + // Ok(att) + // } + // Err(e) => { + // if e.is::() { + // is_shm = false; + // Ok(None) + // } else { + // Err(e) + // } + // } + // }; + // } + // } - let open_ack_attachment = if ps_attachment.is_empty() { - None - } else { - let att = - Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; - Some(att) - }; + // let mut att = att.map_err(|e| (e, Some(close::reason::INVALID)))?; + // if let Some(att) = att.take() { + // ps_attachment + // .insert(Property { + // key: pa.id().into(), + // value: att, + // }) + // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; + // } + // } + + // let open_ack_attachment = if ps_attachment.is_empty() { + // None + // } else { + // let att = + // Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; + // Some(att) + // }; @TODO let output = Output { cookie, initial_sn: open_syn.initial_sn, lease: open_syn.lease, - is_shm, - open_ack_attachment, }; Ok(output) } diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 17eedf8381..c85e364783 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -19,14 +19,15 @@ use zenoh_buffers::{ }; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_crypto::{BlockCipher, PseudoRng}; -use zenoh_protocol::core::{WhatAmI, ZInt, ZenohId}; +use zenoh_protocol::core::{Resolution, WhatAmI, ZInt, ZenohId}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct Cookie { pub whatami: WhatAmI, pub zid: ZenohId, - pub sn_resolution: ZInt, - pub is_qos: bool, + pub resolution: Resolution, + pub batch_size: u16, + // pub is_qos: bool, pub nonce: ZInt, // pub properties: EstablishmentProperties, // @TODO } @@ -41,10 +42,12 @@ where let wai: u8 = x.whatami.into(); self.write(&mut *writer, wai)?; self.write(&mut *writer, &x.zid)?; - self.write(&mut *writer, x.sn_resolution)?; - let is_qos = u8::from(x.is_qos); - self.write(&mut *writer, is_qos)?; + self.write(&mut *writer, x.resolution.as_u8())?; + self.write(&mut *writer, x.batch_size)?; self.write(&mut *writer, x.nonce)?; + + // let is_qos = u8::from(x.is_qos); + // self.write(&mut *writer, is_qos)?; // self.write(&mut *writer, x.properties.as_slice())?; Ok(()) @@ -61,10 +64,13 @@ where let wai: u8 = self.read(&mut *reader)?; let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; let zid: ZenohId = self.read(&mut *reader)?; - let sn_resolution: ZInt = self.read(&mut *reader)?; - let is_qos: u8 = self.read(&mut *reader)?; - let is_qos = is_qos == 1; + let resolution: u8 = self.read(&mut *reader)?; + let resolution = Resolution::from(resolution); + let batch_size: u16 = self.read(&mut *reader)?; let nonce: ZInt = self.read(&mut *reader)?; + + // let is_qos: u8 = self.read(&mut *reader)?; + // let is_qos = is_qos == 1; // let mut ps: Vec = self.read(&mut *reader)?; // let mut properties = EstablishmentProperties::new(); // for p in ps.drain(..) { @@ -74,9 +80,10 @@ where let cookie = Cookie { whatami, zid, - sn_resolution, - is_qos, + resolution, + batch_size, nonce, + // is_qos, // properties, }; @@ -136,9 +143,10 @@ impl Cookie { Self { whatami: WhatAmI::rand(), zid: ZenohId::default(), - sn_resolution: rng.gen(), - is_qos: rng.gen_bool(0.5), + resolution: Resolution::rand(), + batch_size: rng.gen(), nonce: rng.gen(), + // is_qos: rng.gen_bool(0.5), // properties: EstablishmentProperties::rand(), } } diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index bac955c155..61b3912e8d 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -27,7 +27,7 @@ use std::time::Duration; use zenoh_core::{zasynclock, zasyncread}; use zenoh_link::{Link, LinkUnicast}; use zenoh_protocol::{ - core::{WhatAmI, ZInt, ZenohId}, + core::{Field, Resolution, WhatAmI, ZenohId}, transport::{Close, TransportMessage}, }; use zenoh_result::ZResult; @@ -63,23 +63,23 @@ pub(super) async fn close_link( pub(super) struct InputInit { pub(super) zid: ZenohId, pub(super) whatami: WhatAmI, - pub(super) sn_resolution: ZInt, - pub(super) is_shm: bool, - pub(super) is_qos: bool, + pub(super) resolution: Resolution, + pub(super) batch_size: u16, } async fn transport_init( manager: &TransportManager, input: self::InputInit, ) -> ZResult { // Initialize the transport if it is new - let initial_sn_tx = zasynclock!(manager.prng).gen_range(0..input.sn_resolution); + let initial_sn_tx = + zasynclock!(manager.prng).gen_range(0..=input.resolution.get(Field::FrameSN).mask()); let config = TransportConfigUnicast { peer: input.zid, whatami: input.whatami, - sn_resolution: input.sn_resolution, - is_shm: input.is_shm, - is_qos: input.is_qos, + sn_resolution: input.resolution.get(Field::FrameSN).mask(), + is_shm: false, // @TODO + is_qos: false, // @TODO initial_sn_tx, }; diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs index f397575ae5..1b56fb42cc 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs @@ -12,40 +12,32 @@ // ZettaScale Zenoh Team, // use crate::unicast::establishment::open::OResult; -use crate::unicast::establishment::{ - authenticator::AuthenticatedPeerLink, EstablishmentProperties, -}; use crate::TransportManager; -use std::convert::TryFrom; use zenoh_buffers::ZSlice; -use zenoh_core::zasyncread; use zenoh_link::LinkUnicast; use zenoh_protocol::{ - common::Attachment, - core::{Property, WhatAmI, ZInt, ZenohId}, - transport::{tmsg, Close, TransportBody}, + core::{Field, Resolution, WhatAmI, ZenohId}, + transport::{ + close::{self, Close}, + TransportBody, + }, }; use zenoh_result::zerror; -#[cfg(feature = "shared-memory")] -use crate::unicast::establishment::authenticator::PeerAuthenticatorId; - /*************************************/ /* OPEN */ /*************************************/ pub(super) struct Output { pub(super) zid: ZenohId, pub(super) whatami: WhatAmI, - pub(super) sn_resolution: ZInt, - pub(super) is_qos: bool, - pub(super) is_shm: bool, + pub(super) resolution: Resolution, + pub(super) batch_size: u16, pub(super) cookie: ZSlice, - pub(super) open_syn_attachment: Option, } + pub(super) async fn recv( link: &LinkUnicast, manager: &TransportManager, - auth_link: &mut AuthenticatedPeerLink, _input: super::init_syn::Output, ) -> OResult { // Wait to read an InitAck @@ -65,7 +57,7 @@ pub(super) async fn recv( )); } - let mut msg = messages.remove(0); + let msg = messages.remove(0); let init_ack = match msg.body { TransportBody::InitAck(init_ack) => init_ack, TransportBody::Close(Close { reason, .. }) => { @@ -91,93 +83,104 @@ pub(super) async fn recv( } }; - let sn_resolution = match init_ack.sn_resolution { - Some(sn_resolution) => { - if sn_resolution > manager.config.sn_resolution { - return Err(( - zerror!( - "Rejecting InitAck on {}. Invalid sn resolution: {}", - link, - sn_resolution - ) - .into(), - Some(close::reason::INVALID), - )); - } - sn_resolution - } - None => manager.config.sn_resolution, - }; + // Compute the minimum SN resolution + let resolution = { + let i_fsn_res = init_ack.resolution.get(Field::FrameSN); + let m_fsn_res = manager.config.resolution.get(Field::FrameSN); - // Store the peer id associate do this link - auth_link.peer_id = Some(init_ack.zid); + if i_fsn_res > m_fsn_res { + let e = zerror!("Invalid SN resolution on {}: {:?}", link, i_fsn_res); + log::error!("{}", e); + return Err((e.into(), Some(close::reason::INVALID))); + } - let mut init_ack_properties = match msg.attachment.take() { - Some(att) => EstablishmentProperties::try_from(&att) - .map_err(|e| (e, Some(close::reason::INVALID)))?, - None => EstablishmentProperties::new(), + let mut res = Resolution::default(); + res.set(Field::FrameSN, i_fsn_res); + res }; - #[allow(unused_mut)] - let mut is_shm = false; - let mut ps_attachment = EstablishmentProperties::new(); - for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - #[allow(unused_mut)] - let mut att = pa - .handle_init_ack( - auth_link, - &init_ack.zid, - sn_resolution, - init_ack_properties.remove(pa.id().into()).map(|x| x.value), - ) - .await; - - #[cfg(feature = "shared-memory")] - if pa.id() == PeerAuthenticatorId::Shm { - // Check if SHM has been validated from the other side - att = match att { - Ok(att) => { - is_shm = att.is_some(); - Ok(att) - } - Err(e) => { - if e.is::() { - is_shm = false; - Ok(None) - } else { - Err(e) - } - } - }; - } + // Compute the minimum batch size + let batch_size = { + let i_bsize = init_ack.batch_size; + let m_bsize = manager.config.batch_size; - let mut att = att.map_err(|e| (e, Some(close::reason::INVALID)))?; - if let Some(att) = att.take() { - ps_attachment - .insert(Property { - key: pa.id().into(), - value: att, - }) - .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; + if i_bsize > m_bsize { + let e = zerror!("Invalid batch size on {}: {:?}", link, i_bsize); + log::error!("{}", e); + return Err((e.into(), Some(close::reason::INVALID))); } - } - let open_syn_attachment = if ps_attachment.is_empty() { - None - } else { - let att = - Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; - Some(att) + i_bsize }; + // // Store the peer id associate do this link + // auth_link.peer_id = Some(init_ack.zid); + + // let mut init_ack_properties = match msg.attachment.take() { + // Some(att) => EstablishmentProperties::try_from(&att) + // .map_err(|e| (e, Some(close::reason::INVALID)))?, + // None => EstablishmentProperties::new(), + // }; + + // #[allow(unused_mut)] + // let mut is_shm = false; + // let mut ps_attachment = EstablishmentProperties::new(); + // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { + // #[allow(unused_mut)] + // let mut att = pa + // .handle_init_ack( + // auth_link, + // &init_ack.zid, + // sn_resolution, + // init_ack_properties.remove(pa.id().into()).map(|x| x.value), + // ) + // .await; + + // #[cfg(feature = "shared-memory")] + // if pa.id() == PeerAuthenticatorId::Shm { + // // Check if SHM has been validated from the other side + // att = match att { + // Ok(att) => { + // is_shm = att.is_some(); + // Ok(att) + // } + // Err(e) => { + // if e.is::() { + // is_shm = false; + // Ok(None) + // } else { + // Err(e) + // } + // } + // }; + // } + + // let mut att = att.map_err(|e| (e, Some(close::reason::INVALID)))?; + // if let Some(att) = att.take() { + // ps_attachment + // .insert(Property { + // key: pa.id().into(), + // value: att, + // }) + // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; + // } + // } + + // let open_syn_attachment = if ps_attachment.is_empty() { + // None + // } else { + // let att = + // Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; + // Some(att) + // }; @TODO + let output = Output { zid: init_ack.zid, whatami: init_ack.whatami, - sn_resolution, - is_qos: init_ack.is_qos, - is_shm, + resolution, + batch_size, cookie: init_ack.cookie, - open_syn_attachment, }; + Ok(output) } diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs b/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs index 4c6d16911d..27a867ea1a 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs @@ -12,62 +12,53 @@ // ZettaScale Zenoh Team, // use super::OResult; -use crate::unicast::establishment::{ - authenticator::AuthenticatedPeerLink, EstablishmentProperties, -}; use crate::TransportManager; -use std::convert::TryFrom; -use zenoh_core::zasyncread; use zenoh_link::LinkUnicast; -use zenoh_protocol::common::Attachment; -use zenoh_protocol::{ - core::Property, - transport::{tmsg, TransportMessage}, -}; +use zenoh_protocol::transport::{close, init::InitSyn, TransportMessage}; /*************************************/ /* OPEN */ /*************************************/ pub(super) struct Output; -pub(super) async fn send( - link: &LinkUnicast, - manager: &TransportManager, - auth_link: &mut AuthenticatedPeerLink, -) -> OResult { - let mut ps_attachment = EstablishmentProperties::new(); - for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - let mut att = pa - .get_init_syn_properties(auth_link, &manager.config.zid) - .await - .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - if let Some(att) = att.take() { - ps_attachment - .insert(Property { - key: pa.id().into(), - value: att, - }) - .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - } - } +pub(super) async fn send(link: &LinkUnicast, manager: &TransportManager) -> OResult { + // let mut ps_attachment = EstablishmentProperties::new(); + // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { + // let mut att = pa + // .get_init_syn_properties(auth_link, &manager.config.zid) + // .await + // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; + // if let Some(att) = att.take() { + // ps_attachment + // .insert(Property { + // key: pa.id().into(), + // value: att, + // }) + // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; + // } + // } // Build and send the InitSyn message - let init_syn_attachment = if ps_attachment.is_empty() { - None - } else { - let att = - Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; - Some(att) - }; + // let init_syn_attachment = if ps_attachment.is_empty() { + // None + // } else { + // let att = + // Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; + // Some(att) + // }; // @TODO + + let message: TransportMessage = InitSyn { + version: manager.config.version, + whatami: manager.config.whatami, + zid: manager.config.zid, + batch_size: manager.config.batch_size, + resolution: manager.config.resolution, + qos: None, // @TODO + shm: None, // @TODO + auth: None, // @TODO + } + .into(); - let message = TransportMessage::make_init_syn( - manager.config.version, - manager.config.whatami, - manager.config.zid, - manager.config.sn_resolution, - manager.config.unicast.is_qos, - init_syn_attachment, - ); let _ = link .write_transport_message(&message) .await diff --git a/io/zenoh-transport/src/unicast/establishment/open/mod.rs b/io/zenoh-transport/src/unicast/establishment/open/mod.rs index 6367658a0d..dc75e9c8e0 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/mod.rs @@ -44,8 +44,8 @@ pub(crate) async fn open_link( }; } - let output = step!(init_syn::send(link, manager, auth_link).await); - let output = step!(init_ack::recv(link, manager, auth_link, output).await); + let output = step!(init_syn::send(link, manager).await); + let output = step!(init_ack::recv(link, manager, output).await); // Initialize the transport macro_rules! step { @@ -64,9 +64,8 @@ pub(crate) async fn open_link( let input = InputInit { zid, whatami: output.whatami, - sn_resolution: output.sn_resolution, - is_shm: output.is_shm, - is_qos: output.is_qos, + resolution: output.resolution, + batch_size: output.batch_size, }; let transport = step!(super::transport_init(manager, input).await); @@ -93,13 +92,14 @@ pub(crate) async fn open_link( .map_err(|e| (e, Some(close::reason::INVALID)))) .config .initial_sn_tx; + let input = open_syn::Input { cookie: output.cookie, + resolution: output.resolution, initial_sn, - attachment: output.open_syn_attachment, }; - let output = step!(open_syn::send(link, manager, auth_link, input).await); - let output = step!(open_ack::recv(link, manager, auth_link, output).await); + let output = step!(open_syn::send(link, manager, input).await); + let output = step!(open_ack::recv(link, manager, output).await); // Finalize the transport // Add the link to the transport diff --git a/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs b/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs index ad0a602318..54297f60ed 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs @@ -11,18 +11,15 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{ - unicast::establishment::{ - authenticator::AuthenticatedPeerLink, open::OResult, EstablishmentProperties, - }, - TransportManager, -}; -use std::{convert::TryFrom, time::Duration}; -use zenoh_core::zasyncread; +use crate::{unicast::establishment::open::OResult, TransportManager}; +use std::time::Duration; use zenoh_link::LinkUnicast; use zenoh_protocol::{ - core::ZInt, - transport::{tmsg, Close, TransportBody}, + core::{Field, ZInt}, + transport::{ + close::{self, Close}, + TransportBody, + }, }; use zenoh_result::zerror; @@ -33,9 +30,8 @@ pub(super) struct Output { pub(super) async fn recv( link: &LinkUnicast, - manager: &TransportManager, - auth_link: &AuthenticatedPeerLink, - _input: super::open_syn::Output, + _manager: &TransportManager, + input: super::open_syn::Output, ) -> OResult { // Wait to read an OpenAck let mut messages = link @@ -54,7 +50,7 @@ pub(super) async fn recv( )); } - let mut msg = messages.remove(0); + let msg = messages.remove(0); let open_ack = match msg.body { TransportBody::OpenAck(open_ack) => open_ack, TransportBody::Close(Close { reason, .. }) => { @@ -80,21 +76,32 @@ pub(super) async fn recv( } }; - let mut opean_ack_properties = match msg.attachment.take() { - Some(att) => EstablishmentProperties::try_from(&att) - .map_err(|e| (e, Some(close::reason::INVALID)))?, - None => EstablishmentProperties::new(), - }; - for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - let _ = pa - .handle_open_ack( - auth_link, - opean_ack_properties.remove(pa.id().into()).map(|x| x.value), - ) - .await - .map_err(|e| (e, Some(close::reason::INVALID)))?; + // Verify that initial_sn is within the agreed resolution + if open_ack.initial_sn > input.resolution.get(Field::FrameSN).mask() { + let e = zerror!( + "Received invalid initial SN {}: {:?}", + link, + open_ack.initial_sn + ); + log::error!("{}", e); + return Err((e.into(), Some(close::reason::INVALID))); } + // let mut opean_ack_properties = match msg.attachment.take() { + // Some(att) => EstablishmentProperties::try_from(&att) + // .map_err(|e| (e, Some(close::reason::INVALID)))?, + // None => EstablishmentProperties::new(), + // }; + // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { + // let _ = pa + // .handle_open_ack( + // auth_link, + // opean_ack_properties.remove(pa.id().into()).map(|x| x.value), + // ) + // .await + // .map_err(|e| (e, Some(close::reason::INVALID)))?; + // } @TODO + let output = Output { initial_sn: open_ack.initial_sn, lease: open_ack.lease, diff --git a/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs b/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs index d76cb1109a..3c6db84e48 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs @@ -11,40 +11,48 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::super::authenticator::AuthenticatedPeerLink; use super::OResult; use crate::TransportManager; use zenoh_buffers::ZSlice; use zenoh_link::LinkUnicast; use zenoh_protocol::{ - common::Attachment, - core::ZInt, - transport::{tmsg, TransportMessage}, + core::{Resolution, ZInt}, + transport::{close, OpenSyn, TransportMessage}, }; pub(super) struct Input { pub(super) cookie: ZSlice, + pub(super) resolution: Resolution, pub(super) initial_sn: ZInt, - pub(super) attachment: Option, } -pub(super) struct Output; +pub(super) struct Output { + pub(super) resolution: Resolution, +} pub(super) async fn send( link: &LinkUnicast, manager: &TransportManager, - _auth_link: &AuthenticatedPeerLink, input: Input, ) -> OResult { // Build and send an OpenSyn message let lease = manager.config.unicast.lease; - let message = - TransportMessage::make_open_syn(lease, input.initial_sn, input.cookie, input.attachment); + let message: TransportMessage = OpenSyn { + lease, + initial_sn: input.initial_sn, + cookie: input.cookie, + shm: None, // @TODO + auth: None, // @TODO + } + .into(); + let _ = link .write_transport_message(&message) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = Output; + let output = Output { + resolution: input.resolution, + }; Ok(output) } diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index b46427dd9d..a756a1dd06 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -344,7 +344,7 @@ impl TransportManager { // Ignore the non fundamental parameters like initial SN. if transport.config.whatami != config.whatami { let e = zerror!( - "Transport with peer {} already exist. Invalid whatami: {}. Execpted: {}.", + "Transport with peer {} already exist. Invalid whatami: {}. Expected: {}.", config.peer, config.whatami, transport.config.whatami @@ -355,7 +355,7 @@ impl TransportManager { if transport.config.sn_resolution != config.sn_resolution { let e = zerror!( - "Transport with peer {} already exist. Invalid sn resolution: {}. Execpted: {}.", + "Transport with peer {} already exist. Invalid sn resolution: {}. Expected: {}.", config.peer, config.sn_resolution, transport.config.sn_resolution ); log::trace!("{}", e); @@ -365,7 +365,7 @@ impl TransportManager { #[cfg(feature = "shared-memory")] if transport.config.is_shm != config.is_shm { let e = zerror!( - "Transport with peer {} already exist. Invalid is_shm: {}. Execpted: {}.", + "Transport with peer {} already exist. Invalid is_shm: {}. Expected: {}.", config.peer, config.is_shm, transport.config.is_shm @@ -376,7 +376,7 @@ impl TransportManager { if transport.config.is_qos != config.is_qos { let e = zerror!( - "Transport with peer {} already exist. Invalid is_qos: {}. Execpted: {}.", + "Transport with peer {} already exist. Invalid is_qos: {}. Expected: {}.", config.peer, config.is_qos, transport.config.is_qos diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index 9caadd164a..6748830de9 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -82,7 +82,7 @@ impl TransportUnicastInner { } } - fn handle_close(&self, link: &LinkUnicast, reason: u8, session: bool) -> ZResult<()> { + fn handle_close(&self, link: &LinkUnicast, _reason: u8, session: bool) -> ZResult<()> { // Stop now rx and tx tasks before doing the proper cleanup let _ = self.stop_rx(link); let _ = self.stop_tx(link); @@ -103,11 +103,7 @@ impl TransportUnicastInner { Ok(()) } - fn handle_frame( - &self, - payload: SingleOrVec, - mut guard: MutexGuard<'_, TransportChannelRx>, - ) -> ZResult<()> { + fn handle_frame(&self, payload: SingleOrVec) -> ZResult<()> { for msg in payload.into_iter() { self.trigger_callback(msg)?; } @@ -190,7 +186,7 @@ impl TransportUnicastInner { }; self.verify_sn(sn, &mut guard)?; - self.handle_frame(payload, guard) + self.handle_frame(payload) } TransportBody::Fragment(Fragment { reliability, diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index 7ae5ece988..8bd52a3596 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -29,8 +29,8 @@ mod tests { }; use zenoh_result::ZResult; use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportMulticast, - TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, }; const TIMEOUT: Duration = Duration::from_secs(60); diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 2004abb6f9..05e5faf06a 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -31,8 +31,8 @@ use zenoh_protocol::{ }; use zenoh_result::ZResult; use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportMulticast, TransportMulticastEventHandler, - TransportPeer, TransportPeerEventHandler, TransportUnicast, + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, }; // These keys and certificates below are purposedly generated to run TLS and mTLS tests. @@ -337,7 +337,7 @@ async fn open_transport( // Create the listener on the router for e in server_endpoints.iter() { - println!("Add endpoint: {e}\n"); + println!("Add endpoint: {e}"); let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); } @@ -464,6 +464,11 @@ async fn run_single( channel: Channel, msg_size: usize, ) { + println!( + "\n>>> Running test for: {:?}, {:?}, {:?}, {}", + client_endpoints, server_endpoints, channel, msg_size + ); + #[allow(unused_variables)] // Used when stats feature is enabled let (router_manager, router_handler, client_manager, client_transport) = open_transport(client_endpoints, server_endpoints).await; diff --git a/zenoh/src/admin.rs b/zenoh/src/admin.rs index 5d1f6c95c0..82dc29f7e5 100644 --- a/zenoh/src/admin.rs +++ b/zenoh/src/admin.rs @@ -140,13 +140,6 @@ impl TransportEventHandler for Handler { bail!("Unable to build keyexpr from zid") } } - - fn new_multicast( - &self, - _transport: zenoh_transport::TransportMulticast, - ) -> ZResult> { - bail!("unimplemented") - } } pub(crate) struct PeerHandler { diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index 65664694f1..220a0a4f20 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -265,7 +265,7 @@ impl Network { for (idx, details) in idxs { list.push(self.make_link_state(idx, details)); } - ZenohMessage::make_link_state_list(list, None) + ZenohMessage::make_link_state_list(list) } fn send_on_link(&self, idxs: Vec<(NodeIndex, Details)>, transport: &TransportUnicast) { From 5b4df5bebdac478f0bab1954681c5edd39ec1ef9 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 18:00:55 +0100 Subject: [PATCH 024/203] Fix runtime message creation --- zenoh/src/net/runtime/mod.rs | 4 ++-- zenoh/src/net/runtime/orchestrator.rs | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index 6024601bf3..7deab5647f 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -43,8 +43,8 @@ use zenoh_protocol::{ use zenoh_result::{bail, ZResult}; use zenoh_sync::get_mut_unchecked; use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportMulticast, TransportMulticastEventHandler, - TransportPeer, TransportPeerEventHandler, TransportUnicast, + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, }; pub struct RuntimeState { diff --git a/zenoh/src/net/runtime/orchestrator.rs b/zenoh/src/net/runtime/orchestrator.rs index fd90d7f484..11a9a525a2 100644 --- a/zenoh/src/net/runtime/orchestrator.rs +++ b/zenoh/src/net/runtime/orchestrator.rs @@ -485,7 +485,12 @@ impl Runtime { let send = async { let mut delay = SCOUT_INITIAL_PERIOD; - let scout = ScoutingMessage::make_scout(matcher, None, None); + let scout: ScoutingMessage = Scout { + version: zenoh_protocol::VERSION, + what: matcher, + zid: None, + } + .into(); let mut wbuf = vec![]; let mut writer = wbuf.writer(); let codec = Zenoh080::default(); @@ -701,12 +706,13 @@ impl Runtime { let codec = Zenoh080::default(); let zid = self.manager().zid(); - let hello = ScoutingMessage::make_hello( - self.whatami, + let hello: ScoutingMessage = Hello { + version: zenoh_protocol::VERSION, + whatami: self.whatami, zid, - self.get_locators(), - None, - ); + locators: self.get_locators(), + } + .into(); let socket = get_best_match(&peer.ip(), ucast_sockets).unwrap(); log::trace!( "Send {:?} to {} on interface {}", From e67ebf1be0d1d69ab1b50a4db241c204dce0a2af Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Feb 2023 18:06:21 +0100 Subject: [PATCH 025/203] Missing file --- commons/zenoh-protocol/src/core/resolution.rs | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 commons/zenoh-protocol/src/core/resolution.rs diff --git a/commons/zenoh-protocol/src/core/resolution.rs b/commons/zenoh-protocol/src/core/resolution.rs new file mode 100644 index 0000000000..140813688e --- /dev/null +++ b/commons/zenoh-protocol/src/core/resolution.rs @@ -0,0 +1,89 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use super::ZInt; +use crate::defaults::{FRAME_SN_RESOLUTION, KEYEXPR_ID_RESOLUTION, REQUEST_ID_RESOLUTION}; + +#[repr(u8)] +// The value represents the 2-bit encoded value +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum Bits { + U8 = 0b00, + U16 = 0b01, + U32 = 0b10, + U64 = 0b11, +} + +impl Bits { + pub const fn mask(&self) -> ZInt { + match self { + Bits::U8 => u8::MAX as ZInt, + Bits::U16 => u16::MAX as ZInt, + Bits::U32 => u32::MAX as ZInt, + Bits::U64 => u64::MAX as ZInt, + } + } +} + +#[repr(u8)] +// The value indicates the bit offest +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Field { + FrameSN = 0, + RequestID = 2, + KeyExprID = 4, +} + +#[repr(transparent)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Resolution(u8); + +impl Resolution { + pub const fn as_u8(&self) -> u8 { + self.0 + } + + pub const fn get(&self, field: Field) -> Bits { + let value = (self.0 >> (field as u8)) & 0b11; + unsafe { core::mem::transmute(value) } + } + + pub fn set(&mut self, field: Field, bits: Bits) { + self.0 &= !(0b11 << field as u8); // Clear bits + self.0 |= (bits as u8) << (field as u8); // Set bits + } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let v: u8 = rng.gen(); + Self(v & 0b00111111) + } +} + +impl Default for Resolution { + fn default() -> Self { + let frame_sn = FRAME_SN_RESOLUTION as u8; + let request_id = (REQUEST_ID_RESOLUTION as u8) << 2; + let keyexpr_id = (KEYEXPR_ID_RESOLUTION as u8) << 4; + Self(frame_sn | request_id | keyexpr_id) + } +} + +impl From for Resolution { + fn from(v: u8) -> Self { + Self(v) + } +} From 387ae01c953903d57cc643ae225652fd4c40f1df Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 10:37:51 +0100 Subject: [PATCH 026/203] Fix fragmentation --- commons/zenoh-codec/src/transport/mod.rs | 1 + io/zenoh-transport/src/common/batch.rs | 63 ++++----- io/zenoh-transport/src/common/pipeline.rs | 40 ++++-- io/zenoh-transport/tests/endpoints.rs | 4 +- .../tests/unicast_authenticator.rs | 128 +++++++++--------- .../tests/unicast_concurrent.rs | 44 +++--- io/zenoh-transport/tests/unicast_conduits.rs | 10 +- .../tests/unicast_defragmentation.rs | 8 +- .../tests/unicast_intermittent.rs | 22 +-- io/zenoh-transport/tests/unicast_openclose.rs | 122 ++++++++--------- io/zenoh-transport/tests/unicast_shm.rs | 26 ++-- .../tests/unicast_simultaneous.rs | 36 ++--- io/zenoh-transport/tests/unicast_transport.rs | 21 +-- zenoh/tests/session.rs | 24 ++-- 14 files changed, 281 insertions(+), 268 deletions(-) diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index 4684d789c0..5f82b4d38a 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -77,6 +77,7 @@ where id::CLOSE => TransportBody::Close(codec.read(&mut *reader)?), id::KEEP_ALIVE => TransportBody::KeepAlive(codec.read(&mut *reader)?), id::FRAME => TransportBody::Frame(codec.read(&mut *reader)?), + id::FRAGMENT => TransportBody::Fragment(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 238a281294..0e4bf3c563 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -19,12 +19,8 @@ use zenoh_buffers::{ }; use zenoh_codec::{WCodec, Zenoh080}; use zenoh_protocol::{ - core::{Channel, Reliability, ZInt}, - transport::{ - fragment::{self, FragmentHeader}, - frame::{self, FrameHeader}, - TransportMessage, - }, + core::{Reliability, ZInt}, + transport::{fragment::FragmentHeader, frame::FrameHeader, TransportMessage}, zenoh::ZenohMessage, }; @@ -252,7 +248,7 @@ impl Encode<&ZenohMessage> for &mut WBatch { } } -impl Encode<(&ZenohMessage, Channel, ZInt)> for &mut WBatch { +impl Encode<(&ZenohMessage, &FrameHeader)> for &mut WBatch { type Output = Result<(), DidntWrite>; /// Try to serialize a [`ZenohMessage`][ZenohMessage] on the [`SerializationBatch`][SerializationBatch]. @@ -260,8 +256,8 @@ impl Encode<(&ZenohMessage, Channel, ZInt)> for &mut WBatch { /// # Arguments /// * `message` - The [`ZenohMessage`][ZenohMessage] to serialize. /// - fn encode(self, message: (&ZenohMessage, Channel, ZInt)) -> Self::Output { - let (message, channel, sn) = message; + fn encode(self, message: (&ZenohMessage, &FrameHeader)) -> Self::Output { + let (message, frame) = message; // Mark the write operation let mut writer = self.buffer.writer(); @@ -269,12 +265,7 @@ impl Encode<(&ZenohMessage, Channel, ZInt)> for &mut WBatch { let codec = Zenoh080::default(); // Write the frame header - let frame = FrameHeader { - reliability: channel.reliability, - sn, - qos: frame::ext::QoS::new(channel.priority), - }; - codec.write(&mut writer, &frame).map_err(|e| { + codec.write(&mut writer, frame).map_err(|e| { // Revert the write operation writer.rewind(mark); e @@ -288,11 +279,11 @@ impl Encode<(&ZenohMessage, Channel, ZInt)> for &mut WBatch { // Update the frame self.current_frame = match frame.reliability { Reliability::Reliable => { - self.latest_sn.reliable = Some(sn); + self.latest_sn.reliable = Some(frame.sn); CurrentFrame::Reliable } Reliability::BestEffort => { - self.latest_sn.best_effort = Some(sn); + self.latest_sn.best_effort = Some(frame.sn); CurrentFrame::BestEffort } }; @@ -300,7 +291,7 @@ impl Encode<(&ZenohMessage, Channel, ZInt)> for &mut WBatch { } } -impl Encode<(&mut ZBufReader<'_>, Channel, ZInt)> for &mut WBatch { +impl Encode<(&mut ZBufReader<'_>, &mut FragmentHeader)> for &mut WBatch { type Output = Result; /// Try to serialize a [`ZenohMessage`][ZenohMessage] on the [`SerializationBatch`][SerializationBatch]. @@ -308,8 +299,8 @@ impl Encode<(&mut ZBufReader<'_>, Channel, ZInt)> for &mut WBatch { /// # Arguments /// * `message` - The [`ZenohMessage`][ZenohMessage] to serialize. /// - fn encode(self, message: (&mut ZBufReader<'_>, Channel, ZInt)) -> Self::Output { - let (reader, channel, sn) = message; + fn encode(self, message: (&mut ZBufReader<'_>, &mut FragmentHeader)) -> Self::Output { + let (reader, fragment) = message; let mut writer = self.buffer.writer(); let codec = Zenoh080::default(); @@ -317,15 +308,8 @@ impl Encode<(&mut ZBufReader<'_>, Channel, ZInt)> for &mut WBatch { // Mark the buffer for the writing operation let mark = writer.mark(); - // Serialize first assuming is some fragment - let mut frame = FragmentHeader { - reliability: channel.reliability, - more: true, - sn, - qos: fragment::ext::QoS::new(channel.priority), - }; // Write the frame header - codec.write(&mut writer, &frame).map_err(|e| { + codec.write(&mut writer, &*fragment).map_err(|e| { // Revert the write operation writer.rewind(mark); e @@ -336,9 +320,9 @@ impl Encode<(&mut ZBufReader<'_>, Channel, ZInt)> for &mut WBatch { // Revert the buffer writer.rewind(mark); // It is really the finally fragment, reserialize the header - frame.more = false; + fragment.more = false; // Write the frame header - codec.write(&mut writer, &frame).map_err(|e| { + codec.write(&mut writer, &*fragment).map_err(|e| { // Revert the write operation writer.rewind(mark); e @@ -360,7 +344,10 @@ mod tests { use zenoh_buffers::ZBuf; use zenoh_protocol::{ core::{Channel, CongestionControl, Priority, Reliability}, - transport::{KeepAlive, TransportMessage}, + transport::{ + frame::{self, FrameHeader}, + KeepAlive, TransportMessage, + }, zenoh::ZenohMessage, }; @@ -390,8 +377,14 @@ mod tests { assert!(batch.encode(&zmsg).is_err()); assert_eq!(batch.len(), 0); + let mut frame = FrameHeader { + reliability: zmsg.channel.reliability, + sn: 0, + qos: frame::ext::QoS::default(), + }; + // Serialize with a frame - batch.encode((&zmsg, zmsg.channel, 0)).unwrap(); + batch.encode((&zmsg, &frame)).unwrap(); assert_ne!(batch.len(), 0); zmsgs_in.push(zmsg.clone()); @@ -400,7 +393,8 @@ mod tests { assert!(batch.encode(&zmsg).is_err()); assert_ne!(batch.len(), 0); - batch.encode((&zmsg, zmsg.channel, 0)).unwrap(); + frame.reliability = zmsg.channel.reliability; + batch.encode((&zmsg, &frame)).unwrap(); assert_ne!(batch.len(), 0); zmsgs_in.push(zmsg.clone()); @@ -413,7 +407,8 @@ mod tests { assert_ne!(batch.len(), 0); // Serialize with a frame - batch.encode((&zmsg, zmsg.channel, 1)).unwrap(); + frame.sn = 1; + batch.encode((&zmsg, &frame)).unwrap(); assert_ne!(batch.len(), 0); zmsgs_in.push(zmsg.clone()); } diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index b995d1e67b..43cd8d3946 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -32,8 +32,12 @@ use zenoh_codec::{WCodec, Zenoh080}; use zenoh_config::QueueSizeConf; use zenoh_core::zlock; use zenoh_protocol::{ - core::{Channel, Priority}, - transport::TransportMessage, + core::Priority, + transport::{ + fragment::FragmentHeader, + frame::{self, FrameHeader}, + TransportMessage, + }, zenoh::ZenohMessage, }; @@ -175,18 +179,19 @@ impl StageIn { // Lock the channel. We are the only one that will be writing on it. let mut tch = self.mutex.channel(msg.is_reliable()); - // Create the channel - let channel = Channel { + // Retrieve the next SN + let sn = tch.sn.get(); + + // The Frame + let frame = FrameHeader { reliability: msg.channel.reliability, - priority, + sn, + qos: frame::ext::QoS::new(priority), }; - // Retrieve the next SN - let mut sn = tch.sn.get(); - if let WError::NewFrame = e { // Attempt a serialization with a new frame - if batch.encode((&*msg, channel, sn)).is_ok() { + if batch.encode((&*msg, &frame)).is_ok() { zretok!(batch); }; } @@ -198,7 +203,7 @@ impl StageIn { } // Attempt a second serialization on fully empty batch - if batch.encode((&*msg, channel, sn)).is_ok() { + if batch.encode((&*msg, &frame)).is_ok() { zretok!(batch); }; @@ -215,6 +220,12 @@ impl StageIn { codec.write(&mut writer, &*msg).unwrap(); // Fragment the whole message + let mut fragment = FragmentHeader { + reliability: frame.reliability, + more: true, + sn, + qos: frame.qos, + }; let mut reader = self.fragbuf.reader(); while reader.can_read() { // Get the current serialization batch @@ -222,10 +233,10 @@ impl StageIn { batch = zgetbatch_rets!(true); // Serialize the message fragmnet - match batch.encode((&mut reader, channel, sn)) { + match batch.encode((&mut reader, &mut fragment)) { Ok(_) => { // Update the SN - sn = tch.sn.get(); + fragment.sn = tch.sn.get(); // Move the serialization batch into the OUT pipeline self.s_out.move_batch(batch); } @@ -743,7 +754,10 @@ mod tests { "Pipeline Flow [>>>]: Sending {num_msg} messages with payload size of {payload_size} bytes" ); for i in 0..num_msg { - println!("Pipeline Flow [>>>]: Pushed {} msgs", i + 1); + println!( + "Pipeline Flow [>>>]: Pushed {} msgs ({payload_size} bytes)", + i + 1 + ); queue.push_zenoh_message(message.clone()); } } diff --git a/io/zenoh-transport/tests/endpoints.rs b/io/zenoh-transport/tests/endpoints.rs index e921e96338..2dab74ac4c 100644 --- a/io/zenoh-transport/tests/endpoints.rs +++ b/io/zenoh-transport/tests/endpoints.rs @@ -80,7 +80,7 @@ async fn run(endpoints: &[EndPoint]) { for _ in 0..RUNS { // Create the listeners for e in endpoints.iter() { - println!("Add {e}"); + dbg!("Add {e}"); ztimeout!(sm.add_listener(e.clone())).unwrap(); } @@ -88,7 +88,7 @@ async fn run(endpoints: &[EndPoint]) { // Delete the listeners for e in endpoints.iter() { - println!("Del {e}"); + dbg!("Del {e}"); ztimeout!(sm.del_listener(e)).unwrap(); } diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index de657a6668..f5c41295fb 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -316,25 +316,25 @@ async fn authenticator_multilink(endpoint: &EndPoint) { .unwrap(); /* [1] */ - println!("\nTransport Authenticator PubKey [1a1]"); + dbg!("\nTransport Authenticator PubKey [1a1]"); // Add the locator on the router ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); - println!("Transport Authenticator PubKey [1a2]"); + dbg!("Transport Authenticator PubKey [1a2]"); let locators = router_manager.get_listeners(); - println!("Transport Authenticator PubKey [1a2]: {locators:?}"); + dbg!("Transport Authenticator PubKey [1a2]: {locators:?}"); assert_eq!(locators.len(), 1); /* [2a] */ // Open a first transport from client01 to the router // -> This should be accepted - println!("Transport Authenticator PubKey [2a1]"); + dbg!("Transport Authenticator PubKey [2a1]"); let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); assert_eq!(c_ses1.get_links().unwrap().len(), 1); /* [2b] */ // Open a second transport from client01 to the router // -> This should be accepted - println!("Transport Authenticator PubKey [2b1]"); + dbg!("Transport Authenticator PubKey [2b1]"); let c_ses1_tmp = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); assert_eq!(c_ses1, c_ses1_tmp); assert_eq!(c_ses1.get_links().unwrap().len(), 2); @@ -342,15 +342,15 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [2c] */ // Open a third transport from client01 to the router // -> This should be rejected - println!("Transport Authenticator PubKey [2c1]"); + dbg!("Transport Authenticator PubKey [2c1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [2c2]: {res:?}"); + dbg!("Transport Authenticator PubKey [2c2]: {res:?}"); assert!(res.is_err()); assert_eq!(c_ses1.get_links().unwrap().len(), 2); /* [2d] */ // Close the session - println!("Transport Authenticator PubKey [2d1]"); + dbg!("Transport Authenticator PubKey [2d1]"); ztimeout!(c_ses1.close()).unwrap(); ztimeout!(async { @@ -362,14 +362,14 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [3a] */ // Open a first transport from client02 to the router // -> This should be accepted - println!("Transport Authenticator PubKey [3a1]"); + dbg!("Transport Authenticator PubKey [3a1]"); let c_ses2 = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); assert_eq!(c_ses2.get_links().unwrap().len(), 1); /* [3b] */ // Open a second transport from client02 to the router // -> This should be accepted - println!("Transport Authenticator PubKey [3b1]"); + dbg!("Transport Authenticator PubKey [3b1]"); let c_ses2_tmp = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); assert_eq!(c_ses2, c_ses2_tmp); assert_eq!(c_ses2.get_links().unwrap().len(), 2); @@ -377,17 +377,17 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [3c] */ // Open a third transport from client02 to the router // -> This should be rejected - println!("Transport Authenticator PubKey [3c1]"); + dbg!("Transport Authenticator PubKey [3c1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [3c2]: {res:?}"); + dbg!("Transport Authenticator PubKey [3c2]: {res:?}"); assert!(res.is_err()); assert_eq!(c_ses2.get_links().unwrap().len(), 2); /* [3d] */ // Close the session - println!("Transport Authenticator PubKey [3d1]"); + dbg!("Transport Authenticator PubKey [3d1]"); let res = ztimeout!(c_ses2.close()); - println!("Transport Authenticator PubKey [3d2]: {res:?}"); + dbg!("Transport Authenticator PubKey [3d2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -399,9 +399,9 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [4a] */ // Open a first transport from client01_spoof to the router // -> This should be accepted - println!("Transport Authenticator PubKey [4a1]"); + dbg!("Transport Authenticator PubKey [4a1]"); let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [4a2]: {res:?}"); + dbg!("Transport Authenticator PubKey [4a2]: {res:?}"); assert!(res.is_ok()); let c_ses1_spoof = res.unwrap(); assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 1); @@ -409,26 +409,26 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [4b] */ // Open a second transport from client01_spoof to the router // -> This should be accepted - println!("Transport Authenticator PubKey [4b1]"); + dbg!("Transport Authenticator PubKey [4b1]"); let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [4b2]: {res:?}"); + dbg!("Transport Authenticator PubKey [4b2]: {res:?}"); assert!(res.is_ok()); assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); /* [4c] */ // Open a third transport from client02 to the router // -> This should be rejected - println!("Transport Authenticator PubKey [41]"); + dbg!("Transport Authenticator PubKey [41]"); let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [4c2]: {res:?}"); + dbg!("Transport Authenticator PubKey [4c2]: {res:?}"); assert!(res.is_err()); assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); /* [4d] */ // Close the session - println!("Transport Authenticator PubKey [4d1]"); + dbg!("Transport Authenticator PubKey [4d1]"); let res = ztimeout!(c_ses1_spoof.close()); - println!("Transport Authenticator PubKey [4d2]: {res:?}"); + dbg!("Transport Authenticator PubKey [4d2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -440,9 +440,9 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [5a] */ // Open a first transport from client01 to the router // -> This should be accepted - println!("Transport Authenticator PubKey [5a1]"); + dbg!("Transport Authenticator PubKey [5a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [5a2]: {res:?}"); + dbg!("Transport Authenticator PubKey [5a2]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); assert_eq!(c_ses1.get_links().unwrap().len(), 1); @@ -450,26 +450,26 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [5b] */ // Open a spoof transport from client01_spoof to the router // -> This should be rejected. Spoofing detected. - println!("Transport Authenticator PubKey [5b1]"); + dbg!("Transport Authenticator PubKey [5b1]"); let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [5b2]: {res:?}"); + dbg!("Transport Authenticator PubKey [5b2]: {res:?}"); assert!(res.is_err()); /* [5c] */ // Open a second transport from client01 to the router // -> This should be accepted - println!("Transport Authenticator PubKey [5a1]"); + dbg!("Transport Authenticator PubKey [5a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [5a2]: {res:?}"); + dbg!("Transport Authenticator PubKey [5a2]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); assert_eq!(c_ses1.get_links().unwrap().len(), 2); /* [5d] */ // Close the session - println!("Transport Authenticator PubKey [5d1]"); + dbg!("Transport Authenticator PubKey [5d1]"); let res = ztimeout!(c_ses1.close()); - println!("Transport Authenticator PubKey [5d2]: {res:?}"); + dbg!("Transport Authenticator PubKey [5d2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -480,9 +480,9 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [6] */ // Perform clean up of the open locators - println!("Transport Authenticator UserPassword [6a1]"); + dbg!("Transport Authenticator UserPassword [6a1]"); let res = ztimeout!(router_manager.del_listener(endpoint)); - println!("Transport Authenticator UserPassword [6a2]: {res:?}"); + dbg!("Transport Authenticator UserPassword [6a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -581,29 +581,29 @@ async fn authenticator_user_password(endpoint: &EndPoint) { .unwrap(); /* [1] */ - println!("\nTransport Authenticator UserPassword [1a1]"); + dbg!("\nTransport Authenticator UserPassword [1a1]"); // Add the locator on the router let res = ztimeout!(router_manager.add_listener(endpoint.clone())); - println!("Transport Authenticator UserPassword [1a1]: {res:?}"); + dbg!("Transport Authenticator UserPassword [1a1]: {res:?}"); assert!(res.is_ok()); - println!("Transport Authenticator UserPassword [1a2]"); + dbg!("Transport Authenticator UserPassword [1a2]"); let locators = router_manager.get_listeners(); - println!("Transport Authenticator UserPassword [1a2]: {locators:?}"); + dbg!("Transport Authenticator UserPassword [1a2]: {locators:?}"); assert_eq!(locators.len(), 1); /* [2] */ // Open a first transport from the client to the router // -> This should be accepted - println!("Transport Authenticator UserPassword [2a1]"); + dbg!("Transport Authenticator UserPassword [2a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [2a1]: {res:?}"); + dbg!("Transport Authenticator UserPassword [2a1]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); /* [3] */ - println!("Transport Authenticator UserPassword [3a1]"); + dbg!("Transport Authenticator UserPassword [3a1]"); let res = ztimeout!(c_ses1.close()); - println!("Transport Authenticator UserPassword [3a1]: {res:?}"); + dbg!("Transport Authenticator UserPassword [3a1]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -615,17 +615,17 @@ async fn authenticator_user_password(endpoint: &EndPoint) { /* [4] */ // Open a second transport from the client to the router // -> This should be rejected - println!("Transport Authenticator UserPassword [4a1]"); + dbg!("Transport Authenticator UserPassword [4a1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [4a1]: {res:?}"); + dbg!("Transport Authenticator UserPassword [4a1]: {res:?}"); assert!(res.is_err()); /* [5] */ // Open a third transport from the client to the router // -> This should be accepted - println!("Transport Authenticator UserPassword [5a1]"); + dbg!("Transport Authenticator UserPassword [5a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [5a1]: {res:?}"); + dbg!("Transport Authenticator UserPassword [5a1]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); @@ -635,28 +635,28 @@ async fn authenticator_user_password(endpoint: &EndPoint) { assert!(res.is_ok()); // Open a fourth transport from the client to the router // -> This should be accepted - println!("Transport Authenticator UserPassword [6a1]"); + dbg!("Transport Authenticator UserPassword [6a1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [6a1]: {res:?}"); + dbg!("Transport Authenticator UserPassword [6a1]: {res:?}"); assert!(res.is_ok()); let c_ses2 = res.unwrap(); /* [7] */ // Open a fourth transport from the client to the router // -> This should be rejected - println!("Transport Authenticator UserPassword [7a1]"); + dbg!("Transport Authenticator UserPassword [7a1]"); let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [7a1]: {res:?}"); + dbg!("Transport Authenticator UserPassword [7a1]: {res:?}"); assert!(res.is_err()); /* [8] */ - println!("Transport Authenticator UserPassword [8a1]"); + dbg!("Transport Authenticator UserPassword [8a1]"); let res = ztimeout!(c_ses1.close()); - println!("Transport Authenticator UserPassword [8a1]: {res:?}"); + dbg!("Transport Authenticator UserPassword [8a1]: {res:?}"); assert!(res.is_ok()); - println!("Transport Authenticator UserPassword [8a2]"); + dbg!("Transport Authenticator UserPassword [8a2]"); let res = ztimeout!(c_ses2.close()); - println!("Transport Authenticator UserPassword [8a2]: {res:?}"); + dbg!("Transport Authenticator UserPassword [8a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -667,9 +667,9 @@ async fn authenticator_user_password(endpoint: &EndPoint) { /* [9] */ // Perform clean up of the open locators - println!("Transport Authenticator UserPassword [9a1]"); + dbg!("Transport Authenticator UserPassword [9a1]"); let res = ztimeout!(router_manager.del_listener(endpoint)); - println!("Transport Authenticator UserPassword [9a2]: {res:?}"); + dbg!("Transport Authenticator UserPassword [9a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -716,30 +716,30 @@ async fn authenticator_shared_memory(endpoint: &EndPoint) { .unwrap(); /* [1] */ - println!("\nTransport Authenticator SharedMemory [1a1]"); + dbg!("\nTransport Authenticator SharedMemory [1a1]"); // Add the locator on the router let res = ztimeout!(router_manager.add_listener(endpoint.clone())); - println!("Transport Authenticator SharedMemory [1a1]: {res:?}"); + dbg!("Transport Authenticator SharedMemory [1a1]: {res:?}"); assert!(res.is_ok()); - println!("Transport Authenticator SharedMemory [1a2]"); + dbg!("Transport Authenticator SharedMemory [1a2]"); let locators = router_manager.get_listeners(); - println!("Transport Authenticator SharedMemory 1a2]: {locators:?}"); + dbg!("Transport Authenticator SharedMemory 1a2]: {locators:?}"); assert_eq!(locators.len(), 1); /* [2] */ // Open a transport from the client to the router // -> This should be accepted - println!("Transport Authenticator SharedMemory [2a1]"); + dbg!("Transport Authenticator SharedMemory [2a1]"); let res = ztimeout!(client_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator SharedMemory [2a1]: {res:?}"); + dbg!("Transport Authenticator SharedMemory [2a1]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); assert!(c_ses1.is_shm().unwrap()); /* [3] */ - println!("Transport Authenticator SharedMemory [3a1]"); + dbg!("Transport Authenticator SharedMemory [3a1]"); let res = ztimeout!(c_ses1.close()); - println!("Transport Authenticator SharedMemory [3a1]: {res:?}"); + dbg!("Transport Authenticator SharedMemory [3a1]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -750,9 +750,9 @@ async fn authenticator_shared_memory(endpoint: &EndPoint) { /* [4] */ // Perform clean up of the open locators - println!("Transport Authenticator SharedMemory [4a1]"); + dbg!("Transport Authenticator SharedMemory [4a1]"); let res = ztimeout!(router_manager.del_listener(endpoint)); - println!("Transport Authenticator SharedMemory [4a2]: {res:?}"); + dbg!("Transport Authenticator SharedMemory [4a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index e2207e33af..b86a06be09 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -138,11 +138,11 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Adding endpoint {e:?}: {res:?}"); + dbg!("[Transport Peer 01a] => Adding endpoint {e:?}: {res:?}"); assert!(res.is_ok()); } let locs = peer01_manager.get_listeners(); - println!("[Transport Peer 01b] => Getting endpoints: {c_end01:?} {locs:?}"); + dbg!("[Transport Peer 01b] => Getting endpoints: {c_end01:?} {locs:?}"); assert_eq!(c_end01.len(), locs.len()); // Open the transport with the second peer @@ -152,11 +152,11 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting for opening transport"); + dbg!("[Transport Peer 01c] => Waiting for opening transport"); // Syncrhonize before opening the transports ztimeout!(cc_barow.wait()); let res = ztimeout!(c_p01m.open_transport(c_end.clone())); - println!("[Transport Peer 01d] => Opening transport with {c_end:?}: {res:?}"); + dbg!("[Transport Peer 01d] => Opening transport with {c_end:?}: {res:?}"); assert!(res.is_ok()); // Syncrhonize after opening the transports @@ -166,7 +166,7 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting... OK"); + dbg!("[Transport Peer 01e] => Waiting... OK"); // Verify that the transport has been correctly open assert_eq!(peer01_manager.get_transports().len(), 1); @@ -200,13 +200,13 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting... OK"); + dbg!("[Transport Peer 01f] => Waiting... OK"); for i in 0..MSG_COUNT { - println!("[Transport Peer 01g] Scheduling message {i}"); + dbg!("[Transport Peer 01g] Scheduling message {}", i); s02.schedule(message.clone()).unwrap(); } - println!("[Transport Peer 01g] => Scheduling OK"); + dbg!("[Transport Peer 01g] => Scheduling OK"); // Wait for the messages to arrive to the other side ztimeout!(async { @@ -218,9 +218,9 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Closing {s02:?}..."); + dbg!("[Transport Peer 01h] => Closing {s02:?}..."); let res = ztimeout!(s02.close()); - println!("[Transport Peer 01l] => Closing {s02:?}: {res:?}"); + dbg!("[Transport Peer 01l] => Closing {s02:?}: {res:?}"); assert!(res.is_ok()); // Close the transport @@ -238,11 +238,11 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Adding endpoint {e:?}: {res:?}"); + dbg!("[Transport Peer 02a] => Adding endpoint {e:?}: {res:?}"); assert!(res.is_ok()); } let locs = peer02_manager.get_listeners(); - println!("[Transport Peer 02b] => Getting endpoints: {c_end02:?} {locs:?}"); + dbg!("[Transport Peer 02b] => Getting endpoints: {c_end02:?} {locs:?}"); assert_eq!(c_end02.len(), locs.len()); // Open the transport with the first peer @@ -252,12 +252,12 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting for opening transport"); + dbg!("[Transport Peer 02c] => Waiting for opening transport"); // Syncrhonize before opening the transports ztimeout!(cc_barow.wait()); let res = ztimeout!(c_p02m.open_transport(c_end.clone())); - println!("[Transport Peer 02d] => Opening transport with {c_end:?}: {res:?}"); + dbg!("[Transport Peer 02d] => Opening transport with {c_end:?}: {res:?}"); assert!(res.is_ok()); // Syncrhonize after opening the transports @@ -269,7 +269,7 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Transports: {:?}", peer02_manager.get_transports() ); @@ -304,13 +304,13 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting... OK"); + dbg!("[Transport Peer 02f] => Waiting... OK"); for i in 0..MSG_COUNT { - println!("[Transport Peer 02g] Scheduling message {i}"); + dbg!("[Transport Peer 02g] Scheduling message {}", i); s01.schedule(message.clone()).unwrap(); } - println!("[Transport Peer 02g] => Scheduling OK"); + dbg!("[Transport Peer 02g] => Scheduling OK"); // Wait for the messages to arrive to the other side ztimeout!(async { @@ -322,18 +322,18 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Closing {s01:?}..."); + dbg!("[Transport Peer 02h] => Closing {s01:?}..."); let res = ztimeout!(s01.close()); - println!("[Transport Peer 02l] => Closing {s01:?}: {res:?}"); + dbg!("[Transport Peer 02l] => Closing {s01:?}: {res:?}"); assert!(res.is_ok()); // Close the transport ztimeout!(peer02_manager.close()); }); - println!("[Transport Current 01] => Starting..."); + dbg!("[Transport Current 01] => Starting..."); peer01_task.join(peer02_task).await; - println!("[Transport Current 02] => ...Stopped"); + dbg!("[Transport Current 02] => ...Stopped"); // Wait a little bit task::sleep(SLEEP).await; diff --git a/io/zenoh-transport/tests/unicast_conduits.rs b/io/zenoh-transport/tests/unicast_conduits.rs index 52f7e6f051..0e0afc5787 100644 --- a/io/zenoh-transport/tests/unicast_conduits.rs +++ b/io/zenoh-transport/tests/unicast_conduits.rs @@ -188,14 +188,14 @@ async fn open_transport( // Create the listener on the router for e in endpoints.iter() { - println!("Add locator: {e}"); + dbg!("Add locator: {e}"); let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); } // Create an empty transport with the client // Open transport -> This should be accepted for e in endpoints.iter() { - println!("Opening transport with {e}"); + dbg!("Opening transport with {e}"); let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); } @@ -221,7 +221,7 @@ async fn close_transport( for e in endpoints.iter() { let _ = write!(ee, "{e} "); } - println!("Closing transport with {ee}"); + dbg!("Closing transport with {ee}"); ztimeout!(client_transport.close()).unwrap(); ztimeout!(async { @@ -232,7 +232,7 @@ async fn close_transport( // Stop the locators on the manager for e in endpoints.iter() { - println!("Del locator: {e}"); + dbg!("Del locator: {e}"); ztimeout!(router_manager.del_listener(e)).unwrap(); } @@ -268,7 +268,7 @@ async fn single_run( reply_context, ); - println!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); + dbg!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); for _ in 0..MSG_COUNT { client_transport.schedule(message.clone()).unwrap(); } diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index 59e2c6d8aa..8a46d347b6 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -55,12 +55,12 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { .unwrap(); // Create the listener on the router - println!("Add locator: {endpoint}"); + dbg!("Add locator: {endpoint}"); let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); // Create an empty transport with the client // Open transport -> This should be accepted - println!("Opening transport with {endpoint}"); + dbg!("Opening transport with {endpoint}"); let _ = ztimeout!(client_manager.open_transport(endpoint.clone())).unwrap(); let client_transport = client_manager.get_transport(&router_id).unwrap(); @@ -81,7 +81,7 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { reply_context, ); - println!( + dbg!( "Sending message of {msg_size} bytes while defragmentation buffer size is {MSG_DEFRAG_BUF} bytes" ); client_transport.schedule(message.clone()).unwrap(); @@ -101,7 +101,7 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { }); // Stop the locators on the manager - println!("Del locator: {endpoint}"); + dbg!("Del locator: {endpoint}"); ztimeout!(router_manager.del_listener(endpoint)).unwrap(); // Wait a little bit diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index 7fa1a6569c..c343e86027 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -177,10 +177,10 @@ async fn transport_intermittent(endpoint: &EndPoint) { /* [1] */ // Add a listener to the router - println!("\nTransport Intermittent [1a1]"); + dbg!("\nTransport Intermittent [1a1]"); let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); let locators = router_manager.get_listeners(); - println!("Transport Intermittent [1a2]: {locators:?}"); + dbg!("Transport Intermittent [1a2]: {locators:?}"); assert_eq!(locators.len(), 1); /* [2] */ @@ -241,7 +241,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { }); /* [4] */ - println!("Transport Intermittent [4a1]"); + dbg!("Transport Intermittent [4a1]"); let c_router_manager = router_manager.clone(); ztimeout!(task::spawn_blocking(move || { // Create the message to send @@ -272,7 +272,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { let mut count = 0; while count < MSG_COUNT { if count == ticks[0] { - println!("\nScheduled {count}"); + dbg!("\nScheduled {count}"); ticks.remove(0); } let transports = c_router_manager.get_transports(); @@ -304,36 +304,36 @@ async fn transport_intermittent(endpoint: &EndPoint) { ztimeout!(c3_handle.cancel()); // Check that client01 received all the messages - println!("Transport Intermittent [4b1]"); + dbg!("Transport Intermittent [4b1]"); ztimeout!(async { loop { let c = counter.load(Ordering::Acquire); if c == MSG_COUNT { break; } - println!("Transport Intermittent [4b2]: Received {c}/{MSG_COUNT}"); + dbg!("Transport Intermittent [4b2]: Received {c}/{MSG_COUNT}"); task::sleep(SLEEP).await; } }); /* [5] */ // Close the open transport on the client - println!("Transport Intermittent [5a1]"); + dbg!("Transport Intermittent [5a1]"); for s in client01_manager.get_transports().iter() { ztimeout!(s.close()).unwrap(); } - println!("Transport Intermittent [5a2]"); + dbg!("Transport Intermittent [5a2]"); for s in client02_manager.get_transports().iter() { ztimeout!(s.close()).unwrap(); } - println!("Transport Intermittent [5a3]"); + dbg!("Transport Intermittent [5a3]"); for s in client03_manager.get_transports().iter() { ztimeout!(s.close()).unwrap(); } /* [6] */ // Verify that the transport has been closed also on the router - println!("Transport Intermittent [6a1]"); + dbg!("Transport Intermittent [6a1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -346,7 +346,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { /* [7] */ // Perform clean up of the open locators - println!("\nTransport Intermittent [7a1]"); + dbg!("\nTransport Intermittent [7a1]"); ztimeout!(router_manager.del_listener(endpoint)).unwrap(); // Wait a little bit diff --git a/io/zenoh-transport/tests/unicast_openclose.rs b/io/zenoh-transport/tests/unicast_openclose.rs index 0d3494e8bf..b27616b5d7 100644 --- a/io/zenoh-transport/tests/unicast_openclose.rs +++ b/io/zenoh-transport/tests/unicast_openclose.rs @@ -107,37 +107,37 @@ async fn openclose_transport(endpoint: &EndPoint) { .unwrap(); /* [1] */ - println!("\nTransport Open Close [1a1]"); + dbg!("\nTransport Open Close [1a1]"); // Add the locator on the router let res = ztimeout!(router_manager.add_listener(endpoint.clone())); - println!("Transport Open Close [1a1]: {res:?}"); + dbg!("Transport Open Close [1a1]: {res:?}"); assert!(res.is_ok()); - println!("Transport Open Close [1a2]"); + dbg!("Transport Open Close [1a2]"); let locators = router_manager.get_listeners(); - println!("Transport Open Close [1a2]: {locators:?}"); + dbg!("Transport Open Close [1a2]: {locators:?}"); assert_eq!(locators.len(), 1); // Open a first transport from the client to the router // -> This should be accepted let mut links_num = 1; - println!("Transport Open Close [1c1]"); + dbg!("Transport Open Close [1c1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [1c2]: {res:?}"); + dbg!("Transport Open Close [1c2]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); - println!("Transport Open Close [1d1]"); + dbg!("Transport Open Close [1d1]"); let transports = client01_manager.get_transports(); - println!("Transport Open Close [1d2]: {transports:?}"); + dbg!("Transport Open Close [1d2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); - println!("Transport Open Close [1e1]"); + dbg!("Transport Open Close [1e1]"); let links = c_ses1.get_links().unwrap(); - println!("Transport Open Close [1e2]: {links:?}"); + dbg!("Transport Open Close [1e2]: {links:?}"); assert_eq!(links.len(), links_num); // Verify that the transport has been open on the router - println!("Transport Open Close [1f1]"); + dbg!("Transport Open Close [1f1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -161,24 +161,24 @@ async fn openclose_transport(endpoint: &EndPoint) { // -> This should be accepted links_num = 2; - println!("\nTransport Open Close [2a1]"); + dbg!("\nTransport Open Close [2a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [2a2]: {res:?}"); + dbg!("Transport Open Close [2a2]: {res:?}"); assert!(res.is_ok()); let c_ses2 = res.unwrap(); - println!("Transport Open Close [2b1]"); + dbg!("Transport Open Close [2b1]"); let transports = client01_manager.get_transports(); - println!("Transport Open Close [2b2]: {transports:?}"); + dbg!("Transport Open Close [2b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses2.get_zid().unwrap(), router_id); - println!("Transport Open Close [2c1]"); + dbg!("Transport Open Close [2c1]"); let links = c_ses2.get_links().unwrap(); - println!("Transport Open Close [2c2]: {links:?}"); + dbg!("Transport Open Close [2c2]: {links:?}"); assert_eq!(links.len(), links_num); assert_eq!(c_ses2, c_ses1); // Verify that the transport has been open on the router - println!("Transport Open Close [2d1]"); + dbg!("Transport Open Close [2d1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -198,22 +198,22 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [3] */ // Open transport -> This should be rejected because // of the maximum limit of links per transport - println!("\nTransport Open Close [3a1]"); + dbg!("\nTransport Open Close [3a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [3a2]: {res:?}"); + dbg!("Transport Open Close [3a2]: {res:?}"); assert!(res.is_err()); - println!("Transport Open Close [3b1]"); + dbg!("Transport Open Close [3b1]"); let transports = client01_manager.get_transports(); - println!("Transport Open Close [3b2]: {transports:?}"); + dbg!("Transport Open Close [3b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); - println!("Transport Open Close [3c1]"); + dbg!("Transport Open Close [3c1]"); let links = c_ses1.get_links().unwrap(); - println!("Transport Open Close [3c2]: {links:?}"); + dbg!("Transport Open Close [3c2]: {links:?}"); assert_eq!(links.len(), links_num); // Verify that the transport has not been open on the router - println!("Transport Open Close [3d1]"); + dbg!("Transport Open Close [3d1]"); ztimeout!(async { task::sleep(SLEEP).await; let transports = router_manager.get_transports(); @@ -228,17 +228,17 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [4] */ // Close the open transport on the client - println!("\nTransport Open Close [4a1]"); + dbg!("\nTransport Open Close [4a1]"); let res = ztimeout!(c_ses1.close()); - println!("Transport Open Close [4a2]: {res:?}"); + dbg!("Transport Open Close [4a2]: {res:?}"); assert!(res.is_ok()); - println!("Transport Open Close [4b1]"); + dbg!("Transport Open Close [4b1]"); let transports = client01_manager.get_transports(); - println!("Transport Open Close [4b2]: {transports:?}"); + dbg!("Transport Open Close [4b2]: {transports:?}"); assert_eq!(transports.len(), 0); // Verify that the transport has been closed also on the router - println!("Transport Open Close [4c1]"); + dbg!("Transport Open Close [4c1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -257,23 +257,23 @@ async fn openclose_transport(endpoint: &EndPoint) { // the number of links should be back to 0 links_num = 1; - println!("\nTransport Open Close [5a1]"); + dbg!("\nTransport Open Close [5a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [5a2]: {res:?}"); + dbg!("Transport Open Close [5a2]: {res:?}"); assert!(res.is_ok()); let c_ses3 = res.unwrap(); - println!("Transport Open Close [5b1]"); + dbg!("Transport Open Close [5b1]"); let transports = client01_manager.get_transports(); - println!("Transport Open Close [5b2]: {transports:?}"); + dbg!("Transport Open Close [5b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses3.get_zid().unwrap(), router_id); - println!("Transport Open Close [5c1]"); + dbg!("Transport Open Close [5c1]"); let links = c_ses3.get_links().unwrap(); - println!("Transport Open Close [5c2]: {links:?}"); + dbg!("Transport Open Close [5c2]: {links:?}"); assert_eq!(links.len(), links_num); // Verify that the transport has been open on the router - println!("Transport Open Close [5d1]"); + dbg!("Transport Open Close [5d1]"); ztimeout!(async { task::sleep(SLEEP).await; let transports = router_manager.get_transports(); @@ -289,17 +289,17 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [6] */ // Open transport -> This should be rejected because // of the maximum limit of transports - println!("\nTransport Open Close [6a1]"); + dbg!("\nTransport Open Close [6a1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [6a2]: {res:?}"); + dbg!("Transport Open Close [6a2]: {res:?}"); assert!(res.is_err()); - println!("Transport Open Close [6b1]"); + dbg!("Transport Open Close [6b1]"); let transports = client02_manager.get_transports(); - println!("Transport Open Close [6b2]: {transports:?}"); + dbg!("Transport Open Close [6b2]: {transports:?}"); assert_eq!(transports.len(), 0); // Verify that the transport has not been open on the router - println!("Transport Open Close [6c1]"); + dbg!("Transport Open Close [6c1]"); ztimeout!(async { task::sleep(SLEEP).await; let transports = router_manager.get_transports(); @@ -314,17 +314,17 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [7] */ // Close the open transport on the client - println!("\nTransport Open Close [7a1]"); + dbg!("\nTransport Open Close [7a1]"); let res = ztimeout!(c_ses3.close()); - println!("Transport Open Close [7a2]: {res:?}"); + dbg!("Transport Open Close [7a2]: {res:?}"); assert!(res.is_ok()); - println!("Transport Open Close [7b1]"); + dbg!("Transport Open Close [7b1]"); let transports = client01_manager.get_transports(); - println!("Transport Open Close [7b2]: {transports:?}"); + dbg!("Transport Open Close [7b2]: {transports:?}"); assert_eq!(transports.len(), 0); // Verify that the transport has been closed also on the router - println!("Transport Open Close [7c1]"); + dbg!("Transport Open Close [7c1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -340,22 +340,22 @@ async fn openclose_transport(endpoint: &EndPoint) { // the number of transports should be back to 0 links_num = 1; - println!("\nTransport Open Close [8a1]"); + dbg!("\nTransport Open Close [8a1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [8a2]: {res:?}"); + dbg!("Transport Open Close [8a2]: {res:?}"); assert!(res.is_ok()); let c_ses4 = res.unwrap(); - println!("Transport Open Close [8b1]"); + dbg!("Transport Open Close [8b1]"); let transports = client02_manager.get_transports(); - println!("Transport Open Close [8b2]: {transports:?}"); + dbg!("Transport Open Close [8b2]: {transports:?}"); assert_eq!(transports.len(), 1); - println!("Transport Open Close [8c1]"); + dbg!("Transport Open Close [8c1]"); let links = c_ses4.get_links().unwrap(); - println!("Transport Open Close [8c2]: {links:?}"); + dbg!("Transport Open Close [8c2]: {links:?}"); assert_eq!(links.len(), links_num); // Verify that the transport has been open on the router - println!("Transport Open Close [8d1]"); + dbg!("Transport Open Close [8d1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -375,17 +375,17 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [9] */ // Close the open transport on the client - println!("Transport Open Close [9a1]"); + dbg!("Transport Open Close [9a1]"); let res = ztimeout!(c_ses4.close()); - println!("Transport Open Close [9a2]: {res:?}"); + dbg!("Transport Open Close [9a2]: {res:?}"); assert!(res.is_ok()); - println!("Transport Open Close [9b1]"); + dbg!("Transport Open Close [9b1]"); let transports = client02_manager.get_transports(); - println!("Transport Open Close [9b2]: {transports:?}"); + dbg!("Transport Open Close [9b2]: {transports:?}"); assert_eq!(transports.len(), 0); // Verify that the transport has been closed also on the router - println!("Transport Open Close [9c1]"); + dbg!("Transport Open Close [9c1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -398,9 +398,9 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [10] */ // Perform clean up of the open locators - println!("\nTransport Open Close [10a1]"); + dbg!("\nTransport Open Close [10a1]"); let res = ztimeout!(router_manager.del_listener(endpoint)); - println!("Transport Open Close [10a2]: {res:?}"); + dbg!("Transport Open Close [10a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index ba16b1558e..0ee1a8cac4 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -128,7 +128,7 @@ mod tests { } async fn run(endpoint: &EndPoint) { - println!("Transport SHM [0a]: {endpoint:?}"); + dbg!("Transport SHM [0a]: {endpoint:?}"); // Define client and router IDs let peer_shm01 = ZenohId::try_from([1]).unwrap(); @@ -175,29 +175,29 @@ mod tests { .unwrap(); // Create the listener on the peer - println!("Transport SHM [1a]"); + dbg!("Transport SHM [1a]"); let _ = ztimeout!(peer_shm01_manager .add_listener(endpoint.clone()) .timeout(TIMEOUT)) .unwrap(); // Create a transport with the peer - println!("Transport SHM [1b]"); + dbg!("Transport SHM [1b]"); let _ = ztimeout!(peer_shm02_manager.open_transport(endpoint.clone())).unwrap(); // Create a transport with the peer - println!("Transport SHM [1c]"); + dbg!("Transport SHM [1c]"); let _ = ztimeout!(peer_net01_manager.open_transport(endpoint.clone())).unwrap(); // Retrieve the transports - println!("Transport SHM [2a]"); + dbg!("Transport SHM [2a]"); let peer_shm02_transport = peer_shm01_manager.get_transport(&peer_shm02).unwrap(); - println!("Transport SHM [2b]"); + dbg!("Transport SHM [2b]"); let peer_net01_transport = peer_shm01_manager.get_transport(&peer_net01).unwrap(); // Send the message - println!("Transport SHM [3a]"); + dbg!("Transport SHM [3a]"); // The msg count for (msg_count, _) in (0..MSG_COUNT).enumerate() { // Create the message to send @@ -241,7 +241,7 @@ mod tests { task::sleep(SLEEP).await; // Wait for the messages to arrive to the other side - println!("Transport SHM [3b]"); + dbg!("Transport SHM [3b]"); ztimeout!(async { while peer_shm02_handler.get_count() != MSG_COUNT { task::sleep(SLEEP).await; @@ -249,7 +249,7 @@ mod tests { }); // Send the message - println!("Transport SHM [4a]"); + dbg!("Transport SHM [4a]"); // The msg count for (msg_count, _) in (0..MSG_COUNT).enumerate() { // Create the message to send @@ -292,7 +292,7 @@ mod tests { task::sleep(SLEEP).await; // Wait for the messages to arrive to the other side - println!("Transport SHM [4b]"); + dbg!("Transport SHM [4b]"); ztimeout!(async { while peer_net01_handler.get_count() != MSG_COUNT { task::sleep(SLEEP).await; @@ -303,10 +303,10 @@ mod tests { task::sleep(SLEEP).await; // Close the transports - println!("Transport SHM [5a]"); + dbg!("Transport SHM [5a]"); ztimeout!(peer_shm02_transport.close()).unwrap(); - println!("Transport SHM [5b]"); + dbg!("Transport SHM [5b]"); ztimeout!(peer_net01_transport.close()).unwrap(); ztimeout!(async { @@ -316,7 +316,7 @@ mod tests { }); // Delete the listener - println!("Transport SHM [6a]"); + dbg!("Transport SHM [6a]"); ztimeout!(peer_shm01_manager.del_listener(endpoint)).unwrap(); // Wait a little bit diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index 8bd52a3596..e0f78d70eb 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -92,11 +92,11 @@ mod tests { reply_context, ); - println!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); + dbg!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); for _ in 0..MSG_COUNT { transport.handle_message(message.clone()).unwrap(); } - println!("[Simultaneous {}] ... sent {}", self.zid, MSG_COUNT); + dbg!("[Simultaneous {}] ... sent {}", self.zid, MSG_COUNT); let mh = Arc::new(MHPeer::new(self.count.clone())); Ok(mh) @@ -157,21 +157,21 @@ mod tests { // Add the endpoints on the peer01 for e in endpoint01.iter() { let res = ztimeout!(peer01_manager.add_listener(e.clone())); - println!("[Simultaneous 01a] => Adding endpoint {e:?}: {res:?}"); + dbg!("[Simultaneous 01a] => Adding endpoint {e:?}: {res:?}"); assert!(res.is_ok()); } let locs = peer01_manager.get_listeners(); - println!("[Simultaneous 01b] => Getting endpoints: {endpoint01:?} {locs:?}"); + dbg!("[Simultaneous 01b] => Getting endpoints: {endpoint01:?} {locs:?}"); assert_eq!(endpoint01.len(), locs.len()); // Add the endpoints on peer02 for e in endpoint02.iter() { let res = ztimeout!(peer02_manager.add_listener(e.clone())); - println!("[Simultaneous 02a] => Adding endpoint {e:?}: {res:?}"); + dbg!("[Simultaneous 02a] => Adding endpoint {e:?}: {res:?}"); assert!(res.is_ok()); } let locs = peer02_manager.get_listeners(); - println!("[Simultaneous 02b] => Getting endpoints: {endpoint02:?} {locs:?}"); + dbg!("[Simultaneous 02b] => Getting endpoints: {endpoint02:?} {locs:?}"); assert_eq!(endpoint02.len(), locs.len()); // Endpoints @@ -184,13 +184,13 @@ mod tests { // Open the transport with the second peer // These open should succeed for e in c_ep02.iter() { - println!("[Simultaneous 01c] => Opening transport with {e:?}..."); + dbg!("[Simultaneous 01c] => Opening transport with {e:?}..."); let _ = ztimeout!(c_p01m.open_transport(e.clone())).unwrap(); } // These open should fails for e in c_ep02.iter() { - println!("[Simultaneous 01d] => Exceeding transport with {e:?}..."); + dbg!("[Simultaneous 01d] => Exceeding transport with {e:?}..."); let res = ztimeout!(c_p01m.open_transport(e.clone())); assert!(res.is_err()); } @@ -201,7 +201,7 @@ mod tests { let mut tp02 = None; while tp02.is_none() { task::sleep(SLEEP).await; - println!( + dbg!( "[Simultaneous 01e] => Transports: {:?}", peer01_manager.get_transports() ); @@ -218,7 +218,7 @@ mod tests { while tl02.len() != expected { task::sleep(SLEEP).await; tl02 = tp02.get_links().unwrap(); - println!("[Simultaneous 01f] => Links {}/{}", tl02.len(), expected); + dbg!("[Simultaneous 01f] => Links {}/{}", tl02.len(), expected); } }); @@ -228,7 +228,7 @@ mod tests { while check != MSG_COUNT { task::sleep(SLEEP).await; check = peer_sh01.get_count(); - println!("[Simultaneous 01g] => Received {check:?}/{MSG_COUNT:?}"); + dbg!("[Simultaneous 01g] => Received {check:?}/{MSG_COUNT:?}"); } }); }); @@ -239,13 +239,13 @@ mod tests { // Open the transport with the first peer // These open should succeed for e in c_ep01.iter() { - println!("[Simultaneous 02c] => Opening transport with {e:?}..."); + dbg!("[Simultaneous 02c] => Opening transport with {e:?}..."); let _ = ztimeout!(c_p02m.open_transport(e.clone())).unwrap(); } // These open should fails for e in c_ep01.iter() { - println!("[Simultaneous 02d] => Exceeding transport with {e:?}..."); + dbg!("[Simultaneous 02d] => Exceeding transport with {e:?}..."); let res = ztimeout!(c_p02m.open_transport(e.clone())); assert!(res.is_err()); } @@ -257,7 +257,7 @@ mod tests { let mut tp01 = None; while tp01.is_none() { task::sleep(SLEEP).await; - println!( + dbg!( "[Simultaneous 02e] => Transports: {:?}", peer02_manager.get_transports() ); @@ -273,7 +273,7 @@ mod tests { while tl01.len() != expected { task::sleep(SLEEP).await; tl01 = tp01.get_links().unwrap(); - println!("[Simultaneous 02f] => Links {}/{}", tl01.len(), expected); + dbg!("[Simultaneous 02f] => Links {}/{}", tl01.len(), expected); } }); @@ -283,14 +283,14 @@ mod tests { while check != MSG_COUNT { task::sleep(SLEEP).await; check = peer_sh02.get_count(); - println!("[Simultaneous 02g] => Received {check:?}/{MSG_COUNT:?}"); + dbg!("[Simultaneous 02g] => Received {check:?}/{MSG_COUNT:?}"); } }); }); - println!("[Simultaneous] => Waiting for peer01 and peer02 tasks..."); + dbg!("[Simultaneous] => Waiting for peer01 and peer02 tasks..."); peer01_task.join(peer02_task).await; - println!("[Simultaneous] => Waiting for peer01 and peer02 tasks... DONE\n"); + dbg!("[Simultaneous] => Waiting for peer01 and peer02 tasks... DONE\n"); // Wait a little bit task::sleep(SLEEP).await; diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 05e5faf06a..da8eddd96f 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -337,7 +337,7 @@ async fn open_transport( // Create the listener on the router for e in server_endpoints.iter() { - println!("Add endpoint: {e}"); + dbg!("Add endpoint: {e}"); let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); } @@ -353,7 +353,7 @@ async fn open_transport( // Create an empty transport with the client // Open transport -> This should be accepted for e in client_endpoints.iter() { - println!("Opening transport with {e}"); + dbg!("Opening transport with {e}"); let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); } @@ -379,7 +379,7 @@ async fn close_transport( for e in endpoints.iter() { let _ = write!(ee, "{e} "); } - println!("Closing transport with {ee}"); + dbg!("Closing transport with {ee}"); ztimeout!(client_transport.close()).unwrap(); ztimeout!(async { @@ -390,7 +390,7 @@ async fn close_transport( // Stop the locators on the manager for e in endpoints.iter() { - println!("Del locator: {e}"); + dbg!("Del locator: {e}"); ztimeout!(router_manager.del_listener(e)).unwrap(); } @@ -432,7 +432,7 @@ async fn test_transport( reply_context, ); - println!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); + dbg!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); for _ in 0..MSG_COUNT { client_transport.schedule(message.clone()).unwrap(); } @@ -464,9 +464,12 @@ async fn run_single( channel: Channel, msg_size: usize, ) { - println!( + dbg!( "\n>>> Running test for: {:?}, {:?}, {:?}, {}", - client_endpoints, server_endpoints, channel, msg_size + client_endpoints, + server_endpoints, + channel, + msg_size ); #[allow(unused_variables)] // Used when stats feature is enabled @@ -484,13 +487,13 @@ async fn run_single( #[cfg(feature = "stats")] { let c_stats = client_transport.get_stats().unwrap(); - println!("\tClient: {c_stats:?}"); + dbg!("\tClient: {c_stats:?}"); let r_stats = router_manager .get_transport_unicast(&client_manager.config.zid) .unwrap() .get_stats() .unwrap(); - println!("\tRouter: {r_stats:?}"); + dbg!("\tRouter: {r_stats:?}"); } close_transport( diff --git a/zenoh/tests/session.rs b/zenoh/tests/session.rs index d980155a2e..539b2dffa8 100644 --- a/zenoh/tests/session.rs +++ b/zenoh/tests/session.rs @@ -39,7 +39,7 @@ async fn open_session(endpoints: &[&str]) -> (Session, Session) { .map(|e| e.parse().unwrap()) .collect::>(); config.scouting.multicast.set_enabled(Some(false)).unwrap(); - println!("[ ][01a] Opening peer01 session"); + dbg!("[ ][01a] Opening peer01 session"); let peer01 = ztimeout!(zenoh::open(config).res_async()).unwrap(); let mut config = config::peer(); @@ -48,16 +48,16 @@ async fn open_session(endpoints: &[&str]) -> (Session, Session) { .map(|e| e.parse().unwrap()) .collect::>(); config.scouting.multicast.set_enabled(Some(false)).unwrap(); - println!("[ ][02a] Opening peer02 session"); + dbg!("[ ][02a] Opening peer02 session"); let peer02 = ztimeout!(zenoh::open(config).res_async()).unwrap(); (peer01, peer02) } async fn close_session(peer01: Session, peer02: Session) { - println!("[ ][01d] Closing peer02 session"); + dbg!("[ ][01d] Closing peer02 session"); ztimeout!(peer01.close().res_async()).unwrap(); - println!("[ ][02d] Closing peer02 session"); + dbg!("[ ][02d] Closing peer02 session"); ztimeout!(peer02.close().res_async()).unwrap(); } @@ -70,7 +70,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { msgs.store(0, Ordering::SeqCst); // Subscribe to data - println!("[PS][01b] Subscribing on peer01 session"); + dbg!("[PS][01b] Subscribing on peer01 session"); let c_msgs = msgs.clone(); let sub = ztimeout!(peer01 .declare_subscriber(key_expr) @@ -85,7 +85,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { task::sleep(SLEEP).await; // Put data - println!("[PS][02b] Putting on peer02 session. {MSG_COUNT} msgs of {size} bytes."); + dbg!("[PS][02b] Putting on peer02 session. {MSG_COUNT} msgs of {size} bytes."); for _ in 0..MSG_COUNT { ztimeout!(peer02 .put(key_expr, vec![0u8; size]) @@ -97,7 +97,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { ztimeout!(async { loop { let cnt = msgs.load(Ordering::SeqCst); - println!("[PS][03b] Received {cnt}/{MSG_COUNT}."); + dbg!("[PS][03b] Received {cnt}/{MSG_COUNT}."); if cnt < MSG_COUNT { task::sleep(SLEEP).await; } else { @@ -106,7 +106,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { } }); - println!("[PS][03b] Unsubscribing on peer01 session"); + dbg!("[PS][03b] Unsubscribing on peer01 session"); ztimeout!(sub.undeclare().res_async()).unwrap(); // Wait for the declaration to propagate @@ -123,7 +123,7 @@ async fn test_session_qryrep(peer01: &Session, peer02: &Session) { msgs.store(0, Ordering::SeqCst); // Queryable to data - println!("[QR][01c] Queryable on peer01 session"); + dbg!("[QR][01c] Queryable on peer01 session"); let c_msgs = msgs.clone(); let qbl = ztimeout!(peer01 .declare_queryable(key_expr) @@ -139,7 +139,7 @@ async fn test_session_qryrep(peer01: &Session, peer02: &Session) { task::sleep(SLEEP).await; // Get data - println!("[QR][02c] Getting on peer02 session. {MSG_COUNT} msgs."); + dbg!("[QR][02c] Getting on peer02 session. {MSG_COUNT} msgs."); let mut cnt = 0; for _ in 0..MSG_COUNT { let rs = ztimeout!(peer02.get(key_expr).res_async()).unwrap(); @@ -148,11 +148,11 @@ async fn test_session_qryrep(peer01: &Session, peer02: &Session) { cnt += 1; } } - println!("[QR][02c] Got on peer02 session. {cnt}/{MSG_COUNT} msgs."); + dbg!("[QR][02c] Got on peer02 session. {cnt}/{MSG_COUNT} msgs."); assert_eq!(msgs.load(Ordering::SeqCst), MSG_COUNT); assert_eq!(cnt, MSG_COUNT); - println!("[PS][03c] Unqueryable on peer01 session"); + dbg!("[PS][03c] Unqueryable on peer01 session"); ztimeout!(qbl.undeclare().res_async()).unwrap(); // Wait for the declaration to propagate From 96fa7c582eb2ab0908a0bc3793f06d0095c5d884 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 16:18:19 +0100 Subject: [PATCH 027/203] New ZInt encoding --- commons/zenoh-codec/src/core/encoding.rs | 2 +- commons/zenoh-codec/src/core/zbuf.rs | 4 + commons/zenoh-codec/src/core/zint.rs | 354 +++++++------------- commons/zenoh-codec/src/lib.rs | 6 - commons/zenoh-codec/src/zenoh/data.rs | 7 +- commons/zenoh-codec/tests/codec.rs | 3 +- commons/zenoh-protocol/src/core/encoding.rs | 6 + io/zenoh-transport/src/unicast/mod.rs | 4 +- 8 files changed, 133 insertions(+), 253 deletions(-) diff --git a/commons/zenoh-codec/src/core/encoding.rs b/commons/zenoh-codec/src/core/encoding.rs index 0e991e5528..e50c96836a 100644 --- a/commons/zenoh-codec/src/core/encoding.rs +++ b/commons/zenoh-codec/src/core/encoding.rs @@ -26,7 +26,7 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Encoding) -> Self::Output { - self.write(&mut *writer, u8::from(*x.prefix()))?; + self.write(&mut *writer, ZInt::from(*x.prefix()))?; self.write(&mut *writer, x.suffix())?; Ok(()) } diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index ffea9128f4..762829b3b8 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -46,9 +46,13 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { + dbg!(""); let len: usize = self.read(&mut *reader)?; + dbg!(""); let mut zbuf = ZBuf::default(); + dbg!(""); reader.read_zslices(len, |s| zbuf.push_zslice(s))?; + dbg!(""); Ok(zbuf) } } diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 7d93298289..2991572a71 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -12,34 +12,90 @@ // ZettaScale Zenoh Team, // use crate::{RCodec, WCodec, Zenoh080}; -use core::convert::TryInto; +use core::{convert::TryInto, num::NonZeroU64, ptr}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -const VLE_LEN: usize = 10; +// macro_rules! non_zero_array { +// ($($i: expr,)*) => { +// [$(match NonZeroU8::new($i) {Some(x) => x, None => panic!("Attempted to place 0 in an array of non-zeros litteral")}),*] +// }; +// } + +// impl Zenoh080 { +// pub const fn preview_length(&self, x: u64) -> NonZeroU8 { +// let x = match NonZeroU64::new(x) { +// Some(x) => x, +// None => { +// return unsafe { NonZeroU8::new_unchecked(1) }; +// } +// }; +// let needed_bits = u64::BITS - x.leading_zeros(); +// const LENGTH: [NonZeroU8; 65] = non_zero_array![ +// 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, +// 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, +// 9, 9, 9, 9, 9, 9, 9, +// ]; +// LENGTH[needed_bits as usize] +// } +// } -// ZInt impl WCodec for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, mut x: u64) -> Self::Output { + fn write(self, writer: &mut W, x: u64) -> Self::Output { + const VLE_LEN: usize = 9; + const VLE_MASK: [u8; VLE_LEN] = [ + 0b11111111, // This is padding to avoid needless subtractions on index access + 0, 0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111, + ]; + const VLE_SHIFT: [u8; 65] = [ + 1, // This is padding to avoid needless subtractions on index access + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, + 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, + ]; + writer.with_slot(VLE_LEN, move |buffer| { - let mut len = 0; - let mut b = x as u8; - while x > 0x7f { - buffer[len] = b | 0x80; - len += 1; - x >>= 7; - b = x as u8; + // since leading_zeros will jump conditionally on 0 anyway (`asm {bsr 0}` is UB), might as well jump to return + let x = match NonZeroU64::new(x) { + Some(x) => x, + None => { + buffer[0] = 0; + return 1; + } + }; + + let needed_bits = u64::BITS - x.leading_zeros(); + let payload_size = VLE_SHIFT[needed_bits as usize]; + let shift_payload = payload_size == 0; + let mut x: u64 = x.into(); + x <<= payload_size; + let serialized = x.to_le_bytes(); + + unsafe { + ptr::copy_nonoverlapping( + serialized.as_ptr(), + buffer.as_mut_ptr().offset(shift_payload as isize), + u64::BITS as usize / 8, + ) + }; + + let needed_bytes = payload_size as usize; + buffer[0] |= VLE_MASK[needed_bytes]; + if shift_payload { + VLE_LEN + } else { + needed_bytes } - buffer[len] = b; - len + 1 - }) + })?; + + Ok(()) } } @@ -61,23 +117,23 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut b = reader.read_u8()?; + let mut buffer = [0; 8]; + buffer[0] = reader.read_u8()?; - let mut v = 0; - let mut i = 0; - let mut k = VLE_LEN; - while b > 0x7f && k > 0 { - v |= ((b & 0x7f) as u64) << i; - i += 7; - b = reader.read_u8()?; - k -= 1; - } - if k > 0 { - v |= ((b & 0x7f) as u64) << i; - Ok(v) - } else { - Err(DidntRead) + // GCC: `__builtin_ctz(~buffer[0])`, clang: `__tzcnt_u64(~buffer[0])` + let byte_count = (buffer[0].trailing_ones()) as usize; + if byte_count == 0 { + return Ok(u64::from_le_bytes(buffer) >> 1); } + + let shift_payload = (byte_count == 8) as usize; // branches are evil + let shift_payload_multiplier = 1 - shift_payload; + + let len = byte_count + shift_payload_multiplier; + reader.read_exact(&mut buffer[shift_payload_multiplier..len])?; + + // the shift also removes the mask + Ok(u64::from_le_bytes(buffer) >> ((byte_count + 1) * shift_payload_multiplier) as u32) } } @@ -106,221 +162,41 @@ where } } -// macro_rules! non_zero_array { -// ($($i: expr,)*) => { -// [$(match NonZeroU8::new($i) {Some(x) => x, None => panic!("Attempted to place 0 in an array of non-zeros litteral")}),*] -// }; -// } - -// impl Zenoh070 { -// pub const fn preview_length(&self, x: u64) -> NonZeroU8 { -// let x = match core::num::NonZeroU64::new(x) { -// Some(x) => x, -// None => { -// return unsafe { NonZeroU8::new_unchecked(1) }; -// } -// }; -// let needed_bits = u64::BITS - x.leading_zeros(); -// const LENGTH: [NonZeroU8; 65] = non_zero_array![ -// 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, -// 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, -// 9, 9, 9, 9, 9, 9, 9, -// ]; -// LENGTH[needed_bits as usize] -// } -// } - -// macro_rules! impl_unsigned_codec { -// ($t: ty) => { -// impl WCodec for Codec -// where -// Codec: WCodec, -// { -// type Output = >::Output; -// fn write(self, writer: Buffer, x: $t) -> Self::Output { -// self.write(writer, x as u64) -// } -// } - -// impl RCodec for Codec -// where -// Codec: RCodec, -// { -// type Error = ConversionOrReadError>::Error>; +#[cfg(test)] +mod test { + #[test] + fn zint_fuzz() { + use crate::*; + use rand::Rng; + use zenoh_buffers::{reader::HasReader, writer::HasWriter}; -// fn read(self, writer: Reader) -> Result<$t, Self::Error> { -// match self.read(writer) { -// Ok(v) => v -// .try_into() -// .map_err(|e| ConversionOrReadError::ConversionError(e)), -// Err(e) => Err(ConversionOrReadError::ReadError(e)), -// } -// } -// } -// }; -// } - -// impl_unsigned_codec!(usize); -// impl_unsigned_codec!(u32); -// impl_unsigned_codec!(u16); -// impl_unsigned_codec!(u8); - -// #[derive(Debug, Clone)] -// pub enum ConversionOrReadError -// where -// T: TryInto, -// >::Error: core::fmt::Debug + Clone, -// { -// ReadError(E), -// ConversionError(>::Error), -// } + const NUM: usize = 1_000; + const LIMIT: [u64; 4] = [u8::MAX as u64, u16::MAX as u64, u32::MAX as u64, u64::MAX]; -// impl WCodec<&mut W, u64> for &Zenoh070 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; + let codec = Zenoh080::default(); + let mut rng = rand::thread_rng(); -// fn write(self, writer: &mut W, x: u64) -> Self::Output { -// const VLE_SHIFT: [u8; 65] = [ -// 1, // This is padding to avoid needless subtractions on index access -// 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, -// 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 0, 0, -// 0, 0, 0, 0, 0, 0, -// ]; -// const VLE_MASK: [u8; 9] = [ -// 0b11111111, // This is padding to avoid needless subtractions on index access -// 0, 0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111, -// ]; -// const VLE_LEN: usize = 9; -// writer.with_slot(VLE_LEN, move |mut buffer| { -// // since leading_zeros will jump conditionally on 0 anyway (`asm {bsr 0}` is UB), might as well jump to return -// let x = match core::num::NonZeroU64::new(x) { -// Some(x) => x, -// None => { -// buffer[0] = 0; -// return 1; -// } -// }; -// let needed_bits = u64::BITS - x.leading_zeros(); -// let payload_size = VLE_SHIFT[needed_bits as usize]; -// let shift_payload = payload_size == 0; -// let mut x: u64 = x.into(); -// x <<= payload_size; -// let serialized = x.to_le_bytes(); -// unsafe { -// core::ptr::copy_nonoverlapping( -// serialized.as_ptr(), -// buffer.as_mut_ptr().offset(shift_payload as isize), -// u64::BITS as usize / 8, -// ) -// }; -// let needed_bytes = payload_size as usize; -// buffer[0] |= VLE_MASK[needed_bytes]; -// let to_write = if shift_payload { VLE_LEN } else { needed_bytes }; -// to_write -// })?; -// Ok(()) -// } -// } -// impl<'a, R> RCodec<&mut R, u64> for &Zenoh070 -// where -// R: Reader<'a>, -// { -// type Error = (); -// fn read(self, reader: &mut R) -> Result { -// let mut buffer = [0; 8]; -// buffer[0] = match reader.read_u8() { -// None => return Err(()), -// Some(x) => x, -// }; -// // GCC: `__builtin_ctz(~buffer[0])`, clang: `__tzcnt_u64(~buffer[0])` -// let byte_count = (buffer[0].trailing_ones()) as usize; -// if byte_count == 0 { -// return Ok(u64::from_le_bytes(buffer) >> 1); -// } -// let shift_payload = (byte_count == 8) as usize; // branches are evil -// let shift_payload_multiplier = (1 - shift_payload) as usize; + for l in LIMIT.iter() { + let mut values = Vec::with_capacity(NUM); + let mut buffer = vec![]; -// let len = byte_count + shift_payload_multiplier; -// reader.read(&mut buffer[shift_payload_multiplier..len]); + let mut writer = buffer.writer(); -// // the shift also removes the mask -// Ok(u64::from_le_bytes(buffer) >> ((byte_count + 1) * shift_payload_multiplier) as u32) -// } -// } + for _ in 0..NUM { + let x: u64 = rng.gen_range(0..=*l); + values.push(x); + codec.write(&mut writer, x).unwrap(); + } -// #[cfg(test)] -// mod test { -// #[test] -// fn zint_fuzz() { -// use crate::codec::*; -// use rand::Rng; -// let codec = crate::zenoh_070::Zenoh070::default(); -// let mut rng = rand::thread_rng(); -// let dist = rand::distributions::Uniform::new(0, u8::MAX as u64); -// let mut buffer = Vec::with_capacity(9); -// for _ in 0..1000000 { -// buffer.clear(); -// let mut x: u64 = 1; -// for _ in 0..(rng.sample(&dist) % 8) { -// x *= rng.sample(&dist); -// } + let mut reader = buffer.reader(); -// (&codec).write(&mut buffer, x).unwrap(); -// let mut reader = buffer.as_slice(); -// let y: u64 = (&codec).read(&mut reader).unwrap(); -// assert!(reader.is_empty()); -// assert_eq!( -// x, -// y, -// "\n {} ({}) != \n {} ({})\n{} ({})", -// binstr(&x.to_le_bytes()), -// x, -// binstr(&y.to_le_bytes()), -// y, -// binstr(&buffer), -// y, -// ); -// } -// buffer.clear(); -// let mut expected = Vec::new(); -// for _ in 0..1000 { -// let mut x: u64 = 1; -// for _ in 0..(rng.sample(&dist) % 8) { -// x *= rng.sample(&dist); -// } -// expected.push(x); -// let _ = (&codec).write(&mut buffer, x); -// } -// println!("{:x?}", expected); -// let mut reader = buffer.as_slice(); -// for (i, &x) in expected.iter().enumerate() { -// let y: u64 = (&codec).read(&mut reader).unwrap(); -// assert_eq!( -// x, -// y, -// "after reading {} numbers\n {} ({}) != \n {} ({})\n{} ({})", -// i, -// binstr(&x.to_le_bytes()), -// x, -// binstr(&y.to_le_bytes()), -// y, -// binstr(&buffer), -// y, -// ); -// } -// assert!(reader.is_empty()); -// } + for x in values.drain(..).take(NUM) { + let y: u64 = codec.read(&mut reader).unwrap(); + println!("{x} {y}"); + assert_eq!(x, y); + } -// pub fn binstr(buffer: &[u8]) -> String { -// let mut result = String::with_capacity(9 * buffer.len()); -// for byte in buffer { -// for i in 0..8 { -// result.push(if (byte >> i) & 1 == 1 { '1' } else { '0' }) -// } -// result.push(' ') -// } -// result -// } -// } + assert!(reader.is_empty()); + } + } +} diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 630253c60b..03b24ae3bf 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -33,11 +33,9 @@ pub trait RCodec { } #[derive(Clone, Copy, Default)] -#[non_exhaustive] pub struct Zenoh080; #[derive(Clone, Copy)] -#[non_exhaustive] pub struct Zenoh080Header { pub header: u8, pub codec: Zenoh080, @@ -53,7 +51,6 @@ impl Zenoh080Header { } #[derive(Clone, Copy, Default)] -#[non_exhaustive] pub struct Zenoh080Condition { pub condition: bool, pub codec: Zenoh080, @@ -69,7 +66,6 @@ impl Zenoh080Condition { } #[derive(Clone, Copy, Default)] -#[non_exhaustive] pub struct Zenoh080Length { pub length: usize, pub codec: Zenoh080, @@ -85,7 +81,6 @@ impl Zenoh080Length { } #[derive(Clone, Copy, Default)] -#[non_exhaustive] pub struct Zenoh080Reliability { pub reliability: Reliability, pub codec: Zenoh080, @@ -101,7 +96,6 @@ impl Zenoh080Reliability { } #[derive(Clone, Default)] -#[non_exhaustive] pub struct Zenoh080HeaderReplyContext { pub header: u8, pub reply_context: Option, diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index bc72744b38..e35a95cb9e 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -96,7 +96,7 @@ where fn write(self, writer: &mut W, x: &DataInfo) -> Self::Output { // Options - let mut options = 0; + let mut options: ZInt = 0; #[cfg(feature = "shared-memory")] if x.sliced { options |= zmsg::data::info::SLICED; @@ -242,9 +242,7 @@ where ..Default::default() }; if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { - let header: u8 = self.read(&mut *reader)?; - let hodec = Zenoh080Header::new(header); - + let hodec = Zenoh080Header::new(codec.header); codec.reply_context = Some(hodec.read(&mut *reader)?); codec.header = self.read(&mut *reader)?; } @@ -273,6 +271,7 @@ where condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; + let key: WireExpr<'static> = ccond.read(&mut *reader)?; #[cfg(feature = "shared-memory")] diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 7c28f09ac6..192f6c2e10 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -210,7 +210,8 @@ fn codec_extension() { run_extension!(ZExtUnit<0>); run_extension!(ZExtZInt<1>); - run_extension!(ZExtZBuf<2>); + run_extension!(ZExtZSlice<2>); + run_extension!(ZExtZBuf<3>); run_extension!(ZExtUnknown); } diff --git a/commons/zenoh-protocol/src/core/encoding.rs b/commons/zenoh-protocol/src/core/encoding.rs index 715221129a..999e8993b8 100644 --- a/commons/zenoh-protocol/src/core/encoding.rs +++ b/commons/zenoh-protocol/src/core/encoding.rs @@ -75,6 +75,12 @@ impl From for u8 { } } +impl From for ZInt { + fn from(val: KnownEncoding) -> Self { + u8::from(val) as ZInt + } +} + impl From for &str { fn from(val: KnownEncoding) -> Self { consts::MIMES[usize::from(val)] diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 6abe17e79a..615d35a5ce 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -15,8 +15,8 @@ pub mod establishment; pub(crate) mod link; pub(crate) mod manager; pub(crate) mod rx; -#[cfg(feature = "shared-memory")] -pub(crate) mod shm; +// #[cfg(feature = "shared-memory")] +// pub(crate) mod shm; pub(crate) mod transport; pub(crate) mod tx; From 4f4c7fcf32542deb7f0d625d3bb2eeb0fb1d09f5 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 16:18:19 +0100 Subject: [PATCH 028/203] New ZInt encoding --- commons/zenoh-codec/src/core/encoding.rs | 2 +- commons/zenoh-codec/src/core/zbuf.rs | 4 + commons/zenoh-codec/src/core/zint.rs | 354 +++++++------------- commons/zenoh-codec/src/lib.rs | 6 - commons/zenoh-codec/src/zenoh/data.rs | 7 +- commons/zenoh-codec/tests/codec.rs | 3 +- commons/zenoh-protocol/src/core/encoding.rs | 6 + io/zenoh-transport/src/unicast/mod.rs | 4 +- 8 files changed, 133 insertions(+), 253 deletions(-) diff --git a/commons/zenoh-codec/src/core/encoding.rs b/commons/zenoh-codec/src/core/encoding.rs index 0e991e5528..e50c96836a 100644 --- a/commons/zenoh-codec/src/core/encoding.rs +++ b/commons/zenoh-codec/src/core/encoding.rs @@ -26,7 +26,7 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Encoding) -> Self::Output { - self.write(&mut *writer, u8::from(*x.prefix()))?; + self.write(&mut *writer, ZInt::from(*x.prefix()))?; self.write(&mut *writer, x.suffix())?; Ok(()) } diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index ffea9128f4..762829b3b8 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -46,9 +46,13 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { + dbg!(""); let len: usize = self.read(&mut *reader)?; + dbg!(""); let mut zbuf = ZBuf::default(); + dbg!(""); reader.read_zslices(len, |s| zbuf.push_zslice(s))?; + dbg!(""); Ok(zbuf) } } diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 7d93298289..2991572a71 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -12,34 +12,90 @@ // ZettaScale Zenoh Team, // use crate::{RCodec, WCodec, Zenoh080}; -use core::convert::TryInto; +use core::{convert::TryInto, num::NonZeroU64, ptr}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -const VLE_LEN: usize = 10; +// macro_rules! non_zero_array { +// ($($i: expr,)*) => { +// [$(match NonZeroU8::new($i) {Some(x) => x, None => panic!("Attempted to place 0 in an array of non-zeros litteral")}),*] +// }; +// } + +// impl Zenoh080 { +// pub const fn preview_length(&self, x: u64) -> NonZeroU8 { +// let x = match NonZeroU64::new(x) { +// Some(x) => x, +// None => { +// return unsafe { NonZeroU8::new_unchecked(1) }; +// } +// }; +// let needed_bits = u64::BITS - x.leading_zeros(); +// const LENGTH: [NonZeroU8; 65] = non_zero_array![ +// 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, +// 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, +// 9, 9, 9, 9, 9, 9, 9, +// ]; +// LENGTH[needed_bits as usize] +// } +// } -// ZInt impl WCodec for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, mut x: u64) -> Self::Output { + fn write(self, writer: &mut W, x: u64) -> Self::Output { + const VLE_LEN: usize = 9; + const VLE_MASK: [u8; VLE_LEN] = [ + 0b11111111, // This is padding to avoid needless subtractions on index access + 0, 0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111, + ]; + const VLE_SHIFT: [u8; 65] = [ + 1, // This is padding to avoid needless subtractions on index access + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, + 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, + ]; + writer.with_slot(VLE_LEN, move |buffer| { - let mut len = 0; - let mut b = x as u8; - while x > 0x7f { - buffer[len] = b | 0x80; - len += 1; - x >>= 7; - b = x as u8; + // since leading_zeros will jump conditionally on 0 anyway (`asm {bsr 0}` is UB), might as well jump to return + let x = match NonZeroU64::new(x) { + Some(x) => x, + None => { + buffer[0] = 0; + return 1; + } + }; + + let needed_bits = u64::BITS - x.leading_zeros(); + let payload_size = VLE_SHIFT[needed_bits as usize]; + let shift_payload = payload_size == 0; + let mut x: u64 = x.into(); + x <<= payload_size; + let serialized = x.to_le_bytes(); + + unsafe { + ptr::copy_nonoverlapping( + serialized.as_ptr(), + buffer.as_mut_ptr().offset(shift_payload as isize), + u64::BITS as usize / 8, + ) + }; + + let needed_bytes = payload_size as usize; + buffer[0] |= VLE_MASK[needed_bytes]; + if shift_payload { + VLE_LEN + } else { + needed_bytes } - buffer[len] = b; - len + 1 - }) + })?; + + Ok(()) } } @@ -61,23 +117,23 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut b = reader.read_u8()?; + let mut buffer = [0; 8]; + buffer[0] = reader.read_u8()?; - let mut v = 0; - let mut i = 0; - let mut k = VLE_LEN; - while b > 0x7f && k > 0 { - v |= ((b & 0x7f) as u64) << i; - i += 7; - b = reader.read_u8()?; - k -= 1; - } - if k > 0 { - v |= ((b & 0x7f) as u64) << i; - Ok(v) - } else { - Err(DidntRead) + // GCC: `__builtin_ctz(~buffer[0])`, clang: `__tzcnt_u64(~buffer[0])` + let byte_count = (buffer[0].trailing_ones()) as usize; + if byte_count == 0 { + return Ok(u64::from_le_bytes(buffer) >> 1); } + + let shift_payload = (byte_count == 8) as usize; // branches are evil + let shift_payload_multiplier = 1 - shift_payload; + + let len = byte_count + shift_payload_multiplier; + reader.read_exact(&mut buffer[shift_payload_multiplier..len])?; + + // the shift also removes the mask + Ok(u64::from_le_bytes(buffer) >> ((byte_count + 1) * shift_payload_multiplier) as u32) } } @@ -106,221 +162,41 @@ where } } -// macro_rules! non_zero_array { -// ($($i: expr,)*) => { -// [$(match NonZeroU8::new($i) {Some(x) => x, None => panic!("Attempted to place 0 in an array of non-zeros litteral")}),*] -// }; -// } - -// impl Zenoh070 { -// pub const fn preview_length(&self, x: u64) -> NonZeroU8 { -// let x = match core::num::NonZeroU64::new(x) { -// Some(x) => x, -// None => { -// return unsafe { NonZeroU8::new_unchecked(1) }; -// } -// }; -// let needed_bits = u64::BITS - x.leading_zeros(); -// const LENGTH: [NonZeroU8; 65] = non_zero_array![ -// 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, -// 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, -// 9, 9, 9, 9, 9, 9, 9, -// ]; -// LENGTH[needed_bits as usize] -// } -// } - -// macro_rules! impl_unsigned_codec { -// ($t: ty) => { -// impl WCodec for Codec -// where -// Codec: WCodec, -// { -// type Output = >::Output; -// fn write(self, writer: Buffer, x: $t) -> Self::Output { -// self.write(writer, x as u64) -// } -// } - -// impl RCodec for Codec -// where -// Codec: RCodec, -// { -// type Error = ConversionOrReadError>::Error>; +#[cfg(test)] +mod test { + #[test] + fn zint_fuzz() { + use crate::*; + use rand::Rng; + use zenoh_buffers::{reader::HasReader, writer::HasWriter}; -// fn read(self, writer: Reader) -> Result<$t, Self::Error> { -// match self.read(writer) { -// Ok(v) => v -// .try_into() -// .map_err(|e| ConversionOrReadError::ConversionError(e)), -// Err(e) => Err(ConversionOrReadError::ReadError(e)), -// } -// } -// } -// }; -// } - -// impl_unsigned_codec!(usize); -// impl_unsigned_codec!(u32); -// impl_unsigned_codec!(u16); -// impl_unsigned_codec!(u8); - -// #[derive(Debug, Clone)] -// pub enum ConversionOrReadError -// where -// T: TryInto, -// >::Error: core::fmt::Debug + Clone, -// { -// ReadError(E), -// ConversionError(>::Error), -// } + const NUM: usize = 1_000; + const LIMIT: [u64; 4] = [u8::MAX as u64, u16::MAX as u64, u32::MAX as u64, u64::MAX]; -// impl WCodec<&mut W, u64> for &Zenoh070 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; + let codec = Zenoh080::default(); + let mut rng = rand::thread_rng(); -// fn write(self, writer: &mut W, x: u64) -> Self::Output { -// const VLE_SHIFT: [u8; 65] = [ -// 1, // This is padding to avoid needless subtractions on index access -// 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, -// 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 0, 0, -// 0, 0, 0, 0, 0, 0, -// ]; -// const VLE_MASK: [u8; 9] = [ -// 0b11111111, // This is padding to avoid needless subtractions on index access -// 0, 0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111, -// ]; -// const VLE_LEN: usize = 9; -// writer.with_slot(VLE_LEN, move |mut buffer| { -// // since leading_zeros will jump conditionally on 0 anyway (`asm {bsr 0}` is UB), might as well jump to return -// let x = match core::num::NonZeroU64::new(x) { -// Some(x) => x, -// None => { -// buffer[0] = 0; -// return 1; -// } -// }; -// let needed_bits = u64::BITS - x.leading_zeros(); -// let payload_size = VLE_SHIFT[needed_bits as usize]; -// let shift_payload = payload_size == 0; -// let mut x: u64 = x.into(); -// x <<= payload_size; -// let serialized = x.to_le_bytes(); -// unsafe { -// core::ptr::copy_nonoverlapping( -// serialized.as_ptr(), -// buffer.as_mut_ptr().offset(shift_payload as isize), -// u64::BITS as usize / 8, -// ) -// }; -// let needed_bytes = payload_size as usize; -// buffer[0] |= VLE_MASK[needed_bytes]; -// let to_write = if shift_payload { VLE_LEN } else { needed_bytes }; -// to_write -// })?; -// Ok(()) -// } -// } -// impl<'a, R> RCodec<&mut R, u64> for &Zenoh070 -// where -// R: Reader<'a>, -// { -// type Error = (); -// fn read(self, reader: &mut R) -> Result { -// let mut buffer = [0; 8]; -// buffer[0] = match reader.read_u8() { -// None => return Err(()), -// Some(x) => x, -// }; -// // GCC: `__builtin_ctz(~buffer[0])`, clang: `__tzcnt_u64(~buffer[0])` -// let byte_count = (buffer[0].trailing_ones()) as usize; -// if byte_count == 0 { -// return Ok(u64::from_le_bytes(buffer) >> 1); -// } -// let shift_payload = (byte_count == 8) as usize; // branches are evil -// let shift_payload_multiplier = (1 - shift_payload) as usize; + for l in LIMIT.iter() { + let mut values = Vec::with_capacity(NUM); + let mut buffer = vec![]; -// let len = byte_count + shift_payload_multiplier; -// reader.read(&mut buffer[shift_payload_multiplier..len]); + let mut writer = buffer.writer(); -// // the shift also removes the mask -// Ok(u64::from_le_bytes(buffer) >> ((byte_count + 1) * shift_payload_multiplier) as u32) -// } -// } + for _ in 0..NUM { + let x: u64 = rng.gen_range(0..=*l); + values.push(x); + codec.write(&mut writer, x).unwrap(); + } -// #[cfg(test)] -// mod test { -// #[test] -// fn zint_fuzz() { -// use crate::codec::*; -// use rand::Rng; -// let codec = crate::zenoh_070::Zenoh070::default(); -// let mut rng = rand::thread_rng(); -// let dist = rand::distributions::Uniform::new(0, u8::MAX as u64); -// let mut buffer = Vec::with_capacity(9); -// for _ in 0..1000000 { -// buffer.clear(); -// let mut x: u64 = 1; -// for _ in 0..(rng.sample(&dist) % 8) { -// x *= rng.sample(&dist); -// } + let mut reader = buffer.reader(); -// (&codec).write(&mut buffer, x).unwrap(); -// let mut reader = buffer.as_slice(); -// let y: u64 = (&codec).read(&mut reader).unwrap(); -// assert!(reader.is_empty()); -// assert_eq!( -// x, -// y, -// "\n {} ({}) != \n {} ({})\n{} ({})", -// binstr(&x.to_le_bytes()), -// x, -// binstr(&y.to_le_bytes()), -// y, -// binstr(&buffer), -// y, -// ); -// } -// buffer.clear(); -// let mut expected = Vec::new(); -// for _ in 0..1000 { -// let mut x: u64 = 1; -// for _ in 0..(rng.sample(&dist) % 8) { -// x *= rng.sample(&dist); -// } -// expected.push(x); -// let _ = (&codec).write(&mut buffer, x); -// } -// println!("{:x?}", expected); -// let mut reader = buffer.as_slice(); -// for (i, &x) in expected.iter().enumerate() { -// let y: u64 = (&codec).read(&mut reader).unwrap(); -// assert_eq!( -// x, -// y, -// "after reading {} numbers\n {} ({}) != \n {} ({})\n{} ({})", -// i, -// binstr(&x.to_le_bytes()), -// x, -// binstr(&y.to_le_bytes()), -// y, -// binstr(&buffer), -// y, -// ); -// } -// assert!(reader.is_empty()); -// } + for x in values.drain(..).take(NUM) { + let y: u64 = codec.read(&mut reader).unwrap(); + println!("{x} {y}"); + assert_eq!(x, y); + } -// pub fn binstr(buffer: &[u8]) -> String { -// let mut result = String::with_capacity(9 * buffer.len()); -// for byte in buffer { -// for i in 0..8 { -// result.push(if (byte >> i) & 1 == 1 { '1' } else { '0' }) -// } -// result.push(' ') -// } -// result -// } -// } + assert!(reader.is_empty()); + } + } +} diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 630253c60b..03b24ae3bf 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -33,11 +33,9 @@ pub trait RCodec { } #[derive(Clone, Copy, Default)] -#[non_exhaustive] pub struct Zenoh080; #[derive(Clone, Copy)] -#[non_exhaustive] pub struct Zenoh080Header { pub header: u8, pub codec: Zenoh080, @@ -53,7 +51,6 @@ impl Zenoh080Header { } #[derive(Clone, Copy, Default)] -#[non_exhaustive] pub struct Zenoh080Condition { pub condition: bool, pub codec: Zenoh080, @@ -69,7 +66,6 @@ impl Zenoh080Condition { } #[derive(Clone, Copy, Default)] -#[non_exhaustive] pub struct Zenoh080Length { pub length: usize, pub codec: Zenoh080, @@ -85,7 +81,6 @@ impl Zenoh080Length { } #[derive(Clone, Copy, Default)] -#[non_exhaustive] pub struct Zenoh080Reliability { pub reliability: Reliability, pub codec: Zenoh080, @@ -101,7 +96,6 @@ impl Zenoh080Reliability { } #[derive(Clone, Default)] -#[non_exhaustive] pub struct Zenoh080HeaderReplyContext { pub header: u8, pub reply_context: Option, diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index bc72744b38..e35a95cb9e 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -96,7 +96,7 @@ where fn write(self, writer: &mut W, x: &DataInfo) -> Self::Output { // Options - let mut options = 0; + let mut options: ZInt = 0; #[cfg(feature = "shared-memory")] if x.sliced { options |= zmsg::data::info::SLICED; @@ -242,9 +242,7 @@ where ..Default::default() }; if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { - let header: u8 = self.read(&mut *reader)?; - let hodec = Zenoh080Header::new(header); - + let hodec = Zenoh080Header::new(codec.header); codec.reply_context = Some(hodec.read(&mut *reader)?); codec.header = self.read(&mut *reader)?; } @@ -273,6 +271,7 @@ where condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, }; + let key: WireExpr<'static> = ccond.read(&mut *reader)?; #[cfg(feature = "shared-memory")] diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 7c28f09ac6..192f6c2e10 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -210,7 +210,8 @@ fn codec_extension() { run_extension!(ZExtUnit<0>); run_extension!(ZExtZInt<1>); - run_extension!(ZExtZBuf<2>); + run_extension!(ZExtZSlice<2>); + run_extension!(ZExtZBuf<3>); run_extension!(ZExtUnknown); } diff --git a/commons/zenoh-protocol/src/core/encoding.rs b/commons/zenoh-protocol/src/core/encoding.rs index 715221129a..999e8993b8 100644 --- a/commons/zenoh-protocol/src/core/encoding.rs +++ b/commons/zenoh-protocol/src/core/encoding.rs @@ -75,6 +75,12 @@ impl From for u8 { } } +impl From for ZInt { + fn from(val: KnownEncoding) -> Self { + u8::from(val) as ZInt + } +} + impl From for &str { fn from(val: KnownEncoding) -> Self { consts::MIMES[usize::from(val)] diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 6abe17e79a..615d35a5ce 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -15,8 +15,8 @@ pub mod establishment; pub(crate) mod link; pub(crate) mod manager; pub(crate) mod rx; -#[cfg(feature = "shared-memory")] -pub(crate) mod shm; +// #[cfg(feature = "shared-memory")] +// pub(crate) mod shm; pub(crate) mod transport; pub(crate) mod tx; From c2024207763709275d1bbac0616823de48aaf338 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 16:27:46 +0100 Subject: [PATCH 029/203] Fix forgotten print --- commons/zenoh-codec/src/core/zbuf.rs | 4 ---- commons/zenoh-codec/tests/codec.rs | 16 ++++++++-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index 762829b3b8..ffea9128f4 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -46,13 +46,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - dbg!(""); let len: usize = self.read(&mut *reader)?; - dbg!(""); let mut zbuf = ZBuf::default(); - dbg!(""); reader.read_zslices(len, |s| zbuf.push_zslice(s))?; - dbg!(""); Ok(zbuf) } } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 192f6c2e10..65a529b5b3 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -72,19 +72,19 @@ macro_rules! run_fragmented { macro_rules! run_buffers { ($type:ty, $rand:expr, $wcode:expr, $rcode:expr) => { - println!("Vec: codec {}", std::any::type_name::<$type>()); + dbg!("Vec: codec {}", std::any::type_name::<$type>()); let mut buffer = vec![]; run_single!($type, $rand, $wcode, $rcode, buffer); - println!("BBuf: codec {}", std::any::type_name::<$type>()); + dbg!("BBuf: codec {}", std::any::type_name::<$type>()); let mut buffer = BBuf::with_capacity(u16::MAX as usize); run_single!($type, $rand, $wcode, $rcode, buffer); - println!("ZBuf: codec {}", std::any::type_name::<$type>()); + dbg!("ZBuf: codec {}", std::any::type_name::<$type>()); let mut buffer = ZBuf::default(); run_single!($type, $rand, $wcode, $rcode, buffer); - println!("ZSlice: codec {}", std::any::type_name::<$type>()); + dbg!("ZSlice: codec {}", std::any::type_name::<$type>()); for _ in 0..NUM_ITER { let x: $type = $rand; @@ -100,7 +100,7 @@ macro_rules! run_buffers { assert_eq!(x, y); } - println!("Fragmented: codec {}", std::any::type_name::<$type>()); + dbg!("Fragmented: codec {}", std::any::type_name::<$type>()); run_fragmented!($type, $rand, $wcode, $rcode) }; } @@ -194,15 +194,15 @@ fn codec_extension() { macro_rules! run_extension { ($type:ty) => { - println!("Vec: codec {}", std::any::type_name::<$type>()); + dbg!("Vec: codec {}", std::any::type_name::<$type>()); let mut buff = vec![]; run_extension_single!($type, buff); - println!("BBuf: codec {}", std::any::type_name::<$type>()); + dbg!("BBuf: codec {}", std::any::type_name::<$type>()); let mut buff = BBuf::with_capacity(u16::MAX as usize); run_extension_single!($type, buff); - println!("ZBuf: codec {}", std::any::type_name::<$type>()); + dbg!("ZBuf: codec {}", std::any::type_name::<$type>()); let mut buff = ZBuf::default(); run_extension_single!($type, buff); }; From 041dd60f1b35dd38ef615f9408023ca09cb1b8fb Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 16:31:37 +0100 Subject: [PATCH 030/203] Fix forgotten print --- commons/zenoh-codec/src/core/zbuf.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index 762829b3b8..93f080cff9 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -128,7 +128,6 @@ where fn write(self, writer: &mut W, x: &ZBuf) -> Self::Output { let is_sliced = self.condition; - if is_sliced { let codec = Zenoh080Sliced::default(); codec.write(&mut *writer, x) From 1423ccfa360ed3d20966c22ca6406850adfd5afe Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 16:34:02 +0100 Subject: [PATCH 031/203] Fix forgotten print --- commons/zenoh-codec/src/core/zbuf.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index 93f080cff9..ffea9128f4 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -46,13 +46,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - dbg!(""); let len: usize = self.read(&mut *reader)?; - dbg!(""); let mut zbuf = ZBuf::default(); - dbg!(""); reader.read_zslices(len, |s| zbuf.push_zslice(s))?; - dbg!(""); Ok(zbuf) } } @@ -128,6 +124,7 @@ where fn write(self, writer: &mut W, x: &ZBuf) -> Self::Output { let is_sliced = self.condition; + if is_sliced { let codec = Zenoh080Sliced::default(); codec.write(&mut *writer, x) From 3cdf15d4c5f24343bd44dc1fd4f74bd1c74a7ac3 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 16:48:02 +0100 Subject: [PATCH 032/203] Revert to old ZInt encoding --- commons/zenoh-codec/src/core/zint.rs | 318 +++++++++++++++++---------- 1 file changed, 203 insertions(+), 115 deletions(-) diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 2991572a71..b809a1f614 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -12,90 +12,34 @@ // ZettaScale Zenoh Team, // use crate::{RCodec, WCodec, Zenoh080}; -use core::{convert::TryInto, num::NonZeroU64, ptr}; +use core::convert::TryInto; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -// macro_rules! non_zero_array { -// ($($i: expr,)*) => { -// [$(match NonZeroU8::new($i) {Some(x) => x, None => panic!("Attempted to place 0 in an array of non-zeros litteral")}),*] -// }; -// } - -// impl Zenoh080 { -// pub const fn preview_length(&self, x: u64) -> NonZeroU8 { -// let x = match NonZeroU64::new(x) { -// Some(x) => x, -// None => { -// return unsafe { NonZeroU8::new_unchecked(1) }; -// } -// }; -// let needed_bits = u64::BITS - x.leading_zeros(); -// const LENGTH: [NonZeroU8; 65] = non_zero_array![ -// 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, -// 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, -// 9, 9, 9, 9, 9, 9, 9, -// ]; -// LENGTH[needed_bits as usize] -// } -// } +const VLE_LEN: usize = 10; +// ZInt impl WCodec for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: u64) -> Self::Output { - const VLE_LEN: usize = 9; - const VLE_MASK: [u8; VLE_LEN] = [ - 0b11111111, // This is padding to avoid needless subtractions on index access - 0, 0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111, - ]; - const VLE_SHIFT: [u8; 65] = [ - 1, // This is padding to avoid needless subtractions on index access - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 0, 0, - 0, 0, 0, 0, 0, 0, - ]; - + fn write(self, writer: &mut W, mut x: u64) -> Self::Output { writer.with_slot(VLE_LEN, move |buffer| { - // since leading_zeros will jump conditionally on 0 anyway (`asm {bsr 0}` is UB), might as well jump to return - let x = match NonZeroU64::new(x) { - Some(x) => x, - None => { - buffer[0] = 0; - return 1; - } - }; - - let needed_bits = u64::BITS - x.leading_zeros(); - let payload_size = VLE_SHIFT[needed_bits as usize]; - let shift_payload = payload_size == 0; - let mut x: u64 = x.into(); - x <<= payload_size; - let serialized = x.to_le_bytes(); - - unsafe { - ptr::copy_nonoverlapping( - serialized.as_ptr(), - buffer.as_mut_ptr().offset(shift_payload as isize), - u64::BITS as usize / 8, - ) - }; - - let needed_bytes = payload_size as usize; - buffer[0] |= VLE_MASK[needed_bytes]; - if shift_payload { - VLE_LEN - } else { - needed_bytes + let mut len = 0; + let mut b = x as u8; + while x > 0x7f { + buffer[len] = b | 0x80; + len += 1; + x >>= 7; + b = x as u8; } - })?; - - Ok(()) + buffer[len] = b; + len + 1 + }) } } @@ -117,23 +61,23 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let mut buffer = [0; 8]; - buffer[0] = reader.read_u8()?; + let mut b = reader.read_u8()?; - // GCC: `__builtin_ctz(~buffer[0])`, clang: `__tzcnt_u64(~buffer[0])` - let byte_count = (buffer[0].trailing_ones()) as usize; - if byte_count == 0 { - return Ok(u64::from_le_bytes(buffer) >> 1); + let mut v = 0; + let mut i = 0; + let mut k = VLE_LEN; + while b > 0x7f && k > 0 { + v |= ((b & 0x7f) as u64) << i; + i += 7; + b = reader.read_u8()?; + k -= 1; + } + if k > 0 { + v |= ((b & 0x7f) as u64) << i; + Ok(v) + } else { + Err(DidntRead) } - - let shift_payload = (byte_count == 8) as usize; // branches are evil - let shift_payload_multiplier = 1 - shift_payload; - - let len = byte_count + shift_payload_multiplier; - reader.read_exact(&mut buffer[shift_payload_multiplier..len])?; - - // the shift also removes the mask - Ok(u64::from_le_bytes(buffer) >> ((byte_count + 1) * shift_payload_multiplier) as u32) } } @@ -162,41 +106,185 @@ where } } -#[cfg(test)] -mod test { - #[test] - fn zint_fuzz() { - use crate::*; - use rand::Rng; - use zenoh_buffers::{reader::HasReader, writer::HasWriter}; +// macro_rules! non_zero_array { +// ($($i: expr,)*) => { +// [$(match NonZeroU8::new($i) {Some(x) => x, None => panic!("Attempted to place 0 in an array of non-zeros litteral")}),*] +// }; +// } + +// impl Zenoh080 { +// pub const fn preview_length(&self, x: u64) -> NonZeroU8 { +// let x = match NonZeroU64::new(x) { +// Some(x) => x, +// None => { +// return unsafe { NonZeroU8::new_unchecked(1) }; +// } +// }; +// let needed_bits = u64::BITS - x.leading_zeros(); +// const LENGTH: [NonZeroU8; 65] = non_zero_array![ +// 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, +// 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, +// 9, 9, 9, 9, 9, 9, 9, +// ]; +// LENGTH[needed_bits as usize] +// } +// } + +// impl WCodec for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; - const NUM: usize = 1_000; - const LIMIT: [u64; 4] = [u8::MAX as u64, u16::MAX as u64, u32::MAX as u64, u64::MAX]; +// fn write(self, writer: &mut W, x: u64) -> Self::Output { +// const VLE_LEN: usize = 9; +// const VLE_MASK: [u8; VLE_LEN] = [ +// 0b11111111, // This is padding to avoid needless subtractions on index access +// 0, 0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111, +// ]; +// const VLE_SHIFT: [u8; 65] = [ +// 1, // This is padding to avoid needless subtractions on index access +// 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, +// 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 0, 0, +// 0, 0, 0, 0, 0, 0, +// ]; - let codec = Zenoh080::default(); - let mut rng = rand::thread_rng(); +// writer.with_slot(VLE_LEN, move |buffer| { +// // since leading_zeros will jump conditionally on 0 anyway (`asm {bsr 0}` is UB), might as well jump to return +// let x = match NonZeroU64::new(x) { +// Some(x) => x, +// None => { +// buffer[0] = 0; +// return 1; +// } +// }; - for l in LIMIT.iter() { - let mut values = Vec::with_capacity(NUM); - let mut buffer = vec![]; +// let needed_bits = u64::BITS - x.leading_zeros(); +// let payload_size = VLE_SHIFT[needed_bits as usize]; +// let shift_payload = payload_size == 0; +// let mut x: u64 = x.into(); +// x <<= payload_size; +// let serialized = x.to_le_bytes(); - let mut writer = buffer.writer(); +// unsafe { +// ptr::copy_nonoverlapping( +// serialized.as_ptr(), +// buffer.as_mut_ptr().offset(shift_payload as isize), +// u64::BITS as usize / 8, +// ) +// }; - for _ in 0..NUM { - let x: u64 = rng.gen_range(0..=*l); - values.push(x); - codec.write(&mut writer, x).unwrap(); - } +// let needed_bytes = payload_size as usize; +// buffer[0] |= VLE_MASK[needed_bytes]; +// if shift_payload { +// VLE_LEN +// } else { +// needed_bytes +// } +// })?; + +// Ok(()) +// } +// } - let mut reader = buffer.reader(); +// impl WCodec<&u64, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; - for x in values.drain(..).take(NUM) { - let y: u64 = codec.read(&mut reader).unwrap(); - println!("{x} {y}"); - assert_eq!(x, y); - } +// fn write(self, writer: &mut W, x: &u64) -> Self::Output { +// self.write(writer, *x) +// } +// } - assert!(reader.is_empty()); - } - } -} +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let mut buffer = [0; 8]; +// buffer[0] = reader.read_u8()?; + +// // GCC: `__builtin_ctz(~buffer[0])`, clang: `__tzcnt_u64(~buffer[0])` +// let byte_count = (buffer[0].trailing_ones()) as usize; +// if byte_count == 0 { +// return Ok(u64::from_le_bytes(buffer) >> 1); +// } + +// let shift_payload = (byte_count == 8) as usize; // branches are evil +// let shift_payload_multiplier = 1 - shift_payload; + +// let len = byte_count + shift_payload_multiplier; +// reader.read_exact(&mut buffer[shift_payload_multiplier..len])?; + +// // the shift also removes the mask +// Ok(u64::from_le_bytes(buffer) >> ((byte_count + 1) * shift_payload_multiplier) as u32) +// } +// } + +// // usize +// impl WCodec for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; + +// fn write(self, writer: &mut W, x: usize) -> Self::Output { +// let x: u64 = x.try_into().map_err(|_| DidntWrite)?; +// self.write(writer, x) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let x: u64 = >::read(self, reader)?; +// x.try_into().map_err(|_| DidntRead) +// } +// } + +// #[cfg(test)] +// mod test { +// #[test] +// fn zint_fuzz() { +// use crate::*; +// use rand::Rng; +// use zenoh_buffers::{reader::HasReader, writer::HasWriter}; + +// const NUM: usize = 1_000; +// const LIMIT: [u64; 4] = [u8::MAX as u64, u16::MAX as u64, u32::MAX as u64, u64::MAX]; + +// let codec = Zenoh080::default(); +// let mut rng = rand::thread_rng(); + +// for l in LIMIT.iter() { +// let mut values = Vec::with_capacity(NUM); +// let mut buffer = vec![]; + +// let mut writer = buffer.writer(); + +// for _ in 0..NUM { +// let x: u64 = rng.gen_range(0..=*l); +// values.push(x); +// codec.write(&mut writer, x).unwrap(); +// } + +// let mut reader = buffer.reader(); + +// for x in values.drain(..).take(NUM) { +// let y: u64 = codec.read(&mut reader).unwrap(); +// println!("{x} {y}"); +// assert_eq!(x, y); +// } + +// assert!(reader.is_empty()); +// } +// } +// } From da06c4df1d315baeb43bf7cf30cc6c51ed1c6640 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 18:52:49 +0100 Subject: [PATCH 033/203] Rx improvement --- io/zenoh-transport/src/unicast/rx.rs | 124 +++++++++++++-------------- 1 file changed, 59 insertions(+), 65 deletions(-) diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index 6748830de9..e8fc73576a 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -17,8 +17,6 @@ use async_std::task; use std::sync::MutexGuard; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; -use zenoh_buffers::ZSlice; -use zenoh_collections::SingleOrVec; use zenoh_core::{zlock, zread}; use zenoh_link::LinkUnicast; #[cfg(feature = "stats")] @@ -103,20 +101,69 @@ impl TransportUnicastInner { Ok(()) } - fn handle_frame(&self, payload: SingleOrVec) -> ZResult<()> { + fn handle_frame(&self, frame: Frame) -> ZResult<()> { + let Frame { + reliability, + sn, + qos, + payload, + } = frame; + + let priority = qos.priority(); + let c = if self.is_qos() { + &self.conduit_rx[priority as usize] + } else if priority == Priority::default() { + &self.conduit_rx[0] + } else { + bail!( + "Transport: {}. Unknown conduit: {:?}.", + self.config.zid, + priority + ); + }; + + let mut guard = match reliability { + Reliability::Reliable => zlock!(c.reliable), + Reliability::BestEffort => zlock!(c.best_effort), + }; + + self.verify_sn(sn, &mut guard)?; + for msg in payload.into_iter() { self.trigger_callback(msg)?; } Ok(()) } - fn handle_fragment( - &self, - sn: ZInt, - more: bool, - payload: ZSlice, - mut guard: MutexGuard<'_, TransportChannelRx>, - ) -> ZResult<()> { + fn handle_fragment(&self, fragment: Fragment) -> ZResult<()> { + let Fragment { + reliability, + more, + sn, + qos, + payload, + } = fragment; + + let priority = qos.priority(); + let c = if self.is_qos() { + &self.conduit_rx[priority as usize] + } else if priority == Priority::default() { + &self.conduit_rx[0] + } else { + bail!( + "Transport: {}. Unknown conduit: {:?}.", + self.config.zid, + priority + ); + }; + + let mut guard = match reliability { + Reliability::Reliable => zlock!(c.reliable), + Reliability::BestEffort => zlock!(c.best_effort), + }; + + self.verify_sn(sn, &mut guard)?; + if guard.defrag.is_empty() { let _ = guard.defrag.sync(sn); } @@ -161,61 +208,8 @@ impl TransportUnicastInner { log::trace!("Received: {:?}", msg); // Process the received message match msg.body { - TransportBody::Frame(Frame { - reliability, - sn, - payload, - qos, - }) => { - let priority = qos.priority(); - let c = if self.is_qos() { - &self.conduit_rx[priority as usize] - } else if priority == Priority::default() { - &self.conduit_rx[0] - } else { - bail!( - "Transport: {}. Unknown conduit: {:?}.", - self.config.zid, - priority - ); - }; - - let mut guard = match reliability { - Reliability::Reliable => zlock!(c.reliable), - Reliability::BestEffort => zlock!(c.best_effort), - }; - - self.verify_sn(sn, &mut guard)?; - self.handle_frame(payload) - } - TransportBody::Fragment(Fragment { - reliability, - more, - sn, - payload, - qos, - }) => { - let priority = qos.priority(); - let c = if self.is_qos() { - &self.conduit_rx[priority as usize] - } else if priority == Priority::default() { - &self.conduit_rx[0] - } else { - bail!( - "Transport: {}. Unknown conduit: {:?}.", - self.config.zid, - priority - ); - }; - - let mut guard = match reliability { - Reliability::Reliable => zlock!(c.reliable), - Reliability::BestEffort => zlock!(c.best_effort), - }; - - self.verify_sn(sn, &mut guard)?; - self.handle_fragment(sn, more, payload, guard) - } + TransportBody::Frame(msg) => self.handle_frame(msg), + TransportBody::Fragment(fragment) => self.handle_fragment(fragment), TransportBody::Close(Close { reason, session }) => { self.handle_close(link, reason, session) } From 61382fb64ad85d54379dd4bb6ac23ca969892a22 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 19:18:51 +0100 Subject: [PATCH 034/203] Make codec functions const --- commons/zenoh-codec/benches/codec.rs | 18 +++++++++--------- commons/zenoh-codec/src/core/zbuf.rs | 9 ++++++--- commons/zenoh-codec/src/core/zint.rs | 2 +- commons/zenoh-codec/src/lib.rs | 16 +++++++++++----- commons/zenoh-codec/src/zenoh/data.rs | 3 ++- commons/zenoh-codec/src/zenoh/mod.rs | 13 ++++++------- commons/zenoh-codec/src/zenoh/unit.rs | 3 ++- commons/zenoh-codec/tests/codec.rs | 8 ++++---- commons/zenoh-protocol/src/common/extension.rs | 10 +++++----- io/zenoh-link-commons/src/lib.rs | 8 ++++---- io/zenoh-transport/src/common/batch.rs | 8 ++++---- io/zenoh-transport/src/common/pipeline.rs | 4 ++-- .../unicast/establishment/accept/init_ack.rs | 2 +- .../unicast/establishment/accept/open_syn.rs | 2 +- .../establishment/authenticator/pubkey.rs | 10 +++++----- .../unicast/establishment/authenticator/shm.rs | 8 ++++---- .../authenticator/userpassword.rs | 8 ++++---- .../src/unicast/establishment/cookie.rs | 4 ++-- .../src/unicast/establishment/properties.rs | 4 ++-- io/zenoh-transport/src/unicast/link.rs | 4 ++-- zenoh/src/net/runtime/orchestrator.rs | 8 ++++---- 21 files changed, 81 insertions(+), 71 deletions(-) diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 9bc1203a99..d14c6c7c04 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -31,7 +31,7 @@ use zenoh_protocol::{ fn criterion_benchmark(c: &mut Criterion) { // ZInt Vec let mut buff = vec![]; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); c.bench_function("ZInt Vec", |b| { b.iter(|| { buff.clear(); @@ -44,7 +44,7 @@ fn criterion_benchmark(c: &mut Criterion) { // ZInt BBuf let mut buff = BBuf::with_capacity(BATCH_SIZE as usize); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); c.bench_function("ZInt BBuf", |b| { b.iter(|| { buff.clear(); @@ -57,7 +57,7 @@ fn criterion_benchmark(c: &mut Criterion) { // ZInt ZBuf let mut buff = ZBuf::default(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); c.bench_function("ZInt ZBuf", |b| { b.iter(|| { buff.clear(); @@ -70,7 +70,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Batch BBuf Write let mut buff = BBuf::with_capacity(u16::MAX as usize); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let frame = FrameHeader { reliability: Reliability::default(), @@ -107,7 +107,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Batch ZSlice Read NoAlloc let mut buff = BBuf::with_capacity(u16::MAX as usize); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let frame = FrameHeader { reliability: Reliability::default(), @@ -139,7 +139,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Batch ZSlice Read NoAlloc let mut buff = BBuf::with_capacity(u16::MAX as usize); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let frame = FrameHeader { reliability: Reliability::default(), @@ -177,7 +177,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Fragmentation ZBuf Write let mut buff = ZBuf::default(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let data = Data { key: 0.into(), @@ -195,7 +195,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Fragmentation ZBuf Read let mut buff = vec![]; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let data = Data { key: 0.into(), @@ -225,7 +225,7 @@ fn criterion_benchmark(c: &mut Criterion) { // Fragmentation ZSlice ZBuf Read let mut buff = vec![]; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let data = Data { key: 0.into(), diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index ffea9128f4..b98af71ee4 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -55,7 +55,6 @@ where // ZBuf sliced #[cfg(feature = "shared-memory")] -#[derive(Default)] struct Zenoh080Sliced { codec: Zenoh080, } @@ -126,7 +125,9 @@ where let is_sliced = self.condition; if is_sliced { - let codec = Zenoh080Sliced::default(); + let codec = Zenoh080Sliced { + codec: Zenoh080::new(), + }; codec.write(&mut *writer, x) } else { self.codec.write(&mut *writer, x) @@ -145,7 +146,9 @@ where let is_sliced = self.condition; if is_sliced { - let codec = Zenoh080Sliced::default(); + let codec = Zenoh080Sliced { + codec: Zenoh080::new(), + }; codec.read(&mut *reader) } else { self.codec.read(&mut *reader) diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index b809a1f614..61e07c0ffd 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -261,7 +261,7 @@ where // const NUM: usize = 1_000; // const LIMIT: [u64; 4] = [u8::MAX as u64, u16::MAX as u64, u32::MAX as u64, u64::MAX]; -// let codec = Zenoh080::default(); +// let codec = Zenoh080::new(); // let mut rng = rand::thread_rng(); // for l in LIMIT.iter() { diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 03b24ae3bf..30fb794f06 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -32,9 +32,15 @@ pub trait RCodec { fn read(self, buffer: Buffer) -> Result; } -#[derive(Clone, Copy, Default)] +#[derive(Clone, Copy)] pub struct Zenoh080; +impl Zenoh080 { + pub const fn new() -> Self { + Self + } +} + #[derive(Clone, Copy)] pub struct Zenoh080Header { pub header: u8, @@ -50,7 +56,7 @@ impl Zenoh080Header { } } -#[derive(Clone, Copy, Default)] +#[derive(Clone, Copy)] pub struct Zenoh080Condition { pub condition: bool, pub codec: Zenoh080, @@ -65,7 +71,7 @@ impl Zenoh080Condition { } } -#[derive(Clone, Copy, Default)] +#[derive(Clone, Copy)] pub struct Zenoh080Length { pub length: usize, pub codec: Zenoh080, @@ -80,7 +86,7 @@ impl Zenoh080Length { } } -#[derive(Clone, Copy, Default)] +#[derive(Clone, Copy)] pub struct Zenoh080Reliability { pub reliability: Reliability, pub codec: Zenoh080, @@ -95,7 +101,7 @@ impl Zenoh080Reliability { } } -#[derive(Clone, Default)] +#[derive(Clone)] pub struct Zenoh080HeaderReplyContext { pub header: u8, pub reply_context: Option, diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index e35a95cb9e..3b26a992c5 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -239,7 +239,8 @@ where fn read(self, reader: &mut R) -> Result { let mut codec = Zenoh080HeaderReplyContext { header: self.read(&mut *reader)?, - ..Default::default() + reply_context: None, + codec: Zenoh080::new(), }; if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { let hodec = Zenoh080Header::new(codec.header); diff --git a/commons/zenoh-codec/src/zenoh/mod.rs b/commons/zenoh-codec/src/zenoh/mod.rs index f0bdabba7f..9fc243036d 100644 --- a/commons/zenoh-codec/src/zenoh/mod.rs +++ b/commons/zenoh-codec/src/zenoh/mod.rs @@ -64,10 +64,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Reliability { - reliability: Reliability::default(), - ..Default::default() - }; + let codec = Zenoh080Reliability::new(Reliability::default()); codec.read(reader) } } @@ -103,7 +100,7 @@ where let rodec = Zenoh080HeaderReplyContext { header: self.codec.read(&mut *reader)?, reply_context: Some(rc), - ..Default::default() + codec: Zenoh080::new(), }; match imsg::mid(rodec.header) { zmsg::id::DATA => ZenohBody::Data(rodec.read(&mut *reader)?), @@ -114,14 +111,16 @@ where zmsg::id::DATA => { let rodec = Zenoh080HeaderReplyContext { header: codec.header, - ..Default::default() + reply_context: None, + codec: Zenoh080::new(), }; ZenohBody::Data(rodec.read(&mut *reader)?) } zmsg::id::UNIT => { let rodec = Zenoh080HeaderReplyContext { header: codec.header, - ..Default::default() + reply_context: None, + codec: Zenoh080::new(), }; ZenohBody::Unit(rodec.read(&mut *reader)?) } diff --git a/commons/zenoh-codec/src/zenoh/unit.rs b/commons/zenoh-codec/src/zenoh/unit.rs index b23779f57a..65655c28de 100644 --- a/commons/zenoh-codec/src/zenoh/unit.rs +++ b/commons/zenoh-codec/src/zenoh/unit.rs @@ -54,7 +54,8 @@ where fn read(self, reader: &mut R) -> Result { let mut codec = Zenoh080HeaderReplyContext { header: self.read(&mut *reader)?, - ..Default::default() + reply_context: None, + codec: Zenoh080::new(), }; if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { let hodec = Zenoh080Header::new(codec.header); diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 65a529b5b3..a048c605e6 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -107,7 +107,7 @@ macro_rules! run_buffers { macro_rules! run { ($type:ty, $rand:expr) => { - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); run_buffers!($type, $rand, codec, codec); }; ($type:ty, $rand:expr, $wcode:block, $rcode:block) => { @@ -172,7 +172,7 @@ fn codec_encoding() { fn codec_extension() { macro_rules! run_extension_single { ($ext:ty, $buff:expr) => { - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); for _ in 0..NUM_ITER { let more: bool = thread_rng().gen(); @@ -397,7 +397,7 @@ fn codec_zenoh() { x.channel.reliability = Reliability::Reliable; x }, - { Zenoh080::default() }, + { Zenoh080::new() }, { Zenoh080Reliability::new(Reliability::Reliable) } ); run!( @@ -407,7 +407,7 @@ fn codec_zenoh() { x.channel.reliability = Reliability::BestEffort; x }, - { Zenoh080::default() }, + { Zenoh080::new() }, { Zenoh080Reliability::new(Reliability::BestEffort) } ); } diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index dd4c919afe..54bcc70cf3 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -62,13 +62,13 @@ pub mod iext { pub const FLAG_Z: u8 = 1 << 7; } -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ZExtUnit; impl ZExtUnit<{ ID }> { pub const ID: u8 = ID; - pub fn new() -> Self { + pub const fn new() -> Self { Self } @@ -86,7 +86,7 @@ pub struct ZExtZInt { impl ZExtZInt<{ ID }> { pub const ID: u8 = ID; - pub fn new(value: ZInt) -> Self { + pub const fn new(value: ZInt) -> Self { Self { value } } @@ -108,7 +108,7 @@ pub struct ZExtZSlice { impl ZExtZSlice<{ ID }> { pub const ID: u8 = ID; - pub fn new(value: ZSlice) -> Self { + pub const fn new(value: ZSlice) -> Self { Self { value } } @@ -130,7 +130,7 @@ pub struct ZExtZBuf { impl ZExtZBuf<{ ID }> { pub const ID: u8 = ID; - pub fn new(value: ZBuf) -> Self { + pub const fn new(value: ZBuf) -> Self { Self { value } } diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index 51a4f1417c..b27786bac9 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -155,7 +155,7 @@ impl LinkUnicast { // Create the buffer for serializing the message let mut buff = vec![]; let mut writer = buff.writer(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); // Reserve 16 bits to write the length if self.is_streamed() { @@ -201,7 +201,7 @@ impl LinkUnicast { }; let mut reader = buffer.reader(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut messages: Vec = Vec::with_capacity(1); while reader.can_read() { @@ -293,7 +293,7 @@ impl LinkMulticast { // Create the buffer for serializing the message let mut buff = vec![]; let mut writer = buff.writer(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); codec .write(&mut writer, msg) .map_err(|_| zerror!("Encoding error on link: {}", self))?; @@ -311,7 +311,7 @@ impl LinkMulticast { buffer.truncate(n); let mut reader = buffer.reader(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut messages: Vec = Vec::with_capacity(1); while reader.can_read() { diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 0e4bf3c563..0c3cdf4b51 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -194,7 +194,7 @@ impl Encode<&TransportMessage> for &mut WBatch { let mut writer = self.buffer.writer(); let mark = writer.mark(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); codec.write(&mut writer, message).map_err(|e| { // Revert the write operation writer.rewind(mark); @@ -239,7 +239,7 @@ impl Encode<&ZenohMessage> for &mut WBatch { let mut writer = self.buffer.writer(); let mark = writer.mark(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); codec.write(&mut writer, message).map_err(|_| { // Revert the write operation writer.rewind(mark); @@ -263,7 +263,7 @@ impl Encode<(&ZenohMessage, &FrameHeader)> for &mut WBatch { let mut writer = self.buffer.writer(); let mark = writer.mark(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); // Write the frame header codec.write(&mut writer, frame).map_err(|e| { // Revert the write operation @@ -303,7 +303,7 @@ impl Encode<(&mut ZBufReader<'_>, &mut FragmentHeader)> for &mut WBatch { let (reader, fragment) = message; let mut writer = self.buffer.writer(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); // Mark the buffer for the writing operation let mark = writer.mark(); diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 43cd8d3946..f44472d842 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -216,7 +216,7 @@ impl StageIn { self.fragbuf.clear(); let mut writer = self.fragbuf.writer(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); codec.write(&mut writer, &*msg).unwrap(); // Fragment the whole message @@ -776,7 +776,7 @@ mod tests { let bytes = batch.as_bytes(); // Deserialize the messages let mut reader = bytes.reader(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); loop { let res: Result = codec.read(&mut reader); diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs index 372fe4db18..19eac95b17 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs @@ -110,7 +110,7 @@ pub(super) async fn send( let mut codec = Zenoh080Cookie { prng: &mut *zasynclock!(manager.prng), cipher: &manager.cipher, - codec: Zenoh080::default(), + codec: Zenoh080::new(), }; codec.write(&mut writer, &cookie).map_err(|_| { ( diff --git a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs b/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs index 63211024ff..101d8441c3 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs @@ -92,7 +92,7 @@ pub(super) async fn recv( let mut codec = Zenoh080Cookie { prng: &mut *zasynclock!(manager.prng), cipher: &manager.cipher, - codec: Zenoh080::default(), + codec: Zenoh080::new(), }; let mut cookie: Cookie = codec.read(&mut reader).map_err(|_| { ( diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs index 33fe848985..cf44f4f7fd 100644 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs @@ -395,7 +395,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { }; let mut wbuf = vec![]; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut writer = wbuf.writer(); codec .write(&mut writer, &init_syn_property) @@ -415,7 +415,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { Some(pk) => { // Decode the multilink attachment let mut reader = pk.reader(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { zerror!( @@ -465,7 +465,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { } // Create the InitAck attachment - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut wbuf = vec![]; let mut writer = wbuf.writer(); @@ -532,7 +532,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { None => return Ok(None), }; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut reader = pk.reader(); let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { @@ -580,7 +580,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { ) -> ZResult>> { match property { (Some(att), Some(cke)) => { - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut reader = att.reader(); let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs b/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs index a2e9a39e0a..00c844ed40 100644 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs @@ -245,7 +245,7 @@ impl PeerAuthenticatorTrait for SharedMemoryAuthenticator { shm: self.buffer.info.serialize().unwrap().into(), }; let mut buff = vec![]; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut writer = buff.writer(); codec @@ -269,7 +269,7 @@ impl PeerAuthenticatorTrait for SharedMemoryAuthenticator { } }; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut reader = buffer.reader(); let mut init_syn_property: InitSynProperty = codec @@ -336,7 +336,7 @@ impl PeerAuthenticatorTrait for SharedMemoryAuthenticator { } }; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut reader = buffer.reader(); let mut init_ack_property: InitAckProperty = codec @@ -401,7 +401,7 @@ impl PeerAuthenticatorTrait for SharedMemoryAuthenticator { } }; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut reader = buffer.reader(); let open_syn_property: OpenSynProperty = codec diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs b/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs index 0649e2ad28..43ddf88be1 100644 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs +++ b/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs @@ -273,7 +273,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { version: USRPWD_VERSION, }; let mut wbuf = vec![]; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut writer = wbuf.writer(); codec .write(&mut writer, &init_syn_property) @@ -296,7 +296,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { ) })?; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut reader = p.reader(); let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { @@ -343,7 +343,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { ) })?; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut reader = p.reader(); let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { @@ -386,7 +386,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { ) })?; - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let mut reader = a.reader(); let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index c85e364783..4ba0525745 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -191,7 +191,7 @@ mod tests { }; } - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); run!(Cookie, Cookie::rand(), codec); let mut prng = PseudoRng::from_entropy(); @@ -202,7 +202,7 @@ mod tests { let mut codec = Zenoh080Cookie { prng: &mut prng, cipher: &cipher, - codec: Zenoh080::default(), + codec: Zenoh080::new(), }; run!(Cookie, Cookie::rand(), codec); diff --git a/io/zenoh-transport/src/unicast/establishment/properties.rs b/io/zenoh-transport/src/unicast/establishment/properties.rs index b8dcbff511..ca5e8dffd5 100644 --- a/io/zenoh-transport/src/unicast/establishment/properties.rs +++ b/io/zenoh-transport/src/unicast/establishment/properties.rs @@ -68,7 +68,7 @@ impl TryFrom<&EstablishmentProperties> for Attachment { let mut zbuf = ZBuf::default(); let mut writer = zbuf.writer(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); codec .write(&mut writer, eps.0.as_slice()) @@ -97,7 +97,7 @@ impl TryFrom<&Attachment> for EstablishmentProperties { fn try_from(att: &Attachment) -> Result { let mut reader = att.buffer.reader(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let ps: Vec = codec.read(&mut reader).map_err(|_| zerror!(""))?; EstablishmentProperties::try_from(ps) diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/link.rs index 60a22ac0e8..6cad2ad8f0 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/link.rs @@ -255,7 +255,7 @@ async fn rx_task_stream( Ok(Action::Stop) } - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); // The pool of buffers let mtu = link.get_mtu() as usize; @@ -324,7 +324,7 @@ async fn rx_task_dgram( Ok(Action::Stop) } - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); // The pool of buffers let mtu = link.get_mtu() as usize; diff --git a/zenoh/src/net/runtime/orchestrator.rs b/zenoh/src/net/runtime/orchestrator.rs index 11a9a525a2..a04b989658 100644 --- a/zenoh/src/net/runtime/orchestrator.rs +++ b/zenoh/src/net/runtime/orchestrator.rs @@ -493,7 +493,7 @@ impl Runtime { .into(); let mut wbuf = vec![]; let mut writer = wbuf.writer(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); codec.write(&mut writer, &scout).unwrap(); loop { @@ -535,7 +535,7 @@ impl Runtime { match socket.recv_from(&mut buf).await { Ok((n, peer)) => { let mut reader = buf.as_slice()[..n].reader(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let res: Result = codec.read(&mut reader); if let Ok(msg) = res { log::trace!("Received {:?} from {}", msg.body, peer); @@ -695,7 +695,7 @@ impl Runtime { } let mut reader = buf.as_slice()[..n].reader(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let res: Result = codec.read(&mut reader); if let Ok(msg) = res { log::trace!("Received {:?} from {}", msg.body, peer); @@ -703,7 +703,7 @@ impl Runtime { if what.matches(self.whatami) { let mut wbuf = vec![]; let mut writer = wbuf.writer(); - let codec = Zenoh080::default(); + let codec = Zenoh080::new(); let zid = self.manager().zid(); let hello: ScoutingMessage = Hello { From 04ec80edbd2b727a4ff43cf7ce9f52f6380d3ef0 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 23 Feb 2023 19:46:55 +0100 Subject: [PATCH 035/203] Use Vec in frame --- Cargo.lock | 1 - commons/zenoh-codec/Cargo.toml | 1 - commons/zenoh-codec/src/transport/frame.rs | 5 ++--- commons/zenoh-codec/src/transport/mod.rs | 12 +++++----- commons/zenoh-codec/src/zenoh/mod.rs | 22 +++++++------------ commons/zenoh-protocol/src/transport/frame.rs | 6 ++--- io/zenoh-transport/src/unicast/rx.rs | 4 ++-- 7 files changed, 21 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index edb08c22e2..d9deeb664e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3866,7 +3866,6 @@ dependencies = [ "uhlc", "uuid", "zenoh-buffers", - "zenoh-collections", "zenoh-protocol", "zenoh-shm", ] diff --git a/commons/zenoh-codec/Cargo.toml b/commons/zenoh-codec/Cargo.toml index 63ed5e1662..161780ce32 100644 --- a/commons/zenoh-codec/Cargo.toml +++ b/commons/zenoh-codec/Cargo.toml @@ -50,7 +50,6 @@ defmt = [ serde = { workspace = true, features = ["alloc"] } uhlc = { workspace = true } zenoh-buffers = { path = "../zenoh-buffers/", default-features = false } -zenoh-collections = { path = "../zenoh-collections/", default-features = false } zenoh-protocol = { path = "../zenoh-protocol/", default-features = false } zenoh-shm = { path = "../zenoh-shm/", optional = true } diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 896c0bfa71..e95695c877 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -16,7 +16,6 @@ use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_collections::SingleOrVec; use zenoh_protocol::{ common::{imsg, ZExtUnknown, ZExtZInt}, core::{Reliability, ZInt}, @@ -175,7 +174,7 @@ where self.write(&mut *writer, &header)?; // Body - for m in x.payload.as_ref() { + for m in x.payload.iter() { self.write(&mut *writer, m)?; } @@ -206,7 +205,7 @@ where let header: FrameHeader = self.read(&mut *reader)?; let rcode = Zenoh080Reliability::new(header.reliability); - let mut payload = SingleOrVec::default(); + let mut payload = vec![]; while reader.can_read() { let mark = reader.mark(); let res: Result = rcode.read(&mut *reader); diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index 5f82b4d38a..59d90b6a12 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -35,15 +35,15 @@ where fn write(self, writer: &mut W, x: &TransportMessage) -> Self::Output { match &x.body { + TransportBody::Frame(b) => self.write(&mut *writer, b), + TransportBody::Fragment(b) => self.write(&mut *writer, b), + TransportBody::KeepAlive(b) => self.write(&mut *writer, b), TransportBody::InitSyn(b) => self.write(&mut *writer, b), TransportBody::InitAck(b) => self.write(&mut *writer, b), TransportBody::OpenSyn(b) => self.write(&mut *writer, b), TransportBody::OpenAck(b) => self.write(&mut *writer, b), TransportBody::Join(b) => self.write(&mut *writer, b), TransportBody::Close(b) => self.write(&mut *writer, b), - TransportBody::KeepAlive(b) => self.write(&mut *writer, b), - TransportBody::Frame(b) => self.write(&mut *writer, b), - TransportBody::Fragment(b) => self.write(&mut *writer, b), } } } @@ -59,6 +59,9 @@ where let codec = Zenoh080Header::new(header); let body = match imsg::mid(codec.header) { + id::FRAME => TransportBody::Frame(codec.read(&mut *reader)?), + id::FRAGMENT => TransportBody::Fragment(codec.read(&mut *reader)?), + id::KEEP_ALIVE => TransportBody::KeepAlive(codec.read(&mut *reader)?), id::INIT => { if !imsg::has_flag(codec.header, zenoh_protocol::transport::init::flag::A) { TransportBody::InitSyn(codec.read(&mut *reader)?) @@ -75,9 +78,6 @@ where } id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), id::CLOSE => TransportBody::Close(codec.read(&mut *reader)?), - id::KEEP_ALIVE => TransportBody::KeepAlive(codec.read(&mut *reader)?), - id::FRAME => TransportBody::Frame(codec.read(&mut *reader)?), - id::FRAGMENT => TransportBody::Fragment(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/src/zenoh/mod.rs b/commons/zenoh-codec/src/zenoh/mod.rs index 9fc243036d..b90e082510 100644 --- a/commons/zenoh-codec/src/zenoh/mod.rs +++ b/commons/zenoh-codec/src/zenoh/mod.rs @@ -93,25 +93,19 @@ where } else { Priority::default() }; + let reply_context = if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { + let rc: ReplyContext = codec.read(&mut *reader)?; + codec.header = self.codec.read(&mut *reader)?; + Some(rc) + } else { + None + }; let body = match imsg::mid(codec.header) { - zmsg::id::REPLY_CONTEXT => { - let rc: ReplyContext = codec.read(&mut *reader)?; - let rodec = Zenoh080HeaderReplyContext { - header: self.codec.read(&mut *reader)?, - reply_context: Some(rc), - codec: Zenoh080::new(), - }; - match imsg::mid(rodec.header) { - zmsg::id::DATA => ZenohBody::Data(rodec.read(&mut *reader)?), - zmsg::id::UNIT => ZenohBody::Unit(rodec.read(&mut *reader)?), - _ => return Err(DidntRead), - } - } zmsg::id::DATA => { let rodec = Zenoh080HeaderReplyContext { header: codec.header, - reply_context: None, + reply_context, codec: Zenoh080::new(), }; ZenohBody::Data(rodec.read(&mut *reader)?) diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index fe2c2a0d40..6cbe85dece 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -15,7 +15,7 @@ use crate::{ core::{Reliability, ZInt}, zenoh::ZenohMessage, }; -use zenoh_collections::SingleOrVec; +use alloc::vec::Vec; /// # Frame message /// @@ -75,7 +75,7 @@ pub struct Frame { pub reliability: Reliability, pub sn: ZInt, pub qos: ext::QoS, - pub payload: SingleOrVec, + pub payload: Vec, } // Extensions @@ -166,7 +166,7 @@ impl Frame { }; let sn: ZInt = rng.gen(); let qos = ext::QoS::rand(); - let mut payload = SingleOrVec::default(); + let mut payload = vec![]; for _ in 0..rng.gen_range(1..4) { let mut m = ZenohMessage::rand(); m.channel.reliability = reliability; diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index e8fc73576a..b3ea6caeb6 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -106,7 +106,7 @@ impl TransportUnicastInner { reliability, sn, qos, - payload, + mut payload, } = frame; let priority = qos.priority(); @@ -129,7 +129,7 @@ impl TransportUnicastInner { self.verify_sn(sn, &mut guard)?; - for msg in payload.into_iter() { + for msg in payload.drain(..) { self.trigger_callback(msg)?; } Ok(()) From a40455241321149e88fd5a578a3efe9672f3ea49 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 24 Feb 2023 09:36:59 +0100 Subject: [PATCH 036/203] Improve frame encoding --- commons/zenoh-codec/src/transport/mod.rs | 6 +++--- commons/zenoh-codec/tests/codec.rs | 8 ++++---- commons/zenoh-protocol/src/transport/mod.rs | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index 59d90b6a12..7e3d7caf42 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -15,7 +15,7 @@ mod close; mod fragment; mod frame; mod init; -mod join; +// mod join; mod keepalive; mod open; @@ -42,7 +42,7 @@ where TransportBody::InitAck(b) => self.write(&mut *writer, b), TransportBody::OpenSyn(b) => self.write(&mut *writer, b), TransportBody::OpenAck(b) => self.write(&mut *writer, b), - TransportBody::Join(b) => self.write(&mut *writer, b), + // TransportBody::Join(b) => self.write(&mut *writer, b), TransportBody::Close(b) => self.write(&mut *writer, b), } } @@ -76,7 +76,7 @@ where TransportBody::OpenAck(codec.read(&mut *reader)?) } } - id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), + // id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), id::CLOSE => TransportBody::Close(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index a048c605e6..bdef98019c 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -252,10 +252,10 @@ fn codec_open_ack() { run!(OpenAck, OpenAck::rand()); } -#[test] -fn codec_join() { - run!(Join, Join::rand()); -} +// #[test] +// fn codec_join() { +// run!(Join, Join::rand()); +// } #[test] fn codec_close() { diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index e3300cfab2..dc8b708c3a 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -15,7 +15,7 @@ pub mod close; pub mod fragment; pub mod frame; pub mod init; -pub mod join; +// pub mod join; pub mod keepalive; pub mod open; @@ -25,12 +25,12 @@ use core::{convert::TryInto, fmt}; pub use fragment::{Fragment, FragmentHeader}; pub use frame::{Frame, FrameHeader}; pub use init::{InitAck, InitSyn}; -pub use join::Join; +// pub use join::Join; pub use keepalive::KeepAlive; pub use open::{OpenAck, OpenSyn}; pub mod id { - pub const JOIN: u8 = 0x01; // For multicast communications only + // pub const JOIN: u8 = 0x01; // For multicast communications only pub const INIT: u8 = 0x02; // For unicast communications only pub const OPEN: u8 = 0x03; // For unicast communications only pub const CLOSE: u8 = 0x04; @@ -93,7 +93,7 @@ pub enum TransportBody { InitAck(InitAck), OpenSyn(OpenSyn), OpenAck(OpenAck), - Join(Join), + // Join(Join), Close(Close), KeepAlive(KeepAlive), Frame(Frame), @@ -120,7 +120,7 @@ impl TransportMessage { 1 => TransportBody::InitAck(InitAck::rand()), 2 => TransportBody::OpenSyn(OpenSyn::rand()), 3 => TransportBody::OpenAck(OpenAck::rand()), - 4 => TransportBody::Join(Join::rand()), + // 4 => TransportBody::Join(Join::rand()), 5 => TransportBody::Close(Close::rand()), 6 => TransportBody::KeepAlive(KeepAlive::rand()), 7 => TransportBody::Frame(Frame::rand()), @@ -166,11 +166,11 @@ impl From for TransportMessage { } } -impl From for TransportMessage { - fn from(join: Join) -> Self { - TransportBody::Join(join).into() - } -} +// impl From for TransportMessage { +// fn from(join: Join) -> Self { +// TransportBody::Join(join).into() +// } +// } impl From for TransportMessage { fn from(close: Close) -> Self { From 5983ecf14a408463894d110d5bea7817a64952d6 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 24 Feb 2023 12:47:34 +0100 Subject: [PATCH 037/203] Improve frame encoding --- commons/zenoh-codec/src/transport/fragment.rs | 6 +- commons/zenoh-codec/src/transport/frame.rs | 22 +++--- commons/zenoh-codec/src/transport/mod.rs | 6 +- commons/zenoh-codec/tests/codec.rs | 8 +-- .../zenoh-protocol/src/transport/fragment.rs | 2 +- commons/zenoh-protocol/src/transport/frame.rs | 68 ++++--------------- commons/zenoh-protocol/src/transport/mod.rs | 20 +++--- io/zenoh-transport/src/common/batch.rs | 22 +++--- io/zenoh-transport/src/common/pipeline.rs | 8 +-- io/zenoh-transport/src/unicast/rx.rs | 16 ++--- 10 files changed, 70 insertions(+), 108 deletions(-) diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index 0713ce11d1..18c6a10910 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -51,7 +51,7 @@ where // Extensions if x.qos != ext::QoS::default() { - self.write(&mut *writer, (&x.qos.inner, false))?; + self.write(&mut *writer, (x.qos, false))?; } Ok(()) @@ -136,9 +136,7 @@ where self.write(&mut *writer, &header)?; // Body - for m in x.payload.as_ref() { - self.write(&mut *writer, m)?; - } + self.write(&mut *writer, &x.payload)?; Ok(()) } diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index e95695c877..7c183a24bd 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -1,3 +1,5 @@ +use core::convert::TryInto; + // // Copyright (c) 2022 ZettaScale Technology // @@ -18,7 +20,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{imsg, ZExtUnknown, ZExtZInt}, - core::{Reliability, ZInt}, + core::{Priority, Reliability, ZInt}, transport::{ frame::{ext, flag, Frame, FrameHeader}, id, @@ -27,15 +29,16 @@ use zenoh_protocol::{ }; // Extensions: QoS -impl WCodec<(&ext::QoS, bool), &mut W> for Zenoh080 +impl WCodec<(ext::QoS, bool), &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: (&ext::QoS, bool)) -> Self::Output { - let (ext, more) = x; - self.write(&mut *writer, (&ext.inner, more)) + fn write(self, writer: &mut W, x: (ext::QoS, bool)) -> Self::Output { + let (qos, more) = x; + let ext: ZExtZInt<{ ext::QOS }> = ZExtZInt::new(qos.priority as ZInt); + self.write(&mut *writer, (&ext, more)) } } @@ -64,8 +67,11 @@ where return Err(DidntRead); } - let (inner, more): (ZExtZInt<{ ext::QOS }>, bool) = self.read(&mut *reader)?; - Ok((ext::QoS { inner }, more)) + let (ext, more): (ZExtZInt<{ ext::QOS }>, bool) = self.read(&mut *reader)?; + + let v: u8 = ext.value.try_into().map_err(|_| DidntRead)?; + let priority: Priority = v.try_into().map_err(|_| DidntRead)?; + Ok((ext::QoS { priority }, more)) } } @@ -92,7 +98,7 @@ where // Extensions if x.qos != ext::QoS::default() { - self.write(&mut *writer, (&x.qos.inner, false))?; + self.write(&mut *writer, (x.qos, false))?; } Ok(()) diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index 7e3d7caf42..59d90b6a12 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -15,7 +15,7 @@ mod close; mod fragment; mod frame; mod init; -// mod join; +mod join; mod keepalive; mod open; @@ -42,7 +42,7 @@ where TransportBody::InitAck(b) => self.write(&mut *writer, b), TransportBody::OpenSyn(b) => self.write(&mut *writer, b), TransportBody::OpenAck(b) => self.write(&mut *writer, b), - // TransportBody::Join(b) => self.write(&mut *writer, b), + TransportBody::Join(b) => self.write(&mut *writer, b), TransportBody::Close(b) => self.write(&mut *writer, b), } } @@ -76,7 +76,7 @@ where TransportBody::OpenAck(codec.read(&mut *reader)?) } } - // id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), + id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), id::CLOSE => TransportBody::Close(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index bdef98019c..a048c605e6 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -252,10 +252,10 @@ fn codec_open_ack() { run!(OpenAck, OpenAck::rand()); } -// #[test] -// fn codec_join() { -// run!(Join, Join::rand()); -// } +#[test] +fn codec_join() { + run!(Join, Join::rand()); +} #[test] fn codec_close() { diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs index 077974549b..de874dcea7 100644 --- a/commons/zenoh-protocol/src/transport/fragment.rs +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -111,7 +111,7 @@ impl Fragment { } // FragmentHeader -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FragmentHeader { pub reliability: Reliability, diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 6cbe85dece..5f1c586bd7 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -80,8 +80,7 @@ pub struct Frame { // Extensions pub mod ext { - use crate::core::ZInt; - use crate::{common::ZExtZInt, core::Priority}; + use crate::core::Priority; pub const QOS: u8 = 0x01; @@ -92,56 +91,23 @@ pub mod ext { /// % reserved|prio % /// +---------------+ #[repr(transparent)] - #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub struct QoS { - pub inner: ZExtZInt, + pub priority: Priority, } impl QoS { - pub fn new(priority: Priority) -> Self { - Self { - inner: ZExtZInt::new(priority as ZInt), - } - } - - pub fn priority(&self) -> Priority { - // Safety: a unit test below checks the validity of the following unsafe code - unsafe { core::mem::transmute((self.inner.value & 0b111) as u8) } - } - #[cfg(feature = "test")] pub fn rand() -> Self { - Self { - inner: ZExtZInt::rand(), - } - } - } - - impl Default for QoS { - fn default() -> Self { - Self::new(Priority::default()) - } - } - - mod tests { - #[test] - fn priority() { - use crate::{core::Priority, transport::frame::ext::QoS}; - - let ps = [ - Priority::Control, - Priority::RealTime, - Priority::InteractiveHigh, - Priority::InteractiveLow, - Priority::DataHigh, - Priority::Data, - Priority::DataLow, - Priority::Background, - ]; - for p in ps.iter() { - let q = QoS::new(*p); - assert_eq!(q.priority(), *p); - } + use core::convert::TryInto; + use rand::Rng; + + let mut rng = rand::thread_rng(); + let priority: Priority = rng + .gen_range(Priority::MAX as u8..=Priority::MIN as u8) + .try_into() + .unwrap(); + Self { priority } } } } @@ -149,16 +115,10 @@ pub mod ext { impl Frame { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::Priority; - use core::convert::TryInto; use rand::Rng; let mut rng = rand::thread_rng(); - let priority: Priority = rng - .gen_range(Priority::MAX as u8..=Priority::MIN as u8) - .try_into() - .unwrap(); let reliability = if rng.gen_bool(0.5) { Reliability::Reliable } else { @@ -170,7 +130,7 @@ impl Frame { for _ in 0..rng.gen_range(1..4) { let mut m = ZenohMessage::rand(); m.channel.reliability = reliability; - m.channel.priority = priority; + m.channel.priority = qos.priority; payload.push(m); } @@ -184,7 +144,7 @@ impl Frame { } // FrameHeader -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FrameHeader { pub reliability: Reliability, diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index dc8b708c3a..e3300cfab2 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -15,7 +15,7 @@ pub mod close; pub mod fragment; pub mod frame; pub mod init; -// pub mod join; +pub mod join; pub mod keepalive; pub mod open; @@ -25,12 +25,12 @@ use core::{convert::TryInto, fmt}; pub use fragment::{Fragment, FragmentHeader}; pub use frame::{Frame, FrameHeader}; pub use init::{InitAck, InitSyn}; -// pub use join::Join; +pub use join::Join; pub use keepalive::KeepAlive; pub use open::{OpenAck, OpenSyn}; pub mod id { - // pub const JOIN: u8 = 0x01; // For multicast communications only + pub const JOIN: u8 = 0x01; // For multicast communications only pub const INIT: u8 = 0x02; // For unicast communications only pub const OPEN: u8 = 0x03; // For unicast communications only pub const CLOSE: u8 = 0x04; @@ -93,7 +93,7 @@ pub enum TransportBody { InitAck(InitAck), OpenSyn(OpenSyn), OpenAck(OpenAck), - // Join(Join), + Join(Join), Close(Close), KeepAlive(KeepAlive), Frame(Frame), @@ -120,7 +120,7 @@ impl TransportMessage { 1 => TransportBody::InitAck(InitAck::rand()), 2 => TransportBody::OpenSyn(OpenSyn::rand()), 3 => TransportBody::OpenAck(OpenAck::rand()), - // 4 => TransportBody::Join(Join::rand()), + 4 => TransportBody::Join(Join::rand()), 5 => TransportBody::Close(Close::rand()), 6 => TransportBody::KeepAlive(KeepAlive::rand()), 7 => TransportBody::Frame(Frame::rand()), @@ -166,11 +166,11 @@ impl From for TransportMessage { } } -// impl From for TransportMessage { -// fn from(join: Join) -> Self { -// TransportBody::Join(join).into() -// } -// } +impl From for TransportMessage { + fn from(join: Join) -> Self { + TransportBody::Join(join).into() + } +} impl From for TransportMessage { fn from(close: Close) -> Self { diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 0c3cdf4b51..f7cf033e1a 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -248,7 +248,7 @@ impl Encode<&ZenohMessage> for &mut WBatch { } } -impl Encode<(&ZenohMessage, &FrameHeader)> for &mut WBatch { +impl Encode<(&ZenohMessage, FrameHeader)> for &mut WBatch { type Output = Result<(), DidntWrite>; /// Try to serialize a [`ZenohMessage`][ZenohMessage] on the [`SerializationBatch`][SerializationBatch]. @@ -256,7 +256,7 @@ impl Encode<(&ZenohMessage, &FrameHeader)> for &mut WBatch { /// # Arguments /// * `message` - The [`ZenohMessage`][ZenohMessage] to serialize. /// - fn encode(self, message: (&ZenohMessage, &FrameHeader)) -> Self::Output { + fn encode(self, message: (&ZenohMessage, FrameHeader)) -> Self::Output { let (message, frame) = message; // Mark the write operation @@ -265,7 +265,7 @@ impl Encode<(&ZenohMessage, &FrameHeader)> for &mut WBatch { let codec = Zenoh080::new(); // Write the frame header - codec.write(&mut writer, frame).map_err(|e| { + codec.write(&mut writer, &frame).map_err(|e| { // Revert the write operation writer.rewind(mark); e @@ -291,7 +291,7 @@ impl Encode<(&ZenohMessage, &FrameHeader)> for &mut WBatch { } } -impl Encode<(&mut ZBufReader<'_>, &mut FragmentHeader)> for &mut WBatch { +impl Encode<(&mut ZBufReader<'_>, FragmentHeader)> for &mut WBatch { type Output = Result; /// Try to serialize a [`ZenohMessage`][ZenohMessage] on the [`SerializationBatch`][SerializationBatch]. @@ -299,8 +299,8 @@ impl Encode<(&mut ZBufReader<'_>, &mut FragmentHeader)> for &mut WBatch { /// # Arguments /// * `message` - The [`ZenohMessage`][ZenohMessage] to serialize. /// - fn encode(self, message: (&mut ZBufReader<'_>, &mut FragmentHeader)) -> Self::Output { - let (reader, fragment) = message; + fn encode(self, message: (&mut ZBufReader<'_>, FragmentHeader)) -> Self::Output { + let (reader, mut fragment) = message; let mut writer = self.buffer.writer(); let codec = Zenoh080::new(); @@ -309,7 +309,7 @@ impl Encode<(&mut ZBufReader<'_>, &mut FragmentHeader)> for &mut WBatch { let mark = writer.mark(); // Write the frame header - codec.write(&mut writer, &*fragment).map_err(|e| { + codec.write(&mut writer, &fragment).map_err(|e| { // Revert the write operation writer.rewind(mark); e @@ -322,7 +322,7 @@ impl Encode<(&mut ZBufReader<'_>, &mut FragmentHeader)> for &mut WBatch { // It is really the finally fragment, reserialize the header fragment.more = false; // Write the frame header - codec.write(&mut writer, &*fragment).map_err(|e| { + codec.write(&mut writer, &fragment).map_err(|e| { // Revert the write operation writer.rewind(mark); e @@ -384,7 +384,7 @@ mod tests { }; // Serialize with a frame - batch.encode((&zmsg, &frame)).unwrap(); + batch.encode((&zmsg, frame)).unwrap(); assert_ne!(batch.len(), 0); zmsgs_in.push(zmsg.clone()); @@ -394,7 +394,7 @@ mod tests { assert_ne!(batch.len(), 0); frame.reliability = zmsg.channel.reliability; - batch.encode((&zmsg, &frame)).unwrap(); + batch.encode((&zmsg, frame)).unwrap(); assert_ne!(batch.len(), 0); zmsgs_in.push(zmsg.clone()); @@ -408,7 +408,7 @@ mod tests { // Serialize with a frame frame.sn = 1; - batch.encode((&zmsg, &frame)).unwrap(); + batch.encode((&zmsg, frame)).unwrap(); assert_ne!(batch.len(), 0); zmsgs_in.push(zmsg.clone()); } diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index f44472d842..80da290e74 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -186,12 +186,12 @@ impl StageIn { let frame = FrameHeader { reliability: msg.channel.reliability, sn, - qos: frame::ext::QoS::new(priority), + qos: frame::ext::QoS { priority }, }; if let WError::NewFrame = e { // Attempt a serialization with a new frame - if batch.encode((&*msg, &frame)).is_ok() { + if batch.encode((&*msg, frame)).is_ok() { zretok!(batch); }; } @@ -203,7 +203,7 @@ impl StageIn { } // Attempt a second serialization on fully empty batch - if batch.encode((&*msg, &frame)).is_ok() { + if batch.encode((&*msg, frame)).is_ok() { zretok!(batch); }; @@ -233,7 +233,7 @@ impl StageIn { batch = zgetbatch_rets!(true); // Serialize the message fragmnet - match batch.encode((&mut reader, &mut fragment)) { + match batch.encode((&mut reader, fragment)) { Ok(_) => { // Update the SN fragment.sn = tch.sn.get(); diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index b3ea6caeb6..27d3c979cc 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -109,16 +109,15 @@ impl TransportUnicastInner { mut payload, } = frame; - let priority = qos.priority(); let c = if self.is_qos() { - &self.conduit_rx[priority as usize] - } else if priority == Priority::default() { + &self.conduit_rx[qos.priority as usize] + } else if qos.priority == Priority::default() { &self.conduit_rx[0] } else { bail!( "Transport: {}. Unknown conduit: {:?}.", self.config.zid, - priority + qos.priority ); }; @@ -144,16 +143,15 @@ impl TransportUnicastInner { payload, } = fragment; - let priority = qos.priority(); let c = if self.is_qos() { - &self.conduit_rx[priority as usize] - } else if priority == Priority::default() { + &self.conduit_rx[qos.priority as usize] + } else if qos.priority == Priority::default() { &self.conduit_rx[0] } else { bail!( "Transport: {}. Unknown conduit: {:?}.", self.config.zid, - priority + qos.priority ); }; @@ -209,7 +207,7 @@ impl TransportUnicastInner { // Process the received message match msg.body { TransportBody::Frame(msg) => self.handle_frame(msg), - TransportBody::Fragment(fragment) => self.handle_fragment(fragment), + // TransportBody::Fragment(fragment) => self.handle_fragment(fragment), TransportBody::Close(Close { reason, session }) => { self.handle_close(link, reason, session) } From 64558d876ca45744eff2ca09c9bf39be8e0c0cae Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 24 Feb 2023 14:33:28 +0100 Subject: [PATCH 038/203] Fix broken fragmentation --- io/zenoh-transport/src/unicast/rx.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index 27d3c979cc..1fb5e145a1 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -207,7 +207,7 @@ impl TransportUnicastInner { // Process the received message match msg.body { TransportBody::Frame(msg) => self.handle_frame(msg), - // TransportBody::Fragment(fragment) => self.handle_fragment(fragment), + TransportBody::Fragment(fragment) => self.handle_fragment(fragment), TransportBody::Close(Close { reason, session }) => { self.handle_close(link, reason, session) } From 3673f85e5e1ad485aed79092bf29f8ec7ee814d7 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 24 Feb 2023 15:31:27 +0100 Subject: [PATCH 039/203] Fix unit encoding --- commons/zenoh-codec/src/zenoh/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/zenoh-codec/src/zenoh/mod.rs b/commons/zenoh-codec/src/zenoh/mod.rs index b90e082510..04e4910fd7 100644 --- a/commons/zenoh-codec/src/zenoh/mod.rs +++ b/commons/zenoh-codec/src/zenoh/mod.rs @@ -113,7 +113,7 @@ where zmsg::id::UNIT => { let rodec = Zenoh080HeaderReplyContext { header: codec.header, - reply_context: None, + reply_context, codec: Zenoh080::new(), }; ZenohBody::Unit(rodec.read(&mut *reader)?) From 47196f5b618e62aa82c22a2c19982bc08b204b44 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 24 Feb 2023 17:45:33 +0100 Subject: [PATCH 040/203] ZInt encoding improvement --- commons/zenoh-codec/src/core/zint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 61e07c0ffd..436591c34a 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -101,7 +101,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let x: u64 = >::read(self, reader)?; + let x: u64 = self.read(reader)?; x.try_into().map_err(|_| DidntRead) } } From c22e0589973fd3f78efd3adc7f7c453e2df7bcda Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 27 Feb 2023 10:15:52 +0100 Subject: [PATCH 041/203] Reintroduce QoS negotiation --- .../unicast/establishment/accept/init_ack.rs | 4 +++ .../unicast/establishment/accept/init_syn.rs | 3 ++ .../src/unicast/establishment/accept/mod.rs | 1 + .../src/unicast/establishment/cookie.rs | 19 ++++++------ .../src/unicast/establishment/mod.rs | 3 +- .../unicast/establishment/open/init_ack.rs | 8 ++++- .../unicast/establishment/open/init_syn.rs | 30 ++++++++++--------- .../src/unicast/establishment/open/mod.rs | 1 + 8 files changed, 44 insertions(+), 25 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs index 19eac95b17..b9c9726721 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs @@ -94,6 +94,9 @@ pub(super) async fn send( // Compute the minimum batch size let batch_size = input.batch_size.min(manager.config.batch_size); + // Compute the QoS capabilities + let is_qos = input.is_qos && manager.config.unicast.is_qos; + // Create the cookie let nonce: ZInt = zasynclock!(manager.prng).gen(); let cookie = Cookie { @@ -102,6 +105,7 @@ pub(super) async fn send( resolution, batch_size, nonce, + is_qos, // properties: EstablishmentProperties::new(), }; diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs index 1bc029472d..efca6af9fb 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs @@ -30,7 +30,9 @@ pub(super) struct Output { pub(super) zid: ZenohId, pub(super) resolution: Resolution, pub(super) batch_size: u16, + pub(super) is_qos: bool, } + pub(super) async fn recv(link: &LinkUnicast, manager: &TransportManager) -> AResult { // Wait to read an InitSyn let mut messages = link @@ -97,6 +99,7 @@ pub(super) async fn recv(link: &LinkUnicast, manager: &TransportManager) -> ARes zid: init_syn.zid, resolution: init_syn.resolution, batch_size: init_syn.batch_size, + is_qos: init_syn.qos.is_some(), }; Ok(output) } diff --git a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs index 3d9e6356ef..ee4648e4bc 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs @@ -58,6 +58,7 @@ pub(crate) async fn accept_link( whatami: output.cookie.whatami, resolution: output.cookie.resolution, batch_size: output.cookie.batch_size, + is_qos: output.cookie.is_qos, }; let transport = step!(transport_init(manager, input) .await diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 4ba0525745..93d2b684af 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -27,8 +27,9 @@ pub struct Cookie { pub zid: ZenohId, pub resolution: Resolution, pub batch_size: u16, - // pub is_qos: bool, pub nonce: ZInt, + // Extensions + pub is_qos: bool, // pub properties: EstablishmentProperties, // @TODO } @@ -45,9 +46,9 @@ where self.write(&mut *writer, x.resolution.as_u8())?; self.write(&mut *writer, x.batch_size)?; self.write(&mut *writer, x.nonce)?; - - // let is_qos = u8::from(x.is_qos); - // self.write(&mut *writer, is_qos)?; + // Extensions + let is_qos = u8::from(x.is_qos); + self.write(&mut *writer, is_qos)?; // self.write(&mut *writer, x.properties.as_slice())?; Ok(()) @@ -68,9 +69,9 @@ where let resolution = Resolution::from(resolution); let batch_size: u16 = self.read(&mut *reader)?; let nonce: ZInt = self.read(&mut *reader)?; - - // let is_qos: u8 = self.read(&mut *reader)?; - // let is_qos = is_qos == 1; + // Extensions + let is_qos: u8 = self.read(&mut *reader)?; + let is_qos = is_qos == 1; // let mut ps: Vec = self.read(&mut *reader)?; // let mut properties = EstablishmentProperties::new(); // for p in ps.drain(..) { @@ -83,7 +84,7 @@ where resolution, batch_size, nonce, - // is_qos, + is_qos, // properties, }; @@ -146,7 +147,7 @@ impl Cookie { resolution: Resolution::rand(), batch_size: rng.gen(), nonce: rng.gen(), - // is_qos: rng.gen_bool(0.5), + is_qos: rng.gen_bool(0.5), // properties: EstablishmentProperties::rand(), } } diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 61b3912e8d..be72a23a99 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -65,6 +65,7 @@ pub(super) struct InputInit { pub(super) whatami: WhatAmI, pub(super) resolution: Resolution, pub(super) batch_size: u16, + pub(super) is_qos: bool, } async fn transport_init( manager: &TransportManager, @@ -79,7 +80,7 @@ async fn transport_init( whatami: input.whatami, sn_resolution: input.resolution.get(Field::FrameSN).mask(), is_shm: false, // @TODO - is_qos: false, // @TODO + is_qos: input.is_qos, initial_sn_tx, }; diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs index 1b56fb42cc..8ac01b288a 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs @@ -33,12 +33,14 @@ pub(super) struct Output { pub(super) resolution: Resolution, pub(super) batch_size: u16, pub(super) cookie: ZSlice, + // Extensions + pub(super) is_qos: bool, } pub(super) async fn recv( link: &LinkUnicast, manager: &TransportManager, - _input: super::init_syn::Output, + input: super::init_syn::Output, ) -> OResult { // Wait to read an InitAck let mut messages = link @@ -113,6 +115,9 @@ pub(super) async fn recv( i_bsize }; + // Compute QoS + let is_qos = input.is_qos && init_ack.qos.is_some(); + // // Store the peer id associate do this link // auth_link.peer_id = Some(init_ack.zid); @@ -180,6 +185,7 @@ pub(super) async fn recv( resolution, batch_size, cookie: init_ack.cookie, + is_qos, }; Ok(output) diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs b/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs index 27a867ea1a..c75107dd2e 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs @@ -14,12 +14,18 @@ use super::OResult; use crate::TransportManager; use zenoh_link::LinkUnicast; -use zenoh_protocol::transport::{close, init::InitSyn, TransportMessage}; +use zenoh_protocol::transport::{ + close, + init::{ext, InitSyn}, + TransportMessage, +}; /*************************************/ /* OPEN */ /*************************************/ -pub(super) struct Output; +pub(super) struct Output { + pub(super) is_qos: bool, +} pub(super) async fn send(link: &LinkUnicast, manager: &TransportManager) -> OResult { // let mut ps_attachment = EstablishmentProperties::new(); @@ -38,32 +44,28 @@ pub(super) async fn send(link: &LinkUnicast, manager: &TransportManager) -> ORes // } // } - // Build and send the InitSyn message - // let init_syn_attachment = if ps_attachment.is_empty() { - // None - // } else { - // let att = - // Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; - // Some(att) - // }; // @TODO + // Build QoS extension + let qos = manager.config.unicast.is_qos.then_some(ext::QoS::new()); - let message: TransportMessage = InitSyn { + let msg: TransportMessage = InitSyn { version: manager.config.version, whatami: manager.config.whatami, zid: manager.config.zid, batch_size: manager.config.batch_size, resolution: manager.config.resolution, - qos: None, // @TODO + qos, shm: None, // @TODO auth: None, // @TODO } .into(); let _ = link - .write_transport_message(&message) + .write_transport_message(&msg) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = Output; + let output = Output { + is_qos: qos.is_some(), + }; Ok(output) } diff --git a/io/zenoh-transport/src/unicast/establishment/open/mod.rs b/io/zenoh-transport/src/unicast/establishment/open/mod.rs index dc75e9c8e0..9e854f45e2 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/mod.rs @@ -66,6 +66,7 @@ pub(crate) async fn open_link( whatami: output.whatami, resolution: output.resolution, batch_size: output.batch_size, + is_qos: output.is_qos, }; let transport = step!(super::transport_init(manager, input).await); From b223d39e4e1c80ae3680ebbeb33848095d67b056 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 27 Feb 2023 14:22:52 +0100 Subject: [PATCH 042/203] Batch size negotiation --- .../unicast/establishment/accept/init_ack.rs | 2 +- .../src/unicast/establishment/accept/mod.rs | 3 +- .../src/unicast/establishment/cookie.rs | 8 ++--- .../src/unicast/establishment/mod.rs | 18 +++++------ .../unicast/establishment/open/init_ack.rs | 13 +------- .../src/unicast/establishment/open/mod.rs | 3 +- io/zenoh-transport/src/unicast/link.rs | 30 +++++++++++++++---- io/zenoh-transport/src/unicast/manager.rs | 4 +-- io/zenoh-transport/src/unicast/mod.rs | 2 +- io/zenoh-transport/src/unicast/transport.rs | 9 ++++-- 10 files changed, 52 insertions(+), 40 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs index b9c9726721..949bd578db 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs @@ -103,7 +103,7 @@ pub(super) async fn send( whatami: input.whatami, zid: input.zid, resolution, - batch_size, + tx_batch_size: batch_size, nonce, is_qos, // properties: EstablishmentProperties::new(), diff --git a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs index ee4648e4bc..7b4194a230 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs @@ -53,11 +53,11 @@ pub(crate) async fn accept_link( // Initialize the transport let zid = output.cookie.zid; + let tx_batch_size = output.cookie.tx_batch_size; let input = super::InputInit { zid: output.cookie.zid, whatami: output.cookie.whatami, resolution: output.cookie.resolution, - batch_size: output.cookie.batch_size, is_qos: output.cookie.is_qos, }; let transport = step!(transport_init(manager, input) @@ -114,6 +114,7 @@ pub(crate) async fn accept_link( let input = InputFinalize { transport: transport.clone(), lease, + tx_batch_size, }; step!(transport_finalize(link, manager, input) .await diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 93d2b684af..143590111f 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -26,7 +26,7 @@ pub struct Cookie { pub whatami: WhatAmI, pub zid: ZenohId, pub resolution: Resolution, - pub batch_size: u16, + pub tx_batch_size: u16, pub nonce: ZInt, // Extensions pub is_qos: bool, @@ -44,7 +44,7 @@ where self.write(&mut *writer, wai)?; self.write(&mut *writer, &x.zid)?; self.write(&mut *writer, x.resolution.as_u8())?; - self.write(&mut *writer, x.batch_size)?; + self.write(&mut *writer, x.tx_batch_size)?; self.write(&mut *writer, x.nonce)?; // Extensions let is_qos = u8::from(x.is_qos); @@ -82,7 +82,7 @@ where whatami, zid, resolution, - batch_size, + tx_batch_size: batch_size, nonce, is_qos, // properties, @@ -145,7 +145,7 @@ impl Cookie { whatami: WhatAmI::rand(), zid: ZenohId::default(), resolution: Resolution::rand(), - batch_size: rng.gen(), + tx_batch_size: rng.gen(), nonce: rng.gen(), is_qos: rng.gen_bool(0.5), // properties: EstablishmentProperties::rand(), diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index be72a23a99..8e20b2c297 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -64,7 +64,6 @@ pub(super) struct InputInit { pub(super) zid: ZenohId, pub(super) whatami: WhatAmI, pub(super) resolution: Resolution, - pub(super) batch_size: u16, pub(super) is_qos: bool, } async fn transport_init( @@ -72,16 +71,16 @@ async fn transport_init( input: self::InputInit, ) -> ZResult { // Initialize the transport if it is new - let initial_sn_tx = + let tx_initial_sn = zasynclock!(manager.prng).gen_range(0..=input.resolution.get(Field::FrameSN).mask()); let config = TransportConfigUnicast { peer: input.zid, whatami: input.whatami, sn_resolution: input.resolution.get(Field::FrameSN).mask(), - is_shm: false, // @TODO + tx_initial_sn, is_qos: input.is_qos, - initial_sn_tx, + is_shm: false, // @TODO }; manager.init_transport_unicast(config) @@ -90,6 +89,7 @@ async fn transport_init( pub(super) struct InputFinalize { pub(super) transport: TransportUnicast, pub(super) lease: Duration, + pub(super) tx_batch_size: u16, } // Finalize the transport, notify the callback and start the link tasks pub(super) async fn transport_finalize( @@ -102,12 +102,8 @@ pub(super) async fn transport_finalize( // Start the TX loop let keep_alive = manager.config.unicast.lease / manager.config.unicast.keep_alive as u32; - transport.start_tx( - link, - &manager.tx_executor, - keep_alive, - manager.config.batch_size, - )?; + let batch_size = manager.config.batch_size.min(input.tx_batch_size); + transport.start_tx(link, &manager.tx_executor, keep_alive, batch_size)?; // Assign a callback if the transport is new // Keep the lock to avoid concurrent new_transport and closing/closed notifications @@ -138,7 +134,7 @@ pub(super) async fn transport_finalize( drop(a_guard); // Start the RX loop - transport.start_rx(link, input.lease)?; + transport.start_rx(link, input.lease, batch_size)?; Ok(()) } diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs index 8ac01b288a..d949faf106 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs @@ -102,18 +102,7 @@ pub(super) async fn recv( }; // Compute the minimum batch size - let batch_size = { - let i_bsize = init_ack.batch_size; - let m_bsize = manager.config.batch_size; - - if i_bsize > m_bsize { - let e = zerror!("Invalid batch size on {}: {:?}", link, i_bsize); - log::error!("{}", e); - return Err((e.into(), Some(close::reason::INVALID))); - } - - i_bsize - }; + let batch_size = manager.config.batch_size.min(init_ack.batch_size); // Compute QoS let is_qos = input.is_qos && init_ack.qos.is_some(); diff --git a/io/zenoh-transport/src/unicast/establishment/open/mod.rs b/io/zenoh-transport/src/unicast/establishment/open/mod.rs index 9e854f45e2..e687a65f7b 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/mod.rs @@ -65,7 +65,6 @@ pub(crate) async fn open_link( zid, whatami: output.whatami, resolution: output.resolution, - batch_size: output.batch_size, is_qos: output.is_qos, }; let transport = step!(super::transport_init(manager, input).await); @@ -94,6 +93,7 @@ pub(crate) async fn open_link( .config .initial_sn_tx; + let tx_batch_size = output.batch_size; let input = open_syn::Input { cookie: output.cookie, resolution: output.resolution, @@ -122,6 +122,7 @@ pub(crate) async fn open_link( let output = InputFinalize { transport, lease: output.lease, + tx_batch_size, }; let transport = output.transport.clone(); let res = transport_finalize(link, manager, output).await; diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/link.rs index 6cad2ad8f0..a1dda7e672 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/link.rs @@ -115,7 +115,7 @@ impl TransportLinkUnicast { } } - pub(super) fn start_rx(&mut self, lease: Duration) { + pub(super) fn start_rx(&mut self, lease: Duration, batch_size: u16) { if self.handle_rx.is_none() { // Spawn the RX task let c_link = self.link.clone(); @@ -130,6 +130,7 @@ impl TransportLinkUnicast { c_transport.clone(), lease, c_signal.clone(), + batch_size, c_rx_buffer_size, ) .await; @@ -234,6 +235,7 @@ async fn rx_task_stream( transport: TransportUnicastInner, lease: Duration, signal: Signal, + rx_batch_size: u16, rx_buffer_size: usize, ) -> ZResult<()> { enum Action { @@ -258,7 +260,7 @@ async fn rx_task_stream( let codec = Zenoh080::new(); // The pool of buffers - let mtu = link.get_mtu() as usize; + let mtu = link.get_mtu().min(rx_batch_size) as usize; let mut n = rx_buffer_size / mtu; if rx_buffer_size % mtu != 0 { n += 1; @@ -307,6 +309,7 @@ async fn rx_task_dgram( transport: TransportUnicastInner, lease: Duration, signal: Signal, + rx_batch_size: u16, rx_buffer_size: usize, ) -> ZResult<()> { enum Action { @@ -327,7 +330,7 @@ async fn rx_task_dgram( let codec = Zenoh080::new(); // The pool of buffers - let mtu = link.get_mtu() as usize; + let mtu = link.get_mtu().min(rx_batch_size) as usize; let mut n = rx_buffer_size / mtu; if rx_buffer_size % mtu != 0 { n += 1; @@ -381,11 +384,28 @@ async fn rx_task( transport: TransportUnicastInner, lease: Duration, signal: Signal, + rx_batch_size: u16, rx_buffer_size: usize, ) -> ZResult<()> { if link.is_streamed() { - rx_task_stream(link, transport, lease, signal, rx_buffer_size).await + rx_task_stream( + link, + transport, + lease, + signal, + rx_batch_size, + rx_buffer_size, + ) + .await } else { - rx_task_dgram(link, transport, lease, signal, rx_buffer_size).await + rx_task_dgram( + link, + transport, + lease, + signal, + rx_batch_size, + rx_buffer_size, + ) + .await } } diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index a756a1dd06..41d3abc027 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -405,7 +405,7 @@ impl TransportManager { zid: config.peer, whatami: config.whatami, sn_resolution: config.sn_resolution, - initial_sn_tx: config.initial_sn_tx, + initial_sn_tx: config.tx_initial_sn, is_shm: config.is_shm, is_qos: config.is_qos, }; @@ -420,7 +420,7 @@ impl TransportManager { config.peer, config.whatami, config.sn_resolution, - config.initial_sn_tx, + config.tx_initial_sn, config.is_shm, config.is_qos ); diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 615d35a5ce..71dfa3bf3b 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -85,7 +85,7 @@ pub(crate) struct TransportConfigUnicast { pub(crate) peer: ZenohId, pub(crate) whatami: WhatAmI, pub(crate) sn_resolution: ZInt, - pub(crate) initial_sn_tx: ZInt, + pub(crate) tx_initial_sn: ZInt, pub(crate) is_shm: bool, pub(crate) is_qos: bool, } diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index 1488ff164e..1e6d27830a 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -279,11 +279,16 @@ impl TransportUnicastInner { } } - pub(super) fn start_rx(&self, link: &LinkUnicast, lease: Duration) -> ZResult<()> { + pub(super) fn start_rx( + &self, + link: &LinkUnicast, + lease: Duration, + batch_size: u16, + ) -> ZResult<()> { let mut guard = zwrite!(self.links); match zlinkgetmut!(guard, link) { Some(l) => { - l.start_rx(lease); + l.start_rx(lease, batch_size); Ok(()) } None => { From 7aa4231921602c088a1246b64035fe6840bf91f5 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 27 Feb 2023 16:46:36 +0100 Subject: [PATCH 043/203] RequestID negotiation --- commons/zenoh-protocol/src/core/resolution.rs | 8 ++--- commons/zenoh-protocol/src/defaults.rs | 1 - commons/zenoh-protocol/src/transport/init.rs | 3 +- .../unicast/establishment/accept/init_ack.rs | 22 ++++++++++---- .../unicast/establishment/open/init_ack.rs | 29 +++++++++++++++++-- 5 files changed, 47 insertions(+), 16 deletions(-) diff --git a/commons/zenoh-protocol/src/core/resolution.rs b/commons/zenoh-protocol/src/core/resolution.rs index 140813688e..f3036110d2 100644 --- a/commons/zenoh-protocol/src/core/resolution.rs +++ b/commons/zenoh-protocol/src/core/resolution.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use super::ZInt; -use crate::defaults::{FRAME_SN_RESOLUTION, KEYEXPR_ID_RESOLUTION, REQUEST_ID_RESOLUTION}; +use crate::defaults::{FRAME_SN_RESOLUTION, REQUEST_ID_RESOLUTION}; #[repr(u8)] // The value represents the 2-bit encoded value @@ -41,7 +41,6 @@ impl Bits { pub enum Field { FrameSN = 0, RequestID = 2, - KeyExprID = 4, } #[repr(transparent)] @@ -69,7 +68,7 @@ impl Resolution { let mut rng = rand::thread_rng(); let v: u8 = rng.gen(); - Self(v & 0b00111111) + Self(v & 0b00001111) } } @@ -77,8 +76,7 @@ impl Default for Resolution { fn default() -> Self { let frame_sn = FRAME_SN_RESOLUTION as u8; let request_id = (REQUEST_ID_RESOLUTION as u8) << 2; - let keyexpr_id = (KEYEXPR_ID_RESOLUTION as u8) << 4; - Self(frame_sn | request_id | keyexpr_id) + Self(frame_sn | request_id) } } diff --git a/commons/zenoh-protocol/src/defaults.rs b/commons/zenoh-protocol/src/defaults.rs index 43e58f5604..d9fcc95244 100644 --- a/commons/zenoh-protocol/src/defaults.rs +++ b/commons/zenoh-protocol/src/defaults.rs @@ -15,7 +15,6 @@ use crate::core::Bits; pub const FRAME_SN_RESOLUTION: Bits = Bits::U32; pub const REQUEST_ID_RESOLUTION: Bits = Bits::U32; -pub const KEYEXPR_ID_RESOLUTION: Bits = Bits::U32; /// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length /// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index 456d453628..318651d438 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -53,7 +53,7 @@ use zenoh_buffers::ZSlice; /// +-------+-+-+---+ /// ~ [u8] ~ -- ZenohID of the sender of the INIT message /// +---------------+ -/// |x|x|kid|rid|fsn| \ -- SN/ID resolution (+) +/// |x|x|x|x|rid|fsn| \ -- SN/ID resolution (+) /// +---------------+ | if Flag(S)==1 /// | u16 | | -- Batch Size ($) /// | | / @@ -80,7 +80,6 @@ use zenoh_buffers::ZSlice; /// of various SN and ID in Zenoh. /// - fsn: frame/fragment sequence number resolution. Used in Frame/Fragment messages. /// - rid: request ID resolution. Used in Request/Response messages. -/// - kid: key expression ID resolution. Used in Push/Request/Response messages. /// The valid SN/ID resolution values are: /// - 0b00: 8 bits /// - 0b01: 16 bits diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs index 949bd578db..f6bbdd6fb8 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs @@ -23,7 +23,11 @@ use zenoh_core::zasynclock; use zenoh_link::LinkUnicast; use zenoh_protocol::{ core::{Field, Resolution, ZInt}, - transport::{close, InitAck, TransportMessage}, + transport::{ + close, + init::{ext, InitAck}, + TransportMessage, + }, }; use zenoh_result::zerror; @@ -83,19 +87,27 @@ pub(super) async fn send( // Compute the minimum SN resolution let resolution = { + let mut res = Resolution::default(); + + // Frame SN let i_fsn_res = input.resolution.get(Field::FrameSN); let m_fsn_res = manager.config.resolution.get(Field::FrameSN); - - let mut res = Resolution::default(); res.set(Field::FrameSN, i_fsn_res.min(m_fsn_res)); + + // Request ID + let i_rid_res = input.resolution.get(Field::RequestID); + let m_rid_res = manager.config.resolution.get(Field::RequestID); + res.set(Field::RequestID, i_rid_res.min(m_rid_res)); + res }; // Compute the minimum batch size let batch_size = input.batch_size.min(manager.config.batch_size); - // Compute the QoS capabilities + // Extensions: compute the QoS capabilities let is_qos = input.is_qos && manager.config.unicast.is_qos; + let qos = is_qos.then_some(ext::QoS::new()); // Create the cookie let nonce: ZInt = zasynclock!(manager.prng).gen(); @@ -132,7 +144,7 @@ pub(super) async fn send( resolution, batch_size: manager.config.batch_size, cookie, - qos: None, // @TODO + qos, shm: None, // @TODO auth: None, // @TODO } diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs index d949faf106..0277f72440 100644 --- a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs +++ b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs @@ -87,17 +87,40 @@ pub(super) async fn recv( // Compute the minimum SN resolution let resolution = { + let mut res = Resolution::default(); + + // Frame SN let i_fsn_res = init_ack.resolution.get(Field::FrameSN); let m_fsn_res = manager.config.resolution.get(Field::FrameSN); if i_fsn_res > m_fsn_res { - let e = zerror!("Invalid SN resolution on {}: {:?}", link, i_fsn_res); + let e = zerror!( + "Invalid FrameSN resolution on {}: {:?} > {:?}", + link, + i_fsn_res, + m_fsn_res + ); log::error!("{}", e); return Err((e.into(), Some(close::reason::INVALID))); } - - let mut res = Resolution::default(); res.set(Field::FrameSN, i_fsn_res); + + // Request ID + let i_rid_res = init_ack.resolution.get(Field::RequestID); + let m_rid_res = manager.config.resolution.get(Field::RequestID); + + if i_rid_res > m_rid_res { + let e = zerror!( + "Invalid RequestID resolution on {}: {:?} > {:?}", + link, + i_rid_res, + m_rid_res + ); + log::error!("{}", e); + return Err((e.into(), Some(close::reason::INVALID))); + } + res.set(Field::RequestID, i_rid_res); + res }; From 239144f1f112827a23aad5c33c7429feda77615a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 1 Mar 2023 16:55:42 +0100 Subject: [PATCH 044/203] Open/Accept FSM rework --- Cargo.lock | 1 + io/zenoh-link-commons/src/lib.rs | 16 +- io/zenoh-transport/Cargo.toml | 1 + io/zenoh-transport/src/manager.rs | 10 +- io/zenoh-transport/src/shm.rs | 25 +- .../src/unicast/establishment/accept.rs | 434 ++++++++++++++++++ .../unicast/establishment/accept/init_ack.rs | 161 ------- .../unicast/establishment/accept/init_syn.rs | 105 ----- .../src/unicast/establishment/accept/mod.rs | 124 ----- .../unicast/establishment/accept/open_ack.rs | 52 --- .../unicast/establishment/accept/open_syn.rs | 170 ------- .../src/unicast/establishment/cookie.rs | 8 +- .../src/unicast/establishment/mod.rs | 136 +++--- .../src/unicast/establishment/open.rs | 374 +++++++++++++++ .../unicast/establishment/open/init_ack.rs | 204 -------- .../unicast/establishment/open/init_syn.rs | 71 --- .../src/unicast/establishment/open/mod.rs | 135 ------ .../unicast/establishment/open/open_ack.rs | 110 ----- .../unicast/establishment/open/open_syn.rs | 58 --- io/zenoh-transport/src/unicast/link.rs | 2 +- io/zenoh-transport/src/unicast/manager.rs | 161 ++++--- io/zenoh-transport/tests/endpoints.rs | 4 +- .../tests/unicast_authenticator.rs | 128 +++--- .../tests/unicast_concurrent.rs | 44 +- io/zenoh-transport/tests/unicast_conduits.rs | 10 +- .../tests/unicast_defragmentation.rs | 12 +- .../tests/unicast_intermittent.rs | 22 +- io/zenoh-transport/tests/unicast_openclose.rs | 122 ++--- .../tests/unicast_simultaneous.rs | 36 +- io/zenoh-transport/tests/unicast_transport.rs | 24 +- 30 files changed, 1194 insertions(+), 1566 deletions(-) create mode 100644 io/zenoh-transport/src/unicast/establishment/accept.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/accept/mod.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs create mode 100644 io/zenoh-transport/src/unicast/establishment/open.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/open/init_ack.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/open/init_syn.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/open/mod.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/open/open_ack.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/open/open_syn.rs diff --git a/Cargo.lock b/Cargo.lock index d9deeb664e..b8bd597366 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4275,6 +4275,7 @@ dependencies = [ "ringbuffer-spsc", "rsa", "serde", + "sha3", "zenoh-buffers", "zenoh-cfg-properties", "zenoh-codec", diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index b27786bac9..6d53da98f3 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -149,7 +149,7 @@ pub trait LinkUnicastTrait: Send + Sync { } impl LinkUnicast { - pub async fn write_transport_message(&self, msg: &TransportMessage) -> ZResult { + pub async fn send(&self, msg: &TransportMessage) -> ZResult { const ERR: &str = "Write error on link: "; // Create the buffer for serializing the message @@ -181,7 +181,7 @@ impl LinkUnicast { Ok(buff.len()) } - pub async fn read_transport_message(&self) -> ZResult> { + pub async fn recv(&self) -> ZResult { // Read from the link let buffer = if self.is_streamed() { // Read and decode the message length @@ -203,15 +203,11 @@ impl LinkUnicast { let mut reader = buffer.reader(); let codec = Zenoh080::new(); - let mut messages: Vec = Vec::with_capacity(1); - while reader.can_read() { - let msg: TransportMessage = codec - .read(&mut reader) - .map_err(|_| zerror!("Read error on link: {}", self))?; - messages.push(msg); - } + let msg: TransportMessage = codec + .read(&mut reader) + .map_err(|_| zerror!("Read error on link: {}", self))?; - Ok(messages) + Ok(msg) } } diff --git a/io/zenoh-transport/Cargo.toml b/io/zenoh-transport/Cargo.toml index 77cc189386..bcaedd629a 100644 --- a/io/zenoh-transport/Cargo.toml +++ b/io/zenoh-transport/Cargo.toml @@ -52,6 +52,7 @@ paste = { workspace = true } rand = { workspace = true, features = ["default"] } ringbuffer-spsc = { workspace = true } rsa = { workspace = true, optional = true } +sha3 = { workspace = true } serde = { workspace = true, features = ["default"] } zenoh-buffers = { path = "../../commons/zenoh-buffers/" } zenoh-cfg-properties = { path = "../../commons/zenoh-cfg-properties/" } diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index 463e73bec0..64fea96017 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -16,7 +16,7 @@ use super::unicast::manager::{ }; use super::unicast::TransportUnicast; use super::TransportEventHandler; -use async_std::sync::Mutex as AsyncMutex; +use async_std::{sync::Mutex as AsyncMutex, task}; use rand::{RngCore, SeedableRng}; use std::collections::HashMap; use std::sync::Arc; @@ -395,12 +395,12 @@ impl TransportManager { } pub fn get_listeners(&self) -> Vec { - self.get_listeners_unicast() + task::block_on(self.get_listeners_unicast()) // @TODO: multicast } pub fn get_locators(&self) -> Vec { - self.get_locators_unicast() + task::block_on(self.get_locators_unicast()) // @TODO: multicast } @@ -408,12 +408,12 @@ impl TransportManager { /* TRANSPORT */ /*************************************/ pub fn get_transport(&self, peer: &ZenohId) -> Option { - self.get_transport_unicast(peer) + task::block_on(self.get_transport_unicast(peer)) // @TODO: multicast } pub fn get_transports(&self) -> Vec { - self.get_transports_unicast() + task::block_on(self.get_transports_unicast()) // @TODO: multicast } diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index fc62871daf..3f684052d4 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -11,9 +11,8 @@ // Contributors: // ZettaScale Zenoh Team, // -use std::{any::TypeId, sync::RwLock}; +use std::any::TypeId; use zenoh_buffers::{ZBuf, ZSlice}; -use zenoh_core::{zread, zwrite}; use zenoh_protocol::zenoh::*; use zenoh_result::ZResult; use zenoh_shm::{ @@ -53,10 +52,7 @@ macro_rules! set_sliced { }; } -pub fn map_zslice_to_shmbuf( - zslice: &mut ZSlice, - shmr: &RwLock, -) -> ZResult { +pub fn map_zslice_to_shmbuf(zslice: &mut ZSlice, shmr: &mut SharedMemoryReader) -> ZResult { let mut res = false; let ZSlice { buf, .. } = zslice; @@ -65,13 +61,9 @@ pub fn map_zslice_to_shmbuf( let shmbinfo = SharedMemoryBufInfo::deserialize(buf.as_slice())?; // First, try in read mode allowing concurrenct lookups - let r_guard = zread!(shmr); - let smb = r_guard.try_read_shmbuf(&shmbinfo).or_else(|_| { - // Next, try in write mode to eventual link the remote shm - drop(r_guard); - let mut w_guard = zwrite!(shmr); - w_guard.read_shmbuf(&shmbinfo) - })?; + let smb = shmr + .try_read_shmbuf(&shmbinfo) + .or_else(|_| shmr.read_shmbuf(&shmbinfo))?; // Replace the content of the slice let zs: ZSlice = smb.into(); @@ -82,7 +74,7 @@ pub fn map_zslice_to_shmbuf( Ok(res) } -pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &RwLock) -> ZResult { +pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &mut SharedMemoryReader) -> ZResult { let mut res = false; for zs in zbuf.zslices_mut() { res |= map_zslice_to_shmbuf(zs, shmr)?; @@ -115,10 +107,7 @@ pub fn map_zbuf_to_shminfo(zbuf: &mut ZBuf) -> ZResult { Ok(res) } -pub fn map_zmsg_to_shmbuf( - msg: &mut ZenohMessage, - shmr: &RwLock, -) -> ZResult { +pub fn map_zmsg_to_shmbuf(msg: &mut ZenohMessage, shmr: &mut SharedMemoryReader) -> ZResult { let mut res = false; if let ZenohBody::Data(Data { diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs new file mode 100644 index 0000000000..08f8d25852 --- /dev/null +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -0,0 +1,434 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{ + unicast::establishment::{ + close_link, compute_sn, finalize_transport, AcceptFsm, Cookie, InputFinalize, + Zenoh080Cookie, + }, + TransportConfigUnicast, TransportManager, +}; +use async_std::sync::Mutex; +use async_trait::async_trait; +use rand::Rng; +use std::time::Duration; +use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZSlice}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_core::{zasynclock, zerror}; +use zenoh_crypto::{BlockCipher, PseudoRng}; +use zenoh_link::{LinkUnicast, LinkUnicastDirection}; +use zenoh_protocol::{ + core::{Field, Resolution, WhatAmI, ZInt, ZenohId}, + transport::{ + close::{self, Close}, + InitAck, OpenAck, TransportBody, TransportMessage, + }, +}; +use zenoh_result::ZResult; + +pub(super) type AcceptError = (zenoh_result::Error, Option); + +// InitSyn +struct RecvInitSynIn { + mine_version: u8, + mine_resolution: Resolution, + mine_batch_size: u16, +} +struct RecvInitSynOut { + other_zid: ZenohId, + other_whatami: WhatAmI, + agreed_resolution: Resolution, + agreed_batch_size: u16, +} + +// InitAck +struct SendInitAckIn { + mine_version: u8, + mine_zid: ZenohId, + mine_whatami: WhatAmI, + other_zid: ZenohId, + other_whatami: WhatAmI, + agreed_resolution: Resolution, + agreed_batch_size: u16, +} +struct SendInitAckOut { + cookie_nonce: ZInt, +} + +// OpenSyn +struct RecvOpenSynIn { + cookie_nonce: ZInt, +} +struct RecvOpenSynOut { + other_zid: ZenohId, + other_whatami: WhatAmI, + other_lease: Duration, + other_initial_sn: ZInt, + agreed_resolution: Resolution, + agreed_batch_size: u16, +} + +// OpenAck +struct SendOpenAckIn { + mine_lease: Duration, + mine_initial_sn: ZInt, +} +struct SendOpenAckOut {} + +// Fsm +struct AcceptLink<'a> { + link: &'a LinkUnicast, + prng: &'a Mutex, + cipher: &'a BlockCipher, +} + +#[async_trait] +impl<'a> AcceptFsm for AcceptLink<'a> { + type Error = AcceptError; + + type InitSynIn = RecvInitSynIn; + type InitSynOut = RecvInitSynOut; + async fn recv_init_syn(&self, input: Self::InitSynIn) -> Result { + let msg = self + .link + .recv() + .await + .map_err(|e| (e, Some(close::reason::INVALID)))?; + + let init_syn = match msg.body { + TransportBody::InitSyn(init_syn) => init_syn, + _ => { + let e = zerror!( + "Received invalid message instead of an InitSyn on {}: {:?}", + self.link, + msg.body + ); + return Err((e.into(), Some(close::reason::INVALID))); + } + }; + + // Check if the version is supported + if init_syn.version != input.mine_version { + let e = zerror!( + "Rejecting InitSyn on {} because of unsupported Zenoh version from peer: {}", + self.link, + init_syn.zid + ); + return Err((e.into(), Some(close::reason::INVALID))); + } + + // Compute the minimum SN resolution + let agreed_resolution = { + let mut res = Resolution::default(); + + // Frame SN + let i_fsn_res = init_syn.resolution.get(Field::FrameSN); + let m_fsn_res = input.mine_resolution.get(Field::FrameSN); + res.set(Field::FrameSN, i_fsn_res.min(m_fsn_res)); + + // Request ID + let i_rid_res = input.mine_resolution.get(Field::RequestID); + let m_rid_res = input.mine_resolution.get(Field::RequestID); + res.set(Field::RequestID, i_rid_res.min(m_rid_res)); + + res + }; + + // Compute the minimum batch size + let agreed_batch_size = input.mine_batch_size.min(input.mine_batch_size); + + let output = RecvInitSynOut { + other_whatami: init_syn.whatami, + other_zid: init_syn.zid, + agreed_resolution, + agreed_batch_size, + }; + Ok(output) + } + + type InitAckIn = SendInitAckIn; + type InitAckOut = SendInitAckOut; + async fn send_init_ack(&self, input: Self::InitAckIn) -> Result { + // Create the cookie + let cookie_nonce: ZInt = zasynclock!(self.prng).gen(); + let cookie = Cookie { + whatami: input.other_whatami, + zid: input.other_zid, + resolution: input.agreed_resolution, + batch_size: input.agreed_batch_size, + nonce: cookie_nonce, + is_qos: false, // @TODO + // properties: EstablishmentProperties::new(), + }; + + let mut encrypted = vec![]; + let mut writer = encrypted.writer(); + let mut codec = Zenoh080Cookie { + prng: &mut *zasynclock!(self.prng), + cipher: self.cipher, + codec: Zenoh080::new(), + }; + codec.write(&mut writer, &cookie).map_err(|_| { + ( + zerror!("Encoding cookie failed").into(), + Some(close::reason::INVALID), + ) + })?; + let cookie: ZSlice = encrypted.into(); + + // Send the message on the link + let message: TransportMessage = InitAck { + version: input.mine_version, + whatami: input.mine_whatami, + zid: input.mine_zid, + resolution: input.agreed_resolution, + batch_size: input.agreed_batch_size, + cookie, + qos: None, // @TODO + shm: None, // @TODO + auth: None, // @TODO + } + .into(); + + let _ = self + .link + .send(&message) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + + let output = SendInitAckOut { cookie_nonce }; + Ok(output) + } + + type OpenSynIn = RecvOpenSynIn; + type OpenSynOut = RecvOpenSynOut; + async fn recv_open_syn(&self, input: Self::OpenSynIn) -> Result { + let msg = self + .link + .recv() + .await + .map_err(|e| (e, Some(close::reason::INVALID)))?; + + let open_syn = match msg.body { + TransportBody::OpenSyn(open_syn) => open_syn, + TransportBody::Close(Close { reason, .. }) => { + let e = zerror!( + "Received a close message (reason {}) instead of an OpenSyn on: {:?}", + close::reason_to_str(reason), + self.link, + ); + match reason { + close::reason::MAX_LINKS => log::debug!("{}", e), + _ => log::error!("{}", e), + } + return Err((e.into(), None)); + } + _ => { + let e = zerror!( + "Received invalid message instead of an OpenSyn on {}: {:?}", + self.link, + msg.body + ); + log::error!("{}", e); + return Err((e.into(), Some(close::reason::INVALID))); + } + }; + let encrypted = open_syn.cookie.to_vec(); + + // Decrypt the cookie with the cipher + let mut reader = encrypted.reader(); + let mut codec = Zenoh080Cookie { + prng: &mut *zasynclock!(self.prng), + cipher: self.cipher, + codec: Zenoh080::new(), + }; + let cookie: Cookie = codec.read(&mut reader).map_err(|_| { + ( + zerror!("Decoding cookie failed").into(), + Some(close::reason::INVALID), + ) + })?; + + // Verify that the cookie is the one we sent + if input.cookie_nonce != cookie.nonce { + let e = zerror!("Rejecting OpenSyn on: {}. Unkwown cookie.", self.link); + return Err((e.into(), Some(close::reason::INVALID))); + } + + let output = RecvOpenSynOut { + other_zid: cookie.zid, + other_whatami: cookie.whatami, + other_lease: open_syn.lease, + other_initial_sn: open_syn.initial_sn, + agreed_resolution: cookie.resolution, + agreed_batch_size: cookie.batch_size, + }; + Ok(output) + } + + type OpenAckIn = SendOpenAckIn; + type OpenAckOut = SendOpenAckOut; + async fn send_open_ack(&self, input: Self::OpenAckIn) -> Result { + // Build OpenAck message + let message: TransportMessage = OpenAck { + lease: input.mine_lease, + initial_sn: input.mine_initial_sn, + auth: None, // @TODO + } + .into(); + + // Send the message on the link + let _ = self + .link + .send(&message) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + + let output = SendOpenAckOut {}; + Ok(output) + } +} + +pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) -> ZResult<()> { + let fsm = AcceptLink { + link, + prng: &manager.prng, + cipher: &manager.cipher, + }; + + // Init handshake + macro_rules! step { + ($s: expr) => { + match $s { + Ok(output) => output, + Err((e, reason)) => { + log::error!("{}", e); + close_link(link, reason).await; + return Err(e); + } + } + }; + } + + let iack_out = { + // Let's scope the Init phase in such a way memory is freed by Rust + // after having sent the InitAck. The state will be recovered + // from the Cookie received in the OpenSyn. + let isyn_in = RecvInitSynIn { + mine_version: manager.config.version, + mine_resolution: manager.config.resolution, + mine_batch_size: manager.config.batch_size, + }; + let isyn_out = step!(fsm.recv_init_syn(isyn_in).await); + + let iack_in = SendInitAckIn { + mine_version: manager.config.version, + mine_zid: manager.config.zid, + mine_whatami: manager.config.whatami, + other_zid: isyn_out.other_zid, + other_whatami: isyn_out.other_whatami, + agreed_resolution: isyn_out.agreed_resolution, + agreed_batch_size: isyn_out.agreed_batch_size, + }; + step!(fsm.send_init_ack(iack_in).await) + }; + + // Open handshake + let osyn_in = RecvOpenSynIn { + cookie_nonce: iack_out.cookie_nonce, + }; + let osyn_out = step!(fsm.recv_open_syn(osyn_in).await); + + // Initialize the transport before sending the ack to verify that the transport is ok + + // 1) Create a random yet deterministic initial_sn. + let mine_initial_sn = compute_sn( + manager.config.zid, + osyn_out.other_zid, + osyn_out.agreed_resolution, + ); + + // 2) Initialize the transport. + let config = TransportConfigUnicast { + peer: osyn_out.other_zid, + whatami: osyn_out.other_whatami, + sn_resolution: osyn_out.agreed_resolution.get(Field::FrameSN).mask(), + tx_initial_sn: mine_initial_sn, + is_qos: false, // @TODO + is_shm: false, // @TODO + }; + let transport = step!(manager + .init_transport_unicast(config) + .await + .map_err(|e| (e, Some(close::reason::INVALID)))); + + macro_rules! step { + ($s: expr) => { + match $s { + Ok(output) => output, + Err((e, reason)) => { + match reason { + Some(close::reason::MAX_LINKS) => log::debug!("{}", e), + _ => log::error!("{}", e), + } + if let Ok(ll) = transport.get_links() { + if ll.is_empty() { + let _ = manager.del_transport_unicast(&osyn_out.other_zid).await; + } + } + close_link(link, reason).await; + return Err(e); + } + } + }; + } + + // 3) Add the link to the transport + step!(step!(transport + .get_inner() + .map_err(|e| (e, Some(close::reason::INVALID)))) + .add_link(link.clone(), LinkUnicastDirection::Inbound) + .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); + + // 4) Sync the RX sequence number + let _ = step!(transport + .get_inner() + .map_err(|e| (e, Some(close::reason::INVALID)))) + .sync(osyn_out.other_initial_sn) + .await; + + // Send the OpenAck + let oack_in = SendOpenAckIn { + mine_lease: manager.config.unicast.lease, + mine_initial_sn, + }; + let _ = step!(fsm.send_open_ack(oack_in).await); + + // Finalize the transport + let input = InputFinalize { + transport: transport.clone(), + other_lease: osyn_out.other_lease, + agreed_batch_size: osyn_out.agreed_batch_size, + }; + step!(finalize_transport(link, manager, input) + .await + .map_err(|e| (e, Some(close::reason::INVALID)))); + + log::debug!( + "New transport link established from {}: {}", + osyn_out.other_zid, + link + ); + + Ok(()) +} diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs deleted file mode 100644 index f6bbdd6fb8..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_ack.rs +++ /dev/null @@ -1,161 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::{init_syn, AResult}; -use crate::{ - unicast::establishment::{Cookie, Zenoh080Cookie}, - TransportManager, -}; -use rand::Rng; -use zenoh_buffers::{writer::HasWriter, ZSlice}; -use zenoh_codec::{WCodec, Zenoh080}; -use zenoh_core::zasynclock; -use zenoh_link::LinkUnicast; -use zenoh_protocol::{ - core::{Field, Resolution, ZInt}, - transport::{ - close, - init::{ext, InitAck}, - TransportMessage, - }, -}; -use zenoh_result::zerror; - -// Send an InitAck -pub(super) struct Output { - pub(super) nonce: ZInt, -} - -pub(super) async fn send( - link: &LinkUnicast, - manager: &TransportManager, - input: init_syn::Output, -) -> AResult { - // Build the attachment from the authenticators - // let mut ps_attachment = EstablishmentProperties::new(); - // let mut ps_cookie = EstablishmentProperties::new(); - // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - // let (mut att, mut cke) = pa - // .handle_init_syn( - // auth_link, - // &cookie, - // input - // .init_syn_properties - // .remove(pa.id().into()) - // .map(|x| x.value), - // ) - // .await - // .map_err(|e| (e, Some(close::reason::INVALID)))?; - // // Add attachment property if available - // if let Some(att) = att.take() { - // ps_attachment - // .insert(Property { - // key: pa.id().into(), - // value: att, - // }) - // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - // } - // // Add state in the cookie if avaiable - // if let Some(cke) = cke.take() { - // ps_cookie - // .insert(Property { - // key: pa.id().into(), - // value: cke, - // }) - // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - // } - // } - // cookie.properties = ps_cookie; - - // let attachment: Option = if ps_attachment.is_empty() { - // None - // } else { - // let att = - // Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; - // Some(att) - // }; @TODO - - // Compute the minimum SN resolution - let resolution = { - let mut res = Resolution::default(); - - // Frame SN - let i_fsn_res = input.resolution.get(Field::FrameSN); - let m_fsn_res = manager.config.resolution.get(Field::FrameSN); - res.set(Field::FrameSN, i_fsn_res.min(m_fsn_res)); - - // Request ID - let i_rid_res = input.resolution.get(Field::RequestID); - let m_rid_res = manager.config.resolution.get(Field::RequestID); - res.set(Field::RequestID, i_rid_res.min(m_rid_res)); - - res - }; - - // Compute the minimum batch size - let batch_size = input.batch_size.min(manager.config.batch_size); - - // Extensions: compute the QoS capabilities - let is_qos = input.is_qos && manager.config.unicast.is_qos; - let qos = is_qos.then_some(ext::QoS::new()); - - // Create the cookie - let nonce: ZInt = zasynclock!(manager.prng).gen(); - let cookie = Cookie { - whatami: input.whatami, - zid: input.zid, - resolution, - tx_batch_size: batch_size, - nonce, - is_qos, - // properties: EstablishmentProperties::new(), - }; - - let mut encrypted = vec![]; - let mut writer = encrypted.writer(); - let mut codec = Zenoh080Cookie { - prng: &mut *zasynclock!(manager.prng), - cipher: &manager.cipher, - codec: Zenoh080::new(), - }; - codec.write(&mut writer, &cookie).map_err(|_| { - ( - zerror!("Encoding cookie failed").into(), - Some(close::reason::INVALID), - ) - })?; - - // Send the cookie - let cookie: ZSlice = encrypted.into(); - let message: TransportMessage = InitAck { - version: manager.config.version, - whatami: manager.config.whatami, - zid: manager.config.zid, - resolution, - batch_size: manager.config.batch_size, - cookie, - qos, - shm: None, // @TODO - auth: None, // @TODO - } - .into(); - - // Send the message on the link - let _ = link - .write_transport_message(&message) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; - - let output = Output { nonce }; - Ok(output) -} diff --git a/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs b/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs deleted file mode 100644 index efca6af9fb..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/accept/init_syn.rs +++ /dev/null @@ -1,105 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::AResult; -use crate::TransportManager; -use zenoh_link::LinkUnicast; -use zenoh_protocol::{ - core::{Resolution, WhatAmI, ZenohId}, - transport::{close, TransportBody}, -}; -use zenoh_result::zerror; - -/*************************************/ -/* ACCEPT */ -/*************************************/ - -// Read and eventually accept an InitSyn -pub(super) struct Output { - pub(super) whatami: WhatAmI, - pub(super) zid: ZenohId, - pub(super) resolution: Resolution, - pub(super) batch_size: u16, - pub(super) is_qos: bool, -} - -pub(super) async fn recv(link: &LinkUnicast, manager: &TransportManager) -> AResult { - // Wait to read an InitSyn - let mut messages = link - .read_transport_message() - .await - .map_err(|e| (e, Some(close::reason::INVALID)))?; - if messages.len() != 1 { - let e = zerror!( - "Received multiple messages instead of a single InitSyn on {}: {:?}", - link, - messages, - ); - return Err((e.into(), Some(close::reason::INVALID))); - } - - let msg = messages.remove(0); - let init_syn = match msg.body { - TransportBody::InitSyn(init_syn) => init_syn, - _ => { - let e = zerror!( - "Received invalid message instead of an InitSyn on {}: {:?}", - link, - msg.body - ); - return Err((e.into(), Some(close::reason::INVALID))); - } - }; - - // // Check the peer id associate to the authenticated link - // match auth_link.peer_id { - // Some(zid) => { - // if zid != init_syn.zid { - // let e = zerror!( - // "Inconsistent ZenohId in InitSyn on {}: {:?} {:?}", - // link, - // zid, - // init_syn.zid - // ); - // return Err((e.into(), Some(close::reason::INVALID))); - // } - // } - // None => auth_link.peer_id = Some(init_syn.zid), - // } - - // Check if the version is supported - if init_syn.version != manager.config.version { - let e = zerror!( - "Rejecting InitSyn on {} because of unsupported Zenoh version from peer: {}", - link, - init_syn.zid - ); - return Err((e.into(), Some(close::reason::INVALID))); - } - - // // Validate the InitSyn with the peer authenticators - // let init_syn_properties: EstablishmentProperties = match msg.attachment.take() { - // Some(att) => EstablishmentProperties::try_from(&att) - // .map_err(|e| (e, Some(close::reason::INVALID)))?, - // None => EstablishmentProperties::new(), - // }; - - let output = Output { - whatami: init_syn.whatami, - zid: init_syn.zid, - resolution: init_syn.resolution, - batch_size: init_syn.batch_size, - is_qos: init_syn.qos.is_some(), - }; - Ok(output) -} diff --git a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs b/io/zenoh-transport/src/unicast/establishment/accept/mod.rs deleted file mode 100644 index 7b4194a230..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/accept/mod.rs +++ /dev/null @@ -1,124 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -mod init_ack; -mod init_syn; -mod open_ack; -mod open_syn; - -use crate::unicast::establishment::authenticator::AuthenticatedPeerLink; -use crate::unicast::establishment::{ - close_link, transport_finalize, transport_init, InputFinalize, -}; -use crate::TransportManager; -use zenoh_link::{LinkUnicast, LinkUnicastDirection}; -use zenoh_protocol::transport::close; -use zenoh_result::ZResult; - -pub(super) type AError = (zenoh_result::Error, Option); -pub(super) type AResult = Result; - -pub(crate) async fn accept_link( - link: &LinkUnicast, - manager: &TransportManager, - auth_link: &mut AuthenticatedPeerLink, -) -> ZResult<()> { - // INIT handshake - macro_rules! step { - ($s: expr) => { - match $s { - Ok(output) => output, - Err((e, reason)) => { - log::error!("{}", e); - close_link(link, manager, auth_link, reason).await; - return Err(e); - } - } - }; - } - - let output = step!(init_syn::recv(link, manager).await); - let output = step!(init_ack::send(link, manager, output).await); - let output = step!(open_syn::recv(link, manager, output).await); - - // Initialize the transport - let zid = output.cookie.zid; - let tx_batch_size = output.cookie.tx_batch_size; - let input = super::InputInit { - zid: output.cookie.zid, - whatami: output.cookie.whatami, - resolution: output.cookie.resolution, - is_qos: output.cookie.is_qos, - }; - let transport = step!(transport_init(manager, input) - .await - .map_err(|e| (e, Some(close::reason::INVALID)))); - - // OPEN handshake - macro_rules! step { - ($s: expr) => { - match $s { - Ok(output) => output, - Err((e, reason)) => { - match reason { - Some(close::reason::MAX_LINKS) => log::debug!("{}", e), - _ => log::error!("{}", e), - } - if let Ok(ll) = transport.get_links() { - if ll.is_empty() { - let _ = manager.del_transport_unicast(&zid).await; - } - } - close_link(link, manager, auth_link, reason).await; - return Err(e); - } - } - }; - } - - // Add the link to the transport - step!(step!(transport - .get_inner() - .map_err(|e| (e, Some(close::reason::INVALID)))) - .add_link(link.clone(), LinkUnicastDirection::Inbound) - .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); - - // Sync the RX sequence number - let _ = step!(transport - .get_inner() - .map_err(|e| (e, Some(close::reason::INVALID)))) - .sync(output.initial_sn) - .await; - - log::debug!("New transport link established from {}: {}", zid, link); - - let initial_sn = step!(transport - .get_inner() - .map_err(|e| (e, Some(close::reason::INVALID)))) - .config - .initial_sn_tx; - let input = open_ack::Input { initial_sn }; - let lease = output.lease; - step!(open_ack::send(link, manager, auth_link, input).await); - - let input = InputFinalize { - transport: transport.clone(), - lease, - tx_batch_size, - }; - step!(transport_finalize(link, manager, input) - .await - .map_err(|e| (e, Some(close::reason::INVALID)))); - - Ok(()) -} diff --git a/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs b/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs deleted file mode 100644 index fe28417228..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/accept/open_ack.rs +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::super::AuthenticatedPeerLink; -use super::AResult; -use crate::TransportManager; -use zenoh_link::LinkUnicast; -use zenoh_protocol::{ - core::ZInt, - transport::{close, OpenAck, TransportMessage}, -}; - -/*************************************/ -/* ACCEPT */ -/*************************************/ -// Send an OpenAck -pub(super) struct Input { - pub(super) initial_sn: ZInt, -} - -pub(super) async fn send( - link: &LinkUnicast, - manager: &TransportManager, - _auth_link: &AuthenticatedPeerLink, - input: Input, -) -> AResult<()> { - // Build OpenAck message - let message: TransportMessage = OpenAck { - lease: manager.config.unicast.lease, - initial_sn: input.initial_sn, - auth: None, // @TODO - } - .into(); - - // Send the message on the - let _ = link - .write_transport_message(&message) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; - - Ok(()) -} diff --git a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs b/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs deleted file mode 100644 index 101d8441c3..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/accept/open_syn.rs +++ /dev/null @@ -1,170 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::AResult; -use crate::{ - unicast::establishment::cookie::{Cookie, Zenoh080Cookie}, - TransportManager, -}; -use std::time::Duration; -use zenoh_buffers::reader::HasReader; -use zenoh_codec::{RCodec, Zenoh080}; -use zenoh_core::zasynclock; -use zenoh_link::LinkUnicast; -use zenoh_protocol::{ - core::ZInt, - transport::{ - close::{self, Close}, - TransportBody, - }, -}; -use zenoh_result::zerror; - -/*************************************/ -/* ACCEPT */ -/*************************************/ - -// Read and eventually accept an OpenSyn -pub(super) struct Output { - pub(super) cookie: Cookie, - pub(super) initial_sn: ZInt, - pub(super) lease: Duration, -} -#[allow(unused_mut)] -pub(super) async fn recv( - link: &LinkUnicast, - manager: &TransportManager, - input: super::init_ack::Output, -) -> AResult { - // Wait to read an OpenSyn - let mut messages = link - .read_transport_message() - .await - .map_err(|e| (e, Some(close::reason::INVALID)))?; - if messages.len() != 1 { - let e = zerror!( - "Received multiple messages instead of a single OpenSyn on {}: {:?}", - link, - messages - ); - return Err((e.into(), Some(close::reason::INVALID))); - } - - let mut msg = messages.remove(0); - let open_syn = match msg.body { - TransportBody::OpenSyn(open_syn) => open_syn, - TransportBody::Close(Close { reason, .. }) => { - let e = zerror!( - "Received a close message (reason {}) instead of an OpenSyn on: {:?}", - close::reason_to_str(reason), - link, - ); - match reason { - close::reason::MAX_LINKS => log::debug!("{}", e), - _ => log::error!("{}", e), - } - return Err((e.into(), None)); - } - _ => { - let e = zerror!( - "Received invalid message instead of an OpenSyn on {}: {:?}", - link, - msg.body - ); - log::error!("{}", e); - return Err((e.into(), Some(close::reason::INVALID))); - } - }; - let encrypted = open_syn.cookie.to_vec(); - - // Decrypt the cookie with the cipher - let mut reader = encrypted.reader(); - let mut codec = Zenoh080Cookie { - prng: &mut *zasynclock!(manager.prng), - cipher: &manager.cipher, - codec: Zenoh080::new(), - }; - let mut cookie: Cookie = codec.read(&mut reader).map_err(|_| { - ( - zerror!("Decoding cookie failed").into(), - Some(close::reason::INVALID), - ) - })?; - - // Verify that the cookie is the one we sent - if input.nonce != cookie.nonce { - let e = zerror!("Rejecting OpenSyn on: {}. Unkwown cookie.", link); - return Err((e.into(), Some(close::reason::INVALID))); - } - - // // Validate with the peer authenticators - // let mut open_syn_properties: EstablishmentProperties = match msg.attachment.take() { - // Some(att) => EstablishmentProperties::try_from(&att) - // .map_err(|e| (e, Some(close::reason::INVALID)))?, - // None => EstablishmentProperties::new(), - // }; - - // let mut is_shm = false; - // let mut ps_attachment = EstablishmentProperties::new(); - // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - // let po = open_syn_properties.remove(pa.id().into()).map(|x| x.value); - // let pc = cookie.properties.remove(pa.id().into()).map(|x| x.value); - // let mut att = pa.handle_open_syn(auth_link, &cookie, (po, pc)).await; - - // #[cfg(feature = "shared-memory")] - // { - // if pa.id() == super::super::authenticator::PeerAuthenticatorId::Shm { - // // Check if SHM has been validated from the other side - // att = match att { - // Ok(att) => { - // is_shm = true; - // Ok(att) - // } - // Err(e) => { - // if e.is::() { - // is_shm = false; - // Ok(None) - // } else { - // Err(e) - // } - // } - // }; - // } - // } - - // let mut att = att.map_err(|e| (e, Some(close::reason::INVALID)))?; - // if let Some(att) = att.take() { - // ps_attachment - // .insert(Property { - // key: pa.id().into(), - // value: att, - // }) - // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - // } - // } - - // let open_ack_attachment = if ps_attachment.is_empty() { - // None - // } else { - // let att = - // Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; - // Some(att) - // }; @TODO - - let output = Output { - cookie, - initial_sn: open_syn.initial_sn, - lease: open_syn.lease, - }; - Ok(output) -} diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 143590111f..93d2b684af 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -26,7 +26,7 @@ pub struct Cookie { pub whatami: WhatAmI, pub zid: ZenohId, pub resolution: Resolution, - pub tx_batch_size: u16, + pub batch_size: u16, pub nonce: ZInt, // Extensions pub is_qos: bool, @@ -44,7 +44,7 @@ where self.write(&mut *writer, wai)?; self.write(&mut *writer, &x.zid)?; self.write(&mut *writer, x.resolution.as_u8())?; - self.write(&mut *writer, x.tx_batch_size)?; + self.write(&mut *writer, x.batch_size)?; self.write(&mut *writer, x.nonce)?; // Extensions let is_qos = u8::from(x.is_qos); @@ -82,7 +82,7 @@ where whatami, zid, resolution, - tx_batch_size: batch_size, + batch_size, nonce, is_qos, // properties, @@ -145,7 +145,7 @@ impl Cookie { whatami: WhatAmI::rand(), zid: ZenohId::default(), resolution: Resolution::rand(), - tx_batch_size: rng.gen(), + batch_size: rng.gen(), nonce: rng.gen(), is_qos: rng.gen_bool(0.5), // properties: EstablishmentProperties::rand(), diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 8e20b2c297..946d4a05ef 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -12,33 +12,88 @@ // ZettaScale Zenoh Team, // pub(crate) mod accept; -pub mod authenticator; pub(super) mod cookie; +pub(super) mod extensions; pub(crate) mod open; -// pub(super) mod properties; use super::super::TransportManager; -use super::{TransportConfigUnicast, TransportPeer, TransportUnicast}; -use authenticator::AuthenticatedPeerLink; +use super::{TransportPeer, TransportUnicast}; +use async_trait::async_trait; use cookie::*; -// use properties::*; -use rand::Rng; +use sha3::{ + digest::{ExtendableOutput, Update, XofReader}, + Shake128, +}; use std::time::Duration; -use zenoh_core::{zasynclock, zasyncread}; use zenoh_link::{Link, LinkUnicast}; use zenoh_protocol::{ - core::{Field, Resolution, WhatAmI, ZenohId}, + core::{Field, Resolution, ZInt, ZenohId}, transport::{Close, TransportMessage}, }; use zenoh_result::ZResult; -pub(super) async fn close_link( - link: &LinkUnicast, - manager: &TransportManager, - auth_link: &AuthenticatedPeerLink, - mut reason: Option, -) { - if let Some(reason) = reason.take() { +/*************************************/ +/* TRAITS */ +/*************************************/ +#[async_trait] +pub(crate) trait OpenFsm { + type Error; + + type InitSynIn; + type InitSynOut; + async fn send_init_syn(&self, input: Self::InitSynIn) -> Result; + + type InitAckIn; + type InitAckOut; + async fn recv_init_ack(&self, input: Self::InitAckIn) -> Result; + + type OpenSynIn; + type OpenSynOut; + async fn send_open_syn(&self, input: Self::OpenSynIn) -> Result; + + type OpenAckIn; + type OpenAckOut; + async fn recv_open_ack(&self, input: Self::OpenAckIn) -> Result; +} + +#[async_trait] +pub(crate) trait AcceptFsm { + type Error; + + type InitSynIn; + type InitSynOut; + async fn recv_init_syn(&self, input: Self::InitSynIn) -> Result; + + type InitAckIn; + type InitAckOut; + async fn send_init_ack(&self, input: Self::InitAckIn) -> Result; + + type OpenSynIn; + type OpenSynOut; + async fn recv_open_syn(&self, input: Self::OpenSynIn) -> Result; + + type OpenAckIn; + type OpenAckOut; + async fn send_open_ack(&self, input: Self::OpenAckIn) -> Result; +} + +/*************************************/ +/* FUNCTIONS */ +/*************************************/ +pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) -> ZInt { + // Create a random yet deterministic initial_sn. + // In case of multilink it's important that the same initial_sn is used for every connection attempt. + // Instead of storing the state everywhere, we make sure that the we always compute the same initial_sn. + let mut hasher = Shake128::default(); + hasher.update(zid1.as_slice()); + hasher.update(zid2.as_slice()); + let mut array = (0 as ZInt).to_le_bytes(); + hasher.finalize_xof().read(&mut array); + ZInt::from_le_bytes(array) & resolution.get(Field::FrameSN).mask() +} + +pub(super) async fn close_link(link: &LinkUnicast, reason: Option) { + if let Some(reason) = reason { // Build the close message let message: TransportMessage = Close { reason, @@ -46,53 +101,20 @@ pub(super) async fn close_link( } .into(); // Send the close message on the link - let _ = link.write_transport_message(&message).await; + let _ = link.send(&message).await; } // Close the link let _ = link.close().await; - // Notify the authenticators - for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - pa.handle_link_err(auth_link).await; - } -} - -/*************************************/ -/* TRANSPORT */ -/*************************************/ -pub(super) struct InputInit { - pub(super) zid: ZenohId, - pub(super) whatami: WhatAmI, - pub(super) resolution: Resolution, - pub(super) is_qos: bool, -} -async fn transport_init( - manager: &TransportManager, - input: self::InputInit, -) -> ZResult { - // Initialize the transport if it is new - let tx_initial_sn = - zasynclock!(manager.prng).gen_range(0..=input.resolution.get(Field::FrameSN).mask()); - - let config = TransportConfigUnicast { - peer: input.zid, - whatami: input.whatami, - sn_resolution: input.resolution.get(Field::FrameSN).mask(), - tx_initial_sn, - is_qos: input.is_qos, - is_shm: false, // @TODO - }; - - manager.init_transport_unicast(config) } pub(super) struct InputFinalize { pub(super) transport: TransportUnicast, - pub(super) lease: Duration, - pub(super) tx_batch_size: u16, + pub(super) other_lease: Duration, + pub(super) agreed_batch_size: u16, } // Finalize the transport, notify the callback and start the link tasks -pub(super) async fn transport_finalize( +pub(super) async fn finalize_transport( link: &LinkUnicast, manager: &TransportManager, input: self::InputFinalize, @@ -102,8 +124,12 @@ pub(super) async fn transport_finalize( // Start the TX loop let keep_alive = manager.config.unicast.lease / manager.config.unicast.keep_alive as u32; - let batch_size = manager.config.batch_size.min(input.tx_batch_size); - transport.start_tx(link, &manager.tx_executor, keep_alive, batch_size)?; + transport.start_tx( + link, + &manager.tx_executor, + keep_alive, + input.agreed_batch_size, + )?; // Assign a callback if the transport is new // Keep the lock to avoid concurrent new_transport and closing/closed notifications @@ -134,7 +160,7 @@ pub(super) async fn transport_finalize( drop(a_guard); // Start the RX loop - transport.start_rx(link, input.lease, batch_size)?; + transport.start_rx(link, input.other_lease, input.agreed_batch_size)?; Ok(()) } diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs new file mode 100644 index 0000000000..279871e1c9 --- /dev/null +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -0,0 +1,374 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +// mod init_ack; +// mod init_syn; +// mod open_ack; +// mod open_syn; + +use crate::unicast::establishment::{ + close_link, compute_sn, finalize_transport, InputFinalize, OpenFsm, +}; +use crate::{TransportConfigUnicast, TransportManager, TransportUnicast}; +use async_trait::async_trait; +use std::time::Duration; +use zenoh_buffers::ZSlice; +use zenoh_config::{WhatAmI, ZenohId}; +use zenoh_core::zerror; +use zenoh_link::{LinkUnicast, LinkUnicastDirection}; +use zenoh_protocol::core::{Field, Resolution, ZInt}; +use zenoh_protocol::transport::{close, Close, InitSyn, OpenSyn, TransportBody, TransportMessage}; +use zenoh_result::ZResult; + +type OpenError = (zenoh_result::Error, Option); + +// InitSyn +struct SendInitSynIn { + mine_version: u8, + mine_zid: ZenohId, + mine_whatami: WhatAmI, + mine_resolution: Resolution, + mine_batch_size: u16, +} + +struct SendInitSynOut { + mine_batch_size: u16, + mine_resolution: Resolution, +} + +// InitAck +struct RecvInitAckIn { + mine_batch_size: u16, + mine_resolution: Resolution, +} + +struct RecvInitAckOut { + other_zid: ZenohId, + other_whatami: WhatAmI, + other_cookie: ZSlice, + agreed_resolution: Resolution, + agreed_batch_size: u16, +} + +// OpenSyn +struct SendOpenSynIn { + mine_zid: ZenohId, + mine_lease: Duration, + other_zid: ZenohId, + other_cookie: ZSlice, + agreed_resolution: Resolution, +} + +struct SendOpenSynOut { + mine_initial_sn: ZInt, +} + +// OpenAck +struct RecvOpenAckIn {} + +struct RecvOpenAckOut { + other_lease: Duration, + other_initial_sn: ZInt, +} + +// FSM +struct OpenLink<'a> { + link: &'a LinkUnicast, +} + +#[async_trait] +impl<'a> OpenFsm for OpenLink<'a> { + type Error = OpenError; + + type InitSynIn = SendInitSynIn; + type InitSynOut = SendInitSynOut; + async fn send_init_syn(&self, input: Self::InitSynIn) -> Result { + let msg: TransportMessage = InitSyn { + version: input.mine_version, + whatami: input.mine_whatami, + zid: input.mine_zid, + batch_size: input.mine_batch_size, + resolution: input.mine_resolution, + qos: None, // @TODO + shm: None, // @TODO + auth: None, // @TODO + } + .into(); + + let _ = self + .link + .send(&msg) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + + let output = SendInitSynOut { + mine_batch_size: input.mine_batch_size, + mine_resolution: input.mine_resolution, + }; + + Ok(output) + } + + type InitAckIn = RecvInitAckIn; + type InitAckOut = RecvInitAckOut; + async fn recv_init_ack(&self, input: Self::InitAckIn) -> Result { + let msg = self + .link + .recv() + .await + .map_err(|e| (e, Some(close::reason::INVALID)))?; + + let init_ack = match msg.body { + TransportBody::InitAck(init_ack) => init_ack, + TransportBody::Close(Close { reason, .. }) => { + let e = zerror!( + "Received a close message (reason {}) in response to an InitSyn on: {}", + close::reason_to_str(reason), + self.link, + ); + match reason { + close::reason::MAX_LINKS => log::debug!("{}", e), + _ => log::error!("{}", e), + } + return Err((e.into(), None)); + } + _ => { + let e = zerror!( + "Received an invalid message in response to an InitSyn on {}: {:?}", + self.link, + msg.body + ); + log::error!("{}", e); + return Err((e.into(), Some(close::reason::INVALID))); + } + }; + + // Compute the minimum SN resolution + let agreed_resolution = { + let mut res = Resolution::default(); + + // Frame SN + let i_fsn_res = init_ack.resolution.get(Field::FrameSN); + let m_fsn_res = input.mine_resolution.get(Field::FrameSN); + + if i_fsn_res > m_fsn_res { + let e = zerror!( + "Invalid FrameSN resolution on {}: {:?} > {:?}", + self.link, + i_fsn_res, + m_fsn_res + ); + log::error!("{}", e); + return Err((e.into(), Some(close::reason::INVALID))); + } + res.set(Field::FrameSN, i_fsn_res); + + // Request ID + let i_rid_res = init_ack.resolution.get(Field::RequestID); + let m_rid_res = input.mine_resolution.get(Field::RequestID); + + if i_rid_res > m_rid_res { + let e = zerror!( + "Invalid RequestID resolution on {}: {:?} > {:?}", + self.link, + i_rid_res, + m_rid_res + ); + log::error!("{}", e); + return Err((e.into(), Some(close::reason::INVALID))); + } + res.set(Field::RequestID, i_rid_res); + + res + }; + + // Compute the minimum batch size + let agreed_batch_size = input.mine_batch_size.min(init_ack.batch_size); + + let output = RecvInitAckOut { + other_zid: init_ack.zid, + other_whatami: init_ack.whatami, + other_cookie: init_ack.cookie, + agreed_resolution, + agreed_batch_size, + }; + Ok(output) + } + + type OpenSynIn = SendOpenSynIn; + type OpenSynOut = SendOpenSynOut; + async fn send_open_syn(&self, input: Self::OpenSynIn) -> Result { + let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, input.agreed_resolution); + + // Build and send an OpenSyn message + let message: TransportMessage = OpenSyn { + lease: input.mine_lease, + initial_sn: mine_initial_sn, + cookie: input.other_cookie, + shm: None, // @TODO + auth: None, // @TODO + } + .into(); + + let _ = self + .link + .send(&message) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + + let output = SendOpenSynOut { mine_initial_sn }; + Ok(output) + } + + type OpenAckIn = RecvOpenAckIn; + type OpenAckOut = RecvOpenAckOut; + async fn recv_open_ack(&self, _in: Self::OpenAckIn) -> Result { + // Wait to read an OpenAck + let msg = self + .link + .recv() + .await + .map_err(|e| (e, Some(close::reason::INVALID)))?; + + let open_ack = match msg.body { + TransportBody::OpenAck(open_ack) => open_ack, + TransportBody::Close(Close { reason, .. }) => { + let e = zerror!( + "Received a close message (reason {}) in response to an OpenSyn on: {:?}", + close::reason_to_str(reason), + self.link, + ); + match reason { + close::reason::MAX_LINKS => log::debug!("{}", e), + _ => log::error!("{}", e), + } + return Err((e.into(), None)); + } + _ => { + let e = zerror!( + "Received an invalid message in response to an OpenSyn on {}: {:?}", + self.link, + msg.body + ); + log::error!("{}", e); + return Err((e.into(), Some(close::reason::INVALID))); + } + }; + + println!(">>> RECEIVING {}", open_ack.initial_sn); + + let output = RecvOpenAckOut { + other_initial_sn: open_ack.initial_sn, + other_lease: open_ack.lease, + }; + Ok(output) + } +} + +// OLD +pub(crate) async fn open_link( + link: &LinkUnicast, + manager: &TransportManager, +) -> ZResult { + let fsm = OpenLink { link }; + + // Init handshake + macro_rules! step { + ($s: expr) => { + match $s { + Ok(output) => output, + Err((e, reason)) => { + close_link(link, reason).await; + return Err(e); + } + } + }; + } + + let isyn_in = SendInitSynIn { + mine_version: manager.config.version, + mine_zid: manager.config.zid, + mine_whatami: manager.config.whatami, + mine_resolution: manager.config.resolution, + mine_batch_size: manager.config.batch_size, + }; + let isyn_out = step!(fsm.send_init_syn(isyn_in).await); + + let iack_in = RecvInitAckIn { + mine_resolution: isyn_out.mine_resolution, + mine_batch_size: isyn_out.mine_batch_size, + }; + let iack_out = step!(fsm.recv_init_ack(iack_in).await); + + // Open handshake + let osyn_in = SendOpenSynIn { + mine_zid: manager.config.zid, + other_zid: iack_out.other_zid, + mine_lease: manager.config.unicast.lease, + agreed_resolution: iack_out.agreed_resolution, + other_cookie: iack_out.other_cookie, + }; + let osyn_out = step!(fsm.send_open_syn(osyn_in).await); + + let oack_in = RecvOpenAckIn {}; + let oack_out = step!(fsm.recv_open_ack(oack_in).await); + + // Initialize the transport + let config = TransportConfigUnicast { + peer: iack_out.other_zid, + whatami: iack_out.other_whatami, + sn_resolution: iack_out.agreed_resolution.get(Field::FrameSN).mask(), + tx_initial_sn: osyn_out.mine_initial_sn, + is_qos: false, // @TODO + is_shm: false, // @TODO + }; + let transport = step!(manager + .init_transport_unicast(config) + .await + .map_err(|e| (e, Some(close::reason::INVALID)))); + + // Finalize the transport + // Add the link to the transport + step!(step!(transport + .get_inner() + .map_err(|e| (e, Some(close::reason::INVALID)))) + .add_link(link.clone(), LinkUnicastDirection::Outbound) + .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); + + // Sync the RX sequence number + let _ = step!(transport + .get_inner() + .map_err(|e| (e, Some(close::reason::INVALID)))) + .sync(oack_out.other_initial_sn) + .await; + + log::debug!( + "New transport link established with {}: {}", + iack_out.other_zid, + link + ); + + let output = InputFinalize { + transport, + other_lease: oack_out.other_lease, + agreed_batch_size: iack_out.agreed_batch_size, + }; + let transport = output.transport.clone(); + let res = finalize_transport(link, manager, output).await; + if let Err(e) = res { + let _ = transport.close().await; + return Err(e); + } + + Ok(transport) +} diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs b/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs deleted file mode 100644 index 0277f72440..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/open/init_ack.rs +++ /dev/null @@ -1,204 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::unicast::establishment::open::OResult; -use crate::TransportManager; -use zenoh_buffers::ZSlice; -use zenoh_link::LinkUnicast; -use zenoh_protocol::{ - core::{Field, Resolution, WhatAmI, ZenohId}, - transport::{ - close::{self, Close}, - TransportBody, - }, -}; -use zenoh_result::zerror; - -/*************************************/ -/* OPEN */ -/*************************************/ -pub(super) struct Output { - pub(super) zid: ZenohId, - pub(super) whatami: WhatAmI, - pub(super) resolution: Resolution, - pub(super) batch_size: u16, - pub(super) cookie: ZSlice, - // Extensions - pub(super) is_qos: bool, -} - -pub(super) async fn recv( - link: &LinkUnicast, - manager: &TransportManager, - input: super::init_syn::Output, -) -> OResult { - // Wait to read an InitAck - let mut messages = link - .read_transport_message() - .await - .map_err(|e| (e, Some(close::reason::INVALID)))?; - if messages.len() != 1 { - return Err(( - zerror!( - "Received multiple messages in response to an InitSyn on {}: {:?}", - link, - messages, - ) - .into(), - Some(close::reason::INVALID), - )); - } - - let msg = messages.remove(0); - let init_ack = match msg.body { - TransportBody::InitAck(init_ack) => init_ack, - TransportBody::Close(Close { reason, .. }) => { - let e = zerror!( - "Received a close message (reason {}) in response to an InitSyn on: {}", - close::reason_to_str(reason), - link, - ); - match reason { - close::reason::MAX_LINKS => log::debug!("{}", e), - _ => log::error!("{}", e), - } - return Err((e.into(), None)); - } - _ => { - let e = zerror!( - "Received an invalid message in response to an InitSyn on {}: {:?}", - link, - msg.body - ); - log::error!("{}", e); - return Err((e.into(), Some(close::reason::INVALID))); - } - }; - - // Compute the minimum SN resolution - let resolution = { - let mut res = Resolution::default(); - - // Frame SN - let i_fsn_res = init_ack.resolution.get(Field::FrameSN); - let m_fsn_res = manager.config.resolution.get(Field::FrameSN); - - if i_fsn_res > m_fsn_res { - let e = zerror!( - "Invalid FrameSN resolution on {}: {:?} > {:?}", - link, - i_fsn_res, - m_fsn_res - ); - log::error!("{}", e); - return Err((e.into(), Some(close::reason::INVALID))); - } - res.set(Field::FrameSN, i_fsn_res); - - // Request ID - let i_rid_res = init_ack.resolution.get(Field::RequestID); - let m_rid_res = manager.config.resolution.get(Field::RequestID); - - if i_rid_res > m_rid_res { - let e = zerror!( - "Invalid RequestID resolution on {}: {:?} > {:?}", - link, - i_rid_res, - m_rid_res - ); - log::error!("{}", e); - return Err((e.into(), Some(close::reason::INVALID))); - } - res.set(Field::RequestID, i_rid_res); - - res - }; - - // Compute the minimum batch size - let batch_size = manager.config.batch_size.min(init_ack.batch_size); - - // Compute QoS - let is_qos = input.is_qos && init_ack.qos.is_some(); - - // // Store the peer id associate do this link - // auth_link.peer_id = Some(init_ack.zid); - - // let mut init_ack_properties = match msg.attachment.take() { - // Some(att) => EstablishmentProperties::try_from(&att) - // .map_err(|e| (e, Some(close::reason::INVALID)))?, - // None => EstablishmentProperties::new(), - // }; - - // #[allow(unused_mut)] - // let mut is_shm = false; - // let mut ps_attachment = EstablishmentProperties::new(); - // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - // #[allow(unused_mut)] - // let mut att = pa - // .handle_init_ack( - // auth_link, - // &init_ack.zid, - // sn_resolution, - // init_ack_properties.remove(pa.id().into()).map(|x| x.value), - // ) - // .await; - - // #[cfg(feature = "shared-memory")] - // if pa.id() == PeerAuthenticatorId::Shm { - // // Check if SHM has been validated from the other side - // att = match att { - // Ok(att) => { - // is_shm = att.is_some(); - // Ok(att) - // } - // Err(e) => { - // if e.is::() { - // is_shm = false; - // Ok(None) - // } else { - // Err(e) - // } - // } - // }; - // } - - // let mut att = att.map_err(|e| (e, Some(close::reason::INVALID)))?; - // if let Some(att) = att.take() { - // ps_attachment - // .insert(Property { - // key: pa.id().into(), - // value: att, - // }) - // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - // } - // } - - // let open_syn_attachment = if ps_attachment.is_empty() { - // None - // } else { - // let att = - // Attachment::try_from(&ps_attachment).map_err(|e| (e, Some(close::reason::INVALID)))?; - // Some(att) - // }; @TODO - - let output = Output { - zid: init_ack.zid, - whatami: init_ack.whatami, - resolution, - batch_size, - cookie: init_ack.cookie, - is_qos, - }; - - Ok(output) -} diff --git a/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs b/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs deleted file mode 100644 index c75107dd2e..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/open/init_syn.rs +++ /dev/null @@ -1,71 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::OResult; -use crate::TransportManager; -use zenoh_link::LinkUnicast; -use zenoh_protocol::transport::{ - close, - init::{ext, InitSyn}, - TransportMessage, -}; - -/*************************************/ -/* OPEN */ -/*************************************/ -pub(super) struct Output { - pub(super) is_qos: bool, -} - -pub(super) async fn send(link: &LinkUnicast, manager: &TransportManager) -> OResult { - // let mut ps_attachment = EstablishmentProperties::new(); - // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - // let mut att = pa - // .get_init_syn_properties(auth_link, &manager.config.zid) - // .await - // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - // if let Some(att) = att.take() { - // ps_attachment - // .insert(Property { - // key: pa.id().into(), - // value: att, - // }) - // .map_err(|e| (e, Some(close::reason::UNSUPPORTED)))?; - // } - // } - - // Build QoS extension - let qos = manager.config.unicast.is_qos.then_some(ext::QoS::new()); - - let msg: TransportMessage = InitSyn { - version: manager.config.version, - whatami: manager.config.whatami, - zid: manager.config.zid, - batch_size: manager.config.batch_size, - resolution: manager.config.resolution, - qos, - shm: None, // @TODO - auth: None, // @TODO - } - .into(); - - let _ = link - .write_transport_message(&msg) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; - - let output = Output { - is_qos: qos.is_some(), - }; - Ok(output) -} diff --git a/io/zenoh-transport/src/unicast/establishment/open/mod.rs b/io/zenoh-transport/src/unicast/establishment/open/mod.rs deleted file mode 100644 index e687a65f7b..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/open/mod.rs +++ /dev/null @@ -1,135 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -mod init_ack; -mod init_syn; -mod open_ack; -mod open_syn; - -use super::authenticator::AuthenticatedPeerLink; -use crate::unicast::establishment::{close_link, transport_finalize, InputFinalize, InputInit}; -use crate::{TransportManager, TransportUnicast}; -use zenoh_link::{LinkUnicast, LinkUnicastDirection}; -use zenoh_protocol::transport::close; -use zenoh_result::ZResult; - -type OError = (zenoh_result::Error, Option); -type OResult = Result; - -pub(crate) async fn open_link( - link: &LinkUnicast, - manager: &TransportManager, - auth_link: &mut AuthenticatedPeerLink, -) -> ZResult { - // INIT handshake - macro_rules! step { - ($s: expr) => { - match $s { - Ok(output) => output, - Err((e, reason)) => { - close_link(link, manager, auth_link, reason).await; - return Err(e); - } - } - }; - } - - let output = step!(init_syn::send(link, manager).await); - let output = step!(init_ack::recv(link, manager, output).await); - - // Initialize the transport - macro_rules! step { - ($s: expr) => { - match $s { - Ok(output) => output, - Err(e) => { - close_link(link, manager, auth_link, Some(close::reason::INVALID)).await; - return Err(e); - } - } - }; - } - - let zid = output.zid; - let input = InputInit { - zid, - whatami: output.whatami, - resolution: output.resolution, - is_qos: output.is_qos, - }; - let transport = step!(super::transport_init(manager, input).await); - - // OPEN handshake - macro_rules! step { - ($s: expr) => { - match $s { - Ok(output) => output, - Err((e, reason)) => { - if let Ok(ll) = transport.get_links() { - if ll.is_empty() { - let _ = manager.del_transport_unicast(&zid).await; - } - } - close_link(link, manager, auth_link, reason).await; - return Err(e); - } - } - }; - } - - let initial_sn = step!(transport - .get_inner() - .map_err(|e| (e, Some(close::reason::INVALID)))) - .config - .initial_sn_tx; - - let tx_batch_size = output.batch_size; - let input = open_syn::Input { - cookie: output.cookie, - resolution: output.resolution, - initial_sn, - }; - let output = step!(open_syn::send(link, manager, input).await); - let output = step!(open_ack::recv(link, manager, output).await); - - // Finalize the transport - // Add the link to the transport - step!(step!(transport - .get_inner() - .map_err(|e| (e, Some(close::reason::INVALID)))) - .add_link(link.clone(), LinkUnicastDirection::Outbound) - .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); - - // Sync the RX sequence number - let _ = step!(transport - .get_inner() - .map_err(|e| (e, Some(close::reason::INVALID)))) - .sync(output.initial_sn) - .await; - - log::debug!("New transport link established with {}: {}", zid, link); - - let output = InputFinalize { - transport, - lease: output.lease, - tx_batch_size, - }; - let transport = output.transport.clone(); - let res = transport_finalize(link, manager, output).await; - if let Err(e) = res { - let _ = transport.close().await; - return Err(e); - } - - Ok(transport) -} diff --git a/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs b/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs deleted file mode 100644 index 54297f60ed..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/open/open_ack.rs +++ /dev/null @@ -1,110 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{unicast::establishment::open::OResult, TransportManager}; -use std::time::Duration; -use zenoh_link::LinkUnicast; -use zenoh_protocol::{ - core::{Field, ZInt}, - transport::{ - close::{self, Close}, - TransportBody, - }, -}; -use zenoh_result::zerror; - -pub(super) struct Output { - pub(super) initial_sn: ZInt, - pub(super) lease: Duration, -} - -pub(super) async fn recv( - link: &LinkUnicast, - _manager: &TransportManager, - input: super::open_syn::Output, -) -> OResult { - // Wait to read an OpenAck - let mut messages = link - .read_transport_message() - .await - .map_err(|e| (e, Some(close::reason::INVALID)))?; - if messages.len() != 1 { - return Err(( - zerror!( - "Received multiple messages in response to an OpenSyn on {}: {:?}", - link, - messages, - ) - .into(), - Some(close::reason::INVALID), - )); - } - - let msg = messages.remove(0); - let open_ack = match msg.body { - TransportBody::OpenAck(open_ack) => open_ack, - TransportBody::Close(Close { reason, .. }) => { - let e = zerror!( - "Received a close message (reason {}) in response to an OpenSyn on: {:?}", - close::reason_to_str(reason), - link, - ); - match reason { - close::reason::MAX_LINKS => log::debug!("{}", e), - _ => log::error!("{}", e), - } - return Err((e.into(), None)); - } - _ => { - let e = zerror!( - "Received an invalid message in response to an OpenSyn on {}: {:?}", - link, - msg.body - ); - log::error!("{}", e); - return Err((e.into(), Some(close::reason::INVALID))); - } - }; - - // Verify that initial_sn is within the agreed resolution - if open_ack.initial_sn > input.resolution.get(Field::FrameSN).mask() { - let e = zerror!( - "Received invalid initial SN {}: {:?}", - link, - open_ack.initial_sn - ); - log::error!("{}", e); - return Err((e.into(), Some(close::reason::INVALID))); - } - - // let mut opean_ack_properties = match msg.attachment.take() { - // Some(att) => EstablishmentProperties::try_from(&att) - // .map_err(|e| (e, Some(close::reason::INVALID)))?, - // None => EstablishmentProperties::new(), - // }; - // for pa in zasyncread!(manager.state.unicast.peer_authenticator).iter() { - // let _ = pa - // .handle_open_ack( - // auth_link, - // opean_ack_properties.remove(pa.id().into()).map(|x| x.value), - // ) - // .await - // .map_err(|e| (e, Some(close::reason::INVALID)))?; - // } @TODO - - let output = Output { - initial_sn: open_ack.initial_sn, - lease: open_ack.lease, - }; - Ok(output) -} diff --git a/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs b/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs deleted file mode 100644 index 3c6db84e48..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/open/open_syn.rs +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::OResult; -use crate::TransportManager; -use zenoh_buffers::ZSlice; -use zenoh_link::LinkUnicast; -use zenoh_protocol::{ - core::{Resolution, ZInt}, - transport::{close, OpenSyn, TransportMessage}, -}; - -pub(super) struct Input { - pub(super) cookie: ZSlice, - pub(super) resolution: Resolution, - pub(super) initial_sn: ZInt, -} - -pub(super) struct Output { - pub(super) resolution: Resolution, -} - -pub(super) async fn send( - link: &LinkUnicast, - manager: &TransportManager, - input: Input, -) -> OResult { - // Build and send an OpenSyn message - let lease = manager.config.unicast.lease; - let message: TransportMessage = OpenSyn { - lease, - initial_sn: input.initial_sn, - cookie: input.cookie, - shm: None, // @TODO - auth: None, // @TODO - } - .into(); - - let _ = link - .write_transport_message(&message) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; - - let output = Output { - resolution: input.resolution, - }; - Ok(output) -} diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/link.rs index a1dda7e672..e74097bb5a 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/link.rs @@ -202,7 +202,7 @@ async fn tx_task( let message: TransportMessage = KeepAlive.into(); #[allow(unused_variables)] // Used when stats feature is enabled - let n = link.write_transport_message(&message).await?; + let n = link.send(&message).await?; #[cfg(feature = "stats")] { stats.inc_tx_t_msgs(1); diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 41d3abc027..6524250596 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -12,20 +12,19 @@ // ZettaScale Zenoh Team, // use crate::unicast::{ - establishment::authenticator::*, transport::{TransportUnicastConfig, TransportUnicastInner}, TransportConfigUnicast, TransportUnicast, }; use crate::TransportManager; use async_std::prelude::FutureExt; -use async_std::sync::{Mutex as AsyncMutex, RwLock as AsyncRwLock}; +use async_std::sync::Mutex; use async_std::task; -use std::collections::{HashMap, HashSet}; -use std::sync::{Arc, Mutex}; +use std::collections::HashMap; +use std::sync::Arc; use std::time::Duration; use zenoh_cfg_properties::config::*; use zenoh_config::Config; -use zenoh_core::{zasynclock, zasyncread, zasyncwrite, zlock, zparse}; +use zenoh_core::{zasynclock, zparse}; use zenoh_link::*; use zenoh_protocol::{ core::{locator::LocatorProtocol, ZenohId}, @@ -50,9 +49,9 @@ pub struct TransportManagerConfigUnicast { pub struct TransportManagerStateUnicast { // Incoming uninitialized transports - pub(super) incoming: Arc>, + pub(super) incoming: Arc>, // Active peer authenticators - pub(super) peer_authenticator: Arc>>, + // pub(super) peer_authenticator: Arc>>, @TODO // Established listeners pub(super) protocols: Arc>>, // Established transports @@ -79,7 +78,7 @@ pub struct TransportManagerBuilderUnicast { pub(super) is_qos: bool, #[cfg(feature = "shared-memory")] pub(super) is_shm: bool, - pub(super) peer_authenticator: HashSet, + // pub(super) peer_authenticator: HashSet, @TODO } impl TransportManagerBuilderUnicast { @@ -113,10 +112,10 @@ impl TransportManagerBuilderUnicast { self } - pub fn peer_authenticator(mut self, peer_authenticator: HashSet) -> Self { - self.peer_authenticator = peer_authenticator; - self - } + // pub fn peer_authenticator(mut self, peer_authenticator: HashSet) -> Self { + // self.peer_authenticator = peer_authenticator; + // self + // } @TODO pub fn qos(mut self, is_qos: bool) -> Self { self.is_qos = is_qos; @@ -146,7 +145,7 @@ impl TransportManagerBuilderUnicast { { self = self.shm(*config.transport().shared_memory().enabled()); } - self = self.peer_authenticator(PeerAuthenticator::from_config(config).await?); + // self = self.peer_authenticator(PeerAuthenticator::from_config(config).await?); Ok(self) } @@ -168,32 +167,32 @@ impl TransportManagerBuilderUnicast { }; // Enable pubkey authentication by default to avoid ZenohId spoofing - #[cfg(feature = "auth_pubkey")] - if !self - .peer_authenticator - .iter() - .any(|a| a.id() == PeerAuthenticatorId::PublicKey) - { - self.peer_authenticator - .insert(PubKeyAuthenticator::make()?.into()); - } - - #[cfg(feature = "shared-memory")] - if self.is_shm - && !self - .peer_authenticator - .iter() - .any(|a| a.id() == PeerAuthenticatorId::Shm) - { - self.peer_authenticator - .insert(SharedMemoryAuthenticator::make()?.into()); - } + // #[cfg(feature = "auth_pubkey")] + // if !self + // .peer_authenticator + // .iter() + // .any(|a| a.id() == PeerAuthenticatorId::PublicKey) + // { + // self.peer_authenticator + // .insert(PubKeyAuthenticator::make()?.into()); + // } @TODO + + // #[cfg(feature = "shared-memory")] + // if self.is_shm + // && !self + // .peer_authenticator + // .iter() + // .any(|a| a.id() == PeerAuthenticatorId::Shm) + // { + // self.peer_authenticator + // .insert(SharedMemoryAuthenticator::make()?.into()); + // } @TODO let state = TransportManagerStateUnicast { - incoming: Arc::new(AsyncMutex::new(0)), + incoming: Arc::new(Mutex::new(0)), protocols: Arc::new(Mutex::new(HashMap::new())), transports: Arc::new(Mutex::new(HashMap::new())), - peer_authenticator: Arc::new(AsyncRwLock::new(self.peer_authenticator)), + // peer_authenticator: Arc::new(AsyncRwLock::new(self.peer_authenticator)), }; let params = TransportManagerParamsUnicast { config, state }; @@ -214,7 +213,7 @@ impl Default for TransportManagerBuilderUnicast { is_qos: zparse!(ZN_QOS_DEFAULT).unwrap(), #[cfg(feature = "shared-memory")] is_shm: zparse!(ZN_SHM_DEFAULT).unwrap(), - peer_authenticator: HashSet::new(), + // peer_authenticator: HashSet::new(), } } } @@ -230,13 +229,13 @@ impl TransportManager { pub async fn close_unicast(&self) { log::trace!("TransportManagerUnicast::clear())"); - let mut pa_guard = zasyncwrite!(self.state.unicast.peer_authenticator); + // let mut pa_guard = zasyncwrite!(self.state.unicast.peer_authenticator); - for pa in pa_guard.drain() { - pa.close().await; - } + // for pa in pa_guard.drain() { + // pa.close().await; + // } @TODO - let mut pl_guard = zlock!(self.state.unicast.protocols) + let mut pl_guard = zasynclock!(self.state.unicast.protocols) .drain() .map(|(_, v)| v) .collect::>>(); @@ -247,7 +246,7 @@ impl TransportManager { } } - let mut tu_guard = zlock!(self.state.unicast.transports) + let mut tu_guard = zasynclock!(self.state.unicast.transports) .drain() .map(|(_, v)| v) .collect::>>(); @@ -259,8 +258,8 @@ impl TransportManager { /*************************************/ /* LINK MANAGER */ /*************************************/ - fn new_link_manager_unicast(&self, protocol: &str) -> ZResult { - let mut w_guard = zlock!(self.state.unicast.protocols); + async fn new_link_manager_unicast(&self, protocol: &str) -> ZResult { + let mut w_guard = zasynclock!(self.state.unicast.protocols); if let Some(lm) = w_guard.get(protocol) { Ok(lm.clone()) } else { @@ -271,8 +270,11 @@ impl TransportManager { } } - fn get_link_manager_unicast(&self, protocol: &LocatorProtocol) -> ZResult { - match zlock!(self.state.unicast.protocols).get(protocol) { + async fn get_link_manager_unicast( + &self, + protocol: &LocatorProtocol, + ) -> ZResult { + match zasynclock!(self.state.unicast.protocols).get(protocol) { Some(manager) => Ok(manager.clone()), None => bail!( "Can not get the link manager for protocol ({}) because it has not been found", @@ -281,8 +283,8 @@ impl TransportManager { } } - fn del_link_manager_unicast(&self, protocol: &LocatorProtocol) -> ZResult<()> { - match zlock!(self.state.unicast.protocols).remove(protocol) { + async fn del_link_manager_unicast(&self, protocol: &LocatorProtocol) -> ZResult<()> { + match zasynclock!(self.state.unicast.protocols).remove(protocol) { Some(_) => Ok(()), None => bail!( "Can not delete the link manager for protocol ({}) because it has not been found.", @@ -295,7 +297,9 @@ impl TransportManager { /* LISTENER */ /*************************************/ pub async fn add_listener_unicast(&self, mut endpoint: EndPoint) -> ZResult { - let manager = self.new_link_manager_unicast(endpoint.protocol().as_str())?; + let manager = self + .new_link_manager_unicast(endpoint.protocol().as_str()) + .await?; // Fill and merge the endpoint configuration if let Some(config) = self.config.endpoint.get(endpoint.protocol().as_str()) { endpoint.config_mut().extend(config.iter())?; @@ -304,25 +308,28 @@ impl TransportManager { } pub async fn del_listener_unicast(&self, endpoint: &EndPoint) -> ZResult<()> { - let lm = self.get_link_manager_unicast(endpoint.protocol().as_str())?; + let lm = self + .get_link_manager_unicast(endpoint.protocol().as_str()) + .await?; lm.del_listener(endpoint).await?; if lm.get_listeners().is_empty() { - self.del_link_manager_unicast(endpoint.protocol().as_str())?; + self.del_link_manager_unicast(endpoint.protocol().as_str()) + .await?; } Ok(()) } - pub fn get_listeners_unicast(&self) -> Vec { + pub async fn get_listeners_unicast(&self) -> Vec { let mut vec: Vec = vec![]; - for p in zlock!(self.state.unicast.protocols).values() { + for p in zasynclock!(self.state.unicast.protocols).values() { vec.extend_from_slice(&p.get_listeners()); } vec } - pub fn get_locators_unicast(&self) -> Vec { + pub async fn get_locators_unicast(&self) -> Vec { let mut vec: Vec = vec![]; - for p in zlock!(self.state.unicast.protocols).values() { + for p in zasynclock!(self.state.unicast.protocols).values() { vec.extend_from_slice(&p.get_locators()); } vec @@ -331,11 +338,11 @@ impl TransportManager { /*************************************/ /* TRANSPORT */ /*************************************/ - pub(super) fn init_transport_unicast( + pub(super) async fn init_transport_unicast( &self, config: TransportConfigUnicast, ) -> ZResult { - let mut guard = zlock!(self.state.unicast.transports); + let mut guard = zasynclock!(self.state.unicast.transports); // First verify if the transport already exists match guard.get(&config.peer) { @@ -446,7 +453,9 @@ impl TransportManager { } // Automatically create a new link manager for the protocol if it does not exist - let manager = self.new_link_manager_unicast(endpoint.protocol().as_str())?; + let manager = self + .new_link_manager_unicast(endpoint.protocol().as_str()) + .await?; // Fill and merge the endpoint configuration if let Some(config) = self.config.endpoint.get(endpoint.protocol().as_str()) { endpoint.config_mut().extend(config.iter())?; @@ -455,29 +464,24 @@ impl TransportManager { // Create a new link associated by calling the Link Manager let link = manager.new_link(endpoint).await?; // Open the link - let mut auth_link = AuthenticatedPeerLink { - src: link.get_src().to_owned(), - dst: link.get_src().to_owned(), - peer_id: None, - }; - super::establishment::open::open_link(&link, self, &mut auth_link).await + super::establishment::open::open_link(&link, self).await } - pub fn get_transport_unicast(&self, peer: &ZenohId) -> Option { - zlock!(self.state.unicast.transports) + pub async fn get_transport_unicast(&self, peer: &ZenohId) -> Option { + zasynclock!(self.state.unicast.transports) .get(peer) .map(|t| t.into()) } - pub fn get_transports_unicast(&self) -> Vec { - zlock!(self.state.unicast.transports) + pub async fn get_transports_unicast(&self) -> Vec { + zasynclock!(self.state.unicast.transports) .values() .map(|t| t.into()) .collect() } pub(super) async fn del_transport_unicast(&self, peer: &ZenohId) -> ZResult<()> { - let _ = zlock!(self.state.unicast.transports) + let _ = zasynclock!(self.state.unicast.transports) .remove(peer) .ok_or_else(|| { let e = zerror!("Can not delete the transport of peer: {}", peer); @@ -485,9 +489,9 @@ impl TransportManager { e })?; - for pa in zasyncread!(self.state.unicast.peer_authenticator).iter() { - pa.handle_close(peer).await; - } + // for pa in zasyncread!(self.state.unicast.peer_authenticator).iter() { + // pa.handle_close(peer).await; + // } @TODO Ok(()) } @@ -513,16 +517,9 @@ impl TransportManager { // Spawn a task to accept the link let c_manager = self.clone(); task::spawn(async move { - let mut auth_link = AuthenticatedPeerLink { - src: link.get_src().to_owned(), - dst: link.get_dst().to_owned(), - peer_id: None, - }; - - if let Err(e) = - super::establishment::accept::accept_link(&link, &c_manager, &mut auth_link) - .timeout(c_manager.config.unicast.accept_timeout) - .await + if let Err(e) = super::establishment::accept::accept_link(&link, &c_manager) + .timeout(c_manager.config.unicast.accept_timeout) + .await { log::debug!("{}", e); let _ = link.close().await; diff --git a/io/zenoh-transport/tests/endpoints.rs b/io/zenoh-transport/tests/endpoints.rs index 2dab74ac4c..e921e96338 100644 --- a/io/zenoh-transport/tests/endpoints.rs +++ b/io/zenoh-transport/tests/endpoints.rs @@ -80,7 +80,7 @@ async fn run(endpoints: &[EndPoint]) { for _ in 0..RUNS { // Create the listeners for e in endpoints.iter() { - dbg!("Add {e}"); + println!("Add {e}"); ztimeout!(sm.add_listener(e.clone())).unwrap(); } @@ -88,7 +88,7 @@ async fn run(endpoints: &[EndPoint]) { // Delete the listeners for e in endpoints.iter() { - dbg!("Del {e}"); + println!("Del {e}"); ztimeout!(sm.del_listener(e)).unwrap(); } diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index f5c41295fb..de657a6668 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -316,25 +316,25 @@ async fn authenticator_multilink(endpoint: &EndPoint) { .unwrap(); /* [1] */ - dbg!("\nTransport Authenticator PubKey [1a1]"); + println!("\nTransport Authenticator PubKey [1a1]"); // Add the locator on the router ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); - dbg!("Transport Authenticator PubKey [1a2]"); + println!("Transport Authenticator PubKey [1a2]"); let locators = router_manager.get_listeners(); - dbg!("Transport Authenticator PubKey [1a2]: {locators:?}"); + println!("Transport Authenticator PubKey [1a2]: {locators:?}"); assert_eq!(locators.len(), 1); /* [2a] */ // Open a first transport from client01 to the router // -> This should be accepted - dbg!("Transport Authenticator PubKey [2a1]"); + println!("Transport Authenticator PubKey [2a1]"); let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); assert_eq!(c_ses1.get_links().unwrap().len(), 1); /* [2b] */ // Open a second transport from client01 to the router // -> This should be accepted - dbg!("Transport Authenticator PubKey [2b1]"); + println!("Transport Authenticator PubKey [2b1]"); let c_ses1_tmp = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); assert_eq!(c_ses1, c_ses1_tmp); assert_eq!(c_ses1.get_links().unwrap().len(), 2); @@ -342,15 +342,15 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [2c] */ // Open a third transport from client01 to the router // -> This should be rejected - dbg!("Transport Authenticator PubKey [2c1]"); + println!("Transport Authenticator PubKey [2c1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator PubKey [2c2]: {res:?}"); + println!("Transport Authenticator PubKey [2c2]: {res:?}"); assert!(res.is_err()); assert_eq!(c_ses1.get_links().unwrap().len(), 2); /* [2d] */ // Close the session - dbg!("Transport Authenticator PubKey [2d1]"); + println!("Transport Authenticator PubKey [2d1]"); ztimeout!(c_ses1.close()).unwrap(); ztimeout!(async { @@ -362,14 +362,14 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [3a] */ // Open a first transport from client02 to the router // -> This should be accepted - dbg!("Transport Authenticator PubKey [3a1]"); + println!("Transport Authenticator PubKey [3a1]"); let c_ses2 = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); assert_eq!(c_ses2.get_links().unwrap().len(), 1); /* [3b] */ // Open a second transport from client02 to the router // -> This should be accepted - dbg!("Transport Authenticator PubKey [3b1]"); + println!("Transport Authenticator PubKey [3b1]"); let c_ses2_tmp = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); assert_eq!(c_ses2, c_ses2_tmp); assert_eq!(c_ses2.get_links().unwrap().len(), 2); @@ -377,17 +377,17 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [3c] */ // Open a third transport from client02 to the router // -> This should be rejected - dbg!("Transport Authenticator PubKey [3c1]"); + println!("Transport Authenticator PubKey [3c1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator PubKey [3c2]: {res:?}"); + println!("Transport Authenticator PubKey [3c2]: {res:?}"); assert!(res.is_err()); assert_eq!(c_ses2.get_links().unwrap().len(), 2); /* [3d] */ // Close the session - dbg!("Transport Authenticator PubKey [3d1]"); + println!("Transport Authenticator PubKey [3d1]"); let res = ztimeout!(c_ses2.close()); - dbg!("Transport Authenticator PubKey [3d2]: {res:?}"); + println!("Transport Authenticator PubKey [3d2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -399,9 +399,9 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [4a] */ // Open a first transport from client01_spoof to the router // -> This should be accepted - dbg!("Transport Authenticator PubKey [4a1]"); + println!("Transport Authenticator PubKey [4a1]"); let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator PubKey [4a2]: {res:?}"); + println!("Transport Authenticator PubKey [4a2]: {res:?}"); assert!(res.is_ok()); let c_ses1_spoof = res.unwrap(); assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 1); @@ -409,26 +409,26 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [4b] */ // Open a second transport from client01_spoof to the router // -> This should be accepted - dbg!("Transport Authenticator PubKey [4b1]"); + println!("Transport Authenticator PubKey [4b1]"); let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator PubKey [4b2]: {res:?}"); + println!("Transport Authenticator PubKey [4b2]: {res:?}"); assert!(res.is_ok()); assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); /* [4c] */ // Open a third transport from client02 to the router // -> This should be rejected - dbg!("Transport Authenticator PubKey [41]"); + println!("Transport Authenticator PubKey [41]"); let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator PubKey [4c2]: {res:?}"); + println!("Transport Authenticator PubKey [4c2]: {res:?}"); assert!(res.is_err()); assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); /* [4d] */ // Close the session - dbg!("Transport Authenticator PubKey [4d1]"); + println!("Transport Authenticator PubKey [4d1]"); let res = ztimeout!(c_ses1_spoof.close()); - dbg!("Transport Authenticator PubKey [4d2]: {res:?}"); + println!("Transport Authenticator PubKey [4d2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -440,9 +440,9 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [5a] */ // Open a first transport from client01 to the router // -> This should be accepted - dbg!("Transport Authenticator PubKey [5a1]"); + println!("Transport Authenticator PubKey [5a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator PubKey [5a2]: {res:?}"); + println!("Transport Authenticator PubKey [5a2]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); assert_eq!(c_ses1.get_links().unwrap().len(), 1); @@ -450,26 +450,26 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [5b] */ // Open a spoof transport from client01_spoof to the router // -> This should be rejected. Spoofing detected. - dbg!("Transport Authenticator PubKey [5b1]"); + println!("Transport Authenticator PubKey [5b1]"); let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator PubKey [5b2]: {res:?}"); + println!("Transport Authenticator PubKey [5b2]: {res:?}"); assert!(res.is_err()); /* [5c] */ // Open a second transport from client01 to the router // -> This should be accepted - dbg!("Transport Authenticator PubKey [5a1]"); + println!("Transport Authenticator PubKey [5a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator PubKey [5a2]: {res:?}"); + println!("Transport Authenticator PubKey [5a2]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); assert_eq!(c_ses1.get_links().unwrap().len(), 2); /* [5d] */ // Close the session - dbg!("Transport Authenticator PubKey [5d1]"); + println!("Transport Authenticator PubKey [5d1]"); let res = ztimeout!(c_ses1.close()); - dbg!("Transport Authenticator PubKey [5d2]: {res:?}"); + println!("Transport Authenticator PubKey [5d2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -480,9 +480,9 @@ async fn authenticator_multilink(endpoint: &EndPoint) { /* [6] */ // Perform clean up of the open locators - dbg!("Transport Authenticator UserPassword [6a1]"); + println!("Transport Authenticator UserPassword [6a1]"); let res = ztimeout!(router_manager.del_listener(endpoint)); - dbg!("Transport Authenticator UserPassword [6a2]: {res:?}"); + println!("Transport Authenticator UserPassword [6a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -581,29 +581,29 @@ async fn authenticator_user_password(endpoint: &EndPoint) { .unwrap(); /* [1] */ - dbg!("\nTransport Authenticator UserPassword [1a1]"); + println!("\nTransport Authenticator UserPassword [1a1]"); // Add the locator on the router let res = ztimeout!(router_manager.add_listener(endpoint.clone())); - dbg!("Transport Authenticator UserPassword [1a1]: {res:?}"); + println!("Transport Authenticator UserPassword [1a1]: {res:?}"); assert!(res.is_ok()); - dbg!("Transport Authenticator UserPassword [1a2]"); + println!("Transport Authenticator UserPassword [1a2]"); let locators = router_manager.get_listeners(); - dbg!("Transport Authenticator UserPassword [1a2]: {locators:?}"); + println!("Transport Authenticator UserPassword [1a2]: {locators:?}"); assert_eq!(locators.len(), 1); /* [2] */ // Open a first transport from the client to the router // -> This should be accepted - dbg!("Transport Authenticator UserPassword [2a1]"); + println!("Transport Authenticator UserPassword [2a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator UserPassword [2a1]: {res:?}"); + println!("Transport Authenticator UserPassword [2a1]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); /* [3] */ - dbg!("Transport Authenticator UserPassword [3a1]"); + println!("Transport Authenticator UserPassword [3a1]"); let res = ztimeout!(c_ses1.close()); - dbg!("Transport Authenticator UserPassword [3a1]: {res:?}"); + println!("Transport Authenticator UserPassword [3a1]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -615,17 +615,17 @@ async fn authenticator_user_password(endpoint: &EndPoint) { /* [4] */ // Open a second transport from the client to the router // -> This should be rejected - dbg!("Transport Authenticator UserPassword [4a1]"); + println!("Transport Authenticator UserPassword [4a1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator UserPassword [4a1]: {res:?}"); + println!("Transport Authenticator UserPassword [4a1]: {res:?}"); assert!(res.is_err()); /* [5] */ // Open a third transport from the client to the router // -> This should be accepted - dbg!("Transport Authenticator UserPassword [5a1]"); + println!("Transport Authenticator UserPassword [5a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator UserPassword [5a1]: {res:?}"); + println!("Transport Authenticator UserPassword [5a1]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); @@ -635,28 +635,28 @@ async fn authenticator_user_password(endpoint: &EndPoint) { assert!(res.is_ok()); // Open a fourth transport from the client to the router // -> This should be accepted - dbg!("Transport Authenticator UserPassword [6a1]"); + println!("Transport Authenticator UserPassword [6a1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator UserPassword [6a1]: {res:?}"); + println!("Transport Authenticator UserPassword [6a1]: {res:?}"); assert!(res.is_ok()); let c_ses2 = res.unwrap(); /* [7] */ // Open a fourth transport from the client to the router // -> This should be rejected - dbg!("Transport Authenticator UserPassword [7a1]"); + println!("Transport Authenticator UserPassword [7a1]"); let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator UserPassword [7a1]: {res:?}"); + println!("Transport Authenticator UserPassword [7a1]: {res:?}"); assert!(res.is_err()); /* [8] */ - dbg!("Transport Authenticator UserPassword [8a1]"); + println!("Transport Authenticator UserPassword [8a1]"); let res = ztimeout!(c_ses1.close()); - dbg!("Transport Authenticator UserPassword [8a1]: {res:?}"); + println!("Transport Authenticator UserPassword [8a1]: {res:?}"); assert!(res.is_ok()); - dbg!("Transport Authenticator UserPassword [8a2]"); + println!("Transport Authenticator UserPassword [8a2]"); let res = ztimeout!(c_ses2.close()); - dbg!("Transport Authenticator UserPassword [8a2]: {res:?}"); + println!("Transport Authenticator UserPassword [8a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -667,9 +667,9 @@ async fn authenticator_user_password(endpoint: &EndPoint) { /* [9] */ // Perform clean up of the open locators - dbg!("Transport Authenticator UserPassword [9a1]"); + println!("Transport Authenticator UserPassword [9a1]"); let res = ztimeout!(router_manager.del_listener(endpoint)); - dbg!("Transport Authenticator UserPassword [9a2]: {res:?}"); + println!("Transport Authenticator UserPassword [9a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -716,30 +716,30 @@ async fn authenticator_shared_memory(endpoint: &EndPoint) { .unwrap(); /* [1] */ - dbg!("\nTransport Authenticator SharedMemory [1a1]"); + println!("\nTransport Authenticator SharedMemory [1a1]"); // Add the locator on the router let res = ztimeout!(router_manager.add_listener(endpoint.clone())); - dbg!("Transport Authenticator SharedMemory [1a1]: {res:?}"); + println!("Transport Authenticator SharedMemory [1a1]: {res:?}"); assert!(res.is_ok()); - dbg!("Transport Authenticator SharedMemory [1a2]"); + println!("Transport Authenticator SharedMemory [1a2]"); let locators = router_manager.get_listeners(); - dbg!("Transport Authenticator SharedMemory 1a2]: {locators:?}"); + println!("Transport Authenticator SharedMemory 1a2]: {locators:?}"); assert_eq!(locators.len(), 1); /* [2] */ // Open a transport from the client to the router // -> This should be accepted - dbg!("Transport Authenticator SharedMemory [2a1]"); + println!("Transport Authenticator SharedMemory [2a1]"); let res = ztimeout!(client_manager.open_transport(endpoint.clone())); - dbg!("Transport Authenticator SharedMemory [2a1]: {res:?}"); + println!("Transport Authenticator SharedMemory [2a1]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); assert!(c_ses1.is_shm().unwrap()); /* [3] */ - dbg!("Transport Authenticator SharedMemory [3a1]"); + println!("Transport Authenticator SharedMemory [3a1]"); let res = ztimeout!(c_ses1.close()); - dbg!("Transport Authenticator SharedMemory [3a1]: {res:?}"); + println!("Transport Authenticator SharedMemory [3a1]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { @@ -750,9 +750,9 @@ async fn authenticator_shared_memory(endpoint: &EndPoint) { /* [4] */ // Perform clean up of the open locators - dbg!("Transport Authenticator SharedMemory [4a1]"); + println!("Transport Authenticator SharedMemory [4a1]"); let res = ztimeout!(router_manager.del_listener(endpoint)); - dbg!("Transport Authenticator SharedMemory [4a2]: {res:?}"); + println!("Transport Authenticator SharedMemory [4a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index b86a06be09..aaf3baabb9 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -138,11 +138,11 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Adding endpoint {e:?}: {res:?}"); + println!("[Transport Peer 01a] => Adding endpoint {e:?}: {res:?}"); assert!(res.is_ok()); } let locs = peer01_manager.get_listeners(); - dbg!("[Transport Peer 01b] => Getting endpoints: {c_end01:?} {locs:?}"); + println!("[Transport Peer 01b] => Getting endpoints: {c_end01:?} {locs:?}"); assert_eq!(c_end01.len(), locs.len()); // Open the transport with the second peer @@ -152,11 +152,11 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting for opening transport"); + println!("[Transport Peer 01c] => Waiting for opening transport"); // Syncrhonize before opening the transports ztimeout!(cc_barow.wait()); let res = ztimeout!(c_p01m.open_transport(c_end.clone())); - dbg!("[Transport Peer 01d] => Opening transport with {c_end:?}: {res:?}"); + println!("[Transport Peer 01d] => Opening transport with {c_end:?}: {res:?}"); assert!(res.is_ok()); // Syncrhonize after opening the transports @@ -166,7 +166,7 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting... OK"); + println!("[Transport Peer 01e] => Waiting... OK"); // Verify that the transport has been correctly open assert_eq!(peer01_manager.get_transports().len(), 1); @@ -200,13 +200,13 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting... OK"); + println!("[Transport Peer 01f] => Waiting... OK"); for i in 0..MSG_COUNT { - dbg!("[Transport Peer 01g] Scheduling message {}", i); + println!("[Transport Peer 01g] Scheduling message {}", i); s02.schedule(message.clone()).unwrap(); } - dbg!("[Transport Peer 01g] => Scheduling OK"); + println!("[Transport Peer 01g] => Scheduling OK"); // Wait for the messages to arrive to the other side ztimeout!(async { @@ -218,9 +218,9 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Closing {s02:?}..."); + println!("[Transport Peer 01h] => Closing {s02:?}..."); let res = ztimeout!(s02.close()); - dbg!("[Transport Peer 01l] => Closing {s02:?}: {res:?}"); + println!("[Transport Peer 01l] => Closing {s02:?}: {res:?}"); assert!(res.is_ok()); // Close the transport @@ -238,11 +238,11 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Adding endpoint {e:?}: {res:?}"); + println!("[Transport Peer 02a] => Adding endpoint {e:?}: {res:?}"); assert!(res.is_ok()); } let locs = peer02_manager.get_listeners(); - dbg!("[Transport Peer 02b] => Getting endpoints: {c_end02:?} {locs:?}"); + println!("[Transport Peer 02b] => Getting endpoints: {c_end02:?} {locs:?}"); assert_eq!(c_end02.len(), locs.len()); // Open the transport with the first peer @@ -252,12 +252,12 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting for opening transport"); + println!("[Transport Peer 02c] => Waiting for opening transport"); // Syncrhonize before opening the transports ztimeout!(cc_barow.wait()); let res = ztimeout!(c_p02m.open_transport(c_end.clone())); - dbg!("[Transport Peer 02d] => Opening transport with {c_end:?}: {res:?}"); + println!("[Transport Peer 02d] => Opening transport with {c_end:?}: {res:?}"); assert!(res.is_ok()); // Syncrhonize after opening the transports @@ -269,7 +269,7 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Transports: {:?}", peer02_manager.get_transports() ); @@ -304,13 +304,13 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting... OK"); + println!("[Transport Peer 02f] => Waiting... OK"); for i in 0..MSG_COUNT { - dbg!("[Transport Peer 02g] Scheduling message {}", i); + println!("[Transport Peer 02g] Scheduling message {}", i); s01.schedule(message.clone()).unwrap(); } - dbg!("[Transport Peer 02g] => Scheduling OK"); + println!("[Transport Peer 02g] => Scheduling OK"); // Wait for the messages to arrive to the other side ztimeout!(async { @@ -322,18 +322,18 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Closing {s01:?}..."); + println!("[Transport Peer 02h] => Closing {s01:?}..."); let res = ztimeout!(s01.close()); - dbg!("[Transport Peer 02l] => Closing {s01:?}: {res:?}"); + println!("[Transport Peer 02l] => Closing {s01:?}: {res:?}"); assert!(res.is_ok()); // Close the transport ztimeout!(peer02_manager.close()); }); - dbg!("[Transport Current 01] => Starting..."); + println!("[Transport Current 01] => Starting..."); peer01_task.join(peer02_task).await; - dbg!("[Transport Current 02] => ...Stopped"); + println!("[Transport Current 02] => ...Stopped"); // Wait a little bit task::sleep(SLEEP).await; diff --git a/io/zenoh-transport/tests/unicast_conduits.rs b/io/zenoh-transport/tests/unicast_conduits.rs index 0e0afc5787..52f7e6f051 100644 --- a/io/zenoh-transport/tests/unicast_conduits.rs +++ b/io/zenoh-transport/tests/unicast_conduits.rs @@ -188,14 +188,14 @@ async fn open_transport( // Create the listener on the router for e in endpoints.iter() { - dbg!("Add locator: {e}"); + println!("Add locator: {e}"); let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); } // Create an empty transport with the client // Open transport -> This should be accepted for e in endpoints.iter() { - dbg!("Opening transport with {e}"); + println!("Opening transport with {e}"); let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); } @@ -221,7 +221,7 @@ async fn close_transport( for e in endpoints.iter() { let _ = write!(ee, "{e} "); } - dbg!("Closing transport with {ee}"); + println!("Closing transport with {ee}"); ztimeout!(client_transport.close()).unwrap(); ztimeout!(async { @@ -232,7 +232,7 @@ async fn close_transport( // Stop the locators on the manager for e in endpoints.iter() { - dbg!("Del locator: {e}"); + println!("Del locator: {e}"); ztimeout!(router_manager.del_listener(e)).unwrap(); } @@ -268,7 +268,7 @@ async fn single_run( reply_context, ); - dbg!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); + println!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); for _ in 0..MSG_COUNT { client_transport.schedule(message.clone()).unwrap(); } diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index 8a46d347b6..b081954ed4 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -55,12 +55,12 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { .unwrap(); // Create the listener on the router - dbg!("Add locator: {endpoint}"); + println!("Add locator: {endpoint}"); let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); // Create an empty transport with the client // Open transport -> This should be accepted - dbg!("Opening transport with {endpoint}"); + println!("Opening transport with {endpoint}"); let _ = ztimeout!(client_manager.open_transport(endpoint.clone())).unwrap(); let client_transport = client_manager.get_transport(&router_id).unwrap(); @@ -81,7 +81,7 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { reply_context, ); - dbg!( + println!( "Sending message of {msg_size} bytes while defragmentation buffer size is {MSG_DEFRAG_BUF} bytes" ); client_transport.schedule(message.clone()).unwrap(); @@ -95,18 +95,18 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { // Wait on the router manager that the transport has been closed ztimeout!(async { - while !router_manager.get_transports_unicast().is_empty() { + while !router_manager.get_transports_unicast().await.is_empty() { task::sleep(SLEEP).await; } }); // Stop the locators on the manager - dbg!("Del locator: {endpoint}"); + println!("Del locator: {endpoint}"); ztimeout!(router_manager.del_listener(endpoint)).unwrap(); // Wait a little bit ztimeout!(async { - while !router_manager.get_listeners().is_empty() { + while !router_manager.get_listeners_unicast().await.is_empty() { task::sleep(SLEEP).await; } }); diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index c343e86027..7fa1a6569c 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -177,10 +177,10 @@ async fn transport_intermittent(endpoint: &EndPoint) { /* [1] */ // Add a listener to the router - dbg!("\nTransport Intermittent [1a1]"); + println!("\nTransport Intermittent [1a1]"); let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); let locators = router_manager.get_listeners(); - dbg!("Transport Intermittent [1a2]: {locators:?}"); + println!("Transport Intermittent [1a2]: {locators:?}"); assert_eq!(locators.len(), 1); /* [2] */ @@ -241,7 +241,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { }); /* [4] */ - dbg!("Transport Intermittent [4a1]"); + println!("Transport Intermittent [4a1]"); let c_router_manager = router_manager.clone(); ztimeout!(task::spawn_blocking(move || { // Create the message to send @@ -272,7 +272,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { let mut count = 0; while count < MSG_COUNT { if count == ticks[0] { - dbg!("\nScheduled {count}"); + println!("\nScheduled {count}"); ticks.remove(0); } let transports = c_router_manager.get_transports(); @@ -304,36 +304,36 @@ async fn transport_intermittent(endpoint: &EndPoint) { ztimeout!(c3_handle.cancel()); // Check that client01 received all the messages - dbg!("Transport Intermittent [4b1]"); + println!("Transport Intermittent [4b1]"); ztimeout!(async { loop { let c = counter.load(Ordering::Acquire); if c == MSG_COUNT { break; } - dbg!("Transport Intermittent [4b2]: Received {c}/{MSG_COUNT}"); + println!("Transport Intermittent [4b2]: Received {c}/{MSG_COUNT}"); task::sleep(SLEEP).await; } }); /* [5] */ // Close the open transport on the client - dbg!("Transport Intermittent [5a1]"); + println!("Transport Intermittent [5a1]"); for s in client01_manager.get_transports().iter() { ztimeout!(s.close()).unwrap(); } - dbg!("Transport Intermittent [5a2]"); + println!("Transport Intermittent [5a2]"); for s in client02_manager.get_transports().iter() { ztimeout!(s.close()).unwrap(); } - dbg!("Transport Intermittent [5a3]"); + println!("Transport Intermittent [5a3]"); for s in client03_manager.get_transports().iter() { ztimeout!(s.close()).unwrap(); } /* [6] */ // Verify that the transport has been closed also on the router - dbg!("Transport Intermittent [6a1]"); + println!("Transport Intermittent [6a1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -346,7 +346,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { /* [7] */ // Perform clean up of the open locators - dbg!("\nTransport Intermittent [7a1]"); + println!("\nTransport Intermittent [7a1]"); ztimeout!(router_manager.del_listener(endpoint)).unwrap(); // Wait a little bit diff --git a/io/zenoh-transport/tests/unicast_openclose.rs b/io/zenoh-transport/tests/unicast_openclose.rs index b27616b5d7..0d3494e8bf 100644 --- a/io/zenoh-transport/tests/unicast_openclose.rs +++ b/io/zenoh-transport/tests/unicast_openclose.rs @@ -107,37 +107,37 @@ async fn openclose_transport(endpoint: &EndPoint) { .unwrap(); /* [1] */ - dbg!("\nTransport Open Close [1a1]"); + println!("\nTransport Open Close [1a1]"); // Add the locator on the router let res = ztimeout!(router_manager.add_listener(endpoint.clone())); - dbg!("Transport Open Close [1a1]: {res:?}"); + println!("Transport Open Close [1a1]: {res:?}"); assert!(res.is_ok()); - dbg!("Transport Open Close [1a2]"); + println!("Transport Open Close [1a2]"); let locators = router_manager.get_listeners(); - dbg!("Transport Open Close [1a2]: {locators:?}"); + println!("Transport Open Close [1a2]: {locators:?}"); assert_eq!(locators.len(), 1); // Open a first transport from the client to the router // -> This should be accepted let mut links_num = 1; - dbg!("Transport Open Close [1c1]"); + println!("Transport Open Close [1c1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - dbg!("Transport Open Close [1c2]: {res:?}"); + println!("Transport Open Close [1c2]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); - dbg!("Transport Open Close [1d1]"); + println!("Transport Open Close [1d1]"); let transports = client01_manager.get_transports(); - dbg!("Transport Open Close [1d2]: {transports:?}"); + println!("Transport Open Close [1d2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); - dbg!("Transport Open Close [1e1]"); + println!("Transport Open Close [1e1]"); let links = c_ses1.get_links().unwrap(); - dbg!("Transport Open Close [1e2]: {links:?}"); + println!("Transport Open Close [1e2]: {links:?}"); assert_eq!(links.len(), links_num); // Verify that the transport has been open on the router - dbg!("Transport Open Close [1f1]"); + println!("Transport Open Close [1f1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -161,24 +161,24 @@ async fn openclose_transport(endpoint: &EndPoint) { // -> This should be accepted links_num = 2; - dbg!("\nTransport Open Close [2a1]"); + println!("\nTransport Open Close [2a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - dbg!("Transport Open Close [2a2]: {res:?}"); + println!("Transport Open Close [2a2]: {res:?}"); assert!(res.is_ok()); let c_ses2 = res.unwrap(); - dbg!("Transport Open Close [2b1]"); + println!("Transport Open Close [2b1]"); let transports = client01_manager.get_transports(); - dbg!("Transport Open Close [2b2]: {transports:?}"); + println!("Transport Open Close [2b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses2.get_zid().unwrap(), router_id); - dbg!("Transport Open Close [2c1]"); + println!("Transport Open Close [2c1]"); let links = c_ses2.get_links().unwrap(); - dbg!("Transport Open Close [2c2]: {links:?}"); + println!("Transport Open Close [2c2]: {links:?}"); assert_eq!(links.len(), links_num); assert_eq!(c_ses2, c_ses1); // Verify that the transport has been open on the router - dbg!("Transport Open Close [2d1]"); + println!("Transport Open Close [2d1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -198,22 +198,22 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [3] */ // Open transport -> This should be rejected because // of the maximum limit of links per transport - dbg!("\nTransport Open Close [3a1]"); + println!("\nTransport Open Close [3a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - dbg!("Transport Open Close [3a2]: {res:?}"); + println!("Transport Open Close [3a2]: {res:?}"); assert!(res.is_err()); - dbg!("Transport Open Close [3b1]"); + println!("Transport Open Close [3b1]"); let transports = client01_manager.get_transports(); - dbg!("Transport Open Close [3b2]: {transports:?}"); + println!("Transport Open Close [3b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); - dbg!("Transport Open Close [3c1]"); + println!("Transport Open Close [3c1]"); let links = c_ses1.get_links().unwrap(); - dbg!("Transport Open Close [3c2]: {links:?}"); + println!("Transport Open Close [3c2]: {links:?}"); assert_eq!(links.len(), links_num); // Verify that the transport has not been open on the router - dbg!("Transport Open Close [3d1]"); + println!("Transport Open Close [3d1]"); ztimeout!(async { task::sleep(SLEEP).await; let transports = router_manager.get_transports(); @@ -228,17 +228,17 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [4] */ // Close the open transport on the client - dbg!("\nTransport Open Close [4a1]"); + println!("\nTransport Open Close [4a1]"); let res = ztimeout!(c_ses1.close()); - dbg!("Transport Open Close [4a2]: {res:?}"); + println!("Transport Open Close [4a2]: {res:?}"); assert!(res.is_ok()); - dbg!("Transport Open Close [4b1]"); + println!("Transport Open Close [4b1]"); let transports = client01_manager.get_transports(); - dbg!("Transport Open Close [4b2]: {transports:?}"); + println!("Transport Open Close [4b2]: {transports:?}"); assert_eq!(transports.len(), 0); // Verify that the transport has been closed also on the router - dbg!("Transport Open Close [4c1]"); + println!("Transport Open Close [4c1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -257,23 +257,23 @@ async fn openclose_transport(endpoint: &EndPoint) { // the number of links should be back to 0 links_num = 1; - dbg!("\nTransport Open Close [5a1]"); + println!("\nTransport Open Close [5a1]"); let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - dbg!("Transport Open Close [5a2]: {res:?}"); + println!("Transport Open Close [5a2]: {res:?}"); assert!(res.is_ok()); let c_ses3 = res.unwrap(); - dbg!("Transport Open Close [5b1]"); + println!("Transport Open Close [5b1]"); let transports = client01_manager.get_transports(); - dbg!("Transport Open Close [5b2]: {transports:?}"); + println!("Transport Open Close [5b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses3.get_zid().unwrap(), router_id); - dbg!("Transport Open Close [5c1]"); + println!("Transport Open Close [5c1]"); let links = c_ses3.get_links().unwrap(); - dbg!("Transport Open Close [5c2]: {links:?}"); + println!("Transport Open Close [5c2]: {links:?}"); assert_eq!(links.len(), links_num); // Verify that the transport has been open on the router - dbg!("Transport Open Close [5d1]"); + println!("Transport Open Close [5d1]"); ztimeout!(async { task::sleep(SLEEP).await; let transports = router_manager.get_transports(); @@ -289,17 +289,17 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [6] */ // Open transport -> This should be rejected because // of the maximum limit of transports - dbg!("\nTransport Open Close [6a1]"); + println!("\nTransport Open Close [6a1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - dbg!("Transport Open Close [6a2]: {res:?}"); + println!("Transport Open Close [6a2]: {res:?}"); assert!(res.is_err()); - dbg!("Transport Open Close [6b1]"); + println!("Transport Open Close [6b1]"); let transports = client02_manager.get_transports(); - dbg!("Transport Open Close [6b2]: {transports:?}"); + println!("Transport Open Close [6b2]: {transports:?}"); assert_eq!(transports.len(), 0); // Verify that the transport has not been open on the router - dbg!("Transport Open Close [6c1]"); + println!("Transport Open Close [6c1]"); ztimeout!(async { task::sleep(SLEEP).await; let transports = router_manager.get_transports(); @@ -314,17 +314,17 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [7] */ // Close the open transport on the client - dbg!("\nTransport Open Close [7a1]"); + println!("\nTransport Open Close [7a1]"); let res = ztimeout!(c_ses3.close()); - dbg!("Transport Open Close [7a2]: {res:?}"); + println!("Transport Open Close [7a2]: {res:?}"); assert!(res.is_ok()); - dbg!("Transport Open Close [7b1]"); + println!("Transport Open Close [7b1]"); let transports = client01_manager.get_transports(); - dbg!("Transport Open Close [7b2]: {transports:?}"); + println!("Transport Open Close [7b2]: {transports:?}"); assert_eq!(transports.len(), 0); // Verify that the transport has been closed also on the router - dbg!("Transport Open Close [7c1]"); + println!("Transport Open Close [7c1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -340,22 +340,22 @@ async fn openclose_transport(endpoint: &EndPoint) { // the number of transports should be back to 0 links_num = 1; - dbg!("\nTransport Open Close [8a1]"); + println!("\nTransport Open Close [8a1]"); let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - dbg!("Transport Open Close [8a2]: {res:?}"); + println!("Transport Open Close [8a2]: {res:?}"); assert!(res.is_ok()); let c_ses4 = res.unwrap(); - dbg!("Transport Open Close [8b1]"); + println!("Transport Open Close [8b1]"); let transports = client02_manager.get_transports(); - dbg!("Transport Open Close [8b2]: {transports:?}"); + println!("Transport Open Close [8b2]: {transports:?}"); assert_eq!(transports.len(), 1); - dbg!("Transport Open Close [8c1]"); + println!("Transport Open Close [8c1]"); let links = c_ses4.get_links().unwrap(); - dbg!("Transport Open Close [8c2]: {links:?}"); + println!("Transport Open Close [8c2]: {links:?}"); assert_eq!(links.len(), links_num); // Verify that the transport has been open on the router - dbg!("Transport Open Close [8d1]"); + println!("Transport Open Close [8d1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -375,17 +375,17 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [9] */ // Close the open transport on the client - dbg!("Transport Open Close [9a1]"); + println!("Transport Open Close [9a1]"); let res = ztimeout!(c_ses4.close()); - dbg!("Transport Open Close [9a2]: {res:?}"); + println!("Transport Open Close [9a2]: {res:?}"); assert!(res.is_ok()); - dbg!("Transport Open Close [9b1]"); + println!("Transport Open Close [9b1]"); let transports = client02_manager.get_transports(); - dbg!("Transport Open Close [9b2]: {transports:?}"); + println!("Transport Open Close [9b2]: {transports:?}"); assert_eq!(transports.len(), 0); // Verify that the transport has been closed also on the router - dbg!("Transport Open Close [9c1]"); + println!("Transport Open Close [9c1]"); ztimeout!(async { loop { let transports = router_manager.get_transports(); @@ -398,9 +398,9 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [10] */ // Perform clean up of the open locators - dbg!("\nTransport Open Close [10a1]"); + println!("\nTransport Open Close [10a1]"); let res = ztimeout!(router_manager.del_listener(endpoint)); - dbg!("Transport Open Close [10a2]: {res:?}"); + println!("Transport Open Close [10a2]: {res:?}"); assert!(res.is_ok()); ztimeout!(async { diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index e0f78d70eb..8bd52a3596 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -92,11 +92,11 @@ mod tests { reply_context, ); - dbg!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); + println!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); for _ in 0..MSG_COUNT { transport.handle_message(message.clone()).unwrap(); } - dbg!("[Simultaneous {}] ... sent {}", self.zid, MSG_COUNT); + println!("[Simultaneous {}] ... sent {}", self.zid, MSG_COUNT); let mh = Arc::new(MHPeer::new(self.count.clone())); Ok(mh) @@ -157,21 +157,21 @@ mod tests { // Add the endpoints on the peer01 for e in endpoint01.iter() { let res = ztimeout!(peer01_manager.add_listener(e.clone())); - dbg!("[Simultaneous 01a] => Adding endpoint {e:?}: {res:?}"); + println!("[Simultaneous 01a] => Adding endpoint {e:?}: {res:?}"); assert!(res.is_ok()); } let locs = peer01_manager.get_listeners(); - dbg!("[Simultaneous 01b] => Getting endpoints: {endpoint01:?} {locs:?}"); + println!("[Simultaneous 01b] => Getting endpoints: {endpoint01:?} {locs:?}"); assert_eq!(endpoint01.len(), locs.len()); // Add the endpoints on peer02 for e in endpoint02.iter() { let res = ztimeout!(peer02_manager.add_listener(e.clone())); - dbg!("[Simultaneous 02a] => Adding endpoint {e:?}: {res:?}"); + println!("[Simultaneous 02a] => Adding endpoint {e:?}: {res:?}"); assert!(res.is_ok()); } let locs = peer02_manager.get_listeners(); - dbg!("[Simultaneous 02b] => Getting endpoints: {endpoint02:?} {locs:?}"); + println!("[Simultaneous 02b] => Getting endpoints: {endpoint02:?} {locs:?}"); assert_eq!(endpoint02.len(), locs.len()); // Endpoints @@ -184,13 +184,13 @@ mod tests { // Open the transport with the second peer // These open should succeed for e in c_ep02.iter() { - dbg!("[Simultaneous 01c] => Opening transport with {e:?}..."); + println!("[Simultaneous 01c] => Opening transport with {e:?}..."); let _ = ztimeout!(c_p01m.open_transport(e.clone())).unwrap(); } // These open should fails for e in c_ep02.iter() { - dbg!("[Simultaneous 01d] => Exceeding transport with {e:?}..."); + println!("[Simultaneous 01d] => Exceeding transport with {e:?}..."); let res = ztimeout!(c_p01m.open_transport(e.clone())); assert!(res.is_err()); } @@ -201,7 +201,7 @@ mod tests { let mut tp02 = None; while tp02.is_none() { task::sleep(SLEEP).await; - dbg!( + println!( "[Simultaneous 01e] => Transports: {:?}", peer01_manager.get_transports() ); @@ -218,7 +218,7 @@ mod tests { while tl02.len() != expected { task::sleep(SLEEP).await; tl02 = tp02.get_links().unwrap(); - dbg!("[Simultaneous 01f] => Links {}/{}", tl02.len(), expected); + println!("[Simultaneous 01f] => Links {}/{}", tl02.len(), expected); } }); @@ -228,7 +228,7 @@ mod tests { while check != MSG_COUNT { task::sleep(SLEEP).await; check = peer_sh01.get_count(); - dbg!("[Simultaneous 01g] => Received {check:?}/{MSG_COUNT:?}"); + println!("[Simultaneous 01g] => Received {check:?}/{MSG_COUNT:?}"); } }); }); @@ -239,13 +239,13 @@ mod tests { // Open the transport with the first peer // These open should succeed for e in c_ep01.iter() { - dbg!("[Simultaneous 02c] => Opening transport with {e:?}..."); + println!("[Simultaneous 02c] => Opening transport with {e:?}..."); let _ = ztimeout!(c_p02m.open_transport(e.clone())).unwrap(); } // These open should fails for e in c_ep01.iter() { - dbg!("[Simultaneous 02d] => Exceeding transport with {e:?}..."); + println!("[Simultaneous 02d] => Exceeding transport with {e:?}..."); let res = ztimeout!(c_p02m.open_transport(e.clone())); assert!(res.is_err()); } @@ -257,7 +257,7 @@ mod tests { let mut tp01 = None; while tp01.is_none() { task::sleep(SLEEP).await; - dbg!( + println!( "[Simultaneous 02e] => Transports: {:?}", peer02_manager.get_transports() ); @@ -273,7 +273,7 @@ mod tests { while tl01.len() != expected { task::sleep(SLEEP).await; tl01 = tp01.get_links().unwrap(); - dbg!("[Simultaneous 02f] => Links {}/{}", tl01.len(), expected); + println!("[Simultaneous 02f] => Links {}/{}", tl01.len(), expected); } }); @@ -283,14 +283,14 @@ mod tests { while check != MSG_COUNT { task::sleep(SLEEP).await; check = peer_sh02.get_count(); - dbg!("[Simultaneous 02g] => Received {check:?}/{MSG_COUNT:?}"); + println!("[Simultaneous 02g] => Received {check:?}/{MSG_COUNT:?}"); } }); }); - dbg!("[Simultaneous] => Waiting for peer01 and peer02 tasks..."); + println!("[Simultaneous] => Waiting for peer01 and peer02 tasks..."); peer01_task.join(peer02_task).await; - dbg!("[Simultaneous] => Waiting for peer01 and peer02 tasks... DONE\n"); + println!("[Simultaneous] => Waiting for peer01 and peer02 tasks... DONE\n"); // Wait a little bit task::sleep(SLEEP).await; diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index da8eddd96f..20e59ac8a0 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -337,7 +337,7 @@ async fn open_transport( // Create the listener on the router for e in server_endpoints.iter() { - dbg!("Add endpoint: {e}"); + println!("Add endpoint: {}", e); let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); } @@ -353,7 +353,7 @@ async fn open_transport( // Create an empty transport with the client // Open transport -> This should be accepted for e in client_endpoints.iter() { - dbg!("Opening transport with {e}"); + println!("Opening transport with {}", e); let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); } @@ -379,7 +379,7 @@ async fn close_transport( for e in endpoints.iter() { let _ = write!(ee, "{e} "); } - dbg!("Closing transport with {ee}"); + println!("Closing transport with {}", ee); ztimeout!(client_transport.close()).unwrap(); ztimeout!(async { @@ -390,7 +390,7 @@ async fn close_transport( // Stop the locators on the manager for e in endpoints.iter() { - dbg!("Del locator: {e}"); + println!("Del locator: {}", e); ztimeout!(router_manager.del_listener(e)).unwrap(); } @@ -432,7 +432,10 @@ async fn test_transport( reply_context, ); - dbg!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); + println!( + "Sending {} messages... {:?} {}", + MSG_COUNT, channel, msg_size + ); for _ in 0..MSG_COUNT { client_transport.schedule(message.clone()).unwrap(); } @@ -464,12 +467,9 @@ async fn run_single( channel: Channel, msg_size: usize, ) { - dbg!( + println!( "\n>>> Running test for: {:?}, {:?}, {:?}, {}", - client_endpoints, - server_endpoints, - channel, - msg_size + client_endpoints, server_endpoints, channel, msg_size ); #[allow(unused_variables)] // Used when stats feature is enabled @@ -487,13 +487,13 @@ async fn run_single( #[cfg(feature = "stats")] { let c_stats = client_transport.get_stats().unwrap(); - dbg!("\tClient: {c_stats:?}"); + println!("\tClient: {:?}", c_stats); let r_stats = router_manager .get_transport_unicast(&client_manager.config.zid) .unwrap() .get_stats() .unwrap(); - dbg!("\tRouter: {r_stats:?}"); + println!("\tRouter: {:?}", r_stats); } close_transport( From ffe9942b407f47d9062893f3c1e0206a1e83f4fb Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 1 Mar 2023 19:06:40 +0100 Subject: [PATCH 045/203] QoS extension --- .../src/unicast/establishment/accept.rs | 102 +++- .../establishment/authenticator/shm.rs | 446 -------------- .../{ => ext}/authenticator/mod.rs | 94 ++- .../{ => ext}/authenticator/pubkey.rs | 40 +- .../{ => ext}/authenticator/userpassword.rs | 46 +- .../src/unicast/establishment/ext/mod.rs | 18 + .../src/unicast/establishment/ext/qos.rs | 96 ++++ .../src/unicast/establishment/ext/shm.rs | 542 ++++++++++++++++++ .../src/unicast/establishment/mod.rs | 2 +- .../src/unicast/establishment/open.rs | 90 ++- io/zenoh-transport/src/unicast/mod.rs | 4 +- 11 files changed, 885 insertions(+), 595 deletions(-) delete mode 100644 io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs rename io/zenoh-transport/src/unicast/establishment/{ => ext}/authenticator/mod.rs (81%) rename io/zenoh-transport/src/unicast/establishment/{ => ext}/authenticator/pubkey.rs (95%) rename io/zenoh-transport/src/unicast/establishment/{ => ext}/authenticator/userpassword.rs (92%) create mode 100644 io/zenoh-transport/src/unicast/establishment/ext/mod.rs create mode 100644 io/zenoh-transport/src/unicast/establishment/ext/qos.rs create mode 100644 io/zenoh-transport/src/unicast/establishment/ext/shm.rs diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 08f8d25852..e49ee35d53 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -13,7 +13,7 @@ // use crate::{ unicast::establishment::{ - close_link, compute_sn, finalize_transport, AcceptFsm, Cookie, InputFinalize, + close_link, compute_sn, ext, finalize_transport, AcceptFsm, Cookie, InputFinalize, Zenoh080Cookie, }, TransportConfigUnicast, TransportManager, @@ -43,12 +43,14 @@ struct RecvInitSynIn { mine_version: u8, mine_resolution: Resolution, mine_batch_size: u16, + ext_qos: ext::qos::State, } struct RecvInitSynOut { other_zid: ZenohId, other_whatami: WhatAmI, agreed_resolution: Resolution, agreed_batch_size: u16, + ext_qos: ext::qos::State, } // InitAck @@ -60,6 +62,7 @@ struct SendInitAckIn { other_whatami: WhatAmI, agreed_resolution: Resolution, agreed_batch_size: u16, + ext_qos: ext::qos::State, } struct SendInitAckOut { cookie_nonce: ZInt, @@ -76,20 +79,28 @@ struct RecvOpenSynOut { other_initial_sn: ZInt, agreed_resolution: Resolution, agreed_batch_size: u16, + ext_qos: ext::qos::State, } // OpenAck struct SendOpenAckIn { + mine_zid: ZenohId, mine_lease: Duration, + other_zid: ZenohId, + agreed_resolution: Resolution, + ext_qos: ext::qos::State, +} +struct SendOpenAckOut { mine_initial_sn: ZInt, + ext_qos: ext::qos::State, } -struct SendOpenAckOut {} // Fsm struct AcceptLink<'a> { link: &'a LinkUnicast, prng: &'a Mutex, cipher: &'a BlockCipher, + ext_qos: ext::qos::QoS, } #[async_trait] @@ -147,11 +158,19 @@ impl<'a> AcceptFsm for AcceptLink<'a> { // Compute the minimum batch size let agreed_batch_size = input.mine_batch_size.min(input.mine_batch_size); + // Extension QoS + let qos_state = self + .ext_qos + .recv_init_syn((input.ext_qos, init_syn.qos)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvInitSynOut { other_whatami: init_syn.whatami, other_zid: init_syn.zid, agreed_resolution, agreed_batch_size, + ext_qos: qos_state, }; Ok(output) } @@ -159,6 +178,13 @@ impl<'a> AcceptFsm for AcceptLink<'a> { type InitAckIn = SendInitAckIn; type InitAckOut = SendInitAckOut; async fn send_init_ack(&self, input: Self::InitAckIn) -> Result { + // Extension QoS + let (qos_state, qos_mine_ext) = self + .ext_qos + .send_init_ack(input.ext_qos) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Create the cookie let cookie_nonce: ZInt = zasynclock!(self.prng).gen(); let cookie = Cookie { @@ -167,8 +193,8 @@ impl<'a> AcceptFsm for AcceptLink<'a> { resolution: input.agreed_resolution, batch_size: input.agreed_batch_size, nonce: cookie_nonce, - is_qos: false, // @TODO - // properties: EstablishmentProperties::new(), + is_qos: qos_state.is_qos, + // properties: EstablishmentProperties::new(), }; let mut encrypted = vec![]; @@ -194,7 +220,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { resolution: input.agreed_resolution, batch_size: input.agreed_batch_size, cookie, - qos: None, // @TODO + qos: qos_mine_ext, shm: None, // @TODO auth: None, // @TODO } @@ -265,6 +291,15 @@ impl<'a> AcceptFsm for AcceptLink<'a> { return Err((e.into(), Some(close::reason::INVALID))); } + // Extension QoS + let qos_state = self + .ext_qos + .recv_open_syn(ext::qos::State { + is_qos: cookie.is_qos, + }) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvOpenSynOut { other_zid: cookie.zid, other_whatami: cookie.whatami, @@ -272,6 +307,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { other_initial_sn: open_syn.initial_sn, agreed_resolution: cookie.resolution, agreed_batch_size: cookie.batch_size, + ext_qos: qos_state, }; Ok(output) } @@ -279,10 +315,18 @@ impl<'a> AcceptFsm for AcceptLink<'a> { type OpenAckIn = SendOpenAckIn; type OpenAckOut = SendOpenAckOut; async fn send_open_ack(&self, input: Self::OpenAckIn) -> Result { + // Extension QoS + let qos_state = self + .ext_qos + .send_open_ack(input.ext_qos) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Build OpenAck message + let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, input.agreed_resolution); let message: TransportMessage = OpenAck { lease: input.mine_lease, - initial_sn: input.mine_initial_sn, + initial_sn: mine_initial_sn, auth: None, // @TODO } .into(); @@ -294,16 +338,23 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = SendOpenAckOut {}; + let output = SendOpenAckOut { + mine_initial_sn, + ext_qos: qos_state, + }; Ok(output) } } pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) -> ZResult<()> { + // Extension QoS + let ext_qos = ext::qos::QoS; + let fsm = AcceptLink { link, prng: &manager.prng, cipher: &manager.cipher, + ext_qos, }; // Init handshake @@ -328,6 +379,9 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) mine_version: manager.config.version, mine_resolution: manager.config.resolution, mine_batch_size: manager.config.batch_size, + ext_qos: ext::qos::State { + is_qos: manager.config.unicast.is_qos, + }, }; let isyn_out = step!(fsm.recv_init_syn(isyn_in).await); @@ -339,6 +393,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) other_whatami: isyn_out.other_whatami, agreed_resolution: isyn_out.agreed_resolution, agreed_batch_size: isyn_out.agreed_batch_size, + ext_qos: isyn_out.ext_qos, }; step!(fsm.send_init_ack(iack_in).await) }; @@ -349,22 +404,22 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) }; let osyn_out = step!(fsm.recv_open_syn(osyn_in).await); - // Initialize the transport before sending the ack to verify that the transport is ok - - // 1) Create a random yet deterministic initial_sn. - let mine_initial_sn = compute_sn( - manager.config.zid, - osyn_out.other_zid, - osyn_out.agreed_resolution, - ); + let oack_in = SendOpenAckIn { + mine_zid: manager.config.zid, + mine_lease: manager.config.unicast.lease, + other_zid: osyn_out.other_zid, + agreed_resolution: osyn_out.agreed_resolution, + ext_qos: osyn_out.ext_qos, + }; + let oack_out = step!(fsm.send_open_ack(oack_in).await); - // 2) Initialize the transport. + // Initialize the transport let config = TransportConfigUnicast { peer: osyn_out.other_zid, whatami: osyn_out.other_whatami, sn_resolution: osyn_out.agreed_resolution.get(Field::FrameSN).mask(), - tx_initial_sn: mine_initial_sn, - is_qos: false, // @TODO + tx_initial_sn: oack_out.mine_initial_sn, + is_qos: oack_out.ext_qos.is_qos, is_shm: false, // @TODO }; let transport = step!(manager @@ -393,27 +448,20 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) }; } - // 3) Add the link to the transport + // Add the link to the transport step!(step!(transport .get_inner() .map_err(|e| (e, Some(close::reason::INVALID)))) .add_link(link.clone(), LinkUnicastDirection::Inbound) .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); - // 4) Sync the RX sequence number + // Sync the RX sequence number let _ = step!(transport .get_inner() .map_err(|e| (e, Some(close::reason::INVALID)))) .sync(osyn_out.other_initial_sn) .await; - // Send the OpenAck - let oack_in = SendOpenAckIn { - mine_lease: manager.config.unicast.lease, - mine_initial_sn, - }; - let _ = step!(fsm.send_open_ack(oack_in).await); - // Finalize the transport let input = InputFinalize { transport: transport.clone(), diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs b/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs deleted file mode 100644 index 00c844ed40..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/shm.rs +++ /dev/null @@ -1,446 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::{ - AuthenticatedPeerLink, PeerAuthenticator, PeerAuthenticatorId, PeerAuthenticatorTrait, -}; -use crate::unicast::establishment::Cookie; -use async_trait::async_trait; -use rand::{Rng, SeedableRng}; -use std::{ - convert::TryInto, - sync::{Arc, RwLock}, -}; -use zenoh_buffers::{ - reader::{DidntRead, HasReader, Reader}, - writer::{DidntWrite, HasWriter, Writer}, - ZSlice, -}; -use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_config::Config; -use zenoh_crypto::PseudoRng; -use zenoh_protocol::core::{ZInt, ZenohId}; -use zenoh_result::{bail, zerror, ShmError, ZResult}; -use zenoh_shm::{ - SharedMemoryBuf, SharedMemoryBufInfoSerialized, SharedMemoryManager, SharedMemoryReader, -}; - -const SHM_VERSION: ZInt = 0; -const SHM_NAME: &str = "shmauth"; -// Let's use a ZInt as a challenge -const SHM_SIZE: usize = std::mem::size_of::(); - -/*************************************/ -/* InitSyn */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ version ~ -/// +---------------+ -/// ~ ShmMemBuf ~ -/// +---------------+ -struct InitSynProperty { - version: ZInt, - shm: ZSlice, -} - -impl WCodec<&InitSynProperty, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &InitSynProperty) -> Self::Output { - self.write(&mut *writer, x.version)?; - self.write(&mut *writer, &x.shm)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let version: ZInt = self.read(&mut *reader)?; - let bytes: Vec = self.read(&mut *reader)?; - let shm_info: SharedMemoryBufInfoSerialized = bytes.into(); - let shm: ZSlice = shm_info.into(); - Ok(InitSynProperty { version, shm }) - } -} - -/*************************************/ -/* InitAck */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ challenge ~ -/// +---------------+ -/// ~ ShmMemBuf ~ -/// +---------------+ -struct InitAckProperty { - challenge: ZInt, - shm: ZSlice, -} - -impl WCodec<&InitAckProperty, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &InitAckProperty) -> Self::Output { - self.write(&mut *writer, x.challenge)?; - self.write(&mut *writer, &x.shm)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let challenge: ZInt = self.read(&mut *reader)?; - let bytes: Vec = self.read(&mut *reader)?; - let shm_info: SharedMemoryBufInfoSerialized = bytes.into(); - let shm: ZSlice = shm_info.into(); - Ok(InitAckProperty { challenge, shm }) - } -} - -/*************************************/ -/* OpenSyn */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ challenge ~ -/// +---------------+ -struct OpenSynProperty { - challenge: ZInt, -} - -impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &OpenSynProperty) -> Self::Output { - self.write(&mut *writer, x.challenge)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let challenge: ZInt = self.read(&mut *reader)?; - Ok(OpenSynProperty { challenge }) - } -} - -/*************************************/ -/* Authenticator */ -/*************************************/ -pub struct SharedMemoryAuthenticator { - challenge: ZInt, - // Rust guarantees that fields are dropped in the order of declaration. - // Buffer needs to be dropped before the manager. - buffer: SharedMemoryBuf, - _manager: SharedMemoryManager, - reader: Arc>, -} - -impl SharedMemoryAuthenticator { - pub fn make() -> ZResult { - let mut prng = PseudoRng::from_entropy(); - let challenge = prng.gen::(); - - let mut _manager = SharedMemoryManager::make(format!("{SHM_NAME}.{challenge}"), SHM_SIZE)?; - - let mut buffer = _manager.alloc(SHM_SIZE).unwrap(); - let slice = unsafe { buffer.as_mut_slice() }; - slice[0..SHM_SIZE].copy_from_slice(&challenge.to_le_bytes()); - - let shmauth = SharedMemoryAuthenticator { - challenge, - buffer, - _manager, - reader: Arc::new(RwLock::new(SharedMemoryReader::new())), - }; - Ok(shmauth) - } - - pub async fn from_config(config: &Config) -> ZResult> { - if *config.transport().shared_memory().enabled() { - let mut prng = PseudoRng::from_entropy(); - let challenge = prng.gen::(); - - let mut _manager = - SharedMemoryManager::make(format!("{SHM_NAME}.{challenge}"), SHM_SIZE)?; - - let mut buffer = _manager.alloc(SHM_SIZE)?; - let slice = unsafe { buffer.as_mut_slice() }; - slice[0..SHM_SIZE].copy_from_slice(&challenge.to_le_bytes()); - - let sma = SharedMemoryAuthenticator { - challenge, - buffer, - _manager, - reader: Arc::new(RwLock::new(SharedMemoryReader::new())), - }; - Ok(Some(sma)) - } else { - Ok(None) - } - } -} - -unsafe impl Send for SharedMemoryAuthenticator {} -unsafe impl Sync for SharedMemoryAuthenticator {} - -#[async_trait] -impl PeerAuthenticatorTrait for SharedMemoryAuthenticator { - fn id(&self) -> PeerAuthenticatorId { - PeerAuthenticatorId::Shm - } - - async fn close(&self) { - // No cleanup needed - } - - async fn get_init_syn_properties( - &self, - link: &AuthenticatedPeerLink, - _peer_id: &ZenohId, - ) -> ZResult>> { - let init_syn_property = InitSynProperty { - version: SHM_VERSION, - shm: self.buffer.info.serialize().unwrap().into(), - }; - let mut buff = vec![]; - let codec = Zenoh080::new(); - - let mut writer = buff.writer(); - codec - .write(&mut writer, &init_syn_property) - .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; - - Ok(Some(buff)) - } - - async fn handle_init_syn( - &self, - link: &AuthenticatedPeerLink, - cookie: &Cookie, - mut property: Option>, - ) -> ZResult<(Option>, Option>)> { - let buffer = match property.take() { - Some(p) => p, - None => { - log::debug!("Peer {} did not express interest in SHM", cookie.zid); - return Ok((None, None)); - } - }; - - let codec = Zenoh080::new(); - let mut reader = buffer.reader(); - - let mut init_syn_property: InitSynProperty = codec - .read(&mut reader) - .map_err(|_| zerror!("Received InitSyn with invalid attachment on link: {}", link))?; - - if init_syn_property.version > SHM_VERSION { - bail!("Rejected InitSyn with invalid attachment on link: {}", link) - } - - // Try to read from the shared memory - match crate::shm::map_zslice_to_shmbuf(&mut init_syn_property.shm, &self.reader) { - Ok(res) => { - if !res { - log::debug!("Peer {} can not operate over SHM: error", cookie.zid); - return Ok((None, None)); - } - } - Err(e) => { - log::debug!("Peer {} can not operate over SHM: {}", cookie.zid, e); - return Ok((None, None)); - } - } - - log::debug!("Authenticating Shared Memory Access..."); - - let xs = init_syn_property.shm; - let bytes: [u8; SHM_SIZE] = match xs.as_slice().try_into() { - Ok(bytes) => bytes, - Err(e) => { - log::debug!("Peer {} can not operate over SHM: {}", cookie.zid, e); - return Ok((None, None)); - } - }; - let challenge = ZInt::from_le_bytes(bytes); - - // Create the InitAck attachment - let init_ack_property = InitAckProperty { - challenge, - shm: self.buffer.info.serialize().unwrap().into(), - }; - // Encode the InitAck property - let mut buffer = vec![]; - let mut writer = buffer.writer(); - codec - .write(&mut writer, &init_ack_property) - .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; - - Ok((Some(buffer), None)) - } - - async fn handle_init_ack( - &self, - link: &AuthenticatedPeerLink, - peer_id: &ZenohId, - _sn_resolution: ZInt, - mut property: Option>, - ) -> ZResult>> { - let buffer = match property.take() { - Some(p) => p, - None => { - log::debug!("Peer {} did not express interest in SHM", peer_id); - return Ok(None); - } - }; - - let codec = Zenoh080::new(); - let mut reader = buffer.reader(); - - let mut init_ack_property: InitAckProperty = codec - .read(&mut reader) - .map_err(|_| zerror!("Received InitAck with invalid attachment on link: {}", link))?; - - // Try to read from the shared memory - match crate::shm::map_zslice_to_shmbuf(&mut init_ack_property.shm, &self.reader) { - Ok(res) => { - if !res { - return Err(ShmError(zerror!("No SHM on link: {}", link)).into()); - } - } - Err(e) => return Err(ShmError(zerror!("No SHM on link {}: {}", link, e)).into()), - } - - let bytes: [u8; SHM_SIZE] = init_ack_property.shm.as_slice().try_into().map_err(|e| { - zerror!( - "Received InitAck with invalid attachment on link {}: {}", - link, - e - ) - })?; - let challenge = ZInt::from_le_bytes(bytes); - - if init_ack_property.challenge == self.challenge { - // Create the OpenSyn attachment - let open_syn_property = OpenSynProperty { challenge }; - // Encode the OpenSyn property - let mut buffer = vec![]; - let mut writer = buffer.writer(); - - codec - .write(&mut writer, &open_syn_property) - .map_err(|_| zerror!("Error in encoding OpenSyn for SHM on link: {}", link))?; - - Ok(Some(buffer)) - } else { - Err(ShmError(zerror!( - "Received OpenSyn with invalid attachment on link: {}", - link - )) - .into()) - } - } - - async fn handle_open_syn( - &self, - link: &AuthenticatedPeerLink, - _cookie: &Cookie, - property: (Option>, Option>), - ) -> ZResult>> { - let (mut attachment, _cookie) = property; - let buffer = match attachment.take() { - Some(p) => p, - None => { - return Err(ShmError(zerror!( - "Received OpenSyn with no SHM attachment on link: {}", - link - )) - .into()); - } - }; - - let codec = Zenoh080::new(); - let mut reader = buffer.reader(); - - let open_syn_property: OpenSynProperty = codec - .read(&mut reader) - .map_err(|_| zerror!("Received OpenSyn with invalid attachment on link: {}", link))?; - - if open_syn_property.challenge == self.challenge { - Ok(None) - } else { - Err(ShmError(zerror!( - "Received OpenSyn with invalid attachment on link: {}", - link - )) - .into()) - } - } - - async fn handle_open_ack( - &self, - _link: &AuthenticatedPeerLink, - _property: Option>, - ) -> ZResult>> { - Ok(None) - } - - async fn handle_link_err(&self, _link: &AuthenticatedPeerLink) {} - - async fn handle_close(&self, _peer_id: &ZenohId) {} -} - -//noinspection ALL -impl From> for PeerAuthenticator { - fn from(v: Arc) -> PeerAuthenticator { - PeerAuthenticator(v) - } -} - -impl From for PeerAuthenticator { - fn from(v: SharedMemoryAuthenticator) -> PeerAuthenticator { - Self::from(Arc::new(v)) - } -} diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs similarity index 81% rename from io/zenoh-transport/src/unicast/establishment/authenticator/mod.rs rename to io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs index f0f1cc5ddb..38db8a80b4 100644 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs @@ -13,8 +13,6 @@ // #[cfg(feature = "auth_pubkey")] mod pubkey; -#[cfg(feature = "shared-memory")] -mod shm; #[cfg(feature = "auth_usrpwd")] mod userpassword; @@ -22,8 +20,6 @@ use crate::unicast::establishment::Cookie; use async_trait::async_trait; #[cfg(feature = "auth_pubkey")] pub use pubkey::*; -#[cfg(feature = "shared-memory")] -pub use shm::*; use std::collections::HashSet; use std::fmt; use std::hash::{Hash, Hasher}; @@ -122,24 +118,24 @@ impl LinkUnicastAuthenticatorTrait for DummyLinkUnicastAuthenticator { /*************************************/ #[derive(PartialEq, Eq, Hash)] #[repr(u8)] -pub enum PeerAuthenticatorId { +pub enum ZNodeAuthenticatorId { Reserved = 0, Shm = 1, UserPassword = 2, PublicKey = 3, } -impl From for ZInt { - fn from(pa: PeerAuthenticatorId) -> ZInt { +impl From for ZInt { + fn from(pa: ZNodeAuthenticatorId) -> ZInt { pa as ZInt } } #[derive(Clone)] -pub struct PeerAuthenticator(Arc); +pub struct TransportAuthenticator(Arc); -impl PeerAuthenticator { - pub async fn from_config(_config: &Config) -> ZResult> { +impl TransportAuthenticator { + pub async fn from_config(_config: &Config) -> ZResult> { #[allow(unused_mut)] let mut pas = HashSet::new(); @@ -159,35 +155,27 @@ impl PeerAuthenticator { } } - #[cfg(feature = "shared-memory")] - { - let mut res = SharedMemoryAuthenticator::from_config(_config).await?; - if let Some(pa) = res.take() { - pas.insert(pa.into()); - } - } - Ok(pas) } } -impl Deref for PeerAuthenticator { - type Target = Arc; +impl Deref for TransportAuthenticator { + type Target = Arc; fn deref(&self) -> &Self::Target { &self.0 } } -impl Eq for PeerAuthenticator {} +impl Eq for TransportAuthenticator {} -impl PartialEq for PeerAuthenticator { +impl PartialEq for TransportAuthenticator { fn eq(&self, other: &Self) -> bool { self.id() == other.id() } } -impl Hash for PeerAuthenticator { +impl Hash for TransportAuthenticator { fn hash(&self, state: &mut H) { self.id().hash(state); } @@ -195,22 +183,22 @@ impl Hash for PeerAuthenticator { // Authenticated peer link #[derive(Debug)] -pub struct AuthenticatedPeerLink { +pub struct AuthenticatedLink { pub src: Locator, pub dst: Locator, - pub peer_id: Option, + pub node_id: ZenohId, } -impl fmt::Display for AuthenticatedPeerLink { +impl fmt::Display for AuthenticatedLink { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} => {}", self.src, self.dst) } } #[async_trait] -pub trait PeerAuthenticatorTrait: Send + Sync { +pub trait TransportAuthenticatorTrait: Send + Sync { /// Return the ID of this authenticator. - fn id(&self) -> PeerAuthenticatorId; + fn id(&self) -> ZNodeAuthenticatorId; /// Close the authenticator async fn close(&self); @@ -220,13 +208,13 @@ pub trait PeerAuthenticatorTrait: Send + Sync { /// # Arguments /// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the initial InitSyn message will be sent on /// - /// * `peer_id` - The [`ZenohId`][ZenohId] of the sender of the InitSyn, i.e., the peer + /// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitSyn, i.e., the peer /// initiating a new transport. /// async fn get_init_syn_properties( &self, - link: &AuthenticatedPeerLink, - peer_id: &ZenohId, + link: &AuthenticatedLink, + node_id: &ZenohId, ) -> ZResult>>; /// Return the attachment to be included in the InitAck message to be sent @@ -241,7 +229,7 @@ pub trait PeerAuthenticatorTrait: Send + Sync { /// async fn handle_init_syn( &self, - link: &AuthenticatedPeerLink, + link: &AuthenticatedLink, cookie: &Cookie, property: Option>, ) -> ZResult<(Option>, Option>)>; // (Attachment, Cookie) @@ -252,7 +240,7 @@ pub trait PeerAuthenticatorTrait: Send + Sync { /// # Arguments /// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the InitSyn message was received on /// - /// * `peer_id` - The [`ZenohId`][ZenohId] of the sender of the InitAck message + /// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitAck message /// /// * `sn_resolution` - The sn_resolution negotiated by the sender of the InitAck message /// @@ -260,8 +248,8 @@ pub trait PeerAuthenticatorTrait: Send + Sync { /// async fn handle_init_ack( &self, - link: &AuthenticatedPeerLink, - peer_id: &ZenohId, + link: &AuthenticatedLink, + node_id: &ZenohId, sn_resolution: ZInt, property: Option>, ) -> ZResult>>; @@ -278,7 +266,7 @@ pub trait PeerAuthenticatorTrait: Send + Sync { /// async fn handle_open_syn( &self, - link: &AuthenticatedPeerLink, + link: &AuthenticatedLink, cookie: &Cookie, property: (Option>, Option>), // (Attachment, Cookie) ) -> ZResult>>; @@ -292,7 +280,7 @@ pub trait PeerAuthenticatorTrait: Send + Sync { /// async fn handle_open_ack( &self, - link: &AuthenticatedPeerLink, + link: &AuthenticatedLink, property: Option>, ) -> ZResult>>; @@ -302,7 +290,7 @@ pub trait PeerAuthenticatorTrait: Send + Sync { /// # Arguments /// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] generating the error /// - async fn handle_link_err(&self, link: &AuthenticatedPeerLink); + async fn handle_link_err(&self, link: &AuthenticatedLink); /// Handle any error on a link. This callback is mainly used to clean-up any internal state /// of the authenticator in such a way no unnecessary data is left around @@ -310,7 +298,7 @@ pub trait PeerAuthenticatorTrait: Send + Sync { /// # Arguments /// * `peerd_id` - The [`ZenohId`][ZenohId] of the transport being closed. /// - async fn handle_close(&self, peer_id: &ZenohId); + async fn handle_close(&self, node_id: &ZenohId); } /*************************************/ @@ -319,30 +307,30 @@ pub trait PeerAuthenticatorTrait: Send + Sync { pub struct DummyPeerAuthenticator; impl DummyPeerAuthenticator { - pub fn make() -> PeerAuthenticator { - PeerAuthenticator(Arc::new(DummyPeerAuthenticator)) + pub fn make() -> TransportAuthenticator { + TransportAuthenticator(Arc::new(DummyPeerAuthenticator)) } } #[async_trait] -impl PeerAuthenticatorTrait for DummyPeerAuthenticator { - fn id(&self) -> PeerAuthenticatorId { - PeerAuthenticatorId::Reserved +impl TransportAuthenticatorTrait for DummyPeerAuthenticator { + fn id(&self) -> ZNodeAuthenticatorId { + ZNodeAuthenticatorId::Reserved } async fn close(&self) {} async fn get_init_syn_properties( &self, - _link: &AuthenticatedPeerLink, - _peer_id: &ZenohId, + _link: &AuthenticatedLink, + _node_id: &ZenohId, ) -> ZResult>> { Ok(None) } async fn handle_init_syn( &self, - _link: &AuthenticatedPeerLink, + _link: &AuthenticatedLink, _cookie: &Cookie, _property: Option>, ) -> ZResult<(Option>, Option>)> { @@ -351,8 +339,8 @@ impl PeerAuthenticatorTrait for DummyPeerAuthenticator { async fn handle_init_ack( &self, - _link: &AuthenticatedPeerLink, - _peer_id: &ZenohId, + _link: &AuthenticatedLink, + _node_id: &ZenohId, _sn_resolution: ZInt, _property: Option>, ) -> ZResult>> { @@ -361,7 +349,7 @@ impl PeerAuthenticatorTrait for DummyPeerAuthenticator { async fn handle_open_syn( &self, - _link: &AuthenticatedPeerLink, + _link: &AuthenticatedLink, _cookie: &Cookie, _property: (Option>, Option>), ) -> ZResult>> { @@ -370,13 +358,13 @@ impl PeerAuthenticatorTrait for DummyPeerAuthenticator { async fn handle_open_ack( &self, - _link: &AuthenticatedPeerLink, + _link: &AuthenticatedLink, _property: Option>, ) -> ZResult>> { Ok(None) } - async fn handle_link_err(&self, _link: &AuthenticatedPeerLink) {} + async fn handle_link_err(&self, _link: &AuthenticatedLink) {} - async fn handle_close(&self, _peer_id: &ZenohId) {} + async fn handle_close(&self, _node_id: &ZenohId) {} } diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/pubkey.rs similarity index 95% rename from io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs rename to io/zenoh-transport/src/unicast/establishment/ext/authenticator/pubkey.rs index cf44f4f7fd..0e89f37d8f 100644 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/pubkey.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use super::{ - AuthenticatedPeerLink, PeerAuthenticator, PeerAuthenticatorId, PeerAuthenticatorTrait, + AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, }; use crate::unicast::establishment::Cookie; use async_std::sync::Mutex; @@ -375,9 +375,9 @@ impl PubKeyAuthenticator { } #[async_trait] -impl PeerAuthenticatorTrait for PubKeyAuthenticator { - fn id(&self) -> PeerAuthenticatorId { - PeerAuthenticatorId::PublicKey +impl TransportAuthenticatorTrait for PubKeyAuthenticator { + fn id(&self) -> ZNodeAuthenticatorId { + ZNodeAuthenticatorId::PublicKey } async fn close(&self) { @@ -386,8 +386,8 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { async fn get_init_syn_properties( &self, - link: &AuthenticatedPeerLink, - _peer_id: &ZenohId, + link: &AuthenticatedLink, + _node_id: &ZenohId, ) -> ZResult>> { let init_syn_property = InitSynProperty { version: MULTILINK_VERSION, @@ -406,7 +406,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { async fn handle_init_syn( &self, - link: &AuthenticatedPeerLink, + link: &AuthenticatedLink, cookie: &Cookie, property: Option>, ) -> ZResult<(Option>, Option>)> { @@ -522,8 +522,8 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { async fn handle_init_ack( &self, - link: &AuthenticatedPeerLink, - _peer_id: &ZenohId, + link: &AuthenticatedLink, + _node_id: &ZenohId, _sn_resolution: ZInt, property: Option>, ) -> ZResult>> { @@ -574,7 +574,7 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { async fn handle_open_syn( &self, - link: &AuthenticatedPeerLink, + link: &AuthenticatedLink, cookie: &Cookie, property: (Option>, Option>), ) -> ZResult>> { @@ -654,33 +654,33 @@ impl PeerAuthenticatorTrait for PubKeyAuthenticator { async fn handle_open_ack( &self, - _link: &AuthenticatedPeerLink, + _link: &AuthenticatedLink, _property: Option>, ) -> ZResult>> { Ok(None) } - async fn handle_link_err(&self, link: &AuthenticatedPeerLink) { + async fn handle_link_err(&self, link: &AuthenticatedLink) { // Need to check if it authenticated and remove it if this is the last link - if let Some(zid) = link.peer_id.as_ref() { + if let Some(zid) = link.node_id.as_ref() { zasynclock!(self.state).authenticated.remove(zid); } } - async fn handle_close(&self, peer_id: &ZenohId) { - zasynclock!(self.state).authenticated.remove(peer_id); + async fn handle_close(&self, node_id: &ZenohId) { + zasynclock!(self.state).authenticated.remove(node_id); } } //noinspection ALL -impl From> for PeerAuthenticator { - fn from(v: Arc) -> PeerAuthenticator { - PeerAuthenticator(v) +impl From> for TransportAuthenticator { + fn from(v: Arc) -> TransportAuthenticator { + TransportAuthenticator(v) } } -impl From for PeerAuthenticator { - fn from(v: PubKeyAuthenticator) -> PeerAuthenticator { +impl From for TransportAuthenticator { + fn from(v: PubKeyAuthenticator) -> TransportAuthenticator { Self::from(Arc::new(v)) } } diff --git a/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/userpassword.rs similarity index 92% rename from io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs rename to io/zenoh-transport/src/unicast/establishment/ext/authenticator/userpassword.rs index 43ddf88be1..aa4003b6ed 100644 --- a/io/zenoh-transport/src/unicast/establishment/authenticator/userpassword.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/userpassword.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use super::{ - AuthenticatedPeerLink, PeerAuthenticator, PeerAuthenticatorId, PeerAuthenticatorTrait, + AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, }; use super::{Locator, ZInt, ZenohId}; use crate::unicast::establishment::Cookie; @@ -250,9 +250,9 @@ impl UserPasswordAuthenticator { } #[async_trait] -impl PeerAuthenticatorTrait for UserPasswordAuthenticator { - fn id(&self) -> PeerAuthenticatorId { - PeerAuthenticatorId::UserPassword +impl TransportAuthenticatorTrait for UserPasswordAuthenticator { + fn id(&self) -> ZNodeAuthenticatorId { + ZNodeAuthenticatorId::UserPassword } async fn close(&self) { @@ -261,8 +261,8 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { async fn get_init_syn_properties( &self, - link: &AuthenticatedPeerLink, - _peer_id: &ZenohId, + link: &AuthenticatedLink, + _node_id: &ZenohId, ) -> ZResult>> { // If credentials are not configured, don't initiate the USRPWD authentication if self.credentials.is_none() { @@ -285,7 +285,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { async fn handle_init_syn( &self, - link: &AuthenticatedPeerLink, + link: &AuthenticatedLink, cookie: &Cookie, property: Option>, ) -> ZResult<(Option>, Option>)> { @@ -325,8 +325,8 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { async fn handle_init_ack( &self, - link: &AuthenticatedPeerLink, - _peer_id: &ZenohId, + link: &AuthenticatedLink, + _node_id: &ZenohId, _sn_resolution: ZInt, property: Option>, ) -> ZResult>> { @@ -374,7 +374,7 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { async fn handle_open_syn( &self, - link: &AuthenticatedPeerLink, + link: &AuthenticatedLink, cookie: &Cookie, property: (Option>, Option>), ) -> ZResult>> { @@ -435,42 +435,42 @@ impl PeerAuthenticatorTrait for UserPasswordAuthenticator { async fn handle_open_ack( &self, - _link: &AuthenticatedPeerLink, + _link: &AuthenticatedLink, _property: Option>, ) -> ZResult>> { Ok(None) } - async fn handle_link_err(&self, link: &AuthenticatedPeerLink) { + async fn handle_link_err(&self, link: &AuthenticatedLink) { // Need to check if it authenticated and remove it if this is the last link let mut guard = zasynclock!(self.authenticated); let mut to_del: Option = None; - for (peer_id, auth) in guard.iter_mut() { + for (node_id, auth) in guard.iter_mut() { auth.links.remove(&(link.src.clone(), link.dst.clone())); if auth.links.is_empty() { - to_del = Some(*peer_id); + to_del = Some(*node_id); break; } } - if let Some(peer_id) = to_del.take() { - guard.remove(&peer_id); + if let Some(node_id) = to_del.take() { + guard.remove(&node_id); } } - async fn handle_close(&self, peer_id: &ZenohId) { - zasynclock!(self.authenticated).remove(peer_id); + async fn handle_close(&self, node_id: &ZenohId) { + zasynclock!(self.authenticated).remove(node_id); } } //noinspection ALL -impl From> for PeerAuthenticator { - fn from(v: Arc) -> PeerAuthenticator { - PeerAuthenticator(v) +impl From> for TransportAuthenticator { + fn from(v: Arc) -> TransportAuthenticator { + TransportAuthenticator(v) } } -impl From for PeerAuthenticator { - fn from(v: UserPasswordAuthenticator) -> PeerAuthenticator { +impl From for TransportAuthenticator { + fn from(v: UserPasswordAuthenticator) -> TransportAuthenticator { Self::from(Arc::new(v)) } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs new file mode 100644 index 0000000000..d419a5a11b --- /dev/null +++ b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs @@ -0,0 +1,18 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +// pub(crate) mod authenticator; +pub(crate) mod qos; +// #[cfg(feature = "shared-memory")] +// pub(crate) mod shm; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs new file mode 100644 index 0000000000..7b53e34571 --- /dev/null +++ b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs @@ -0,0 +1,96 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::unicast::establishment::{AcceptFsm, OpenFsm}; +use async_trait::async_trait; +use zenoh_protocol::transport::init; +use zenoh_result::Error as ZError; + +pub(crate) struct QoS; + +pub(crate) struct State { + pub(crate) is_qos: bool, +} + +/*************************************/ +/* OPEN */ +/*************************************/ + +#[async_trait] +impl OpenFsm for QoS { + type Error = ZError; + + type InitSynIn = State; + type InitSynOut = (State, Option); + async fn send_init_syn(&self, state: Self::InitSynIn) -> Result { + let mine_ext = state.is_qos.then_some(init::ext::QoS::new()); + let output = (state, mine_ext); + Ok(output) + } + + type InitAckIn = (State, Option); + type InitAckOut = State; + async fn recv_init_ack(&self, input: Self::InitAckIn) -> Result { + let (mut state, other_ext) = input; + state.is_qos &= other_ext.is_some(); + Ok(state) + } + + type OpenSynIn = State; + type OpenSynOut = State; + async fn send_open_syn(&self, state: Self::OpenSynIn) -> Result { + Ok(state) + } + + type OpenAckIn = State; + type OpenAckOut = State; + async fn recv_open_ack(&self, state: Self::OpenAckIn) -> Result { + Ok(state) + } +} + +/*************************************/ +/* ACCEPT */ +/*************************************/ +#[async_trait] +impl AcceptFsm for QoS { + type Error = ZError; + + type InitSynIn = (State, Option); + type InitSynOut = State; + async fn recv_init_syn(&self, input: Self::InitSynIn) -> Result { + let (mut state, other_ext) = input; + state.is_qos &= other_ext.is_some(); + Ok(state) + } + + type InitAckIn = State; + type InitAckOut = (State, Option); + async fn send_init_ack(&self, state: Self::InitAckIn) -> Result { + let mine_ext = state.is_qos.then_some(init::ext::QoS::new()); + let output = (state, mine_ext); + Ok(output) + } + + type OpenSynIn = State; + type OpenSynOut = State; + async fn recv_open_syn(&self, state: Self::OpenSynIn) -> Result { + Ok(state) + } + + type OpenAckIn = State; + type OpenAckOut = State; + async fn send_open_ack(&self, state: Self::OpenAckIn) -> Result { + Ok(state) + } +} diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs new file mode 100644 index 0000000000..227748cc26 --- /dev/null +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -0,0 +1,542 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::unicast::{establishment::Cookie, shm::SharedMemoryUnicast}; +use async_trait::async_trait; +use rand::{Rng, SeedableRng}; +use std::{ + convert::TryInto, + sync::{Arc, RwLock}, +}; +use zenoh_buffers::{ + reader::{DidntRead, HasReader, Reader}, + writer::{DidntWrite, HasWriter, Writer}, + ZSlice, +}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_config::Config; +use zenoh_crypto::PseudoRng; +use zenoh_protocol::{ + core::{ZInt, ZenohId}, + transport::{init, open}, +}; +use zenoh_result::{bail, zerror, ShmError, ZResult}; +use zenoh_shm::{ + SharedMemoryBuf, SharedMemoryBufInfo, SharedMemoryBufInfoSerialized, SharedMemoryManager, + SharedMemoryReader, +}; + +pub(crate) struct Shm<'a> { + inner: &'a SharedMemoryUnicast, +} +/*************************************/ +/* InitSyn */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |X 1 0| EXT | +/// +-+-+-+---------+ +/// | version | +/// +---------------+ +/// ~ ShmMemBufInfo ~ +/// +---------------+ +pub(crate) struct InitSyn { + pub(crate) version: u8, + pub(crate) info: ZSlice, +} + +// Codec +impl WCodec<&InitSyn, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &InitSyn) -> Self::Output { + self.write(&mut *writer, x.version)?; + self.write(&mut *writer, &x.shm)?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let version: ZInt = self.read(&mut *reader)?; + let info: ZSlice = self.read(&mut *reader)?; + Ok(InitSyn { version, info }) + } +} + +// Open +pub(crate) struct InitSynOpenState { + buffer: SharedMemoryBuf, +} + +impl InitSyn { + pub(crate) fn send(shm: &SharedMemoryUnicast) -> ZResult<(init::ext::Shm, InitSynOpenState)> { + let init_syn_property = InitSyn { + version: shm::VERSION, + info: shm + .buffer + .info + .serialize() + .map_err(|e| zerror!("{e}"))? + .into(), + }; + let mut buff = vec![]; + let codec = Zenoh080::new(); + + let mut writer = buff.writer(); + codec + .write(&mut writer, &init_syn_property) + .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; + + Ok(Some(buff)) + } +} + +// pub(crate) struct InitSynAcceptInput { +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: Option>, +// } + +// Accept +// pub(crate) struct InitSynAcceptState {} + +// impl InitSyn { +// pub(crate) fn accept( +// ext: &init::ext::Shm, +// reader: &SharedMemoryReader, +// ) -> ZResult { +// let codec = Zenoh080::new(); +// let mut reader = ext.reader(); + +// let mut init_syn_ext: InitSyn = codec +// .read(&mut reader) +// .map_err(|_| zerror!("Error in decoding InitSyn SHM extension"))?; + +// if init_syn_ext.version != SHM_VERSION { +// bail!( +// "Incompatible InitSyn SHM extension version. Expected: {}. Received: {}.", +// SHM_VERSION, +// init_syn_ext.version +// ); +// } + +// // Try to read from the shared memory +// match crate::shm::map_zslice_to_shmbuf(&mut init_syn_ext.shm, reader) { +// Ok(false) => { +// log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); +// return Ok((None, None)); +// } +// Err(e) => { +// log::debug!("Zenoh node can not operate over SHM: {}", e); +// return Ok((None, None)); +// } +// Ok(true) => { +// // Payload is SHM: continue. +// } +// } + +// log::trace!("Verifying SHM extension"); + +// let xs = init_syn_ext.shm; +// let bytes: [u8; SHM_SIZE] = match xs.as_slice().try_into() { +// Ok(bytes) => bytes, +// Err(e) => { +// log::debug!("Zenoh node can not operate over SHM: {}", e); +// return Ok((None, None)); +// } +// }; +// let challenge = ZInt::from_le_bytes(bytes); + +// // Create the InitAck attachment +// let init_ack_property = InitAckExt { +// challenge, +// shm: buffer.info.serialize()?.into(), +// }; +// // Encode the InitAck property +// let mut buffer = vec![]; +// let mut writer = buffer.writer(); +// codec +// .write(&mut writer, &init_ack_property) +// .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; + +// Ok((Some(buffer), None)) +// } +// } + +/*************************************/ +/* InitAck */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |0 0 0| ATTCH | +/// +-+-+-+---------+ +/// ~ challenge ~ +/// +---------------+ +/// ~ ShmMemBufInfo ~ +/// +---------------+ +struct InitAck { + challenge: ZInt, + info: ZSlice, +} + +impl WCodec<&InitAck, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &InitAck) -> Self::Output { + self.write(&mut *writer, x.challenge)?; + self.write(&mut *writer, &x.shm)?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let challenge: ZInt = self.read(&mut *reader)?; + let info: ZSlice = self.read(&mut *reader)?; + Ok(InitAck { challenge, info }) + } +} + +// Open +pub(crate) struct InitAckOpenState { + buffer: SharedMemoryBuf, +} + +impl InitAck { + pub(crate) fn recv( + ext: &init::ext::Shm, + shm: &SharedMemoryUnicast, + ) -> ZResult<(init::ext::Shm, InitAckOpenState)> { + // let info = SharedMemoryBufInfo::deserialize(ext.value.as_slice())?; + + // // Try to read from the shared memory + // let mut zslice = ext.value.clone(); + // match crate::shm::map_zslice_to_shmbuf(&mut zslice, reader) { + // Ok(false) => { + // log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); + // return Ok((None, None)); + // } + // Err(e) => { + // log::debug!("Zenoh node can not operate over SHM: {}", e); + // return Ok((None, None)); + // } + // Ok(true) => { + // // Payload is SHM: continue. + // } + // } + + // match crate::shm::map_zslice_to_shmbuf(&mut ext, &shm.reader) { + // Ok(res) => { + // if !res { + // return Err(ShmError(zerror!("No SHM on link: {}", link)).into()); + // } + // } + // Err(e) => return Err(ShmError(zerror!("No SHM on link {}: {}", link, e)).into()), + // } + + // let bytes: [u8; std::mem::size_of::()] = + // init_ack_property.shm.as_slice().try_into().map_err(|e| { + // zerror!( + // "Received InitAck with invalid attachment on link {}: {}", + // link, + // e + // ) + // })?; + // let challenge = ZInt::from_le_bytes(bytes); + + // let challenge = (); + // let init_syn_property = InitAck { + // version: shm::VERSION, + // info: shm + // .buffer + // .info + // .serialize() + // .map_err(|e| zerror!("{e}"))? + // .into(), + // }; + // let mut buff = vec![]; + // let codec = Zenoh080::new(); + + // let mut writer = buff.writer(); + // codec + // .write(&mut writer, &init_syn_property) + // .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; + + // Ok(Some(buff)) + panic!() + } +} + +// /*************************************/ +// /* OpenSyn */ +// /*************************************/ +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// |0 0 0| ATTCH | +// /// +-+-+-+---------+ +// /// ~ challenge ~ +// /// +---------------+ +// struct OpenSynExt { +// challenge: ZInt, +// } + +// impl WCodec<&OpenSynExt, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; + +// fn write(self, writer: &mut W, x: &OpenSynExt) -> Self::Output { +// self.write(&mut *writer, x.challenge)?; +// Ok(()) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let challenge: ZInt = self.read(&mut *reader)?; +// Ok(OpenSynExt { challenge }) +// } +// } + +// /*************************************/ +// /* Authenticator */ +// /*************************************/ +// #[async_trait] +// impl TransportAuthenticatorTrait for SharedMemoryAuthenticator { +// fn id(&self) -> ZNodeAuthenticatorId { +// ZNodeAuthenticatorId::Shm +// } + +// async fn close(&self) { +// // No cleanup needed +// } + +// async fn get_init_syn_properties( +// &self, +// link: &AuthenticatedLink, +// _node_id: &ZenohId, +// ) -> ZResult>> { +// let init_syn_property = InitSyn { +// version: SHM_VERSION, +// shm: self.buffer.info.serialize().unwrap().into(), +// }; +// let mut buff = vec![]; +// let codec = Zenoh080::new(); + +// let mut writer = buff.writer(); +// codec +// .write(&mut writer, &init_syn_property) +// .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; + +// Ok(Some(buff)) +// } + +// async fn handle_init_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// mut property: Option>, +// ) -> ZResult<(Option>, Option>)> { +// let buffer = match property.take() { +// Some(p) => p, +// None => { +// log::debug!("Peer {} did not express interest in SHM", cookie.zid); +// return Ok((None, None)); +// } +// }; + +// let codec = Zenoh080::new(); +// let mut reader = buffer.reader(); + +// let mut init_syn_property: InitSyn = codec +// .read(&mut reader) +// .map_err(|_| zerror!("Received InitSyn with invalid attachment on link: {}", link))?; + +// if init_syn_property.version > SHM_VERSION { +// bail!("Rejected InitSyn with invalid attachment on link: {}", link) +// } + +// // Try to read from the shared memory +// match crate::shm::map_zslice_to_shmbuf(&mut init_syn_property.shm, &self.reader) { +// Ok(res) => { +// if !res { +// log::debug!("Peer {} can not operate over SHM: error", cookie.zid); +// return Ok((None, None)); +// } +// } +// Err(e) => { +// log::debug!("Peer {} can not operate over SHM: {}", cookie.zid, e); +// return Ok((None, None)); +// } +// } + +// log::debug!("Authenticating Shared Memory Access..."); + +// let xs = init_syn_property.shm; +// let bytes: [u8; SHM_SIZE] = match xs.as_slice().try_into() { +// Ok(bytes) => bytes, +// Err(e) => { +// log::debug!("Peer {} can not operate over SHM: {}", cookie.zid, e); +// return Ok((None, None)); +// } +// }; +// let challenge = ZInt::from_le_bytes(bytes); + +// // Create the InitAck attachment +// let init_ack_property = InitAckExt { +// challenge, +// shm: self.buffer.info.serialize().unwrap().into(), +// }; +// // Encode the InitAck property +// let mut buffer = vec![]; +// let mut writer = buffer.writer(); +// codec +// .write(&mut writer, &init_ack_property) +// .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; + +// Ok((Some(buffer), None)) +// } + +// async fn handle_init_ack( +// &self, +// link: &AuthenticatedLink, +// node_id: &ZenohId, +// _sn_resolution: ZInt, +// mut property: Option>, +// ) -> ZResult>> { +// let buffer = match property.take() { +// Some(p) => p, +// None => { +// log::debug!("Peer {} did not express interest in SHM", node_id); +// return Ok(None); +// } +// }; + +// let codec = Zenoh080::new(); +// let mut reader = buffer.reader(); + +// let mut init_ack_property: InitAckExt = codec +// .read(&mut reader) +// .map_err(|_| zerror!("Received InitAck with invalid attachment on link: {}", link))?; + +// // Try to read from the shared memory +// match crate::shm::map_zslice_to_shmbuf(&mut init_ack_property.shm, &self.reader) { +// Ok(res) => { +// if !res { +// return Err(ShmError(zerror!("No SHM on link: {}", link)).into()); +// } +// } +// Err(e) => return Err(ShmError(zerror!("No SHM on link {}: {}", link, e)).into()), +// } + +// let bytes: [u8; SHM_SIZE] = init_ack_property.shm.as_slice().try_into().map_err(|e| { +// zerror!( +// "Received InitAck with invalid attachment on link {}: {}", +// link, +// e +// ) +// })?; +// let challenge = ZInt::from_le_bytes(bytes); + +// if init_ack_property.challenge == self.challenge { +// // Create the OpenSyn attachment +// let open_syn_property = OpenSynExt { challenge }; +// // Encode the OpenSyn property +// let mut buffer = vec![]; +// let mut writer = buffer.writer(); + +// codec +// .write(&mut writer, &open_syn_property) +// .map_err(|_| zerror!("Error in encoding OpenSyn for SHM on link: {}", link))?; + +// Ok(Some(buffer)) +// } else { +// Err(ShmError(zerror!( +// "Received OpenSyn with invalid attachment on link: {}", +// link +// )) +// .into()) +// } +// } + +// async fn handle_open_syn( +// &self, +// link: &AuthenticatedLink, +// _cookie: &Cookie, +// property: (Option>, Option>), +// ) -> ZResult>> { +// let (mut attachment, _cookie) = property; +// let buffer = match attachment.take() { +// Some(p) => p, +// None => { +// return Err(ShmError(zerror!( +// "Received OpenSyn with no SHM attachment on link: {}", +// link +// )) +// .into()); +// } +// }; + +// let codec = Zenoh080::new(); +// let mut reader = buffer.reader(); + +// let open_syn_property: OpenSynExt = codec +// .read(&mut reader) +// .map_err(|_| zerror!("Received OpenSyn with invalid attachment on link: {}", link))?; + +// if open_syn_property.challenge == self.challenge { +// Ok(None) +// } else { +// Err(ShmError(zerror!( +// "Received OpenSyn with invalid attachment on link: {}", +// link +// )) +// .into()) +// } +// } + +// async fn handle_open_ack( +// &self, +// _link: &AuthenticatedLink, +// _property: Option>, +// ) -> ZResult>> { +// Ok(None) +// } + +// async fn handle_link_err(&self, _link: &AuthenticatedLink) {} + +// async fn handle_close(&self, _node_id: &ZenohId) {} +// } diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 946d4a05ef..6cc323df1d 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -13,7 +13,7 @@ // pub(crate) mod accept; pub(super) mod cookie; -pub(super) mod extensions; +pub(super) mod ext; pub(crate) mod open; use super::super::TransportManager; diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 279871e1c9..d2334f98fa 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -11,13 +11,8 @@ // Contributors: // ZettaScale Zenoh Team, // -// mod init_ack; -// mod init_syn; -// mod open_ack; -// mod open_syn; - use crate::unicast::establishment::{ - close_link, compute_sn, finalize_transport, InputFinalize, OpenFsm, + close_link, compute_sn, ext, finalize_transport, InputFinalize, OpenFsm, }; use crate::{TransportConfigUnicast, TransportManager, TransportUnicast}; use async_trait::async_trait; @@ -39,17 +34,20 @@ struct SendInitSynIn { mine_whatami: WhatAmI, mine_resolution: Resolution, mine_batch_size: u16, + ext_qos: ext::qos::State, } struct SendInitSynOut { mine_batch_size: u16, mine_resolution: Resolution, + ext_qos: ext::qos::State, } // InitAck struct RecvInitAckIn { mine_batch_size: u16, mine_resolution: Resolution, + ext_qos: ext::qos::State, } struct RecvInitAckOut { @@ -58,6 +56,7 @@ struct RecvInitAckOut { other_cookie: ZSlice, agreed_resolution: Resolution, agreed_batch_size: u16, + ext_qos: ext::qos::State, } // OpenSyn @@ -67,23 +66,29 @@ struct SendOpenSynIn { other_zid: ZenohId, other_cookie: ZSlice, agreed_resolution: Resolution, + ext_qos: ext::qos::State, } struct SendOpenSynOut { mine_initial_sn: ZInt, + ext_qos: ext::qos::State, } // OpenAck -struct RecvOpenAckIn {} +struct RecvOpenAckIn { + ext_qos: ext::qos::State, +} struct RecvOpenAckOut { other_lease: Duration, other_initial_sn: ZInt, + ext_qos: ext::qos::State, } // FSM struct OpenLink<'a> { link: &'a LinkUnicast, + ext_qos: ext::qos::QoS, } #[async_trait] @@ -93,13 +98,20 @@ impl<'a> OpenFsm for OpenLink<'a> { type InitSynIn = SendInitSynIn; type InitSynOut = SendInitSynOut; async fn send_init_syn(&self, input: Self::InitSynIn) -> Result { + // Extension QoS + let (qos_state, qos_mine_ext) = self + .ext_qos + .send_init_syn(input.ext_qos) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let msg: TransportMessage = InitSyn { version: input.mine_version, whatami: input.mine_whatami, zid: input.mine_zid, batch_size: input.mine_batch_size, resolution: input.mine_resolution, - qos: None, // @TODO + qos: qos_mine_ext, shm: None, // @TODO auth: None, // @TODO } @@ -114,6 +126,7 @@ impl<'a> OpenFsm for OpenLink<'a> { let output = SendInitSynOut { mine_batch_size: input.mine_batch_size, mine_resolution: input.mine_resolution, + ext_qos: qos_state, }; Ok(output) @@ -195,12 +208,20 @@ impl<'a> OpenFsm for OpenLink<'a> { // Compute the minimum batch size let agreed_batch_size = input.mine_batch_size.min(init_ack.batch_size); + // Extension QoS + let qos_state = self + .ext_qos + .recv_init_ack((input.ext_qos, init_ack.qos)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvInitAckOut { other_zid: init_ack.zid, other_whatami: init_ack.whatami, other_cookie: init_ack.cookie, agreed_resolution, agreed_batch_size, + ext_qos: qos_state, }; Ok(output) } @@ -208,9 +229,15 @@ impl<'a> OpenFsm for OpenLink<'a> { type OpenSynIn = SendOpenSynIn; type OpenSynOut = SendOpenSynOut; async fn send_open_syn(&self, input: Self::OpenSynIn) -> Result { - let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, input.agreed_resolution); + // Extension QoS + let ext_qos = self + .ext_qos + .send_open_syn(input.ext_qos) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Build and send an OpenSyn message + let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, input.agreed_resolution); let message: TransportMessage = OpenSyn { lease: input.mine_lease, initial_sn: mine_initial_sn, @@ -226,14 +253,16 @@ impl<'a> OpenFsm for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = SendOpenSynOut { mine_initial_sn }; + let output = SendOpenSynOut { + mine_initial_sn, + ext_qos, + }; Ok(output) } type OpenAckIn = RecvOpenAckIn; type OpenAckOut = RecvOpenAckOut; - async fn recv_open_ack(&self, _in: Self::OpenAckIn) -> Result { - // Wait to read an OpenAck + async fn recv_open_ack(&self, input: Self::OpenAckIn) -> Result { let msg = self .link .recv() @@ -265,22 +294,30 @@ impl<'a> OpenFsm for OpenLink<'a> { } }; - println!(">>> RECEIVING {}", open_ack.initial_sn); + // Extension QoS + let ext_qos = self + .ext_qos + .recv_open_ack(input.ext_qos) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; let output = RecvOpenAckOut { other_initial_sn: open_ack.initial_sn, other_lease: open_ack.lease, + ext_qos, }; Ok(output) } } -// OLD pub(crate) async fn open_link( link: &LinkUnicast, manager: &TransportManager, ) -> ZResult { - let fsm = OpenLink { link }; + // Extension QoS + let ext_qos = ext::qos::QoS; + + let fsm = OpenLink { link, ext_qos }; // Init handshake macro_rules! step { @@ -301,12 +338,16 @@ pub(crate) async fn open_link( mine_whatami: manager.config.whatami, mine_resolution: manager.config.resolution, mine_batch_size: manager.config.batch_size, + ext_qos: ext::qos::State { + is_qos: manager.config.unicast.is_qos, + }, }; let isyn_out = step!(fsm.send_init_syn(isyn_in).await); let iack_in = RecvInitAckIn { mine_resolution: isyn_out.mine_resolution, mine_batch_size: isyn_out.mine_batch_size, + ext_qos: isyn_out.ext_qos, }; let iack_out = step!(fsm.recv_init_ack(iack_in).await); @@ -317,10 +358,13 @@ pub(crate) async fn open_link( mine_lease: manager.config.unicast.lease, agreed_resolution: iack_out.agreed_resolution, other_cookie: iack_out.other_cookie, + ext_qos: iack_out.ext_qos, }; let osyn_out = step!(fsm.send_open_syn(osyn_in).await); - let oack_in = RecvOpenAckIn {}; + let oack_in = RecvOpenAckIn { + ext_qos: osyn_out.ext_qos, + }; let oack_out = step!(fsm.recv_open_ack(oack_in).await); // Initialize the transport @@ -329,7 +373,7 @@ pub(crate) async fn open_link( whatami: iack_out.other_whatami, sn_resolution: iack_out.agreed_resolution.get(Field::FrameSN).mask(), tx_initial_sn: osyn_out.mine_initial_sn, - is_qos: false, // @TODO + is_qos: oack_out.ext_qos.is_qos, is_shm: false, // @TODO }; let transport = step!(manager @@ -352,12 +396,6 @@ pub(crate) async fn open_link( .sync(oack_out.other_initial_sn) .await; - log::debug!( - "New transport link established with {}: {}", - iack_out.other_zid, - link - ); - let output = InputFinalize { transport, other_lease: oack_out.other_lease, @@ -370,5 +408,11 @@ pub(crate) async fn open_link( return Err(e); } + log::debug!( + "New transport link established with {}: {}", + iack_out.other_zid, + link + ); + Ok(transport) } diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 71dfa3bf3b..349d025bbe 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -15,8 +15,8 @@ pub mod establishment; pub(crate) mod link; pub(crate) mod manager; pub(crate) mod rx; -// #[cfg(feature = "shared-memory")] -// pub(crate) mod shm; +#[cfg(feature = "shared-memory")] +pub(crate) mod shm; pub(crate) mod transport; pub(crate) mod tx; From 983f760ce426f65500006414b14dece58d51dd3b Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 2 Mar 2023 09:48:21 +0100 Subject: [PATCH 046/203] Improve OpenFsm --- .../src/unicast/establishment/ext/mod.rs | 4 +- .../src/unicast/establishment/ext/qos.rs | 50 ++- .../src/unicast/establishment/ext/shm.rs | 338 +++++++++--------- .../src/unicast/establishment/mod.rs | 22 +- .../src/unicast/establishment/open.rs | 160 ++++----- io/zenoh-transport/src/unicast/manager.rs | 12 +- 6 files changed, 296 insertions(+), 290 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs index d419a5a11b..403a9bbd77 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs @@ -14,5 +14,5 @@ // pub(crate) mod authenticator; pub(crate) mod qos; -// #[cfg(feature = "shared-memory")] -// pub(crate) mod shm; +#[cfg(feature = "shared-memory")] +pub(crate) mod shm; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs index 7b53e34571..f29bf227b1 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs @@ -18,6 +18,7 @@ use zenoh_result::Error as ZError; pub(crate) struct QoS; +#[derive(Clone, Copy, Debug)] pub(crate) struct State { pub(crate) is_qos: bool, } @@ -27,35 +28,46 @@ pub(crate) struct State { /*************************************/ #[async_trait] -impl OpenFsm for QoS { +impl<'a> OpenFsm<'a> for QoS { type Error = ZError; - type InitSynIn = State; - type InitSynOut = (State, Option); - async fn send_init_syn(&self, state: Self::InitSynIn) -> Result { - let mine_ext = state.is_qos.then_some(init::ext::QoS::new()); - let output = (state, mine_ext); + type InitSynIn = &'a State; + type InitSynOut = Option; + async fn send_init_syn( + &'a self, + state: Self::InitSynIn, + ) -> Result { + let output = state.is_qos.then_some(init::ext::QoS::new()); Ok(output) } - type InitAckIn = (State, Option); - type InitAckOut = State; - async fn recv_init_ack(&self, input: Self::InitAckIn) -> Result { - let (mut state, other_ext) = input; + type InitAckIn = (&'a mut State, Option); + type InitAckOut = (); + async fn recv_init_ack( + &'a self, + input: Self::InitAckIn, + ) -> Result { + let (state, other_ext) = input; state.is_qos &= other_ext.is_some(); - Ok(state) + Ok(()) } - type OpenSynIn = State; - type OpenSynOut = State; - async fn send_open_syn(&self, state: Self::OpenSynIn) -> Result { - Ok(state) + type OpenSynIn = &'a State; + type OpenSynOut = (); + async fn send_open_syn( + &'a self, + _state: Self::OpenSynIn, + ) -> Result { + Ok(()) } - type OpenAckIn = State; - type OpenAckOut = State; - async fn recv_open_ack(&self, state: Self::OpenAckIn) -> Result { - Ok(state) + type OpenAckIn = &'a State; + type OpenAckOut = (); + async fn recv_open_ack( + &'a self, + _state: Self::OpenAckIn, + ) -> Result { + Ok(()) } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index 227748cc26..239e8bad75 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -39,76 +39,76 @@ use zenoh_shm::{ pub(crate) struct Shm<'a> { inner: &'a SharedMemoryUnicast, } -/*************************************/ -/* InitSyn */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |X 1 0| EXT | -/// +-+-+-+---------+ -/// | version | -/// +---------------+ -/// ~ ShmMemBufInfo ~ -/// +---------------+ -pub(crate) struct InitSyn { - pub(crate) version: u8, - pub(crate) info: ZSlice, -} +// /*************************************/ +// /* InitSyn */ +// /*************************************/ +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// |X 1 0| EXT | +// /// +-+-+-+---------+ +// /// | version | +// /// +---------------+ +// /// ~ ShmMemBufInfo ~ +// /// +---------------+ +// pub(crate) struct InitSyn { +// pub(crate) version: u8, +// pub(crate) info: ZSlice, +// } -// Codec -impl WCodec<&InitSyn, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &InitSyn) -> Self::Output { - self.write(&mut *writer, x.version)?; - self.write(&mut *writer, &x.shm)?; - Ok(()) - } -} +// // Codec +// impl WCodec<&InitSyn, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let version: ZInt = self.read(&mut *reader)?; - let info: ZSlice = self.read(&mut *reader)?; - Ok(InitSyn { version, info }) - } -} +// fn write(self, writer: &mut W, x: &InitSyn) -> Self::Output { +// self.write(&mut *writer, x.version)?; +// self.write(&mut *writer, &x.info)?; +// Ok(()) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let version: ZInt = self.read(&mut *reader)?; +// let info: ZSlice = self.read(&mut *reader)?; +// Ok(InitSyn { version, info }) +// } +// } // Open -pub(crate) struct InitSynOpenState { - buffer: SharedMemoryBuf, -} +// pub(crate) struct InitSynOpenState { +// buffer: SharedMemoryBuf, +// } -impl InitSyn { - pub(crate) fn send(shm: &SharedMemoryUnicast) -> ZResult<(init::ext::Shm, InitSynOpenState)> { - let init_syn_property = InitSyn { - version: shm::VERSION, - info: shm - .buffer - .info - .serialize() - .map_err(|e| zerror!("{e}"))? - .into(), - }; - let mut buff = vec![]; - let codec = Zenoh080::new(); - - let mut writer = buff.writer(); - codec - .write(&mut writer, &init_syn_property) - .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; - - Ok(Some(buff)) - } -} +// impl InitSyn { +// pub(crate) fn send(shm: &SharedMemoryUnicast) -> ZResult<(init::ext::Shm, InitSynOpenState)> { +// let init_syn_property = InitSyn { +// version: shm::VERSION, +// info: shm +// .buffer +// .info +// .serialize() +// .map_err(|e| zerror!("{e}"))? +// .into(), +// }; +// let mut buff = vec![]; +// let codec = Zenoh080::new(); + +// let mut writer = buff.writer(); +// codec +// .write(&mut writer, &init_syn_property) +// .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; + +// Ok(Some(buff)) +// } +// } // pub(crate) struct InitSynAcceptInput { // link: &AuthenticatedLink, @@ -185,114 +185,114 @@ impl InitSyn { /*************************************/ /* InitAck */ /*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ challenge ~ -/// +---------------+ -/// ~ ShmMemBufInfo ~ -/// +---------------+ -struct InitAck { - challenge: ZInt, - info: ZSlice, -} +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// |0 0 0| ATTCH | +// /// +-+-+-+---------+ +// /// ~ challenge ~ +// /// +---------------+ +// /// ~ ShmMemBufInfo ~ +// /// +---------------+ +// struct InitAck { +// challenge: ZInt, +// info: ZSlice, +// } -impl WCodec<&InitAck, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &InitAck) -> Self::Output { - self.write(&mut *writer, x.challenge)?; - self.write(&mut *writer, &x.shm)?; - Ok(()) - } -} +// impl WCodec<&InitAck, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let challenge: ZInt = self.read(&mut *reader)?; - let info: ZSlice = self.read(&mut *reader)?; - Ok(InitAck { challenge, info }) - } -} +// fn write(self, writer: &mut W, x: &InitAck) -> Self::Output { +// self.write(&mut *writer, x.challenge)?; +// self.write(&mut *writer, &x.shm)?; +// Ok(()) +// } +// } -// Open -pub(crate) struct InitAckOpenState { - buffer: SharedMemoryBuf, -} +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; -impl InitAck { - pub(crate) fn recv( - ext: &init::ext::Shm, - shm: &SharedMemoryUnicast, - ) -> ZResult<(init::ext::Shm, InitAckOpenState)> { - // let info = SharedMemoryBufInfo::deserialize(ext.value.as_slice())?; - - // // Try to read from the shared memory - // let mut zslice = ext.value.clone(); - // match crate::shm::map_zslice_to_shmbuf(&mut zslice, reader) { - // Ok(false) => { - // log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); - // return Ok((None, None)); - // } - // Err(e) => { - // log::debug!("Zenoh node can not operate over SHM: {}", e); - // return Ok((None, None)); - // } - // Ok(true) => { - // // Payload is SHM: continue. - // } - // } - - // match crate::shm::map_zslice_to_shmbuf(&mut ext, &shm.reader) { - // Ok(res) => { - // if !res { - // return Err(ShmError(zerror!("No SHM on link: {}", link)).into()); - // } - // } - // Err(e) => return Err(ShmError(zerror!("No SHM on link {}: {}", link, e)).into()), - // } - - // let bytes: [u8; std::mem::size_of::()] = - // init_ack_property.shm.as_slice().try_into().map_err(|e| { - // zerror!( - // "Received InitAck with invalid attachment on link {}: {}", - // link, - // e - // ) - // })?; - // let challenge = ZInt::from_le_bytes(bytes); - - // let challenge = (); - // let init_syn_property = InitAck { - // version: shm::VERSION, - // info: shm - // .buffer - // .info - // .serialize() - // .map_err(|e| zerror!("{e}"))? - // .into(), - // }; - // let mut buff = vec![]; - // let codec = Zenoh080::new(); - - // let mut writer = buff.writer(); - // codec - // .write(&mut writer, &init_syn_property) - // .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; - - // Ok(Some(buff)) - panic!() - } -} +// fn read(self, reader: &mut R) -> Result { +// let challenge: ZInt = self.read(&mut *reader)?; +// let info: ZSlice = self.read(&mut *reader)?; +// Ok(InitAck { challenge, info }) +// } +// } + +// // Open +// pub(crate) struct InitAckOpenState { +// buffer: SharedMemoryBuf, +// } + +// impl InitAck { +// pub(crate) fn recv( +// ext: &init::ext::Shm, +// shm: &SharedMemoryUnicast, +// ) -> ZResult<(init::ext::Shm, InitAckOpenState)> { +// let info = SharedMemoryBufInfo::deserialize(ext.value.as_slice())?; + +// // Try to read from the shared memory +// let mut zslice = ext.value.clone(); +// match crate::shm::map_zslice_to_shmbuf(&mut zslice, reader) { +// Ok(false) => { +// log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); +// return Ok((None, None)); +// } +// Err(e) => { +// log::debug!("Zenoh node can not operate over SHM: {}", e); +// return Ok((None, None)); +// } +// Ok(true) => { +// // Payload is SHM: continue. +// } +// } + +// match crate::shm::map_zslice_to_shmbuf(&mut ext, &shm.reader) { +// Ok(res) => { +// if !res { +// return Err(ShmError(zerror!("No SHM on link: {}", link)).into()); +// } +// } +// Err(e) => return Err(ShmError(zerror!("No SHM on link {}: {}", link, e)).into()), +// } + +// let bytes: [u8; std::mem::size_of::()] = +// init_ack_property.shm.as_slice().try_into().map_err(|e| { +// zerror!( +// "Received InitAck with invalid attachment on link {}: {}", +// link, +// e +// ) +// })?; +// let challenge = ZInt::from_le_bytes(bytes); + +// let challenge = (); +// let init_syn_property = InitAck { +// version: shm::VERSION, +// info: shm +// .buffer +// .info +// .serialize() +// .map_err(|e| zerror!("{e}"))? +// .into(), +// }; +// let mut buff = vec![]; +// let codec = Zenoh080::new(); + +// let mut writer = buff.writer(); +// codec +// .write(&mut writer, &init_syn_property) +// .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; + +// Ok(Some(buff)) +// panic!() +// } +// } // /*************************************/ // /* OpenSyn */ diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 6cc323df1d..18fb1be925 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -36,24 +36,36 @@ use zenoh_result::ZResult; /* TRAITS */ /*************************************/ #[async_trait] -pub(crate) trait OpenFsm { +pub(crate) trait OpenFsm<'a> { type Error; type InitSynIn; type InitSynOut; - async fn send_init_syn(&self, input: Self::InitSynIn) -> Result; + async fn send_init_syn( + &'a self, + input: Self::InitSynIn, + ) -> Result; type InitAckIn; type InitAckOut; - async fn recv_init_ack(&self, input: Self::InitAckIn) -> Result; + async fn recv_init_ack( + &'a self, + input: Self::InitAckIn, + ) -> Result; type OpenSynIn; type OpenSynOut; - async fn send_open_syn(&self, input: Self::OpenSynIn) -> Result; + async fn send_open_syn( + &'a self, + input: Self::OpenSynIn, + ) -> Result; type OpenAckIn; type OpenAckOut; - async fn recv_open_ack(&self, input: Self::OpenAckIn) -> Result; + async fn recv_open_ack( + &'a self, + input: Self::OpenAckIn, + ) -> Result; } #[async_trait] diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index d2334f98fa..07c00f9860 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -27,36 +27,29 @@ use zenoh_result::ZResult; type OpenError = (zenoh_result::Error, Option); +struct StateZenoh { + batch_size: u16, + resolution: Resolution, +} + +struct State { + zenoh: StateZenoh, + ext_qos: ext::qos::State, +} + // InitSyn struct SendInitSynIn { mine_version: u8, mine_zid: ZenohId, mine_whatami: WhatAmI, - mine_resolution: Resolution, - mine_batch_size: u16, - ext_qos: ext::qos::State, -} - -struct SendInitSynOut { - mine_batch_size: u16, - mine_resolution: Resolution, - ext_qos: ext::qos::State, } // InitAck -struct RecvInitAckIn { - mine_batch_size: u16, - mine_resolution: Resolution, - ext_qos: ext::qos::State, -} struct RecvInitAckOut { other_zid: ZenohId, other_whatami: WhatAmI, other_cookie: ZSlice, - agreed_resolution: Resolution, - agreed_batch_size: u16, - ext_qos: ext::qos::State, } // OpenSyn @@ -65,24 +58,16 @@ struct SendOpenSynIn { mine_lease: Duration, other_zid: ZenohId, other_cookie: ZSlice, - agreed_resolution: Resolution, - ext_qos: ext::qos::State, } struct SendOpenSynOut { mine_initial_sn: ZInt, - ext_qos: ext::qos::State, } // OpenAck -struct RecvOpenAckIn { - ext_qos: ext::qos::State, -} - struct RecvOpenAckOut { other_lease: Duration, other_initial_sn: ZInt, - ext_qos: ext::qos::State, } // FSM @@ -92,16 +77,21 @@ struct OpenLink<'a> { } #[async_trait] -impl<'a> OpenFsm for OpenLink<'a> { +impl<'a> OpenFsm<'a> for OpenLink<'a> { type Error = OpenError; - type InitSynIn = SendInitSynIn; - type InitSynOut = SendInitSynOut; - async fn send_init_syn(&self, input: Self::InitSynIn) -> Result { + type InitSynIn = (&'a mut State, SendInitSynIn); + type InitSynOut = (); + async fn send_init_syn( + &'a self, + input: Self::InitSynIn, + ) -> Result { + let (state, input) = input; + // Extension QoS - let (qos_state, qos_mine_ext) = self + let qos_mine_ext = self .ext_qos - .send_init_syn(input.ext_qos) + .send_init_syn(&state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; @@ -109,8 +99,8 @@ impl<'a> OpenFsm for OpenLink<'a> { version: input.mine_version, whatami: input.mine_whatami, zid: input.mine_zid, - batch_size: input.mine_batch_size, - resolution: input.mine_resolution, + batch_size: state.zenoh.batch_size, + resolution: state.zenoh.resolution, qos: qos_mine_ext, shm: None, // @TODO auth: None, // @TODO @@ -123,18 +113,15 @@ impl<'a> OpenFsm for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = SendInitSynOut { - mine_batch_size: input.mine_batch_size, - mine_resolution: input.mine_resolution, - ext_qos: qos_state, - }; - - Ok(output) + Ok(()) } - type InitAckIn = RecvInitAckIn; + type InitAckIn = &'a mut State; type InitAckOut = RecvInitAckOut; - async fn recv_init_ack(&self, input: Self::InitAckIn) -> Result { + async fn recv_init_ack( + &'a self, + state: Self::InitAckIn, + ) -> Result { let msg = self .link .recv() @@ -167,12 +154,12 @@ impl<'a> OpenFsm for OpenLink<'a> { }; // Compute the minimum SN resolution - let agreed_resolution = { + state.zenoh.resolution = { let mut res = Resolution::default(); // Frame SN let i_fsn_res = init_ack.resolution.get(Field::FrameSN); - let m_fsn_res = input.mine_resolution.get(Field::FrameSN); + let m_fsn_res = state.zenoh.resolution.get(Field::FrameSN); if i_fsn_res > m_fsn_res { let e = zerror!( @@ -188,7 +175,7 @@ impl<'a> OpenFsm for OpenLink<'a> { // Request ID let i_rid_res = init_ack.resolution.get(Field::RequestID); - let m_rid_res = input.mine_resolution.get(Field::RequestID); + let m_rid_res = state.zenoh.resolution.get(Field::RequestID); if i_rid_res > m_rid_res { let e = zerror!( @@ -206,12 +193,11 @@ impl<'a> OpenFsm for OpenLink<'a> { }; // Compute the minimum batch size - let agreed_batch_size = input.mine_batch_size.min(init_ack.batch_size); + state.zenoh.batch_size = state.zenoh.batch_size.min(init_ack.batch_size); // Extension QoS - let qos_state = self - .ext_qos - .recv_init_ack((input.ext_qos, init_ack.qos)) + self.ext_qos + .recv_init_ack((&mut state.ext_qos, init_ack.qos)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; @@ -219,25 +205,26 @@ impl<'a> OpenFsm for OpenLink<'a> { other_zid: init_ack.zid, other_whatami: init_ack.whatami, other_cookie: init_ack.cookie, - agreed_resolution, - agreed_batch_size, - ext_qos: qos_state, }; Ok(output) } - type OpenSynIn = SendOpenSynIn; + type OpenSynIn = (&'a mut State, SendOpenSynIn); type OpenSynOut = SendOpenSynOut; - async fn send_open_syn(&self, input: Self::OpenSynIn) -> Result { + async fn send_open_syn( + &'a self, + input: Self::OpenSynIn, + ) -> Result { + let (state, input) = input; + // Extension QoS - let ext_qos = self - .ext_qos - .send_open_syn(input.ext_qos) + self.ext_qos + .send_open_syn(&state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Build and send an OpenSyn message - let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, input.agreed_resolution); + let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); let message: TransportMessage = OpenSyn { lease: input.mine_lease, initial_sn: mine_initial_sn, @@ -253,16 +240,16 @@ impl<'a> OpenFsm for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = SendOpenSynOut { - mine_initial_sn, - ext_qos, - }; + let output = SendOpenSynOut { mine_initial_sn }; Ok(output) } - type OpenAckIn = RecvOpenAckIn; + type OpenAckIn = &'a mut State; type OpenAckOut = RecvOpenAckOut; - async fn recv_open_ack(&self, input: Self::OpenAckIn) -> Result { + async fn recv_open_ack( + &'a self, + state: Self::OpenAckIn, + ) -> Result { let msg = self .link .recv() @@ -295,16 +282,14 @@ impl<'a> OpenFsm for OpenLink<'a> { }; // Extension QoS - let ext_qos = self - .ext_qos - .recv_open_ack(input.ext_qos) + self.ext_qos + .recv_open_ack(&mut state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; let output = RecvOpenAckOut { other_initial_sn: open_ack.initial_sn, other_lease: open_ack.lease, - ext_qos, }; Ok(output) } @@ -332,48 +317,43 @@ pub(crate) async fn open_link( }; } - let isyn_in = SendInitSynIn { - mine_version: manager.config.version, - mine_zid: manager.config.zid, - mine_whatami: manager.config.whatami, - mine_resolution: manager.config.resolution, - mine_batch_size: manager.config.batch_size, + let mut state = State { + zenoh: StateZenoh { + batch_size: manager.config.batch_size, + resolution: manager.config.resolution, + }, ext_qos: ext::qos::State { is_qos: manager.config.unicast.is_qos, }, }; - let isyn_out = step!(fsm.send_init_syn(isyn_in).await); - let iack_in = RecvInitAckIn { - mine_resolution: isyn_out.mine_resolution, - mine_batch_size: isyn_out.mine_batch_size, - ext_qos: isyn_out.ext_qos, + let isyn_in = SendInitSynIn { + mine_version: manager.config.version, + mine_zid: manager.config.zid, + mine_whatami: manager.config.whatami, }; - let iack_out = step!(fsm.recv_init_ack(iack_in).await); + step!(fsm.send_init_syn((&mut state, isyn_in)).await); + + let iack_out = step!(fsm.recv_init_ack(&mut state).await); // Open handshake let osyn_in = SendOpenSynIn { mine_zid: manager.config.zid, other_zid: iack_out.other_zid, mine_lease: manager.config.unicast.lease, - agreed_resolution: iack_out.agreed_resolution, other_cookie: iack_out.other_cookie, - ext_qos: iack_out.ext_qos, }; - let osyn_out = step!(fsm.send_open_syn(osyn_in).await); + let osyn_out = step!(fsm.send_open_syn((&mut state, osyn_in)).await); - let oack_in = RecvOpenAckIn { - ext_qos: osyn_out.ext_qos, - }; - let oack_out = step!(fsm.recv_open_ack(oack_in).await); + let oack_out = step!(fsm.recv_open_ack(&mut state).await); // Initialize the transport let config = TransportConfigUnicast { peer: iack_out.other_zid, whatami: iack_out.other_whatami, - sn_resolution: iack_out.agreed_resolution.get(Field::FrameSN).mask(), + sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), tx_initial_sn: osyn_out.mine_initial_sn, - is_qos: oack_out.ext_qos.is_qos, + is_qos: state.ext_qos.is_qos, is_shm: false, // @TODO }; let transport = step!(manager @@ -399,7 +379,7 @@ pub(crate) async fn open_link( let output = InputFinalize { transport, other_lease: oack_out.other_lease, - agreed_batch_size: iack_out.agreed_batch_size, + agreed_batch_size: state.zenoh.batch_size, }; let transport = output.transport.clone(); let res = finalize_transport(link, manager, output).await; diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 6524250596..51eee49858 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::unicast::{ + shm::SharedMemoryUnicast, transport::{TransportUnicastConfig, TransportUnicastInner}, TransportConfigUnicast, TransportUnicast, }; @@ -56,6 +57,9 @@ pub struct TransportManagerStateUnicast { pub(super) protocols: Arc>>, // Established transports pub(super) transports: Arc>>>, + // Shared memory + #[cfg(feature = "shared-memory")] + pub(super) shm: Arc, } pub struct TransportManagerParamsUnicast { @@ -179,20 +183,18 @@ impl TransportManagerBuilderUnicast { // #[cfg(feature = "shared-memory")] // if self.is_shm - // && !self - // .peer_authenticator - // .iter() - // .any(|a| a.id() == PeerAuthenticatorId::Shm) // { // self.peer_authenticator // .insert(SharedMemoryAuthenticator::make()?.into()); - // } @TODO + // } let state = TransportManagerStateUnicast { incoming: Arc::new(Mutex::new(0)), protocols: Arc::new(Mutex::new(HashMap::new())), transports: Arc::new(Mutex::new(HashMap::new())), // peer_authenticator: Arc::new(AsyncRwLock::new(self.peer_authenticator)), + #[cfg(feature = "shared-memory")] + shm: Arc::new(SharedMemoryUnicast::make()?), }; let params = TransportManagerParamsUnicast { config, state }; From dfa51b58b3dc3513df71644779a32e9249d9c4ae Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 2 Mar 2023 11:12:48 +0100 Subject: [PATCH 047/203] Improve AcceptFsm --- .../src/unicast/establishment/accept.rs | 162 ++++++++++-------- .../src/unicast/establishment/ext/qos.rs | 49 ++++-- .../src/unicast/establishment/mod.rs | 22 ++- io/zenoh-transport/src/unicast/manager.rs | 13 +- .../tests/unicast_authenticator.rs | 12 +- io/zenoh-transport/tests/unicast_shm.rs | 4 +- 6 files changed, 149 insertions(+), 113 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index e49ee35d53..4a0665fc22 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -38,19 +38,23 @@ use zenoh_result::ZResult; pub(super) type AcceptError = (zenoh_result::Error, Option); +struct StateZenoh { + batch_size: u16, + resolution: Resolution, +} + +struct State { + zenoh: StateZenoh, + ext_qos: ext::qos::State, +} + // InitSyn struct RecvInitSynIn { mine_version: u8, - mine_resolution: Resolution, - mine_batch_size: u16, - ext_qos: ext::qos::State, } struct RecvInitSynOut { other_zid: ZenohId, other_whatami: WhatAmI, - agreed_resolution: Resolution, - agreed_batch_size: u16, - ext_qos: ext::qos::State, } // InitAck @@ -60,9 +64,6 @@ struct SendInitAckIn { mine_whatami: WhatAmI, other_zid: ZenohId, other_whatami: WhatAmI, - agreed_resolution: Resolution, - agreed_batch_size: u16, - ext_qos: ext::qos::State, } struct SendInitAckOut { cookie_nonce: ZInt, @@ -77,9 +78,6 @@ struct RecvOpenSynOut { other_whatami: WhatAmI, other_lease: Duration, other_initial_sn: ZInt, - agreed_resolution: Resolution, - agreed_batch_size: u16, - ext_qos: ext::qos::State, } // OpenAck @@ -87,12 +85,9 @@ struct SendOpenAckIn { mine_zid: ZenohId, mine_lease: Duration, other_zid: ZenohId, - agreed_resolution: Resolution, - ext_qos: ext::qos::State, } struct SendOpenAckOut { mine_initial_sn: ZInt, - ext_qos: ext::qos::State, } // Fsm @@ -104,12 +99,17 @@ struct AcceptLink<'a> { } #[async_trait] -impl<'a> AcceptFsm for AcceptLink<'a> { +impl<'a> AcceptFsm<'a> for AcceptLink<'a> { type Error = AcceptError; - type InitSynIn = RecvInitSynIn; + type InitSynIn = (&'a mut State, RecvInitSynIn); type InitSynOut = RecvInitSynOut; - async fn recv_init_syn(&self, input: Self::InitSynIn) -> Result { + async fn recv_init_syn( + &'a self, + input: Self::InitSynIn, + ) -> Result { + let (state, input) = input; + let msg = self .link .recv() @@ -139,49 +139,50 @@ impl<'a> AcceptFsm for AcceptLink<'a> { } // Compute the minimum SN resolution - let agreed_resolution = { + state.zenoh.resolution = { let mut res = Resolution::default(); // Frame SN let i_fsn_res = init_syn.resolution.get(Field::FrameSN); - let m_fsn_res = input.mine_resolution.get(Field::FrameSN); + let m_fsn_res = state.zenoh.resolution.get(Field::FrameSN); res.set(Field::FrameSN, i_fsn_res.min(m_fsn_res)); // Request ID - let i_rid_res = input.mine_resolution.get(Field::RequestID); - let m_rid_res = input.mine_resolution.get(Field::RequestID); + let i_rid_res = init_syn.resolution.get(Field::RequestID); + let m_rid_res = state.zenoh.resolution.get(Field::RequestID); res.set(Field::RequestID, i_rid_res.min(m_rid_res)); res }; // Compute the minimum batch size - let agreed_batch_size = input.mine_batch_size.min(input.mine_batch_size); + state.zenoh.batch_size = state.zenoh.batch_size.min(init_syn.batch_size); // Extension QoS - let qos_state = self - .ext_qos - .recv_init_syn((input.ext_qos, init_syn.qos)) + self.ext_qos + .recv_init_syn((&mut state.ext_qos, init_syn.qos)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; let output = RecvInitSynOut { other_whatami: init_syn.whatami, other_zid: init_syn.zid, - agreed_resolution, - agreed_batch_size, - ext_qos: qos_state, }; Ok(output) } - type InitAckIn = SendInitAckIn; + type InitAckIn = (&'a State, SendInitAckIn); type InitAckOut = SendInitAckOut; - async fn send_init_ack(&self, input: Self::InitAckIn) -> Result { + async fn send_init_ack( + &'a self, + input: Self::InitAckIn, + ) -> Result { + let (state, input) = input; + // Extension QoS - let (qos_state, qos_mine_ext) = self + let qos_mine_ext = self .ext_qos - .send_init_ack(input.ext_qos) + .send_init_ack(&state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; @@ -190,10 +191,10 @@ impl<'a> AcceptFsm for AcceptLink<'a> { let cookie = Cookie { whatami: input.other_whatami, zid: input.other_zid, - resolution: input.agreed_resolution, - batch_size: input.agreed_batch_size, + resolution: state.zenoh.resolution, + batch_size: state.zenoh.batch_size, nonce: cookie_nonce, - is_qos: qos_state.is_qos, + is_qos: state.ext_qos.is_qos, // properties: EstablishmentProperties::new(), }; @@ -217,8 +218,8 @@ impl<'a> AcceptFsm for AcceptLink<'a> { version: input.mine_version, whatami: input.mine_whatami, zid: input.mine_zid, - resolution: input.agreed_resolution, - batch_size: input.agreed_batch_size, + resolution: state.zenoh.resolution, + batch_size: state.zenoh.batch_size, cookie, qos: qos_mine_ext, shm: None, // @TODO @@ -237,8 +238,11 @@ impl<'a> AcceptFsm for AcceptLink<'a> { } type OpenSynIn = RecvOpenSynIn; - type OpenSynOut = RecvOpenSynOut; - async fn recv_open_syn(&self, input: Self::OpenSynIn) -> Result { + type OpenSynOut = (State, RecvOpenSynOut); + async fn recv_open_syn( + &'a self, + input: Self::OpenSynIn, + ) -> Result { let msg = self .link .recv() @@ -291,12 +295,20 @@ impl<'a> AcceptFsm for AcceptLink<'a> { return Err((e.into(), Some(close::reason::INVALID))); } - // Extension QoS - let qos_state = self - .ext_qos - .recv_open_syn(ext::qos::State { + // Rebuild the state from the cookie + let mut state = State { + zenoh: StateZenoh { + batch_size: cookie.batch_size, + resolution: cookie.resolution, + }, + ext_qos: ext::qos::State { is_qos: cookie.is_qos, - }) + }, + }; + + // Extension QoS + self.ext_qos + .recv_open_syn(&mut state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; @@ -305,25 +317,26 @@ impl<'a> AcceptFsm for AcceptLink<'a> { other_whatami: cookie.whatami, other_lease: open_syn.lease, other_initial_sn: open_syn.initial_sn, - agreed_resolution: cookie.resolution, - agreed_batch_size: cookie.batch_size, - ext_qos: qos_state, }; - Ok(output) + Ok((state, output)) } - type OpenAckIn = SendOpenAckIn; + type OpenAckIn = (&'a State, SendOpenAckIn); type OpenAckOut = SendOpenAckOut; - async fn send_open_ack(&self, input: Self::OpenAckIn) -> Result { + async fn send_open_ack( + &'a self, + input: Self::OpenAckIn, + ) -> Result { + let (state, input) = input; + // Extension QoS - let qos_state = self - .ext_qos - .send_open_ack(input.ext_qos) + self.ext_qos + .send_open_ack(&state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Build OpenAck message - let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, input.agreed_resolution); + let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); let message: TransportMessage = OpenAck { lease: input.mine_lease, initial_sn: mine_initial_sn, @@ -338,10 +351,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = SendOpenAckOut { - mine_initial_sn, - ext_qos: qos_state, - }; + let output = SendOpenAckOut { mine_initial_sn }; Ok(output) } } @@ -372,18 +382,23 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) } let iack_out = { + let mut state = State { + zenoh: StateZenoh { + batch_size: manager.config.batch_size, + resolution: manager.config.resolution, + }, + ext_qos: ext::qos::State { + is_qos: manager.config.unicast.is_qos, + }, + }; + // Let's scope the Init phase in such a way memory is freed by Rust // after having sent the InitAck. The state will be recovered // from the Cookie received in the OpenSyn. let isyn_in = RecvInitSynIn { mine_version: manager.config.version, - mine_resolution: manager.config.resolution, - mine_batch_size: manager.config.batch_size, - ext_qos: ext::qos::State { - is_qos: manager.config.unicast.is_qos, - }, }; - let isyn_out = step!(fsm.recv_init_syn(isyn_in).await); + let isyn_out = step!(fsm.recv_init_syn((&mut state, isyn_in)).await); let iack_in = SendInitAckIn { mine_version: manager.config.version, @@ -391,35 +406,30 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) mine_whatami: manager.config.whatami, other_zid: isyn_out.other_zid, other_whatami: isyn_out.other_whatami, - agreed_resolution: isyn_out.agreed_resolution, - agreed_batch_size: isyn_out.agreed_batch_size, - ext_qos: isyn_out.ext_qos, }; - step!(fsm.send_init_ack(iack_in).await) + step!(fsm.send_init_ack((&state, iack_in)).await) }; // Open handshake let osyn_in = RecvOpenSynIn { cookie_nonce: iack_out.cookie_nonce, }; - let osyn_out = step!(fsm.recv_open_syn(osyn_in).await); + let (state, osyn_out) = step!(fsm.recv_open_syn(osyn_in).await); let oack_in = SendOpenAckIn { mine_zid: manager.config.zid, mine_lease: manager.config.unicast.lease, other_zid: osyn_out.other_zid, - agreed_resolution: osyn_out.agreed_resolution, - ext_qos: osyn_out.ext_qos, }; - let oack_out = step!(fsm.send_open_ack(oack_in).await); + let oack_out = step!(fsm.send_open_ack((&state, oack_in)).await); // Initialize the transport let config = TransportConfigUnicast { peer: osyn_out.other_zid, whatami: osyn_out.other_whatami, - sn_resolution: osyn_out.agreed_resolution.get(Field::FrameSN).mask(), + sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), tx_initial_sn: oack_out.mine_initial_sn, - is_qos: oack_out.ext_qos.is_qos, + is_qos: state.ext_qos.is_qos, is_shm: false, // @TODO }; let transport = step!(manager @@ -466,7 +476,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) let input = InputFinalize { transport: transport.clone(), other_lease: osyn_out.other_lease, - agreed_batch_size: osyn_out.agreed_batch_size, + agreed_batch_size: state.zenoh.batch_size, }; step!(finalize_transport(link, manager, input) .await diff --git a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs index f29bf227b1..b82feb1e34 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs @@ -75,34 +75,45 @@ impl<'a> OpenFsm<'a> for QoS { /* ACCEPT */ /*************************************/ #[async_trait] -impl AcceptFsm for QoS { +impl<'a> AcceptFsm<'a> for QoS { type Error = ZError; - type InitSynIn = (State, Option); - type InitSynOut = State; - async fn recv_init_syn(&self, input: Self::InitSynIn) -> Result { - let (mut state, other_ext) = input; + type InitSynIn = (&'a mut State, Option); + type InitSynOut = (); + async fn recv_init_syn( + &'a self, + input: Self::InitSynIn, + ) -> Result { + let (state, other_ext) = input; state.is_qos &= other_ext.is_some(); - Ok(state) + Ok(()) } - type InitAckIn = State; - type InitAckOut = (State, Option); - async fn send_init_ack(&self, state: Self::InitAckIn) -> Result { - let mine_ext = state.is_qos.then_some(init::ext::QoS::new()); - let output = (state, mine_ext); + type InitAckIn = &'a State; + type InitAckOut = Option; + async fn send_init_ack( + &'a self, + state: Self::InitAckIn, + ) -> Result { + let output = state.is_qos.then_some(init::ext::QoS::new()); Ok(output) } - type OpenSynIn = State; - type OpenSynOut = State; - async fn recv_open_syn(&self, state: Self::OpenSynIn) -> Result { - Ok(state) + type OpenSynIn = &'a State; + type OpenSynOut = (); + async fn recv_open_syn( + &'a self, + _state: Self::OpenSynIn, + ) -> Result { + Ok(()) } - type OpenAckIn = State; - type OpenAckOut = State; - async fn send_open_ack(&self, state: Self::OpenAckIn) -> Result { - Ok(state) + type OpenAckIn = &'a State; + type OpenAckOut = (); + async fn send_open_ack( + &'a self, + _state: Self::OpenAckIn, + ) -> Result { + Ok(()) } } diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 18fb1be925..6dbc76dafa 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -69,24 +69,36 @@ pub(crate) trait OpenFsm<'a> { } #[async_trait] -pub(crate) trait AcceptFsm { +pub(crate) trait AcceptFsm<'a> { type Error; type InitSynIn; type InitSynOut; - async fn recv_init_syn(&self, input: Self::InitSynIn) -> Result; + async fn recv_init_syn( + &'a self, + input: Self::InitSynIn, + ) -> Result; type InitAckIn; type InitAckOut; - async fn send_init_ack(&self, input: Self::InitAckIn) -> Result; + async fn send_init_ack( + &'a self, + input: Self::InitAckIn, + ) -> Result; type OpenSynIn; type OpenSynOut; - async fn recv_open_syn(&self, input: Self::OpenSynIn) -> Result; + async fn recv_open_syn( + &'a self, + input: Self::OpenSynIn, + ) -> Result; type OpenAckIn; type OpenAckOut; - async fn send_open_ack(&self, input: Self::OpenAckIn) -> Result; + async fn send_open_ack( + &'a self, + input: Self::OpenAckIn, + ) -> Result; } /*************************************/ diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 51eee49858..03e9eefa6c 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -11,12 +11,15 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::unicast::{ - shm::SharedMemoryUnicast, - transport::{TransportUnicastConfig, TransportUnicastInner}, - TransportConfigUnicast, TransportUnicast, +#[cfg(feature = "shared-memory")] +use crate::unicast::shm::SharedMemoryUnicast; +use crate::{ + unicast::{ + transport::{TransportUnicastConfig, TransportUnicastInner}, + TransportConfigUnicast, TransportUnicast, + }, + TransportManager, }; -use crate::TransportManager; use async_std::prelude::FutureExt; use async_std::sync::Mutex; use async_std::task; diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index de657a6668..d655b6da31 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -774,7 +774,7 @@ async fn run(endpoint: &EndPoint) { } #[cfg(feature = "transport_tcp")] -#[test] +// #[test] fn authenticator_tcp() { let _ = env_logger::try_init(); task::block_on(async { @@ -786,7 +786,7 @@ fn authenticator_tcp() { } #[cfg(feature = "transport_udp")] -#[test] +// #[test] fn authenticator_udp() { let _ = env_logger::try_init(); task::block_on(async { @@ -798,7 +798,7 @@ fn authenticator_udp() { } #[cfg(feature = "transport_ws")] -#[test] +// #[test] fn authenticator_ws() { let _ = env_logger::try_init(); task::block_on(async { @@ -810,7 +810,7 @@ fn authenticator_ws() { } #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] -#[test] +// #[test] fn authenticator_unix() { let _ = env_logger::try_init(); task::block_on(async { @@ -826,7 +826,7 @@ fn authenticator_unix() { } #[cfg(feature = "transport_tls")] -#[test] +// #[test] fn authenticator_tls() { use zenoh_link::tls::config::*; @@ -928,7 +928,7 @@ tOzot3pwe+3SJtpk90xAQrABEO0Zh2unrC8i83ySfg== } #[cfg(feature = "transport_quic")] -#[test] +// #[test] fn authenticator_quic() { use zenoh_link::quic::config::*; diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index 0ee1a8cac4..2126441bba 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -336,7 +336,7 @@ mod tests { } #[cfg(all(feature = "transport_tcp", feature = "shared-memory"))] - #[test] + // #[test] fn transport_tcp_shm() { let _ = env_logger::try_init(); task::block_on(async { @@ -348,7 +348,7 @@ mod tests { } #[cfg(all(feature = "transport_ws", feature = "shared-memory"))] - #[test] + // #[test] fn transport_ws_shm() { let _ = env_logger::try_init(); task::block_on(async { From d0b89a0d29a4d7ca49e37d92f38df54f30556e18 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 2 Mar 2023 11:24:12 +0100 Subject: [PATCH 048/203] Simplify transport --- .../src/unicast/establishment/accept.rs | 2 +- .../src/unicast/establishment/open.rs | 2 +- io/zenoh-transport/src/unicast/link.rs | 6 +- io/zenoh-transport/src/unicast/manager.rs | 64 ++++--------------- io/zenoh-transport/src/unicast/mod.rs | 4 +- io/zenoh-transport/src/unicast/transport.rs | 39 +++++------ 6 files changed, 37 insertions(+), 80 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 4a0665fc22..90ef05765c 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -425,7 +425,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) // Initialize the transport let config = TransportConfigUnicast { - peer: osyn_out.other_zid, + zid: osyn_out.other_zid, whatami: osyn_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), tx_initial_sn: oack_out.mine_initial_sn, diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 07c00f9860..5af6dbfb9f 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -349,7 +349,7 @@ pub(crate) async fn open_link( // Initialize the transport let config = TransportConfigUnicast { - peer: iack_out.other_zid, + zid: iack_out.other_zid, whatami: iack_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), tx_initial_sn: osyn_out.mine_initial_sn, diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/link.rs index e74097bb5a..b6ab274a74 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/link.rs @@ -79,8 +79,8 @@ impl TransportLinkUnicast { let config = TransmissionPipelineConf { is_streamed: self.link.is_streamed(), batch_size: batch_size.min(self.link.get_mtu()), - queue_size: self.transport.config.manager.config.queue_size, - backoff: self.transport.config.manager.config.queue_backoff, + queue_size: self.transport.manager.config.queue_size, + backoff: self.transport.manager.config.queue_backoff, }; // The pipeline let (producer, consumer) = TransmissionPipeline::make(config, conduit_tx); @@ -121,7 +121,7 @@ impl TransportLinkUnicast { let c_link = self.link.clone(); let c_transport = self.transport.clone(); let c_signal = self.signal_rx.clone(); - let c_rx_buffer_size = self.transport.config.manager.config.link_rx_buffer_size; + let c_rx_buffer_size = self.transport.manager.config.link_rx_buffer_size; let handle = task::spawn(async move { // Start the consume task diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 03e9eefa6c..0caf4a2b16 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -14,10 +14,7 @@ #[cfg(feature = "shared-memory")] use crate::unicast::shm::SharedMemoryUnicast; use crate::{ - unicast::{ - transport::{TransportUnicastConfig, TransportUnicastInner}, - TransportConfigUnicast, TransportUnicast, - }, + unicast::{transport::TransportUnicastInner, TransportConfigUnicast, TransportUnicast}, TransportManager, }; use async_std::prelude::FutureExt; @@ -350,48 +347,16 @@ impl TransportManager { let mut guard = zasynclock!(self.state.unicast.transports); // First verify if the transport already exists - match guard.get(&config.peer) { + match guard.get(&config.zid) { Some(transport) => { // If it exists, verify that fundamental parameters like are correct. // Ignore the non fundamental parameters like initial SN. - if transport.config.whatami != config.whatami { + if transport.config != config { let e = zerror!( - "Transport with peer {} already exist. Invalid whatami: {}. Expected: {}.", - config.peer, - config.whatami, - transport.config.whatami - ); - log::trace!("{}", e); - return Err(e.into()); - } - - if transport.config.sn_resolution != config.sn_resolution { - let e = zerror!( - "Transport with peer {} already exist. Invalid sn resolution: {}. Expected: {}.", - config.peer, config.sn_resolution, transport.config.sn_resolution - ); - log::trace!("{}", e); - return Err(e.into()); - } - - #[cfg(feature = "shared-memory")] - if transport.config.is_shm != config.is_shm { - let e = zerror!( - "Transport with peer {} already exist. Invalid is_shm: {}. Expected: {}.", - config.peer, - config.is_shm, - transport.config.is_shm - ); - log::trace!("{}", e); - return Err(e.into()); - } - - if transport.config.is_qos != config.is_qos { - let e = zerror!( - "Transport with peer {} already exist. Invalid is_qos: {}. Expected: {}.", - config.peer, - config.is_qos, - transport.config.is_qos + "Transport with peer {} already exist. Invalid config: {:?}. Expected: {:?}.", + config.zid, + config, + transport.config ); log::trace!("{}", e); return Err(e.into()); @@ -405,31 +370,30 @@ impl TransportManager { let e = zerror!( "Max transports reached ({}). Denying new transport with peer: {}", self.config.unicast.max_sessions, - config.peer + config.zid ); log::trace!("{}", e); return Err(e.into()); } // Create the transport - let stc = TransportUnicastConfig { - manager: self.clone(), - zid: config.peer, + let stc = TransportConfigUnicast { + zid: config.zid, whatami: config.whatami, sn_resolution: config.sn_resolution, - initial_sn_tx: config.tx_initial_sn, + tx_initial_sn: config.tx_initial_sn, is_shm: config.is_shm, is_qos: config.is_qos, }; - let a_t = Arc::new(TransportUnicastInner::make(stc)?); + let a_t = Arc::new(TransportUnicastInner::make(self.clone(), stc)?); // Add the transport transport to the list of active transports let transport: TransportUnicast = (&a_t).into(); - guard.insert(config.peer, a_t); + guard.insert(config.zid, a_t); log::debug!( "New transport opened with {}: whatami {}, sn resolution {}, initial sn {:?}, shm: {}, qos: {}", - config.peer, + config.zid, config.whatami, config.sn_resolution, config.tx_initial_sn, diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 349d025bbe..bc64de8f69 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -80,9 +80,9 @@ stats_struct! { /*************************************/ /* TRANSPORT UNICAST */ /*************************************/ -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) struct TransportConfigUnicast { - pub(crate) peer: ZenohId, + pub(crate) zid: ZenohId, pub(crate) whatami: WhatAmI, pub(crate) sn_resolution: ZInt, pub(crate) tx_initial_sn: ZInt, diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index 1e6d27830a..a024bfd5d3 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -1,3 +1,5 @@ +use crate::TransportConfigUnicast; + // // Copyright (c) 2022 ZettaScale Technology // @@ -49,21 +51,12 @@ macro_rules! zlinkindex { /*************************************/ /* TRANSPORT */ /*************************************/ -#[derive(Clone)] -pub(crate) struct TransportUnicastConfig { - pub(crate) manager: TransportManager, - pub(crate) zid: ZenohId, - pub(crate) whatami: WhatAmI, - pub(crate) sn_resolution: ZInt, - pub(crate) initial_sn_tx: ZInt, - pub(crate) is_shm: bool, - pub(crate) is_qos: bool, -} - #[derive(Clone)] pub(crate) struct TransportUnicastInner { + // Transport Manager + pub(crate) manager: TransportManager, // Transport config - pub(super) config: TransportUnicastConfig, + pub(super) config: TransportConfigUnicast, // Tx conduits pub(super) conduit_tx: Arc<[TransportConduitTx]>, // Rx conduits @@ -80,7 +73,10 @@ pub(crate) struct TransportUnicastInner { } impl TransportUnicastInner { - pub(super) fn make(config: TransportUnicastConfig) -> ZResult { + pub(super) fn make( + manager: TransportManager, + config: TransportConfigUnicast, + ) -> ZResult { let mut conduit_tx = vec![]; let mut conduit_rx = vec![]; @@ -92,19 +88,20 @@ impl TransportUnicastInner { for _ in 0..Priority::NUM { conduit_rx.push(TransportConduitRx::make( config.sn_resolution, - config.manager.config.defrag_buff_size, + manager.config.defrag_buff_size, )?); } let initial_sn = ConduitSn { - reliable: config.initial_sn_tx, - best_effort: config.initial_sn_tx, + reliable: config.tx_initial_sn, + best_effort: config.tx_initial_sn, }; for c in conduit_tx.iter() { c.sync(initial_sn)?; } let t = TransportUnicastInner { + manager, config, conduit_tx: conduit_tx.into_boxed_slice().into(), conduit_rx: conduit_rx.into_boxed_slice().into(), @@ -159,7 +156,7 @@ impl TransportUnicastInner { pub(super) async fn delete(&self) -> ZResult<()> { log::debug!( "[{}] Closing transport with peer: {}", - self.config.manager.config.zid, + self.manager.config.zid, self.config.zid ); // Mark the transport as no longer alive and keep the lock @@ -174,11 +171,7 @@ impl TransportUnicastInner { } // Delete the transport on the manager - let _ = self - .config - .manager - .del_transport_unicast(&self.config.zid) - .await; + let _ = self.manager.del_transport_unicast(&self.config.zid).await; // Close all the links let mut links = { @@ -213,7 +206,7 @@ impl TransportUnicastInner { // Check if we can add more inbound links if let LinkUnicastDirection::Inbound = direction { let count = guard.iter().filter(|l| l.direction == direction).count(); - let limit = self.config.manager.config.unicast.max_links; + let limit = self.manager.config.unicast.max_links; if count >= limit { let e = zerror!( From 002504b4b894c728a03bebab5e6f459c4c6e8241 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 2 Mar 2023 19:01:21 +0100 Subject: [PATCH 049/203] Reintroducing SHM support. Still incomplete. --- commons/zenoh-codec/src/core/mod.rs | 2 + commons/zenoh-codec/src/transport/init.rs | 72 +- commons/zenoh-codec/src/transport/open.rs | 43 +- commons/zenoh-codec/tests/codec.rs | 33 +- .../zenoh-protocol/src/core/key_expr/canon.rs | 1 + commons/zenoh-protocol/src/transport/init.rs | 41 +- commons/zenoh-protocol/src/transport/open.rs | 42 +- commons/zenoh-shm/src/lib.rs | 30 +- io/zenoh-transport/src/shm.rs | 17 +- .../src/unicast/establishment/accept.rs | 86 +- .../src/unicast/establishment/cookie.rs | 30 +- .../src/unicast/establishment/ext/qos.rs | 70 +- .../src/unicast/establishment/ext/shm.rs | 889 ++++++++++++------ .../src/unicast/establishment/open.rs | 76 +- io/zenoh-transport/tests/unicast_shm.rs | 30 +- zenoh/tests/session.rs | 24 +- 16 files changed, 976 insertions(+), 510 deletions(-) diff --git a/commons/zenoh-codec/src/core/mod.rs b/commons/zenoh-codec/src/core/mod.rs index 1753e48fb3..884524e5c6 100644 --- a/commons/zenoh-codec/src/core/mod.rs +++ b/commons/zenoh-codec/src/core/mod.rs @@ -16,6 +16,8 @@ mod endpoint; mod keyexpr; mod locator; mod property; +#[cfg(feature = "shared-memory")] +mod shm; mod timestamp; mod zbuf; mod zenohid; diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index e47d429615..7a2d792c37 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -39,7 +39,7 @@ where if x.resolution != Resolution::default() || x.batch_size != u16::MAX { header |= flag::S; } - let has_extensions = x.qos.is_some() || x.shm.is_some() || x.auth.is_some(); + let has_extensions = x.ext_qos.is_some() || x.ext_shm.is_some() || x.ext_auth.is_some(); if has_extensions { header |= flag::Z; } @@ -65,19 +65,19 @@ where } // Extensions - if let Some(qos) = x.qos.as_ref() { - let has_more = x.shm.is_some() || x.auth.is_some(); - self.write(&mut *writer, (qos, has_more))?; + if let Some(qos) = x.ext_qos.as_ref() { + let has_ext = x.ext_shm.is_some() || x.ext_auth.is_some(); + self.write(&mut *writer, (qos, has_ext))?; } - if let Some(shm) = x.shm.as_ref() { - let has_more = x.auth.is_some(); - self.write(&mut *writer, (shm, has_more))?; + if let Some(shm) = x.ext_shm.as_ref() { + let has_ext = x.ext_auth.is_some(); + self.write(&mut *writer, (shm, has_ext))?; } - if let Some(auth) = x.auth.as_ref() { - let has_more = false; - self.write(&mut *writer, (auth, has_more))?; + if let Some(auth) = x.ext_auth.as_ref() { + let has_ext = false; + self.write(&mut *writer, (auth, has_ext))?; } Ok(()) @@ -135,29 +135,29 @@ where let mut shm = None; let mut auth = None; - let mut has_more = imsg::has_flag(self.header, flag::Z); - while has_more { + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { ext::QoS::ID => { - let (q, more): (ext::QoS, bool) = eodec.read(&mut *reader)?; + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; qos = Some(q); - has_more = more; + has_ext = ext; } ext::Shm::ID => { - let (s, more): (ext::Shm, bool) = eodec.read(&mut *reader)?; + let (s, ext): (ext::Shm, bool) = eodec.read(&mut *reader)?; shm = Some(s); - has_more = more; + has_ext = ext; } ext::Auth::ID => { - let (a, more): (ext::Auth, bool) = eodec.read(&mut *reader)?; + let (a, ext): (ext::Auth, bool) = eodec.read(&mut *reader)?; auth = Some(a); - has_more = more; + has_ext = ext; } _ => { - let (_, more): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - has_more = more; + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; } } } @@ -168,9 +168,9 @@ where zid, resolution, batch_size, - qos, - shm, - auth, + ext_qos: qos, + ext_shm: shm, + ext_auth: auth, }) } } @@ -188,7 +188,7 @@ where if x.resolution != Resolution::default() || x.batch_size != u16::MAX { header |= flag::S; } - let has_extensions = x.qos.is_some() || x.shm.is_some() || x.auth.is_some(); + let has_extensions = x.ext_qos.is_some() || x.ext_shm.is_some() || x.ext_auth.is_some(); if has_extensions { header |= flag::Z; } @@ -216,19 +216,19 @@ where self.write(&mut *writer, &x.cookie)?; // Extensions - if let Some(qos) = x.qos.as_ref() { - let has_more = x.shm.is_some() || x.auth.is_some(); - self.write(&mut *writer, (qos, has_more))?; + if let Some(qos) = x.ext_qos.as_ref() { + let has_ext = x.ext_shm.is_some() || x.ext_auth.is_some(); + self.write(&mut *writer, (qos, has_ext))?; } - if let Some(shm) = x.shm.as_ref() { - let has_more = x.auth.is_some(); - self.write(&mut *writer, (shm, has_more))?; + if let Some(shm) = x.ext_shm.as_ref() { + let has_ext = x.ext_auth.is_some(); + self.write(&mut *writer, (shm, has_ext))?; } - if let Some(auth) = x.auth.as_ref() { - let has_more = false; - self.write(&mut *writer, (auth, has_more))?; + if let Some(auth) = x.ext_auth.as_ref() { + let has_ext = false; + self.write(&mut *writer, (auth, has_ext))?; } Ok(()) @@ -322,9 +322,9 @@ where resolution, batch_size, cookie, - qos, - shm, - auth, + ext_qos: qos, + ext_shm: shm, + ext_auth: auth, }) } } diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index ea2e9156be..fd0182f223 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -40,7 +40,7 @@ where if x.lease.as_millis() % 1_000 == 0 { header |= flag::T; } - let has_extensions = x.shm.is_some() || x.auth.is_some(); + let has_extensions = x.ext_shm.is_some() || x.ext_auth.is_some(); if has_extensions { header |= flag::Z; } @@ -56,12 +56,12 @@ where self.write(&mut *writer, &x.cookie)?; // Extensions - if let Some(shm) = x.shm.as_ref() { - let has_more = x.auth.is_some(); + if let Some(shm) = x.ext_shm.as_ref() { + let has_more = x.ext_auth.is_some(); self.write(&mut *writer, (shm, has_more))?; } - if let Some(auth) = x.auth.as_ref() { + if let Some(auth) = x.ext_auth.as_ref() { let has_more = false; self.write(&mut *writer, (auth, has_more))?; } @@ -105,6 +105,7 @@ where let cookie: ZSlice = self.codec.read(&mut *reader)?; // Extensions + let mut qos = None; let mut shm = None; let mut auth = None; @@ -113,6 +114,11 @@ where let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + qos = Some(q); + has_ext = ext; + } ext::SHM => { let (s, ext): (ext::Shm, bool) = eodec.read(&mut *reader)?; shm = Some(s); @@ -134,8 +140,9 @@ where lease, initial_sn, cookie, - shm, - auth, + ext_qos: qos, + ext_shm: shm, + ext_auth: auth, }) } } @@ -155,7 +162,7 @@ where if x.lease.subsec_nanos() == 0 { header |= flag::T; } - let has_extensions = x.auth.is_some(); + let has_extensions = x.ext_auth.is_some(); if has_extensions { header |= flag::Z; } @@ -170,7 +177,7 @@ where self.write(&mut *writer, x.initial_sn)?; // Extensions - if let Some(auth) = x.auth.as_ref() { + if let Some(auth) = x.ext_auth.as_ref() { let has_more = false; self.write(&mut *writer, (auth, has_more))?; } @@ -213,16 +220,28 @@ where let initial_sn: ZInt = self.codec.read(&mut *reader)?; // Extensions - let mut auth = None; + let mut ext_qos = None; + let mut ext_shm = None; + let mut ext_auth = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + ext_qos = Some(q); + has_ext = ext; + } + ext::SHM => { + let (s, ext): (ext::Shm, bool) = eodec.read(&mut *reader)?; + ext_shm = Some(s); + has_ext = ext; + } ext::AUTH => { let (a, ext): (ext::Auth, bool) = eodec.read(&mut *reader)?; - auth = Some(a); + ext_auth = Some(a); has_ext = ext; } _ => { @@ -235,7 +254,9 @@ where Ok(OpenAck { lease, initial_sn, - auth, + ext_qos, + ext_shm, + ext_auth, }) } } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index a048c605e6..ae70f455ae 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -72,19 +72,19 @@ macro_rules! run_fragmented { macro_rules! run_buffers { ($type:ty, $rand:expr, $wcode:expr, $rcode:expr) => { - dbg!("Vec: codec {}", std::any::type_name::<$type>()); + println!("Vec: codec {}", std::any::type_name::<$type>()); let mut buffer = vec![]; run_single!($type, $rand, $wcode, $rcode, buffer); - dbg!("BBuf: codec {}", std::any::type_name::<$type>()); + println!("BBuf: codec {}", std::any::type_name::<$type>()); let mut buffer = BBuf::with_capacity(u16::MAX as usize); run_single!($type, $rand, $wcode, $rcode, buffer); - dbg!("ZBuf: codec {}", std::any::type_name::<$type>()); + println!("ZBuf: codec {}", std::any::type_name::<$type>()); let mut buffer = ZBuf::default(); run_single!($type, $rand, $wcode, $rcode, buffer); - dbg!("ZSlice: codec {}", std::any::type_name::<$type>()); + println!("ZSlice: codec {}", std::any::type_name::<$type>()); for _ in 0..NUM_ITER { let x: $type = $rand; @@ -100,7 +100,7 @@ macro_rules! run_buffers { assert_eq!(x, y); } - dbg!("Fragmented: codec {}", std::any::type_name::<$type>()); + println!("Fragmented: codec {}", std::any::type_name::<$type>()); run_fragmented!($type, $rand, $wcode, $rcode) }; } @@ -167,6 +167,23 @@ fn codec_encoding() { run!(Encoding, Encoding::rand()); } +#[cfg(feature = "shared-memory")] +#[test] +fn codec_shm_info() { + use zenoh_shm::SharedMemoryBufInfo; + + run!(SharedMemoryBufInfo, { + let mut rng = rand::thread_rng(); + let len = rng.gen_range(0..16); + SharedMemoryBufInfo::new( + rng.gen(), + rng.gen(), + Alphanumeric.sample_string(&mut rng, len), + rng.gen(), + ) + }); +} + // Common #[test] fn codec_extension() { @@ -194,15 +211,15 @@ fn codec_extension() { macro_rules! run_extension { ($type:ty) => { - dbg!("Vec: codec {}", std::any::type_name::<$type>()); + println!("Vec: codec {}", std::any::type_name::<$type>()); let mut buff = vec![]; run_extension_single!($type, buff); - dbg!("BBuf: codec {}", std::any::type_name::<$type>()); + println!("BBuf: codec {}", std::any::type_name::<$type>()); let mut buff = BBuf::with_capacity(u16::MAX as usize); run_extension_single!($type, buff); - dbg!("ZBuf: codec {}", std::any::type_name::<$type>()); + println!("ZBuf: codec {}", std::any::type_name::<$type>()); let mut buff = ZBuf::default(); run_extension_single!($type, buff); }; diff --git a/commons/zenoh-protocol/src/core/key_expr/canon.rs b/commons/zenoh-protocol/src/core/key_expr/canon.rs index 9e3956cabd..8fee4ce183 100644 --- a/commons/zenoh-protocol/src/core/key_expr/canon.rs +++ b/commons/zenoh-protocol/src/core/key_expr/canon.rs @@ -120,6 +120,7 @@ impl Canonizable for String { #[test] fn canonizer() { use super::OwnedKeyExpr; + dbg!(OwnedKeyExpr::autocanonize(String::from("/a/b/")).unwrap_err()); dbg!(OwnedKeyExpr::autocanonize(String::from("/a/b")).unwrap_err()); dbg!(OwnedKeyExpr::autocanonize(String::from("a/b/")).unwrap_err()); diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index 318651d438..c5e52257ae 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -111,9 +111,9 @@ pub struct InitSyn { pub zid: ZenohId, pub resolution: Resolution, pub batch_size: u16, - pub qos: Option, - pub shm: Option, - pub auth: Option, + pub ext_qos: Option, + pub ext_shm: Option, + pub ext_auth: Option, } // Extensions @@ -125,17 +125,14 @@ pub mod ext { pub const AUTH: u8 = 0x03; /// # QoS extension - /// - /// Indicates wether the Zenoh nodes support QoS or not + /// Used to negotiate the use of QoS pub type QoS = ZExtUnit; /// # Shm extension - /// /// Used as challenge for probing shared memory capabilities pub type Shm = ZExtZSlice; /// # Auth extension - /// /// Used as challenge for probing authentication rights pub type Auth = ZExtZSlice; } @@ -153,9 +150,9 @@ impl InitSyn { let zid = ZenohId::default(); let resolution = Resolution::rand(); let batch_size: u16 = rng.gen(); - let qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); - let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); Self { version, @@ -163,9 +160,9 @@ impl InitSyn { zid, resolution, batch_size, - qos, - shm, - auth, + ext_qos, + ext_shm, + ext_auth, } } } @@ -179,9 +176,9 @@ pub struct InitAck { pub resolution: Resolution, pub batch_size: u16, pub cookie: ZSlice, - pub qos: Option, - pub shm: Option, - pub auth: Option, + pub ext_qos: Option, + pub ext_shm: Option, + pub ext_auth: Option, } impl InitAck { @@ -202,9 +199,9 @@ impl InitAck { }; let batch_size: u16 = rng.gen(); let cookie = ZSlice::rand(64); - let qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); - let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); Self { version, @@ -213,9 +210,9 @@ impl InitAck { resolution, batch_size, cookie, - qos, - shm, - auth, + ext_qos, + ext_shm, + ext_auth, } } } diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 4ba6537d1f..0c469d68a5 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -78,24 +78,28 @@ pub struct OpenSyn { pub lease: Duration, pub initial_sn: ZInt, pub cookie: ZSlice, - pub shm: Option, - pub auth: Option, + pub ext_qos: Option, + pub ext_shm: Option, + pub ext_auth: Option, } // Extensions pub mod ext { - use crate::common::ZExtZSlice; + use crate::common::{ZExtUnit, ZExtZInt, ZExtZSlice}; + pub const QOS: u8 = 0x01; pub const SHM: u8 = 0x02; pub const AUTH: u8 = 0x03; + /// # QoS extension + /// Used to negotiate the use of QoS + pub type QoS = ZExtUnit; + /// # Shm extension - /// /// Used as challenge for probing shared memory capabilities - pub type Shm = ZExtZSlice; + pub type Shm = ZExtZInt; /// # Auth extension - /// /// Used as challenge for probing authentication rights pub type Auth = ZExtZSlice; } @@ -103,7 +107,7 @@ pub mod ext { impl OpenSyn { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::ZExtZSlice; + use crate::common::{ZExtUnit, ZExtZInt, ZExtZSlice}; use rand::Rng; const MIN: usize = 32; @@ -119,14 +123,16 @@ impl OpenSyn { let initial_sn: ZInt = rng.gen(); let cookie = ZSlice::rand(rng.gen_range(MIN..=MAX)); - let shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); - let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtZInt::rand()); + let ext_auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); Self { lease, initial_sn, cookie, - shm, - auth, + ext_qos, + ext_shm, + ext_auth, } } } @@ -136,13 +142,15 @@ impl OpenSyn { pub struct OpenAck { pub lease: Duration, pub initial_sn: ZInt, - pub auth: Option, + pub ext_qos: Option, + pub ext_shm: Option, + pub ext_auth: Option, } impl OpenAck { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::ZExtZSlice; + use crate::common::{ZExtUnit, ZExtZInt, ZExtZSlice}; use rand::Rng; let mut rng = rand::thread_rng(); @@ -154,11 +162,15 @@ impl OpenAck { }; let initial_sn: ZInt = rng.gen(); - let auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtZInt::rand()); + let ext_auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); Self { lease, initial_sn, - auth, + ext_qos, + ext_shm, + ext_auth, } } } diff --git a/commons/zenoh-shm/src/lib.rs b/commons/zenoh-shm/src/lib.rs index 812c0d8a61..4c480d9152 100644 --- a/commons/zenoh-shm/src/lib.rs +++ b/commons/zenoh-shm/src/lib.rs @@ -11,7 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -use serde::{Deserialize, Serialize}; use shared_memory::{Shmem, ShmemConf, ShmemError}; use std::{ any::Any, @@ -21,7 +20,7 @@ use std::{ sync::atomic::{AtomicPtr, AtomicUsize, Ordering}, }; use zenoh_buffers::ZSliceBuffer; -use zenoh_result::{bail, zerror, ShmError, ZResult}; +use zenoh_result::{zerror, ShmError, ZResult}; const MIN_FREE_CHUNK_SIZE: usize = 1_024; const ACCOUNTED_OVERHEAD: usize = 4_096; @@ -67,7 +66,7 @@ impl PartialEq for Chunk { /// /// This that can be serialized and can be used to retrieve the [`SharedMemoryBuf`] in a remote process. #[non_exhaustive] -#[derive(Serialize, Deserialize, Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct SharedMemoryBufInfo { /// The index of the beginning of the buffer in the shm segment. pub offset: usize, @@ -90,31 +89,6 @@ impl SharedMemoryBufInfo { } } -impl SharedMemoryBufInfo { - pub fn serialize(&self) -> ZResult> { - bincode::serialize(self) - .map_err(|e| zerror!("Unable to serialize SharedMemoryBufInfo: {}", e).into()) - } - - pub fn deserialize(bs: &[u8]) -> ZResult { - match bincode::deserialize::(bs) { - Ok(info) => Ok(info), - Err(e) => bail!("Unable to deserialize SharedMemoryBufInfo: {}", e), - } - } -} - -impl Clone for SharedMemoryBufInfo { - fn clone(&self) -> SharedMemoryBufInfo { - SharedMemoryBufInfo { - shm_manager: self.shm_manager.clone(), - kind: self.kind, - offset: self.offset, - length: self.length, - } - } -} - /// A zenoh buffer in shared memory. #[non_exhaustive] pub struct SharedMemoryBuf { diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index 3f684052d4..e9abc4c129 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -12,7 +12,9 @@ // ZettaScale Zenoh Team, // use std::any::TypeId; -use zenoh_buffers::{ZBuf, ZSlice}; +use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZBuf, ZSlice}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_core::zerror; use zenoh_protocol::zenoh::*; use zenoh_result::ZResult; use zenoh_shm::{ @@ -58,7 +60,10 @@ pub fn map_zslice_to_shmbuf(zslice: &mut ZSlice, shmr: &mut SharedMemoryReader) let ZSlice { buf, .. } = zslice; if buf.as_any().type_id() == TypeId::of::() { // Deserialize the shmb info into shm buff - let shmbinfo = SharedMemoryBufInfo::deserialize(buf.as_slice())?; + let codec = Zenoh080::new(); + let mut reader = buf.as_slice().reader(); + let shmbinfo: SharedMemoryBufInfo = + codec.read(&mut reader).map_err(|e| zerror!("{:?}", e))?; // First, try in read mode allowing concurrenct lookups let smb = shmr @@ -87,7 +92,13 @@ pub fn map_zslice_to_shminfo(zslice: &mut ZSlice) -> ZResult { let ZSlice { buf, .. } = zslice; if let Some(shmb) = buf.as_any().downcast_ref::() { // Serialize the shmb info - let info: SharedMemoryBufInfoSerialized = shmb.info.serialize()?.into(); + let codec = Zenoh080::new(); + let mut bytes = vec![]; + let mut writer = bytes.writer(); + codec + .write(&mut writer, &shmb.info) + .map_err(|e| zerror!("{:?}", e))?; + let info: SharedMemoryBufInfoSerialized = bytes.into(); // Increase the reference count so to keep the SharedMemoryBuf valid shmb.inc_ref_count(); // Replace the content of the slice diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 90ef05765c..b7fb795b1a 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -12,9 +12,12 @@ // ZettaScale Zenoh Team, // use crate::{ - unicast::establishment::{ - close_link, compute_sn, ext, finalize_transport, AcceptFsm, Cookie, InputFinalize, - Zenoh080Cookie, + unicast::{ + establishment::{ + close_link, compute_sn, ext, finalize_transport, AcceptFsm, Cookie, InputFinalize, + Zenoh080Cookie, + }, + shm::Challenge, }, TransportConfigUnicast, TransportManager, }; @@ -46,6 +49,7 @@ struct StateZenoh { struct State { zenoh: StateZenoh, ext_qos: ext::qos::State, + ext_shm: ext::shm::State, } // InitSyn @@ -55,6 +59,7 @@ struct RecvInitSynIn { struct RecvInitSynOut { other_zid: ZenohId, other_whatami: WhatAmI, + ext_shm: Challenge, } // InitAck @@ -64,6 +69,7 @@ struct SendInitAckIn { mine_whatami: WhatAmI, other_zid: ZenohId, other_whatami: WhatAmI, + ext_shm: Challenge, } struct SendInitAckOut { cookie_nonce: ZInt, @@ -96,6 +102,7 @@ struct AcceptLink<'a> { prng: &'a Mutex, cipher: &'a BlockCipher, ext_qos: ext::qos::QoS, + ext_shm: ext::shm::Shm<'a>, } #[async_trait] @@ -160,18 +167,26 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { // Extension QoS self.ext_qos - .recv_init_syn((&mut state.ext_qos, init_syn.qos)) + .recv_init_syn((&mut state.ext_qos, init_syn.ext_qos)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + + // Extension Shm + let ext_shm = self + .ext_shm + .recv_init_syn((&mut state.ext_shm, init_syn.ext_shm)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; let output = RecvInitSynOut { other_whatami: init_syn.whatami, other_zid: init_syn.zid, + ext_shm, }; Ok(output) } - type InitAckIn = (&'a State, SendInitAckIn); + type InitAckIn = (&'a mut State, SendInitAckIn); type InitAckOut = SendInitAckOut; async fn send_init_ack( &'a self, @@ -180,12 +195,19 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { let (state, input) = input; // Extension QoS - let qos_mine_ext = self + let ext_qos = self .ext_qos .send_init_ack(&state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension Shm + let ext_shm = self + .ext_shm + .send_init_ack((&mut state.ext_shm, input.ext_shm)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Create the cookie let cookie_nonce: ZInt = zasynclock!(self.prng).gen(); let cookie = Cookie { @@ -194,7 +216,8 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { resolution: state.zenoh.resolution, batch_size: state.zenoh.batch_size, nonce: cookie_nonce, - is_qos: state.ext_qos.is_qos, + ext_qos: state.ext_qos, + ext_shm: state.ext_shm, // properties: EstablishmentProperties::new(), }; @@ -221,9 +244,9 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { resolution: state.zenoh.resolution, batch_size: state.zenoh.batch_size, cookie, - qos: qos_mine_ext, - shm: None, // @TODO - auth: None, // @TODO + ext_qos, + ext_shm, + ext_auth: None, // @TODO } .into(); @@ -301,14 +324,13 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { batch_size: cookie.batch_size, resolution: cookie.resolution, }, - ext_qos: ext::qos::State { - is_qos: cookie.is_qos, - }, + ext_qos: cookie.ext_qos, + ext_shm: cookie.ext_shm, }; // Extension QoS self.ext_qos - .recv_open_syn(&mut state.ext_qos) + .recv_open_syn((&mut state.ext_qos, open_syn.ext_qos)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; @@ -321,7 +343,7 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { Ok((state, output)) } - type OpenAckIn = (&'a State, SendOpenAckIn); + type OpenAckIn = (&'a mut State, SendOpenAckIn); type OpenAckOut = SendOpenAckOut; async fn send_open_ack( &'a self, @@ -330,17 +352,27 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { let (state, input) = input; // Extension QoS - self.ext_qos + let ext_qos = self + .ext_qos .send_open_ack(&state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension Shm + let ext_shm = self + .ext_shm + .send_open_ack(&mut state.ext_shm) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Build OpenAck message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); let message: TransportMessage = OpenAck { lease: input.mine_lease, initial_sn: mine_initial_sn, - auth: None, // @TODO + ext_qos, + ext_shm, + ext_auth: None, // @TODO } .into(); @@ -357,14 +389,12 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { } pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) -> ZResult<()> { - // Extension QoS - let ext_qos = ext::qos::QoS; - let fsm = AcceptLink { link, prng: &manager.prng, cipher: &manager.cipher, - ext_qos, + ext_qos: ext::qos::QoS::new(), + ext_shm: ext::shm::Shm::new(&manager.state.unicast.shm), }; // Init handshake @@ -387,9 +417,8 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) batch_size: manager.config.batch_size, resolution: manager.config.resolution, }, - ext_qos: ext::qos::State { - is_qos: manager.config.unicast.is_qos, - }, + ext_qos: ext::qos::State::new(manager.config.unicast.is_qos), + ext_shm: ext::shm::State::new(manager.config.unicast.is_shm), }; // Let's scope the Init phase in such a way memory is freed by Rust @@ -406,22 +435,23 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) mine_whatami: manager.config.whatami, other_zid: isyn_out.other_zid, other_whatami: isyn_out.other_whatami, + ext_shm: isyn_out.ext_shm, }; - step!(fsm.send_init_ack((&state, iack_in)).await) + step!(fsm.send_init_ack((&mut state, iack_in)).await) }; // Open handshake let osyn_in = RecvOpenSynIn { cookie_nonce: iack_out.cookie_nonce, }; - let (state, osyn_out) = step!(fsm.recv_open_syn(osyn_in).await); + let (mut state, osyn_out) = step!(fsm.recv_open_syn(osyn_in).await); let oack_in = SendOpenAckIn { mine_zid: manager.config.zid, mine_lease: manager.config.unicast.lease, other_zid: osyn_out.other_zid, }; - let oack_out = step!(fsm.send_open_ack((&state, oack_in)).await); + let oack_out = step!(fsm.send_open_ack((&mut state, oack_in)).await); // Initialize the transport let config = TransportConfigUnicast { @@ -429,7 +459,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) whatami: osyn_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), tx_initial_sn: oack_out.mine_initial_sn, - is_qos: state.ext_qos.is_qos, + is_qos: state.ext_qos.is_qos(), is_shm: false, // @TODO }; let transport = step!(manager diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 93d2b684af..be603d2d0c 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // // use super::properties::EstablishmentProperties; +use crate::unicast::establishment::ext; use std::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, HasReader, Reader}, @@ -22,14 +23,15 @@ use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_protocol::core::{Resolution, WhatAmI, ZInt, ZenohId}; #[derive(Clone, Debug, PartialEq, Eq)] -pub struct Cookie { - pub whatami: WhatAmI, - pub zid: ZenohId, - pub resolution: Resolution, - pub batch_size: u16, - pub nonce: ZInt, +pub(crate) struct Cookie { + pub(crate) whatami: WhatAmI, + pub(crate) zid: ZenohId, + pub(crate) resolution: Resolution, + pub(crate) batch_size: u16, + pub(crate) nonce: ZInt, // Extensions - pub is_qos: bool, + pub(crate) ext_qos: ext::qos::State, + pub(crate) ext_shm: ext::shm::State, // pub properties: EstablishmentProperties, // @TODO } @@ -47,8 +49,8 @@ where self.write(&mut *writer, x.batch_size)?; self.write(&mut *writer, x.nonce)?; // Extensions - let is_qos = u8::from(x.is_qos); - self.write(&mut *writer, is_qos)?; + self.write(&mut *writer, &x.ext_qos)?; + self.write(&mut *writer, &x.ext_shm)?; // self.write(&mut *writer, x.properties.as_slice())?; Ok(()) @@ -70,8 +72,8 @@ where let batch_size: u16 = self.read(&mut *reader)?; let nonce: ZInt = self.read(&mut *reader)?; // Extensions - let is_qos: u8 = self.read(&mut *reader)?; - let is_qos = is_qos == 1; + let ext_qos: ext::qos::State = self.read(&mut *reader)?; + let ext_shm: ext::shm::State = self.read(&mut *reader)?; // let mut ps: Vec = self.read(&mut *reader)?; // let mut properties = EstablishmentProperties::new(); // for p in ps.drain(..) { @@ -84,7 +86,8 @@ where resolution, batch_size, nonce, - is_qos, + ext_qos, + ext_shm, // properties, }; @@ -147,7 +150,8 @@ impl Cookie { resolution: Resolution::rand(), batch_size: rng.gen(), nonce: rng.gen(), - is_qos: rng.gen_bool(0.5), + ext_qos: ext::qos::State::new(rng.gen_bool(0.5)), + ext_shm: ext::shm::State::new(rng.gen_bool(0.5)), // properties: EstablishmentProperties::rand(), } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs index b82feb1e34..34d5b2dba4 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs @@ -13,20 +13,68 @@ // use crate::unicast::establishment::{AcceptFsm, OpenFsm}; use async_trait::async_trait; -use zenoh_protocol::transport::init; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_protocol::transport::{init, open}; use zenoh_result::Error as ZError; +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) struct State { + is_qos: bool, +} + +impl State { + pub(crate) const fn new(is_qos: bool) -> Self { + Self { is_qos } + } + + pub(crate) const fn is_qos(&self) -> bool { + self.is_qos + } +} + +// Codec +impl WCodec<&State, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &State) -> Self::Output { + let is_qos = u8::from(x.is_qos); + self.write(&mut *writer, is_qos)?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let is_qos: u8 = self.read(&mut *reader)?; + let is_qos = is_qos == 1; + Ok(State { is_qos }) + } +} + +// Extension Fsm pub(crate) struct QoS; -#[derive(Clone, Copy, Debug)] -pub(crate) struct State { - pub(crate) is_qos: bool, +impl QoS { + pub(crate) const fn new() -> Self { + Self + } } /*************************************/ /* OPEN */ /*************************************/ - #[async_trait] impl<'a> OpenFsm<'a> for QoS { type Error = ZError; @@ -53,15 +101,15 @@ impl<'a> OpenFsm<'a> for QoS { } type OpenSynIn = &'a State; - type OpenSynOut = (); + type OpenSynOut = Option; async fn send_open_syn( &'a self, _state: Self::OpenSynIn, ) -> Result { - Ok(()) + Ok(None) } - type OpenAckIn = &'a State; + type OpenAckIn = (&'a mut State, Option); type OpenAckOut = (); async fn recv_open_ack( &'a self, @@ -99,7 +147,7 @@ impl<'a> AcceptFsm<'a> for QoS { Ok(output) } - type OpenSynIn = &'a State; + type OpenSynIn = (&'a mut State, Option); type OpenSynOut = (); async fn recv_open_syn( &'a self, @@ -109,11 +157,11 @@ impl<'a> AcceptFsm<'a> for QoS { } type OpenAckIn = &'a State; - type OpenAckOut = (); + type OpenAckOut = Option; async fn send_open_ack( &'a self, _state: Self::OpenAckIn, ) -> Result { - Ok(()) + Ok(None) } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index 239e8bad75..277c0fec51 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -11,325 +11,466 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::unicast::{establishment::Cookie, shm::SharedMemoryUnicast}; -use async_trait::async_trait; -use rand::{Rng, SeedableRng}; -use std::{ - convert::TryInto, - sync::{Arc, RwLock}, +use crate::{ + establishment::{AcceptFsm, OpenFsm}, + unicast::{shm::Challenge, shm::SharedMemoryUnicast}, }; +use async_trait::async_trait; +use std::convert::TryInto; use zenoh_buffers::{ reader::{DidntRead, HasReader, Reader}, writer::{DidntWrite, HasWriter, Writer}, - ZSlice, }; use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_config::Config; -use zenoh_crypto::PseudoRng; +use zenoh_core::zasyncwrite; use zenoh_protocol::{ - core::{ZInt, ZenohId}, + core::ZInt, transport::{init, open}, }; -use zenoh_result::{bail, zerror, ShmError, ZResult}; -use zenoh_shm::{ - SharedMemoryBuf, SharedMemoryBufInfo, SharedMemoryBufInfoSerialized, SharedMemoryManager, - SharedMemoryReader, -}; +use zenoh_result::{zerror, Error as ZError}; +use zenoh_shm::SharedMemoryBufInfo; -pub(crate) struct Shm<'a> { - inner: &'a SharedMemoryUnicast, +/*************************************/ +/* InitSyn */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// ~ ShmMemBufInfo ~ +/// +---------------+ +pub(crate) struct InitSyn { + pub(crate) alice_info: SharedMemoryBufInfo, } -// /*************************************/ -// /* InitSyn */ -// /*************************************/ -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// |X 1 0| EXT | -// /// +-+-+-+---------+ -// /// | version | -// /// +---------------+ -// /// ~ ShmMemBufInfo ~ -// /// +---------------+ -// pub(crate) struct InitSyn { -// pub(crate) version: u8, -// pub(crate) info: ZSlice, -// } - -// // Codec -// impl WCodec<&InitSyn, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; - -// fn write(self, writer: &mut W, x: &InitSyn) -> Self::Output { -// self.write(&mut *writer, x.version)?; -// self.write(&mut *writer, &x.info)?; -// Ok(()) -// } -// } - -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; - -// fn read(self, reader: &mut R) -> Result { -// let version: ZInt = self.read(&mut *reader)?; -// let info: ZSlice = self.read(&mut *reader)?; -// Ok(InitSyn { version, info }) -// } -// } - -// Open -// pub(crate) struct InitSynOpenState { -// buffer: SharedMemoryBuf, -// } - -// impl InitSyn { -// pub(crate) fn send(shm: &SharedMemoryUnicast) -> ZResult<(init::ext::Shm, InitSynOpenState)> { -// let init_syn_property = InitSyn { -// version: shm::VERSION, -// info: shm -// .buffer -// .info -// .serialize() -// .map_err(|e| zerror!("{e}"))? -// .into(), -// }; -// let mut buff = vec![]; -// let codec = Zenoh080::new(); - -// let mut writer = buff.writer(); -// codec -// .write(&mut writer, &init_syn_property) -// .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; - -// Ok(Some(buff)) -// } -// } - -// pub(crate) struct InitSynAcceptInput { -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: Option>, -// } - -// Accept -// pub(crate) struct InitSynAcceptState {} - -// impl InitSyn { -// pub(crate) fn accept( -// ext: &init::ext::Shm, -// reader: &SharedMemoryReader, -// ) -> ZResult { -// let codec = Zenoh080::new(); -// let mut reader = ext.reader(); - -// let mut init_syn_ext: InitSyn = codec -// .read(&mut reader) -// .map_err(|_| zerror!("Error in decoding InitSyn SHM extension"))?; - -// if init_syn_ext.version != SHM_VERSION { -// bail!( -// "Incompatible InitSyn SHM extension version. Expected: {}. Received: {}.", -// SHM_VERSION, -// init_syn_ext.version -// ); -// } - -// // Try to read from the shared memory -// match crate::shm::map_zslice_to_shmbuf(&mut init_syn_ext.shm, reader) { -// Ok(false) => { -// log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); -// return Ok((None, None)); -// } -// Err(e) => { -// log::debug!("Zenoh node can not operate over SHM: {}", e); -// return Ok((None, None)); -// } -// Ok(true) => { -// // Payload is SHM: continue. -// } -// } - -// log::trace!("Verifying SHM extension"); -// let xs = init_syn_ext.shm; -// let bytes: [u8; SHM_SIZE] = match xs.as_slice().try_into() { -// Ok(bytes) => bytes, -// Err(e) => { -// log::debug!("Zenoh node can not operate over SHM: {}", e); -// return Ok((None, None)); -// } -// }; -// let challenge = ZInt::from_le_bytes(bytes); +// Codec +impl WCodec<&InitSyn, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &InitSyn) -> Self::Output { + self.write(&mut *writer, &x.alice_info)?; + Ok(()) + } +} -// // Create the InitAck attachment -// let init_ack_property = InitAckExt { -// challenge, -// shm: buffer.info.serialize()?.into(), -// }; -// // Encode the InitAck property -// let mut buffer = vec![]; -// let mut writer = buffer.writer(); -// codec -// .write(&mut writer, &init_ack_property) -// .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; -// Ok((Some(buffer), None)) -// } -// } + fn read(self, reader: &mut R) -> Result { + let alice_info: SharedMemoryBufInfo = self.read(&mut *reader)?; + Ok(InitSyn { alice_info }) + } +} /*************************************/ /* InitAck */ /*************************************/ -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// |0 0 0| ATTCH | -// /// +-+-+-+---------+ -// /// ~ challenge ~ -// /// +---------------+ -// /// ~ ShmMemBufInfo ~ -// /// +---------------+ -// struct InitAck { -// challenge: ZInt, -// info: ZSlice, -// } - -// impl WCodec<&InitAck, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; - -// fn write(self, writer: &mut W, x: &InitAck) -> Self::Output { -// self.write(&mut *writer, x.challenge)?; -// self.write(&mut *writer, &x.shm)?; -// Ok(()) -// } -// } - -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; - -// fn read(self, reader: &mut R) -> Result { -// let challenge: ZInt = self.read(&mut *reader)?; -// let info: ZSlice = self.read(&mut *reader)?; -// Ok(InitAck { challenge, info }) -// } -// } - -// // Open -// pub(crate) struct InitAckOpenState { -// buffer: SharedMemoryBuf, -// } +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// ~ challenge ~ +/// +---------------+ +/// ~ ShmMemBufInfo ~ +/// +---------------+ +struct InitAck { + alice_challenge: ZInt, + bob_info: SharedMemoryBufInfo, +} -// impl InitAck { -// pub(crate) fn recv( -// ext: &init::ext::Shm, -// shm: &SharedMemoryUnicast, -// ) -> ZResult<(init::ext::Shm, InitAckOpenState)> { -// let info = SharedMemoryBufInfo::deserialize(ext.value.as_slice())?; +impl WCodec<&InitAck, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &InitAck) -> Self::Output { + self.write(&mut *writer, x.alice_challenge)?; + self.write(&mut *writer, &x.bob_info)?; + Ok(()) + } +} -// // Try to read from the shared memory -// let mut zslice = ext.value.clone(); -// match crate::shm::map_zslice_to_shmbuf(&mut zslice, reader) { -// Ok(false) => { -// log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); -// return Ok((None, None)); -// } -// Err(e) => { -// log::debug!("Zenoh node can not operate over SHM: {}", e); -// return Ok((None, None)); -// } -// Ok(true) => { -// // Payload is SHM: continue. -// } -// } +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let alice_challenge: ZInt = self.read(&mut *reader)?; + let bob_info: SharedMemoryBufInfo = self.read(&mut *reader)?; + Ok(InitAck { + alice_challenge, + bob_info, + }) + } +} -// match crate::shm::map_zslice_to_shmbuf(&mut ext, &shm.reader) { -// Ok(res) => { -// if !res { -// return Err(ShmError(zerror!("No SHM on link: {}", link)).into()); -// } -// } -// Err(e) => return Err(ShmError(zerror!("No SHM on link {}: {}", link, e)).into()), -// } +/*************************************/ +/* OpenSyn */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// ~ challenge ~ +/// +---------------+ -// let bytes: [u8; std::mem::size_of::()] = -// init_ack_property.shm.as_slice().try_into().map_err(|e| { -// zerror!( -// "Received InitAck with invalid attachment on link {}: {}", -// link, -// e -// ) -// })?; -// let challenge = ZInt::from_le_bytes(bytes); +/*************************************/ +/* OpenAck */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// ~ ack ~ +/// +---------------+ + +// Extension Fsm State +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) struct State { + is_shm: bool, +} -// let challenge = (); -// let init_syn_property = InitAck { -// version: shm::VERSION, -// info: shm -// .buffer -// .info -// .serialize() -// .map_err(|e| zerror!("{e}"))? -// .into(), -// }; -// let mut buff = vec![]; -// let codec = Zenoh080::new(); +impl State { + pub(crate) const fn new(is_shm: bool) -> Self { + Self { is_shm } + } -// let mut writer = buff.writer(); -// codec -// .write(&mut writer, &init_syn_property) -// .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; + pub(crate) const fn is_shm(&self) -> bool { + self.is_shm + } +} -// Ok(Some(buff)) -// panic!() -// } -// } +// Codec +impl WCodec<&State, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &State) -> Self::Output { + let is_shm = u8::from(x.is_shm); + self.write(&mut *writer, is_shm)?; + Ok(()) + } +} -// /*************************************/ -// /* OpenSyn */ -// /*************************************/ -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// |0 0 0| ATTCH | -// /// +-+-+-+---------+ -// /// ~ challenge ~ -// /// +---------------+ -// struct OpenSynExt { -// challenge: ZInt, -// } +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let is_shm: u8 = self.read(&mut *reader)?; + let is_shm = is_shm == 1; + Ok(State { is_shm }) + } +} -// impl WCodec<&OpenSynExt, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; +// Extension Fsm +pub(crate) struct Shm<'a> { + inner: &'a SharedMemoryUnicast, +} -// fn write(self, writer: &mut W, x: &OpenSynExt) -> Self::Output { -// self.write(&mut *writer, x.challenge)?; -// Ok(()) -// } -// } +impl<'a> Shm<'a> { + pub(crate) const fn new(inner: &'a SharedMemoryUnicast) -> Self { + Self { inner } + } +} -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; +#[async_trait] +impl<'a> OpenFsm<'a> for Shm<'a> { + type Error = ZError; + + type InitSynIn = &'a State; + type InitSynOut = Option; + async fn send_init_syn( + &'a self, + state: Self::InitSynIn, + ) -> Result { + const S: &str = "Shm extension - Send InitSyn."; + + if !state.is_shm() { + return Ok(None); + } + + let init_syn = InitSyn { + alice_info: self.inner.challenge.info.clone(), + }; + + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, &init_syn) + .map_err(|_| zerror!("{} Encoding error", S))?; + + Ok(Some(init::ext::Shm::new(buff.into()))) + } + + type InitAckIn = (&'a mut State, Option); + type InitAckOut = Challenge; + async fn recv_init_ack( + &'a self, + input: Self::InitAckIn, + ) -> Result { + const S: &str = "Shm extension - Recv InitAck."; + + let (state, mut ext) = input; + if !state.is_shm() { + return Ok(0); + } + + let Some(mut ext) = ext.take() else { + state.is_shm = false; + return Ok(0); + }; + + // Decode the extension + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let Ok(init_ack): Result = codec.read(&mut reader) else { + log::trace!("{} Decoding error.", S); + state.is_shm = false; + return Ok(0); + }; + + // Alice challenge as seen by Alice + let bytes: [u8; std::mem::size_of::()] = self + .inner + .challenge + .as_slice() + .try_into() + .map_err(|e| zerror!("{}", e))?; + let challenge = ZInt::from_le_bytes(bytes); + + // Verify that Bob has correctly read Alice challenge + if challenge != init_ack.alice_challenge { + log::trace!( + "{} Challenge mismatch: {} != {}.", + S, + init_ack.alice_challenge, + challenge + ); + state.is_shm = false; + return Ok(0); + } + + // Read Bob's SharedMemoryBuf + let shm_buff = match zasyncwrite!(self.inner.reader).read_shmbuf(&init_ack.bob_info) { + Ok(buff) => buff, + Err(e) => { + log::trace!("{} {}", S, e); + state.is_shm = false; + return Ok(0); + } + }; + + // Bob challenge as seen by Alice + let bytes: [u8; std::mem::size_of::()] = match shm_buff.as_slice().try_into() { + Ok(bytes) => bytes, + Err(_) => { + log::trace!("{} Failed to read remote Shm.", S); + state.is_shm = false; + return Ok(0); + } + }; + let bob_challenge = ZInt::from_le_bytes(bytes); + + Ok(bob_challenge) + } + + type OpenSynIn = (&'a State, Self::InitAckOut); + type OpenSynOut = Option; + async fn send_open_syn( + &'a self, + input: Self::OpenSynIn, + ) -> Result { + const S: &str = "Shm extension - Send OpenSyn."; + + let (state, bob_challenge) = input; + if !state.is_shm() { + return Ok(None); + } + + Ok(Some(open::ext::Shm::new(bob_challenge))) + } + + type OpenAckIn = (&'a mut State, Option); + type OpenAckOut = (); + async fn recv_open_ack( + &'a self, + input: Self::OpenAckIn, + ) -> Result { + const S: &str = "Shm extension - Recv OpenAck."; + + let (state, mut ext) = input; + if !state.is_shm() { + return Ok(()); + } + + let Some(ext) = ext.take() else { + state.is_shm = false; + return Ok(()); + }; + + if ext.value != 1 { + log::trace!("{} Invalid value.", S); + state.is_shm = false; + return Ok(()); + } + + state.is_shm = true; + Ok(()) + } +} -// fn read(self, reader: &mut R) -> Result { -// let challenge: ZInt = self.read(&mut *reader)?; -// Ok(OpenSynExt { challenge }) -// } -// } +/*************************************/ +/* ACCEPT */ +/*************************************/ +#[async_trait] +impl<'a> AcceptFsm<'a> for Shm<'a> { + type Error = ZError; + + type InitSynIn = (&'a mut State, Option); + type InitSynOut = Challenge; + async fn recv_init_syn( + &'a self, + input: Self::InitSynIn, + ) -> Result { + const S: &str = "Shm extension - Recv InitSyn."; + + let (state, mut ext) = input; + if !state.is_shm() { + return Ok(0); + } + + let Some(mut ext) = ext.take() else { + state.is_shm = false; + return Ok(0); + }; + + // Decode the extension + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let Ok(init_syn): Result = codec.read(&mut reader) else { + log::trace!("{} Decoding error.", S); + state.is_shm = false; + return Ok(0); + }; + + // Read Alice's SharedMemoryBuf + let shm_buff = match zasyncwrite!(self.inner.reader).read_shmbuf(&init_syn.alice_info) { + Ok(buff) => buff, + Err(e) => { + log::trace!("{} {}", S, e); + state.is_shm = false; + return Ok(0); + } + }; + + // Alice challenge as seen by Bob + let bytes: [u8; std::mem::size_of::()] = match shm_buff.as_slice().try_into() { + Ok(bytes) => bytes, + Err(_) => { + log::trace!("{} Failed to read remote Shm.", S); + state.is_shm = false; + return Ok(0); + } + }; + let alice_challenge = ZInt::from_le_bytes(bytes); + + Ok(alice_challenge) + } + + type InitAckIn = (&'a State, Self::InitSynOut); + type InitAckOut = Option; + async fn send_init_ack( + &'a self, + input: Self::InitAckIn, + ) -> Result { + const S: &str = "Shm extension - Send InitAck."; + + let (state, alice_challenge) = input; + if !state.is_shm() { + return Ok(None); + } + + let init_syn = InitAck { + alice_challenge, + bob_info: self.inner.challenge.info.clone(), + }; + + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, &init_syn) + .map_err(|_| zerror!("{} Encoding error", S))?; + + Ok(Some(init::ext::Shm::new(buff.into()))) + } + + type OpenSynIn = (&'a mut State, Option); + type OpenSynOut = (); + async fn recv_open_syn( + &'a self, + input: Self::OpenSynIn, + ) -> Result { + const S: &str = "Shm extension - Recv OpenSyn."; + + let (state, mut ext) = input; + if !state.is_shm() { + return Ok(()); + } + + let Some(ext) = ext.take() else { + state.is_shm = false; + return Ok(()); + }; + + // Bob challenge as seen by Bob + let bytes: [u8; std::mem::size_of::()] = self + .inner + .challenge + .as_slice() + .try_into() + .map_err(|e| zerror!("{}", e))?; + let challenge = ZInt::from_le_bytes(bytes); + + // Verify that Alice has correctly read Bob challenge + let bob_challnge = ext.value; + if challenge != bob_challnge { + log::trace!( + "{} Challenge mismatch: {} != {}.", + S, + bob_challnge, + challenge + ); + state.is_shm = false; + return Ok(()); + } + + Ok(()) + } + + type OpenAckIn = &'a mut State; + type OpenAckOut = Option; + async fn send_open_ack( + &'a self, + state: Self::OpenAckIn, + ) -> Result { + const S: &str = "Shm extension - Recv OpenSyn."; + + if !state.is_shm() { + return Ok(None); + } + + state.is_shm = true; + Ok(Some(open::ext::Shm::new(1))) + } +} // /*************************************/ // /* Authenticator */ @@ -540,3 +681,173 @@ pub(crate) struct Shm<'a> { // async fn handle_close(&self, _node_id: &ZenohId) {} // } + +// // Open +// pub(crate) struct InitAckOpenState { +// buffer: SharedMemoryBuf, +// } + +// impl InitAck { +// pub(crate) fn recv( +// ext: &init::ext::Shm, +// shm: &SharedMemoryUnicast, +// ) -> ZResult<(init::ext::Shm, InitAckOpenState)> { +// let info = SharedMemoryBufInfo::deserialize(ext.value.as_slice())?; + +// // Try to read from the shared memory +// let mut zslice = ext.value.clone(); +// match crate::shm::map_zslice_to_shmbuf(&mut zslice, reader) { +// Ok(false) => { +// log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); +// return Ok((None, None)); +// } +// Err(e) => { +// log::debug!("Zenoh node can not operate over SHM: {}", e); +// return Ok((None, None)); +// } +// Ok(true) => { +// // Payload is SHM: continue. +// } +// } + +// match crate::shm::map_zslice_to_shmbuf(&mut ext, &shm.reader) { +// Ok(res) => { +// if !res { +// return Err(ShmError(zerror!("No SHM on link: {}", link)).into()); +// } +// } +// Err(e) => return Err(ShmError(zerror!("No SHM on link {}: {}", link, e)).into()), +// } + +// let bytes: [u8; std::mem::size_of::()] = +// init_ack_property.shm.as_slice().try_into().map_err(|e| { +// zerror!( +// "Received InitAck with invalid attachment on link {}: {}", +// link, +// e +// ) +// })?; +// let challenge = ZInt::from_le_bytes(bytes); + +// let challenge = (); +// let init_syn_property = InitAck { +// version: shm::VERSION, +// info: shm +// .buffer +// .info +// .serialize() +// .map_err(|e| zerror!("{e}"))? +// .into(), +// }; +// let mut buff = vec![]; +// let codec = Zenoh080::new(); + +// let mut writer = buff.writer(); +// codec +// .write(&mut writer, &init_syn_property) +// .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; + +// Ok(Some(buff)) +// panic!() +// } +// } + +// Open +// pub(crate) struct InitSynOpenState { +// buffer: SharedMemoryBuf, +// } + +// impl InitSyn { +// pub(crate) fn send(shm: &SharedMemoryUnicast) -> ZResult<(init::ext::Shm, InitSynOpenState)> { +// let init_syn_property = InitSyn { +// version: shm::VERSION, +// info: shm +// .buffer +// .info +// .serialize() +// .map_err(|e| zerror!("{e}"))? +// .into(), +// }; +// let mut buff = vec![]; +// let codec = Zenoh080::new(); + +// let mut writer = buff.writer(); +// codec +// .write(&mut writer, &init_syn_property) +// .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; + +// Ok(Some(buff)) +// } +// } + +// pub(crate) struct InitSynAcceptInput { +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: Option>, +// } + +// Accept +// pub(crate) struct InitSynAcceptState {} + +// impl InitSyn { +// pub(crate) fn accept( +// ext: &init::ext::Shm, +// reader: &SharedMemoryReader, +// ) -> ZResult { +// let codec = Zenoh080::new(); +// let mut reader = ext.reader(); + +// let mut init_syn_ext: InitSyn = codec +// .read(&mut reader) +// .map_err(|_| zerror!("Error in decoding InitSyn SHM extension"))?; + +// if init_syn_ext.version != SHM_VERSION { +// bail!( +// "Incompatible InitSyn SHM extension version. Expected: {}. Received: {}.", +// SHM_VERSION, +// init_syn_ext.version +// ); +// } + +// // Try to read from the shared memory +// match crate::shm::map_zslice_to_shmbuf(&mut init_syn_ext.shm, reader) { +// Ok(false) => { +// log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); +// return Ok((None, None)); +// } +// Err(e) => { +// log::debug!("Zenoh node can not operate over SHM: {}", e); +// return Ok((None, None)); +// } +// Ok(true) => { +// // Payload is SHM: continue. +// } +// } + +// log::trace!("Verifying SHM extension"); + +// let xs = init_syn_ext.shm; +// let bytes: [u8; SHM_SIZE] = match xs.as_slice().try_into() { +// Ok(bytes) => bytes, +// Err(e) => { +// log::debug!("Zenoh node can not operate over SHM: {}", e); +// return Ok((None, None)); +// } +// }; +// let challenge = ZInt::from_le_bytes(bytes); + +// // Create the InitAck attachment +// let init_ack_property = InitAckExt { +// challenge, +// shm: buffer.info.serialize()?.into(), +// }; +// // Encode the InitAck property +// let mut buffer = vec![]; +// let mut writer = buffer.writer(); +// codec +// .write(&mut writer, &init_ack_property) +// .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; + +// Ok((Some(buffer), None)) +// } +// } diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 5af6dbfb9f..49f7e34fcb 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -11,10 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::unicast::establishment::{ - close_link, compute_sn, ext, finalize_transport, InputFinalize, OpenFsm, +use crate::{ + unicast::{ + establishment::{close_link, compute_sn, ext, finalize_transport, InputFinalize, OpenFsm}, + shm::Challenge, + }, + TransportConfigUnicast, TransportManager, TransportUnicast, }; -use crate::{TransportConfigUnicast, TransportManager, TransportUnicast}; use async_trait::async_trait; use std::time::Duration; use zenoh_buffers::ZSlice; @@ -35,6 +38,7 @@ struct StateZenoh { struct State { zenoh: StateZenoh, ext_qos: ext::qos::State, + ext_shm: ext::shm::State, } // InitSyn @@ -50,6 +54,7 @@ struct RecvInitAckOut { other_zid: ZenohId, other_whatami: WhatAmI, other_cookie: ZSlice, + ext_shm: Challenge, } // OpenSyn @@ -58,6 +63,7 @@ struct SendOpenSynIn { mine_lease: Duration, other_zid: ZenohId, other_cookie: ZSlice, + ext_shm: Challenge, } struct SendOpenSynOut { @@ -74,6 +80,7 @@ struct RecvOpenAckOut { struct OpenLink<'a> { link: &'a LinkUnicast, ext_qos: ext::qos::QoS, + ext_shm: ext::shm::Shm<'a>, } #[async_trait] @@ -95,15 +102,22 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension Shm + let shm_mine_ext = self + .ext_shm + .send_init_syn(&state.ext_shm) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let msg: TransportMessage = InitSyn { version: input.mine_version, whatami: input.mine_whatami, zid: input.mine_zid, batch_size: state.zenoh.batch_size, resolution: state.zenoh.resolution, - qos: qos_mine_ext, - shm: None, // @TODO - auth: None, // @TODO + ext_qos: qos_mine_ext, + ext_shm: shm_mine_ext, + ext_auth: None, // @TODO } .into(); @@ -197,7 +211,14 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { // Extension QoS self.ext_qos - .recv_init_ack((&mut state.ext_qos, init_ack.qos)) + .recv_init_ack((&mut state.ext_qos, init_ack.ext_qos)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + + // Extension Shm + let shm_challenge = self + .ext_shm + .recv_init_ack((&mut state.ext_shm, init_ack.ext_shm)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; @@ -205,6 +226,7 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { other_zid: init_ack.zid, other_whatami: init_ack.whatami, other_cookie: init_ack.cookie, + ext_shm: shm_challenge, }; Ok(output) } @@ -218,19 +240,28 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { let (state, input) = input; // Extension QoS - self.ext_qos + let ext_qos = self + .ext_qos .send_open_syn(&state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension Shm + let ext_shm = self + .ext_shm + .send_open_syn((&state.ext_shm, input.ext_shm)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Build and send an OpenSyn message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); let message: TransportMessage = OpenSyn { lease: input.mine_lease, initial_sn: mine_initial_sn, cookie: input.other_cookie, - shm: None, // @TODO - auth: None, // @TODO + ext_qos, + ext_shm, + ext_auth: None, // @TODO } .into(); @@ -283,7 +314,13 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { // Extension QoS self.ext_qos - .recv_open_ack(&mut state.ext_qos) + .recv_open_ack((&mut state.ext_qos, open_ack.ext_qos)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + + // Extension Shm + self.ext_shm + .recv_open_ack((&mut state.ext_shm, open_ack.ext_shm)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; @@ -299,10 +336,11 @@ pub(crate) async fn open_link( link: &LinkUnicast, manager: &TransportManager, ) -> ZResult { - // Extension QoS - let ext_qos = ext::qos::QoS; - - let fsm = OpenLink { link, ext_qos }; + let fsm = OpenLink { + link, + ext_qos: ext::qos::QoS::new(), + ext_shm: ext::shm::Shm::new(&manager.state.unicast.shm), + }; // Init handshake macro_rules! step { @@ -322,9 +360,8 @@ pub(crate) async fn open_link( batch_size: manager.config.batch_size, resolution: manager.config.resolution, }, - ext_qos: ext::qos::State { - is_qos: manager.config.unicast.is_qos, - }, + ext_qos: ext::qos::State::new(manager.config.unicast.is_qos), + ext_shm: ext::shm::State::new(manager.config.unicast.is_shm), }; let isyn_in = SendInitSynIn { @@ -342,6 +379,7 @@ pub(crate) async fn open_link( other_zid: iack_out.other_zid, mine_lease: manager.config.unicast.lease, other_cookie: iack_out.other_cookie, + ext_shm: iack_out.ext_shm, }; let osyn_out = step!(fsm.send_open_syn((&mut state, osyn_in)).await); @@ -353,7 +391,7 @@ pub(crate) async fn open_link( whatami: iack_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), tx_initial_sn: osyn_out.mine_initial_sn, - is_qos: state.ext_qos.is_qos, + is_qos: state.ext_qos.is_qos(), is_shm: false, // @TODO }; let transport = step!(manager diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index 2126441bba..7d121c6ddb 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -35,8 +35,8 @@ mod tests { use zenoh_result::ZResult; use zenoh_shm::SharedMemoryManager; use zenoh_transport::{ - unicast::establishment::authenticator::SharedMemoryAuthenticator, TransportEventHandler, - TransportManager, TransportPeer, TransportPeerEventHandler, TransportUnicast, + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, }; const TIMEOUT: Duration = Duration::from_secs(60); @@ -128,7 +128,7 @@ mod tests { } async fn run(endpoint: &EndPoint) { - dbg!("Transport SHM [0a]: {endpoint:?}"); + println!("Transport SHM [0a]: {endpoint:?}"); // Define client and router IDs let peer_shm01 = ZenohId::try_from([1]).unwrap(); @@ -175,29 +175,29 @@ mod tests { .unwrap(); // Create the listener on the peer - dbg!("Transport SHM [1a]"); + println!("Transport SHM [1a]"); let _ = ztimeout!(peer_shm01_manager .add_listener(endpoint.clone()) .timeout(TIMEOUT)) .unwrap(); // Create a transport with the peer - dbg!("Transport SHM [1b]"); + println!("Transport SHM [1b]"); let _ = ztimeout!(peer_shm02_manager.open_transport(endpoint.clone())).unwrap(); // Create a transport with the peer - dbg!("Transport SHM [1c]"); + println!("Transport SHM [1c]"); let _ = ztimeout!(peer_net01_manager.open_transport(endpoint.clone())).unwrap(); // Retrieve the transports - dbg!("Transport SHM [2a]"); + println!("Transport SHM [2a]"); let peer_shm02_transport = peer_shm01_manager.get_transport(&peer_shm02).unwrap(); - dbg!("Transport SHM [2b]"); + println!("Transport SHM [2b]"); let peer_net01_transport = peer_shm01_manager.get_transport(&peer_net01).unwrap(); // Send the message - dbg!("Transport SHM [3a]"); + println!("Transport SHM [3a]"); // The msg count for (msg_count, _) in (0..MSG_COUNT).enumerate() { // Create the message to send @@ -241,7 +241,7 @@ mod tests { task::sleep(SLEEP).await; // Wait for the messages to arrive to the other side - dbg!("Transport SHM [3b]"); + println!("Transport SHM [3b]"); ztimeout!(async { while peer_shm02_handler.get_count() != MSG_COUNT { task::sleep(SLEEP).await; @@ -249,7 +249,7 @@ mod tests { }); // Send the message - dbg!("Transport SHM [4a]"); + println!("Transport SHM [4a]"); // The msg count for (msg_count, _) in (0..MSG_COUNT).enumerate() { // Create the message to send @@ -292,7 +292,7 @@ mod tests { task::sleep(SLEEP).await; // Wait for the messages to arrive to the other side - dbg!("Transport SHM [4b]"); + println!("Transport SHM [4b]"); ztimeout!(async { while peer_net01_handler.get_count() != MSG_COUNT { task::sleep(SLEEP).await; @@ -303,10 +303,10 @@ mod tests { task::sleep(SLEEP).await; // Close the transports - dbg!("Transport SHM [5a]"); + println!("Transport SHM [5a]"); ztimeout!(peer_shm02_transport.close()).unwrap(); - dbg!("Transport SHM [5b]"); + println!("Transport SHM [5b]"); ztimeout!(peer_net01_transport.close()).unwrap(); ztimeout!(async { @@ -316,7 +316,7 @@ mod tests { }); // Delete the listener - dbg!("Transport SHM [6a]"); + println!("Transport SHM [6a]"); ztimeout!(peer_shm01_manager.del_listener(endpoint)).unwrap(); // Wait a little bit diff --git a/zenoh/tests/session.rs b/zenoh/tests/session.rs index 539b2dffa8..d980155a2e 100644 --- a/zenoh/tests/session.rs +++ b/zenoh/tests/session.rs @@ -39,7 +39,7 @@ async fn open_session(endpoints: &[&str]) -> (Session, Session) { .map(|e| e.parse().unwrap()) .collect::>(); config.scouting.multicast.set_enabled(Some(false)).unwrap(); - dbg!("[ ][01a] Opening peer01 session"); + println!("[ ][01a] Opening peer01 session"); let peer01 = ztimeout!(zenoh::open(config).res_async()).unwrap(); let mut config = config::peer(); @@ -48,16 +48,16 @@ async fn open_session(endpoints: &[&str]) -> (Session, Session) { .map(|e| e.parse().unwrap()) .collect::>(); config.scouting.multicast.set_enabled(Some(false)).unwrap(); - dbg!("[ ][02a] Opening peer02 session"); + println!("[ ][02a] Opening peer02 session"); let peer02 = ztimeout!(zenoh::open(config).res_async()).unwrap(); (peer01, peer02) } async fn close_session(peer01: Session, peer02: Session) { - dbg!("[ ][01d] Closing peer02 session"); + println!("[ ][01d] Closing peer02 session"); ztimeout!(peer01.close().res_async()).unwrap(); - dbg!("[ ][02d] Closing peer02 session"); + println!("[ ][02d] Closing peer02 session"); ztimeout!(peer02.close().res_async()).unwrap(); } @@ -70,7 +70,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { msgs.store(0, Ordering::SeqCst); // Subscribe to data - dbg!("[PS][01b] Subscribing on peer01 session"); + println!("[PS][01b] Subscribing on peer01 session"); let c_msgs = msgs.clone(); let sub = ztimeout!(peer01 .declare_subscriber(key_expr) @@ -85,7 +85,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { task::sleep(SLEEP).await; // Put data - dbg!("[PS][02b] Putting on peer02 session. {MSG_COUNT} msgs of {size} bytes."); + println!("[PS][02b] Putting on peer02 session. {MSG_COUNT} msgs of {size} bytes."); for _ in 0..MSG_COUNT { ztimeout!(peer02 .put(key_expr, vec![0u8; size]) @@ -97,7 +97,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { ztimeout!(async { loop { let cnt = msgs.load(Ordering::SeqCst); - dbg!("[PS][03b] Received {cnt}/{MSG_COUNT}."); + println!("[PS][03b] Received {cnt}/{MSG_COUNT}."); if cnt < MSG_COUNT { task::sleep(SLEEP).await; } else { @@ -106,7 +106,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { } }); - dbg!("[PS][03b] Unsubscribing on peer01 session"); + println!("[PS][03b] Unsubscribing on peer01 session"); ztimeout!(sub.undeclare().res_async()).unwrap(); // Wait for the declaration to propagate @@ -123,7 +123,7 @@ async fn test_session_qryrep(peer01: &Session, peer02: &Session) { msgs.store(0, Ordering::SeqCst); // Queryable to data - dbg!("[QR][01c] Queryable on peer01 session"); + println!("[QR][01c] Queryable on peer01 session"); let c_msgs = msgs.clone(); let qbl = ztimeout!(peer01 .declare_queryable(key_expr) @@ -139,7 +139,7 @@ async fn test_session_qryrep(peer01: &Session, peer02: &Session) { task::sleep(SLEEP).await; // Get data - dbg!("[QR][02c] Getting on peer02 session. {MSG_COUNT} msgs."); + println!("[QR][02c] Getting on peer02 session. {MSG_COUNT} msgs."); let mut cnt = 0; for _ in 0..MSG_COUNT { let rs = ztimeout!(peer02.get(key_expr).res_async()).unwrap(); @@ -148,11 +148,11 @@ async fn test_session_qryrep(peer01: &Session, peer02: &Session) { cnt += 1; } } - dbg!("[QR][02c] Got on peer02 session. {cnt}/{MSG_COUNT} msgs."); + println!("[QR][02c] Got on peer02 session. {cnt}/{MSG_COUNT} msgs."); assert_eq!(msgs.load(Ordering::SeqCst), MSG_COUNT); assert_eq!(cnt, MSG_COUNT); - dbg!("[PS][03c] Unqueryable on peer01 session"); + println!("[PS][03c] Unqueryable on peer01 session"); ztimeout!(qbl.undeclare().res_async()).unwrap(); // Wait for the declaration to propagate From 9d564148e438390137d7360014a29cf34779f755 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 3 Mar 2023 12:40:55 +0100 Subject: [PATCH 050/203] Reintroduced SHM --- commons/zenoh-codec/benches/codec.rs | 6 +- commons/zenoh-codec/src/core/shm.rs | 51 + commons/zenoh-codec/src/transport/fragment.rs | 2 +- commons/zenoh-codec/src/transport/frame.rs | 12 +- commons/zenoh-codec/src/transport/mod.rs | 4 +- commons/zenoh-codec/src/transport/open.rs | 35 +- commons/zenoh-codec/tests/codec.rs | 2 +- commons/zenoh-config/src/defaults.rs | 6 - commons/zenoh-config/src/lib.rs | 5 +- commons/zenoh-protocol/src/transport/frame.rs | 8 +- commons/zenoh-protocol/src/transport/mod.rs | 24 +- io/zenoh-transport/src/common/batch.rs | 2 +- io/zenoh-transport/src/common/pipeline.rs | 4 +- .../src/unicast/establishment/accept.rs | 51 +- .../src/unicast/establishment/open.rs | 5 +- io/zenoh-transport/src/unicast/manager.rs | 10 +- io/zenoh-transport/src/unicast/rx.rs | 17 +- io/zenoh-transport/src/unicast/shm.rs | 57 + io/zenoh-transport/src/unicast/transport.rs | 22 - io/zenoh-transport/src/unicast/tx.rs | 21 +- .../tests/unicast_authenticator.rs | 2060 ++++++++--------- io/zenoh-transport/tests/unicast_shm.rs | 21 +- 22 files changed, 1253 insertions(+), 1172 deletions(-) create mode 100644 commons/zenoh-codec/src/core/shm.rs create mode 100644 io/zenoh-transport/src/unicast/shm.rs diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index d14c6c7c04..98d857cf52 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -75,7 +75,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), sn: ZInt::MIN, - qos: zenoh_protocol::transport::frame::ext::QoS::default(), + ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; let data = Data { @@ -112,7 +112,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), sn: ZInt::MIN, - qos: zenoh_protocol::transport::frame::ext::QoS::default(), + ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; let data = Data { @@ -144,7 +144,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), sn: ZInt::MIN, - qos: zenoh_protocol::transport::frame::ext::QoS::default(), + ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; let data = Data { diff --git a/commons/zenoh-codec/src/core/shm.rs b/commons/zenoh-codec/src/core/shm.rs new file mode 100644 index 0000000000..1ab6976ebe --- /dev/null +++ b/commons/zenoh-codec/src/core/shm.rs @@ -0,0 +1,51 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh080}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_shm::SharedMemoryBufInfo; + +impl WCodec<&SharedMemoryBufInfo, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &SharedMemoryBufInfo) -> Self::Output { + self.write(&mut *writer, x.offset)?; + self.write(&mut *writer, x.length)?; + self.write(&mut *writer, x.shm_manager.as_str())?; + self.write(&mut *writer, x.kind)?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let offset: usize = self.read(&mut *reader)?; + let length: usize = self.read(&mut *reader)?; + let shm_manager: String = self.read(&mut *reader)?; + let kind: u8 = self.read(&mut *reader)?; + + let shm_info = SharedMemoryBufInfo::new(offset, length, shm_manager, kind); + Ok(shm_info) + } +} diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index 18c6a10910..192c2474f5 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -136,7 +136,7 @@ where self.write(&mut *writer, &header)?; // Body - self.write(&mut *writer, &x.payload)?; + writer.write_zslice(&x.payload)?; Ok(()) } diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 7c183a24bd..993bc5737a 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -88,7 +88,7 @@ where if let Reliability::Reliable = x.reliability { header |= flag::R; } - if x.qos != ext::QoS::default() { + if x.ext_qos != ext::QoS::default() { header |= flag::Z; } self.write(&mut *writer, header)?; @@ -97,8 +97,8 @@ where self.write(&mut *writer, x.sn)?; // Extensions - if x.qos != ext::QoS::default() { - self.write(&mut *writer, (x.qos, false))?; + if x.ext_qos != ext::QoS::default() { + self.write(&mut *writer, (x.ext_qos, false))?; } Ok(()) @@ -158,7 +158,7 @@ where Ok(FrameHeader { reliability, sn, - qos, + ext_qos: qos, }) } } @@ -175,7 +175,7 @@ where let header = FrameHeader { reliability: x.reliability, sn: x.sn, - qos: x.qos, + ext_qos: x.ext_qos, }; self.write(&mut *writer, &header)?; @@ -227,7 +227,7 @@ where Ok(Frame { reliability: header.reliability, sn: header.sn, - qos: header.qos, + ext_qos: header.ext_qos, payload, }) } diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index 59d90b6a12..83ffaa0941 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -42,7 +42,7 @@ where TransportBody::InitAck(b) => self.write(&mut *writer, b), TransportBody::OpenSyn(b) => self.write(&mut *writer, b), TransportBody::OpenAck(b) => self.write(&mut *writer, b), - TransportBody::Join(b) => self.write(&mut *writer, b), + // TransportBody::Join(b) => self.write(&mut *writer, b), TransportBody::Close(b) => self.write(&mut *writer, b), } } @@ -76,7 +76,7 @@ where TransportBody::OpenAck(codec.read(&mut *reader)?) } } - id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), + // id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), id::CLOSE => TransportBody::Close(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index fd0182f223..7fdf93185e 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -40,8 +40,8 @@ where if x.lease.as_millis() % 1_000 == 0 { header |= flag::T; } - let has_extensions = x.ext_shm.is_some() || x.ext_auth.is_some(); - if has_extensions { + let has_ext = x.ext_qos.is_some() || x.ext_shm.is_some() || x.ext_auth.is_some(); + if has_ext { header |= flag::Z; } self.write(&mut *writer, header)?; @@ -56,14 +56,17 @@ where self.write(&mut *writer, &x.cookie)?; // Extensions + if let Some(qos) = x.ext_qos.as_ref() { + let has_ext = x.ext_shm.is_some() || x.ext_auth.is_some(); + self.write(&mut *writer, (qos, has_ext))?; + } if let Some(shm) = x.ext_shm.as_ref() { - let has_more = x.ext_auth.is_some(); - self.write(&mut *writer, (shm, has_more))?; + let has_ext = x.ext_auth.is_some(); + self.write(&mut *writer, (shm, has_ext))?; } - if let Some(auth) = x.ext_auth.as_ref() { - let has_more = false; - self.write(&mut *writer, (auth, has_more))?; + let has_ext = false; + self.write(&mut *writer, (auth, has_ext))?; } Ok(()) @@ -114,7 +117,7 @@ where let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { - ext::QoS::ID => { + ext::QOS => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; qos = Some(q); has_ext = ext; @@ -162,7 +165,7 @@ where if x.lease.subsec_nanos() == 0 { header |= flag::T; } - let has_extensions = x.ext_auth.is_some(); + let has_extensions = x.ext_qos.is_some() || x.ext_shm.is_some() || x.ext_auth.is_some(); if has_extensions { header |= flag::Z; } @@ -177,9 +180,17 @@ where self.write(&mut *writer, x.initial_sn)?; // Extensions + if let Some(qos) = x.ext_qos.as_ref() { + let has_ext = x.ext_shm.is_some() || x.ext_auth.is_some(); + self.write(&mut *writer, (qos, has_ext))?; + } + if let Some(shm) = x.ext_shm.as_ref() { + let has_ext = x.ext_auth.is_some(); + self.write(&mut *writer, (shm, has_ext))?; + } if let Some(auth) = x.ext_auth.as_ref() { - let has_more = false; - self.write(&mut *writer, (auth, has_more))?; + let has_ext = false; + self.write(&mut *writer, (auth, has_ext))?; } Ok(()) @@ -229,7 +240,7 @@ where let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { - ext::QoS::ID => { + ext::QOS => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; ext_qos = Some(q); has_ext = ext; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index ae70f455ae..3822a6ca3a 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -269,7 +269,7 @@ fn codec_open_ack() { run!(OpenAck, OpenAck::rand()); } -#[test] +// #[test] fn codec_join() { run!(Join, Join::rand()); } diff --git a/commons/zenoh-config/src/defaults.rs b/commons/zenoh-config/src/defaults.rs index e8758803b9..1d3b0853ed 100644 --- a/commons/zenoh-config/src/defaults.rs +++ b/commons/zenoh-config/src/defaults.rs @@ -175,9 +175,3 @@ impl Default for LinkRxConf { } } } - -impl Default for SharedMemoryConf { - fn default() -> Self { - Self { enabled: true } - } -} diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 319b27aa1c..8010e34686 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -283,9 +283,10 @@ validated_struct::validator! { client_certificate: Option, }, }, - pub shared_memory: SharedMemoryConf { + pub shared_memory: #[derive(Default)] + SharedMemoryConf { /// Whether shared memory is enabled or not. - /// If set to `false`, the shared-memory transport will be disabled. (default `true`). + /// If set to `false`, the shared-memory transport will be disabled. (default `false`). enabled: bool, }, pub auth: #[derive(Default)] diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 5f1c586bd7..e813852cb7 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -74,7 +74,7 @@ pub mod flag { pub struct Frame { pub reliability: Reliability, pub sn: ZInt, - pub qos: ext::QoS, + pub ext_qos: ext::QoS, pub payload: Vec, } @@ -137,7 +137,7 @@ impl Frame { Frame { reliability, sn, - qos, + ext_qos: qos, payload, } } @@ -149,7 +149,7 @@ impl Frame { pub struct FrameHeader { pub reliability: Reliability, pub sn: ZInt, - pub qos: ext::QoS, + pub ext_qos: ext::QoS, } impl FrameHeader { @@ -170,7 +170,7 @@ impl FrameHeader { FrameHeader { reliability, sn, - qos, + ext_qos: qos, } } } diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index e3300cfab2..564f5028b0 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -93,7 +93,7 @@ pub enum TransportBody { InitAck(InitAck), OpenSyn(OpenSyn), OpenAck(OpenAck), - Join(Join), + // Join(Join), Close(Close), KeepAlive(KeepAlive), Frame(Frame), @@ -115,16 +115,16 @@ impl TransportMessage { let mut rng = rand::thread_rng(); - let body = match rng.gen_range(0..9) { + let body = match rng.gen_range(0..8) { 0 => TransportBody::InitSyn(InitSyn::rand()), 1 => TransportBody::InitAck(InitAck::rand()), 2 => TransportBody::OpenSyn(OpenSyn::rand()), 3 => TransportBody::OpenAck(OpenAck::rand()), - 4 => TransportBody::Join(Join::rand()), - 5 => TransportBody::Close(Close::rand()), - 6 => TransportBody::KeepAlive(KeepAlive::rand()), - 7 => TransportBody::Frame(Frame::rand()), - 8 => TransportBody::Fragment(Fragment::rand()), + // 4 => TransportBody::Join(Join::rand()), + 4 => TransportBody::Close(Close::rand()), + 5 => TransportBody::KeepAlive(KeepAlive::rand()), + 6 => TransportBody::Frame(Frame::rand()), + 7 => TransportBody::Fragment(Fragment::rand()), _ => unreachable!(), }; @@ -166,11 +166,11 @@ impl From for TransportMessage { } } -impl From for TransportMessage { - fn from(join: Join) -> Self { - TransportBody::Join(join).into() - } -} +// impl From for TransportMessage { +// fn from(join: Join) -> Self { +// TransportBody::Join(join).into() +// } +// } impl From for TransportMessage { fn from(close: Close) -> Self { diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index f7cf033e1a..9ec8af505a 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -380,7 +380,7 @@ mod tests { let mut frame = FrameHeader { reliability: zmsg.channel.reliability, sn: 0, - qos: frame::ext::QoS::default(), + ext_qos: frame::ext::QoS::default(), }; // Serialize with a frame diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 80da290e74..500c64c971 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -186,7 +186,7 @@ impl StageIn { let frame = FrameHeader { reliability: msg.channel.reliability, sn, - qos: frame::ext::QoS { priority }, + ext_qos: frame::ext::QoS { priority }, }; if let WError::NewFrame = e { @@ -224,7 +224,7 @@ impl StageIn { reliability: frame.reliability, more: true, sn, - qos: frame.qos, + qos: frame.ext_qos, }; let mut reader = self.fragbuf.reader(); while reader.can_read() { diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index b7fb795b1a..0674543d72 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -93,7 +93,7 @@ struct SendOpenAckIn { other_zid: ZenohId, } struct SendOpenAckOut { - mine_initial_sn: ZInt, + open_ack: OpenAck, } // Fsm @@ -367,23 +367,17 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { // Build OpenAck message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); - let message: TransportMessage = OpenAck { + let open_ack = OpenAck { lease: input.mine_lease, initial_sn: mine_initial_sn, ext_qos, ext_shm, ext_auth: None, // @TODO - } - .into(); + }; - // Send the message on the link - let _ = self - .link - .send(&message) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Do not send the OpenAck right now since we might still incur in MAX_LINKS error - let output = SendOpenAckOut { mine_initial_sn }; + let output = SendOpenAckOut { open_ack }; Ok(output) } } @@ -446,6 +440,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) }; let (mut state, osyn_out) = step!(fsm.recv_open_syn(osyn_in).await); + // Create the OpenAck but not send it yet let oack_in = SendOpenAckIn { mine_zid: manager.config.zid, mine_lease: manager.config.unicast.lease, @@ -458,36 +453,15 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) zid: osyn_out.other_zid, whatami: osyn_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), - tx_initial_sn: oack_out.mine_initial_sn, + tx_initial_sn: oack_out.open_ack.initial_sn, is_qos: state.ext_qos.is_qos(), - is_shm: false, // @TODO + is_shm: state.ext_shm.is_shm(), }; let transport = step!(manager .init_transport_unicast(config) .await .map_err(|e| (e, Some(close::reason::INVALID)))); - macro_rules! step { - ($s: expr) => { - match $s { - Ok(output) => output, - Err((e, reason)) => { - match reason { - Some(close::reason::MAX_LINKS) => log::debug!("{}", e), - _ => log::error!("{}", e), - } - if let Ok(ll) = transport.get_links() { - if ll.is_empty() { - let _ = manager.del_transport_unicast(&osyn_out.other_zid).await; - } - } - close_link(link, reason).await; - return Err(e); - } - } - }; - } - // Add the link to the transport step!(step!(transport .get_inner() @@ -495,6 +469,12 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) .add_link(link.clone(), LinkUnicastDirection::Inbound) .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); + // Send the open_ack on the link + step!(link + .send(&oack_out.open_ack.into()) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))); + // Sync the RX sequence number let _ = step!(transport .get_inner() @@ -513,8 +493,9 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) .map_err(|e| (e, Some(close::reason::INVALID)))); log::debug!( - "New transport link established from {}: {}", + "New transport link accepted from {} to {}: {}", osyn_out.other_zid, + manager.config.zid, link ); diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 49f7e34fcb..ac4e7d495e 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -392,7 +392,7 @@ pub(crate) async fn open_link( sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), tx_initial_sn: osyn_out.mine_initial_sn, is_qos: state.ext_qos.is_qos(), - is_shm: false, // @TODO + is_shm: state.ext_shm.is_shm(), }; let transport = step!(manager .init_transport_unicast(config) @@ -427,7 +427,8 @@ pub(crate) async fn open_link( } log::debug!( - "New transport link established with {}: {}", + "New transport link opened from {} to {}: {}", + manager.config.zid, iack_out.other_zid, link ); diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 0caf4a2b16..f9f4ca2fea 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -181,13 +181,6 @@ impl TransportManagerBuilderUnicast { // .insert(PubKeyAuthenticator::make()?.into()); // } @TODO - // #[cfg(feature = "shared-memory")] - // if self.is_shm - // { - // self.peer_authenticator - // .insert(SharedMemoryAuthenticator::make()?.into()); - // } - let state = TransportManagerStateUnicast { incoming: Arc::new(Mutex::new(0)), protocols: Arc::new(Mutex::new(HashMap::new())), @@ -392,7 +385,8 @@ impl TransportManager { guard.insert(config.zid, a_t); log::debug!( - "New transport opened with {}: whatami {}, sn resolution {}, initial sn {:?}, shm: {}, qos: {}", + "New transport opened between {} and {}: whatami {}, sn resolution {}, initial sn {:?}, shm: {}, qos: {}", + self.config.zid, config.zid, config.whatami, config.sn_resolution, diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index 1fb5e145a1..c33f7b895d 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -17,7 +17,7 @@ use async_std::task; use std::sync::MutexGuard; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; -use zenoh_core::{zlock, zread}; +use zenoh_core::{zasyncwrite, zlock, zread}; use zenoh_link::LinkUnicast; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; @@ -65,10 +65,15 @@ impl TransportUnicastInner { let callback = zread!(self.callback).clone(); if let Some(callback) = callback.as_ref() { - // #[cfg(feature = "shared-memory")] - // { - // crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.config.manager.shmr)?; - // } @TODO + #[cfg(feature = "shared-memory")] + { + if self.config.is_shm { + task::block_on(async { + let mut w_guard = zasyncwrite!(self.manager.state.unicast.shm.reader); + crate::shm::map_zmsg_to_shmbuf(&mut msg, &mut w_guard) + })?; + } + } callback.handle_message(msg) } else { log::debug!( @@ -105,7 +110,7 @@ impl TransportUnicastInner { let Frame { reliability, sn, - qos, + ext_qos: qos, mut payload, } = frame; diff --git a/io/zenoh-transport/src/unicast/shm.rs b/io/zenoh-transport/src/unicast/shm.rs new file mode 100644 index 0000000000..b019f75fa2 --- /dev/null +++ b/io/zenoh-transport/src/unicast/shm.rs @@ -0,0 +1,57 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use async_std::sync::RwLock; +use rand::{Rng, SeedableRng}; +use zenoh_core::zerror; +use zenoh_crypto::PseudoRng; +use zenoh_result::ZResult; +use zenoh_shm::{SharedMemoryBuf, SharedMemoryManager, SharedMemoryReader}; + +pub(crate) type Challenge = u64; +const NAME: &str = "zshm"; + +/*************************************/ +/* Authenticator */ +/*************************************/ +pub(crate) struct SharedMemoryUnicast { + // Rust guarantees that fields are dropped in the order of declaration. + // Buffer needs to be dropped before the manager. + pub(crate) challenge: SharedMemoryBuf, + pub(crate) _manager: SharedMemoryManager, + pub(crate) reader: RwLock, +} + +unsafe impl Sync for SharedMemoryUnicast {} + +impl SharedMemoryUnicast { + pub fn make() -> ZResult { + // Create a challenge for session establishment + let mut prng = PseudoRng::from_entropy(); + let nonce = prng.gen::(); + let size = std::mem::size_of::(); + + let mut _manager = SharedMemoryManager::make(format!("{NAME}.{nonce}"), size)?; + + let mut challenge = _manager.alloc(size).map_err(|e| zerror!("{e}"))?; + let slice = unsafe { challenge.as_mut_slice() }; + slice[0..size].copy_from_slice(&nonce.to_le_bytes()); + + let shmauth = SharedMemoryUnicast { + challenge, + _manager, + reader: RwLock::new(SharedMemoryReader::new()), + }; + Ok(shmauth) + } +} diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index a024bfd5d3..fc40d0e979 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -26,7 +26,6 @@ use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ core::{Priority, WhatAmI, ZInt, ZenohId}, transport::{Close, ConduitSn, TransportMessage}, - zenoh::ZenohMessage, }; use zenoh_result::{bail, zerror, ZResult}; @@ -433,27 +432,6 @@ impl TransportUnicastInner { self.delete().await } - /*************************************/ - /* SCHEDULE AND SEND TX */ - /*************************************/ - /// Schedule a Zenoh message on the transmission queue - pub(crate) fn schedule(&self, #[allow(unused_mut)] mut message: ZenohMessage) -> bool { - // #[cfg(feature = "shared-memory")] - // { - // let res = if self.config.is_shm { - // crate::shm::map_zmsg_to_shminfo(&mut message) - // } else { - // crate::shm::map_zmsg_to_shmbuf(&mut message, &self.config.manager.shmr) - // }; - // if let Err(e) = res { - // log::trace!("Failed SHM conversion: {}", e); - // return false; - // } - // } // @TODO - - self.schedule_first_fit(message) - } - pub(crate) fn get_links(&self) -> Vec { zread!(self.links).iter().map(|l| l.link.clone()).collect() } diff --git a/io/zenoh-transport/src/unicast/tx.rs b/io/zenoh-transport/src/unicast/tx.rs index 4e20eb0111..a4a7b5bca0 100644 --- a/io/zenoh-transport/src/unicast/tx.rs +++ b/io/zenoh-transport/src/unicast/tx.rs @@ -12,9 +12,10 @@ // ZettaScale Zenoh Team, // use super::transport::TransportUnicastInner; +use async_std::task; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; -use zenoh_core::zread; +use zenoh_core::{zasyncwrite, zread}; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::zenoh::ZenohMessage; @@ -65,7 +66,23 @@ impl TransportUnicastInner { #[allow(clippy::let_and_return)] // When feature "stats" is not enabled #[inline(always)] - pub(super) fn schedule_first_fit(&self, msg: ZenohMessage) -> bool { + pub(crate) fn schedule(&self, mut msg: ZenohMessage) -> bool { + #[cfg(feature = "shared-memory")] + { + let res = if self.config.is_shm { + crate::shm::map_zmsg_to_shminfo(&mut msg) + } else { + task::block_on(async { + let mut w_guard = zasyncwrite!(self.manager.state.unicast.shm.reader); + crate::shm::map_zmsg_to_shmbuf(&mut msg, &mut w_guard) + }) + }; + if let Err(e) = res { + log::trace!("Failed SHM conversion: {}", e); + return false; + } + } + #[cfg(feature = "stats")] match &msg.body { ZenohBody::Data(data) => match data.reply_context { diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index d655b6da31..f1adff1826 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -1,1030 +1,1030 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use async_std::{prelude::FutureExt, task}; -#[cfg(feature = "auth_pubkey")] -use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; -#[cfg(feature = "auth_usrpwd")] -use std::collections::HashMap; -use std::{any::Any, collections::HashSet, iter::FromIterator, sync::Arc, time::Duration}; -use zenoh_core::zasync_executor_init; -use zenoh_link::Link; -use zenoh_protocol::{ - core::{EndPoint, WhatAmI, ZenohId}, - zenoh::ZenohMessage, -}; -use zenoh_result::ZResult; -#[cfg(feature = "auth_pubkey")] -use zenoh_transport::unicast::establishment::authenticator::PubKeyAuthenticator; -#[cfg(feature = "shared-memory")] -use zenoh_transport::unicast::establishment::authenticator::SharedMemoryAuthenticator; -#[cfg(feature = "auth_usrpwd")] -use zenoh_transport::unicast::establishment::authenticator::UserPasswordAuthenticator; -use zenoh_transport::{ - DummyTransportPeerEventHandler, TransportEventHandler, TransportPeer, - TransportPeerEventHandler, TransportUnicast, -}; - -const TIMEOUT: Duration = Duration::from_secs(60); -const SLEEP: Duration = Duration::from_millis(100); - -macro_rules! ztimeout { - ($f:expr) => { - $f.timeout(TIMEOUT).await.unwrap() - }; -} - -#[cfg(test)] -struct SHRouterAuthenticator; - -impl SHRouterAuthenticator { - fn new() -> Self { - Self - } -} - -impl TransportEventHandler for SHRouterAuthenticator { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - Ok(Arc::new(MHRouterAuthenticator::new())) - } -} - -struct MHRouterAuthenticator; - -impl MHRouterAuthenticator { - fn new() -> Self { - Self - } -} - -impl TransportPeerEventHandler for MHRouterAuthenticator { - fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { - Ok(()) - } - fn new_link(&self, _link: Link) {} - fn del_link(&self, _link: Link) {} - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } -} - -// Transport Handler for the client -#[derive(Default)] -struct SHClientAuthenticator; - -impl TransportEventHandler for SHClientAuthenticator { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) - } -} - -#[cfg(feature = "auth_pubkey")] -async fn authenticator_multilink(endpoint: &EndPoint) { - use std::convert::TryFrom; - use zenoh_transport::TransportManager; - - // Create the router transport manager - let router_id = ZenohId::try_from([1]).unwrap(); - let router_handler = Arc::new(SHRouterAuthenticator::new()); - let n = BigUint::from_bytes_le(&[ - 0x31, 0xd1, 0xfc, 0x7e, 0x70, 0x5f, 0xd7, 0xe3, 0xcc, 0xa4, 0xca, 0xcb, 0x38, 0x84, 0x2f, - 0xf5, 0x88, 0xaa, 0x4b, 0xbc, 0x2f, 0x74, 0x59, 0x49, 0xa9, 0xb9, 0x1a, 0x4d, 0x1c, 0x93, - 0xbc, 0xc7, 0x02, 0xd0, 0xe0, 0x0f, 0xa7, 0x68, 0xeb, 0xef, 0x9b, 0xf9, 0x4f, 0xdc, 0xe3, - 0x40, 0x5a, 0x3c, 0x8f, 0x20, 0xf4, 0x2c, 0x90, 0x1c, 0x70, 0x56, 0x9b, 0xae, 0x44, 0x17, - 0xca, 0x85, 0x60, 0xb5, - ]); - let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); - let router_pub_key = RsaPublicKey::new(n, e).unwrap(); - - let n = BigUint::from_bytes_le(&[ - 0x31, 0xd1, 0xfc, 0x7e, 0x70, 0x5f, 0xd7, 0xe3, 0xcc, 0xa4, 0xca, 0xcb, 0x38, 0x84, 0x2f, - 0xf5, 0x88, 0xaa, 0x4b, 0xbc, 0x2f, 0x74, 0x59, 0x49, 0xa9, 0xb9, 0x1a, 0x4d, 0x1c, 0x93, - 0xbc, 0xc7, 0x02, 0xd0, 0xe0, 0x0f, 0xa7, 0x68, 0xeb, 0xef, 0x9b, 0xf9, 0x4f, 0xdc, 0xe3, - 0x40, 0x5a, 0x3c, 0x8f, 0x20, 0xf4, 0x2c, 0x90, 0x1c, 0x70, 0x56, 0x9b, 0xae, 0x44, 0x17, - 0xca, 0x85, 0x60, 0xb5, - ]); - let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); - let d = BigUint::from_bytes_le(&[ - 0xc1, 0xd1, 0xc1, 0x0f, 0xbe, 0xa7, 0xe6, 0x18, 0x98, 0x3c, 0xf8, 0x26, 0x74, 0xc0, 0xc7, - 0xef, 0xf9, 0x38, 0x95, 0x75, 0x40, 0x45, 0xd4, 0x0d, 0x27, 0xec, 0x4c, 0xcd, 0x81, 0xf9, - 0xf4, 0x69, 0x36, 0x99, 0x95, 0x97, 0xd0, 0xc8, 0x43, 0xac, 0xbb, 0x3e, 0x8f, 0xfb, 0x97, - 0x53, 0xdb, 0x92, 0x12, 0xc5, 0xc0, 0x50, 0x83, 0xb2, 0x04, 0x25, 0x79, 0xeb, 0xa7, 0x32, - 0x84, 0xbb, 0xc6, 0x35, - ]); - let primes = vec![ - BigUint::from_bytes_le(&[ - 0xb9, 0x17, 0xd3, 0x45, 0x0a, 0x8e, 0xf7, 0x41, 0xaf, 0x75, 0xe3, 0x7f, 0xe9, 0x3c, - 0x10, 0x28, 0x24, 0x0a, 0x95, 0x32, 0xc0, 0xcb, 0x23, 0x60, 0x6e, 0x2d, 0xb8, 0x2e, - 0x96, 0x78, 0x21, 0xdf, - ]), - BigUint::from_bytes_le(&[ - 0x39, 0x51, 0xd3, 0xf3, 0xfe, 0xd1, 0x81, 0xd3, 0xc3, 0x2b, 0x49, 0x65, 0x3a, 0x44, - 0x41, 0x31, 0xa7, 0x38, 0x8b, 0xd9, 0x18, 0xc7, 0x41, 0x8c, 0x86, 0x0b, 0x65, 0x2d, - 0x18, 0x78, 0x18, 0xd0, - ]), - ]; - let router_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); - let peer_auth_router = Arc::new(PubKeyAuthenticator::new(router_pub_key, router_pri_key)); - let unicast = TransportManager::config_unicast() - .max_links(2) - .peer_authenticator(HashSet::from_iter(vec![peer_auth_router.clone().into()])); - let router_manager = TransportManager::builder() - .whatami(WhatAmI::Router) - .zid(router_id) - .unicast(unicast) - .build(router_handler.clone()) - .unwrap(); - - // Create the transport transport manager for the client 01 - let client01_id = ZenohId::try_from([2]).unwrap(); - - let n = BigUint::from_bytes_le(&[ - 0x41, 0x74, 0xc6, 0x40, 0x18, 0x63, 0xbd, 0x59, 0xe6, 0x0d, 0xe9, 0x23, 0x3e, 0x95, 0xca, - 0xb4, 0x5d, 0x17, 0x3d, 0x14, 0xdd, 0xbb, 0x16, 0x4a, 0x49, 0xeb, 0x43, 0x27, 0x79, 0x3e, - 0x75, 0x67, 0xd6, 0xf6, 0x7f, 0xe7, 0xbf, 0xb5, 0x1d, 0xf6, 0x27, 0x80, 0xca, 0x26, 0x35, - 0xa2, 0xc5, 0x4c, 0x96, 0x50, 0xaa, 0x9f, 0xf4, 0x47, 0xbe, 0x06, 0x9c, 0xd1, 0xec, 0xfd, - 0x1e, 0x81, 0xe9, 0xc4, - ]); - let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); - let client01_pub_key = RsaPublicKey::new(n, e).unwrap(); - - let n = BigUint::from_bytes_le(&[ - 0x41, 0x74, 0xc6, 0x40, 0x18, 0x63, 0xbd, 0x59, 0xe6, 0x0d, 0xe9, 0x23, 0x3e, 0x95, 0xca, - 0xb4, 0x5d, 0x17, 0x3d, 0x14, 0xdd, 0xbb, 0x16, 0x4a, 0x49, 0xeb, 0x43, 0x27, 0x79, 0x3e, - 0x75, 0x67, 0xd6, 0xf6, 0x7f, 0xe7, 0xbf, 0xb5, 0x1d, 0xf6, 0x27, 0x80, 0xca, 0x26, 0x35, - 0xa2, 0xc5, 0x4c, 0x96, 0x50, 0xaa, 0x9f, 0xf4, 0x47, 0xbe, 0x06, 0x9c, 0xd1, 0xec, 0xfd, - 0x1e, 0x81, 0xe9, 0xc4, - ]); - let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); - let d = BigUint::from_bytes_le(&[ - 0x15, 0xe1, 0x93, 0xda, 0x75, 0xcb, 0x76, 0x40, 0xce, 0x70, 0x6f, 0x0f, 0x62, 0xe1, 0x58, - 0xa5, 0x53, 0x7b, 0x17, 0x63, 0x71, 0x70, 0x2d, 0x0d, 0xc5, 0xce, 0xcd, 0xb4, 0x26, 0xe0, - 0x22, 0x3d, 0xd4, 0x04, 0x88, 0x51, 0x24, 0x34, 0x01, 0x9c, 0x94, 0x01, 0x47, 0x49, 0x86, - 0xe3, 0x2f, 0x3b, 0x65, 0x5c, 0xcc, 0x0b, 0x8a, 0x00, 0x93, 0x26, 0x79, 0xbb, 0x18, 0xab, - 0x94, 0x4b, 0x52, 0x99, - ]); - let primes = vec![ - BigUint::from_bytes_le(&[ - 0x87, 0x9c, 0xbd, 0x9c, 0xbf, 0xd5, 0xb7, 0xc2, 0x73, 0x16, 0x44, 0x3f, 0x67, 0x90, - 0xaa, 0xab, 0xfe, 0x20, 0xac, 0x7d, 0xe9, 0xc4, 0xb9, 0xfb, 0x12, 0xab, 0x09, 0x35, - 0xec, 0xf5, 0x9f, 0xe1, - ]), - BigUint::from_bytes_le(&[ - 0xf7, 0xa2, 0xc1, 0x81, 0x63, 0xe1, 0x1c, 0x39, 0xe4, 0x7b, 0xbf, 0x56, 0xd5, 0x35, - 0xc3, 0xd1, 0x11, 0xf9, 0x1f, 0x42, 0x4e, 0x3e, 0xe7, 0xc9, 0xa2, 0x3c, 0x98, 0x08, - 0xaa, 0xf9, 0x6b, 0xdf, - ]), - ]; - let client01_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); - let peer_auth_client01 = PubKeyAuthenticator::new(client01_pub_key, client01_pri_key); - let unicast = TransportManager::config_unicast() - .max_links(2) - .peer_authenticator(HashSet::from_iter(vec![peer_auth_client01.into()])); - let client01_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client01_id) - .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) - .unwrap(); - - // Create the transport transport manager for the client 02 - let client02_id = ZenohId::try_from([3]).unwrap(); - - let n = BigUint::from_bytes_le(&[ - 0xd1, 0x36, 0xcf, 0x94, 0xda, 0x04, 0x7e, 0x9f, 0x53, 0x39, 0xb8, 0x7b, 0x53, 0x3a, 0xe6, - 0xa4, 0x0e, 0x6c, 0xf0, 0x92, 0x5d, 0xd9, 0x1d, 0x84, 0xc3, 0x10, 0xab, 0x8f, 0x7d, 0xe8, - 0xf4, 0xff, 0x79, 0xae, 0x00, 0x25, 0xfc, 0xaf, 0x0c, 0x0f, 0x05, 0xc7, 0xa3, 0xfd, 0x31, - 0x9a, 0xd3, 0x79, 0x0f, 0x44, 0xa6, 0x1c, 0x19, 0x61, 0xed, 0xb0, 0x27, 0x99, 0x53, 0x23, - 0x50, 0xad, 0x67, 0xcf, - ]); - let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); - let client02_pub_key = RsaPublicKey::new(n, e).unwrap(); - - let n = BigUint::from_bytes_le(&[ - 0xd1, 0x36, 0xcf, 0x94, 0xda, 0x04, 0x7e, 0x9f, 0x53, 0x39, 0xb8, 0x7b, 0x53, 0x3a, 0xe6, - 0xa4, 0x0e, 0x6c, 0xf0, 0x92, 0x5d, 0xd9, 0x1d, 0x84, 0xc3, 0x10, 0xab, 0x8f, 0x7d, 0xe8, - 0xf4, 0xff, 0x79, 0xae, 0x00, 0x25, 0xfc, 0xaf, 0x0c, 0x0f, 0x05, 0xc7, 0xa3, 0xfd, 0x31, - 0x9a, 0xd3, 0x79, 0x0f, 0x44, 0xa6, 0x1c, 0x19, 0x61, 0xed, 0xb0, 0x27, 0x99, 0x53, 0x23, - 0x50, 0xad, 0x67, 0xcf, - ]); - let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); - let d = BigUint::from_bytes_le(&[ - 0x01, 0xe4, 0xe9, 0x20, 0x20, 0x8c, 0x17, 0xd3, 0xea, 0xd0, 0x1f, 0xfa, 0x25, 0x5c, 0xaf, - 0x5d, 0x19, 0xa4, 0x2a, 0xbc, 0x62, 0x5e, 0x2c, 0x63, 0x4f, 0x6e, 0x30, 0x07, 0x7c, 0x04, - 0x72, 0xc9, 0x57, 0x3d, 0xe0, 0x59, 0x33, 0x8a, 0x36, 0x02, 0x5d, 0xa6, 0x81, 0x4e, 0x27, - 0x82, 0xce, 0x95, 0x85, 0xd4, 0xa3, 0x9b, 0x5e, 0x2a, 0x04, 0xa8, 0x9d, 0x74, 0x25, 0x70, - 0xf4, 0x37, 0x7d, 0x27, - ]); - let primes = vec![ - BigUint::from_bytes_le(&[ - 0x31, 0x55, 0x19, 0x90, 0xf4, 0xb5, 0x76, 0xed, 0xa4, 0x2e, 0x52, 0x37, 0x16, 0xd5, - 0xef, 0x0b, 0xcb, 0x00, 0x10, 0xea, 0xff, 0x4f, 0xfe, 0x04, 0xf4, 0x44, 0xac, 0x24, - 0xfc, 0x68, 0x02, 0xe4, - ]), - BigUint::from_bytes_le(&[ - 0xa1, 0x13, 0xee, 0xe0, 0xe2, 0x98, 0x4e, 0x0b, 0x90, 0x11, 0x73, 0x87, 0xa2, 0x54, - 0x8c, 0x5c, 0xe7, 0x03, 0x4b, 0xbf, 0x26, 0xfc, 0xb4, 0xba, 0xf9, 0xf9, 0x03, 0x84, - 0xb9, 0xbc, 0xdd, 0xe8, - ]), - ]; - let client02_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); - - let peer_auth_client02 = PubKeyAuthenticator::new(client02_pub_key, client02_pri_key); - let unicast = TransportManager::config_unicast() - .max_links(2) - .peer_authenticator(HashSet::from_iter(vec![peer_auth_client02.into()])); - let client02_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client02_id) - .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) - .unwrap(); - - // Create the transport transport manager for the third client - let client01_spoof_id = client01_id; - - let n = BigUint::from_bytes_le(&[ - 0x19, 0x01, 0x60, 0xf9, 0x1b, 0xd5, 0x2f, 0x1d, 0xb9, 0x16, 0xb5, 0xe4, 0xe3, 0x89, 0x7d, - 0x94, 0xa7, 0x82, 0x2f, 0xa7, 0xab, 0xec, 0xf2, 0xc2, 0x31, 0xf4, 0xf9, 0x66, 0x97, 0x6a, - 0x98, 0xf7, 0x02, 0x00, 0x0f, 0x51, 0xe4, 0xe4, 0x19, 0x29, 0xb6, 0x95, 0x1b, 0xb1, 0x2e, - 0x86, 0x2b, 0x99, 0x7f, 0x4e, 0x5a, 0x84, 0x44, 0xf3, 0xaa, 0xb3, 0xbf, 0x6c, 0xb5, 0xd4, - 0x05, 0x37, 0x33, 0xc2, - ]); - let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); - let client01_spoof_pub_key = RsaPublicKey::new(n, e).unwrap(); - - let n = BigUint::from_bytes_le(&[ - 0x19, 0x01, 0x60, 0xf9, 0x1b, 0xd5, 0x2f, 0x1d, 0xb9, 0x16, 0xb5, 0xe4, 0xe3, 0x89, 0x7d, - 0x94, 0xa7, 0x82, 0x2f, 0xa7, 0xab, 0xec, 0xf2, 0xc2, 0x31, 0xf4, 0xf9, 0x66, 0x97, 0x6a, - 0x98, 0xf7, 0x02, 0x00, 0x0f, 0x51, 0xe4, 0xe4, 0x19, 0x29, 0xb6, 0x95, 0x1b, 0xb1, 0x2e, - 0x86, 0x2b, 0x99, 0x7f, 0x4e, 0x5a, 0x84, 0x44, 0xf3, 0xaa, 0xb3, 0xbf, 0x6c, 0xb5, 0xd4, - 0x05, 0x37, 0x33, 0xc2, - ]); - let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); - let d = BigUint::from_bytes_le(&[ - 0x01, 0xef, 0x77, 0x79, 0x99, 0xf7, 0xa7, 0x14, 0x0f, 0x61, 0xc6, 0xca, 0x3e, 0x14, 0xfa, - 0x52, 0x6a, 0xbc, 0x94, 0x2a, 0xb1, 0x7e, 0x3a, 0x57, 0xd1, 0x85, 0x62, 0xa4, 0xd0, 0xf5, - 0x40, 0x6a, 0x0f, 0xb3, 0x59, 0xec, 0x7d, 0xbd, 0xac, 0xcf, 0x28, 0x5c, 0xa1, 0x11, 0x40, - 0xfa, 0x84, 0x4a, 0x54, 0xd1, 0x7f, 0x44, 0xc8, 0xce, 0xb2, 0x21, 0x63, 0xd0, 0xc4, 0x02, - 0x55, 0x0a, 0x3a, 0x12, - ]); - let primes = vec![ - BigUint::from_bytes_le(&[ - 0xe1, 0x93, 0xce, 0x13, 0x6e, 0xf4, 0xb9, 0xb8, 0xea, 0xdc, 0xc9, 0x83, 0xcb, 0xe5, - 0x7d, 0x2b, 0x2f, 0x4e, 0xef, 0x75, 0x1f, 0x10, 0x4b, 0x6e, 0xbe, 0xf1, 0xc3, 0x61, - 0x33, 0x71, 0x65, 0xce, - ]), - BigUint::from_bytes_le(&[ - 0x39, 0x94, 0x43, 0x4f, 0xd3, 0x74, 0x27, 0x94, 0xc7, 0x1b, 0x0f, 0xbb, 0x2b, 0xd4, - 0x9b, 0xf9, 0xe7, 0xfc, 0x47, 0x63, 0x44, 0x28, 0xa7, 0x81, 0x20, 0x91, 0x8e, 0xcf, - 0x5d, 0x66, 0xdf, 0xf0, - ]), - ]; - let client01_spoof_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); - - let peer_auth_client01_spoof = - PubKeyAuthenticator::new(client01_spoof_pub_key, client01_spoof_pri_key); - let unicast = TransportManager::config_unicast() - .max_links(2) - .peer_authenticator(HashSet::from_iter(vec![peer_auth_client01_spoof.into()])); - let client01_spoof_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client01_spoof_id) - .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) - .unwrap(); - - /* [1] */ - println!("\nTransport Authenticator PubKey [1a1]"); - // Add the locator on the router - ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); - println!("Transport Authenticator PubKey [1a2]"); - let locators = router_manager.get_listeners(); - println!("Transport Authenticator PubKey [1a2]: {locators:?}"); - assert_eq!(locators.len(), 1); - - /* [2a] */ - // Open a first transport from client01 to the router - // -> This should be accepted - println!("Transport Authenticator PubKey [2a1]"); - let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); - assert_eq!(c_ses1.get_links().unwrap().len(), 1); - - /* [2b] */ - // Open a second transport from client01 to the router - // -> This should be accepted - println!("Transport Authenticator PubKey [2b1]"); - let c_ses1_tmp = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); - assert_eq!(c_ses1, c_ses1_tmp); - assert_eq!(c_ses1.get_links().unwrap().len(), 2); - - /* [2c] */ - // Open a third transport from client01 to the router - // -> This should be rejected - println!("Transport Authenticator PubKey [2c1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [2c2]: {res:?}"); - assert!(res.is_err()); - assert_eq!(c_ses1.get_links().unwrap().len(), 2); - - /* [2d] */ - // Close the session - println!("Transport Authenticator PubKey [2d1]"); - ztimeout!(c_ses1.close()).unwrap(); - - ztimeout!(async { - while !router_manager.get_transports().is_empty() { - task::sleep(SLEEP).await; - } - }); - - /* [3a] */ - // Open a first transport from client02 to the router - // -> This should be accepted - println!("Transport Authenticator PubKey [3a1]"); - let c_ses2 = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); - assert_eq!(c_ses2.get_links().unwrap().len(), 1); - - /* [3b] */ - // Open a second transport from client02 to the router - // -> This should be accepted - println!("Transport Authenticator PubKey [3b1]"); - let c_ses2_tmp = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); - assert_eq!(c_ses2, c_ses2_tmp); - assert_eq!(c_ses2.get_links().unwrap().len(), 2); - - /* [3c] */ - // Open a third transport from client02 to the router - // -> This should be rejected - println!("Transport Authenticator PubKey [3c1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [3c2]: {res:?}"); - assert!(res.is_err()); - assert_eq!(c_ses2.get_links().unwrap().len(), 2); - - /* [3d] */ - // Close the session - println!("Transport Authenticator PubKey [3d1]"); - let res = ztimeout!(c_ses2.close()); - println!("Transport Authenticator PubKey [3d2]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_transports().is_empty() { - task::sleep(SLEEP).await; - } - }); - - /* [4a] */ - // Open a first transport from client01_spoof to the router - // -> This should be accepted - println!("Transport Authenticator PubKey [4a1]"); - let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [4a2]: {res:?}"); - assert!(res.is_ok()); - let c_ses1_spoof = res.unwrap(); - assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 1); - - /* [4b] */ - // Open a second transport from client01_spoof to the router - // -> This should be accepted - println!("Transport Authenticator PubKey [4b1]"); - let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [4b2]: {res:?}"); - assert!(res.is_ok()); - assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); - - /* [4c] */ - // Open a third transport from client02 to the router - // -> This should be rejected - println!("Transport Authenticator PubKey [41]"); - let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [4c2]: {res:?}"); - assert!(res.is_err()); - assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); - - /* [4d] */ - // Close the session - println!("Transport Authenticator PubKey [4d1]"); - let res = ztimeout!(c_ses1_spoof.close()); - println!("Transport Authenticator PubKey [4d2]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_transports().is_empty() { - task::sleep(SLEEP).await; - } - }); - - /* [5a] */ - // Open a first transport from client01 to the router - // -> This should be accepted - println!("Transport Authenticator PubKey [5a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [5a2]: {res:?}"); - assert!(res.is_ok()); - let c_ses1 = res.unwrap(); - assert_eq!(c_ses1.get_links().unwrap().len(), 1); - - /* [5b] */ - // Open a spoof transport from client01_spoof to the router - // -> This should be rejected. Spoofing detected. - println!("Transport Authenticator PubKey [5b1]"); - let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [5b2]: {res:?}"); - assert!(res.is_err()); - - /* [5c] */ - // Open a second transport from client01 to the router - // -> This should be accepted - println!("Transport Authenticator PubKey [5a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator PubKey [5a2]: {res:?}"); - assert!(res.is_ok()); - let c_ses1 = res.unwrap(); - assert_eq!(c_ses1.get_links().unwrap().len(), 2); - - /* [5d] */ - // Close the session - println!("Transport Authenticator PubKey [5d1]"); - let res = ztimeout!(c_ses1.close()); - println!("Transport Authenticator PubKey [5d2]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_transports().is_empty() { - task::sleep(SLEEP).await; - } - }); - - /* [6] */ - // Perform clean up of the open locators - println!("Transport Authenticator UserPassword [6a1]"); - let res = ztimeout!(router_manager.del_listener(endpoint)); - println!("Transport Authenticator UserPassword [6a2]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_listeners().is_empty() { - task::sleep(SLEEP).await; - } - }); - - ztimeout!(router_manager.close()); - ztimeout!(client01_manager.close()); - ztimeout!(client01_spoof_manager.close()); - - // Wait a little bit - task::sleep(SLEEP).await; -} - -#[cfg(feature = "auth_usrpwd")] -async fn authenticator_user_password(endpoint: &EndPoint) { - use std::convert::TryFrom; - use zenoh_transport::TransportManager; - - /* [CLIENT] */ - let client01_id = ZenohId::try_from([2]).unwrap(); - let user01 = "user01".to_string(); - let password01 = "password01".to_string(); - - let client02_id = ZenohId::try_from([3]).unwrap(); - let user02 = "invalid".to_string(); - let password02 = "invalid".to_string(); - - let client03_id = client01_id; - let user03 = "user03".to_string(); - let password03 = "password03".to_string(); - - /* [ROUTER] */ - let router_id = ZenohId::try_from([1]).unwrap(); - let router_handler = Arc::new(SHRouterAuthenticator::new()); - // Create the router transport manager - let mut lookup: HashMap, Vec> = HashMap::new(); - lookup.insert(user01.clone().into(), password01.clone().into()); - lookup.insert(user03.clone().into(), password03.clone().into()); - - let peer_auth_router = Arc::new(UserPasswordAuthenticator::new(lookup, None)); - let unicast = TransportManager::config_unicast() - .peer_authenticator(HashSet::from_iter(vec![peer_auth_router.clone().into()])); - let router_manager = TransportManager::builder() - .whatami(WhatAmI::Router) - .zid(router_id) - .unicast(unicast) - .build(router_handler.clone()) - .unwrap(); - - // Create the transport transport manager for the first client - let lookup: HashMap, Vec> = HashMap::new(); - let peer_auth_client01 = UserPasswordAuthenticator::new( - lookup, - Some((user01.clone().into(), password01.clone().into())), - ); - let unicast = TransportManager::config_unicast() - .peer_authenticator(HashSet::from_iter(vec![peer_auth_client01.into()])); - let client01_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client01_id) - .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) - .unwrap(); - - // Create the transport transport manager for the second client - let lookup: HashMap, Vec> = HashMap::new(); - let peer_auth_client02 = UserPasswordAuthenticator::new( - lookup, - Some((user02.clone().into(), password02.clone().into())), - ); - let unicast = TransportManager::config_unicast() - .peer_authenticator(HashSet::from_iter(vec![peer_auth_client02.into()])); - let client02_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client02_id) - .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) - .unwrap(); - - // Create the transport transport manager for the third client - let lookup: HashMap, Vec> = HashMap::new(); - let peer_auth_client03 = UserPasswordAuthenticator::new( - lookup, - Some((user03.clone().into(), password03.clone().into())), - ); - let unicast = TransportManager::config_unicast() - .peer_authenticator(HashSet::from_iter(vec![peer_auth_client03.into()])); - let client03_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client03_id) - .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) - .unwrap(); - - /* [1] */ - println!("\nTransport Authenticator UserPassword [1a1]"); - // Add the locator on the router - let res = ztimeout!(router_manager.add_listener(endpoint.clone())); - println!("Transport Authenticator UserPassword [1a1]: {res:?}"); - assert!(res.is_ok()); - println!("Transport Authenticator UserPassword [1a2]"); - let locators = router_manager.get_listeners(); - println!("Transport Authenticator UserPassword [1a2]: {locators:?}"); - assert_eq!(locators.len(), 1); - - /* [2] */ - // Open a first transport from the client to the router - // -> This should be accepted - println!("Transport Authenticator UserPassword [2a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [2a1]: {res:?}"); - assert!(res.is_ok()); - let c_ses1 = res.unwrap(); - - /* [3] */ - println!("Transport Authenticator UserPassword [3a1]"); - let res = ztimeout!(c_ses1.close()); - println!("Transport Authenticator UserPassword [3a1]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_transports().is_empty() { - task::sleep(SLEEP).await; - } - }); - - /* [4] */ - // Open a second transport from the client to the router - // -> This should be rejected - println!("Transport Authenticator UserPassword [4a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [4a1]: {res:?}"); - assert!(res.is_err()); - - /* [5] */ - // Open a third transport from the client to the router - // -> This should be accepted - println!("Transport Authenticator UserPassword [5a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [5a1]: {res:?}"); - assert!(res.is_ok()); - let c_ses1 = res.unwrap(); - - /* [6] */ - // Add client02 credentials on the router - let res = ztimeout!(peer_auth_router.add_user(user02.into(), password02.into())); - assert!(res.is_ok()); - // Open a fourth transport from the client to the router - // -> This should be accepted - println!("Transport Authenticator UserPassword [6a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [6a1]: {res:?}"); - assert!(res.is_ok()); - let c_ses2 = res.unwrap(); - - /* [7] */ - // Open a fourth transport from the client to the router - // -> This should be rejected - println!("Transport Authenticator UserPassword [7a1]"); - let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator UserPassword [7a1]: {res:?}"); - assert!(res.is_err()); - - /* [8] */ - println!("Transport Authenticator UserPassword [8a1]"); - let res = ztimeout!(c_ses1.close()); - println!("Transport Authenticator UserPassword [8a1]: {res:?}"); - assert!(res.is_ok()); - println!("Transport Authenticator UserPassword [8a2]"); - let res = ztimeout!(c_ses2.close()); - println!("Transport Authenticator UserPassword [8a2]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_transports().is_empty() { - task::sleep(SLEEP).await; - } - }); - - /* [9] */ - // Perform clean up of the open locators - println!("Transport Authenticator UserPassword [9a1]"); - let res = ztimeout!(router_manager.del_listener(endpoint)); - println!("Transport Authenticator UserPassword [9a2]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_listeners().is_empty() { - task::sleep(SLEEP).await; - } - }); - - // Wait a little bit - task::sleep(SLEEP).await; -} - -#[cfg(feature = "shared-memory")] -async fn authenticator_shared_memory(endpoint: &EndPoint) { - use std::convert::TryFrom; - use zenoh_transport::TransportManager; - - /* [CLIENT] */ - let client_id = ZenohId::try_from([2]).unwrap(); - - /* [ROUTER] */ - let router_id = ZenohId::try_from([1]).unwrap(); - let router_handler = Arc::new(SHRouterAuthenticator::new()); - // Create the router transport manager - let peer_auth_router = SharedMemoryAuthenticator::make().unwrap(); - let unicast = TransportManager::config_unicast() - .peer_authenticator(HashSet::from_iter(vec![peer_auth_router.into()])); - let router_manager = TransportManager::builder() - .whatami(WhatAmI::Router) - .zid(router_id) - .unicast(unicast) - .build(router_handler.clone()) - .unwrap(); - - // Create the transport transport manager for the first client - let peer_auth_client = SharedMemoryAuthenticator::make().unwrap(); - let unicast = TransportManager::config_unicast() - .peer_authenticator(HashSet::from_iter(vec![peer_auth_client.into()])); - let client_manager = TransportManager::builder() - .whatami(WhatAmI::Router) - .zid(client_id) - .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) - .unwrap(); - - /* [1] */ - println!("\nTransport Authenticator SharedMemory [1a1]"); - // Add the locator on the router - let res = ztimeout!(router_manager.add_listener(endpoint.clone())); - println!("Transport Authenticator SharedMemory [1a1]: {res:?}"); - assert!(res.is_ok()); - println!("Transport Authenticator SharedMemory [1a2]"); - let locators = router_manager.get_listeners(); - println!("Transport Authenticator SharedMemory 1a2]: {locators:?}"); - assert_eq!(locators.len(), 1); - - /* [2] */ - // Open a transport from the client to the router - // -> This should be accepted - println!("Transport Authenticator SharedMemory [2a1]"); - let res = ztimeout!(client_manager.open_transport(endpoint.clone())); - println!("Transport Authenticator SharedMemory [2a1]: {res:?}"); - assert!(res.is_ok()); - let c_ses1 = res.unwrap(); - assert!(c_ses1.is_shm().unwrap()); - - /* [3] */ - println!("Transport Authenticator SharedMemory [3a1]"); - let res = ztimeout!(c_ses1.close()); - println!("Transport Authenticator SharedMemory [3a1]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_transports().is_empty() { - task::sleep(SLEEP).await; - } - }); - - /* [4] */ - // Perform clean up of the open locators - println!("Transport Authenticator SharedMemory [4a1]"); - let res = ztimeout!(router_manager.del_listener(endpoint)); - println!("Transport Authenticator SharedMemory [4a2]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_listeners().is_empty() { - task::sleep(SLEEP).await; - } - }); - - task::sleep(SLEEP).await; -} - -async fn run(endpoint: &EndPoint) { - #[cfg(feature = "auth_pubkey")] - authenticator_multilink(endpoint).await; - #[cfg(feature = "auth_usrpwd")] - authenticator_user_password(endpoint).await; - #[cfg(feature = "shared-memory")] - authenticator_shared_memory(endpoint).await; -} - -#[cfg(feature = "transport_tcp")] -// #[test] -fn authenticator_tcp() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 8000).parse().unwrap(); - task::block_on(run(&endpoint)); -} - -#[cfg(feature = "transport_udp")] -// #[test] -fn authenticator_udp() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 8010).parse().unwrap(); - task::block_on(run(&endpoint)); -} - -#[cfg(feature = "transport_ws")] -// #[test] -fn authenticator_ws() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 8020).parse().unwrap(); - task::block_on(run(&endpoint)); -} - -#[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] -// #[test] -fn authenticator_unix() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let f1 = "zenoh-test-unix-socket-10.sock"; - let _ = std::fs::remove_file(f1); - let endpoint: EndPoint = format!("unixsock-stream/{f1}").parse().unwrap(); - task::block_on(run(&endpoint)); - let _ = std::fs::remove_file(f1); - let _ = std::fs::remove_file(format!("{f1}.lock")); -} - -#[cfg(feature = "transport_tls")] -// #[test] -fn authenticator_tls() { - use zenoh_link::tls::config::*; - - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // NOTE: this an auto-generated pair of certificate and key. - // The target domain is localhost, so it has no real - // mapping to any existing domain. The certificate and key - // have been generated using: https://github.com/jsha/minica - let key = "-----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAz105EYUbOdW5uJ8o/TqtxtOtKJL7AQdy5yiXoslosAsulaew -4JSJetVa6Fa6Bq5BK6fsphGD9bpGGeiBZFBt75JRjOrkj4DwlLGa0CPLTgG5hul4 -Ufe9B7VG3J5P8OwUqIYmPzj8uTbNtkgFRcYumHR28h4GkYdG5Y04AV4vIjgKE47j -AgV5ACRHkcmGrTzF2HOes2wT73l4yLSkKR4GlIWu5cLRdI8PTUmjMFAh/GIh1ahd -+VqXz051V3jok0n1klVNjc6DnWuH3j/MSOg/52C3YfcUjCeIJGVfcqDnPTJKSNEF -yVTYCUjWy+B0B4fMz3MpU17dDWpvS5hfc4VrgQIDAQABAoIBAQCq+i208XBqdnwk -6y7r5Tcl6qErBE3sIk0upjypX7Ju/TlS8iqYckENQ+AqFGBcY8+ehF5O68BHm2hz -sk8F/H84+wc8zuzYGjPEFtEUb38RecCUqeqog0Gcmm6sN+ioOLAr6DifBojy2mox -sx6N0oPW9qigp/s4gTcGzTLxhcwNRHWuoWjQwq6y6qwt2PJXnllii5B5iIJhKAxE -EOmcVCmFbPavQ1Xr9F5jd5rRc1TYq28hXX8dZN2JhdVUbLlHzaiUfTnA/8yI4lyq -bEmqu29Oqe+CmDtB6jRnrLiIwyZxzXKuxXaO6NqgxqtaVjLcdISEgZMeHEftuOtf -C1xxodaVAoGBAOb1Y1SvUGx+VADSt1d30h3bBm1kU/1LhLKZOAQrnFMrEfyOfYbz -AZ4FJgXE6ZsB1BA7hC0eJDVHz8gTgDJQrOOO8WJWDGRe4TbZkCi5IizYg5UH/6az -I/WKlfdA4j1tftbQhycHL+9bGzdoRzrwIK489PG4oVAJJCaK2CVtx+l3AoGBAOXY -75sHOiMaIvDA7qlqFbaBkdi1NzH7bCgy8IntNfLxlOCmGjxeNZzKrkode3JWY9SI -Mo/nuWj8EZBEHj5omCapzOtkW/Nhnzc4C6U3BCspdrQ4mzbmzEGTdhqvxepa7U7K -iRcoD1iU7kINCEwg2PsB/BvCSrkn6lpIJlYXlJDHAoGAY7QjgXd9fJi8ou5Uf8oW -RxU6nRbmuz5Sttc2O3aoMa8yQJkyz4Mwe4s1cuAjCOutJKTM1r1gXC/4HyNsAEyb -llErG4ySJPJgv1EEzs+9VSbTBw9A6jIDoAiH3QmBoYsXapzy+4I6y1XFVhIKTgND -2HQwOfm+idKobIsb7GyMFNkCgYBIsixWZBrHL2UNsHfLrXngl2qBmA81B8hVjob1 -mMkPZckopGB353Qdex1U464/o4M/nTQgv7GsuszzTBgktQAqeloNuVg7ygyJcnh8 -cMIoxJx+s8ijvKutse4Q0rdOQCP+X6CsakcwRSp2SZjuOxVljmMmhHUNysocc+Vs -JVkf0QKBgHiCVLU60EoPketADvhRJTZGAtyCMSb3q57Nb0VIJwxdTB5KShwpul1k -LPA8Z7Y2i9+IEXcPT0r3M+hTwD7noyHXNlNuzwXot4B8PvbgKkMLyOpcwBjppJd7 -ns4PifoQbhDFnZPSfnrpr+ZXSEzxtiyv7Ql69jznl/vB8b75hBL4 ------END RSA PRIVATE KEY-----"; - - let cert = "-----BEGIN CERTIFICATE----- -MIIDLDCCAhSgAwIBAgIIIXlwQVKrtaAwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMmJiOTlkMB4XDTIxMDIwMjE0NDYzNFoXDTIzMDMw -NDE0NDYzNFowFDESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAz105EYUbOdW5uJ8o/TqtxtOtKJL7AQdy5yiXoslosAsu -laew4JSJetVa6Fa6Bq5BK6fsphGD9bpGGeiBZFBt75JRjOrkj4DwlLGa0CPLTgG5 -hul4Ufe9B7VG3J5P8OwUqIYmPzj8uTbNtkgFRcYumHR28h4GkYdG5Y04AV4vIjgK -E47jAgV5ACRHkcmGrTzF2HOes2wT73l4yLSkKR4GlIWu5cLRdI8PTUmjMFAh/GIh -1ahd+VqXz051V3jok0n1klVNjc6DnWuH3j/MSOg/52C3YfcUjCeIJGVfcqDnPTJK -SNEFyVTYCUjWy+B0B4fMz3MpU17dDWpvS5hfc4VrgQIDAQABo3YwdDAOBgNVHQ8B -Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB -/wQCMAAwHwYDVR0jBBgwFoAULXa6lBiO7OLL5Z6XuF5uF5wR9PQwFAYDVR0RBA0w -C4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQBOMkNXfzPEDU475zbiSi3v -JOhpZLyuoaYY62RzZc9VF8YRybJlWKUWdR3szAiUd1xCJe/beNX7b9lPg6wNadKq -DGTWFmVxSfpVMO9GQYBXLDcNaAUXzsDLC5sbAFST7jkAJELiRn6KtQYxZ2kEzo7G -QmzNMfNMc1KeL8Qr4nfEHZx642yscSWj9edGevvx4o48j5KXcVo9+pxQQFao9T2O -F5QxyGdov+uNATWoYl92Gj8ERi7ovHimU3H7HLIwNPqMJEaX4hH/E/Oz56314E9b -AXVFFIgCSluyrolaD6CWD9MqOex4YOfJR2bNxI7lFvuK4AwjyUJzT1U1HXib17mM ------END CERTIFICATE-----"; - - // Configure the client - let ca = "-----BEGIN CERTIFICATE----- -MIIDSzCCAjOgAwIBAgIIK7mduKtTVxkwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMmJiOTlkMCAXDTIxMDIwMjEzMTc0NVoYDzIxMjEw -MjAyMTMxNzQ1WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAyYmI5OWQwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoBZOxIfVq7LoEpVCMlQzuDnFy -d+yuk5pFasEQvZ3IvWVta4rPFJ3WGl4UNF6v9bZegNHp+oo70guZ8ps9ez34qrwB -rrNtZ0YJLDvR0ygloinZZeiclrZcu+x9vRdnyfWqrAulJBMlJIbbHcNx2OCkq7MM -HdpLJMXxKVbIlQQYGUzRkNTAaK2PiFX5BaqmnZZyo7zNbz7L2asg+0K/FpiS2IRA -coHPTa9BtsLUJUPRHPr08pgTjM1MQwa+Xxg1+wtMh85xdrqMi6Oe0cxefS+0L04F -KVfMD3bW8AyuugvcTEpGnea2EvMoPfLWpnPGU3XO8lRZyotZDQzrPvNyYKM3AgMB -AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQtdrqUGI7s4svl -npe4Xm4XnBH09DAfBgNVHSMEGDAWgBQtdrqUGI7s4svlnpe4Xm4XnBH09DANBgkq -hkiG9w0BAQsFAAOCAQEAJliEt607VUOSDsUeabhG8MIhYDhxe+mjJ4i7N/0xk9JU -piCUdQr26HyYCzN+bNdjw663rxuVGtTTdHSw2CJHsPSOEDinbYkLMSyDeomsnr0S -4e0hKUeqXXYg0iC/O2283ZEvvQK5SE+cjm0La0EmqO0mj3Mkc4Fsg8hExYuOur4M -M0AufDKUhroksKKiCmjsFj1x55VcU45Ag8069lzBk7ntcGQpHUUkwZzvD4FXf8IR -pVVHiH6WC99p77T9Di99dE5ufjsprfbzkuafgTo2Rz03HgPq64L4po/idP8uBMd6 -tOzot3pwe+3SJtpk90xAQrABEO0Zh2unrC8i83ySfg== ------END CERTIFICATE-----"; - - // Define the locator - let mut endpoint: EndPoint = format!("tls/localhost:{}", 8030).parse().unwrap(); - endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, ca), - (TLS_SERVER_CERTIFICATE_RAW, cert), - (TLS_SERVER_PRIVATE_KEY_RAW, key), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - - task::block_on(run(&endpoint)); -} - -#[cfg(feature = "transport_quic")] -// #[test] -fn authenticator_quic() { - use zenoh_link::quic::config::*; - - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // NOTE: this an auto-generated pair of certificate and key. - // The target domain is localhost, so it has no real - // mapping to any existing domain. The certificate and key - // have been generated using: https://github.com/jsha/minica - let key = "-----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAz105EYUbOdW5uJ8o/TqtxtOtKJL7AQdy5yiXoslosAsulaew -4JSJetVa6Fa6Bq5BK6fsphGD9bpGGeiBZFBt75JRjOrkj4DwlLGa0CPLTgG5hul4 -Ufe9B7VG3J5P8OwUqIYmPzj8uTbNtkgFRcYumHR28h4GkYdG5Y04AV4vIjgKE47j -AgV5ACRHkcmGrTzF2HOes2wT73l4yLSkKR4GlIWu5cLRdI8PTUmjMFAh/GIh1ahd -+VqXz051V3jok0n1klVNjc6DnWuH3j/MSOg/52C3YfcUjCeIJGVfcqDnPTJKSNEF -yVTYCUjWy+B0B4fMz3MpU17dDWpvS5hfc4VrgQIDAQABAoIBAQCq+i208XBqdnwk -6y7r5Tcl6qErBE3sIk0upjypX7Ju/TlS8iqYckENQ+AqFGBcY8+ehF5O68BHm2hz -sk8F/H84+wc8zuzYGjPEFtEUb38RecCUqeqog0Gcmm6sN+ioOLAr6DifBojy2mox -sx6N0oPW9qigp/s4gTcGzTLxhcwNRHWuoWjQwq6y6qwt2PJXnllii5B5iIJhKAxE -EOmcVCmFbPavQ1Xr9F5jd5rRc1TYq28hXX8dZN2JhdVUbLlHzaiUfTnA/8yI4lyq -bEmqu29Oqe+CmDtB6jRnrLiIwyZxzXKuxXaO6NqgxqtaVjLcdISEgZMeHEftuOtf -C1xxodaVAoGBAOb1Y1SvUGx+VADSt1d30h3bBm1kU/1LhLKZOAQrnFMrEfyOfYbz -AZ4FJgXE6ZsB1BA7hC0eJDVHz8gTgDJQrOOO8WJWDGRe4TbZkCi5IizYg5UH/6az -I/WKlfdA4j1tftbQhycHL+9bGzdoRzrwIK489PG4oVAJJCaK2CVtx+l3AoGBAOXY -75sHOiMaIvDA7qlqFbaBkdi1NzH7bCgy8IntNfLxlOCmGjxeNZzKrkode3JWY9SI -Mo/nuWj8EZBEHj5omCapzOtkW/Nhnzc4C6U3BCspdrQ4mzbmzEGTdhqvxepa7U7K -iRcoD1iU7kINCEwg2PsB/BvCSrkn6lpIJlYXlJDHAoGAY7QjgXd9fJi8ou5Uf8oW -RxU6nRbmuz5Sttc2O3aoMa8yQJkyz4Mwe4s1cuAjCOutJKTM1r1gXC/4HyNsAEyb -llErG4ySJPJgv1EEzs+9VSbTBw9A6jIDoAiH3QmBoYsXapzy+4I6y1XFVhIKTgND -2HQwOfm+idKobIsb7GyMFNkCgYBIsixWZBrHL2UNsHfLrXngl2qBmA81B8hVjob1 -mMkPZckopGB353Qdex1U464/o4M/nTQgv7GsuszzTBgktQAqeloNuVg7ygyJcnh8 -cMIoxJx+s8ijvKutse4Q0rdOQCP+X6CsakcwRSp2SZjuOxVljmMmhHUNysocc+Vs -JVkf0QKBgHiCVLU60EoPketADvhRJTZGAtyCMSb3q57Nb0VIJwxdTB5KShwpul1k -LPA8Z7Y2i9+IEXcPT0r3M+hTwD7noyHXNlNuzwXot4B8PvbgKkMLyOpcwBjppJd7 -ns4PifoQbhDFnZPSfnrpr+ZXSEzxtiyv7Ql69jznl/vB8b75hBL4 ------END RSA PRIVATE KEY-----"; - - let cert = "-----BEGIN CERTIFICATE----- -MIIDLDCCAhSgAwIBAgIIIXlwQVKrtaAwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMmJiOTlkMB4XDTIxMDIwMjE0NDYzNFoXDTIzMDMw -NDE0NDYzNFowFDESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAz105EYUbOdW5uJ8o/TqtxtOtKJL7AQdy5yiXoslosAsu -laew4JSJetVa6Fa6Bq5BK6fsphGD9bpGGeiBZFBt75JRjOrkj4DwlLGa0CPLTgG5 -hul4Ufe9B7VG3J5P8OwUqIYmPzj8uTbNtkgFRcYumHR28h4GkYdG5Y04AV4vIjgK -E47jAgV5ACRHkcmGrTzF2HOes2wT73l4yLSkKR4GlIWu5cLRdI8PTUmjMFAh/GIh -1ahd+VqXz051V3jok0n1klVNjc6DnWuH3j/MSOg/52C3YfcUjCeIJGVfcqDnPTJK -SNEFyVTYCUjWy+B0B4fMz3MpU17dDWpvS5hfc4VrgQIDAQABo3YwdDAOBgNVHQ8B -Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB -/wQCMAAwHwYDVR0jBBgwFoAULXa6lBiO7OLL5Z6XuF5uF5wR9PQwFAYDVR0RBA0w -C4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQBOMkNXfzPEDU475zbiSi3v -JOhpZLyuoaYY62RzZc9VF8YRybJlWKUWdR3szAiUd1xCJe/beNX7b9lPg6wNadKq -DGTWFmVxSfpVMO9GQYBXLDcNaAUXzsDLC5sbAFST7jkAJELiRn6KtQYxZ2kEzo7G -QmzNMfNMc1KeL8Qr4nfEHZx642yscSWj9edGevvx4o48j5KXcVo9+pxQQFao9T2O -F5QxyGdov+uNATWoYl92Gj8ERi7ovHimU3H7HLIwNPqMJEaX4hH/E/Oz56314E9b -AXVFFIgCSluyrolaD6CWD9MqOex4YOfJR2bNxI7lFvuK4AwjyUJzT1U1HXib17mM ------END CERTIFICATE-----"; - - // Configure the client - let ca = "-----BEGIN CERTIFICATE----- -MIIDSzCCAjOgAwIBAgIIK7mduKtTVxkwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMmJiOTlkMCAXDTIxMDIwMjEzMTc0NVoYDzIxMjEw -MjAyMTMxNzQ1WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAyYmI5OWQwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoBZOxIfVq7LoEpVCMlQzuDnFy -d+yuk5pFasEQvZ3IvWVta4rPFJ3WGl4UNF6v9bZegNHp+oo70guZ8ps9ez34qrwB -rrNtZ0YJLDvR0ygloinZZeiclrZcu+x9vRdnyfWqrAulJBMlJIbbHcNx2OCkq7MM -HdpLJMXxKVbIlQQYGUzRkNTAaK2PiFX5BaqmnZZyo7zNbz7L2asg+0K/FpiS2IRA -coHPTa9BtsLUJUPRHPr08pgTjM1MQwa+Xxg1+wtMh85xdrqMi6Oe0cxefS+0L04F -KVfMD3bW8AyuugvcTEpGnea2EvMoPfLWpnPGU3XO8lRZyotZDQzrPvNyYKM3AgMB -AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQtdrqUGI7s4svl -npe4Xm4XnBH09DAfBgNVHSMEGDAWgBQtdrqUGI7s4svlnpe4Xm4XnBH09DANBgkq -hkiG9w0BAQsFAAOCAQEAJliEt607VUOSDsUeabhG8MIhYDhxe+mjJ4i7N/0xk9JU -piCUdQr26HyYCzN+bNdjw663rxuVGtTTdHSw2CJHsPSOEDinbYkLMSyDeomsnr0S -4e0hKUeqXXYg0iC/O2283ZEvvQK5SE+cjm0La0EmqO0mj3Mkc4Fsg8hExYuOur4M -M0AufDKUhroksKKiCmjsFj1x55VcU45Ag8069lzBk7ntcGQpHUUkwZzvD4FXf8IR -pVVHiH6WC99p77T9Di99dE5ufjsprfbzkuafgTo2Rz03HgPq64L4po/idP8uBMd6 -tOzot3pwe+3SJtpk90xAQrABEO0Zh2unrC8i83ySfg== ------END CERTIFICATE-----"; - - // Define the locator - let mut endpoint: EndPoint = format!("quic/localhost:{}", 8040).parse().unwrap(); - endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, ca), - (TLS_SERVER_CERTIFICATE_RAW, cert), - (TLS_SERVER_PRIVATE_KEY_RAW, key), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - - task::block_on(run(&endpoint)); -} +// // +// // Copyright (c) 2022 ZettaScale Technology +// // +// // This program and the accompanying materials are made available under the +// // terms of the Eclipse Public License 2.0 which is available at +// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// // which is available at https://www.apache.org/licenses/LICENSE-2.0. +// // +// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// // +// // Contributors: +// // ZettaScale Zenoh Team, +// // +// use async_std::{prelude::FutureExt, task}; +// #[cfg(feature = "auth_pubkey")] +// use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; +// #[cfg(feature = "auth_usrpwd")] +// use std::collections::HashMap; +// use std::{any::Any, collections::HashSet, iter::FromIterator, sync::Arc, time::Duration}; +// use zenoh_core::zasync_executor_init; +// use zenoh_link::Link; +// use zenoh_protocol::{ +// core::{EndPoint, WhatAmI, ZenohId}, +// zenoh::ZenohMessage, +// }; +// use zenoh_result::ZResult; +// #[cfg(feature = "auth_pubkey")] +// use zenoh_transport::unicast::establishment::authenticator::PubKeyAuthenticator; +// #[cfg(feature = "shared-memory")] +// use zenoh_transport::unicast::establishment::authenticator::SharedMemoryAuthenticator; +// #[cfg(feature = "auth_usrpwd")] +// use zenoh_transport::unicast::establishment::authenticator::UserPasswordAuthenticator; +// use zenoh_transport::{ +// DummyTransportPeerEventHandler, TransportEventHandler, TransportPeer, +// TransportPeerEventHandler, TransportUnicast, +// }; + +// const TIMEOUT: Duration = Duration::from_secs(60); +// const SLEEP: Duration = Duration::from_millis(100); + +// macro_rules! ztimeout { +// ($f:expr) => { +// $f.timeout(TIMEOUT).await.unwrap() +// }; +// } + +// #[cfg(test)] +// struct SHRouterAuthenticator; + +// impl SHRouterAuthenticator { +// fn new() -> Self { +// Self +// } +// } + +// impl TransportEventHandler for SHRouterAuthenticator { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// Ok(Arc::new(MHRouterAuthenticator::new())) +// } +// } + +// struct MHRouterAuthenticator; + +// impl MHRouterAuthenticator { +// fn new() -> Self { +// Self +// } +// } + +// impl TransportPeerEventHandler for MHRouterAuthenticator { +// fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { +// Ok(()) +// } +// fn new_link(&self, _link: Link) {} +// fn del_link(&self, _link: Link) {} +// fn closing(&self) {} +// fn closed(&self) {} + +// fn as_any(&self) -> &dyn Any { +// self +// } +// } + +// // Transport Handler for the client +// #[derive(Default)] +// struct SHClientAuthenticator; + +// impl TransportEventHandler for SHClientAuthenticator { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// Ok(Arc::new(DummyTransportPeerEventHandler::default())) +// } +// } + +// #[cfg(feature = "auth_pubkey")] +// async fn authenticator_multilink(endpoint: &EndPoint) { +// use std::convert::TryFrom; +// use zenoh_transport::TransportManager; + +// // Create the router transport manager +// let router_id = ZenohId::try_from([1]).unwrap(); +// let router_handler = Arc::new(SHRouterAuthenticator::new()); +// let n = BigUint::from_bytes_le(&[ +// 0x31, 0xd1, 0xfc, 0x7e, 0x70, 0x5f, 0xd7, 0xe3, 0xcc, 0xa4, 0xca, 0xcb, 0x38, 0x84, 0x2f, +// 0xf5, 0x88, 0xaa, 0x4b, 0xbc, 0x2f, 0x74, 0x59, 0x49, 0xa9, 0xb9, 0x1a, 0x4d, 0x1c, 0x93, +// 0xbc, 0xc7, 0x02, 0xd0, 0xe0, 0x0f, 0xa7, 0x68, 0xeb, 0xef, 0x9b, 0xf9, 0x4f, 0xdc, 0xe3, +// 0x40, 0x5a, 0x3c, 0x8f, 0x20, 0xf4, 0x2c, 0x90, 0x1c, 0x70, 0x56, 0x9b, 0xae, 0x44, 0x17, +// 0xca, 0x85, 0x60, 0xb5, +// ]); +// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); +// let router_pub_key = RsaPublicKey::new(n, e).unwrap(); + +// let n = BigUint::from_bytes_le(&[ +// 0x31, 0xd1, 0xfc, 0x7e, 0x70, 0x5f, 0xd7, 0xe3, 0xcc, 0xa4, 0xca, 0xcb, 0x38, 0x84, 0x2f, +// 0xf5, 0x88, 0xaa, 0x4b, 0xbc, 0x2f, 0x74, 0x59, 0x49, 0xa9, 0xb9, 0x1a, 0x4d, 0x1c, 0x93, +// 0xbc, 0xc7, 0x02, 0xd0, 0xe0, 0x0f, 0xa7, 0x68, 0xeb, 0xef, 0x9b, 0xf9, 0x4f, 0xdc, 0xe3, +// 0x40, 0x5a, 0x3c, 0x8f, 0x20, 0xf4, 0x2c, 0x90, 0x1c, 0x70, 0x56, 0x9b, 0xae, 0x44, 0x17, +// 0xca, 0x85, 0x60, 0xb5, +// ]); +// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); +// let d = BigUint::from_bytes_le(&[ +// 0xc1, 0xd1, 0xc1, 0x0f, 0xbe, 0xa7, 0xe6, 0x18, 0x98, 0x3c, 0xf8, 0x26, 0x74, 0xc0, 0xc7, +// 0xef, 0xf9, 0x38, 0x95, 0x75, 0x40, 0x45, 0xd4, 0x0d, 0x27, 0xec, 0x4c, 0xcd, 0x81, 0xf9, +// 0xf4, 0x69, 0x36, 0x99, 0x95, 0x97, 0xd0, 0xc8, 0x43, 0xac, 0xbb, 0x3e, 0x8f, 0xfb, 0x97, +// 0x53, 0xdb, 0x92, 0x12, 0xc5, 0xc0, 0x50, 0x83, 0xb2, 0x04, 0x25, 0x79, 0xeb, 0xa7, 0x32, +// 0x84, 0xbb, 0xc6, 0x35, +// ]); +// let primes = vec![ +// BigUint::from_bytes_le(&[ +// 0xb9, 0x17, 0xd3, 0x45, 0x0a, 0x8e, 0xf7, 0x41, 0xaf, 0x75, 0xe3, 0x7f, 0xe9, 0x3c, +// 0x10, 0x28, 0x24, 0x0a, 0x95, 0x32, 0xc0, 0xcb, 0x23, 0x60, 0x6e, 0x2d, 0xb8, 0x2e, +// 0x96, 0x78, 0x21, 0xdf, +// ]), +// BigUint::from_bytes_le(&[ +// 0x39, 0x51, 0xd3, 0xf3, 0xfe, 0xd1, 0x81, 0xd3, 0xc3, 0x2b, 0x49, 0x65, 0x3a, 0x44, +// 0x41, 0x31, 0xa7, 0x38, 0x8b, 0xd9, 0x18, 0xc7, 0x41, 0x8c, 0x86, 0x0b, 0x65, 0x2d, +// 0x18, 0x78, 0x18, 0xd0, +// ]), +// ]; +// let router_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); +// let peer_auth_router = Arc::new(PubKeyAuthenticator::new(router_pub_key, router_pri_key)); +// let unicast = TransportManager::config_unicast() +// .max_links(2) +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_router.clone().into()])); +// let router_manager = TransportManager::builder() +// .whatami(WhatAmI::Router) +// .zid(router_id) +// .unicast(unicast) +// .build(router_handler.clone()) +// .unwrap(); + +// // Create the transport transport manager for the client 01 +// let client01_id = ZenohId::try_from([2]).unwrap(); + +// let n = BigUint::from_bytes_le(&[ +// 0x41, 0x74, 0xc6, 0x40, 0x18, 0x63, 0xbd, 0x59, 0xe6, 0x0d, 0xe9, 0x23, 0x3e, 0x95, 0xca, +// 0xb4, 0x5d, 0x17, 0x3d, 0x14, 0xdd, 0xbb, 0x16, 0x4a, 0x49, 0xeb, 0x43, 0x27, 0x79, 0x3e, +// 0x75, 0x67, 0xd6, 0xf6, 0x7f, 0xe7, 0xbf, 0xb5, 0x1d, 0xf6, 0x27, 0x80, 0xca, 0x26, 0x35, +// 0xa2, 0xc5, 0x4c, 0x96, 0x50, 0xaa, 0x9f, 0xf4, 0x47, 0xbe, 0x06, 0x9c, 0xd1, 0xec, 0xfd, +// 0x1e, 0x81, 0xe9, 0xc4, +// ]); +// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); +// let client01_pub_key = RsaPublicKey::new(n, e).unwrap(); + +// let n = BigUint::from_bytes_le(&[ +// 0x41, 0x74, 0xc6, 0x40, 0x18, 0x63, 0xbd, 0x59, 0xe6, 0x0d, 0xe9, 0x23, 0x3e, 0x95, 0xca, +// 0xb4, 0x5d, 0x17, 0x3d, 0x14, 0xdd, 0xbb, 0x16, 0x4a, 0x49, 0xeb, 0x43, 0x27, 0x79, 0x3e, +// 0x75, 0x67, 0xd6, 0xf6, 0x7f, 0xe7, 0xbf, 0xb5, 0x1d, 0xf6, 0x27, 0x80, 0xca, 0x26, 0x35, +// 0xa2, 0xc5, 0x4c, 0x96, 0x50, 0xaa, 0x9f, 0xf4, 0x47, 0xbe, 0x06, 0x9c, 0xd1, 0xec, 0xfd, +// 0x1e, 0x81, 0xe9, 0xc4, +// ]); +// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); +// let d = BigUint::from_bytes_le(&[ +// 0x15, 0xe1, 0x93, 0xda, 0x75, 0xcb, 0x76, 0x40, 0xce, 0x70, 0x6f, 0x0f, 0x62, 0xe1, 0x58, +// 0xa5, 0x53, 0x7b, 0x17, 0x63, 0x71, 0x70, 0x2d, 0x0d, 0xc5, 0xce, 0xcd, 0xb4, 0x26, 0xe0, +// 0x22, 0x3d, 0xd4, 0x04, 0x88, 0x51, 0x24, 0x34, 0x01, 0x9c, 0x94, 0x01, 0x47, 0x49, 0x86, +// 0xe3, 0x2f, 0x3b, 0x65, 0x5c, 0xcc, 0x0b, 0x8a, 0x00, 0x93, 0x26, 0x79, 0xbb, 0x18, 0xab, +// 0x94, 0x4b, 0x52, 0x99, +// ]); +// let primes = vec![ +// BigUint::from_bytes_le(&[ +// 0x87, 0x9c, 0xbd, 0x9c, 0xbf, 0xd5, 0xb7, 0xc2, 0x73, 0x16, 0x44, 0x3f, 0x67, 0x90, +// 0xaa, 0xab, 0xfe, 0x20, 0xac, 0x7d, 0xe9, 0xc4, 0xb9, 0xfb, 0x12, 0xab, 0x09, 0x35, +// 0xec, 0xf5, 0x9f, 0xe1, +// ]), +// BigUint::from_bytes_le(&[ +// 0xf7, 0xa2, 0xc1, 0x81, 0x63, 0xe1, 0x1c, 0x39, 0xe4, 0x7b, 0xbf, 0x56, 0xd5, 0x35, +// 0xc3, 0xd1, 0x11, 0xf9, 0x1f, 0x42, 0x4e, 0x3e, 0xe7, 0xc9, 0xa2, 0x3c, 0x98, 0x08, +// 0xaa, 0xf9, 0x6b, 0xdf, +// ]), +// ]; +// let client01_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); +// let peer_auth_client01 = PubKeyAuthenticator::new(client01_pub_key, client01_pri_key); +// let unicast = TransportManager::config_unicast() +// .max_links(2) +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client01.into()])); +// let client01_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client01_id) +// .unicast(unicast) +// .build(Arc::new(SHClientAuthenticator::default())) +// .unwrap(); + +// // Create the transport transport manager for the client 02 +// let client02_id = ZenohId::try_from([3]).unwrap(); + +// let n = BigUint::from_bytes_le(&[ +// 0xd1, 0x36, 0xcf, 0x94, 0xda, 0x04, 0x7e, 0x9f, 0x53, 0x39, 0xb8, 0x7b, 0x53, 0x3a, 0xe6, +// 0xa4, 0x0e, 0x6c, 0xf0, 0x92, 0x5d, 0xd9, 0x1d, 0x84, 0xc3, 0x10, 0xab, 0x8f, 0x7d, 0xe8, +// 0xf4, 0xff, 0x79, 0xae, 0x00, 0x25, 0xfc, 0xaf, 0x0c, 0x0f, 0x05, 0xc7, 0xa3, 0xfd, 0x31, +// 0x9a, 0xd3, 0x79, 0x0f, 0x44, 0xa6, 0x1c, 0x19, 0x61, 0xed, 0xb0, 0x27, 0x99, 0x53, 0x23, +// 0x50, 0xad, 0x67, 0xcf, +// ]); +// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); +// let client02_pub_key = RsaPublicKey::new(n, e).unwrap(); + +// let n = BigUint::from_bytes_le(&[ +// 0xd1, 0x36, 0xcf, 0x94, 0xda, 0x04, 0x7e, 0x9f, 0x53, 0x39, 0xb8, 0x7b, 0x53, 0x3a, 0xe6, +// 0xa4, 0x0e, 0x6c, 0xf0, 0x92, 0x5d, 0xd9, 0x1d, 0x84, 0xc3, 0x10, 0xab, 0x8f, 0x7d, 0xe8, +// 0xf4, 0xff, 0x79, 0xae, 0x00, 0x25, 0xfc, 0xaf, 0x0c, 0x0f, 0x05, 0xc7, 0xa3, 0xfd, 0x31, +// 0x9a, 0xd3, 0x79, 0x0f, 0x44, 0xa6, 0x1c, 0x19, 0x61, 0xed, 0xb0, 0x27, 0x99, 0x53, 0x23, +// 0x50, 0xad, 0x67, 0xcf, +// ]); +// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); +// let d = BigUint::from_bytes_le(&[ +// 0x01, 0xe4, 0xe9, 0x20, 0x20, 0x8c, 0x17, 0xd3, 0xea, 0xd0, 0x1f, 0xfa, 0x25, 0x5c, 0xaf, +// 0x5d, 0x19, 0xa4, 0x2a, 0xbc, 0x62, 0x5e, 0x2c, 0x63, 0x4f, 0x6e, 0x30, 0x07, 0x7c, 0x04, +// 0x72, 0xc9, 0x57, 0x3d, 0xe0, 0x59, 0x33, 0x8a, 0x36, 0x02, 0x5d, 0xa6, 0x81, 0x4e, 0x27, +// 0x82, 0xce, 0x95, 0x85, 0xd4, 0xa3, 0x9b, 0x5e, 0x2a, 0x04, 0xa8, 0x9d, 0x74, 0x25, 0x70, +// 0xf4, 0x37, 0x7d, 0x27, +// ]); +// let primes = vec![ +// BigUint::from_bytes_le(&[ +// 0x31, 0x55, 0x19, 0x90, 0xf4, 0xb5, 0x76, 0xed, 0xa4, 0x2e, 0x52, 0x37, 0x16, 0xd5, +// 0xef, 0x0b, 0xcb, 0x00, 0x10, 0xea, 0xff, 0x4f, 0xfe, 0x04, 0xf4, 0x44, 0xac, 0x24, +// 0xfc, 0x68, 0x02, 0xe4, +// ]), +// BigUint::from_bytes_le(&[ +// 0xa1, 0x13, 0xee, 0xe0, 0xe2, 0x98, 0x4e, 0x0b, 0x90, 0x11, 0x73, 0x87, 0xa2, 0x54, +// 0x8c, 0x5c, 0xe7, 0x03, 0x4b, 0xbf, 0x26, 0xfc, 0xb4, 0xba, 0xf9, 0xf9, 0x03, 0x84, +// 0xb9, 0xbc, 0xdd, 0xe8, +// ]), +// ]; +// let client02_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); + +// let peer_auth_client02 = PubKeyAuthenticator::new(client02_pub_key, client02_pri_key); +// let unicast = TransportManager::config_unicast() +// .max_links(2) +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client02.into()])); +// let client02_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client02_id) +// .unicast(unicast) +// .build(Arc::new(SHClientAuthenticator::default())) +// .unwrap(); + +// // Create the transport transport manager for the third client +// let client01_spoof_id = client01_id; + +// let n = BigUint::from_bytes_le(&[ +// 0x19, 0x01, 0x60, 0xf9, 0x1b, 0xd5, 0x2f, 0x1d, 0xb9, 0x16, 0xb5, 0xe4, 0xe3, 0x89, 0x7d, +// 0x94, 0xa7, 0x82, 0x2f, 0xa7, 0xab, 0xec, 0xf2, 0xc2, 0x31, 0xf4, 0xf9, 0x66, 0x97, 0x6a, +// 0x98, 0xf7, 0x02, 0x00, 0x0f, 0x51, 0xe4, 0xe4, 0x19, 0x29, 0xb6, 0x95, 0x1b, 0xb1, 0x2e, +// 0x86, 0x2b, 0x99, 0x7f, 0x4e, 0x5a, 0x84, 0x44, 0xf3, 0xaa, 0xb3, 0xbf, 0x6c, 0xb5, 0xd4, +// 0x05, 0x37, 0x33, 0xc2, +// ]); +// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); +// let client01_spoof_pub_key = RsaPublicKey::new(n, e).unwrap(); + +// let n = BigUint::from_bytes_le(&[ +// 0x19, 0x01, 0x60, 0xf9, 0x1b, 0xd5, 0x2f, 0x1d, 0xb9, 0x16, 0xb5, 0xe4, 0xe3, 0x89, 0x7d, +// 0x94, 0xa7, 0x82, 0x2f, 0xa7, 0xab, 0xec, 0xf2, 0xc2, 0x31, 0xf4, 0xf9, 0x66, 0x97, 0x6a, +// 0x98, 0xf7, 0x02, 0x00, 0x0f, 0x51, 0xe4, 0xe4, 0x19, 0x29, 0xb6, 0x95, 0x1b, 0xb1, 0x2e, +// 0x86, 0x2b, 0x99, 0x7f, 0x4e, 0x5a, 0x84, 0x44, 0xf3, 0xaa, 0xb3, 0xbf, 0x6c, 0xb5, 0xd4, +// 0x05, 0x37, 0x33, 0xc2, +// ]); +// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); +// let d = BigUint::from_bytes_le(&[ +// 0x01, 0xef, 0x77, 0x79, 0x99, 0xf7, 0xa7, 0x14, 0x0f, 0x61, 0xc6, 0xca, 0x3e, 0x14, 0xfa, +// 0x52, 0x6a, 0xbc, 0x94, 0x2a, 0xb1, 0x7e, 0x3a, 0x57, 0xd1, 0x85, 0x62, 0xa4, 0xd0, 0xf5, +// 0x40, 0x6a, 0x0f, 0xb3, 0x59, 0xec, 0x7d, 0xbd, 0xac, 0xcf, 0x28, 0x5c, 0xa1, 0x11, 0x40, +// 0xfa, 0x84, 0x4a, 0x54, 0xd1, 0x7f, 0x44, 0xc8, 0xce, 0xb2, 0x21, 0x63, 0xd0, 0xc4, 0x02, +// 0x55, 0x0a, 0x3a, 0x12, +// ]); +// let primes = vec![ +// BigUint::from_bytes_le(&[ +// 0xe1, 0x93, 0xce, 0x13, 0x6e, 0xf4, 0xb9, 0xb8, 0xea, 0xdc, 0xc9, 0x83, 0xcb, 0xe5, +// 0x7d, 0x2b, 0x2f, 0x4e, 0xef, 0x75, 0x1f, 0x10, 0x4b, 0x6e, 0xbe, 0xf1, 0xc3, 0x61, +// 0x33, 0x71, 0x65, 0xce, +// ]), +// BigUint::from_bytes_le(&[ +// 0x39, 0x94, 0x43, 0x4f, 0xd3, 0x74, 0x27, 0x94, 0xc7, 0x1b, 0x0f, 0xbb, 0x2b, 0xd4, +// 0x9b, 0xf9, 0xe7, 0xfc, 0x47, 0x63, 0x44, 0x28, 0xa7, 0x81, 0x20, 0x91, 0x8e, 0xcf, +// 0x5d, 0x66, 0xdf, 0xf0, +// ]), +// ]; +// let client01_spoof_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); + +// let peer_auth_client01_spoof = +// PubKeyAuthenticator::new(client01_spoof_pub_key, client01_spoof_pri_key); +// let unicast = TransportManager::config_unicast() +// .max_links(2) +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client01_spoof.into()])); +// let client01_spoof_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client01_spoof_id) +// .unicast(unicast) +// .build(Arc::new(SHClientAuthenticator::default())) +// .unwrap(); + +// /* [1] */ +// println!("\nTransport Authenticator PubKey [1a1]"); +// // Add the locator on the router +// ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); +// println!("Transport Authenticator PubKey [1a2]"); +// let locators = router_manager.get_listeners(); +// println!("Transport Authenticator PubKey [1a2]: {locators:?}"); +// assert_eq!(locators.len(), 1); + +// /* [2a] */ +// // Open a first transport from client01 to the router +// // -> This should be accepted +// println!("Transport Authenticator PubKey [2a1]"); +// let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); +// assert_eq!(c_ses1.get_links().unwrap().len(), 1); + +// /* [2b] */ +// // Open a second transport from client01 to the router +// // -> This should be accepted +// println!("Transport Authenticator PubKey [2b1]"); +// let c_ses1_tmp = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); +// assert_eq!(c_ses1, c_ses1_tmp); +// assert_eq!(c_ses1.get_links().unwrap().len(), 2); + +// /* [2c] */ +// // Open a third transport from client01 to the router +// // -> This should be rejected +// println!("Transport Authenticator PubKey [2c1]"); +// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator PubKey [2c2]: {res:?}"); +// assert!(res.is_err()); +// assert_eq!(c_ses1.get_links().unwrap().len(), 2); + +// /* [2d] */ +// // Close the session +// println!("Transport Authenticator PubKey [2d1]"); +// ztimeout!(c_ses1.close()).unwrap(); + +// ztimeout!(async { +// while !router_manager.get_transports().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// /* [3a] */ +// // Open a first transport from client02 to the router +// // -> This should be accepted +// println!("Transport Authenticator PubKey [3a1]"); +// let c_ses2 = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); +// assert_eq!(c_ses2.get_links().unwrap().len(), 1); + +// /* [3b] */ +// // Open a second transport from client02 to the router +// // -> This should be accepted +// println!("Transport Authenticator PubKey [3b1]"); +// let c_ses2_tmp = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); +// assert_eq!(c_ses2, c_ses2_tmp); +// assert_eq!(c_ses2.get_links().unwrap().len(), 2); + +// /* [3c] */ +// // Open a third transport from client02 to the router +// // -> This should be rejected +// println!("Transport Authenticator PubKey [3c1]"); +// let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator PubKey [3c2]: {res:?}"); +// assert!(res.is_err()); +// assert_eq!(c_ses2.get_links().unwrap().len(), 2); + +// /* [3d] */ +// // Close the session +// println!("Transport Authenticator PubKey [3d1]"); +// let res = ztimeout!(c_ses2.close()); +// println!("Transport Authenticator PubKey [3d2]: {res:?}"); +// assert!(res.is_ok()); + +// ztimeout!(async { +// while !router_manager.get_transports().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// /* [4a] */ +// // Open a first transport from client01_spoof to the router +// // -> This should be accepted +// println!("Transport Authenticator PubKey [4a1]"); +// let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator PubKey [4a2]: {res:?}"); +// assert!(res.is_ok()); +// let c_ses1_spoof = res.unwrap(); +// assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 1); + +// /* [4b] */ +// // Open a second transport from client01_spoof to the router +// // -> This should be accepted +// println!("Transport Authenticator PubKey [4b1]"); +// let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator PubKey [4b2]: {res:?}"); +// assert!(res.is_ok()); +// assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); + +// /* [4c] */ +// // Open a third transport from client02 to the router +// // -> This should be rejected +// println!("Transport Authenticator PubKey [41]"); +// let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator PubKey [4c2]: {res:?}"); +// assert!(res.is_err()); +// assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); + +// /* [4d] */ +// // Close the session +// println!("Transport Authenticator PubKey [4d1]"); +// let res = ztimeout!(c_ses1_spoof.close()); +// println!("Transport Authenticator PubKey [4d2]: {res:?}"); +// assert!(res.is_ok()); + +// ztimeout!(async { +// while !router_manager.get_transports().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// /* [5a] */ +// // Open a first transport from client01 to the router +// // -> This should be accepted +// println!("Transport Authenticator PubKey [5a1]"); +// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator PubKey [5a2]: {res:?}"); +// assert!(res.is_ok()); +// let c_ses1 = res.unwrap(); +// assert_eq!(c_ses1.get_links().unwrap().len(), 1); + +// /* [5b] */ +// // Open a spoof transport from client01_spoof to the router +// // -> This should be rejected. Spoofing detected. +// println!("Transport Authenticator PubKey [5b1]"); +// let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator PubKey [5b2]: {res:?}"); +// assert!(res.is_err()); + +// /* [5c] */ +// // Open a second transport from client01 to the router +// // -> This should be accepted +// println!("Transport Authenticator PubKey [5a1]"); +// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator PubKey [5a2]: {res:?}"); +// assert!(res.is_ok()); +// let c_ses1 = res.unwrap(); +// assert_eq!(c_ses1.get_links().unwrap().len(), 2); + +// /* [5d] */ +// // Close the session +// println!("Transport Authenticator PubKey [5d1]"); +// let res = ztimeout!(c_ses1.close()); +// println!("Transport Authenticator PubKey [5d2]: {res:?}"); +// assert!(res.is_ok()); + +// ztimeout!(async { +// while !router_manager.get_transports().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// /* [6] */ +// // Perform clean up of the open locators +// println!("Transport Authenticator UserPassword [6a1]"); +// let res = ztimeout!(router_manager.del_listener(endpoint)); +// println!("Transport Authenticator UserPassword [6a2]: {res:?}"); +// assert!(res.is_ok()); + +// ztimeout!(async { +// while !router_manager.get_listeners().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// ztimeout!(router_manager.close()); +// ztimeout!(client01_manager.close()); +// ztimeout!(client01_spoof_manager.close()); + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// #[cfg(feature = "auth_usrpwd")] +// async fn authenticator_user_password(endpoint: &EndPoint) { +// use std::convert::TryFrom; +// use zenoh_transport::TransportManager; + +// /* [CLIENT] */ +// let client01_id = ZenohId::try_from([2]).unwrap(); +// let user01 = "user01".to_string(); +// let password01 = "password01".to_string(); + +// let client02_id = ZenohId::try_from([3]).unwrap(); +// let user02 = "invalid".to_string(); +// let password02 = "invalid".to_string(); + +// let client03_id = client01_id; +// let user03 = "user03".to_string(); +// let password03 = "password03".to_string(); + +// /* [ROUTER] */ +// let router_id = ZenohId::try_from([1]).unwrap(); +// let router_handler = Arc::new(SHRouterAuthenticator::new()); +// // Create the router transport manager +// let mut lookup: HashMap, Vec> = HashMap::new(); +// lookup.insert(user01.clone().into(), password01.clone().into()); +// lookup.insert(user03.clone().into(), password03.clone().into()); + +// let peer_auth_router = Arc::new(UserPasswordAuthenticator::new(lookup, None)); +// let unicast = TransportManager::config_unicast() +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_router.clone().into()])); +// let router_manager = TransportManager::builder() +// .whatami(WhatAmI::Router) +// .zid(router_id) +// .unicast(unicast) +// .build(router_handler.clone()) +// .unwrap(); + +// // Create the transport transport manager for the first client +// let lookup: HashMap, Vec> = HashMap::new(); +// let peer_auth_client01 = UserPasswordAuthenticator::new( +// lookup, +// Some((user01.clone().into(), password01.clone().into())), +// ); +// let unicast = TransportManager::config_unicast() +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client01.into()])); +// let client01_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client01_id) +// .unicast(unicast) +// .build(Arc::new(SHClientAuthenticator::default())) +// .unwrap(); + +// // Create the transport transport manager for the second client +// let lookup: HashMap, Vec> = HashMap::new(); +// let peer_auth_client02 = UserPasswordAuthenticator::new( +// lookup, +// Some((user02.clone().into(), password02.clone().into())), +// ); +// let unicast = TransportManager::config_unicast() +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client02.into()])); +// let client02_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client02_id) +// .unicast(unicast) +// .build(Arc::new(SHClientAuthenticator::default())) +// .unwrap(); + +// // Create the transport transport manager for the third client +// let lookup: HashMap, Vec> = HashMap::new(); +// let peer_auth_client03 = UserPasswordAuthenticator::new( +// lookup, +// Some((user03.clone().into(), password03.clone().into())), +// ); +// let unicast = TransportManager::config_unicast() +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client03.into()])); +// let client03_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client03_id) +// .unicast(unicast) +// .build(Arc::new(SHClientAuthenticator::default())) +// .unwrap(); + +// /* [1] */ +// println!("\nTransport Authenticator UserPassword [1a1]"); +// // Add the locator on the router +// let res = ztimeout!(router_manager.add_listener(endpoint.clone())); +// println!("Transport Authenticator UserPassword [1a1]: {res:?}"); +// assert!(res.is_ok()); +// println!("Transport Authenticator UserPassword [1a2]"); +// let locators = router_manager.get_listeners(); +// println!("Transport Authenticator UserPassword [1a2]: {locators:?}"); +// assert_eq!(locators.len(), 1); + +// /* [2] */ +// // Open a first transport from the client to the router +// // -> This should be accepted +// println!("Transport Authenticator UserPassword [2a1]"); +// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator UserPassword [2a1]: {res:?}"); +// assert!(res.is_ok()); +// let c_ses1 = res.unwrap(); + +// /* [3] */ +// println!("Transport Authenticator UserPassword [3a1]"); +// let res = ztimeout!(c_ses1.close()); +// println!("Transport Authenticator UserPassword [3a1]: {res:?}"); +// assert!(res.is_ok()); + +// ztimeout!(async { +// while !router_manager.get_transports().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// /* [4] */ +// // Open a second transport from the client to the router +// // -> This should be rejected +// println!("Transport Authenticator UserPassword [4a1]"); +// let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator UserPassword [4a1]: {res:?}"); +// assert!(res.is_err()); + +// /* [5] */ +// // Open a third transport from the client to the router +// // -> This should be accepted +// println!("Transport Authenticator UserPassword [5a1]"); +// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator UserPassword [5a1]: {res:?}"); +// assert!(res.is_ok()); +// let c_ses1 = res.unwrap(); + +// /* [6] */ +// // Add client02 credentials on the router +// let res = ztimeout!(peer_auth_router.add_user(user02.into(), password02.into())); +// assert!(res.is_ok()); +// // Open a fourth transport from the client to the router +// // -> This should be accepted +// println!("Transport Authenticator UserPassword [6a1]"); +// let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator UserPassword [6a1]: {res:?}"); +// assert!(res.is_ok()); +// let c_ses2 = res.unwrap(); + +// /* [7] */ +// // Open a fourth transport from the client to the router +// // -> This should be rejected +// println!("Transport Authenticator UserPassword [7a1]"); +// let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator UserPassword [7a1]: {res:?}"); +// assert!(res.is_err()); + +// /* [8] */ +// println!("Transport Authenticator UserPassword [8a1]"); +// let res = ztimeout!(c_ses1.close()); +// println!("Transport Authenticator UserPassword [8a1]: {res:?}"); +// assert!(res.is_ok()); +// println!("Transport Authenticator UserPassword [8a2]"); +// let res = ztimeout!(c_ses2.close()); +// println!("Transport Authenticator UserPassword [8a2]: {res:?}"); +// assert!(res.is_ok()); + +// ztimeout!(async { +// while !router_manager.get_transports().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// /* [9] */ +// // Perform clean up of the open locators +// println!("Transport Authenticator UserPassword [9a1]"); +// let res = ztimeout!(router_manager.del_listener(endpoint)); +// println!("Transport Authenticator UserPassword [9a2]: {res:?}"); +// assert!(res.is_ok()); + +// ztimeout!(async { +// while !router_manager.get_listeners().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// #[cfg(feature = "shared-memory")] +// async fn authenticator_shared_memory(endpoint: &EndPoint) { +// use std::convert::TryFrom; +// use zenoh_transport::TransportManager; + +// /* [CLIENT] */ +// let client_id = ZenohId::try_from([2]).unwrap(); + +// /* [ROUTER] */ +// let router_id = ZenohId::try_from([1]).unwrap(); +// let router_handler = Arc::new(SHRouterAuthenticator::new()); +// // Create the router transport manager +// let peer_auth_router = SharedMemoryAuthenticator::make().unwrap(); +// let unicast = TransportManager::config_unicast() +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_router.into()])); +// let router_manager = TransportManager::builder() +// .whatami(WhatAmI::Router) +// .zid(router_id) +// .unicast(unicast) +// .build(router_handler.clone()) +// .unwrap(); + +// // Create the transport transport manager for the first client +// let peer_auth_client = SharedMemoryAuthenticator::make().unwrap(); +// let unicast = TransportManager::config_unicast() +// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client.into()])); +// let client_manager = TransportManager::builder() +// .whatami(WhatAmI::Router) +// .zid(client_id) +// .unicast(unicast) +// .build(Arc::new(SHClientAuthenticator::default())) +// .unwrap(); + +// /* [1] */ +// println!("\nTransport Authenticator SharedMemory [1a1]"); +// // Add the locator on the router +// let res = ztimeout!(router_manager.add_listener(endpoint.clone())); +// println!("Transport Authenticator SharedMemory [1a1]: {res:?}"); +// assert!(res.is_ok()); +// println!("Transport Authenticator SharedMemory [1a2]"); +// let locators = router_manager.get_listeners(); +// println!("Transport Authenticator SharedMemory 1a2]: {locators:?}"); +// assert_eq!(locators.len(), 1); + +// /* [2] */ +// // Open a transport from the client to the router +// // -> This should be accepted +// println!("Transport Authenticator SharedMemory [2a1]"); +// let res = ztimeout!(client_manager.open_transport(endpoint.clone())); +// println!("Transport Authenticator SharedMemory [2a1]: {res:?}"); +// assert!(res.is_ok()); +// let c_ses1 = res.unwrap(); +// assert!(c_ses1.is_shm().unwrap()); + +// /* [3] */ +// println!("Transport Authenticator SharedMemory [3a1]"); +// let res = ztimeout!(c_ses1.close()); +// println!("Transport Authenticator SharedMemory [3a1]: {res:?}"); +// assert!(res.is_ok()); + +// ztimeout!(async { +// while !router_manager.get_transports().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// /* [4] */ +// // Perform clean up of the open locators +// println!("Transport Authenticator SharedMemory [4a1]"); +// let res = ztimeout!(router_manager.del_listener(endpoint)); +// println!("Transport Authenticator SharedMemory [4a2]: {res:?}"); +// assert!(res.is_ok()); + +// ztimeout!(async { +// while !router_manager.get_listeners().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// task::sleep(SLEEP).await; +// } + +// async fn run(endpoint: &EndPoint) { +// #[cfg(feature = "auth_pubkey")] +// authenticator_multilink(endpoint).await; +// #[cfg(feature = "auth_usrpwd")] +// authenticator_user_password(endpoint).await; +// #[cfg(feature = "shared-memory")] +// authenticator_shared_memory(endpoint).await; +// } + +// #[cfg(feature = "transport_tcp")] +// // #[test] +// fn authenticator_tcp() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 8000).parse().unwrap(); +// task::block_on(run(&endpoint)); +// } + +// #[cfg(feature = "transport_udp")] +// // #[test] +// fn authenticator_udp() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 8010).parse().unwrap(); +// task::block_on(run(&endpoint)); +// } + +// #[cfg(feature = "transport_ws")] +// // #[test] +// fn authenticator_ws() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 8020).parse().unwrap(); +// task::block_on(run(&endpoint)); +// } + +// #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] +// // #[test] +// fn authenticator_unix() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let f1 = "zenoh-test-unix-socket-10.sock"; +// let _ = std::fs::remove_file(f1); +// let endpoint: EndPoint = format!("unixsock-stream/{f1}").parse().unwrap(); +// task::block_on(run(&endpoint)); +// let _ = std::fs::remove_file(f1); +// let _ = std::fs::remove_file(format!("{f1}.lock")); +// } + +// #[cfg(feature = "transport_tls")] +// // #[test] +// fn authenticator_tls() { +// use zenoh_link::tls::config::*; + +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // NOTE: this an auto-generated pair of certificate and key. +// // The target domain is localhost, so it has no real +// // mapping to any existing domain. The certificate and key +// // have been generated using: https://github.com/jsha/minica +// let key = "-----BEGIN RSA PRIVATE KEY----- +// MIIEowIBAAKCAQEAz105EYUbOdW5uJ8o/TqtxtOtKJL7AQdy5yiXoslosAsulaew +// 4JSJetVa6Fa6Bq5BK6fsphGD9bpGGeiBZFBt75JRjOrkj4DwlLGa0CPLTgG5hul4 +// Ufe9B7VG3J5P8OwUqIYmPzj8uTbNtkgFRcYumHR28h4GkYdG5Y04AV4vIjgKE47j +// AgV5ACRHkcmGrTzF2HOes2wT73l4yLSkKR4GlIWu5cLRdI8PTUmjMFAh/GIh1ahd +// +VqXz051V3jok0n1klVNjc6DnWuH3j/MSOg/52C3YfcUjCeIJGVfcqDnPTJKSNEF +// yVTYCUjWy+B0B4fMz3MpU17dDWpvS5hfc4VrgQIDAQABAoIBAQCq+i208XBqdnwk +// 6y7r5Tcl6qErBE3sIk0upjypX7Ju/TlS8iqYckENQ+AqFGBcY8+ehF5O68BHm2hz +// sk8F/H84+wc8zuzYGjPEFtEUb38RecCUqeqog0Gcmm6sN+ioOLAr6DifBojy2mox +// sx6N0oPW9qigp/s4gTcGzTLxhcwNRHWuoWjQwq6y6qwt2PJXnllii5B5iIJhKAxE +// EOmcVCmFbPavQ1Xr9F5jd5rRc1TYq28hXX8dZN2JhdVUbLlHzaiUfTnA/8yI4lyq +// bEmqu29Oqe+CmDtB6jRnrLiIwyZxzXKuxXaO6NqgxqtaVjLcdISEgZMeHEftuOtf +// C1xxodaVAoGBAOb1Y1SvUGx+VADSt1d30h3bBm1kU/1LhLKZOAQrnFMrEfyOfYbz +// AZ4FJgXE6ZsB1BA7hC0eJDVHz8gTgDJQrOOO8WJWDGRe4TbZkCi5IizYg5UH/6az +// I/WKlfdA4j1tftbQhycHL+9bGzdoRzrwIK489PG4oVAJJCaK2CVtx+l3AoGBAOXY +// 75sHOiMaIvDA7qlqFbaBkdi1NzH7bCgy8IntNfLxlOCmGjxeNZzKrkode3JWY9SI +// Mo/nuWj8EZBEHj5omCapzOtkW/Nhnzc4C6U3BCspdrQ4mzbmzEGTdhqvxepa7U7K +// iRcoD1iU7kINCEwg2PsB/BvCSrkn6lpIJlYXlJDHAoGAY7QjgXd9fJi8ou5Uf8oW +// RxU6nRbmuz5Sttc2O3aoMa8yQJkyz4Mwe4s1cuAjCOutJKTM1r1gXC/4HyNsAEyb +// llErG4ySJPJgv1EEzs+9VSbTBw9A6jIDoAiH3QmBoYsXapzy+4I6y1XFVhIKTgND +// 2HQwOfm+idKobIsb7GyMFNkCgYBIsixWZBrHL2UNsHfLrXngl2qBmA81B8hVjob1 +// mMkPZckopGB353Qdex1U464/o4M/nTQgv7GsuszzTBgktQAqeloNuVg7ygyJcnh8 +// cMIoxJx+s8ijvKutse4Q0rdOQCP+X6CsakcwRSp2SZjuOxVljmMmhHUNysocc+Vs +// JVkf0QKBgHiCVLU60EoPketADvhRJTZGAtyCMSb3q57Nb0VIJwxdTB5KShwpul1k +// LPA8Z7Y2i9+IEXcPT0r3M+hTwD7noyHXNlNuzwXot4B8PvbgKkMLyOpcwBjppJd7 +// ns4PifoQbhDFnZPSfnrpr+ZXSEzxtiyv7Ql69jznl/vB8b75hBL4 +// -----END RSA PRIVATE KEY-----"; + +// let cert = "-----BEGIN CERTIFICATE----- +// MIIDLDCCAhSgAwIBAgIIIXlwQVKrtaAwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +// AxMVbWluaWNhIHJvb3QgY2EgMmJiOTlkMB4XDTIxMDIwMjE0NDYzNFoXDTIzMDMw +// NDE0NDYzNFowFDESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +// AAOCAQ8AMIIBCgKCAQEAz105EYUbOdW5uJ8o/TqtxtOtKJL7AQdy5yiXoslosAsu +// laew4JSJetVa6Fa6Bq5BK6fsphGD9bpGGeiBZFBt75JRjOrkj4DwlLGa0CPLTgG5 +// hul4Ufe9B7VG3J5P8OwUqIYmPzj8uTbNtkgFRcYumHR28h4GkYdG5Y04AV4vIjgK +// E47jAgV5ACRHkcmGrTzF2HOes2wT73l4yLSkKR4GlIWu5cLRdI8PTUmjMFAh/GIh +// 1ahd+VqXz051V3jok0n1klVNjc6DnWuH3j/MSOg/52C3YfcUjCeIJGVfcqDnPTJK +// SNEFyVTYCUjWy+B0B4fMz3MpU17dDWpvS5hfc4VrgQIDAQABo3YwdDAOBgNVHQ8B +// Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB +// /wQCMAAwHwYDVR0jBBgwFoAULXa6lBiO7OLL5Z6XuF5uF5wR9PQwFAYDVR0RBA0w +// C4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQBOMkNXfzPEDU475zbiSi3v +// JOhpZLyuoaYY62RzZc9VF8YRybJlWKUWdR3szAiUd1xCJe/beNX7b9lPg6wNadKq +// DGTWFmVxSfpVMO9GQYBXLDcNaAUXzsDLC5sbAFST7jkAJELiRn6KtQYxZ2kEzo7G +// QmzNMfNMc1KeL8Qr4nfEHZx642yscSWj9edGevvx4o48j5KXcVo9+pxQQFao9T2O +// F5QxyGdov+uNATWoYl92Gj8ERi7ovHimU3H7HLIwNPqMJEaX4hH/E/Oz56314E9b +// AXVFFIgCSluyrolaD6CWD9MqOex4YOfJR2bNxI7lFvuK4AwjyUJzT1U1HXib17mM +// -----END CERTIFICATE-----"; + +// // Configure the client +// let ca = "-----BEGIN CERTIFICATE----- +// MIIDSzCCAjOgAwIBAgIIK7mduKtTVxkwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +// AxMVbWluaWNhIHJvb3QgY2EgMmJiOTlkMCAXDTIxMDIwMjEzMTc0NVoYDzIxMjEw +// MjAyMTMxNzQ1WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAyYmI5OWQwggEi +// MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoBZOxIfVq7LoEpVCMlQzuDnFy +// d+yuk5pFasEQvZ3IvWVta4rPFJ3WGl4UNF6v9bZegNHp+oo70guZ8ps9ez34qrwB +// rrNtZ0YJLDvR0ygloinZZeiclrZcu+x9vRdnyfWqrAulJBMlJIbbHcNx2OCkq7MM +// HdpLJMXxKVbIlQQYGUzRkNTAaK2PiFX5BaqmnZZyo7zNbz7L2asg+0K/FpiS2IRA +// coHPTa9BtsLUJUPRHPr08pgTjM1MQwa+Xxg1+wtMh85xdrqMi6Oe0cxefS+0L04F +// KVfMD3bW8AyuugvcTEpGnea2EvMoPfLWpnPGU3XO8lRZyotZDQzrPvNyYKM3AgMB +// AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +// BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQtdrqUGI7s4svl +// npe4Xm4XnBH09DAfBgNVHSMEGDAWgBQtdrqUGI7s4svlnpe4Xm4XnBH09DANBgkq +// hkiG9w0BAQsFAAOCAQEAJliEt607VUOSDsUeabhG8MIhYDhxe+mjJ4i7N/0xk9JU +// piCUdQr26HyYCzN+bNdjw663rxuVGtTTdHSw2CJHsPSOEDinbYkLMSyDeomsnr0S +// 4e0hKUeqXXYg0iC/O2283ZEvvQK5SE+cjm0La0EmqO0mj3Mkc4Fsg8hExYuOur4M +// M0AufDKUhroksKKiCmjsFj1x55VcU45Ag8069lzBk7ntcGQpHUUkwZzvD4FXf8IR +// pVVHiH6WC99p77T9Di99dE5ufjsprfbzkuafgTo2Rz03HgPq64L4po/idP8uBMd6 +// tOzot3pwe+3SJtpk90xAQrABEO0Zh2unrC8i83ySfg== +// -----END CERTIFICATE-----"; + +// // Define the locator +// let mut endpoint: EndPoint = format!("tls/localhost:{}", 8030).parse().unwrap(); +// endpoint +// .config_mut() +// .extend( +// [ +// (TLS_ROOT_CA_CERTIFICATE_RAW, ca), +// (TLS_SERVER_CERTIFICATE_RAW, cert), +// (TLS_SERVER_PRIVATE_KEY_RAW, key), +// ] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); + +// task::block_on(run(&endpoint)); +// } + +// #[cfg(feature = "transport_quic")] +// // #[test] +// fn authenticator_quic() { +// use zenoh_link::quic::config::*; + +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // NOTE: this an auto-generated pair of certificate and key. +// // The target domain is localhost, so it has no real +// // mapping to any existing domain. The certificate and key +// // have been generated using: https://github.com/jsha/minica +// let key = "-----BEGIN RSA PRIVATE KEY----- +// MIIEowIBAAKCAQEAz105EYUbOdW5uJ8o/TqtxtOtKJL7AQdy5yiXoslosAsulaew +// 4JSJetVa6Fa6Bq5BK6fsphGD9bpGGeiBZFBt75JRjOrkj4DwlLGa0CPLTgG5hul4 +// Ufe9B7VG3J5P8OwUqIYmPzj8uTbNtkgFRcYumHR28h4GkYdG5Y04AV4vIjgKE47j +// AgV5ACRHkcmGrTzF2HOes2wT73l4yLSkKR4GlIWu5cLRdI8PTUmjMFAh/GIh1ahd +// +VqXz051V3jok0n1klVNjc6DnWuH3j/MSOg/52C3YfcUjCeIJGVfcqDnPTJKSNEF +// yVTYCUjWy+B0B4fMz3MpU17dDWpvS5hfc4VrgQIDAQABAoIBAQCq+i208XBqdnwk +// 6y7r5Tcl6qErBE3sIk0upjypX7Ju/TlS8iqYckENQ+AqFGBcY8+ehF5O68BHm2hz +// sk8F/H84+wc8zuzYGjPEFtEUb38RecCUqeqog0Gcmm6sN+ioOLAr6DifBojy2mox +// sx6N0oPW9qigp/s4gTcGzTLxhcwNRHWuoWjQwq6y6qwt2PJXnllii5B5iIJhKAxE +// EOmcVCmFbPavQ1Xr9F5jd5rRc1TYq28hXX8dZN2JhdVUbLlHzaiUfTnA/8yI4lyq +// bEmqu29Oqe+CmDtB6jRnrLiIwyZxzXKuxXaO6NqgxqtaVjLcdISEgZMeHEftuOtf +// C1xxodaVAoGBAOb1Y1SvUGx+VADSt1d30h3bBm1kU/1LhLKZOAQrnFMrEfyOfYbz +// AZ4FJgXE6ZsB1BA7hC0eJDVHz8gTgDJQrOOO8WJWDGRe4TbZkCi5IizYg5UH/6az +// I/WKlfdA4j1tftbQhycHL+9bGzdoRzrwIK489PG4oVAJJCaK2CVtx+l3AoGBAOXY +// 75sHOiMaIvDA7qlqFbaBkdi1NzH7bCgy8IntNfLxlOCmGjxeNZzKrkode3JWY9SI +// Mo/nuWj8EZBEHj5omCapzOtkW/Nhnzc4C6U3BCspdrQ4mzbmzEGTdhqvxepa7U7K +// iRcoD1iU7kINCEwg2PsB/BvCSrkn6lpIJlYXlJDHAoGAY7QjgXd9fJi8ou5Uf8oW +// RxU6nRbmuz5Sttc2O3aoMa8yQJkyz4Mwe4s1cuAjCOutJKTM1r1gXC/4HyNsAEyb +// llErG4ySJPJgv1EEzs+9VSbTBw9A6jIDoAiH3QmBoYsXapzy+4I6y1XFVhIKTgND +// 2HQwOfm+idKobIsb7GyMFNkCgYBIsixWZBrHL2UNsHfLrXngl2qBmA81B8hVjob1 +// mMkPZckopGB353Qdex1U464/o4M/nTQgv7GsuszzTBgktQAqeloNuVg7ygyJcnh8 +// cMIoxJx+s8ijvKutse4Q0rdOQCP+X6CsakcwRSp2SZjuOxVljmMmhHUNysocc+Vs +// JVkf0QKBgHiCVLU60EoPketADvhRJTZGAtyCMSb3q57Nb0VIJwxdTB5KShwpul1k +// LPA8Z7Y2i9+IEXcPT0r3M+hTwD7noyHXNlNuzwXot4B8PvbgKkMLyOpcwBjppJd7 +// ns4PifoQbhDFnZPSfnrpr+ZXSEzxtiyv7Ql69jznl/vB8b75hBL4 +// -----END RSA PRIVATE KEY-----"; + +// let cert = "-----BEGIN CERTIFICATE----- +// MIIDLDCCAhSgAwIBAgIIIXlwQVKrtaAwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +// AxMVbWluaWNhIHJvb3QgY2EgMmJiOTlkMB4XDTIxMDIwMjE0NDYzNFoXDTIzMDMw +// NDE0NDYzNFowFDESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +// AAOCAQ8AMIIBCgKCAQEAz105EYUbOdW5uJ8o/TqtxtOtKJL7AQdy5yiXoslosAsu +// laew4JSJetVa6Fa6Bq5BK6fsphGD9bpGGeiBZFBt75JRjOrkj4DwlLGa0CPLTgG5 +// hul4Ufe9B7VG3J5P8OwUqIYmPzj8uTbNtkgFRcYumHR28h4GkYdG5Y04AV4vIjgK +// E47jAgV5ACRHkcmGrTzF2HOes2wT73l4yLSkKR4GlIWu5cLRdI8PTUmjMFAh/GIh +// 1ahd+VqXz051V3jok0n1klVNjc6DnWuH3j/MSOg/52C3YfcUjCeIJGVfcqDnPTJK +// SNEFyVTYCUjWy+B0B4fMz3MpU17dDWpvS5hfc4VrgQIDAQABo3YwdDAOBgNVHQ8B +// Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB +// /wQCMAAwHwYDVR0jBBgwFoAULXa6lBiO7OLL5Z6XuF5uF5wR9PQwFAYDVR0RBA0w +// C4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQBOMkNXfzPEDU475zbiSi3v +// JOhpZLyuoaYY62RzZc9VF8YRybJlWKUWdR3szAiUd1xCJe/beNX7b9lPg6wNadKq +// DGTWFmVxSfpVMO9GQYBXLDcNaAUXzsDLC5sbAFST7jkAJELiRn6KtQYxZ2kEzo7G +// QmzNMfNMc1KeL8Qr4nfEHZx642yscSWj9edGevvx4o48j5KXcVo9+pxQQFao9T2O +// F5QxyGdov+uNATWoYl92Gj8ERi7ovHimU3H7HLIwNPqMJEaX4hH/E/Oz56314E9b +// AXVFFIgCSluyrolaD6CWD9MqOex4YOfJR2bNxI7lFvuK4AwjyUJzT1U1HXib17mM +// -----END CERTIFICATE-----"; + +// // Configure the client +// let ca = "-----BEGIN CERTIFICATE----- +// MIIDSzCCAjOgAwIBAgIIK7mduKtTVxkwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +// AxMVbWluaWNhIHJvb3QgY2EgMmJiOTlkMCAXDTIxMDIwMjEzMTc0NVoYDzIxMjEw +// MjAyMTMxNzQ1WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAyYmI5OWQwggEi +// MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoBZOxIfVq7LoEpVCMlQzuDnFy +// d+yuk5pFasEQvZ3IvWVta4rPFJ3WGl4UNF6v9bZegNHp+oo70guZ8ps9ez34qrwB +// rrNtZ0YJLDvR0ygloinZZeiclrZcu+x9vRdnyfWqrAulJBMlJIbbHcNx2OCkq7MM +// HdpLJMXxKVbIlQQYGUzRkNTAaK2PiFX5BaqmnZZyo7zNbz7L2asg+0K/FpiS2IRA +// coHPTa9BtsLUJUPRHPr08pgTjM1MQwa+Xxg1+wtMh85xdrqMi6Oe0cxefS+0L04F +// KVfMD3bW8AyuugvcTEpGnea2EvMoPfLWpnPGU3XO8lRZyotZDQzrPvNyYKM3AgMB +// AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +// BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQtdrqUGI7s4svl +// npe4Xm4XnBH09DAfBgNVHSMEGDAWgBQtdrqUGI7s4svlnpe4Xm4XnBH09DANBgkq +// hkiG9w0BAQsFAAOCAQEAJliEt607VUOSDsUeabhG8MIhYDhxe+mjJ4i7N/0xk9JU +// piCUdQr26HyYCzN+bNdjw663rxuVGtTTdHSw2CJHsPSOEDinbYkLMSyDeomsnr0S +// 4e0hKUeqXXYg0iC/O2283ZEvvQK5SE+cjm0La0EmqO0mj3Mkc4Fsg8hExYuOur4M +// M0AufDKUhroksKKiCmjsFj1x55VcU45Ag8069lzBk7ntcGQpHUUkwZzvD4FXf8IR +// pVVHiH6WC99p77T9Di99dE5ufjsprfbzkuafgTo2Rz03HgPq64L4po/idP8uBMd6 +// tOzot3pwe+3SJtpk90xAQrABEO0Zh2unrC8i83ySfg== +// -----END CERTIFICATE-----"; + +// // Define the locator +// let mut endpoint: EndPoint = format!("quic/localhost:{}", 8040).parse().unwrap(); +// endpoint +// .config_mut() +// .extend( +// [ +// (TLS_ROOT_CA_CERTIFICATE_RAW, ca), +// (TLS_SERVER_CERTIFICATE_RAW, cert), +// (TLS_SERVER_PRIVATE_KEY_RAW, key), +// ] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); + +// task::block_on(run(&endpoint)); +// } diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index 7d121c6ddb..d918d98e46 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -16,9 +16,7 @@ mod tests { use async_std::{prelude::FutureExt, task}; use std::{ any::Any, - collections::HashSet, convert::TryFrom, - iter::FromIterator, sync::{ atomic::{AtomicUsize, Ordering}, Arc, @@ -141,28 +139,20 @@ mod tests { .unwrap(); // Create a peer manager with shared-memory authenticator enabled - let peer_shm01_handler = Arc::new(SHPeer::new(false)); - let unicast = - TransportManager::config_unicast().peer_authenticator(HashSet::from_iter(vec![ - SharedMemoryAuthenticator::make().unwrap().into(), - ])); + let peer_shm01_handler = Arc::new(SHPeer::new(true)); let peer_shm01_manager = TransportManager::builder() .whatami(WhatAmI::Peer) .zid(peer_shm01) - .unicast(unicast) + .unicast(TransportManager::config_unicast().shm(true)) .build(peer_shm01_handler.clone()) .unwrap(); // Create a peer manager with shared-memory authenticator enabled let peer_shm02_handler = Arc::new(SHPeer::new(true)); - let unicast = - TransportManager::config_unicast().peer_authenticator(HashSet::from_iter(vec![ - SharedMemoryAuthenticator::make().unwrap().into(), - ])); let peer_shm02_manager = TransportManager::builder() .whatami(WhatAmI::Peer) .zid(peer_shm02) - .unicast(unicast) + .unicast(TransportManager::config_unicast().shm(true)) .build(peer_shm02_handler.clone()) .unwrap(); @@ -171,6 +161,7 @@ mod tests { let peer_net01_manager = TransportManager::builder() .whatami(WhatAmI::Peer) .zid(peer_net01) + .unicast(TransportManager::config_unicast().shm(false)) .build(peer_net01_handler.clone()) .unwrap(); @@ -336,7 +327,7 @@ mod tests { } #[cfg(all(feature = "transport_tcp", feature = "shared-memory"))] - // #[test] + #[test] fn transport_tcp_shm() { let _ = env_logger::try_init(); task::block_on(async { @@ -348,7 +339,7 @@ mod tests { } #[cfg(all(feature = "transport_ws", feature = "shared-memory"))] - // #[test] + #[test] fn transport_ws_shm() { let _ = env_logger::try_init(); task::block_on(async { From 1d910115214578e72636b836086717c4e350ed87 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 3 Mar 2023 19:45:56 +0100 Subject: [PATCH 051/203] Remove zenoh-cfg-properties crate --- .github/workflows/release.yml | 1 - Cargo.lock | 17 - Cargo.toml | 1 - commons/zenoh-cfg-properties/Cargo.toml | 32 -- commons/zenoh-cfg-properties/src/config.rs | 374 ------------------- commons/zenoh-cfg-properties/src/lib.rs | 358 ------------------ commons/zenoh-collections/src/lib.rs | 5 + commons/zenoh-collections/src/properties.rs | 169 +++++++++ commons/zenoh-config/Cargo.toml | 1 - commons/zenoh-config/src/defaults.rs | 11 +- commons/zenoh-config/src/lib.rs | 3 +- commons/zenoh-protocol/src/core/endpoint.rs | 110 +++--- io/zenoh-link-commons/Cargo.toml | 1 - io/zenoh-link-commons/src/lib.rs | 164 +------- io/zenoh-link-commons/src/multicast.rs | 0 io/zenoh-link-commons/src/unicast.rs | 179 +++++++++ io/zenoh-link/Cargo.toml | 1 - io/zenoh-link/src/lib.rs | 8 +- io/zenoh-links/zenoh-link-quic/Cargo.toml | 1 - io/zenoh-links/zenoh-link-quic/src/lib.rs | 45 +-- io/zenoh-links/zenoh-link-serial/Cargo.toml | 1 - io/zenoh-links/zenoh-link-serial/src/lib.rs | 1 + io/zenoh-links/zenoh-link-tls/Cargo.toml | 1 - io/zenoh-links/zenoh-link-tls/src/lib.rs | 86 ++--- io/zenoh-links/zenoh-link-tls/src/unicast.rs | 25 +- io/zenoh-transport/Cargo.toml | 1 - io/zenoh-transport/src/manager.rs | 25 +- io/zenoh-transport/src/unicast/manager.rs | 48 +-- plugins/zenoh-backend-traits/src/lib.rs | 1 - plugins/zenoh-plugin-rest/Cargo.toml | 1 - plugins/zenoh-plugin-rest/src/lib.rs | 2 +- zenoh/Cargo.toml | 1 - zenoh/src/lib.rs | 4 +- zenoh/src/net/tests/tables.rs | 9 +- zenoh/src/scouting.rs | 28 +- zenoh/src/value.rs | 2 +- 36 files changed, 559 insertions(+), 1158 deletions(-) delete mode 100644 commons/zenoh-cfg-properties/Cargo.toml delete mode 100644 commons/zenoh-cfg-properties/src/config.rs delete mode 100644 commons/zenoh-cfg-properties/src/lib.rs create mode 100644 commons/zenoh-collections/src/properties.rs create mode 100644 io/zenoh-link-commons/src/multicast.rs create mode 100644 io/zenoh-link-commons/src/unicast.rs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b72cdb5708..ea13fc363c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -339,7 +339,6 @@ jobs: cargo login ${{ secrets.CRATES_IO_TOKEN }} cd commons/zenoh-macros && cargo publish && cd - cd commons/zenoh-core && cargo publish && cd - - cd commons/zenoh-cfg-properties && cargo publish && cd - cd commons/zenoh-sync && cargo publish && cd - cd commons/zenoh-collections && cargo publish && cd - cd commons/zenoh-crypto && cargo publish && cd - diff --git a/Cargo.lock b/Cargo.lock index b8bd597366..99d60165b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3823,7 +3823,6 @@ dependencies = [ "uuid", "vec_map", "zenoh-buffers", - "zenoh-cfg-properties", "zenoh-codec", "zenoh-collections", "zenoh-config", @@ -3848,14 +3847,6 @@ dependencies = [ "zenoh-collections", ] -[[package]] -name = "zenoh-cfg-properties" -version = "0.7.0-rc" -dependencies = [ - "zenoh-macros", - "zenoh-result", -] - [[package]] name = "zenoh-codec" version = "0.7.0-rc" @@ -3888,7 +3879,6 @@ dependencies = [ "serde_json", "serde_yaml", "validated_struct", - "zenoh-cfg-properties", "zenoh-core", "zenoh-protocol", "zenoh-result", @@ -3961,7 +3951,6 @@ dependencies = [ "async-std", "async-trait", "rcgen", - "zenoh-cfg-properties", "zenoh-config", "zenoh-link-commons", "zenoh-link-quic", @@ -3985,7 +3974,6 @@ dependencies = [ "serde", "typenum", "zenoh-buffers", - "zenoh-cfg-properties", "zenoh-codec", "zenoh-protocol", "zenoh-result", @@ -4004,7 +3992,6 @@ dependencies = [ "rustls-native-certs", "rustls-pemfile", "webpki", - "zenoh-cfg-properties", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -4025,7 +4012,6 @@ dependencies = [ "tokio", "uuid", "z-serial", - "zenoh-cfg-properties", "zenoh-collections", "zenoh-config", "zenoh-core", @@ -4063,7 +4049,6 @@ dependencies = [ "rustls-pemfile", "webpki", "webpki-roots", - "zenoh-cfg-properties", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -4158,7 +4143,6 @@ dependencies = [ "serde_json", "tide", "zenoh", - "zenoh-cfg-properties", "zenoh-plugin-trait", "zenoh-result", "zenoh-util", @@ -4277,7 +4261,6 @@ dependencies = [ "serde", "sha3", "zenoh-buffers", - "zenoh-cfg-properties", "zenoh-codec", "zenoh-collections", "zenoh-config", diff --git a/Cargo.toml b/Cargo.toml index 6cc98d303e..e4c87a3300 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,6 @@ [workspace] members = [ "commons/zenoh-buffers", - "commons/zenoh-cfg-properties", "commons/zenoh-codec", "commons/zenoh-collections", "commons/zenoh-config", diff --git a/commons/zenoh-cfg-properties/Cargo.toml b/commons/zenoh-cfg-properties/Cargo.toml deleted file mode 100644 index fd8cf6fadc..0000000000 --- a/commons/zenoh-cfg-properties/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2022 ZettaScale Technology -# -# This program and the accompanying materials are made available under the -# terms of the Eclipse Public License 2.0 which is available at -# http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -# which is available at https://www.apache.org/licenses/LICENSE-2.0. -# -# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -# -# Contributors: -# ZettaScale Zenoh Team, -[package] -rust-version = { workspace = true } -name = "zenoh-cfg-properties" -version = { workspace = true } -repository = { workspace = true } -homepage = { workspace = true } -authors = [ - "kydos ", - "Luca Cominardi ", - "Pierre Avital ", -] -edition = { workspace = true } -license = { workspace = true } -categories = { workspace = true } -description = "Internal crate for zenoh." -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -zenoh-macros = { path = "../zenoh-macros/" } -zenoh-result = { path = "../zenoh-result/" } diff --git a/commons/zenoh-cfg-properties/src/config.rs b/commons/zenoh-cfg-properties/src/config.rs deleted file mode 100644 index da793fcfc3..0000000000 --- a/commons/zenoh-cfg-properties/src/config.rs +++ /dev/null @@ -1,374 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// - -/// `"true"` -pub const ZN_TRUE: &str = "true"; -/// `"false"` -pub const ZN_FALSE: &str = "false"; -/// `"auto"` -pub const ZN_AUTO: &str = "auto"; - -/// The library mode. -/// String key: `"mode"`. -/// Accepted values: `"peer"`, `"client"`. -/// Default value: `"peer"`. -pub const ZN_MODE_KEY: u64 = 0x40; -pub const ZN_MODE_STR: &str = "mode"; -pub const ZN_MODE_DEFAULT: &str = "peer"; - -/// The locator of a peer to connect to. -/// String key: `"connect"`. -/// Accepted values: `` (ex: `"tcp/10.10.10.10:7447"`). -/// Default value: None. -/// Multiple values accepted. -pub const ZN_CONNECT_KEY: u64 = 0x41; -pub const ZN_CONNECT_STR: &str = "connect"; - -/// A locator to listen on. -/// String key: `"listen"`. -/// Accepted values: `` (ex: `"tcp/10.10.10.10:7447"`). -/// Default value: None. -/// Multiple values accepted. -pub const ZN_LISTEN_KEY: u64 = 0x42; -pub const ZN_LISTEN_STR: &str = "listen"; - -/// The user name to use for authentication. -/// String key: `"user"`. -/// Accepted values: ``. -pub const ZN_USER_KEY: u64 = 0x43; -pub const ZN_USER_STR: &str = "user"; - -/// The password to use for authentication. -/// String key: `"password"`. -/// Accepted values: ``. -pub const ZN_PASSWORD_KEY: u64 = 0x44; -pub const ZN_PASSWORD_STR: &str = "password"; - -/// Activates/Desactivates multicast scouting. -/// String key: `"multicast_scouting"`. -/// Accepted values: `"true"`, `"false"`. -/// Default value: `"true"`. -pub const ZN_MULTICAST_SCOUTING_KEY: u64 = 0x45; -pub const ZN_MULTICAST_SCOUTING_STR: &str = "multicast_scouting"; -pub const ZN_MULTICAST_SCOUTING_DEFAULT: &str = ZN_TRUE; - -/// The network interface to use for multicast scouting. -/// String key: `"multicast_interface"`. -/// Accepted values: `"auto"`, ``, ``. -/// Default value: `"auto"`. -pub const ZN_MULTICAST_INTERFACE_KEY: u64 = 0x46; -pub const ZN_MULTICAST_INTERFACE_STR: &str = "multicast_interface"; -pub const ZN_MULTICAST_INTERFACE_DEFAULT: &str = ZN_AUTO; - -/// The multicast IPv4 address and ports to use for multicast scouting. -/// String key: `"multicast_ipv4_address"`. -/// Accepted values: `:`. -/// Default value: `"224.0.0.224:7446"`. -pub const ZN_MULTICAST_IPV4_ADDRESS_KEY: u64 = 0x47; -pub const ZN_MULTICAST_IPV4_ADDRESS_STR: &str = "multicast_ipv4_address"; -pub const ZN_MULTICAST_IPV4_ADDRESS_DEFAULT: &str = "224.0.0.224:7446"; - -/// In client mode, the period dedicated to scouting a router before failing. -/// String key: `"scouting_timeout"`. -/// Accepted values: ``. -/// Default value: `"3.0"`. -pub const ZN_SCOUTING_TIMEOUT_KEY: u64 = 0x48; -pub const ZN_SCOUTING_TIMEOUT_STR: &str = "scouting_timeout"; -pub const ZN_SCOUTING_TIMEOUT_DEFAULT: &str = "3.0"; - -/// In peer mode, the period dedicated to scouting first remote peers before doing anything else. -/// String key: `"scouting_delay"`. -/// Accepted values: ``. -/// Default value: `"0.2"`. -pub const ZN_SCOUTING_DELAY_KEY: u64 = 0x49; -pub const ZN_SCOUTING_DELAY_STR: &str = "scouting_delay"; -pub const ZN_SCOUTING_DELAY_DEFAULT: &str = "0.2"; - -/// Indicates if data messages should be timestamped. -/// String key: `"add_timestamp"`. -/// Accepted values: `"true"`, `"false"`. -/// Default value: `"false"`. -pub const ZN_ADD_TIMESTAMP_KEY: u64 = 0x4A; -pub const ZN_ADD_TIMESTAMP_STR: &str = "add_timestamp"; -pub const ZN_ADD_TIMESTAMP_DEFAULT: &str = ZN_FALSE; - -/// Indicates if the link state protocol should run. -/// String key: `"link_state"`. -/// Accepted values: `"true"`, `"false"`. -/// Default value: `"true"`. -pub const ZN_LINK_STATE_KEY: u64 = 0x4B; -pub const ZN_LINK_STATE_STR: &str = "link_state"; -pub const ZN_LINK_STATE_DEFAULT: &str = ZN_TRUE; - -/// The file path containing the user password dictionary. -/// String key: `"user_password_dictionary"`. -/// Accepted values: ``. -pub const ZN_USER_PASSWORD_DICTIONARY_KEY: u64 = 0x4C; -pub const ZN_USER_PASSWORD_DICTIONARY_STR: &str = "user_password_dictionary"; - -/// Indicates if peers should connect to each other -/// when they discover each other (through multicast -/// or gossip discovery). -/// String key: `"peers_autoconnect"`. -/// Accepted values: `"true"`, `"false"`. -/// Default value: `"true"`. -pub const ZN_PEERS_AUTOCONNECT_KEY: u64 = 0x4D; -pub const ZN_PEERS_AUTOCONNECT_STR: &str = "peers_autoconnect"; -pub const ZN_PEERS_AUTOCONNECT_DEFAULT: &str = ZN_TRUE; - -/// The file path containing the TLS server private key. -/// String key: `"tls_server_private_key"`. -/// Accepted values: ``. -/// Default value: None. -pub const ZN_TLS_SERVER_PRIVATE_KEY_KEY: u64 = 0x4E; -pub const ZN_TLS_SERVER_PRIVATE_KEY_STR: &str = "tls_server_private_key"; - -/// The file path containing the TLS server certificate. -/// String key: `"tls_server_certificate"`. -/// Accepted values: ``. -/// Default value: None. -pub const ZN_TLS_SERVER_CERTIFICATE_KEY: u64 = 0x4F; -pub const ZN_TLS_SERVER_CERTIFICATE_STR: &str = "tls_server_certificate"; - -/// The file path containing the TLS root CA certificate. -/// String key: `"tls_root_ca_certificate"`. -/// Accepted values: ``. -/// Default value: None. -pub const ZN_TLS_ROOT_CA_CERTIFICATE_KEY: u64 = 0x50; -pub const ZN_TLS_ROOT_CA_CERTIFICATE_STR: &str = "tls_root_ca_certificate"; - -/// Indicates if the shared-memory features should be used. -/// String key: `"shm"`. -/// Accepted values: `"true"`, `"false"`. -/// Default value: `"true"`. -pub const ZN_SHM_KEY: u64 = 0x51; -pub const ZN_SHM_STR: &str = "shm"; -pub const ZN_SHM_DEFAULT: &str = ZN_TRUE; - -/// Indicates if routers should connect to each other -/// when they discover each other through multicast. -/// String key: `"routers_autoconnect_multicast"`. -/// Accepted values: `"true"`, `"false"`. -/// Default value: `"false"`. -pub const ZN_ROUTERS_AUTOCONNECT_MULTICAST_KEY: u64 = 0x52; -pub const ZN_ROUTERS_AUTOCONNECT_MULTICAST_STR: &str = "routers_autoconnect_multicast"; -pub const ZN_ROUTERS_AUTOCONNECT_MULTICAST_DEFAULT: &str = ZN_FALSE; - -/// Indicates if routers should connect to each other -/// when they discover each other through gossip discovery. -/// String key: `"routers_autoconnect_gossip"`. -/// Accepted values: `"true"`, `"false"`. -/// Default value: `"false"`. -pub const ZN_ROUTERS_AUTOCONNECT_GOSSIP_KEY: u64 = 0x53; -pub const ZN_ROUTERS_AUTOCONNECT_GOSSIP_STR: &str = "routers_autoconnect_gossip"; -pub const ZN_ROUTERS_AUTOCONNECT_GOSSIP_DEFAULT: &str = ZN_FALSE; - -pub const ZN_JOIN_SUBSCRIPTIONS_KEY: u64 = 0x61; -pub const ZN_JOIN_SUBSCRIPTIONS_STR: &str = "join_subscriptions"; - -pub const ZN_JOIN_PUBLICATIONS_KEY: u64 = 0x62; -pub const ZN_JOIN_PUBLICATIONS_STR: &str = "join_publications"; - -/// Configures the link lease expressed in milliseconds. -/// String key: `"link_lease"`. -/// Accepted values: ``. -/// Default value: `10000 (10 seconds)`. -pub const ZN_LINK_LEASE_KEY: u64 = 0x63; -pub const ZN_LINK_LEASE_STR: &str = "link_lease"; -pub const ZN_LINK_LEASE_DEFAULT: &str = "10000"; - -/// Configures the number of keep-alive messages in a link lease duration. -/// String key: `"link_keep_alive"`. -/// Accepted values: ``. -/// Default value: `4 (2.5 seconds)`. -pub const ZN_LINK_KEEP_ALIVE_KEY: u64 = 0x64; -pub const ZN_LINK_KEEP_ALIVE_STR: &str = "link_keep_alive"; -pub const ZN_LINK_KEEP_ALIVE_DEFAULT: &str = "4"; - -/// Configures the sequence number resolution. -/// String key: `"seq_num_resolution"`. -/// Accepted values: ``. -/// Default value: `268435456` (2^28). -pub const ZN_SEQ_NUM_RESOLUTION_KEY: u64 = 0x65; -pub const ZN_SEQ_NUM_RESOLUTION_STR: &str = "seq_num_resolution"; -pub const ZN_SEQ_NUM_RESOLUTION_DEFAULT: &str = "268435456"; - -/// Configures the timeout in milliseconds when opening a link. -/// String key: `"open_timeout"`. -/// Accepted values: ``. -/// Default value: `10000`. -pub const ZN_OPEN_TIMEOUT_KEY: u64 = 0x66; -pub const ZN_OPEN_TIMEOUT_STR: &str = "open_timeout"; -pub const ZN_OPEN_TIMEOUT_DEFAULT: &str = "10000"; - -/// Configures the number of open session that can be in pending state. -/// String key: `"open_pending"`. -/// Accepted values: ``. -/// Default value: `1024`. -pub const ZN_OPEN_INCOMING_PENDING_KEY: u64 = 0x67; -pub const ZN_OPEN_INCOMING_PENDING_STR: &str = "open_pending"; -pub const ZN_OPEN_INCOMING_PENDING_DEFAULT: &str = "100"; - -/// Configures the peer ID. -/// String key: `"peer_id"`. -/// Accepted values: ``. -pub const ZN_PEER_ID_KEY: u64 = 0x68; -pub const ZN_PEER_ID_STR: &str = "peer_id"; - -/// Configures the batch size. -/// String key: `"batch_size"`. -/// Accepted values: ``. -/// Default value: `65535`. -pub const ZN_BATCH_SIZE_KEY: u64 = 0x69; -pub const ZN_BATCH_SIZE_STR: &str = "batch_size"; -pub const ZN_BATCH_SIZE_DEFAULT: &str = "65535"; - -/// Configures the maximum number of simultaneous open unicast sessions. -/// String key: `"max_sessions_unicast"`. -/// Accepted values: ``. -/// Default value: `1024`. -pub const ZN_MAX_SESSIONS_UNICAST_KEY: u64 = 0x70; -pub const ZN_MAX_SESSIONS_UNICAST_STR: &str = "max_sessions_unicast"; -pub const ZN_MAX_SESSIONS_UNICAST_DEFAULT: &str = "1024"; - -/// Configures the maximum number of inbound links per open session. -/// String key: `"max_links"`. -/// Accepted values: ``. -/// Default value: `1`. -pub const ZN_MAX_LINKS_KEY: u64 = 0x71; -pub const ZN_MAX_LINKS_STR: &str = "max_links"; -pub const ZN_MAX_LINKS_DEFAULT: &str = "1"; - -/// Configures the zenoh version. -/// String key: `"version"`. -/// Accepted values: ``. -pub const ZN_VERSION_KEY: u64 = 0x72; -pub const ZN_VERSION_STR: &str = "version"; - -/// Configures the QoS support. -/// String key: `"qos"`. -/// Accepted values: `"true"`, `"false"`. -/// Default value: `"true"`. -pub const ZN_QOS_KEY: u64 = 0x73; -pub const ZN_QOS_STR: &str = "qos"; -pub const ZN_QOS_DEFAULT: &str = ZN_TRUE; - -/// Configures the link keep alive expressed in milliseconds. -/// String key: `"join_interval"`. -/// Accepted values: ``. -/// Default value: `2500`. -pub const ZN_JOIN_INTERVAL_KEY: u64 = 0x74; -pub const ZN_JOIN_INTERVAL_STR: &str = "join_interval"; -pub const ZN_JOIN_INTERVAL_DEFAULT: &str = "2500"; - -/// Configures the maximum size in bytes of the defragmentation -/// buffer at receiving side. Messages that have been fragmented -/// and that are larger than the configured size will be dropped. -/// String key: `"defrag_buff_size"`. -/// Accepted values: ``. -/// Default value: `1073741824` (1GiB). -pub const ZN_DEFRAG_BUFF_SIZE_KEY: u64 = 0x75; -pub const ZN_DEFRAG_BUFF_SIZE_STR: &str = "defrag_buff_size"; -pub const ZN_DEFRAG_BUFF_SIZE_DEFAULT: &str = "1073741824"; - -/// Configures the buffer size in bytes at receiving side for each link. -/// String key: `"link_rx_buff_size"`. -/// Accepted values: ``. -/// Default value: `65535` (64KiB). -pub const ZN_LINK_RX_BUFF_SIZE_KEY: u64 = 0x76; -pub const ZN_LINK_RX_BUFF_SIZE_STR: &str = "link_rx_buff_size"; -pub const ZN_LINK_RX_BUFF_SIZE_DEFAULT: &str = "65535"; - -/// The multicast IPv6 address and ports to use for multicast scouting. -/// String key: `"multicast_ipv6_address"`. -/// Accepted values: `:`. -/// Default value: `"[ff24::224]:7446"`. -pub const ZN_MULTICAST_IPV6_ADDRESS_KEY: u64 = 0x77; -pub const ZN_MULTICAST_IPV6_ADDRESS_STR: &str = "multicast_ipv6_address"; -pub const ZN_MULTICAST_IPV6_ADDRESS_DEFAULT: &str = "[ff24::224]:7446"; - -/// The public RSA key. -/// String key: `"auth_rsa_public_key_pem"`. -/// Accepted values: ``. -pub const ZN_AUTH_RSA_PUBLIC_KEY_PEM_KEY: u64 = 0x78; -pub const ZN_AUTH_RSA_PUBLIC_KEY_PEM_STR: &str = "auth_rsa_public_key_pem"; - -/// The private RSA key. -/// String key: `"auth_rsa_private_key_pem"`. -/// Accepted values: ``. -pub const ZN_AUTH_RSA_PRIVATE_KEY_PEM_KEY: u64 = 0x79; -pub const ZN_AUTH_RSA_PRIVATE_KEY_PEM_STR: &str = "auth_rsa_private_key_pem"; - -/// The public RSA key. -/// String key: `"auth_rsa_public_key_pem"`. -/// Accepted values: ``. -pub const ZN_AUTH_RSA_PUBLIC_KEY_FILE_KEY: u64 = 0x80; -pub const ZN_AUTH_RSA_PUBLIC_KEY_FILE_STR: &str = "auth_rsa_public_key_file"; - -/// The private RSA key. -/// String key: `"auth_rsa_private_key_pem"`. -/// Accepted values: ``. -pub const ZN_AUTH_RSA_PRIVATE_KEY_FILE_KEY: u64 = 0x81; -pub const ZN_AUTH_RSA_PRIVATE_KEY_FILE_STR: &str = "auth_rsa_private_key_file"; - -/// The default RSA key size. -/// String key: `"auth_rsa_key_size"`. -/// Accepted values: ``. -pub const ZN_AUTH_RSA_KEY_SIZE_KEY: u64 = 0x82; -pub const ZN_AUTH_RSA_KEY_SIZE_STR: &str = "auth_rsa_key_size"; -pub const ZN_AUTH_RSA_KEY_SIZE_DEFAULT: &str = "512"; - -/// The list of known RSA public keys. -/// String key: `"auth_rsa_known_keys_file"`. -/// Accepted values: ``. -pub const ZN_AUTH_RSA_KNOWN_KEYS_FILE_KEY: u64 = 0x83; -pub const ZN_AUTH_RSA_KNOWN_KEYS_FILE_STR: &str = "auth_rsa_known_keys_file"; - -/// Configures the maximum number of simultaneous open unicast sessions. -/// String key: `"max_sessions_unicast"`. -/// Accepted values: ``. -/// Default value: `1024`. -pub const ZN_MAX_SESSIONS_MULTICAST_KEY: u64 = 0x84; -pub const ZN_MAX_SESSIONS_MULTICAST_STR: &str = "max_sessions_multicast"; -pub const ZN_MAX_SESSIONS_MULTICAST_DEFAULT: &str = "1024"; - -/// The file path containing the TLS server private key. -/// String key: `"tls_client_private_key"`. -/// Accepted values: ``. -/// Default value: None. -pub const ZN_TLS_CLIENT_PRIVATE_KEY_KEY: u64 = 0x85; -pub const ZN_TLS_CLIENT_PRIVATE_KEY_STR: &str = "tls_client_private_key"; - -/// The file path containing the TLS server certificate. -/// String key: `"tls_client_private_key"`. -/// Accepted values: ``. -/// Default value: None. -pub const ZN_TLS_CLIENT_CERTIFICATE_KEY: u64 = 0x86; -pub const ZN_TLS_CLIENT_CERTIFICATE_STR: &str = "tls_client_certificate"; - -/// The file path containing the TLS server certificate. -/// String key: `"tls_private_key"`. -/// Accepted values: `"true"`, `"false"`. -/// Default value: `"false"`. -pub const ZN_TLS_CLIENT_AUTH_KEY: u64 = 0x87; -pub const ZN_TLS_CLIENT_AUTH_STR: &str = "tls_client_auth"; -pub const ZN_TLS_CLIENT_AUTH_DEFAULT: &str = ZN_FALSE; - -/// The default timeout to apply to queries in milliseconds. -/// String key: `"queries_default_timeout"`. -/// Accepted values: ``. -/// Default value: `10000`. -pub const ZN_QUERIES_DEFAULT_TIMEOUT_KEY: u64 = 0x88; -pub const ZN_QUERIES_DEFAULT_TIMEOUT_STR: &str = "local_routing"; -pub const ZN_QUERIES_DEFAULT_TIMEOUT_DEFAULT: &str = "10000"; diff --git a/commons/zenoh-cfg-properties/src/lib.rs b/commons/zenoh-cfg-properties/src/lib.rs deleted file mode 100644 index ccd47091d5..0000000000 --- a/commons/zenoh-cfg-properties/src/lib.rs +++ /dev/null @@ -1,358 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// - -//! ⚠️ WARNING ⚠️ -//! -//! This crate is depecrated and it will be completely removed in the future. -//! -//! This crate is intended for Zenoh's internal use. -//! -//! [Click here for Zenoh's documentation](../zenoh/index.html) -pub mod config; - -use std::collections::HashMap; -use std::convert::{From, TryFrom}; -use std::fmt; -use std::marker::PhantomData; -use std::ops::{Deref, DerefMut}; - -pub trait KeyTranscoder { - fn encode(key: &str) -> Option; - fn decode(key: u64) -> Option; -} - -/// A set of Key/Value (`u64`/`String`) pairs. -#[non_exhaustive] -#[derive(PartialEq, Eq)] -pub struct IntKeyProperties(pub HashMap, PhantomData) -where - T: KeyTranscoder; - -impl IntKeyProperties { - #[inline] - pub fn get_or<'a>(&'a self, key: &u64, default: &'a str) -> &'a str { - self.get(key).map(|s| &s[..]).unwrap_or(default) - } -} - -impl Clone for IntKeyProperties { - fn clone(&self) -> Self { - Self(self.0.clone(), PhantomData) - } -} - -impl Default for IntKeyProperties { - fn default() -> Self { - Self(HashMap::new(), PhantomData) - } -} - -impl Deref for IntKeyProperties { - type Target = HashMap; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for IntKeyProperties { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl fmt::Display for IntKeyProperties { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&Properties::from(self.clone()), f) - } -} - -impl fmt::Debug for IntKeyProperties { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&Properties::from(self.clone()), f) - } -} - -impl From> for HashMap { - fn from(props: IntKeyProperties) -> Self { - props - .0 - .into_iter() - .filter_map(|(k, v)| T::decode(k).map(|k| (k, v))) - .collect() - } -} - -impl From> for IntKeyProperties { - fn from(map: HashMap) -> Self { - Self(map, PhantomData) - } -} - -impl From> for IntKeyProperties { - fn from(map: HashMap) -> Self { - Self( - map.into_iter() - .filter_map(|(k, v)| T::encode(&k).map(|k| (k, v))) - .collect(), - PhantomData, - ) - } -} - -impl From for IntKeyProperties { - fn from(props: Properties) -> Self { - props.0.into() - } -} - -impl From<&str> for IntKeyProperties { - fn from(s: &str) -> Self { - Properties::from(s).into() - } -} - -impl From for IntKeyProperties { - fn from(s: String) -> Self { - Properties::from(s).into() - } -} - -impl From<&[(&str, &str)]> for IntKeyProperties { - fn from(kvs: &[(&str, &str)]) -> Self { - Self( - kvs.iter() - .filter_map(|(k, v)| T::encode(k).map(|k| (k, v.to_string()))) - .collect(), - PhantomData, - ) - } -} - -impl From<&[(u64, &str)]> for IntKeyProperties { - fn from(kvs: &[(u64, &str)]) -> Self { - Self( - kvs.iter() - .cloned() - .map(|(k, v)| (k, v.to_string())) - .collect(), - PhantomData, - ) - } -} - -static PROP_SEPS: &[&str] = &["\r\n", "\n", ";"]; -const DEFAULT_PROP_SEP: char = ';'; -const KV_SEP: &[char] = &['=', ':']; -const COMMENT_PREFIX: char = '#'; - -/// A map of key/value (String,String) properties. -/// -/// It can be parsed from a String, using `;` or `` as separator between each properties -/// and `=` as separator between a key and its value. Keys and values are trimed. -#[non_exhaustive] -#[derive(Clone, PartialEq, Eq, Default)] -pub struct Properties(pub HashMap); - -impl Deref for Properties { - type Target = HashMap; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for Properties { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl fmt::Display for Properties { - /// Format the Properties as a string, using `'='` for key/value separator - /// and `';'` for separator between each keys/values. - /// - /// **WARNING**: the passwords are displayed in clear. This is required for the result - /// of the [`trait@ToString`] automatic implementation that must preserve all the properties. - /// To display the properties, hidding the passwords, rather use the [`Debug`](core::fmt::Debug) trait implementation. - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut it = self.0.iter(); - if let Some((k, v)) = it.next() { - if v.is_empty() { - write!(f, "{k}")? - } else { - write!(f, "{}{}{}", k, KV_SEP[0], v)? - } - for (k, v) in it { - if v.is_empty() { - write!(f, "{DEFAULT_PROP_SEP}{k}")? - } else { - write!(f, "{}{}{}{}", DEFAULT_PROP_SEP, k, KV_SEP[0], v)? - } - } - } - Ok(()) - } -} - -impl fmt::Debug for Properties { - /// Format the Properties as a string, using `'='` for key/value separator - /// and `';'` for separator between each keys/values. - /// - /// **NOTE**: for each key containing `"password"` as sub-string, - /// the value is replaced by `"*****"`. - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut it = self.0.iter(); - if let Some((k, v)) = it.next() { - if v.is_empty() { - write!(f, "{k}")? - } else if k.contains("password") { - write!(f, "{}{}*****", k, KV_SEP[0])? - } else { - write!(f, "{}{}{}", k, KV_SEP[0], v)? - } - for (k, v) in it { - if v.is_empty() { - write!(f, "{DEFAULT_PROP_SEP}{k}")? - } else if k.contains("password") { - write!(f, "{}{}{}*****", DEFAULT_PROP_SEP, k, KV_SEP[0])? - } else { - write!(f, "{}{}{}{}", DEFAULT_PROP_SEP, k, KV_SEP[0], v)? - } - } - } - Ok(()) - } -} - -impl From<&str> for Properties { - fn from(s: &str) -> Self { - let mut props = vec![s]; - for sep in PROP_SEPS { - props = props - .into_iter() - .flat_map(|s| s.split(sep)) - .collect::>(); - } - props = props.into_iter().map(|s| s.trim()).collect::>(); - - Properties( - props - .iter() - .filter_map(|prop| { - if prop.is_empty() || prop.starts_with(COMMENT_PREFIX) { - None - } else { - let mut it = prop.splitn(2, KV_SEP); - Some(( - it.next().unwrap().trim().to_string(), - it.next().unwrap_or("").trim().to_string(), - )) - } - }) - .collect(), - ) - } -} - -impl From for Properties { - fn from(s: String) -> Self { - Self::from(s.as_str()) - } -} - -impl From> for Properties { - fn from(map: HashMap) -> Self { - Self(map) - } -} - -impl From> for Properties { - fn from(props: IntKeyProperties) -> Self { - Self( - props - .0 - .into_iter() - .filter_map(|(k, v)| T::decode(k).map(|k| (k, v))) - .collect(), - ) - } -} - -impl From<&[(&str, &str)]> for Properties { - fn from(kvs: &[(&str, &str)]) -> Self { - Properties( - kvs.iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - ) - } -} - -impl TryFrom<&std::path::Path> for Properties { - type Error = zenoh_result::Error; - fn try_from(p: &std::path::Path) -> Result { - Ok(Self::from(std::fs::read_to_string(p)?)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_properties() { - assert!(Properties::from("").0.is_empty()); - - assert_eq!(Properties::from("p1"), Properties::from(&[("p1", "")][..])); - - assert_eq!( - Properties::from("p1=v1"), - Properties::from(&[("p1", "v1")][..]) - ); - - assert_eq!( - Properties::from("p1=v1;p2=v2;"), - Properties::from(&[("p1", "v1"), ("p2", "v2")][..]) - ); - - assert_eq!( - Properties::from("p1=v1;p2;p3=v3"), - Properties::from(&[("p1", "v1"), ("p2", ""), ("p3", "v3")][..]) - ); - - assert_eq!( - Properties::from("p1=v 1;p 2=v2"), - Properties::from(&[("p1", "v 1"), ("p 2", "v2")][..]) - ); - - assert_eq!( - Properties::from("p1=x=y;p2=a==b"), - Properties::from(&[("p1", "x=y"), ("p2", "a==b")][..]) - ); - } -} - -#[non_exhaustive] -pub struct DummyTranscoder; - -impl KeyTranscoder for DummyTranscoder { - fn encode(_key: &str) -> Option { - None - } - - fn decode(_key: u64) -> Option { - None - } -} diff --git a/commons/zenoh-collections/src/lib.rs b/commons/zenoh-collections/src/lib.rs index b25b76b985..b7a0f8e011 100644 --- a/commons/zenoh-collections/src/lib.rs +++ b/commons/zenoh-collections/src/lib.rs @@ -32,3 +32,8 @@ pub use ring_buffer::*; pub mod stack_buffer; #[cfg(feature = "std")] pub use stack_buffer::*; + +#[cfg(feature = "std")] +pub mod properties; +#[cfg(feature = "std")] +pub use properties::*; diff --git a/commons/zenoh-collections/src/properties.rs b/commons/zenoh-collections/src/properties.rs new file mode 100644 index 0000000000..7c9291bbd6 --- /dev/null +++ b/commons/zenoh-collections/src/properties.rs @@ -0,0 +1,169 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use std::{ + collections::HashMap, + convert::{From, TryFrom}, + fmt, + ops::{Deref, DerefMut}, +}; + +const PROP_SEPS: &[&str] = &["\r\n", "\n", ";"]; +const DEFAULT_PROP_SEP: char = ';'; +const KV_SEP: char = '='; +const COMMENT_PREFIX: char = '#'; + +/// A map of key/value (String,String) properties. +/// It can be parsed from a String, using `;` or `` as separator between each properties +/// and `=` as separator between a key and its value. Keys and values are trimed. +#[non_exhaustive] +#[derive(Clone, PartialEq, Eq, Default)] +pub struct Properties(HashMap); + +impl Deref for Properties { + type Target = HashMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Properties { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl fmt::Display for Properties { + /// Format the Properties as a string, using `'='` for key/value separator + /// and `';'` for separator between each keys/values. + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut it = self.0.iter(); + if let Some((k, v)) = it.next() { + if v.is_empty() { + write!(f, "{k}")? + } else { + write!(f, "{}{}{}", k, KV_SEP, v)? + } + for (k, v) in it { + if v.is_empty() { + write!(f, "{DEFAULT_PROP_SEP}{k}")? + } else { + write!(f, "{}{}{}{}", DEFAULT_PROP_SEP, k, KV_SEP, v)? + } + } + } + Ok(()) + } +} + +impl fmt::Debug for Properties { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self) + } +} + +impl From<&str> for Properties { + fn from(s: &str) -> Self { + let mut props = vec![s]; + for sep in PROP_SEPS { + props = props + .into_iter() + .flat_map(|s| s.split(sep)) + .collect::>(); + } + props = props.into_iter().map(|s| s.trim()).collect::>(); + let inner = props + .iter() + .filter_map(|prop| { + if prop.is_empty() || prop.starts_with(COMMENT_PREFIX) { + None + } else { + let mut it = prop.splitn(2, KV_SEP); + Some(( + it.next().unwrap().trim().to_string(), + it.next().unwrap_or("").trim().to_string(), + )) + } + }) + .collect(); + Self(inner) + } +} + +impl From for Properties { + fn from(s: String) -> Self { + Self::from(s.as_str()) + } +} + +impl From> for Properties { + fn from(map: HashMap) -> Self { + Self(map) + } +} + +impl From<&[(&str, &str)]> for Properties { + fn from(kvs: &[(&str, &str)]) -> Self { + let inner = kvs + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + Self(inner) + } +} + +impl TryFrom<&std::path::Path> for Properties { + type Error = std::io::Error; + + fn try_from(p: &std::path::Path) -> Result { + Ok(Self::from(std::fs::read_to_string(p)?)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_properties() { + assert!(Properties::from("").0.is_empty()); + + assert_eq!(Properties::from("p1"), Properties::from(&[("p1", "")][..])); + + assert_eq!( + Properties::from("p1=v1"), + Properties::from(&[("p1", "v1")][..]) + ); + + assert_eq!( + Properties::from("p1=v1;p2=v2;"), + Properties::from(&[("p1", "v1"), ("p2", "v2")][..]) + ); + + assert_eq!( + Properties::from("p1=v1;p2;p3=v3"), + Properties::from(&[("p1", "v1"), ("p2", ""), ("p3", "v3")][..]) + ); + + assert_eq!( + Properties::from("p1=v 1;p 2=v2"), + Properties::from(&[("p1", "v 1"), ("p 2", "v2")][..]) + ); + + assert_eq!( + Properties::from("p1=x=y;p2=a==b"), + Properties::from(&[("p1", "x=y"), ("p2", "a==b")][..]) + ); + } +} diff --git a/commons/zenoh-config/Cargo.toml b/commons/zenoh-config/Cargo.toml index ae588ab909..11951268d2 100644 --- a/commons/zenoh-config/Cargo.toml +++ b/commons/zenoh-config/Cargo.toml @@ -31,7 +31,6 @@ serde = { workspace = true, features = ["default"] } serde_json = { workspace = true } serde_yaml = { workspace = true } validated_struct = { workspace = true, features = ["json5", "json_get"] } -zenoh-cfg-properties = { path = "../zenoh-cfg-properties/" } zenoh-core = { path = "../zenoh-core/" } zenoh-protocol = { path = "../zenoh-protocol/" } zenoh-result = { path = "../zenoh-result/" } diff --git a/commons/zenoh-config/src/defaults.rs b/commons/zenoh-config/src/defaults.rs index 1d3b0853ed..00be5dac47 100644 --- a/commons/zenoh-config/src/defaults.rs +++ b/commons/zenoh-config/src/defaults.rs @@ -123,6 +123,13 @@ impl Default for QoSConf { } } +#[allow(clippy::derivable_impls)] +impl Default for SharedMemoryConf { + fn default() -> Self { + Self { enabled: false } + } +} + impl Default for LinkTxConf { #[allow(clippy::unnecessary_cast)] fn default() -> Self { @@ -161,8 +168,8 @@ impl Default for QueueSizeConf { interactive_high: 1, data_high: 2, data: 4, - data_low: 4, - background: 4, + data_low: 2, + background: 1, } } } diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 8010e34686..4c78ba8de0 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -33,7 +33,6 @@ use std::{ }; use validated_struct::ValidatedMapAssociatedTypes; pub use validated_struct::{GetError, ValidatedMap}; -pub use zenoh_cfg_properties::config::*; use zenoh_core::zlock; use zenoh_protocol::core::{ key_expr::OwnedKeyExpr, @@ -283,7 +282,7 @@ validated_struct::validator! { client_certificate: Option, }, }, - pub shared_memory: #[derive(Default)] + pub shared_memory: SharedMemoryConf { /// Whether shared memory is enabled or not. /// If set to `false`, the shared-memory transport will be disabled. (default `false`). diff --git a/commons/zenoh-protocol/src/core/endpoint.rs b/commons/zenoh-protocol/src/core/endpoint.rs index e635190ca8..d8401d07f6 100644 --- a/commons/zenoh-protocol/src/core/endpoint.rs +++ b/commons/zenoh-protocol/src/core/endpoint.rs @@ -63,56 +63,64 @@ pub(super) fn config(s: &str) -> &str { } } -pub(super) fn read_properties(s: &str) -> impl Iterator + DoubleEndedIterator { - s.split(LIST_SEPARATOR).filter_map(|prop| { - if prop.is_empty() { - None - } else { - Some(split_once(prop, FIELD_SEPARATOR)) - } - }) -} +pub struct Parameters; -pub(super) fn write_properties<'s, I>(iter: I, into: &mut String) -where - I: Iterator, -{ - let mut first = true; - for (k, v) in iter { - if !first { - into.push(LIST_SEPARATOR); - } - into.push_str(k); - if !v.is_empty() { - into.push(FIELD_SEPARATOR); - into.push_str(v); +impl Parameters { + pub fn extend<'s, I>(iter: I, into: &mut String) + where + I: Iterator, + { + let mut first = into.is_empty(); + for (k, v) in iter { + if !first { + into.push(LIST_SEPARATOR); + } + into.push_str(k); + if !v.is_empty() { + into.push(FIELD_SEPARATOR); + into.push_str(v); + } + first = false; } - first = false; } -} -pub(super) fn extend_properties<'s, I>(iter: I, k: &'s str, v: &'s str) -> String -where - I: Iterator, -{ - let current = iter.filter(|x| x.0 != k); - let new = Some((k, v)).into_iter(); - let iter = current.chain(new); + pub fn iter(s: &str) -> impl Iterator + DoubleEndedIterator { + s.split(LIST_SEPARATOR).filter_map(|prop| { + if prop.is_empty() { + None + } else { + Some(split_once(prop, FIELD_SEPARATOR)) + } + }) + } - let mut into = String::new(); - write_properties(iter, &mut into); - into -} + pub fn get<'s>(s: &'s str, k: &str) -> Option<&'s str> { + Self::iter(s).find(|x| x.0 == k).map(|x| x.1) + } + + pub(super) fn insert<'s, I>(iter: I, k: &'s str, v: &'s str) -> String + where + I: Iterator, + { + let current = iter.filter(|x| x.0 != k); + let new = Some((k, v)).into_iter(); + let iter = current.chain(new); -pub(super) fn remove_properties<'s, I>(iter: I, k: &'s str) -> String -where - I: Iterator, -{ - let iter = iter.filter(|x| x.0 != k); + let mut into = String::new(); + Parameters::extend(iter, &mut into); + into + } - let mut into = String::new(); - write_properties(iter, &mut into); - into + pub(super) fn remove<'s, I>(iter: I, k: &'s str) -> String + where + I: Iterator, + { + let iter = iter.filter(|x| x.0 != k); + + let mut into = String::new(); + Parameters::extend(iter, &mut into); + into + } } // Protocol @@ -239,11 +247,11 @@ impl<'a> Metadata<'a> { } pub fn iter(&'a self) -> impl Iterator + DoubleEndedIterator { - read_properties(self.0) + Parameters::iter(self.0) } pub fn get(&'a self, k: &str) -> Option<&'a str> { - self.iter().find(|x| x.0 == k).map(|x| x.1) + Parameters::get(self.0, k) } } @@ -293,7 +301,7 @@ impl MetadataMut<'_> { let ep = EndPoint::new( self.0.protocol(), self.0.address(), - extend_properties(self.0.metadata().iter(), k, v), + Parameters::insert(self.0.metadata().iter(), k, v), self.0.config(), )?; @@ -305,7 +313,7 @@ impl MetadataMut<'_> { let ep = EndPoint::new( self.0.protocol(), self.0.address(), - remove_properties(self.0.metadata().iter(), k), + Parameters::remove(self.0.metadata().iter(), k), self.0.config(), )?; @@ -342,11 +350,11 @@ impl<'a> Config<'a> { } pub fn iter(&'a self) -> impl Iterator + DoubleEndedIterator { - read_properties(self.0) + Parameters::iter(self.0) } pub fn get(&'a self, k: &str) -> Option<&'a str> { - self.iter().find(|x| x.0 == k).map(|x| x.1) + Parameters::get(self.0, k) } } @@ -397,7 +405,7 @@ impl ConfigMut<'_> { self.0.protocol(), self.0.address(), self.0.metadata(), - extend_properties(self.0.config().iter(), k, v), + Parameters::insert(self.0.config().iter(), k, v), )?; self.0.inner = ep.inner; @@ -409,7 +417,7 @@ impl ConfigMut<'_> { self.0.protocol(), self.0.address(), self.0.metadata(), - remove_properties(self.0.config().iter(), k), + Parameters::remove(self.0.config().iter(), k), )?; self.0.inner = ep.inner; diff --git a/io/zenoh-link-commons/Cargo.toml b/io/zenoh-link-commons/Cargo.toml index e6566a449a..cbf6772400 100644 --- a/io/zenoh-link-commons/Cargo.toml +++ b/io/zenoh-link-commons/Cargo.toml @@ -31,7 +31,6 @@ flume = { workspace = true } serde = { workspace = true, features = ["default"] } typenum = { workspace = true } zenoh-buffers = { path = "../../commons/zenoh-buffers/" } -zenoh-cfg-properties = { path = "../../commons/zenoh-cfg-properties/" } zenoh-codec = { path = "../../commons/zenoh-codec/" } zenoh-result = { path = "../../commons/zenoh-result/" } zenoh-protocol = { path = "../../commons/zenoh-protocol/" } diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index 6d53da98f3..3fe8cc16a0 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -17,22 +17,25 @@ //! This crate is intended for Zenoh's internal use. //! //! [Click here for Zenoh's documentation](../zenoh/index.html) +extern crate alloc; + +mod unicast; + use async_trait::async_trait; use serde::Serialize; use std::{ borrow::Cow, cmp::PartialEq, - convert::TryFrom, fmt, hash::{Hash, Hasher}, ops::Deref, sync::Arc, }; +pub use unicast::*; use zenoh_buffers::{ reader::{HasReader, Reader}, - writer::{HasWriter, Writer}, + writer::HasWriter, }; -use zenoh_cfg_properties::Properties; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_protocol::{ core::{EndPoint, Locator}, @@ -58,9 +61,10 @@ pub trait LocatorInspector: Default { fn protocol(&self) -> &str; async fn is_multicast(&self, locator: &Locator) -> ZResult; } + #[async_trait] pub trait ConfigurationInspector: Default { - async fn inspect_config(&self, configuration: &C) -> ZResult; + async fn inspect_config(&self, configuration: &C) -> ZResult; } impl fmt::Display for Link { @@ -107,158 +111,6 @@ impl From for Link { } } -/*************************************/ -/* UNICAST */ -/*************************************/ - -pub type LinkManagerUnicast = Arc; -#[async_trait] -pub trait LinkManagerUnicastTrait: Send + Sync { - async fn new_link(&self, endpoint: EndPoint) -> ZResult; - async fn new_listener(&self, endpoint: EndPoint) -> ZResult; - async fn del_listener(&self, endpoint: &EndPoint) -> ZResult<()>; - fn get_listeners(&self) -> Vec; - fn get_locators(&self) -> Vec; -} -pub type NewLinkChannelSender = flume::Sender; -pub trait ConstructibleLinkManagerUnicast: Sized { - fn new(new_link_sender: NewLinkChannelSender, config: T) -> ZResult; -} - -#[derive(Clone, PartialEq, Eq)] -pub enum LinkUnicastDirection { - Inbound, - Outbound, -} - -#[derive(Clone)] -pub struct LinkUnicast(pub Arc); - -#[async_trait] -pub trait LinkUnicastTrait: Send + Sync { - fn get_mtu(&self) -> u16; - fn get_src(&self) -> &Locator; - fn get_dst(&self) -> &Locator; - fn is_reliable(&self) -> bool; - fn is_streamed(&self) -> bool; - async fn write(&self, buffer: &[u8]) -> ZResult; - async fn write_all(&self, buffer: &[u8]) -> ZResult<()>; - async fn read(&self, buffer: &mut [u8]) -> ZResult; - async fn read_exact(&self, buffer: &mut [u8]) -> ZResult<()>; - async fn close(&self) -> ZResult<()>; -} - -impl LinkUnicast { - pub async fn send(&self, msg: &TransportMessage) -> ZResult { - const ERR: &str = "Write error on link: "; - - // Create the buffer for serializing the message - let mut buff = vec![]; - let mut writer = buff.writer(); - let codec = Zenoh080::new(); - - // Reserve 16 bits to write the length - if self.is_streamed() { - writer - .write_exact(u16::MIN.to_le_bytes().as_slice()) - .map_err(|_| zerror!("{ERR}{self}"))?; - } - // Serialize the message - codec - .write(&mut writer, msg) - .map_err(|_| zerror!("{ERR}{self}"))?; - - // Write the length - if self.is_streamed() { - let num = u16::MIN.to_le_bytes().len(); - let len = u16::try_from(writer.len() - num).map_err(|_| zerror!("{ERR}{self}"))?; - buff[..num].copy_from_slice(len.to_le_bytes().as_slice()); - } - - // Send the message on the link - self.0.write_all(buff.as_slice()).await?; - - Ok(buff.len()) - } - - pub async fn recv(&self) -> ZResult { - // Read from the link - let buffer = if self.is_streamed() { - // Read and decode the message length - let mut length_bytes = [0_u8; 2]; - self.read_exact(&mut length_bytes).await?; - let to_read = u16::from_le_bytes(length_bytes) as usize; - // Read the message - let mut buffer = zenoh_buffers::vec::uninit(to_read); - self.read_exact(&mut buffer).await?; - buffer - } else { - // Read the message - let mut buffer = zenoh_buffers::vec::uninit(self.get_mtu() as usize); - let n = self.read(&mut buffer).await?; - buffer.truncate(n); - buffer - }; - - let mut reader = buffer.reader(); - let codec = Zenoh080::new(); - - let msg: TransportMessage = codec - .read(&mut reader) - .map_err(|_| zerror!("Read error on link: {}", self))?; - - Ok(msg) - } -} - -impl Deref for LinkUnicast { - type Target = Arc; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl Eq for LinkUnicast {} - -impl PartialEq for LinkUnicast { - fn eq(&self, other: &Self) -> bool { - self.get_src() == other.get_src() && self.get_dst() == other.get_dst() - } -} - -impl Hash for LinkUnicast { - fn hash(&self, state: &mut H) { - self.get_src().hash(state); - self.get_dst().hash(state); - } -} - -impl fmt::Display for LinkUnicast { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{} => {}", self.get_src(), self.get_dst()) - } -} - -impl fmt::Debug for LinkUnicast { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Link") - .field("src", &self.get_src()) - .field("dst", &self.get_dst()) - .field("mtu", &self.get_mtu()) - .field("is_reliable", &self.is_reliable()) - .field("is_streamed", &self.is_streamed()) - .finish() - } -} - -impl From> for LinkUnicast { - fn from(link: Arc) -> LinkUnicast { - LinkUnicast(link) - } -} - /*************************************/ /* MULTICAST */ /*************************************/ diff --git a/io/zenoh-link-commons/src/multicast.rs b/io/zenoh-link-commons/src/multicast.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs new file mode 100644 index 0000000000..ab16515ec3 --- /dev/null +++ b/io/zenoh-link-commons/src/unicast.rs @@ -0,0 +1,179 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use alloc::sync::Arc; +use async_trait::async_trait; +use core::{ + convert::TryFrom, + fmt, + hash::{Hash, Hasher}, + ops::Deref, +}; +use zenoh_buffers::{ + reader::HasReader, + writer::{HasWriter, Writer}, +}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_protocol::{ + core::{EndPoint, Locator}, + transport::TransportMessage, +}; +use zenoh_result::{zerror, ZResult}; + +pub type LinkManagerUnicast = Arc; +#[async_trait] +pub trait LinkManagerUnicastTrait: Send + Sync { + async fn new_link(&self, endpoint: EndPoint) -> ZResult; + async fn new_listener(&self, endpoint: EndPoint) -> ZResult; + async fn del_listener(&self, endpoint: &EndPoint) -> ZResult<()>; + fn get_listeners(&self) -> Vec; + fn get_locators(&self) -> Vec; +} +pub type NewLinkChannelSender = flume::Sender; +pub trait ConstructibleLinkManagerUnicast: Sized { + fn new(new_link_sender: NewLinkChannelSender, config: T) -> ZResult; +} + +#[derive(Clone, PartialEq, Eq)] +pub enum LinkUnicastDirection { + Inbound, + Outbound, +} + +#[derive(Clone)] +pub struct LinkUnicast(pub Arc); + +#[async_trait] +pub trait LinkUnicastTrait: Send + Sync { + fn get_mtu(&self) -> u16; + fn get_src(&self) -> &Locator; + fn get_dst(&self) -> &Locator; + fn is_reliable(&self) -> bool; + fn is_streamed(&self) -> bool; + async fn write(&self, buffer: &[u8]) -> ZResult; + async fn write_all(&self, buffer: &[u8]) -> ZResult<()>; + async fn read(&self, buffer: &mut [u8]) -> ZResult; + async fn read_exact(&self, buffer: &mut [u8]) -> ZResult<()>; + async fn close(&self) -> ZResult<()>; +} + +impl LinkUnicast { + pub async fn send(&self, msg: &TransportMessage) -> ZResult { + const ERR: &str = "Write error on link: "; + + // Create the buffer for serializing the message + let mut buff = vec![]; + let mut writer = buff.writer(); + let codec = Zenoh080::new(); + + // Reserve 16 bits to write the length + if self.is_streamed() { + writer + .write_exact(u16::MIN.to_le_bytes().as_slice()) + .map_err(|_| zerror!("{ERR}{self}"))?; + } + // Serialize the message + codec + .write(&mut writer, msg) + .map_err(|_| zerror!("{ERR}{self}"))?; + + // Write the length + if self.is_streamed() { + let num = u16::MIN.to_le_bytes().len(); + let len = u16::try_from(writer.len() - num).map_err(|_| zerror!("{ERR}{self}"))?; + buff[..num].copy_from_slice(len.to_le_bytes().as_slice()); + } + + // Send the message on the link + self.0.write_all(buff.as_slice()).await?; + + Ok(buff.len()) + } + + pub async fn recv(&self) -> ZResult { + // Read from the link + let buffer = if self.is_streamed() { + // Read and decode the message length + let mut length_bytes = [0_u8; 2]; + self.read_exact(&mut length_bytes).await?; + let to_read = u16::from_le_bytes(length_bytes) as usize; + // Read the message + let mut buffer = zenoh_buffers::vec::uninit(to_read); + self.read_exact(&mut buffer).await?; + buffer + } else { + // Read the message + let mut buffer = zenoh_buffers::vec::uninit(self.get_mtu() as usize); + let n = self.read(&mut buffer).await?; + buffer.truncate(n); + buffer + }; + + let mut reader = buffer.reader(); + let codec = Zenoh080::new(); + + let msg: TransportMessage = codec + .read(&mut reader) + .map_err(|_| zerror!("Read error on link: {}", self))?; + + Ok(msg) + } +} + +impl Deref for LinkUnicast { + type Target = Arc; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Eq for LinkUnicast {} + +impl PartialEq for LinkUnicast { + fn eq(&self, other: &Self) -> bool { + self.get_src() == other.get_src() && self.get_dst() == other.get_dst() + } +} + +impl Hash for LinkUnicast { + fn hash(&self, state: &mut H) { + self.get_src().hash(state); + self.get_dst().hash(state); + } +} + +impl fmt::Display for LinkUnicast { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} => {}", self.get_src(), self.get_dst()) + } +} + +impl fmt::Debug for LinkUnicast { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Link") + .field("src", &self.get_src()) + .field("dst", &self.get_dst()) + .field("mtu", &self.get_mtu()) + .field("is_reliable", &self.is_reliable()) + .field("is_streamed", &self.is_streamed()) + .finish() + } +} + +impl From> for LinkUnicast { + fn from(link: Arc) -> LinkUnicast { + LinkUnicast(link) + } +} diff --git a/io/zenoh-link/Cargo.toml b/io/zenoh-link/Cargo.toml index 6d2d1e5652..18b2557161 100644 --- a/io/zenoh-link/Cargo.toml +++ b/io/zenoh-link/Cargo.toml @@ -37,7 +37,6 @@ transport_serial = ["zenoh-link-serial"] async-std = { workspace = true } async-trait = { workspace = true } rcgen = { workspace = true, optional = true } -zenoh-cfg-properties = { path = "../../commons/zenoh-cfg-properties/" } zenoh-config = { path = "../../commons/zenoh-config/" } zenoh-result = { path = "../../commons/zenoh-result/" } zenoh-link-commons = { path = "../zenoh-link-commons/" } diff --git a/io/zenoh-link/src/lib.rs b/io/zenoh-link/src/lib.rs index a8b44d938b..ce3c50645c 100644 --- a/io/zenoh-link/src/lib.rs +++ b/io/zenoh-link/src/lib.rs @@ -18,10 +18,7 @@ //! //! [Click here for Zenoh's documentation](../zenoh/index.html) use std::collections::HashMap; -#[allow(unused_imports)] use std::sync::Arc; - -use zenoh_cfg_properties::Properties; use zenoh_config::Config; use zenoh_result::{bail, ZResult}; @@ -112,18 +109,19 @@ pub struct LinkConfigurator { #[cfg(feature = "transport_tls")] tls_inspector: TlsConfigurator, } + impl LinkConfigurator { #[allow(unused_variables, unused_mut)] pub async fn configurations( &self, config: &Config, ) -> ( - HashMap, + HashMap, HashMap, ) { let mut configs = HashMap::new(); let mut errors = HashMap::new(); - let mut insert_config = |proto: String, cfg: ZResult| match cfg { + let mut insert_config = |proto: String, cfg: ZResult| match cfg { Ok(v) => { configs.insert(proto, v); } diff --git a/io/zenoh-links/zenoh-link-quic/Cargo.toml b/io/zenoh-links/zenoh-link-quic/Cargo.toml index b90c964405..64f5767864 100644 --- a/io/zenoh-links/zenoh-link-quic/Cargo.toml +++ b/io/zenoh-links/zenoh-link-quic/Cargo.toml @@ -34,7 +34,6 @@ rustls = { workspace = true } rustls-native-certs = { workspace = true } rustls-pemfile = { workspace = true } webpki = { workspace = true } -zenoh-cfg-properties = { path = "../../../commons/zenoh-cfg-properties/" } zenoh-config = { path = "../../../commons/zenoh-config/" } zenoh-core = { path = "../../../commons/zenoh-core/" } zenoh-link-commons = { path = "../../zenoh-link-commons/" } diff --git a/io/zenoh-links/zenoh-link-quic/src/lib.rs b/io/zenoh-links/zenoh-link-quic/src/lib.rs index d3827d1a3d..841e40aaaa 100644 --- a/io/zenoh-links/zenoh-link-quic/src/lib.rs +++ b/io/zenoh-links/zenoh-link-quic/src/lib.rs @@ -24,11 +24,10 @@ use config::{ }; use std::net::SocketAddr; use webpki::DnsNameRef; -use zenoh_cfg_properties::Properties; use zenoh_config::{Config, Locator}; use zenoh_core::zconfigurable; use zenoh_link_commons::{ConfigurationInspector, LocatorInspector}; -use zenoh_protocol::core::endpoint::Address; +use zenoh_protocol::core::endpoint::{self, Address}; use zenoh_result::{bail, zerror, ZResult}; mod unicast; @@ -48,43 +47,41 @@ pub const QUIC_LOCATOR_PREFIX: &str = "quic"; #[derive(Default, Clone, Copy, Debug)] pub struct QuicLocatorInspector; + #[async_trait] impl LocatorInspector for QuicLocatorInspector { fn protocol(&self) -> &str { QUIC_LOCATOR_PREFIX } + async fn is_multicast(&self, _locator: &Locator) -> ZResult { Ok(false) } } + #[derive(Default, Clone, Copy, Debug)] pub struct QuicConfigurator; + #[async_trait] impl ConfigurationInspector for QuicConfigurator { - async fn inspect_config(&self, config: &Config) -> ZResult { - let mut properties = Properties::default(); + async fn inspect_config(&self, config: &Config) -> ZResult { + let mut ps: Vec<(&str, &str)> = vec![]; let c = config.transport().link().tls(); if let Some(tls_ca_certificate) = c.root_ca_certificate() { - properties.insert( - TLS_ROOT_CA_CERTIFICATE_FILE.into(), - tls_ca_certificate.into(), - ); + ps.push((TLS_ROOT_CA_CERTIFICATE_FILE, tls_ca_certificate)); } if let Some(tls_server_private_key) = c.server_private_key() { - properties.insert( - TLS_SERVER_PRIVATE_KEY_FILE.into(), - tls_server_private_key.into(), - ); + ps.push((TLS_SERVER_PRIVATE_KEY_FILE, tls_server_private_key)); } if let Some(tls_server_certificate) = c.server_certificate() { - properties.insert( - TLS_SERVER_CERTIFICATE_FILE.into(), - tls_server_certificate.into(), - ); + ps.push((TLS_SERVER_CERTIFICATE_FILE, tls_server_certificate)); } - Ok(properties) + let mut s = String::new(); + endpoint::Parameters::extend(ps.drain(..), &mut s); + + Ok(s) } } @@ -102,16 +99,14 @@ zconfigurable! { } pub mod config { - use zenoh_cfg_properties::config::*; - - pub const TLS_ROOT_CA_CERTIFICATE_FILE: &str = ZN_TLS_ROOT_CA_CERTIFICATE_STR; - pub const TLS_ROOT_CA_CERTIFICATE_RAW: &str = "tls_root_ca_certificate_raw"; + pub const TLS_ROOT_CA_CERTIFICATE_FILE: &str = "root_ca_certificate_file"; + pub const TLS_ROOT_CA_CERTIFICATE_RAW: &str = "root_ca_certificate_raw"; - pub const TLS_SERVER_PRIVATE_KEY_FILE: &str = ZN_TLS_SERVER_PRIVATE_KEY_STR; - pub const TLS_SERVER_PRIVATE_KEY_RAW: &str = "tls_server_private_key_raw"; + pub const TLS_SERVER_PRIVATE_KEY_FILE: &str = "server_private_key_file"; + pub const TLS_SERVER_PRIVATE_KEY_RAW: &str = "server_private_key_raw"; - pub const TLS_SERVER_CERTIFICATE_FILE: &str = ZN_TLS_SERVER_CERTIFICATE_STR; - pub const TLS_SERVER_CERTIFICATE_RAW: &str = "tls_server_certificate_raw"; + pub const TLS_SERVER_CERTIFICATE_FILE: &str = "server_certificate_file"; + pub const TLS_SERVER_CERTIFICATE_RAW: &str = "server_certificate_raw"; } async fn get_quic_addr(address: &Address<'_>) -> ZResult { diff --git a/io/zenoh-links/zenoh-link-serial/Cargo.toml b/io/zenoh-links/zenoh-link-serial/Cargo.toml index 97eb094151..ffa68a6e3a 100644 --- a/io/zenoh-links/zenoh-link-serial/Cargo.toml +++ b/io/zenoh-links/zenoh-link-serial/Cargo.toml @@ -39,7 +39,6 @@ log = { workspace = true } tokio = { workspace = true, features = ["io-std", "macros", "net", "rt-multi-thread", "time", "io-util"] } uuid = { workspace = true, default-features = true } z-serial = { workspace = true } -zenoh-cfg-properties = { path = "../../../commons/zenoh-cfg-properties/" } zenoh-collections = { path = "../../../commons/zenoh-collections/" } zenoh-config = { path = "../../../commons/zenoh-config/" } zenoh-core = { path = "../../../commons/zenoh-core/" } diff --git a/io/zenoh-links/zenoh-link-serial/src/lib.rs b/io/zenoh-links/zenoh-link-serial/src/lib.rs index 58e3bd214e..f006f66bfb 100644 --- a/io/zenoh-links/zenoh-link-serial/src/lib.rs +++ b/io/zenoh-links/zenoh-link-serial/src/lib.rs @@ -53,6 +53,7 @@ impl LocatorInspector for SerialLocatorInspector { fn protocol(&self) -> &str { SERIAL_LOCATOR_PREFIX } + async fn is_multicast(&self, _locator: &Locator) -> ZResult { Ok(false) } diff --git a/io/zenoh-links/zenoh-link-tls/Cargo.toml b/io/zenoh-links/zenoh-link-tls/Cargo.toml index 5f28131a7d..8a2fa78af9 100644 --- a/io/zenoh-links/zenoh-link-tls/Cargo.toml +++ b/io/zenoh-links/zenoh-link-tls/Cargo.toml @@ -33,7 +33,6 @@ log = { workspace = true } rustls-pemfile = { workspace = true } webpki = { workspace = true } webpki-roots = { workspace = true } -zenoh-cfg-properties = { path = "../../../commons/zenoh-cfg-properties/" } zenoh-config = { path = "../../../commons/zenoh-config/" } zenoh-core = { path = "../../../commons/zenoh-core/" } zenoh-link-commons = { path = "../../zenoh-link-commons/" } diff --git a/io/zenoh-links/zenoh-link-tls/src/lib.rs b/io/zenoh-links/zenoh-link-tls/src/lib.rs index 8bb607b0a7..c0c4e0224e 100644 --- a/io/zenoh-links/zenoh-link-tls/src/lib.rs +++ b/io/zenoh-links/zenoh-link-tls/src/lib.rs @@ -25,11 +25,13 @@ use config::{ TLS_CLIENT_AUTH, TLS_CLIENT_CERTIFICATE_FILE, TLS_CLIENT_PRIVATE_KEY_FILE, TLS_ROOT_CA_CERTIFICATE_FILE, TLS_SERVER_CERTIFICATE_FILE, TLS_SERVER_PRIVATE_KEY_FILE, }; -use zenoh_cfg_properties::Properties; -use zenoh_config::{Config, ZN_FALSE, ZN_TRUE}; +use zenoh_config::Config; use zenoh_core::zconfigurable; use zenoh_link_commons::{ConfigurationInspector, LocatorInspector}; -use zenoh_protocol::core::{endpoint::Address, Locator}; +use zenoh_protocol::core::{ + endpoint::{self, Address}, + Locator, +}; use zenoh_result::{bail, zerror, ZResult}; mod unicast; @@ -51,56 +53,46 @@ impl LocatorInspector for TlsLocatorInspector { fn protocol(&self) -> &str { TLS_LOCATOR_PREFIX } + async fn is_multicast(&self, _locator: &Locator) -> ZResult { Ok(false) } } #[derive(Default, Clone, Copy, Debug)] pub struct TlsConfigurator; + #[async_trait] impl ConfigurationInspector for TlsConfigurator { - async fn inspect_config(&self, config: &Config) -> ZResult { - let mut properties = Properties::default(); + async fn inspect_config(&self, config: &Config) -> ZResult { + let mut ps: Vec<(&str, &str)> = vec![]; let c = config.transport().link().tls(); - if let Some(tls_ca_certificate) = c.root_ca_certificate() { - properties.insert( - TLS_ROOT_CA_CERTIFICATE_FILE.into(), - tls_ca_certificate.into(), - ); + if let Some(ca_certificate) = c.root_ca_certificate() { + ps.push((TLS_ROOT_CA_CERTIFICATE_FILE, ca_certificate)); } - if let Some(tls_server_private_key) = c.server_private_key() { - properties.insert( - TLS_SERVER_PRIVATE_KEY_FILE.into(), - tls_server_private_key.into(), - ); + if let Some(server_private_key) = c.server_private_key() { + ps.push((TLS_SERVER_PRIVATE_KEY_FILE, server_private_key)); } - if let Some(tls_server_certificate) = c.server_certificate() { - properties.insert( - TLS_SERVER_CERTIFICATE_FILE.into(), - tls_server_certificate.into(), - ); + if let Some(server_certificate) = c.server_certificate() { + ps.push((TLS_SERVER_CERTIFICATE_FILE, server_certificate)); } - if let Some(tls_client_auth) = c.client_auth() { - match tls_client_auth { - true => properties.insert(TLS_CLIENT_AUTH.into(), ZN_TRUE.into()), - false => properties.insert(TLS_CLIENT_AUTH.into(), ZN_FALSE.into()), + if let Some(client_auth) = c.client_auth() { + match client_auth { + true => ps.push((TLS_CLIENT_AUTH, "true")), + false => ps.push((TLS_CLIENT_AUTH, "false")), }; } - if let Some(tls_client_private_key) = c.client_private_key() { - properties.insert( - TLS_CLIENT_PRIVATE_KEY_FILE.into(), - tls_client_private_key.into(), - ); + if let Some(client_private_key) = c.client_private_key() { + ps.push((TLS_CLIENT_PRIVATE_KEY_FILE, client_private_key)); } - if let Some(tls_client_certificate) = c.client_certificate() { - properties.insert( - TLS_CLIENT_CERTIFICATE_FILE.into(), - tls_client_certificate.into(), - ); + if let Some(client_certificate) = c.client_certificate() { + ps.push((TLS_CLIENT_CERTIFICATE_FILE, client_certificate)); } - Ok(properties) + let mut s = String::new(); + endpoint::Parameters::extend(ps.drain(..), &mut s); + + Ok(s) } } @@ -118,24 +110,22 @@ zconfigurable! { } pub mod config { - use zenoh_cfg_properties::config::*; - pub const TLS_ROOT_CA_CERTIFICATE_FILE: &str = ZN_TLS_ROOT_CA_CERTIFICATE_STR; - pub const TLS_ROOT_CA_CERTIFICATE_RAW: &str = "tls_root_ca_certificate_raw"; + pub const TLS_ROOT_CA_CERTIFICATE_FILE: &str = "root_ca_certificate_file"; + pub const TLS_ROOT_CA_CERTIFICATE_RAW: &str = "root_ca_certificate_raw"; - pub const TLS_SERVER_PRIVATE_KEY_FILE: &str = ZN_TLS_SERVER_PRIVATE_KEY_STR; - pub const TLS_SERVER_PRIVATE_KEY_RAW: &str = "tls_server_private_key_raw"; + pub const TLS_SERVER_PRIVATE_KEY_FILE: &str = "server_private_key_file"; + pub const TLS_SERVER_PRIVATE_KEY_RAW: &str = "server_private_key_raw"; - pub const TLS_SERVER_CERTIFICATE_FILE: &str = ZN_TLS_SERVER_CERTIFICATE_STR; - pub const TLS_SERVER_CERTIFICATE_RAW: &str = "tls_server_certificate_raw"; + pub const TLS_SERVER_CERTIFICATE_FILE: &str = "server_certificate_file"; + pub const TLS_SERVER_CERTIFICATE_RAW: &str = "server_certificate_raw"; - pub const TLS_CLIENT_PRIVATE_KEY_FILE: &str = ZN_TLS_CLIENT_PRIVATE_KEY_STR; - pub const TLS_CLIENT_PRIVATE_KEY_RAW: &str = "tls_client_private_key_raw"; + pub const TLS_CLIENT_PRIVATE_KEY_FILE: &str = "client_private_key_file"; + pub const TLS_CLIENT_PRIVATE_KEY_RAW: &str = "client_private_key_raw"; - pub const TLS_CLIENT_CERTIFICATE_FILE: &str = ZN_TLS_CLIENT_CERTIFICATE_STR; - pub const TLS_CLIENT_CERTIFICATE_RAW: &str = "tls_client_certificate_raw"; + pub const TLS_CLIENT_CERTIFICATE_FILE: &str = "client_certificate_file"; + pub const TLS_CLIENT_CERTIFICATE_RAW: &str = "client_certificate_raw"; - pub const TLS_CLIENT_AUTH: &str = ZN_TLS_CLIENT_AUTH_STR; - pub const TLS_CLIENT_AUTH_DEFAULT: &str = ZN_TLS_CLIENT_AUTH_DEFAULT; + pub const TLS_CLIENT_AUTH: &str = "client_auth"; } pub async fn get_tls_addr(address: &Address<'_>) -> ZResult { diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast.rs b/io/zenoh-links/zenoh-link-tls/src/unicast.rs index 4477e4185a..2d52ee4954 100644 --- a/io/zenoh-links/zenoh-link-tls/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tls/src/unicast.rs @@ -513,7 +513,12 @@ struct TlsServerConfig { impl TlsServerConfig { pub async fn new(config: &Config<'_>) -> ZResult { - let mut client_auth: bool = TLS_CLIENT_AUTH_DEFAULT.parse().unwrap(); + let tls_server_client_auth: bool = match config.get(TLS_CLIENT_AUTH) { + Some(s) => s + .parse() + .map_err(|_| zerror!("Unknown client auth argument: {}", s))?, + None => false, + }; let tls_server_private_key = TlsServerConfig::load_tls_private_key(config).await?; let tls_server_certificate = TlsServerConfig::load_tls_certificate(config).await?; @@ -537,11 +542,7 @@ impl TlsServerConfig { .map_err(|e| zerror!(e)) .map(|mut certs| certs.drain(..).map(Certificate).collect())?; - if let Some(value) = config.get(TLS_CLIENT_AUTH) { - client_auth = value.parse()? - } - - let sc = if client_auth { + let sc = if tls_server_client_auth { let root_cert_store = load_trust_anchors(config)?.map_or_else( || { Err(zerror!( @@ -593,17 +594,19 @@ struct TlsClientConfig { impl TlsClientConfig { pub async fn new(config: &Config<'_>) -> ZResult { - let mut client_auth: bool = TLS_CLIENT_AUTH_DEFAULT.parse().unwrap(); - if let Some(value) = config.get(TLS_CLIENT_AUTH) { - client_auth = value.parse()? - } + let tls_client_server_auth: bool = match config.get(TLS_CLIENT_AUTH) { + Some(s) => s + .parse() + .map_err(|_| zerror!("Unknown client auth argument: {}", s))?, + None => false, + }; let root_cert_store = load_trust_anchors(config)?.map_or_else(|| { log::debug!("Field 'root_ca_certificate' not specified. Loading default Web PKI certificates instead."); load_default_webpki_certs() }, |certs| certs); - let cc = if client_auth { + let cc = if tls_client_server_auth { log::debug!("Loading client authentication key and certificate..."); let tls_client_private_key = TlsClientConfig::load_tls_private_key(config).await?; let tls_client_certificate = TlsClientConfig::load_tls_certificate(config).await?; diff --git a/io/zenoh-transport/Cargo.toml b/io/zenoh-transport/Cargo.toml index bcaedd629a..35ae7a5156 100644 --- a/io/zenoh-transport/Cargo.toml +++ b/io/zenoh-transport/Cargo.toml @@ -55,7 +55,6 @@ rsa = { workspace = true, optional = true } sha3 = { workspace = true } serde = { workspace = true, features = ["default"] } zenoh-buffers = { path = "../../commons/zenoh-buffers/" } -zenoh-cfg-properties = { path = "../../commons/zenoh-cfg-properties/" } zenoh-codec = { path = "../../commons/zenoh-codec/" } zenoh-collections = { path = "../../commons/zenoh-collections/" } zenoh-config = { path = "../../commons/zenoh-config/" } diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index 64fea96017..c1cb99ea34 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -21,9 +21,7 @@ use rand::{RngCore, SeedableRng}; use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; -use zenoh_cfg_properties::{config::*, Properties}; -use zenoh_config::{Config, QueueConf, QueueSizeConf}; -use zenoh_core::zparse; +use zenoh_config::{Config, LinkRxConf, QueueConf, QueueSizeConf}; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::NewLinkChannelSender; use zenoh_protocol::{ @@ -89,7 +87,7 @@ pub struct TransportManagerConfig { pub defrag_buff_size: usize, pub link_rx_buffer_size: usize, pub unicast: TransportManagerConfigUnicast, - pub endpoint: HashMap, + pub endpoints: HashMap, // (protocol, config) pub handler: Arc, pub tx_threads: usize, } @@ -114,7 +112,7 @@ pub struct TransportManagerBuilder { defrag_buff_size: usize, link_rx_buffer_size: usize, unicast: TransportManagerBuilderUnicast, - endpoint: HashMap, + endpoints: HashMap, // (protocol, config) tx_threads: usize, } @@ -159,8 +157,8 @@ impl TransportManagerBuilder { self } - pub fn endpoint(mut self, endpoint: HashMap) -> Self { - self.endpoint = endpoint; + pub fn endpoints(mut self, endpoints: HashMap) -> Self { + self.endpoints = endpoints; self } @@ -205,7 +203,7 @@ impl TransportManagerBuilder { } bail!("{}", formatter); } - self = self.endpoint(c); + self = self.endpoints(c); self = self.unicast( TransportManagerBuilderUnicast::default() .from_config(config) @@ -239,7 +237,7 @@ impl TransportManagerBuilder { defrag_buff_size: self.defrag_buff_size, link_rx_buffer_size: self.link_rx_buffer_size, unicast: unicast.config, - endpoint: self.endpoint, + endpoints: self.endpoints, handler, tx_threads: self.tx_threads, }; @@ -256,19 +254,20 @@ impl TransportManagerBuilder { impl Default for TransportManagerBuilder { fn default() -> Self { + let link_rx = LinkRxConf::default(); let queue = QueueConf::default(); let backoff = queue.backoff().unwrap(); Self { version: VERSION, zid: ZenohId::rand(), - whatami: ZN_MODE_DEFAULT.parse().unwrap(), + whatami: zenoh_config::defaults::mode, resolution: Resolution::default(), batch_size: BATCH_SIZE, queue_size: queue.size, queue_backoff: Duration::from_nanos(backoff), - defrag_buff_size: zparse!(ZN_DEFRAG_BUFF_SIZE_DEFAULT).unwrap(), - link_rx_buffer_size: zparse!(ZN_LINK_RX_BUFF_SIZE_DEFAULT).unwrap(), - endpoint: HashMap::new(), + defrag_buff_size: link_rx.max_message_size().unwrap(), + link_rx_buffer_size: link_rx.buffer_size().unwrap(), + endpoints: HashMap::new(), unicast: TransportManagerBuilderUnicast::default(), tx_threads: 1, } diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index f9f4ca2fea..c2ee61444e 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -17,18 +17,13 @@ use crate::{ unicast::{transport::TransportUnicastInner, TransportConfigUnicast, TransportUnicast}, TransportManager, }; -use async_std::prelude::FutureExt; -use async_std::sync::Mutex; -use async_std::task; -use std::collections::HashMap; -use std::sync::Arc; -use std::time::Duration; -use zenoh_cfg_properties::config::*; -use zenoh_config::Config; -use zenoh_core::{zasynclock, zparse}; +use async_std::{prelude::FutureExt, sync::Mutex, task}; +use std::{collections::HashMap, sync::Arc, time::Duration}; +use zenoh_config::{Config, LinkTxConf, QoSConf, SharedMemoryConf, TransportUnicastConf}; +use zenoh_core::zasynclock; use zenoh_link::*; use zenoh_protocol::{ - core::{locator::LocatorProtocol, ZenohId}, + core::{endpoint, locator::LocatorProtocol, ZenohId}, transport::close, }; use zenoh_result::{bail, zerror, ZResult}; @@ -198,16 +193,21 @@ impl TransportManagerBuilderUnicast { impl Default for TransportManagerBuilderUnicast { fn default() -> Self { + let link_tx = LinkTxConf::default(); + let transport = TransportUnicastConf::default(); + let qos = QoSConf::default(); + let shm = SharedMemoryConf::default(); + Self { - lease: Duration::from_millis(zparse!(ZN_LINK_LEASE_DEFAULT).unwrap()), - keep_alive: zparse!(ZN_LINK_KEEP_ALIVE_DEFAULT).unwrap(), - accept_timeout: Duration::from_millis(zparse!(ZN_OPEN_TIMEOUT_DEFAULT).unwrap()), - accept_pending: zparse!(ZN_OPEN_INCOMING_PENDING_DEFAULT).unwrap(), - max_sessions: zparse!(ZN_MAX_SESSIONS_UNICAST_DEFAULT).unwrap(), - max_links: zparse!(ZN_MAX_LINKS_DEFAULT).unwrap(), - is_qos: zparse!(ZN_QOS_DEFAULT).unwrap(), + lease: Duration::from_millis(link_tx.lease().unwrap()), + keep_alive: link_tx.keep_alive().unwrap(), + accept_timeout: Duration::from_millis(transport.accept_timeout().unwrap()), + accept_pending: transport.accept_pending().unwrap(), + max_sessions: transport.max_sessions().unwrap(), + max_links: transport.max_links().unwrap(), + is_qos: *qos.enabled(), #[cfg(feature = "shared-memory")] - is_shm: zparse!(ZN_SHM_DEFAULT).unwrap(), + is_shm: *shm.enabled(), // peer_authenticator: HashSet::new(), } } @@ -296,8 +296,10 @@ impl TransportManager { .new_link_manager_unicast(endpoint.protocol().as_str()) .await?; // Fill and merge the endpoint configuration - if let Some(config) = self.config.endpoint.get(endpoint.protocol().as_str()) { - endpoint.config_mut().extend(config.iter())?; + if let Some(config) = self.config.endpoints.get(endpoint.protocol().as_str()) { + endpoint + .config_mut() + .extend(endpoint::Parameters::iter(config))?; }; manager.new_listener(endpoint).await } @@ -420,8 +422,10 @@ impl TransportManager { .new_link_manager_unicast(endpoint.protocol().as_str()) .await?; // Fill and merge the endpoint configuration - if let Some(config) = self.config.endpoint.get(endpoint.protocol().as_str()) { - endpoint.config_mut().extend(config.iter())?; + if let Some(config) = self.config.endpoints.get(endpoint.protocol().as_str()) { + endpoint + .config_mut() + .extend(endpoint::Parameters::iter(config))?; }; // Create a new link associated by calling the Link Manager diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 12c40d03f8..922e7b5507 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -24,7 +24,6 @@ //! use std::sync::Arc; //! use async_trait::async_trait; //! use zenoh::prelude::r#async::*; -//! use zenoh::properties::properties_to_json_value; //! use zenoh::time::Timestamp; //! use zenoh_backend_traits::*; //! use zenoh_backend_traits::config::*; diff --git a/plugins/zenoh-plugin-rest/Cargo.toml b/plugins/zenoh-plugin-rest/Cargo.toml index 18503f6086..054313e326 100644 --- a/plugins/zenoh-plugin-rest/Cargo.toml +++ b/plugins/zenoh-plugin-rest/Cargo.toml @@ -47,7 +47,6 @@ serde = { workspace = true, features = ["default"] } serde_json = { workspace = true } tide = { workspace = true } zenoh = { path = "../../zenoh/", default-features = false, features = ["unstable"] } -zenoh-cfg-properties = { path = "../../commons/zenoh-cfg-properties/" } zenoh-plugin-trait = { path = "../zenoh-plugin-trait/", default-features = false } zenoh-result = { path = "../../commons/zenoh-result/" } zenoh-util = { path = "../../commons/zenoh-util/" } diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 43d26af2fb..8df759e760 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -24,11 +24,11 @@ use tide::sse::Sender; use tide::{Request, Response, Server, StatusCode}; use zenoh::plugins::{Plugin, RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::r#async::*; +use zenoh::properties::Properties; use zenoh::query::{QueryConsolidation, Reply}; use zenoh::runtime::Runtime; use zenoh::selector::TIME_RANGE_KEY; use zenoh::Session; -use zenoh_cfg_properties::Properties; use zenoh_result::{bail, zerror, ZResult}; mod config; diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 92d939c6c9..84d9e5f28d 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -84,7 +84,6 @@ uhlc = { workspace = true, features = ["default"] } uuid = { workspace = true, features = ["default"] } vec_map = { workspace = true } zenoh-buffers = { path = "../commons/zenoh-buffers/" } -zenoh-cfg-properties = { path = "../commons/zenoh-cfg-properties/" } zenoh-codec = { path = "../commons/zenoh-codec/" } zenoh-collections = { path = "../commons/zenoh-collections/" } zenoh-config = { path = "../commons/zenoh-config/" } diff --git a/zenoh/src/lib.rs b/zenoh/src/lib.rs index a8adb79eb4..b702d50d8a 100644 --- a/zenoh/src/lib.rs +++ b/zenoh/src/lib.rs @@ -145,7 +145,7 @@ pub mod time { /// A map of key/value (String,String) properties. pub mod properties { use super::prelude::Value; - pub use zenoh_cfg_properties::Properties; + pub use zenoh_collections::Properties; /// Convert a set of [`Properties`] into a [`Value`]. /// For instance, Properties: `[("k1", "v1"), ("k2, v2")]` @@ -171,7 +171,7 @@ pub mod scouting; /// # Arguments /// /// * `what` - The kind of zenoh process to scout for -/// * `config` - The configuration [`Properties`](crate::properties::Properties) to use for scouting +/// * `config` - The configuration [`Config`](crate::config::Config) to use for scouting /// /// # Examples /// ```no_run diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index ab62fbba87..fdbd884fbb 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -17,7 +17,6 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use uhlc::HLC; use zenoh_buffers::ZBuf; -use zenoh_config::ZN_QUERIES_DEFAULT_TIMEOUT_DEFAULT; use zenoh_core::zlock; use zenoh_protocol::{ core::{ @@ -39,7 +38,7 @@ fn base_test() { Some(Arc::new(HLC::default())), false, true, - Duration::from_millis(ZN_QUERIES_DEFAULT_TIMEOUT_DEFAULT.parse().unwrap()), + Duration::from_millis(zenoh_config::defaults::queries_default_timeout), ); let primitives = Arc::new(DummyPrimitives::new()); let face = tables.open_face(ZenohId::try_from([1]).unwrap(), WhatAmI::Client, primitives); @@ -130,7 +129,7 @@ fn match_test() { Some(Arc::new(HLC::default())), false, true, - Duration::from_millis(ZN_QUERIES_DEFAULT_TIMEOUT_DEFAULT.parse().unwrap()), + Duration::from_millis(zenoh_config::defaults::queries_default_timeout), ); let primitives = Arc::new(DummyPrimitives::new()); let face = tables.open_face(ZenohId::try_from([1]).unwrap(), WhatAmI::Client, primitives); @@ -168,7 +167,7 @@ fn clean_test() { Some(Arc::new(HLC::default())), false, true, - Duration::from_millis(ZN_QUERIES_DEFAULT_TIMEOUT_DEFAULT.parse().unwrap()), + Duration::from_millis(zenoh_config::defaults::queries_default_timeout), ); let primitives = Arc::new(DummyPrimitives::new()); @@ -502,7 +501,7 @@ fn client_test() { Some(Arc::new(HLC::default())), false, true, - Duration::from_millis(ZN_QUERIES_DEFAULT_TIMEOUT_DEFAULT.parse().unwrap()), + Duration::from_millis(zenoh_config::defaults::queries_default_timeout), )); let sub_info = SubInfo { diff --git a/zenoh/src/scouting.rs b/zenoh/src/scouting.rs index 76fd688cf2..803888da18 100644 --- a/zenoh/src/scouting.rs +++ b/zenoh/src/scouting.rs @@ -16,11 +16,8 @@ use crate::net::runtime::{orchestrator::Loop, Runtime}; use async_std::net::UdpSocket; use futures::StreamExt; -use std::future::Ready; -use std::{fmt, ops::Deref}; -use zenoh_config::{ - whatami::WhatAmIMatcher, ZN_MULTICAST_INTERFACE_DEFAULT, ZN_MULTICAST_IPV4_ADDRESS_DEFAULT, -}; +use std::{fmt, future::Ready, net::SocketAddr, ops::Deref}; +use zenoh_config::whatami::WhatAmIMatcher; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; use zenoh_result::ZResult; @@ -295,23 +292,12 @@ fn scout( callback: Callback<'static, Hello>, ) -> ZResult { log::trace!("scout({}, {})", what, &config); - let default_addr = match ZN_MULTICAST_IPV4_ADDRESS_DEFAULT.parse() { - Ok(addr) => addr, - Err(e) => { - bail!( - "invalid default addr {}: {:?}", - ZN_MULTICAST_IPV4_ADDRESS_DEFAULT, - &e - ) - } - }; + let default_addr = SocketAddr::from(zenoh_config::defaults::scouting::multicast::address); let addr = config.scouting.multicast.address().unwrap_or(default_addr); - let ifaces = config - .scouting - .multicast - .interface() - .as_ref() - .map_or(ZN_MULTICAST_INTERFACE_DEFAULT, |s| s.as_ref()); + let ifaces = config.scouting.multicast.interface().as_ref().map_or( + zenoh_config::defaults::scouting::multicast::interface, + |s| s.as_ref(), + ); let (stop_sender, stop_receiver) = flume::bounded::<()>(1); let ifaces = Runtime::get_interfaces(ifaces); if !ifaces.is_empty() { diff --git a/zenoh/src/value.rs b/zenoh/src/value.rs index 8fb53a0bc9..805541a936 100644 --- a/zenoh/src/value.rs +++ b/zenoh/src/value.rs @@ -20,7 +20,7 @@ use std::convert::TryFrom; #[cfg(feature = "shared-memory")] use std::sync::Arc; -use zenoh_cfg_properties::Properties; +use zenoh_collections::Properties; use zenoh_result::ZError; use crate::buffers::ZBuf; From c8d8bccd9b07c9f5324082604bde33a39eefb1a6 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 3 Mar 2023 19:51:53 +0100 Subject: [PATCH 052/203] Remove defmt dependency --- Cargo.lock | 60 ------------------- Cargo.toml | 1 - commons/zenoh-buffers/Cargo.toml | 2 - commons/zenoh-buffers/src/bbuf.rs | 1 - commons/zenoh-buffers/src/lib.rs | 3 - commons/zenoh-buffers/src/zbuf.rs | 4 -- commons/zenoh-buffers/src/zslice.rs | 7 --- commons/zenoh-codec/Cargo.toml | 4 -- commons/zenoh-collections/Cargo.toml | 2 - .../zenoh-collections/src/single_or_vec.rs | 2 - commons/zenoh-protocol/Cargo.toml | 2 - commons/zenoh-protocol/src/core/encoding.rs | 2 - commons/zenoh-protocol/src/core/endpoint.rs | 9 --- .../src/core/key_expr/borrowed.rs | 2 - .../src/core/key_expr/intersect/mod.rs | 2 - .../zenoh-protocol/src/core/key_expr/owned.rs | 1 - .../zenoh-protocol/src/core/key_expr/utils.rs | 1 - commons/zenoh-protocol/src/core/locator.rs | 1 - commons/zenoh-protocol/src/core/mod.rs | 7 --- commons/zenoh-protocol/src/core/whatami.rs | 2 - commons/zenoh-protocol/src/core/wire_expr.rs | 1 - commons/zenoh-protocol/src/scouting/hello.rs | 2 - commons/zenoh-protocol/src/scouting/mod.rs | 2 - commons/zenoh-protocol/src/scouting/scout.rs | 1 - commons/zenoh-protocol/src/transport/close.rs | 1 - .../zenoh-protocol/src/transport/fragment.rs | 2 - commons/zenoh-protocol/src/transport/frame.rs | 2 - commons/zenoh-protocol/src/transport/init.rs | 2 - commons/zenoh-protocol/src/transport/join.rs | 1 - .../zenoh-protocol/src/transport/keepalive.rs | 1 - commons/zenoh-protocol/src/transport/mod.rs | 4 -- commons/zenoh-protocol/src/transport/open.rs | 2 - commons/zenoh-protocol/src/zenoh/data.rs | 5 -- commons/zenoh-protocol/src/zenoh/declare.rs | 13 ---- commons/zenoh-protocol/src/zenoh/linkstate.rs | 2 - commons/zenoh-protocol/src/zenoh/mod.rs | 2 - commons/zenoh-protocol/src/zenoh/pull.rs | 1 - commons/zenoh-protocol/src/zenoh/query.rs | 4 -- commons/zenoh-protocol/src/zenoh/routing.rs | 1 - commons/zenoh-protocol/src/zenoh/unit.rs | 1 - commons/zenoh-result/Cargo.toml | 2 - commons/zenoh-result/src/lib.rs | 5 -- 42 files changed, 172 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99d60165b0..b01ecc6a3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -916,35 +916,6 @@ dependencies = [ "syn", ] -[[package]] -name = "defmt" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a0ae7494d9bff013d7b89471f4c424356a71e9752e0c78abe7e6c608a16bb3" -dependencies = [ - "bitflags", - "defmt-macros", -] - -[[package]] -name = "defmt-macros" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8500cbe4cca056412efce4215a63d0bc20492942aeee695f23b624a53e0a6854" -dependencies = [ - "defmt-parser", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "defmt-parser" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db23d29972d99baa3de2ee2ae3f104c10564a6d05a346eb3f4c4f2c0525a06e" - [[package]] name = "der" version = "0.6.1" @@ -2228,30 +2199,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -3331,7 +3278,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d291a7454d390b753ef68df8145da18367e32883ec2fa863959f0aefb915cdb" dependencies = [ - "defmt", "hex", "humantime", "lazy_static", @@ -3842,7 +3788,6 @@ dependencies = [ name = "zenoh-buffers" version = "0.7.0-rc" dependencies = [ - "defmt", "rand 0.8.5", "zenoh-collections", ] @@ -3864,9 +3809,6 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.7.0-rc" -dependencies = [ - "defmt", -] [[package]] name = "zenoh-config" @@ -4195,7 +4137,6 @@ name = "zenoh-protocol" version = "0.7.0-rc" dependencies = [ "const_format", - "defmt", "hex", "lazy_static", "rand 0.8.5", @@ -4213,7 +4154,6 @@ name = "zenoh-result" version = "0.7.0-rc" dependencies = [ "anyhow", - "defmt", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e4c87a3300..6d4e923e86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,7 +79,6 @@ clap = "3.2.23" const_format = { version = "0.2.30", default-features = false } crc = "3.0.0" criterion = "0.4.0" -defmt = { version = "0.3.2", features = ["alloc"] } derive_more = "0.99.17" derive-new = "0.5.9" env_logger = "0.10.0" diff --git a/commons/zenoh-buffers/Cargo.toml b/commons/zenoh-buffers/Cargo.toml index 70d2cea29e..3a96bb0b4a 100644 --- a/commons/zenoh-buffers/Cargo.toml +++ b/commons/zenoh-buffers/Cargo.toml @@ -26,9 +26,7 @@ description = "Internal crate for zenoh." # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] test = ["rand"] -defmt = ["dep:defmt", "zenoh-collections/defmt"] [dependencies] -defmt = { workspace = true, optional = true } rand = { workspace = true, optional = true } zenoh-collections = { path = "../zenoh-collections/", default-features = false } diff --git a/commons/zenoh-buffers/src/bbuf.rs b/commons/zenoh-buffers/src/bbuf.rs index 6945048e3c..96bfcd458f 100644 --- a/commons/zenoh-buffers/src/bbuf.rs +++ b/commons/zenoh-buffers/src/bbuf.rs @@ -20,7 +20,6 @@ use alloc::boxed::Box; use core::num::NonZeroUsize; #[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct BBuf { buffer: Box<[u8]>, len: usize, diff --git a/commons/zenoh-buffers/src/lib.rs b/commons/zenoh-buffers/src/lib.rs index 2fa603ce83..a3c2f72649 100644 --- a/commons/zenoh-buffers/src/lib.rs +++ b/commons/zenoh-buffers/src/lib.rs @@ -32,7 +32,6 @@ pub mod writer { use core::num::NonZeroUsize; #[derive(Debug, Clone, Copy)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DidntWrite; pub trait Writer { @@ -75,7 +74,6 @@ pub mod reader { use core::num::NonZeroUsize; #[derive(Debug, Clone, Copy)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DidntRead; pub trait Reader { @@ -116,7 +114,6 @@ pub mod reader { } #[derive(Debug, Clone, Copy)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DidntSiphon; pub trait SiphonableReader: Reader { diff --git a/commons/zenoh-buffers/src/zbuf.rs b/commons/zenoh-buffers/src/zbuf.rs index 3ea707c1bb..aabd34f9a3 100644 --- a/commons/zenoh-buffers/src/zbuf.rs +++ b/commons/zenoh-buffers/src/zbuf.rs @@ -25,7 +25,6 @@ fn get_mut_unchecked(arc: &mut Arc) -> &mut T { } #[derive(Debug, Clone, Default, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ZBuf { slices: SingleOrVec, } @@ -124,14 +123,12 @@ where // Reader #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ZBufPos { slice: usize, byte: usize, } #[derive(Debug, Clone)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ZBufReader<'a> { inner: &'a ZBuf, cursor: ZBufPos, @@ -349,7 +346,6 @@ impl Iterator for ZBufSliceIterator<'_, '_> { // Writer #[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ZBufWriter<'a> { inner: &'a mut ZBuf, cache: Arc>, diff --git a/commons/zenoh-buffers/src/zslice.rs b/commons/zenoh-buffers/src/zslice.rs index 5814498c2a..340a60e7ae 100644 --- a/commons/zenoh-buffers/src/zslice.rs +++ b/commons/zenoh-buffers/src/zslice.rs @@ -213,13 +213,6 @@ impl fmt::Debug for ZSlice { } } -#[cfg(feature = "defmt")] -impl defmt::Format for ZSlice { - fn format(&self, f: defmt::Formatter) { - defmt::write!(f, "{:02x}", self.as_slice()); - } -} - // From impls impl From> for ZSlice where diff --git a/commons/zenoh-codec/Cargo.toml b/commons/zenoh-codec/Cargo.toml index 161780ce32..f378aa1d4f 100644 --- a/commons/zenoh-codec/Cargo.toml +++ b/commons/zenoh-codec/Cargo.toml @@ -41,10 +41,6 @@ shared-memory = [ "zenoh-protocol/shared-memory" ] complete_n = ["zenoh-protocol/complete_n"] -defmt = [ - "zenoh-buffers/defmt", - "zenoh-protocol/defmt" -] [dependencies] serde = { workspace = true, features = ["alloc"] } diff --git a/commons/zenoh-collections/Cargo.toml b/commons/zenoh-collections/Cargo.toml index a4731aac20..4b36919f6d 100644 --- a/commons/zenoh-collections/Cargo.toml +++ b/commons/zenoh-collections/Cargo.toml @@ -31,7 +31,5 @@ description = "Internal crate for zenoh." [features] default = ["std"] std = [] -defmt = ["dep:defmt"] [dependencies] -defmt = { workspace = true, optional = true } diff --git a/commons/zenoh-collections/src/single_or_vec.rs b/commons/zenoh-collections/src/single_or_vec.rs index 2d5f1e88d0..77f729de9a 100644 --- a/commons/zenoh-collections/src/single_or_vec.rs +++ b/commons/zenoh-collections/src/single_or_vec.rs @@ -20,7 +20,6 @@ use core::{ }; #[derive(Clone, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] enum SingleOrVecInner { Single(T), Vec(Vec), @@ -82,7 +81,6 @@ where } #[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct SingleOrVec(SingleOrVecInner); impl SingleOrVec { diff --git a/commons/zenoh-protocol/Cargo.toml b/commons/zenoh-protocol/Cargo.toml index 18ab488b29..861d2d905d 100644 --- a/commons/zenoh-protocol/Cargo.toml +++ b/commons/zenoh-protocol/Cargo.toml @@ -37,11 +37,9 @@ std = [ test = ["rand", "zenoh-buffers/test"] shared-memory = ["std"] complete_n = [] -defmt = ["dep:defmt", "uhlc/defmt", "zenoh-buffers/defmt"] [dependencies] const_format = { workspace = true } -defmt = { workspace = true, optional = true } hex = { workspace = true, features = ["alloc"] } rand = { workspace = true, features = ["alloc", "getrandom"], optional = true } serde = { workspace = true, features = ["alloc"] } diff --git a/commons/zenoh-protocol/src/core/encoding.rs b/commons/zenoh-protocol/src/core/encoding.rs index 999e8993b8..eee6336736 100644 --- a/commons/zenoh-protocol/src/core/encoding.rs +++ b/commons/zenoh-protocol/src/core/encoding.rs @@ -44,7 +44,6 @@ mod consts { #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum KnownEncoding { Empty = 0, AppOctetStream = 1, @@ -126,7 +125,6 @@ impl AsRef for KnownEncoding { /// A zenoh encoding is a HTTP Mime type represented, for wire efficiency, /// as an integer prefix (that maps to a string) and a string suffix. #[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Encoding { Exact(KnownEncoding), WithSuffix(KnownEncoding, Cow<'static, str>), diff --git a/commons/zenoh-protocol/src/core/endpoint.rs b/commons/zenoh-protocol/src/core/endpoint.rs index d8401d07f6..7a5317b58b 100644 --- a/commons/zenoh-protocol/src/core/endpoint.rs +++ b/commons/zenoh-protocol/src/core/endpoint.rs @@ -126,7 +126,6 @@ impl Parameters { // Protocol #[repr(transparent)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Protocol<'a>(pub(super) &'a str); impl<'a> Protocol<'a> { @@ -149,7 +148,6 @@ impl fmt::Display for Protocol<'_> { #[repr(transparent)] #[derive(Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ProtocolMut<'a>(&'a mut EndPoint); impl<'a> ProtocolMut<'a> { @@ -180,7 +178,6 @@ impl fmt::Display for ProtocolMut<'_> { // Address #[repr(transparent)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Address<'a>(pub(super) &'a str); impl<'a> Address<'a> { @@ -203,7 +200,6 @@ impl fmt::Display for Address<'_> { #[repr(transparent)] #[derive(Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct AddressMut<'a>(&'a mut EndPoint); impl<'a> AddressMut<'a> { @@ -234,7 +230,6 @@ impl fmt::Display for AddressMut<'_> { // Metadata #[repr(transparent)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Metadata<'a>(pub(super) &'a str); impl<'a> Metadata<'a> { @@ -269,7 +264,6 @@ impl fmt::Display for Metadata<'_> { #[repr(transparent)] #[derive(Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct MetadataMut<'a>(&'a mut EndPoint); impl<'a> MetadataMut<'a> { @@ -337,7 +331,6 @@ impl fmt::Display for MetadataMut<'_> { // Config #[repr(transparent)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Config<'a>(pub(super) &'a str); impl<'a> Config<'a> { @@ -372,7 +365,6 @@ impl fmt::Display for Config<'_> { #[repr(transparent)] #[derive(Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ConfigMut<'a>(&'a mut EndPoint); impl<'a> ConfigMut<'a> { @@ -438,7 +430,6 @@ impl fmt::Display for ConfigMut<'_> { } /// A `String` that respects the [`EndPoint`] canon form: `#`, such that `` is a valid [`Locator`] `` is of the form `=;...;=` where keys are alphabetically sorted. #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[serde(into = "String")] #[serde(try_from = "String")] pub struct EndPoint { diff --git a/commons/zenoh-protocol/src/core/key_expr/borrowed.rs b/commons/zenoh-protocol/src/core/key_expr/borrowed.rs index 2c4592f218..8bd6dc5720 100644 --- a/commons/zenoh-protocol/src/core/key_expr/borrowed.rs +++ b/commons/zenoh-protocol/src/core/key_expr/borrowed.rs @@ -45,7 +45,6 @@ use zenoh_result::{bail, Error as ZError, ZResult}; #[allow(non_camel_case_types)] #[repr(transparent)] #[derive(PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct keyexpr(str); impl keyexpr { @@ -308,7 +307,6 @@ impl Div for &keyexpr { /// /// You can check for intersection with `level >= SetIntersecionLevel::Intersection` and for inclusion with `level >= SetIntersectionLevel::Includes`. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SetIntersectionLevel { Disjoint, Intersects, diff --git a/commons/zenoh-protocol/src/core/key_expr/intersect/mod.rs b/commons/zenoh-protocol/src/core/key_expr/intersect/mod.rs index 74b3ba8553..3270ce279d 100644 --- a/commons/zenoh-protocol/src/core/key_expr/intersect/mod.rs +++ b/commons/zenoh-protocol/src/core/key_expr/intersect/mod.rs @@ -41,11 +41,9 @@ pub(crate) mod restiction { #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct NoBigWilds(pub T); #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct NoSubWilds(pub T); impl Deref for NoBigWilds { diff --git a/commons/zenoh-protocol/src/core/key_expr/owned.rs b/commons/zenoh-protocol/src/core/key_expr/owned.rs index 0d20f92f4d..3735d68a61 100644 --- a/commons/zenoh-protocol/src/core/key_expr/owned.rs +++ b/commons/zenoh-protocol/src/core/key_expr/owned.rs @@ -32,7 +32,6 @@ use core::{ /// /// See [`keyexpr`](super::borrowed::keyexpr). #[derive(Clone, PartialEq, Eq, Hash, serde::Deserialize)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[serde(try_from = "String")] pub struct OwnedKeyExpr(pub(crate) Arc); impl serde::Serialize for OwnedKeyExpr { diff --git a/commons/zenoh-protocol/src/core/key_expr/utils.rs b/commons/zenoh-protocol/src/core/key_expr/utils.rs index 4676f74b7f..7444f2f893 100644 --- a/commons/zenoh-protocol/src/core/key_expr/utils.rs +++ b/commons/zenoh-protocol/src/core/key_expr/utils.rs @@ -31,7 +31,6 @@ impl Writer { } #[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Splitter<'a, S: ?Sized, D: ?Sized> { s: Option<&'a S>, d: &'a D, diff --git a/commons/zenoh-protocol/src/core/locator.rs b/commons/zenoh-protocol/src/core/locator.rs index 3dfb97b6c3..898f891c5b 100644 --- a/commons/zenoh-protocol/src/core/locator.rs +++ b/commons/zenoh-protocol/src/core/locator.rs @@ -20,7 +20,6 @@ use zenoh_result::{Error as ZError, ZResult}; /// A `String` that respects the [`Locator`] canon form: `/
[?]`, /// such that `` is of the form `=;...;=` where keys are alphabetically sorted. #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[serde(into = "String")] #[serde(try_from = "String")] pub struct Locator(pub(super) EndPoint); diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index 1617237399..83bdcf26c6 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -60,7 +60,6 @@ pub mod resolution; pub use resolution::*; #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Property { pub key: ZInt, pub value: Vec, @@ -68,7 +67,6 @@ pub struct Property { /// The global unique id of a zenoh peer. #[derive(Clone, Copy, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ZenohId(uhlc::ID); impl ZenohId { @@ -108,7 +106,6 @@ impl From for ZenohId { // Mimics uhlc::SizeError, #[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct SizeError(usize); #[cfg(feature = "std")] @@ -291,7 +288,6 @@ impl<'de> serde::Deserialize<'de> for ZenohId { /// The kind of congestion control. #[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u8)] pub enum CongestionControl { Block, @@ -305,7 +301,6 @@ impl Default for CongestionControl { } #[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u8)] pub enum Reliability { BestEffort, @@ -319,14 +314,12 @@ impl Default for Reliability { } #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Channel { pub priority: Priority, pub reliability: Reliability, } #[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u8)] pub enum Priority { Control = 0, diff --git a/commons/zenoh-protocol/src/core/whatami.rs b/commons/zenoh-protocol/src/core/whatami.rs index 2dcc422789..407f7ff2d8 100644 --- a/commons/zenoh-protocol/src/core/whatami.rs +++ b/commons/zenoh-protocol/src/core/whatami.rs @@ -22,7 +22,6 @@ const WAI_STR_C: &str = "client"; #[repr(u8)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum WhatAmI { Router = 0b001, Peer = 0b010, @@ -95,7 +94,6 @@ impl From for u8 { #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct WhatAmIMatcher(NonZeroU8); impl WhatAmIMatcher { diff --git a/commons/zenoh-protocol/src/core/wire_expr.rs b/commons/zenoh-protocol/src/core/wire_expr.rs index 3ff71a455b..546710d46a 100644 --- a/commons/zenoh-protocol/src/core/wire_expr.rs +++ b/commons/zenoh-protocol/src/core/wire_expr.rs @@ -51,7 +51,6 @@ pub const EMPTY_EXPR_ID: ExprId = 0; // +---------------+ // #[derive(PartialEq, Eq, Hash, Clone)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct WireExpr<'a> { pub scope: ExprId, // 0 marks global scope pub suffix: Cow<'a, str>, diff --git a/commons/zenoh-protocol/src/scouting/hello.rs b/commons/zenoh-protocol/src/scouting/hello.rs index 92799c7cf4..ab9b7d710f 100644 --- a/commons/zenoh-protocol/src/scouting/hello.rs +++ b/commons/zenoh-protocol/src/scouting/hello.rs @@ -99,8 +99,6 @@ pub mod flag { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct Hello { pub version: u8, pub whatami: WhatAmI, diff --git a/commons/zenoh-protocol/src/scouting/mod.rs b/commons/zenoh-protocol/src/scouting/mod.rs index e43323339a..6a5606d2a2 100644 --- a/commons/zenoh-protocol/src/scouting/mod.rs +++ b/commons/zenoh-protocol/src/scouting/mod.rs @@ -25,14 +25,12 @@ pub mod id { // Zenoh messages at scouting level #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ScoutingBody { Scout(Scout), Hello(Hello), } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ScoutingMessage { pub body: ScoutingBody, #[cfg(feature = "stats")] diff --git a/commons/zenoh-protocol/src/scouting/scout.rs b/commons/zenoh-protocol/src/scouting/scout.rs index 4ef1205b21..660dbc599f 100644 --- a/commons/zenoh-protocol/src/scouting/scout.rs +++ b/commons/zenoh-protocol/src/scouting/scout.rs @@ -72,7 +72,6 @@ pub mod flag { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Scout { pub version: u8, pub what: WhatAmIMatcher, diff --git a/commons/zenoh-protocol/src/transport/close.rs b/commons/zenoh-protocol/src/transport/close.rs index cc3b1f5223..c0f362945c 100644 --- a/commons/zenoh-protocol/src/transport/close.rs +++ b/commons/zenoh-protocol/src/transport/close.rs @@ -80,7 +80,6 @@ pub fn reason_to_str(reason: u8) -> &'static str { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Close { pub reason: u8, pub session: bool, diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs index de874dcea7..e3d6333e07 100644 --- a/commons/zenoh-protocol/src/transport/fragment.rs +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -67,7 +67,6 @@ pub mod flag { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Fragment { pub reliability: Reliability, pub more: bool, @@ -112,7 +111,6 @@ impl Fragment { // FragmentHeader #[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FragmentHeader { pub reliability: Reliability, pub more: bool, diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index e813852cb7..4cb1e6f13c 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -70,7 +70,6 @@ pub mod flag { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Frame { pub reliability: Reliability, pub sn: ZInt, @@ -145,7 +144,6 @@ impl Frame { // FrameHeader #[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FrameHeader { pub reliability: Reliability, pub sn: ZInt, diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index c5e52257ae..871f33e50b 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -104,7 +104,6 @@ pub mod flag { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct InitSyn { pub version: u8, pub whatami: WhatAmI, @@ -168,7 +167,6 @@ impl InitSyn { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct InitAck { pub version: u8, pub whatami: WhatAmI, diff --git a/commons/zenoh-protocol/src/transport/join.rs b/commons/zenoh-protocol/src/transport/join.rs index 2f4d8ab6d0..96fdb379f1 100644 --- a/commons/zenoh-protocol/src/transport/join.rs +++ b/commons/zenoh-protocol/src/transport/join.rs @@ -56,7 +56,6 @@ use core::time::Duration; /// /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Join { pub version: u8, pub whatami: WhatAmI, diff --git a/commons/zenoh-protocol/src/transport/keepalive.rs b/commons/zenoh-protocol/src/transport/keepalive.rs index 8432fa5342..e1f673e925 100644 --- a/commons/zenoh-protocol/src/transport/keepalive.rs +++ b/commons/zenoh-protocol/src/transport/keepalive.rs @@ -82,7 +82,6 @@ pub mod flag { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct KeepAlive; impl KeepAlive { diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 564f5028b0..56e66a2ae2 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -40,7 +40,6 @@ pub mod id { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ConduitSnList { Plain(ConduitSn), QoS(Box<[ConduitSn; Priority::NUM]>), @@ -79,7 +78,6 @@ impl fmt::Display for ConduitSnList { /// The kind of reliability. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ConduitSn { pub reliable: ZInt, pub best_effort: ZInt, @@ -87,7 +85,6 @@ pub struct ConduitSn { // Zenoh messages at zenoh-transport level #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum TransportBody { InitSyn(InitSyn), InitAck(InitAck), @@ -101,7 +98,6 @@ pub enum TransportBody { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct TransportMessage { pub body: TransportBody, #[cfg(feature = "stats")] diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 0c469d68a5..311c3e1dac 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -73,7 +73,6 @@ pub mod flag { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct OpenSyn { pub lease: Duration, pub initial_sn: ZInt, @@ -138,7 +137,6 @@ impl OpenSyn { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct OpenAck { pub lease: Duration, pub initial_sn: ZInt, diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs index 57914bd6f4..383cdac30e 100644 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ b/commons/zenoh-protocol/src/zenoh/data.rs @@ -18,7 +18,6 @@ use zenoh_buffers::ZBuf; /// The kind of a `Sample`. #[repr(u8)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SampleKind { /// if the `Sample` was issued by a `put` operation. Put = 0, @@ -73,12 +72,10 @@ impl TryFrom for SampleKind { /// - if F==1 then the message is a REPLY_FINAL /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ReplierInfo { pub id: ZenohId, } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ReplyContext { pub qid: ZInt, pub replier: Option, @@ -152,7 +149,6 @@ impl ReplyContext { /// /// ``` #[derive(Debug, Clone, PartialEq, Eq, Default)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DataInfo { #[cfg(feature = "shared-memory")] pub sliced: bool, @@ -210,7 +206,6 @@ impl DataInfo { /// /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Data { pub key: WireExpr<'static>, pub data_info: Option, diff --git a/commons/zenoh-protocol/src/zenoh/declare.rs b/commons/zenoh-protocol/src/zenoh/declare.rs index e463f51184..e604545d70 100644 --- a/commons/zenoh-protocol/src/zenoh/declare.rs +++ b/commons/zenoh-protocol/src/zenoh/declare.rs @@ -28,7 +28,6 @@ use alloc::vec::Vec; /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Declare { pub declarations: Vec, } @@ -50,7 +49,6 @@ impl Declare { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Declaration { Resource(Resource), ForgetResource(ForgetResource), @@ -94,7 +92,6 @@ impl Declaration { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Resource { pub expr_id: ZInt, pub key: WireExpr<'static>, @@ -123,7 +120,6 @@ impl Resource { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ForgetResource { pub expr_id: ZInt, } @@ -150,7 +146,6 @@ impl ForgetResource { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Publisher { pub key: WireExpr<'static>, } @@ -173,7 +168,6 @@ impl Publisher { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ForgetPublisher { pub key: WireExpr<'static>, } @@ -189,7 +183,6 @@ impl ForgetPublisher { /// The subscription mode. #[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u8)] pub enum SubMode { Push, @@ -204,7 +197,6 @@ impl Default for SubMode { } #[derive(Debug, Clone, PartialEq, Eq, Default)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct SubInfo { pub reliability: Reliability, pub mode: SubMode, @@ -221,7 +213,6 @@ pub struct SubInfo { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Subscriber { pub key: WireExpr<'static>, pub info: SubInfo, @@ -260,7 +251,6 @@ impl Subscriber { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ForgetSubscriber { pub key: WireExpr<'static>, } @@ -275,7 +265,6 @@ impl ForgetSubscriber { } #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct QueryableInfo { pub complete: ZInt, // Default 0: incomplete pub distance: ZInt, // Default 0: no distance @@ -292,7 +281,6 @@ pub struct QueryableInfo { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Queryable { pub key: WireExpr<'static>, pub info: QueryableInfo, @@ -323,7 +311,6 @@ impl Queryable { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ForgetQueryable { pub key: WireExpr<'static>, } diff --git a/commons/zenoh-protocol/src/zenoh/linkstate.rs b/commons/zenoh-protocol/src/zenoh/linkstate.rs index 70c7e64e4a..2e60f80d27 100644 --- a/commons/zenoh-protocol/src/zenoh/linkstate.rs +++ b/commons/zenoh-protocol/src/zenoh/linkstate.rs @@ -31,7 +31,6 @@ use alloc::vec::Vec; // ~ [links] ~ // +---------------+ #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct LinkState { pub psid: ZInt, pub sn: ZInt, @@ -91,7 +90,6 @@ impl LinkState { // ~ [link_states] ~ // +---------------+ #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct LinkStateList { pub link_states: Vec, } diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index 04b92ca85f..39af2dd944 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -188,7 +188,6 @@ pub mod zmsg { // Zenoh messages at zenoh level #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ZenohBody { Data(Data), Unit(Unit), @@ -199,7 +198,6 @@ pub enum ZenohBody { } #[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ZenohMessage { pub body: ZenohBody, pub channel: Channel, diff --git a/commons/zenoh-protocol/src/zenoh/pull.rs b/commons/zenoh-protocol/src/zenoh/pull.rs index 83f2a988f2..ba5c260005 100644 --- a/commons/zenoh-protocol/src/zenoh/pull.rs +++ b/commons/zenoh-protocol/src/zenoh/pull.rs @@ -28,7 +28,6 @@ use crate::core::{WireExpr, ZInt}; /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Pull { pub key: WireExpr<'static>, pub pull_id: ZInt, diff --git a/commons/zenoh-protocol/src/zenoh/query.rs b/commons/zenoh-protocol/src/zenoh/query.rs index a87d037c64..e3014d81d8 100644 --- a/commons/zenoh-protocol/src/zenoh/query.rs +++ b/commons/zenoh-protocol/src/zenoh/query.rs @@ -20,7 +20,6 @@ use zenoh_buffers::ZBuf; /// The kind of consolidation. #[derive(Debug, Clone, PartialEq, Eq, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ConsolidationMode { /// No consolidation applied: multiple samples may be received for the same key-timestamp. None, @@ -38,7 +37,6 @@ pub enum ConsolidationMode { /// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum QueryTarget { BestMatching, All, @@ -66,7 +64,6 @@ impl Default for QueryTarget { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq, Default)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct QueryBody { pub data_info: DataInfo, pub payload: ZBuf, @@ -109,7 +106,6 @@ impl QueryBody { /// ~ QueryBody ~ if B==1 /// +---------------+ #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Query { pub key: WireExpr<'static>, pub parameters: String, diff --git a/commons/zenoh-protocol/src/zenoh/routing.rs b/commons/zenoh-protocol/src/zenoh/routing.rs index 3f37ec8f7a..47d3208d18 100644 --- a/commons/zenoh-protocol/src/zenoh/routing.rs +++ b/commons/zenoh-protocol/src/zenoh/routing.rs @@ -27,7 +27,6 @@ use crate::core::ZInt; /// +---------------+ /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct RoutingContext { pub tree_id: ZInt, } diff --git a/commons/zenoh-protocol/src/zenoh/unit.rs b/commons/zenoh-protocol/src/zenoh/unit.rs index 66cc7ac5f5..05dd75e232 100644 --- a/commons/zenoh-protocol/src/zenoh/unit.rs +++ b/commons/zenoh-protocol/src/zenoh/unit.rs @@ -24,7 +24,6 @@ use crate::core::CongestionControl; /// /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Unit { pub congestion_control: CongestionControl, pub reply_context: Option, diff --git a/commons/zenoh-result/Cargo.toml b/commons/zenoh-result/Cargo.toml index 803828a2fc..5443d6c81b 100644 --- a/commons/zenoh-result/Cargo.toml +++ b/commons/zenoh-result/Cargo.toml @@ -27,8 +27,6 @@ description = "Internal crate for zenoh." [features] default = ["std"] std = ["anyhow/std"] -defmt = ["dep:defmt"] [dependencies] anyhow = { workspace = true } -defmt = { workspace = true, optional = true } diff --git a/commons/zenoh-result/src/lib.rs b/commons/zenoh-result/src/lib.rs index 880a0ca2ac..06f1fa9be1 100644 --- a/commons/zenoh-result/src/lib.rs +++ b/commons/zenoh-result/src/lib.rs @@ -86,7 +86,6 @@ pub type ZResult = core::result::Result; #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct NegativeI8(i8); impl NegativeI8 { @@ -102,14 +101,11 @@ impl NegativeI8 { pub const MIN: Self = Self::new(i8::MIN); } -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ZError { - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] error: AnyError, file: &'static str, line: u32, errno: NegativeI8, - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] source: Option, } @@ -177,7 +173,6 @@ impl From for Error { // +----------+ #[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ShmError(pub ZError); #[cfg(feature = "std")] From 7f83eb41b743c0293c95007f6cc9fcde1193d3b3 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 3 Mar 2023 20:05:38 +0100 Subject: [PATCH 053/203] zenoh-link-commons is no_std --- io/zenoh-link-commons/src/lib.rs | 17 +++- io/zenoh-link-commons/src/multicast.rs | 129 +++++++++++++++++++++++++ io/zenoh-link-commons/src/unicast.rs | 4 +- 3 files changed, 143 insertions(+), 7 deletions(-) diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index 3fe8cc16a0..3bb0879f2b 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -17,20 +17,27 @@ //! This crate is intended for Zenoh's internal use. //! //! [Click here for Zenoh's documentation](../zenoh/index.html) +#![no_std] extern crate alloc; +mod multicast; mod unicast; +use alloc::{ + borrow::{Cow, ToOwned}, + boxed::Box, + string::String, + sync::Arc, + vec::Vec, +}; use async_trait::async_trait; -use serde::Serialize; -use std::{ - borrow::Cow, +use core::{ cmp::PartialEq, fmt, hash::{Hash, Hasher}, ops::Deref, - sync::Arc, }; +use serde::Serialize; pub use unicast::*; use zenoh_buffers::{ reader::{HasReader, Reader}, @@ -139,7 +146,7 @@ pub trait LinkMulticastTrait: Send + Sync { impl LinkMulticast { pub async fn write_transport_message(&self, msg: &TransportMessage) -> ZResult { // Create the buffer for serializing the message - let mut buff = vec![]; + let mut buff = Vec::new(); let mut writer = buff.writer(); let codec = Zenoh080::new(); codec diff --git a/io/zenoh-link-commons/src/multicast.rs b/io/zenoh-link-commons/src/multicast.rs index e69de29bb2..824bb0e800 100644 --- a/io/zenoh-link-commons/src/multicast.rs +++ b/io/zenoh-link-commons/src/multicast.rs @@ -0,0 +1,129 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; +use async_trait::async_trait; +use core::{ + fmt, + hash::{Hash, Hasher}, + ops::Deref, +}; +use zenoh_buffers::{reader::HasReader, writer::HasWriter}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_protocol::{ + core::{EndPoint, Locator}, + transport::TransportMessage, +}; +use zenoh_result::{zerror, ZResult}; +#[async_trait] +pub trait LinkManagerMulticastTrait: Send + Sync { + async fn new_link(&self, endpoint: &EndPoint) -> ZResult; +} + +pub type LinkManagerMulticast = Arc; + +#[derive(Clone)] +pub struct LinkMulticast(pub Arc); + +#[async_trait] +pub trait LinkMulticastTrait: Send + Sync { + fn get_mtu(&self) -> u16; + fn get_src(&self) -> &Locator; + fn get_dst(&self) -> &Locator; + fn is_reliable(&self) -> bool; + async fn write(&self, buffer: &[u8]) -> ZResult; + async fn write_all(&self, buffer: &[u8]) -> ZResult<()>; + async fn read<'a>(&'a self, buffer: &mut [u8]) -> ZResult<(usize, Cow<'a, Locator>)>; + async fn close(&self) -> ZResult<()>; +} + +impl LinkMulticast { + pub async fn send(&self, msg: &TransportMessage) -> ZResult { + // Create the buffer for serializing the message + let mut buff = Vec::new(); + + let codec = Zenoh080::new(); + let mut writer = buff.writer(); + + codec + .write(&mut writer, msg) + .map_err(|_| zerror!("Encoding error on link: {}", self))?; + + // Send the message on the link + self.0.write_all(buff.as_slice()).await?; + + Ok(buff.len()) + } + + pub async fn recv(&self) -> ZResult<(TransportMessage, Locator)> { + // Read the message + let mut buffer = zenoh_buffers::vec::uninit(self.get_mtu() as usize); + let (n, locator) = self.read(&mut buffer).await?; + buffer.truncate(n); + + let codec = Zenoh080::new(); + let mut reader = buffer.reader(); + + let msg: TransportMessage = codec + .read(&mut reader) + .map_err(|_| zerror!("Invalid Message: Decoding error on link: {}", self))?; + + Ok((msg, locator.into_owned())) + } +} + +impl Deref for LinkMulticast { + type Target = Arc; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Eq for LinkMulticast {} + +impl PartialEq for LinkMulticast { + fn eq(&self, other: &Self) -> bool { + self.get_src() == other.get_src() && self.get_dst() == other.get_dst() + } +} + +impl Hash for LinkMulticast { + fn hash(&self, state: &mut H) { + self.get_src().hash(state); + self.get_dst().hash(state); + } +} + +impl fmt::Display for LinkMulticast { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} => {}", self.get_src(), self.get_dst()) + } +} + +impl fmt::Debug for LinkMulticast { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Link") + .field("src", &self.get_src()) + .field("dst", &self.get_dst()) + .field("mtu", &self.get_mtu()) + .field("is_reliable", &self.is_reliable()) + .finish() + } +} + +impl From> for LinkMulticast { + fn from(link: Arc) -> LinkMulticast { + LinkMulticast(link) + } +} diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index ab16515ec3..3279f63486 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use alloc::sync::Arc; +use alloc::{boxed::Box, sync::Arc, vec::Vec}; use async_trait::async_trait; use core::{ convert::TryFrom, @@ -72,7 +72,7 @@ impl LinkUnicast { const ERR: &str = "Write error on link: "; // Create the buffer for serializing the message - let mut buff = vec![]; + let mut buff = Vec::new(); let mut writer = buff.writer(); let codec = Zenoh080::new(); From dd6e86576df3fa613631bc589cb3b935fb5363f0 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 6 Mar 2023 09:43:55 +0100 Subject: [PATCH 054/203] Feature gate when shared-memory is disabled --- .../src/unicast/establishment/accept.rs | 31 +++++++++++++---- .../src/unicast/establishment/cookie.rs | 5 +++ .../src/unicast/establishment/open.rs | 34 +++++++++++++++---- io/zenoh-transport/src/unicast/manager.rs | 5 ++- io/zenoh-transport/src/unicast/rx.rs | 4 ++- io/zenoh-transport/src/unicast/tx.rs | 6 +++- 6 files changed, 69 insertions(+), 16 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 0674543d72..902f9096a8 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -11,13 +11,12 @@ // Contributors: // ZettaScale Zenoh Team, // +#[cfg(feature = "shared-memory")] +use crate::unicast::shm::Challenge; use crate::{ - unicast::{ - establishment::{ - close_link, compute_sn, ext, finalize_transport, AcceptFsm, Cookie, InputFinalize, - Zenoh080Cookie, - }, - shm::Challenge, + unicast::establishment::{ + close_link, compute_sn, ext, finalize_transport, AcceptFsm, Cookie, InputFinalize, + Zenoh080Cookie, }, TransportConfigUnicast, TransportManager, }; @@ -49,6 +48,7 @@ struct StateZenoh { struct State { zenoh: StateZenoh, ext_qos: ext::qos::State, + #[cfg(feature = "shared-memory")] ext_shm: ext::shm::State, } @@ -59,6 +59,7 @@ struct RecvInitSynIn { struct RecvInitSynOut { other_zid: ZenohId, other_whatami: WhatAmI, + #[cfg(feature = "shared-memory")] ext_shm: Challenge, } @@ -69,6 +70,7 @@ struct SendInitAckIn { mine_whatami: WhatAmI, other_zid: ZenohId, other_whatami: WhatAmI, + #[cfg(feature = "shared-memory")] ext_shm: Challenge, } struct SendInitAckOut { @@ -102,6 +104,7 @@ struct AcceptLink<'a> { prng: &'a Mutex, cipher: &'a BlockCipher, ext_qos: ext::qos::QoS, + #[cfg(feature = "shared-memory")] ext_shm: ext::shm::Shm<'a>, } @@ -172,6 +175,7 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm + #[cfg(feature = "shared-memory")] let ext_shm = self .ext_shm .recv_init_syn((&mut state.ext_shm, init_syn.ext_shm)) @@ -181,6 +185,7 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { let output = RecvInitSynOut { other_whatami: init_syn.whatami, other_zid: init_syn.zid, + #[cfg(feature = "shared-memory")] ext_shm, }; Ok(output) @@ -202,11 +207,14 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm + #[cfg(feature = "shared-memory")] let ext_shm = self .ext_shm .send_init_ack((&mut state.ext_shm, input.ext_shm)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + #[cfg(not(feature = "shared-memory"))] + let ext_shm = None; // Create the cookie let cookie_nonce: ZInt = zasynclock!(self.prng).gen(); @@ -217,6 +225,7 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { batch_size: state.zenoh.batch_size, nonce: cookie_nonce, ext_qos: state.ext_qos, + #[cfg(feature = "shared-memory")] ext_shm: state.ext_shm, // properties: EstablishmentProperties::new(), }; @@ -325,6 +334,7 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { resolution: cookie.resolution, }, ext_qos: cookie.ext_qos, + #[cfg(feature = "shared-memory")] ext_shm: cookie.ext_shm, }; @@ -359,11 +369,14 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm + #[cfg(feature = "shared-memory")] let ext_shm = self .ext_shm .send_open_ack(&mut state.ext_shm) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + #[cfg(not(feature = "shared-memory"))] + let ext_shm = None; // Build OpenAck message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); @@ -388,6 +401,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) prng: &manager.prng, cipher: &manager.cipher, ext_qos: ext::qos::QoS::new(), + #[cfg(feature = "shared-memory")] ext_shm: ext::shm::Shm::new(&manager.state.unicast.shm), }; @@ -412,6 +426,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) resolution: manager.config.resolution, }, ext_qos: ext::qos::State::new(manager.config.unicast.is_qos), + #[cfg(feature = "shared-memory")] ext_shm: ext::shm::State::new(manager.config.unicast.is_shm), }; @@ -429,6 +444,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) mine_whatami: manager.config.whatami, other_zid: isyn_out.other_zid, other_whatami: isyn_out.other_whatami, + #[cfg(feature = "shared-memory")] ext_shm: isyn_out.ext_shm, }; step!(fsm.send_init_ack((&mut state, iack_in)).await) @@ -455,7 +471,10 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), tx_initial_sn: oack_out.open_ack.initial_sn, is_qos: state.ext_qos.is_qos(), + #[cfg(feature = "shared-memory")] is_shm: state.ext_shm.is_shm(), + #[cfg(not(feature = "shared-memory"))] + is_shm: false, }; let transport = step!(manager .init_transport_unicast(config) diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index be603d2d0c..29ff627ce3 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -31,6 +31,7 @@ pub(crate) struct Cookie { pub(crate) nonce: ZInt, // Extensions pub(crate) ext_qos: ext::qos::State, + #[cfg(feature = "shared-memory")] pub(crate) ext_shm: ext::shm::State, // pub properties: EstablishmentProperties, // @TODO } @@ -50,6 +51,7 @@ where self.write(&mut *writer, x.nonce)?; // Extensions self.write(&mut *writer, &x.ext_qos)?; + #[cfg(feature = "shared-memory")] self.write(&mut *writer, &x.ext_shm)?; // self.write(&mut *writer, x.properties.as_slice())?; @@ -73,6 +75,7 @@ where let nonce: ZInt = self.read(&mut *reader)?; // Extensions let ext_qos: ext::qos::State = self.read(&mut *reader)?; + #[cfg(feature = "shared-memory")] let ext_shm: ext::shm::State = self.read(&mut *reader)?; // let mut ps: Vec = self.read(&mut *reader)?; // let mut properties = EstablishmentProperties::new(); @@ -87,6 +90,7 @@ where batch_size, nonce, ext_qos, + #[cfg(feature = "shared-memory")] ext_shm, // properties, }; @@ -151,6 +155,7 @@ impl Cookie { batch_size: rng.gen(), nonce: rng.gen(), ext_qos: ext::qos::State::new(rng.gen_bool(0.5)), + #[cfg(feature = "shared-memory")] ext_shm: ext::shm::State::new(rng.gen_bool(0.5)), // properties: EstablishmentProperties::rand(), } diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index ac4e7d495e..248b531802 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -11,10 +11,11 @@ // Contributors: // ZettaScale Zenoh Team, // +#[cfg(feature = "shared-memory")] +use crate::unicast::shm::Challenge; use crate::{ - unicast::{ - establishment::{close_link, compute_sn, ext, finalize_transport, InputFinalize, OpenFsm}, - shm::Challenge, + unicast::establishment::{ + close_link, compute_sn, ext, finalize_transport, InputFinalize, OpenFsm, }, TransportConfigUnicast, TransportManager, TransportUnicast, }; @@ -38,6 +39,7 @@ struct StateZenoh { struct State { zenoh: StateZenoh, ext_qos: ext::qos::State, + #[cfg(feature = "shared-memory")] ext_shm: ext::shm::State, } @@ -54,6 +56,7 @@ struct RecvInitAckOut { other_zid: ZenohId, other_whatami: WhatAmI, other_cookie: ZSlice, + #[cfg(feature = "shared-memory")] ext_shm: Challenge, } @@ -63,6 +66,7 @@ struct SendOpenSynIn { mine_lease: Duration, other_zid: ZenohId, other_cookie: ZSlice, + #[cfg(feature = "shared-memory")] ext_shm: Challenge, } @@ -80,6 +84,7 @@ struct RecvOpenAckOut { struct OpenLink<'a> { link: &'a LinkUnicast, ext_qos: ext::qos::QoS, + #[cfg(feature = "shared-memory")] ext_shm: ext::shm::Shm<'a>, } @@ -96,18 +101,21 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { let (state, input) = input; // Extension QoS - let qos_mine_ext = self + let ext_qos = self .ext_qos .send_init_syn(&state.ext_qos) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm - let shm_mine_ext = self + #[cfg(feature = "shared-memory")] + let ext_shm = self .ext_shm .send_init_syn(&state.ext_shm) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + #[cfg(not(feature = "shared-memory"))] + let ext_shm = None; let msg: TransportMessage = InitSyn { version: input.mine_version, @@ -115,8 +123,8 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { zid: input.mine_zid, batch_size: state.zenoh.batch_size, resolution: state.zenoh.resolution, - ext_qos: qos_mine_ext, - ext_shm: shm_mine_ext, + ext_qos, + ext_shm, ext_auth: None, // @TODO } .into(); @@ -216,6 +224,7 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm + #[cfg(feature = "shared-memory")] let shm_challenge = self .ext_shm .recv_init_ack((&mut state.ext_shm, init_ack.ext_shm)) @@ -226,6 +235,7 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { other_zid: init_ack.zid, other_whatami: init_ack.whatami, other_cookie: init_ack.cookie, + #[cfg(feature = "shared-memory")] ext_shm: shm_challenge, }; Ok(output) @@ -247,11 +257,14 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm + #[cfg(feature = "shared-memory")] let ext_shm = self .ext_shm .send_open_syn((&state.ext_shm, input.ext_shm)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + #[cfg(not(feature = "shared-memory"))] + let ext_shm = None; // Build and send an OpenSyn message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); @@ -319,6 +332,7 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm + #[cfg(feature = "shared-memory")] self.ext_shm .recv_open_ack((&mut state.ext_shm, open_ack.ext_shm)) .await @@ -339,6 +353,7 @@ pub(crate) async fn open_link( let fsm = OpenLink { link, ext_qos: ext::qos::QoS::new(), + #[cfg(feature = "shared-memory")] ext_shm: ext::shm::Shm::new(&manager.state.unicast.shm), }; @@ -361,6 +376,7 @@ pub(crate) async fn open_link( resolution: manager.config.resolution, }, ext_qos: ext::qos::State::new(manager.config.unicast.is_qos), + #[cfg(feature = "shared-memory")] ext_shm: ext::shm::State::new(manager.config.unicast.is_shm), }; @@ -379,6 +395,7 @@ pub(crate) async fn open_link( other_zid: iack_out.other_zid, mine_lease: manager.config.unicast.lease, other_cookie: iack_out.other_cookie, + #[cfg(feature = "shared-memory")] ext_shm: iack_out.ext_shm, }; let osyn_out = step!(fsm.send_open_syn((&mut state, osyn_in)).await); @@ -392,7 +409,10 @@ pub(crate) async fn open_link( sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), tx_initial_sn: osyn_out.mine_initial_sn, is_qos: state.ext_qos.is_qos(), + #[cfg(feature = "shared-memory")] is_shm: state.ext_shm.is_shm(), + #[cfg(not(feature = "shared-memory"))] + is_shm: false, }; let transport = step!(manager .init_transport_unicast(config) diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index c2ee61444e..98cecdc386 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -19,7 +19,9 @@ use crate::{ }; use async_std::{prelude::FutureExt, sync::Mutex, task}; use std::{collections::HashMap, sync::Arc, time::Duration}; -use zenoh_config::{Config, LinkTxConf, QoSConf, SharedMemoryConf, TransportUnicastConf}; +#[cfg(feature = "shared-memory")] +use zenoh_config::SharedMemoryConf; +use zenoh_config::{Config, LinkTxConf, QoSConf, TransportUnicastConf}; use zenoh_core::zasynclock; use zenoh_link::*; use zenoh_protocol::{ @@ -196,6 +198,7 @@ impl Default for TransportManagerBuilderUnicast { let link_tx = LinkTxConf::default(); let transport = TransportUnicastConf::default(); let qos = QoSConf::default(); + #[cfg(feature = "shared-memory")] let shm = SharedMemoryConf::default(); Self { diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index c33f7b895d..d3e60cb8f0 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -17,7 +17,9 @@ use async_std::task; use std::sync::MutexGuard; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; -use zenoh_core::{zasyncwrite, zlock, zread}; +#[cfg(feature = "shared-memory")] +use zenoh_core::zasyncwrite; +use zenoh_core::{zlock, zread}; use zenoh_link::LinkUnicast; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; diff --git a/io/zenoh-transport/src/unicast/tx.rs b/io/zenoh-transport/src/unicast/tx.rs index a4a7b5bca0..e63eae31ce 100644 --- a/io/zenoh-transport/src/unicast/tx.rs +++ b/io/zenoh-transport/src/unicast/tx.rs @@ -12,10 +12,13 @@ // ZettaScale Zenoh Team, // use super::transport::TransportUnicastInner; +#[cfg(feature = "shared-memory")] use async_std::task; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; -use zenoh_core::{zasyncwrite, zread}; +#[cfg(feature = "shared-memory")] +use zenoh_core::zasyncwrite; +use zenoh_core::zread; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::zenoh::ZenohMessage; @@ -64,6 +67,7 @@ impl TransportUnicastInner { false } + #[allow(unused_mut)] // When feature "shared-memory" is not enabled #[allow(clippy::let_and_return)] // When feature "stats" is not enabled #[inline(always)] pub(crate) fn schedule(&self, mut msg: ZenohMessage) -> bool { From 984299c0c620569cd4635af39added3389e56dab Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 6 Mar 2023 09:46:44 +0100 Subject: [PATCH 055/203] Fix cargo doc --- io/zenoh-transport/src/manager.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index c1cb99ea34..603429c733 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -35,7 +35,7 @@ use zenoh_result::{bail, ZResult}; /// ``` /// use std::sync::Arc; /// use std::time::Duration; -/// use zenoh_protocol::core::{ZenohId, WhatAmI, whatami}; +/// use zenoh_protocol::core::{ZenohId, Resolution, Field, Bits, WhatAmI, whatami}; /// use zenoh_transport::*; /// use zenoh_result::ZResult; /// @@ -66,11 +66,13 @@ use zenoh_result::{bail, ZResult}; /// .accept_pending(10) // Set to 10 the number of simultanous pending incoming transports /// .max_links(1) // Allow max 1 inbound link per transport /// .max_sessions(5); // Allow max 5 transports open +/// let mut resolution = Resolution::default(); +/// resolution.set(Field::FrameSN, Bits::U8); /// let manager = TransportManager::builder() /// .zid(ZenohId::rand()) /// .whatami(WhatAmI::Peer) /// .batch_size(1_024) // Use a batch size of 1024 bytes -/// .sn_resolution(128) // Use a sequence number resolution of 128 +/// .resolution(resolution) // Use a sequence number resolution of 128 /// .unicast(unicast) // Configure unicast parameters /// .build(Arc::new(MySH::default())) /// .unwrap(); From c18c20697bf4ca5ba8ed744b8de6e48ddeba3969 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 6 Mar 2023 09:52:46 +0100 Subject: [PATCH 056/203] Disable multicast link and join message --- commons/zenoh-codec/src/transport/mod.rs | 2 +- commons/zenoh-codec/tests/codec.rs | 6 +++--- commons/zenoh-protocol/src/transport/mod.rs | 6 +++--- io/zenoh-link-commons/src/lib.rs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index 83ffaa0941..7e3d7caf42 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -15,7 +15,7 @@ mod close; mod fragment; mod frame; mod init; -mod join; +// mod join; mod keepalive; mod open; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 3822a6ca3a..61d1bd64dc 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -270,9 +270,9 @@ fn codec_open_ack() { } // #[test] -fn codec_join() { - run!(Join, Join::rand()); -} +// fn codec_join() { +// run!(Join, Join::rand()); +// } #[test] fn codec_close() { diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 56e66a2ae2..75f7503146 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -15,7 +15,7 @@ pub mod close; pub mod fragment; pub mod frame; pub mod init; -pub mod join; +// pub mod join; pub mod keepalive; pub mod open; @@ -25,12 +25,12 @@ use core::{convert::TryInto, fmt}; pub use fragment::{Fragment, FragmentHeader}; pub use frame::{Frame, FrameHeader}; pub use init::{InitAck, InitSyn}; -pub use join::Join; +// pub use join::Join; pub use keepalive::KeepAlive; pub use open::{OpenAck, OpenSyn}; pub mod id { - pub const JOIN: u8 = 0x01; // For multicast communications only + // pub const JOIN: u8 = 0x01; // For multicast communications only pub const INIT: u8 = 0x02; // For unicast communications only pub const OPEN: u8 = 0x03; // For unicast communications only pub const CLOSE: u8 = 0x04; diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index 3bb0879f2b..113ba255b6 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -20,7 +20,7 @@ #![no_std] extern crate alloc; -mod multicast; +// mod multicast; mod unicast; use alloc::{ From 1a39e91f89bdc91c984477b150a92dcaaaac2add Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 6 Mar 2023 17:25:53 +0100 Subject: [PATCH 057/203] Adding more ZInt tests --- commons/zenoh-codec/src/core/zint.rs | 91 ++++++++++++++++++++++++++++ commons/zenoh-codec/tests/codec.rs | 20 +++++- 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 436591c34a..e7736bdae6 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -106,6 +106,97 @@ where } } +// const MAX_LEN: usize = 9; +// const VLE_THR: u64 = 0xf8; // 248 +// impl WCodec for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; +// fn write(self, writer: &mut W, mut x: u64) -> Self::Output { +// writer.with_slot(MAX_LEN, move |into| { +// if x < VLE_THR { +// into[0] = x as u8; +// return 1; +// } +// x -= VLE_THR - 1; +// // Safety: +// // The `if x < VLE_THR` check at the beginning followed by `x -= VLE_THR - 1` +// // guarantees at this point that `x` is never `0`. Since `x` is 64bit, +// // then `n` is guaranteed to have a value between 1 and 8, both inclusives. +// // `into` is guaranteed to be exactly 9 bytes long. Therefore, copying at most +// // 8 bytes with a pointer offest of 1 is actually safe. +// let n = 8 - (x.leading_zeros() / 8) as usize; +// unsafe { +// core::ptr::copy_nonoverlapping( +// x.to_le_bytes().as_ptr(), +// into.as_mut_ptr().offset(1), +// n, +// ) +// } +// into[0] = VLE_THR as u8 | (n - 1) as u8; +// 1 + n +// }) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; +// fn read(self, reader: &mut R) -> Result { +// let b = reader.read_u8()?; +// if b < (VLE_THR as u8) { +// return Ok(b as u64); +// } +// let n = (1 + (b & !VLE_THR as u8)) as usize; +// let mut zint: [u8; 8] = 0u64.to_le_bytes(); +// reader.read_exact(&mut zint[0..n])?; +// let zint = u64::from_le_bytes(zint); +// Ok(zint.saturating_add(VLE_THR - 1)) +// } +// } + +// mod tests { +// #[test] +// fn zint_overhead() { +// use crate::{WCodec, Zenoh080}; +// use zenoh_buffers::{ +// reader::{HasReader, Reader}, +// writer::HasWriter, +// }; + +// fn overhead(x: u64) -> usize { +// let codec = Zenoh080::new(); +// let mut b = vec![]; +// let mut w = b.writer(); +// codec.write(&mut w, x).unwrap(); +// let r = b.reader().remaining(); +// println!("{} {}", x, r); +// r +// } + +// assert_eq!(overhead(247), 1); +// assert_eq!(overhead(248), 2); +// assert_eq!(overhead(502), 2); +// assert_eq!(overhead(503), 3); +// assert_eq!(overhead(65_782), 3); +// assert_eq!(overhead(65_783), 4); +// assert_eq!(overhead(16_777_462), 4); +// assert_eq!(overhead(16_777_463), 5); +// assert_eq!(overhead(4_294_967_542), 5); +// assert_eq!(overhead(4_294_967_543), 6); +// assert_eq!(overhead(1_099_511_628_022), 6); +// assert_eq!(overhead(1_099_511_628_023), 7); +// assert_eq!(overhead(281_474_976_710_902), 7); +// assert_eq!(overhead(281_474_976_710_903), 8); +// assert_eq!(overhead(72_057_594_037_928_182), 8); +// assert_eq!(overhead(72_057_594_037_928_183), 9); +// assert_eq!(overhead(u64::MAX), 9); +// } +// } + // macro_rules! non_zero_array { // ($($i: expr,)*) => { // [$(match NonZeroU8::new($i) {Some(x) => x, None => panic!("Attempted to place 0 in an array of non-zeros litteral")}),*] diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 61d1bd64dc..1a01b0bd9b 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -118,7 +118,25 @@ macro_rules! run { // Core #[test] fn codec_zint() { - run!(ZInt, thread_rng().gen::()); + run!(ZInt, { thread_rng().gen::() as ZInt }); + run!(ZInt, u8::MIN as ZInt); + run!(ZInt, u8::MAX as ZInt); + + run!(ZInt, { thread_rng().gen::() as ZInt }); + run!(ZInt, u16::MIN as ZInt); + run!(ZInt, u16::MAX as ZInt); + + run!(ZInt, { thread_rng().gen::() as ZInt }); + run!(ZInt, u32::MIN as ZInt); + run!(ZInt, u32::MAX as ZInt); + + run!(ZInt, { thread_rng().gen::() as ZInt }); + run!(ZInt, u64::MIN as ZInt); + run!(ZInt, u64::MAX as ZInt); + + run!(ZInt, thread_rng().gen::() as ZInt); + run!(ZInt, usize::MIN as ZInt); + run!(ZInt, usize::MAX as ZInt); } #[test] From 85ff47ff8d93071c9389e1ab6dfbb292f188a487 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 7 Mar 2023 09:44:56 +0100 Subject: [PATCH 058/203] Improved SeqNum --- io/zenoh-transport/src/common/conduit.rs | 28 ++- .../src/common/defragmentation.rs | 6 +- io/zenoh-transport/src/common/pipeline.rs | 6 +- io/zenoh-transport/src/common/seq_num.rs | 164 ++++++------------ .../src/unicast/establishment/accept.rs | 2 +- .../src/unicast/establishment/open.rs | 2 +- io/zenoh-transport/src/unicast/manager.rs | 2 +- io/zenoh-transport/src/unicast/mod.rs | 6 +- io/zenoh-transport/src/unicast/transport.rs | 7 +- 9 files changed, 78 insertions(+), 145 deletions(-) diff --git a/io/zenoh-transport/src/common/conduit.rs b/io/zenoh-transport/src/common/conduit.rs index e3157fdd24..f5c185ff73 100644 --- a/io/zenoh-transport/src/common/conduit.rs +++ b/io/zenoh-transport/src/common/conduit.rs @@ -16,7 +16,7 @@ use super::seq_num::{SeqNum, SeqNumGenerator}; use std::sync::{Arc, Mutex}; use zenoh_core::zlock; use zenoh_protocol::{ - core::{Reliability, ZInt}, + core::{Bits, Reliability, ZInt}, transport::ConduitSn, }; use zenoh_result::ZResult; @@ -27,9 +27,9 @@ pub(crate) struct TransportChannelTx { } impl TransportChannelTx { - pub(crate) fn make(sn_resolution: ZInt) -> ZResult { + pub(crate) fn make(resolution: Bits) -> ZResult { let tch = TransportChannelTx { - sn: SeqNumGenerator::make(0, sn_resolution)?, + sn: SeqNumGenerator::make(0, resolution)?, }; Ok(tch) } @@ -48,11 +48,11 @@ pub(crate) struct TransportChannelRx { impl TransportChannelRx { pub(crate) fn make( reliability: Reliability, - sn_resolution: ZInt, + resolution: Bits, defrag_buff_size: usize, ) -> ZResult { - let sn = SeqNum::make(0, sn_resolution)?; - let defrag = DefragBuffer::make(reliability, sn_resolution, defrag_buff_size)?; + let sn = SeqNum::make(0, resolution)?; + let defrag = DefragBuffer::make(reliability, resolution, defrag_buff_size)?; let tch = TransportChannelRx { sn, defrag }; Ok(tch) } @@ -77,9 +77,9 @@ pub(crate) struct TransportConduitTx { } impl TransportConduitTx { - pub(crate) fn make(sn_resolution: ZInt) -> ZResult { - let rch = TransportChannelTx::make(sn_resolution)?; - let bch = TransportChannelTx::make(sn_resolution)?; + pub(crate) fn make(resolution: Bits) -> ZResult { + let rch = TransportChannelTx::make(resolution)?; + let bch = TransportChannelTx::make(resolution)?; let ctx = TransportConduitTx { reliable: Arc::new(Mutex::new(rch)), best_effort: Arc::new(Mutex::new(bch)), @@ -100,13 +100,9 @@ pub(crate) struct TransportConduitRx { } impl TransportConduitRx { - pub(crate) fn make( - sn_resolution: ZInt, - defrag_buff_size: usize, - ) -> ZResult { - let rch = TransportChannelRx::make(Reliability::Reliable, sn_resolution, defrag_buff_size)?; - let bch = - TransportChannelRx::make(Reliability::BestEffort, sn_resolution, defrag_buff_size)?; + pub(crate) fn make(resolution: Bits, defrag_buff_size: usize) -> ZResult { + let rch = TransportChannelRx::make(Reliability::Reliable, resolution, defrag_buff_size)?; + let bch = TransportChannelRx::make(Reliability::BestEffort, resolution, defrag_buff_size)?; let ctr = TransportConduitRx { reliable: Arc::new(Mutex::new(rch)), best_effort: Arc::new(Mutex::new(bch)), diff --git a/io/zenoh-transport/src/common/defragmentation.rs b/io/zenoh-transport/src/common/defragmentation.rs index c059f98a5c..40fde5a376 100644 --- a/io/zenoh-transport/src/common/defragmentation.rs +++ b/io/zenoh-transport/src/common/defragmentation.rs @@ -15,7 +15,7 @@ use super::seq_num::SeqNum; use zenoh_buffers::{reader::HasReader, SplitBuffer, ZBuf, ZSlice}; use zenoh_codec::{RCodec, Zenoh080Reliability}; use zenoh_protocol::{ - core::{Reliability, ZInt}, + core::{Bits, Reliability, ZInt}, zenoh::ZenohMessage, }; use zenoh_result::{bail, ZResult}; @@ -32,12 +32,12 @@ pub(crate) struct DefragBuffer { impl DefragBuffer { pub(crate) fn make( reliability: Reliability, - sn_resolution: ZInt, + resolution: Bits, capacity: usize, ) -> ZResult { let db = DefragBuffer { reliability, - sn: SeqNum::make(0, sn_resolution)?, + sn: SeqNum::make(0, resolution)?, buffer: ZBuf::default(), capacity, len: 0, diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 500c64c971..ff1f642c26 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -812,7 +812,7 @@ mod tests { } // Pipeline conduits - let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION.mask()).unwrap(); + let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION).unwrap(); let conduits = vec![tct]; // Total amount of bytes to send in each test @@ -898,7 +898,7 @@ mod tests { } // Pipeline - let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION.mask()).unwrap(); + let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION).unwrap(); let conduits = vec![tct]; let (producer, mut consumer) = TransmissionPipeline::make(TransmissionPipelineConf::default(), conduits.as_slice()); @@ -950,7 +950,7 @@ mod tests { #[ignore] fn tx_pipeline_thr() { // Queue - let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION.mask()).unwrap(); + let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION).unwrap(); let conduits = vec![tct]; let (producer, mut consumer) = TransmissionPipeline::make(CONFIG, conduits.as_slice()); let count = Arc::new(AtomicUsize::new(0)); diff --git a/io/zenoh-transport/src/common/seq_num.rs b/io/zenoh-transport/src/common/seq_num.rs index 32df9366d5..fae0e13481 100644 --- a/io/zenoh-transport/src/common/seq_num.rs +++ b/io/zenoh-transport/src/common/seq_num.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use zenoh_protocol::core::ZInt; +use zenoh_protocol::core::{Bits, ZInt}; use zenoh_result::{bail, ZResult}; /// Sequence Number @@ -26,8 +26,7 @@ use zenoh_result::{bail, ZResult}; #[derive(Clone, Copy, Debug)] pub(crate) struct SeqNum { value: ZInt, - semi_int: ZInt, - resolution: ZInt, + mask: ZInt, } impl SeqNum { @@ -47,12 +46,14 @@ impl SeqNum { /// This funtion will panic if `value` is out of bound w.r.t. `resolution`. That is if /// `value` is greater or equal than `resolution`. /// - pub(crate) fn make(value: ZInt, resolution: ZInt) -> ZResult { - let mut sn = SeqNum { - value: 0, - semi_int: resolution >> 1, - resolution, + pub(crate) fn make(value: ZInt, resolution: Bits) -> ZResult { + let mask = match resolution { + Bits::U8 => (u8::MAX >> 1) as ZInt, // 1 byte max when encoded + Bits::U16 => (u16::MAX >> 2) as ZInt, // 2 bytes max when encoded + Bits::U32 => (u32::MAX >> 4) as ZInt, // 4 bytes max when encoded + Bits::U64 => (u64::MAX >> 8) as ZInt, // 8 bytes max when encoded }; + let mut sn = SeqNum { value: 0, mask }; sn.set(value)?; Ok(sn) } @@ -64,12 +65,12 @@ impl SeqNum { #[inline(always)] pub(crate) fn resolution(&self) -> ZInt { - self.resolution + self.mask } #[inline(always)] pub(crate) fn set(&mut self, value: ZInt) -> ZResult<()> { - if value >= self.resolution { + if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -79,7 +80,7 @@ impl SeqNum { #[inline(always)] pub(crate) fn increment(&mut self) { - self.value = (self.value + 1) % self.resolution; + self.value = self.value.wrapping_add(1) & self.mask; } /// Checks to see if two sequence number are in a precedence relationship, @@ -102,47 +103,20 @@ impl SeqNum { /// /// * `value` - The sequence number which should be checked for precedence relation. pub(crate) fn precedes(&self, value: ZInt) -> ZResult { - if value >= self.resolution { + if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } - - let res = if value > self.value { - value - self.value <= self.semi_int - } else { - self.value - value > self.semi_int - }; - - Ok(res) + let gap = value.wrapping_sub(self.value) & self.mask; + Ok((gap != 0) && ((gap & !(self.mask >> 1)) == 0)) } /// Computes the modulo gap between two sequence numbers. - /// - /// Two case are considered: - /// - /// ## Case 1: sna < snb - /// - /// In this case the gap is computed as *snb* - *sna*. - /// - /// ## Case 2: sna > snb - /// - /// In this case the gap is computed as *resolution* - (*sna* - *snb*). - /// - /// # Arguments - /// - /// * `value` - The sequence number which should be checked for gap computation. #[cfg(test)] // @TODO: remove once reliability is implemented pub(crate) fn gap(&self, value: ZInt) -> ZResult { - if value >= self.resolution { - bail!("The sequence number value must be smaller than the resolution") + if (value & !self.mask) != 0 { + bail!("The sequence number value must be smaller than the resolution"); } - - let gap = if value >= self.value { - value - self.value - } else { - self.resolution - (self.value - value) - }; - - Ok(gap) + Ok(value.wrapping_sub(self.value) & self.mask) } } @@ -166,8 +140,8 @@ impl SeqNumGenerator { /// This funtion will panic if `value` is out of bound w.r.t. `resolution`. That is if /// `value` is greater or equal than `resolution`. /// - pub(crate) fn make(initial_sn: ZInt, sn_resolution: ZInt) -> ZResult { - let sn = SeqNum::make(initial_sn, sn_resolution)?; + pub(crate) fn make(initial_sn: ZInt, resolution: Bits) -> ZResult { + let sn = SeqNum::make(initial_sn, resolution)?; Ok(SeqNumGenerator(sn)) } @@ -196,17 +170,17 @@ mod tests { #[test] fn sn_set() { - let mut sn0a = SeqNum::make(0, 14).unwrap(); + let mask = (u8::MAX >> 1) as ZInt; + + let mut sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert_eq!(sn0a.get(), 0); - assert_eq!(sn0a.resolution, 14); + assert_eq!(sn0a.mask, mask); - let res = sn0a.set(13); - assert!(res.is_ok()); - assert_eq!(sn0a.get(), 13); + sn0a.set(mask).unwrap(); + assert_eq!(sn0a.get(), mask); - let res = sn0a.set(14); - assert!(res.is_err()); - assert_eq!(sn0a.get(), 13); + assert!(sn0a.set(mask + 1).is_err()); + assert_eq!(sn0a.get(), mask); sn0a.increment(); assert_eq!(sn0a.get(), 0); @@ -217,76 +191,40 @@ mod tests { #[test] fn sn_gap() { - let mut sn0a = SeqNum::make(0, 14).unwrap(); - let sn1a: ZInt = 0; - let res = sn0a.gap(sn1a); - assert_eq!(res.unwrap(), 0); - - let sn1a: ZInt = 1; - let res = sn0a.gap(sn1a); - assert_eq!(res.unwrap(), 1); - - let sn1a: ZInt = 13; - let res = sn0a.gap(sn1a); - assert_eq!(res.unwrap(), 13); - - let sn1a: ZInt = 14; - let res = sn0a.gap(sn1a); - assert!(res.is_err()); - - let res = sn0a.set(13); - assert!(res.is_ok()); + let mask = (u8::MAX >> 1) as ZInt; + let mut sn0a = SeqNum::make(0, Bits::U8).unwrap(); - let sn1a: ZInt = 13; - let res = sn0a.gap(sn1a); - assert_eq!(res.unwrap(), 0); + assert_eq!(sn0a.gap(0).unwrap(), 0); + assert_eq!(sn0a.gap(1).unwrap(), 1); + assert_eq!(sn0a.gap(mask).unwrap(), mask); + assert!(sn0a.gap(mask + 1).is_err()); - let sn1a: ZInt = 0; - let res = sn0a.gap(sn1a); - assert_eq!(res.unwrap(), 1); + sn0a.set(mask).unwrap(); + assert_eq!(sn0a.gap(mask).unwrap(), 0); + assert_eq!(sn0a.gap(0).unwrap(), 1); } #[test] fn sn_precedence() { - let mut sn0a = SeqNum::make(0, 14).unwrap(); - let sn1a: ZInt = 1; - let res = sn0a.precedes(sn1a); - assert!(res.unwrap()); - - let sn1a: ZInt = 0; - let res = sn0a.precedes(sn1a); - assert!(!res.unwrap()); - - let sn1a: ZInt = 6; - let res = sn0a.precedes(sn1a); - assert!(res.unwrap()); - - let sn1a: ZInt = 7; - let res = sn0a.precedes(sn1a); - assert!(res.unwrap()); - - let res = sn0a.set(13); - assert!(res.is_ok()); - - let sn1a: ZInt = 6; - let res = sn0a.precedes(sn1a); - assert!(!res.unwrap()); - - let sn1a: ZInt = 1; - let res = sn0a.precedes(sn1a); - assert!(res.unwrap()); - - let sn1a: ZInt = 5; - let res = sn0a.precedes(sn1a); - assert!(res.unwrap()); + let mask = (u8::MAX >> 1) as ZInt; + + let sn0a = SeqNum::make(0, Bits::U8).unwrap(); + assert!(sn0a.precedes(1).unwrap()); + assert!(!sn0a.precedes(0).unwrap()); + assert!(!sn0a.precedes(mask).unwrap()); + assert!(sn0a.precedes(6).unwrap()); + assert!(sn0a.precedes((mask / 2) - 1).unwrap()); + assert!(sn0a.precedes(mask / 2).unwrap()); + assert!(!sn0a.precedes((mask / 2) + 1).unwrap()); } #[test] fn sn_generation() { - let mut sn0 = SeqNumGenerator::make(13, 14).unwrap(); - let mut sn1 = SeqNumGenerator::make(5, 14).unwrap(); + let mask = (u8::MAX >> 1) as ZInt; + let mut sn0 = SeqNumGenerator::make(mask, Bits::U8).unwrap(); + let mut sn1 = SeqNumGenerator::make(5, Bits::U8).unwrap(); - assert_eq!(sn0.get(), 13); + assert_eq!(sn0.get(), mask); assert_eq!(sn1.get(), 5); assert_eq!(sn0.get(), 0); diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 902f9096a8..b4cfd67c7b 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -468,7 +468,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) let config = TransportConfigUnicast { zid: osyn_out.other_zid, whatami: osyn_out.other_whatami, - sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), + sn_resolution: state.zenoh.resolution.get(Field::FrameSN), tx_initial_sn: oack_out.open_ack.initial_sn, is_qos: state.ext_qos.is_qos(), #[cfg(feature = "shared-memory")] diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 248b531802..9e7164f9d3 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -406,7 +406,7 @@ pub(crate) async fn open_link( let config = TransportConfigUnicast { zid: iack_out.other_zid, whatami: iack_out.other_whatami, - sn_resolution: state.zenoh.resolution.get(Field::FrameSN).mask(), + sn_resolution: state.zenoh.resolution.get(Field::FrameSN), tx_initial_sn: osyn_out.mine_initial_sn, is_qos: state.ext_qos.is_qos(), #[cfg(feature = "shared-memory")] diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 98cecdc386..410715f435 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -390,7 +390,7 @@ impl TransportManager { guard.insert(config.zid, a_t); log::debug!( - "New transport opened between {} and {}: whatami {}, sn resolution {}, initial sn {:?}, shm: {}, qos: {}", + "New transport opened between {} and {}: whatami {}, sn resolution {:?}, initial sn {:?}, shm: {}, qos: {}", self.config.zid, config.zid, config.whatami, diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index bc64de8f69..fad7de5a5b 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -30,7 +30,7 @@ use std::sync::{Arc, Weak}; use transport::TransportUnicastInner; use zenoh_link::Link; use zenoh_protocol::{ - core::{WhatAmI, ZInt, ZenohId}, + core::{Bits, WhatAmI, ZInt, ZenohId}, transport::close, zenoh::ZenohMessage, }; @@ -84,7 +84,7 @@ stats_struct! { pub(crate) struct TransportConfigUnicast { pub(crate) zid: ZenohId, pub(crate) whatami: WhatAmI, - pub(crate) sn_resolution: ZInt, + pub(crate) sn_resolution: Bits, pub(crate) tx_initial_sn: ZInt, pub(crate) is_shm: bool, pub(crate) is_qos: bool, @@ -118,7 +118,7 @@ impl TransportUnicast { #[inline(always)] pub fn get_sn_resolution(&self) -> ZResult { let transport = self.get_inner()?; - Ok(transport.get_sn_resolution()) + Ok(transport.get_sn_resolution().mask()) } #[inline(always)] diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index fc40d0e979..3e24561382 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -1,5 +1,3 @@ -use crate::TransportConfigUnicast; - // // Copyright (c) 2022 ZettaScale Technology // @@ -18,13 +16,14 @@ use super::common::conduit::{TransportConduitRx, TransportConduitTx}; use super::link::TransportLinkUnicast; #[cfg(feature = "stats")] use super::TransportUnicastStatsAtomic; +use crate::TransportConfigUnicast; use async_std::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; use std::sync::{Arc, RwLock}; use std::time::Duration; use zenoh_core::{zasynclock, zread, zwrite}; use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ - core::{Priority, WhatAmI, ZInt, ZenohId}, + core::{Bits, Priority, WhatAmI, ZInt, ZenohId}, transport::{Close, ConduitSn, TransportMessage}, }; use zenoh_result::{bail, zerror, ZResult}; @@ -367,7 +366,7 @@ impl TransportUnicastInner { self.config.whatami } - pub(crate) fn get_sn_resolution(&self) -> ZInt { + pub(crate) fn get_sn_resolution(&self) -> Bits { self.config.sn_resolution } From ea08f8d3ee9df078283b6f56220b13ceda50c4b1 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 7 Mar 2023 10:45:14 +0100 Subject: [PATCH 059/203] Fix SN generation --- io/zenoh-transport/src/common/seq_num.rs | 21 +++++++++++++------ .../src/unicast/establishment/mod.rs | 4 ++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/io/zenoh-transport/src/common/seq_num.rs b/io/zenoh-transport/src/common/seq_num.rs index fae0e13481..23134ad478 100644 --- a/io/zenoh-transport/src/common/seq_num.rs +++ b/io/zenoh-transport/src/common/seq_num.rs @@ -14,6 +14,20 @@ use zenoh_protocol::core::{Bits, ZInt}; use zenoh_result::{bail, ZResult}; +const RES_U8: ZInt = (u8::MAX >> 1) as ZInt; // 1 byte max when encoded +const RES_U16: ZInt = (u16::MAX >> 2) as ZInt; // 2 bytes max when encoded +const RES_U32: ZInt = (u32::MAX >> 4) as ZInt; // 4 bytes max when encoded +const RES_U64: ZInt = (u64::MAX >> 1) as ZInt; // 9 bytes max when encoded + +pub(crate) fn get_mask(resolution: Bits) -> ZInt { + match resolution { + Bits::U8 => RES_U8, + Bits::U16 => RES_U16, + Bits::U32 => RES_U32, + Bits::U64 => RES_U64, + } +} + /// Sequence Number /// /// Zenoh sequence numbers have a negotiable resolution. Each session can @@ -47,12 +61,7 @@ impl SeqNum { /// `value` is greater or equal than `resolution`. /// pub(crate) fn make(value: ZInt, resolution: Bits) -> ZResult { - let mask = match resolution { - Bits::U8 => (u8::MAX >> 1) as ZInt, // 1 byte max when encoded - Bits::U16 => (u16::MAX >> 2) as ZInt, // 2 bytes max when encoded - Bits::U32 => (u32::MAX >> 4) as ZInt, // 4 bytes max when encoded - Bits::U64 => (u64::MAX >> 8) as ZInt, // 8 bytes max when encoded - }; + let mask = get_mask(resolution); let mut sn = SeqNum { value: 0, mask }; sn.set(value)?; Ok(sn) diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 6dbc76dafa..f7d68ed8e1 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -16,8 +16,8 @@ pub(super) mod cookie; pub(super) mod ext; pub(crate) mod open; -use super::super::TransportManager; use super::{TransportPeer, TransportUnicast}; +use crate::{common::seq_num, TransportManager}; use async_trait::async_trait; use cookie::*; use sha3::{ @@ -113,7 +113,7 @@ pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) - hasher.update(zid2.as_slice()); let mut array = (0 as ZInt).to_le_bytes(); hasher.finalize_xof().read(&mut array); - ZInt::from_le_bytes(array) & resolution.get(Field::FrameSN).mask() + ZInt::from_le_bytes(array) & seq_num::get_mask(resolution.get(Field::FrameSN)) } pub(super) async fn close_link(link: &LinkUnicast, reason: Option) { From 7ef66e7e98781f73dbe5d86bbf73256e230db049 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 7 Mar 2023 10:47:48 +0100 Subject: [PATCH 060/203] Fix SN generation --- io/zenoh-transport/src/common/seq_num.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/io/zenoh-transport/src/common/seq_num.rs b/io/zenoh-transport/src/common/seq_num.rs index 23134ad478..f168a3f479 100644 --- a/io/zenoh-transport/src/common/seq_num.rs +++ b/io/zenoh-transport/src/common/seq_num.rs @@ -67,17 +67,14 @@ impl SeqNum { Ok(sn) } - #[inline(always)] pub(crate) fn get(&self) -> ZInt { self.value } - #[inline(always)] pub(crate) fn resolution(&self) -> ZInt { self.mask } - #[inline(always)] pub(crate) fn set(&mut self, value: ZInt) -> ZResult<()> { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); @@ -87,7 +84,6 @@ impl SeqNum { Ok(()) } - #[inline(always)] pub(crate) fn increment(&mut self) { self.value = self.value.wrapping_add(1) & self.mask; } @@ -154,20 +150,17 @@ impl SeqNumGenerator { Ok(SeqNumGenerator(sn)) } - #[inline(always)] pub(crate) fn now(&mut self) -> ZInt { self.0.get() } /// Generates the next sequence number - #[inline(always)] pub(crate) fn get(&mut self) -> ZInt { let now = self.now(); self.0.increment(); now } - #[inline(always)] pub(crate) fn set(&mut self, sn: ZInt) -> ZResult<()> { self.0.set(sn) } From 63f68d652c6b60687a74ca8f3a5027dd740c65c9 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 7 Mar 2023 11:47:02 +0100 Subject: [PATCH 061/203] Make no_std CI happy --- Cargo.lock | 62 +++++++++---------- Cargo.toml | 2 +- commons/zenoh-codec/src/transport/frame.rs | 3 +- commons/zenoh-protocol/src/transport/mod.rs | 1 + plugins/zenoh-plugin-rest/Cargo.toml | 2 +- .../zenoh-plugin-storage-manager/Cargo.toml | 2 +- 6 files changed, 37 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36815f4948..ac1d6ffa3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3771,7 +3771,7 @@ dependencies = [ [[package]] name = "zenoh" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-global-executor", "async-std", @@ -3816,7 +3816,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "rand 0.8.5", "zenoh-collections", @@ -3824,7 +3824,7 @@ dependencies = [ [[package]] name = "zenoh-codec" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "criterion", "rand 0.8.5", @@ -3838,11 +3838,11 @@ dependencies = [ [[package]] name = "zenoh-collections" -version = "0.7.0-rc" +version = "0.8.0-rc" [[package]] name = "zenoh-config" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "flume", "json5", @@ -3859,7 +3859,7 @@ dependencies = [ [[package]] name = "zenoh-core" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "lazy_static", @@ -3869,7 +3869,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "aes 0.8.2", "hmac 0.12.1", @@ -3881,7 +3881,7 @@ dependencies = [ [[package]] name = "zenoh-examples" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "clap", @@ -3899,7 +3899,7 @@ dependencies = [ [[package]] name = "zenoh-ext" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "bincode", @@ -3918,7 +3918,7 @@ dependencies = [ [[package]] name = "zenoh-link" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -3938,7 +3938,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -3953,7 +3953,7 @@ dependencies = [ [[package]] name = "zenoh-link-quic" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -3975,7 +3975,7 @@ dependencies = [ [[package]] name = "zenoh-link-serial" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -3996,7 +3996,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -4011,7 +4011,7 @@ dependencies = [ [[package]] name = "zenoh-link-tls" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-rustls", "async-std", @@ -4032,7 +4032,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -4050,7 +4050,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -4067,7 +4067,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -4086,7 +4086,7 @@ dependencies = [ [[package]] name = "zenoh-macros" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "proc-macro2", "quote", @@ -4097,7 +4097,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-rest" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "anyhow", "async-std", @@ -4122,7 +4122,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-storage-manager" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-global-executor", "async-std", @@ -4152,7 +4152,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "libloading", "log", @@ -4164,7 +4164,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "const_format", "hex", @@ -4181,14 +4181,14 @@ dependencies = [ [[package]] name = "zenoh-result" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "anyhow", ] [[package]] name = "zenoh-shm" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "bincode", "log", @@ -4200,7 +4200,7 @@ dependencies = [ [[package]] name = "zenoh-sync" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "event-listener", @@ -4214,7 +4214,7 @@ dependencies = [ [[package]] name = "zenoh-transport" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-executor", "async-global-executor", @@ -4246,7 +4246,7 @@ dependencies = [ [[package]] name = "zenoh-util" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -4277,7 +4277,7 @@ dependencies = [ [[package]] name = "zenoh_backend_traits" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "async-trait", @@ -4290,7 +4290,7 @@ dependencies = [ [[package]] name = "zenohd" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "clap", @@ -4313,7 +4313,7 @@ checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" [[package]] name = "zplugin-example" -version = "0.7.0-rc" +version = "0.8.0-rc" dependencies = [ "async-std", "clap", diff --git a/Cargo.toml b/Cargo.toml index 37e13d1b38..cf3ccb0878 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ exclude = [ [workspace.package] rust-version = "1.62.1" -version = "0.7.0-rc" # Zenoh version +version = "0.8.0-rc" # Zenoh version repository = "https://github.com/eclipse-zenoh/zenoh" homepage = "http://zenoh.io" authors = [ diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 993bc5737a..7211c9a759 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -14,6 +14,7 @@ use core::convert::TryInto; // ZettaScale Zenoh Team, // use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Reliability}; +use alloc::vec::Vec; use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -211,7 +212,7 @@ where let header: FrameHeader = self.read(&mut *reader)?; let rcode = Zenoh080Reliability::new(header.reliability); - let mut payload = vec![]; + let mut payload = Vec::new(); while reader.can_read() { let mark = reader.mark(); let res: Result = rcode.read(&mut *reader); diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 75f7503146..29f6b5a40d 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -20,6 +20,7 @@ pub mod keepalive; pub mod open; use crate::core::{Priority, ZInt}; +use alloc::boxed::Box; pub use close::Close; use core::{convert::TryInto, fmt}; pub use fragment::{Fragment, FragmentHeader}; diff --git a/plugins/zenoh-plugin-rest/Cargo.toml b/plugins/zenoh-plugin-rest/Cargo.toml index 054313e326..9bd296159f 100644 --- a/plugins/zenoh-plugin-rest/Cargo.toml +++ b/plugins/zenoh-plugin-rest/Cargo.toml @@ -64,4 +64,4 @@ maintainer = "zenoh-dev@eclipse.org" copyright = "2022 ZettaScale Technology" section = "net" license-file = ["../../LICENSE", "0"] -depends = "zenohd (=0.7.0-rc)" +depends = "zenohd (=0.8.0-rc)" diff --git a/plugins/zenoh-plugin-storage-manager/Cargo.toml b/plugins/zenoh-plugin-storage-manager/Cargo.toml index 65ed3cfed9..bdb7fa22f7 100644 --- a/plugins/zenoh-plugin-storage-manager/Cargo.toml +++ b/plugins/zenoh-plugin-storage-manager/Cargo.toml @@ -72,4 +72,4 @@ maintainer = "zenoh-dev@eclipse.org" copyright = "2022 ZettaScale Technology" section = "net" license-file = ["../../LICENSE", "0"] -depends = "zenohd (=0.7.0-rc)" +depends = "zenohd (=0.8.0-rc)" From e9eefd772f59c89277604a100e86bec2b67643ff Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 7 Mar 2023 20:59:17 +0100 Subject: [PATCH 062/203] Remove lifetime from OpenFsm and AcceptFsm traits --- .../src/unicast/establishment/accept.rs | 44 +- .../establishment/ext/authenticator/mod.rs | 567 +++---- .../establishment/ext/authenticator/pubkey.rs | 1340 ++++++++--------- .../ext/authenticator/userpassword.rs | 476 ------ .../establishment/ext/authenticator/usrpwd.rs | 476 ++++++ .../src/unicast/establishment/ext/mod.rs | 2 +- .../src/unicast/establishment/ext/qos.rs | 93 +- .../src/unicast/establishment/ext/shm.rs | 84 +- .../src/unicast/establishment/mod.rs | 84 +- .../src/unicast/establishment/open.rs | 44 +- io/zenoh-transport/src/unicast/manager.rs | 2 +- 11 files changed, 1568 insertions(+), 1644 deletions(-) delete mode 100644 io/zenoh-transport/src/unicast/establishment/ext/authenticator/userpassword.rs create mode 100644 io/zenoh-transport/src/unicast/establishment/ext/authenticator/usrpwd.rs diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index b4cfd67c7b..c00971d503 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -103,21 +103,21 @@ struct AcceptLink<'a> { link: &'a LinkUnicast, prng: &'a Mutex, cipher: &'a BlockCipher, - ext_qos: ext::qos::QoS, + ext_qos: ext::qos::QoS<'a>, #[cfg(feature = "shared-memory")] ext_shm: ext::shm::Shm<'a>, } #[async_trait] -impl<'a> AcceptFsm<'a> for AcceptLink<'a> { +impl<'a> AcceptFsm for AcceptLink<'a> { type Error = AcceptError; - type InitSynIn = (&'a mut State, RecvInitSynIn); - type InitSynOut = RecvInitSynOut; + type RecvInitSynIn = (&'a mut State, RecvInitSynIn); + type RecvInitSynOut = RecvInitSynOut; async fn recv_init_syn( - &'a self, - input: Self::InitSynIn, - ) -> Result { + &self, + input: Self::RecvInitSynIn, + ) -> Result { let (state, input) = input; let msg = self @@ -191,12 +191,12 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { Ok(output) } - type InitAckIn = (&'a mut State, SendInitAckIn); - type InitAckOut = SendInitAckOut; + type SendInitAckIn = (&'a mut State, SendInitAckIn); + type SendInitAckOut = SendInitAckOut; async fn send_init_ack( - &'a self, - input: Self::InitAckIn, - ) -> Result { + &self, + input: Self::SendInitAckIn, + ) -> Result { let (state, input) = input; // Extension QoS @@ -269,12 +269,12 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { Ok(output) } - type OpenSynIn = RecvOpenSynIn; - type OpenSynOut = (State, RecvOpenSynOut); + type RecvOpenSynIn = RecvOpenSynIn; + type RecvOpenSynOut = (State, RecvOpenSynOut); async fn recv_open_syn( - &'a self, - input: Self::OpenSynIn, - ) -> Result { + &self, + input: Self::RecvOpenSynIn, + ) -> Result { let msg = self .link .recv() @@ -353,12 +353,12 @@ impl<'a> AcceptFsm<'a> for AcceptLink<'a> { Ok((state, output)) } - type OpenAckIn = (&'a mut State, SendOpenAckIn); - type OpenAckOut = SendOpenAckOut; + type SendOpenAckIn = (&'a mut State, SendOpenAckIn); + type SendOpenAckOut = SendOpenAckOut; async fn send_open_ack( - &'a self, - input: Self::OpenAckIn, - ) -> Result { + &self, + input: Self::SendOpenAckIn, + ) -> Result { let (state, input) = input; // Extension QoS diff --git a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs index 38db8a80b4..073e704552 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs @@ -13,358 +13,279 @@ // #[cfg(feature = "auth_pubkey")] mod pubkey; -#[cfg(feature = "auth_usrpwd")] -mod userpassword; +// #[cfg(feature = "auth_usrpwd")] +// mod userpassword; -use crate::unicast::establishment::Cookie; -use async_trait::async_trait; +// use crate::unicast::establishment::Cookie; +// use async_trait::async_trait; #[cfg(feature = "auth_pubkey")] pub use pubkey::*; -use std::collections::HashSet; -use std::fmt; -use std::hash::{Hash, Hasher}; -use std::ops::Deref; -use std::sync::Arc; -#[cfg(feature = "auth_usrpwd")] -pub use userpassword::*; -use zenoh_config::Config; -use zenoh_link::{Link, Locator}; -use zenoh_protocol::core::{ZInt, ZenohId}; -use zenoh_result::ZResult; - -/*************************************/ -/* LINK */ -/*************************************/ -#[derive(PartialEq, Eq, Hash)] -#[repr(u8)] -pub enum LinkAuthenticatorId { - Reserved = 0, -} - -pub struct LinkAuthenticator(Arc); - -impl LinkAuthenticator { - pub(crate) async fn from_config(_config: &Config) -> ZResult> { - Ok(HashSet::new()) - } -} - -impl Deref for LinkAuthenticator { - type Target = Arc; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl Eq for LinkAuthenticator {} - -impl PartialEq for LinkAuthenticator { - fn eq(&self, other: &Self) -> bool { - self.id() == other.id() - } +use zenoh_buffers::reader::Reader; +use zenoh_buffers::writer::Writer; +// use std::collections::HashSet; +// use std::fmt; +// use std::hash::{Hash, Hasher}; +// use std::ops::Deref; +// use std::sync::Arc; +// #[cfg(feature = "auth_usrpwd")] +// pub use userpassword::*; +// use zenoh_config::Config; +// use zenoh_link::{Link, Locator}; +// use zenoh_protocol::core::{ZInt, ZenohId}; +// use zenoh_result::ZResult; + +use crate::establishment::{AcceptFsm, OpenFsm}; +use async_trait::async_trait; +use std::collections::HashMap; +use zenoh_codec::{RCodec, WCodec}; +use zenoh_config::ZenohId; +use zenoh_protocol::common::ZExtUnknown; +use zenoh_protocol::core::ZInt; +use zenoh_result::{ZError, ZResult}; + +struct Auth<'a> { + inner: &'a HashMap<&'static str, Box>, } -impl Hash for LinkAuthenticator { - fn hash(&self, state: &mut H) { - self.id().hash(state); - } -} +pub type TransportAuthenticator<'a> = Box; +// impl<'a> /*************************************/ -/* DUMMY LINK */ +/* PEER */ /*************************************/ -#[async_trait] -pub trait LinkUnicastAuthenticatorTrait { - /// Return the ID of this authenticator. - fn id(&self) -> LinkAuthenticatorId; - - /// Close the authenticator - async fn close(&self); - - /// Handle new links - async fn handle_new_link(&self, link: &Link) -> ZResult>; - - /// Handle any error on a link. This callback is mainly used to clean-up any internal state - /// of the authenticator in such a way no unnecessary data is left around. - async fn handle_link_err(&self, link: &Link); -} - -pub struct DummyLinkUnicastAuthenticator; - -impl DummyLinkUnicastAuthenticator { - pub fn make() -> LinkAuthenticator { - LinkAuthenticator(Arc::new(DummyLinkUnicastAuthenticator)) - } -} - -#[async_trait] -impl LinkUnicastAuthenticatorTrait for DummyLinkUnicastAuthenticator { - fn id(&self) -> LinkAuthenticatorId { - LinkAuthenticatorId::Reserved - } - - async fn close(&self) {} - - async fn handle_new_link(&self, _link: &Link) -> ZResult> { - Ok(None) - } - - async fn handle_link_err(&self, _link: &Link) {} -} +// #[derive(PartialEq, Eq, Hash)] +// #[repr(u8)] +// pub enum ZNodeAuthenticatorId { +// Reserved = 0, +// Shm = 1, +// UserPassword = 2, +// PublicKey = 3, +// } + +// impl From for ZInt { +// fn from(pa: ZNodeAuthenticatorId) -> ZInt { +// pa as ZInt +// } +// } + +// #[derive(Clone)] +// pub struct TransportAuthenticator(Arc); + +// impl TransportAuthenticator { +// pub async fn from_config(_config: &Config) -> ZResult> { +// #[allow(unused_mut)] +// let mut pas = HashSet::new(); + +// #[cfg(feature = "auth_pubkey")] +// { +// let mut res = PubKeyAuthenticator::from_config(_config).await?; +// if let Some(pa) = res.take() { +// pas.insert(pa.into()); +// } +// } + +// #[cfg(feature = "auth_usrpwd")] +// { +// let mut res = UserPasswordAuthenticator::from_config(_config).await?; +// if let Some(pa) = res.take() { +// pas.insert(pa.into()); +// } +// } + +// Ok(pas) +// } +// } /*************************************/ -/* PEER */ +/* OPEN */ /*************************************/ -#[derive(PartialEq, Eq, Hash)] -#[repr(u8)] -pub enum ZNodeAuthenticatorId { - Reserved = 0, - Shm = 1, - UserPassword = 2, - PublicKey = 3, -} - -impl From for ZInt { - fn from(pa: ZNodeAuthenticatorId) -> ZInt { - pa as ZInt - } +// InitSyn +pub struct SendInitSynIn<'a> { + state: &'a mut [u8], + zid: &'a ZenohId, } -#[derive(Clone)] -pub struct TransportAuthenticator(Arc); - -impl TransportAuthenticator { - pub async fn from_config(_config: &Config) -> ZResult> { - #[allow(unused_mut)] - let mut pas = HashSet::new(); - - #[cfg(feature = "auth_pubkey")] - { - let mut res = PubKeyAuthenticator::from_config(_config).await?; - if let Some(pa) = res.take() { - pas.insert(pa.into()); - } - } - - #[cfg(feature = "auth_usrpwd")] - { - let mut res = UserPasswordAuthenticator::from_config(_config).await?; - if let Some(pa) = res.take() { - pas.insert(pa.into()); - } - } - - Ok(pas) - } +pub struct SendInitSynOut { + ext: Option, } -impl Deref for TransportAuthenticator { - type Target = Arc; - - fn deref(&self) -> &Self::Target { - &self.0 - } +// InitAck +pub struct RecvInitAckIn<'a> { + state: &'a mut [u8], + zid: &'a ZenohId, + ext: Option, } -impl Eq for TransportAuthenticator {} +pub struct RecvInitAckOut {} -impl PartialEq for TransportAuthenticator { - fn eq(&self, other: &Self) -> bool { - self.id() == other.id() - } +// OpenSyn +pub struct SendOpenSynIn<'a> { + state: &'a mut [u8], + zid: &'a ZenohId, } -impl Hash for TransportAuthenticator { - fn hash(&self, state: &mut H) { - self.id().hash(state); - } +pub struct SendOpenSynOut { + ext: Option, } -// Authenticated peer link -#[derive(Debug)] -pub struct AuthenticatedLink { - pub src: Locator, - pub dst: Locator, - pub node_id: ZenohId, +// OpenAck +pub struct RecvOpenAckIn<'a> { + state: &'a mut [u8], + zid: &'a ZenohId, } -impl fmt::Display for AuthenticatedLink { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{} => {}", self.src, self.dst) - } -} +pub struct RecvOpenAckOut {} #[async_trait] -pub trait TransportAuthenticatorTrait: Send + Sync { - /// Return the ID of this authenticator. - fn id(&self) -> ZNodeAuthenticatorId; - - /// Close the authenticator +pub trait TransportAuthenticatorTrait<'a>: + OpenFsm< + '_, + SendInitSynIn = SendInitSynIn<'a>, + SendInitSynOut = SendInitSynOut, + RecvInitAckIn = RecvInitAckIn<'a>, + RecvInitAckOut = RecvInitAckOut, + SendOpenSynIn = SendOpenSynIn<'a>, + SendOpenSynOut = SendOpenSynOut, + RecvOpenAckIn = RecvOpenAckIn<'a>, + RecvOpenAckOut = RecvOpenAckOut, + Error = ZError, + > + AcceptFsm< + 'a, + RecvInitSynIn = (&'a mut [u8], &'a ZenohId, Option), + RecvInitSynOut = (), + SendInitAckIn = &'a mut [u8], + SendInitAckOut = Option, + RecvOpenSynIn = (&'a mut [u8], Option), + RecvOpenSynOut = (), + SendOpenAckIn = &'a mut [u8], + SendOpenAckOut = Option, + Error = ZError, + > + Send + + Sync +{ + fn id(&self) -> &'static str; + + async fn from_config(config: ()) -> ZResult + where + Self: Sized; + + async fn init(&self) -> ZResult>; + + // Close the authenticator async fn close(&self); +} - /// Return the attachment to be included in the InitSyn message. - /// - /// # Arguments - /// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the initial InitSyn message will be sent on - /// - /// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitSyn, i.e., the peer - /// initiating a new transport. - /// - async fn get_init_syn_properties( - &self, - link: &AuthenticatedLink, - node_id: &ZenohId, - ) -> ZResult>>; - - /// Return the attachment to be included in the InitAck message to be sent - /// in response of the authenticated InitSyn. - /// - /// # Arguments - /// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the InitSyn message was received on - /// - /// * `cookie` - The Cookie containing the internal state - /// - /// * `property` - The optional `Property` included in the InitSyn message - /// - async fn handle_init_syn( - &self, - link: &AuthenticatedLink, - cookie: &Cookie, - property: Option>, - ) -> ZResult<(Option>, Option>)>; // (Attachment, Cookie) - - /// Return the attachment to be included in the OpenSyn message to be sent - /// in response of the authenticated InitAck. - /// - /// # Arguments - /// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the InitSyn message was received on - /// - /// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitAck message - /// - /// * `sn_resolution` - The sn_resolution negotiated by the sender of the InitAck message - /// - /// * `properties` - The optional `Property` included in the InitAck message - /// - async fn handle_init_ack( - &self, - link: &AuthenticatedLink, - node_id: &ZenohId, - sn_resolution: ZInt, - property: Option>, - ) -> ZResult>>; - - /// Return the attachment to be included in the OpenAck message to be sent - /// in response of the authenticated OpenSyn. - /// - /// # Arguments - /// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the OpenSyn message was received on - /// - /// * `properties` - The optional `Property` included in the OpenSyn message - /// - /// * `cookie` - The optional `Property` included in the OpenSyn message - /// - async fn handle_open_syn( - &self, - link: &AuthenticatedLink, - cookie: &Cookie, - property: (Option>, Option>), // (Attachment, Cookie) - ) -> ZResult>>; - - /// Auhtenticate the OpenAck. No message is sent back in response to an OpenAck - /// - /// # Arguments - /// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the OpenAck message was received on - /// - /// * `properties` - The optional `Property` included in the OpenAck message - /// - async fn handle_open_ack( - &self, - link: &AuthenticatedLink, - property: Option>, - ) -> ZResult>>; - - /// Handle any error on a link. This callback is mainly used to clean-up any internal state - /// of the authenticator in such a way no unnecessary data is left around - /// - /// # Arguments - /// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] generating the error - /// - async fn handle_link_err(&self, link: &AuthenticatedLink); - - /// Handle any error on a link. This callback is mainly used to clean-up any internal state - /// of the authenticator in such a way no unnecessary data is left around - /// - /// # Arguments - /// * `peerd_id` - The [`ZenohId`][ZenohId] of the transport being closed. - /// - async fn handle_close(&self, node_id: &ZenohId); +#[async_trait] +pub trait TransportAuthenticatorState<'a, W, R>: WCodec<&'a Self, W> + RCodec +where + Self: 'a + Sized, + W: Writer, + R: Reader, +{ } -/*************************************/ -/* DUMMY PEER */ -/*************************************/ -pub struct DummyPeerAuthenticator; +// #[async_trait] +// pub trait TransportAuthenticatorTrait: Send + Sync { +// // Return the ID of this authenticator. +// fn id(&self) -> ZNodeAuthenticatorId; -impl DummyPeerAuthenticator { - pub fn make() -> TransportAuthenticator { - TransportAuthenticator(Arc::new(DummyPeerAuthenticator)) - } -} +// Close the authenticator +// async fn close(&self); -#[async_trait] -impl TransportAuthenticatorTrait for DummyPeerAuthenticator { - fn id(&self) -> ZNodeAuthenticatorId { - ZNodeAuthenticatorId::Reserved - } - - async fn close(&self) {} - - async fn get_init_syn_properties( - &self, - _link: &AuthenticatedLink, - _node_id: &ZenohId, - ) -> ZResult>> { - Ok(None) - } - - async fn handle_init_syn( - &self, - _link: &AuthenticatedLink, - _cookie: &Cookie, - _property: Option>, - ) -> ZResult<(Option>, Option>)> { - Ok((None, None)) - } - - async fn handle_init_ack( - &self, - _link: &AuthenticatedLink, - _node_id: &ZenohId, - _sn_resolution: ZInt, - _property: Option>, - ) -> ZResult>> { - Ok(None) - } - - async fn handle_open_syn( - &self, - _link: &AuthenticatedLink, - _cookie: &Cookie, - _property: (Option>, Option>), - ) -> ZResult>> { - Ok(None) - } - - async fn handle_open_ack( - &self, - _link: &AuthenticatedLink, - _property: Option>, - ) -> ZResult>> { - Ok(None) - } - - async fn handle_link_err(&self, _link: &AuthenticatedLink) {} - - async fn handle_close(&self, _node_id: &ZenohId) {} -} +// Return the attachment to be included in the InitSyn message. +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the initial InitSyn message will be sent on +// +// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitSyn, i.e., the peer +// initiating a new transport. +// +// async fn get_init_syn_properties( +// &self, +// link: &AuthenticatedLink, +// node_id: &ZenohId, +// ) -> ZResult>>; + +// Return the attachment to be included in the InitAck message to be sent +// in response of the authenticated InitSyn. +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the InitSyn message was received on +// +// * `cookie` - The Cookie containing the internal state +// +// * `property` - The optional `Property` included in the InitSyn message +// +// async fn handle_init_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: Option>, +// ) -> ZResult<(Option>, Option>)>; // (Attachment, Cookie) + +// Return the attachment to be included in the OpenSyn message to be sent +// in response of the authenticated InitAck. +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the InitSyn message was received on +// +// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitAck message +// +// * `sn_resolution` - The sn_resolution negotiated by the sender of the InitAck message +// +// * `properties` - The optional `Property` included in the InitAck message +// +// async fn handle_init_ack( +// &self, +// link: &AuthenticatedLink, +// node_id: &ZenohId, +// sn_resolution: ZInt, +// property: Option>, +// ) -> ZResult>>; + +// Return the attachment to be included in the OpenAck message to be sent +// in response of the authenticated OpenSyn. +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the OpenSyn message was received on +// +// * `properties` - The optional `Property` included in the OpenSyn message +// +// * `cookie` - The optional `Property` included in the OpenSyn message +// +// async fn handle_open_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: (Option>, Option>), // (Attachment, Cookie) +// ) -> ZResult>>; + +// Auhtenticate the OpenAck. No message is sent back in response to an OpenAck +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the OpenAck message was received on +// +// * `properties` - The optional `Property` included in the OpenAck message +// +// async fn handle_open_ack( +// &self, +// link: &AuthenticatedLink, +// property: Option>, +// ) -> ZResult>>; + +// Handle any error on a link. This callback is mainly used to clean-up any internal state +// of the authenticator in such a way no unnecessary data is left around +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] generating the error +// +// async fn handle_link_err(&self, link: &AuthenticatedLink); + +// Handle any error on a link. This callback is mainly used to clean-up any internal state +// of the authenticator in such a way no unnecessary data is left around +// +// # Arguments +// * `peerd_id` - The [`ZenohId`][ZenohId] of the transport being closed. +// +// async fn handle_close(&self, node_id: &ZenohId); +// } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/pubkey.rs index 0e89f37d8f..dc466e4d37 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/pubkey.rs @@ -11,676 +11,676 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::{ - AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, -}; -use crate::unicast::establishment::Cookie; -use async_std::sync::Mutex; -use async_trait::async_trait; -use rand::SeedableRng; -use rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}; -use rsa::{BigUint, PaddingScheme, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey}; -use std::collections::HashMap; -use std::ops::Deref; -use std::path::Path; -use std::sync::Arc; -use zenoh_buffers::{ - reader::{DidntRead, HasReader, Reader}, - writer::{DidntWrite, HasWriter, Writer}, -}; -use zenoh_cfg_properties::config::ZN_AUTH_RSA_KEY_SIZE_DEFAULT; -use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_config::Config; -use zenoh_core::{zasynclock, zparse}; -use zenoh_crypto::PseudoRng; -use zenoh_protocol::core::{ZInt, ZenohId}; -use zenoh_result::{bail, zerror, ZResult}; - -const MULTILINK_VERSION: ZInt = 1; - -/// # Attachment decorator -/// -/// ```text -/// The Attachment can decorate any message (i.e., TransportMessage and ZenohMessage) and it allows to -/// append to the message any additional information. Since the information contained in the -/// Attachement is relevant only to the layer that provided them (e.g., Transport, Zenoh, User) it -/// is the duty of that layer to serialize and de-serialize the attachment whenever deemed necessary. -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// | ENC | ATTCH | -/// +-+-+-+---------+ -/// ~ Attachment ~ -/// +---------------+ -/// -/// ENC values: -/// - 0x00 => Zenoh Properties -/// ``` -#[repr(transparent)] -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ZPublicKey(RsaPublicKey); - -impl Deref for ZPublicKey { - type Target = RsaPublicKey; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl From for ZPublicKey { - fn from(x: RsaPublicKey) -> Self { - Self(x) - } -} - -#[repr(transparent)] -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ZPrivateKey(RsaPrivateKey); - -impl Deref for ZPrivateKey { - type Target = RsaPrivateKey; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl From for ZPrivateKey { - fn from(x: RsaPrivateKey) -> Self { - Self(x) - } -} - -impl WCodec<&ZPublicKey, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ZPublicKey) -> Self::Output { - self.write(&mut *writer, x.n().to_bytes_le().as_slice())?; - self.write(&mut *writer, x.e().to_bytes_le().as_slice())?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let n: Vec = self.read(&mut *reader)?; - let n = BigUint::from_bytes_le(n.as_slice()); - let e: Vec = self.read(&mut *reader)?; - let e = BigUint::from_bytes_le(e.as_slice()); - let rsa = RsaPublicKey::new(n, e).map_err(|_| DidntRead)?; - - Ok(ZPublicKey(rsa)) - } -} - -/*************************************/ -/* InitSyn */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ version ~ -/// +---------------+ -/// ~ public key ~ -/// +---------------+ -struct InitSynProperty { - version: ZInt, - alice_pubkey: ZPublicKey, -} - -impl WCodec<&InitSynProperty, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &InitSynProperty) -> Self::Output { - self.write(&mut *writer, x.version)?; - self.write(&mut *writer, &x.alice_pubkey)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let version: ZInt = self.read(&mut *reader)?; - let alice_pubkey: ZPublicKey = self.read(&mut *reader)?; - Ok(InitSynProperty { - version, - alice_pubkey, - }) - } -} - -/*************************************/ -/* InitAck */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ public key ~ -/// +---------------+ -/// ~ ciphered nonce~ -/// +---------------+ -struct InitAckProperty { - bob_pubkey: ZPublicKey, - nonce_encrypted_with_alice_pubkey: Vec, -} - -impl WCodec<&InitAckProperty, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &InitAckProperty) -> Self::Output { - self.write(&mut *writer, &x.bob_pubkey)?; - self.write(&mut *writer, x.nonce_encrypted_with_alice_pubkey.as_slice())?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let bob_pubkey: ZPublicKey = self.read(&mut *reader)?; - let nonce_encrypted_with_alice_pubkey: Vec = self.read(&mut *reader)?; - Ok(InitAckProperty { - bob_pubkey, - nonce_encrypted_with_alice_pubkey, - }) - } -} - -/*************************************/ -/* OpenSyn */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ ciphered nonce~ -/// +---------------+ -struct OpenSynProperty { - nonce_encrypted_with_bob_pubkey: Vec, -} - -impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &OpenSynProperty) -> Self::Output { - self.write(&mut *writer, x.nonce_encrypted_with_bob_pubkey.as_slice())?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let nonce_encrypted_with_bob_pubkey: Vec = self.read(&mut *reader)?; - Ok(OpenSynProperty { - nonce_encrypted_with_bob_pubkey, - }) - } -} +// use super::{ +// AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, +// }; +// use crate::unicast::establishment::Cookie; +// use async_std::sync::Mutex; +// use async_trait::async_trait; +// use rand::SeedableRng; +// use rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}; +// use rsa::{BigUint, PaddingScheme, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey}; +// use std::collections::HashMap; +// use std::ops::Deref; +// use std::path::Path; +// use std::sync::Arc; +// use zenoh_buffers::{ +// reader::{DidntRead, HasReader, Reader}, +// writer::{DidntWrite, HasWriter, Writer}, +// }; +// use zenoh_cfg_properties::config::ZN_AUTH_RSA_KEY_SIZE_DEFAULT; +// use zenoh_codec::{RCodec, WCodec, Zenoh080}; +// use zenoh_config::Config; +// use zenoh_core::{zasynclock, zparse}; +// use zenoh_crypto::PseudoRng; +// use zenoh_protocol::core::{ZInt, ZenohId}; +// use zenoh_result::{bail, zerror, ZResult}; + +// const MULTILINK_VERSION: ZInt = 1; + +// /// # Attachment decorator +// /// +// /// ```text +// /// The Attachment can decorate any message (i.e., TransportMessage and ZenohMessage) and it allows to +// /// append to the message any additional information. Since the information contained in the +// /// Attachement is relevant only to the layer that provided them (e.g., Transport, Zenoh, User) it +// /// is the duty of that layer to serialize and de-serialize the attachment whenever deemed necessary. +// /// +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// | ENC | ATTCH | +// /// +-+-+-+---------+ +// /// ~ Attachment ~ +// /// +---------------+ +// /// +// /// ENC values: +// /// - 0x00 => Zenoh Properties +// /// ``` +// #[repr(transparent)] +// #[derive(Debug, Clone, PartialEq, Eq)] +// pub struct ZPublicKey(RsaPublicKey); + +// impl Deref for ZPublicKey { +// type Target = RsaPublicKey; + +// fn deref(&self) -> &Self::Target { +// &self.0 +// } +// } + +// impl From for ZPublicKey { +// fn from(x: RsaPublicKey) -> Self { +// Self(x) +// } +// } + +// #[repr(transparent)] +// #[derive(Debug, Clone, PartialEq, Eq)] +// pub struct ZPrivateKey(RsaPrivateKey); + +// impl Deref for ZPrivateKey { +// type Target = RsaPrivateKey; + +// fn deref(&self) -> &Self::Target { +// &self.0 +// } +// } + +// impl From for ZPrivateKey { +// fn from(x: RsaPrivateKey) -> Self { +// Self(x) +// } +// } + +// impl WCodec<&ZPublicKey, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; + +// fn write(self, writer: &mut W, x: &ZPublicKey) -> Self::Output { +// self.write(&mut *writer, x.n().to_bytes_le().as_slice())?; +// self.write(&mut *writer, x.e().to_bytes_le().as_slice())?; +// Ok(()) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let n: Vec = self.read(&mut *reader)?; +// let n = BigUint::from_bytes_le(n.as_slice()); +// let e: Vec = self.read(&mut *reader)?; +// let e = BigUint::from_bytes_le(e.as_slice()); +// let rsa = RsaPublicKey::new(n, e).map_err(|_| DidntRead)?; + +// Ok(ZPublicKey(rsa)) +// } +// } + +// /*************************************/ +// /* InitSyn */ +// /*************************************/ +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// |0 0 0| ATTCH | +// /// +-+-+-+---------+ +// /// ~ version ~ +// /// +---------------+ +// /// ~ public key ~ +// /// +---------------+ +// struct InitSynProperty { +// version: ZInt, +// alice_pubkey: ZPublicKey, +// } + +// impl WCodec<&InitSynProperty, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; + +// fn write(self, writer: &mut W, x: &InitSynProperty) -> Self::Output { +// self.write(&mut *writer, x.version)?; +// self.write(&mut *writer, &x.alice_pubkey)?; +// Ok(()) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let version: ZInt = self.read(&mut *reader)?; +// let alice_pubkey: ZPublicKey = self.read(&mut *reader)?; +// Ok(InitSynProperty { +// version, +// alice_pubkey, +// }) +// } +// } + +// /*************************************/ +// /* InitAck */ +// /*************************************/ +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// |0 0 0| ATTCH | +// /// +-+-+-+---------+ +// /// ~ public key ~ +// /// +---------------+ +// /// ~ ciphered nonce~ +// /// +---------------+ +// struct InitAckProperty { +// bob_pubkey: ZPublicKey, +// nonce_encrypted_with_alice_pubkey: Vec, +// } + +// impl WCodec<&InitAckProperty, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; + +// fn write(self, writer: &mut W, x: &InitAckProperty) -> Self::Output { +// self.write(&mut *writer, &x.bob_pubkey)?; +// self.write(&mut *writer, x.nonce_encrypted_with_alice_pubkey.as_slice())?; +// Ok(()) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let bob_pubkey: ZPublicKey = self.read(&mut *reader)?; +// let nonce_encrypted_with_alice_pubkey: Vec = self.read(&mut *reader)?; +// Ok(InitAckProperty { +// bob_pubkey, +// nonce_encrypted_with_alice_pubkey, +// }) +// } +// } + +// /*************************************/ +// /* OpenSyn */ +// /*************************************/ +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// |0 0 0| ATTCH | +// /// +-+-+-+---------+ +// /// ~ ciphered nonce~ +// /// +---------------+ +// struct OpenSynProperty { +// nonce_encrypted_with_bob_pubkey: Vec, +// } + +// impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; + +// fn write(self, writer: &mut W, x: &OpenSynProperty) -> Self::Output { +// self.write(&mut *writer, x.nonce_encrypted_with_bob_pubkey.as_slice())?; +// Ok(()) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let nonce_encrypted_with_bob_pubkey: Vec = self.read(&mut *reader)?; +// Ok(OpenSynProperty { +// nonce_encrypted_with_bob_pubkey, +// }) +// } +// } /*************************************/ /* Authenticator */ -/*************************************/ -struct InnerState { - prng: PseudoRng, - known_keys: Option>, - authenticated: HashMap>, -} - -pub struct PubKeyAuthenticator { - pub_key: ZPublicKey, - pri_key: ZPrivateKey, - state: Mutex, -} - -impl PubKeyAuthenticator { - pub fn new(pub_key: T, pri_key: U) -> PubKeyAuthenticator - where - T: Into, - U: Into, - { - PubKeyAuthenticator { - pub_key: pub_key.into(), - pri_key: pri_key.into(), - state: Mutex::new(InnerState { - prng: PseudoRng::from_entropy(), - known_keys: None, - authenticated: HashMap::new(), - }), - } - } - - pub fn make() -> ZResult { - let mut prng = PseudoRng::from_entropy(); - let bits = zparse!(ZN_AUTH_RSA_KEY_SIZE_DEFAULT)?; - let pri_key = RsaPrivateKey::new(&mut prng, bits)?; - let pub_key = RsaPublicKey::from(&pri_key); - - let pka = PubKeyAuthenticator { - pub_key: pub_key.into(), - pri_key: pri_key.into(), - state: Mutex::new(InnerState { - prng, - known_keys: None, - authenticated: HashMap::new(), - }), - }; - Ok(pka) - } - - pub async fn add_key(&self, key: ZPublicKey) -> ZResult<()> { - let mut guard = zasynclock!(self.state); - match guard.known_keys.as_mut() { - Some(kk) => { - if !kk.iter().any(|x| x == &key) { - kk.push(key); - } - } - None => { - let hs = vec![key]; - guard.known_keys = Some(hs); - } - } - Ok(()) - } - - pub async fn del_key(&self, key: &ZPublicKey) -> ZResult<()> { - let mut guard = zasynclock!(self.state); - if let Some(kk) = guard.known_keys.as_mut() { - if let Some(i) = kk.iter().position(|x| x == key) { - kk.remove(i); - } - } - Ok(()) - } - - pub async fn from_config(config: &Config) -> ZResult> { - let c = config.transport().auth().pubkey(); - - // @TODO: support PubKey keys import - - // First, check if PEM keys are provided - match (c.public_key_pem(), c.private_key_pem()) { - (Some(public), Some(private)) => { - let pub_key = RsaPublicKey::from_pkcs1_pem(public) - .map_err(|e| zerror!("Rsa Public Key: {}", e))?; - let pri_key = RsaPrivateKey::from_pkcs1_pem(private) - .map_err(|e| zerror!("Rsa Private Key: {}", e))?; - return Ok(Some(Self::new(pub_key, pri_key))); - } - (Some(_), None) => { - bail!("Missing Rsa Private Key: PEM") - } - (None, Some(_)) => { - bail!("Missing Rsa Public Key: PEM") - } - (None, None) => {} - } - - // Second, check if PEM files are provided - match (c.public_key_file(), c.private_key_file()) { - (Some(public), Some(private)) => { - let path = Path::new(public); - let pub_key = RsaPublicKey::read_pkcs1_pem_file(path) - .map_err(|e| zerror!("Rsa Public Key: {}", e))?; - let path = Path::new(private); - let pri_key = RsaPrivateKey::read_pkcs1_pem_file(path) - .map_err(|e| zerror!("Rsa Private Key: {}", e))?; - return Ok(Some(Self::new(pub_key, pri_key))); - } - (Some(_), None) => { - bail!("Missing Rsa Private Key: file") - } - (None, Some(_)) => { - bail!("Missing Rsa Public Key: file") - } - (None, None) => {} - } - - Ok(None) - } -} - -#[async_trait] -impl TransportAuthenticatorTrait for PubKeyAuthenticator { - fn id(&self) -> ZNodeAuthenticatorId { - ZNodeAuthenticatorId::PublicKey - } - - async fn close(&self) { - // No cleanup needed - } - - async fn get_init_syn_properties( - &self, - link: &AuthenticatedLink, - _node_id: &ZenohId, - ) -> ZResult>> { - let init_syn_property = InitSynProperty { - version: MULTILINK_VERSION, - alice_pubkey: self.pub_key.clone(), - }; - - let mut wbuf = vec![]; - let codec = Zenoh080::new(); - let mut writer = wbuf.writer(); - codec - .write(&mut writer, &init_syn_property) - .map_err(|_| zerror!("Error in encoding InitSyn for PubKey on link: {}", link))?; - - Ok(Some(wbuf)) - } - - async fn handle_init_syn( - &self, - link: &AuthenticatedLink, - cookie: &Cookie, - property: Option>, - ) -> ZResult<(Option>, Option>)> { - match property { - // The connecting zenoh peer wants to do multilink - Some(pk) => { - // Decode the multilink attachment - let mut reader = pk.reader(); - let codec = Zenoh080::new(); - - let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { - zerror!( - "Received InitSyn with invalid PubKey attachment on link: {}", - link - ) - })?; - - // Check if we are compatible - if init_syn_property.version != MULTILINK_VERSION { - bail!("PubKey version not supported on link: {}", link); - } - - // Check if the peer is already present - let mut guard = zasynclock!(self.state); - match guard.authenticated.get(&cookie.zid) { - Some(alice_pubkey) => { - // Check if the public key is the same - match alice_pubkey.as_ref() { - Some(apk) => { - // Check if pub key is used consistently - if apk != &init_syn_property.alice_pubkey { - bail!("Invalid multilink PubKey on link: {}", link); - } - } - None => { - // The peer is already present but no previous multilink intereset - // was declared. Rejecting for inconsistent declaration. - bail!("Unexpected multilink PubKey on link: {}", link); - } - } - } - None => { - // It's the first time we see this peer, check if it is authorized it - if let Some(kk) = guard.known_keys.as_ref() { - if !kk.iter().any(|x| x == &init_syn_property.alice_pubkey) { - // The peer is already present but no previous multilink intereset - // was declared. Rejecting for inconsistent declaration. - bail!("Unauthorized multilink PubKey on link: {}", link); - } - } - - guard - .authenticated - .insert(cookie.zid, Some(init_syn_property.alice_pubkey.clone())); - } - } - - // Create the InitAck attachment - let codec = Zenoh080::new(); - - let mut wbuf = vec![]; - let mut writer = wbuf.writer(); - codec.write(&mut writer, cookie.nonce).map_err(|_| { - zerror!("Error in encoding InitAck for PubKey on link: {}", link) - })?; - - let nonce_bytes = wbuf; - let nonce_encrypted_with_alice_pubkey = init_syn_property.alice_pubkey.encrypt( - &mut guard.prng, - PaddingScheme::PKCS1v15Encrypt, - nonce_bytes.as_slice(), - )?; - - let init_ack_property = InitAckProperty { - bob_pubkey: self.pub_key.clone(), - nonce_encrypted_with_alice_pubkey, - }; - - // Store the public key in the cookie - let mut wbuf = vec![]; - let mut writer = wbuf.writer(); - codec - .write(&mut writer, &init_syn_property.alice_pubkey) - .map_err(|_| { - zerror!("Error in encoding InitAck for PubKey on link: {}", link) - })?; - let cookie = wbuf; - - // Encode the InitAck property - let mut wbuf = vec![]; - let mut writer = wbuf.writer(); - codec.write(&mut writer, &init_ack_property).map_err(|_| { - zerror!("Error in encoding InitAck for PubKey on link: {}", link) - })?; - let attachment = wbuf; - - Ok((Some(attachment), Some(cookie))) - } - // The connecting zenoh peer does not want to do multilink - None => { - let guard = zasynclock!(self.state); - if guard.authenticated.get(&cookie.zid).is_some() { - // The peer is already present but no multilink intereset is declared. - // Rejecting for inconsistent declaration. - bail!("No multilink supported on link: {}", link); - } - - // No properties need to be included in the InitAck attachment - Ok((None, None)) - } - } - } - - async fn handle_init_ack( - &self, - link: &AuthenticatedLink, - _node_id: &ZenohId, - _sn_resolution: ZInt, - property: Option>, - ) -> ZResult>> { - let pk = match property { - Some(pk) => pk, - None => return Ok(None), - }; - - let codec = Zenoh080::new(); - - let mut reader = pk.reader(); - let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { - zerror!( - "Received InitAck with invalid PubKey attachment on link: {}", - link - ) - })?; - let nonce = self.pri_key.decrypt( - PaddingScheme::PKCS1v15Encrypt, - init_ack_property - .nonce_encrypted_with_alice_pubkey - .as_slice(), - )?; - - // Create the OpenSyn attachment - let mut guard = zasynclock!(self.state); - let nonce_encrypted_with_bob_pubkey = init_ack_property.bob_pubkey.encrypt( - &mut guard.prng, - PaddingScheme::PKCS1v15Encrypt, - &nonce[..], - )?; - drop(guard); - - let open_syn_property = OpenSynProperty { - nonce_encrypted_with_bob_pubkey, - }; - - // Encode the OpenSyn property - let mut wbuf = vec![]; - let mut writer = wbuf.writer(); - codec - .write(&mut writer, &open_syn_property) - .map_err(|_| zerror!("Error in encoding OpenSyn for PubKey on link: {}", link))?; - let attachment = wbuf; - - Ok(Some(attachment)) - } - - async fn handle_open_syn( - &self, - link: &AuthenticatedLink, - cookie: &Cookie, - property: (Option>, Option>), - ) -> ZResult>> { - match property { - (Some(att), Some(cke)) => { - let codec = Zenoh080::new(); - - let mut reader = att.reader(); - let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { - zerror!( - "Received OpenSyn with invalid PubKey attachment on link: {}", - link - ) - })?; - - let nonce_bytes = self.pri_key.decrypt( - PaddingScheme::PKCS1v15Encrypt, - open_syn_property.nonce_encrypted_with_bob_pubkey.as_slice(), - )?; - let mut reader = nonce_bytes.reader(); - let nonce: ZInt = codec.read(&mut reader).map_err(|_| { - zerror!( - "Received OpenSyn with invalid PubKey attachment on link: {}", - link - ) - })?; - - if nonce != cookie.nonce { - bail!("Received invalid nonce on link: {}", link); - } - - let mut reader = cke.reader(); - let alice_pubkey: ZPublicKey = codec.read(&mut reader).map_err(|_| { - zerror!( - "Received OpenSyn with invalid PubKey attachment on link: {}", - link - ) - })?; - - let mut guard = zasynclock!(self.state); - match guard.authenticated.get(&cookie.zid) { - Some(apk) => match apk { - Some(apk) => { - // Check if the public key is still correct - if apk != &alice_pubkey { - bail!("Invalid multilink pub key on link: {}", link); - } - } - None => { - // The peer did not previously express interest in multilink - bail!("Invalid multilink pub key on link: {}", link); - } - }, - None => { - // Finally store the public key - guard.authenticated.insert(cookie.zid, Some(alice_pubkey)); - } - } - } - (None, None) => { - // No multilink - let mut guard = zasynclock!(self.state); - if guard.authenticated.get(&cookie.zid).is_some() { - // The peer did not previously express interest in multilink - bail!("Invalid multilink pub key on link: {}", link); - } - // Finally store the public key - guard.authenticated.insert(cookie.zid, None); - } - _ => { - bail!("Received invalid nonce on link: {}", link); - } - } - - Ok(None) - } - - async fn handle_open_ack( - &self, - _link: &AuthenticatedLink, - _property: Option>, - ) -> ZResult>> { - Ok(None) - } - - async fn handle_link_err(&self, link: &AuthenticatedLink) { - // Need to check if it authenticated and remove it if this is the last link - if let Some(zid) = link.node_id.as_ref() { - zasynclock!(self.state).authenticated.remove(zid); - } - } - - async fn handle_close(&self, node_id: &ZenohId) { - zasynclock!(self.state).authenticated.remove(node_id); - } -} - -//noinspection ALL -impl From> for TransportAuthenticator { - fn from(v: Arc) -> TransportAuthenticator { - TransportAuthenticator(v) - } -} - -impl From for TransportAuthenticator { - fn from(v: PubKeyAuthenticator) -> TransportAuthenticator { - Self::from(Arc::new(v)) - } -} +// /*************************************/ +// struct InnerState { +// prng: PseudoRng, +// known_keys: Option>, +// authenticated: HashMap>, +// } + +// pub struct PubKeyAuthenticator { +// pub_key: ZPublicKey, +// pri_key: ZPrivateKey, +// state: Mutex, +// } + +// impl PubKeyAuthenticator { +// pub fn new(pub_key: T, pri_key: U) -> PubKeyAuthenticator +// where +// T: Into, +// U: Into, +// { +// PubKeyAuthenticator { +// pub_key: pub_key.into(), +// pri_key: pri_key.into(), +// state: Mutex::new(InnerState { +// prng: PseudoRng::from_entropy(), +// known_keys: None, +// authenticated: HashMap::new(), +// }), +// } +// } + +// pub fn make() -> ZResult { +// let mut prng = PseudoRng::from_entropy(); +// let bits = zparse!(ZN_AUTH_RSA_KEY_SIZE_DEFAULT)?; +// let pri_key = RsaPrivateKey::new(&mut prng, bits)?; +// let pub_key = RsaPublicKey::from(&pri_key); + +// let pka = PubKeyAuthenticator { +// pub_key: pub_key.into(), +// pri_key: pri_key.into(), +// state: Mutex::new(InnerState { +// prng, +// known_keys: None, +// authenticated: HashMap::new(), +// }), +// }; +// Ok(pka) +// } + +// pub async fn add_key(&self, key: ZPublicKey) -> ZResult<()> { +// let mut guard = zasynclock!(self.state); +// match guard.known_keys.as_mut() { +// Some(kk) => { +// if !kk.iter().any(|x| x == &key) { +// kk.push(key); +// } +// } +// None => { +// let hs = vec![key]; +// guard.known_keys = Some(hs); +// } +// } +// Ok(()) +// } + +// pub async fn del_key(&self, key: &ZPublicKey) -> ZResult<()> { +// let mut guard = zasynclock!(self.state); +// if let Some(kk) = guard.known_keys.as_mut() { +// if let Some(i) = kk.iter().position(|x| x == key) { +// kk.remove(i); +// } +// } +// Ok(()) +// } + +// pub async fn from_config(config: &Config) -> ZResult> { +// let c = config.transport().auth().pubkey(); + +// // @TODO: support PubKey keys import + +// // First, check if PEM keys are provided +// match (c.public_key_pem(), c.private_key_pem()) { +// (Some(public), Some(private)) => { +// let pub_key = RsaPublicKey::from_pkcs1_pem(public) +// .map_err(|e| zerror!("Rsa Public Key: {}", e))?; +// let pri_key = RsaPrivateKey::from_pkcs1_pem(private) +// .map_err(|e| zerror!("Rsa Private Key: {}", e))?; +// return Ok(Some(Self::new(pub_key, pri_key))); +// } +// (Some(_), None) => { +// bail!("Missing Rsa Private Key: PEM") +// } +// (None, Some(_)) => { +// bail!("Missing Rsa Public Key: PEM") +// } +// (None, None) => {} +// } + +// // Second, check if PEM files are provided +// match (c.public_key_file(), c.private_key_file()) { +// (Some(public), Some(private)) => { +// let path = Path::new(public); +// let pub_key = RsaPublicKey::read_pkcs1_pem_file(path) +// .map_err(|e| zerror!("Rsa Public Key: {}", e))?; +// let path = Path::new(private); +// let pri_key = RsaPrivateKey::read_pkcs1_pem_file(path) +// .map_err(|e| zerror!("Rsa Private Key: {}", e))?; +// return Ok(Some(Self::new(pub_key, pri_key))); +// } +// (Some(_), None) => { +// bail!("Missing Rsa Private Key: file") +// } +// (None, Some(_)) => { +// bail!("Missing Rsa Public Key: file") +// } +// (None, None) => {} +// } + +// Ok(None) +// } +// } + +// #[async_trait] +// impl TransportAuthenticatorTrait for PubKeyAuthenticator { +// fn id(&self) -> ZNodeAuthenticatorId { +// ZNodeAuthenticatorId::PublicKey +// } + +// async fn close(&self) { +// // No cleanup needed +// } + +// async fn get_init_syn_properties( +// &self, +// link: &AuthenticatedLink, +// _node_id: &ZenohId, +// ) -> ZResult>> { +// let init_syn_property = InitSynProperty { +// version: MULTILINK_VERSION, +// alice_pubkey: self.pub_key.clone(), +// }; + +// let mut wbuf = vec![]; +// let codec = Zenoh080::new(); +// let mut writer = wbuf.writer(); +// codec +// .write(&mut writer, &init_syn_property) +// .map_err(|_| zerror!("Error in encoding InitSyn for PubKey on link: {}", link))?; + +// Ok(Some(wbuf)) +// } + +// async fn handle_init_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: Option>, +// ) -> ZResult<(Option>, Option>)> { +// match property { +// // The connecting zenoh peer wants to do multilink +// Some(pk) => { +// // Decode the multilink attachment +// let mut reader = pk.reader(); +// let codec = Zenoh080::new(); + +// let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received InitSyn with invalid PubKey attachment on link: {}", +// link +// ) +// })?; + +// // Check if we are compatible +// if init_syn_property.version != MULTILINK_VERSION { +// bail!("PubKey version not supported on link: {}", link); +// } + +// // Check if the peer is already present +// let mut guard = zasynclock!(self.state); +// match guard.authenticated.get(&cookie.zid) { +// Some(alice_pubkey) => { +// // Check if the public key is the same +// match alice_pubkey.as_ref() { +// Some(apk) => { +// // Check if pub key is used consistently +// if apk != &init_syn_property.alice_pubkey { +// bail!("Invalid multilink PubKey on link: {}", link); +// } +// } +// None => { +// // The peer is already present but no previous multilink intereset +// // was declared. Rejecting for inconsistent declaration. +// bail!("Unexpected multilink PubKey on link: {}", link); +// } +// } +// } +// None => { +// // It's the first time we see this peer, check if it is authorized it +// if let Some(kk) = guard.known_keys.as_ref() { +// if !kk.iter().any(|x| x == &init_syn_property.alice_pubkey) { +// // The peer is already present but no previous multilink intereset +// // was declared. Rejecting for inconsistent declaration. +// bail!("Unauthorized multilink PubKey on link: {}", link); +// } +// } + +// guard +// .authenticated +// .insert(cookie.zid, Some(init_syn_property.alice_pubkey.clone())); +// } +// } + +// // Create the InitAck attachment +// let codec = Zenoh080::new(); + +// let mut wbuf = vec![]; +// let mut writer = wbuf.writer(); +// codec.write(&mut writer, cookie.nonce).map_err(|_| { +// zerror!("Error in encoding InitAck for PubKey on link: {}", link) +// })?; + +// let nonce_bytes = wbuf; +// let nonce_encrypted_with_alice_pubkey = init_syn_property.alice_pubkey.encrypt( +// &mut guard.prng, +// PaddingScheme::PKCS1v15Encrypt, +// nonce_bytes.as_slice(), +// )?; + +// let init_ack_property = InitAckProperty { +// bob_pubkey: self.pub_key.clone(), +// nonce_encrypted_with_alice_pubkey, +// }; + +// // Store the public key in the cookie +// let mut wbuf = vec![]; +// let mut writer = wbuf.writer(); +// codec +// .write(&mut writer, &init_syn_property.alice_pubkey) +// .map_err(|_| { +// zerror!("Error in encoding InitAck for PubKey on link: {}", link) +// })?; +// let cookie = wbuf; + +// // Encode the InitAck property +// let mut wbuf = vec![]; +// let mut writer = wbuf.writer(); +// codec.write(&mut writer, &init_ack_property).map_err(|_| { +// zerror!("Error in encoding InitAck for PubKey on link: {}", link) +// })?; +// let attachment = wbuf; + +// Ok((Some(attachment), Some(cookie))) +// } +// // The connecting zenoh peer does not want to do multilink +// None => { +// let guard = zasynclock!(self.state); +// if guard.authenticated.get(&cookie.zid).is_some() { +// // The peer is already present but no multilink intereset is declared. +// // Rejecting for inconsistent declaration. +// bail!("No multilink supported on link: {}", link); +// } + +// // No properties need to be included in the InitAck attachment +// Ok((None, None)) +// } +// } +// } + +// async fn handle_init_ack( +// &self, +// link: &AuthenticatedLink, +// _node_id: &ZenohId, +// _sn_resolution: ZInt, +// property: Option>, +// ) -> ZResult>> { +// let pk = match property { +// Some(pk) => pk, +// None => return Ok(None), +// }; + +// let codec = Zenoh080::new(); + +// let mut reader = pk.reader(); +// let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received InitAck with invalid PubKey attachment on link: {}", +// link +// ) +// })?; +// let nonce = self.pri_key.decrypt( +// PaddingScheme::PKCS1v15Encrypt, +// init_ack_property +// .nonce_encrypted_with_alice_pubkey +// .as_slice(), +// )?; + +// // Create the OpenSyn attachment +// let mut guard = zasynclock!(self.state); +// let nonce_encrypted_with_bob_pubkey = init_ack_property.bob_pubkey.encrypt( +// &mut guard.prng, +// PaddingScheme::PKCS1v15Encrypt, +// &nonce[..], +// )?; +// drop(guard); + +// let open_syn_property = OpenSynProperty { +// nonce_encrypted_with_bob_pubkey, +// }; + +// // Encode the OpenSyn property +// let mut wbuf = vec![]; +// let mut writer = wbuf.writer(); +// codec +// .write(&mut writer, &open_syn_property) +// .map_err(|_| zerror!("Error in encoding OpenSyn for PubKey on link: {}", link))?; +// let attachment = wbuf; + +// Ok(Some(attachment)) +// } + +// async fn handle_open_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: (Option>, Option>), +// ) -> ZResult>> { +// match property { +// (Some(att), Some(cke)) => { +// let codec = Zenoh080::new(); + +// let mut reader = att.reader(); +// let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received OpenSyn with invalid PubKey attachment on link: {}", +// link +// ) +// })?; + +// let nonce_bytes = self.pri_key.decrypt( +// PaddingScheme::PKCS1v15Encrypt, +// open_syn_property.nonce_encrypted_with_bob_pubkey.as_slice(), +// )?; +// let mut reader = nonce_bytes.reader(); +// let nonce: ZInt = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received OpenSyn with invalid PubKey attachment on link: {}", +// link +// ) +// })?; + +// if nonce != cookie.nonce { +// bail!("Received invalid nonce on link: {}", link); +// } + +// let mut reader = cke.reader(); +// let alice_pubkey: ZPublicKey = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received OpenSyn with invalid PubKey attachment on link: {}", +// link +// ) +// })?; + +// let mut guard = zasynclock!(self.state); +// match guard.authenticated.get(&cookie.zid) { +// Some(apk) => match apk { +// Some(apk) => { +// // Check if the public key is still correct +// if apk != &alice_pubkey { +// bail!("Invalid multilink pub key on link: {}", link); +// } +// } +// None => { +// // The peer did not previously express interest in multilink +// bail!("Invalid multilink pub key on link: {}", link); +// } +// }, +// None => { +// // Finally store the public key +// guard.authenticated.insert(cookie.zid, Some(alice_pubkey)); +// } +// } +// } +// (None, None) => { +// // No multilink +// let mut guard = zasynclock!(self.state); +// if guard.authenticated.get(&cookie.zid).is_some() { +// // The peer did not previously express interest in multilink +// bail!("Invalid multilink pub key on link: {}", link); +// } +// // Finally store the public key +// guard.authenticated.insert(cookie.zid, None); +// } +// _ => { +// bail!("Received invalid nonce on link: {}", link); +// } +// } + +// Ok(None) +// } + +// async fn handle_open_ack( +// &self, +// _link: &AuthenticatedLink, +// _property: Option>, +// ) -> ZResult>> { +// Ok(None) +// } + +// async fn handle_link_err(&self, link: &AuthenticatedLink) { +// // Need to check if it authenticated and remove it if this is the last link +// if let Some(zid) = link.node_id.as_ref() { +// zasynclock!(self.state).authenticated.remove(zid); +// } +// } + +// async fn handle_close(&self, node_id: &ZenohId) { +// zasynclock!(self.state).authenticated.remove(node_id); +// } +// } + +// //noinspection ALL +// impl From> for TransportAuthenticator { +// fn from(v: Arc) -> TransportAuthenticator { +// TransportAuthenticator(v) +// } +// } + +// impl From for TransportAuthenticator { +// fn from(v: PubKeyAuthenticator) -> TransportAuthenticator { +// Self::from(Arc::new(v)) +// } +// } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/userpassword.rs b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/userpassword.rs deleted file mode 100644 index aa4003b6ed..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/userpassword.rs +++ /dev/null @@ -1,476 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::{ - AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, -}; -use super::{Locator, ZInt, ZenohId}; -use crate::unicast::establishment::Cookie; -use async_std::fs; -use async_std::sync::{Mutex, RwLock}; -use async_trait::async_trait; -use std::collections::{HashMap, HashSet}; -use std::sync::Arc; -use zenoh_buffers::{ - reader::{DidntRead, HasReader, Reader}, - writer::{DidntWrite, HasWriter, Writer}, -}; -use zenoh_cfg_properties::Properties; -use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_config::Config; -use zenoh_core::{zasynclock, zasyncread, zasyncwrite}; -use zenoh_crypto::hmac; -use zenoh_result::{bail, zerror, ZResult}; - -const USRPWD_VERSION: ZInt = 1; - -/// # Attachment decorator -/// -/// ```text -/// The Attachment can decorate any message (i.e., TransportMessage and ZenohMessage) and it allows to -/// append to the message any additional information. Since the information contained in the -/// Attachement is relevant only to the layer that provided them (e.g., Transport, Zenoh, User) it -/// is the duty of that layer to serialize and de-serialize the attachment whenever deemed necessary. -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// | ENC | ATTCH | -/// +-+-+-+---------+ -/// ~ Attachment ~ -/// +---------------+ -/// -/// ENC values: -/// - 0x00 => Zenoh Properties -/// ``` - -/*************************************/ -/* InitSyn */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ version ~ -/// +---------------+ -struct InitSynProperty { - version: ZInt, -} - -impl WCodec<&InitSynProperty, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &InitSynProperty) -> Self::Output { - self.write(&mut *writer, x.version)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let version: ZInt = self.read(&mut *reader)?; - Ok(InitSynProperty { version }) - } -} - -/*************************************/ -/* InitAck */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ nonce ~ -/// +---------------+ -struct InitAckProperty { - nonce: ZInt, -} - -impl WCodec<&InitAckProperty, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &InitAckProperty) -> Self::Output { - self.write(&mut *writer, x.nonce)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let nonce: ZInt = self.read(&mut *reader)?; - Ok(InitAckProperty { nonce }) - } -} - -/*************************************/ -/* OpenSyn */ -/*************************************/ -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |0 0 0| ATTCH | -/// +-+-+-+---------+ -/// ~ user ~ -/// +---------------+ -/// ~ hash ~ -/// +---------------+ -struct OpenSynProperty { - user: Vec, - hmac: Vec, -} - -impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &OpenSynProperty) -> Self::Output { - self.write(&mut *writer, x.user.as_slice())?; - self.write(&mut *writer, x.hmac.as_slice())?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let user: Vec = self.read(&mut *reader)?; - let hmac: Vec = self.read(&mut *reader)?; - Ok(OpenSynProperty { user, hmac }) - } -} - -/*************************************/ -/* Authenticator */ -/*************************************/ -struct Credentials { - user: Vec, - password: Vec, -} - -struct Authenticated { - credentials: Credentials, - links: HashSet<(Locator, Locator)>, -} - -pub struct UserPasswordAuthenticator { - lookup: RwLock, Vec>>, - credentials: Option, - authenticated: Mutex>, -} - -impl UserPasswordAuthenticator { - pub fn new( - lookup: HashMap, Vec>, - mut credentials: Option<(Vec, Vec)>, - ) -> UserPasswordAuthenticator { - let credentials = credentials.take().map(|cr| Credentials { - user: cr.0, - password: cr.1, - }); - UserPasswordAuthenticator { - lookup: RwLock::new(lookup), - credentials, - authenticated: Mutex::new(HashMap::new()), - } - } - - pub async fn add_user(&self, user: Vec, password: Vec) -> ZResult<()> { - let mut guard = zasyncwrite!(self.lookup); - guard.insert(user, password); - Ok(()) - } - - pub async fn del_user(&self, user: &[u8]) -> ZResult<()> { - let mut guard = zasyncwrite!(self.lookup); - guard.remove(user); - Ok(()) - } - - pub async fn from_config(config: &Config) -> ZResult> { - let c = config.transport().auth().usrpwd(); - - let mut lookup: HashMap, Vec> = HashMap::new(); - if let Some(dict) = c.dictionary_file() { - let content = fs::read_to_string(dict) - .await - .map_err(|e| zerror!("Invalid user-password dictionary file: {}", e))?; - // Populate the user-password dictionary - let mut ps = Properties::from(content); - for (user, password) in ps.drain() { - lookup.insert(user.into(), password.into()); - } - log::debug!("User-password dictionary has been configured"); - } - - let mut credentials: Option<(Vec, Vec)> = None; - if let Some(user) = c.user() { - if let Some(password) = c.password() { - log::debug!("User and password have been configured"); - credentials = Some((user.to_string().into(), password.to_string().into())); - } - } - - if !lookup.is_empty() || credentials.is_some() { - log::debug!("User-password authentication is enabled"); - Ok(Some(UserPasswordAuthenticator::new(lookup, credentials))) - } else { - Ok(None) - } - } -} - -#[async_trait] -impl TransportAuthenticatorTrait for UserPasswordAuthenticator { - fn id(&self) -> ZNodeAuthenticatorId { - ZNodeAuthenticatorId::UserPassword - } - - async fn close(&self) { - // No cleanup needed - } - - async fn get_init_syn_properties( - &self, - link: &AuthenticatedLink, - _node_id: &ZenohId, - ) -> ZResult>> { - // If credentials are not configured, don't initiate the USRPWD authentication - if self.credentials.is_none() { - return Ok(None); - } - - let init_syn_property = InitSynProperty { - version: USRPWD_VERSION, - }; - let mut wbuf = vec![]; - let codec = Zenoh080::new(); - let mut writer = wbuf.writer(); - codec - .write(&mut writer, &init_syn_property) - .map_err(|_| zerror!("Error in encoding InitSyn for UsrPwd on link: {}", link))?; - let attachment = wbuf; - - Ok(Some(attachment)) - } - - async fn handle_init_syn( - &self, - link: &AuthenticatedLink, - cookie: &Cookie, - property: Option>, - ) -> ZResult<(Option>, Option>)> { - let p = property.ok_or_else(|| { - zerror!( - "Received InitSyn with no UsrPwd attachment on link: {}", - link - ) - })?; - - let codec = Zenoh080::new(); - - let mut reader = p.reader(); - let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { - zerror!( - "Received InitSyn with invalid UsrPwd attachment on link: {}", - link - ) - })?; - if init_syn_property.version > USRPWD_VERSION { - bail!("Rejected InitSyn with invalid attachment on link: {}", link) - } - - // Create the InitAck attachment - let init_ack_property = InitAckProperty { - nonce: cookie.nonce, - }; - let mut wbuf = vec![]; - let mut writer = wbuf.writer(); - codec - .write(&mut writer, &init_ack_property) - .map_err(|_| zerror!("Error in encoding InitAck for UsrPwd on link: {}", link))?; - let attachment = wbuf; - - Ok((Some(attachment), None)) - } - - async fn handle_init_ack( - &self, - link: &AuthenticatedLink, - _node_id: &ZenohId, - _sn_resolution: ZInt, - property: Option>, - ) -> ZResult>> { - // If credentials are not configured, don't continue the USRPWD authentication - let credentials = match self.credentials.as_ref() { - Some(cr) => cr, - None => return Ok(None), - }; - - let p = property.ok_or_else(|| { - zerror!( - "Received InitAck with no UsrPwd attachment on link: {}", - link - ) - })?; - - let codec = Zenoh080::new(); - - let mut reader = p.reader(); - let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { - zerror!( - "Received InitAck with invalid UsrPwd attachment on link: {}", - link - ) - })?; - - // Create the HMAC of the password using the nonce received as a key (it's a challenge) - let key = init_ack_property.nonce.to_le_bytes(); - let hmac = hmac::sign(&key, &credentials.password)?; - // Create the OpenSyn attachment - let open_syn_property = OpenSynProperty { - user: credentials.user.clone(), - hmac, - }; - // Encode the InitAck attachment - let mut wbuf = vec![]; - let mut writer = wbuf.writer(); - codec - .write(&mut writer, &open_syn_property) - .map_err(|_| zerror!("Error in encoding OpenSyn for UsrPwd on link: {}", link))?; - let attachment = wbuf; - - Ok(Some(attachment)) - } - - async fn handle_open_syn( - &self, - link: &AuthenticatedLink, - cookie: &Cookie, - property: (Option>, Option>), - ) -> ZResult>> { - let (attachment, _cookie) = property; - let a = attachment.ok_or_else(|| { - zerror!( - "Received OpenSyn with no UsrPwd attachment on link: {}", - link - ) - })?; - - let codec = Zenoh080::new(); - - let mut reader = a.reader(); - let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { - zerror!( - "Received OpenSyn with invalid UsrPwd attachment on link: {}", - link - ) - })?; - let password = match zasyncread!(self.lookup).get(&open_syn_property.user) { - Some(password) => password.clone(), - None => bail!("Received OpenSyn with invalid user on link: {}", link), - }; - - // Create the HMAC of the password using the nonce received as challenge - let key = cookie.nonce.to_le_bytes(); - let hmac = hmac::sign(&key, &password)?; - if hmac != open_syn_property.hmac { - bail!("Received OpenSyn with invalid password on link: {}", link) - } - - // Check PID validity - let mut guard = zasynclock!(self.authenticated); - match guard.get_mut(&cookie.zid) { - Some(auth) => { - if open_syn_property.user != auth.credentials.user - || password != auth.credentials.password - { - bail!("Received OpenSyn with invalid password on link: {}", link) - } - auth.links.insert((link.src.clone(), link.dst.clone())); - } - None => { - let credentials = Credentials { - user: open_syn_property.user, - password, - }; - let mut links = HashSet::new(); - links.insert((link.src.clone(), link.dst.clone())); - let auth = Authenticated { credentials, links }; - guard.insert(cookie.zid, auth); - } - } - - Ok(None) - } - - async fn handle_open_ack( - &self, - _link: &AuthenticatedLink, - _property: Option>, - ) -> ZResult>> { - Ok(None) - } - - async fn handle_link_err(&self, link: &AuthenticatedLink) { - // Need to check if it authenticated and remove it if this is the last link - let mut guard = zasynclock!(self.authenticated); - let mut to_del: Option = None; - for (node_id, auth) in guard.iter_mut() { - auth.links.remove(&(link.src.clone(), link.dst.clone())); - if auth.links.is_empty() { - to_del = Some(*node_id); - break; - } - } - if let Some(node_id) = to_del.take() { - guard.remove(&node_id); - } - } - - async fn handle_close(&self, node_id: &ZenohId) { - zasynclock!(self.authenticated).remove(node_id); - } -} - -//noinspection ALL -impl From> for TransportAuthenticator { - fn from(v: Arc) -> TransportAuthenticator { - TransportAuthenticator(v) - } -} - -impl From for TransportAuthenticator { - fn from(v: UserPasswordAuthenticator) -> TransportAuthenticator { - Self::from(Arc::new(v)) - } -} diff --git a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/usrpwd.rs new file mode 100644 index 0000000000..11772a8c4e --- /dev/null +++ b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/usrpwd.rs @@ -0,0 +1,476 @@ +// // +// // Copyright (c) 2022 ZettaScale Technology +// // +// // This program and the accompanying materials are made available under the +// // terms of the Eclipse Public License 2.0 which is available at +// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// // which is available at https://www.apache.org/licenses/LICENSE-2.0. +// // +// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// // +// // Contributors: +// // ZettaScale Zenoh Team, +// // +// use super::{ +// AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, +// }; +// use super::{Locator, ZInt, ZenohId}; +// use crate::unicast::establishment::Cookie; +// use async_std::fs; +// use async_std::sync::{Mutex, RwLock}; +// use async_trait::async_trait; +// use std::collections::{HashMap, HashSet}; +// use std::sync::Arc; +// use zenoh_buffers::{ +// reader::{DidntRead, HasReader, Reader}, +// writer::{DidntWrite, HasWriter, Writer}, +// }; +// use zenoh_cfg_properties::Properties; +// use zenoh_codec::{RCodec, WCodec, Zenoh080}; +// use zenoh_config::Config; +// use zenoh_core::{zasynclock, zasyncread, zasyncwrite}; +// use zenoh_crypto::hmac; +// use zenoh_result::{bail, zerror, ZResult}; + +// const USRPWD_VERSION: ZInt = 1; + +// /// # Attachment decorator +// /// +// /// ```text +// /// The Attachment can decorate any message (i.e., TransportMessage and ZenohMessage) and it allows to +// /// append to the message any additional information. Since the information contained in the +// /// Attachement is relevant only to the layer that provided them (e.g., Transport, Zenoh, User) it +// /// is the duty of that layer to serialize and de-serialize the attachment whenever deemed necessary. +// /// +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// | ENC | ATTCH | +// /// +-+-+-+---------+ +// /// ~ Attachment ~ +// /// +---------------+ +// /// +// /// ENC values: +// /// - 0x00 => Zenoh Properties +// /// ``` + +// /*************************************/ +// /* InitSyn */ +// /*************************************/ +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// |0 0 0| ATTCH | +// /// +-+-+-+---------+ +// /// ~ version ~ +// /// +---------------+ +// struct InitSynProperty { +// version: ZInt, +// } + +// impl WCodec<&InitSynProperty, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; + +// fn write(self, writer: &mut W, x: &InitSynProperty) -> Self::Output { +// self.write(&mut *writer, x.version)?; +// Ok(()) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let version: ZInt = self.read(&mut *reader)?; +// Ok(InitSynProperty { version }) +// } +// } + +// /*************************************/ +// /* InitAck */ +// /*************************************/ +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// |0 0 0| ATTCH | +// /// +-+-+-+---------+ +// /// ~ nonce ~ +// /// +---------------+ +// struct InitAckProperty { +// nonce: ZInt, +// } + +// impl WCodec<&InitAckProperty, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; + +// fn write(self, writer: &mut W, x: &InitAckProperty) -> Self::Output { +// self.write(&mut *writer, x.nonce)?; +// Ok(()) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let nonce: ZInt = self.read(&mut *reader)?; +// Ok(InitAckProperty { nonce }) +// } +// } + +// /*************************************/ +// /* OpenSyn */ +// /*************************************/ +// /// 7 6 5 4 3 2 1 0 +// /// +-+-+-+-+-+-+-+-+ +// /// |0 0 0| ATTCH | +// /// +-+-+-+---------+ +// /// ~ user ~ +// /// +---------------+ +// /// ~ hash ~ +// /// +---------------+ +// struct OpenSynProperty { +// user: Vec, +// hmac: Vec, +// } + +// impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 +// where +// W: Writer, +// { +// type Output = Result<(), DidntWrite>; + +// fn write(self, writer: &mut W, x: &OpenSynProperty) -> Self::Output { +// self.write(&mut *writer, x.user.as_slice())?; +// self.write(&mut *writer, x.hmac.as_slice())?; +// Ok(()) +// } +// } + +// impl RCodec for Zenoh080 +// where +// R: Reader, +// { +// type Error = DidntRead; + +// fn read(self, reader: &mut R) -> Result { +// let user: Vec = self.read(&mut *reader)?; +// let hmac: Vec = self.read(&mut *reader)?; +// Ok(OpenSynProperty { user, hmac }) +// } +// } + +// /*************************************/ +// /* Authenticator */ +// /*************************************/ +// struct Credentials { +// user: Vec, +// password: Vec, +// } + +// struct Authenticated { +// credentials: Credentials, +// links: HashSet<(Locator, Locator)>, +// } + +// pub struct UserPasswordAuthenticator { +// lookup: RwLock, Vec>>, +// credentials: Option, +// authenticated: Mutex>, +// } + +// impl UserPasswordAuthenticator { +// pub fn new( +// lookup: HashMap, Vec>, +// mut credentials: Option<(Vec, Vec)>, +// ) -> UserPasswordAuthenticator { +// let credentials = credentials.take().map(|cr| Credentials { +// user: cr.0, +// password: cr.1, +// }); +// UserPasswordAuthenticator { +// lookup: RwLock::new(lookup), +// credentials, +// authenticated: Mutex::new(HashMap::new()), +// } +// } + +// pub async fn add_user(&self, user: Vec, password: Vec) -> ZResult<()> { +// let mut guard = zasyncwrite!(self.lookup); +// guard.insert(user, password); +// Ok(()) +// } + +// pub async fn del_user(&self, user: &[u8]) -> ZResult<()> { +// let mut guard = zasyncwrite!(self.lookup); +// guard.remove(user); +// Ok(()) +// } + +// pub async fn from_config(config: &Config) -> ZResult> { +// let c = config.transport().auth().usrpwd(); + +// let mut lookup: HashMap, Vec> = HashMap::new(); +// if let Some(dict) = c.dictionary_file() { +// let content = fs::read_to_string(dict) +// .await +// .map_err(|e| zerror!("Invalid user-password dictionary file: {}", e))?; +// // Populate the user-password dictionary +// let mut ps = Properties::from(content); +// for (user, password) in ps.drain() { +// lookup.insert(user.into(), password.into()); +// } +// log::debug!("User-password dictionary has been configured"); +// } + +// let mut credentials: Option<(Vec, Vec)> = None; +// if let Some(user) = c.user() { +// if let Some(password) = c.password() { +// log::debug!("User and password have been configured"); +// credentials = Some((user.to_string().into(), password.to_string().into())); +// } +// } + +// if !lookup.is_empty() || credentials.is_some() { +// log::debug!("User-password authentication is enabled"); +// Ok(Some(UserPasswordAuthenticator::new(lookup, credentials))) +// } else { +// Ok(None) +// } +// } +// } + +// #[async_trait] +// impl TransportAuthenticatorTrait for UserPasswordAuthenticator { +// fn id(&self) -> ZNodeAuthenticatorId { +// ZNodeAuthenticatorId::UserPassword +// } + +// async fn close(&self) { +// // No cleanup needed +// } + +// async fn get_init_syn_properties( +// &self, +// link: &AuthenticatedLink, +// _node_id: &ZenohId, +// ) -> ZResult>> { +// // If credentials are not configured, don't initiate the USRPWD authentication +// if self.credentials.is_none() { +// return Ok(None); +// } + +// let init_syn_property = InitSynProperty { +// version: USRPWD_VERSION, +// }; +// let mut wbuf = vec![]; +// let codec = Zenoh080::new(); +// let mut writer = wbuf.writer(); +// codec +// .write(&mut writer, &init_syn_property) +// .map_err(|_| zerror!("Error in encoding InitSyn for UsrPwd on link: {}", link))?; +// let attachment = wbuf; + +// Ok(Some(attachment)) +// } + +// async fn handle_init_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: Option>, +// ) -> ZResult<(Option>, Option>)> { +// let p = property.ok_or_else(|| { +// zerror!( +// "Received InitSyn with no UsrPwd attachment on link: {}", +// link +// ) +// })?; + +// let codec = Zenoh080::new(); + +// let mut reader = p.reader(); +// let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received InitSyn with invalid UsrPwd attachment on link: {}", +// link +// ) +// })?; +// if init_syn_property.version > USRPWD_VERSION { +// bail!("Rejected InitSyn with invalid attachment on link: {}", link) +// } + +// // Create the InitAck attachment +// let init_ack_property = InitAckProperty { +// nonce: cookie.nonce, +// }; +// let mut wbuf = vec![]; +// let mut writer = wbuf.writer(); +// codec +// .write(&mut writer, &init_ack_property) +// .map_err(|_| zerror!("Error in encoding InitAck for UsrPwd on link: {}", link))?; +// let attachment = wbuf; + +// Ok((Some(attachment), None)) +// } + +// async fn handle_init_ack( +// &self, +// link: &AuthenticatedLink, +// _node_id: &ZenohId, +// _sn_resolution: ZInt, +// property: Option>, +// ) -> ZResult>> { +// // If credentials are not configured, don't continue the USRPWD authentication +// let credentials = match self.credentials.as_ref() { +// Some(cr) => cr, +// None => return Ok(None), +// }; + +// let p = property.ok_or_else(|| { +// zerror!( +// "Received InitAck with no UsrPwd attachment on link: {}", +// link +// ) +// })?; + +// let codec = Zenoh080::new(); + +// let mut reader = p.reader(); +// let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received InitAck with invalid UsrPwd attachment on link: {}", +// link +// ) +// })?; + +// // Create the HMAC of the password using the nonce received as a key (it's a challenge) +// let key = init_ack_property.nonce.to_le_bytes(); +// let hmac = hmac::sign(&key, &credentials.password)?; +// // Create the OpenSyn attachment +// let open_syn_property = OpenSynProperty { +// user: credentials.user.clone(), +// hmac, +// }; +// // Encode the InitAck attachment +// let mut wbuf = vec![]; +// let mut writer = wbuf.writer(); +// codec +// .write(&mut writer, &open_syn_property) +// .map_err(|_| zerror!("Error in encoding OpenSyn for UsrPwd on link: {}", link))?; +// let attachment = wbuf; + +// Ok(Some(attachment)) +// } + +// async fn handle_open_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: (Option>, Option>), +// ) -> ZResult>> { +// let (attachment, _cookie) = property; +// let a = attachment.ok_or_else(|| { +// zerror!( +// "Received OpenSyn with no UsrPwd attachment on link: {}", +// link +// ) +// })?; + +// let codec = Zenoh080::new(); + +// let mut reader = a.reader(); +// let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received OpenSyn with invalid UsrPwd attachment on link: {}", +// link +// ) +// })?; +// let password = match zasyncread!(self.lookup).get(&open_syn_property.user) { +// Some(password) => password.clone(), +// None => bail!("Received OpenSyn with invalid user on link: {}", link), +// }; + +// // Create the HMAC of the password using the nonce received as challenge +// let key = cookie.nonce.to_le_bytes(); +// let hmac = hmac::sign(&key, &password)?; +// if hmac != open_syn_property.hmac { +// bail!("Received OpenSyn with invalid password on link: {}", link) +// } + +// // Check PID validity +// let mut guard = zasynclock!(self.authenticated); +// match guard.get_mut(&cookie.zid) { +// Some(auth) => { +// if open_syn_property.user != auth.credentials.user +// || password != auth.credentials.password +// { +// bail!("Received OpenSyn with invalid password on link: {}", link) +// } +// auth.links.insert((link.src.clone(), link.dst.clone())); +// } +// None => { +// let credentials = Credentials { +// user: open_syn_property.user, +// password, +// }; +// let mut links = HashSet::new(); +// links.insert((link.src.clone(), link.dst.clone())); +// let auth = Authenticated { credentials, links }; +// guard.insert(cookie.zid, auth); +// } +// } + +// Ok(None) +// } + +// async fn handle_open_ack( +// &self, +// _link: &AuthenticatedLink, +// _property: Option>, +// ) -> ZResult>> { +// Ok(None) +// } + +// async fn handle_link_err(&self, link: &AuthenticatedLink) { +// // Need to check if it authenticated and remove it if this is the last link +// let mut guard = zasynclock!(self.authenticated); +// let mut to_del: Option = None; +// for (node_id, auth) in guard.iter_mut() { +// auth.links.remove(&(link.src.clone(), link.dst.clone())); +// if auth.links.is_empty() { +// to_del = Some(*node_id); +// break; +// } +// } +// if let Some(node_id) = to_del.take() { +// guard.remove(&node_id); +// } +// } + +// async fn handle_close(&self, node_id: &ZenohId) { +// zasynclock!(self.authenticated).remove(node_id); +// } +// } + +// //noinspection ALL +// impl From> for TransportAuthenticator { +// fn from(v: Arc) -> TransportAuthenticator { +// TransportAuthenticator(v) +// } +// } + +// impl From for TransportAuthenticator { +// fn from(v: UserPasswordAuthenticator) -> TransportAuthenticator { +// Self::from(Arc::new(v)) +// } +// } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs index 403a9bbd77..169faa461f 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // -// pub(crate) mod authenticator; +// pub(crate) mod auth; pub(crate) mod qos; #[cfg(feature = "shared-memory")] pub(crate) mod shm; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs index 34d5b2dba4..872479ecd0 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs @@ -13,6 +13,7 @@ // use crate::unicast::establishment::{AcceptFsm, OpenFsm}; use async_trait::async_trait; +use core::marker::PhantomData; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -64,11 +65,13 @@ where } // Extension Fsm -pub(crate) struct QoS; +pub(crate) struct QoS<'a> { + _a: PhantomData<&'a ()>, +} -impl QoS { +impl<'a> QoS<'a> { pub(crate) const fn new() -> Self { - Self + Self { _a: PhantomData } } } @@ -76,45 +79,45 @@ impl QoS { /* OPEN */ /*************************************/ #[async_trait] -impl<'a> OpenFsm<'a> for QoS { +impl<'a> OpenFsm for QoS<'a> { type Error = ZError; - type InitSynIn = &'a State; - type InitSynOut = Option; + type SendInitSynIn = &'a State; + type SendInitSynOut = Option; async fn send_init_syn( - &'a self, - state: Self::InitSynIn, - ) -> Result { + &self, + state: Self::SendInitSynIn, + ) -> Result { let output = state.is_qos.then_some(init::ext::QoS::new()); Ok(output) } - type InitAckIn = (&'a mut State, Option); - type InitAckOut = (); + type RecvInitAckIn = (&'a mut State, Option); + type RecvInitAckOut = (); async fn recv_init_ack( - &'a self, - input: Self::InitAckIn, - ) -> Result { + &self, + input: Self::RecvInitAckIn, + ) -> Result { let (state, other_ext) = input; state.is_qos &= other_ext.is_some(); Ok(()) } - type OpenSynIn = &'a State; - type OpenSynOut = Option; + type SendOpenSynIn = &'a State; + type SendOpenSynOut = Option; async fn send_open_syn( - &'a self, - _state: Self::OpenSynIn, - ) -> Result { + &self, + _state: Self::SendOpenSynIn, + ) -> Result { Ok(None) } - type OpenAckIn = (&'a mut State, Option); - type OpenAckOut = (); + type RecvOpenAckIn = (&'a mut State, Option); + type RecvOpenAckOut = (); async fn recv_open_ack( - &'a self, - _state: Self::OpenAckIn, - ) -> Result { + &self, + _state: Self::RecvOpenAckIn, + ) -> Result { Ok(()) } } @@ -123,45 +126,45 @@ impl<'a> OpenFsm<'a> for QoS { /* ACCEPT */ /*************************************/ #[async_trait] -impl<'a> AcceptFsm<'a> for QoS { +impl<'a> AcceptFsm for QoS<'a> { type Error = ZError; - type InitSynIn = (&'a mut State, Option); - type InitSynOut = (); + type RecvInitSynIn = (&'a mut State, Option); + type RecvInitSynOut = (); async fn recv_init_syn( - &'a self, - input: Self::InitSynIn, - ) -> Result { + &self, + input: Self::RecvInitSynIn, + ) -> Result { let (state, other_ext) = input; state.is_qos &= other_ext.is_some(); Ok(()) } - type InitAckIn = &'a State; - type InitAckOut = Option; + type SendInitAckIn = &'a State; + type SendInitAckOut = Option; async fn send_init_ack( - &'a self, - state: Self::InitAckIn, - ) -> Result { + &self, + state: Self::SendInitAckIn, + ) -> Result { let output = state.is_qos.then_some(init::ext::QoS::new()); Ok(output) } - type OpenSynIn = (&'a mut State, Option); - type OpenSynOut = (); + type RecvOpenSynIn = (&'a mut State, Option); + type RecvOpenSynOut = (); async fn recv_open_syn( - &'a self, - _state: Self::OpenSynIn, - ) -> Result { + &self, + _state: Self::RecvOpenSynIn, + ) -> Result { Ok(()) } - type OpenAckIn = &'a State; - type OpenAckOut = Option; + type SendOpenAckIn = &'a State; + type SendOpenAckOut = Option; async fn send_open_ack( - &'a self, - _state: Self::OpenAckIn, - ) -> Result { + &self, + _state: Self::SendOpenAckIn, + ) -> Result { Ok(None) } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index 277c0fec51..f0c4b1959e 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -180,15 +180,15 @@ impl<'a> Shm<'a> { } #[async_trait] -impl<'a> OpenFsm<'a> for Shm<'a> { +impl<'a> OpenFsm for Shm<'a> { type Error = ZError; - type InitSynIn = &'a State; - type InitSynOut = Option; + type SendInitSynIn = &'a State; + type SendInitSynOut = Option; async fn send_init_syn( - &'a self, - state: Self::InitSynIn, - ) -> Result { + &self, + state: Self::SendInitSynIn, + ) -> Result { const S: &str = "Shm extension - Send InitSyn."; if !state.is_shm() { @@ -209,12 +209,12 @@ impl<'a> OpenFsm<'a> for Shm<'a> { Ok(Some(init::ext::Shm::new(buff.into()))) } - type InitAckIn = (&'a mut State, Option); - type InitAckOut = Challenge; + type RecvInitAckIn = (&'a mut State, Option); + type RecvInitAckOut = Challenge; async fn recv_init_ack( - &'a self, - input: Self::InitAckIn, - ) -> Result { + &self, + input: Self::RecvInitAckIn, + ) -> Result { const S: &str = "Shm extension - Recv InitAck."; let (state, mut ext) = input; @@ -281,12 +281,12 @@ impl<'a> OpenFsm<'a> for Shm<'a> { Ok(bob_challenge) } - type OpenSynIn = (&'a State, Self::InitAckOut); - type OpenSynOut = Option; + type SendOpenSynIn = (&'a State, Self::RecvInitAckOut); + type SendOpenSynOut = Option; async fn send_open_syn( - &'a self, - input: Self::OpenSynIn, - ) -> Result { + &self, + input: Self::SendOpenSynIn, + ) -> Result { const S: &str = "Shm extension - Send OpenSyn."; let (state, bob_challenge) = input; @@ -297,12 +297,12 @@ impl<'a> OpenFsm<'a> for Shm<'a> { Ok(Some(open::ext::Shm::new(bob_challenge))) } - type OpenAckIn = (&'a mut State, Option); - type OpenAckOut = (); + type RecvOpenAckIn = (&'a mut State, Option); + type RecvOpenAckOut = (); async fn recv_open_ack( - &'a self, - input: Self::OpenAckIn, - ) -> Result { + &self, + input: Self::RecvOpenAckIn, + ) -> Result { const S: &str = "Shm extension - Recv OpenAck."; let (state, mut ext) = input; @@ -330,15 +330,15 @@ impl<'a> OpenFsm<'a> for Shm<'a> { /* ACCEPT */ /*************************************/ #[async_trait] -impl<'a> AcceptFsm<'a> for Shm<'a> { +impl<'a> AcceptFsm for Shm<'a> { type Error = ZError; - type InitSynIn = (&'a mut State, Option); - type InitSynOut = Challenge; + type RecvInitSynIn = (&'a mut State, Option); + type RecvInitSynOut = Challenge; async fn recv_init_syn( - &'a self, - input: Self::InitSynIn, - ) -> Result { + &self, + input: Self::RecvInitSynIn, + ) -> Result { const S: &str = "Shm extension - Recv InitSyn."; let (state, mut ext) = input; @@ -384,12 +384,12 @@ impl<'a> AcceptFsm<'a> for Shm<'a> { Ok(alice_challenge) } - type InitAckIn = (&'a State, Self::InitSynOut); - type InitAckOut = Option; + type SendInitAckIn = (&'a State, Self::RecvInitSynOut); + type SendInitAckOut = Option; async fn send_init_ack( - &'a self, - input: Self::InitAckIn, - ) -> Result { + &self, + input: Self::SendInitAckIn, + ) -> Result { const S: &str = "Shm extension - Send InitAck."; let (state, alice_challenge) = input; @@ -412,12 +412,12 @@ impl<'a> AcceptFsm<'a> for Shm<'a> { Ok(Some(init::ext::Shm::new(buff.into()))) } - type OpenSynIn = (&'a mut State, Option); - type OpenSynOut = (); + type RecvOpenSynIn = (&'a mut State, Option); + type RecvOpenSynOut = (); async fn recv_open_syn( - &'a self, - input: Self::OpenSynIn, - ) -> Result { + &self, + input: Self::RecvOpenSynIn, + ) -> Result { const S: &str = "Shm extension - Recv OpenSyn."; let (state, mut ext) = input; @@ -455,12 +455,12 @@ impl<'a> AcceptFsm<'a> for Shm<'a> { Ok(()) } - type OpenAckIn = &'a mut State; - type OpenAckOut = Option; + type SendOpenAckIn = &'a mut State; + type SendOpenAckOut = Option; async fn send_open_ack( - &'a self, - state: Self::OpenAckIn, - ) -> Result { + &self, + state: Self::SendOpenAckIn, + ) -> Result { const S: &str = "Shm extension - Recv OpenSyn."; if !state.is_shm() { diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index f7d68ed8e1..ea2b58e370 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -36,69 +36,69 @@ use zenoh_result::ZResult; /* TRAITS */ /*************************************/ #[async_trait] -pub(crate) trait OpenFsm<'a> { +pub trait OpenFsm { type Error; - type InitSynIn; - type InitSynOut; + type SendInitSynIn; + type SendInitSynOut; async fn send_init_syn( - &'a self, - input: Self::InitSynIn, - ) -> Result; + &self, + input: Self::SendInitSynIn, + ) -> Result; - type InitAckIn; - type InitAckOut; + type RecvInitAckIn; + type RecvInitAckOut; async fn recv_init_ack( - &'a self, - input: Self::InitAckIn, - ) -> Result; + &self, + input: Self::RecvInitAckIn, + ) -> Result; - type OpenSynIn; - type OpenSynOut; + type SendOpenSynIn; + type SendOpenSynOut; async fn send_open_syn( - &'a self, - input: Self::OpenSynIn, - ) -> Result; + &self, + input: Self::SendOpenSynIn, + ) -> Result; - type OpenAckIn; - type OpenAckOut; + type RecvOpenAckIn; + type RecvOpenAckOut; async fn recv_open_ack( - &'a self, - input: Self::OpenAckIn, - ) -> Result; + &self, + input: Self::RecvOpenAckIn, + ) -> Result; } #[async_trait] -pub(crate) trait AcceptFsm<'a> { +pub trait AcceptFsm { type Error; - type InitSynIn; - type InitSynOut; + type RecvInitSynIn; + type RecvInitSynOut; async fn recv_init_syn( - &'a self, - input: Self::InitSynIn, - ) -> Result; + &self, + input: Self::RecvInitSynIn, + ) -> Result; - type InitAckIn; - type InitAckOut; + type SendInitAckIn; + type SendInitAckOut; async fn send_init_ack( - &'a self, - input: Self::InitAckIn, - ) -> Result; + &self, + input: Self::SendInitAckIn, + ) -> Result; - type OpenSynIn; - type OpenSynOut; + type RecvOpenSynIn; + type RecvOpenSynOut; async fn recv_open_syn( - &'a self, - input: Self::OpenSynIn, - ) -> Result; + &self, + input: Self::RecvOpenSynIn, + ) -> Result; - type OpenAckIn; - type OpenAckOut; + type SendOpenAckIn; + type SendOpenAckOut; async fn send_open_ack( - &'a self, - input: Self::OpenAckIn, - ) -> Result; + &self, + input: Self::SendOpenAckIn, + ) -> Result; } /*************************************/ diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 9e7164f9d3..72e55d6ba4 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -83,21 +83,21 @@ struct RecvOpenAckOut { // FSM struct OpenLink<'a> { link: &'a LinkUnicast, - ext_qos: ext::qos::QoS, + ext_qos: ext::qos::QoS<'a>, #[cfg(feature = "shared-memory")] ext_shm: ext::shm::Shm<'a>, } #[async_trait] -impl<'a> OpenFsm<'a> for OpenLink<'a> { +impl<'a> OpenFsm for OpenLink<'a> { type Error = OpenError; - type InitSynIn = (&'a mut State, SendInitSynIn); - type InitSynOut = (); + type SendInitSynIn = (&'a mut State, SendInitSynIn); + type SendInitSynOut = (); async fn send_init_syn( - &'a self, - input: Self::InitSynIn, - ) -> Result { + &self, + input: Self::SendInitSynIn, + ) -> Result { let (state, input) = input; // Extension QoS @@ -138,12 +138,12 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { Ok(()) } - type InitAckIn = &'a mut State; - type InitAckOut = RecvInitAckOut; + type RecvInitAckIn = &'a mut State; + type RecvInitAckOut = RecvInitAckOut; async fn recv_init_ack( - &'a self, - state: Self::InitAckIn, - ) -> Result { + &self, + state: Self::RecvInitAckIn, + ) -> Result { let msg = self .link .recv() @@ -241,12 +241,12 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { Ok(output) } - type OpenSynIn = (&'a mut State, SendOpenSynIn); - type OpenSynOut = SendOpenSynOut; + type SendOpenSynIn = (&'a mut State, SendOpenSynIn); + type SendOpenSynOut = SendOpenSynOut; async fn send_open_syn( - &'a self, - input: Self::OpenSynIn, - ) -> Result { + &self, + input: Self::SendOpenSynIn, + ) -> Result { let (state, input) = input; // Extension QoS @@ -288,12 +288,12 @@ impl<'a> OpenFsm<'a> for OpenLink<'a> { Ok(output) } - type OpenAckIn = &'a mut State; - type OpenAckOut = RecvOpenAckOut; + type RecvOpenAckIn = &'a mut State; + type RecvOpenAckOut = RecvOpenAckOut; async fn recv_open_ack( - &'a self, - state: Self::OpenAckIn, - ) -> Result { + &self, + state: Self::RecvOpenAckIn, + ) -> Result { let msg = self .link .recv() diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 410715f435..9ca8451459 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -49,7 +49,7 @@ pub struct TransportManagerStateUnicast { // Incoming uninitialized transports pub(super) incoming: Arc>, // Active peer authenticators - // pub(super) peer_authenticator: Arc>>, @TODO + // pub(super) peer_authenticator: Arc>>, @TODO // Established listeners pub(super) protocols: Arc>>, // Established transports From 43dffcfff5089252bd832fdcf9d099043d5fd98e Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 9 Mar 2023 12:33:44 +0100 Subject: [PATCH 063/203] Reintroduced UsrPwd auth --- Cargo.lock | 1 + commons/zenoh-buffers/src/lib.rs | 2 +- commons/zenoh-buffers/src/slice.rs | 2 +- commons/zenoh-buffers/src/zbuf.rs | 32 +- commons/zenoh-buffers/tests/readwrite.rs | 35 +- commons/zenoh-codec/benches/codec.rs | 8 +- commons/zenoh-codec/src/common/extension.rs | 87 +-- commons/zenoh-codec/src/core/zbuf.rs | 4 +- commons/zenoh-codec/tests/codec.rs | 10 +- commons/zenoh-config/src/lib.rs | 4 +- .../zenoh-protocol/src/common/extension.rs | 90 ++- commons/zenoh-protocol/src/transport/init.rs | 18 +- commons/zenoh-protocol/src/transport/open.rs | 12 +- io/zenoh-transport/Cargo.toml | 2 + io/zenoh-transport/src/common/batch.rs | 2 +- .../src/common/defragmentation.rs | 2 +- io/zenoh-transport/src/common/pipeline.rs | 2 +- .../src/unicast/establishment/accept.rs | 61 +- .../src/unicast/establishment/cookie.rs | 24 +- .../src/unicast/establishment/ext/auth/mod.rs | 621 ++++++++++++++++ .../ext/{authenticator => auth}/pubkey.rs | 0 .../unicast/establishment/ext/auth/usrpwd.rs | 612 +++++++++++++++ .../establishment/ext/authenticator/mod.rs | 291 -------- .../establishment/ext/authenticator/usrpwd.rs | 476 ------------ .../src/unicast/establishment/ext/mod.rs | 2 +- .../src/unicast/establishment/ext/qos.rs | 15 +- .../src/unicast/establishment/ext/shm.rs | 399 +--------- .../src/unicast/establishment/mod.rs | 2 +- .../src/unicast/establishment/open.rs | 45 +- .../src/unicast/establishment/properties.rs | 2 +- io/zenoh-transport/src/unicast/manager.rs | 38 +- .../tests/unicast_authenticator.rs | 698 ++++++++---------- io/zenoh-transport/tests/unicast_shm.rs | 10 +- zenoh/src/net/tests/tables.rs | 10 +- zenoh/src/value.rs | 2 +- 35 files changed, 1890 insertions(+), 1731 deletions(-) create mode 100644 io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs rename io/zenoh-transport/src/unicast/establishment/ext/{authenticator => auth}/pubkey.rs (100%) create mode 100644 io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs delete mode 100644 io/zenoh-transport/src/unicast/establishment/ext/authenticator/usrpwd.rs diff --git a/Cargo.lock b/Cargo.lock index ac1d6ffa3a..572fc11366 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4241,6 +4241,7 @@ dependencies = [ "zenoh-result", "zenoh-shm", "zenoh-sync", + "zenoh-transport", "zenoh-util", ] diff --git a/commons/zenoh-buffers/src/lib.rs b/commons/zenoh-buffers/src/lib.rs index a3c2f72649..7a108b7730 100644 --- a/commons/zenoh-buffers/src/lib.rs +++ b/commons/zenoh-buffers/src/lib.rs @@ -117,7 +117,7 @@ pub mod reader { pub struct DidntSiphon; pub trait SiphonableReader: Reader { - fn siphon(&mut self, writer: W) -> Result + fn siphon(&mut self, writer: &mut W) -> Result where W: crate::writer::Writer; } diff --git a/commons/zenoh-buffers/src/slice.rs b/commons/zenoh-buffers/src/slice.rs index 33e2002385..dd77997c9f 100644 --- a/commons/zenoh-buffers/src/slice.rs +++ b/commons/zenoh-buffers/src/slice.rs @@ -177,7 +177,7 @@ impl<'a> BacktrackableReader for &'a [u8] { } impl<'a> SiphonableReader for &'a [u8] { - fn siphon(&mut self, mut writer: W) -> Result + fn siphon(&mut self, writer: &mut W) -> Result where W: Writer, { diff --git a/commons/zenoh-buffers/src/zbuf.rs b/commons/zenoh-buffers/src/zbuf.rs index aabd34f9a3..430eb9400f 100644 --- a/commons/zenoh-buffers/src/zbuf.rs +++ b/commons/zenoh-buffers/src/zbuf.rs @@ -30,6 +30,10 @@ pub struct ZBuf { } impl ZBuf { + pub fn empty() -> Self { + Self::default() + } + pub fn clear(&mut self) { self.slices.clear(); } @@ -43,7 +47,9 @@ impl ZBuf { } pub fn push_zslice(&mut self, zslice: ZSlice) { - self.slices.push(zslice); + if !zslice.is_empty() { + self.slices.push(zslice); + } } } @@ -100,15 +106,21 @@ impl PartialEq for ZBuf { } // From impls +impl From for ZBuf { + fn from(zs: ZSlice) -> Self { + let mut zbuf = ZBuf::empty(); + zbuf.push_zslice(zs); + zbuf + } +} + impl From> for ZBuf where T: ZSliceBuffer + 'static, { fn from(buf: Arc) -> Self { let zs: ZSlice = buf.into(); - let mut zbuf = ZBuf::default(); - zbuf.push_zslice(zs); - zbuf + Self::from(zs) } } @@ -264,7 +276,7 @@ impl<'a> BacktrackableReader for ZBufReader<'a> { } impl<'a> SiphonableReader for ZBufReader<'a> { - fn siphon(&mut self, mut writer: W) -> Result + fn siphon(&mut self, writer: &mut W) -> Result where W: Writer, { @@ -487,7 +499,7 @@ impl BacktrackableWriter for ZBufWriter<'_> { #[cfg(feature = "test")] impl ZBuf { pub fn rand(len: usize) -> Self { - let mut zbuf = ZBuf::default(); + let mut zbuf = ZBuf::empty(); zbuf.push_zslice(ZSlice::rand(len)); zbuf } @@ -500,22 +512,22 @@ mod tests { let slice: ZSlice = [0u8, 1, 2, 3, 4, 5, 6, 7].to_vec().into(); - let mut zbuf1 = ZBuf::default(); + let mut zbuf1 = ZBuf::empty(); zbuf1.push_zslice(slice.new_sub_slice(0, 4).unwrap()); zbuf1.push_zslice(slice.new_sub_slice(4, 8).unwrap()); - let mut zbuf2 = ZBuf::default(); + let mut zbuf2 = ZBuf::empty(); zbuf2.push_zslice(slice.new_sub_slice(0, 1).unwrap()); zbuf2.push_zslice(slice.new_sub_slice(1, 4).unwrap()); zbuf2.push_zslice(slice.new_sub_slice(4, 8).unwrap()); assert_eq!(zbuf1, zbuf2); - let mut zbuf1 = ZBuf::default(); + let mut zbuf1 = ZBuf::empty(); zbuf1.push_zslice(slice.new_sub_slice(2, 4).unwrap()); zbuf1.push_zslice(slice.new_sub_slice(4, 8).unwrap()); - let mut zbuf2 = ZBuf::default(); + let mut zbuf2 = ZBuf::empty(); zbuf2.push_zslice(slice.new_sub_slice(2, 3).unwrap()); zbuf2.push_zslice(slice.new_sub_slice(3, 6).unwrap()); zbuf2.push_zslice(slice.new_sub_slice(6, 8).unwrap()); diff --git a/commons/zenoh-buffers/tests/readwrite.rs b/commons/zenoh-buffers/tests/readwrite.rs index b8da788bdf..5bf107fbb0 100644 --- a/commons/zenoh-buffers/tests/readwrite.rs +++ b/commons/zenoh-buffers/tests/readwrite.rs @@ -91,6 +91,18 @@ macro_rules! run_read { }; } +macro_rules! run_empty { + ($buffer:expr) => { + let mut s = [0u8; 64]; + + println!(">>> Read empty"); + let mut reader = $buffer.reader(); + assert!(reader.read_u8().is_err()); + assert!(reader.read(&mut s).is_err()); + assert!(reader.read_exact(&mut s).is_err()); + }; +} + macro_rules! run_bound { ($buffer:expr, $capacity:expr) => { println!(">>> Write bound"); @@ -127,8 +139,8 @@ macro_rules! run_siphon { while read < $fcap { $into.clear(); - let writer = $into.writer(); - let written = reader.siphon(writer).unwrap(); + let mut writer = $into.writer(); + let written = reader.siphon(&mut writer).unwrap(); let mut reader = $into.reader(); for i in read..read + written.get() { @@ -155,6 +167,7 @@ fn buffer_slice() { fn buffer_vec() { println!("Buffer Vec"); let mut vbuf = vec![]; + run_empty!(vbuf); run_write!(&mut vbuf); run_read!(&vbuf); } @@ -164,6 +177,7 @@ fn buffer_bbuf() { println!("Buffer BBuf"); let capacity = 1 + u8::MAX as usize; let mut bbuf = BBuf::with_capacity(capacity); + run_empty!(bbuf); run_write!(bbuf); run_read!(bbuf); @@ -175,9 +189,13 @@ fn buffer_bbuf() { #[test] fn buffer_zbuf() { println!("Buffer ZBuf"); - let mut zbuf = ZBuf::default(); + let mut zbuf = ZBuf::empty(); + run_empty!(zbuf); run_write!(zbuf); run_read!(zbuf); + + let zbuf = ZBuf::from(vec![]); + run_empty!(zbuf); } #[test] @@ -188,6 +206,9 @@ fn buffer_zslice() { let mut zslice = ZSlice::from(Arc::new(vbuf)); run_read!(zslice); + + let mut zslice = ZSlice::from(vec![]); + run_empty!(zslice); } #[test] @@ -200,12 +221,12 @@ fn buffer_siphon() { run_siphon!(bbuf1, capacity, bbuf2, capacity); println!("Buffer Siphon ZBuf({capacity}) -> ZBuf({capacity})"); - let mut zbuf1 = ZBuf::default(); - let mut zbuf2 = ZBuf::default(); + let mut zbuf1 = ZBuf::empty(); + let mut zbuf2 = ZBuf::empty(); run_siphon!(zbuf1, capacity, zbuf2, capacity); println!("Buffer Siphon ZBuf({capacity}) -> BBuf({capacity})"); - let mut zbuf1 = ZBuf::default(); + let mut zbuf1 = ZBuf::empty(); let mut bbuf1 = BBuf::with_capacity(capacity); run_siphon!(zbuf1, capacity, bbuf1, capacity); @@ -216,7 +237,7 @@ fn buffer_siphon() { run_siphon!(bbuf1, capacity, bbuf2, capacity2); println!("Buffer Siphon ZBuf({capacity}) -> BBuf({capacity2})"); - let mut zbuf1 = ZBuf::default(); + let mut zbuf1 = ZBuf::empty(); let mut bbuf1 = BBuf::with_capacity(capacity2); run_siphon!(zbuf1, capacity, bbuf1, capacity2); } diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 98d857cf52..757a0b7c14 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -56,7 +56,7 @@ fn criterion_benchmark(c: &mut Criterion) { }); // ZInt ZBuf - let mut buff = ZBuf::default(); + let mut buff = ZBuf::empty(); let codec = Zenoh080::new(); c.bench_function("ZInt ZBuf", |b| { b.iter(|| { @@ -176,7 +176,7 @@ fn criterion_benchmark(c: &mut Criterion) { }); // Fragmentation ZBuf Write - let mut buff = ZBuf::default(); + let mut buff = ZBuf::empty(); let codec = Zenoh080::new(); let data = Data { @@ -208,7 +208,7 @@ fn criterion_benchmark(c: &mut Criterion) { let mut writer = buff.writer(); codec.write(&mut writer, &data).unwrap(); - let mut zbuf = ZBuf::default(); + let mut zbuf = ZBuf::empty(); let chunk = u16::MAX as usize; let mut idx = 0; while idx < buff.len() { @@ -242,7 +242,7 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("Fragmentation ZSlice ZBuf Read", |b| { b.iter(|| { - let mut zbuf = ZBuf::default(); + let mut zbuf = ZBuf::empty(); let chunk = u16::MAX as usize; let mut idx = 0; while idx < zslice.len() { diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 25f2322fbe..4e9c641aa9 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -15,12 +15,10 @@ use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, - ZBuf, ZSlice, + ZBuf, }; use zenoh_protocol::{ - common::{ - iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtZInt, ZExtZSlice, ZExtensionBody, - }, + common::{iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtZInt, ZExtensionBody}, core::ZInt, }; @@ -117,54 +115,6 @@ where } } -impl WCodec<(&ZExtZSlice<{ ID }>, bool), &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: (&ZExtZSlice<{ ID }>, bool)) -> Self::Output { - let (x, more) = x; - let mut header: u8 = ID | iext::ENC_ZINT; - if more { - header |= iext::FLAG_Z; - } - self.write(&mut *writer, header)?; - self.write(&mut *writer, &x.value)?; - Ok(()) - } -} - -impl RCodec<(ZExtZSlice<{ ID }>, bool), &mut R> for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ZExtZSlice<{ ID }>, bool), Self::Error> { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - codec.read(&mut *reader) - } -} - -impl RCodec<(ZExtZSlice<{ ID }>, bool), &mut R> for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ZExtZSlice<{ ID }>, bool), Self::Error> { - if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZINT) { - return Err(DidntRead); - } - - let value: ZSlice = self.codec.read(&mut *reader)?; - - Ok((ZExtZSlice::new(value), has_flag(self.header, iext::FLAG_Z))) - } -} - impl WCodec<(&ZExtZBuf<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, @@ -287,3 +237,36 @@ where )) } } + +impl WCodec<&[ZExtUnknown], &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &[ZExtUnknown]) -> Self::Output { + let len = x.len(); + for (i, e) in x.iter().enumerate() { + self.write(&mut *writer, (e, i < len - 1))?; + } + Ok(()) + } +} + +impl RCodec, &mut R> for Zenoh080 +where + R: Reader + std::fmt::Debug, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result, Self::Error> { + let mut exts = vec![]; + let mut has_ext = reader.can_read(); + while has_ext { + let (e, more): (ZExtUnknown, bool) = self.read(&mut *reader)?; + exts.push(e); + has_ext = more; + } + Ok(exts) + } +} diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index b98af71ee4..44998d50fc 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -47,7 +47,7 @@ where fn read(self, reader: &mut R) -> Result { let len: usize = self.read(&mut *reader)?; - let mut zbuf = ZBuf::default(); + let mut zbuf = ZBuf::empty(); reader.read_zslices(len, |s| zbuf.push_zslice(s))?; Ok(zbuf) } @@ -93,7 +93,7 @@ where fn read(self, reader: &mut R) -> Result { let num: usize = self.codec.read(&mut *reader)?; - let mut zbuf = ZBuf::default(); + let mut zbuf = ZBuf::empty(); for _ in 0..num { let kind: u8 = self.codec.read(&mut *reader)?; match kind { diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 1a01b0bd9b..6248fde7e9 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -55,7 +55,7 @@ macro_rules! run_fragmented { let mut writer = vbuf.writer(); $wcode.write(&mut writer, &x).unwrap(); - let mut zbuf = ZBuf::default(); + let mut zbuf = ZBuf::empty(); let mut reader = vbuf.reader(); while let Ok(b) = reader.read_u8() { zbuf.push_zslice(vec![b].into()); @@ -81,7 +81,7 @@ macro_rules! run_buffers { run_single!($type, $rand, $wcode, $rcode, buffer); println!("ZBuf: codec {}", std::any::type_name::<$type>()); - let mut buffer = ZBuf::default(); + let mut buffer = ZBuf::empty(); run_single!($type, $rand, $wcode, $rcode, buffer); println!("ZSlice: codec {}", std::any::type_name::<$type>()); @@ -157,7 +157,7 @@ fn codec_zid() { fn codec_zbuf() { run!( ZBuf, - ZBuf::rand(thread_rng().gen_range(1..=MAX_PAYLOAD_SIZE)) + ZBuf::rand(thread_rng().gen_range(0..=MAX_PAYLOAD_SIZE)) ); } @@ -238,14 +238,14 @@ fn codec_extension() { run_extension_single!($type, buff); println!("ZBuf: codec {}", std::any::type_name::<$type>()); - let mut buff = ZBuf::default(); + let mut buff = ZBuf::empty(); run_extension_single!($type, buff); }; } run_extension!(ZExtUnit<0>); run_extension!(ZExtZInt<1>); - run_extension!(ZExtZSlice<2>); + run_extension!(ZExtZBuf<2>); run_extension!(ZExtZBuf<3>); run_extension!(ZExtUnknown); } diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 4c78ba8de0..46b2c1a888 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -293,7 +293,7 @@ validated_struct::validator! { /// The configuration of authentification. /// A password implies a username is required. pub usrpwd: #[derive(Default)] - UserConf { + UsrPwdConf { user: Option, password: Option, /// The path to a file containing the user password dictionary, a file containing `:` @@ -762,7 +762,7 @@ fn queue_size_validator(q: &QueueSizeConf) -> bool { && check(background) } -fn user_conf_validator(u: &UserConf) -> bool { +fn user_conf_validator(u: &UsrPwdConf) -> bool { (u.password().is_none() && u.user().is_none()) || (u.password().is_some() && u.user().is_some()) } diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index 54bcc70cf3..a4e4c07159 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -12,7 +12,8 @@ // ZettaScale Zenoh Team, // use crate::core::ZInt; -use zenoh_buffers::{ZBuf, ZSlice}; +use core::convert::TryFrom; +use zenoh_buffers::ZBuf; /// # Zenoh extensions /// @@ -62,6 +63,8 @@ pub mod iext { pub const FLAG_Z: u8 = 1 << 7; } +pub struct DidntConvert; + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ZExtUnit; @@ -78,6 +81,20 @@ impl ZExtUnit<{ ID }> { } } +impl TryFrom for ZExtUnit<{ ID }> { + type Error = DidntConvert; + + fn try_from(v: ZExtUnknown) -> Result { + if v.id != ID { + return Err(DidntConvert); + } + match v.body { + ZExtensionBody::Unit => Ok(Self::new()), + _ => Err(DidntConvert), + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ZExtZInt { pub value: ZInt, @@ -100,25 +117,17 @@ impl ZExtZInt<{ ID }> { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ZExtZSlice { - pub value: ZSlice, -} - -impl ZExtZSlice<{ ID }> { - pub const ID: u8 = ID; - - pub const fn new(value: ZSlice) -> Self { - Self { value } - } - - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - let value = ZSlice::rand(rng.gen_range(8..=64)); - Self { value } +impl TryFrom for ZExtZInt<{ ID }> { + type Error = DidntConvert; + + fn try_from(v: ZExtUnknown) -> Result { + if v.id != ID { + return Err(DidntConvert); + } + match v.body { + ZExtensionBody::ZInt(v) => Ok(Self::new(v)), + _ => Err(DidntConvert), + } } } @@ -144,6 +153,20 @@ impl ZExtZBuf<{ ID }> { } } +impl TryFrom for ZExtZBuf<{ ID }> { + type Error = DidntConvert; + + fn try_from(v: ZExtUnknown) -> Result { + if v.id != ID { + return Err(DidntConvert); + } + match v.body { + ZExtensionBody::ZBuf(v) => Ok(Self::new(v)), + _ => Err(DidntConvert), + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ZExtUnknown { pub id: u8, @@ -175,3 +198,30 @@ impl ZExtUnknown { Self { id, body } } } + +impl From> for ZExtUnknown { + fn from(_: ZExtUnit<{ ID }>) -> Self { + ZExtUnknown { + id: ID, + body: ZExtensionBody::Unit, + } + } +} + +impl From> for ZExtUnknown { + fn from(e: ZExtZInt<{ ID }>) -> Self { + ZExtUnknown { + id: ID, + body: ZExtensionBody::ZInt(e.value), + } + } +} + +impl From> for ZExtUnknown { + fn from(e: ZExtZBuf<{ ID }>) -> Self { + ZExtUnknown { + id: ID, + body: ZExtensionBody::ZBuf(e.value), + } + } +} diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index 871f33e50b..fd2f67eed6 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -117,7 +117,7 @@ pub struct InitSyn { // Extensions pub mod ext { - use crate::common::{ZExtUnit, ZExtZSlice}; + use crate::common::{ZExtUnit, ZExtZBuf}; pub const QOS: u8 = 0x01; pub const SHM: u8 = 0x02; @@ -129,17 +129,17 @@ pub mod ext { /// # Shm extension /// Used as challenge for probing shared memory capabilities - pub type Shm = ZExtZSlice; + pub type Shm = ZExtZBuf; /// # Auth extension /// Used as challenge for probing authentication rights - pub type Auth = ZExtZSlice; + pub type Auth = ZExtZBuf; } impl InitSyn { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::{ZExtUnit, ZExtZSlice}; + use crate::common::{ZExtUnit, ZExtZBuf}; use rand::Rng; let mut rng = rand::thread_rng(); @@ -150,8 +150,8 @@ impl InitSyn { let resolution = Resolution::rand(); let batch_size: u16 = rng.gen(); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - let ext_shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); - let ext_auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); Self { version, @@ -182,7 +182,7 @@ pub struct InitAck { impl InitAck { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::{ZExtUnit, ZExtZSlice}; + use crate::common::{ZExtUnit, ZExtZBuf}; use rand::Rng; let mut rng = rand::thread_rng(); @@ -198,8 +198,8 @@ impl InitAck { let batch_size: u16 = rng.gen(); let cookie = ZSlice::rand(64); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - let ext_shm = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); - let ext_auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); Self { version, diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 311c3e1dac..156c94b175 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -84,7 +84,7 @@ pub struct OpenSyn { // Extensions pub mod ext { - use crate::common::{ZExtUnit, ZExtZInt, ZExtZSlice}; + use crate::common::{ZExtUnit, ZExtZBuf, ZExtZInt}; pub const QOS: u8 = 0x01; pub const SHM: u8 = 0x02; @@ -100,13 +100,13 @@ pub mod ext { /// # Auth extension /// Used as challenge for probing authentication rights - pub type Auth = ZExtZSlice; + pub type Auth = ZExtZBuf; } impl OpenSyn { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::{ZExtUnit, ZExtZInt, ZExtZSlice}; + use crate::common::{ZExtUnit, ZExtZBuf, ZExtZInt}; use rand::Rng; const MIN: usize = 32; @@ -124,7 +124,7 @@ impl OpenSyn { let cookie = ZSlice::rand(rng.gen_range(MIN..=MAX)); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZInt::rand()); - let ext_auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); Self { lease, initial_sn, @@ -148,7 +148,7 @@ pub struct OpenAck { impl OpenAck { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::{ZExtUnit, ZExtZInt, ZExtZSlice}; + use crate::common::{ZExtUnit, ZExtZBuf, ZExtZInt}; use rand::Rng; let mut rng = rand::thread_rng(); @@ -162,7 +162,7 @@ impl OpenAck { let initial_sn: ZInt = rng.gen(); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZInt::rand()); - let ext_auth = rng.gen_bool(0.5).then_some(ZExtZSlice::rand()); + let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); Self { lease, initial_sn, diff --git a/io/zenoh-transport/Cargo.toml b/io/zenoh-transport/Cargo.toml index 35ae7a5156..51a991c0d6 100644 --- a/io/zenoh-transport/Cargo.toml +++ b/io/zenoh-transport/Cargo.toml @@ -40,6 +40,7 @@ transport_unixsock-stream = ["zenoh-link/transport_unixsock-stream"] transport_ws = ["zenoh-link/transport_ws"] transport_serial = ["zenoh-link/transport_serial"] stats = [] +test = [] [dependencies] async-executor = { workspace = true } @@ -71,3 +72,4 @@ zenoh-util = { path = "../../commons/zenoh-util/" } env_logger = { workspace = true } panic-message = { workspace = true } zenoh-protocol = { path = "../../commons/zenoh-protocol/", features = ["test"] } +zenoh-transport = { path = ".", features = ["test"] } diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 9ec8af505a..a3167eaa4d 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -330,7 +330,7 @@ impl Encode<(&mut ZBufReader<'_>, FragmentHeader)> for &mut WBatch { } // Write the fragment - reader.siphon(&mut *writer).map_err(|_| { + reader.siphon(&mut writer).map_err(|_| { // Revert the write operation writer.rewind(mark); DidntWrite diff --git a/io/zenoh-transport/src/common/defragmentation.rs b/io/zenoh-transport/src/common/defragmentation.rs index 40fde5a376..f4d4a723b5 100644 --- a/io/zenoh-transport/src/common/defragmentation.rs +++ b/io/zenoh-transport/src/common/defragmentation.rs @@ -38,7 +38,7 @@ impl DefragBuffer { let db = DefragBuffer { reliability, sn: SeqNum::make(0, resolution)?, - buffer: ZBuf::default(), + buffer: ZBuf::empty(), capacity, len: 0, }; diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index ff1f642c26..999faf23b2 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -548,7 +548,7 @@ impl TransmissionPipeline { current: current.clone(), conduit: conduit[prio].clone(), }, - fragbuf: ZBuf::default(), + fragbuf: ZBuf::empty(), })); // The stage out for this priority diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index c00971d503..635ab6c11f 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -26,7 +26,7 @@ use rand::Rng; use std::time::Duration; use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZSlice}; use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_core::{zasynclock, zerror}; +use zenoh_core::{zasynclock, zasyncread, zerror}; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ @@ -50,6 +50,7 @@ struct State { ext_qos: ext::qos::State, #[cfg(feature = "shared-memory")] ext_shm: ext::shm::State, + ext_auth: ext::auth::State, } // InitSyn @@ -103,9 +104,10 @@ struct AcceptLink<'a> { link: &'a LinkUnicast, prng: &'a Mutex, cipher: &'a BlockCipher, - ext_qos: ext::qos::QoS<'a>, + ext_qos: ext::qos::QoSFsm<'a>, #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::Shm<'a>, + ext_shm: ext::shm::ShmFsm<'a>, + ext_auth: ext::auth::AuthFsm<'a>, } #[async_trait] @@ -182,6 +184,12 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension Auth + self.ext_auth + .recv_init_syn((&mut state.ext_auth, init_syn.ext_auth)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvInitSynOut { other_whatami: init_syn.whatami, other_zid: init_syn.zid, @@ -191,13 +199,13 @@ impl<'a> AcceptFsm for AcceptLink<'a> { Ok(output) } - type SendInitAckIn = (&'a mut State, SendInitAckIn); + type SendInitAckIn = (State, SendInitAckIn); type SendInitAckOut = SendInitAckOut; async fn send_init_ack( &self, input: Self::SendInitAckIn, ) -> Result { - let (state, input) = input; + let (mut state, input) = input; // Extension QoS let ext_qos = self @@ -216,6 +224,13 @@ impl<'a> AcceptFsm for AcceptLink<'a> { #[cfg(not(feature = "shared-memory"))] let ext_shm = None; + // Extension Auth + let ext_auth = self + .ext_auth + .send_init_ack(&state.ext_auth) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Create the cookie let cookie_nonce: ZInt = zasynclock!(self.prng).gen(); let cookie = Cookie { @@ -227,7 +242,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { ext_qos: state.ext_qos, #[cfg(feature = "shared-memory")] ext_shm: state.ext_shm, - // properties: EstablishmentProperties::new(), + ext_auth: state.ext_auth, }; let mut encrypted = vec![]; @@ -255,7 +270,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { cookie, ext_qos, ext_shm, - ext_auth: None, // @TODO + ext_auth, } .into(); @@ -336,6 +351,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { ext_qos: cookie.ext_qos, #[cfg(feature = "shared-memory")] ext_shm: cookie.ext_shm, + ext_auth: cookie.ext_auth, }; // Extension QoS @@ -344,6 +360,19 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension Shm + #[cfg(feature = "shared-memory")] + self.ext_shm + .recv_open_syn((&mut state.ext_shm, open_syn.ext_shm)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + + // Extension Auth + self.ext_auth + .recv_open_syn((&mut state.ext_auth, open_syn.ext_auth)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvOpenSynOut { other_zid: cookie.zid, other_whatami: cookie.whatami, @@ -378,6 +407,13 @@ impl<'a> AcceptFsm for AcceptLink<'a> { #[cfg(not(feature = "shared-memory"))] let ext_shm = None; + // Extension Auth + let ext_auth = self + .ext_auth + .send_open_ack(&state.ext_auth) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Build OpenAck message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); let open_ack = OpenAck { @@ -385,7 +421,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { initial_sn: mine_initial_sn, ext_qos, ext_shm, - ext_auth: None, // @TODO + ext_auth, }; // Do not send the OpenAck right now since we might still incur in MAX_LINKS error @@ -396,13 +432,15 @@ impl<'a> AcceptFsm for AcceptLink<'a> { } pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) -> ZResult<()> { + let auth = zasyncread!(manager.state.unicast.authenticator); let fsm = AcceptLink { link, prng: &manager.prng, cipher: &manager.cipher, - ext_qos: ext::qos::QoS::new(), + ext_qos: ext::qos::QoSFsm::new(), #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::Shm::new(&manager.state.unicast.shm), + ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), + ext_auth: ext::auth::AuthFsm::new(&auth), }; // Init handshake @@ -428,6 +466,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) ext_qos: ext::qos::State::new(manager.config.unicast.is_qos), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::State::new(manager.config.unicast.is_shm), + ext_auth: auth.state(&mut *zasynclock!(manager.prng)), }; // Let's scope the Init phase in such a way memory is freed by Rust @@ -447,7 +486,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) #[cfg(feature = "shared-memory")] ext_shm: isyn_out.ext_shm, }; - step!(fsm.send_init_ack((&mut state, iack_in)).await) + step!(fsm.send_init_ack((state, iack_in)).await) }; // Open handshake diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 29ff627ce3..21c98db67c 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -22,7 +22,7 @@ use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_protocol::core::{Resolution, WhatAmI, ZInt, ZenohId}; -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub(crate) struct Cookie { pub(crate) whatami: WhatAmI, pub(crate) zid: ZenohId, @@ -33,7 +33,7 @@ pub(crate) struct Cookie { pub(crate) ext_qos: ext::qos::State, #[cfg(feature = "shared-memory")] pub(crate) ext_shm: ext::shm::State, - // pub properties: EstablishmentProperties, // @TODO + pub(crate) ext_auth: ext::auth::State, } impl WCodec<&Cookie, &mut W> for Zenoh080 @@ -53,7 +53,7 @@ where self.write(&mut *writer, &x.ext_qos)?; #[cfg(feature = "shared-memory")] self.write(&mut *writer, &x.ext_shm)?; - // self.write(&mut *writer, x.properties.as_slice())?; + self.write(&mut *writer, &x.ext_auth)?; Ok(()) } @@ -77,11 +77,7 @@ where let ext_qos: ext::qos::State = self.read(&mut *reader)?; #[cfg(feature = "shared-memory")] let ext_shm: ext::shm::State = self.read(&mut *reader)?; - // let mut ps: Vec = self.read(&mut *reader)?; - // let mut properties = EstablishmentProperties::new(); - // for p in ps.drain(..) { - // properties.insert(p).map_err(|_| DidntRead)?; - // } + let ext_auth: ext::auth::State = self.read(&mut *reader)?; let cookie = Cookie { whatami, @@ -92,7 +88,7 @@ where ext_qos, #[cfg(feature = "shared-memory")] ext_shm, - // properties, + ext_auth, }; Ok(cookie) @@ -143,7 +139,7 @@ where impl Cookie { #[cfg(test)] - pub fn rand() -> Self { + pub(crate) fn rand() -> Self { use rand::Rng; let mut rng = rand::thread_rng(); @@ -154,10 +150,10 @@ impl Cookie { resolution: Resolution::rand(), batch_size: rng.gen(), nonce: rng.gen(), - ext_qos: ext::qos::State::new(rng.gen_bool(0.5)), + ext_qos: ext::qos::State::rand(), #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::State::new(rng.gen_bool(0.5)), - // properties: EstablishmentProperties::rand(), + ext_shm: ext::shm::State::rand(), + ext_auth: ext::auth::State::rand(), } } } @@ -196,7 +192,7 @@ mod tests { run_single!($type, $rand, $codec, $codec, buffer); println!("ZBuf: codec {}", std::any::type_name::<$type>()); - let mut buffer = ZBuf::default(); + let mut buffer = ZBuf::empty(); run_single!($type, $rand, $codec, $codec, buffer); }; } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs new file mode 100644 index 0000000000..8672e4fb9c --- /dev/null +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -0,0 +1,621 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#[cfg(feature = "auth_pubkey")] +mod pubkey; +#[cfg(feature = "auth_usrpwd")] +pub mod usrpwd; + +#[cfg(feature = "auth_usrpwd")] +use crate::establishment::ext::auth::usrpwd::{AuthUsrPwd, AuthUsrPwdFsm}; +use crate::establishment::{AcceptFsm, OpenFsm}; +use async_trait::async_trait; +use rand::Rng; +use std::convert::TryInto; +use std::marker::PhantomData; +use zenoh_buffers::reader::SiphonableReader; +use zenoh_buffers::ZBuf; +use zenoh_buffers::{ + reader::{DidntRead, HasReader, Reader}, + writer::{DidntWrite, HasWriter, Writer}, +}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_config::Config; +use zenoh_core::{bail, zerror, Error as ZError, Result as ZResult}; +use zenoh_protocol::{ + common::ZExtUnknown, + transport::{init, open}, +}; + +pub(crate) mod id { + pub(crate) const USRPWD: u8 = 1; + // pub(crate) const PUBKEY: u8 = 2; +} + +macro_rules! ztryinto { + ($x:expr, $s:expr) => { + if let Some(x) = $x { + Some( + x.try_into() + .map_err(|_| zerror!("{} Decoding error.", $s))?, + ) + } else { + None + } + }; +} + +macro_rules! ztake { + ($x:expr, $id:expr) => { + $x.iter().position(|x| x.id == $id).map(|i| $x.remove(i)) + }; +} + +#[derive(Debug, Default)] +pub struct Auth { + #[cfg(feature = "auth_usrpwd")] + usrpwd: Option, +} + +impl Auth { + pub(crate) async fn from_config(config: &Config) -> ZResult { + let auth = config.transport().auth(); + + Ok(Self { + #[cfg(feature = "auth_usrpwd")] + usrpwd: AuthUsrPwd::from_config(auth.usrpwd()).await?, + }) + } + + pub(crate) fn state(&self, prng: &mut R) -> State + where + R: Rng, + { + State { + #[cfg(feature = "auth_usrpwd")] + usrpwd: self.usrpwd.is_some().then_some(usrpwd::State::new(prng)), + } + } +} + +#[cfg(feature = "test")] +impl Auth { + pub const fn empty() -> Self { + Self { + #[cfg(feature = "auth_usrpwd")] + usrpwd: None, + } + } + + #[cfg(feature = "auth_usrpwd")] + pub fn set_usrpwd(&mut self, usrpwd: Option) { + self.usrpwd = usrpwd; + } + + #[cfg(feature = "auth_usrpwd")] + pub fn get_usrpwd(&self) -> Option<&AuthUsrPwd> { + self.usrpwd.as_ref() + } + + #[cfg(feature = "auth_usrpwd")] + pub fn get_usrpwd_mut(&mut self) -> Option<&mut AuthUsrPwd> { + self.usrpwd.as_mut() + } +} + +pub(crate) struct AuthFsm<'a> { + #[cfg(feature = "auth_usrpwd")] + usrpwd: Option>, + _a: PhantomData<&'a ()>, // Required only when all auth features are disabled +} + +impl<'a> AuthFsm<'a> { + pub(crate) fn new(a: &'a Auth) -> Self { + Self { + #[cfg(feature = "auth_usrpwd")] + usrpwd: a.usrpwd.as_ref().map(AuthUsrPwdFsm::new), + _a: PhantomData, + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct State { + #[cfg(feature = "auth_usrpwd")] + usrpwd: Option, +} + +impl State { + #[cfg(test)] + pub(crate) fn rand() -> Self { + let mut rng = rand::thread_rng(); + Self { + #[cfg(feature = "auth_usrpwd")] + usrpwd: rng.gen_bool(0.5).then_some(usrpwd::State::rand()), + } + } +} + +// Codec +impl WCodec<&State, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &State) -> Self::Output { + let mut buff = vec![]; + let mut wbuf = buff.writer(); + + let mut count: usize = 0; + #[cfg(feature = "auth_usrpwd")] + { + if let Some(usrpwd) = x.usrpwd.as_ref() { + self.write(&mut wbuf, id::USRPWD)?; + self.write(&mut wbuf, usrpwd)?; + count += 1; + } + } + + self.write(&mut *writer, count)?; + if !buff.is_empty() { + let mut rbuf = buff.reader(); + rbuf.siphon(&mut *writer).map_err(|_| DidntWrite)?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let mut count: usize = self.read(&mut *reader)?; + + #[cfg(feature = "auth_usrpwd")] + let mut usrpwd: Option = None; + + while count > 0 { + let e: u8 = self.read(&mut *reader)?; + match e { + #[cfg(feature = "auth_usrpwd")] + id::USRPWD => { + usrpwd = Some(self.read(&mut *reader)?); + } + _ => return Err(DidntRead), + } + + count -= 1; + } + + let state = State { + #[cfg(feature = "auth_usrpwd")] + usrpwd, + }; + Ok(state) + } +} + +/*************************************/ +/* OPEN */ +/*************************************/ +#[async_trait] +impl<'a> OpenFsm for AuthFsm<'a> { + type Error = ZError; + + type SendInitSynIn = &'a State; + type SendInitSynOut = Option; + async fn send_init_syn( + &self, + state: Self::SendInitSynIn, + ) -> Result { + const S: &str = "Auth extension - Send InitSyn."; + + let mut exts: Vec = vec![]; + + #[cfg(feature = "auth_usrpwd")] + { + match (self.usrpwd.as_ref(), state.usrpwd.as_ref()) { + (Some(e), Some(s)) => { + if let Some(e) = e.send_init_syn(s).await?.take() { + exts.push(e.into()) + } + } + (None, None) => {} + _ => bail!("{} Invalid configuration.", S), + } + } + + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, exts.as_slice()) + .map_err(|_| zerror!("{} Encoding error.", S))?; + + let output = (!buff.is_empty()).then_some(init::ext::Auth::new(buff.into())); + Ok(output) + } + + type RecvInitAckIn = (&'a mut State, Option); + type RecvInitAckOut = (); + async fn recv_init_ack( + &self, + input: Self::RecvInitAckIn, + ) -> Result { + const S: &str = "Auth extension - Recv InitAck."; + + let (state, ext) = input; + let ext = ext.unwrap_or(init::ext::Auth::new(ZBuf::empty())); + + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let mut exts: Vec = codec + .read(&mut reader) + .map_err(|_| zerror!("{} Decoding error.", S))?; + + #[cfg(feature = "auth_usrpwd")] + { + match (self.usrpwd.as_ref(), state.usrpwd.as_mut()) { + (Some(e), Some(s)) => { + let x = ztake!(exts, id::USRPWD); + e.recv_init_ack((s, ztryinto!(x, S))).await?; + } + (None, None) => {} + _ => bail!("{} Invalid configuration.", S), + } + } + + Ok(()) + } + + type SendOpenSynIn = &'a State; + type SendOpenSynOut = Option; + async fn send_open_syn( + &self, + state: Self::SendOpenSynIn, + ) -> Result { + const S: &str = "Auth extension - Send OpenSyn."; + + let mut exts: Vec = vec![]; + + #[cfg(feature = "auth_usrpwd")] + { + match (self.usrpwd.as_ref(), state.usrpwd.as_ref()) { + (Some(e), Some(s)) => { + if let Some(e) = e.send_open_syn(s).await?.take() { + exts.push(e.into()) + } + } + (None, None) => {} + _ => bail!("{} Invalid configuration.", S), + } + } + + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, exts.as_slice()) + .map_err(|_| zerror!("{} Encoding error.", S))?; + + let output = (!buff.is_empty()).then_some(open::ext::Auth::new(buff.into())); + Ok(output) + } + + type RecvOpenAckIn = (&'a mut State, Option); + type RecvOpenAckOut = (); + async fn recv_open_ack( + &self, + input: Self::RecvOpenAckIn, + ) -> Result { + const S: &str = "Auth extension - Recv OpenAck."; + + let (state, ext) = input; + let ext = ext.unwrap_or(init::ext::Auth::new(ZBuf::empty())); + + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let mut exts: Vec = codec + .read(&mut reader) + .map_err(|_| zerror!("{} Decoding error.", S))?; + + #[cfg(feature = "auth_usrpwd")] + { + match (self.usrpwd.as_ref(), state.usrpwd.as_mut()) { + (Some(e), Some(s)) => { + let x = ztake!(exts, id::USRPWD); + e.recv_open_ack((s, ztryinto!(x, S))).await?; + } + (None, None) => {} + _ => bail!("{} Invalid configuration.", S), + } + } + + Ok(()) + } +} + +/*************************************/ +/* ACCEPT */ +/*************************************/ +#[async_trait] +impl<'a> AcceptFsm for AuthFsm<'a> { + type Error = ZError; + + type RecvInitSynIn = (&'a mut State, Option); + type RecvInitSynOut = (); + async fn recv_init_syn( + &self, + input: Self::RecvInitSynIn, + ) -> Result { + const S: &str = "Auth extension - Recv InitSyn."; + + let (state, ext) = input; + let ext = ext.unwrap_or(init::ext::Auth::new(ZBuf::empty())); + + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let mut exts: Vec = codec + .read(&mut reader) + .map_err(|_| zerror!("{} Decoding error.", S))?; + + #[cfg(feature = "auth_usrpwd")] + { + match (self.usrpwd.as_ref(), state.usrpwd.as_mut()) { + (Some(e), Some(s)) => { + let x = ztake!(exts, id::USRPWD); + e.recv_init_syn((s, ztryinto!(x, S))).await?; + } + (None, None) => {} + _ => bail!("{} Invalid configuration.", S), + } + } + + Ok(()) + } + + type SendInitAckIn = &'a State; + type SendInitAckOut = Option; + async fn send_init_ack( + &self, + state: Self::SendInitAckIn, + ) -> Result { + const S: &str = "Auth extension - Send InitAck."; + + let mut exts: Vec = vec![]; + + #[cfg(feature = "auth_usrpwd")] + { + match (self.usrpwd.as_ref(), state.usrpwd.as_ref()) { + (Some(e), Some(s)) => { + if let Some(e) = e.send_init_ack(s).await?.take() { + exts.push(e.into()) + } + } + (None, None) => {} + _ => bail!("{} Invalid configuration.", S), + } + } + + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, exts.as_slice()) + .map_err(|_| zerror!("{} Encoding error.", S))?; + + let output = (!buff.is_empty()).then_some(init::ext::Auth::new(buff.into())); + Ok(output) + } + + type RecvOpenSynIn = (&'a mut State, Option); + type RecvOpenSynOut = (); + async fn recv_open_syn( + &self, + input: Self::RecvOpenSynIn, + ) -> Result { + const S: &str = "Auth extension - Recv OpenSyn."; + + let (state, ext) = input; + let ext = ext.unwrap_or(init::ext::Auth::new(ZBuf::empty())); + + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let mut exts: Vec = codec + .read(&mut reader) + .map_err(|_| zerror!("{} Decoding error.", S))?; + + #[cfg(feature = "auth_usrpwd")] + { + match (self.usrpwd.as_ref(), state.usrpwd.as_mut()) { + (Some(e), Some(s)) => { + let x = ztake!(exts, id::USRPWD); + e.recv_open_syn((s, ztryinto!(x, S))).await?; + } + (None, None) => {} + _ => bail!("{} Invalid configuration.", S), + } + } + + Ok(()) + } + + type SendOpenAckIn = &'a State; + type SendOpenAckOut = Option; + async fn send_open_ack( + &self, + state: Self::SendOpenAckIn, + ) -> Result { + const S: &str = "Auth extension - Send InitAck."; + + let mut exts: Vec = vec![]; + + #[cfg(feature = "auth_usrpwd")] + { + match (self.usrpwd.as_ref(), state.usrpwd.as_ref()) { + (Some(e), Some(s)) => { + if let Some(e) = e.send_open_ack(s).await?.take() { + exts.push(e.into()) + } + } + (None, None) => {} + _ => bail!("{} Invalid configuration.", S), + } + } + + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, exts.as_slice()) + .map_err(|_| zerror!("{} Encoding error.", S))?; + + let output = (!buff.is_empty()).then_some(open::ext::Auth::new(buff.into())); + Ok(output) + } +} + +// #[derive(Clone)] +// pub struct TransportAuthenticator(Arc); + +// impl TransportAuthenticator { +// pub async fn from_config(_config: &Config) -> ZResult> { +// #[allow(unused_mut)] +// let mut pas = HashSet::new(); + +// #[cfg(feature = "auth_pubkey")] +// { +// let mut res = PubKeyAuthenticator::from_config(_config).await?; +// if let Some(pa) = res.take() { +// pas.insert(pa.into()); +// } +// } + +// #[cfg(feature = "auth_usrpwd")] +// { +// let mut res = UserPasswordAuthenticator::from_config(_config).await?; +// if let Some(pa) = res.take() { +// pas.insert(pa.into()); +// } +// } + +// Ok(pas) +// } +// } + +/*************************************/ +/* ACCEPT */ +/*************************************/ + +// Return the attachment to be included in the InitSyn message. +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the initial InitSyn message will be sent on +// +// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitSyn, i.e., the peer +// initiating a new transport. +// +// async fn get_init_syn_properties( +// &self, +// link: &AuthenticatedLink, +// node_id: &ZenohId, +// ) -> ZResult>>; + +// Return the attachment to be included in the InitAck message to be sent +// in response of the authenticated InitSyn. +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the InitSyn message was received on +// +// * `cookie` - The Cookie containing the internal state +// +// * `property` - The optional `Property` included in the InitSyn message +// +// async fn handle_init_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: Option>, +// ) -> ZResult<(Option>, Option>)>; // (Attachment, Cookie) + +// Return the attachment to be included in the OpenSyn message to be sent +// in response of the authenticated InitAck. +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the InitSyn message was received on +// +// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitAck message +// +// * `sn_resolution` - The sn_resolution negotiated by the sender of the InitAck message +// +// * `properties` - The optional `Property` included in the InitAck message +// +// async fn handle_init_ack( +// &self, +// link: &AuthenticatedLink, +// node_id: &ZenohId, +// sn_resolution: ZInt, +// property: Option>, +// ) -> ZResult>>; + +// Return the attachment to be included in the OpenAck message to be sent +// in response of the authenticated OpenSyn. +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the OpenSyn message was received on +// +// * `properties` - The optional `Property` included in the OpenSyn message +// +// * `cookie` - The optional `Property` included in the OpenSyn message +// +// async fn handle_open_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: (Option>, Option>), // (Attachment, Cookie) +// ) -> ZResult>>; + +// Auhtenticate the OpenAck. No message is sent back in response to an OpenAck +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the OpenAck message was received on +// +// * `properties` - The optional `Property` included in the OpenAck message +// +// async fn handle_open_ack( +// &self, +// link: &AuthenticatedLink, +// property: Option>, +// ) -> ZResult>>; + +// Handle any error on a link. This callback is mainly used to clean-up any internal state +// of the authenticator in such a way no unnecessary data is left around +// +// # Arguments +// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] generating the error +// +// async fn handle_link_err(&self, link: &AuthenticatedLink); + +// Handle any error on a link. This callback is mainly used to clean-up any internal state +// of the authenticator in such a way no unnecessary data is left around +// +// # Arguments +// * `peerd_id` - The [`ZenohId`][ZenohId] of the transport being closed. +// +// async fn handle_close(&self, node_id: &ZenohId); +// } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs similarity index 100% rename from io/zenoh-transport/src/unicast/establishment/ext/authenticator/pubkey.rs rename to io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs new file mode 100644 index 0000000000..bc8bc351e7 --- /dev/null +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -0,0 +1,612 @@ +// // +// // Copyright (c) 2022 ZettaScale Technology +// // +// // This program and the accompanying materials are made available under the +// // terms of the Eclipse Public License 2.0 which is available at +// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// // which is available at https://www.apache.org/licenses/LICENSE-2.0. +// // +// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// // +// // Contributors: +// // ZettaScale Zenoh Team, +// // +// use super::{ +// AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, +// }; +// use super::{Locator, ZInt, ZenohId}; +// use crate::unicast::establishment::Cookie; +use crate::establishment::{AcceptFsm, OpenFsm}; +use async_std::fs; +use async_trait::async_trait; +use rand::Rng; +use std::collections::HashMap; +use zenoh_buffers::{ + reader::{DidntRead, HasReader, Reader}, + writer::{DidntWrite, HasWriter, Writer}, +}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_collections::Properties; +use zenoh_config::UsrPwdConf; +use zenoh_core::{bail, zerror, Error as ZError, Result as ZResult}; +use zenoh_crypto::hmac; +use zenoh_protocol::{ + common::{ZExtUnit, ZExtZBuf, ZExtZInt}, + core::ZInt, +}; + +// Authenticator +type User = Vec; +type Password = Vec; + +#[derive(Debug)] +pub struct AuthUsrPwd { + lookup: HashMap, + credentials: Option<(User, Password)>, +} + +impl AuthUsrPwd { + pub fn new(credentials: Option<(User, Password)>) -> Self { + Self { + lookup: HashMap::new(), + credentials, + } + } + + pub async fn add_user(&mut self, user: User, password: Password) -> ZResult<()> { + self.lookup.insert(user, password); + Ok(()) + } + + pub async fn del_user(&mut self, user: &User) -> ZResult<()> { + self.lookup.remove(user); + Ok(()) + } + + pub async fn from_config(config: &UsrPwdConf) -> ZResult> { + let mut lookup: HashMap = HashMap::new(); + if let Some(dict) = config.dictionary_file() { + let content = fs::read_to_string(dict) + .await + .map_err(|e| zerror!("Invalid user-password dictionary file: {}", e))?; + + // Populate the user-password dictionary + let mut ps = Properties::from(content); + for (user, password) in ps.drain() { + lookup.insert(user.as_bytes().to_owned(), password.as_bytes().to_owned()); + } + log::debug!("User-password dictionary has been configured"); + } + + let mut credentials: Option<(User, Password)> = None; + if let Some(user) = config.user() { + if let Some(password) = config.password() { + log::debug!("User and password have been configured"); + credentials = Some((user.as_bytes().to_owned(), password.as_bytes().to_owned())); + } + } + + if !lookup.is_empty() || credentials.is_some() { + log::debug!("User-password authentication is enabled"); + Ok(Some(Self { + lookup, + credentials, + })) + } else { + Ok(None) + } + } +} + +// OpenFsm / AcceptFsm +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct State { + nonce: ZInt, +} + +impl State { + pub(crate) fn new(prng: &mut R) -> Self + where + R: Rng, + { + Self { nonce: prng.gen() } + } + + #[cfg(test)] + pub(crate) fn rand() -> Self { + let mut rng = rand::thread_rng(); + Self::new(&mut rng) + } +} + +// Codec +impl WCodec<&State, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &State) -> Self::Output { + self.write(&mut *writer, x.nonce) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let nonce: ZInt = self.read(&mut *reader)?; + Ok(State { nonce }) + } +} + +pub(crate) struct AuthUsrPwdFsm<'a> { + inner: &'a AuthUsrPwd, +} + +impl<'a> AuthUsrPwdFsm<'a> { + pub(super) const fn new(a: &'a AuthUsrPwd) -> Self { + Self { inner: a } + } +} + +/*************************************/ +/* InitSyn */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// +---------------+ +/// +/// ZExtUnit + +/*************************************/ +/* InitAck */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// ~ nonce ~ +/// +---------------+ +/// +/// ZExtZInt + +/*************************************/ +/* OpenSyn */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// ~ user ~ +/// +---------------+ +/// ~ hash ~ +/// +---------------+ +/// +/// ZExtZBuf +struct OpenSyn { + user: Vec, + hmac: Vec, +} + +impl WCodec<&OpenSyn, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &OpenSyn) -> Self::Output { + self.write(&mut *writer, x.user.as_slice())?; + self.write(&mut *writer, x.hmac.as_slice())?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let user: Vec = self.read(&mut *reader)?; + let hmac: Vec = self.read(&mut *reader)?; + Ok(OpenSyn { user, hmac }) + } +} + +/*************************************/ +/* OpenAck */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// +---------------+ +/// +/// ZExtUnit + +#[async_trait] +impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { + type Error = ZError; + + type SendInitSynIn = &'a State; + type SendInitSynOut = Option>; + async fn send_init_syn( + &self, + _input: Self::SendInitSynIn, + ) -> Result { + let output = self.inner.credentials.is_some().then_some(ZExtUnit::new()); + Ok(output) + } + + type RecvInitAckIn = (&'a mut State, Option>); + type RecvInitAckOut = (); + async fn recv_init_ack( + &self, + input: Self::RecvInitAckIn, + ) -> Result { + const S: &str = "UsrPwd extension - Recv InitSyn."; + + if self.inner.credentials.is_none() { + return Ok(()); + }; + + let (state, mut ext_userwpd) = input; + let ext_usrpwd = ext_userwpd + .take() + .ok_or_else(|| zerror!("{} Decoding error.", S))?; + state.nonce = ext_usrpwd.value; + + Ok(()) + } + + type SendOpenSynIn = &'a State; + type SendOpenSynOut = Option>; + async fn send_open_syn( + &self, + state: Self::SendOpenSynIn, + ) -> Result { + const S: &str = "UsrPwd extension - Send OpenSyn."; + + // If credentials are not configured, don't continue the USRPWD authentication + let (user, password) = match self.inner.credentials.as_ref() { + Some(cr) => cr, + None => return Ok(None), + }; + + // Create the HMAC of the password using the nonce received as a key (it's a challenge) + let key = state.nonce.to_le_bytes(); + let hmac = hmac::sign(&key, password).map_err(|_| zerror!("{} Encoding error.", S))?; + // Create the OpenSyn extension + let open_syn = OpenSyn { + user: user.to_vec(), + hmac, + }; + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, &open_syn) + .map_err(|_| zerror!("{} Encoding error.", S))?; + + let output = Some(ZExtZBuf::new(buff.into())); + Ok(output) + } + + type RecvOpenAckIn = (&'a mut State, Option>); + type RecvOpenAckOut = (); + async fn recv_open_ack( + &self, + input: Self::RecvOpenAckIn, + ) -> Result { + const S: &str = "UsrPwd extension - Recv OpenAck."; + + let (_, ext) = input; + if self.inner.credentials.is_some() && ext.is_none() { + bail!("{} Expected extension.", S); + } + + Ok(()) + } +} + +/*************************************/ +/* ACCEPT */ +/*************************************/ +#[async_trait] +impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { + type Error = ZError; + + type RecvInitSynIn = (&'a mut State, Option>); + type RecvInitSynOut = (); + async fn recv_init_syn( + &self, + input: Self::RecvInitSynIn, + ) -> Result { + const S: &str = "UsrPwd extension - Recv InitSyn."; + + let (_, ext_usrpwd) = input; + if ext_usrpwd.is_none() { + bail!("{} Expected extension.", S); + } + + Ok(()) + } + + type SendInitAckIn = &'a State; + type SendInitAckOut = Option>; + async fn send_init_ack( + &self, + state: Self::SendInitAckIn, + ) -> Result { + Ok(Some(ZExtZInt::new(state.nonce))) + } + + type RecvOpenSynIn = (&'a mut State, Option>); + type RecvOpenSynOut = (); + async fn recv_open_syn( + &self, + input: Self::RecvOpenSynIn, + ) -> Result { + const S: &str = "UsrPwd extension - Recv OpenSyn."; + + let (state, mut ext_usrpwd) = input; + let ext_usrpwd = ext_usrpwd + .take() + .ok_or_else(|| zerror!("{} Expected extension.", S))?; + + let codec = Zenoh080::new(); + let mut reader = ext_usrpwd.value.reader(); + let open_syn: OpenSyn = codec + .read(&mut reader) + .map_err(|_| zerror!("{} Decoding error.", S))?; + + let pwd = self + .inner + .lookup + .get(&open_syn.user) + .ok_or_else(|| zerror!("{} Invalid user.", S))?; + + // Create the HMAC of the password using the nonce received as challenge + let key = state.nonce.to_le_bytes(); + let hmac = hmac::sign(&key, pwd).map_err(|_| zerror!("{} Encoding error.", S))?; + if hmac != open_syn.hmac { + bail!("{} Invalid password.", S); + } + + Ok(()) + } + + type SendOpenAckIn = &'a State; + type SendOpenAckOut = Option>; + async fn send_open_ack( + &self, + _input: Self::SendOpenAckIn, + ) -> Result { + Ok(Some(ZExtUnit::new())) + } +} + +// #[async_trait] +// impl TransportAuthenticatorTrait for UserPasswordAuthenticator { +// fn id(&self) -> ZNodeAuthenticatorId { +// ZNodeAuthenticatorId::UserPassword +// } + +// async fn close(&self) { +// // No cleanup needed +// } + +// async fn get_init_syn_properties( +// &self, +// link: &AuthenticatedLink, +// _node_id: &ZenohId, +// ) -> ZResult>> { +// // If credentials are not configured, don't initiate the USRPWD authentication +// if self.credentials.is_none() { +// return Ok(None); +// } + +// let init_syn_property = InitSynProperty { +// version: USRPWD_VERSION, +// }; +// let mut wbuf = vec![]; +// let codec = Zenoh080::new(); +// let mut writer = wbuf.writer(); +// codec +// .write(&mut writer, &init_syn_property) +// .map_err(|_| zerror!("Error in encoding InitSyn for UsrPwd on link: {}", link))?; +// let attachment = wbuf; + +// Ok(Some(attachment)) +// } + +// async fn handle_init_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: Option>, +// ) -> ZResult<(Option>, Option>)> { +// let p = property.ok_or_else(|| { +// zerror!( +// "Received InitSyn with no UsrPwd attachment on link: {}", +// link +// ) +// })?; + +// let codec = Zenoh080::new(); + +// let mut reader = p.reader(); +// let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received InitSyn with invalid UsrPwd attachment on link: {}", +// link +// ) +// })?; +// if init_syn_property.version > USRPWD_VERSION { +// bail!("Rejected InitSyn with invalid attachment on link: {}", link) +// } + +// // Create the InitAck attachment +// let init_ack_property = InitAckProperty { +// nonce: cookie.nonce, +// }; +// let mut wbuf = vec![]; +// let mut writer = wbuf.writer(); +// codec +// .write(&mut writer, &init_ack_property) +// .map_err(|_| zerror!("Error in encoding InitAck for UsrPwd on link: {}", link))?; +// let attachment = wbuf; + +// Ok((Some(attachment), None)) +// } + +// async fn handle_init_ack( +// &self, +// link: &AuthenticatedLink, +// _node_id: &ZenohId, +// _sn_resolution: ZInt, +// property: Option>, +// ) -> ZResult>> { +// // If credentials are not configured, don't continue the USRPWD authentication +// let credentials = match self.credentials.as_ref() { +// Some(cr) => cr, +// None => return Ok(None), +// }; + +// let p = property.ok_or_else(|| { +// zerror!( +// "Received InitAck with no UsrPwd attachment on link: {}", +// link +// ) +// })?; + +// let codec = Zenoh080::new(); + +// let mut reader = p.reader(); +// let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received InitAck with invalid UsrPwd attachment on link: {}", +// link +// ) +// })?; + +// // Create the HMAC of the password using the nonce received as a key (it's a challenge) +// let key = init_ack_property.nonce.to_le_bytes(); +// let hmac = hmac::sign(&key, &credentials.password)?; +// // Create the OpenSyn attachment +// let open_syn_property = OpenSynProperty { +// user: credentials.user.clone(), +// hmac, +// }; +// // Encode the InitAck attachment +// let mut wbuf = vec![]; +// let mut writer = wbuf.writer(); +// codec +// .write(&mut writer, &open_syn_property) +// .map_err(|_| zerror!("Error in encoding OpenSyn for UsrPwd on link: {}", link))?; +// let attachment = wbuf; + +// Ok(Some(attachment)) +// } + +// async fn handle_open_syn( +// &self, +// link: &AuthenticatedLink, +// cookie: &Cookie, +// property: (Option>, Option>), +// ) -> ZResult>> { +// let (attachment, _cookie) = property; +// let a = attachment.ok_or_else(|| { +// zerror!( +// "Received OpenSyn with no UsrPwd attachment on link: {}", +// link +// ) +// })?; + +// let codec = Zenoh080::new(); + +// let mut reader = a.reader(); +// let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { +// zerror!( +// "Received OpenSyn with invalid UsrPwd attachment on link: {}", +// link +// ) +// })?; +// let password = match zasyncread!(self.lookup).get(&open_syn_property.user) { +// Some(password) => password.clone(), +// None => bail!("Received OpenSyn with invalid user on link: {}", link), +// }; + +// // Create the HMAC of the password using the nonce received as challenge +// let key = cookie.nonce.to_le_bytes(); +// let hmac = hmac::sign(&key, &password)?; +// if hmac != open_syn_property.hmac { +// bail!("Received OpenSyn with invalid password on link: {}", link) +// } + +// // Check PID validity +// let mut guard = zasynclock!(self.authenticated); +// match guard.get_mut(&cookie.zid) { +// Some(auth) => { +// if open_syn_property.user != auth.credentials.user +// || password != auth.credentials.password +// { +// bail!("Received OpenSyn with invalid password on link: {}", link) +// } +// auth.links.insert((link.src.clone(), link.dst.clone())); +// } +// None => { +// let credentials = Credentials { +// user: open_syn_property.user, +// password, +// }; +// let mut links = HashSet::new(); +// links.insert((link.src.clone(), link.dst.clone())); +// let auth = Authenticated { credentials, links }; +// guard.insert(cookie.zid, auth); +// } +// } + +// Ok(None) +// } + +// async fn handle_open_ack( +// &self, +// _link: &AuthenticatedLink, +// _property: Option>, +// ) -> ZResult>> { +// Ok(None) +// } + +// async fn handle_link_err(&self, link: &AuthenticatedLink) { +// // Need to check if it authenticated and remove it if this is the last link +// let mut guard = zasynclock!(self.authenticated); +// let mut to_del: Option = None; +// for (node_id, auth) in guard.iter_mut() { +// auth.links.remove(&(link.src.clone(), link.dst.clone())); +// if auth.links.is_empty() { +// to_del = Some(*node_id); +// break; +// } +// } +// if let Some(node_id) = to_del.take() { +// guard.remove(&node_id); +// } +// } + +// async fn handle_close(&self, node_id: &ZenohId) { +// zasynclock!(self.authenticated).remove(node_id); +// } +// } + +// //noinspection ALL +// impl From> for TransportAuthenticator { +// fn from(v: Arc) -> TransportAuthenticator { +// TransportAuthenticator(v) +// } +// } + +// impl From for TransportAuthenticator { +// fn from(v: UserPasswordAuthenticator) -> TransportAuthenticator { +// Self::from(Arc::new(v)) +// } +// } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs deleted file mode 100644 index 073e704552..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/mod.rs +++ /dev/null @@ -1,291 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -#[cfg(feature = "auth_pubkey")] -mod pubkey; -// #[cfg(feature = "auth_usrpwd")] -// mod userpassword; - -// use crate::unicast::establishment::Cookie; -// use async_trait::async_trait; -#[cfg(feature = "auth_pubkey")] -pub use pubkey::*; -use zenoh_buffers::reader::Reader; -use zenoh_buffers::writer::Writer; -// use std::collections::HashSet; -// use std::fmt; -// use std::hash::{Hash, Hasher}; -// use std::ops::Deref; -// use std::sync::Arc; -// #[cfg(feature = "auth_usrpwd")] -// pub use userpassword::*; -// use zenoh_config::Config; -// use zenoh_link::{Link, Locator}; -// use zenoh_protocol::core::{ZInt, ZenohId}; -// use zenoh_result::ZResult; - -use crate::establishment::{AcceptFsm, OpenFsm}; -use async_trait::async_trait; -use std::collections::HashMap; -use zenoh_codec::{RCodec, WCodec}; -use zenoh_config::ZenohId; -use zenoh_protocol::common::ZExtUnknown; -use zenoh_protocol::core::ZInt; -use zenoh_result::{ZError, ZResult}; - -struct Auth<'a> { - inner: &'a HashMap<&'static str, Box>, -} - -pub type TransportAuthenticator<'a> = Box; -// impl<'a> - -/*************************************/ -/* PEER */ -/*************************************/ -// #[derive(PartialEq, Eq, Hash)] -// #[repr(u8)] -// pub enum ZNodeAuthenticatorId { -// Reserved = 0, -// Shm = 1, -// UserPassword = 2, -// PublicKey = 3, -// } - -// impl From for ZInt { -// fn from(pa: ZNodeAuthenticatorId) -> ZInt { -// pa as ZInt -// } -// } - -// #[derive(Clone)] -// pub struct TransportAuthenticator(Arc); - -// impl TransportAuthenticator { -// pub async fn from_config(_config: &Config) -> ZResult> { -// #[allow(unused_mut)] -// let mut pas = HashSet::new(); - -// #[cfg(feature = "auth_pubkey")] -// { -// let mut res = PubKeyAuthenticator::from_config(_config).await?; -// if let Some(pa) = res.take() { -// pas.insert(pa.into()); -// } -// } - -// #[cfg(feature = "auth_usrpwd")] -// { -// let mut res = UserPasswordAuthenticator::from_config(_config).await?; -// if let Some(pa) = res.take() { -// pas.insert(pa.into()); -// } -// } - -// Ok(pas) -// } -// } - -/*************************************/ -/* OPEN */ -/*************************************/ -// InitSyn -pub struct SendInitSynIn<'a> { - state: &'a mut [u8], - zid: &'a ZenohId, -} - -pub struct SendInitSynOut { - ext: Option, -} - -// InitAck -pub struct RecvInitAckIn<'a> { - state: &'a mut [u8], - zid: &'a ZenohId, - ext: Option, -} - -pub struct RecvInitAckOut {} - -// OpenSyn -pub struct SendOpenSynIn<'a> { - state: &'a mut [u8], - zid: &'a ZenohId, -} - -pub struct SendOpenSynOut { - ext: Option, -} - -// OpenAck -pub struct RecvOpenAckIn<'a> { - state: &'a mut [u8], - zid: &'a ZenohId, -} - -pub struct RecvOpenAckOut {} - -#[async_trait] -pub trait TransportAuthenticatorTrait<'a>: - OpenFsm< - '_, - SendInitSynIn = SendInitSynIn<'a>, - SendInitSynOut = SendInitSynOut, - RecvInitAckIn = RecvInitAckIn<'a>, - RecvInitAckOut = RecvInitAckOut, - SendOpenSynIn = SendOpenSynIn<'a>, - SendOpenSynOut = SendOpenSynOut, - RecvOpenAckIn = RecvOpenAckIn<'a>, - RecvOpenAckOut = RecvOpenAckOut, - Error = ZError, - > + AcceptFsm< - 'a, - RecvInitSynIn = (&'a mut [u8], &'a ZenohId, Option), - RecvInitSynOut = (), - SendInitAckIn = &'a mut [u8], - SendInitAckOut = Option, - RecvOpenSynIn = (&'a mut [u8], Option), - RecvOpenSynOut = (), - SendOpenAckIn = &'a mut [u8], - SendOpenAckOut = Option, - Error = ZError, - > + Send - + Sync -{ - fn id(&self) -> &'static str; - - async fn from_config(config: ()) -> ZResult - where - Self: Sized; - - async fn init(&self) -> ZResult>; - - // Close the authenticator - async fn close(&self); -} - -#[async_trait] -pub trait TransportAuthenticatorState<'a, W, R>: WCodec<&'a Self, W> + RCodec -where - Self: 'a + Sized, - W: Writer, - R: Reader, -{ -} - -// #[async_trait] -// pub trait TransportAuthenticatorTrait: Send + Sync { -// // Return the ID of this authenticator. -// fn id(&self) -> ZNodeAuthenticatorId; - -// Close the authenticator -// async fn close(&self); - -// Return the attachment to be included in the InitSyn message. -// -// # Arguments -// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the initial InitSyn message will be sent on -// -// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitSyn, i.e., the peer -// initiating a new transport. -// -// async fn get_init_syn_properties( -// &self, -// link: &AuthenticatedLink, -// node_id: &ZenohId, -// ) -> ZResult>>; - -// Return the attachment to be included in the InitAck message to be sent -// in response of the authenticated InitSyn. -// -// # Arguments -// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the InitSyn message was received on -// -// * `cookie` - The Cookie containing the internal state -// -// * `property` - The optional `Property` included in the InitSyn message -// -// async fn handle_init_syn( -// &self, -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: Option>, -// ) -> ZResult<(Option>, Option>)>; // (Attachment, Cookie) - -// Return the attachment to be included in the OpenSyn message to be sent -// in response of the authenticated InitAck. -// -// # Arguments -// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the InitSyn message was received on -// -// * `node_id` - The [`ZenohId`][ZenohId] of the sender of the InitAck message -// -// * `sn_resolution` - The sn_resolution negotiated by the sender of the InitAck message -// -// * `properties` - The optional `Property` included in the InitAck message -// -// async fn handle_init_ack( -// &self, -// link: &AuthenticatedLink, -// node_id: &ZenohId, -// sn_resolution: ZInt, -// property: Option>, -// ) -> ZResult>>; - -// Return the attachment to be included in the OpenAck message to be sent -// in response of the authenticated OpenSyn. -// -// # Arguments -// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the OpenSyn message was received on -// -// * `properties` - The optional `Property` included in the OpenSyn message -// -// * `cookie` - The optional `Property` included in the OpenSyn message -// -// async fn handle_open_syn( -// &self, -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: (Option>, Option>), // (Attachment, Cookie) -// ) -> ZResult>>; - -// Auhtenticate the OpenAck. No message is sent back in response to an OpenAck -// -// # Arguments -// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] the OpenAck message was received on -// -// * `properties` - The optional `Property` included in the OpenAck message -// -// async fn handle_open_ack( -// &self, -// link: &AuthenticatedLink, -// property: Option>, -// ) -> ZResult>>; - -// Handle any error on a link. This callback is mainly used to clean-up any internal state -// of the authenticator in such a way no unnecessary data is left around -// -// # Arguments -// * `link` - The [`AuthenticatedPeerLink`][AuthenticatedPeerLink] generating the error -// -// async fn handle_link_err(&self, link: &AuthenticatedLink); - -// Handle any error on a link. This callback is mainly used to clean-up any internal state -// of the authenticator in such a way no unnecessary data is left around -// -// # Arguments -// * `peerd_id` - The [`ZenohId`][ZenohId] of the transport being closed. -// -// async fn handle_close(&self, node_id: &ZenohId); -// } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/authenticator/usrpwd.rs deleted file mode 100644 index 11772a8c4e..0000000000 --- a/io/zenoh-transport/src/unicast/establishment/ext/authenticator/usrpwd.rs +++ /dev/null @@ -1,476 +0,0 @@ -// // -// // Copyright (c) 2022 ZettaScale Technology -// // -// // This program and the accompanying materials are made available under the -// // terms of the Eclipse Public License 2.0 which is available at -// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// // which is available at https://www.apache.org/licenses/LICENSE-2.0. -// // -// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// // -// // Contributors: -// // ZettaScale Zenoh Team, -// // -// use super::{ -// AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, -// }; -// use super::{Locator, ZInt, ZenohId}; -// use crate::unicast::establishment::Cookie; -// use async_std::fs; -// use async_std::sync::{Mutex, RwLock}; -// use async_trait::async_trait; -// use std::collections::{HashMap, HashSet}; -// use std::sync::Arc; -// use zenoh_buffers::{ -// reader::{DidntRead, HasReader, Reader}, -// writer::{DidntWrite, HasWriter, Writer}, -// }; -// use zenoh_cfg_properties::Properties; -// use zenoh_codec::{RCodec, WCodec, Zenoh080}; -// use zenoh_config::Config; -// use zenoh_core::{zasynclock, zasyncread, zasyncwrite}; -// use zenoh_crypto::hmac; -// use zenoh_result::{bail, zerror, ZResult}; - -// const USRPWD_VERSION: ZInt = 1; - -// /// # Attachment decorator -// /// -// /// ```text -// /// The Attachment can decorate any message (i.e., TransportMessage and ZenohMessage) and it allows to -// /// append to the message any additional information. Since the information contained in the -// /// Attachement is relevant only to the layer that provided them (e.g., Transport, Zenoh, User) it -// /// is the duty of that layer to serialize and de-serialize the attachment whenever deemed necessary. -// /// -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// | ENC | ATTCH | -// /// +-+-+-+---------+ -// /// ~ Attachment ~ -// /// +---------------+ -// /// -// /// ENC values: -// /// - 0x00 => Zenoh Properties -// /// ``` - -// /*************************************/ -// /* InitSyn */ -// /*************************************/ -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// |0 0 0| ATTCH | -// /// +-+-+-+---------+ -// /// ~ version ~ -// /// +---------------+ -// struct InitSynProperty { -// version: ZInt, -// } - -// impl WCodec<&InitSynProperty, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; - -// fn write(self, writer: &mut W, x: &InitSynProperty) -> Self::Output { -// self.write(&mut *writer, x.version)?; -// Ok(()) -// } -// } - -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; - -// fn read(self, reader: &mut R) -> Result { -// let version: ZInt = self.read(&mut *reader)?; -// Ok(InitSynProperty { version }) -// } -// } - -// /*************************************/ -// /* InitAck */ -// /*************************************/ -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// |0 0 0| ATTCH | -// /// +-+-+-+---------+ -// /// ~ nonce ~ -// /// +---------------+ -// struct InitAckProperty { -// nonce: ZInt, -// } - -// impl WCodec<&InitAckProperty, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; - -// fn write(self, writer: &mut W, x: &InitAckProperty) -> Self::Output { -// self.write(&mut *writer, x.nonce)?; -// Ok(()) -// } -// } - -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; - -// fn read(self, reader: &mut R) -> Result { -// let nonce: ZInt = self.read(&mut *reader)?; -// Ok(InitAckProperty { nonce }) -// } -// } - -// /*************************************/ -// /* OpenSyn */ -// /*************************************/ -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// |0 0 0| ATTCH | -// /// +-+-+-+---------+ -// /// ~ user ~ -// /// +---------------+ -// /// ~ hash ~ -// /// +---------------+ -// struct OpenSynProperty { -// user: Vec, -// hmac: Vec, -// } - -// impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; - -// fn write(self, writer: &mut W, x: &OpenSynProperty) -> Self::Output { -// self.write(&mut *writer, x.user.as_slice())?; -// self.write(&mut *writer, x.hmac.as_slice())?; -// Ok(()) -// } -// } - -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; - -// fn read(self, reader: &mut R) -> Result { -// let user: Vec = self.read(&mut *reader)?; -// let hmac: Vec = self.read(&mut *reader)?; -// Ok(OpenSynProperty { user, hmac }) -// } -// } - -// /*************************************/ -// /* Authenticator */ -// /*************************************/ -// struct Credentials { -// user: Vec, -// password: Vec, -// } - -// struct Authenticated { -// credentials: Credentials, -// links: HashSet<(Locator, Locator)>, -// } - -// pub struct UserPasswordAuthenticator { -// lookup: RwLock, Vec>>, -// credentials: Option, -// authenticated: Mutex>, -// } - -// impl UserPasswordAuthenticator { -// pub fn new( -// lookup: HashMap, Vec>, -// mut credentials: Option<(Vec, Vec)>, -// ) -> UserPasswordAuthenticator { -// let credentials = credentials.take().map(|cr| Credentials { -// user: cr.0, -// password: cr.1, -// }); -// UserPasswordAuthenticator { -// lookup: RwLock::new(lookup), -// credentials, -// authenticated: Mutex::new(HashMap::new()), -// } -// } - -// pub async fn add_user(&self, user: Vec, password: Vec) -> ZResult<()> { -// let mut guard = zasyncwrite!(self.lookup); -// guard.insert(user, password); -// Ok(()) -// } - -// pub async fn del_user(&self, user: &[u8]) -> ZResult<()> { -// let mut guard = zasyncwrite!(self.lookup); -// guard.remove(user); -// Ok(()) -// } - -// pub async fn from_config(config: &Config) -> ZResult> { -// let c = config.transport().auth().usrpwd(); - -// let mut lookup: HashMap, Vec> = HashMap::new(); -// if let Some(dict) = c.dictionary_file() { -// let content = fs::read_to_string(dict) -// .await -// .map_err(|e| zerror!("Invalid user-password dictionary file: {}", e))?; -// // Populate the user-password dictionary -// let mut ps = Properties::from(content); -// for (user, password) in ps.drain() { -// lookup.insert(user.into(), password.into()); -// } -// log::debug!("User-password dictionary has been configured"); -// } - -// let mut credentials: Option<(Vec, Vec)> = None; -// if let Some(user) = c.user() { -// if let Some(password) = c.password() { -// log::debug!("User and password have been configured"); -// credentials = Some((user.to_string().into(), password.to_string().into())); -// } -// } - -// if !lookup.is_empty() || credentials.is_some() { -// log::debug!("User-password authentication is enabled"); -// Ok(Some(UserPasswordAuthenticator::new(lookup, credentials))) -// } else { -// Ok(None) -// } -// } -// } - -// #[async_trait] -// impl TransportAuthenticatorTrait for UserPasswordAuthenticator { -// fn id(&self) -> ZNodeAuthenticatorId { -// ZNodeAuthenticatorId::UserPassword -// } - -// async fn close(&self) { -// // No cleanup needed -// } - -// async fn get_init_syn_properties( -// &self, -// link: &AuthenticatedLink, -// _node_id: &ZenohId, -// ) -> ZResult>> { -// // If credentials are not configured, don't initiate the USRPWD authentication -// if self.credentials.is_none() { -// return Ok(None); -// } - -// let init_syn_property = InitSynProperty { -// version: USRPWD_VERSION, -// }; -// let mut wbuf = vec![]; -// let codec = Zenoh080::new(); -// let mut writer = wbuf.writer(); -// codec -// .write(&mut writer, &init_syn_property) -// .map_err(|_| zerror!("Error in encoding InitSyn for UsrPwd on link: {}", link))?; -// let attachment = wbuf; - -// Ok(Some(attachment)) -// } - -// async fn handle_init_syn( -// &self, -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: Option>, -// ) -> ZResult<(Option>, Option>)> { -// let p = property.ok_or_else(|| { -// zerror!( -// "Received InitSyn with no UsrPwd attachment on link: {}", -// link -// ) -// })?; - -// let codec = Zenoh080::new(); - -// let mut reader = p.reader(); -// let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received InitSyn with invalid UsrPwd attachment on link: {}", -// link -// ) -// })?; -// if init_syn_property.version > USRPWD_VERSION { -// bail!("Rejected InitSyn with invalid attachment on link: {}", link) -// } - -// // Create the InitAck attachment -// let init_ack_property = InitAckProperty { -// nonce: cookie.nonce, -// }; -// let mut wbuf = vec![]; -// let mut writer = wbuf.writer(); -// codec -// .write(&mut writer, &init_ack_property) -// .map_err(|_| zerror!("Error in encoding InitAck for UsrPwd on link: {}", link))?; -// let attachment = wbuf; - -// Ok((Some(attachment), None)) -// } - -// async fn handle_init_ack( -// &self, -// link: &AuthenticatedLink, -// _node_id: &ZenohId, -// _sn_resolution: ZInt, -// property: Option>, -// ) -> ZResult>> { -// // If credentials are not configured, don't continue the USRPWD authentication -// let credentials = match self.credentials.as_ref() { -// Some(cr) => cr, -// None => return Ok(None), -// }; - -// let p = property.ok_or_else(|| { -// zerror!( -// "Received InitAck with no UsrPwd attachment on link: {}", -// link -// ) -// })?; - -// let codec = Zenoh080::new(); - -// let mut reader = p.reader(); -// let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received InitAck with invalid UsrPwd attachment on link: {}", -// link -// ) -// })?; - -// // Create the HMAC of the password using the nonce received as a key (it's a challenge) -// let key = init_ack_property.nonce.to_le_bytes(); -// let hmac = hmac::sign(&key, &credentials.password)?; -// // Create the OpenSyn attachment -// let open_syn_property = OpenSynProperty { -// user: credentials.user.clone(), -// hmac, -// }; -// // Encode the InitAck attachment -// let mut wbuf = vec![]; -// let mut writer = wbuf.writer(); -// codec -// .write(&mut writer, &open_syn_property) -// .map_err(|_| zerror!("Error in encoding OpenSyn for UsrPwd on link: {}", link))?; -// let attachment = wbuf; - -// Ok(Some(attachment)) -// } - -// async fn handle_open_syn( -// &self, -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: (Option>, Option>), -// ) -> ZResult>> { -// let (attachment, _cookie) = property; -// let a = attachment.ok_or_else(|| { -// zerror!( -// "Received OpenSyn with no UsrPwd attachment on link: {}", -// link -// ) -// })?; - -// let codec = Zenoh080::new(); - -// let mut reader = a.reader(); -// let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received OpenSyn with invalid UsrPwd attachment on link: {}", -// link -// ) -// })?; -// let password = match zasyncread!(self.lookup).get(&open_syn_property.user) { -// Some(password) => password.clone(), -// None => bail!("Received OpenSyn with invalid user on link: {}", link), -// }; - -// // Create the HMAC of the password using the nonce received as challenge -// let key = cookie.nonce.to_le_bytes(); -// let hmac = hmac::sign(&key, &password)?; -// if hmac != open_syn_property.hmac { -// bail!("Received OpenSyn with invalid password on link: {}", link) -// } - -// // Check PID validity -// let mut guard = zasynclock!(self.authenticated); -// match guard.get_mut(&cookie.zid) { -// Some(auth) => { -// if open_syn_property.user != auth.credentials.user -// || password != auth.credentials.password -// { -// bail!("Received OpenSyn with invalid password on link: {}", link) -// } -// auth.links.insert((link.src.clone(), link.dst.clone())); -// } -// None => { -// let credentials = Credentials { -// user: open_syn_property.user, -// password, -// }; -// let mut links = HashSet::new(); -// links.insert((link.src.clone(), link.dst.clone())); -// let auth = Authenticated { credentials, links }; -// guard.insert(cookie.zid, auth); -// } -// } - -// Ok(None) -// } - -// async fn handle_open_ack( -// &self, -// _link: &AuthenticatedLink, -// _property: Option>, -// ) -> ZResult>> { -// Ok(None) -// } - -// async fn handle_link_err(&self, link: &AuthenticatedLink) { -// // Need to check if it authenticated and remove it if this is the last link -// let mut guard = zasynclock!(self.authenticated); -// let mut to_del: Option = None; -// for (node_id, auth) in guard.iter_mut() { -// auth.links.remove(&(link.src.clone(), link.dst.clone())); -// if auth.links.is_empty() { -// to_del = Some(*node_id); -// break; -// } -// } -// if let Some(node_id) = to_del.take() { -// guard.remove(&node_id); -// } -// } - -// async fn handle_close(&self, node_id: &ZenohId) { -// zasynclock!(self.authenticated).remove(node_id); -// } -// } - -// //noinspection ALL -// impl From> for TransportAuthenticator { -// fn from(v: Arc) -> TransportAuthenticator { -// TransportAuthenticator(v) -// } -// } - -// impl From for TransportAuthenticator { -// fn from(v: UserPasswordAuthenticator) -> TransportAuthenticator { -// Self::from(Arc::new(v)) -// } -// } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs index 169faa461f..b982cbb461 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // -// pub(crate) mod auth; +pub mod auth; pub(crate) mod qos; #[cfg(feature = "shared-memory")] pub(crate) mod shm; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs index 872479ecd0..193d4352cb 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs @@ -35,6 +35,13 @@ impl State { pub(crate) const fn is_qos(&self) -> bool { self.is_qos } + + #[cfg(test)] + pub(crate) fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + Self::new(rng.gen_bool(0.5)) + } } // Codec @@ -65,11 +72,11 @@ where } // Extension Fsm -pub(crate) struct QoS<'a> { +pub(crate) struct QoSFsm<'a> { _a: PhantomData<&'a ()>, } -impl<'a> QoS<'a> { +impl<'a> QoSFsm<'a> { pub(crate) const fn new() -> Self { Self { _a: PhantomData } } @@ -79,7 +86,7 @@ impl<'a> QoS<'a> { /* OPEN */ /*************************************/ #[async_trait] -impl<'a> OpenFsm for QoS<'a> { +impl<'a> OpenFsm for QoSFsm<'a> { type Error = ZError; type SendInitSynIn = &'a State; @@ -126,7 +133,7 @@ impl<'a> OpenFsm for QoS<'a> { /* ACCEPT */ /*************************************/ #[async_trait] -impl<'a> AcceptFsm for QoS<'a> { +impl<'a> AcceptFsm for QoSFsm<'a> { type Error = ZError; type RecvInitSynIn = (&'a mut State, Option); diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index f0c4b1959e..51ab9260a6 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -139,6 +139,13 @@ impl State { pub(crate) const fn is_shm(&self) -> bool { self.is_shm } + + #[cfg(test)] + pub(crate) fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + Self::new(rng.gen_bool(0.5)) + } } // Codec @@ -169,18 +176,18 @@ where } // Extension Fsm -pub(crate) struct Shm<'a> { +pub(crate) struct ShmFsm<'a> { inner: &'a SharedMemoryUnicast, } -impl<'a> Shm<'a> { +impl<'a> ShmFsm<'a> { pub(crate) const fn new(inner: &'a SharedMemoryUnicast) -> Self { Self { inner } } } #[async_trait] -impl<'a> OpenFsm for Shm<'a> { +impl<'a> OpenFsm for ShmFsm<'a> { type Error = ZError; type SendInitSynIn = &'a State; @@ -222,7 +229,7 @@ impl<'a> OpenFsm for Shm<'a> { return Ok(0); } - let Some(mut ext) = ext.take() else { + let Some(ext) = ext.take() else { state.is_shm = false; return Ok(0); }; @@ -330,7 +337,7 @@ impl<'a> OpenFsm for Shm<'a> { /* ACCEPT */ /*************************************/ #[async_trait] -impl<'a> AcceptFsm for Shm<'a> { +impl<'a> AcceptFsm for ShmFsm<'a> { type Error = ZError; type RecvInitSynIn = (&'a mut State, Option); @@ -346,7 +353,7 @@ impl<'a> AcceptFsm for Shm<'a> { return Ok(0); } - let Some(mut ext) = ext.take() else { + let Some(ext) = ext.take() else { state.is_shm = false; return Ok(0); }; @@ -471,383 +478,3 @@ impl<'a> AcceptFsm for Shm<'a> { Ok(Some(open::ext::Shm::new(1))) } } - -// /*************************************/ -// /* Authenticator */ -// /*************************************/ -// #[async_trait] -// impl TransportAuthenticatorTrait for SharedMemoryAuthenticator { -// fn id(&self) -> ZNodeAuthenticatorId { -// ZNodeAuthenticatorId::Shm -// } - -// async fn close(&self) { -// // No cleanup needed -// } - -// async fn get_init_syn_properties( -// &self, -// link: &AuthenticatedLink, -// _node_id: &ZenohId, -// ) -> ZResult>> { -// let init_syn_property = InitSyn { -// version: SHM_VERSION, -// shm: self.buffer.info.serialize().unwrap().into(), -// }; -// let mut buff = vec![]; -// let codec = Zenoh080::new(); - -// let mut writer = buff.writer(); -// codec -// .write(&mut writer, &init_syn_property) -// .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; - -// Ok(Some(buff)) -// } - -// async fn handle_init_syn( -// &self, -// link: &AuthenticatedLink, -// cookie: &Cookie, -// mut property: Option>, -// ) -> ZResult<(Option>, Option>)> { -// let buffer = match property.take() { -// Some(p) => p, -// None => { -// log::debug!("Peer {} did not express interest in SHM", cookie.zid); -// return Ok((None, None)); -// } -// }; - -// let codec = Zenoh080::new(); -// let mut reader = buffer.reader(); - -// let mut init_syn_property: InitSyn = codec -// .read(&mut reader) -// .map_err(|_| zerror!("Received InitSyn with invalid attachment on link: {}", link))?; - -// if init_syn_property.version > SHM_VERSION { -// bail!("Rejected InitSyn with invalid attachment on link: {}", link) -// } - -// // Try to read from the shared memory -// match crate::shm::map_zslice_to_shmbuf(&mut init_syn_property.shm, &self.reader) { -// Ok(res) => { -// if !res { -// log::debug!("Peer {} can not operate over SHM: error", cookie.zid); -// return Ok((None, None)); -// } -// } -// Err(e) => { -// log::debug!("Peer {} can not operate over SHM: {}", cookie.zid, e); -// return Ok((None, None)); -// } -// } - -// log::debug!("Authenticating Shared Memory Access..."); - -// let xs = init_syn_property.shm; -// let bytes: [u8; SHM_SIZE] = match xs.as_slice().try_into() { -// Ok(bytes) => bytes, -// Err(e) => { -// log::debug!("Peer {} can not operate over SHM: {}", cookie.zid, e); -// return Ok((None, None)); -// } -// }; -// let challenge = ZInt::from_le_bytes(bytes); - -// // Create the InitAck attachment -// let init_ack_property = InitAckExt { -// challenge, -// shm: self.buffer.info.serialize().unwrap().into(), -// }; -// // Encode the InitAck property -// let mut buffer = vec![]; -// let mut writer = buffer.writer(); -// codec -// .write(&mut writer, &init_ack_property) -// .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; - -// Ok((Some(buffer), None)) -// } - -// async fn handle_init_ack( -// &self, -// link: &AuthenticatedLink, -// node_id: &ZenohId, -// _sn_resolution: ZInt, -// mut property: Option>, -// ) -> ZResult>> { -// let buffer = match property.take() { -// Some(p) => p, -// None => { -// log::debug!("Peer {} did not express interest in SHM", node_id); -// return Ok(None); -// } -// }; - -// let codec = Zenoh080::new(); -// let mut reader = buffer.reader(); - -// let mut init_ack_property: InitAckExt = codec -// .read(&mut reader) -// .map_err(|_| zerror!("Received InitAck with invalid attachment on link: {}", link))?; - -// // Try to read from the shared memory -// match crate::shm::map_zslice_to_shmbuf(&mut init_ack_property.shm, &self.reader) { -// Ok(res) => { -// if !res { -// return Err(ShmError(zerror!("No SHM on link: {}", link)).into()); -// } -// } -// Err(e) => return Err(ShmError(zerror!("No SHM on link {}: {}", link, e)).into()), -// } - -// let bytes: [u8; SHM_SIZE] = init_ack_property.shm.as_slice().try_into().map_err(|e| { -// zerror!( -// "Received InitAck with invalid attachment on link {}: {}", -// link, -// e -// ) -// })?; -// let challenge = ZInt::from_le_bytes(bytes); - -// if init_ack_property.challenge == self.challenge { -// // Create the OpenSyn attachment -// let open_syn_property = OpenSynExt { challenge }; -// // Encode the OpenSyn property -// let mut buffer = vec![]; -// let mut writer = buffer.writer(); - -// codec -// .write(&mut writer, &open_syn_property) -// .map_err(|_| zerror!("Error in encoding OpenSyn for SHM on link: {}", link))?; - -// Ok(Some(buffer)) -// } else { -// Err(ShmError(zerror!( -// "Received OpenSyn with invalid attachment on link: {}", -// link -// )) -// .into()) -// } -// } - -// async fn handle_open_syn( -// &self, -// link: &AuthenticatedLink, -// _cookie: &Cookie, -// property: (Option>, Option>), -// ) -> ZResult>> { -// let (mut attachment, _cookie) = property; -// let buffer = match attachment.take() { -// Some(p) => p, -// None => { -// return Err(ShmError(zerror!( -// "Received OpenSyn with no SHM attachment on link: {}", -// link -// )) -// .into()); -// } -// }; - -// let codec = Zenoh080::new(); -// let mut reader = buffer.reader(); - -// let open_syn_property: OpenSynExt = codec -// .read(&mut reader) -// .map_err(|_| zerror!("Received OpenSyn with invalid attachment on link: {}", link))?; - -// if open_syn_property.challenge == self.challenge { -// Ok(None) -// } else { -// Err(ShmError(zerror!( -// "Received OpenSyn with invalid attachment on link: {}", -// link -// )) -// .into()) -// } -// } - -// async fn handle_open_ack( -// &self, -// _link: &AuthenticatedLink, -// _property: Option>, -// ) -> ZResult>> { -// Ok(None) -// } - -// async fn handle_link_err(&self, _link: &AuthenticatedLink) {} - -// async fn handle_close(&self, _node_id: &ZenohId) {} -// } - -// // Open -// pub(crate) struct InitAckOpenState { -// buffer: SharedMemoryBuf, -// } - -// impl InitAck { -// pub(crate) fn recv( -// ext: &init::ext::Shm, -// shm: &SharedMemoryUnicast, -// ) -> ZResult<(init::ext::Shm, InitAckOpenState)> { -// let info = SharedMemoryBufInfo::deserialize(ext.value.as_slice())?; - -// // Try to read from the shared memory -// let mut zslice = ext.value.clone(); -// match crate::shm::map_zslice_to_shmbuf(&mut zslice, reader) { -// Ok(false) => { -// log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); -// return Ok((None, None)); -// } -// Err(e) => { -// log::debug!("Zenoh node can not operate over SHM: {}", e); -// return Ok((None, None)); -// } -// Ok(true) => { -// // Payload is SHM: continue. -// } -// } - -// match crate::shm::map_zslice_to_shmbuf(&mut ext, &shm.reader) { -// Ok(res) => { -// if !res { -// return Err(ShmError(zerror!("No SHM on link: {}", link)).into()); -// } -// } -// Err(e) => return Err(ShmError(zerror!("No SHM on link {}: {}", link, e)).into()), -// } - -// let bytes: [u8; std::mem::size_of::()] = -// init_ack_property.shm.as_slice().try_into().map_err(|e| { -// zerror!( -// "Received InitAck with invalid attachment on link {}: {}", -// link, -// e -// ) -// })?; -// let challenge = ZInt::from_le_bytes(bytes); - -// let challenge = (); -// let init_syn_property = InitAck { -// version: shm::VERSION, -// info: shm -// .buffer -// .info -// .serialize() -// .map_err(|e| zerror!("{e}"))? -// .into(), -// }; -// let mut buff = vec![]; -// let codec = Zenoh080::new(); - -// let mut writer = buff.writer(); -// codec -// .write(&mut writer, &init_syn_property) -// .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; - -// Ok(Some(buff)) -// panic!() -// } -// } - -// Open -// pub(crate) struct InitSynOpenState { -// buffer: SharedMemoryBuf, -// } - -// impl InitSyn { -// pub(crate) fn send(shm: &SharedMemoryUnicast) -> ZResult<(init::ext::Shm, InitSynOpenState)> { -// let init_syn_property = InitSyn { -// version: shm::VERSION, -// info: shm -// .buffer -// .info -// .serialize() -// .map_err(|e| zerror!("{e}"))? -// .into(), -// }; -// let mut buff = vec![]; -// let codec = Zenoh080::new(); - -// let mut writer = buff.writer(); -// codec -// .write(&mut writer, &init_syn_property) -// .map_err(|_| zerror!("Error in encoding InitSyn SHM extension"))?; - -// Ok(Some(buff)) -// } -// } - -// pub(crate) struct InitSynAcceptInput { -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: Option>, -// } - -// Accept -// pub(crate) struct InitSynAcceptState {} - -// impl InitSyn { -// pub(crate) fn accept( -// ext: &init::ext::Shm, -// reader: &SharedMemoryReader, -// ) -> ZResult { -// let codec = Zenoh080::new(); -// let mut reader = ext.reader(); - -// let mut init_syn_ext: InitSyn = codec -// .read(&mut reader) -// .map_err(|_| zerror!("Error in decoding InitSyn SHM extension"))?; - -// if init_syn_ext.version != SHM_VERSION { -// bail!( -// "Incompatible InitSyn SHM extension version. Expected: {}. Received: {}.", -// SHM_VERSION, -// init_syn_ext.version -// ); -// } - -// // Try to read from the shared memory -// match crate::shm::map_zslice_to_shmbuf(&mut init_syn_ext.shm, reader) { -// Ok(false) => { -// log::debug!("Zenoh node can not operate over SHM: not an SHM buffer"); -// return Ok((None, None)); -// } -// Err(e) => { -// log::debug!("Zenoh node can not operate over SHM: {}", e); -// return Ok((None, None)); -// } -// Ok(true) => { -// // Payload is SHM: continue. -// } -// } - -// log::trace!("Verifying SHM extension"); - -// let xs = init_syn_ext.shm; -// let bytes: [u8; SHM_SIZE] = match xs.as_slice().try_into() { -// Ok(bytes) => bytes, -// Err(e) => { -// log::debug!("Zenoh node can not operate over SHM: {}", e); -// return Ok((None, None)); -// } -// }; -// let challenge = ZInt::from_le_bytes(bytes); - -// // Create the InitAck attachment -// let init_ack_property = InitAckExt { -// challenge, -// shm: buffer.info.serialize()?.into(), -// }; -// // Encode the InitAck property -// let mut buffer = vec![]; -// let mut writer = buffer.writer(); -// codec -// .write(&mut writer, &init_ack_property) -// .map_err(|_| zerror!("Error in encoding InitSyn for SHM on link: {}", link))?; - -// Ok((Some(buffer), None)) -// } -// } diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index ea2b58e370..5006d6f86d 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -13,7 +13,7 @@ // pub(crate) mod accept; pub(super) mod cookie; -pub(super) mod ext; +pub mod ext; pub(crate) mod open; use super::{TransportPeer, TransportUnicast}; diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 72e55d6ba4..56ddcdd89d 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -23,7 +23,7 @@ use async_trait::async_trait; use std::time::Duration; use zenoh_buffers::ZSlice; use zenoh_config::{WhatAmI, ZenohId}; -use zenoh_core::zerror; +use zenoh_core::{zasynclock, zasyncread, zerror}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::core::{Field, Resolution, ZInt}; use zenoh_protocol::transport::{close, Close, InitSyn, OpenSyn, TransportBody, TransportMessage}; @@ -41,6 +41,7 @@ struct State { ext_qos: ext::qos::State, #[cfg(feature = "shared-memory")] ext_shm: ext::shm::State, + ext_auth: ext::auth::State, } // InitSyn @@ -83,9 +84,10 @@ struct RecvOpenAckOut { // FSM struct OpenLink<'a> { link: &'a LinkUnicast, - ext_qos: ext::qos::QoS<'a>, + ext_qos: ext::qos::QoSFsm<'a>, #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::Shm<'a>, + ext_shm: ext::shm::ShmFsm<'a>, + ext_auth: ext::auth::AuthFsm<'a>, } #[async_trait] @@ -117,6 +119,13 @@ impl<'a> OpenFsm for OpenLink<'a> { #[cfg(not(feature = "shared-memory"))] let ext_shm = None; + // Extension Auth + let ext_auth = self + .ext_auth + .send_init_syn(&state.ext_auth) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let msg: TransportMessage = InitSyn { version: input.mine_version, whatami: input.mine_whatami, @@ -125,7 +134,7 @@ impl<'a> OpenFsm for OpenLink<'a> { resolution: state.zenoh.resolution, ext_qos, ext_shm, - ext_auth: None, // @TODO + ext_auth, } .into(); @@ -231,6 +240,12 @@ impl<'a> OpenFsm for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension Auth + self.ext_auth + .recv_init_ack((&mut state.ext_auth, init_ack.ext_auth)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvInitAckOut { other_zid: init_ack.zid, other_whatami: init_ack.whatami, @@ -266,6 +281,13 @@ impl<'a> OpenFsm for OpenLink<'a> { #[cfg(not(feature = "shared-memory"))] let ext_shm = None; + // Extension Auth + let ext_auth = self + .ext_auth + .send_open_syn(&state.ext_auth) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Build and send an OpenSyn message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); let message: TransportMessage = OpenSyn { @@ -274,7 +296,7 @@ impl<'a> OpenFsm for OpenLink<'a> { cookie: input.other_cookie, ext_qos, ext_shm, - ext_auth: None, // @TODO + ext_auth, } .into(); @@ -338,6 +360,12 @@ impl<'a> OpenFsm for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension Auth + self.ext_auth + .recv_open_ack((&mut state.ext_auth, open_ack.ext_auth)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvOpenAckOut { other_initial_sn: open_ack.initial_sn, other_lease: open_ack.lease, @@ -350,11 +378,13 @@ pub(crate) async fn open_link( link: &LinkUnicast, manager: &TransportManager, ) -> ZResult { + let auth = zasyncread!(manager.state.unicast.authenticator); let fsm = OpenLink { link, - ext_qos: ext::qos::QoS::new(), + ext_qos: ext::qos::QoSFsm::new(), #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::Shm::new(&manager.state.unicast.shm), + ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), + ext_auth: ext::auth::AuthFsm::new(&auth), }; // Init handshake @@ -378,6 +408,7 @@ pub(crate) async fn open_link( ext_qos: ext::qos::State::new(manager.config.unicast.is_qos), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::State::new(manager.config.unicast.is_shm), + ext_auth: auth.state(&mut *zasynclock!(manager.prng)), }; let isyn_in = SendInitSynIn { diff --git a/io/zenoh-transport/src/unicast/establishment/properties.rs b/io/zenoh-transport/src/unicast/establishment/properties.rs index ca5e8dffd5..19e1d7c345 100644 --- a/io/zenoh-transport/src/unicast/establishment/properties.rs +++ b/io/zenoh-transport/src/unicast/establishment/properties.rs @@ -66,7 +66,7 @@ impl TryFrom<&EstablishmentProperties> for Attachment { bail!("Can not create an attachment with zero properties") } - let mut zbuf = ZBuf::default(); + let mut zbuf = ZBuf::empty(); let mut writer = zbuf.writer(); let codec = Zenoh080::new(); diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 9ca8451459..0df859b706 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -14,10 +14,17 @@ #[cfg(feature = "shared-memory")] use crate::unicast::shm::SharedMemoryUnicast; use crate::{ - unicast::{transport::TransportUnicastInner, TransportConfigUnicast, TransportUnicast}, + unicast::{ + establishment::ext::auth::Auth, transport::TransportUnicastInner, TransportConfigUnicast, + TransportUnicast, + }, TransportManager, }; -use async_std::{prelude::FutureExt, sync::Mutex, task}; +use async_std::{ + prelude::FutureExt, + sync::{Mutex, RwLock}, + task, +}; use std::{collections::HashMap, sync::Arc, time::Duration}; #[cfg(feature = "shared-memory")] use zenoh_config::SharedMemoryConf; @@ -48,8 +55,8 @@ pub struct TransportManagerConfigUnicast { pub struct TransportManagerStateUnicast { // Incoming uninitialized transports pub(super) incoming: Arc>, - // Active peer authenticators - // pub(super) peer_authenticator: Arc>>, @TODO + // Active authenticators + pub(super) authenticator: Arc>, // Established listeners pub(super) protocols: Arc>>, // Established transports @@ -79,7 +86,7 @@ pub struct TransportManagerBuilderUnicast { pub(super) is_qos: bool, #[cfg(feature = "shared-memory")] pub(super) is_shm: bool, - // pub(super) peer_authenticator: HashSet, @TODO + pub(super) authenticator: Auth, } impl TransportManagerBuilderUnicast { @@ -113,10 +120,10 @@ impl TransportManagerBuilderUnicast { self } - // pub fn peer_authenticator(mut self, peer_authenticator: HashSet) -> Self { - // self.peer_authenticator = peer_authenticator; - // self - // } @TODO + pub fn authenticator(mut self, authenticator: Auth) -> Self { + self.authenticator = authenticator; + self + } pub fn qos(mut self, is_qos: bool) -> Self { self.is_qos = is_qos; @@ -146,7 +153,7 @@ impl TransportManagerBuilderUnicast { { self = self.shm(*config.transport().shared_memory().enabled()); } - // self = self.peer_authenticator(PeerAuthenticator::from_config(config).await?); + self = self.authenticator(Auth::from_config(config).await?); Ok(self) } @@ -182,7 +189,7 @@ impl TransportManagerBuilderUnicast { incoming: Arc::new(Mutex::new(0)), protocols: Arc::new(Mutex::new(HashMap::new())), transports: Arc::new(Mutex::new(HashMap::new())), - // peer_authenticator: Arc::new(AsyncRwLock::new(self.peer_authenticator)), + authenticator: Arc::new(RwLock::new(self.authenticator)), #[cfg(feature = "shared-memory")] shm: Arc::new(SharedMemoryUnicast::make()?), }; @@ -211,7 +218,7 @@ impl Default for TransportManagerBuilderUnicast { is_qos: *qos.enabled(), #[cfg(feature = "shared-memory")] is_shm: *shm.enabled(), - // peer_authenticator: HashSet::new(), + authenticator: Auth::default(), } } } @@ -499,3 +506,10 @@ impl TransportManager { }); } } + +#[cfg(feature = "test")] +impl TransportManager { + pub fn get_auth_handle_unicast(&self) -> Arc> { + self.state.unicast.authenticator.clone() + } +} diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index 34ba00949f..cb4f4be451 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -1,117 +1,99 @@ -// // -// // Copyright (c) 2022 ZettaScale Technology -// // -// // This program and the accompanying materials are made available under the -// // terms of the Eclipse Public License 2.0 which is available at -// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// // which is available at https://www.apache.org/licenses/LICENSE-2.0. -// // -// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// // -// // Contributors: -// // ZettaScale Zenoh Team, -// // -// use async_std::{prelude::FutureExt, task}; -// #[cfg(feature = "auth_pubkey")] +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use async_std::{prelude::FutureExt, task}; +#[cfg(feature = "auth_pubkey")] // use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; -// #[cfg(feature = "auth_usrpwd")] -// use std::collections::HashMap; -// use std::{any::Any, collections::HashSet, iter::FromIterator, sync::Arc, time::Duration}; -// use zenoh_core::zasync_executor_init; -// use zenoh_link::Link; -// use zenoh_protocol::{ -// core::{EndPoint, WhatAmI, ZenohId}, -// zenoh::ZenohMessage, -// }; -// use zenoh_result::ZResult; +use std::{any::Any, sync::Arc, time::Duration}; +use zenoh_core::{zasync_executor_init, zasyncwrite}; +use zenoh_link::Link; +use zenoh_protocol::{ + core::{EndPoint, WhatAmI, ZenohId}, + zenoh::ZenohMessage, +}; +use zenoh_result::ZResult; // #[cfg(feature = "auth_pubkey")] -// use zenoh_transport::unicast::establishment::authenticator::PubKeyAuthenticator; -// #[cfg(feature = "shared-memory")] -// use zenoh_transport::unicast::establishment::authenticator::SharedMemoryAuthenticator; -// #[cfg(feature = "auth_usrpwd")] -// use zenoh_transport::unicast::establishment::authenticator::UserPasswordAuthenticator; -// use zenoh_transport::{ -// DummyTransportPeerEventHandler, TransportEventHandler, TransportMulticast, -// TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, -// }; - -// const TIMEOUT: Duration = Duration::from_secs(60); -// const SLEEP: Duration = Duration::from_millis(100); - -// macro_rules! ztimeout { -// ($f:expr) => { -// $f.timeout(TIMEOUT).await.unwrap() -// }; -// } - -// #[cfg(test)] -// struct SHRouterAuthenticator; - -// impl SHRouterAuthenticator { -// fn new() -> Self { -// Self -// } -// } - -// impl TransportEventHandler for SHRouterAuthenticator { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// Ok(Arc::new(MHRouterAuthenticator::new())) -// } - -// fn new_multicast( -// &self, -// _transport: TransportMulticast, -// ) -> ZResult> { -// panic!(); -// } -// } - -// struct MHRouterAuthenticator; - -// impl MHRouterAuthenticator { -// fn new() -> Self { -// Self -// } -// } - -// impl TransportPeerEventHandler for MHRouterAuthenticator { -// fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { -// Ok(()) -// } -// fn new_link(&self, _link: Link) {} -// fn del_link(&self, _link: Link) {} -// fn closing(&self) {} -// fn closed(&self) {} - -// fn as_any(&self) -> &dyn Any { -// self -// } -// } - -// // Transport Handler for the client -// #[derive(Default)] -// struct SHClientAuthenticator; - -// impl TransportEventHandler for SHClientAuthenticator { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// Ok(Arc::new(DummyTransportPeerEventHandler::default())) -// } - -// fn new_multicast( -// &self, -// _transport: TransportMulticast, -// ) -> ZResult> { -// panic!(); -// } -// } +// use zenoh_transport::unicast::establishment::ext::auth::PubKeyAuthenticator; +#[cfg(feature = "auth_usrpwd")] +use zenoh_transport::unicast::establishment::ext::auth::Auth; +use zenoh_transport::{ + DummyTransportPeerEventHandler, TransportEventHandler, TransportPeer, + TransportPeerEventHandler, TransportUnicast, +}; + +const TIMEOUT: Duration = Duration::from_secs(60); +const SLEEP: Duration = Duration::from_millis(100); + +macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; +} + +#[cfg(test)] +struct SHRouterAuthenticator; + +impl SHRouterAuthenticator { + fn new() -> Self { + Self + } +} + +impl TransportEventHandler for SHRouterAuthenticator { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + Ok(Arc::new(MHRouterAuthenticator::new())) + } +} + +struct MHRouterAuthenticator; + +impl MHRouterAuthenticator { + fn new() -> Self { + Self + } +} + +impl TransportPeerEventHandler for MHRouterAuthenticator { + fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { + Ok(()) + } + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } +} + +// Transport Handler for the client +#[derive(Default)] +struct SHClientAuthenticator; + +impl TransportEventHandler for SHClientAuthenticator { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + Ok(Arc::new(DummyTransportPeerEventHandler::default())) + } +} // #[cfg(feature = "auth_pubkey")] // async fn authenticator_multilink(endpoint: &EndPoint) { @@ -513,291 +495,213 @@ // task::sleep(SLEEP).await; // } -// #[cfg(feature = "auth_usrpwd")] -// async fn authenticator_user_password(endpoint: &EndPoint) { -// use std::convert::TryFrom; -// use zenoh_transport::TransportManager; - -// /* [CLIENT] */ -// let client01_id = ZenohId::try_from([2]).unwrap(); -// let user01 = "user01".to_string(); -// let password01 = "password01".to_string(); - -// let client02_id = ZenohId::try_from([3]).unwrap(); -// let user02 = "invalid".to_string(); -// let password02 = "invalid".to_string(); - -// let client03_id = client01_id; -// let user03 = "user03".to_string(); -// let password03 = "password03".to_string(); - -// /* [ROUTER] */ -// let router_id = ZenohId::try_from([1]).unwrap(); -// let router_handler = Arc::new(SHRouterAuthenticator::new()); -// // Create the router transport manager -// let mut lookup: HashMap, Vec> = HashMap::new(); -// lookup.insert(user01.clone().into(), password01.clone().into()); -// lookup.insert(user03.clone().into(), password03.clone().into()); - -// let peer_auth_router = Arc::new(UserPasswordAuthenticator::new(lookup, None)); -// let unicast = TransportManager::config_unicast() -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_router.clone().into()])); -// let router_manager = TransportManager::builder() -// .whatami(WhatAmI::Router) -// .zid(router_id) -// .unicast(unicast) -// .build(router_handler.clone()) -// .unwrap(); - -// // Create the transport transport manager for the first client -// let lookup: HashMap, Vec> = HashMap::new(); -// let peer_auth_client01 = UserPasswordAuthenticator::new( -// lookup, -// Some((user01.clone().into(), password01.clone().into())), -// ); -// let unicast = TransportManager::config_unicast() -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client01.into()])); -// let client01_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client01_id) -// .unicast(unicast) -// .build(Arc::new(SHClientAuthenticator::default())) -// .unwrap(); - -// // Create the transport transport manager for the second client -// let lookup: HashMap, Vec> = HashMap::new(); -// let peer_auth_client02 = UserPasswordAuthenticator::new( -// lookup, -// Some((user02.clone().into(), password02.clone().into())), -// ); -// let unicast = TransportManager::config_unicast() -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client02.into()])); -// let client02_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client02_id) -// .unicast(unicast) -// .build(Arc::new(SHClientAuthenticator::default())) -// .unwrap(); - -// // Create the transport transport manager for the third client -// let lookup: HashMap, Vec> = HashMap::new(); -// let peer_auth_client03 = UserPasswordAuthenticator::new( -// lookup, -// Some((user03.clone().into(), password03.clone().into())), -// ); -// let unicast = TransportManager::config_unicast() -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client03.into()])); -// let client03_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client03_id) -// .unicast(unicast) -// .build(Arc::new(SHClientAuthenticator::default())) -// .unwrap(); - -// /* [1] */ -// println!("\nTransport Authenticator UserPassword [1a1]"); -// // Add the locator on the router -// let res = ztimeout!(router_manager.add_listener(endpoint.clone())); -// println!("Transport Authenticator UserPassword [1a1]: {res:?}"); -// assert!(res.is_ok()); -// println!("Transport Authenticator UserPassword [1a2]"); -// let locators = router_manager.get_listeners(); -// println!("Transport Authenticator UserPassword [1a2]: {locators:?}"); -// assert_eq!(locators.len(), 1); - -// /* [2] */ -// // Open a first transport from the client to the router -// // -> This should be accepted -// println!("Transport Authenticator UserPassword [2a1]"); -// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator UserPassword [2a1]: {res:?}"); -// assert!(res.is_ok()); -// let c_ses1 = res.unwrap(); - -// /* [3] */ -// println!("Transport Authenticator UserPassword [3a1]"); -// let res = ztimeout!(c_ses1.close()); -// println!("Transport Authenticator UserPassword [3a1]: {res:?}"); -// assert!(res.is_ok()); - -// ztimeout!(async { -// while !router_manager.get_transports().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// /* [4] */ -// // Open a second transport from the client to the router -// // -> This should be rejected -// println!("Transport Authenticator UserPassword [4a1]"); -// let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator UserPassword [4a1]: {res:?}"); -// assert!(res.is_err()); - -// /* [5] */ -// // Open a third transport from the client to the router -// // -> This should be accepted -// println!("Transport Authenticator UserPassword [5a1]"); -// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator UserPassword [5a1]: {res:?}"); -// assert!(res.is_ok()); -// let c_ses1 = res.unwrap(); - -// /* [6] */ -// // Add client02 credentials on the router -// let res = ztimeout!(peer_auth_router.add_user(user02.into(), password02.into())); -// assert!(res.is_ok()); -// // Open a fourth transport from the client to the router -// // -> This should be accepted -// println!("Transport Authenticator UserPassword [6a1]"); -// let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator UserPassword [6a1]: {res:?}"); -// assert!(res.is_ok()); -// let c_ses2 = res.unwrap(); - -// /* [7] */ -// // Open a fourth transport from the client to the router -// // -> This should be rejected -// println!("Transport Authenticator UserPassword [7a1]"); -// let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator UserPassword [7a1]: {res:?}"); -// assert!(res.is_err()); - -// /* [8] */ -// println!("Transport Authenticator UserPassword [8a1]"); -// let res = ztimeout!(c_ses1.close()); -// println!("Transport Authenticator UserPassword [8a1]: {res:?}"); -// assert!(res.is_ok()); -// println!("Transport Authenticator UserPassword [8a2]"); -// let res = ztimeout!(c_ses2.close()); -// println!("Transport Authenticator UserPassword [8a2]: {res:?}"); -// assert!(res.is_ok()); - -// ztimeout!(async { -// while !router_manager.get_transports().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// /* [9] */ -// // Perform clean up of the open locators -// println!("Transport Authenticator UserPassword [9a1]"); -// let res = ztimeout!(router_manager.del_listener(endpoint)); -// println!("Transport Authenticator UserPassword [9a2]: {res:?}"); -// assert!(res.is_ok()); - -// ztimeout!(async { -// while !router_manager.get_listeners().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } - -// #[cfg(feature = "shared-memory")] -// async fn authenticator_shared_memory(endpoint: &EndPoint) { -// use std::convert::TryFrom; -// use zenoh_transport::TransportManager; - -// /* [CLIENT] */ -// let client_id = ZenohId::try_from([2]).unwrap(); - -// /* [ROUTER] */ -// let router_id = ZenohId::try_from([1]).unwrap(); -// let router_handler = Arc::new(SHRouterAuthenticator::new()); -// // Create the router transport manager -// let peer_auth_router = SharedMemoryAuthenticator::make().unwrap(); -// let unicast = TransportManager::config_unicast() -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_router.into()])); -// let router_manager = TransportManager::builder() -// .whatami(WhatAmI::Router) -// .zid(router_id) -// .unicast(unicast) -// .build(router_handler.clone()) -// .unwrap(); - -// // Create the transport transport manager for the first client -// let peer_auth_client = SharedMemoryAuthenticator::make().unwrap(); -// let unicast = TransportManager::config_unicast() -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client.into()])); -// let client_manager = TransportManager::builder() -// .whatami(WhatAmI::Router) -// .zid(client_id) -// .unicast(unicast) -// .build(Arc::new(SHClientAuthenticator::default())) -// .unwrap(); - -// /* [1] */ -// println!("\nTransport Authenticator SharedMemory [1a1]"); -// // Add the locator on the router -// let res = ztimeout!(router_manager.add_listener(endpoint.clone())); -// println!("Transport Authenticator SharedMemory [1a1]: {res:?}"); -// assert!(res.is_ok()); -// println!("Transport Authenticator SharedMemory [1a2]"); -// let locators = router_manager.get_listeners(); -// println!("Transport Authenticator SharedMemory 1a2]: {locators:?}"); -// assert_eq!(locators.len(), 1); - -// /* [2] */ -// // Open a transport from the client to the router -// // -> This should be accepted -// println!("Transport Authenticator SharedMemory [2a1]"); -// let res = ztimeout!(client_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator SharedMemory [2a1]: {res:?}"); -// assert!(res.is_ok()); -// let c_ses1 = res.unwrap(); -// assert!(c_ses1.is_shm().unwrap()); - -// /* [3] */ -// println!("Transport Authenticator SharedMemory [3a1]"); -// let res = ztimeout!(c_ses1.close()); -// println!("Transport Authenticator SharedMemory [3a1]: {res:?}"); -// assert!(res.is_ok()); - -// ztimeout!(async { -// while !router_manager.get_transports().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// /* [4] */ -// // Perform clean up of the open locators -// println!("Transport Authenticator SharedMemory [4a1]"); -// let res = ztimeout!(router_manager.del_listener(endpoint)); -// println!("Transport Authenticator SharedMemory [4a2]: {res:?}"); -// assert!(res.is_ok()); - -// ztimeout!(async { -// while !router_manager.get_listeners().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// task::sleep(SLEEP).await; -// } - -// async fn run(endpoint: &EndPoint) { -// #[cfg(feature = "auth_pubkey")] -// authenticator_multilink(endpoint).await; -// #[cfg(feature = "auth_usrpwd")] -// authenticator_user_password(endpoint).await; -// #[cfg(feature = "shared-memory")] -// authenticator_shared_memory(endpoint).await; -// } - -// #[cfg(feature = "transport_tcp")] -// #[test] -// fn authenticator_tcp() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 8000).parse().unwrap(); -// task::block_on(run(&endpoint)); -// } +#[cfg(feature = "auth_usrpwd")] +async fn auth_usrpwd(endpoint: &EndPoint) { + use std::convert::TryFrom; + use zenoh_transport::establishment::ext::auth::usrpwd::AuthUsrPwd; + use zenoh_transport::TransportManager; + + /* [CLIENT] */ + let client01_id = ZenohId::try_from([2]).unwrap(); + let user01 = "user01".to_string(); + let password01 = "password01".to_string(); + + let client02_id = ZenohId::try_from([3]).unwrap(); + let user02 = "invalid".to_string(); + let password02 = "invalid".to_string(); + + let client03_id = client01_id; + let user03 = "user03".to_string(); + let password03 = "password03".to_string(); + + /* [ROUTER] */ + let router_id = ZenohId::try_from([1]).unwrap(); + let router_handler = Arc::new(SHRouterAuthenticator::new()); + // Create the router transport manager + let mut auth_usrpwd_router = AuthUsrPwd::new(None); + auth_usrpwd_router + .add_user(user01.clone().into(), password01.clone().into()) + .await + .unwrap(); + auth_usrpwd_router + .add_user(user03.clone().into(), password03.clone().into()) + .await + .unwrap(); + let mut auth_router = Auth::empty(); + auth_router.set_usrpwd(Some(auth_usrpwd_router)); + + let unicast = TransportManager::config_unicast().authenticator(auth_router); + let router_manager = TransportManager::builder() + .whatami(WhatAmI::Router) + .zid(router_id) + .unicast(unicast) + .build(router_handler.clone()) + .unwrap(); + + // Create the transport transport manager for the first client + let auth_usrpwdr_client01 = + AuthUsrPwd::new(Some((user01.clone().into(), password01.clone().into()))); + let mut auth_client01 = Auth::empty(); + auth_client01.set_usrpwd(Some(auth_usrpwdr_client01)); + let unicast = TransportManager::config_unicast().authenticator(auth_client01); + let client01_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client01_id) + .unicast(unicast) + .build(Arc::new(SHClientAuthenticator::default())) + .unwrap(); + + // Create the transport transport manager for the second client + let auth_usrpwdr_client02 = + AuthUsrPwd::new(Some((user02.clone().into(), password02.clone().into()))); + let mut auth_client02 = Auth::empty(); + auth_client02.set_usrpwd(Some(auth_usrpwdr_client02)); + let unicast = TransportManager::config_unicast().authenticator(auth_client02); + let client02_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client02_id) + .unicast(unicast) + .build(Arc::new(SHClientAuthenticator::default())) + .unwrap(); + + // Create the transport transport manager for the third client + let auth_usrpwdr_client03 = + AuthUsrPwd::new(Some((user03.clone().into(), password03.clone().into()))); + let mut auth_client03 = Auth::empty(); + auth_client03.set_usrpwd(Some(auth_usrpwdr_client03)); + let unicast = TransportManager::config_unicast().authenticator(auth_client03); + let client03_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client03_id) + .unicast(unicast) + .build(Arc::new(SHClientAuthenticator::default())) + .unwrap(); + + /* [1] */ + println!("\nTransport Authenticator UserPassword [1a1]"); + // Add the locator on the router + let res = ztimeout!(router_manager.add_listener(endpoint.clone())); + println!("Transport Authenticator UserPassword [1a1]: {res:?}"); + assert!(res.is_ok()); + println!("Transport Authenticator UserPassword [1a2]"); + let locators = router_manager.get_listeners(); + println!("Transport Authenticator UserPassword [1a2]: {locators:?}"); + assert_eq!(locators.len(), 1); + + /* [2] */ + // Open a first transport from the client to the router + // -> This should be accepted + println!("Transport Authenticator UserPassword [2a1]"); + let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + println!("Transport Authenticator UserPassword [2a1]: {res:?}"); + assert!(res.is_ok()); + let c_ses1 = res.unwrap(); + + /* [3] */ + println!("Transport Authenticator UserPassword [3a1]"); + let res = ztimeout!(c_ses1.close()); + println!("Transport Authenticator UserPassword [3a1]: {res:?}"); + assert!(res.is_ok()); + + ztimeout!(async { + while !router_manager.get_transports().is_empty() { + task::sleep(SLEEP).await; + } + }); + + /* [4] */ + // Open a second transport from the client to the router + // -> This should be rejected + println!("Transport Authenticator UserPassword [4a1]"); + let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + println!("Transport Authenticator UserPassword [4a1]: {res:?}"); + assert!(res.is_err()); + + /* [5] */ + // Open a third transport from the client to the router + // -> This should be accepted + println!("Transport Authenticator UserPassword [5a1]"); + let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + println!("Transport Authenticator UserPassword [5a1]: {res:?}"); + assert!(res.is_ok()); + let c_ses1 = res.unwrap(); + + /* [6] */ + // Add client02 credentials on the router + let auth_router = router_manager.get_auth_handle_unicast(); + ztimeout!(zasyncwrite!(auth_router) + .get_usrpwd_mut() + .unwrap() + .add_user(user02.into(), password02.into())) + .unwrap(); + + // Open a fourth transport from the client to the router + // -> This should be accepted + println!("Transport Authenticator UserPassword [6a1]"); + let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + println!("Transport Authenticator UserPassword [6a1]: {res:?}"); + assert!(res.is_ok()); + let c_ses2 = res.unwrap(); + + /* [7] */ + // Open a fourth transport from the client to the router + // -> This should be rejected + println!("Transport Authenticator UserPassword [7a1]"); + let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); + println!("Transport Authenticator UserPassword [7a1]: {res:?}"); + assert!(res.is_err()); + + /* [8] */ + println!("Transport Authenticator UserPassword [8a1]"); + let res = ztimeout!(c_ses1.close()); + println!("Transport Authenticator UserPassword [8a1]: {res:?}"); + assert!(res.is_ok()); + println!("Transport Authenticator UserPassword [8a2]"); + let res = ztimeout!(c_ses2.close()); + println!("Transport Authenticator UserPassword [8a2]: {res:?}"); + assert!(res.is_ok()); + + ztimeout!(async { + while !router_manager.get_transports().is_empty() { + task::sleep(SLEEP).await; + } + }); + + /* [9] */ + // Perform clean up of the open locators + println!("Transport Authenticator UserPassword [9a1]"); + let res = ztimeout!(router_manager.del_listener(endpoint)); + println!("Transport Authenticator UserPassword [9a2]: {res:?}"); + assert!(res.is_ok()); + + ztimeout!(async { + while !router_manager.get_listeners().is_empty() { + task::sleep(SLEEP).await; + } + }); + + // Wait a little bit + task::sleep(SLEEP).await; +} + +async fn run(endpoint: &EndPoint) { + // #[cfg(feature = "auth_pubkey")] + // authenticator_multilink(endpoint).await; + #[cfg(feature = "auth_usrpwd")] + auth_usrpwd(endpoint).await; +} + +#[cfg(feature = "transport_tcp")] +#[test] +fn authenticator_tcp() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 8000).parse().unwrap(); + task::block_on(run(&endpoint)); +} // #[cfg(feature = "transport_udp")] // #[test] diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index d918d98e46..0deff10fad 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -174,18 +174,24 @@ mod tests { // Create a transport with the peer println!("Transport SHM [1b]"); - let _ = ztimeout!(peer_shm02_manager.open_transport(endpoint.clone())).unwrap(); + let peer_shm01_transport = + ztimeout!(peer_shm02_manager.open_transport(endpoint.clone())).unwrap(); + assert!(peer_shm01_transport.is_shm().unwrap()); // Create a transport with the peer println!("Transport SHM [1c]"); - let _ = ztimeout!(peer_net01_manager.open_transport(endpoint.clone())).unwrap(); + let peer_net02_transport = + ztimeout!(peer_net01_manager.open_transport(endpoint.clone())).unwrap(); + assert!(!peer_net02_transport.is_shm().unwrap()); // Retrieve the transports println!("Transport SHM [2a]"); let peer_shm02_transport = peer_shm01_manager.get_transport(&peer_shm02).unwrap(); + assert!(peer_shm02_transport.is_shm().unwrap()); println!("Transport SHM [2b]"); let peer_net01_transport = peer_shm01_manager.get_transport(&peer_net01).unwrap(); + assert!(!peer_net01_transport.is_shm().unwrap()); // Send the message println!("Transport SHM [3a]"); diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index fdbd884fbb..3d4d9806ff 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -595,7 +595,7 @@ fn client_test() { Channel::default(), CongestionControl::default(), None, - ZBuf::default(), + ZBuf::empty(), None, ); @@ -621,7 +621,7 @@ fn client_test() { Channel::default(), CongestionControl::default(), None, - ZBuf::default(), + ZBuf::empty(), None, ); @@ -647,7 +647,7 @@ fn client_test() { Channel::default(), CongestionControl::default(), None, - ZBuf::default(), + ZBuf::empty(), None, ); @@ -673,7 +673,7 @@ fn client_test() { Channel::default(), CongestionControl::default(), None, - ZBuf::default(), + ZBuf::empty(), None, ); @@ -699,7 +699,7 @@ fn client_test() { Channel::default(), CongestionControl::default(), None, - ZBuf::default(), + ZBuf::empty(), None, ); diff --git a/zenoh/src/value.rs b/zenoh/src/value.rs index 805541a936..d8eeb7dd2c 100644 --- a/zenoh/src/value.rs +++ b/zenoh/src/value.rs @@ -50,7 +50,7 @@ impl Value { /// Creates an empty Value. pub fn empty() -> Self { Value { - payload: ZBuf::default(), + payload: ZBuf::empty(), encoding: KnownEncoding::AppOctetStream.into(), } } From ec56c4c55b2a042836e79ba359ca3402583f2b26 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 9 Mar 2023 12:48:42 +0100 Subject: [PATCH 064/203] Re-enable protocols in authenticator tests --- .../tests/unicast_authenticator.rs | 464 +++++++++--------- 1 file changed, 232 insertions(+), 232 deletions(-) diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index cb4f4be451..58f5f3618f 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -703,248 +703,248 @@ fn authenticator_tcp() { task::block_on(run(&endpoint)); } -// #[cfg(feature = "transport_udp")] -// #[test] -// fn authenticator_udp() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); +#[cfg(feature = "transport_udp")] +#[test] +fn authenticator_udp() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); -// let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 8010).parse().unwrap(); -// task::block_on(run(&endpoint)); -// } + let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 8010).parse().unwrap(); + task::block_on(run(&endpoint)); +} -// #[cfg(feature = "transport_ws")] -// #[test] -// fn authenticator_ws() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); +#[cfg(feature = "transport_ws")] +#[test] +fn authenticator_ws() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); -// let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 8020).parse().unwrap(); -// task::block_on(run(&endpoint)); -// } + let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 8020).parse().unwrap(); + task::block_on(run(&endpoint)); +} -// #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] -// #[test] -// fn authenticator_unix() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); +#[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] +#[test] +fn authenticator_unix() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); -// let f1 = "zenoh-test-unix-socket-10.sock"; -// let _ = std::fs::remove_file(f1); -// let endpoint: EndPoint = format!("unixsock-stream/{f1}").parse().unwrap(); -// task::block_on(run(&endpoint)); -// let _ = std::fs::remove_file(f1); -// let _ = std::fs::remove_file(format!("{f1}.lock")); -// } + let f1 = "zenoh-test-unix-socket-10.sock"; + let _ = std::fs::remove_file(f1); + let endpoint: EndPoint = format!("unixsock-stream/{f1}").parse().unwrap(); + task::block_on(run(&endpoint)); + let _ = std::fs::remove_file(f1); + let _ = std::fs::remove_file(format!("{f1}.lock")); +} -// #[cfg(feature = "transport_tls")] -// #[test] -// fn authenticator_tls() { -// use zenoh_link::tls::config::*; +#[cfg(feature = "transport_tls")] +#[test] +fn authenticator_tls() { + use zenoh_link::tls::config::*; -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); -// // NOTE: this an auto-generated pair of certificate and key. -// // The target domain is localhost, so it has no real -// // mapping to any existing domain. The certificate and key -// // have been generated using: https://github.com/jsha/minica -// let key = "-----BEGIN RSA PRIVATE KEY----- -// MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi -// qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy -// aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU -// cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha -// Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr -// Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 -// 2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 -// lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU -// WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX -// Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI -// 9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak -// r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn -// qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY -// CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu -// fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj -// 4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih -// XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 -// 38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT -// Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV -// jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R -// 5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H -// n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm -// qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD -// tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v -// F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== -// -----END RSA PRIVATE KEY-----"; - -// let cert = "-----BEGIN CERTIFICATE----- -// MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -// AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw -// MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -// AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT -// He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ -// Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj -// eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 -// eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M -// tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud -// DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -// AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE -// DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 -// 3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD -// wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q -// GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC -// 9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ -// p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ -// abY= -// -----END CERTIFICATE-----"; - -// // Configure the client -// let ca = "-----BEGIN CERTIFICATE----- -// MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -// AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw -// MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi -// MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ -// uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs -// DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc -// 8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 -// T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b -// QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB -// AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -// BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 -// /llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq -// hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ -// e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc -// yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 -// 8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 -// Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN -// R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== -// -----END CERTIFICATE-----"; - -// // Define the locator -// let mut endpoint: EndPoint = format!("tls/localhost:{}", 8030).parse().unwrap(); -// endpoint -// .config_mut() -// .extend( -// [ -// (TLS_ROOT_CA_CERTIFICATE_RAW, ca), -// (TLS_SERVER_CERTIFICATE_RAW, cert), -// (TLS_SERVER_PRIVATE_KEY_RAW, key), -// ] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); + // NOTE: this an auto-generated pair of certificate and key. + // The target domain is localhost, so it has no real + // mapping to any existing domain. The certificate and key + // have been generated using: https://github.com/jsha/minica + let key = "-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi +qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy +aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU +cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha +Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr +Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 +2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 +lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU +WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX +Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI +9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak +r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn +qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY +CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu +fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj +4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih +XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 +38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT +Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV +jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R +5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H +n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm +qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD +tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v +F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== +-----END RSA PRIVATE KEY-----"; + + let cert = "-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw +MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT +He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ +Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj +eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 +eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M +tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE +DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 +3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD +wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q +GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC +9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ +p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ +abY= +-----END CERTIFICATE-----"; + + // Configure the client + let ca = "-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw +MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ +uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs +DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc +8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 +T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b +QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB +AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 +/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq +hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ +e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc +yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 +8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 +Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN +R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== +-----END CERTIFICATE-----"; + + // Define the locator + let mut endpoint: EndPoint = format!("tls/localhost:{}", 8030).parse().unwrap(); + endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, ca), + (TLS_SERVER_CERTIFICATE_RAW, cert), + (TLS_SERVER_PRIVATE_KEY_RAW, key), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); -// task::block_on(run(&endpoint)); -// } + task::block_on(run(&endpoint)); +} -// #[cfg(feature = "transport_quic")] -// #[test] -// fn authenticator_quic() { -// use zenoh_link::quic::config::*; +#[cfg(feature = "transport_quic")] +#[test] +fn authenticator_quic() { + use zenoh_link::quic::config::*; -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); -// // NOTE: this an auto-generated pair of certificate and key. -// // The target domain is localhost, so it has no real -// // mapping to any existing domain. The certificate and key -// // have been generated using: https://github.com/jsha/minica -// let key = "-----BEGIN RSA PRIVATE KEY----- -// MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi -// qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy -// aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU -// cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha -// Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr -// Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 -// 2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 -// lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU -// WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX -// Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI -// 9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak -// r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn -// qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY -// CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu -// fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj -// 4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih -// XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 -// 38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT -// Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV -// jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R -// 5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H -// n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm -// qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD -// tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v -// F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== -// -----END RSA PRIVATE KEY-----"; - -// let cert = "-----BEGIN CERTIFICATE----- -// MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -// AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw -// MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -// AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT -// He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ -// Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj -// eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 -// eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M -// tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud -// DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -// AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE -// DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 -// 3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD -// wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q -// GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC -// 9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ -// p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ -// abY= -// -----END CERTIFICATE-----"; - -// // Configure the client -// let ca = "-----BEGIN CERTIFICATE----- -// MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -// AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw -// MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi -// MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ -// uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs -// DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc -// 8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 -// T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b -// QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB -// AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -// BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 -// /llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq -// hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ -// e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc -// yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 -// 8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 -// Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN -// R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== -// -----END CERTIFICATE-----"; - -// // Define the locator -// let mut endpoint: EndPoint = format!("quic/localhost:{}", 8040).parse().unwrap(); -// endpoint -// .config_mut() -// .extend( -// [ -// (TLS_ROOT_CA_CERTIFICATE_RAW, ca), -// (TLS_SERVER_CERTIFICATE_RAW, cert), -// (TLS_SERVER_PRIVATE_KEY_RAW, key), -// ] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); + // NOTE: this an auto-generated pair of certificate and key. + // The target domain is localhost, so it has no real + // mapping to any existing domain. The certificate and key + // have been generated using: https://github.com/jsha/minica + let key = "-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi +qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy +aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU +cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha +Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr +Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 +2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 +lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU +WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX +Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI +9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak +r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn +qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY +CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu +fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj +4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih +XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 +38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT +Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV +jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R +5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H +n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm +qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD +tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v +F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== +-----END RSA PRIVATE KEY-----"; + + let cert = "-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw +MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT +He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ +Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj +eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 +eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M +tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE +DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 +3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD +wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q +GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC +9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ +p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ +abY= +-----END CERTIFICATE-----"; + + // Configure the client + let ca = "-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw +MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ +uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs +DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc +8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 +T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b +QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB +AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 +/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq +hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ +e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc +yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 +8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 +Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN +R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== +-----END CERTIFICATE-----"; + + // Define the locator + let mut endpoint: EndPoint = format!("quic/localhost:{}", 8040).parse().unwrap(); + endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, ca), + (TLS_SERVER_CERTIFICATE_RAW, cert), + (TLS_SERVER_PRIVATE_KEY_RAW, key), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); -// task::block_on(run(&endpoint)); -// } + task::block_on(run(&endpoint)); +} From 7033f9ea1feefd4e3c3fff5bb59edfc33f7920bf Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 9 Mar 2023 12:53:27 +0100 Subject: [PATCH 065/203] Update dependencies --- Cargo.lock | 67 +++++++++++++++++++++++++++++++----------------------- Cargo.toml | 8 +++---- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 572fc11366..82c1181799 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,7 +239,7 @@ dependencies = [ "parking", "polling", "slab", - "socket2", + "socket2 0.4.7", "waker-fn", "windows-sys 0.42.0", ] @@ -1536,9 +1536,9 @@ dependencies = [ [[package]] name = "ipnetwork" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f84f1612606f3753f205a4e9a2efd6fe5b4c573a6269b2cc6c3003d44a0d127" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" dependencies = [ "serde", ] @@ -2087,30 +2087,32 @@ dependencies = [ [[package]] name = "pnet" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0caaf5b11fd907ff15cf14a4477bfabca4b37ab9e447a4f8dead969a59cdafad" +checksum = "cd959a8268165518e2bf5546ba84c7b3222744435616381df3c456fe8d983576" dependencies = [ + "ipnetwork", "pnet_base", "pnet_datalink", "pnet_packet", + "pnet_sys", "pnet_transport", ] [[package]] name = "pnet_base" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d3a993d49e5fd5d4d854d6999d4addca1f72d86c65adf224a36757161c02b6" +checksum = "872e46346144ebf35219ccaa64b1dffacd9c6f188cd7d012bd6977a2a838f42e" dependencies = [ "no-std-net", ] [[package]] name = "pnet_datalink" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e466faf03a98ad27f6e15cd27a2b7cc89e73e640a43527742977bc503c37f8aa" +checksum = "c302da22118d2793c312a35fb3da6846cb0fab6c3ad53fd67e37809b06cdafce" dependencies = [ "ipnetwork", "libc", @@ -2121,9 +2123,9 @@ dependencies = [ [[package]] name = "pnet_macros" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dd52a5211fac27e7acb14cfc9f30ae16ae0e956b7b779c8214c74559cef4c3" +checksum = "2a780e80005c2e463ec25a6e9f928630049a10b43945fea83207207d4a7606f4" dependencies = [ "proc-macro2", "quote", @@ -2133,18 +2135,18 @@ dependencies = [ [[package]] name = "pnet_macros_support" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89de095dc7739349559913aed1ef6a11e73ceade4897dadc77c5e09de6740750" +checksum = "e6d932134f32efd7834eb8b16d42418dac87086347d1bc7d142370ef078582bc" dependencies = [ "pnet_base", ] [[package]] name = "pnet_packet" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc3b5111e697c39c8b9795b9fdccbc301ab696699e88b9ea5a4e4628978f495f" +checksum = "8bde678bbd85cb1c2d99dc9fc596e57f03aa725f84f3168b0eaf33eeccb41706" dependencies = [ "glob", "pnet_base", @@ -2154,9 +2156,9 @@ dependencies = [ [[package]] name = "pnet_sys" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "328e231f0add6d247d82421bf3790b4b33b39c8930637f428eef24c4c6a90805" +checksum = "faf7a58b2803d818a374be9278a1fe8f88fce14b936afbe225000cfcd9c73f16" dependencies = [ "libc", "winapi", @@ -2164,9 +2166,9 @@ dependencies = [ [[package]] name = "pnet_transport" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff597185e6f1f5671b3122e4dba892a1c73e17c17e723d7669bd9299cbe7f124" +checksum = "813d1c0e4defbe7ee22f6fe1755f122b77bfb5abe77145b1b5baaf463cab9249" dependencies = [ "libc", "pnet_base", @@ -2265,7 +2267,7 @@ checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4" dependencies = [ "libc", "quinn-proto", - "socket2", + "socket2 0.4.7", "tracing", "windows-sys 0.42.0", ] @@ -2454,9 +2456,9 @@ checksum = "56770675ebc04927ded3e60633437841581c285dc6236109ea25fbf3beb7b59e" [[package]] name = "rsa" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" +checksum = "55a77d189da1fee555ad95b7e50e7457d91c0e089ec68ca69ad2989413bbdab4" dependencies = [ "byteorder", "digest 0.10.6", @@ -2468,7 +2470,6 @@ dependencies = [ "pkcs8", "rand_core 0.6.4", "signature", - "smallvec", "subtle", "zeroize", ] @@ -2829,9 +2830,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" dependencies = [ "digest 0.10.6", "rand_core 0.6.4", @@ -2871,6 +2872,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc8d618c6641ae355025c449427f9e96b98abf99a772be3cef6708d15c77147a" +dependencies = [ + "libc", + "windows-sys 0.45.0", +] + [[package]] name = "spin" version = "0.5.2" @@ -3174,7 +3185,7 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite 0.2.9", - "socket2", + "socket2 0.4.7", "tokio-macros", "windows-sys 0.42.0", ] @@ -3793,7 +3804,7 @@ dependencies = [ "rustc_version 0.4.0", "serde", "serde_json", - "socket2", + "socket2 0.5.1", "stop-token", "uhlc", "uuid", @@ -4037,7 +4048,7 @@ dependencies = [ "async-std", "async-trait", "log", - "socket2", + "socket2 0.5.1", "zenoh-buffers", "zenoh-collections", "zenoh-core", diff --git a/Cargo.toml b/Cargo.toml index cf3ccb0878..2f21d07d39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -109,8 +109,8 @@ ordered-float = "3.4.0" panic-message = "0.3.0" paste = "1.0.9" petgraph = "0.6.2" -pnet = "0.31.0" -pnet_datalink = "0.31.0" +pnet = "0.33.0" +pnet_datalink = "0.33.0" proc-macro2 = "1.0.47" quinn = "0.9.3" quote = "1.0.21" @@ -119,7 +119,7 @@ rand_chacha = "0.3.1" rcgen = "0.10.0" regex = "1.7.0" ringbuffer-spsc = "0.1.8" -rsa = "0.7.2" +rsa = "0.8.2" rustc_version = "0.4.0" rustls = "0.20.6" rustls-native-certs = "0.6.2" @@ -132,7 +132,7 @@ serde_yaml = "0.9.14" sha3 = "0.10.6" shared_memory = "0.12.4" shellexpand = "3.0.0" -socket2 = "0.4.7" +socket2 = "0.5.1" stop-token = "0.7.0" syn = "1.0.105" tide = "0.16.0" From 9ff979d783c6cbcb66ec190c89fa07338489ee4d Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 9 Mar 2023 13:59:20 +0100 Subject: [PATCH 066/203] Fix nostd CI --- commons/zenoh-codec/src/common/extension.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 4e9c641aa9..4c24f83a4a 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -255,12 +256,12 @@ where impl RCodec, &mut R> for Zenoh080 where - R: Reader + std::fmt::Debug, + R: Reader, { type Error = DidntRead; fn read(self, reader: &mut R) -> Result, Self::Error> { - let mut exts = vec![]; + let mut exts = Vec::new(); let mut has_ext = reader.can_read(); while has_ext { let (e, more): (ZExtUnknown, bool) = self.read(&mut *reader)?; From 05835f911b022a86f8f1a7baaf6ed7184a498885 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 9 Mar 2023 21:29:22 +0100 Subject: [PATCH 067/203] PubKey auth --- .../src/unicast/establishment/accept.rs | 40 +- .../src/unicast/establishment/cookie.rs | 20 +- .../src/unicast/establishment/ext/auth/mod.rs | 310 +++- .../unicast/establishment/ext/auth/pubkey.rs | 1281 ++++++++--------- .../unicast/establishment/ext/auth/usrpwd.rs | 307 +--- .../src/unicast/establishment/ext/qos.rs | 129 +- .../src/unicast/establishment/ext/shm.rs | 130 +- .../src/unicast/establishment/open.rs | 14 +- .../tests/unicast_authenticator.rs | 694 ++++----- 9 files changed, 1377 insertions(+), 1548 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 635ab6c11f..de6f40000d 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -47,10 +47,10 @@ struct StateZenoh { struct State { zenoh: StateZenoh, - ext_qos: ext::qos::State, + ext_qos: ext::qos::StateAccept, #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::State, - ext_auth: ext::auth::State, + ext_shm: ext::shm::StateAccept, + ext_auth: ext::auth::StateAccept, } // InitSyn @@ -323,18 +323,20 @@ impl<'a> AcceptFsm for AcceptLink<'a> { let encrypted = open_syn.cookie.to_vec(); // Decrypt the cookie with the cipher - let mut reader = encrypted.reader(); - let mut codec = Zenoh080Cookie { - prng: &mut *zasynclock!(self.prng), - cipher: self.cipher, - codec: Zenoh080::new(), - }; - let cookie: Cookie = codec.read(&mut reader).map_err(|_| { - ( - zerror!("Decoding cookie failed").into(), - Some(close::reason::INVALID), - ) - })?; + let cookie: Cookie = { + let mut codec = Zenoh080Cookie { + prng: &mut *zasynclock!(self.prng), + cipher: self.cipher, + codec: Zenoh080::new(), + }; + let mut reader = encrypted.reader(); + codec.read(&mut reader).map_err(|_| { + ( + zerror!("Decoding cookie failed").into(), + Some(close::reason::INVALID), + ) + }) + }?; // Verify that the cookie is the one we sent if input.cookie_nonce != cookie.nonce { @@ -440,7 +442,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) ext_qos: ext::qos::QoSFsm::new(), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), - ext_auth: ext::auth::AuthFsm::new(&auth), + ext_auth: ext::auth::AuthFsm::new(&auth, &manager.prng), }; // Init handshake @@ -463,10 +465,10 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) batch_size: manager.config.batch_size, resolution: manager.config.resolution, }, - ext_qos: ext::qos::State::new(manager.config.unicast.is_qos), + ext_qos: ext::qos::StateAccept::new(manager.config.unicast.is_qos), #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::State::new(manager.config.unicast.is_shm), - ext_auth: auth.state(&mut *zasynclock!(manager.prng)), + ext_shm: ext::shm::StateAccept::new(manager.config.unicast.is_shm), + ext_auth: auth.accept(&mut *zasynclock!(manager.prng)), }; // Let's scope the Init phase in such a way memory is freed by Rust diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 21c98db67c..b1014b10ea 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -22,7 +22,7 @@ use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_protocol::core::{Resolution, WhatAmI, ZInt, ZenohId}; -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq)] pub(crate) struct Cookie { pub(crate) whatami: WhatAmI, pub(crate) zid: ZenohId, @@ -30,10 +30,10 @@ pub(crate) struct Cookie { pub(crate) batch_size: u16, pub(crate) nonce: ZInt, // Extensions - pub(crate) ext_qos: ext::qos::State, + pub(crate) ext_qos: ext::qos::StateAccept, #[cfg(feature = "shared-memory")] - pub(crate) ext_shm: ext::shm::State, - pub(crate) ext_auth: ext::auth::State, + pub(crate) ext_shm: ext::shm::StateAccept, + pub(crate) ext_auth: ext::auth::StateAccept, } impl WCodec<&Cookie, &mut W> for Zenoh080 @@ -74,10 +74,10 @@ where let batch_size: u16 = self.read(&mut *reader)?; let nonce: ZInt = self.read(&mut *reader)?; // Extensions - let ext_qos: ext::qos::State = self.read(&mut *reader)?; + let ext_qos: ext::qos::StateAccept = self.read(&mut *reader)?; #[cfg(feature = "shared-memory")] - let ext_shm: ext::shm::State = self.read(&mut *reader)?; - let ext_auth: ext::auth::State = self.read(&mut *reader)?; + let ext_shm: ext::shm::StateAccept = self.read(&mut *reader)?; + let ext_auth: ext::auth::StateAccept = self.read(&mut *reader)?; let cookie = Cookie { whatami, @@ -150,10 +150,10 @@ impl Cookie { resolution: Resolution::rand(), batch_size: rng.gen(), nonce: rng.gen(), - ext_qos: ext::qos::State::rand(), + ext_qos: ext::qos::StateAccept::rand(), #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::State::rand(), - ext_auth: ext::auth::State::rand(), + ext_shm: ext::shm::StateAccept::rand(), + ext_auth: ext::auth::StateAccept::rand(), } } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs index 8672e4fb9c..7bd0c90b85 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -14,15 +14,18 @@ #[cfg(feature = "auth_pubkey")] mod pubkey; #[cfg(feature = "auth_usrpwd")] -pub mod usrpwd; +mod usrpwd; -#[cfg(feature = "auth_usrpwd")] -use crate::establishment::ext::auth::usrpwd::{AuthUsrPwd, AuthUsrPwdFsm}; use crate::establishment::{AcceptFsm, OpenFsm}; +use async_std::sync::Mutex; use async_trait::async_trait; -use rand::Rng; +#[cfg(feature = "auth_pubkey")] +pub use pubkey::*; +use rand::{CryptoRng, Rng}; use std::convert::TryInto; use std::marker::PhantomData; +#[cfg(feature = "auth_usrpwd")] +pub use usrpwd::*; use zenoh_buffers::reader::SiphonableReader; use zenoh_buffers::ZBuf; use zenoh_buffers::{ @@ -32,37 +35,21 @@ use zenoh_buffers::{ use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_config::Config; use zenoh_core::{bail, zerror, Error as ZError, Result as ZResult}; +use zenoh_crypto::PseudoRng; use zenoh_protocol::{ common::ZExtUnknown, transport::{init, open}, }; pub(crate) mod id { - pub(crate) const USRPWD: u8 = 1; - // pub(crate) const PUBKEY: u8 = 2; -} - -macro_rules! ztryinto { - ($x:expr, $s:expr) => { - if let Some(x) = $x { - Some( - x.try_into() - .map_err(|_| zerror!("{} Decoding error.", $s))?, - ) - } else { - None - } - }; -} - -macro_rules! ztake { - ($x:expr, $id:expr) => { - $x.iter().position(|x| x.id == $id).map(|i| $x.remove(i)) - }; + pub(crate) const PUBKEY: u8 = 1; + pub(crate) const USRPWD: u8 = 2; } #[derive(Debug, Default)] pub struct Auth { + #[cfg(feature = "auth_pubkey")] + pubkey: Option, #[cfg(feature = "auth_usrpwd")] usrpwd: Option, } @@ -72,18 +59,40 @@ impl Auth { let auth = config.transport().auth(); Ok(Self { + #[cfg(feature = "auth_pubkey")] + pubkey: AuthPubKey::from_config(auth.pubkey()).await?, #[cfg(feature = "auth_usrpwd")] usrpwd: AuthUsrPwd::from_config(auth.usrpwd()).await?, }) } - pub(crate) fn state(&self, prng: &mut R) -> State + pub(crate) fn open(&self, prng: &mut R) -> StateOpen where - R: Rng, + R: Rng + CryptoRng, { - State { + StateOpen { + #[cfg(feature = "auth_pubkey")] + pubkey: self.pubkey.is_some().then_some(pubkey::StateOpen::new()), #[cfg(feature = "auth_usrpwd")] - usrpwd: self.usrpwd.is_some().then_some(usrpwd::State::new(prng)), + usrpwd: self + .usrpwd + .is_some() + .then_some(usrpwd::StateOpen::new(prng)), + } + } + + pub(crate) fn accept(&self, prng: &mut R) -> StateAccept + where + R: Rng + CryptoRng, + { + StateAccept { + #[cfg(feature = "auth_pubkey")] + pubkey: self.pubkey.is_some().then_some(pubkey::StateAccept::new()), + #[cfg(feature = "auth_usrpwd")] + usrpwd: self + .usrpwd + .is_some() + .then_some(usrpwd::StateAccept::new(prng)), } } } @@ -92,11 +101,28 @@ impl Auth { impl Auth { pub const fn empty() -> Self { Self { + #[cfg(feature = "auth_pubkey")] + pubkey: None, #[cfg(feature = "auth_usrpwd")] usrpwd: None, } } + #[cfg(feature = "auth_pubkey")] + pub fn set_pubkey(&mut self, pubkey: Option) { + self.pubkey = pubkey; + } + + #[cfg(feature = "auth_pubkey")] + pub fn get_pubkey(&self) -> Option<&AuthPubKey> { + self.pubkey.as_ref() + } + + #[cfg(feature = "auth_pubkey")] + pub fn get_pubkey_mut(&mut self) -> Option<&mut AuthPubKey> { + self.pubkey.as_mut() + } + #[cfg(feature = "auth_usrpwd")] pub fn set_usrpwd(&mut self, usrpwd: Option) { self.usrpwd = usrpwd; @@ -114,14 +140,18 @@ impl Auth { } pub(crate) struct AuthFsm<'a> { + #[cfg(feature = "auth_pubkey")] + pubkey: Option>, #[cfg(feature = "auth_usrpwd")] usrpwd: Option>, _a: PhantomData<&'a ()>, // Required only when all auth features are disabled } impl<'a> AuthFsm<'a> { - pub(crate) fn new(a: &'a Auth) -> Self { + pub(crate) fn new(a: &'a Auth, prng: &'a Mutex) -> Self { Self { + #[cfg(feature = "auth_pubkey")] + pubkey: a.pubkey.as_ref().map(|x| AuthPubKeyFsm::new(x, prng)), #[cfg(feature = "auth_usrpwd")] usrpwd: a.usrpwd.as_ref().map(AuthUsrPwdFsm::new), _a: PhantomData, @@ -130,34 +160,55 @@ impl<'a> AuthFsm<'a> { } #[derive(Debug, PartialEq, Eq)] -pub(crate) struct State { +pub(crate) struct StateOpen { + #[cfg(feature = "auth_pubkey")] + pubkey: Option, #[cfg(feature = "auth_usrpwd")] - usrpwd: Option, + usrpwd: Option, } -impl State { +#[derive(Debug, PartialEq)] +pub(crate) struct StateAccept { + #[cfg(feature = "auth_pubkey")] + pubkey: Option, + #[cfg(feature = "auth_usrpwd")] + usrpwd: Option, +} + +impl StateAccept { #[cfg(test)] pub(crate) fn rand() -> Self { let mut rng = rand::thread_rng(); Self { + #[cfg(feature = "auth_pubkey")] + pubkey: rng.gen_bool(0.5).then_some(pubkey::StateAccept::rand()), #[cfg(feature = "auth_usrpwd")] - usrpwd: rng.gen_bool(0.5).then_some(usrpwd::State::rand()), + usrpwd: rng.gen_bool(0.5).then_some(usrpwd::StateAccept::rand()), } } } // Codec -impl WCodec<&State, &mut W> for Zenoh080 +impl WCodec<&StateAccept, &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &State) -> Self::Output { + fn write(self, writer: &mut W, x: &StateAccept) -> Self::Output { + let mut count: usize = 0; let mut buff = vec![]; let mut wbuf = buff.writer(); - let mut count: usize = 0; + #[cfg(feature = "auth_pubkey")] + { + if let Some(pubkey) = x.pubkey.as_ref() { + self.write(&mut wbuf, id::PUBKEY)?; + self.write(&mut wbuf, pubkey)?; + count += 1; + } + } + #[cfg(feature = "auth_usrpwd")] { if let Some(usrpwd) = x.usrpwd.as_ref() { @@ -177,21 +228,27 @@ where } } -impl RCodec for Zenoh080 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result { let mut count: usize = self.read(&mut *reader)?; + #[cfg(feature = "auth_pubkey")] + let mut pubkey: Option = None; #[cfg(feature = "auth_usrpwd")] - let mut usrpwd: Option = None; + let mut usrpwd: Option = None; while count > 0 { let e: u8 = self.read(&mut *reader)?; match e { + #[cfg(feature = "auth_pubkey")] + id::PUBKEY => { + pubkey = Some(self.read(&mut *reader)?); + } #[cfg(feature = "auth_usrpwd")] id::USRPWD => { usrpwd = Some(self.read(&mut *reader)?); @@ -202,7 +259,9 @@ where count -= 1; } - let state = State { + let state = StateAccept { + #[cfg(feature = "auth_pubkey")] + pubkey, #[cfg(feature = "auth_usrpwd")] usrpwd, }; @@ -210,6 +269,25 @@ where } } +macro_rules! ztryinto { + ($x:expr, $s:expr) => { + if let Some(x) = $x { + Some( + x.try_into() + .map_err(|_| zerror!("{} Decoding error.", $s))?, + ) + } else { + None + } + }; +} + +macro_rules! ztake { + ($x:expr, $id:expr) => { + $x.iter().position(|x| x.id == $id).map(|i| $x.remove(i)) + }; +} + /*************************************/ /* OPEN */ /*************************************/ @@ -217,7 +295,7 @@ where impl<'a> OpenFsm for AuthFsm<'a> { type Error = ZError; - type SendInitSynIn = &'a State; + type SendInitSynIn = &'a StateOpen; type SendInitSynOut = Option; async fn send_init_syn( &self, @@ -227,6 +305,19 @@ impl<'a> OpenFsm for AuthFsm<'a> { let mut exts: Vec = vec![]; + #[cfg(feature = "auth_pubkey")] + { + match (self.pubkey.as_ref(), state.pubkey.as_ref()) { + (Some(e), Some(s)) => { + if let Some(e) = e.send_init_syn(s).await?.take() { + exts.push(e.into()) + } + } + (None, None) => {} + _ => bail!("{S} Invalid PubKey configuration."), + } + } + #[cfg(feature = "auth_usrpwd")] { match (self.usrpwd.as_ref(), state.usrpwd.as_ref()) { @@ -236,7 +327,7 @@ impl<'a> OpenFsm for AuthFsm<'a> { } } (None, None) => {} - _ => bail!("{} Invalid configuration.", S), + _ => bail!("{S} Invalid UsrPwd configuration."), } } @@ -245,13 +336,13 @@ impl<'a> OpenFsm for AuthFsm<'a> { let mut writer = buff.writer(); codec .write(&mut writer, exts.as_slice()) - .map_err(|_| zerror!("{} Encoding error.", S))?; + .map_err(|_| zerror!("{S} Encoding error."))?; let output = (!buff.is_empty()).then_some(init::ext::Auth::new(buff.into())); Ok(output) } - type RecvInitAckIn = (&'a mut State, Option); + type RecvInitAckIn = (&'a mut StateOpen, Option); type RecvInitAckOut = (); async fn recv_init_ack( &self, @@ -266,7 +357,19 @@ impl<'a> OpenFsm for AuthFsm<'a> { let mut reader = ext.value.reader(); let mut exts: Vec = codec .read(&mut reader) - .map_err(|_| zerror!("{} Decoding error.", S))?; + .map_err(|_| zerror!("{S} Decoding error."))?; + + #[cfg(feature = "auth_pubkey")] + { + match (self.pubkey.as_ref(), state.pubkey.as_mut()) { + (Some(e), Some(s)) => { + let x = ztake!(exts, id::PUBKEY); + e.recv_init_ack((s, ztryinto!(x, S))).await?; + } + (None, None) => {} + _ => bail!("{S} Invalid PubKey configuration."), + } + } #[cfg(feature = "auth_usrpwd")] { @@ -276,14 +379,14 @@ impl<'a> OpenFsm for AuthFsm<'a> { e.recv_init_ack((s, ztryinto!(x, S))).await?; } (None, None) => {} - _ => bail!("{} Invalid configuration.", S), + _ => bail!("{S} Invalid UsrPwd configuration."), } } Ok(()) } - type SendOpenSynIn = &'a State; + type SendOpenSynIn = &'a StateOpen; type SendOpenSynOut = Option; async fn send_open_syn( &self, @@ -293,6 +396,19 @@ impl<'a> OpenFsm for AuthFsm<'a> { let mut exts: Vec = vec![]; + #[cfg(feature = "auth_pubkey")] + { + match (self.pubkey.as_ref(), state.pubkey.as_ref()) { + (Some(e), Some(s)) => { + if let Some(e) = e.send_open_syn(s).await?.take() { + exts.push(e.into()) + } + } + (None, None) => {} + _ => bail!("{S} Invalid PubKey configuration."), + } + } + #[cfg(feature = "auth_usrpwd")] { match (self.usrpwd.as_ref(), state.usrpwd.as_ref()) { @@ -302,7 +418,7 @@ impl<'a> OpenFsm for AuthFsm<'a> { } } (None, None) => {} - _ => bail!("{} Invalid configuration.", S), + _ => bail!("{S} Invalid UsrPwd configuration."), } } @@ -311,13 +427,13 @@ impl<'a> OpenFsm for AuthFsm<'a> { let mut writer = buff.writer(); codec .write(&mut writer, exts.as_slice()) - .map_err(|_| zerror!("{} Encoding error.", S))?; + .map_err(|_| zerror!("{S} Encoding error."))?; let output = (!buff.is_empty()).then_some(open::ext::Auth::new(buff.into())); Ok(output) } - type RecvOpenAckIn = (&'a mut State, Option); + type RecvOpenAckIn = (&'a mut StateOpen, Option); type RecvOpenAckOut = (); async fn recv_open_ack( &self, @@ -332,7 +448,19 @@ impl<'a> OpenFsm for AuthFsm<'a> { let mut reader = ext.value.reader(); let mut exts: Vec = codec .read(&mut reader) - .map_err(|_| zerror!("{} Decoding error.", S))?; + .map_err(|_| zerror!("{S} Decoding error."))?; + + #[cfg(feature = "auth_pubkey")] + { + match (self.pubkey.as_ref(), state.pubkey.as_mut()) { + (Some(e), Some(s)) => { + let x = ztake!(exts, id::PUBKEY); + e.recv_open_ack((s, ztryinto!(x, S))).await?; + } + (None, None) => {} + _ => bail!("{S} Invalid PubKey configuration."), + } + } #[cfg(feature = "auth_usrpwd")] { @@ -342,7 +470,7 @@ impl<'a> OpenFsm for AuthFsm<'a> { e.recv_open_ack((s, ztryinto!(x, S))).await?; } (None, None) => {} - _ => bail!("{} Invalid configuration.", S), + _ => bail!("{S} Invalid UsrPwd configuration."), } } @@ -357,7 +485,7 @@ impl<'a> OpenFsm for AuthFsm<'a> { impl<'a> AcceptFsm for AuthFsm<'a> { type Error = ZError; - type RecvInitSynIn = (&'a mut State, Option); + type RecvInitSynIn = (&'a mut StateAccept, Option); type RecvInitSynOut = (); async fn recv_init_syn( &self, @@ -372,7 +500,19 @@ impl<'a> AcceptFsm for AuthFsm<'a> { let mut reader = ext.value.reader(); let mut exts: Vec = codec .read(&mut reader) - .map_err(|_| zerror!("{} Decoding error.", S))?; + .map_err(|_| zerror!("{S} Decoding error."))?; + + #[cfg(feature = "auth_pubkey")] + { + match (self.pubkey.as_ref(), state.pubkey.as_mut()) { + (Some(e), Some(s)) => { + let x = ztake!(exts, id::PUBKEY); + e.recv_init_syn((s, ztryinto!(x, S))).await?; + } + (None, None) => {} + _ => bail!("{S} Invalid PubKey configuration."), + } + } #[cfg(feature = "auth_usrpwd")] { @@ -382,14 +522,14 @@ impl<'a> AcceptFsm for AuthFsm<'a> { e.recv_init_syn((s, ztryinto!(x, S))).await?; } (None, None) => {} - _ => bail!("{} Invalid configuration.", S), + _ => bail!("{S} Invalid UsrPwd configuration."), } } Ok(()) } - type SendInitAckIn = &'a State; + type SendInitAckIn = &'a StateAccept; type SendInitAckOut = Option; async fn send_init_ack( &self, @@ -399,6 +539,19 @@ impl<'a> AcceptFsm for AuthFsm<'a> { let mut exts: Vec = vec![]; + #[cfg(feature = "auth_pubkey")] + { + match (self.pubkey.as_ref(), state.pubkey.as_ref()) { + (Some(e), Some(s)) => { + if let Some(e) = e.send_init_ack(s).await?.take() { + exts.push(e.into()) + } + } + (None, None) => {} + _ => bail!("{S} Invalid PubKey configuration."), + } + } + #[cfg(feature = "auth_usrpwd")] { match (self.usrpwd.as_ref(), state.usrpwd.as_ref()) { @@ -408,7 +561,7 @@ impl<'a> AcceptFsm for AuthFsm<'a> { } } (None, None) => {} - _ => bail!("{} Invalid configuration.", S), + _ => bail!("{S} Invalid UsrPwd configuration."), } } @@ -417,13 +570,13 @@ impl<'a> AcceptFsm for AuthFsm<'a> { let mut writer = buff.writer(); codec .write(&mut writer, exts.as_slice()) - .map_err(|_| zerror!("{} Encoding error.", S))?; + .map_err(|_| zerror!("{S} Encoding error."))?; let output = (!buff.is_empty()).then_some(init::ext::Auth::new(buff.into())); Ok(output) } - type RecvOpenSynIn = (&'a mut State, Option); + type RecvOpenSynIn = (&'a mut StateAccept, Option); type RecvOpenSynOut = (); async fn recv_open_syn( &self, @@ -438,7 +591,19 @@ impl<'a> AcceptFsm for AuthFsm<'a> { let mut reader = ext.value.reader(); let mut exts: Vec = codec .read(&mut reader) - .map_err(|_| zerror!("{} Decoding error.", S))?; + .map_err(|_| zerror!("{S} Decoding error."))?; + + #[cfg(feature = "auth_pubkey")] + { + match (self.pubkey.as_ref(), state.pubkey.as_mut()) { + (Some(e), Some(s)) => { + let x = ztake!(exts, id::PUBKEY); + e.recv_open_syn((s, ztryinto!(x, S))).await?; + } + (None, None) => {} + _ => bail!("{S} Invalid PubKey configuration."), + } + } #[cfg(feature = "auth_usrpwd")] { @@ -448,23 +613,36 @@ impl<'a> AcceptFsm for AuthFsm<'a> { e.recv_open_syn((s, ztryinto!(x, S))).await?; } (None, None) => {} - _ => bail!("{} Invalid configuration.", S), + _ => bail!("{S} Invalid UsrPwd configuration."), } } Ok(()) } - type SendOpenAckIn = &'a State; + type SendOpenAckIn = &'a StateAccept; type SendOpenAckOut = Option; async fn send_open_ack( &self, state: Self::SendOpenAckIn, ) -> Result { - const S: &str = "Auth extension - Send InitAck."; + const S: &str = "Auth extension - Send OpenAck."; let mut exts: Vec = vec![]; + #[cfg(feature = "auth_pubkey")] + { + match (self.pubkey.as_ref(), state.pubkey.as_ref()) { + (Some(e), Some(s)) => { + if let Some(e) = e.send_open_ack(s).await?.take() { + exts.push(e.into()) + } + } + (None, None) => {} + _ => bail!("{S} Invalid PubKey configuration."), + } + } + #[cfg(feature = "auth_usrpwd")] { match (self.usrpwd.as_ref(), state.usrpwd.as_ref()) { @@ -474,7 +652,7 @@ impl<'a> AcceptFsm for AuthFsm<'a> { } } (None, None) => {} - _ => bail!("{} Invalid configuration.", S), + _ => bail!("{S} Invalid UsrPwd configuration."), } } @@ -483,7 +661,7 @@ impl<'a> AcceptFsm for AuthFsm<'a> { let mut writer = buff.writer(); codec .write(&mut writer, exts.as_slice()) - .map_err(|_| zerror!("{} Encoding error.", S))?; + .map_err(|_| zerror!("{S} Encoding error."))?; let output = (!buff.is_empty()).then_some(open::ext::Auth::new(buff.into())); Ok(output) diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs index dc466e4d37..e2cf83d0a8 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs @@ -14,673 +14,618 @@ // use super::{ // AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, // }; -// use crate::unicast::establishment::Cookie; -// use async_std::sync::Mutex; -// use async_trait::async_trait; -// use rand::SeedableRng; -// use rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}; -// use rsa::{BigUint, PaddingScheme, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey}; -// use std::collections::HashMap; -// use std::ops::Deref; -// use std::path::Path; -// use std::sync::Arc; -// use zenoh_buffers::{ -// reader::{DidntRead, HasReader, Reader}, -// writer::{DidntWrite, HasWriter, Writer}, -// }; -// use zenoh_cfg_properties::config::ZN_AUTH_RSA_KEY_SIZE_DEFAULT; -// use zenoh_codec::{RCodec, WCodec, Zenoh080}; -// use zenoh_config::Config; -// use zenoh_core::{zasynclock, zparse}; -// use zenoh_crypto::PseudoRng; -// use zenoh_protocol::core::{ZInt, ZenohId}; -// use zenoh_result::{bail, zerror, ZResult}; - -// const MULTILINK_VERSION: ZInt = 1; - -// /// # Attachment decorator -// /// -// /// ```text -// /// The Attachment can decorate any message (i.e., TransportMessage and ZenohMessage) and it allows to -// /// append to the message any additional information. Since the information contained in the -// /// Attachement is relevant only to the layer that provided them (e.g., Transport, Zenoh, User) it -// /// is the duty of that layer to serialize and de-serialize the attachment whenever deemed necessary. -// /// -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// | ENC | ATTCH | -// /// +-+-+-+---------+ -// /// ~ Attachment ~ -// /// +---------------+ -// /// -// /// ENC values: -// /// - 0x00 => Zenoh Properties -// /// ``` -// #[repr(transparent)] -// #[derive(Debug, Clone, PartialEq, Eq)] -// pub struct ZPublicKey(RsaPublicKey); - -// impl Deref for ZPublicKey { -// type Target = RsaPublicKey; - -// fn deref(&self) -> &Self::Target { -// &self.0 -// } -// } - -// impl From for ZPublicKey { -// fn from(x: RsaPublicKey) -> Self { -// Self(x) -// } -// } - -// #[repr(transparent)] -// #[derive(Debug, Clone, PartialEq, Eq)] -// pub struct ZPrivateKey(RsaPrivateKey); - -// impl Deref for ZPrivateKey { -// type Target = RsaPrivateKey; - -// fn deref(&self) -> &Self::Target { -// &self.0 -// } -// } - -// impl From for ZPrivateKey { -// fn from(x: RsaPrivateKey) -> Self { -// Self(x) -// } -// } - -// impl WCodec<&ZPublicKey, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; - -// fn write(self, writer: &mut W, x: &ZPublicKey) -> Self::Output { -// self.write(&mut *writer, x.n().to_bytes_le().as_slice())?; -// self.write(&mut *writer, x.e().to_bytes_le().as_slice())?; -// Ok(()) -// } -// } - -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; - -// fn read(self, reader: &mut R) -> Result { -// let n: Vec = self.read(&mut *reader)?; -// let n = BigUint::from_bytes_le(n.as_slice()); -// let e: Vec = self.read(&mut *reader)?; -// let e = BigUint::from_bytes_le(e.as_slice()); -// let rsa = RsaPublicKey::new(n, e).map_err(|_| DidntRead)?; - -// Ok(ZPublicKey(rsa)) -// } -// } - -// /*************************************/ -// /* InitSyn */ -// /*************************************/ -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// |0 0 0| ATTCH | -// /// +-+-+-+---------+ -// /// ~ version ~ -// /// +---------------+ -// /// ~ public key ~ -// /// +---------------+ -// struct InitSynProperty { -// version: ZInt, -// alice_pubkey: ZPublicKey, -// } - -// impl WCodec<&InitSynProperty, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; - -// fn write(self, writer: &mut W, x: &InitSynProperty) -> Self::Output { -// self.write(&mut *writer, x.version)?; -// self.write(&mut *writer, &x.alice_pubkey)?; -// Ok(()) -// } -// } - -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; - -// fn read(self, reader: &mut R) -> Result { -// let version: ZInt = self.read(&mut *reader)?; -// let alice_pubkey: ZPublicKey = self.read(&mut *reader)?; -// Ok(InitSynProperty { -// version, -// alice_pubkey, -// }) -// } -// } - -// /*************************************/ -// /* InitAck */ -// /*************************************/ -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// |0 0 0| ATTCH | -// /// +-+-+-+---------+ -// /// ~ public key ~ -// /// +---------------+ -// /// ~ ciphered nonce~ -// /// +---------------+ -// struct InitAckProperty { -// bob_pubkey: ZPublicKey, -// nonce_encrypted_with_alice_pubkey: Vec, -// } - -// impl WCodec<&InitAckProperty, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; - -// fn write(self, writer: &mut W, x: &InitAckProperty) -> Self::Output { -// self.write(&mut *writer, &x.bob_pubkey)?; -// self.write(&mut *writer, x.nonce_encrypted_with_alice_pubkey.as_slice())?; -// Ok(()) -// } -// } - -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; - -// fn read(self, reader: &mut R) -> Result { -// let bob_pubkey: ZPublicKey = self.read(&mut *reader)?; -// let nonce_encrypted_with_alice_pubkey: Vec = self.read(&mut *reader)?; -// Ok(InitAckProperty { -// bob_pubkey, -// nonce_encrypted_with_alice_pubkey, -// }) -// } -// } - -// /*************************************/ -// /* OpenSyn */ -// /*************************************/ -// /// 7 6 5 4 3 2 1 0 -// /// +-+-+-+-+-+-+-+-+ -// /// |0 0 0| ATTCH | -// /// +-+-+-+---------+ -// /// ~ ciphered nonce~ -// /// +---------------+ -// struct OpenSynProperty { -// nonce_encrypted_with_bob_pubkey: Vec, -// } - -// impl WCodec<&OpenSynProperty, &mut W> for Zenoh080 -// where -// W: Writer, -// { -// type Output = Result<(), DidntWrite>; - -// fn write(self, writer: &mut W, x: &OpenSynProperty) -> Self::Output { -// self.write(&mut *writer, x.nonce_encrypted_with_bob_pubkey.as_slice())?; -// Ok(()) -// } -// } - -// impl RCodec for Zenoh080 -// where -// R: Reader, -// { -// type Error = DidntRead; - -// fn read(self, reader: &mut R) -> Result { -// let nonce_encrypted_with_bob_pubkey: Vec = self.read(&mut *reader)?; -// Ok(OpenSynProperty { -// nonce_encrypted_with_bob_pubkey, -// }) -// } -// } +use async_std::sync::Mutex; +use async_trait::async_trait; +use rand::{CryptoRng, Rng}; +use rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}; +use rsa::{BigUint, Pkcs1v15Encrypt, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey}; +use std::collections::HashSet; +use std::ops::Deref; +use std::path::Path; +use zenoh_buffers::{ + reader::{DidntRead, HasReader, Reader}, + writer::{DidntWrite, HasWriter, Writer}, +}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_config::PubKeyConf; +use zenoh_core::{bail, zasynclock, zerror, Error as ZError, Result as ZResult}; +use zenoh_crypto::PseudoRng; +use zenoh_protocol::common::{ZExtUnit, ZExtZBuf}; +use zenoh_protocol::core::ZInt; + +use crate::establishment::{AcceptFsm, OpenFsm}; + +const KEY_SIZE: usize = 512; + +// Authenticator +#[derive(Debug)] +pub struct AuthPubKey { + lookup: HashSet, + pub_key: ZPublicKey, + pri_key: ZPrivateKey, +} + +impl AuthPubKey { + pub fn new(pub_key: ZPublicKey, pri_key: ZPrivateKey) -> Self { + Self { + lookup: HashSet::new(), + pub_key, + pri_key, + } + } + + pub fn make(rng: &mut R) -> ZResult + where + R: Rng + CryptoRng, + { + let pri_key = RsaPrivateKey::new(rng, KEY_SIZE)?; + let pub_key = RsaPublicKey::from(&pri_key); + Ok(Self::new(pub_key.into(), pri_key.into())) + } + + pub async fn add_pubkey(&mut self, pub_key: ZPublicKey) -> ZResult<()> { + self.lookup.insert(pub_key); + Ok(()) + } + + pub async fn del_pubkey(&mut self, pub_key: &ZPublicKey) -> ZResult<()> { + self.lookup.remove(pub_key); + Ok(()) + } + + pub async fn from_config(config: &PubKeyConf) -> ZResult> { + const S: &str = "PubKey extension - From config."; + + // First, check if PEM keys are provided + match (config.public_key_pem(), config.private_key_pem()) { + (Some(public), Some(private)) => { + let pub_key = RsaPublicKey::from_pkcs1_pem(public) + .map_err(|e| zerror!("{} Rsa Public Key: {}.", S, e))?; + let pri_key = RsaPrivateKey::from_pkcs1_pem(private) + .map_err(|e| zerror!("{} Rsa Private Key: {}.", S, e))?; + return Ok(Some(Self::new(pub_key.into(), pri_key.into()))); + } + (Some(_), None) => { + bail!("{S} Missing Rsa Private Key: PEM.") + } + (None, Some(_)) => { + bail!("{S} Missing Rsa Public Key: PEM.") + } + (None, None) => {} + } + + // Second, check if PEM files are provided + match (config.public_key_file(), config.private_key_file()) { + (Some(public), Some(private)) => { + let path = Path::new(public); + let pub_key = RsaPublicKey::read_pkcs1_pem_file(path) + .map_err(|e| zerror!("{} Rsa Public Key: {}.", S, e))?; + let path = Path::new(private); + let pri_key = RsaPrivateKey::read_pkcs1_pem_file(path) + .map_err(|e| zerror!("{} Rsa Private Key: {}.", S, e))?; + return Ok(Some(Self::new(pub_key.into(), pri_key.into()))); + } + (Some(_), None) => { + bail!("{S} Missing Rsa Private Key: file.") + } + (None, Some(_)) => { + bail!("{S} Missing Rsa Public Key: file.") + } + (None, None) => {} + } + + // @TODO: populate lookup file + + Ok(None) + } +} + +#[repr(transparent)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ZPublicKey(RsaPublicKey); + +impl Deref for ZPublicKey { + type Target = RsaPublicKey; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for ZPublicKey { + fn from(x: RsaPublicKey) -> Self { + Self(x) + } +} + +#[repr(transparent)] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ZPrivateKey(RsaPrivateKey); + +impl Deref for ZPrivateKey { + type Target = RsaPrivateKey; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for ZPrivateKey { + fn from(x: RsaPrivateKey) -> Self { + Self(x) + } +} + +impl WCodec<&ZPublicKey, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ZPublicKey) -> Self::Output { + self.write(&mut *writer, x.n().to_bytes_le().as_slice())?; + self.write(&mut *writer, x.e().to_bytes_le().as_slice())?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let n: Vec = self.read(&mut *reader)?; + let n = BigUint::from_bytes_le(n.as_slice()); + let e: Vec = self.read(&mut *reader)?; + let e = BigUint::from_bytes_le(e.as_slice()); + let rsa = RsaPublicKey::new(n, e).map_err(|_| DidntRead)?; + + Ok(ZPublicKey(rsa)) + } +} + +/*************************************/ +/* InitSyn */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// ~ public key ~ +/// +---------------+ +/// +/// ZExtZBuf +struct InitSyn { + alice_pubkey: ZPublicKey, +} + +impl WCodec<&InitSyn, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &InitSyn) -> Self::Output { + self.write(&mut *writer, &x.alice_pubkey)?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let alice_pubkey: ZPublicKey = self.read(&mut *reader)?; + Ok(InitSyn { alice_pubkey }) + } +} + +/*************************************/ +/* InitAck */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// ~ public key ~ +/// +---------------+ +/// ~ ciphered nonce~ +/// +---------------+ +/// +/// ZExtZBuf +struct InitAck { + bob_pubkey: ZPublicKey, + nonce_encrypted_with_alice_pubkey: Vec, +} + +impl WCodec<&InitAck, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &InitAck) -> Self::Output { + self.write(&mut *writer, &x.bob_pubkey)?; + self.write(&mut *writer, x.nonce_encrypted_with_alice_pubkey.as_slice())?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let bob_pubkey: ZPublicKey = self.read(&mut *reader)?; + let nonce_encrypted_with_alice_pubkey: Vec = self.read(&mut *reader)?; + Ok(InitAck { + bob_pubkey, + nonce_encrypted_with_alice_pubkey, + }) + } +} + +/*************************************/ +/* OpenSyn */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// ~ ciphered nonce~ +/// +---------------+ +/// +/// ZExtZBuf +struct OpenSyn { + nonce_encrypted_with_bob_pubkey: Vec, +} + +impl WCodec<&OpenSyn, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &OpenSyn) -> Self::Output { + self.write(&mut *writer, x.nonce_encrypted_with_bob_pubkey.as_slice())?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let nonce_encrypted_with_bob_pubkey: Vec = self.read(&mut *reader)?; + Ok(OpenSyn { + nonce_encrypted_with_bob_pubkey, + }) + } +} /*************************************/ -/* Authenticator */ -// /*************************************/ -// struct InnerState { -// prng: PseudoRng, -// known_keys: Option>, -// authenticated: HashMap>, -// } - -// pub struct PubKeyAuthenticator { -// pub_key: ZPublicKey, -// pri_key: ZPrivateKey, -// state: Mutex, -// } - -// impl PubKeyAuthenticator { -// pub fn new(pub_key: T, pri_key: U) -> PubKeyAuthenticator -// where -// T: Into, -// U: Into, -// { -// PubKeyAuthenticator { -// pub_key: pub_key.into(), -// pri_key: pri_key.into(), -// state: Mutex::new(InnerState { -// prng: PseudoRng::from_entropy(), -// known_keys: None, -// authenticated: HashMap::new(), -// }), -// } -// } - -// pub fn make() -> ZResult { -// let mut prng = PseudoRng::from_entropy(); -// let bits = zparse!(ZN_AUTH_RSA_KEY_SIZE_DEFAULT)?; -// let pri_key = RsaPrivateKey::new(&mut prng, bits)?; -// let pub_key = RsaPublicKey::from(&pri_key); - -// let pka = PubKeyAuthenticator { -// pub_key: pub_key.into(), -// pri_key: pri_key.into(), -// state: Mutex::new(InnerState { -// prng, -// known_keys: None, -// authenticated: HashMap::new(), -// }), -// }; -// Ok(pka) -// } - -// pub async fn add_key(&self, key: ZPublicKey) -> ZResult<()> { -// let mut guard = zasynclock!(self.state); -// match guard.known_keys.as_mut() { -// Some(kk) => { -// if !kk.iter().any(|x| x == &key) { -// kk.push(key); -// } -// } -// None => { -// let hs = vec![key]; -// guard.known_keys = Some(hs); -// } -// } -// Ok(()) -// } - -// pub async fn del_key(&self, key: &ZPublicKey) -> ZResult<()> { -// let mut guard = zasynclock!(self.state); -// if let Some(kk) = guard.known_keys.as_mut() { -// if let Some(i) = kk.iter().position(|x| x == key) { -// kk.remove(i); -// } -// } -// Ok(()) -// } - -// pub async fn from_config(config: &Config) -> ZResult> { -// let c = config.transport().auth().pubkey(); - -// // @TODO: support PubKey keys import - -// // First, check if PEM keys are provided -// match (c.public_key_pem(), c.private_key_pem()) { -// (Some(public), Some(private)) => { -// let pub_key = RsaPublicKey::from_pkcs1_pem(public) -// .map_err(|e| zerror!("Rsa Public Key: {}", e))?; -// let pri_key = RsaPrivateKey::from_pkcs1_pem(private) -// .map_err(|e| zerror!("Rsa Private Key: {}", e))?; -// return Ok(Some(Self::new(pub_key, pri_key))); -// } -// (Some(_), None) => { -// bail!("Missing Rsa Private Key: PEM") -// } -// (None, Some(_)) => { -// bail!("Missing Rsa Public Key: PEM") -// } -// (None, None) => {} -// } - -// // Second, check if PEM files are provided -// match (c.public_key_file(), c.private_key_file()) { -// (Some(public), Some(private)) => { -// let path = Path::new(public); -// let pub_key = RsaPublicKey::read_pkcs1_pem_file(path) -// .map_err(|e| zerror!("Rsa Public Key: {}", e))?; -// let path = Path::new(private); -// let pri_key = RsaPrivateKey::read_pkcs1_pem_file(path) -// .map_err(|e| zerror!("Rsa Private Key: {}", e))?; -// return Ok(Some(Self::new(pub_key, pri_key))); -// } -// (Some(_), None) => { -// bail!("Missing Rsa Private Key: file") -// } -// (None, Some(_)) => { -// bail!("Missing Rsa Public Key: file") -// } -// (None, None) => {} -// } - -// Ok(None) -// } -// } - -// #[async_trait] -// impl TransportAuthenticatorTrait for PubKeyAuthenticator { -// fn id(&self) -> ZNodeAuthenticatorId { -// ZNodeAuthenticatorId::PublicKey -// } - -// async fn close(&self) { -// // No cleanup needed -// } - -// async fn get_init_syn_properties( -// &self, -// link: &AuthenticatedLink, -// _node_id: &ZenohId, -// ) -> ZResult>> { -// let init_syn_property = InitSynProperty { -// version: MULTILINK_VERSION, -// alice_pubkey: self.pub_key.clone(), -// }; - -// let mut wbuf = vec![]; -// let codec = Zenoh080::new(); -// let mut writer = wbuf.writer(); -// codec -// .write(&mut writer, &init_syn_property) -// .map_err(|_| zerror!("Error in encoding InitSyn for PubKey on link: {}", link))?; - -// Ok(Some(wbuf)) -// } - -// async fn handle_init_syn( -// &self, -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: Option>, -// ) -> ZResult<(Option>, Option>)> { -// match property { -// // The connecting zenoh peer wants to do multilink -// Some(pk) => { -// // Decode the multilink attachment -// let mut reader = pk.reader(); -// let codec = Zenoh080::new(); - -// let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received InitSyn with invalid PubKey attachment on link: {}", -// link -// ) -// })?; - -// // Check if we are compatible -// if init_syn_property.version != MULTILINK_VERSION { -// bail!("PubKey version not supported on link: {}", link); -// } - -// // Check if the peer is already present -// let mut guard = zasynclock!(self.state); -// match guard.authenticated.get(&cookie.zid) { -// Some(alice_pubkey) => { -// // Check if the public key is the same -// match alice_pubkey.as_ref() { -// Some(apk) => { -// // Check if pub key is used consistently -// if apk != &init_syn_property.alice_pubkey { -// bail!("Invalid multilink PubKey on link: {}", link); -// } -// } -// None => { -// // The peer is already present but no previous multilink intereset -// // was declared. Rejecting for inconsistent declaration. -// bail!("Unexpected multilink PubKey on link: {}", link); -// } -// } -// } -// None => { -// // It's the first time we see this peer, check if it is authorized it -// if let Some(kk) = guard.known_keys.as_ref() { -// if !kk.iter().any(|x| x == &init_syn_property.alice_pubkey) { -// // The peer is already present but no previous multilink intereset -// // was declared. Rejecting for inconsistent declaration. -// bail!("Unauthorized multilink PubKey on link: {}", link); -// } -// } - -// guard -// .authenticated -// .insert(cookie.zid, Some(init_syn_property.alice_pubkey.clone())); -// } -// } - -// // Create the InitAck attachment -// let codec = Zenoh080::new(); - -// let mut wbuf = vec![]; -// let mut writer = wbuf.writer(); -// codec.write(&mut writer, cookie.nonce).map_err(|_| { -// zerror!("Error in encoding InitAck for PubKey on link: {}", link) -// })?; - -// let nonce_bytes = wbuf; -// let nonce_encrypted_with_alice_pubkey = init_syn_property.alice_pubkey.encrypt( -// &mut guard.prng, -// PaddingScheme::PKCS1v15Encrypt, -// nonce_bytes.as_slice(), -// )?; - -// let init_ack_property = InitAckProperty { -// bob_pubkey: self.pub_key.clone(), -// nonce_encrypted_with_alice_pubkey, -// }; - -// // Store the public key in the cookie -// let mut wbuf = vec![]; -// let mut writer = wbuf.writer(); -// codec -// .write(&mut writer, &init_syn_property.alice_pubkey) -// .map_err(|_| { -// zerror!("Error in encoding InitAck for PubKey on link: {}", link) -// })?; -// let cookie = wbuf; - -// // Encode the InitAck property -// let mut wbuf = vec![]; -// let mut writer = wbuf.writer(); -// codec.write(&mut writer, &init_ack_property).map_err(|_| { -// zerror!("Error in encoding InitAck for PubKey on link: {}", link) -// })?; -// let attachment = wbuf; - -// Ok((Some(attachment), Some(cookie))) -// } -// // The connecting zenoh peer does not want to do multilink -// None => { -// let guard = zasynclock!(self.state); -// if guard.authenticated.get(&cookie.zid).is_some() { -// // The peer is already present but no multilink intereset is declared. -// // Rejecting for inconsistent declaration. -// bail!("No multilink supported on link: {}", link); -// } - -// // No properties need to be included in the InitAck attachment -// Ok((None, None)) -// } -// } -// } - -// async fn handle_init_ack( -// &self, -// link: &AuthenticatedLink, -// _node_id: &ZenohId, -// _sn_resolution: ZInt, -// property: Option>, -// ) -> ZResult>> { -// let pk = match property { -// Some(pk) => pk, -// None => return Ok(None), -// }; - -// let codec = Zenoh080::new(); - -// let mut reader = pk.reader(); -// let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received InitAck with invalid PubKey attachment on link: {}", -// link -// ) -// })?; -// let nonce = self.pri_key.decrypt( -// PaddingScheme::PKCS1v15Encrypt, -// init_ack_property -// .nonce_encrypted_with_alice_pubkey -// .as_slice(), -// )?; - -// // Create the OpenSyn attachment -// let mut guard = zasynclock!(self.state); -// let nonce_encrypted_with_bob_pubkey = init_ack_property.bob_pubkey.encrypt( -// &mut guard.prng, -// PaddingScheme::PKCS1v15Encrypt, -// &nonce[..], -// )?; -// drop(guard); - -// let open_syn_property = OpenSynProperty { -// nonce_encrypted_with_bob_pubkey, -// }; - -// // Encode the OpenSyn property -// let mut wbuf = vec![]; -// let mut writer = wbuf.writer(); -// codec -// .write(&mut writer, &open_syn_property) -// .map_err(|_| zerror!("Error in encoding OpenSyn for PubKey on link: {}", link))?; -// let attachment = wbuf; - -// Ok(Some(attachment)) -// } - -// async fn handle_open_syn( -// &self, -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: (Option>, Option>), -// ) -> ZResult>> { -// match property { -// (Some(att), Some(cke)) => { -// let codec = Zenoh080::new(); - -// let mut reader = att.reader(); -// let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received OpenSyn with invalid PubKey attachment on link: {}", -// link -// ) -// })?; - -// let nonce_bytes = self.pri_key.decrypt( -// PaddingScheme::PKCS1v15Encrypt, -// open_syn_property.nonce_encrypted_with_bob_pubkey.as_slice(), -// )?; -// let mut reader = nonce_bytes.reader(); -// let nonce: ZInt = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received OpenSyn with invalid PubKey attachment on link: {}", -// link -// ) -// })?; - -// if nonce != cookie.nonce { -// bail!("Received invalid nonce on link: {}", link); -// } - -// let mut reader = cke.reader(); -// let alice_pubkey: ZPublicKey = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received OpenSyn with invalid PubKey attachment on link: {}", -// link -// ) -// })?; - -// let mut guard = zasynclock!(self.state); -// match guard.authenticated.get(&cookie.zid) { -// Some(apk) => match apk { -// Some(apk) => { -// // Check if the public key is still correct -// if apk != &alice_pubkey { -// bail!("Invalid multilink pub key on link: {}", link); -// } -// } -// None => { -// // The peer did not previously express interest in multilink -// bail!("Invalid multilink pub key on link: {}", link); -// } -// }, -// None => { -// // Finally store the public key -// guard.authenticated.insert(cookie.zid, Some(alice_pubkey)); -// } -// } -// } -// (None, None) => { -// // No multilink -// let mut guard = zasynclock!(self.state); -// if guard.authenticated.get(&cookie.zid).is_some() { -// // The peer did not previously express interest in multilink -// bail!("Invalid multilink pub key on link: {}", link); -// } -// // Finally store the public key -// guard.authenticated.insert(cookie.zid, None); -// } -// _ => { -// bail!("Received invalid nonce on link: {}", link); -// } -// } - -// Ok(None) -// } - -// async fn handle_open_ack( -// &self, -// _link: &AuthenticatedLink, -// _property: Option>, -// ) -> ZResult>> { -// Ok(None) -// } - -// async fn handle_link_err(&self, link: &AuthenticatedLink) { -// // Need to check if it authenticated and remove it if this is the last link -// if let Some(zid) = link.node_id.as_ref() { -// zasynclock!(self.state).authenticated.remove(zid); -// } -// } - -// async fn handle_close(&self, node_id: &ZenohId) { -// zasynclock!(self.state).authenticated.remove(node_id); -// } -// } - -// //noinspection ALL -// impl From> for TransportAuthenticator { -// fn from(v: Arc) -> TransportAuthenticator { -// TransportAuthenticator(v) -// } -// } - -// impl From for TransportAuthenticator { -// fn from(v: PubKeyAuthenticator) -> TransportAuthenticator { -// Self::from(Arc::new(v)) -// } -// } +/* OpenAck */ +/*************************************/ +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// +---------------+ +/// +/// ZExtUnit + +pub(crate) struct AuthPubKeyFsm<'a> { + inner: &'a AuthPubKey, + prng: &'a Mutex, +} + +impl<'a> AuthPubKeyFsm<'a> { + pub(super) const fn new(inner: &'a AuthPubKey, prng: &'a Mutex) -> Self { + Self { inner, prng } + } +} + +/*************************************/ +/* OPEN */ +/*************************************/ +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct StateOpen { + nonce: Vec, +} + +impl StateOpen { + pub(crate) const fn new() -> Self { + Self { nonce: vec![] } + } +} + +#[async_trait] +impl<'a> OpenFsm for AuthPubKeyFsm<'a> { + type Error = ZError; + + type SendInitSynIn = &'a StateOpen; + type SendInitSynOut = Option>; + async fn send_init_syn( + &self, + _input: Self::SendInitSynIn, + ) -> Result { + const S: &str = "PubKey extension - Send InitSyn."; + log::trace!("{S}"); + + let init_syn = InitSyn { + alice_pubkey: self.inner.pub_key.clone(), + }; + + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, &init_syn) + .map_err(|_| zerror!("{S} Encoding error."))?; + + Ok(Some(ZExtZBuf::new(buff.into()))) + } + + type RecvInitAckIn = (&'a mut StateOpen, Option>); + type RecvInitAckOut = (); + async fn recv_init_ack( + &self, + input: Self::RecvInitAckIn, + ) -> Result { + const S: &str = "PubKey extension - Recv InitAck."; + log::trace!("{S}"); + + let (state, mut ext) = input; + + let ext = ext + .take() + .ok_or_else(|| zerror!("{S} Missing PubKey extension."))?; + + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let init_ack: InitAck = codec + .read(&mut reader) + .map_err(|_| zerror!("{S} Decoding error."))?; + + if !self.inner.lookup.is_empty() && !self.inner.lookup.contains(&init_ack.bob_pubkey) { + bail!("{S} Unauthorized PubKey."); + } + + let mut prng = zasynclock!(self.prng); + let nonce = self + .inner + .pri_key + .decrypt_blinded( + &mut *prng, + Pkcs1v15Encrypt, + init_ack.nonce_encrypted_with_alice_pubkey.as_slice(), + ) + .map_err(|_| zerror!("{S} Decryption error."))?; + + state.nonce = init_ack + .bob_pubkey + .encrypt(&mut *prng, Pkcs1v15Encrypt, nonce.as_slice())?; + + Ok(()) + } + + type SendOpenSynIn = &'a StateOpen; + type SendOpenSynOut = Option>; + async fn send_open_syn( + &self, + state: Self::SendOpenSynIn, + ) -> Result { + const S: &str = "PubKey extension - Send OpenSyn."; + log::trace!("{S}"); + + let open_syn = OpenSyn { + nonce_encrypted_with_bob_pubkey: state.nonce.clone(), + }; + + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, &open_syn) + .map_err(|_| zerror!("{S} Encoding error."))?; + + Ok(Some(ZExtZBuf::new(buff.into()))) + } + + type RecvOpenAckIn = (&'a mut StateOpen, Option>); + type RecvOpenAckOut = (); + async fn recv_open_ack( + &self, + input: Self::RecvOpenAckIn, + ) -> Result { + const S: &str = "PubKey extension - Recv OpenAck."; + + let (_, ext) = input; + if ext.is_none() { + bail!("{S} Expected extension."); + } + + Ok(()) + } +} + +/*************************************/ +/* ACCEPT */ +/*************************************/ + +#[derive(Debug)] +pub(crate) struct StateAccept { + nonce: Vec, + challenge: ZInt, +} + +impl StateAccept { + pub(crate) const fn new() -> Self { + Self { + nonce: vec![], + challenge: 0, + } + } + + #[cfg(test)] + pub(crate) fn rand() -> Self { + let mut rng = rand::thread_rng(); + let mut nonce = vec![0u8; rng.gen_range(0..=64)]; + rng.fill(&mut nonce[..]); + Self { + nonce, + challenge: rng.gen(), + } + } +} + +// Codec +impl WCodec<&StateAccept, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &StateAccept) -> Self::Output { + self.write(&mut *writer, x.challenge) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let challenge: ZInt = self.read(&mut *reader)?; + Ok(StateAccept { + nonce: vec![], + challenge, + }) + } +} + +impl PartialEq for StateAccept { + fn eq(&self, other: &Self) -> bool { + self.challenge == other.challenge + } +} + +#[async_trait] +impl<'a> AcceptFsm for AuthPubKeyFsm<'a> { + type Error = ZError; + + type RecvInitSynIn = (&'a mut StateAccept, Option>); + type RecvInitSynOut = (); + async fn recv_init_syn( + &self, + input: Self::RecvInitSynIn, + ) -> Result { + const S: &str = "PubKey extension - Recv InitSyn."; + log::trace!("{S}"); + + let (state, mut ext) = input; + + let ext = ext + .take() + .ok_or_else(|| zerror!("{S} Missing PubKey extension."))?; + + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let init_syn: InitSyn = codec + .read(&mut reader) + .map_err(|_| zerror!("{S} Decoding error."))?; + + if !self.inner.lookup.contains(&init_syn.alice_pubkey) { + bail!("{S} Unauthorized PubKey."); + } + + let mut prng = zasynclock!(self.prng); + state.challenge = prng.gen(); + state.nonce = init_syn + .alice_pubkey + .encrypt(&mut *prng, Pkcs1v15Encrypt, &state.challenge.to_le_bytes()) + .map_err(|_| zerror!("{S} Encoding error."))?; + + Ok(()) + } + + type SendInitAckIn = &'a StateAccept; + type SendInitAckOut = Option>; + async fn send_init_ack( + &self, + state: Self::SendInitAckIn, + ) -> Result { + const S: &str = "PubKey extension - Send InitAck."; + log::trace!("{S}"); + + let init_ack = InitAck { + bob_pubkey: self.inner.pub_key.clone(), + nonce_encrypted_with_alice_pubkey: state.nonce.clone(), + }; + + let codec = Zenoh080::new(); + let mut buff = vec![]; + let mut writer = buff.writer(); + codec + .write(&mut writer, &init_ack) + .map_err(|_| zerror!("{S} Encoding error."))?; + + Ok(Some(ZExtZBuf::new(buff.into()))) + } + + type RecvOpenSynIn = (&'a mut StateAccept, Option>); + type RecvOpenSynOut = (); + async fn recv_open_syn( + &self, + input: Self::RecvOpenSynIn, + ) -> Result { + const S: &str = "PubKey extension - Recv OpenSyn."; + log::trace!("{S}"); + + let (state, mut ext) = input; + + let ext = ext + .take() + .ok_or_else(|| zerror!("{S} Missing PubKey extension."))?; + + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let open_syn: OpenSyn = codec + .read(&mut reader) + .map_err(|_| zerror!("{S} Decoding error."))?; + + let mut prng = zasynclock!(self.prng); + let nonce = self + .inner + .pri_key + .decrypt_blinded( + &mut *prng, + Pkcs1v15Encrypt, + open_syn.nonce_encrypted_with_bob_pubkey.as_slice(), + ) + .map_err(|_| zerror!("{S} Decryption error."))?; + + if nonce.as_slice() != state.challenge.to_le_bytes() { + println!("{:02x?}\n{:02x?}", nonce, state.nonce); + bail!("{S} Invalid nonce."); + } + + Ok(()) + } + + type SendOpenAckIn = &'a StateAccept; + type SendOpenAckOut = Option>; + async fn send_open_ack( + &self, + _input: Self::SendOpenAckIn, + ) -> Result { + const S: &str = "PubKey extension - Send OpenAck."; + log::trace!("{S}"); + + Ok(Some(ZExtUnit::new())) + } +} diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index bc8bc351e7..815629a5e6 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -19,7 +19,7 @@ use crate::establishment::{AcceptFsm, OpenFsm}; use async_std::fs; use async_trait::async_trait; -use rand::Rng; +use rand::{CryptoRng, Rng}; use std::collections::HashMap; use zenoh_buffers::{ reader::{DidntRead, HasReader, Reader}, @@ -64,30 +64,32 @@ impl AuthUsrPwd { } pub async fn from_config(config: &UsrPwdConf) -> ZResult> { + const S: &str = "UsrPwd extension - From config."; + let mut lookup: HashMap = HashMap::new(); if let Some(dict) = config.dictionary_file() { let content = fs::read_to_string(dict) .await - .map_err(|e| zerror!("Invalid user-password dictionary file: {}", e))?; + .map_err(|e| zerror!("{S} Invalid user-password dictionary file: {}.", e))?; // Populate the user-password dictionary let mut ps = Properties::from(content); for (user, password) in ps.drain() { lookup.insert(user.as_bytes().to_owned(), password.as_bytes().to_owned()); } - log::debug!("User-password dictionary has been configured"); + log::debug!("{S} User-password dictionary has been configured."); } let mut credentials: Option<(User, Password)> = None; if let Some(user) = config.user() { if let Some(password) = config.password() { - log::debug!("User and password have been configured"); + log::debug!("{S} User-password has been configured."); credentials = Some((user.as_bytes().to_owned(), password.as_bytes().to_owned())); } } if !lookup.is_empty() || credentials.is_some() { - log::debug!("User-password authentication is enabled"); + log::debug!("{S} User-password authentication is enabled."); Ok(Some(Self { lookup, credentials, @@ -100,19 +102,34 @@ impl AuthUsrPwd { // OpenFsm / AcceptFsm #[derive(Debug, PartialEq, Eq)] -pub(crate) struct State { +pub(crate) struct StateOpen { nonce: ZInt, } -impl State { +impl StateOpen { pub(crate) fn new(prng: &mut R) -> Self where - R: Rng, + R: Rng + CryptoRng, { Self { nonce: prng.gen() } } +} - #[cfg(test)] +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct StateAccept { + nonce: ZInt, +} + +impl StateAccept { + pub(crate) fn new(prng: &mut R) -> Self + where + R: Rng + CryptoRng, + { + Self { nonce: prng.gen() } + } + + #[cfg(feature = "test")] + #[allow(unused)] // Used for testing pub(crate) fn rand() -> Self { let mut rng = rand::thread_rng(); Self::new(&mut rng) @@ -120,26 +137,26 @@ impl State { } // Codec -impl WCodec<&State, &mut W> for Zenoh080 +impl WCodec<&StateAccept, &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &State) -> Self::Output { + fn write(self, writer: &mut W, x: &StateAccept) -> Self::Output { self.write(&mut *writer, x.nonce) } } -impl RCodec for Zenoh080 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result { let nonce: ZInt = self.read(&mut *reader)?; - Ok(State { nonce }) + Ok(StateAccept { nonce }) } } @@ -227,7 +244,7 @@ where impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { type Error = ZError; - type SendInitSynIn = &'a State; + type SendInitSynIn = &'a StateOpen; type SendInitSynOut = Option>; async fn send_init_syn( &self, @@ -237,7 +254,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { Ok(output) } - type RecvInitAckIn = (&'a mut State, Option>); + type RecvInitAckIn = (&'a mut StateOpen, Option>); type RecvInitAckOut = (); async fn recv_init_ack( &self, @@ -252,13 +269,13 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { let (state, mut ext_userwpd) = input; let ext_usrpwd = ext_userwpd .take() - .ok_or_else(|| zerror!("{} Decoding error.", S))?; + .ok_or_else(|| zerror!("{S} Decoding error."))?; state.nonce = ext_usrpwd.value; Ok(()) } - type SendOpenSynIn = &'a State; + type SendOpenSynIn = &'a StateOpen; type SendOpenSynOut = Option>; async fn send_open_syn( &self, @@ -274,7 +291,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { // Create the HMAC of the password using the nonce received as a key (it's a challenge) let key = state.nonce.to_le_bytes(); - let hmac = hmac::sign(&key, password).map_err(|_| zerror!("{} Encoding error.", S))?; + let hmac = hmac::sign(&key, password).map_err(|_| zerror!("{S} Encoding error."))?; // Create the OpenSyn extension let open_syn = OpenSyn { user: user.to_vec(), @@ -285,13 +302,13 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { let mut writer = buff.writer(); codec .write(&mut writer, &open_syn) - .map_err(|_| zerror!("{} Encoding error.", S))?; + .map_err(|_| zerror!("{S} Encoding error."))?; let output = Some(ZExtZBuf::new(buff.into())); Ok(output) } - type RecvOpenAckIn = (&'a mut State, Option>); + type RecvOpenAckIn = (&'a mut StateOpen, Option>); type RecvOpenAckOut = (); async fn recv_open_ack( &self, @@ -301,7 +318,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { let (_, ext) = input; if self.inner.credentials.is_some() && ext.is_none() { - bail!("{} Expected extension.", S); + bail!("{S} Expected extension."); } Ok(()) @@ -315,7 +332,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { type Error = ZError; - type RecvInitSynIn = (&'a mut State, Option>); + type RecvInitSynIn = (&'a mut StateAccept, Option>); type RecvInitSynOut = (); async fn recv_init_syn( &self, @@ -325,13 +342,13 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { let (_, ext_usrpwd) = input; if ext_usrpwd.is_none() { - bail!("{} Expected extension.", S); + bail!("{S} Expected extension."); } Ok(()) } - type SendInitAckIn = &'a State; + type SendInitAckIn = &'a StateAccept; type SendInitAckOut = Option>; async fn send_init_ack( &self, @@ -340,7 +357,7 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { Ok(Some(ZExtZInt::new(state.nonce))) } - type RecvOpenSynIn = (&'a mut State, Option>); + type RecvOpenSynIn = (&'a mut StateAccept, Option>); type RecvOpenSynOut = (); async fn recv_open_syn( &self, @@ -351,31 +368,31 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { let (state, mut ext_usrpwd) = input; let ext_usrpwd = ext_usrpwd .take() - .ok_or_else(|| zerror!("{} Expected extension.", S))?; + .ok_or_else(|| zerror!("{S} Expected extension."))?; let codec = Zenoh080::new(); let mut reader = ext_usrpwd.value.reader(); let open_syn: OpenSyn = codec .read(&mut reader) - .map_err(|_| zerror!("{} Decoding error.", S))?; + .map_err(|_| zerror!("{S} Decoding error."))?; let pwd = self .inner .lookup .get(&open_syn.user) - .ok_or_else(|| zerror!("{} Invalid user.", S))?; + .ok_or_else(|| zerror!("{S} Invalid user."))?; // Create the HMAC of the password using the nonce received as challenge let key = state.nonce.to_le_bytes(); - let hmac = hmac::sign(&key, pwd).map_err(|_| zerror!("{} Encoding error.", S))?; + let hmac = hmac::sign(&key, pwd).map_err(|_| zerror!("{S} Encoding error."))?; if hmac != open_syn.hmac { - bail!("{} Invalid password.", S); + bail!("{S} Invalid password."); } Ok(()) } - type SendOpenAckIn = &'a State; + type SendOpenAckIn = &'a StateAccept; type SendOpenAckOut = Option>; async fn send_open_ack( &self, @@ -384,229 +401,3 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { Ok(Some(ZExtUnit::new())) } } - -// #[async_trait] -// impl TransportAuthenticatorTrait for UserPasswordAuthenticator { -// fn id(&self) -> ZNodeAuthenticatorId { -// ZNodeAuthenticatorId::UserPassword -// } - -// async fn close(&self) { -// // No cleanup needed -// } - -// async fn get_init_syn_properties( -// &self, -// link: &AuthenticatedLink, -// _node_id: &ZenohId, -// ) -> ZResult>> { -// // If credentials are not configured, don't initiate the USRPWD authentication -// if self.credentials.is_none() { -// return Ok(None); -// } - -// let init_syn_property = InitSynProperty { -// version: USRPWD_VERSION, -// }; -// let mut wbuf = vec![]; -// let codec = Zenoh080::new(); -// let mut writer = wbuf.writer(); -// codec -// .write(&mut writer, &init_syn_property) -// .map_err(|_| zerror!("Error in encoding InitSyn for UsrPwd on link: {}", link))?; -// let attachment = wbuf; - -// Ok(Some(attachment)) -// } - -// async fn handle_init_syn( -// &self, -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: Option>, -// ) -> ZResult<(Option>, Option>)> { -// let p = property.ok_or_else(|| { -// zerror!( -// "Received InitSyn with no UsrPwd attachment on link: {}", -// link -// ) -// })?; - -// let codec = Zenoh080::new(); - -// let mut reader = p.reader(); -// let init_syn_property: InitSynProperty = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received InitSyn with invalid UsrPwd attachment on link: {}", -// link -// ) -// })?; -// if init_syn_property.version > USRPWD_VERSION { -// bail!("Rejected InitSyn with invalid attachment on link: {}", link) -// } - -// // Create the InitAck attachment -// let init_ack_property = InitAckProperty { -// nonce: cookie.nonce, -// }; -// let mut wbuf = vec![]; -// let mut writer = wbuf.writer(); -// codec -// .write(&mut writer, &init_ack_property) -// .map_err(|_| zerror!("Error in encoding InitAck for UsrPwd on link: {}", link))?; -// let attachment = wbuf; - -// Ok((Some(attachment), None)) -// } - -// async fn handle_init_ack( -// &self, -// link: &AuthenticatedLink, -// _node_id: &ZenohId, -// _sn_resolution: ZInt, -// property: Option>, -// ) -> ZResult>> { -// // If credentials are not configured, don't continue the USRPWD authentication -// let credentials = match self.credentials.as_ref() { -// Some(cr) => cr, -// None => return Ok(None), -// }; - -// let p = property.ok_or_else(|| { -// zerror!( -// "Received InitAck with no UsrPwd attachment on link: {}", -// link -// ) -// })?; - -// let codec = Zenoh080::new(); - -// let mut reader = p.reader(); -// let init_ack_property: InitAckProperty = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received InitAck with invalid UsrPwd attachment on link: {}", -// link -// ) -// })?; - -// // Create the HMAC of the password using the nonce received as a key (it's a challenge) -// let key = init_ack_property.nonce.to_le_bytes(); -// let hmac = hmac::sign(&key, &credentials.password)?; -// // Create the OpenSyn attachment -// let open_syn_property = OpenSynProperty { -// user: credentials.user.clone(), -// hmac, -// }; -// // Encode the InitAck attachment -// let mut wbuf = vec![]; -// let mut writer = wbuf.writer(); -// codec -// .write(&mut writer, &open_syn_property) -// .map_err(|_| zerror!("Error in encoding OpenSyn for UsrPwd on link: {}", link))?; -// let attachment = wbuf; - -// Ok(Some(attachment)) -// } - -// async fn handle_open_syn( -// &self, -// link: &AuthenticatedLink, -// cookie: &Cookie, -// property: (Option>, Option>), -// ) -> ZResult>> { -// let (attachment, _cookie) = property; -// let a = attachment.ok_or_else(|| { -// zerror!( -// "Received OpenSyn with no UsrPwd attachment on link: {}", -// link -// ) -// })?; - -// let codec = Zenoh080::new(); - -// let mut reader = a.reader(); -// let open_syn_property: OpenSynProperty = codec.read(&mut reader).map_err(|_| { -// zerror!( -// "Received OpenSyn with invalid UsrPwd attachment on link: {}", -// link -// ) -// })?; -// let password = match zasyncread!(self.lookup).get(&open_syn_property.user) { -// Some(password) => password.clone(), -// None => bail!("Received OpenSyn with invalid user on link: {}", link), -// }; - -// // Create the HMAC of the password using the nonce received as challenge -// let key = cookie.nonce.to_le_bytes(); -// let hmac = hmac::sign(&key, &password)?; -// if hmac != open_syn_property.hmac { -// bail!("Received OpenSyn with invalid password on link: {}", link) -// } - -// // Check PID validity -// let mut guard = zasynclock!(self.authenticated); -// match guard.get_mut(&cookie.zid) { -// Some(auth) => { -// if open_syn_property.user != auth.credentials.user -// || password != auth.credentials.password -// { -// bail!("Received OpenSyn with invalid password on link: {}", link) -// } -// auth.links.insert((link.src.clone(), link.dst.clone())); -// } -// None => { -// let credentials = Credentials { -// user: open_syn_property.user, -// password, -// }; -// let mut links = HashSet::new(); -// links.insert((link.src.clone(), link.dst.clone())); -// let auth = Authenticated { credentials, links }; -// guard.insert(cookie.zid, auth); -// } -// } - -// Ok(None) -// } - -// async fn handle_open_ack( -// &self, -// _link: &AuthenticatedLink, -// _property: Option>, -// ) -> ZResult>> { -// Ok(None) -// } - -// async fn handle_link_err(&self, link: &AuthenticatedLink) { -// // Need to check if it authenticated and remove it if this is the last link -// let mut guard = zasynclock!(self.authenticated); -// let mut to_del: Option = None; -// for (node_id, auth) in guard.iter_mut() { -// auth.links.remove(&(link.src.clone(), link.dst.clone())); -// if auth.links.is_empty() { -// to_del = Some(*node_id); -// break; -// } -// } -// if let Some(node_id) = to_del.take() { -// guard.remove(&node_id); -// } -// } - -// async fn handle_close(&self, node_id: &ZenohId) { -// zasynclock!(self.authenticated).remove(node_id); -// } -// } - -// //noinspection ALL -// impl From> for TransportAuthenticator { -// fn from(v: Arc) -> TransportAuthenticator { -// TransportAuthenticator(v) -// } -// } - -// impl From for TransportAuthenticator { -// fn from(v: UserPasswordAuthenticator) -> TransportAuthenticator { -// Self::from(Arc::new(v)) -// } -// } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs index 193d4352cb..b72e34c636 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/qos.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/qos.rs @@ -22,55 +22,6 @@ use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_protocol::transport::{init, open}; use zenoh_result::Error as ZError; -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) struct State { - is_qos: bool, -} - -impl State { - pub(crate) const fn new(is_qos: bool) -> Self { - Self { is_qos } - } - - pub(crate) const fn is_qos(&self) -> bool { - self.is_qos - } - - #[cfg(test)] - pub(crate) fn rand() -> Self { - use rand::Rng; - let mut rng = rand::thread_rng(); - Self::new(rng.gen_bool(0.5)) - } -} - -// Codec -impl WCodec<&State, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &State) -> Self::Output { - let is_qos = u8::from(x.is_qos); - self.write(&mut *writer, is_qos)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let is_qos: u8 = self.read(&mut *reader)?; - let is_qos = is_qos == 1; - Ok(State { is_qos }) - } -} - // Extension Fsm pub(crate) struct QoSFsm<'a> { _a: PhantomData<&'a ()>, @@ -85,11 +36,26 @@ impl<'a> QoSFsm<'a> { /*************************************/ /* OPEN */ /*************************************/ +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) struct StateOpen { + is_qos: bool, +} + +impl StateOpen { + pub(crate) const fn new(is_qos: bool) -> Self { + Self { is_qos } + } + + pub(crate) const fn is_qos(&self) -> bool { + self.is_qos + } +} + #[async_trait] impl<'a> OpenFsm for QoSFsm<'a> { type Error = ZError; - type SendInitSynIn = &'a State; + type SendInitSynIn = &'a StateOpen; type SendInitSynOut = Option; async fn send_init_syn( &self, @@ -99,7 +65,7 @@ impl<'a> OpenFsm for QoSFsm<'a> { Ok(output) } - type RecvInitAckIn = (&'a mut State, Option); + type RecvInitAckIn = (&'a mut StateOpen, Option); type RecvInitAckOut = (); async fn recv_init_ack( &self, @@ -110,7 +76,7 @@ impl<'a> OpenFsm for QoSFsm<'a> { Ok(()) } - type SendOpenSynIn = &'a State; + type SendOpenSynIn = &'a StateOpen; type SendOpenSynOut = Option; async fn send_open_syn( &self, @@ -119,7 +85,7 @@ impl<'a> OpenFsm for QoSFsm<'a> { Ok(None) } - type RecvOpenAckIn = (&'a mut State, Option); + type RecvOpenAckIn = (&'a mut StateOpen, Option); type RecvOpenAckOut = (); async fn recv_open_ack( &self, @@ -132,11 +98,60 @@ impl<'a> OpenFsm for QoSFsm<'a> { /*************************************/ /* ACCEPT */ /*************************************/ +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) struct StateAccept { + is_qos: bool, +} + +impl StateAccept { + pub(crate) const fn new(is_qos: bool) -> Self { + Self { is_qos } + } + + pub(crate) const fn is_qos(&self) -> bool { + self.is_qos + } + + #[cfg(test)] + pub(crate) fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + Self::new(rng.gen_bool(0.5)) + } +} + +// Codec +impl WCodec<&StateAccept, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &StateAccept) -> Self::Output { + let is_qos = u8::from(x.is_qos); + self.write(&mut *writer, is_qos)?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let is_qos: u8 = self.read(&mut *reader)?; + let is_qos = is_qos == 1; + Ok(StateAccept { is_qos }) + } +} + #[async_trait] impl<'a> AcceptFsm for QoSFsm<'a> { type Error = ZError; - type RecvInitSynIn = (&'a mut State, Option); + type RecvInitSynIn = (&'a mut StateAccept, Option); type RecvInitSynOut = (); async fn recv_init_syn( &self, @@ -147,7 +162,7 @@ impl<'a> AcceptFsm for QoSFsm<'a> { Ok(()) } - type SendInitAckIn = &'a State; + type SendInitAckIn = &'a StateAccept; type SendInitAckOut = Option; async fn send_init_ack( &self, @@ -157,7 +172,7 @@ impl<'a> AcceptFsm for QoSFsm<'a> { Ok(output) } - type RecvOpenSynIn = (&'a mut State, Option); + type RecvOpenSynIn = (&'a mut StateAccept, Option); type RecvOpenSynOut = (); async fn recv_open_syn( &self, @@ -166,7 +181,7 @@ impl<'a> AcceptFsm for QoSFsm<'a> { Ok(()) } - type SendOpenAckIn = &'a State; + type SendOpenAckIn = &'a StateAccept; type SendOpenAckOut = Option; async fn send_open_ack( &self, diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index 51ab9260a6..ec644a135e 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -125,13 +125,26 @@ where /// ~ ack ~ /// +---------------+ -// Extension Fsm State +// Extension Fsm +pub(crate) struct ShmFsm<'a> { + inner: &'a SharedMemoryUnicast, +} + +impl<'a> ShmFsm<'a> { + pub(crate) const fn new(inner: &'a SharedMemoryUnicast) -> Self { + Self { inner } + } +} + +/*************************************/ +/* OPEN */ +/*************************************/ #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) struct State { +pub(crate) struct StateOpen { is_shm: bool, } -impl State { +impl StateOpen { pub(crate) const fn new(is_shm: bool) -> Self { Self { is_shm } } @@ -139,58 +152,13 @@ impl State { pub(crate) const fn is_shm(&self) -> bool { self.is_shm } - - #[cfg(test)] - pub(crate) fn rand() -> Self { - use rand::Rng; - let mut rng = rand::thread_rng(); - Self::new(rng.gen_bool(0.5)) - } -} - -// Codec -impl WCodec<&State, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &State) -> Self::Output { - let is_shm = u8::from(x.is_shm); - self.write(&mut *writer, is_shm)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let is_shm: u8 = self.read(&mut *reader)?; - let is_shm = is_shm == 1; - Ok(State { is_shm }) - } -} - -// Extension Fsm -pub(crate) struct ShmFsm<'a> { - inner: &'a SharedMemoryUnicast, -} - -impl<'a> ShmFsm<'a> { - pub(crate) const fn new(inner: &'a SharedMemoryUnicast) -> Self { - Self { inner } - } } #[async_trait] impl<'a> OpenFsm for ShmFsm<'a> { type Error = ZError; - type SendInitSynIn = &'a State; + type SendInitSynIn = &'a StateOpen; type SendInitSynOut = Option; async fn send_init_syn( &self, @@ -216,7 +184,7 @@ impl<'a> OpenFsm for ShmFsm<'a> { Ok(Some(init::ext::Shm::new(buff.into()))) } - type RecvInitAckIn = (&'a mut State, Option); + type RecvInitAckIn = (&'a mut StateOpen, Option); type RecvInitAckOut = Challenge; async fn recv_init_ack( &self, @@ -288,7 +256,7 @@ impl<'a> OpenFsm for ShmFsm<'a> { Ok(bob_challenge) } - type SendOpenSynIn = (&'a State, Self::RecvInitAckOut); + type SendOpenSynIn = (&'a StateOpen, Self::RecvInitAckOut); type SendOpenSynOut = Option; async fn send_open_syn( &self, @@ -304,7 +272,7 @@ impl<'a> OpenFsm for ShmFsm<'a> { Ok(Some(open::ext::Shm::new(bob_challenge))) } - type RecvOpenAckIn = (&'a mut State, Option); + type RecvOpenAckIn = (&'a mut StateOpen, Option); type RecvOpenAckOut = (); async fn recv_open_ack( &self, @@ -336,11 +304,61 @@ impl<'a> OpenFsm for ShmFsm<'a> { /*************************************/ /* ACCEPT */ /*************************************/ + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) struct StateAccept { + is_shm: bool, +} + +impl StateAccept { + pub(crate) const fn new(is_shm: bool) -> Self { + Self { is_shm } + } + + pub(crate) const fn is_shm(&self) -> bool { + self.is_shm + } + + #[cfg(test)] + pub(crate) fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + Self::new(rng.gen_bool(0.5)) + } +} + +// Codec +impl WCodec<&StateAccept, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &StateAccept) -> Self::Output { + let is_shm = u8::from(x.is_shm); + self.write(&mut *writer, is_shm)?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let is_shm: u8 = self.read(&mut *reader)?; + let is_shm = is_shm == 1; + Ok(StateAccept { is_shm }) + } +} + #[async_trait] impl<'a> AcceptFsm for ShmFsm<'a> { type Error = ZError; - type RecvInitSynIn = (&'a mut State, Option); + type RecvInitSynIn = (&'a mut StateAccept, Option); type RecvInitSynOut = Challenge; async fn recv_init_syn( &self, @@ -391,7 +409,7 @@ impl<'a> AcceptFsm for ShmFsm<'a> { Ok(alice_challenge) } - type SendInitAckIn = (&'a State, Self::RecvInitSynOut); + type SendInitAckIn = (&'a StateAccept, Self::RecvInitSynOut); type SendInitAckOut = Option; async fn send_init_ack( &self, @@ -419,7 +437,7 @@ impl<'a> AcceptFsm for ShmFsm<'a> { Ok(Some(init::ext::Shm::new(buff.into()))) } - type RecvOpenSynIn = (&'a mut State, Option); + type RecvOpenSynIn = (&'a mut StateAccept, Option); type RecvOpenSynOut = (); async fn recv_open_syn( &self, @@ -462,7 +480,7 @@ impl<'a> AcceptFsm for ShmFsm<'a> { Ok(()) } - type SendOpenAckIn = &'a mut State; + type SendOpenAckIn = &'a mut StateAccept; type SendOpenAckOut = Option; async fn send_open_ack( &self, diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 56ddcdd89d..8bc7610ecf 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -38,10 +38,10 @@ struct StateZenoh { struct State { zenoh: StateZenoh, - ext_qos: ext::qos::State, + ext_qos: ext::qos::StateOpen, #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::State, - ext_auth: ext::auth::State, + ext_shm: ext::shm::StateOpen, + ext_auth: ext::auth::StateOpen, } // InitSyn @@ -384,7 +384,7 @@ pub(crate) async fn open_link( ext_qos: ext::qos::QoSFsm::new(), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), - ext_auth: ext::auth::AuthFsm::new(&auth), + ext_auth: ext::auth::AuthFsm::new(&auth, &manager.prng), }; // Init handshake @@ -405,10 +405,10 @@ pub(crate) async fn open_link( batch_size: manager.config.batch_size, resolution: manager.config.resolution, }, - ext_qos: ext::qos::State::new(manager.config.unicast.is_qos), + ext_qos: ext::qos::StateOpen::new(manager.config.unicast.is_qos), #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::State::new(manager.config.unicast.is_shm), - ext_auth: auth.state(&mut *zasynclock!(manager.prng)), + ext_shm: ext::shm::StateOpen::new(manager.config.unicast.is_shm), + ext_auth: auth.open(&mut *zasynclock!(manager.prng)), }; let isyn_in = SendInitSynIn { diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index 58f5f3618f..4ee1ab59de 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -12,8 +12,6 @@ // ZettaScale Zenoh Team, // use async_std::{prelude::FutureExt, task}; -#[cfg(feature = "auth_pubkey")] -// use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; use std::{any::Any, sync::Arc, time::Duration}; use zenoh_core::{zasync_executor_init, zasyncwrite}; use zenoh_link::Link; @@ -22,9 +20,6 @@ use zenoh_protocol::{ zenoh::ZenohMessage, }; use zenoh_result::ZResult; -// #[cfg(feature = "auth_pubkey")] -// use zenoh_transport::unicast::establishment::ext::auth::PubKeyAuthenticator; -#[cfg(feature = "auth_usrpwd")] use zenoh_transport::unicast::establishment::ext::auth::Auth; use zenoh_transport::{ DummyTransportPeerEventHandler, TransportEventHandler, TransportPeer, @@ -95,410 +90,295 @@ impl TransportEventHandler for SHClientAuthenticator { } } -// #[cfg(feature = "auth_pubkey")] -// async fn authenticator_multilink(endpoint: &EndPoint) { -// use std::convert::TryFrom; -// use zenoh_transport::TransportManager; - -// // Create the router transport manager -// let router_id = ZenohId::try_from([1]).unwrap(); -// let router_handler = Arc::new(SHRouterAuthenticator::new()); -// let n = BigUint::from_bytes_le(&[ -// 0x31, 0xd1, 0xfc, 0x7e, 0x70, 0x5f, 0xd7, 0xe3, 0xcc, 0xa4, 0xca, 0xcb, 0x38, 0x84, 0x2f, -// 0xf5, 0x88, 0xaa, 0x4b, 0xbc, 0x2f, 0x74, 0x59, 0x49, 0xa9, 0xb9, 0x1a, 0x4d, 0x1c, 0x93, -// 0xbc, 0xc7, 0x02, 0xd0, 0xe0, 0x0f, 0xa7, 0x68, 0xeb, 0xef, 0x9b, 0xf9, 0x4f, 0xdc, 0xe3, -// 0x40, 0x5a, 0x3c, 0x8f, 0x20, 0xf4, 0x2c, 0x90, 0x1c, 0x70, 0x56, 0x9b, 0xae, 0x44, 0x17, -// 0xca, 0x85, 0x60, 0xb5, -// ]); -// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); -// let router_pub_key = RsaPublicKey::new(n, e).unwrap(); - -// let n = BigUint::from_bytes_le(&[ -// 0x31, 0xd1, 0xfc, 0x7e, 0x70, 0x5f, 0xd7, 0xe3, 0xcc, 0xa4, 0xca, 0xcb, 0x38, 0x84, 0x2f, -// 0xf5, 0x88, 0xaa, 0x4b, 0xbc, 0x2f, 0x74, 0x59, 0x49, 0xa9, 0xb9, 0x1a, 0x4d, 0x1c, 0x93, -// 0xbc, 0xc7, 0x02, 0xd0, 0xe0, 0x0f, 0xa7, 0x68, 0xeb, 0xef, 0x9b, 0xf9, 0x4f, 0xdc, 0xe3, -// 0x40, 0x5a, 0x3c, 0x8f, 0x20, 0xf4, 0x2c, 0x90, 0x1c, 0x70, 0x56, 0x9b, 0xae, 0x44, 0x17, -// 0xca, 0x85, 0x60, 0xb5, -// ]); -// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); -// let d = BigUint::from_bytes_le(&[ -// 0xc1, 0xd1, 0xc1, 0x0f, 0xbe, 0xa7, 0xe6, 0x18, 0x98, 0x3c, 0xf8, 0x26, 0x74, 0xc0, 0xc7, -// 0xef, 0xf9, 0x38, 0x95, 0x75, 0x40, 0x45, 0xd4, 0x0d, 0x27, 0xec, 0x4c, 0xcd, 0x81, 0xf9, -// 0xf4, 0x69, 0x36, 0x99, 0x95, 0x97, 0xd0, 0xc8, 0x43, 0xac, 0xbb, 0x3e, 0x8f, 0xfb, 0x97, -// 0x53, 0xdb, 0x92, 0x12, 0xc5, 0xc0, 0x50, 0x83, 0xb2, 0x04, 0x25, 0x79, 0xeb, 0xa7, 0x32, -// 0x84, 0xbb, 0xc6, 0x35, -// ]); -// let primes = vec![ -// BigUint::from_bytes_le(&[ -// 0xb9, 0x17, 0xd3, 0x45, 0x0a, 0x8e, 0xf7, 0x41, 0xaf, 0x75, 0xe3, 0x7f, 0xe9, 0x3c, -// 0x10, 0x28, 0x24, 0x0a, 0x95, 0x32, 0xc0, 0xcb, 0x23, 0x60, 0x6e, 0x2d, 0xb8, 0x2e, -// 0x96, 0x78, 0x21, 0xdf, -// ]), -// BigUint::from_bytes_le(&[ -// 0x39, 0x51, 0xd3, 0xf3, 0xfe, 0xd1, 0x81, 0xd3, 0xc3, 0x2b, 0x49, 0x65, 0x3a, 0x44, -// 0x41, 0x31, 0xa7, 0x38, 0x8b, 0xd9, 0x18, 0xc7, 0x41, 0x8c, 0x86, 0x0b, 0x65, 0x2d, -// 0x18, 0x78, 0x18, 0xd0, -// ]), -// ]; -// let router_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); -// let peer_auth_router = Arc::new(PubKeyAuthenticator::new(router_pub_key, router_pri_key)); -// let unicast = TransportManager::config_unicast() -// .max_links(2) -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_router.clone().into()])); -// let router_manager = TransportManager::builder() -// .whatami(WhatAmI::Router) -// .zid(router_id) -// .unicast(unicast) -// .build(router_handler.clone()) -// .unwrap(); - -// // Create the transport transport manager for the client 01 -// let client01_id = ZenohId::try_from([2]).unwrap(); - -// let n = BigUint::from_bytes_le(&[ -// 0x41, 0x74, 0xc6, 0x40, 0x18, 0x63, 0xbd, 0x59, 0xe6, 0x0d, 0xe9, 0x23, 0x3e, 0x95, 0xca, -// 0xb4, 0x5d, 0x17, 0x3d, 0x14, 0xdd, 0xbb, 0x16, 0x4a, 0x49, 0xeb, 0x43, 0x27, 0x79, 0x3e, -// 0x75, 0x67, 0xd6, 0xf6, 0x7f, 0xe7, 0xbf, 0xb5, 0x1d, 0xf6, 0x27, 0x80, 0xca, 0x26, 0x35, -// 0xa2, 0xc5, 0x4c, 0x96, 0x50, 0xaa, 0x9f, 0xf4, 0x47, 0xbe, 0x06, 0x9c, 0xd1, 0xec, 0xfd, -// 0x1e, 0x81, 0xe9, 0xc4, -// ]); -// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); -// let client01_pub_key = RsaPublicKey::new(n, e).unwrap(); - -// let n = BigUint::from_bytes_le(&[ -// 0x41, 0x74, 0xc6, 0x40, 0x18, 0x63, 0xbd, 0x59, 0xe6, 0x0d, 0xe9, 0x23, 0x3e, 0x95, 0xca, -// 0xb4, 0x5d, 0x17, 0x3d, 0x14, 0xdd, 0xbb, 0x16, 0x4a, 0x49, 0xeb, 0x43, 0x27, 0x79, 0x3e, -// 0x75, 0x67, 0xd6, 0xf6, 0x7f, 0xe7, 0xbf, 0xb5, 0x1d, 0xf6, 0x27, 0x80, 0xca, 0x26, 0x35, -// 0xa2, 0xc5, 0x4c, 0x96, 0x50, 0xaa, 0x9f, 0xf4, 0x47, 0xbe, 0x06, 0x9c, 0xd1, 0xec, 0xfd, -// 0x1e, 0x81, 0xe9, 0xc4, -// ]); -// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); -// let d = BigUint::from_bytes_le(&[ -// 0x15, 0xe1, 0x93, 0xda, 0x75, 0xcb, 0x76, 0x40, 0xce, 0x70, 0x6f, 0x0f, 0x62, 0xe1, 0x58, -// 0xa5, 0x53, 0x7b, 0x17, 0x63, 0x71, 0x70, 0x2d, 0x0d, 0xc5, 0xce, 0xcd, 0xb4, 0x26, 0xe0, -// 0x22, 0x3d, 0xd4, 0x04, 0x88, 0x51, 0x24, 0x34, 0x01, 0x9c, 0x94, 0x01, 0x47, 0x49, 0x86, -// 0xe3, 0x2f, 0x3b, 0x65, 0x5c, 0xcc, 0x0b, 0x8a, 0x00, 0x93, 0x26, 0x79, 0xbb, 0x18, 0xab, -// 0x94, 0x4b, 0x52, 0x99, -// ]); -// let primes = vec![ -// BigUint::from_bytes_le(&[ -// 0x87, 0x9c, 0xbd, 0x9c, 0xbf, 0xd5, 0xb7, 0xc2, 0x73, 0x16, 0x44, 0x3f, 0x67, 0x90, -// 0xaa, 0xab, 0xfe, 0x20, 0xac, 0x7d, 0xe9, 0xc4, 0xb9, 0xfb, 0x12, 0xab, 0x09, 0x35, -// 0xec, 0xf5, 0x9f, 0xe1, -// ]), -// BigUint::from_bytes_le(&[ -// 0xf7, 0xa2, 0xc1, 0x81, 0x63, 0xe1, 0x1c, 0x39, 0xe4, 0x7b, 0xbf, 0x56, 0xd5, 0x35, -// 0xc3, 0xd1, 0x11, 0xf9, 0x1f, 0x42, 0x4e, 0x3e, 0xe7, 0xc9, 0xa2, 0x3c, 0x98, 0x08, -// 0xaa, 0xf9, 0x6b, 0xdf, -// ]), -// ]; -// let client01_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); -// let peer_auth_client01 = PubKeyAuthenticator::new(client01_pub_key, client01_pri_key); -// let unicast = TransportManager::config_unicast() -// .max_links(2) -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client01.into()])); -// let client01_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client01_id) -// .unicast(unicast) -// .build(Arc::new(SHClientAuthenticator::default())) -// .unwrap(); - -// // Create the transport transport manager for the client 02 -// let client02_id = ZenohId::try_from([3]).unwrap(); - -// let n = BigUint::from_bytes_le(&[ -// 0xd1, 0x36, 0xcf, 0x94, 0xda, 0x04, 0x7e, 0x9f, 0x53, 0x39, 0xb8, 0x7b, 0x53, 0x3a, 0xe6, -// 0xa4, 0x0e, 0x6c, 0xf0, 0x92, 0x5d, 0xd9, 0x1d, 0x84, 0xc3, 0x10, 0xab, 0x8f, 0x7d, 0xe8, -// 0xf4, 0xff, 0x79, 0xae, 0x00, 0x25, 0xfc, 0xaf, 0x0c, 0x0f, 0x05, 0xc7, 0xa3, 0xfd, 0x31, -// 0x9a, 0xd3, 0x79, 0x0f, 0x44, 0xa6, 0x1c, 0x19, 0x61, 0xed, 0xb0, 0x27, 0x99, 0x53, 0x23, -// 0x50, 0xad, 0x67, 0xcf, -// ]); -// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); -// let client02_pub_key = RsaPublicKey::new(n, e).unwrap(); - -// let n = BigUint::from_bytes_le(&[ -// 0xd1, 0x36, 0xcf, 0x94, 0xda, 0x04, 0x7e, 0x9f, 0x53, 0x39, 0xb8, 0x7b, 0x53, 0x3a, 0xe6, -// 0xa4, 0x0e, 0x6c, 0xf0, 0x92, 0x5d, 0xd9, 0x1d, 0x84, 0xc3, 0x10, 0xab, 0x8f, 0x7d, 0xe8, -// 0xf4, 0xff, 0x79, 0xae, 0x00, 0x25, 0xfc, 0xaf, 0x0c, 0x0f, 0x05, 0xc7, 0xa3, 0xfd, 0x31, -// 0x9a, 0xd3, 0x79, 0x0f, 0x44, 0xa6, 0x1c, 0x19, 0x61, 0xed, 0xb0, 0x27, 0x99, 0x53, 0x23, -// 0x50, 0xad, 0x67, 0xcf, -// ]); -// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); -// let d = BigUint::from_bytes_le(&[ -// 0x01, 0xe4, 0xe9, 0x20, 0x20, 0x8c, 0x17, 0xd3, 0xea, 0xd0, 0x1f, 0xfa, 0x25, 0x5c, 0xaf, -// 0x5d, 0x19, 0xa4, 0x2a, 0xbc, 0x62, 0x5e, 0x2c, 0x63, 0x4f, 0x6e, 0x30, 0x07, 0x7c, 0x04, -// 0x72, 0xc9, 0x57, 0x3d, 0xe0, 0x59, 0x33, 0x8a, 0x36, 0x02, 0x5d, 0xa6, 0x81, 0x4e, 0x27, -// 0x82, 0xce, 0x95, 0x85, 0xd4, 0xa3, 0x9b, 0x5e, 0x2a, 0x04, 0xa8, 0x9d, 0x74, 0x25, 0x70, -// 0xf4, 0x37, 0x7d, 0x27, -// ]); -// let primes = vec![ -// BigUint::from_bytes_le(&[ -// 0x31, 0x55, 0x19, 0x90, 0xf4, 0xb5, 0x76, 0xed, 0xa4, 0x2e, 0x52, 0x37, 0x16, 0xd5, -// 0xef, 0x0b, 0xcb, 0x00, 0x10, 0xea, 0xff, 0x4f, 0xfe, 0x04, 0xf4, 0x44, 0xac, 0x24, -// 0xfc, 0x68, 0x02, 0xe4, -// ]), -// BigUint::from_bytes_le(&[ -// 0xa1, 0x13, 0xee, 0xe0, 0xe2, 0x98, 0x4e, 0x0b, 0x90, 0x11, 0x73, 0x87, 0xa2, 0x54, -// 0x8c, 0x5c, 0xe7, 0x03, 0x4b, 0xbf, 0x26, 0xfc, 0xb4, 0xba, 0xf9, 0xf9, 0x03, 0x84, -// 0xb9, 0xbc, 0xdd, 0xe8, -// ]), -// ]; -// let client02_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); - -// let peer_auth_client02 = PubKeyAuthenticator::new(client02_pub_key, client02_pri_key); -// let unicast = TransportManager::config_unicast() -// .max_links(2) -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client02.into()])); -// let client02_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client02_id) -// .unicast(unicast) -// .build(Arc::new(SHClientAuthenticator::default())) -// .unwrap(); - -// // Create the transport transport manager for the third client -// let client01_spoof_id = client01_id; - -// let n = BigUint::from_bytes_le(&[ -// 0x19, 0x01, 0x60, 0xf9, 0x1b, 0xd5, 0x2f, 0x1d, 0xb9, 0x16, 0xb5, 0xe4, 0xe3, 0x89, 0x7d, -// 0x94, 0xa7, 0x82, 0x2f, 0xa7, 0xab, 0xec, 0xf2, 0xc2, 0x31, 0xf4, 0xf9, 0x66, 0x97, 0x6a, -// 0x98, 0xf7, 0x02, 0x00, 0x0f, 0x51, 0xe4, 0xe4, 0x19, 0x29, 0xb6, 0x95, 0x1b, 0xb1, 0x2e, -// 0x86, 0x2b, 0x99, 0x7f, 0x4e, 0x5a, 0x84, 0x44, 0xf3, 0xaa, 0xb3, 0xbf, 0x6c, 0xb5, 0xd4, -// 0x05, 0x37, 0x33, 0xc2, -// ]); -// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); -// let client01_spoof_pub_key = RsaPublicKey::new(n, e).unwrap(); - -// let n = BigUint::from_bytes_le(&[ -// 0x19, 0x01, 0x60, 0xf9, 0x1b, 0xd5, 0x2f, 0x1d, 0xb9, 0x16, 0xb5, 0xe4, 0xe3, 0x89, 0x7d, -// 0x94, 0xa7, 0x82, 0x2f, 0xa7, 0xab, 0xec, 0xf2, 0xc2, 0x31, 0xf4, 0xf9, 0x66, 0x97, 0x6a, -// 0x98, 0xf7, 0x02, 0x00, 0x0f, 0x51, 0xe4, 0xe4, 0x19, 0x29, 0xb6, 0x95, 0x1b, 0xb1, 0x2e, -// 0x86, 0x2b, 0x99, 0x7f, 0x4e, 0x5a, 0x84, 0x44, 0xf3, 0xaa, 0xb3, 0xbf, 0x6c, 0xb5, 0xd4, -// 0x05, 0x37, 0x33, 0xc2, -// ]); -// let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); -// let d = BigUint::from_bytes_le(&[ -// 0x01, 0xef, 0x77, 0x79, 0x99, 0xf7, 0xa7, 0x14, 0x0f, 0x61, 0xc6, 0xca, 0x3e, 0x14, 0xfa, -// 0x52, 0x6a, 0xbc, 0x94, 0x2a, 0xb1, 0x7e, 0x3a, 0x57, 0xd1, 0x85, 0x62, 0xa4, 0xd0, 0xf5, -// 0x40, 0x6a, 0x0f, 0xb3, 0x59, 0xec, 0x7d, 0xbd, 0xac, 0xcf, 0x28, 0x5c, 0xa1, 0x11, 0x40, -// 0xfa, 0x84, 0x4a, 0x54, 0xd1, 0x7f, 0x44, 0xc8, 0xce, 0xb2, 0x21, 0x63, 0xd0, 0xc4, 0x02, -// 0x55, 0x0a, 0x3a, 0x12, -// ]); -// let primes = vec![ -// BigUint::from_bytes_le(&[ -// 0xe1, 0x93, 0xce, 0x13, 0x6e, 0xf4, 0xb9, 0xb8, 0xea, 0xdc, 0xc9, 0x83, 0xcb, 0xe5, -// 0x7d, 0x2b, 0x2f, 0x4e, 0xef, 0x75, 0x1f, 0x10, 0x4b, 0x6e, 0xbe, 0xf1, 0xc3, 0x61, -// 0x33, 0x71, 0x65, 0xce, -// ]), -// BigUint::from_bytes_le(&[ -// 0x39, 0x94, 0x43, 0x4f, 0xd3, 0x74, 0x27, 0x94, 0xc7, 0x1b, 0x0f, 0xbb, 0x2b, 0xd4, -// 0x9b, 0xf9, 0xe7, 0xfc, 0x47, 0x63, 0x44, 0x28, 0xa7, 0x81, 0x20, 0x91, 0x8e, 0xcf, -// 0x5d, 0x66, 0xdf, 0xf0, -// ]), -// ]; -// let client01_spoof_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); - -// let peer_auth_client01_spoof = -// PubKeyAuthenticator::new(client01_spoof_pub_key, client01_spoof_pri_key); -// let unicast = TransportManager::config_unicast() -// .max_links(2) -// .peer_authenticator(HashSet::from_iter(vec![peer_auth_client01_spoof.into()])); -// let client01_spoof_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client01_spoof_id) -// .unicast(unicast) -// .build(Arc::new(SHClientAuthenticator::default())) -// .unwrap(); - -// /* [1] */ -// println!("\nTransport Authenticator PubKey [1a1]"); -// // Add the locator on the router -// ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); -// println!("Transport Authenticator PubKey [1a2]"); -// let locators = router_manager.get_listeners(); -// println!("Transport Authenticator PubKey [1a2]: {locators:?}"); -// assert_eq!(locators.len(), 1); - -// /* [2a] */ -// // Open a first transport from client01 to the router -// // -> This should be accepted -// println!("Transport Authenticator PubKey [2a1]"); -// let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); -// assert_eq!(c_ses1.get_links().unwrap().len(), 1); - -// /* [2b] */ -// // Open a second transport from client01 to the router -// // -> This should be accepted -// println!("Transport Authenticator PubKey [2b1]"); -// let c_ses1_tmp = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); -// assert_eq!(c_ses1, c_ses1_tmp); -// assert_eq!(c_ses1.get_links().unwrap().len(), 2); - -// /* [2c] */ -// // Open a third transport from client01 to the router -// // -> This should be rejected -// println!("Transport Authenticator PubKey [2c1]"); -// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator PubKey [2c2]: {res:?}"); -// assert!(res.is_err()); -// assert_eq!(c_ses1.get_links().unwrap().len(), 2); - -// /* [2d] */ -// // Close the session -// println!("Transport Authenticator PubKey [2d1]"); -// ztimeout!(c_ses1.close()).unwrap(); - -// ztimeout!(async { -// while !router_manager.get_transports().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// /* [3a] */ -// // Open a first transport from client02 to the router -// // -> This should be accepted -// println!("Transport Authenticator PubKey [3a1]"); -// let c_ses2 = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); -// assert_eq!(c_ses2.get_links().unwrap().len(), 1); - -// /* [3b] */ -// // Open a second transport from client02 to the router -// // -> This should be accepted -// println!("Transport Authenticator PubKey [3b1]"); -// let c_ses2_tmp = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); -// assert_eq!(c_ses2, c_ses2_tmp); -// assert_eq!(c_ses2.get_links().unwrap().len(), 2); - -// /* [3c] */ -// // Open a third transport from client02 to the router -// // -> This should be rejected -// println!("Transport Authenticator PubKey [3c1]"); -// let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator PubKey [3c2]: {res:?}"); -// assert!(res.is_err()); -// assert_eq!(c_ses2.get_links().unwrap().len(), 2); - -// /* [3d] */ -// // Close the session -// println!("Transport Authenticator PubKey [3d1]"); -// let res = ztimeout!(c_ses2.close()); -// println!("Transport Authenticator PubKey [3d2]: {res:?}"); -// assert!(res.is_ok()); - -// ztimeout!(async { -// while !router_manager.get_transports().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// /* [4a] */ -// // Open a first transport from client01_spoof to the router -// // -> This should be accepted -// println!("Transport Authenticator PubKey [4a1]"); -// let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator PubKey [4a2]: {res:?}"); -// assert!(res.is_ok()); -// let c_ses1_spoof = res.unwrap(); -// assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 1); - -// /* [4b] */ -// // Open a second transport from client01_spoof to the router -// // -> This should be accepted -// println!("Transport Authenticator PubKey [4b1]"); -// let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator PubKey [4b2]: {res:?}"); -// assert!(res.is_ok()); -// assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); - -// /* [4c] */ -// // Open a third transport from client02 to the router -// // -> This should be rejected -// println!("Transport Authenticator PubKey [41]"); -// let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator PubKey [4c2]: {res:?}"); -// assert!(res.is_err()); -// assert_eq!(c_ses1_spoof.get_links().unwrap().len(), 2); - -// /* [4d] */ -// // Close the session -// println!("Transport Authenticator PubKey [4d1]"); -// let res = ztimeout!(c_ses1_spoof.close()); -// println!("Transport Authenticator PubKey [4d2]: {res:?}"); -// assert!(res.is_ok()); - -// ztimeout!(async { -// while !router_manager.get_transports().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// /* [5a] */ -// // Open a first transport from client01 to the router -// // -> This should be accepted -// println!("Transport Authenticator PubKey [5a1]"); -// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator PubKey [5a2]: {res:?}"); -// assert!(res.is_ok()); -// let c_ses1 = res.unwrap(); -// assert_eq!(c_ses1.get_links().unwrap().len(), 1); - -// /* [5b] */ -// // Open a spoof transport from client01_spoof to the router -// // -> This should be rejected. Spoofing detected. -// println!("Transport Authenticator PubKey [5b1]"); -// let res = ztimeout!(client01_spoof_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator PubKey [5b2]: {res:?}"); -// assert!(res.is_err()); - -// /* [5c] */ -// // Open a second transport from client01 to the router -// // -> This should be accepted -// println!("Transport Authenticator PubKey [5a1]"); -// let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); -// println!("Transport Authenticator PubKey [5a2]: {res:?}"); -// assert!(res.is_ok()); -// let c_ses1 = res.unwrap(); -// assert_eq!(c_ses1.get_links().unwrap().len(), 2); - -// /* [5d] */ -// // Close the session -// println!("Transport Authenticator PubKey [5d1]"); -// let res = ztimeout!(c_ses1.close()); -// println!("Transport Authenticator PubKey [5d2]: {res:?}"); -// assert!(res.is_ok()); - -// ztimeout!(async { -// while !router_manager.get_transports().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// /* [6] */ -// // Perform clean up of the open locators -// println!("Transport Authenticator UserPassword [6a1]"); -// let res = ztimeout!(router_manager.del_listener(endpoint)); -// println!("Transport Authenticator UserPassword [6a2]: {res:?}"); -// assert!(res.is_ok()); - -// ztimeout!(async { -// while !router_manager.get_listeners().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// ztimeout!(router_manager.close()); -// ztimeout!(client01_manager.close()); -// ztimeout!(client01_spoof_manager.close()); - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } +#[cfg(feature = "auth_pubkey")] +async fn auth_pubkey(endpoint: &EndPoint) { + use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; + use std::convert::TryFrom; + use zenoh_transport::unicast::establishment::ext::auth::AuthPubKey; + use zenoh_transport::TransportManager; + + // Create the transport transport manager for the client 01 + let client01_id = ZenohId::try_from([2]).unwrap(); + + let n = BigUint::from_bytes_le(&[ + 0x41, 0x74, 0xc6, 0x40, 0x18, 0x63, 0xbd, 0x59, 0xe6, 0x0d, 0xe9, 0x23, 0x3e, 0x95, 0xca, + 0xb4, 0x5d, 0x17, 0x3d, 0x14, 0xdd, 0xbb, 0x16, 0x4a, 0x49, 0xeb, 0x43, 0x27, 0x79, 0x3e, + 0x75, 0x67, 0xd6, 0xf6, 0x7f, 0xe7, 0xbf, 0xb5, 0x1d, 0xf6, 0x27, 0x80, 0xca, 0x26, 0x35, + 0xa2, 0xc5, 0x4c, 0x96, 0x50, 0xaa, 0x9f, 0xf4, 0x47, 0xbe, 0x06, 0x9c, 0xd1, 0xec, 0xfd, + 0x1e, 0x81, 0xe9, 0xc4, + ]); + let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); + let client01_pub_key = RsaPublicKey::new(n, e).unwrap(); + + let n = BigUint::from_bytes_le(&[ + 0x41, 0x74, 0xc6, 0x40, 0x18, 0x63, 0xbd, 0x59, 0xe6, 0x0d, 0xe9, 0x23, 0x3e, 0x95, 0xca, + 0xb4, 0x5d, 0x17, 0x3d, 0x14, 0xdd, 0xbb, 0x16, 0x4a, 0x49, 0xeb, 0x43, 0x27, 0x79, 0x3e, + 0x75, 0x67, 0xd6, 0xf6, 0x7f, 0xe7, 0xbf, 0xb5, 0x1d, 0xf6, 0x27, 0x80, 0xca, 0x26, 0x35, + 0xa2, 0xc5, 0x4c, 0x96, 0x50, 0xaa, 0x9f, 0xf4, 0x47, 0xbe, 0x06, 0x9c, 0xd1, 0xec, 0xfd, + 0x1e, 0x81, 0xe9, 0xc4, + ]); + let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); + let d = BigUint::from_bytes_le(&[ + 0x15, 0xe1, 0x93, 0xda, 0x75, 0xcb, 0x76, 0x40, 0xce, 0x70, 0x6f, 0x0f, 0x62, 0xe1, 0x58, + 0xa5, 0x53, 0x7b, 0x17, 0x63, 0x71, 0x70, 0x2d, 0x0d, 0xc5, 0xce, 0xcd, 0xb4, 0x26, 0xe0, + 0x22, 0x3d, 0xd4, 0x04, 0x88, 0x51, 0x24, 0x34, 0x01, 0x9c, 0x94, 0x01, 0x47, 0x49, 0x86, + 0xe3, 0x2f, 0x3b, 0x65, 0x5c, 0xcc, 0x0b, 0x8a, 0x00, 0x93, 0x26, 0x79, 0xbb, 0x18, 0xab, + 0x94, 0x4b, 0x52, 0x99, + ]); + let primes = vec![ + BigUint::from_bytes_le(&[ + 0x87, 0x9c, 0xbd, 0x9c, 0xbf, 0xd5, 0xb7, 0xc2, 0x73, 0x16, 0x44, 0x3f, 0x67, 0x90, + 0xaa, 0xab, 0xfe, 0x20, 0xac, 0x7d, 0xe9, 0xc4, 0xb9, 0xfb, 0x12, 0xab, 0x09, 0x35, + 0xec, 0xf5, 0x9f, 0xe1, + ]), + BigUint::from_bytes_le(&[ + 0xf7, 0xa2, 0xc1, 0x81, 0x63, 0xe1, 0x1c, 0x39, 0xe4, 0x7b, 0xbf, 0x56, 0xd5, 0x35, + 0xc3, 0xd1, 0x11, 0xf9, 0x1f, 0x42, 0x4e, 0x3e, 0xe7, 0xc9, 0xa2, 0x3c, 0x98, 0x08, + 0xaa, 0xf9, 0x6b, 0xdf, + ]), + ]; + let client01_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); + let mut auth = Auth::empty(); + auth.set_pubkey(Some(AuthPubKey::new( + client01_pub_key.clone().into(), + client01_pri_key.into(), + ))); + let unicast = TransportManager::config_unicast().authenticator(auth); + let client01_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client01_id) + .unicast(unicast) + .build(Arc::new(SHClientAuthenticator::default())) + .unwrap(); + + // Create the transport transport manager for the client 02 + let client02_id = ZenohId::try_from([3]).unwrap(); + + let n = BigUint::from_bytes_le(&[ + 0xd1, 0x36, 0xcf, 0x94, 0xda, 0x04, 0x7e, 0x9f, 0x53, 0x39, 0xb8, 0x7b, 0x53, 0x3a, 0xe6, + 0xa4, 0x0e, 0x6c, 0xf0, 0x92, 0x5d, 0xd9, 0x1d, 0x84, 0xc3, 0x10, 0xab, 0x8f, 0x7d, 0xe8, + 0xf4, 0xff, 0x79, 0xae, 0x00, 0x25, 0xfc, 0xaf, 0x0c, 0x0f, 0x05, 0xc7, 0xa3, 0xfd, 0x31, + 0x9a, 0xd3, 0x79, 0x0f, 0x44, 0xa6, 0x1c, 0x19, 0x61, 0xed, 0xb0, 0x27, 0x99, 0x53, 0x23, + 0x50, 0xad, 0x67, 0xcf, + ]); + let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); + let client02_pub_key = RsaPublicKey::new(n, e).unwrap(); + + let n = BigUint::from_bytes_le(&[ + 0xd1, 0x36, 0xcf, 0x94, 0xda, 0x04, 0x7e, 0x9f, 0x53, 0x39, 0xb8, 0x7b, 0x53, 0x3a, 0xe6, + 0xa4, 0x0e, 0x6c, 0xf0, 0x92, 0x5d, 0xd9, 0x1d, 0x84, 0xc3, 0x10, 0xab, 0x8f, 0x7d, 0xe8, + 0xf4, 0xff, 0x79, 0xae, 0x00, 0x25, 0xfc, 0xaf, 0x0c, 0x0f, 0x05, 0xc7, 0xa3, 0xfd, 0x31, + 0x9a, 0xd3, 0x79, 0x0f, 0x44, 0xa6, 0x1c, 0x19, 0x61, 0xed, 0xb0, 0x27, 0x99, 0x53, 0x23, + 0x50, 0xad, 0x67, 0xcf, + ]); + let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); + let d = BigUint::from_bytes_le(&[ + 0x01, 0xe4, 0xe9, 0x20, 0x20, 0x8c, 0x17, 0xd3, 0xea, 0xd0, 0x1f, 0xfa, 0x25, 0x5c, 0xaf, + 0x5d, 0x19, 0xa4, 0x2a, 0xbc, 0x62, 0x5e, 0x2c, 0x63, 0x4f, 0x6e, 0x30, 0x07, 0x7c, 0x04, + 0x72, 0xc9, 0x57, 0x3d, 0xe0, 0x59, 0x33, 0x8a, 0x36, 0x02, 0x5d, 0xa6, 0x81, 0x4e, 0x27, + 0x82, 0xce, 0x95, 0x85, 0xd4, 0xa3, 0x9b, 0x5e, 0x2a, 0x04, 0xa8, 0x9d, 0x74, 0x25, 0x70, + 0xf4, 0x37, 0x7d, 0x27, + ]); + let primes = vec![ + BigUint::from_bytes_le(&[ + 0x31, 0x55, 0x19, 0x90, 0xf4, 0xb5, 0x76, 0xed, 0xa4, 0x2e, 0x52, 0x37, 0x16, 0xd5, + 0xef, 0x0b, 0xcb, 0x00, 0x10, 0xea, 0xff, 0x4f, 0xfe, 0x04, 0xf4, 0x44, 0xac, 0x24, + 0xfc, 0x68, 0x02, 0xe4, + ]), + BigUint::from_bytes_le(&[ + 0xa1, 0x13, 0xee, 0xe0, 0xe2, 0x98, 0x4e, 0x0b, 0x90, 0x11, 0x73, 0x87, 0xa2, 0x54, + 0x8c, 0x5c, 0xe7, 0x03, 0x4b, 0xbf, 0x26, 0xfc, 0xb4, 0xba, 0xf9, 0xf9, 0x03, 0x84, + 0xb9, 0xbc, 0xdd, 0xe8, + ]), + ]; + let client02_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); + let mut auth = Auth::empty(); + auth.set_pubkey(Some(AuthPubKey::new( + client02_pub_key.clone().into(), + client02_pri_key.clone().into(), + ))); + let unicast = TransportManager::config_unicast().authenticator(auth); + let client02_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client02_id) + .unicast(unicast) + .build(Arc::new(SHClientAuthenticator::default())) + .unwrap(); + + // Create the transport transport manager for the client 03 with the same key as client 02 + let client03_id = ZenohId::try_from([4]).unwrap(); + let mut auth = Auth::empty(); + auth.set_pubkey(Some(AuthPubKey::new( + client02_pub_key.clone().into(), + client02_pri_key.clone().into(), + ))); + let unicast = TransportManager::config_unicast().authenticator(auth); + let client03_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client03_id) + .unicast(unicast) + .build(Arc::new(SHClientAuthenticator::default())) + .unwrap(); + + // Create the router transport manager + let router_id = ZenohId::try_from([1]).unwrap(); + let router_handler = Arc::new(SHRouterAuthenticator::new()); + let n = BigUint::from_bytes_le(&[ + 0x31, 0xd1, 0xfc, 0x7e, 0x70, 0x5f, 0xd7, 0xe3, 0xcc, 0xa4, 0xca, 0xcb, 0x38, 0x84, 0x2f, + 0xf5, 0x88, 0xaa, 0x4b, 0xbc, 0x2f, 0x74, 0x59, 0x49, 0xa9, 0xb9, 0x1a, 0x4d, 0x1c, 0x93, + 0xbc, 0xc7, 0x02, 0xd0, 0xe0, 0x0f, 0xa7, 0x68, 0xeb, 0xef, 0x9b, 0xf9, 0x4f, 0xdc, 0xe3, + 0x40, 0x5a, 0x3c, 0x8f, 0x20, 0xf4, 0x2c, 0x90, 0x1c, 0x70, 0x56, 0x9b, 0xae, 0x44, 0x17, + 0xca, 0x85, 0x60, 0xb5, + ]); + let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); + let router_pub_key = RsaPublicKey::new(n, e).unwrap(); + + let n = BigUint::from_bytes_le(&[ + 0x31, 0xd1, 0xfc, 0x7e, 0x70, 0x5f, 0xd7, 0xe3, 0xcc, 0xa4, 0xca, 0xcb, 0x38, 0x84, 0x2f, + 0xf5, 0x88, 0xaa, 0x4b, 0xbc, 0x2f, 0x74, 0x59, 0x49, 0xa9, 0xb9, 0x1a, 0x4d, 0x1c, 0x93, + 0xbc, 0xc7, 0x02, 0xd0, 0xe0, 0x0f, 0xa7, 0x68, 0xeb, 0xef, 0x9b, 0xf9, 0x4f, 0xdc, 0xe3, + 0x40, 0x5a, 0x3c, 0x8f, 0x20, 0xf4, 0x2c, 0x90, 0x1c, 0x70, 0x56, 0x9b, 0xae, 0x44, 0x17, + 0xca, 0x85, 0x60, 0xb5, + ]); + let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); + let d = BigUint::from_bytes_le(&[ + 0xc1, 0xd1, 0xc1, 0x0f, 0xbe, 0xa7, 0xe6, 0x18, 0x98, 0x3c, 0xf8, 0x26, 0x74, 0xc0, 0xc7, + 0xef, 0xf9, 0x38, 0x95, 0x75, 0x40, 0x45, 0xd4, 0x0d, 0x27, 0xec, 0x4c, 0xcd, 0x81, 0xf9, + 0xf4, 0x69, 0x36, 0x99, 0x95, 0x97, 0xd0, 0xc8, 0x43, 0xac, 0xbb, 0x3e, 0x8f, 0xfb, 0x97, + 0x53, 0xdb, 0x92, 0x12, 0xc5, 0xc0, 0x50, 0x83, 0xb2, 0x04, 0x25, 0x79, 0xeb, 0xa7, 0x32, + 0x84, 0xbb, 0xc6, 0x35, + ]); + let primes = vec![ + BigUint::from_bytes_le(&[ + 0xb9, 0x17, 0xd3, 0x45, 0x0a, 0x8e, 0xf7, 0x41, 0xaf, 0x75, 0xe3, 0x7f, 0xe9, 0x3c, + 0x10, 0x28, 0x24, 0x0a, 0x95, 0x32, 0xc0, 0xcb, 0x23, 0x60, 0x6e, 0x2d, 0xb8, 0x2e, + 0x96, 0x78, 0x21, 0xdf, + ]), + BigUint::from_bytes_le(&[ + 0x39, 0x51, 0xd3, 0xf3, 0xfe, 0xd1, 0x81, 0xd3, 0xc3, 0x2b, 0x49, 0x65, 0x3a, 0x44, + 0x41, 0x31, 0xa7, 0x38, 0x8b, 0xd9, 0x18, 0xc7, 0x41, 0x8c, 0x86, 0x0b, 0x65, 0x2d, + 0x18, 0x78, 0x18, 0xd0, + ]), + ]; + let router_pri_key = RsaPrivateKey::from_components(n, e, d, primes).unwrap(); + let mut auth_pubkey = AuthPubKey::new(router_pub_key.into(), router_pri_key.into()); + auth_pubkey + .add_pubkey(client01_pub_key.into()) + .await + .unwrap(); + let mut auth = Auth::empty(); + auth.set_pubkey(Some(auth_pubkey)); + let unicast = TransportManager::config_unicast().authenticator(auth); + let router_manager = TransportManager::builder() + .whatami(WhatAmI::Router) + .zid(router_id) + .unicast(unicast) + .build(router_handler.clone()) + .unwrap(); + + /* [1] */ + println!("\nTransport Authenticator PubKey [1a1]"); + // Add the locator on the router + ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); + println!("Transport Authenticator PubKey [1a2]"); + let locators = router_manager.get_listeners(); + println!("Transport Authenticator PubKey [1a2]: {locators:?}"); + assert_eq!(locators.len(), 1); + + /* [2a] */ + // Open a first transport from client01 to the router + // -> This should be accepted + println!("Transport Authenticator PubKey [2a1]"); + let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); + assert_eq!(c_ses1.get_links().unwrap().len(), 1); + + /* [2b] */ + // Open a first transport from client02 to the router + // -> This should be rejected + println!("Transport Authenticator PubKey [2b1]"); + let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + println!("Transport Authenticator PubKey [2b2]: {res:?}"); + assert!(res.is_err()); + + /* [2c] */ + // Open a first transport from client03 to the router + // -> This should be rejected + println!("Transport Authenticator PubKey [2c1]"); + let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); + println!("Transport Authenticator PubKey [2c2]: {res:?}"); + assert!(res.is_err()); + + // Add client02 pubkey to the router + let router_auth_handle = router_manager.get_auth_handle_unicast(); + zasyncwrite!(router_auth_handle) + .get_pubkey_mut() + .unwrap() + .add_pubkey(client02_pub_key.into()) + .await + .unwrap(); + + /* [3b] */ + // Open a first transport from client02 to the router + // -> This should be accepted + println!("Transport Authenticator PubKey [3a1]"); + let c_ses2 = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); + assert_eq!(c_ses2.get_links().unwrap().len(), 1); + + // Open a first transport from client03 to the router + // -> This should be accepted + println!("Transport Authenticator PubKey [3b1]"); + let c_ses3 = ztimeout!(client03_manager.open_transport(endpoint.clone())).unwrap(); + assert_eq!(c_ses3.get_links().unwrap().len(), 1); + + // /* [4a] */ + // Close the sessions + println!("Transport Authenticator PubKey [4a1]"); + let res = ztimeout!(c_ses1.close()); + println!("Transport Authenticator PubKey [4a2]: {res:?}"); + assert!(res.is_ok()); + + println!("Transport Authenticator PubKey [4b1]"); + let res = ztimeout!(c_ses2.close()); + println!("Transport Authenticator PubKey [4b2]: {res:?}"); + assert!(res.is_ok()); + + println!("Transport Authenticator PubKey [4c1]"); + let res = ztimeout!(c_ses3.close()); + println!("Transport Authenticator PubKey [4c2]: {res:?}"); + assert!(res.is_ok()); + + ztimeout!(async { + while !router_manager.get_transports().is_empty() { + task::sleep(SLEEP).await; + } + }); + + /* [5] */ + // Perform clean up of the open locators + println!("Transport Authenticator PubKey [5a1]"); + let res = ztimeout!(router_manager.del_listener(endpoint)); + println!("Transport Authenticator PubKey [5a2]: {res:?}"); + assert!(res.is_ok()); + + ztimeout!(async { + while !router_manager.get_listeners().is_empty() { + task::sleep(SLEEP).await; + } + }); + + ztimeout!(client01_manager.close()); + ztimeout!(client02_manager.close()); + ztimeout!(client03_manager.close()); + ztimeout!(router_manager.close()); + + // Wait a little bit + task::sleep(SLEEP).await; +} #[cfg(feature = "auth_usrpwd")] async fn auth_usrpwd(endpoint: &EndPoint) { use std::convert::TryFrom; - use zenoh_transport::establishment::ext::auth::usrpwd::AuthUsrPwd; + use zenoh_transport::establishment::ext::auth::AuthUsrPwd; use zenoh_transport::TransportManager; /* [CLIENT] */ @@ -685,8 +565,8 @@ async fn auth_usrpwd(endpoint: &EndPoint) { } async fn run(endpoint: &EndPoint) { - // #[cfg(feature = "auth_pubkey")] - // authenticator_multilink(endpoint).await; + #[cfg(feature = "auth_pubkey")] + auth_pubkey(endpoint).await; #[cfg(feature = "auth_usrpwd")] auth_usrpwd(endpoint).await; } From 58ac1ec8bee231ea692289caf75dd89886cade2e Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 10 Mar 2023 15:06:54 +0100 Subject: [PATCH 068/203] Fix clippy warnings --- commons/zenoh-protocol/src/core/mod.rs | 10 ---------- commons/zenoh-protocol/src/zenoh/data.rs | 9 ++------- commons/zenoh-protocol/src/zenoh/declare.rs | 11 ++--------- commons/zenoh-protocol/src/zenoh/query.rs | 9 ++------- 4 files changed, 6 insertions(+), 33 deletions(-) diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index 01c0f01eef..3e33242806 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -480,13 +480,3 @@ pub enum QueryTarget { #[cfg(feature = "complete_n")] Complete(ZInt), } - -pub(crate) fn split_once(s: &str, c: char) -> (&str, &str) { - match s.find(c) { - Some(index) => { - let (l, r) = s.split_at(index); - (l, &r[1..]) - } - None => (s, ""), - } -} diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs index 383cdac30e..620381e35d 100644 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ b/commons/zenoh-protocol/src/zenoh/data.rs @@ -17,20 +17,15 @@ use zenoh_buffers::ZBuf; /// The kind of a `Sample`. #[repr(u8)] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] pub enum SampleKind { /// if the `Sample` was issued by a `put` operation. + #[default] Put = 0, /// if the `Sample` was issued by a `delete` operation. Delete = 1, } -impl Default for SampleKind { - fn default() -> Self { - SampleKind::Put - } -} - impl fmt::Display for SampleKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/commons/zenoh-protocol/src/zenoh/declare.rs b/commons/zenoh-protocol/src/zenoh/declare.rs index e604545d70..1f8e7bc406 100644 --- a/commons/zenoh-protocol/src/zenoh/declare.rs +++ b/commons/zenoh-protocol/src/zenoh/declare.rs @@ -182,20 +182,13 @@ impl ForgetPublisher { } /// The subscription mode. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] #[repr(u8)] pub enum SubMode { + #[default] Push, Pull, } - -impl Default for SubMode { - #[inline] - fn default() -> Self { - SubMode::Push - } -} - #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct SubInfo { pub reliability: Reliability, diff --git a/commons/zenoh-protocol/src/zenoh/query.rs b/commons/zenoh-protocol/src/zenoh/query.rs index e3014d81d8..acd2f959b3 100644 --- a/commons/zenoh-protocol/src/zenoh/query.rs +++ b/commons/zenoh-protocol/src/zenoh/query.rs @@ -36,8 +36,9 @@ pub enum ConsolidationMode { } /// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub enum QueryTarget { + #[default] BestMatching, All, AllComplete, @@ -45,12 +46,6 @@ pub enum QueryTarget { Complete(ZInt), } -impl Default for QueryTarget { - fn default() -> Self { - QueryTarget::BestMatching - } -} - /// # QueryBody /// /// QueryBody data structure is optionally included in Query messages From 226d29e9cd8c2eb3ede3cfb706437252ddb13609 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 10 Mar 2023 15:11:56 +0100 Subject: [PATCH 069/203] Enable CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse in CI --- .github/workflows/ci.yml | 12 ++++++++++++ .github/workflows/release.yml | 30 ++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27e03c14e6..0f1490a9ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,18 +43,24 @@ jobs: with: command: fmt args: -- --check + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - name: Clippy uses: actions-rs/cargo@v1 with: command: clippy args: --all-targets -- -D warnings + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - name: Clippy unstable uses: actions-rs/cargo@v1 with: command: clippy args: --all-targets --features unstable -- -D warnings + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse test: name: Run tests on ${{ matrix.os }} @@ -82,6 +88,8 @@ jobs: with: command: build args: --verbose --all-targets + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - name: Install nextest run: cargo install cargo-nextest --locked @@ -92,6 +100,7 @@ jobs: command: nextest args: run env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse ASYNC_STD_THREAD_COUNT: 4 - name: Run doctests @@ -100,6 +109,7 @@ jobs: command: test args: --doc env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse ASYNC_STD_THREAD_COUNT: 4 nostd: @@ -124,3 +134,5 @@ jobs: with: command: check args: --bin nostd_check --target x86_64-unknown-none --manifest-path ci/nostd-check/Cargo.toml + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea13fc363c..f4d3519643 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,21 +30,31 @@ jobs: uses: actions-rs/toolchain@v1 with: components: rustfmt, clippy + - name: Code format check uses: actions-rs/cargo@v1 with: command: fmt args: -- --check + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + - name: Clippy check uses: actions-rs/cargo@v1 with: command: clippy args: --all-targets -- -D warnings + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + - name: Clippy unstable check uses: actions-rs/cargo@v1 with: command: clippy args: --all-targets --features unstable -- -D warnings + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + - name: Environment setup id: env shell: bash @@ -95,21 +105,28 @@ jobs: - uses: actions/checkout@v2 - name: Install Rust toolchain uses: actions-rs/toolchain@v1 + - name: Install nextest run: cargo install cargo-nextest --locked + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + - name: Run tests uses: actions-rs/cargo@v1 with: command: nextest args: run --release --verbose env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse ASYNC_STD_THREAD_COUNT: 4 + - name: Run doctests uses: actions-rs/cargo@v1 with: command: test args: --doc env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse ASYNC_STD_THREAD_COUNT: 4 doc: @@ -121,12 +138,13 @@ jobs: - name: Install Rust toolchain uses: actions-rs/toolchain@v1 - name: generate doc - env: - RUSTDOCFLAGS: -Dwarnings uses: actions-rs/cargo@v1 with: command: doc args: --no-deps + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + RUSTDOCFLAGS: -Dwarnings builds: name: Build for ${{ matrix.job.target }} on ${{ matrix.job.os }} @@ -221,6 +239,8 @@ jobs: use-cross: ${{ matrix.job.use-cross }} command: build args: --release --bins --lib --target=${{ matrix.job.target }} + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - name: Debian package - zenohd if: contains(matrix.job.target, '-linux-gnu') @@ -228,6 +248,8 @@ jobs: with: command: deb args: --no-build --target=${{ matrix.job.target }} -p zenohd + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - name: Debian package - zenoh-plugin-storage-manager if: contains(matrix.job.target, '-linux-gnu') @@ -235,6 +257,8 @@ jobs: with: command: deb args: --no-build --target=${{ matrix.job.target }} -p zenoh-plugin-storage-manager + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - name: Debian package - zenoh-plugin-rest if: contains(matrix.job.target, '-linux-gnu') @@ -242,6 +266,8 @@ jobs: with: command: deb args: --no-build --target=${{ matrix.job.target }} -p zenoh-plugin-rest + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - name: Packaging id: package From 47fadc499260b1ef2d8f22980eb774a288494fa6 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 10 Mar 2023 15:13:02 +0100 Subject: [PATCH 070/203] Fix release CI.yaml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f4d3519643..4b4c179026 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -108,7 +108,7 @@ jobs: - name: Install nextest run: cargo install cargo-nextest --locked - env: + env: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - name: Run tests From 7021326ca8a46f85dba82da8c474521861ce58bd Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 10 Mar 2023 16:07:09 +0100 Subject: [PATCH 071/203] MultiLink extension definition --- commons/zenoh-codec/src/transport/init.rs | 106 +++++++++++------- commons/zenoh-codec/src/transport/open.rs | 90 ++++++++++----- commons/zenoh-protocol/src/transport/init.rs | 11 ++ commons/zenoh-protocol/src/transport/open.rs | 13 +++ .../src/unicast/establishment/accept.rs | 2 + .../src/unicast/establishment/open.rs | 2 + 6 files changed, 152 insertions(+), 72 deletions(-) diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index 7a2d792c37..42e0594f70 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -39,8 +39,11 @@ where if x.resolution != Resolution::default() || x.batch_size != u16::MAX { header |= flag::S; } - let has_extensions = x.ext_qos.is_some() || x.ext_shm.is_some() || x.ext_auth.is_some(); - if has_extensions { + let mut n_exts = (x.ext_qos.is_some() as u8) + + (x.ext_shm.is_some() as u8) + + (x.ext_auth.is_some() as u8) + + (x.ext_mlink.is_some() as u8); + if n_exts != 0 { header |= flag::Z; } self.write(&mut *writer, header)?; @@ -66,18 +69,20 @@ where // Extensions if let Some(qos) = x.ext_qos.as_ref() { - let has_ext = x.ext_shm.is_some() || x.ext_auth.is_some(); - self.write(&mut *writer, (qos, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (qos, n_exts != 0))?; } - if let Some(shm) = x.ext_shm.as_ref() { - let has_ext = x.ext_auth.is_some(); - self.write(&mut *writer, (shm, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (shm, n_exts != 0))?; } - if let Some(auth) = x.ext_auth.as_ref() { - let has_ext = false; - self.write(&mut *writer, (auth, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (auth, n_exts != 0))?; + } + if let Some(mlink) = x.ext_mlink.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (mlink, n_exts != 0))?; } Ok(()) @@ -131,9 +136,10 @@ where } // Extensions - let mut qos = None; - let mut shm = None; - let mut auth = None; + let mut ext_qos = None; + let mut ext_shm = None; + let mut ext_auth = None; + let mut ext_mlink = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -142,17 +148,22 @@ where match imsg::mid(ext) { ext::QoS::ID => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; - qos = Some(q); + ext_qos = Some(q); has_ext = ext; } ext::Shm::ID => { let (s, ext): (ext::Shm, bool) = eodec.read(&mut *reader)?; - shm = Some(s); + ext_shm = Some(s); has_ext = ext; } ext::Auth::ID => { let (a, ext): (ext::Auth, bool) = eodec.read(&mut *reader)?; - auth = Some(a); + ext_auth = Some(a); + has_ext = ext; + } + ext::MultiLink::ID => { + let (a, ext): (ext::MultiLink, bool) = eodec.read(&mut *reader)?; + ext_mlink = Some(a); has_ext = ext; } _ => { @@ -168,9 +179,10 @@ where zid, resolution, batch_size, - ext_qos: qos, - ext_shm: shm, - ext_auth: auth, + ext_qos, + ext_shm, + ext_auth, + ext_mlink, }) } } @@ -188,8 +200,11 @@ where if x.resolution != Resolution::default() || x.batch_size != u16::MAX { header |= flag::S; } - let has_extensions = x.ext_qos.is_some() || x.ext_shm.is_some() || x.ext_auth.is_some(); - if has_extensions { + let mut n_exts = (x.ext_qos.is_some() as u8) + + (x.ext_shm.is_some() as u8) + + (x.ext_auth.is_some() as u8) + + (x.ext_mlink.is_some() as u8); + if n_exts != 0 { header |= flag::Z; } self.write(&mut *writer, header)?; @@ -217,18 +232,20 @@ where // Extensions if let Some(qos) = x.ext_qos.as_ref() { - let has_ext = x.ext_shm.is_some() || x.ext_auth.is_some(); - self.write(&mut *writer, (qos, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (qos, n_exts != 0))?; } - if let Some(shm) = x.ext_shm.as_ref() { - let has_ext = x.ext_auth.is_some(); - self.write(&mut *writer, (shm, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (shm, n_exts != 0))?; } - if let Some(auth) = x.ext_auth.as_ref() { - let has_ext = false; - self.write(&mut *writer, (auth, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (auth, n_exts != 0))?; + } + if let Some(mlink) = x.ext_mlink.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (mlink, n_exts != 0))?; } Ok(()) @@ -284,28 +301,34 @@ where let cookie: ZSlice = self.codec.read(&mut *reader)?; // Extensions - let mut qos = None; - let mut shm = None; - let mut auth = None; + let mut ext_qos = None; + let mut ext_shm = None; + let mut ext_auth = None; + let mut ext_mlink = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { - ext::QOS => { + ext::QoS::ID => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; - qos = Some(q); + ext_qos = Some(q); has_ext = ext; } - ext::SHM => { + ext::Shm::ID => { let (s, ext): (ext::Shm, bool) = eodec.read(&mut *reader)?; - shm = Some(s); + ext_shm = Some(s); has_ext = ext; } - ext::AUTH => { + ext::Auth::ID => { let (a, ext): (ext::Auth, bool) = eodec.read(&mut *reader)?; - auth = Some(a); + ext_auth = Some(a); + has_ext = ext; + } + ext::MultiLink::ID => { + let (a, ext): (ext::MultiLink, bool) = eodec.read(&mut *reader)?; + ext_mlink = Some(a); has_ext = ext; } _ => { @@ -322,9 +345,10 @@ where resolution, batch_size, cookie, - ext_qos: qos, - ext_shm: shm, - ext_auth: auth, + ext_qos, + ext_shm, + ext_auth, + ext_mlink, }) } } diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index 7fdf93185e..5203c6d802 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -40,8 +40,11 @@ where if x.lease.as_millis() % 1_000 == 0 { header |= flag::T; } - let has_ext = x.ext_qos.is_some() || x.ext_shm.is_some() || x.ext_auth.is_some(); - if has_ext { + let mut n_exts = (x.ext_qos.is_some() as u8) + + (x.ext_shm.is_some() as u8) + + (x.ext_auth.is_some() as u8) + + (x.ext_mlink.is_some() as u8); + if n_exts != 0 { header |= flag::Z; } self.write(&mut *writer, header)?; @@ -57,16 +60,20 @@ where // Extensions if let Some(qos) = x.ext_qos.as_ref() { - let has_ext = x.ext_shm.is_some() || x.ext_auth.is_some(); - self.write(&mut *writer, (qos, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (qos, n_exts != 0))?; } if let Some(shm) = x.ext_shm.as_ref() { - let has_ext = x.ext_auth.is_some(); - self.write(&mut *writer, (shm, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (shm, n_exts != 0))?; } if let Some(auth) = x.ext_auth.as_ref() { - let has_ext = false; - self.write(&mut *writer, (auth, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (auth, n_exts != 0))?; + } + if let Some(mlink) = x.ext_mlink.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (mlink, n_exts != 0))?; } Ok(()) @@ -108,28 +115,34 @@ where let cookie: ZSlice = self.codec.read(&mut *reader)?; // Extensions - let mut qos = None; - let mut shm = None; - let mut auth = None; + let mut ext_qos = None; + let mut ext_shm = None; + let mut ext_auth = None; + let mut ext_mlink = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { - ext::QOS => { + ext::QoS::ID => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; - qos = Some(q); + ext_qos = Some(q); has_ext = ext; } - ext::SHM => { + ext::Shm::ID => { let (s, ext): (ext::Shm, bool) = eodec.read(&mut *reader)?; - shm = Some(s); + ext_shm = Some(s); has_ext = ext; } - ext::AUTH => { + ext::Auth::ID => { let (a, ext): (ext::Auth, bool) = eodec.read(&mut *reader)?; - auth = Some(a); + ext_auth = Some(a); + has_ext = ext; + } + ext::MultiLink::ID => { + let (a, ext): (ext::MultiLink, bool) = eodec.read(&mut *reader)?; + ext_mlink = Some(a); has_ext = ext; } _ => { @@ -143,9 +156,10 @@ where lease, initial_sn, cookie, - ext_qos: qos, - ext_shm: shm, - ext_auth: auth, + ext_qos, + ext_shm, + ext_auth, + ext_mlink, }) } } @@ -165,8 +179,11 @@ where if x.lease.subsec_nanos() == 0 { header |= flag::T; } - let has_extensions = x.ext_qos.is_some() || x.ext_shm.is_some() || x.ext_auth.is_some(); - if has_extensions { + let mut n_exts = (x.ext_qos.is_some() as u8) + + (x.ext_shm.is_some() as u8) + + (x.ext_auth.is_some() as u8) + + (x.ext_mlink.is_some() as u8); + if n_exts != 0 { header |= flag::Z; } self.write(&mut *writer, header)?; @@ -181,16 +198,20 @@ where // Extensions if let Some(qos) = x.ext_qos.as_ref() { - let has_ext = x.ext_shm.is_some() || x.ext_auth.is_some(); - self.write(&mut *writer, (qos, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (qos, n_exts != 0))?; } if let Some(shm) = x.ext_shm.as_ref() { - let has_ext = x.ext_auth.is_some(); - self.write(&mut *writer, (shm, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (shm, n_exts != 0))?; } if let Some(auth) = x.ext_auth.as_ref() { - let has_ext = false; - self.write(&mut *writer, (auth, has_ext))?; + n_exts -= 1; + self.write(&mut *writer, (auth, n_exts != 0))?; + } + if let Some(mlink) = x.ext_mlink.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (mlink, n_exts != 0))?; } Ok(()) @@ -234,27 +255,33 @@ where let mut ext_qos = None; let mut ext_shm = None; let mut ext_auth = None; + let mut ext_mlink = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match imsg::mid(ext) { - ext::QOS => { + ext::QoS::ID => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; ext_qos = Some(q); has_ext = ext; } - ext::SHM => { + ext::Shm::ID => { let (s, ext): (ext::Shm, bool) = eodec.read(&mut *reader)?; ext_shm = Some(s); has_ext = ext; } - ext::AUTH => { + ext::Auth::ID => { let (a, ext): (ext::Auth, bool) = eodec.read(&mut *reader)?; ext_auth = Some(a); has_ext = ext; } + ext::MultiLink::ID => { + let (a, ext): (ext::MultiLink, bool) = eodec.read(&mut *reader)?; + ext_mlink = Some(a); + has_ext = ext; + } _ => { let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; has_ext = ext; @@ -268,6 +295,7 @@ where ext_qos, ext_shm, ext_auth, + ext_mlink, }) } } diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index fd2f67eed6..8d74b62539 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -113,6 +113,7 @@ pub struct InitSyn { pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, + pub ext_mlink: Option, } // Extensions @@ -122,6 +123,7 @@ pub mod ext { pub const QOS: u8 = 0x01; pub const SHM: u8 = 0x02; pub const AUTH: u8 = 0x03; + pub const MLINK: u8 = 0x04; /// # QoS extension /// Used to negotiate the use of QoS @@ -134,6 +136,10 @@ pub mod ext { /// # Auth extension /// Used as challenge for probing authentication rights pub type Auth = ZExtZBuf; + + /// # Multilink extension + /// Used as challenge for probing multilink capabilities + pub type MultiLink = ZExtZBuf; } impl InitSyn { @@ -152,6 +158,7 @@ impl InitSyn { let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + let ext_mlink = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); Self { version, @@ -162,6 +169,7 @@ impl InitSyn { ext_qos, ext_shm, ext_auth, + ext_mlink, } } } @@ -177,6 +185,7 @@ pub struct InitAck { pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, + pub ext_mlink: Option, } impl InitAck { @@ -200,6 +209,7 @@ impl InitAck { let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + let ext_mlink = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); Self { version, @@ -211,6 +221,7 @@ impl InitAck { ext_qos, ext_shm, ext_auth, + ext_mlink, } } } diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 156c94b175..49669b5961 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -80,6 +80,7 @@ pub struct OpenSyn { pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, + pub ext_mlink: Option, } // Extensions @@ -89,6 +90,7 @@ pub mod ext { pub const QOS: u8 = 0x01; pub const SHM: u8 = 0x02; pub const AUTH: u8 = 0x03; + pub const MLINK: u8 = 0x04; /// # QoS extension /// Used to negotiate the use of QoS @@ -101,6 +103,10 @@ pub mod ext { /// # Auth extension /// Used as challenge for probing authentication rights pub type Auth = ZExtZBuf; + + /// # MultiLink extension + /// Used as challenge for probing multilink capabilities + pub type MultiLink = ZExtZBuf; } impl OpenSyn { @@ -125,6 +131,8 @@ impl OpenSyn { let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZInt::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + let ext_mlink = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + Self { lease, initial_sn, @@ -132,6 +140,7 @@ impl OpenSyn { ext_qos, ext_shm, ext_auth, + ext_mlink, } } } @@ -143,6 +152,7 @@ pub struct OpenAck { pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, + pub ext_mlink: Option, } impl OpenAck { @@ -163,12 +173,15 @@ impl OpenAck { let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZInt::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + let ext_mlink = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + Self { lease, initial_sn, ext_qos, ext_shm, ext_auth, + ext_mlink, } } } diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index de6f40000d..4ec513e52c 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -271,6 +271,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { ext_qos, ext_shm, ext_auth, + ext_mlink: None, // @TODO } .into(); @@ -424,6 +425,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { ext_qos, ext_shm, ext_auth, + ext_mlink: None, // @TODO }; // Do not send the OpenAck right now since we might still incur in MAX_LINKS error diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 8bc7610ecf..c1207d2df4 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -135,6 +135,7 @@ impl<'a> OpenFsm for OpenLink<'a> { ext_qos, ext_shm, ext_auth, + ext_mlink: None, // @TODO } .into(); @@ -297,6 +298,7 @@ impl<'a> OpenFsm for OpenLink<'a> { ext_qos, ext_shm, ext_auth, + ext_mlink: None, // @TODO } .into(); From 818d0c13d703727b9d39ea9e749f51c818b90f43 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 10 Mar 2023 16:46:17 +0100 Subject: [PATCH 072/203] Auth RwLock sharding --- .../src/unicast/establishment/accept.rs | 11 ++-- .../src/unicast/establishment/ext/auth/mod.rs | 54 ++++++++--------- .../unicast/establishment/ext/auth/pubkey.rs | 27 +++++---- .../unicast/establishment/ext/auth/usrpwd.rs | 59 ++++++++++--------- .../src/unicast/establishment/open.rs | 31 +++++----- io/zenoh-transport/src/unicast/manager.rs | 23 ++------ .../tests/unicast_authenticator.rs | 11 ++-- 7 files changed, 100 insertions(+), 116 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 4ec513e52c..817ad9121a 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -26,7 +26,7 @@ use rand::Rng; use std::time::Duration; use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZSlice}; use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_core::{zasynclock, zasyncread, zerror}; +use zenoh_core::{zasynclock, zerror}; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ @@ -436,7 +436,6 @@ impl<'a> AcceptFsm for AcceptLink<'a> { } pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) -> ZResult<()> { - let auth = zasyncread!(manager.state.unicast.authenticator); let fsm = AcceptLink { link, prng: &manager.prng, @@ -444,7 +443,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) ext_qos: ext::qos::QoSFsm::new(), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), - ext_auth: ext::auth::AuthFsm::new(&auth, &manager.prng), + ext_auth: manager.state.unicast.authenticator.fsm(&manager.prng), }; // Init handshake @@ -470,7 +469,11 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) ext_qos: ext::qos::StateAccept::new(manager.config.unicast.is_qos), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateAccept::new(manager.config.unicast.is_shm), - ext_auth: auth.accept(&mut *zasynclock!(manager.prng)), + ext_auth: manager + .state + .unicast + .authenticator + .accept(&mut *zasynclock!(manager.prng)), }; // Let's scope the Init phase in such a way memory is freed by Rust diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs index 7bd0c90b85..323e348d28 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -17,7 +17,7 @@ mod pubkey; mod usrpwd; use crate::establishment::{AcceptFsm, OpenFsm}; -use async_std::sync::Mutex; +use async_std::sync::{Mutex, RwLock}; use async_trait::async_trait; #[cfg(feature = "auth_pubkey")] pub use pubkey::*; @@ -49,9 +49,9 @@ pub(crate) mod id { #[derive(Debug, Default)] pub struct Auth { #[cfg(feature = "auth_pubkey")] - pubkey: Option, + pubkey: Option>, #[cfg(feature = "auth_usrpwd")] - usrpwd: Option, + usrpwd: Option>, } impl Auth { @@ -60,9 +60,13 @@ impl Auth { Ok(Self { #[cfg(feature = "auth_pubkey")] - pubkey: AuthPubKey::from_config(auth.pubkey()).await?, + pubkey: AuthPubKey::from_config(auth.pubkey()) + .await? + .map(RwLock::new), #[cfg(feature = "auth_usrpwd")] - usrpwd: AuthUsrPwd::from_config(auth.usrpwd()).await?, + usrpwd: AuthUsrPwd::from_config(auth.usrpwd()) + .await? + .map(RwLock::new), }) } @@ -95,6 +99,16 @@ impl Auth { .then_some(usrpwd::StateAccept::new(prng)), } } + + pub(crate) fn fsm<'a>(&'a self, prng: &'a Mutex) -> AuthFsm<'a> { + AuthFsm { + #[cfg(feature = "auth_pubkey")] + pubkey: self.pubkey.as_ref().map(|x| AuthPubKeyFsm::new(x, prng)), + #[cfg(feature = "auth_usrpwd")] + usrpwd: self.usrpwd.as_ref().map(AuthUsrPwdFsm::new), + _a: PhantomData, + } + } } #[cfg(feature = "test")] @@ -110,33 +124,23 @@ impl Auth { #[cfg(feature = "auth_pubkey")] pub fn set_pubkey(&mut self, pubkey: Option) { - self.pubkey = pubkey; + self.pubkey = pubkey.map(RwLock::new); } #[cfg(feature = "auth_pubkey")] - pub fn get_pubkey(&self) -> Option<&AuthPubKey> { + pub fn get_pubkey(&self) -> Option<&RwLock> { self.pubkey.as_ref() } - #[cfg(feature = "auth_pubkey")] - pub fn get_pubkey_mut(&mut self) -> Option<&mut AuthPubKey> { - self.pubkey.as_mut() - } - #[cfg(feature = "auth_usrpwd")] pub fn set_usrpwd(&mut self, usrpwd: Option) { - self.usrpwd = usrpwd; + self.usrpwd = usrpwd.map(RwLock::new); } #[cfg(feature = "auth_usrpwd")] - pub fn get_usrpwd(&self) -> Option<&AuthUsrPwd> { + pub fn get_usrpwd(&self) -> Option<&RwLock> { self.usrpwd.as_ref() } - - #[cfg(feature = "auth_usrpwd")] - pub fn get_usrpwd_mut(&mut self) -> Option<&mut AuthUsrPwd> { - self.usrpwd.as_mut() - } } pub(crate) struct AuthFsm<'a> { @@ -147,18 +151,6 @@ pub(crate) struct AuthFsm<'a> { _a: PhantomData<&'a ()>, // Required only when all auth features are disabled } -impl<'a> AuthFsm<'a> { - pub(crate) fn new(a: &'a Auth, prng: &'a Mutex) -> Self { - Self { - #[cfg(feature = "auth_pubkey")] - pubkey: a.pubkey.as_ref().map(|x| AuthPubKeyFsm::new(x, prng)), - #[cfg(feature = "auth_usrpwd")] - usrpwd: a.usrpwd.as_ref().map(AuthUsrPwdFsm::new), - _a: PhantomData, - } - } -} - #[derive(Debug, PartialEq, Eq)] pub(crate) struct StateOpen { #[cfg(feature = "auth_pubkey")] diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs index e2cf83d0a8..41011ac8c1 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs @@ -14,7 +14,7 @@ // use super::{ // AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, // }; -use async_std::sync::Mutex; +use async_std::sync::{Mutex, RwLock}; use async_trait::async_trait; use rand::{CryptoRng, Rng}; use rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}; @@ -28,7 +28,7 @@ use zenoh_buffers::{ }; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_config::PubKeyConf; -use zenoh_core::{bail, zasynclock, zerror, Error as ZError, Result as ZResult}; +use zenoh_core::{bail, zasynclock, zasyncread, zerror, Error as ZError, Result as ZResult}; use zenoh_crypto::PseudoRng; use zenoh_protocol::common::{ZExtUnit, ZExtZBuf}; use zenoh_protocol::core::ZInt; @@ -317,12 +317,12 @@ where /// ZExtUnit pub(crate) struct AuthPubKeyFsm<'a> { - inner: &'a AuthPubKey, + inner: &'a RwLock, prng: &'a Mutex, } impl<'a> AuthPubKeyFsm<'a> { - pub(super) const fn new(inner: &'a AuthPubKey, prng: &'a Mutex) -> Self { + pub(super) const fn new(inner: &'a RwLock, prng: &'a Mutex) -> Self { Self { inner, prng } } } @@ -355,7 +355,7 @@ impl<'a> OpenFsm for AuthPubKeyFsm<'a> { log::trace!("{S}"); let init_syn = InitSyn { - alice_pubkey: self.inner.pub_key.clone(), + alice_pubkey: zasyncread!(self.inner).pub_key.clone(), }; let codec = Zenoh080::new(); @@ -389,13 +389,13 @@ impl<'a> OpenFsm for AuthPubKeyFsm<'a> { .read(&mut reader) .map_err(|_| zerror!("{S} Decoding error."))?; - if !self.inner.lookup.is_empty() && !self.inner.lookup.contains(&init_ack.bob_pubkey) { + let r_inner = zasyncread!(self.inner); + if !r_inner.lookup.is_empty() && !r_inner.lookup.contains(&init_ack.bob_pubkey) { bail!("{S} Unauthorized PubKey."); } let mut prng = zasynclock!(self.prng); - let nonce = self - .inner + let nonce = r_inner .pri_key .decrypt_blinded( &mut *prng, @@ -403,6 +403,7 @@ impl<'a> OpenFsm for AuthPubKeyFsm<'a> { init_ack.nonce_encrypted_with_alice_pubkey.as_slice(), ) .map_err(|_| zerror!("{S} Decryption error."))?; + drop(r_inner); state.nonce = init_ack .bob_pubkey @@ -539,7 +540,10 @@ impl<'a> AcceptFsm for AuthPubKeyFsm<'a> { .read(&mut reader) .map_err(|_| zerror!("{S} Decoding error."))?; - if !self.inner.lookup.contains(&init_syn.alice_pubkey) { + if !zasyncread!(self.inner) + .lookup + .contains(&init_syn.alice_pubkey) + { bail!("{S} Unauthorized PubKey."); } @@ -563,7 +567,7 @@ impl<'a> AcceptFsm for AuthPubKeyFsm<'a> { log::trace!("{S}"); let init_ack = InitAck { - bob_pubkey: self.inner.pub_key.clone(), + bob_pubkey: zasyncread!(self.inner).pub_key.clone(), nonce_encrypted_with_alice_pubkey: state.nonce.clone(), }; @@ -599,8 +603,7 @@ impl<'a> AcceptFsm for AuthPubKeyFsm<'a> { .map_err(|_| zerror!("{S} Decoding error."))?; let mut prng = zasynclock!(self.prng); - let nonce = self - .inner + let nonce = zasyncread!(self.inner) .pri_key .decrypt_blinded( &mut *prng, diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index 815629a5e6..a33279b112 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -1,23 +1,18 @@ -// // -// // Copyright (c) 2022 ZettaScale Technology -// // -// // This program and the accompanying materials are made available under the -// // terms of the Eclipse Public License 2.0 which is available at -// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// // which is available at https://www.apache.org/licenses/LICENSE-2.0. -// // -// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// // -// // Contributors: -// // ZettaScale Zenoh Team, -// // -// use super::{ -// AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, -// }; -// use super::{Locator, ZInt, ZenohId}; -// use crate::unicast::establishment::Cookie; +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// use crate::establishment::{AcceptFsm, OpenFsm}; -use async_std::fs; +use async_std::{fs, sync::RwLock}; use async_trait::async_trait; use rand::{CryptoRng, Rng}; use std::collections::HashMap; @@ -28,7 +23,7 @@ use zenoh_buffers::{ use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_collections::Properties; use zenoh_config::UsrPwdConf; -use zenoh_core::{bail, zerror, Error as ZError, Result as ZResult}; +use zenoh_core::{bail, zasyncread, zerror, Error as ZError, Result as ZResult}; use zenoh_crypto::hmac; use zenoh_protocol::{ common::{ZExtUnit, ZExtZBuf, ZExtZInt}, @@ -161,12 +156,12 @@ where } pub(crate) struct AuthUsrPwdFsm<'a> { - inner: &'a AuthUsrPwd, + inner: &'a RwLock, } impl<'a> AuthUsrPwdFsm<'a> { - pub(super) const fn new(a: &'a AuthUsrPwd) -> Self { - Self { inner: a } + pub(super) const fn new(inner: &'a RwLock) -> Self { + Self { inner } } } @@ -250,7 +245,10 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { &self, _input: Self::SendInitSynIn, ) -> Result { - let output = self.inner.credentials.is_some().then_some(ZExtUnit::new()); + let output = zasyncread!(self.inner) + .credentials + .is_some() + .then_some(ZExtUnit::new()); Ok(output) } @@ -262,7 +260,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { ) -> Result { const S: &str = "UsrPwd extension - Recv InitSyn."; - if self.inner.credentials.is_none() { + if zasyncread!(self.inner).credentials.is_none() { return Ok(()); }; @@ -284,7 +282,8 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { const S: &str = "UsrPwd extension - Send OpenSyn."; // If credentials are not configured, don't continue the USRPWD authentication - let (user, password) = match self.inner.credentials.as_ref() { + let r_inner = zasyncread!(self.inner); + let (user, password) = match r_inner.credentials.as_ref() { Some(cr) => cr, None => return Ok(None), }; @@ -297,6 +296,8 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { user: user.to_vec(), hmac, }; + drop(r_inner); + let codec = Zenoh080::new(); let mut buff = vec![]; let mut writer = buff.writer(); @@ -317,7 +318,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { const S: &str = "UsrPwd extension - Recv OpenAck."; let (_, ext) = input; - if self.inner.credentials.is_some() && ext.is_none() { + if zasyncread!(self.inner).credentials.is_some() && ext.is_none() { bail!("{S} Expected extension."); } @@ -376,8 +377,8 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { .read(&mut reader) .map_err(|_| zerror!("{S} Decoding error."))?; - let pwd = self - .inner + let r_inner = zasyncread!(self.inner); + let pwd = r_inner .lookup .get(&open_syn.user) .ok_or_else(|| zerror!("{S} Invalid user."))?; diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index c1207d2df4..10225a2e6f 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -23,7 +23,7 @@ use async_trait::async_trait; use std::time::Duration; use zenoh_buffers::ZSlice; use zenoh_config::{WhatAmI, ZenohId}; -use zenoh_core::{zasynclock, zasyncread, zerror}; +use zenoh_core::{zasynclock, zerror}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::core::{Field, Resolution, ZInt}; use zenoh_protocol::transport::{close, Close, InitSyn, OpenSyn, TransportBody, TransportMessage}; @@ -380,13 +380,27 @@ pub(crate) async fn open_link( link: &LinkUnicast, manager: &TransportManager, ) -> ZResult { - let auth = zasyncread!(manager.state.unicast.authenticator); let fsm = OpenLink { link, ext_qos: ext::qos::QoSFsm::new(), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), - ext_auth: ext::auth::AuthFsm::new(&auth, &manager.prng), + ext_auth: manager.state.unicast.authenticator.fsm(&manager.prng), + }; + + let mut state = State { + zenoh: StateZenoh { + batch_size: manager.config.batch_size, + resolution: manager.config.resolution, + }, + ext_qos: ext::qos::StateOpen::new(manager.config.unicast.is_qos), + #[cfg(feature = "shared-memory")] + ext_shm: ext::shm::StateOpen::new(manager.config.unicast.is_shm), + ext_auth: manager + .state + .unicast + .authenticator + .open(&mut *zasynclock!(manager.prng)), }; // Init handshake @@ -402,17 +416,6 @@ pub(crate) async fn open_link( }; } - let mut state = State { - zenoh: StateZenoh { - batch_size: manager.config.batch_size, - resolution: manager.config.resolution, - }, - ext_qos: ext::qos::StateOpen::new(manager.config.unicast.is_qos), - #[cfg(feature = "shared-memory")] - ext_shm: ext::shm::StateOpen::new(manager.config.unicast.is_shm), - ext_auth: auth.open(&mut *zasynclock!(manager.prng)), - }; - let isyn_in = SendInitSynIn { mine_version: manager.config.version, mine_zid: manager.config.zid, diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 0df859b706..9768b3aa09 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -20,11 +20,7 @@ use crate::{ }, TransportManager, }; -use async_std::{ - prelude::FutureExt, - sync::{Mutex, RwLock}, - task, -}; +use async_std::{prelude::FutureExt, sync::Mutex, task}; use std::{collections::HashMap, sync::Arc, time::Duration}; #[cfg(feature = "shared-memory")] use zenoh_config::SharedMemoryConf; @@ -56,7 +52,7 @@ pub struct TransportManagerStateUnicast { // Incoming uninitialized transports pub(super) incoming: Arc>, // Active authenticators - pub(super) authenticator: Arc>, + pub(super) authenticator: Arc, // Established listeners pub(super) protocols: Arc>>, // Established transports @@ -174,22 +170,11 @@ impl TransportManagerBuilderUnicast { is_shm: self.is_shm, }; - // Enable pubkey authentication by default to avoid ZenohId spoofing - // #[cfg(feature = "auth_pubkey")] - // if !self - // .peer_authenticator - // .iter() - // .any(|a| a.id() == PeerAuthenticatorId::PublicKey) - // { - // self.peer_authenticator - // .insert(PubKeyAuthenticator::make()?.into()); - // } @TODO - let state = TransportManagerStateUnicast { incoming: Arc::new(Mutex::new(0)), protocols: Arc::new(Mutex::new(HashMap::new())), transports: Arc::new(Mutex::new(HashMap::new())), - authenticator: Arc::new(RwLock::new(self.authenticator)), + authenticator: Arc::new(self.authenticator), #[cfg(feature = "shared-memory")] shm: Arc::new(SharedMemoryUnicast::make()?), }; @@ -509,7 +494,7 @@ impl TransportManager { #[cfg(feature = "test")] impl TransportManager { - pub fn get_auth_handle_unicast(&self) -> Arc> { + pub fn get_auth_handle_unicast(&self) -> Arc { self.state.unicast.authenticator.clone() } } diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index 4ee1ab59de..071b0e016a 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -310,9 +310,7 @@ async fn auth_pubkey(endpoint: &EndPoint) { // Add client02 pubkey to the router let router_auth_handle = router_manager.get_auth_handle_unicast(); - zasyncwrite!(router_auth_handle) - .get_pubkey_mut() - .unwrap() + zasyncwrite!(router_auth_handle.get_pubkey().unwrap()) .add_pubkey(client02_pub_key.into()) .await .unwrap(); @@ -509,10 +507,9 @@ async fn auth_usrpwd(endpoint: &EndPoint) { /* [6] */ // Add client02 credentials on the router let auth_router = router_manager.get_auth_handle_unicast(); - ztimeout!(zasyncwrite!(auth_router) - .get_usrpwd_mut() - .unwrap() - .add_user(user02.into(), password02.into())) + ztimeout!( + zasyncwrite!(auth_router.get_usrpwd().unwrap()).add_user(user02.into(), password02.into()) + ) .unwrap(); // Open a fourth transport from the client to the router From 6eaac4e9eebfeabb617e28051527773e55902f06 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 10 Mar 2023 21:32:33 +0100 Subject: [PATCH 073/203] Initial MultiLink ext --- commons/zenoh-codec/src/transport/open.rs | 8 +- .../zenoh-protocol/src/common/extension.rs | 12 + commons/zenoh-protocol/src/transport/open.rs | 9 +- io/zenoh-transport/src/manager.rs | 12 +- .../src/unicast/establishment/accept.rs | 71 +++- .../src/unicast/establishment/cookie.rs | 17 +- .../src/unicast/establishment/ext/auth/mod.rs | 4 +- .../unicast/establishment/ext/auth/pubkey.rs | 29 +- .../src/unicast/establishment/ext/mod.rs | 2 + .../unicast/establishment/ext/multilink.rs | 355 ++++++++++++++++++ .../src/unicast/establishment/mod.rs | 10 +- .../src/unicast/establishment/open.rs | 5 +- io/zenoh-transport/src/unicast/manager.rs | 8 + 13 files changed, 481 insertions(+), 61 deletions(-) create mode 100644 io/zenoh-transport/src/unicast/establishment/ext/multilink.rs diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index 5203c6d802..db4a11e9e7 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -140,8 +140,8 @@ where ext_auth = Some(a); has_ext = ext; } - ext::MultiLink::ID => { - let (a, ext): (ext::MultiLink, bool) = eodec.read(&mut *reader)?; + ext::MultiLinkSyn::ID => { + let (a, ext): (ext::MultiLinkSyn, bool) = eodec.read(&mut *reader)?; ext_mlink = Some(a); has_ext = ext; } @@ -277,8 +277,8 @@ where ext_auth = Some(a); has_ext = ext; } - ext::MultiLink::ID => { - let (a, ext): (ext::MultiLink, bool) = eodec.read(&mut *reader)?; + ext::MultiLinkAck::ID => { + let (a, ext): (ext::MultiLinkAck, bool) = eodec.read(&mut *reader)?; ext_mlink = Some(a); has_ext = ext; } diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index a4e4c07159..2650a47ee0 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -75,6 +75,10 @@ impl ZExtUnit<{ ID }> { Self } + pub const fn transmute(self) -> ZExtUnit<{ DI }> { + ZExtUnit::new() + } + #[cfg(feature = "test")] pub fn rand() -> Self { Self::new() @@ -107,6 +111,10 @@ impl ZExtZInt<{ ID }> { Self { value } } + pub const fn transmute(self) -> ZExtZInt<{ DI }> { + ZExtZInt::new(self.value) + } + #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; @@ -143,6 +151,10 @@ impl ZExtZBuf<{ ID }> { Self { value } } + pub fn transmute(self) -> ZExtZBuf<{ DI }> { + ZExtZBuf::new(self.value) + } + #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 49669b5961..636871ac0a 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -80,7 +80,7 @@ pub struct OpenSyn { pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, - pub ext_mlink: Option, + pub ext_mlink: Option, } // Extensions @@ -106,7 +106,8 @@ pub mod ext { /// # MultiLink extension /// Used as challenge for probing multilink capabilities - pub type MultiLink = ZExtZBuf; + pub type MultiLinkSyn = ZExtZBuf; + pub type MultiLinkAck = ZExtUnit; } impl OpenSyn { @@ -152,7 +153,7 @@ pub struct OpenAck { pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, - pub ext_mlink: Option, + pub ext_mlink: Option, } impl OpenAck { @@ -173,7 +174,7 @@ impl OpenAck { let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZInt::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); - let ext_mlink = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + let ext_mlink = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); Self { lease, diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index 603429c733..d64369f259 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -216,7 +216,10 @@ impl TransportManagerBuilder { } pub fn build(self, handler: Arc) -> ZResult { - let unicast = self.unicast.build()?; + // Initialize the PRNG and the Cipher + let mut prng = PseudoRng::from_entropy(); + + let unicast = self.unicast.build(&mut prng)?; let mut queue_size = [0; Priority::NUM]; queue_size[Priority::Control as usize] = *self.queue_size.control(); @@ -250,7 +253,7 @@ impl TransportManagerBuilder { let params = TransportManagerParams { config, state }; - Ok(TransportManager::new(params)) + Ok(TransportManager::new(params, prng)) } } @@ -318,9 +321,8 @@ pub struct TransportManager { } impl TransportManager { - pub fn new(params: TransportManagerParams) -> TransportManager { - // Initialize the PRNG and the Cipher - let mut prng = PseudoRng::from_entropy(); + pub fn new(params: TransportManagerParams, mut prng: PseudoRng) -> TransportManager { + // Initialize the Cipher let mut key = [0_u8; BlockCipher::BLOCK_SIZE]; prng.fill_bytes(&mut key); let cipher = BlockCipher::new(key); diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 817ad9121a..6ce0dfe0c5 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -41,6 +41,7 @@ use zenoh_result::ZResult; pub(super) type AcceptError = (zenoh_result::Error, Option); struct StateZenoh { + other_zid: ZenohId, batch_size: u16, resolution: Resolution, } @@ -51,6 +52,7 @@ struct State { #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateAccept, ext_auth: ext::auth::StateAccept, + ext_mlink: ext::multilink::StateAccept, } // InitSyn @@ -58,7 +60,6 @@ struct RecvInitSynIn { mine_version: u8, } struct RecvInitSynOut { - other_zid: ZenohId, other_whatami: WhatAmI, #[cfg(feature = "shared-memory")] ext_shm: Challenge, @@ -69,21 +70,21 @@ struct SendInitAckIn { mine_version: u8, mine_zid: ZenohId, mine_whatami: WhatAmI, - other_zid: ZenohId, other_whatami: WhatAmI, #[cfg(feature = "shared-memory")] ext_shm: Challenge, } struct SendInitAckOut { + other_zid: ZenohId, cookie_nonce: ZInt, } // OpenSyn struct RecvOpenSynIn { + other_zid: ZenohId, cookie_nonce: ZInt, } struct RecvOpenSynOut { - other_zid: ZenohId, other_whatami: WhatAmI, other_lease: Duration, other_initial_sn: ZInt, @@ -93,7 +94,6 @@ struct RecvOpenSynOut { struct SendOpenAckIn { mine_zid: ZenohId, mine_lease: Duration, - other_zid: ZenohId, } struct SendOpenAckOut { open_ack: OpenAck, @@ -108,6 +108,8 @@ struct AcceptLink<'a> { #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm<'a>, ext_auth: ext::auth::AuthFsm<'a>, + #[cfg(feature = "auth_pubkey")] + ext_mlink: ext::multilink::MultiLinkFsm<'a>, } #[async_trait] @@ -140,6 +142,9 @@ impl<'a> AcceptFsm for AcceptLink<'a> { } }; + // Store the ZenohId + state.zenoh.other_zid = init_syn.zid; + // Check if the version is supported if init_syn.version != input.mine_version { let e = zerror!( @@ -190,9 +195,14 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension MultiLink + self.ext_mlink + .recv_init_syn((&mut state.ext_mlink, init_syn.ext_mlink, init_syn.zid)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvInitSynOut { other_whatami: init_syn.whatami, - other_zid: init_syn.zid, #[cfg(feature = "shared-memory")] ext_shm, }; @@ -231,11 +241,17 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension MultiLink + let ext_mlink = self + .ext_mlink + .send_init_ack(&state.ext_mlink) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Create the cookie let cookie_nonce: ZInt = zasynclock!(self.prng).gen(); let cookie = Cookie { whatami: input.other_whatami, - zid: input.other_zid, resolution: state.zenoh.resolution, batch_size: state.zenoh.batch_size, nonce: cookie_nonce, @@ -243,6 +259,8 @@ impl<'a> AcceptFsm for AcceptLink<'a> { #[cfg(feature = "shared-memory")] ext_shm: state.ext_shm, ext_auth: state.ext_auth, + #[cfg(feature = "auth_pubkey")] + ext_mlink: state.ext_mlink, }; let mut encrypted = vec![]; @@ -271,7 +289,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { ext_qos, ext_shm, ext_auth, - ext_mlink: None, // @TODO + ext_mlink, } .into(); @@ -281,7 +299,10 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = SendInitAckOut { cookie_nonce }; + let output = SendInitAckOut { + other_zid: state.zenoh.other_zid, + cookie_nonce, + }; Ok(output) } @@ -348,6 +369,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { // Rebuild the state from the cookie let mut state = State { zenoh: StateZenoh { + other_zid: input.other_zid, batch_size: cookie.batch_size, resolution: cookie.resolution, }, @@ -355,6 +377,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { #[cfg(feature = "shared-memory")] ext_shm: cookie.ext_shm, ext_auth: cookie.ext_auth, + ext_mlink: cookie.ext_mlink, }; // Extension QoS @@ -376,8 +399,13 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension MultiLink + self.ext_mlink + .recv_open_syn((&mut state.ext_mlink, open_syn.ext_mlink)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvOpenSynOut { - other_zid: cookie.zid, other_whatami: cookie.whatami, other_lease: open_syn.lease, other_initial_sn: open_syn.initial_sn, @@ -418,7 +446,11 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Build OpenAck message - let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); + let mine_initial_sn = compute_sn( + input.mine_zid, + state.zenoh.other_zid, + state.zenoh.resolution, + ); let open_ack = OpenAck { lease: input.mine_lease, initial_sn: mine_initial_sn, @@ -444,16 +476,19 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), ext_auth: manager.state.unicast.authenticator.fsm(&manager.prng), + #[cfg(feature = "auth_pubkey")] + ext_mlink: manager.state.unicast.multilink.fsm(&manager.prng), }; // Init handshake macro_rules! step { - ($s: expr) => { - match $s { + ($res:expr) => { + match $res { Ok(output) => output, Err((e, reason)) => { log::error!("{}", e); - close_link(link, reason).await; + // @TODO + close_link(link, manager, ZenohId::default(), reason).await; return Err(e); } } @@ -463,6 +498,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) let iack_out = { let mut state = State { zenoh: StateZenoh { + other_zid: manager.config.zid, // This is a temporary value batch_size: manager.config.batch_size, resolution: manager.config.resolution, }, @@ -474,6 +510,8 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) .unicast .authenticator .accept(&mut *zasynclock!(manager.prng)), + #[cfg(feature = "auth_pubkey")] + ext_mlink: manager.state.unicast.multilink.accept(false), // @TODO }; // Let's scope the Init phase in such a way memory is freed by Rust @@ -488,7 +526,6 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) mine_version: manager.config.version, mine_zid: manager.config.zid, mine_whatami: manager.config.whatami, - other_zid: isyn_out.other_zid, other_whatami: isyn_out.other_whatami, #[cfg(feature = "shared-memory")] ext_shm: isyn_out.ext_shm, @@ -498,6 +535,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) // Open handshake let osyn_in = RecvOpenSynIn { + other_zid: iack_out.other_zid, cookie_nonce: iack_out.cookie_nonce, }; let (mut state, osyn_out) = step!(fsm.recv_open_syn(osyn_in).await); @@ -506,13 +544,12 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) let oack_in = SendOpenAckIn { mine_zid: manager.config.zid, mine_lease: manager.config.unicast.lease, - other_zid: osyn_out.other_zid, }; let oack_out = step!(fsm.send_open_ack((&mut state, oack_in)).await); // Initialize the transport let config = TransportConfigUnicast { - zid: osyn_out.other_zid, + zid: state.zenoh.other_zid, whatami: osyn_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN), tx_initial_sn: oack_out.open_ack.initial_sn, @@ -559,7 +596,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) log::debug!( "New transport link accepted from {} to {}: {}", - osyn_out.other_zid, + state.zenoh.other_zid, manager.config.zid, link ); diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index b1014b10ea..4623bf28ea 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -20,12 +20,11 @@ use zenoh_buffers::{ }; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_crypto::{BlockCipher, PseudoRng}; -use zenoh_protocol::core::{Resolution, WhatAmI, ZInt, ZenohId}; +use zenoh_protocol::core::{Resolution, WhatAmI, ZInt}; #[derive(Debug, PartialEq)] pub(crate) struct Cookie { pub(crate) whatami: WhatAmI, - pub(crate) zid: ZenohId, pub(crate) resolution: Resolution, pub(crate) batch_size: u16, pub(crate) nonce: ZInt, @@ -34,6 +33,8 @@ pub(crate) struct Cookie { #[cfg(feature = "shared-memory")] pub(crate) ext_shm: ext::shm::StateAccept, pub(crate) ext_auth: ext::auth::StateAccept, + #[cfg(feature = "auth_pubkey")] + pub(crate) ext_mlink: ext::multilink::StateAccept, } impl WCodec<&Cookie, &mut W> for Zenoh080 @@ -45,7 +46,6 @@ where fn write(self, writer: &mut W, x: &Cookie) -> Self::Output { let wai: u8 = x.whatami.into(); self.write(&mut *writer, wai)?; - self.write(&mut *writer, &x.zid)?; self.write(&mut *writer, x.resolution.as_u8())?; self.write(&mut *writer, x.batch_size)?; self.write(&mut *writer, x.nonce)?; @@ -54,6 +54,8 @@ where #[cfg(feature = "shared-memory")] self.write(&mut *writer, &x.ext_shm)?; self.write(&mut *writer, &x.ext_auth)?; + #[cfg(feature = "auth_pubkey")] + self.write(&mut *writer, &x.ext_mlink)?; Ok(()) } @@ -68,7 +70,6 @@ where fn read(self, reader: &mut R) -> Result { let wai: u8 = self.read(&mut *reader)?; let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; - let zid: ZenohId = self.read(&mut *reader)?; let resolution: u8 = self.read(&mut *reader)?; let resolution = Resolution::from(resolution); let batch_size: u16 = self.read(&mut *reader)?; @@ -78,10 +79,11 @@ where #[cfg(feature = "shared-memory")] let ext_shm: ext::shm::StateAccept = self.read(&mut *reader)?; let ext_auth: ext::auth::StateAccept = self.read(&mut *reader)?; + #[cfg(feature = "auth_pubkey")] + let ext_mlink: ext::multilink::StateAccept = self.read(&mut *reader)?; let cookie = Cookie { whatami, - zid, resolution, batch_size, nonce, @@ -89,6 +91,8 @@ where #[cfg(feature = "shared-memory")] ext_shm, ext_auth, + #[cfg(feature = "auth_pubkey")] + ext_mlink, }; Ok(cookie) @@ -146,7 +150,6 @@ impl Cookie { Self { whatami: WhatAmI::rand(), - zid: ZenohId::default(), resolution: Resolution::rand(), batch_size: rng.gen(), nonce: rng.gen(), @@ -154,6 +157,8 @@ impl Cookie { #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateAccept::rand(), ext_auth: ext::auth::StateAccept::rand(), + #[cfg(feature = "auth_pubkey")] + ext_mlink: ext::multilink::StateAccept::rand(), } } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs index 323e348d28..59154385ff 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -12,9 +12,9 @@ // ZettaScale Zenoh Team, // #[cfg(feature = "auth_pubkey")] -mod pubkey; +pub(crate) mod pubkey; #[cfg(feature = "auth_usrpwd")] -mod usrpwd; +pub(crate) mod usrpwd; use crate::establishment::{AcceptFsm, OpenFsm}; use async_std::sync::{Mutex, RwLock}; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs index 41011ac8c1..294428afb5 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs @@ -16,7 +16,7 @@ // }; use async_std::sync::{Mutex, RwLock}; use async_trait::async_trait; -use rand::{CryptoRng, Rng}; +use rand::Rng; use rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}; use rsa::{BigUint, Pkcs1v15Encrypt, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey}; use std::collections::HashSet; @@ -35,8 +35,6 @@ use zenoh_protocol::core::ZInt; use crate::establishment::{AcceptFsm, OpenFsm}; -const KEY_SIZE: usize = 512; - // Authenticator #[derive(Debug)] pub struct AuthPubKey { @@ -54,15 +52,6 @@ impl AuthPubKey { } } - pub fn make(rng: &mut R) -> ZResult - where - R: Rng + CryptoRng, - { - let pri_key = RsaPrivateKey::new(rng, KEY_SIZE)?; - let pub_key = RsaPublicKey::from(&pri_key); - Ok(Self::new(pub_key.into(), pri_key.into())) - } - pub async fn add_pubkey(&mut self, pub_key: ZPublicKey) -> ZResult<()> { self.lookup.insert(pub_key); Ok(()) @@ -195,8 +184,8 @@ where /// +---------------+ /// /// ZExtZBuf -struct InitSyn { - alice_pubkey: ZPublicKey, +pub(crate) struct InitSyn { + pub(crate) alice_pubkey: ZPublicKey, } impl WCodec<&InitSyn, &mut W> for Zenoh080 @@ -234,9 +223,9 @@ where /// +---------------+ /// /// ZExtZBuf -struct InitAck { - bob_pubkey: ZPublicKey, - nonce_encrypted_with_alice_pubkey: Vec, +pub(crate) struct InitAck { + pub(crate) bob_pubkey: ZPublicKey, + pub(crate) nonce_encrypted_with_alice_pubkey: Vec, } impl WCodec<&InitAck, &mut W> for Zenoh080 @@ -277,8 +266,8 @@ where /// +---------------+ /// /// ZExtZBuf -struct OpenSyn { - nonce_encrypted_with_bob_pubkey: Vec, +pub(crate) struct OpenSyn { + pub(crate) nonce_encrypted_with_bob_pubkey: Vec, } impl WCodec<&OpenSyn, &mut W> for Zenoh080 @@ -322,7 +311,7 @@ pub(crate) struct AuthPubKeyFsm<'a> { } impl<'a> AuthPubKeyFsm<'a> { - pub(super) const fn new(inner: &'a RwLock, prng: &'a Mutex) -> Self { + pub(crate) const fn new(inner: &'a RwLock, prng: &'a Mutex) -> Self { Self { inner, prng } } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs index b982cbb461..bd14c9aa4f 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs @@ -13,6 +13,8 @@ // pub mod auth; +#[cfg(feature = "auth_pubkey")] +pub(crate) mod multilink; pub(crate) mod qos; #[cfg(feature = "shared-memory")] pub(crate) mod shm; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs b/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs new file mode 100644 index 0000000000..524c8d82a8 --- /dev/null +++ b/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs @@ -0,0 +1,355 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{ + establishment::AcceptFsm, + unicast::establishment::{ + ext::auth::pubkey::{self, AuthPubKey, AuthPubKeyFsm, ZPublicKey}, + OpenFsm, + }, +}; +use async_std::sync::{Mutex, RwLock}; +use async_trait::async_trait; +use rand::{CryptoRng, Rng}; +use rsa::{RsaPrivateKey, RsaPublicKey}; +use std::collections::HashMap; +use zenoh_buffers::{ + reader::{DidntRead, HasReader, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_core::{bail, zasynclock, zasyncwrite, zerror, Error as ZError, Result as ZResult}; +use zenoh_crypto::PseudoRng; +use zenoh_protocol::{ + core::ZenohId, + transport::{init, open}, +}; + +const KEY_SIZE: usize = 512; + +// Extension Fsm +pub(crate) struct MultiLink { + known: Mutex>>, + pubkey: RwLock, +} + +impl MultiLink { + pub(crate) fn make(rng: &mut R) -> ZResult + where + R: Rng + CryptoRng, + { + let pri_key = RsaPrivateKey::new(rng, KEY_SIZE)?; + let pub_key = RsaPublicKey::from(&pri_key); + let s = Self { + known: Mutex::new(HashMap::new()), + pubkey: RwLock::new(AuthPubKey::new(pub_key.into(), pri_key.into())), + }; + Ok(s) + } + + pub(crate) fn open(&self, is_multilink: bool) -> StateOpen { + StateOpen { + pubkey: is_multilink.then_some(pubkey::StateOpen::new()), + } + } + + pub(crate) fn accept(&self, is_multilink: bool) -> StateAccept { + StateAccept { + pubkey: is_multilink.then_some(pubkey::StateAccept::new()), + } + } + + pub(crate) fn fsm<'a>(&'a self, prng: &'a Mutex) -> MultiLinkFsm<'a> { + MultiLinkFsm { + known: &self.known, + pubkey: &self.pubkey, + fsm: AuthPubKeyFsm::new(&self.pubkey, prng), + } + } + + pub(crate) async fn close(&self, zid: ZenohId) -> ZResult<()> { + if let Some(Some(pk)) = zasynclock!(self.known).remove(&zid) { + zasyncwrite!(self.pubkey).del_pubkey(&pk).await?; + } + Ok(()) + } +} + +pub(crate) struct MultiLinkFsm<'a> { + known: &'a Mutex>>, + pubkey: &'a RwLock, + fsm: AuthPubKeyFsm<'a>, +} + +/*************************************/ +/* OPEN */ +/*************************************/ +pub(crate) struct StateOpen { + pubkey: Option, +} + +impl StateOpen { + pub(crate) const fn is_multilink(&self) -> bool { + self.pubkey.is_some() + } +} + +#[async_trait] +impl<'a> OpenFsm for MultiLinkFsm<'a> { + type Error = ZError; + + type SendInitSynIn = &'a StateOpen; + type SendInitSynOut = Option; + async fn send_init_syn( + &self, + input: Self::SendInitSynIn, + ) -> Result { + let pubkey = match input.pubkey.as_ref() { + Some(pubkey) => pubkey, + None => return Ok(None), + }; + + let r = self.fsm.send_init_syn(pubkey).await?.map(|x| x.transmute()); + Ok(r) + } + + type RecvInitAckIn = (&'a mut StateOpen, Option); + type RecvInitAckOut = (); + async fn recv_init_ack( + &self, + input: Self::RecvInitAckIn, + ) -> Result { + let (state, mut ext) = input; + let pubkey = match state.pubkey.as_mut() { + Some(pubkey) => pubkey, + None => return Ok(()), + }; + + match ext.take() { + Some(ext) => { + self.fsm + .recv_init_ack((pubkey, Some(ext.transmute()))) + .await + } + None => { + state.pubkey = None; + Ok(()) + } + } + } + + type SendOpenSynIn = &'a StateOpen; + type SendOpenSynOut = Option; + async fn send_open_syn( + &self, + input: Self::SendOpenSynIn, + ) -> Result { + let pubkey = match input.pubkey.as_ref() { + Some(pubkey) => pubkey, + None => return Ok(None), + }; + + let r = self.fsm.send_open_syn(pubkey).await?.map(|x| x.transmute()); + Ok(r) + } + + type RecvOpenAckIn = (&'a mut StateOpen, Option); + type RecvOpenAckOut = (); + async fn recv_open_ack( + &self, + input: Self::RecvOpenAckIn, + ) -> Result { + let (state, mut ext) = input; + let pubkey = match state.pubkey.as_mut() { + Some(pubkey) => pubkey, + None => return Ok(()), + }; + + match ext.take() { + Some(ext) => { + self.fsm + .recv_open_ack((pubkey, Some(ext.transmute()))) + .await + } + None => { + state.pubkey = None; + Ok(()) + } + } + } +} + +/*************************************/ +/* ACCEPT */ +/*************************************/ +#[derive(Debug, PartialEq)] +pub(crate) struct StateAccept { + pubkey: Option, +} + +impl StateAccept { + #[cfg(test)] + pub(crate) fn rand() -> Self { + let mut rng = rand::thread_rng(); + Self { + pubkey: rng.gen_bool(0.5).then_some(pubkey::StateAccept::rand()), + } + } +} + +impl WCodec<&StateAccept, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &StateAccept) -> Self::Output { + match x.pubkey.as_ref() { + Some(p) => { + self.write(&mut *writer, 1u8)?; + self.write(&mut *writer, p) + } + None => self.write(&mut *writer, 0u8), + } + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let is_multilink: u8 = self.read(&mut *reader)?; + Ok(StateAccept { + pubkey: if is_multilink == 1 { + Some(self.read(&mut *reader)?) + } else { + None + }, + }) + } +} + +#[async_trait] +impl<'a> AcceptFsm for MultiLinkFsm<'a> { + type Error = ZError; + + type RecvInitSynIn = (&'a mut StateAccept, Option, ZenohId); + type RecvInitSynOut = (); + async fn recv_init_syn( + &self, + input: Self::RecvInitSynIn, + ) -> Result { + const S: &str = "MultiLink extension - Recv InitSyn."; + + let (state, mut ext, zid) = input; + let pubkey = match state.pubkey.as_mut() { + Some(pubkey) => pubkey, + None => return Ok(()), + }; + + match ext.take() { + Some(ext) => { + // Verify if the configuration is coherent with what we have in memory + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let init_syn: pubkey::InitSyn = codec + .read(&mut reader) + .map_err(|_| zerror!("{S} Decoding error."))?; + + { + let mut m_known = zasynclock!(self.known); + match m_known.get(&zid) { + Some(Some(pk)) if pk != &init_syn.alice_pubkey => { + bail!("{S} Spoofing detected."); + } + Some(None) => bail!("{S} Spoofing detected."), + _ => {} + } + m_known.insert(zid, Some(init_syn.alice_pubkey.clone())); + zasyncwrite!(self.pubkey) + .add_pubkey(init_syn.alice_pubkey) + .await?; + } + + self.fsm + .recv_open_syn((pubkey, Some(ext.transmute()))) + .await + } + None => { + // Verify if the configuration is coherent with what we have in memory + let mut m_known = zasynclock!(self.known); + match m_known.get(&zid) { + Some(Some(_)) => { + bail!("{S} Spoofing detected."); + } + Some(None) => {} + None => { + let _ = m_known.insert(zid, None); + } + } + state.pubkey = None; + Ok(()) + } + } + } + + type SendInitAckIn = &'a StateAccept; + type SendInitAckOut = Option; + async fn send_init_ack( + &self, + input: Self::SendInitAckIn, + ) -> Result { + let pubkey = match input.pubkey.as_ref() { + Some(pubkey) => pubkey, + None => return Ok(None), + }; + + let r = self.fsm.send_init_ack(pubkey).await?.map(|x| x.transmute()); + Ok(r) + } + + type RecvOpenSynIn = (&'a mut StateAccept, Option); + type RecvOpenSynOut = (); + async fn recv_open_syn( + &self, + input: Self::RecvOpenSynIn, + ) -> Result { + let (state, ext) = input; + let pubkey = match state.pubkey.as_mut() { + Some(pubkey) => pubkey, + None => return Ok(()), + }; + + self.fsm + .recv_open_syn((pubkey, ext.map(|x| x.transmute()))) + .await + } + + type SendOpenAckIn = &'a StateAccept; + type SendOpenAckOut = Option; + async fn send_open_ack( + &self, + input: Self::SendOpenAckIn, + ) -> Result { + let pubkey = match input.pubkey.as_ref() { + Some(pubkey) => pubkey, + None => return Ok(None), + }; + + let r = self.fsm.send_open_ack(pubkey).await?.map(|x| x.transmute()); + Ok(r) + } +} diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 5006d6f86d..028c11feb3 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -116,7 +116,15 @@ pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) - ZInt::from_le_bytes(array) & seq_num::get_mask(resolution.get(Field::FrameSN)) } -pub(super) async fn close_link(link: &LinkUnicast, reason: Option) { +pub(super) async fn close_link( + link: &LinkUnicast, + manager: &TransportManager, + zid: ZenohId, + reason: Option, +) { + #[cfg(feature = "auth_pubkey")] + let _ = manager.state.unicast.multilink.close(zid).await; + if let Some(reason) = reason { // Build the close message let message: TransportMessage = Close { diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 10225a2e6f..66d24f4463 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -23,7 +23,7 @@ use async_trait::async_trait; use std::time::Duration; use zenoh_buffers::ZSlice; use zenoh_config::{WhatAmI, ZenohId}; -use zenoh_core::{zasynclock, zerror}; +use zenoh_core::{zasynclock, zerror}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::core::{Field, Resolution, ZInt}; use zenoh_protocol::transport::{close, Close, InitSyn, OpenSyn, TransportBody, TransportMessage}; @@ -409,7 +409,8 @@ pub(crate) async fn open_link( match $s { Ok(output) => output, Err((e, reason)) => { - close_link(link, reason).await; + // @TODO + close_link(link, manager, ZenohId::default(), reason).await; return Err(e); } } diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 9768b3aa09..739ed9ccd0 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -11,6 +11,8 @@ // Contributors: // ZettaScale Zenoh Team, // +#[cfg(feature = "auth_pubkey")] +use crate::unicast::establishment::ext::multilink::MultiLink; #[cfg(feature = "shared-memory")] use crate::unicast::shm::SharedMemoryUnicast; use crate::{ @@ -26,6 +28,7 @@ use std::{collections::HashMap, sync::Arc, time::Duration}; use zenoh_config::SharedMemoryConf; use zenoh_config::{Config, LinkTxConf, QoSConf, TransportUnicastConf}; use zenoh_core::zasynclock; +use zenoh_crypto::PseudoRng; use zenoh_link::*; use zenoh_protocol::{ core::{endpoint, locator::LocatorProtocol, ZenohId}, @@ -60,6 +63,8 @@ pub struct TransportManagerStateUnicast { // Shared memory #[cfg(feature = "shared-memory")] pub(super) shm: Arc, + // Multilink + pub(super) multilink: Arc, } pub struct TransportManagerParamsUnicast { @@ -157,6 +162,7 @@ impl TransportManagerBuilderUnicast { pub fn build( #[allow(unused_mut)] // auth_pubkey and shared-memory features require mut mut self, + prng: &mut PseudoRng, ) -> ZResult { let config = TransportManagerConfigUnicast { lease: self.lease, @@ -177,6 +183,8 @@ impl TransportManagerBuilderUnicast { authenticator: Arc::new(self.authenticator), #[cfg(feature = "shared-memory")] shm: Arc::new(SharedMemoryUnicast::make()?), + #[cfg(feature = "auth_pubkey")] + multilink: Arc::new(MultiLink::make(prng)?), }; let params = TransportManagerParamsUnicast { config, state }; From 9d7f6ccd1720b448703c39195691ca27f74428c1 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 11 Mar 2023 00:16:29 +0100 Subject: [PATCH 074/203] Multilink negotiation - No spoofing tests yet --- io/zenoh-transport/Cargo.toml | 1 + .../src/unicast/establishment/accept.rs | 68 +- .../src/unicast/establishment/cookie.rs | 17 +- .../unicast/establishment/ext/auth/pubkey.rs | 32 +- .../src/unicast/establishment/ext/mod.rs | 2 +- .../unicast/establishment/ext/multilink.rs | 183 ++--- .../src/unicast/establishment/mod.rs | 10 +- .../src/unicast/establishment/open.rs | 51 +- io/zenoh-transport/src/unicast/manager.rs | 22 +- io/zenoh-transport/src/unicast/mod.rs | 6 +- io/zenoh-transport/src/unicast/transport.rs | 8 +- io/zenoh-transport/tests/unicast_openclose.rs | 677 ------------------ zenoh/Cargo.toml | 2 + 13 files changed, 245 insertions(+), 834 deletions(-) delete mode 100644 io/zenoh-transport/tests/unicast_openclose.rs diff --git a/io/zenoh-transport/Cargo.toml b/io/zenoh-transport/Cargo.toml index 51a991c0d6..8be7e8a6bf 100644 --- a/io/zenoh-transport/Cargo.toml +++ b/io/zenoh-transport/Cargo.toml @@ -32,6 +32,7 @@ shared-memory = [ ] auth_pubkey = ["rsa"] auth_usrpwd = [] +transport_multilink = ["auth_pubkey"] transport_quic = ["zenoh-link/transport_quic"] transport_tcp = ["zenoh-link/transport_tcp"] transport_tls = ["zenoh-link/transport_tls"] diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 6ce0dfe0c5..6e3078e9a9 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -41,7 +41,6 @@ use zenoh_result::ZResult; pub(super) type AcceptError = (zenoh_result::Error, Option); struct StateZenoh { - other_zid: ZenohId, batch_size: u16, resolution: Resolution, } @@ -52,6 +51,7 @@ struct State { #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateAccept, ext_auth: ext::auth::StateAccept, + #[cfg(feature = "transport_multilink")] ext_mlink: ext::multilink::StateAccept, } @@ -60,6 +60,7 @@ struct RecvInitSynIn { mine_version: u8, } struct RecvInitSynOut { + other_zid: ZenohId, other_whatami: WhatAmI, #[cfg(feature = "shared-memory")] ext_shm: Challenge, @@ -70,21 +71,21 @@ struct SendInitAckIn { mine_version: u8, mine_zid: ZenohId, mine_whatami: WhatAmI, + other_zid: ZenohId, other_whatami: WhatAmI, #[cfg(feature = "shared-memory")] ext_shm: Challenge, } struct SendInitAckOut { - other_zid: ZenohId, cookie_nonce: ZInt, } // OpenSyn struct RecvOpenSynIn { - other_zid: ZenohId, cookie_nonce: ZInt, } struct RecvOpenSynOut { + other_zid: ZenohId, other_whatami: WhatAmI, other_lease: Duration, other_initial_sn: ZInt, @@ -94,6 +95,7 @@ struct RecvOpenSynOut { struct SendOpenAckIn { mine_zid: ZenohId, mine_lease: Duration, + other_zid: ZenohId, } struct SendOpenAckOut { open_ack: OpenAck, @@ -108,7 +110,7 @@ struct AcceptLink<'a> { #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm<'a>, ext_auth: ext::auth::AuthFsm<'a>, - #[cfg(feature = "auth_pubkey")] + #[cfg(feature = "transport_multilink")] ext_mlink: ext::multilink::MultiLinkFsm<'a>, } @@ -142,9 +144,6 @@ impl<'a> AcceptFsm for AcceptLink<'a> { } }; - // Store the ZenohId - state.zenoh.other_zid = init_syn.zid; - // Check if the version is supported if init_syn.version != input.mine_version { let e = zerror!( @@ -196,12 +195,14 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension MultiLink + #[cfg(feature = "transport_multilink")] self.ext_mlink - .recv_init_syn((&mut state.ext_mlink, init_syn.ext_mlink, init_syn.zid)) + .recv_init_syn((&mut state.ext_mlink, init_syn.ext_mlink)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; let output = RecvInitSynOut { + other_zid: init_syn.zid, other_whatami: init_syn.whatami, #[cfg(feature = "shared-memory")] ext_shm, @@ -242,6 +243,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension MultiLink + #[cfg(feature = "transport_multilink")] let ext_mlink = self .ext_mlink .send_init_ack(&state.ext_mlink) @@ -251,6 +253,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { // Create the cookie let cookie_nonce: ZInt = zasynclock!(self.prng).gen(); let cookie = Cookie { + zid: input.other_zid, whatami: input.other_whatami, resolution: state.zenoh.resolution, batch_size: state.zenoh.batch_size, @@ -259,7 +262,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { #[cfg(feature = "shared-memory")] ext_shm: state.ext_shm, ext_auth: state.ext_auth, - #[cfg(feature = "auth_pubkey")] + #[cfg(feature = "transport_multilink")] ext_mlink: state.ext_mlink, }; @@ -299,10 +302,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - let output = SendInitAckOut { - other_zid: state.zenoh.other_zid, - cookie_nonce, - }; + let output = SendInitAckOut { cookie_nonce }; Ok(output) } @@ -369,7 +369,6 @@ impl<'a> AcceptFsm for AcceptLink<'a> { // Rebuild the state from the cookie let mut state = State { zenoh: StateZenoh { - other_zid: input.other_zid, batch_size: cookie.batch_size, resolution: cookie.resolution, }, @@ -400,12 +399,14 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension MultiLink + #[cfg(feature = "transport_multilink")] self.ext_mlink .recv_open_syn((&mut state.ext_mlink, open_syn.ext_mlink)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; let output = RecvOpenSynOut { + other_zid: cookie.zid, other_whatami: cookie.whatami, other_lease: open_syn.lease, other_initial_sn: open_syn.initial_sn, @@ -445,19 +446,23 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension MultiLink + #[cfg(feature = "transport_multilink")] + let ext_mlink = self + .ext_mlink + .send_open_ack(&state.ext_mlink) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Build OpenAck message - let mine_initial_sn = compute_sn( - input.mine_zid, - state.zenoh.other_zid, - state.zenoh.resolution, - ); + let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); let open_ack = OpenAck { lease: input.mine_lease, initial_sn: mine_initial_sn, ext_qos, ext_shm, ext_auth, - ext_mlink: None, // @TODO + ext_mlink, }; // Do not send the OpenAck right now since we might still incur in MAX_LINKS error @@ -476,7 +481,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), ext_auth: manager.state.unicast.authenticator.fsm(&manager.prng), - #[cfg(feature = "auth_pubkey")] + #[cfg(feature = "transport_multilink")] ext_mlink: manager.state.unicast.multilink.fsm(&manager.prng), }; @@ -487,8 +492,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) Ok(output) => output, Err((e, reason)) => { log::error!("{}", e); - // @TODO - close_link(link, manager, ZenohId::default(), reason).await; + close_link(link, reason).await; return Err(e); } } @@ -498,7 +502,6 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) let iack_out = { let mut state = State { zenoh: StateZenoh { - other_zid: manager.config.zid, // This is a temporary value batch_size: manager.config.batch_size, resolution: manager.config.resolution, }, @@ -510,8 +513,12 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) .unicast .authenticator .accept(&mut *zasynclock!(manager.prng)), - #[cfg(feature = "auth_pubkey")] - ext_mlink: manager.state.unicast.multilink.accept(false), // @TODO + #[cfg(feature = "transport_multilink")] + ext_mlink: manager + .state + .unicast + .multilink + .accept(manager.config.unicast.max_links > 1), }; // Let's scope the Init phase in such a way memory is freed by Rust @@ -526,6 +533,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) mine_version: manager.config.version, mine_zid: manager.config.zid, mine_whatami: manager.config.whatami, + other_zid: isyn_out.other_zid, other_whatami: isyn_out.other_whatami, #[cfg(feature = "shared-memory")] ext_shm: isyn_out.ext_shm, @@ -535,7 +543,6 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) // Open handshake let osyn_in = RecvOpenSynIn { - other_zid: iack_out.other_zid, cookie_nonce: iack_out.cookie_nonce, }; let (mut state, osyn_out) = step!(fsm.recv_open_syn(osyn_in).await); @@ -544,15 +551,18 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) let oack_in = SendOpenAckIn { mine_zid: manager.config.zid, mine_lease: manager.config.unicast.lease, + other_zid: osyn_out.other_zid, }; let oack_out = step!(fsm.send_open_ack((&mut state, oack_in)).await); // Initialize the transport let config = TransportConfigUnicast { - zid: state.zenoh.other_zid, + zid: osyn_out.other_zid, whatami: osyn_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN), tx_initial_sn: oack_out.open_ack.initial_sn, + #[cfg(feature = "transport_multilink")] + multilink: state.ext_mlink.multilink(), is_qos: state.ext_qos.is_qos(), #[cfg(feature = "shared-memory")] is_shm: state.ext_shm.is_shm(), @@ -596,7 +606,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) log::debug!( "New transport link accepted from {} to {}: {}", - state.zenoh.other_zid, + osyn_out.other_zid, manager.config.zid, link ); diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 4623bf28ea..3b277f5007 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -20,10 +20,11 @@ use zenoh_buffers::{ }; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_crypto::{BlockCipher, PseudoRng}; -use zenoh_protocol::core::{Resolution, WhatAmI, ZInt}; +use zenoh_protocol::core::{Resolution, WhatAmI, ZInt, ZenohId}; #[derive(Debug, PartialEq)] pub(crate) struct Cookie { + pub(crate) zid: ZenohId, pub(crate) whatami: WhatAmI, pub(crate) resolution: Resolution, pub(crate) batch_size: u16, @@ -33,7 +34,7 @@ pub(crate) struct Cookie { #[cfg(feature = "shared-memory")] pub(crate) ext_shm: ext::shm::StateAccept, pub(crate) ext_auth: ext::auth::StateAccept, - #[cfg(feature = "auth_pubkey")] + #[cfg(feature = "transport_multilink")] pub(crate) ext_mlink: ext::multilink::StateAccept, } @@ -44,6 +45,7 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Cookie) -> Self::Output { + self.write(&mut *writer, &x.zid)?; let wai: u8 = x.whatami.into(); self.write(&mut *writer, wai)?; self.write(&mut *writer, x.resolution.as_u8())?; @@ -54,7 +56,7 @@ where #[cfg(feature = "shared-memory")] self.write(&mut *writer, &x.ext_shm)?; self.write(&mut *writer, &x.ext_auth)?; - #[cfg(feature = "auth_pubkey")] + #[cfg(feature = "transport_multilink")] self.write(&mut *writer, &x.ext_mlink)?; Ok(()) @@ -68,6 +70,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { + let zid: ZenohId = self.read(&mut *reader)?; let wai: u8 = self.read(&mut *reader)?; let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; let resolution: u8 = self.read(&mut *reader)?; @@ -79,10 +82,11 @@ where #[cfg(feature = "shared-memory")] let ext_shm: ext::shm::StateAccept = self.read(&mut *reader)?; let ext_auth: ext::auth::StateAccept = self.read(&mut *reader)?; - #[cfg(feature = "auth_pubkey")] + #[cfg(feature = "transport_multilink")] let ext_mlink: ext::multilink::StateAccept = self.read(&mut *reader)?; let cookie = Cookie { + zid, whatami, resolution, batch_size, @@ -91,7 +95,7 @@ where #[cfg(feature = "shared-memory")] ext_shm, ext_auth, - #[cfg(feature = "auth_pubkey")] + #[cfg(feature = "transport_multilink")] ext_mlink, }; @@ -149,6 +153,7 @@ impl Cookie { let mut rng = rand::thread_rng(); Self { + zid: ZenohId::default(), whatami: WhatAmI::rand(), resolution: Resolution::rand(), batch_size: rng.gen(), @@ -157,7 +162,7 @@ impl Cookie { #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateAccept::rand(), ext_auth: ext::auth::StateAccept::rand(), - #[cfg(feature = "auth_pubkey")] + #[cfg(feature = "transport_multilink")] ext_mlink: ext::multilink::StateAccept::rand(), } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs index 294428afb5..89530070fd 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs @@ -38,7 +38,7 @@ use crate::establishment::{AcceptFsm, OpenFsm}; // Authenticator #[derive(Debug)] pub struct AuthPubKey { - lookup: HashSet, + lookup: Option>, pub_key: ZPublicKey, pri_key: ZPrivateKey, } @@ -46,19 +46,27 @@ pub struct AuthPubKey { impl AuthPubKey { pub fn new(pub_key: ZPublicKey, pri_key: ZPrivateKey) -> Self { Self { - lookup: HashSet::new(), + lookup: Some(HashSet::new()), pub_key, pri_key, } } + pub(crate) fn disable_lookup(&mut self) { + self.lookup = None; + } + pub async fn add_pubkey(&mut self, pub_key: ZPublicKey) -> ZResult<()> { - self.lookup.insert(pub_key); + if let Some(lookup) = self.lookup.as_mut() { + lookup.insert(pub_key); + } Ok(()) } pub async fn del_pubkey(&mut self, pub_key: &ZPublicKey) -> ZResult<()> { - self.lookup.remove(pub_key); + if let Some(lookup) = self.lookup.as_mut() { + lookup.remove(pub_key); + } Ok(()) } @@ -379,8 +387,10 @@ impl<'a> OpenFsm for AuthPubKeyFsm<'a> { .map_err(|_| zerror!("{S} Decoding error."))?; let r_inner = zasyncread!(self.inner); - if !r_inner.lookup.is_empty() && !r_inner.lookup.contains(&init_ack.bob_pubkey) { - bail!("{S} Unauthorized PubKey."); + if let Some(lookup) = r_inner.lookup.as_ref() { + if !lookup.is_empty() && !lookup.contains(&init_ack.bob_pubkey) { + bail!("{S} Unauthorized PubKey."); + } } let mut prng = zasynclock!(self.prng); @@ -529,11 +539,11 @@ impl<'a> AcceptFsm for AuthPubKeyFsm<'a> { .read(&mut reader) .map_err(|_| zerror!("{S} Decoding error."))?; - if !zasyncread!(self.inner) - .lookup - .contains(&init_syn.alice_pubkey) - { - bail!("{S} Unauthorized PubKey."); + let r_inner = zasyncread!(self.inner); + if let Some(lookup) = r_inner.lookup.as_ref() { + if !lookup.contains(&init_syn.alice_pubkey) { + bail!("{S} Unauthorized PubKey."); + } } let mut prng = zasynclock!(self.prng); diff --git a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs index bd14c9aa4f..728972f80b 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs @@ -13,7 +13,7 @@ // pub mod auth; -#[cfg(feature = "auth_pubkey")] +#[cfg(feature = "transport_multilink")] pub(crate) mod multilink; pub(crate) mod qos; #[cfg(feature = "shared-memory")] diff --git a/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs b/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs index 524c8d82a8..2e71bd4a02 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs @@ -21,25 +21,20 @@ use crate::{ use async_std::sync::{Mutex, RwLock}; use async_trait::async_trait; use rand::{CryptoRng, Rng}; -use rsa::{RsaPrivateKey, RsaPublicKey}; -use std::collections::HashMap; +use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; use zenoh_buffers::{ reader::{DidntRead, HasReader, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_core::{bail, zasynclock, zasyncwrite, zerror, Error as ZError, Result as ZResult}; +use zenoh_core::{zerror, Error as ZError, Result as ZResult}; use zenoh_crypto::PseudoRng; -use zenoh_protocol::{ - core::ZenohId, - transport::{init, open}, -}; +use zenoh_protocol::transport::{init, open}; const KEY_SIZE: usize = 512; // Extension Fsm pub(crate) struct MultiLink { - known: Mutex>>, pubkey: RwLock, } @@ -50,44 +45,39 @@ impl MultiLink { { let pri_key = RsaPrivateKey::new(rng, KEY_SIZE)?; let pub_key = RsaPublicKey::from(&pri_key); - let s = Self { - known: Mutex::new(HashMap::new()), - pubkey: RwLock::new(AuthPubKey::new(pub_key.into(), pri_key.into())), - }; - Ok(s) + let mut auth = AuthPubKey::new(pub_key.into(), pri_key.into()); + auth.disable_lookup(); + Ok(Self { + pubkey: RwLock::new(auth), + }) } pub(crate) fn open(&self, is_multilink: bool) -> StateOpen { StateOpen { - pubkey: is_multilink.then_some(pubkey::StateOpen::new()), + pubkey: is_multilink.then_some(( + pubkey::StateOpen::new(), + RsaPublicKey::new_unchecked(BigUint::new(vec![]), BigUint::new(vec![])).into(), + )), } } pub(crate) fn accept(&self, is_multilink: bool) -> StateAccept { StateAccept { - pubkey: is_multilink.then_some(pubkey::StateAccept::new()), + pubkey: is_multilink.then_some(( + pubkey::StateAccept::new(), + RsaPublicKey::new_unchecked(BigUint::new(vec![]), BigUint::new(vec![])).into(), + )), } } pub(crate) fn fsm<'a>(&'a self, prng: &'a Mutex) -> MultiLinkFsm<'a> { MultiLinkFsm { - known: &self.known, - pubkey: &self.pubkey, fsm: AuthPubKeyFsm::new(&self.pubkey, prng), } } - - pub(crate) async fn close(&self, zid: ZenohId) -> ZResult<()> { - if let Some(Some(pk)) = zasynclock!(self.known).remove(&zid) { - zasyncwrite!(self.pubkey).del_pubkey(&pk).await?; - } - Ok(()) - } } pub(crate) struct MultiLinkFsm<'a> { - known: &'a Mutex>>, - pubkey: &'a RwLock, fsm: AuthPubKeyFsm<'a>, } @@ -95,12 +85,12 @@ pub(crate) struct MultiLinkFsm<'a> { /* OPEN */ /*************************************/ pub(crate) struct StateOpen { - pubkey: Option, + pubkey: Option<(pubkey::StateOpen, ZPublicKey)>, } impl StateOpen { - pub(crate) const fn is_multilink(&self) -> bool { - self.pubkey.is_some() + pub(crate) fn multilink(&self) -> Option { + self.pubkey.as_ref().map(|(_, p)| p.clone()) } } @@ -119,7 +109,11 @@ impl<'a> OpenFsm for MultiLinkFsm<'a> { None => return Ok(None), }; - let r = self.fsm.send_init_syn(pubkey).await?.map(|x| x.transmute()); + let r = self + .fsm + .send_init_syn(&pubkey.0) + .await? + .map(|x| x.transmute()); Ok(r) } @@ -129,23 +123,33 @@ impl<'a> OpenFsm for MultiLinkFsm<'a> { &self, input: Self::RecvInitAckIn, ) -> Result { + const S: &str = "MultiLink extension - Recv InitAck."; + let (state, mut ext) = input; - let pubkey = match state.pubkey.as_mut() { + let mut pubkey = match state.pubkey.take() { Some(pubkey) => pubkey, None => return Ok(()), }; match ext.take() { Some(ext) => { + let codec = Zenoh080::new(); + let mut reader = ext.value.reader(); + let init_ack: pubkey::InitAck = codec + .read(&mut reader) + .map_err(|_| zerror!("{S} Decoding error."))?; + self.fsm - .recv_init_ack((pubkey, Some(ext.transmute()))) - .await + .recv_init_ack((&mut pubkey.0, Some(ext.transmute()))) + .await?; + + state.pubkey = Some((pubkey.0, init_ack.bob_pubkey)); } None => { state.pubkey = None; - Ok(()) } } + Ok(()) } type SendOpenSynIn = &'a StateOpen; @@ -159,7 +163,11 @@ impl<'a> OpenFsm for MultiLinkFsm<'a> { None => return Ok(None), }; - let r = self.fsm.send_open_syn(pubkey).await?.map(|x| x.transmute()); + let r = self + .fsm + .send_open_syn(&pubkey.0) + .await? + .map(|x| x.transmute()); Ok(r) } @@ -178,14 +186,15 @@ impl<'a> OpenFsm for MultiLinkFsm<'a> { match ext.take() { Some(ext) => { self.fsm - .recv_open_ack((pubkey, Some(ext.transmute()))) - .await + .recv_open_ack((&mut pubkey.0, Some(ext.transmute()))) + .await?; } None => { state.pubkey = None; - Ok(()) } } + + Ok(()) } } @@ -194,16 +203,32 @@ impl<'a> OpenFsm for MultiLinkFsm<'a> { /*************************************/ #[derive(Debug, PartialEq)] pub(crate) struct StateAccept { - pubkey: Option, + pubkey: Option<(pubkey::StateAccept, ZPublicKey)>, } impl StateAccept { + pub(crate) fn multilink(&self) -> Option { + self.pubkey.as_ref().map(|(_, p)| p.clone()) + } + #[cfg(test)] pub(crate) fn rand() -> Self { let mut rng = rand::thread_rng(); - Self { - pubkey: rng.gen_bool(0.5).then_some(pubkey::StateAccept::rand()), - } + let pubkey = if rng.gen_bool(0.5) { + let n = BigUint::from_bytes_le(&[ + 0x41, 0x74, 0xc6, 0x40, 0x18, 0x63, 0xbd, 0x59, 0xe6, 0x0d, 0xe9, 0x23, 0x3e, 0x95, + 0xca, 0xb4, 0x5d, 0x17, 0x3d, 0x14, 0xdd, 0xbb, 0x16, 0x4a, 0x49, 0xeb, 0x43, 0x27, + 0x79, 0x3e, 0x75, 0x67, 0xd6, 0xf6, 0x7f, 0xe7, 0xbf, 0xb5, 0x1d, 0xf6, 0x27, 0x80, + 0xca, 0x26, 0x35, 0xa2, 0xc5, 0x4c, 0x96, 0x50, 0xaa, 0x9f, 0xf4, 0x47, 0xbe, 0x06, + 0x9c, 0xd1, 0xec, 0xfd, 0x1e, 0x81, 0xe9, 0xc4, + ]); + let e = BigUint::from_bytes_le(&[0x01, 0x00, 0x01]); + let pub_key = RsaPublicKey::new(n, e).unwrap(); + Some((pubkey::StateAccept::rand(), pub_key.into())) + } else { + None + }; + Self { pubkey } } } @@ -215,8 +240,9 @@ where fn write(self, writer: &mut W, x: &StateAccept) -> Self::Output { match x.pubkey.as_ref() { - Some(p) => { + Some((s, p)) => { self.write(&mut *writer, 1u8)?; + self.write(&mut *writer, s)?; self.write(&mut *writer, p) } None => self.write(&mut *writer, 0u8), @@ -232,13 +258,14 @@ where fn read(self, reader: &mut R) -> Result { let is_multilink: u8 = self.read(&mut *reader)?; - Ok(StateAccept { - pubkey: if is_multilink == 1 { - Some(self.read(&mut *reader)?) - } else { - None - }, - }) + let pubkey = if is_multilink == 1 { + let s: pubkey::StateAccept = self.read(&mut *reader)?; + let p: ZPublicKey = self.read(&mut *reader)?; + Some((s, p)) + } else { + None + }; + Ok(StateAccept { pubkey }) } } @@ -246,7 +273,7 @@ where impl<'a> AcceptFsm for MultiLinkFsm<'a> { type Error = ZError; - type RecvInitSynIn = (&'a mut StateAccept, Option, ZenohId); + type RecvInitSynIn = (&'a mut StateAccept, Option); type RecvInitSynOut = (); async fn recv_init_syn( &self, @@ -254,56 +281,32 @@ impl<'a> AcceptFsm for MultiLinkFsm<'a> { ) -> Result { const S: &str = "MultiLink extension - Recv InitSyn."; - let (state, mut ext, zid) = input; - let pubkey = match state.pubkey.as_mut() { + let (mut state, mut ext) = input; + let mut pubkey = match state.pubkey.take() { Some(pubkey) => pubkey, None => return Ok(()), }; match ext.take() { Some(ext) => { - // Verify if the configuration is coherent with what we have in memory let codec = Zenoh080::new(); let mut reader = ext.value.reader(); let init_syn: pubkey::InitSyn = codec .read(&mut reader) .map_err(|_| zerror!("{S} Decoding error."))?; - { - let mut m_known = zasynclock!(self.known); - match m_known.get(&zid) { - Some(Some(pk)) if pk != &init_syn.alice_pubkey => { - bail!("{S} Spoofing detected."); - } - Some(None) => bail!("{S} Spoofing detected."), - _ => {} - } - m_known.insert(zid, Some(init_syn.alice_pubkey.clone())); - zasyncwrite!(self.pubkey) - .add_pubkey(init_syn.alice_pubkey) - .await?; - } - self.fsm - .recv_open_syn((pubkey, Some(ext.transmute()))) - .await + .recv_init_syn((&mut pubkey.0, Some(ext.transmute()))) + .await?; + + state.pubkey = Some((pubkey.0, init_syn.alice_pubkey)); } None => { - // Verify if the configuration is coherent with what we have in memory - let mut m_known = zasynclock!(self.known); - match m_known.get(&zid) { - Some(Some(_)) => { - bail!("{S} Spoofing detected."); - } - Some(None) => {} - None => { - let _ = m_known.insert(zid, None); - } - } state.pubkey = None; - Ok(()) } } + + Ok(()) } type SendInitAckIn = &'a StateAccept; @@ -317,7 +320,11 @@ impl<'a> AcceptFsm for MultiLinkFsm<'a> { None => return Ok(None), }; - let r = self.fsm.send_init_ack(pubkey).await?.map(|x| x.transmute()); + let r = self + .fsm + .send_init_ack(&pubkey.0) + .await? + .map(|x| x.transmute()); Ok(r) } @@ -334,7 +341,7 @@ impl<'a> AcceptFsm for MultiLinkFsm<'a> { }; self.fsm - .recv_open_syn((pubkey, ext.map(|x| x.transmute()))) + .recv_open_syn((&mut pubkey.0, ext.map(|x| x.transmute()))) .await } @@ -349,7 +356,11 @@ impl<'a> AcceptFsm for MultiLinkFsm<'a> { None => return Ok(None), }; - let r = self.fsm.send_open_ack(pubkey).await?.map(|x| x.transmute()); + let r = self + .fsm + .send_open_ack(&pubkey.0) + .await? + .map(|x| x.transmute()); Ok(r) } } diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 028c11feb3..5006d6f86d 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -116,15 +116,7 @@ pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) - ZInt::from_le_bytes(array) & seq_num::get_mask(resolution.get(Field::FrameSN)) } -pub(super) async fn close_link( - link: &LinkUnicast, - manager: &TransportManager, - zid: ZenohId, - reason: Option, -) { - #[cfg(feature = "auth_pubkey")] - let _ = manager.state.unicast.multilink.close(zid).await; - +pub(super) async fn close_link(link: &LinkUnicast, reason: Option) { if let Some(reason) = reason { // Build the close message let message: TransportMessage = Close { diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 66d24f4463..f3b1e44041 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -42,6 +42,8 @@ struct State { #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateOpen, ext_auth: ext::auth::StateOpen, + #[cfg(feature = "transport_multilink")] + ext_mlink: ext::multilink::StateOpen, } // InitSyn @@ -88,6 +90,8 @@ struct OpenLink<'a> { #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm<'a>, ext_auth: ext::auth::AuthFsm<'a>, + #[cfg(feature = "transport_multilink")] + ext_mlink: ext::multilink::MultiLinkFsm<'a>, } #[async_trait] @@ -126,6 +130,14 @@ impl<'a> OpenFsm for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension MultiLink + #[cfg(feature = "transport_multilink")] + let ext_mlink = self + .ext_mlink + .send_init_syn(&state.ext_mlink) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let msg: TransportMessage = InitSyn { version: input.mine_version, whatami: input.mine_whatami, @@ -135,7 +147,7 @@ impl<'a> OpenFsm for OpenLink<'a> { ext_qos, ext_shm, ext_auth, - ext_mlink: None, // @TODO + ext_mlink, } .into(); @@ -247,6 +259,13 @@ impl<'a> OpenFsm for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension MultiLink + #[cfg(feature = "transport_multilink")] + self.ext_mlink + .recv_init_ack((&mut state.ext_mlink, init_ack.ext_mlink)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvInitAckOut { other_zid: init_ack.zid, other_whatami: init_ack.whatami, @@ -289,6 +308,14 @@ impl<'a> OpenFsm for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension MultiLink + #[cfg(feature = "transport_multilink")] + let ext_mlink = self + .ext_mlink + .send_open_syn(&state.ext_mlink) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Build and send an OpenSyn message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); let message: TransportMessage = OpenSyn { @@ -298,7 +325,7 @@ impl<'a> OpenFsm for OpenLink<'a> { ext_qos, ext_shm, ext_auth, - ext_mlink: None, // @TODO + ext_mlink, } .into(); @@ -368,6 +395,13 @@ impl<'a> OpenFsm for OpenLink<'a> { .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; + // Extension MultiLink + #[cfg(feature = "transport_multilink")] + self.ext_mlink + .recv_open_ack((&mut state.ext_mlink, open_ack.ext_mlink)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let output = RecvOpenAckOut { other_initial_sn: open_ack.initial_sn, other_lease: open_ack.lease, @@ -386,6 +420,8 @@ pub(crate) async fn open_link( #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), ext_auth: manager.state.unicast.authenticator.fsm(&manager.prng), + #[cfg(feature = "transport_multilink")] + ext_mlink: manager.state.unicast.multilink.fsm(&manager.prng), }; let mut state = State { @@ -401,6 +437,12 @@ pub(crate) async fn open_link( .unicast .authenticator .open(&mut *zasynclock!(manager.prng)), + #[cfg(feature = "transport_multilink")] + ext_mlink: manager + .state + .unicast + .multilink + .open(manager.config.unicast.max_links > 1), }; // Init handshake @@ -409,8 +451,7 @@ pub(crate) async fn open_link( match $s { Ok(output) => output, Err((e, reason)) => { - // @TODO - close_link(link, manager, ZenohId::default(), reason).await; + close_link(link, reason).await; return Err(e); } } @@ -450,6 +491,8 @@ pub(crate) async fn open_link( is_shm: state.ext_shm.is_shm(), #[cfg(not(feature = "shared-memory"))] is_shm: false, + #[cfg(feature = "transport_multilink")] + multilink: state.ext_mlink.multilink(), }; let transport = step!(manager .init_transport_unicast(config) diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 739ed9ccd0..7dd5c4c17a 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -#[cfg(feature = "auth_pubkey")] +#[cfg(feature = "transport_multilink")] use crate::unicast::establishment::ext::multilink::MultiLink; #[cfg(feature = "shared-memory")] use crate::unicast::shm::SharedMemoryUnicast; @@ -159,11 +159,7 @@ impl TransportManagerBuilderUnicast { Ok(self) } - pub fn build( - #[allow(unused_mut)] // auth_pubkey and shared-memory features require mut - mut self, - prng: &mut PseudoRng, - ) -> ZResult { + pub fn build(self, prng: &mut PseudoRng) -> ZResult { let config = TransportManagerConfigUnicast { lease: self.lease, keep_alive: self.keep_alive, @@ -183,7 +179,7 @@ impl TransportManagerBuilderUnicast { authenticator: Arc::new(self.authenticator), #[cfg(feature = "shared-memory")] shm: Arc::new(SharedMemoryUnicast::make()?), - #[cfg(feature = "auth_pubkey")] + #[cfg(feature = "transport_multilink")] multilink: Arc::new(MultiLink::make(prng)?), }; @@ -375,6 +371,11 @@ impl TransportManager { } // Create the transport + #[cfg(not(feature = "transport_multilink"))] + let is_multilink = false; + #[cfg(feature = "transport_multilink")] + let is_multilink = config.multilink.is_some(); + let stc = TransportConfigUnicast { zid: config.zid, whatami: config.whatami, @@ -382,6 +383,8 @@ impl TransportManager { tx_initial_sn: config.tx_initial_sn, is_shm: config.is_shm, is_qos: config.is_qos, + #[cfg(feature = "transport_multilink")] + multilink: config.multilink, }; let a_t = Arc::new(TransportUnicastInner::make(self.clone(), stc)?); @@ -390,14 +393,15 @@ impl TransportManager { guard.insert(config.zid, a_t); log::debug!( - "New transport opened between {} and {}: whatami {}, sn resolution {:?}, initial sn {:?}, shm: {}, qos: {}", + "New transport opened between {} and {} - whatami: {}, sn resolution: {:?}, initial sn: {:?}, shm: {}, qos: {}, multilink: {}", self.config.zid, config.zid, config.whatami, config.sn_resolution, config.tx_initial_sn, config.is_shm, - config.is_qos + config.is_qos, + is_multilink ); Ok(transport) diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index fad7de5a5b..d0a9002046 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -24,6 +24,8 @@ use super::common; #[cfg(feature = "stats")] use super::common::stats::stats_struct; use super::{TransportPeer, TransportPeerEventHandler}; +#[cfg(feature = "transport_multilink")] +use crate::establishment::ext::auth::ZPublicKey; pub use manager::*; use std::fmt; use std::sync::{Arc, Weak}; @@ -80,7 +82,7 @@ stats_struct! { /*************************************/ /* TRANSPORT UNICAST */ /*************************************/ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct TransportConfigUnicast { pub(crate) zid: ZenohId, pub(crate) whatami: WhatAmI, @@ -88,6 +90,8 @@ pub(crate) struct TransportConfigUnicast { pub(crate) tx_initial_sn: ZInt, pub(crate) is_shm: bool, pub(crate) is_qos: bool, + #[cfg(feature = "transport_multilink")] + pub(crate) multilink: Option, } /// [`TransportUnicast`] is the transport handler returned diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index 3e24561382..d5e36758cb 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -204,7 +204,13 @@ impl TransportUnicastInner { // Check if we can add more inbound links if let LinkUnicastDirection::Inbound = direction { let count = guard.iter().filter(|l| l.direction == direction).count(); - let limit = self.manager.config.unicast.max_links; + + let mut limit = 1; + + #[cfg(feature = "transport_multilink")] + if self.config.multilink.is_some() { + limit = self.manager.config.unicast.max_links; + } if count >= limit { let e = zerror!( diff --git a/io/zenoh-transport/tests/unicast_openclose.rs b/io/zenoh-transport/tests/unicast_openclose.rs deleted file mode 100644 index 515b9a5eeb..0000000000 --- a/io/zenoh-transport/tests/unicast_openclose.rs +++ /dev/null @@ -1,677 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use async_std::{prelude::FutureExt, task}; -use std::{convert::TryFrom, sync::Arc, time::Duration}; -use zenoh_core::zasync_executor_init; -use zenoh_link::EndPoint; -use zenoh_protocol::core::{WhatAmI, ZenohId}; -use zenoh_result::ZResult; -use zenoh_transport::{ - DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportPeer, - TransportPeerEventHandler, TransportUnicast, -}; - -const TIMEOUT: Duration = Duration::from_secs(60); -const SLEEP: Duration = Duration::from_millis(100); - -macro_rules! ztimeout { - ($f:expr) => { - $f.timeout(TIMEOUT).await.unwrap() - }; -} - -#[cfg(test)] -#[derive(Default)] -struct SHRouterOpenClose; - -impl TransportEventHandler for SHRouterOpenClose { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) - } -} - -// Transport Handler for the client -struct SHClientOpenClose {} - -impl SHClientOpenClose { - fn new() -> Self { - Self {} - } -} - -impl TransportEventHandler for SHClientOpenClose { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) - } -} - -async fn openclose_transport(endpoint: &EndPoint) { - /* [ROUTER] */ - let router_id = ZenohId::try_from([1]).unwrap(); - - let router_handler = Arc::new(SHRouterOpenClose::default()); - // Create the router transport manager - let unicast = TransportManager::config_unicast() - .max_links(2) - .max_sessions(1); - let router_manager = TransportManager::builder() - .whatami(WhatAmI::Router) - .zid(router_id) - .unicast(unicast) - .build(router_handler.clone()) - .unwrap(); - - /* [CLIENT] */ - let client01_id = ZenohId::try_from([2]).unwrap(); - let client02_id = ZenohId::try_from([3]).unwrap(); - - // Create the transport transport manager for the first client - let unicast = TransportManager::config_unicast() - .max_links(2) - .max_sessions(1); - let client01_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client01_id) - .unicast(unicast) - .build(Arc::new(SHClientOpenClose::new())) - .unwrap(); - - // Create the transport transport manager for the second client - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(1); - let client02_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client02_id) - .unicast(unicast) - .build(Arc::new(SHClientOpenClose::new())) - .unwrap(); - - /* [1] */ - println!("\nTransport Open Close [1a1]"); - // Add the locator on the router - let res = ztimeout!(router_manager.add_listener(endpoint.clone())); - println!("Transport Open Close [1a1]: {res:?}"); - assert!(res.is_ok()); - println!("Transport Open Close [1a2]"); - let locators = router_manager.get_listeners(); - println!("Transport Open Close [1a2]: {locators:?}"); - assert_eq!(locators.len(), 1); - - // Open a first transport from the client to the router - // -> This should be accepted - let mut links_num = 1; - - println!("Transport Open Close [1c1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [1c2]: {res:?}"); - assert!(res.is_ok()); - let c_ses1 = res.unwrap(); - println!("Transport Open Close [1d1]"); - let transports = client01_manager.get_transports(); - println!("Transport Open Close [1d2]: {transports:?}"); - assert_eq!(transports.len(), 1); - assert_eq!(c_ses1.get_zid().unwrap(), router_id); - println!("Transport Open Close [1e1]"); - let links = c_ses1.get_links().unwrap(); - println!("Transport Open Close [1e2]: {links:?}"); - assert_eq!(links.len(), links_num); - - // Verify that the transport has been open on the router - println!("Transport Open Close [1f1]"); - ztimeout!(async { - loop { - let transports = router_manager.get_transports(); - let s = transports - .iter() - .find(|s| s.get_zid().unwrap() == client01_id); - - match s { - Some(s) => { - let links = s.get_links().unwrap(); - assert_eq!(links.len(), links_num); - break; - } - None => task::sleep(SLEEP).await, - } - } - }); - - /* [2] */ - // Open a second transport from the client to the router - // -> This should be accepted - links_num = 2; - - println!("\nTransport Open Close [2a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [2a2]: {res:?}"); - assert!(res.is_ok()); - let c_ses2 = res.unwrap(); - println!("Transport Open Close [2b1]"); - let transports = client01_manager.get_transports(); - println!("Transport Open Close [2b2]: {transports:?}"); - assert_eq!(transports.len(), 1); - assert_eq!(c_ses2.get_zid().unwrap(), router_id); - println!("Transport Open Close [2c1]"); - let links = c_ses2.get_links().unwrap(); - println!("Transport Open Close [2c2]: {links:?}"); - assert_eq!(links.len(), links_num); - assert_eq!(c_ses2, c_ses1); - - // Verify that the transport has been open on the router - println!("Transport Open Close [2d1]"); - ztimeout!(async { - loop { - let transports = router_manager.get_transports(); - let s = transports - .iter() - .find(|s| s.get_zid().unwrap() == client01_id) - .unwrap(); - - let links = s.get_links().unwrap(); - if links.len() == links_num { - break; - } - task::sleep(SLEEP).await; - } - }); - - /* [3] */ - // Open transport -> This should be rejected because - // of the maximum limit of links per transport - println!("\nTransport Open Close [3a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [3a2]: {res:?}"); - assert!(res.is_err()); - println!("Transport Open Close [3b1]"); - let transports = client01_manager.get_transports(); - println!("Transport Open Close [3b2]: {transports:?}"); - assert_eq!(transports.len(), 1); - assert_eq!(c_ses1.get_zid().unwrap(), router_id); - println!("Transport Open Close [3c1]"); - let links = c_ses1.get_links().unwrap(); - println!("Transport Open Close [3c2]: {links:?}"); - assert_eq!(links.len(), links_num); - - // Verify that the transport has not been open on the router - println!("Transport Open Close [3d1]"); - ztimeout!(async { - task::sleep(SLEEP).await; - let transports = router_manager.get_transports(); - assert_eq!(transports.len(), 1); - let s = transports - .iter() - .find(|s| s.get_zid().unwrap() == client01_id) - .unwrap(); - let links = s.get_links().unwrap(); - assert_eq!(links.len(), links_num); - }); - - /* [4] */ - // Close the open transport on the client - println!("\nTransport Open Close [4a1]"); - let res = ztimeout!(c_ses1.close()); - println!("Transport Open Close [4a2]: {res:?}"); - assert!(res.is_ok()); - println!("Transport Open Close [4b1]"); - let transports = client01_manager.get_transports(); - println!("Transport Open Close [4b2]: {transports:?}"); - assert_eq!(transports.len(), 0); - - // Verify that the transport has been closed also on the router - println!("Transport Open Close [4c1]"); - ztimeout!(async { - loop { - let transports = router_manager.get_transports(); - let index = transports - .iter() - .find(|s| s.get_zid().unwrap() == client01_id); - if index.is_none() { - break; - } - task::sleep(SLEEP).await; - } - }); - - /* [5] */ - // Open transport -> This should be accepted because - // the number of links should be back to 0 - links_num = 1; - - println!("\nTransport Open Close [5a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [5a2]: {res:?}"); - assert!(res.is_ok()); - let c_ses3 = res.unwrap(); - println!("Transport Open Close [5b1]"); - let transports = client01_manager.get_transports(); - println!("Transport Open Close [5b2]: {transports:?}"); - assert_eq!(transports.len(), 1); - assert_eq!(c_ses3.get_zid().unwrap(), router_id); - println!("Transport Open Close [5c1]"); - let links = c_ses3.get_links().unwrap(); - println!("Transport Open Close [5c2]: {links:?}"); - assert_eq!(links.len(), links_num); - - // Verify that the transport has been open on the router - println!("Transport Open Close [5d1]"); - ztimeout!(async { - task::sleep(SLEEP).await; - let transports = router_manager.get_transports(); - assert_eq!(transports.len(), 1); - let s = transports - .iter() - .find(|s| s.get_zid().unwrap() == client01_id) - .unwrap(); - let links = s.get_links().unwrap(); - assert_eq!(links.len(), links_num); - }); - - /* [6] */ - // Open transport -> This should be rejected because - // of the maximum limit of transports - println!("\nTransport Open Close [6a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [6a2]: {res:?}"); - assert!(res.is_err()); - println!("Transport Open Close [6b1]"); - let transports = client02_manager.get_transports(); - println!("Transport Open Close [6b2]: {transports:?}"); - assert_eq!(transports.len(), 0); - - // Verify that the transport has not been open on the router - println!("Transport Open Close [6c1]"); - ztimeout!(async { - task::sleep(SLEEP).await; - let transports = router_manager.get_transports(); - assert_eq!(transports.len(), 1); - let s = transports - .iter() - .find(|s| s.get_zid().unwrap() == client01_id) - .unwrap(); - let links = s.get_links().unwrap(); - assert_eq!(links.len(), links_num); - }); - - /* [7] */ - // Close the open transport on the client - println!("\nTransport Open Close [7a1]"); - let res = ztimeout!(c_ses3.close()); - println!("Transport Open Close [7a2]: {res:?}"); - assert!(res.is_ok()); - println!("Transport Open Close [7b1]"); - let transports = client01_manager.get_transports(); - println!("Transport Open Close [7b2]: {transports:?}"); - assert_eq!(transports.len(), 0); - - // Verify that the transport has been closed also on the router - println!("Transport Open Close [7c1]"); - ztimeout!(async { - loop { - let transports = router_manager.get_transports(); - if transports.is_empty() { - break; - } - task::sleep(SLEEP).await; - } - }); - - /* [8] */ - // Open transport -> This should be accepted because - // the number of transports should be back to 0 - links_num = 1; - - println!("\nTransport Open Close [8a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); - println!("Transport Open Close [8a2]: {res:?}"); - assert!(res.is_ok()); - let c_ses4 = res.unwrap(); - println!("Transport Open Close [8b1]"); - let transports = client02_manager.get_transports(); - println!("Transport Open Close [8b2]: {transports:?}"); - assert_eq!(transports.len(), 1); - println!("Transport Open Close [8c1]"); - let links = c_ses4.get_links().unwrap(); - println!("Transport Open Close [8c2]: {links:?}"); - assert_eq!(links.len(), links_num); - - // Verify that the transport has been open on the router - println!("Transport Open Close [8d1]"); - ztimeout!(async { - loop { - let transports = router_manager.get_transports(); - let s = transports - .iter() - .find(|s| s.get_zid().unwrap() == client02_id); - match s { - Some(s) => { - let links = s.get_links().unwrap(); - assert_eq!(links.len(), links_num); - break; - } - None => task::sleep(SLEEP).await, - } - } - }); - - /* [9] */ - // Close the open transport on the client - println!("Transport Open Close [9a1]"); - let res = ztimeout!(c_ses4.close()); - println!("Transport Open Close [9a2]: {res:?}"); - assert!(res.is_ok()); - println!("Transport Open Close [9b1]"); - let transports = client02_manager.get_transports(); - println!("Transport Open Close [9b2]: {transports:?}"); - assert_eq!(transports.len(), 0); - - // Verify that the transport has been closed also on the router - println!("Transport Open Close [9c1]"); - ztimeout!(async { - loop { - let transports = router_manager.get_transports(); - if transports.is_empty() { - break; - } - task::sleep(SLEEP).await; - } - }); - - /* [10] */ - // Perform clean up of the open locators - println!("\nTransport Open Close [10a1]"); - let res = ztimeout!(router_manager.del_listener(endpoint)); - println!("Transport Open Close [10a2]: {res:?}"); - assert!(res.is_ok()); - - ztimeout!(async { - while !router_manager.get_listeners().is_empty() { - task::sleep(SLEEP).await; - } - }); - - // Wait a little bit - task::sleep(SLEEP).await; - - ztimeout!(router_manager.close()); - ztimeout!(client01_manager.close()); - ztimeout!(client02_manager.close()); - - // Wait a little bit - task::sleep(SLEEP).await; -} - -#[cfg(feature = "transport_tcp")] -#[test] -fn openclose_tcp_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 13000).parse().unwrap(); - task::block_on(openclose_transport(&endpoint)); -} - -#[cfg(feature = "transport_udp")] -#[test] -fn openclose_udp_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 13010).parse().unwrap(); - task::block_on(openclose_transport(&endpoint)); -} - -#[cfg(feature = "transport_ws")] -#[test] -fn openclose_ws_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 13020).parse().unwrap(); - task::block_on(openclose_transport(&endpoint)); -} - -#[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] -#[test] -fn openclose_unix_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let f1 = "zenoh-test-unix-socket-9.sock"; - let _ = std::fs::remove_file(f1); - let endpoint: EndPoint = format!("unixsock-stream/{f1}").parse().unwrap(); - task::block_on(openclose_transport(&endpoint)); - let _ = std::fs::remove_file(f1); - let _ = std::fs::remove_file(format!("{f1}.lock")); -} - -#[cfg(feature = "transport_tls")] -#[test] -fn openclose_tls_only() { - use zenoh_link::tls::config::*; - - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // NOTE: this an auto-generated pair of certificate and key. - // The target domain is localhost, so it has no real - // mapping to any existing domain. The certificate and key - // have been generated using: https://github.com/jsha/minica - let key = "-----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi -qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy -aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU -cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha -Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr -Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 -2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 -lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU -WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX -Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI -9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak -r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn -qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY -CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu -fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj -4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih -XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 -38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT -Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV -jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R -5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H -n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm -qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD -tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v -F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== ------END RSA PRIVATE KEY-----"; - - let cert = "-----BEGIN CERTIFICATE----- -MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw -MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT -He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ -Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj -eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 -eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M -tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud -DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE -DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 -3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD -wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q -GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC -9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ -p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ -abY= ------END CERTIFICATE-----"; - - // Configure the client - let ca = "-----BEGIN CERTIFICATE----- -MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw -MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ -uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs -DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc -8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 -T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b -QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB -AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 -/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq -hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ -e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc -yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 -8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 -Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN -R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== ------END CERTIFICATE-----"; - - let mut endpoint: EndPoint = format!("tls/localhost:{}", 13030).parse().unwrap(); - endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, ca), - (TLS_SERVER_PRIVATE_KEY_RAW, key), - (TLS_SERVER_CERTIFICATE_RAW, cert), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - - task::block_on(openclose_transport(&endpoint)); -} - -#[cfg(feature = "transport_quic")] -#[test] -fn openclose_quic_only() { - use zenoh_link::quic::config::*; - - task::block_on(async { - zasync_executor_init!(); - }); - - // NOTE: this an auto-generated pair of certificate and key. - // The target domain is localhost, so it has no real - // mapping to any existing domain. The certificate and key - // have been generated using: https://github.com/jsha/minica - let key = "-----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi -qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy -aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU -cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha -Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr -Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 -2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 -lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU -WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX -Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI -9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak -r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn -qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY -CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu -fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj -4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih -XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 -38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT -Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV -jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R -5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H -n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm -qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD -tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v -F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== ------END RSA PRIVATE KEY-----"; - - let cert = "-----BEGIN CERTIFICATE----- -MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw -MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT -He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ -Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj -eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 -eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M -tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud -DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE -DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 -3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD -wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q -GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC -9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ -p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ -abY= ------END CERTIFICATE-----"; - - // Configure the client - let ca = "-----BEGIN CERTIFICATE----- -MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw -MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ -uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs -DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc -8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 -T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b -QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB -AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 -/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq -hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ -e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc -yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 -8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 -Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN -R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== ------END CERTIFICATE-----"; - - // Define the locator - let mut endpoint: EndPoint = format!("quic/localhost:{}", 13040).parse().unwrap(); - endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, ca), - (TLS_SERVER_PRIVATE_KEY_RAW, key), - (TLS_SERVER_CERTIFICATE_RAW, cert), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - - task::block_on(openclose_transport(&endpoint)); -} diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 84d9e5f28d..1b3a27de30 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -38,6 +38,7 @@ shared-memory = [ "zenoh-transport/shared-memory", ] stats = ["zenoh-transport/stats"] +transport_multilink = ["zenoh-transport/transport_multilink"] transport_quic = ["zenoh-transport/transport_quic"] transport_serial = ["zenoh-transport/transport_serial"] transport_tcp = ["zenoh-transport/transport_tcp"] @@ -49,6 +50,7 @@ unstable = [] default = [ "auth_pubkey", "auth_usrpwd", + "transport_multilink", "transport_quic", "transport_tcp", "transport_tls", From 48b3b30e341f420686d356e851a0454cf0064312 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 11 Mar 2023 01:46:47 +0100 Subject: [PATCH 075/203] Improved tests and debug --- .../unicast/establishment/ext/auth/pubkey.rs | 41 +- .../unicast/establishment/ext/auth/usrpwd.rs | 24 +- io/zenoh-transport/src/unicast/manager.rs | 6 - io/zenoh-transport/src/unicast/mod.rs | 2 +- io/zenoh-transport/tests/unicast_conduits.rs | 114 +-- io/zenoh-transport/tests/unicast_multilink.rs | 724 ++++++++++++++++++ 6 files changed, 844 insertions(+), 67 deletions(-) create mode 100644 io/zenoh-transport/tests/unicast_multilink.rs diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs index 89530070fd..2a1253b76b 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs @@ -14,14 +14,15 @@ // use super::{ // AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, // }; +use crate::establishment::{AcceptFsm, OpenFsm}; use async_std::sync::{Mutex, RwLock}; use async_trait::async_trait; use rand::Rng; -use rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}; -use rsa::{BigUint, Pkcs1v15Encrypt, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey}; -use std::collections::HashSet; -use std::ops::Deref; -use std::path::Path; +use rsa::{ + pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}, + BigUint, Pkcs1v15Encrypt, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey, +}; +use std::{collections::HashSet, fmt, ops::Deref, path::Path}; use zenoh_buffers::{ reader::{DidntRead, HasReader, Reader}, writer::{DidntWrite, HasWriter, Writer}, @@ -30,10 +31,10 @@ use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_config::PubKeyConf; use zenoh_core::{bail, zasynclock, zasyncread, zerror, Error as ZError, Result as ZResult}; use zenoh_crypto::PseudoRng; -use zenoh_protocol::common::{ZExtUnit, ZExtZBuf}; -use zenoh_protocol::core::ZInt; - -use crate::establishment::{AcceptFsm, OpenFsm}; +use zenoh_protocol::{ + common::{ZExtUnit, ZExtZBuf}, + core::ZInt, +}; // Authenticator #[derive(Debug)] @@ -118,7 +119,7 @@ impl AuthPubKey { } #[repr(transparent)] -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Hash)] pub struct ZPublicKey(RsaPublicKey); impl Deref for ZPublicKey { @@ -129,6 +130,18 @@ impl Deref for ZPublicKey { } } +impl fmt::Debug for ZPublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for b in self.0.n().to_bytes_le() { + write!(f, "{:02x}", b)?; + } + for b in self.0.e().to_bytes_le() { + write!(f, "{:02x}", b)?; + } + Ok(()) + } +} + impl From for ZPublicKey { fn from(x: RsaPublicKey) -> Self { Self(x) @@ -136,7 +149,7 @@ impl From for ZPublicKey { } #[repr(transparent)] -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq)] pub struct ZPrivateKey(RsaPrivateKey); impl Deref for ZPrivateKey { @@ -147,6 +160,12 @@ impl Deref for ZPrivateKey { } } +impl fmt::Debug for ZPrivateKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "***",) + } +} + impl From for ZPrivateKey { fn from(x: RsaPrivateKey) -> Self { Self(x) diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index a33279b112..6479bec935 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -15,7 +15,7 @@ use crate::establishment::{AcceptFsm, OpenFsm}; use async_std::{fs, sync::RwLock}; use async_trait::async_trait; use rand::{CryptoRng, Rng}; -use std::collections::HashMap; +use std::{collections::HashMap, fmt}; use zenoh_buffers::{ reader::{DidntRead, HasReader, Reader}, writer::{DidntWrite, HasWriter, Writer}, @@ -34,7 +34,6 @@ use zenoh_protocol::{ type User = Vec; type Password = Vec; -#[derive(Debug)] pub struct AuthUsrPwd { lookup: HashMap, credentials: Option<(User, Password)>, @@ -95,6 +94,27 @@ impl AuthUsrPwd { } } +impl fmt::Debug for AuthUsrPwd { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.credentials.as_ref() { + Some(c) => write!( + f, + "User: '{}', Password: '***'", + String::from_utf8_lossy(&c.0) + )?, + None => write!(f, "User: '', Password: ''")?, + } + write!(f, "Dictionary: {{")?; + for (i, (u, _)) in self.lookup.iter().enumerate() { + if i != 0 { + write!(f, ",")?; + } + write!(f, " {}", String::from_utf8_lossy(u))?; + } + write!(f, " }}") + } +} + // OpenFsm / AcceptFsm #[derive(Debug, PartialEq, Eq)] pub(crate) struct StateOpen { diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 7dd5c4c17a..d7e4d56b91 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -223,12 +223,6 @@ impl TransportManager { pub async fn close_unicast(&self) { log::trace!("TransportManagerUnicast::clear())"); - // let mut pa_guard = zasyncwrite!(self.state.unicast.peer_authenticator); - - // for pa in pa_guard.drain() { - // pa.close().await; - // } @TODO - let mut pl_guard = zasynclock!(self.state.unicast.protocols) .drain() .map(|(_, v)| v) diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index d0a9002046..40962eb2fc 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -90,7 +90,7 @@ pub(crate) struct TransportConfigUnicast { pub(crate) tx_initial_sn: ZInt, pub(crate) is_shm: bool, pub(crate) is_qos: bool, - #[cfg(feature = "transport_multilink")] + #[cfg(feature = "transport_multilink")] pub(crate) multilink: Option, } diff --git a/io/zenoh-transport/tests/unicast_conduits.rs b/io/zenoh-transport/tests/unicast_conduits.rs index 52f7e6f051..b2397ed79b 100644 --- a/io/zenoh-transport/tests/unicast_conduits.rs +++ b/io/zenoh-transport/tests/unicast_conduits.rs @@ -58,20 +58,28 @@ macro_rules! ztimeout { // Transport Handler for the router struct SHRouter { - priority: Priority, + priority: Arc, count: Arc, } impl SHRouter { - fn new(priority: Priority) -> Self { + fn new() -> Self { Self { - priority, + priority: Arc::new(AtomicUsize::new(0)), count: Arc::new(AtomicUsize::new(0)), } } + fn set_priority(&self, priority: Priority) { + self.priority.store(priority as usize, Ordering::Relaxed) + } + + fn reset_count(&self) { + self.count.store(0, Ordering::Relaxed) + } + fn get_count(&self) -> usize { - self.count.load(Ordering::SeqCst) + self.count.load(Ordering::Relaxed) } } @@ -81,27 +89,30 @@ impl TransportEventHandler for SHRouter { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - let arc = Arc::new(SCRouter::new(self.count.clone(), self.priority)); + let arc = Arc::new(SCRouter::new(self.priority.clone(), self.count.clone())); Ok(arc) } } // Transport Callback for the router pub struct SCRouter { - priority: Priority, + priority: Arc, count: Arc, } impl SCRouter { - pub fn new(count: Arc, priority: Priority) -> Self { + pub fn new(priority: Arc, count: Arc) -> Self { Self { priority, count } } } impl TransportPeerEventHandler for SCRouter { fn handle_message(&self, message: ZenohMessage) -> ZResult<()> { - assert_eq!(self.priority, message.channel.priority); - self.count.fetch_add(1, Ordering::SeqCst); + assert_eq!( + self.priority.load(Ordering::Relaxed), + message.channel.priority as usize + ); + self.count.fetch_add(1, Ordering::Relaxed); Ok(()) } @@ -160,7 +171,6 @@ impl TransportPeerEventHandler for SCClient { async fn open_transport( endpoints: &[EndPoint], - priority: Priority, ) -> ( TransportManager, Arc, @@ -172,7 +182,7 @@ async fn open_transport( let router_id = ZenohId::try_from([2]).unwrap(); // Create the router transport manager - let router_handler = Arc::new(SHRouter::new(priority)); + let router_handler = Arc::new(SHRouter::new()); let router_manager = TransportManager::builder() .whatami(WhatAmI::Router) .zid(router_id) @@ -249,50 +259,60 @@ async fn close_transport( async fn single_run( router_handler: Arc, client_transport: TransportUnicast, - channel: Channel, - msg_size: usize, + channel: &[Channel], + msg_size: &[usize], ) { - // Create the message to send - let key = "test".into(); - let payload = ZBuf::from(vec![0_u8; msg_size]); - let data_info = None; - let routing_context = None; - let reply_context = None; - let message = ZenohMessage::make_data( - key, - payload, - channel, - CongestionControl::Block, - data_info, - routing_context, - reply_context, - ); - - println!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); - for _ in 0..MSG_COUNT { - client_transport.schedule(message.clone()).unwrap(); - } - - // Wait for the messages to arrive to the other side - ztimeout!(async { - while router_handler.get_count() != MSG_COUNT { - task::sleep(SLEEP_COUNT).await; + for ch in channel.iter() { + for ms in msg_size.iter() { + // Reset the counter and set priority on the router + router_handler.reset_count(); + router_handler.set_priority(ch.priority); + + // Create the message to send + let key = "test".into(); + let payload = ZBuf::from(vec![0_u8; *ms]); + let data_info = None; + let routing_context = None; + let reply_context = None; + let message = ZenohMessage::make_data( + key, + payload, + *ch, + CongestionControl::Block, + data_info, + routing_context, + reply_context, + ); + + println!("Sending {MSG_COUNT} messages... {ch:?} {ms}"); + for _ in 0..MSG_COUNT { + client_transport.schedule(message.clone()).unwrap(); + } + + // Wait for the messages to arrive to the other side + ztimeout!(async { + while router_handler.get_count() != MSG_COUNT { + task::sleep(SLEEP_COUNT).await; + } + }); } - }); + } // Wait a little bit task::sleep(SLEEP).await; } async fn run(endpoints: &[EndPoint], channel: &[Channel], msg_size: &[usize]) { - for ch in channel.iter() { - for ms in msg_size.iter() { - let (router_manager, router_handler, client_manager, client_transport) = - open_transport(endpoints, ch.priority).await; - single_run(router_handler.clone(), client_transport.clone(), *ch, *ms).await; - close_transport(router_manager, client_manager, client_transport, endpoints).await; - } - } + let (router_manager, router_handler, client_manager, client_transport) = + open_transport(endpoints).await; + single_run( + router_handler.clone(), + client_transport.clone(), + channel, + msg_size, + ) + .await; + close_transport(router_manager, client_manager, client_transport, endpoints).await; } #[cfg(feature = "transport_tcp")] diff --git a/io/zenoh-transport/tests/unicast_multilink.rs b/io/zenoh-transport/tests/unicast_multilink.rs new file mode 100644 index 0000000000..22dd67d46c --- /dev/null +++ b/io/zenoh-transport/tests/unicast_multilink.rs @@ -0,0 +1,724 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#[cfg(feature = "transport_multilink")] +mod tests { + use async_std::{prelude::FutureExt, task}; + use std::{convert::TryFrom, sync::Arc, time::Duration}; + use zenoh_core::zasync_executor_init; + use zenoh_link::EndPoint; + use zenoh_protocol::core::{WhatAmI, ZenohId}; + use zenoh_result::ZResult; + use zenoh_transport::{ + DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportPeer, + TransportPeerEventHandler, TransportUnicast, + }; + + const TIMEOUT: Duration = Duration::from_secs(60); + const SLEEP: Duration = Duration::from_millis(100); + + macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; + } + + #[cfg(test)] + #[derive(Default)] + struct SHRouterOpenClose; + + impl TransportEventHandler for SHRouterOpenClose { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + Ok(Arc::new(DummyTransportPeerEventHandler::default())) + } + } + + // Transport Handler for the client + struct SHClientOpenClose {} + + impl SHClientOpenClose { + fn new() -> Self { + Self {} + } + } + + impl TransportEventHandler for SHClientOpenClose { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + Ok(Arc::new(DummyTransportPeerEventHandler::default())) + } + } + + async fn multilink_transport(endpoint: &EndPoint) { + /* [ROUTER] */ + let router_id = ZenohId::try_from([1]).unwrap(); + + let router_handler = Arc::new(SHRouterOpenClose::default()); + // Create the router transport manager + let unicast = TransportManager::config_unicast() + .max_links(2) + .max_sessions(2); + let router_manager = TransportManager::builder() + .whatami(WhatAmI::Router) + .zid(router_id) + .unicast(unicast) + .build(router_handler.clone()) + .unwrap(); + + /* [CLIENT] */ + let client01_id = ZenohId::try_from([2]).unwrap(); + let client02_id = ZenohId::try_from([3]).unwrap(); + + // Create the transport transport manager for the first client + let unicast = TransportManager::config_unicast() + .max_links(2) + .max_sessions(1); + let client01_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client01_id) + .unicast(unicast) + .build(Arc::new(SHClientOpenClose::new())) + .unwrap(); + + // Create the transport transport manager for the second client + let unicast = TransportManager::config_unicast() + .max_links(1) + .max_sessions(1); + let client02_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client02_id) + .unicast(unicast) + .build(Arc::new(SHClientOpenClose::new())) + .unwrap(); + + // Create the transport transport manager for the third client spoofing the first + let unicast = TransportManager::config_unicast() + .max_links(2) + .max_sessions(1); + let client03_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client01_id) + .unicast(unicast) + .build(Arc::new(SHClientOpenClose::new())) + .unwrap(); + + /* [1] */ + println!("\nTransport Open Close [1a1]"); + // Add the locator on the router + let res = ztimeout!(router_manager.add_listener(endpoint.clone())); + println!("Transport Open Close [1a1]: {res:?}"); + assert!(res.is_ok()); + println!("Transport Open Close [1a2]"); + let locators = router_manager.get_listeners(); + println!("Transport Open Close [1a2]: {locators:?}"); + assert_eq!(locators.len(), 1); + + // Open a first transport from the client to the router + // -> This should be accepted + let mut links_num = 1; + + println!("Transport Open Close [1c1]"); + let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + println!("Transport Open Close [1c2]: {res:?}"); + assert!(res.is_ok()); + let c_ses1 = res.unwrap(); + println!("Transport Open Close [1d1]"); + let transports = client01_manager.get_transports(); + println!("Transport Open Close [1d2]: {transports:?}"); + assert_eq!(transports.len(), 1); + assert_eq!(c_ses1.get_zid().unwrap(), router_id); + println!("Transport Open Close [1e1]"); + let links = c_ses1.get_links().unwrap(); + println!("Transport Open Close [1e2]: {links:?}"); + assert_eq!(links.len(), links_num); + + // Verify that the transport has been open on the router + println!("Transport Open Close [1f1]"); + ztimeout!(async { + loop { + let transports = router_manager.get_transports(); + let s = transports + .iter() + .find(|s| s.get_zid().unwrap() == client01_id); + + match s { + Some(s) => { + let links = s.get_links().unwrap(); + assert_eq!(links.len(), links_num); + break; + } + None => task::sleep(SLEEP).await, + } + } + }); + + /* [2] */ + // Open a second transport from the client to the router + // -> This should be accepted + links_num = 2; + + println!("\nTransport Open Close [2a1]"); + let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + println!("Transport Open Close [2a2]: {res:?}"); + assert!(res.is_ok()); + let c_ses2 = res.unwrap(); + println!("Transport Open Close [2b1]"); + let transports = client01_manager.get_transports(); + println!("Transport Open Close [2b2]: {transports:?}"); + assert_eq!(transports.len(), 1); + assert_eq!(c_ses2.get_zid().unwrap(), router_id); + println!("Transport Open Close [2c1]"); + let links = c_ses2.get_links().unwrap(); + println!("Transport Open Close [2c2]: {links:?}"); + assert_eq!(links.len(), links_num); + assert_eq!(c_ses2, c_ses1); + + // Verify that the transport has been open on the router + println!("Transport Open Close [2d1]"); + ztimeout!(async { + loop { + let transports = router_manager.get_transports(); + let s = transports + .iter() + .find(|s| s.get_zid().unwrap() == client01_id) + .unwrap(); + + let links = s.get_links().unwrap(); + if links.len() == links_num { + break; + } + task::sleep(SLEEP).await; + } + }); + + /* [3] */ + // Open transport -> This should be rejected because + // of the maximum limit of links per transport + println!("\nTransport Open Close [3a1]"); + let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + println!("Transport Open Close [3a2]: {res:?}"); + assert!(res.is_err()); + println!("Transport Open Close [3b1]"); + let transports = client01_manager.get_transports(); + println!("Transport Open Close [3b2]: {transports:?}"); + assert_eq!(transports.len(), 1); + assert_eq!(c_ses1.get_zid().unwrap(), router_id); + println!("Transport Open Close [3c1]"); + let links = c_ses1.get_links().unwrap(); + println!("Transport Open Close [3c2]: {links:?}"); + assert_eq!(links.len(), links_num); + + // Verify that the transport has not been open on the router + println!("Transport Open Close [3d1]"); + ztimeout!(async { + task::sleep(SLEEP).await; + let transports = router_manager.get_transports(); + assert_eq!(transports.len(), 1); + let s = transports + .iter() + .find(|s| s.get_zid().unwrap() == client01_id) + .unwrap(); + let links = s.get_links().unwrap(); + assert_eq!(links.len(), links_num); + }); + + /* [4] */ + // Close the open transport on the client + println!("\nTransport Open Close [4a1]"); + let res = ztimeout!(c_ses1.close()); + println!("Transport Open Close [4a2]: {res:?}"); + assert!(res.is_ok()); + println!("Transport Open Close [4b1]"); + let transports = client01_manager.get_transports(); + println!("Transport Open Close [4b2]: {transports:?}"); + assert_eq!(transports.len(), 0); + + // Verify that the transport has been closed also on the router + println!("Transport Open Close [4c1]"); + ztimeout!(async { + loop { + let transports = router_manager.get_transports(); + let index = transports + .iter() + .find(|s| s.get_zid().unwrap() == client01_id); + if index.is_none() { + break; + } + task::sleep(SLEEP).await; + } + }); + + /* [5] */ + // Open transport -> This should be accepted because + // the number of links should be back to 0 + links_num = 1; + + println!("\nTransport Open Close [5a1]"); + let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + println!("Transport Open Close [5a2]: {res:?}"); + assert!(res.is_ok()); + let c_ses3 = res.unwrap(); + println!("Transport Open Close [5b1]"); + let transports = client01_manager.get_transports(); + println!("Transport Open Close [5b2]: {transports:?}"); + assert_eq!(transports.len(), 1); + assert_eq!(c_ses3.get_zid().unwrap(), router_id); + println!("Transport Open Close [5c1]"); + let links = c_ses3.get_links().unwrap(); + println!("Transport Open Close [5c2]: {links:?}"); + assert_eq!(links.len(), links_num); + + // Verify that the transport has been open on the router + println!("Transport Open Close [5d1]"); + ztimeout!(async { + task::sleep(SLEEP).await; + let transports = router_manager.get_transports(); + assert_eq!(transports.len(), 1); + let s = transports + .iter() + .find(|s| s.get_zid().unwrap() == client01_id) + .unwrap(); + let links = s.get_links().unwrap(); + assert_eq!(links.len(), links_num); + }); + + /* [6] */ + // Open transport -> This should be rejected because + // of the maximum limit of transports + println!("\nTransport Open Close [6a1]"); + let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + println!("Transport Open Close [6a2]: {res:?}"); + assert!(res.is_ok()); + let c_ses4 = res.unwrap(); + println!("Transport Open Close [6b1]"); + let transports = client02_manager.get_transports(); + println!("Transport Open Close [6b2]: {transports:?}"); + assert_eq!(transports.len(), 1); + assert_eq!(c_ses4.get_zid().unwrap(), router_id); + println!("Transport Open Close [6c1]"); + let links = c_ses4.get_links().unwrap(); + println!("Transport Open Close [6c2]: {links:?}"); + assert_eq!(links.len(), links_num); + + // Open transport -> This should be rejected because + // of the maximum limit of transports + println!("\nTransport Open Close [6d1]"); + let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + println!("Transport Open Close [6d2]: {res:?}"); + assert!(res.is_err()); + println!("Transport Open Close [6e1]"); + let transports = client02_manager.get_transports(); + println!("Transport Open Close [6e2]: {transports:?}"); + assert_eq!(transports.len(), 1); + + // Verify that the transport has been open on the router + println!("Transport Open Close [6f1]"); + ztimeout!(async { + task::sleep(SLEEP).await; + let transports = router_manager.get_transports(); + assert_eq!(transports.len(), 2); + let s = transports + .iter() + .find(|s| s.get_zid().unwrap() == client01_id) + .unwrap(); + let links = s.get_links().unwrap(); + assert_eq!(links.len(), links_num); + }); + + /* [7] */ + // Try to spoof the first client + // -> This should be rejected + println!("\nTransport Open Close [7a1]"); + let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); + println!("Transport Open Close [7a2]: {res:?}"); + assert!(res.is_err()); + println!("Transport Open Close [7b1]"); + let transports = client03_manager.get_transports(); + println!("Transport Open Close [7b2]: {transports:?}"); + assert_eq!(transports.len(), 0); + + /* [8] */ + // Close the open transport on the client + println!("\nTransport Open Close [8a1]"); + let res = ztimeout!(c_ses3.close()); + println!("Transport Open Close [8a2]: {res:?}"); + assert!(res.is_ok()); + println!("\nTransport Open Close [8b1]"); + let res = ztimeout!(c_ses4.close()); + println!("Transport Open Close [8b2]: {res:?}"); + assert!(res.is_ok()); + println!("Transport Open Close [8c1]"); + let transports = client01_manager.get_transports(); + println!("Transport Open Close [8c2]: {transports:?}"); + assert_eq!(transports.len(), 0); + + // Verify that the transport has been closed also on the router + println!("Transport Open Close [8d1]"); + ztimeout!(async { + loop { + let transports = router_manager.get_transports(); + if transports.is_empty() { + break; + } + task::sleep(SLEEP).await; + } + }); + + /* [9] */ + // Open transport -> This should be accepted because + // the number of transports should be back to 0 + links_num = 1; + + println!("\nTransport Open Close [9a1]"); + let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + println!("Transport Open Close [9a2]: {res:?}"); + assert!(res.is_ok()); + let c_ses4 = res.unwrap(); + println!("Transport Open Close [9b1]"); + let transports = client02_manager.get_transports(); + println!("Transport Open Close [9b2]: {transports:?}"); + assert_eq!(transports.len(), 1); + println!("Transport Open Close [9c1]"); + let links = c_ses4.get_links().unwrap(); + println!("Transport Open Close [9c2]: {links:?}"); + assert_eq!(links.len(), links_num); + + // Verify that the transport has been open on the router + println!("Transport Open Close [9d1]"); + ztimeout!(async { + loop { + let transports = router_manager.get_transports(); + let s = transports + .iter() + .find(|s| s.get_zid().unwrap() == client02_id); + match s { + Some(s) => { + let links = s.get_links().unwrap(); + assert_eq!(links.len(), links_num); + break; + } + None => task::sleep(SLEEP).await, + } + } + }); + + /* [9] */ + // Close the open transport on the client + println!("Transport Open Close [9a1]"); + let res = ztimeout!(c_ses4.close()); + println!("Transport Open Close [9a2]: {res:?}"); + assert!(res.is_ok()); + println!("Transport Open Close [9b1]"); + let transports = client02_manager.get_transports(); + println!("Transport Open Close [9b2]: {transports:?}"); + assert_eq!(transports.len(), 0); + + // Verify that the transport has been closed also on the router + println!("Transport Open Close [9c1]"); + ztimeout!(async { + loop { + let transports = router_manager.get_transports(); + if transports.is_empty() { + break; + } + task::sleep(SLEEP).await; + } + }); + + /* [10] */ + // Perform clean up of the open locators + println!("\nTransport Open Close [10a1]"); + let res = ztimeout!(router_manager.del_listener(endpoint)); + println!("Transport Open Close [10a2]: {res:?}"); + assert!(res.is_ok()); + + ztimeout!(async { + while !router_manager.get_listeners().is_empty() { + task::sleep(SLEEP).await; + } + }); + + // Wait a little bit + task::sleep(SLEEP).await; + + ztimeout!(router_manager.close()); + ztimeout!(client01_manager.close()); + ztimeout!(client02_manager.close()); + + // Wait a little bit + task::sleep(SLEEP).await; + } + + #[cfg(all(feature = "transport_tcp"))] + #[test] + fn multilink_tcp_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 13000).parse().unwrap(); + task::block_on(multilink_transport(&endpoint)); + } + + #[cfg(feature = "transport_udp")] + #[test] + fn multilink_udp_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 13010).parse().unwrap(); + task::block_on(multilink_transport(&endpoint)); + } + + #[cfg(feature = "transport_ws")] + #[test] + fn multilink_ws_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 13020).parse().unwrap(); + task::block_on(multilink_transport(&endpoint)); + } + + #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] + #[test] + fn multilink_unix_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let f1 = "zenoh-test-unix-socket-9.sock"; + let _ = std::fs::remove_file(f1); + let endpoint: EndPoint = format!("unixsock-stream/{f1}").parse().unwrap(); + task::block_on(multilink_transport(&endpoint)); + let _ = std::fs::remove_file(f1); + let _ = std::fs::remove_file(format!("{f1}.lock")); + } + + #[cfg(feature = "transport_tls")] + #[test] + fn multilink_tls_only() { + use zenoh_link::tls::config::*; + + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // NOTE: this an auto-generated pair of certificate and key. + // The target domain is localhost, so it has no real + // mapping to any existing domain. The certificate and key + // have been generated using: https://github.com/jsha/minica + let key = "-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi +qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy +aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU +cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha +Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr +Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 +2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 +lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU +WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX +Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI +9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak +r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn +qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY +CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu +fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj +4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih +XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 +38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT +Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV +jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R +5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H +n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm +qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD +tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v +F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== +-----END RSA PRIVATE KEY-----"; + + let cert = "-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw +MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT +He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ +Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj +eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 +eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M +tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE +DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 +3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD +wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q +GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC +9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ +p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ +abY= +-----END CERTIFICATE-----"; + + // Configure the client + let ca = "-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw +MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ +uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs +DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc +8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 +T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b +QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB +AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 +/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq +hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ +e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc +yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 +8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 +Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN +R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== +-----END CERTIFICATE-----"; + + let mut endpoint: EndPoint = format!("tls/localhost:{}", 13030).parse().unwrap(); + endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, ca), + (TLS_SERVER_PRIVATE_KEY_RAW, key), + (TLS_SERVER_CERTIFICATE_RAW, cert), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + + task::block_on(multilink_transport(&endpoint)); + } + + #[cfg(feature = "transport_quic")] + #[test] + fn multilink_quic_only() { + use zenoh_link::quic::config::*; + + task::block_on(async { + zasync_executor_init!(); + }); + + // NOTE: this an auto-generated pair of certificate and key. + // The target domain is localhost, so it has no real + // mapping to any existing domain. The certificate and key + // have been generated using: https://github.com/jsha/minica + let key = "-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi +qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy +aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU +cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha +Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr +Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 +2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 +lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU +WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX +Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI +9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak +r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn +qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY +CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu +fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj +4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih +XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 +38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT +Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV +jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R +5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H +n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm +qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD +tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v +F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== +-----END RSA PRIVATE KEY-----"; + + let cert = "-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw +MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT +He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ +Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj +eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 +eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M +tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE +DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 +3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD +wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q +GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC +9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ +p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ +abY= +-----END CERTIFICATE-----"; + + // Configure the client + let ca = "-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw +MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ +uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs +DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc +8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 +T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b +QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB +AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 +/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq +hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ +e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc +yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 +8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 +Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN +R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== +-----END CERTIFICATE-----"; + + // Define the locator + let mut endpoint: EndPoint = format!("quic/localhost:{}", 13040).parse().unwrap(); + endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, ca), + (TLS_SERVER_PRIVATE_KEY_RAW, key), + (TLS_SERVER_CERTIFICATE_RAW, cert), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + + task::block_on(multilink_transport(&endpoint)); + } +} From 1899bdf2d02127380c9bad8f06d8b5c8e9a83369 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 09:41:27 +0100 Subject: [PATCH 076/203] Disable shared-memory by default --- io/zenoh-transport/src/unicast/establishment/open.rs | 4 ++-- zenoh/Cargo.toml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index f3b1e44041..ea8acb021d 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -486,13 +486,13 @@ pub(crate) async fn open_link( whatami: iack_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN), tx_initial_sn: osyn_out.mine_initial_sn, + #[cfg(feature = "transport_multilink")] + multilink: state.ext_mlink.multilink(), is_qos: state.ext_qos.is_qos(), #[cfg(feature = "shared-memory")] is_shm: state.ext_shm.is_shm(), #[cfg(not(feature = "shared-memory"))] is_shm: false, - #[cfg(feature = "transport_multilink")] - multilink: state.ext_mlink.multilink(), }; let transport = step!(manager .init_transport_unicast(config) diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 1b3a27de30..996bed77fa 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -57,7 +57,6 @@ default = [ "transport_udp", "transport_unixsock-stream", "transport_ws", - "shared-memory", ] [dependencies] From a2bafb1b897e61729026d1182a5233f529817a57 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 09:44:20 +0100 Subject: [PATCH 077/203] Fix cargo clippy --- io/zenoh-transport/src/unicast/establishment/accept.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 6e3078e9a9..2dd07a0173 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -216,6 +216,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { &self, input: Self::SendInitAckIn, ) -> Result { + #[allow(unused_mut)] // Required for "shared-memory" feature let (mut state, input) = input; // Extension QoS From d8a6fb004c0fcf59d3253eb35e9405f3adaeb128 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 11:13:25 +0100 Subject: [PATCH 078/203] Fix sequence_number_resolution config support --- DEFAULT_CONFIG.json5 | 6 +- commons/zenoh-config/src/defaults.rs | 2 +- commons/zenoh-config/src/lib.rs | 8 +- commons/zenoh-protocol/src/core/resolution.rs | 100 ++++++++++++++++++ commons/zenoh-protocol/src/core/whatami.rs | 89 ++++++++++------ io/zenoh-transport/src/common/seq_num.rs | 2 +- io/zenoh-transport/src/manager.rs | 21 ++-- io/zenoh-transport/src/unicast/manager.rs | 4 - 8 files changed, 178 insertions(+), 54 deletions(-) diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index 57a1b1ab42..fbf8235938 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -125,10 +125,10 @@ link: { /// Configure the zenoh TX parameters of a link tx: { - /// The largest value allowed for Zenoh message sequence numbers (wrappring to 0 when reached). + /// The resolution in bits to be used for the message sequence numbers. /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. - /// Defaults to 2^28. - sequence_number_resolution: 268435456, + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", /// Link lease duration in milliseconds to announce to other zenoh nodes lease: 10000, /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive diff --git a/commons/zenoh-config/src/defaults.rs b/commons/zenoh-config/src/defaults.rs index 00be5dac47..c9d8c95847 100644 --- a/commons/zenoh-config/src/defaults.rs +++ b/commons/zenoh-config/src/defaults.rs @@ -135,7 +135,7 @@ impl Default for LinkTxConf { fn default() -> Self { let num = 1 + ((num_cpus::get() - 1) / 4); Self { - sequence_number_resolution: Some((2 as ZInt).pow(28)), + sequence_number_resolution: Some(Bits::U32), lease: Some(10000), keep_alive: Some(4), batch_size: Some(u16::MAX), diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 46b2c1a888..f0d4b2ebf1 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -37,6 +37,7 @@ use zenoh_core::zlock; use zenoh_protocol::core::{ key_expr::OwnedKeyExpr, whatami::{WhatAmIMatcher, WhatAmIMatcherVisitor}, + Bits, }; pub use zenoh_protocol::core::{whatami, EndPoint, Locator, Priority, WhatAmI, ZenohId}; use zenoh_result::{bail, zerror, ZResult}; @@ -229,9 +230,10 @@ validated_struct::validator! { pub link: #[derive(Default)] TransportLinkConf { pub tx: LinkTxConf { - /// The largest value allowed for Zenoh message sequence numbers (wrappring to 0 when reached). When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. - /// Defaults to 2^28. - sequence_number_resolution: Option, + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: Option, /// Link lease duration in milliseconds (default: 10000) lease: Option, /// Number fo keep-alive messages in a link lease duration (default: 4) diff --git a/commons/zenoh-protocol/src/core/resolution.rs b/commons/zenoh-protocol/src/core/resolution.rs index f3036110d2..9c149a8b6b 100644 --- a/commons/zenoh-protocol/src/core/resolution.rs +++ b/commons/zenoh-protocol/src/core/resolution.rs @@ -13,6 +13,8 @@ // use super::ZInt; use crate::defaults::{FRAME_SN_RESOLUTION, REQUEST_ID_RESOLUTION}; +use core::{fmt, str::FromStr}; +use zenoh_result::{bail, ZError}; #[repr(u8)] // The value represents the 2-bit encoded value @@ -25,6 +27,11 @@ pub enum Bits { } impl Bits { + const S8: &str = "8bit"; + const S16: &str = "16bit"; + const S32: &str = "32bit"; + const S64: &str = "64bit"; + pub const fn mask(&self) -> ZInt { match self { Bits::U8 => u8::MAX as ZInt, @@ -33,6 +40,41 @@ impl Bits { Bits::U64 => u64::MAX as ZInt, } } + + pub const fn to_str(self) -> &'static str { + match self { + Bits::U8 => Self::S8, + Bits::U16 => Self::S16, + Bits::U32 => Self::S32, + Bits::U64 => Self::S64, + } + } +} + +impl FromStr for Bits { + type Err = ZError; + + fn from_str(s: &str) -> Result { + match s { + Bits::S8 => Ok(Bits::U8), + Bits::S16 => Ok(Bits::U16), + Bits::S32 => Ok(Bits::U32), + Bits::S64 => Ok(Bits::U64), + _ => bail!( + "{s} is not a valid Bits value. Valid values are: '{}', '{}', '{}', '{}'.", + Bits::S8, + Bits::S16, + Bits::S32, + Bits::S64 + ), + } + } +} + +impl fmt::Display for Bits { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.to_str()) + } } #[repr(u8)] @@ -85,3 +127,61 @@ impl From for Resolution { Self(v) } } + +// Serde +impl serde::Serialize for Bits { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.to_str()) + } +} + +pub struct BitsVisitor; +impl<'de> serde::de::Visitor<'de> for BitsVisitor { + type Value = Bits; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!( + formatter, + "either '{}', '{}', '{}', '{}'.", + Bits::S8, + Bits::S16, + Bits::S32, + Bits::S64, + ) + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + v.parse().map_err(|_| { + serde::de::Error::unknown_variant(v, &[Bits::S8, Bits::S16, Bits::S32, Bits::S64]) + }) + } + + fn visit_borrowed_str(self, v: &'de str) -> Result + where + E: serde::de::Error, + { + self.visit_str(v) + } + + fn visit_string(self, v: String) -> Result + where + E: serde::de::Error, + { + self.visit_str(&v) + } +} + +impl<'de> serde::Deserialize<'de> for Bits { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_str(BitsVisitor) + } +} diff --git a/commons/zenoh-protocol/src/core/whatami.rs b/commons/zenoh-protocol/src/core/whatami.rs index 407f7ff2d8..932640fe67 100644 --- a/commons/zenoh-protocol/src/core/whatami.rs +++ b/commons/zenoh-protocol/src/core/whatami.rs @@ -16,10 +16,6 @@ use const_format::formatcp; use core::{convert::TryFrom, fmt, num::NonZeroU8, ops::BitOr, str::FromStr}; use zenoh_result::{bail, ZError}; -const WAI_STR_R: &str = "router"; -const WAI_STR_P: &str = "peer"; -const WAI_STR_C: &str = "client"; - #[repr(u8)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum WhatAmI { @@ -29,15 +25,19 @@ pub enum WhatAmI { } impl WhatAmI { - const U8_R: u8 = WhatAmI::Router as u8; - const U8_P: u8 = WhatAmI::Peer as u8; - const U8_C: u8 = WhatAmI::Client as u8; + const STR_R: &str = "router"; + const STR_P: &str = "peer"; + const STR_C: &str = "client"; + + const U8_R: u8 = Self::Router as u8; + const U8_P: u8 = Self::Peer as u8; + const U8_C: u8 = Self::Client as u8; pub const fn to_str(self) -> &'static str { match self { - WhatAmI::Router => WAI_STR_R, - WhatAmI::Peer => WAI_STR_P, - WhatAmI::Client => WAI_STR_C, + Self::Router => Self::STR_R, + Self::Peer => Self::STR_P, + Self::Client => Self::STR_C, } } @@ -46,7 +46,7 @@ impl WhatAmI { use rand::prelude::SliceRandom; let mut rng = rand::thread_rng(); - *[WhatAmI::Router, WhatAmI::Peer, WhatAmI::Client] + *[Self::Router, Self::Peer, Self::Client] .choose(&mut rng) .unwrap() } @@ -57,9 +57,9 @@ impl TryFrom for WhatAmI { fn try_from(v: u8) -> Result { match v { - Self::U8_R => Ok(WhatAmI::Router), - Self::U8_P => Ok(WhatAmI::Peer), - Self::U8_C => Ok(WhatAmI::Client), + Self::U8_R => Ok(Self::Router), + Self::U8_P => Ok(Self::Peer), + Self::U8_C => Ok(Self::Client), _ => Err(()), } } @@ -70,11 +70,14 @@ impl FromStr for WhatAmI { fn from_str(s: &str) -> Result { match s { - WAI_STR_R => Ok(WhatAmI::Router), - WAI_STR_P => Ok(WhatAmI::Peer), - WAI_STR_C => Ok(WhatAmI::Client), + Self::STR_R => Ok(Self::Router), + Self::STR_P => Ok(Self::Peer), + Self::STR_C => Ok(Self::Client), _ => bail!( - "{s} is not a valid WhatAmI value. Valid values are: {WAI_STR_R}, {WAI_STR_P}, {WAI_STR_C}." + "{s} is not a valid WhatAmI value. Valid values are: {}, {}, {}.", + Self::STR_R, + Self::STR_P, + Self::STR_C ), } } @@ -134,13 +137,13 @@ impl WhatAmIMatcher { pub const fn to_str(self) -> &'static str { match self.0.get() { Self::U8_0 => "", - Self::U8_R => WAI_STR_R, - Self::U8_P => WAI_STR_P, - Self::U8_C => WAI_STR_C, - Self::U8_R_P => formatcp!("{}|{}", WAI_STR_R, WAI_STR_P), - Self::U8_R_C => formatcp!("{}|{}", WAI_STR_R, WAI_STR_C), - Self::U8_P_C => formatcp!("{}|{}", WAI_STR_P, WAI_STR_C), - Self::U8_R_P_C => formatcp!("{}|{}|{}", WAI_STR_R, WAI_STR_P, WAI_STR_C), + Self::U8_R => WhatAmI::STR_R, + Self::U8_P => WhatAmI::STR_P, + Self::U8_C => WhatAmI::STR_C, + Self::U8_R_P => formatcp!("{}|{}", WhatAmI::STR_R, WhatAmI::STR_P), + Self::U8_R_C => formatcp!("{}|{}", WhatAmI::STR_R, WhatAmI::STR_C), + Self::U8_P_C => formatcp!("{}|{}", WhatAmI::STR_P, WhatAmI::STR_C), + Self::U8_R_P_C => formatcp!("{}|{}|{}", WhatAmI::STR_R, WhatAmI::STR_P, WhatAmI::STR_C), _ => unreachable!(), } } @@ -189,9 +192,9 @@ impl FromStr for WhatAmIMatcher { for s in s.split('|') { match s.trim() { "" => {} - WAI_STR_R => inner |= WhatAmI::U8_R, - WAI_STR_P => inner |= WhatAmI::U8_P, - WAI_STR_C => inner |= WhatAmI::U8_C, + WhatAmI::STR_R => inner |= WhatAmI::U8_R, + WhatAmI::STR_P => inner |= WhatAmI::U8_P, + WhatAmI::STR_C => inner |= WhatAmI::U8_C, _ => return Err(()), } } @@ -270,14 +273,21 @@ impl<'de> serde::de::Visitor<'de> for WhatAmIVisitor { type Value = WhatAmI; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("either 'router', 'client' or 'peer'") + write!( + formatter, + "either '{}', '{}' or '{}'", + WhatAmI::STR_R, + WhatAmI::STR_P, + WhatAmI::STR_C + ) } fn visit_str(self, v: &str) -> Result where E: serde::de::Error, { - v.parse() - .map_err(|_| serde::de::Error::unknown_variant(v, &["router", "client", "peer"])) + v.parse().map_err(|_| { + serde::de::Error::unknown_variant(v, &[WhatAmI::STR_R, WhatAmI::STR_P, WhatAmI::STR_C]) + }) } fn visit_borrowed_str(self, v: &'de str) -> Result where @@ -315,8 +325,15 @@ pub struct WhatAmIMatcherVisitor; impl<'de> serde::de::Visitor<'de> for WhatAmIMatcherVisitor { type Value = WhatAmIMatcher; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a | separated list of whatami variants ('peer', 'client' or 'router')") + write!( + formatter, + "a | separated list of whatami variants ('{}', '{}', '{}')", + WhatAmI::STR_R, + WhatAmI::STR_P, + WhatAmI::STR_C + ) } + fn visit_str(self, v: &str) -> Result where E: serde::de::Error, @@ -324,10 +341,16 @@ impl<'de> serde::de::Visitor<'de> for WhatAmIMatcherVisitor { v.parse().map_err(|_| { serde::de::Error::invalid_value( serde::de::Unexpected::Str(v), - &"a | separated list of whatami variants ('peer', 'client' or 'router')", + &formatcp!( + "a | separated list of whatami variants ('{}', '{}', '{}')", + WhatAmI::STR_R, + WhatAmI::STR_P, + WhatAmI::STR_C + ), ) }) } + fn visit_borrowed_str(self, v: &'de str) -> Result where E: serde::de::Error, diff --git a/io/zenoh-transport/src/common/seq_num.rs b/io/zenoh-transport/src/common/seq_num.rs index f168a3f479..16813bed4c 100644 --- a/io/zenoh-transport/src/common/seq_num.rs +++ b/io/zenoh-transport/src/common/seq_num.rs @@ -116,7 +116,7 @@ impl SeqNum { } /// Computes the modulo gap between two sequence numbers. - #[cfg(test)] // @TODO: remove once reliability is implemented + #[cfg(test)] // @TODO: remove #[cfg(test)] once reliability is implemented pub(crate) fn gap(&self, value: ZInt) -> ZResult { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index d64369f259..85f20e0327 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -25,7 +25,7 @@ use zenoh_config::{Config, LinkRxConf, QueueConf, QueueSizeConf}; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::NewLinkChannelSender; use zenoh_protocol::{ - core::{EndPoint, Locator, Priority, Resolution, WhatAmI, ZenohId}, + core::{EndPoint, Field, Locator, Priority, Resolution, WhatAmI, ZenohId}, defaults::BATCH_SIZE, VERSION, }; @@ -180,14 +180,17 @@ impl TransportManagerBuilder { self = self.whatami(*v); } - // self = self.resolution( - // config - // .transport() - // .link() - // .tx() - // .sequence_number_resolution() - // .unwrap(), - // ); // @TODO + let mut resolution = Resolution::default(); + resolution.set( + Field::FrameSN, + config + .transport() + .link() + .tx() + .sequence_number_resolution() + .unwrap(), + ); + self = self.resolution(resolution); self = self.batch_size(config.transport().link().tx().batch_size().unwrap()); self = self.defrag_buff_size(config.transport().link().rx().max_message_size().unwrap()); self = self.link_rx_buffer_size(config.transport().link().rx().buffer_size().unwrap()); diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index d7e4d56b91..5eca82d54b 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -457,10 +457,6 @@ impl TransportManager { e })?; - // for pa in zasyncread!(self.state.unicast.peer_authenticator).iter() { - // pa.handle_close(peer).await; - // } @TODO - Ok(()) } From 9490756c7a9bc2a889f9a8fa95c311af679dce9c Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 12:10:30 +0100 Subject: [PATCH 079/203] Resolves #443 --- DEFAULT_CONFIG.json5 | 5 ++++ commons/zenoh-config/src/lib.rs | 3 ++ commons/zenoh-protocol/src/core/locator.rs | 2 -- io/zenoh-transport/src/manager.rs | 32 +++++++++++++++++++++ io/zenoh-transport/src/multicast/manager.rs | 21 ++++++-------- io/zenoh-transport/src/unicast/manager.rs | 30 ++++++++++--------- 6 files changed, 65 insertions(+), 28 deletions(-) diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index 57a1b1ab42..fe596e18a0 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -109,6 +109,11 @@ /// Configure internal transport parameters transport: { + // /// An optional whitelist of protocols to be used for accepting and opening sessions. + // /// If not configured, all the supported protocols are automatically whitelisted. + // /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + // /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], unicast: { /// Timeout in milliseconds when opening a link accept_timeout: 10000, diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 28acb61bad..c0fda5b157 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -227,6 +227,9 @@ validated_struct::validator! { }, pub link: #[derive(Default)] TransportLinkConf { + // An optional whitelist of protocols to be used for accepting and opening sessions. + // If not configured, all the supported protocols are automatically whitelisted. + pub protocols: Option>, pub tx: LinkTxConf { /// The largest value allowed for Zenoh message sequence numbers (wrappring to 0 when reached). When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. /// Defaults to 2^28. diff --git a/commons/zenoh-protocol/src/core/locator.rs b/commons/zenoh-protocol/src/core/locator.rs index 898f891c5b..0f1a50a13a 100644 --- a/commons/zenoh-protocol/src/core/locator.rs +++ b/commons/zenoh-protocol/src/core/locator.rs @@ -110,8 +110,6 @@ impl fmt::Display for Locator { } } -pub type LocatorProtocol = str; - impl Locator { #[cfg(feature = "test")] pub fn rand() -> Self { diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index a1a125a969..eb5401e8ad 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -106,6 +106,7 @@ pub struct TransportManagerConfig { pub endpoint: HashMap, pub handler: Arc, pub tx_threads: usize, + pub protocols: Option>, } pub struct TransportManagerState { @@ -132,6 +133,7 @@ pub struct TransportManagerBuilder { multicast: TransportManagerBuilderMulticast, endpoint: HashMap, tx_threads: usize, + protocols: Option>, } impl TransportManagerBuilder { @@ -195,6 +197,11 @@ impl TransportManagerBuilder { self } + pub fn protocols(mut self, protocols: Option>) -> Self { + self.protocols = protocols; + self + } + pub async fn from_config(mut self, config: &Config) -> ZResult { self = self.zid(*config.id()); if let Some(v) = config.mode() { @@ -214,6 +221,7 @@ impl TransportManagerBuilder { self = self.link_rx_buffer_size(config.transport().link().rx().buffer_size().unwrap()); self = self.queue_size(config.transport().link().tx().queue().size().clone()); self = self.tx_threads(config.transport().link().tx().threads().unwrap()); + self = self.protocols(config.transport().link().protocols().clone()); let (c, errors) = zenoh_link::LinkConfigurator::default() .configurations(config) @@ -270,6 +278,7 @@ impl TransportManagerBuilder { endpoint: self.endpoint, handler, tx_threads: self.tx_threads, + protocols: self.protocols, }; let state = TransportManagerState { @@ -301,6 +310,7 @@ impl Default for TransportManagerBuilder { unicast: TransportManagerBuilderUnicast::default(), multicast: TransportManagerBuilderMulticast::default(), tx_threads: 1, + protocols: None, } } } @@ -404,6 +414,17 @@ impl TransportManager { /* LISTENER */ /*************************************/ pub async fn add_listener(&self, endpoint: EndPoint) -> ZResult { + if let Some(protocols) = self.config.protocols.as_ref() { + let p = endpoint.protocol(); + if !protocols.iter().any(|x| x.as_str() == p.as_str()) { + bail!( + "Unauthorized protocol: {}. Whitelisted protocols are: {:?}", + p, + protocols + ); + } + } + if self .locator_inspector .is_multicast(&endpoint.to_locator()) @@ -453,6 +474,17 @@ impl TransportManager { } pub async fn open_transport(&self, endpoint: EndPoint) -> ZResult { + if let Some(protocols) = self.config.protocols.as_ref() { + let p = endpoint.protocol(); + if !protocols.iter().any(|x| x.as_str() == p.as_str()) { + bail!( + "Unauthorized protocol: {}. Whitelisted protocols are: {:?}", + p, + protocols + ); + } + } + if self .locator_inspector .is_multicast(&endpoint.to_locator()) diff --git a/io/zenoh-transport/src/multicast/manager.rs b/io/zenoh-transport/src/multicast/manager.rs index 99e4ae12c5..c7d7553da1 100644 --- a/io/zenoh-transport/src/multicast/manager.rs +++ b/io/zenoh-transport/src/multicast/manager.rs @@ -20,7 +20,7 @@ use std::time::Duration; use zenoh_config::{Config, ZN_LINK_KEEP_ALIVE_DEFAULT, ZN_LINK_LEASE_DEFAULT}; use zenoh_core::{zlock, zparse}; use zenoh_link::*; -use zenoh_protocol::{core::locator::LocatorProtocol, transport::tmsg}; +use zenoh_protocol::{core::endpoint::Protocol, transport::tmsg}; use zenoh_result::{bail, zerror, ZResult}; pub struct TransportManagerConfigMulticast { @@ -149,23 +149,20 @@ impl TransportManager { /*************************************/ /* LINK MANAGER */ /*************************************/ - fn new_link_manager_multicast( - &self, - protocol: &LocatorProtocol, - ) -> ZResult { + fn new_link_manager_multicast(&self, protocol: &Protocol) -> ZResult { let mut w_guard = zlock!(self.state.multicast.protocols); - match w_guard.get(protocol) { + match w_guard.get(protocol.as_str()) { Some(lm) => Ok(lm.clone()), None => { - let lm = LinkManagerBuilderMulticast::make(protocol)?; - w_guard.insert(protocol.to_owned(), lm.clone()); + let lm = LinkManagerBuilderMulticast::make(protocol.as_str())?; + w_guard.insert(protocol.to_string(), lm.clone()); Ok(lm) } } } - fn del_link_manager_multicast(&self, protocol: &LocatorProtocol) -> ZResult<()> { - match zlock!(self.state.multicast.protocols).remove(protocol) { + fn del_link_manager_multicast(&self, protocol: &Protocol) -> ZResult<()> { + match zlock!(self.state.multicast.protocols).remove(protocol.as_str()) { Some(_) => Ok(()), None => bail!( "Can not delete the link manager for protocol ({}) because it has not been found.", @@ -193,7 +190,7 @@ impl TransportManager { } // Automatically create a new link manager for the protocol if it does not exist - let manager = self.new_link_manager_multicast(endpoint.protocol().as_str())?; + let manager = self.new_link_manager_multicast(&endpoint.protocol())?; // Fill and merge the endpoint configuration if let Some(config) = self.config.endpoint.get(endpoint.protocol().as_str()) { endpoint.config_mut().extend(config.iter())?; @@ -223,7 +220,7 @@ impl TransportManager { let proto = locator.protocol(); if !guard.iter().any(|(l, _)| l.protocol() == proto) { - let _ = self.del_link_manager_multicast(proto.as_str()); + let _ = self.del_link_manager_multicast(&proto); } res.map(|_| ()).ok_or_else(|| { diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 3e6d988dab..74d0f0fa69 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -28,7 +28,7 @@ use zenoh_config::Config; use zenoh_core::{zasynclock, zasyncread, zasyncwrite, zlock, zparse}; use zenoh_link::*; use zenoh_protocol::{ - core::{locator::LocatorProtocol, ZenohId}, + core::{endpoint::Protocol, ZenohId}, transport::tmsg, }; use zenoh_result::{bail, zerror, ZResult}; @@ -275,20 +275,22 @@ impl TransportManager { /*************************************/ /* LINK MANAGER */ /*************************************/ - fn new_link_manager_unicast(&self, protocol: &str) -> ZResult { + fn new_link_manager_unicast(&self, protocol: &Protocol) -> ZResult { let mut w_guard = zlock!(self.state.unicast.protocols); - if let Some(lm) = w_guard.get(protocol) { + if let Some(lm) = w_guard.get(protocol.as_str()) { Ok(lm.clone()) } else { - let lm = - LinkManagerBuilderUnicast::make(self.new_unicast_link_sender.clone(), protocol)?; - w_guard.insert(protocol.to_owned(), lm.clone()); + let lm = LinkManagerBuilderUnicast::make( + self.new_unicast_link_sender.clone(), + protocol.as_str(), + )?; + w_guard.insert(protocol.to_string(), lm.clone()); Ok(lm) } } - fn get_link_manager_unicast(&self, protocol: &LocatorProtocol) -> ZResult { - match zlock!(self.state.unicast.protocols).get(protocol) { + fn get_link_manager_unicast(&self, protocol: &Protocol) -> ZResult { + match zlock!(self.state.unicast.protocols).get(protocol.as_str()) { Some(manager) => Ok(manager.clone()), None => bail!( "Can not get the link manager for protocol ({}) because it has not been found", @@ -297,8 +299,8 @@ impl TransportManager { } } - fn del_link_manager_unicast(&self, protocol: &LocatorProtocol) -> ZResult<()> { - match zlock!(self.state.unicast.protocols).remove(protocol) { + fn del_link_manager_unicast(&self, protocol: &Protocol) -> ZResult<()> { + match zlock!(self.state.unicast.protocols).remove(protocol.as_str()) { Some(_) => Ok(()), None => bail!( "Can not delete the link manager for protocol ({}) because it has not been found.", @@ -311,7 +313,7 @@ impl TransportManager { /* LISTENER */ /*************************************/ pub async fn add_listener_unicast(&self, mut endpoint: EndPoint) -> ZResult { - let manager = self.new_link_manager_unicast(endpoint.protocol().as_str())?; + let manager = self.new_link_manager_unicast(&endpoint.protocol())?; // Fill and merge the endpoint configuration if let Some(config) = self.config.endpoint.get(endpoint.protocol().as_str()) { endpoint.config_mut().extend(config.iter())?; @@ -320,10 +322,10 @@ impl TransportManager { } pub async fn del_listener_unicast(&self, endpoint: &EndPoint) -> ZResult<()> { - let lm = self.get_link_manager_unicast(endpoint.protocol().as_str())?; + let lm = self.get_link_manager_unicast(&endpoint.protocol())?; lm.del_listener(endpoint).await?; if lm.get_listeners().is_empty() { - self.del_link_manager_unicast(endpoint.protocol().as_str())?; + self.del_link_manager_unicast(&endpoint.protocol())?; } Ok(()) } @@ -462,7 +464,7 @@ impl TransportManager { } // Automatically create a new link manager for the protocol if it does not exist - let manager = self.new_link_manager_unicast(endpoint.protocol().as_str())?; + let manager = self.new_link_manager_unicast(&endpoint.protocol())?; // Fill and merge the endpoint configuration if let Some(config) = self.config.endpoint.get(endpoint.protocol().as_str()) { endpoint.config_mut().extend(config.iter())?; From ad944b96cf5ab507f71623363411351467dab6dd Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 12:12:55 +0100 Subject: [PATCH 080/203] Add missing test file --- .../tests/transport_whitelist.rs | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 io/zenoh-transport/tests/transport_whitelist.rs diff --git a/io/zenoh-transport/tests/transport_whitelist.rs b/io/zenoh-transport/tests/transport_whitelist.rs new file mode 100644 index 0000000000..785944de6c --- /dev/null +++ b/io/zenoh-transport/tests/transport_whitelist.rs @@ -0,0 +1,139 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use async_std::{prelude::FutureExt, task}; +use std::{any::Any, convert::TryFrom, iter::FromIterator, sync::Arc, time::Duration}; +use zenoh_core::zasync_executor_init; +use zenoh_link::Link; +use zenoh_protocol::{ + core::{EndPoint, ZenohId}, + zenoh::ZenohMessage, +}; +use zenoh_result::ZResult; +use zenoh_transport::{ + TransportEventHandler, TransportManager, TransportMulticast, TransportMulticastEventHandler, + TransportPeer, TransportPeerEventHandler, TransportUnicast, +}; + +const TIMEOUT: Duration = Duration::from_secs(60); +const SLEEP: Duration = Duration::from_secs(1); + +macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; +} + +// Transport Handler for the router +struct SHRouter; + +impl TransportEventHandler for SHRouter { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + let arc = Arc::new(SCRouter); + Ok(arc) + } + + fn new_multicast( + &self, + _transport: TransportMulticast, + ) -> ZResult> { + panic!(); + } +} + +pub struct SCRouter; + +impl TransportPeerEventHandler for SCRouter { + fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { + Ok(()) + } + + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } +} + +async fn run(endpoints: &[EndPoint]) { + // Define client and router IDs + let router_id = ZenohId::try_from([1]).unwrap(); + + // Create the router transport manager + println!(">>> Transport Whitelist [1a1]"); + let router_manager = TransportManager::builder() + .zid(router_id) + .protocols(Some(vec![])) // No protocols allowed + .build(Arc::new(SHRouter)) + .unwrap(); + + // Create the listener on the router + for e in endpoints.iter() { + println!("Listener endpoint: {e}"); + let res = ztimeout!(router_manager.add_listener(e.clone())); + assert!(res.is_err()); + + println!("Open endpoint: {e}"); + let res = ztimeout!(router_manager.open_transport(e.clone())); + assert!(res.is_err()); + } + + // Create the router transport manager + println!(">>> Transport Whitelist [2a1]"); + let unicast = TransportManager::config_unicast().max_links(usize::MAX); + let router_manager = TransportManager::builder() + .zid(router_id) + .unicast(unicast) + .protocols(Some(Vec::from_iter( + endpoints.iter().map(|e| e.protocol().to_string()), + ))) + .build(Arc::new(SHRouter)) + .unwrap(); + + // Create the listener on the router + for e in endpoints.iter() { + println!("Listener endpoint: {e}"); + let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); + + task::sleep(SLEEP).await; + + println!("Open endpoint: {e}"); + let _ = ztimeout!(router_manager.open_transport(e.clone())).unwrap(); + + task::sleep(SLEEP).await; + } +} + +#[cfg(feature = "transport_tcp")] +#[test] +fn transport_whitelist_tcp() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoints: Vec = vec![ + format!("tcp/127.0.0.1:{}", 17000).parse().unwrap(), + format!("tcp/[::1]:{}", 17001).parse().unwrap(), + ]; + // Run + task::block_on(run(&endpoints)); +} From 0b8e0371a3f041ef06c1a5de87c4c18882d1b69a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 12:25:16 +0100 Subject: [PATCH 081/203] Fix nostd CI --- commons/zenoh-protocol/src/core/resolution.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/commons/zenoh-protocol/src/core/resolution.rs b/commons/zenoh-protocol/src/core/resolution.rs index 9c149a8b6b..c7227ece08 100644 --- a/commons/zenoh-protocol/src/core/resolution.rs +++ b/commons/zenoh-protocol/src/core/resolution.rs @@ -13,6 +13,7 @@ // use super::ZInt; use crate::defaults::{FRAME_SN_RESOLUTION, REQUEST_ID_RESOLUTION}; +use alloc::string::String; use core::{fmt, str::FromStr}; use zenoh_result::{bail, ZError}; From f564cef590f8e8108f534b6e79a247f7cc48592d Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 12:59:42 +0100 Subject: [PATCH 082/203] Improve SHM automatic translation --- io/zenoh-transport/src/shm.rs | 60 +++++++++++-------- .../src/unicast/establishment/accept.rs | 2 +- .../src/unicast/establishment/open.rs | 1 - io/zenoh-transport/src/unicast/rx.rs | 10 ++-- io/zenoh-transport/src/unicast/tx.rs | 9 +-- zenoh/Cargo.toml | 1 + 6 files changed, 41 insertions(+), 42 deletions(-) diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index e9abc4c129..67ee3932e3 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -11,10 +11,11 @@ // Contributors: // ZettaScale Zenoh Team, // +use async_std::{sync::RwLock, task}; use std::any::TypeId; use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZBuf, ZSlice}; use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_core::zerror; +use zenoh_core::{zasyncread, zasyncwrite, zerror}; use zenoh_protocol::zenoh::*; use zenoh_result::ZResult; use zenoh_shm::{ @@ -54,35 +55,39 @@ macro_rules! set_sliced { }; } -pub fn map_zslice_to_shmbuf(zslice: &mut ZSlice, shmr: &mut SharedMemoryReader) -> ZResult { - let mut res = false; - +#[inline(never)] +pub fn map_zslice_to_shmbuf( + zslice: &mut ZSlice, + shmr: &RwLock, +) -> ZResult { let ZSlice { buf, .. } = zslice; - if buf.as_any().type_id() == TypeId::of::() { - // Deserialize the shmb info into shm buff - let codec = Zenoh080::new(); - let mut reader = buf.as_slice().reader(); - let shmbinfo: SharedMemoryBufInfo = - codec.read(&mut reader).map_err(|e| zerror!("{:?}", e))?; - - // First, try in read mode allowing concurrenct lookups - let smb = shmr - .try_read_shmbuf(&shmbinfo) - .or_else(|_| shmr.read_shmbuf(&shmbinfo))?; - - // Replace the content of the slice - let zs: ZSlice = smb.into(); - *zslice = zs; - - res = true; - } - Ok(res) + // Deserialize the shmb info into shm buff + let codec = Zenoh080::new(); + let mut reader = buf.as_slice().reader(); + let shmbinfo: SharedMemoryBufInfo = codec.read(&mut reader).map_err(|e| zerror!("{:?}", e))?; + + // First, try in read mode allowing concurrenct lookups + let r_guard = task::block_on(async { zasyncread!(shmr) }); + let smb = r_guard.try_read_shmbuf(&shmbinfo).or_else(|_| { + drop(r_guard); + let mut w_guard = task::block_on(async { zasyncwrite!(shmr) }); + w_guard.read_shmbuf(&shmbinfo) + })?; + + // Replace the content of the slice + let zs: ZSlice = smb.into(); + *zslice = zs; + + Ok(true) } -pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &mut SharedMemoryReader) -> ZResult { +pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &RwLock) -> ZResult { let mut res = false; for zs in zbuf.zslices_mut() { - res |= map_zslice_to_shmbuf(zs, shmr)?; + let ZSlice { buf, .. } = zs; + if buf.as_any().type_id() == TypeId::of::() { + res |= map_zslice_to_shmbuf(zs, shmr)?; + } } Ok(res) } @@ -118,7 +123,10 @@ pub fn map_zbuf_to_shminfo(zbuf: &mut ZBuf) -> ZResult { Ok(res) } -pub fn map_zmsg_to_shmbuf(msg: &mut ZenohMessage, shmr: &mut SharedMemoryReader) -> ZResult { +pub fn map_zmsg_to_shmbuf( + msg: &mut ZenohMessage, + shmr: &RwLock, +) -> ZResult { let mut res = false; if let ZenohBody::Data(Data { diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 2dd07a0173..74676fdd04 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -492,7 +492,7 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) match $res { Ok(output) => output, Err((e, reason)) => { - log::error!("{}", e); + log::debug!("{}", e); close_link(link, reason).await; return Err(e); } diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index ea8acb021d..9fbe8c1c88 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -54,7 +54,6 @@ struct SendInitSynIn { } // InitAck - struct RecvInitAckOut { other_zid: ZenohId, other_whatami: WhatAmI, diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index d3e60cb8f0..8ee3e29537 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -17,8 +17,6 @@ use async_std::task; use std::sync::MutexGuard; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; -#[cfg(feature = "shared-memory")] -use zenoh_core::zasyncwrite; use zenoh_core::{zlock, zread}; use zenoh_link::LinkUnicast; #[cfg(feature = "stats")] @@ -70,10 +68,10 @@ impl TransportUnicastInner { #[cfg(feature = "shared-memory")] { if self.config.is_shm { - task::block_on(async { - let mut w_guard = zasyncwrite!(self.manager.state.unicast.shm.reader); - crate::shm::map_zmsg_to_shmbuf(&mut msg, &mut w_guard) - })?; + crate::shm::map_zmsg_to_shmbuf( + &mut msg, + &self.manager.state.unicast.shm.reader, + )?; } } callback.handle_message(msg) diff --git a/io/zenoh-transport/src/unicast/tx.rs b/io/zenoh-transport/src/unicast/tx.rs index e63eae31ce..a846909aff 100644 --- a/io/zenoh-transport/src/unicast/tx.rs +++ b/io/zenoh-transport/src/unicast/tx.rs @@ -12,12 +12,8 @@ // ZettaScale Zenoh Team, // use super::transport::TransportUnicastInner; -#[cfg(feature = "shared-memory")] -use async_std::task; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; -#[cfg(feature = "shared-memory")] -use zenoh_core::zasyncwrite; use zenoh_core::zread; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; @@ -76,10 +72,7 @@ impl TransportUnicastInner { let res = if self.config.is_shm { crate::shm::map_zmsg_to_shminfo(&mut msg) } else { - task::block_on(async { - let mut w_guard = zasyncwrite!(self.manager.state.unicast.shm.reader); - crate::shm::map_zmsg_to_shmbuf(&mut msg, &mut w_guard) - }) + crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.state.unicast.shm.reader) }; if let Err(e) = res { log::trace!("Failed SHM conversion: {}", e); diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 996bed77fa..1b3a27de30 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -57,6 +57,7 @@ default = [ "transport_udp", "transport_unixsock-stream", "transport_ws", + "shared-memory", ] [dependencies] From efc7e5565529e4a0c9d787088b58b862da0a013a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 18:06:49 +0100 Subject: [PATCH 083/203] Improve conditional compilation of features --- commons/zenoh-core/src/macros.rs | 18 +++ io/zenoh-transport/Cargo.toml | 5 +- .../src/unicast/establishment/accept.rs | 128 ++++++++++-------- .../src/unicast/establishment/cookie.rs | 25 ++-- .../src/unicast/establishment/ext/mod.rs | 2 +- .../src/unicast/establishment/open.rs | 123 +++++++++-------- io/zenoh-transport/src/unicast/manager.rs | 75 ++++++---- io/zenoh-transport/src/unicast/mod.rs | 3 +- io/zenoh-transport/src/unicast/transport.rs | 16 ++- 9 files changed, 237 insertions(+), 158 deletions(-) diff --git a/commons/zenoh-core/src/macros.rs b/commons/zenoh-core/src/macros.rs index 0755d846e5..73556d4c28 100644 --- a/commons/zenoh-core/src/macros.rs +++ b/commons/zenoh-core/src/macros.rs @@ -191,3 +191,21 @@ macro_rules! zparse { }) }; } + +// This macro allows to do conditional compilation +#[macro_export] +macro_rules! zcondfeat { + ($feature:literal, $yes:expr, $not:expr) => {{ + { + #[cfg(feature = $feature)] + { + $yes + } + + #[cfg(not(feature = $feature))] + { + $not + } + } + }}; +} diff --git a/io/zenoh-transport/Cargo.toml b/io/zenoh-transport/Cargo.toml index 8be7e8a6bf..0177335788 100644 --- a/io/zenoh-transport/Cargo.toml +++ b/io/zenoh-transport/Cargo.toml @@ -30,8 +30,9 @@ shared-memory = [ "zenoh-shm", "zenoh-codec/shared-memory", ] -auth_pubkey = ["rsa"] -auth_usrpwd = [] +auth_pubkey = ["transport_auth", "rsa"] +auth_usrpwd = ["transport_auth"] +transport_auth = [] transport_multilink = ["auth_pubkey"] transport_quic = ["zenoh-link/transport_quic"] transport_tcp = ["zenoh-link/transport_tcp"] diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 74676fdd04..ff8d681cb1 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -26,7 +26,7 @@ use rand::Rng; use std::time::Duration; use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZSlice}; use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_core::{zasynclock, zerror}; +use zenoh_core::{zasynclock, zcondfeat, zerror}; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ @@ -48,11 +48,12 @@ struct StateZenoh { struct State { zenoh: StateZenoh, ext_qos: ext::qos::StateAccept, + #[cfg(feature = "transport_multilink")] + ext_mlink: ext::multilink::StateAccept, #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateAccept, + #[cfg(feature = "transport_auth")] ext_auth: ext::auth::StateAccept, - #[cfg(feature = "transport_multilink")] - ext_mlink: ext::multilink::StateAccept, } // InitSyn @@ -107,11 +108,12 @@ struct AcceptLink<'a> { prng: &'a Mutex, cipher: &'a BlockCipher, ext_qos: ext::qos::QoSFsm<'a>, + #[cfg(feature = "transport_multilink")] + ext_mlink: ext::multilink::MultiLinkFsm<'a>, #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm<'a>, + #[cfg(feature = "transport_auth")] ext_auth: ext::auth::AuthFsm<'a>, - #[cfg(feature = "transport_multilink")] - ext_mlink: ext::multilink::MultiLinkFsm<'a>, } #[async_trait] @@ -189,6 +191,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Auth + #[cfg(feature = "transport_auth")] self.ext_auth .recv_init_syn((&mut state.ext_auth, init_syn.ext_auth)) .await @@ -227,29 +230,35 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm - #[cfg(feature = "shared-memory")] - let ext_shm = self - .ext_shm - .send_init_ack((&mut state.ext_shm, input.ext_shm)) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; - #[cfg(not(feature = "shared-memory"))] - let ext_shm = None; + let ext_shm = zcondfeat!( + "shared-memory", + self.ext_shm + .send_init_ack((&mut state.ext_shm, input.ext_shm)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Extension Auth - let ext_auth = self - .ext_auth - .send_init_ack(&state.ext_auth) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let ext_auth = zcondfeat!( + "transport_auth", + self.ext_auth + .send_init_ack(&state.ext_auth) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Extension MultiLink #[cfg(feature = "transport_multilink")] - let ext_mlink = self - .ext_mlink - .send_init_ack(&state.ext_mlink) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let ext_mlink = zcondfeat!( + "transport_multilink", + self.ext_mlink + .send_init_ack(&state.ext_mlink) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Create the cookie let cookie_nonce: ZInt = zasynclock!(self.prng).gen(); @@ -260,11 +269,12 @@ impl<'a> AcceptFsm for AcceptLink<'a> { batch_size: state.zenoh.batch_size, nonce: cookie_nonce, ext_qos: state.ext_qos, + #[cfg(feature = "transport_multilink")] + ext_mlink: state.ext_mlink, #[cfg(feature = "shared-memory")] ext_shm: state.ext_shm, + #[cfg(feature = "transport_auth")] ext_auth: state.ext_auth, - #[cfg(feature = "transport_multilink")] - ext_mlink: state.ext_mlink, }; let mut encrypted = vec![]; @@ -374,10 +384,12 @@ impl<'a> AcceptFsm for AcceptLink<'a> { resolution: cookie.resolution, }, ext_qos: cookie.ext_qos, + #[cfg(feature = "transport_multilink")] + ext_mlink: cookie.ext_mlink, #[cfg(feature = "shared-memory")] ext_shm: cookie.ext_shm, + #[cfg(feature = "transport_auth")] ext_auth: cookie.ext_auth, - ext_mlink: cookie.ext_mlink, }; // Extension QoS @@ -394,6 +406,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Auth + #[cfg(feature = "transport_auth")] self.ext_auth .recv_open_syn((&mut state.ext_auth, open_syn.ext_auth)) .await @@ -431,29 +444,34 @@ impl<'a> AcceptFsm for AcceptLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm - #[cfg(feature = "shared-memory")] - let ext_shm = self - .ext_shm - .send_open_ack(&mut state.ext_shm) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; - #[cfg(not(feature = "shared-memory"))] - let ext_shm = None; + let ext_shm = zcondfeat!( + "shared-memory", + self.ext_shm + .send_open_ack(&mut state.ext_shm) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Extension Auth - let ext_auth = self - .ext_auth - .send_open_ack(&state.ext_auth) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let ext_auth = zcondfeat!( + "transport_auth", + self.ext_auth + .send_open_ack(&state.ext_auth) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Extension MultiLink - #[cfg(feature = "transport_multilink")] - let ext_mlink = self - .ext_mlink - .send_open_ack(&state.ext_mlink) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let ext_mlink = zcondfeat!( + "transport_multilink", + self.ext_mlink + .send_open_ack(&state.ext_mlink) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Build OpenAck message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); @@ -481,9 +499,10 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) ext_qos: ext::qos::QoSFsm::new(), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), - ext_auth: manager.state.unicast.authenticator.fsm(&manager.prng), #[cfg(feature = "transport_multilink")] ext_mlink: manager.state.unicast.multilink.fsm(&manager.prng), + #[cfg(feature = "transport_auth")] + ext_auth: manager.state.unicast.authenticator.fsm(&manager.prng), }; // Init handshake @@ -507,19 +526,20 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) resolution: manager.config.resolution, }, ext_qos: ext::qos::StateAccept::new(manager.config.unicast.is_qos), + #[cfg(feature = "transport_multilink")] + ext_mlink: manager + .state + .unicast + .multilink + .accept(manager.config.unicast.max_links > 1), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateAccept::new(manager.config.unicast.is_shm), + #[cfg(feature = "transport_auth")] ext_auth: manager .state .unicast .authenticator .accept(&mut *zasynclock!(manager.prng)), - #[cfg(feature = "transport_multilink")] - ext_mlink: manager - .state - .unicast - .multilink - .accept(manager.config.unicast.max_links > 1), }; // Let's scope the Init phase in such a way memory is freed by Rust @@ -562,13 +582,11 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) whatami: osyn_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN), tx_initial_sn: oack_out.open_ack.initial_sn, + is_qos: state.ext_qos.is_qos(), #[cfg(feature = "transport_multilink")] multilink: state.ext_mlink.multilink(), - is_qos: state.ext_qos.is_qos(), #[cfg(feature = "shared-memory")] is_shm: state.ext_shm.is_shm(), - #[cfg(not(feature = "shared-memory"))] - is_shm: false, }; let transport = step!(manager .init_transport_unicast(config) diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index 3b277f5007..b5752ed5ff 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -31,11 +31,12 @@ pub(crate) struct Cookie { pub(crate) nonce: ZInt, // Extensions pub(crate) ext_qos: ext::qos::StateAccept, + #[cfg(feature = "transport_multilink")] + pub(crate) ext_mlink: ext::multilink::StateAccept, #[cfg(feature = "shared-memory")] pub(crate) ext_shm: ext::shm::StateAccept, + #[cfg(feature = "transport_auth")] pub(crate) ext_auth: ext::auth::StateAccept, - #[cfg(feature = "transport_multilink")] - pub(crate) ext_mlink: ext::multilink::StateAccept, } impl WCodec<&Cookie, &mut W> for Zenoh080 @@ -53,11 +54,12 @@ where self.write(&mut *writer, x.nonce)?; // Extensions self.write(&mut *writer, &x.ext_qos)?; + #[cfg(feature = "transport_multilink")] + self.write(&mut *writer, &x.ext_mlink)?; #[cfg(feature = "shared-memory")] self.write(&mut *writer, &x.ext_shm)?; + #[cfg(feature = "transport_auth")] self.write(&mut *writer, &x.ext_auth)?; - #[cfg(feature = "transport_multilink")] - self.write(&mut *writer, &x.ext_mlink)?; Ok(()) } @@ -79,11 +81,12 @@ where let nonce: ZInt = self.read(&mut *reader)?; // Extensions let ext_qos: ext::qos::StateAccept = self.read(&mut *reader)?; + #[cfg(feature = "transport_multilink")] + let ext_mlink: ext::multilink::StateAccept = self.read(&mut *reader)?; #[cfg(feature = "shared-memory")] let ext_shm: ext::shm::StateAccept = self.read(&mut *reader)?; + #[cfg(feature = "transport_auth")] let ext_auth: ext::auth::StateAccept = self.read(&mut *reader)?; - #[cfg(feature = "transport_multilink")] - let ext_mlink: ext::multilink::StateAccept = self.read(&mut *reader)?; let cookie = Cookie { zid, @@ -92,11 +95,12 @@ where batch_size, nonce, ext_qos, + #[cfg(feature = "transport_multilink")] + ext_mlink, #[cfg(feature = "shared-memory")] ext_shm, + #[cfg(feature = "transport_auth")] ext_auth, - #[cfg(feature = "transport_multilink")] - ext_mlink, }; Ok(cookie) @@ -159,11 +163,12 @@ impl Cookie { batch_size: rng.gen(), nonce: rng.gen(), ext_qos: ext::qos::StateAccept::rand(), + #[cfg(feature = "transport_multilink")] + ext_mlink: ext::multilink::StateAccept::rand(), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateAccept::rand(), + #[cfg(feature = "transport_auth")] ext_auth: ext::auth::StateAccept::rand(), - #[cfg(feature = "transport_multilink")] - ext_mlink: ext::multilink::StateAccept::rand(), } } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs index 728972f80b..30e7a12b53 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/mod.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // - +#[cfg(feature = "transport_auth")] pub mod auth; #[cfg(feature = "transport_multilink")] pub(crate) mod multilink; diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 9fbe8c1c88..1990f8573f 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -23,7 +23,9 @@ use async_trait::async_trait; use std::time::Duration; use zenoh_buffers::ZSlice; use zenoh_config::{WhatAmI, ZenohId}; -use zenoh_core::{zasynclock, zerror}; +#[cfg(feature = "transport_auth")] +use zenoh_core::zasynclock; +use zenoh_core::{zcondfeat, zerror}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::core::{Field, Resolution, ZInt}; use zenoh_protocol::transport::{close, Close, InitSyn, OpenSyn, TransportBody, TransportMessage}; @@ -39,11 +41,12 @@ struct StateZenoh { struct State { zenoh: StateZenoh, ext_qos: ext::qos::StateOpen, + #[cfg(feature = "transport_multilink")] + ext_mlink: ext::multilink::StateOpen, #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateOpen, + #[cfg(feature = "transport_auth")] ext_auth: ext::auth::StateOpen, - #[cfg(feature = "transport_multilink")] - ext_mlink: ext::multilink::StateOpen, } // InitSyn @@ -86,11 +89,12 @@ struct RecvOpenAckOut { struct OpenLink<'a> { link: &'a LinkUnicast, ext_qos: ext::qos::QoSFsm<'a>, + #[cfg(feature = "transport_multilink")] + ext_mlink: ext::multilink::MultiLinkFsm<'a>, #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm<'a>, + #[cfg(feature = "transport_auth")] ext_auth: ext::auth::AuthFsm<'a>, - #[cfg(feature = "transport_multilink")] - ext_mlink: ext::multilink::MultiLinkFsm<'a>, } #[async_trait] @@ -113,29 +117,34 @@ impl<'a> OpenFsm for OpenLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm - #[cfg(feature = "shared-memory")] - let ext_shm = self - .ext_shm - .send_init_syn(&state.ext_shm) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; - #[cfg(not(feature = "shared-memory"))] - let ext_shm = None; + let ext_shm = zcondfeat!( + "shared-memory", + self.ext_shm + .send_init_syn(&state.ext_shm) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Extension Auth - let ext_auth = self - .ext_auth - .send_init_syn(&state.ext_auth) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let ext_auth = zcondfeat!( + "transport_auth", + self.ext_auth + .send_init_syn(&state.ext_auth) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Extension MultiLink - #[cfg(feature = "transport_multilink")] - let ext_mlink = self - .ext_mlink - .send_init_syn(&state.ext_mlink) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let ext_mlink = zcondfeat!( + "transport_multilink", + self.ext_mlink + .send_init_syn(&state.ext_mlink) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); let msg: TransportMessage = InitSyn { version: input.mine_version, @@ -253,6 +262,7 @@ impl<'a> OpenFsm for OpenLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Auth + #[cfg(feature = "transport_auth")] self.ext_auth .recv_init_ack((&mut state.ext_auth, init_ack.ext_auth)) .await @@ -291,29 +301,35 @@ impl<'a> OpenFsm for OpenLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Shm - #[cfg(feature = "shared-memory")] - let ext_shm = self - .ext_shm - .send_open_syn((&state.ext_shm, input.ext_shm)) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; - #[cfg(not(feature = "shared-memory"))] - let ext_shm = None; + let ext_shm = zcondfeat!( + "shared-memory", + self.ext_shm + .send_open_syn((&state.ext_shm, input.ext_shm)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Extension Auth - let ext_auth = self - .ext_auth - .send_open_syn(&state.ext_auth) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let ext_auth = zcondfeat!( + "transport_auth", + self.ext_auth + .send_open_syn(&state.ext_auth) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Extension MultiLink #[cfg(feature = "transport_multilink")] - let ext_mlink = self - .ext_mlink - .send_open_syn(&state.ext_mlink) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + let ext_mlink = zcondfeat!( + "transport_multilink", + self.ext_mlink + .send_open_syn(&state.ext_mlink) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?, + None + ); // Build and send an OpenSyn message let mine_initial_sn = compute_sn(input.mine_zid, input.other_zid, state.zenoh.resolution); @@ -389,6 +405,7 @@ impl<'a> OpenFsm for OpenLink<'a> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Auth + #[cfg(feature = "transport_auth")] self.ext_auth .recv_open_ack((&mut state.ext_auth, open_ack.ext_auth)) .await @@ -416,11 +433,12 @@ pub(crate) async fn open_link( let fsm = OpenLink { link, ext_qos: ext::qos::QoSFsm::new(), + #[cfg(feature = "transport_multilink")] + ext_mlink: manager.state.unicast.multilink.fsm(&manager.prng), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::ShmFsm::new(&manager.state.unicast.shm), + #[cfg(feature = "transport_auth")] ext_auth: manager.state.unicast.authenticator.fsm(&manager.prng), - #[cfg(feature = "transport_multilink")] - ext_mlink: manager.state.unicast.multilink.fsm(&manager.prng), }; let mut state = State { @@ -429,19 +447,20 @@ pub(crate) async fn open_link( resolution: manager.config.resolution, }, ext_qos: ext::qos::StateOpen::new(manager.config.unicast.is_qos), + #[cfg(feature = "transport_multilink")] + ext_mlink: manager + .state + .unicast + .multilink + .open(manager.config.unicast.max_links > 1), #[cfg(feature = "shared-memory")] ext_shm: ext::shm::StateOpen::new(manager.config.unicast.is_shm), + #[cfg(feature = "transport_auth")] ext_auth: manager .state .unicast .authenticator .open(&mut *zasynclock!(manager.prng)), - #[cfg(feature = "transport_multilink")] - ext_mlink: manager - .state - .unicast - .multilink - .open(manager.config.unicast.max_links > 1), }; // Init handshake @@ -485,13 +504,11 @@ pub(crate) async fn open_link( whatami: iack_out.other_whatami, sn_resolution: state.zenoh.resolution.get(Field::FrameSN), tx_initial_sn: osyn_out.mine_initial_sn, + is_qos: state.ext_qos.is_qos(), #[cfg(feature = "transport_multilink")] multilink: state.ext_mlink.multilink(), - is_qos: state.ext_qos.is_qos(), #[cfg(feature = "shared-memory")] is_shm: state.ext_shm.is_shm(), - #[cfg(not(feature = "shared-memory"))] - is_shm: false, }; let transport = step!(manager .init_transport_unicast(config) diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 90cc4c8c3b..100310ec6e 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -11,15 +11,14 @@ // Contributors: // ZettaScale Zenoh Team, // +#[cfg(feature = "transport_auth")] +use crate::unicast::establishment::ext::auth::Auth; #[cfg(feature = "transport_multilink")] use crate::unicast::establishment::ext::multilink::MultiLink; #[cfg(feature = "shared-memory")] use crate::unicast::shm::SharedMemoryUnicast; use crate::{ - unicast::{ - establishment::ext::auth::Auth, transport::TransportUnicastInner, TransportConfigUnicast, - TransportUnicast, - }, + unicast::{transport::TransportUnicastInner, TransportConfigUnicast, TransportUnicast}, TransportManager, }; use async_std::{prelude::FutureExt, sync::Mutex, task}; @@ -27,7 +26,7 @@ use std::{collections::HashMap, sync::Arc, time::Duration}; #[cfg(feature = "shared-memory")] use zenoh_config::SharedMemoryConf; use zenoh_config::{Config, LinkTxConf, QoSConf, TransportUnicastConf}; -use zenoh_core::zasynclock; +use zenoh_core::{zasynclock, zcondfeat}; use zenoh_crypto::PseudoRng; use zenoh_link::*; use zenoh_protocol::{ @@ -45,8 +44,9 @@ pub struct TransportManagerConfigUnicast { pub accept_timeout: Duration, pub accept_pending: usize, pub max_sessions: usize, - pub max_links: usize, pub is_qos: bool, + #[cfg(feature = "transport_multilink")] + pub max_links: usize, #[cfg(feature = "shared-memory")] pub is_shm: bool, } @@ -54,17 +54,19 @@ pub struct TransportManagerConfigUnicast { pub struct TransportManagerStateUnicast { // Incoming uninitialized transports pub(super) incoming: Arc>, - // Active authenticators - pub(super) authenticator: Arc, // Established listeners pub(super) protocols: Arc>>, // Established transports pub(super) transports: Arc>>>, + // Multilink + #[cfg(feature = "transport_multilink")] + pub(super) multilink: Arc, + // Active authenticators + #[cfg(feature = "transport_auth")] + pub(super) authenticator: Arc, // Shared memory #[cfg(feature = "shared-memory")] pub(super) shm: Arc, - // Multilink - pub(super) multilink: Arc, } pub struct TransportManagerParamsUnicast { @@ -83,10 +85,12 @@ pub struct TransportManagerBuilderUnicast { pub(super) accept_timeout: Duration, pub(super) accept_pending: usize, pub(super) max_sessions: usize, - pub(super) max_links: usize, pub(super) is_qos: bool, + #[cfg(feature = "transport_multilink")] + pub(super) max_links: usize, #[cfg(feature = "shared-memory")] pub(super) is_shm: bool, + #[cfg(feature = "transport_auth")] pub(super) authenticator: Auth, } @@ -116,21 +120,23 @@ impl TransportManagerBuilderUnicast { self } + pub fn qos(mut self, is_qos: bool) -> Self { + self.is_qos = is_qos; + self + } + + #[cfg(feature = "transport_multilink")] pub fn max_links(mut self, max_links: usize) -> Self { self.max_links = max_links; self } + #[cfg(feature = "transport_auth")] pub fn authenticator(mut self, authenticator: Auth) -> Self { self.authenticator = authenticator; self } - pub fn qos(mut self, is_qos: bool) -> Self { - self.is_qos = is_qos; - self - } - #[cfg(feature = "shared-memory")] pub fn shm(mut self, is_shm: bool) -> Self { self.is_shm = is_shm; @@ -147,27 +153,37 @@ impl TransportManagerBuilderUnicast { )); self = self.accept_pending(config.transport().unicast().accept_pending().unwrap()); self = self.max_sessions(config.transport().unicast().max_sessions().unwrap()); - self = self.max_links(config.transport().unicast().max_links().unwrap()); self = self.qos(*config.transport().qos().enabled()); + #[cfg(feature = "transport_multilink")] + { + self = self.max_links(config.transport().unicast().max_links().unwrap()); + } #[cfg(feature = "shared-memory")] { self = self.shm(*config.transport().shared_memory().enabled()); } - self = self.authenticator(Auth::from_config(config).await?); + #[cfg(feature = "transport_auth")] + { + self = self.authenticator(Auth::from_config(config).await?); + } Ok(self) } - pub fn build(self, prng: &mut PseudoRng) -> ZResult { + pub fn build( + self, + #[allow(unused)] prng: &mut PseudoRng, // Required for #[cfg(feature = "transport_multilink")] + ) -> ZResult { let config = TransportManagerConfigUnicast { lease: self.lease, keep_alive: self.keep_alive, accept_timeout: self.accept_timeout, accept_pending: self.accept_pending, max_sessions: self.max_sessions, - max_links: self.max_links, is_qos: self.is_qos, + #[cfg(feature = "transport_multilink")] + max_links: self.max_links, #[cfg(feature = "shared-memory")] is_shm: self.is_shm, }; @@ -176,11 +192,12 @@ impl TransportManagerBuilderUnicast { incoming: Arc::new(Mutex::new(0)), protocols: Arc::new(Mutex::new(HashMap::new())), transports: Arc::new(Mutex::new(HashMap::new())), - authenticator: Arc::new(self.authenticator), - #[cfg(feature = "shared-memory")] - shm: Arc::new(SharedMemoryUnicast::make()?), #[cfg(feature = "transport_multilink")] multilink: Arc::new(MultiLink::make(prng)?), + #[cfg(feature = "shared-memory")] + shm: Arc::new(SharedMemoryUnicast::make()?), + #[cfg(feature = "transport_auth")] + authenticator: Arc::new(self.authenticator), }; let params = TransportManagerParamsUnicast { config, state }; @@ -203,10 +220,12 @@ impl Default for TransportManagerBuilderUnicast { accept_timeout: Duration::from_millis(transport.accept_timeout().unwrap()), accept_pending: transport.accept_pending().unwrap(), max_sessions: transport.max_sessions().unwrap(), - max_links: transport.max_links().unwrap(), is_qos: *qos.enabled(), + #[cfg(feature = "transport_multilink")] + max_links: transport.max_links().unwrap(), #[cfg(feature = "shared-memory")] is_shm: *shm.enabled(), + #[cfg(feature = "transport_auth")] authenticator: Auth::default(), } } @@ -362,10 +381,8 @@ impl TransportManager { } // Create the transport - #[cfg(not(feature = "transport_multilink"))] - let is_multilink = false; - #[cfg(feature = "transport_multilink")] - let is_multilink = config.multilink.is_some(); + let is_multilink = + zcondfeat!("transport_multilink", config.multilink.is_some(), false); let stc = TransportConfigUnicast { zid: config.zid, @@ -491,7 +508,7 @@ impl TransportManager { } } -#[cfg(feature = "test")] +#[cfg(all(feature = "test", feature = "transport_auth"))] impl TransportManager { pub fn get_auth_handle_unicast(&self) -> Arc { self.state.unicast.authenticator.clone() diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 40962eb2fc..c4307bd39f 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -88,10 +88,11 @@ pub(crate) struct TransportConfigUnicast { pub(crate) whatami: WhatAmI, pub(crate) sn_resolution: Bits, pub(crate) tx_initial_sn: ZInt, - pub(crate) is_shm: bool, pub(crate) is_qos: bool, #[cfg(feature = "transport_multilink")] pub(crate) multilink: Option, + #[cfg(feature = "shared-memory")] + pub(crate) is_shm: bool, } /// [`TransportUnicast`] is the transport handler returned diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index d5e36758cb..795b1be0eb 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -20,7 +20,7 @@ use crate::TransportConfigUnicast; use async_std::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; use std::sync::{Arc, RwLock}; use std::time::Duration; -use zenoh_core::{zasynclock, zread, zwrite}; +use zenoh_core::{zasynclock, zcondfeat, zread, zwrite}; use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ core::{Bits, Priority, WhatAmI, ZInt, ZenohId}, @@ -205,12 +205,14 @@ impl TransportUnicastInner { if let LinkUnicastDirection::Inbound = direction { let count = guard.iter().filter(|l| l.direction == direction).count(); - let mut limit = 1; - - #[cfg(feature = "transport_multilink")] - if self.config.multilink.is_some() { - limit = self.manager.config.unicast.max_links; - } + let limit = zcondfeat!( + "transport_multilink", + match self.config.multilink { + Some(_) => self.manager.config.unicast.max_links, + None => 1, + }, + 1 + ); if count >= limit { let e = zerror!( From 7ba514d408d1027a103937ee7fa5fc80619d8f7e Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 18:32:08 +0100 Subject: [PATCH 084/203] Improve conditional compilation of features --- io/zenoh-transport/src/lib.rs | 3 ++- io/zenoh-transport/src/shm.rs | 1 + .../src/unicast/establishment/accept.rs | 1 - .../src/unicast/establishment/ext/auth/mod.rs | 8 +++--- .../src/unicast/establishment/mod.rs | 3 ++- .../src/unicast/establishment/open.rs | 1 - io/zenoh-transport/src/unicast/manager.rs | 9 ++++--- io/zenoh-transport/src/unicast/mod.rs | 27 +++++++++++-------- io/zenoh-transport/src/unicast/transport.rs | 1 + 9 files changed, 32 insertions(+), 22 deletions(-) diff --git a/io/zenoh-transport/src/lib.rs b/io/zenoh-transport/src/lib.rs index ef103c0d9f..24c702c262 100644 --- a/io/zenoh-transport/src/lib.rs +++ b/io/zenoh-transport/src/lib.rs @@ -68,9 +68,10 @@ pub struct TransportPeer { pub zid: ZenohId, pub whatami: WhatAmI, pub is_qos: bool, - pub is_shm: bool, #[serde(skip)] pub links: Vec, + #[cfg(feature = "shared-memory")] + pub is_shm: bool, } pub trait TransportPeerEventHandler: Send + Sync { diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index 67ee3932e3..047985e484 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -55,6 +55,7 @@ macro_rules! set_sliced { }; } +#[cold] #[inline(never)] pub fn map_zslice_to_shmbuf( zslice: &mut ZSlice, diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index ff8d681cb1..995741a613 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -250,7 +250,6 @@ impl<'a> AcceptFsm for AcceptLink<'a> { ); // Extension MultiLink - #[cfg(feature = "transport_multilink")] let ext_mlink = zcondfeat!( "transport_multilink", self.ext_mlink diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs index 59154385ff..3055b0a819 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -42,7 +42,9 @@ use zenoh_protocol::{ }; pub(crate) mod id { + #[cfg(feature = "auth_pubkey")] pub(crate) const PUBKEY: u8 = 1; + #[cfg(feature = "auth_usrpwd")] pub(crate) const USRPWD: u8 = 2; } @@ -70,7 +72,7 @@ impl Auth { }) } - pub(crate) fn open(&self, prng: &mut R) -> StateOpen + pub(crate) fn open(&self, #[allow(unused)] prng: &mut R) -> StateOpen where R: Rng + CryptoRng, { @@ -85,7 +87,7 @@ impl Auth { } } - pub(crate) fn accept(&self, prng: &mut R) -> StateAccept + pub(crate) fn accept(&self, #[allow(unused)] prng: &mut R) -> StateAccept where R: Rng + CryptoRng, { @@ -100,7 +102,7 @@ impl Auth { } } - pub(crate) fn fsm<'a>(&'a self, prng: &'a Mutex) -> AuthFsm<'a> { + pub(crate) fn fsm<'a>(&'a self, #[allow(unused)] prng: &'a Mutex) -> AuthFsm<'a> { AuthFsm { #[cfg(feature = "auth_pubkey")] pubkey: self.pubkey.as_ref().map(|x| AuthPubKeyFsm::new(x, prng)), diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 5006d6f86d..d08589ff27 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -162,9 +162,10 @@ pub(super) async fn finalize_transport( let peer = TransportPeer { zid: transport.get_zid(), whatami: transport.get_whatami(), + links: vec![Link::from(link)], is_qos: transport.is_qos(), + #[cfg(feature = "shared-memory")] is_shm: transport.is_shm(), - links: vec![Link::from(link)], }; // Notify the transport handler that there is a new transport and get back a callback // NOTE: the read loop of the link the open message was sent on remains blocked diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 1990f8573f..80f161e733 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -321,7 +321,6 @@ impl<'a> OpenFsm for OpenLink<'a> { ); // Extension MultiLink - #[cfg(feature = "transport_multilink")] let ext_mlink = zcondfeat!( "transport_multilink", self.ext_mlink diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 100310ec6e..8c448530c8 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -383,16 +383,18 @@ impl TransportManager { // Create the transport let is_multilink = zcondfeat!("transport_multilink", config.multilink.is_some(), false); + let is_shm = zcondfeat!("shared-memory", config.is_shm, false); let stc = TransportConfigUnicast { zid: config.zid, whatami: config.whatami, sn_resolution: config.sn_resolution, tx_initial_sn: config.tx_initial_sn, - is_shm: config.is_shm, is_qos: config.is_qos, #[cfg(feature = "transport_multilink")] multilink: config.multilink, + #[cfg(feature = "shared-memory")] + is_shm: config.is_shm, }; let a_t = Arc::new(TransportUnicastInner::make(self.clone(), stc)?); @@ -401,15 +403,14 @@ impl TransportManager { guard.insert(config.zid, a_t); log::debug!( - "New transport opened between {} and {} - whatami: {}, sn resolution: {:?}, initial sn: {:?}, shm: {}, qos: {}, multilink: {}", + "New transport opened between {} and {} - whatami: {}, sn resolution: {:?}, initial sn: {:?}, qos: {}, shm: {}, multilink: {}", self.config.zid, config.zid, config.whatami, config.sn_resolution, config.tx_initial_sn, - config.is_shm, config.is_qos, - is_multilink + is_multilink, is_shm ); Ok(transport) diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index c4307bd39f..6c88054a62 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -30,6 +30,7 @@ pub use manager::*; use std::fmt; use std::sync::{Arc, Weak}; use transport::TransportUnicastInner; +use zenoh_core::zcondfeat; use zenoh_link::Link; use zenoh_protocol::{ core::{Bits, WhatAmI, ZInt, ZenohId}, @@ -126,6 +127,7 @@ impl TransportUnicast { Ok(transport.get_sn_resolution().mask()) } + #[cfg(feature = "shared-memory")] #[inline(always)] pub fn is_shm(&self) -> ZResult { let transport = self.get_inner()?; @@ -149,13 +151,14 @@ impl TransportUnicast { let tp = TransportPeer { zid: transport.get_zid(), whatami: transport.get_whatami(), - is_qos: transport.is_qos(), - is_shm: transport.is_shm(), links: transport .get_links() .into_iter() .map(|l| l.into()) .collect(), + is_qos: transport.is_qos(), + #[cfg(feature = "shared-memory")] + is_shm: transport.is_shm(), }; Ok(tp) } @@ -226,15 +229,17 @@ impl PartialEq for TransportUnicast { impl fmt::Debug for TransportUnicast { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.get_inner() { - Ok(transport) => f - .debug_struct("Transport Unicast") - .field("zid", &transport.get_zid()) - .field("whatami", &transport.get_whatami()) - .field("sn_resolution", &transport.get_sn_resolution()) - .field("is_qos", &transport.is_qos()) - .field("is_shm", &transport.is_shm()) - .field("links", &transport.get_links()) - .finish(), + Ok(transport) => { + let is_shm = zcondfeat!("shared-memory", transport.is_shm(), false); + f.debug_struct("Transport Unicast") + .field("zid", &transport.get_zid()) + .field("whatami", &transport.get_whatami()) + .field("sn_resolution", &transport.get_sn_resolution()) + .field("is_qos", &transport.is_qos()) + .field("is_shm", &is_shm) + .field("links", &transport.get_links()) + .finish() + } Err(e) => { write!(f, "{e}") } diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index 795b1be0eb..6e24ab2225 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -378,6 +378,7 @@ impl TransportUnicastInner { self.config.sn_resolution } + #[cfg(feature = "shared-memory")] pub(crate) fn is_shm(&self) -> bool { self.config.is_shm } From 5b2d10986dad49b2ff2bf8840effda0e959b7eeb Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 18:39:57 +0100 Subject: [PATCH 085/203] Add cold path to shm --- io/zenoh-transport/src/shm.rs | 58 +++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index 047985e484..57bfeb7dae 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -93,33 +93,31 @@ pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &RwLock) -> Ok(res) } -pub fn map_zslice_to_shminfo(zslice: &mut ZSlice) -> ZResult { - let mut res = false; - let ZSlice { buf, .. } = zslice; - if let Some(shmb) = buf.as_any().downcast_ref::() { - // Serialize the shmb info - let codec = Zenoh080::new(); - let mut bytes = vec![]; - let mut writer = bytes.writer(); - codec - .write(&mut writer, &shmb.info) - .map_err(|e| zerror!("{:?}", e))?; - let info: SharedMemoryBufInfoSerialized = bytes.into(); - // Increase the reference count so to keep the SharedMemoryBuf valid - shmb.inc_ref_count(); - // Replace the content of the slice - let zs: ZSlice = info.into(); - *zslice = zs; - - res = true; - } - Ok(res) +#[cold] +#[inline(never)] +pub fn map_zslice_to_shminfo(shmb: &SharedMemoryBuf) -> ZResult { + // Serialize the shmb info + let codec = Zenoh080::new(); + let mut bytes = vec![]; + let mut writer = bytes.writer(); + codec + .write(&mut writer, &shmb.info) + .map_err(|e| zerror!("{:?}", e))?; + let info: SharedMemoryBufInfoSerialized = bytes.into(); + // Increase the reference count so to keep the SharedMemoryBuf valid + shmb.inc_ref_count(); + // Replace the content of the slice + Ok(info.into()) } pub fn map_zbuf_to_shminfo(zbuf: &mut ZBuf) -> ZResult { let mut res = false; for zs in zbuf.zslices_mut() { - res |= map_zslice_to_shminfo(zs)?; + let ZSlice { buf, .. } = zs; + if let Some(shmb) = buf.as_any().downcast_ref::() { + *zs = map_zslice_to_shminfo(shmb)?; + res = true; + } } Ok(res) } @@ -135,13 +133,17 @@ pub fn map_zmsg_to_shmbuf( }) = &mut msg.body { res |= map_zbuf_to_shmbuf(payload, shmr)?; - unset_sliced!(msg, data_info); + if res { + unset_sliced!(msg, data_info); + } } else if let ZenohBody::Query(Query { body: Some(body), .. }) = &mut msg.body { res |= map_zbuf_to_shmbuf(&mut body.payload, shmr)?; - body.data_info.sliced = false; + if res { + body.data_info.sliced = false; + } } Ok(res) @@ -155,13 +157,17 @@ pub fn map_zmsg_to_shminfo(msg: &mut ZenohMessage) -> ZResult { }) = &mut msg.body { res |= map_zbuf_to_shminfo(payload)?; - set_sliced!(msg, data_info); + if res { + set_sliced!(msg, data_info); + } } else if let ZenohBody::Query(Query { body: Some(body), .. }) = &mut msg.body { res |= map_zbuf_to_shminfo(&mut body.payload)?; - body.data_info.sliced = true; + if res { + body.data_info.sliced = true; + } } Ok(res) From 02e65bdef77e4b7f1f04b41eb1d63717c38e52ac Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 13 Mar 2023 20:25:11 +0100 Subject: [PATCH 086/203] Remove shared-memory from default features --- zenoh/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 1b3a27de30..996bed77fa 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -57,7 +57,6 @@ default = [ "transport_udp", "transport_unixsock-stream", "transport_ws", - "shared-memory", ] [dependencies] From 738658e62cc05f82e65b6315d5d9552951ec85e7 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 14 Mar 2023 14:59:12 +0100 Subject: [PATCH 087/203] Remove ZInt typedef --- commons/zenoh-codec/benches/codec.rs | 32 ++++---- commons/zenoh-codec/src/common/extension.rs | 41 +++++----- commons/zenoh-codec/src/core/encoding.rs | 6 +- commons/zenoh-codec/src/core/keyexpr.rs | 4 +- commons/zenoh-codec/src/core/property.rs | 4 +- commons/zenoh-codec/src/core/zint.rs | 14 ++-- commons/zenoh-codec/src/transport/fragment.rs | 4 +- commons/zenoh-codec/src/transport/frame.rs | 10 +-- commons/zenoh-codec/src/transport/join.rs | 14 ++-- commons/zenoh-codec/src/transport/open.rs | 17 ++-- commons/zenoh-codec/src/zenoh/data.rs | 14 ++-- commons/zenoh-codec/src/zenoh/declare.rs | 10 +-- commons/zenoh-codec/src/zenoh/linkstate.rs | 12 +-- commons/zenoh-codec/src/zenoh/pull.rs | 6 +- commons/zenoh-codec/src/zenoh/query.rs | 20 ++--- commons/zenoh-codec/src/zenoh/routing.rs | 3 +- commons/zenoh-codec/tests/codec.rs | 34 ++++---- commons/zenoh-config/src/lib.rs | 11 ++- commons/zenoh-core/src/macros.rs | 10 +-- .../zenoh-protocol/src/common/extension.rs | 35 ++++---- commons/zenoh-protocol/src/common/mod.rs | 3 +- commons/zenoh-protocol/src/core/encoding.rs | 16 ++-- commons/zenoh-protocol/src/core/mod.rs | 25 ++---- commons/zenoh-protocol/src/core/resolution.rs | 11 ++- commons/zenoh-protocol/src/core/wire_expr.rs | 3 +- commons/zenoh-protocol/src/lib.rs | 6 +- .../zenoh-protocol/src/transport/fragment.rs | 10 +-- commons/zenoh-protocol/src/transport/frame.rs | 13 ++- commons/zenoh-protocol/src/transport/join.rs | 6 +- commons/zenoh-protocol/src/transport/mod.rs | 6 +- commons/zenoh-protocol/src/transport/open.rs | 21 +++-- commons/zenoh-protocol/src/zenoh/data.rs | 16 ++-- commons/zenoh-protocol/src/zenoh/declare.rs | 21 ++--- commons/zenoh-protocol/src/zenoh/linkstate.rs | 14 ++-- commons/zenoh-protocol/src/zenoh/mod.rs | 40 ++++----- commons/zenoh-protocol/src/zenoh/pull.rs | 8 +- commons/zenoh-protocol/src/zenoh/query.rs | 11 +-- commons/zenoh-protocol/src/zenoh/routing.rs | 5 +- io/zenoh-transport/src/common/batch.rs | 6 +- io/zenoh-transport/src/common/conduit.rs | 6 +- .../src/common/defragmentation.rs | 6 +- io/zenoh-transport/src/common/pipeline.rs | 4 +- io/zenoh-transport/src/common/seq_num.rs | 44 +++++----- io/zenoh-transport/src/primitives/mod.rs | 30 +++---- io/zenoh-transport/src/primitives/mux.rs | 16 ++-- .../src/unicast/establishment/accept.rs | 10 +-- .../src/unicast/establishment/cookie.rs | 6 +- .../src/unicast/establishment/ext/auth/mod.rs | 2 +- .../unicast/establishment/ext/auth/pubkey.rs | 9 +- .../unicast/establishment/ext/auth/usrpwd.rs | 19 ++--- .../src/unicast/establishment/ext/shm.rs | 17 ++-- .../src/unicast/establishment/mod.rs | 8 +- .../src/unicast/establishment/open.rs | 6 +- .../src/unicast/establishment/properties.rs | 6 +- io/zenoh-transport/src/unicast/mod.rs | 6 +- io/zenoh-transport/src/unicast/reliability.rs | 82 +++++++++---------- io/zenoh-transport/src/unicast/rx.rs | 4 +- io/zenoh-transport/src/unicast/transport.rs | 4 +- zenoh/src/net/routing/face.rs | 28 +++---- zenoh/src/net/routing/network.rs | 18 ++-- zenoh/src/net/routing/pubsub.rs | 14 ++-- zenoh/src/net/routing/queries.rs | 24 +++--- zenoh/src/net/routing/resource.rs | 16 ++-- zenoh/src/net/routing/router.rs | 4 +- zenoh/src/net/runtime/adminspace.rs | 18 ++-- zenoh/src/net/tests/tables.rs | 20 ++--- zenoh/src/prelude.rs | 1 - zenoh/src/sample.rs | 4 +- zenoh/src/session.rs | 34 ++++---- 69 files changed, 480 insertions(+), 528 deletions(-) diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 757a0b7c14..2adc8f3f0a 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -22,49 +22,49 @@ use zenoh_buffers::{ }; use zenoh_codec::*; use zenoh_protocol::{ - core::{CongestionControl, Reliability, ZInt}, + core::{CongestionControl, Reliability}, defaults::BATCH_SIZE, transport::{Frame, FrameHeader}, zenoh::Data, }; fn criterion_benchmark(c: &mut Criterion) { - // ZInt Vec + // u64 Vec let mut buff = vec![]; let codec = Zenoh080::new(); - c.bench_function("ZInt Vec", |b| { + c.bench_function("u64 Vec", |b| { b.iter(|| { buff.clear(); let mut writer = buff.writer(); - codec.write(&mut writer, ZInt::MAX).unwrap(); + codec.write(&mut writer, u64::MAX).unwrap(); let mut reader = buff.reader(); - let _: ZInt = codec.read(&mut reader).unwrap(); + let _: u64 = codec.read(&mut reader).unwrap(); }) }); - // ZInt BBuf + // u64 BBuf let mut buff = BBuf::with_capacity(BATCH_SIZE as usize); let codec = Zenoh080::new(); - c.bench_function("ZInt BBuf", |b| { + c.bench_function("u64 BBuf", |b| { b.iter(|| { buff.clear(); let mut writer = buff.writer(); - codec.write(&mut writer, ZInt::MAX).unwrap(); + codec.write(&mut writer, u64::MAX).unwrap(); let mut reader = buff.reader(); - let _: ZInt = codec.read(&mut reader).unwrap(); + let _: u64 = codec.read(&mut reader).unwrap(); }) }); - // ZInt ZBuf + // u64 ZBuf let mut buff = ZBuf::empty(); let codec = Zenoh080::new(); - c.bench_function("ZInt ZBuf", |b| { + c.bench_function("u64 ZBuf", |b| { b.iter(|| { buff.clear(); let mut writer = buff.writer(); - codec.write(&mut writer, ZInt::MAX).unwrap(); + codec.write(&mut writer, u64::MAX).unwrap(); let mut reader = buff.reader(); - let _: ZInt = codec.read(&mut reader).unwrap(); + let _: u64 = codec.read(&mut reader).unwrap(); }) }); @@ -74,7 +74,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), - sn: ZInt::MIN, + sn: u64::MIN, ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; @@ -111,7 +111,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), - sn: ZInt::MIN, + sn: u64::MIN, ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; @@ -143,7 +143,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), - sn: ZInt::MIN, + sn: u64::MIN, ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 4c24f83a4a..bdebdc8e4c 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -18,9 +18,8 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, ZBuf, }; -use zenoh_protocol::{ - common::{iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtZInt, ZExtensionBody}, - core::ZInt, +use zenoh_protocol::common::{ + iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtensionBody, ZExtu64, }; impl WCodec<(&ZExtUnit<{ ID }>, bool), &mut W> for Zenoh080 @@ -68,15 +67,15 @@ where } } -impl WCodec<(&ZExtZInt<{ ID }>, bool), &mut W> for Zenoh080 +impl WCodec<(&ZExtu64<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: (&ZExtZInt<{ ID }>, bool)) -> Self::Output { + fn write(self, writer: &mut W, x: (&ZExtu64<{ ID }>, bool)) -> Self::Output { let (x, more) = x; - let mut header: u8 = ID | iext::ENC_ZINT; + let mut header: u8 = ID | iext::ENC_Z64; if more { header |= iext::FLAG_Z; } @@ -86,33 +85,33 @@ where } } -impl RCodec<(ZExtZInt<{ ID }>, bool), &mut R> for Zenoh080 +impl RCodec<(ZExtu64<{ ID }>, bool), &mut R> for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ZExtZInt<{ ID }>, bool), Self::Error> { + fn read(self, reader: &mut R) -> Result<(ZExtu64<{ ID }>, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); codec.read(&mut *reader) } } -impl RCodec<(ZExtZInt<{ ID }>, bool), &mut R> for Zenoh080Header +impl RCodec<(ZExtu64<{ ID }>, bool), &mut R> for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ZExtZInt<{ ID }>, bool), Self::Error> { - if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZINT) { + fn read(self, reader: &mut R) -> Result<(ZExtu64<{ ID }>, bool), Self::Error> { + if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_Z64) { return Err(DidntRead); } - let value: ZInt = self.codec.read(&mut *reader)?; + let value: u64 = self.codec.read(&mut *reader)?; - Ok((ZExtZInt::new(value), has_flag(self.header, iext::FLAG_Z))) + Ok((ZExtu64::new(value), has_flag(self.header, iext::FLAG_Z))) } } @@ -124,7 +123,7 @@ where fn write(self, writer: &mut W, x: (&ZExtZBuf<{ ID }>, bool)) -> Self::Output { let (x, more) = x; - let mut header: u8 = ID | iext::ENC_ZINT; + let mut header: u8 = ID | iext::ENC_Z64; if more { header |= iext::FLAG_Z; } @@ -154,7 +153,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result<(ZExtZBuf<{ ID }>, bool), Self::Error> { - if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZINT) { + if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_Z64) { return Err(DidntRead); } @@ -181,10 +180,10 @@ where header |= iext::ENC_UNIT; self.write(&mut *writer, header)? } - ZExtensionBody::ZInt(zint) => { - header |= iext::ENC_ZINT; + ZExtensionBody::Z64(u64) => { + header |= iext::ENC_Z64; self.write(&mut *writer, header)?; - self.write(&mut *writer, zint)? + self.write(&mut *writer, u64)? } ZExtensionBody::ZBuf(zbuf) => { header |= iext::ENC_ZBUF; @@ -218,9 +217,9 @@ where fn read(self, reader: &mut R) -> Result<(ZExtUnknown, bool), Self::Error> { let body = match self.header & iext::ENC_MASK { iext::ENC_UNIT => ZExtensionBody::Unit, - iext::ENC_ZINT => { - let zint: ZInt = self.codec.read(&mut *reader)?; - ZExtensionBody::ZInt(zint) + iext::ENC_Z64 => { + let u64: u64 = self.codec.read(&mut *reader)?; + ZExtensionBody::Z64(u64) } iext::ENC_ZBUF => { let zbuf: ZBuf = self.codec.read(&mut *reader)?; diff --git a/commons/zenoh-codec/src/core/encoding.rs b/commons/zenoh-codec/src/core/encoding.rs index e50c96836a..9955320927 100644 --- a/commons/zenoh-codec/src/core/encoding.rs +++ b/commons/zenoh-codec/src/core/encoding.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_protocol::core::{Encoding, ZInt}; +use zenoh_protocol::core::Encoding; impl WCodec<&Encoding, &mut W> for Zenoh080 where @@ -26,7 +26,7 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Encoding) -> Self::Output { - self.write(&mut *writer, ZInt::from(*x.prefix()))?; + self.write(&mut *writer, u64::from(*x.prefix()))?; self.write(&mut *writer, x.suffix())?; Ok(()) } @@ -39,7 +39,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let prefix: ZInt = self.read(&mut *reader)?; + let prefix: u64 = self.read(&mut *reader)?; let suffix: String = self.read(&mut *reader)?; let encoding = Encoding::new(prefix, suffix).ok_or(DidntRead)?; Ok(encoding) diff --git a/commons/zenoh-codec/src/core/keyexpr.rs b/commons/zenoh-codec/src/core/keyexpr.rs index 97f5c34e7a..3b97111b45 100644 --- a/commons/zenoh-codec/src/core/keyexpr.rs +++ b/commons/zenoh-codec/src/core/keyexpr.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_protocol::core::{WireExpr, ZInt}; +use zenoh_protocol::core::WireExpr; impl WCodec<&WireExpr<'_>, &mut W> for Zenoh080 where @@ -41,7 +41,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result, Self::Error> { - let scope: ZInt = self.codec.read(&mut *reader)?; + let scope: u64 = self.codec.read(&mut *reader)?; let suffix: String = if self.condition { self.codec.read(&mut *reader)? } else { diff --git a/commons/zenoh-codec/src/core/property.rs b/commons/zenoh-codec/src/core/property.rs index ef713a2f9f..a5a8091fa7 100644 --- a/commons/zenoh-codec/src/core/property.rs +++ b/commons/zenoh-codec/src/core/property.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_protocol::core::{Property, ZInt}; +use zenoh_protocol::core::Property; impl WCodec<&Property, &mut W> for Zenoh080 where @@ -39,7 +39,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let key: ZInt = self.read(&mut *reader)?; + let key: u64 = self.read(&mut *reader)?; let value: Vec = self.read(&mut *reader)?; Ok(Property { key, value }) diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index e7736bdae6..8591008486 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -20,7 +20,7 @@ use zenoh_buffers::{ const VLE_LEN: usize = 10; -// ZInt +// u64 impl WCodec for Zenoh080 where W: Writer, @@ -151,16 +151,16 @@ where // return Ok(b as u64); // } // let n = (1 + (b & !VLE_THR as u8)) as usize; -// let mut zint: [u8; 8] = 0u64.to_le_bytes(); -// reader.read_exact(&mut zint[0..n])?; -// let zint = u64::from_le_bytes(zint); -// Ok(zint.saturating_add(VLE_THR - 1)) +// let mut u64: [u8; 8] = 0u64.to_le_bytes(); +// reader.read_exact(&mut u64[0..n])?; +// let u64 = u64::from_le_bytes(u64); +// Ok(u64.saturating_add(VLE_THR - 1)) // } // } // mod tests { // #[test] -// fn zint_overhead() { +// fn u64_overhead() { // use crate::{WCodec, Zenoh080}; // use zenoh_buffers::{ // reader::{HasReader, Reader}, @@ -344,7 +344,7 @@ where // #[cfg(test)] // mod test { // #[test] -// fn zint_fuzz() { +// fn u64_fuzz() { // use crate::*; // use rand::Rng; // use zenoh_buffers::{reader::HasReader, writer::HasWriter}; diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index 192c2474f5..38dfd7da92 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -18,7 +18,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{imsg, ZExtUnknown}, - core::{Reliability, ZInt}, + core::Reliability, transport::{ fragment::{ext, flag, Fragment, FragmentHeader}, id, @@ -87,7 +87,7 @@ where false => Reliability::BestEffort, }; let more = imsg::has_flag(self.header, flag::M); - let sn: ZInt = self.codec.read(&mut *reader)?; + let sn: u64 = self.codec.read(&mut *reader)?; // Extensions let mut qos = ext::QoS::default(); diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 7211c9a759..0e18250200 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -20,8 +20,8 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown, ZExtZInt}, - core::{Priority, Reliability, ZInt}, + common::{imsg, ZExtUnknown, ZExtu64}, + core::{Priority, Reliability}, transport::{ frame::{ext, flag, Frame, FrameHeader}, id, @@ -38,7 +38,7 @@ where fn write(self, writer: &mut W, x: (ext::QoS, bool)) -> Self::Output { let (qos, more) = x; - let ext: ZExtZInt<{ ext::QOS }> = ZExtZInt::new(qos.priority as ZInt); + let ext: ZExtu64<{ ext::QOS }> = ZExtu64::new(qos.priority as u64); self.write(&mut *writer, (&ext, more)) } } @@ -68,7 +68,7 @@ where return Err(DidntRead); } - let (ext, more): (ZExtZInt<{ ext::QOS }>, bool) = self.read(&mut *reader)?; + let (ext, more): (ZExtu64<{ ext::QOS }>, bool) = self.read(&mut *reader)?; let v: u8 = ext.value.try_into().map_err(|_| DidntRead)?; let priority: Priority = v.try_into().map_err(|_| DidntRead)?; @@ -134,7 +134,7 @@ where true => Reliability::Reliable, false => Reliability::BestEffort, }; - let sn: ZInt = self.codec.read(&mut *reader)?; + let sn: u64 = self.codec.read(&mut *reader)?; // Extensions let mut qos = ext::QoS::default(); diff --git a/commons/zenoh-codec/src/transport/join.rs b/commons/zenoh-codec/src/transport/join.rs index cb992214ca..2f3902238e 100644 --- a/commons/zenoh-codec/src/transport/join.rs +++ b/commons/zenoh-codec/src/transport/join.rs @@ -20,7 +20,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{Priority, WhatAmI, ZInt, ZenohId}, + core::{Priority, WhatAmI, ZenohId}, transport::{ConduitSn, ConduitSnList, Join}, }; @@ -31,7 +31,7 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Join) -> Self::Output { - // fn options(x: &Join) -> ZInt { + // fn options(x: &Join) -> u64 { // let mut options = 0; // if x.is_qos() { // options |= tmsg::join_options::QOS; @@ -62,9 +62,9 @@ where // self.write(&mut *writer, wai)?; // self.write(&mut *writer, &x.zid)?; // if imsg::has_flag(header, tmsg::flag::T1) { - // self.write(&mut *writer, x.lease.as_secs() as ZInt)?; + // self.write(&mut *writer, x.lease.as_secs() as u64)?; // } else { - // self.write(&mut *writer, x.lease.as_millis() as ZInt)?; + // self.write(&mut *writer, x.lease.as_millis() as u64)?; // } // if imsg::has_flag(header, tmsg::flag::S) { // self.write(&mut *writer, x.sn_resolution)?; @@ -111,7 +111,7 @@ where // return Err(DidntRead); // } - // let options: ZInt = if imsg::has_flag(self.header, tmsg::flag::O) { + // let options: u64 = if imsg::has_flag(self.header, tmsg::flag::O) { // self.codec.read(&mut *reader)? // } else { // 0 @@ -120,13 +120,13 @@ where // let wai: u8 = self.codec.read(&mut *reader)?; // let whatami = WhatAmI::try_from(wai).map_err(|_| DidntRead)?; // let zid: ZenohId = self.codec.read(&mut *reader)?; - // let lease: ZInt = self.codec.read(&mut *reader)?; + // let lease: u64 = self.codec.read(&mut *reader)?; // let lease = if imsg::has_flag(self.header, tmsg::flag::T1) { // Duration::from_secs(lease) // } else { // Duration::from_millis(lease) // }; - // let sn_resolution: ZInt = if imsg::has_flag(self.header, tmsg::flag::S) { + // let sn_resolution: u64 = if imsg::has_flag(self.header, tmsg::flag::S) { // self.codec.read(&mut *reader)? // } else { // SEQ_NUM_RES diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index db4a11e9e7..fe16e57c65 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -20,7 +20,6 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{imsg, ZExtUnknown}, - core::ZInt, transport::{ id, open::{ext, flag, OpenAck, OpenSyn}, @@ -51,9 +50,9 @@ where // Body if imsg::has_flag(header, flag::T) { - self.write(&mut *writer, x.lease.as_secs() as ZInt)?; + self.write(&mut *writer, x.lease.as_secs())?; } else { - self.write(&mut *writer, x.lease.as_millis() as ZInt)?; + self.write(&mut *writer, x.lease.as_millis() as u64)?; } self.write(&mut *writer, x.initial_sn)?; self.write(&mut *writer, &x.cookie)?; @@ -105,13 +104,13 @@ where } // Body - let lease: ZInt = self.codec.read(&mut *reader)?; + let lease: u64 = self.codec.read(&mut *reader)?; let lease = if imsg::has_flag(self.header, flag::T) { Duration::from_secs(lease) } else { Duration::from_millis(lease) }; - let initial_sn: ZInt = self.codec.read(&mut *reader)?; + let initial_sn: u64 = self.codec.read(&mut *reader)?; let cookie: ZSlice = self.codec.read(&mut *reader)?; // Extensions @@ -190,9 +189,9 @@ where // Body if imsg::has_flag(header, flag::T) { - self.write(&mut *writer, x.lease.as_secs() as ZInt)?; + self.write(&mut *writer, x.lease.as_secs())?; } else { - self.write(&mut *writer, x.lease.as_millis() as ZInt)?; + self.write(&mut *writer, x.lease.as_millis() as u64)?; } self.write(&mut *writer, x.initial_sn)?; @@ -243,13 +242,13 @@ where } // Body - let lease: ZInt = self.codec.read(&mut *reader)?; + let lease: u64 = self.codec.read(&mut *reader)?; let lease = if imsg::has_flag(self.header, flag::T) { Duration::from_secs(lease) } else { Duration::from_millis(lease) }; - let initial_sn: ZInt = self.codec.read(&mut *reader)?; + let initial_sn: u64 = self.codec.read(&mut *reader)?; // Extensions let mut ext_qos = None; diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index 3b26a992c5..cfe8a4b678 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -23,7 +23,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{CongestionControl, Encoding, WireExpr, ZInt, ZenohId}, + core::{CongestionControl, Encoding, WireExpr, ZenohId}, zenoh::{zmsg, Data, DataInfo, ReplierInfo, ReplyContext, SampleKind}, }; @@ -76,7 +76,7 @@ where return Err(DidntRead); } - let qid: ZInt = self.codec.read(&mut *reader)?; + let qid: u64 = self.codec.read(&mut *reader)?; let replier = if imsg::has_flag(self.header, zmsg::flag::F) { None } else { @@ -96,7 +96,7 @@ where fn write(self, writer: &mut W, x: &DataInfo) -> Self::Output { // Options - let mut options: ZInt = 0; + let mut options: u64 = 0; #[cfg(feature = "shared-memory")] if x.sliced { options |= zmsg::data::info::SLICED; @@ -119,7 +119,7 @@ where self.write(&mut *writer, options)?; if x.kind != SampleKind::Put { - self.write(&mut *writer, x.kind as ZInt)?; + self.write(&mut *writer, x.kind as u64)?; } if let Some(enc) = x.encoding.as_ref() { self.write(&mut *writer, enc)?; @@ -146,13 +146,13 @@ where fn read(self, reader: &mut R) -> Result { let mut info = DataInfo::default(); - let options: ZInt = self.read(&mut *reader)?; + let options: u64 = self.read(&mut *reader)?; #[cfg(feature = "shared-memory")] { info.sliced = imsg::has_option(options, zmsg::data::info::SLICED); } if imsg::has_option(options, zmsg::data::info::KIND) { - let kind: ZInt = self.read(&mut *reader)?; + let kind: u64 = self.read(&mut *reader)?; info.kind = kind.try_into().map_err(|_| DidntRead)?; } if imsg::has_option(options, zmsg::data::info::ENCODING) { @@ -168,7 +168,7 @@ where info.source_id = Some(source_id); } if imsg::has_option(options, zmsg::data::info::SRCSN) { - let source_sn: ZInt = self.read(&mut *reader)?; + let source_sn: u64 = self.read(&mut *reader)?; info.source_sn = Some(source_sn); } diff --git a/commons/zenoh-codec/src/zenoh/declare.rs b/commons/zenoh-codec/src/zenoh/declare.rs index 806c0b925c..2cca388d90 100644 --- a/commons/zenoh-codec/src/zenoh/declare.rs +++ b/commons/zenoh-codec/src/zenoh/declare.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{Reliability, WireExpr, ZInt}, + core::{Reliability, WireExpr}, zenoh::{ zmsg, Declaration, Declare, ForgetPublisher, ForgetQueryable, ForgetResource, ForgetSubscriber, Publisher, Queryable, QueryableInfo, Resource, SubInfo, SubMode, @@ -184,7 +184,7 @@ where return Err(DidntRead); } - let expr_id: ZInt = self.codec.read(&mut *reader)?; + let expr_id: u64 = self.codec.read(&mut *reader)?; let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, @@ -239,7 +239,7 @@ where return Err(DidntRead); } - let expr_id: ZInt = self.codec.read(&mut *reader)?; + let expr_id: u64 = self.codec.read(&mut *reader)?; Ok(ForgetResource { expr_id }) } @@ -559,8 +559,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let complete: ZInt = self.read(&mut *reader)?; - let distance: ZInt = self.read(&mut *reader)?; + let complete: u64 = self.read(&mut *reader)?; + let distance: u64 = self.read(&mut *reader)?; Ok(QueryableInfo { complete, distance }) } diff --git a/commons/zenoh-codec/src/zenoh/linkstate.rs b/commons/zenoh-codec/src/zenoh/linkstate.rs index 3d7e3fdb92..12a75d18da 100644 --- a/commons/zenoh-codec/src/zenoh/linkstate.rs +++ b/commons/zenoh-codec/src/zenoh/linkstate.rs @@ -20,7 +20,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{Locator, WhatAmI, ZInt, ZenohId}, + core::{Locator, WhatAmI, ZenohId}, zenoh::{zmsg, LinkState, LinkStateList}, }; @@ -74,9 +74,9 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let options: ZInt = self.read(&mut *reader)?; - let psid: ZInt = self.read(&mut *reader)?; - let sn: ZInt = self.read(&mut *reader)?; + let options: u64 = self.read(&mut *reader)?; + let psid: u64 = self.read(&mut *reader)?; + let sn: u64 = self.read(&mut *reader)?; let zid = if imsg::has_option(options, zmsg::link_state::PID) { let zid: ZenohId = self.read(&mut *reader)?; Some(zid) @@ -96,9 +96,9 @@ where None }; let len: usize = self.read(&mut *reader)?; - let mut links: Vec = Vec::with_capacity(len); + let mut links: Vec = Vec::with_capacity(len); for _ in 0..len { - let l: ZInt = self.read(&mut *reader)?; + let l: u64 = self.read(&mut *reader)?; links.push(l); } diff --git a/commons/zenoh-codec/src/zenoh/pull.rs b/commons/zenoh-codec/src/zenoh/pull.rs index 3172ca83da..4126370619 100644 --- a/commons/zenoh-codec/src/zenoh/pull.rs +++ b/commons/zenoh-codec/src/zenoh/pull.rs @@ -18,7 +18,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{WireExpr, ZInt}, + core::WireExpr, zenoh::{zmsg, Pull}, }; @@ -83,9 +83,9 @@ where codec: self.codec, }; let key: WireExpr<'static> = ccond.read(&mut *reader)?; - let pull_id: ZInt = self.codec.read(&mut *reader)?; + let pull_id: u64 = self.codec.read(&mut *reader)?; let max_samples = if imsg::has_flag(self.header, zmsg::flag::N) { - let n: ZInt = self.codec.read(&mut *reader)?; + let n: u64 = self.codec.read(&mut *reader)?; Some(n) } else { None diff --git a/commons/zenoh-codec/src/zenoh/query.rs b/commons/zenoh-codec/src/zenoh/query.rs index af295dcc79..8b9836a824 100644 --- a/commons/zenoh-codec/src/zenoh/query.rs +++ b/commons/zenoh-codec/src/zenoh/query.rs @@ -20,7 +20,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{WireExpr, ZInt}, + core::WireExpr, zenoh::{zmsg, ConsolidationMode, DataInfo, Query, QueryBody, QueryTarget}, }; @@ -34,12 +34,12 @@ where fn write(self, writer: &mut W, x: &QueryTarget) -> Self::Output { #![allow(clippy::unnecessary_cast)] match x { - QueryTarget::BestMatching => self.write(&mut *writer, 0 as ZInt)?, - QueryTarget::All => self.write(&mut *writer, 1 as ZInt)?, - QueryTarget::AllComplete => self.write(&mut *writer, 2 as ZInt)?, + QueryTarget::BestMatching => self.write(&mut *writer, 0 as u64)?, + QueryTarget::All => self.write(&mut *writer, 1 as u64)?, + QueryTarget::AllComplete => self.write(&mut *writer, 2 as u64)?, #[cfg(feature = "complete_n")] QueryTarget::Complete(n) => { - self.write(&mut *writer, 3 as ZInt)?; + self.write(&mut *writer, 3 as u64)?; self.write(&mut *writer, *n)?; } } @@ -54,14 +54,14 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let t: ZInt = self.read(&mut *reader)?; + let t: u64 = self.read(&mut *reader)?; let t = match t { 0 => QueryTarget::BestMatching, 1 => QueryTarget::All, 2 => QueryTarget::AllComplete, #[cfg(feature = "complete_n")] 3 => { - let n: ZInt = self.read(&mut *reader)?; + let n: u64 = self.read(&mut *reader)?; QueryTarget::Complete(n) } _ => return Err(DidntRead), @@ -78,7 +78,7 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &ConsolidationMode) -> Self::Output { - let cm: ZInt = match x { + let cm: u64 = match x { ConsolidationMode::None => 0, ConsolidationMode::Monotonic => 1, ConsolidationMode::Latest => 2, @@ -95,7 +95,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let cm: ZInt = self.read(&mut *reader)?; + let cm: u64 = self.read(&mut *reader)?; let cm = match cm { 0 => ConsolidationMode::None, 1 => ConsolidationMode::Monotonic, @@ -202,7 +202,7 @@ where let key: WireExpr<'static> = ccond.read(&mut *reader)?; let parameters: String = self.codec.read(&mut *reader)?; - let qid: ZInt = self.codec.read(&mut *reader)?; + let qid: u64 = self.codec.read(&mut *reader)?; let target = if imsg::has_flag(self.header, zmsg::flag::T) { let qt: QueryTarget = self.codec.read(&mut *reader)?; Some(qt) diff --git a/commons/zenoh-codec/src/zenoh/routing.rs b/commons/zenoh-codec/src/zenoh/routing.rs index 26648b91f8..548316a8ff 100644 --- a/commons/zenoh-codec/src/zenoh/routing.rs +++ b/commons/zenoh-codec/src/zenoh/routing.rs @@ -18,7 +18,6 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::ZInt, zenoh::{zmsg, RoutingContext}, }; @@ -64,7 +63,7 @@ where return Err(DidntRead); } - let tree_id: ZInt = self.codec.read(&mut *reader)?; + let tree_id: u64 = self.codec.read(&mut *reader)?; Ok(RoutingContext { tree_id }) } } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 6248fde7e9..ed97bffebd 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -117,26 +117,26 @@ macro_rules! run { // Core #[test] -fn codec_zint() { - run!(ZInt, { thread_rng().gen::() as ZInt }); - run!(ZInt, u8::MIN as ZInt); - run!(ZInt, u8::MAX as ZInt); +fn codec_u64() { + run!(u64, { thread_rng().gen::() as u64 }); + run!(u64, u8::MIN as u64); + run!(u64, u8::MAX as u64); - run!(ZInt, { thread_rng().gen::() as ZInt }); - run!(ZInt, u16::MIN as ZInt); - run!(ZInt, u16::MAX as ZInt); + run!(u64, { thread_rng().gen::() as u64 }); + run!(u64, u16::MIN as u64); + run!(u64, u16::MAX as u64); - run!(ZInt, { thread_rng().gen::() as ZInt }); - run!(ZInt, u32::MIN as ZInt); - run!(ZInt, u32::MAX as ZInt); + run!(u64, { thread_rng().gen::() as u64 }); + run!(u64, u32::MIN as u64); + run!(u64, u32::MAX as u64); - run!(ZInt, { thread_rng().gen::() as ZInt }); - run!(ZInt, u64::MIN as ZInt); - run!(ZInt, u64::MAX as ZInt); + run!(u64, { thread_rng().gen::() }); + run!(u64, u64::MIN); + run!(u64, u64::MAX); - run!(ZInt, thread_rng().gen::() as ZInt); - run!(ZInt, usize::MIN as ZInt); - run!(ZInt, usize::MAX as ZInt); + run!(u64, thread_rng().gen::() as u64); + run!(u64, usize::MIN as u64); + run!(u64, usize::MAX as u64); } #[test] @@ -244,7 +244,7 @@ fn codec_extension() { } run_extension!(ZExtUnit<0>); - run_extension!(ZExtZInt<1>); + run_extension!(ZExtu64<1>); run_extension!(ZExtZBuf<2>); run_extension!(ZExtZBuf<3>); run_extension!(ZExtUnknown); diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index e17a36fe73..ef514264d9 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -52,7 +52,6 @@ pub type ValidationFunction = std::sync::Arc< + Send + Sync, >; -type ZInt = u64; /// Creates an empty zenoh net Session configuration. pub fn empty() -> Config { @@ -174,7 +173,7 @@ validated_struct::validator! { }, /// The default timeout to apply to queries in milliseconds. - queries_default_timeout: Option, + queries_default_timeout: Option, /// The routing strategy to use and it's configuration. pub routing: #[derive(Default)] @@ -208,7 +207,7 @@ validated_struct::validator! { TransportConf { pub unicast: TransportUnicastConf { /// Timeout in milliseconds when opening a link (default: 10000). - accept_timeout: Option, + accept_timeout: Option, /// Number of links that may stay pending during accept phase (default: 100). accept_pending: Option, /// Maximum number of unicast sessions (default: 1000) @@ -218,7 +217,7 @@ validated_struct::validator! { }, pub multicast: TransportMulticastConf { /// Link join interval duration in milliseconds (default: 2500) - join_interval: Option, + join_interval: Option, /// Maximum number of multicast sessions (default: 1000) max_sessions: Option, }, @@ -238,7 +237,7 @@ validated_struct::validator! { /// Accepted values: 8bit, 16bit, 32bit, 64bit. sequence_number_resolution: Option, /// Link lease duration in milliseconds (default: 10000) - lease: Option, + lease: Option, /// Number fo keep-alive messages in a link lease duration (default: 4) keep_alive: Option, /// Zenoh's MTU equivalent (default: 2^16-1) @@ -261,7 +260,7 @@ validated_struct::validator! { } where (queue_size_validator), /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. /// Higher values lead to a more aggressive batching but it will introduce additional latency. - backoff: Option + backoff: Option }, // Number of threads used for TX threads: Option, diff --git a/commons/zenoh-core/src/macros.rs b/commons/zenoh-core/src/macros.rs index 73556d4c28..81597bf142 100644 --- a/commons/zenoh-core/src/macros.rs +++ b/commons/zenoh-core/src/macros.rs @@ -140,17 +140,17 @@ macro_rules! zconfigurable { () => () } -// This macro is a shorthand for the conversion to ZInt +// This macro is a shorthand for the conversion to u64 // This macro requires to previously import the following: // use std::convert::TryFrom; #[macro_export] -macro_rules! to_zint { +macro_rules! to_u64 { ($val:expr) => { - ZInt::try_from($val).unwrap_or_else(|_| { + u64::try_from($val).unwrap_or_else(|_| { panic!( - "Can not encode {} as ZInt (max ZInt value: {})", + "Can not encode {} as u64 (max u64 value: {})", $val, - ZInt::MAX + u64::MAX ) }) }; diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index 2650a47ee0..b7e9e4ab59 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -11,7 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::ZInt; use core::convert::TryFrom; use zenoh_buffers::ZBuf; @@ -36,7 +35,7 @@ use zenoh_buffers::ZBuf; /// +-+-+-+-+-+-+-+-+ /// |Z|ENC| ID | /// +-+-+-+---------+ -/// % length % -- If ENC == ZInt || ENC == ZBuf +/// % length % -- If ENC == u64 || ENC == ZBuf /// +---------------+ /// ~ [u8] ~ -- If ENC == ZBuf /// +---------------+ @@ -44,7 +43,7 @@ use zenoh_buffers::ZBuf; /// /// Encoding: /// - 0b00: Unit -/// - 0b01: ZInt +/// - 0b01: u64 /// - 0b10: ZBuf /// - 0b11: Reserved /// @@ -56,7 +55,7 @@ pub mod iext { pub const ID_MASK: u8 = !(u8::MAX << ID_BITS); pub const ENC_UNIT: u8 = 0b00 << ID_BITS; - pub const ENC_ZINT: u8 = 0b01 << ID_BITS; + pub const ENC_Z64: u8 = 0b01 << ID_BITS; pub const ENC_ZBUF: u8 = 0b10 << ID_BITS; pub const ENC_MASK: u8 = 0b11 << ID_BITS; @@ -100,19 +99,19 @@ impl TryFrom for ZExtUnit<{ ID }> { } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct ZExtZInt { - pub value: ZInt, +pub struct ZExtu64 { + pub value: u64, } -impl ZExtZInt<{ ID }> { +impl ZExtu64<{ ID }> { pub const ID: u8 = ID; - pub const fn new(value: ZInt) -> Self { + pub const fn new(value: u64) -> Self { Self { value } } - pub const fn transmute(self) -> ZExtZInt<{ DI }> { - ZExtZInt::new(self.value) + pub const fn transmute(self) -> ZExtu64<{ DI }> { + ZExtu64::new(self.value) } #[cfg(feature = "test")] @@ -120,12 +119,12 @@ impl ZExtZInt<{ ID }> { use rand::Rng; let mut rng = rand::thread_rng(); - let value: ZInt = rng.gen(); + let value: u64 = rng.gen(); Self { value } } } -impl TryFrom for ZExtZInt<{ ID }> { +impl TryFrom for ZExtu64<{ ID }> { type Error = DidntConvert; fn try_from(v: ZExtUnknown) -> Result { @@ -133,7 +132,7 @@ impl TryFrom for ZExtZInt<{ ID }> { return Err(DidntConvert); } match v.body { - ZExtensionBody::ZInt(v) => Ok(Self::new(v)), + ZExtensionBody::Z64(v) => Ok(Self::new(v)), _ => Err(DidntConvert), } } @@ -188,7 +187,7 @@ pub struct ZExtUnknown { #[derive(Debug, Clone, PartialEq, Eq)] pub enum ZExtensionBody { Unit, - ZInt(ZInt), + Z64(u64), ZBuf(ZBuf), } @@ -201,7 +200,7 @@ impl ZExtUnknown { let id: u8 = rng.gen_range(0x00..=iext::ID_MASK); let body = [ ZExtensionBody::Unit, - ZExtensionBody::ZInt(rng.gen()), + ZExtensionBody::Z64(rng.gen()), ZExtensionBody::ZBuf(ZBuf::rand(rng.gen_range(8..=64))), ] .choose(&mut rng) @@ -220,11 +219,11 @@ impl From> for ZExtUnknown { } } -impl From> for ZExtUnknown { - fn from(e: ZExtZInt<{ ID }>) -> Self { +impl From> for ZExtUnknown { + fn from(e: ZExtu64<{ ID }>) -> Self { ZExtUnknown { id: ID, - body: ZExtensionBody::ZInt(e.value), + body: ZExtensionBody::Z64(e.value), } } } diff --git a/commons/zenoh-protocol/src/common/mod.rs b/commons/zenoh-protocol/src/common/mod.rs index f236a1a075..d2c3d4df36 100644 --- a/commons/zenoh-protocol/src/common/mod.rs +++ b/commons/zenoh-protocol/src/common/mod.rs @@ -19,7 +19,6 @@ pub use extension::*; /*************************************/ // Inner Message IDs pub mod imsg { - use crate::core::ZInt; pub mod id { // Zenoh Messages @@ -52,7 +51,7 @@ pub mod imsg { byte & flag != 0 } - pub const fn has_option(options: ZInt, flag: ZInt) -> bool { + pub const fn has_option(options: u64, flag: u64) -> bool { options & flag != 0 } } diff --git a/commons/zenoh-protocol/src/core/encoding.rs b/commons/zenoh-protocol/src/core/encoding.rs index 6471e51b1c..79b7d51f05 100644 --- a/commons/zenoh-protocol/src/core/encoding.rs +++ b/commons/zenoh-protocol/src/core/encoding.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{CowStr, ZInt}; +use crate::core::CowStr; use alloc::{borrow::Cow, string::String}; use core::{ convert::TryFrom, @@ -78,9 +78,9 @@ impl From for u8 { } } -impl From for ZInt { +impl From for u64 { fn from(val: KnownEncoding) -> Self { - u8::from(val) as ZInt + u8::from(val) as u64 } } @@ -107,11 +107,11 @@ impl TryFrom for KnownEncoding { } } -impl TryFrom for KnownEncoding { +impl TryFrom for KnownEncoding { type Error = (); - fn try_from(value: ZInt) -> Result { - if value < consts::MIMES.len() as ZInt + 1 { + fn try_from(value: u64) -> Result { + if value < consts::MIMES.len() as u64 + 1 { Ok(unsafe { mem::transmute(value as u8) }) } else { Err(()) @@ -135,7 +135,7 @@ pub enum Encoding { } impl Encoding { - pub fn new(prefix: ZInt, suffix: IntoCowStr) -> Option + pub fn new(prefix: u64, suffix: IntoCowStr) -> Option where IntoCowStr: Into> + AsRef, { @@ -296,7 +296,7 @@ impl Encoding { let mut rng = rand::thread_rng(); - let prefix: ZInt = rng.gen_range(0..20); + let prefix: u64 = rng.gen_range(0..20); let suffix: String = if rng.gen_bool(0.5) { let len = rng.gen_range(MIN..MAX); Alphanumeric.sample_string(&mut rng, len) diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index 3e33242806..752c9ffd27 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -23,7 +23,6 @@ use core::{ convert::{From, TryFrom, TryInto}, fmt, hash::{Hash, Hasher}, - num::NonZeroU64, str::FromStr, }; use key_expr::OwnedKeyExpr; @@ -31,12 +30,6 @@ pub use uhlc::{Timestamp, NTP64}; use uuid::Uuid; use zenoh_result::{bail, zerror}; -/// A zenoh integer. -pub type ZInt = u64; -pub type ZiInt = i64; -pub type NonZeroZInt = NonZeroU64; -pub const ZINT_MAX_BYTES: usize = 10; - /// The unique Id of the [`HLC`](uhlc::HLC) that generated the concerned [`Timestamp`]. pub type TimestampId = uhlc::ID; @@ -63,7 +56,7 @@ pub use resolution::*; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Property { - pub key: ZInt, + pub key: u64, pub value: Vec, } @@ -87,9 +80,9 @@ impl fmt::Display for SampleKind { } } -impl TryFrom for SampleKind { - type Error = ZInt; - fn try_from(kind: ZInt) -> Result { +impl TryFrom for SampleKind { + type Error = u64; + fn try_from(kind: u64) -> Result { match kind { 0 => Ok(SampleKind::Put), 1 => Ok(SampleKind::Delete), @@ -419,8 +412,8 @@ impl fmt::Display for ConduitSnList { /// The kind of reliability. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct ConduitSn { - pub reliable: ZInt, - pub best_effort: ZInt, + pub reliable: u64, + pub best_effort: u64, } /// The kind of congestion control. @@ -449,8 +442,8 @@ pub struct SubInfo { #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] pub struct QueryableInfo { - pub complete: ZInt, // Default 0: incomplete - pub distance: ZInt, // Default 0: no distance + pub complete: u64, // Default 0: incomplete + pub distance: u64, // Default 0: no distance } /// The kind of consolidation. @@ -478,5 +471,5 @@ pub enum QueryTarget { All, AllComplete, #[cfg(feature = "complete_n")] - Complete(ZInt), + Complete(u64), } diff --git a/commons/zenoh-protocol/src/core/resolution.rs b/commons/zenoh-protocol/src/core/resolution.rs index c7227ece08..74a3a78e00 100644 --- a/commons/zenoh-protocol/src/core/resolution.rs +++ b/commons/zenoh-protocol/src/core/resolution.rs @@ -11,7 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::ZInt; use crate::defaults::{FRAME_SN_RESOLUTION, REQUEST_ID_RESOLUTION}; use alloc::string::String; use core::{fmt, str::FromStr}; @@ -33,12 +32,12 @@ impl Bits { const S32: &str = "32bit"; const S64: &str = "64bit"; - pub const fn mask(&self) -> ZInt { + pub const fn mask(&self) -> u64 { match self { - Bits::U8 => u8::MAX as ZInt, - Bits::U16 => u16::MAX as ZInt, - Bits::U32 => u32::MAX as ZInt, - Bits::U64 => u64::MAX as ZInt, + Bits::U8 => u8::MAX as u64, + Bits::U16 => u16::MAX as u64, + Bits::U32 => u32::MAX as u64, + Bits::U64 => u64::MAX, } } diff --git a/commons/zenoh-protocol/src/core/wire_expr.rs b/commons/zenoh-protocol/src/core/wire_expr.rs index 546710d46a..deea670270 100644 --- a/commons/zenoh-protocol/src/core/wire_expr.rs +++ b/commons/zenoh-protocol/src/core/wire_expr.rs @@ -13,7 +13,6 @@ // //! This module defines the wire representation of Key Expressions. -use crate::core::ZInt; use alloc::{ borrow::Cow, string::{String, ToString}, @@ -22,7 +21,7 @@ use core::{convert::TryInto, fmt}; use zenoh_result::{bail, ZResult}; /// A numerical Id mapped to a key expression. -pub type ExprId = ZInt; +pub type ExprId = u64; pub const EMPTY_EXPR_ID: ExprId = 0; /// A zenoh **resource** is represented by a pair composed by a **key** and a diff --git a/commons/zenoh-protocol/src/lib.rs b/commons/zenoh-protocol/src/lib.rs index 21983384be..b0e151e173 100644 --- a/commons/zenoh-protocol/src/lib.rs +++ b/commons/zenoh-protocol/src/lib.rs @@ -58,14 +58,14 @@ pub const VERSION: u8 = 0x08; // ``` // // -// # ZInt field +// # u64 field // -// A ZInt is a specialized variable lenght field that is used to encode an unsigned integer. +// A u64 is a specialized variable lenght field that is used to encode an unsigned integer. // // ```text // 7 6 5 4 3 2 1 0 // +-+-+-+-+-+-+-+-+ -// % zint % +// % u64 % // +---------------+ // ``` // diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs index e3d6333e07..a95aee95e2 100644 --- a/commons/zenoh-protocol/src/transport/fragment.rs +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{Reliability, ZInt}; +use crate::core::Reliability; use zenoh_buffers::ZSlice; /// # Fragment message @@ -70,7 +70,7 @@ pub mod flag { pub struct Fragment { pub reliability: Reliability, pub more: bool, - pub sn: ZInt, + pub sn: u64, pub qos: ext::QoS, pub payload: ZSlice, } @@ -95,7 +95,7 @@ impl Fragment { Reliability::BestEffort }; let more = rng.gen_bool(0.5); - let sn: ZInt = rng.gen(); + let sn: u64 = rng.gen(); let qos = ext::QoS::rand(); let payload = ZSlice::rand(rng.gen_range(8..128)); @@ -114,7 +114,7 @@ impl Fragment { pub struct FragmentHeader { pub reliability: Reliability, pub more: bool, - pub sn: ZInt, + pub sn: u64, pub qos: ext::QoS, } @@ -131,7 +131,7 @@ impl FragmentHeader { Reliability::BestEffort }; let more = rng.gen_bool(0.5); - let sn: ZInt = rng.gen(); + let sn: u64 = rng.gen(); let qos = ext::QoS::rand(); FragmentHeader { diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 4cb1e6f13c..04f79538c1 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -11,10 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{ - core::{Reliability, ZInt}, - zenoh::ZenohMessage, -}; +use crate::{core::Reliability, zenoh::ZenohMessage}; use alloc::vec::Vec; /// # Frame message @@ -72,7 +69,7 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Frame { pub reliability: Reliability, - pub sn: ZInt, + pub sn: u64, pub ext_qos: ext::QoS, pub payload: Vec, } @@ -123,7 +120,7 @@ impl Frame { } else { Reliability::BestEffort }; - let sn: ZInt = rng.gen(); + let sn: u64 = rng.gen(); let qos = ext::QoS::rand(); let mut payload = vec![]; for _ in 0..rng.gen_range(1..4) { @@ -146,7 +143,7 @@ impl Frame { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct FrameHeader { pub reliability: Reliability, - pub sn: ZInt, + pub sn: u64, pub ext_qos: ext::QoS, } @@ -162,7 +159,7 @@ impl FrameHeader { } else { Reliability::BestEffort }; - let sn: ZInt = rng.gen(); + let sn: u64 = rng.gen(); let qos = ext::QoS::rand(); FrameHeader { diff --git a/commons/zenoh-protocol/src/transport/join.rs b/commons/zenoh-protocol/src/transport/join.rs index 96fdb379f1..41d03a05a4 100644 --- a/commons/zenoh-protocol/src/transport/join.rs +++ b/commons/zenoh-protocol/src/transport/join.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{ - core::{WhatAmI, ZInt, ZenohId}, + core::{WhatAmI, ZenohId}, transport::ConduitSnList, }; use core::time::Duration; @@ -61,7 +61,7 @@ pub struct Join { pub whatami: WhatAmI, pub zid: ZenohId, pub lease: Duration, - pub sn_resolution: ZInt, + pub sn_resolution: u64, pub next_sns: ConduitSnList, } @@ -90,7 +90,7 @@ impl Join { } else { Duration::from_millis(rng.gen()) }; - let sn_resolution: ZInt = rng.gen(); + let sn_resolution: u64 = rng.gen(); let next_sns = if rng.gen_bool(0.5) { let mut sns = Box::new([ConduitSn::default(); Priority::NUM]); for i in 0..Priority::NUM { diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 29f6b5a40d..fd0e5f2b79 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -19,7 +19,7 @@ pub mod init; pub mod keepalive; pub mod open; -use crate::core::{Priority, ZInt}; +use crate::core::Priority; use alloc::boxed::Box; pub use close::Close; use core::{convert::TryInto, fmt}; @@ -80,8 +80,8 @@ impl fmt::Display for ConduitSnList { /// The kind of reliability. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct ConduitSn { - pub reliable: ZInt, - pub best_effort: ZInt, + pub reliable: u64, + pub best_effort: u64, } // Zenoh messages at zenoh-transport level diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 636871ac0a..b4586bf56f 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -11,7 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::ZInt; use core::time::Duration; use zenoh_buffers::ZSlice; @@ -75,7 +74,7 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpenSyn { pub lease: Duration, - pub initial_sn: ZInt, + pub initial_sn: u64, pub cookie: ZSlice, pub ext_qos: Option, pub ext_shm: Option, @@ -85,7 +84,7 @@ pub struct OpenSyn { // Extensions pub mod ext { - use crate::common::{ZExtUnit, ZExtZBuf, ZExtZInt}; + use crate::common::{ZExtUnit, ZExtZBuf, ZExtu64}; pub const QOS: u8 = 0x01; pub const SHM: u8 = 0x02; @@ -98,7 +97,7 @@ pub mod ext { /// # Shm extension /// Used as challenge for probing shared memory capabilities - pub type Shm = ZExtZInt; + pub type Shm = ZExtu64; /// # Auth extension /// Used as challenge for probing authentication rights @@ -113,7 +112,7 @@ pub mod ext { impl OpenSyn { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::{ZExtUnit, ZExtZBuf, ZExtZInt}; + use crate::common::{ZExtUnit, ZExtZBuf, ZExtu64}; use rand::Rng; const MIN: usize = 32; @@ -127,10 +126,10 @@ impl OpenSyn { Duration::from_millis(rng.gen()) }; - let initial_sn: ZInt = rng.gen(); + let initial_sn: u64 = rng.gen(); let cookie = ZSlice::rand(rng.gen_range(MIN..=MAX)); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - let ext_shm = rng.gen_bool(0.5).then_some(ZExtZInt::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtu64::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); let ext_mlink = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); @@ -149,7 +148,7 @@ impl OpenSyn { #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpenAck { pub lease: Duration, - pub initial_sn: ZInt, + pub initial_sn: u64, pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, @@ -159,7 +158,7 @@ pub struct OpenAck { impl OpenAck { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::{ZExtUnit, ZExtZBuf, ZExtZInt}; + use crate::common::{ZExtUnit, ZExtZBuf, ZExtu64}; use rand::Rng; let mut rng = rand::thread_rng(); @@ -170,9 +169,9 @@ impl OpenAck { Duration::from_millis(rng.gen()) }; - let initial_sn: ZInt = rng.gen(); + let initial_sn: u64 = rng.gen(); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - let ext_shm = rng.gen_bool(0.5).then_some(ZExtZInt::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtu64::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); let ext_mlink = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs index 620381e35d..30b0f27e24 100644 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ b/commons/zenoh-protocol/src/zenoh/data.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{CongestionControl, Encoding, Timestamp, WireExpr, ZInt, ZenohId}; +use crate::core::{CongestionControl, Encoding, Timestamp, WireExpr, ZenohId}; use core::{convert::TryFrom, fmt}; use zenoh_buffers::ZBuf; @@ -35,9 +35,9 @@ impl fmt::Display for SampleKind { } } -impl TryFrom for SampleKind { - type Error = ZInt; - fn try_from(kind: ZInt) -> Result { +impl TryFrom for SampleKind { + type Error = u64; + fn try_from(kind: u64) -> Result { match kind { 0 => Ok(SampleKind::Put), 1 => Ok(SampleKind::Delete), @@ -72,13 +72,13 @@ pub struct ReplierInfo { } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ReplyContext { - pub qid: ZInt, + pub qid: u64, pub replier: Option, } impl ReplyContext { // Note: id replier_id=None flag F is set, meaning it's a REPLY_FINAL - pub fn new(qid: ZInt, replier: Option) -> Self { + pub fn new(qid: u64, replier: Option) -> Self { Self { qid, replier } } @@ -94,7 +94,7 @@ impl ReplyContext { let mut rng = rand::thread_rng(); - let qid: ZInt = rng.gen(); + let qid: u64 = rng.gen(); let replier = if rng.gen_bool(0.5) { Some(ReplierInfo { id: ZenohId::default(), @@ -151,7 +151,7 @@ pub struct DataInfo { pub encoding: Option, pub timestamp: Option, pub source_id: Option, - pub source_sn: Option, + pub source_sn: Option, } impl DataInfo { diff --git a/commons/zenoh-protocol/src/zenoh/declare.rs b/commons/zenoh-protocol/src/zenoh/declare.rs index 1f8e7bc406..d1e786b21b 100644 --- a/commons/zenoh-protocol/src/zenoh/declare.rs +++ b/commons/zenoh-protocol/src/zenoh/declare.rs @@ -11,10 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{ - core::{WireExpr, ZInt}, - zenoh::Reliability, -}; +use crate::{core::WireExpr, zenoh::Reliability}; use alloc::vec::Vec; /// ```text @@ -93,7 +90,7 @@ impl Declaration { /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct Resource { - pub expr_id: ZInt, + pub expr_id: u64, pub key: WireExpr<'static>, } @@ -104,7 +101,7 @@ impl Resource { let mut rng = rand::thread_rng(); - let expr_id: ZInt = rng.gen(); + let expr_id: u64 = rng.gen(); let key = WireExpr::rand(); Self { expr_id, key } @@ -121,7 +118,7 @@ impl Resource { /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct ForgetResource { - pub expr_id: ZInt, + pub expr_id: u64, } impl ForgetResource { @@ -131,7 +128,7 @@ impl ForgetResource { let mut rng = rand::thread_rng(); - let expr_id: ZInt = rng.gen(); + let expr_id: u64 = rng.gen(); Self { expr_id } } @@ -259,8 +256,8 @@ impl ForgetSubscriber { #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] pub struct QueryableInfo { - pub complete: ZInt, // Default 0: incomplete - pub distance: ZInt, // Default 0: no distance + pub complete: u64, // Default 0: incomplete + pub distance: u64, // Default 0: no distance } /// ```text @@ -287,8 +284,8 @@ impl Queryable { let mut rng = rand::thread_rng(); let key = WireExpr::rand(); - let complete: ZInt = rng.gen(); - let distance: ZInt = rng.gen(); + let complete: u64 = rng.gen(); + let distance: u64 = rng.gen(); let info = QueryableInfo { complete, distance }; Self { key, info } diff --git a/commons/zenoh-protocol/src/zenoh/linkstate.rs b/commons/zenoh-protocol/src/zenoh/linkstate.rs index 2e60f80d27..3f410e670a 100644 --- a/commons/zenoh-protocol/src/zenoh/linkstate.rs +++ b/commons/zenoh-protocol/src/zenoh/linkstate.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{Locator, WhatAmI, ZInt, ZenohId}; +use crate::core::{Locator, WhatAmI, ZenohId}; use alloc::vec::Vec; // 7 6 5 4 3 2 1 0 @@ -32,12 +32,12 @@ use alloc::vec::Vec; // +---------------+ #[derive(Debug, Clone, PartialEq, Eq)] pub struct LinkState { - pub psid: ZInt, - pub sn: ZInt, + pub psid: u64, + pub sn: u64, pub zid: Option, pub whatami: Option, pub locators: Option>, - pub links: Vec, + pub links: Vec, } impl LinkState { @@ -50,8 +50,8 @@ impl LinkState { let mut rng = rand::thread_rng(); - let psid: ZInt = rng.gen(); - let sn: ZInt = rng.gen(); + let psid: u64 = rng.gen(); + let sn: u64 = rng.gen(); let zid = if rng.gen_bool(0.5) { Some(ZenohId::default()) } else { @@ -70,7 +70,7 @@ impl LinkState { None }; let n = rng.gen_range(MIN..=MAX); - let links = (0..n).map(|_| rng.gen()).collect::>(); + let links = (0..n).map(|_| rng.gen()).collect::>(); Self { psid, diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index 39af2dd944..ce8740ca32 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -19,7 +19,7 @@ mod query; mod routing; mod unit; -use crate::core::{Channel, CongestionControl, Reliability, WireExpr, ZInt}; +use crate::core::{Channel, CongestionControl, Reliability, WireExpr}; use alloc::{string::String, vec::Vec}; use core::fmt; pub use data::*; @@ -34,7 +34,7 @@ use zenoh_buffers::ZBuf; pub mod zmsg { use crate::{ common::imsg, - core::{Channel, CongestionControl, Priority, Reliability, ZInt}, + core::{Channel, CongestionControl, Priority, Reliability}, }; // Zenoh message IDs -- Re-export of some of the Inner Message IDs @@ -74,21 +74,17 @@ pub mod zmsg { // Options used for DataInfo pub mod data { - use super::ZInt; - pub mod info { - use super::ZInt; - #[cfg(feature = "shared-memory")] - pub const SLICED: ZInt = 1 << 0; // 0x01 - pub const KIND: ZInt = 1 << 1; // 0x02 - pub const ENCODING: ZInt = 1 << 2; // 0x04 - pub const TIMESTAMP: ZInt = 1 << 3; // 0x08 - // 0x10: Reserved - // 0x20: Reserved - // 0x40: Reserved - pub const SRCID: ZInt = 1 << 7; // 0x80 - pub const SRCSN: ZInt = 1 << 8; // 0x100 + pub const SLICED: u64 = 1 << 0; // 0x01 + pub const KIND: u64 = 1 << 1; // 0x02 + pub const ENCODING: u64 = 1 << 2; // 0x04 + pub const TIMESTAMP: u64 = 1 << 3; // 0x08 + // 0x10: Reserved + // 0x20: Reserved + // 0x40: Reserved + pub const SRCID: u64 = 1 << 7; // 0x80 + pub const SRCSN: u64 = 1 << 8; // 0x100 } } @@ -117,11 +113,9 @@ pub mod zmsg { // Options used for LinkState pub mod link_state { - use super::ZInt; - - pub const PID: ZInt = 1; // 0x01 - pub const WAI: ZInt = 1 << 1; // 0x02 - pub const LOC: ZInt = 1 << 2; // 0x04 + pub const PID: u64 = 1; // 0x01 + pub const WAI: u64 = 1 << 1; // 0x02 + pub const LOC: u64 = 1 << 2; // 0x04 } pub mod conduit { @@ -266,8 +260,8 @@ impl ZenohMessage { pub fn make_pull( is_final: bool, key: WireExpr<'static>, - pull_id: ZInt, - max_samples: Option, + pull_id: u64, + max_samples: Option, ) -> ZenohMessage { ZenohMessage { body: ZenohBody::Pull(Pull { @@ -288,7 +282,7 @@ impl ZenohMessage { pub fn make_query( key: WireExpr<'static>, parameters: String, - qid: ZInt, + qid: u64, target: Option, consolidation: ConsolidationMode, body: Option, diff --git a/commons/zenoh-protocol/src/zenoh/pull.rs b/commons/zenoh-protocol/src/zenoh/pull.rs index ba5c260005..db2f673527 100644 --- a/commons/zenoh-protocol/src/zenoh/pull.rs +++ b/commons/zenoh-protocol/src/zenoh/pull.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{WireExpr, ZInt}; +use crate::core::WireExpr; /// # Pull message /// @@ -30,8 +30,8 @@ use crate::core::{WireExpr, ZInt}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Pull { pub key: WireExpr<'static>, - pub pull_id: ZInt, - pub max_samples: Option, + pub pull_id: u64, + pub max_samples: Option, pub is_final: bool, } @@ -43,7 +43,7 @@ impl Pull { let mut rng = rand::thread_rng(); let key = WireExpr::rand(); - let pull_id: ZInt = rng.gen(); + let pull_id: u64 = rng.gen(); let max_samples = if rng.gen_bool(0.5) { Some(rng.gen()) } else { diff --git a/commons/zenoh-protocol/src/zenoh/query.rs b/commons/zenoh-protocol/src/zenoh/query.rs index acd2f959b3..860d90e68f 100644 --- a/commons/zenoh-protocol/src/zenoh/query.rs +++ b/commons/zenoh-protocol/src/zenoh/query.rs @@ -11,10 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{ - core::{WireExpr, ZInt}, - zenoh::DataInfo, -}; +use crate::{core::WireExpr, zenoh::DataInfo}; use alloc::string::String; use zenoh_buffers::ZBuf; @@ -43,7 +40,7 @@ pub enum QueryTarget { All, AllComplete, #[cfg(feature = "complete_n")] - Complete(ZInt), + Complete(u64), } /// # QueryBody @@ -104,7 +101,7 @@ impl QueryBody { pub struct Query { pub key: WireExpr<'static>, pub parameters: String, - pub qid: ZInt, + pub qid: u64, pub target: Option, pub consolidation: ConsolidationMode, pub body: Option, @@ -133,7 +130,7 @@ impl Query { String::new() }; - let qid: ZInt = rng.gen(); + let qid: u64 = rng.gen(); let target = if rng.gen_bool(0.5) { let t = [ diff --git a/commons/zenoh-protocol/src/zenoh/routing.rs b/commons/zenoh-protocol/src/zenoh/routing.rs index 47d3208d18..6eb69c133c 100644 --- a/commons/zenoh-protocol/src/zenoh/routing.rs +++ b/commons/zenoh-protocol/src/zenoh/routing.rs @@ -11,7 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::ZInt; /// -- RoutingContext decorator /// @@ -28,11 +27,11 @@ use crate::core::ZInt; /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct RoutingContext { - pub tree_id: ZInt, + pub tree_id: u64, } impl RoutingContext { - pub fn new(tree_id: ZInt) -> RoutingContext { + pub fn new(tree_id: u64) -> RoutingContext { RoutingContext { tree_id } } } diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index a3167eaa4d..3067298bbc 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_codec::{WCodec, Zenoh080}; use zenoh_protocol::{ - core::{Reliability, ZInt}, + core::Reliability, transport::{fragment::FragmentHeader, frame::FrameHeader, TransportMessage}, zenoh::ZenohMessage, }; @@ -46,8 +46,8 @@ pub(crate) enum CurrentFrame { #[derive(Clone, Copy, Debug)] pub(crate) struct LatestSn { - pub(crate) reliable: Option, - pub(crate) best_effort: Option, + pub(crate) reliable: Option, + pub(crate) best_effort: Option, } impl LatestSn { diff --git a/io/zenoh-transport/src/common/conduit.rs b/io/zenoh-transport/src/common/conduit.rs index f5c185ff73..8ca51fe0df 100644 --- a/io/zenoh-transport/src/common/conduit.rs +++ b/io/zenoh-transport/src/common/conduit.rs @@ -16,7 +16,7 @@ use super::seq_num::{SeqNum, SeqNumGenerator}; use std::sync::{Arc, Mutex}; use zenoh_core::zlock; use zenoh_protocol::{ - core::{Bits, Reliability, ZInt}, + core::{Bits, Reliability}, transport::ConduitSn, }; use zenoh_result::ZResult; @@ -34,7 +34,7 @@ impl TransportChannelTx { Ok(tch) } - pub(crate) fn sync(&mut self, sn: ZInt) -> ZResult<()> { + pub(crate) fn sync(&mut self, sn: u64) -> ZResult<()> { self.sn.set(sn) } } @@ -57,7 +57,7 @@ impl TransportChannelRx { Ok(tch) } - pub(crate) fn sync(&mut self, sn: ZInt) -> ZResult<()> { + pub(crate) fn sync(&mut self, sn: u64) -> ZResult<()> { // Set the sequence number in the state as it had received a message with sn - 1 let sn = if sn == 0 { self.sn.resolution() - 1 diff --git a/io/zenoh-transport/src/common/defragmentation.rs b/io/zenoh-transport/src/common/defragmentation.rs index f4d4a723b5..c07ec5ac3e 100644 --- a/io/zenoh-transport/src/common/defragmentation.rs +++ b/io/zenoh-transport/src/common/defragmentation.rs @@ -15,7 +15,7 @@ use super::seq_num::SeqNum; use zenoh_buffers::{reader::HasReader, SplitBuffer, ZBuf, ZSlice}; use zenoh_codec::{RCodec, Zenoh080Reliability}; use zenoh_protocol::{ - core::{Bits, Reliability, ZInt}, + core::{Bits, Reliability}, zenoh::ZenohMessage, }; use zenoh_result::{bail, ZResult}; @@ -57,11 +57,11 @@ impl DefragBuffer { } #[inline(always)] - pub(crate) fn sync(&mut self, sn: ZInt) -> ZResult<()> { + pub(crate) fn sync(&mut self, sn: u64) -> ZResult<()> { self.sn.set(sn) } - pub(crate) fn push(&mut self, sn: ZInt, zslice: ZSlice) -> ZResult<()> { + pub(crate) fn push(&mut self, sn: u64, zslice: ZSlice) -> ZResult<()> { if sn != self.sn.get() { self.clear(); bail!("Expected SN {}, received {}", self.sn.get(), sn) diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 999faf23b2..517982bb8d 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -709,7 +709,7 @@ mod tests { }; use zenoh_codec::{RCodec, Zenoh080}; use zenoh_protocol::{ - core::{Channel, CongestionControl, Priority, Reliability, ZInt}, + core::{Channel, CongestionControl, Priority, Reliability}, defaults::{BATCH_SIZE, FRAME_SN_RESOLUTION}, transport::{Fragment, Frame, TransportBody}, zenoh::ZenohMessage, @@ -823,7 +823,7 @@ mod tests { task::block_on(async { for ps in payload_sizes.iter() { - if ZInt::try_from(*ps).is_err() { + if u64::try_from(*ps).is_err() { break; } diff --git a/io/zenoh-transport/src/common/seq_num.rs b/io/zenoh-transport/src/common/seq_num.rs index 16813bed4c..6ceb66c30c 100644 --- a/io/zenoh-transport/src/common/seq_num.rs +++ b/io/zenoh-transport/src/common/seq_num.rs @@ -11,15 +11,15 @@ // Contributors: // ZettaScale Zenoh Team, // -use zenoh_protocol::core::{Bits, ZInt}; +use zenoh_protocol::core::Bits; use zenoh_result::{bail, ZResult}; -const RES_U8: ZInt = (u8::MAX >> 1) as ZInt; // 1 byte max when encoded -const RES_U16: ZInt = (u16::MAX >> 2) as ZInt; // 2 bytes max when encoded -const RES_U32: ZInt = (u32::MAX >> 4) as ZInt; // 4 bytes max when encoded -const RES_U64: ZInt = (u64::MAX >> 1) as ZInt; // 9 bytes max when encoded +const RES_U8: u64 = (u8::MAX >> 1) as u64; // 1 byte max when encoded +const RES_U16: u64 = (u16::MAX >> 2) as u64; // 2 bytes max when encoded +const RES_U32: u64 = (u32::MAX >> 4) as u64; // 4 bytes max when encoded +const RES_U64: u64 = u64::MAX >> 1; // 9 bytes max when encoded -pub(crate) fn get_mask(resolution: Bits) -> ZInt { +pub(crate) fn get_mask(resolution: Bits) -> u64 { match resolution { Bits::U8 => RES_U8, Bits::U16 => RES_U16, @@ -39,8 +39,8 @@ pub(crate) fn get_mask(resolution: Bits) -> ZInt { /// #[derive(Clone, Copy, Debug)] pub(crate) struct SeqNum { - value: ZInt, - mask: ZInt, + value: u64, + mask: u64, } impl SeqNum { @@ -60,22 +60,22 @@ impl SeqNum { /// This funtion will panic if `value` is out of bound w.r.t. `resolution`. That is if /// `value` is greater or equal than `resolution`. /// - pub(crate) fn make(value: ZInt, resolution: Bits) -> ZResult { + pub(crate) fn make(value: u64, resolution: Bits) -> ZResult { let mask = get_mask(resolution); let mut sn = SeqNum { value: 0, mask }; sn.set(value)?; Ok(sn) } - pub(crate) fn get(&self) -> ZInt { + pub(crate) fn get(&self) -> u64 { self.value } - pub(crate) fn resolution(&self) -> ZInt { + pub(crate) fn resolution(&self) -> u64 { self.mask } - pub(crate) fn set(&mut self, value: ZInt) -> ZResult<()> { + pub(crate) fn set(&mut self, value: u64) -> ZResult<()> { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -107,7 +107,7 @@ impl SeqNum { /// # Arguments /// /// * `value` - The sequence number which should be checked for precedence relation. - pub(crate) fn precedes(&self, value: ZInt) -> ZResult { + pub(crate) fn precedes(&self, value: u64) -> ZResult { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -117,7 +117,7 @@ impl SeqNum { /// Computes the modulo gap between two sequence numbers. #[cfg(test)] // @TODO: remove #[cfg(test)] once reliability is implemented - pub(crate) fn gap(&self, value: ZInt) -> ZResult { + pub(crate) fn gap(&self, value: u64) -> ZResult { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -145,23 +145,23 @@ impl SeqNumGenerator { /// This funtion will panic if `value` is out of bound w.r.t. `resolution`. That is if /// `value` is greater or equal than `resolution`. /// - pub(crate) fn make(initial_sn: ZInt, resolution: Bits) -> ZResult { + pub(crate) fn make(initial_sn: u64, resolution: Bits) -> ZResult { let sn = SeqNum::make(initial_sn, resolution)?; Ok(SeqNumGenerator(sn)) } - pub(crate) fn now(&mut self) -> ZInt { + pub(crate) fn now(&mut self) -> u64 { self.0.get() } /// Generates the next sequence number - pub(crate) fn get(&mut self) -> ZInt { + pub(crate) fn get(&mut self) -> u64 { let now = self.now(); self.0.increment(); now } - pub(crate) fn set(&mut self, sn: ZInt) -> ZResult<()> { + pub(crate) fn set(&mut self, sn: u64) -> ZResult<()> { self.0.set(sn) } } @@ -172,7 +172,7 @@ mod tests { #[test] fn sn_set() { - let mask = (u8::MAX >> 1) as ZInt; + let mask = (u8::MAX >> 1) as u64; let mut sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert_eq!(sn0a.get(), 0); @@ -193,7 +193,7 @@ mod tests { #[test] fn sn_gap() { - let mask = (u8::MAX >> 1) as ZInt; + let mask = (u8::MAX >> 1) as u64; let mut sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert_eq!(sn0a.gap(0).unwrap(), 0); @@ -208,7 +208,7 @@ mod tests { #[test] fn sn_precedence() { - let mask = (u8::MAX >> 1) as ZInt; + let mask = (u8::MAX >> 1) as u64; let sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert!(sn0a.precedes(1).unwrap()); @@ -222,7 +222,7 @@ mod tests { #[test] fn sn_generation() { - let mask = (u8::MAX >> 1) as ZInt; + let mask = (u8::MAX >> 1) as u64; let mut sn0 = SeqNumGenerator::make(mask, Bits::U8).unwrap(); let mut sn1 = SeqNumGenerator::make(5, Bits::U8).unwrap(); diff --git a/io/zenoh-transport/src/primitives/mod.rs b/io/zenoh-transport/src/primitives/mod.rs index cb8866134d..d686068bac 100644 --- a/io/zenoh-transport/src/primitives/mod.rs +++ b/io/zenoh-transport/src/primitives/mod.rs @@ -18,15 +18,15 @@ pub use demux::*; pub use mux::*; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{Channel, CongestionControl, WireExpr, ZInt, ZenohId}, + core::{Channel, CongestionControl, WireExpr, ZenohId}, zenoh::{ ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo, }, }; pub trait Primitives: Send + Sync { - fn decl_resource(&self, expr_id: ZInt, key_expr: &WireExpr); - fn forget_resource(&self, expr_id: ZInt); + fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr); + fn forget_resource(&self, expr_id: u64); fn decl_publisher(&self, key_expr: &WireExpr, routing_context: Option); fn forget_publisher(&self, key_expr: &WireExpr, routing_context: Option); @@ -62,7 +62,7 @@ pub trait Primitives: Send + Sync { &self, key_expr: &WireExpr, parameters: &str, - qid: ZInt, + qid: u64, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -71,21 +71,21 @@ pub trait Primitives: Send + Sync { fn send_reply_data( &self, - qid: ZInt, + qid: u64, replier_id: ZenohId, key_expr: WireExpr, info: Option, payload: ZBuf, ); - fn send_reply_final(&self, qid: ZInt); + fn send_reply_final(&self, qid: u64); fn send_pull( &self, is_final: bool, key_expr: &WireExpr, - pull_id: ZInt, - max_samples: &Option, + pull_id: u64, + max_samples: &Option, ); fn send_close(&self); @@ -101,8 +101,8 @@ impl DummyPrimitives { } impl Primitives for DummyPrimitives { - fn decl_resource(&self, _expr_id: ZInt, _key_expr: &WireExpr) {} - fn forget_resource(&self, _expr_id: ZInt) {} + fn decl_resource(&self, _expr_id: u64, _key_expr: &WireExpr) {} + fn forget_resource(&self, _expr_id: u64) {} fn decl_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} fn forget_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} @@ -139,7 +139,7 @@ impl Primitives for DummyPrimitives { &self, _key_expr: &WireExpr, _parameters: &str, - _qid: ZInt, + _qid: u64, _target: QueryTarget, _consolidation: ConsolidationMode, _body: Option, @@ -148,20 +148,20 @@ impl Primitives for DummyPrimitives { } fn send_reply_data( &self, - _qid: ZInt, + _qid: u64, _replier_id: ZenohId, _key_expr: WireExpr, _info: Option, _payload: ZBuf, ) { } - fn send_reply_final(&self, _qid: ZInt) {} + fn send_reply_final(&self, _qid: u64) {} fn send_pull( &self, _is_final: bool, _key_expr: &WireExpr, - _pull_id: ZInt, - _max_samples: &Option, + _pull_id: u64, + _max_samples: &Option, ) { } diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index 965ca33b26..9e31472275 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -15,7 +15,7 @@ use super::super::TransportUnicast; use super::Primitives; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{Channel, CongestionControl, WireExpr, ZInt, ZenohId}, + core::{Channel, CongestionControl, WireExpr, ZenohId}, zenoh::{ zmsg, ConsolidationMode, DataInfo, Declaration, ForgetPublisher, ForgetQueryable, ForgetResource, ForgetSubscriber, Publisher, QueryBody, QueryTarget, Queryable, @@ -35,7 +35,7 @@ impl Mux { } impl Primitives for Mux { - fn decl_resource(&self, expr_id: ZInt, key_expr: &WireExpr) { + fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr) { let d = Declaration::Resource(Resource { expr_id, key: key_expr.to_owned(), @@ -46,7 +46,7 @@ impl Primitives for Mux { .handle_message(ZenohMessage::make_declare(decls, None)); } - fn forget_resource(&self, expr_id: ZInt) { + fn forget_resource(&self, expr_id: u64) { let d = Declaration::ForgetResource(ForgetResource { expr_id }); let decls = vec![d]; let _ = self @@ -150,7 +150,7 @@ impl Primitives for Mux { &self, key_expr: &WireExpr, parameters: &str, - qid: ZInt, + qid: u64, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -174,7 +174,7 @@ impl Primitives for Mux { fn send_reply_data( &self, - qid: ZInt, + qid: u64, replier_id: ZenohId, key_expr: WireExpr, data_info: Option, @@ -191,7 +191,7 @@ impl Primitives for Mux { )); } - fn send_reply_final(&self, qid: ZInt) { + fn send_reply_final(&self, qid: u64) { let _ = self.handler.handle_message(ZenohMessage::make_unit( zmsg::default_channel::REPLY, zmsg::default_congestion_control::REPLY, @@ -203,8 +203,8 @@ impl Primitives for Mux { &self, is_final: bool, key_expr: &WireExpr, - pull_id: ZInt, - max_samples: &Option, + pull_id: u64, + max_samples: &Option, ) { let _ = self.handler.handle_message(ZenohMessage::make_pull( is_final, diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 995741a613..81bd8d6006 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -30,7 +30,7 @@ use zenoh_core::{zasynclock, zcondfeat, zerror}; use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ - core::{Field, Resolution, WhatAmI, ZInt, ZenohId}, + core::{Field, Resolution, WhatAmI, ZenohId}, transport::{ close::{self, Close}, InitAck, OpenAck, TransportBody, TransportMessage, @@ -78,18 +78,18 @@ struct SendInitAckIn { ext_shm: Challenge, } struct SendInitAckOut { - cookie_nonce: ZInt, + cookie_nonce: u64, } // OpenSyn struct RecvOpenSynIn { - cookie_nonce: ZInt, + cookie_nonce: u64, } struct RecvOpenSynOut { other_zid: ZenohId, other_whatami: WhatAmI, other_lease: Duration, - other_initial_sn: ZInt, + other_initial_sn: u64, } // OpenAck @@ -260,7 +260,7 @@ impl<'a> AcceptFsm for AcceptLink<'a> { ); // Create the cookie - let cookie_nonce: ZInt = zasynclock!(self.prng).gen(); + let cookie_nonce: u64 = zasynclock!(self.prng).gen(); let cookie = Cookie { zid: input.other_zid, whatami: input.other_whatami, diff --git a/io/zenoh-transport/src/unicast/establishment/cookie.rs b/io/zenoh-transport/src/unicast/establishment/cookie.rs index b5752ed5ff..e062628beb 100644 --- a/io/zenoh-transport/src/unicast/establishment/cookie.rs +++ b/io/zenoh-transport/src/unicast/establishment/cookie.rs @@ -20,7 +20,7 @@ use zenoh_buffers::{ }; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_crypto::{BlockCipher, PseudoRng}; -use zenoh_protocol::core::{Resolution, WhatAmI, ZInt, ZenohId}; +use zenoh_protocol::core::{Resolution, WhatAmI, ZenohId}; #[derive(Debug, PartialEq)] pub(crate) struct Cookie { @@ -28,7 +28,7 @@ pub(crate) struct Cookie { pub(crate) whatami: WhatAmI, pub(crate) resolution: Resolution, pub(crate) batch_size: u16, - pub(crate) nonce: ZInt, + pub(crate) nonce: u64, // Extensions pub(crate) ext_qos: ext::qos::StateAccept, #[cfg(feature = "transport_multilink")] @@ -78,7 +78,7 @@ where let resolution: u8 = self.read(&mut *reader)?; let resolution = Resolution::from(resolution); let batch_size: u16 = self.read(&mut *reader)?; - let nonce: ZInt = self.read(&mut *reader)?; + let nonce: u64 = self.read(&mut *reader)?; // Extensions let ext_qos: ext::qos::StateAccept = self.read(&mut *reader)?; #[cfg(feature = "transport_multilink")] diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs index 3055b0a819..fae4e8058c 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -741,7 +741,7 @@ impl<'a> AcceptFsm for AuthFsm<'a> { // &self, // link: &AuthenticatedLink, // node_id: &ZenohId, -// sn_resolution: ZInt, +// sn_resolution: u64, // property: Option>, // ) -> ZResult>>; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs index 2a1253b76b..1bbbdf8f46 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs @@ -31,10 +31,7 @@ use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_config::PubKeyConf; use zenoh_core::{bail, zasynclock, zasyncread, zerror, Error as ZError, Result as ZResult}; use zenoh_crypto::PseudoRng; -use zenoh_protocol::{ - common::{ZExtUnit, ZExtZBuf}, - core::ZInt, -}; +use zenoh_protocol::common::{ZExtUnit, ZExtZBuf}; // Authenticator #[derive(Debug)] @@ -477,7 +474,7 @@ impl<'a> OpenFsm for AuthPubKeyFsm<'a> { #[derive(Debug)] pub(crate) struct StateAccept { nonce: Vec, - challenge: ZInt, + challenge: u64, } impl StateAccept { @@ -519,7 +516,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let challenge: ZInt = self.read(&mut *reader)?; + let challenge: u64 = self.read(&mut *reader)?; Ok(StateAccept { nonce: vec![], challenge, diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index 6479bec935..306132a1b7 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -25,10 +25,7 @@ use zenoh_collections::Properties; use zenoh_config::UsrPwdConf; use zenoh_core::{bail, zasyncread, zerror, Error as ZError, Result as ZResult}; use zenoh_crypto::hmac; -use zenoh_protocol::{ - common::{ZExtUnit, ZExtZBuf, ZExtZInt}, - core::ZInt, -}; +use zenoh_protocol::common::{ZExtUnit, ZExtZBuf, ZExtu64}; // Authenticator type User = Vec; @@ -118,7 +115,7 @@ impl fmt::Debug for AuthUsrPwd { // OpenFsm / AcceptFsm #[derive(Debug, PartialEq, Eq)] pub(crate) struct StateOpen { - nonce: ZInt, + nonce: u64, } impl StateOpen { @@ -132,7 +129,7 @@ impl StateOpen { #[derive(Debug, PartialEq, Eq)] pub(crate) struct StateAccept { - nonce: ZInt, + nonce: u64, } impl StateAccept { @@ -170,7 +167,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let nonce: ZInt = self.read(&mut *reader)?; + let nonce: u64 = self.read(&mut *reader)?; Ok(StateAccept { nonce }) } } @@ -202,7 +199,7 @@ impl<'a> AuthUsrPwdFsm<'a> { /// ~ nonce ~ /// +---------------+ /// -/// ZExtZInt +/// ZExtu64 /*************************************/ /* OpenSyn */ @@ -272,7 +269,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { Ok(output) } - type RecvInitAckIn = (&'a mut StateOpen, Option>); + type RecvInitAckIn = (&'a mut StateOpen, Option>); type RecvInitAckOut = (); async fn recv_init_ack( &self, @@ -370,12 +367,12 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { } type SendInitAckIn = &'a StateAccept; - type SendInitAckOut = Option>; + type SendInitAckOut = Option>; async fn send_init_ack( &self, state: Self::SendInitAckIn, ) -> Result { - Ok(Some(ZExtZInt::new(state.nonce))) + Ok(Some(ZExtu64::new(state.nonce))) } type RecvOpenSynIn = (&'a mut StateAccept, Option>); diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index ec644a135e..220e86293d 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -23,10 +23,7 @@ use zenoh_buffers::{ }; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_core::zasyncwrite; -use zenoh_protocol::{ - core::ZInt, - transport::{init, open}, -}; +use zenoh_protocol::transport::{init, open}; use zenoh_result::{zerror, Error as ZError}; use zenoh_shm::SharedMemoryBufInfo; @@ -76,7 +73,7 @@ where /// ~ ShmMemBufInfo ~ /// +---------------+ struct InitAck { - alice_challenge: ZInt, + alice_challenge: u64, bob_info: SharedMemoryBufInfo, } @@ -100,7 +97,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let alice_challenge: ZInt = self.read(&mut *reader)?; + let alice_challenge: u64 = self.read(&mut *reader)?; let bob_info: SharedMemoryBufInfo = self.read(&mut *reader)?; Ok(InitAck { alice_challenge, @@ -218,7 +215,7 @@ impl<'a> OpenFsm for ShmFsm<'a> { .as_slice() .try_into() .map_err(|e| zerror!("{}", e))?; - let challenge = ZInt::from_le_bytes(bytes); + let challenge = u64::from_le_bytes(bytes); // Verify that Bob has correctly read Alice challenge if challenge != init_ack.alice_challenge { @@ -251,7 +248,7 @@ impl<'a> OpenFsm for ShmFsm<'a> { return Ok(0); } }; - let bob_challenge = ZInt::from_le_bytes(bytes); + let bob_challenge = u64::from_le_bytes(bytes); Ok(bob_challenge) } @@ -404,7 +401,7 @@ impl<'a> AcceptFsm for ShmFsm<'a> { return Ok(0); } }; - let alice_challenge = ZInt::from_le_bytes(bytes); + let alice_challenge = u64::from_le_bytes(bytes); Ok(alice_challenge) } @@ -462,7 +459,7 @@ impl<'a> AcceptFsm for ShmFsm<'a> { .as_slice() .try_into() .map_err(|e| zerror!("{}", e))?; - let challenge = ZInt::from_le_bytes(bytes); + let challenge = u64::from_le_bytes(bytes); // Verify that Alice has correctly read Bob challenge let bob_challnge = ext.value; diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index d08589ff27..55c771a2b1 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -27,7 +27,7 @@ use sha3::{ use std::time::Duration; use zenoh_link::{Link, LinkUnicast}; use zenoh_protocol::{ - core::{Field, Resolution, ZInt, ZenohId}, + core::{Field, Resolution, ZenohId}, transport::{Close, TransportMessage}, }; use zenoh_result::ZResult; @@ -104,16 +104,16 @@ pub trait AcceptFsm { /*************************************/ /* FUNCTIONS */ /*************************************/ -pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) -> ZInt { +pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) -> u64 { // Create a random yet deterministic initial_sn. // In case of multilink it's important that the same initial_sn is used for every connection attempt. // Instead of storing the state everywhere, we make sure that the we always compute the same initial_sn. let mut hasher = Shake128::default(); hasher.update(zid1.as_slice()); hasher.update(zid2.as_slice()); - let mut array = (0 as ZInt).to_le_bytes(); + let mut array = 0_u64.to_le_bytes(); hasher.finalize_xof().read(&mut array); - ZInt::from_le_bytes(array) & seq_num::get_mask(resolution.get(Field::FrameSN)) + u64::from_le_bytes(array) & seq_num::get_mask(resolution.get(Field::FrameSN)) } pub(super) async fn close_link(link: &LinkUnicast, reason: Option) { diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 80f161e733..c5006fda41 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -27,7 +27,7 @@ use zenoh_config::{WhatAmI, ZenohId}; use zenoh_core::zasynclock; use zenoh_core::{zcondfeat, zerror}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; -use zenoh_protocol::core::{Field, Resolution, ZInt}; +use zenoh_protocol::core::{Field, Resolution}; use zenoh_protocol::transport::{close, Close, InitSyn, OpenSyn, TransportBody, TransportMessage}; use zenoh_result::ZResult; @@ -76,13 +76,13 @@ struct SendOpenSynIn { } struct SendOpenSynOut { - mine_initial_sn: ZInt, + mine_initial_sn: u64, } // OpenAck struct RecvOpenAckOut { other_lease: Duration, - other_initial_sn: ZInt, + other_initial_sn: u64, } // FSM diff --git a/io/zenoh-transport/src/unicast/establishment/properties.rs b/io/zenoh-transport/src/unicast/establishment/properties.rs index 19e1d7c345..56e0d2cd79 100644 --- a/io/zenoh-transport/src/unicast/establishment/properties.rs +++ b/io/zenoh-transport/src/unicast/establishment/properties.rs @@ -17,7 +17,7 @@ use std::{ }; use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZBuf}; use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_protocol::core::{Property, ZInt}; +use zenoh_protocol::core::Property; use zenoh_result::{bail, zerror, Error as ZError, ZResult}; #[derive(Clone, Debug, PartialEq, Eq)] @@ -50,7 +50,7 @@ impl EstablishmentProperties { Ok(()) } - pub(super) fn remove(&mut self, key: ZInt) -> Option { + pub(super) fn remove(&mut self, key: u64) -> Option { self.0 .iter() .position(|x| x.key == key) @@ -117,7 +117,7 @@ impl EstablishmentProperties { let mut eps = EstablishmentProperties::new(); for _ in MIN..=MAX { loop { - let key: ZInt = rng.gen(); + let key: u64 = rng.gen(); let mut value = vec![0u8; rng.gen_range(MIN..=MAX)]; rng.fill(&mut value[..]); let p = Property { key, value }; diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 6c88054a62..09a3a24e59 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -33,7 +33,7 @@ use transport::TransportUnicastInner; use zenoh_core::zcondfeat; use zenoh_link::Link; use zenoh_protocol::{ - core::{Bits, WhatAmI, ZInt, ZenohId}, + core::{Bits, WhatAmI, ZenohId}, transport::close, zenoh::ZenohMessage, }; @@ -88,7 +88,7 @@ pub(crate) struct TransportConfigUnicast { pub(crate) zid: ZenohId, pub(crate) whatami: WhatAmI, pub(crate) sn_resolution: Bits, - pub(crate) tx_initial_sn: ZInt, + pub(crate) tx_initial_sn: u64, pub(crate) is_qos: bool, #[cfg(feature = "transport_multilink")] pub(crate) multilink: Option, @@ -122,7 +122,7 @@ impl TransportUnicast { } #[inline(always)] - pub fn get_sn_resolution(&self) -> ZResult { + pub fn get_sn_resolution(&self) -> ZResult { let transport = self.get_inner()?; Ok(transport.get_sn_resolution().mask()) } diff --git a/io/zenoh-transport/src/unicast/reliability.rs b/io/zenoh-transport/src/unicast/reliability.rs index 14ec612e33..e557fbf015 100644 --- a/io/zenoh-transport/src/unicast/reliability.rs +++ b/io/zenoh-transport/src/unicast/reliability.rs @@ -15,7 +15,7 @@ use std::convert::TryInto; use std::fmt; use super::common::seq_num::SeqNum; -use super::core::ZInt; +use super::core::u64; use zenoh_result::{ZError, ZErrorKind, ZResult}; use zenoh_util::zerror; @@ -28,11 +28,7 @@ pub(super) struct ReliabilityQueue { } impl ReliabilityQueue { - pub(super) fn new( - capacity: usize, - initial_sn: ZInt, - sn_resolution: ZInt, - ) -> ReliabilityQueue { + pub(super) fn new(capacity: usize, initial_sn: u64, sn_resolution: u64) -> ReliabilityQueue { let mut inner = Vec::with_capacity(capacity); for _ in 0..capacity { inner.push(None); @@ -67,11 +63,11 @@ impl ReliabilityQueue { } #[inline] - pub(super) fn get_base(&self) -> ZInt { + pub(super) fn get_base(&self) -> u64 { self.sn.get() } - pub(super) fn set_base(&mut self, sn: ZInt) -> ZResult<()> { + pub(super) fn set_base(&mut self, sn: u64) -> ZResult<()> { let gap: usize = match self.sn.gap(sn) { Ok(gap) => match gap.try_into() { Ok(gap) => gap, @@ -103,7 +99,7 @@ impl ReliabilityQueue { Ok(()) } - pub(super) fn insert(&mut self, t: T, sn: ZInt) -> ZResult<()> { + pub(super) fn insert(&mut self, t: T, sn: u64) -> ZResult<()> { let gap: usize = match self.sn.gap(sn) { Ok(gap) => match gap.try_into() { Ok(gap) => gap, @@ -135,7 +131,7 @@ impl ReliabilityQueue { Ok(()) } - pub(super) fn remove(&mut self, sn: ZInt) -> ZResult { + pub(super) fn remove(&mut self, sn: u64) -> ZResult { let gap: usize = match self.sn.gap(sn) { Ok(gap) => match gap.try_into() { Ok(gap) => gap, @@ -187,8 +183,8 @@ impl ReliabilityQueue { /// Returns a bitmask of surely missed messages. /// A bit is set to 1 iff the position in the queue is empty and /// there is at least one message with a higher sequence number. - pub(super) fn get_mask(&self) -> ZInt { - let mut mask: ZInt = 0; + pub(super) fn get_mask(&self) -> u64 { + let mut mask: u64 = 0; let mut count = 0; let mut i = 0; while count < self.len() { @@ -205,7 +201,7 @@ impl ReliabilityQueue { } impl ReliabilityQueue { - pub(super) fn get(&mut self, sn: ZInt) -> ZResult { + pub(super) fn get(&mut self, sn: u64) -> ZResult { let gap: usize = match self.sn.gap(sn) { Ok(gap) => match gap.try_into() { Ok(gap) => gap, @@ -259,9 +255,9 @@ mod tests { #[test] fn reliability_queue_simple() { let size = 2; - let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 2); + let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 2); - let mut sn: ZInt = 0; + let mut sn: u64 = 0; // Add the first element let res = queue.insert(0, sn); assert!(res.is_ok()); @@ -282,9 +278,9 @@ mod tests { #[test] fn reliability_queue_order() { let size = 2; - let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 3); + let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 3); - let sn: ZInt = 0; + let sn: u64 = 0; // Add the second element let res = queue.insert(1, sn + 1); @@ -309,9 +305,9 @@ mod tests { #[test] fn reliability_queue_full() { let size = 2; - let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 3); + let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 3); - let mut sn: ZInt = 0; + let mut sn: u64 = 0; // Fill the queue let res = queue.insert(0, sn); @@ -336,9 +332,9 @@ mod tests { #[test] fn reliability_queue_out_of_sync() { let size = 2; - let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 2); + let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 2); - let sn: ZInt = 3; + let sn: u64 = 3; let res = queue.insert(sn, sn); assert!(res.is_err()); @@ -351,10 +347,10 @@ mod tests { fn reliability_queue_overflow() { // Test the overflow case let size = 4; - let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 4); + let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 4); - let min: ZInt = 0; - let max: ZInt = 3; + let min: u64 = 0; + let max: u64 = 3; let res = queue.set_base(max - 1); assert!(res.is_ok()); @@ -385,22 +381,22 @@ mod tests { fn reliability_queue_mask() { // Test the deterministic insertion of elements and mask let size = 8; - let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 8); + let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 8); - let mut sn: ZInt = 0; - while sn < size as ZInt { + let mut sn: u64 = 0; + while sn < size as u64 { let res = queue.insert(sn, sn); assert!(res.is_ok()); sn = sn + 2; } // Verify that the mask is correct - let mask: ZInt = 0b00101010; + let mask: u64 = 0b00101010; assert_eq!(queue.get_mask(), mask); // Insert the missing elements - let mut sn: ZInt = 1; - while sn < size as ZInt { + let mut sn: u64 = 1; + while sn < size as u64 { let res = queue.insert(sn, sn); assert!(res.is_ok()); sn = sn + 2; @@ -420,16 +416,16 @@ mod tests { fn reliability_queue_random_mask() { // Test the random insertion of elements and the mask let size = 64; - let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 64); + let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 64); - let mut sequence = Vec::::new(); - for i in 0..size as ZInt { + let mut sequence = Vec::::new(); + for i in 0..size as u64 { sequence.push(i); } let head = 0; let mut tail = 0; - let mut mask: ZInt = 0; + let mut mask: u64 = 0; let mut rng = thread_rng(); while sequence.len() > 0 { // Get random sequence number @@ -445,7 +441,7 @@ mod tests { // Locally compute the mask mask = mask | (1 << sn); let shift: u32 = tail.wrapping_sub(head) as u32; - let window = !ZInt::max_value().wrapping_shl(shift); + let window = !u64::max_value().wrapping_shl(shift); // Verify that the mask is correct assert_eq!(queue.get_mask(), !mask & window); } @@ -453,7 +449,7 @@ mod tests { // Verify that we have filled the queue assert!(queue.is_full()); // Verify that no elements are marked for retransmission - assert_eq!(queue.get_mask(), !ZInt::max_value()); + assert_eq!(queue.get_mask(), !u64::max_value()); // Drain the queue while let Some(_) = queue.pull() {} @@ -468,10 +464,10 @@ mod tests { #[test] fn reliability_queue_rebase() { let size = 8; - let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 32); + let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 32); // Fill the queue - for i in 0..size as ZInt { + for i in 0..size as u64 { // Push the element on the queue let res = queue.insert(i, i); assert!(res.is_ok()); @@ -523,7 +519,7 @@ mod tests { assert_eq!(queue.get_base(), 0); // Fill the queue - for i in 0..size as ZInt { + for i in 0..size as u64 { // Push the element on the queue is correct let res = queue.insert(i, i); assert!(res.is_ok()); @@ -533,7 +529,7 @@ mod tests { assert!(queue.is_full()); // Rebase beyond the current boundaries triggering a reset - let base = 2 * size as ZInt; + let base = 2 * size as u64; let res = queue.set_base(base); assert!(res.is_ok()); assert_eq!(queue.get_base(), base); @@ -549,10 +545,10 @@ mod tests { #[test] fn reliability_queue_remove() { let size = 8; - let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 8); + let mut queue: ReliabilityQueue = ReliabilityQueue::new(size, 0, 8); // Fill the queue - for i in 0..size as ZInt { + for i in 0..size as u64 { // Push the element on the queue let res = queue.insert(i, i); assert!(res.is_ok()); @@ -595,7 +591,7 @@ mod tests { assert!(queue.is_empty()); // Check that everything is None - for i in 0..size as ZInt { + for i in 0..size as u64 { // Remove the element from the queue let res = queue.remove(i); assert!(res.is_err()); diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index 8ee3e29537..1321a180d3 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -22,7 +22,7 @@ use zenoh_link::LinkUnicast; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::{ - core::{Priority, Reliability, ZInt}, + core::{Priority, Reliability}, transport::{Close, Fragment, Frame, KeepAlive, TransportBody, TransportMessage}, zenoh::ZenohMessage, }; @@ -183,7 +183,7 @@ impl TransportUnicastInner { Ok(()) } - fn verify_sn(&self, sn: ZInt, guard: &mut MutexGuard<'_, TransportChannelRx>) -> ZResult<()> { + fn verify_sn(&self, sn: u64, guard: &mut MutexGuard<'_, TransportChannelRx>) -> ZResult<()> { let precedes = guard.sn.precedes(sn)?; if !precedes { log::debug!( diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index 6e24ab2225..411bbda3b3 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -23,7 +23,7 @@ use std::time::Duration; use zenoh_core::{zasynclock, zcondfeat, zread, zwrite}; use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ - core::{Bits, Priority, WhatAmI, ZInt, ZenohId}, + core::{Bits, Priority, WhatAmI, ZenohId}, transport::{Close, ConduitSn, TransportMessage}, }; use zenoh_result::{bail, zerror, ZResult}; @@ -125,7 +125,7 @@ impl TransportUnicastInner { /*************************************/ /* INITIATION */ /*************************************/ - pub(super) async fn sync(&self, initial_sn_rx: ZInt) -> ZResult<()> { + pub(super) async fn sync(&self, initial_sn_rx: u64) -> ZResult<()> { // Mark the transport as alive and keep the lock // to avoid concurrent new_transport and closing/closed notifications let mut a_guard = zasynclock!(self.alive); diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index 1e323c04cc..3949cd3289 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use std::sync::RwLock; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{Channel, CongestionControl, WhatAmI, WireExpr, ZInt, ZenohId}, + core::{Channel, CongestionControl, WhatAmI, WireExpr, ZenohId}, zenoh::{ ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo, }, @@ -31,14 +31,14 @@ pub struct FaceState { pub(super) whatami: WhatAmI, pub(super) primitives: Arc, pub(super) link_id: usize, - pub(super) local_mappings: HashMap>, - pub(super) remote_mappings: HashMap>, + pub(super) local_mappings: HashMap>, + pub(super) remote_mappings: HashMap>, pub(super) local_subs: HashSet>, pub(super) remote_subs: HashSet>, pub(super) local_qabls: HashMap, QueryableInfo>, pub(super) remote_qabls: HashSet>, - pub(super) next_qid: ZInt, - pub(super) pending_queries: HashMap>, + pub(super) next_qid: u64, + pub(super) pending_queries: HashMap>, } impl FaceState { @@ -68,14 +68,14 @@ impl FaceState { #[inline] #[allow(clippy::trivially_copy_pass_by_ref)] - pub(super) fn get_mapping(&self, prefixid: &ZInt) -> Option<&std::sync::Arc> { + pub(super) fn get_mapping(&self, prefixid: &u64) -> Option<&std::sync::Arc> { match self.remote_mappings.get(prefixid) { Some(prefix) => Some(prefix), None => self.local_mappings.get(prefixid), } } - pub(super) fn get_next_local_id(&self) -> ZInt { + pub(super) fn get_next_local_id(&self) -> u64 { let mut id = 1; while self.local_mappings.get(&id).is_some() || self.remote_mappings.get(&id).is_some() { id += 1; @@ -165,12 +165,12 @@ pub struct Face { } impl Primitives for Face { - fn decl_resource(&self, expr_id: ZInt, key_expr: &WireExpr) { + fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr) { let mut tables = zwrite!(self.tables); register_expr(&mut tables, &mut self.state.clone(), expr_id, key_expr); } - fn forget_resource(&self, expr_id: ZInt) { + fn forget_resource(&self, expr_id: u64) { let mut tables = zwrite!(self.tables); unregister_expr(&mut tables, &mut self.state.clone(), expr_id); } @@ -357,7 +357,7 @@ impl Primitives for Face { &self, key_expr: &WireExpr, parameters: &str, - qid: ZInt, + qid: u64, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -378,7 +378,7 @@ impl Primitives for Face { fn send_reply_data( &self, - qid: ZInt, + qid: u64, replier_id: ZenohId, key_expr: WireExpr, info: Option, @@ -395,7 +395,7 @@ impl Primitives for Face { ); } - fn send_reply_final(&self, qid: ZInt) { + fn send_reply_final(&self, qid: u64) { route_send_reply_final(&self.tables, &mut self.state.clone(), qid); } @@ -403,8 +403,8 @@ impl Primitives for Face { &self, is_final: bool, key_expr: &WireExpr, - pull_id: ZInt, - max_samples: &Option, + pull_id: u64, + max_samples: &Option, ) { pull_data( &self.tables, diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index 220a0a4f20..48393ef3ad 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -19,7 +19,7 @@ use vec_map::VecMap; use zenoh_config::whatami::WhatAmIMatcher; use zenoh_link::Locator; use zenoh_protocol::{ - core::{WhatAmI, ZInt, ZenohId}, + core::{WhatAmI, ZenohId}, zenoh::{LinkState, ZenohMessage}, }; use zenoh_transport::TransportUnicast; @@ -36,7 +36,7 @@ pub(crate) struct Node { pub(crate) zid: ZenohId, pub(crate) whatami: Option, pub(crate) locators: Option>, - pub(crate) sn: ZInt, + pub(crate) sn: u64, pub(crate) links: Vec, } @@ -50,7 +50,7 @@ pub(crate) struct Link { pub(crate) transport: TransportUnicast, zid: ZenohId, mappings: VecMap, - local_mappings: VecMap, + local_mappings: VecMap, } impl Link { @@ -65,23 +65,23 @@ impl Link { } #[inline] - pub(crate) fn set_zid_mapping(&mut self, psid: ZInt, zid: ZenohId) { + pub(crate) fn set_zid_mapping(&mut self, psid: u64, zid: ZenohId) { self.mappings.insert(psid.try_into().unwrap(), zid); } #[inline] - pub(crate) fn get_zid(&self, psid: &ZInt) -> Option<&ZenohId> { + pub(crate) fn get_zid(&self, psid: &u64) -> Option<&ZenohId> { self.mappings.get((*psid).try_into().unwrap()) } #[inline] - pub(crate) fn set_local_psid_mapping(&mut self, psid: ZInt, local_psid: ZInt) { + pub(crate) fn set_local_psid_mapping(&mut self, psid: u64, local_psid: u64) { self.local_mappings .insert(psid.try_into().unwrap(), local_psid); } #[inline] - pub(crate) fn get_local_psid(&self, psid: &ZInt) -> Option<&ZInt> { + pub(crate) fn get_local_psid(&self, psid: &u64) -> Option<&u64> { self.local_mappings.get((*psid).try_into().unwrap()) } } @@ -185,7 +185,7 @@ impl Network { } #[inline] - pub(crate) fn get_local_context(&self, context: Option, link_id: usize) -> usize { + pub(crate) fn get_local_context(&self, context: Option, link_id: usize) -> usize { let context = context.unwrap_or(0); match self.get_link(link_id) { Some(link) => match link.get_local_psid(&context) { @@ -211,7 +211,7 @@ impl Network { let idx = self.graph.add_node(node); for link in self.links.values_mut() { if let Some((psid, _)) = link.mappings.iter().find(|(_, p)| **p == zid) { - link.local_mappings.insert(psid, idx.index() as ZInt); + link.local_mappings.insert(psid, idx.index() as u64); } } idx diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index 46bffc1555..a803ab5b52 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -26,7 +26,7 @@ use zenoh_core::zread; use zenoh_protocol::{ core::{ key_expr::OwnedKeyExpr, Channel, CongestionControl, Priority, Reliability, WhatAmI, - WireExpr, ZInt, ZenohId, + WireExpr, ZenohId, }, zenoh::{DataInfo, RoutingContext, SubInfo, SubMode}, }; @@ -145,7 +145,7 @@ fn propagate_sourced_subscription( res, src_face, sub_info, - Some(RoutingContext::new(tree_sid.index() as ZInt)), + Some(RoutingContext::new(tree_sid.index() as u64)), ); } else { log::trace!( @@ -483,7 +483,7 @@ fn propagate_forget_sourced_subscription( &net.trees[tree_sid.index()].childs, res, src_face, - Some(RoutingContext::new(tree_sid.index() as ZInt)), + Some(RoutingContext::new(tree_sid.index() as u64)), ); } else { log::trace!( @@ -840,7 +840,7 @@ pub(crate) fn pubsub_tree_change( res, None, &sub_info, - Some(RoutingContext::new(tree_sid as ZInt)), + Some(RoutingContext::new(tree_sid as u64)), ); } } @@ -937,7 +937,7 @@ fn insert_faces_for_subs( face.clone(), key_expr.to_owned(), if source != 0 { - Some(RoutingContext::new(source as ZInt)) + Some(RoutingContext::new(source as u64)) } else { None }, @@ -1450,8 +1450,8 @@ pub fn pull_data( face: &Arc, _is_final: bool, expr: &WireExpr, - _pull_id: ZInt, - _max_samples: &Option, + _pull_id: u64, + _max_samples: &Option, ) { let tables = zread!(tables_ref); match tables.get_mapping(face, &expr.scope) { diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 2d47cc2b9f..56907947b0 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -30,7 +30,7 @@ use zenoh_protocol::{ include::{Includer, DEFAULT_INCLUDER}, OwnedKeyExpr, }, - WhatAmI, WireExpr, ZInt, ZenohId, + WhatAmI, WireExpr, ZenohId, }, zenoh::{ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext}, }; @@ -39,7 +39,7 @@ use zenoh_util::Timed; pub(crate) struct Query { src_face: Arc, - src_qid: ZInt, + src_qid: u64, } #[cfg(feature = "complete_n")] @@ -53,7 +53,7 @@ fn merge_qabl_infos(mut this: QueryableInfo, info: &QueryableInfo) -> QueryableI #[cfg(not(feature = "complete_n"))] #[inline] fn merge_qabl_infos(mut this: QueryableInfo, info: &QueryableInfo) -> QueryableInfo { - this.complete = ZInt::from(this.complete != 0 || info.complete != 0); + this.complete = u64::from(this.complete != 0 || info.complete != 0); this.distance = std::cmp::min(this.distance, info.distance); this } @@ -290,7 +290,7 @@ fn propagate_sourced_queryable( res, qabl_info, src_face, - Some(RoutingContext::new(tree_sid.index() as ZInt)), + Some(RoutingContext::new(tree_sid.index() as u64)), ); } else { log::trace!( @@ -630,7 +630,7 @@ fn propagate_forget_sourced_queryable( &net.trees[tree_sid.index()].childs, res, src_face, - Some(RoutingContext::new(tree_sid.index() as ZInt)), + Some(RoutingContext::new(tree_sid.index() as u64)), ); } else { log::trace!( @@ -1051,7 +1051,7 @@ pub(crate) fn queries_tree_change( res, qabl_info, None, - Some(RoutingContext::new(tree_sid as ZInt)), + Some(RoutingContext::new(tree_sid as u64)), ); } } @@ -1089,7 +1089,7 @@ fn insert_target_for_qabls( face.clone(), key_expr.to_owned(), if source != 0 { - Some(RoutingContext::new(source as ZInt)) + Some(RoutingContext::new(source as u64)) } else { None }, @@ -1316,7 +1316,7 @@ pub(crate) fn compute_matches_query_routes(tables: &mut Tables, res: &mut Arc, query: Arc) -> ZInt { +fn insert_pending_query(outface: &mut Arc, query: Arc) -> u64 { let outface_mut = get_mut_unchecked(outface); outface_mut.next_qid += 1; let qid = outface_mut.next_qid; @@ -1485,7 +1485,7 @@ fn compute_final_route( struct QueryCleanup { tables: Arc>, face: Weak, - qid: ZInt, + qid: u64, } #[async_trait] @@ -1591,7 +1591,7 @@ pub fn route_query( face: &Arc, expr: &WireExpr, parameters: &str, - qid: ZInt, + qid: u64, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -1705,7 +1705,7 @@ pub fn route_query( pub(crate) fn route_send_reply_data( tables_ref: &RwLock, face: &mut Arc, - qid: ZInt, + qid: u64, replier_id: ZenohId, key_expr: WireExpr, info: Option, @@ -1735,7 +1735,7 @@ pub(crate) fn route_send_reply_data( pub(crate) fn route_send_reply_final( tables_ref: &RwLock, face: &mut Arc, - qid: ZInt, + qid: u64, ) { let tables_lock = zwrite!(tables_ref); match get_mut_unchecked(face).pending_queries.remove(&qid) { diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index 55d1b8b416..b98f30bd84 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -19,7 +19,7 @@ use std::hash::{Hash, Hasher}; use std::sync::{Arc, Weak}; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{key_expr::keyexpr, WireExpr, ZInt, ZenohId}, + core::{key_expr::keyexpr, WireExpr, ZenohId}, zenoh::{DataInfo, QueryableInfo, RoutingContext, SubInfo}, }; use zenoh_sync::get_mut_unchecked; @@ -27,12 +27,12 @@ use zenoh_sync::get_mut_unchecked; pub(super) type Direction = (Arc, WireExpr<'static>, Option); pub(super) type Route = HashMap; #[cfg(feature = "complete_n")] -pub(super) type QueryRoute = HashMap; +pub(super) type QueryRoute = HashMap; #[cfg(not(feature = "complete_n"))] -pub(super) type QueryRoute = HashMap; +pub(super) type QueryRoute = HashMap; pub(super) struct QueryTargetQabl { pub(super) direction: Direction, - pub(super) complete: ZInt, + pub(super) complete: u64, pub(super) distance: f64, } pub(super) type QueryTargetQablSet = Vec; @@ -40,8 +40,8 @@ pub(super) type PullCaches = Vec>; pub(super) struct SessionContext { pub(super) face: Arc, - pub(super) local_expr_id: Option, - pub(super) remote_expr_id: Option, + pub(super) local_expr_id: Option, + pub(super) remote_expr_id: Option, pub(super) subs: Option, pub(super) qabl: Option, pub(super) last_values: HashMap, ZBuf)>, @@ -583,7 +583,7 @@ impl Resource { pub fn register_expr( tables: &mut Tables, face: &mut Arc, - expr_id: ZInt, + expr_id: u64, expr: &WireExpr, ) { match tables.get_mapping(face, &expr.scope).cloned() { @@ -633,7 +633,7 @@ pub fn register_expr( } } -pub fn unregister_expr(_tables: &mut Tables, face: &mut Arc, expr_id: ZInt) { +pub fn unregister_expr(_tables: &mut Tables, face: &mut Arc, expr_id: u64) { match get_mut_unchecked(face).remote_mappings.remove(&expr_id) { Some(mut res) => Resource::clean(&mut res), None => log::error!("Undeclare unknown resource!"), diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index f15a09f193..ecca9fe192 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -29,7 +29,7 @@ use uhlc::HLC; use zenoh_config::whatami::WhatAmIMatcher; use zenoh_link::Link; use zenoh_protocol::{ - core::{WhatAmI, ZInt, ZenohId}, + core::{WhatAmI, ZenohId}, zenoh::{ZenohBody, ZenohMessage}, }; use zenoh_transport::{DeMux, Mux, Primitives, TransportPeerEventHandler, TransportUnicast}; @@ -138,7 +138,7 @@ impl Tables { pub(crate) fn get_mapping<'a>( &'a self, face: &'a FaceState, - expr_id: &ZInt, + expr_id: &u64, ) -> Option<&'a Arc> { match expr_id { 0 => Some(&self.root_res), diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 400c5f6515..3770a5d991 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -28,7 +28,7 @@ use zenoh_config::WhatAmI; use zenoh_protocol::{ core::{ key_expr::OwnedKeyExpr, Channel, CongestionControl, Encoding, KnownEncoding, WireExpr, - ZInt, ZenohId, EMPTY_EXPR_ID, + ZenohId, EMPTY_EXPR_ID, }, zenoh::{ ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, @@ -54,7 +54,7 @@ type Handler = Box< pub struct AdminSpace { zid: ZenohId, primitives: Mutex>>, - mappings: Mutex>, + mappings: Mutex>, handlers: HashMap>, context: Arc, } @@ -243,7 +243,7 @@ impl AdminSpace { } impl Primitives for AdminSpace { - fn decl_resource(&self, expr_id: ZInt, key_expr: &WireExpr) { + fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr) { trace!("recv Resource {} {:?}", expr_id, key_expr); match self.key_expr_to_string(key_expr) { Ok(s) => { @@ -253,7 +253,7 @@ impl Primitives for AdminSpace { } } - fn forget_resource(&self, _expr_id: ZInt) { + fn forget_resource(&self, _expr_id: u64) { trace!("recv Forget Resource {}", _expr_id); } @@ -366,7 +366,7 @@ impl Primitives for AdminSpace { &self, key_expr: &WireExpr, parameters: &str, - qid: ZInt, + qid: u64, target: QueryTarget, _consolidation: ConsolidationMode, _body: Option, @@ -473,7 +473,7 @@ impl Primitives for AdminSpace { fn send_reply_data( &self, - qid: ZInt, + qid: u64, replier_id: ZenohId, key_expr: WireExpr, info: Option, @@ -489,7 +489,7 @@ impl Primitives for AdminSpace { ); } - fn send_reply_final(&self, qid: ZInt) { + fn send_reply_final(&self, qid: u64) { trace!("recv ReplyFinal {:?}", qid); } @@ -497,8 +497,8 @@ impl Primitives for AdminSpace { &self, _is_final: bool, _key_expr: &WireExpr, - _pull_id: ZInt, - _max_samples: &Option, + _pull_id: u64, + _max_samples: &Option, ) { trace!( "recv Pull {:?} {:?} {:?} {:?}", diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index 3d4d9806ff..941868caf9 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -20,8 +20,8 @@ use zenoh_buffers::ZBuf; use zenoh_core::zlock; use zenoh_protocol::{ core::{ - key_expr::keyexpr, Channel, CongestionControl, Reliability, WhatAmI, WireExpr, ZInt, - ZenohId, EMPTY_EXPR_ID, + key_expr::keyexpr, Channel, CongestionControl, Reliability, WhatAmI, WireExpr, ZenohId, + EMPTY_EXPR_ID, }, zenoh::{ ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, @@ -366,7 +366,7 @@ fn clean_test() { pub struct ClientPrimitives { data: std::sync::Mutex>>, - mapping: std::sync::Mutex>, + mapping: std::sync::Mutex>, } impl ClientPrimitives { @@ -416,12 +416,12 @@ impl ClientPrimitives { } impl Primitives for ClientPrimitives { - fn decl_resource(&self, expr_id: ZInt, key_expr: &WireExpr) { + fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr) { let name = self.get_name(key_expr); zlock!(self.mapping).insert(expr_id, name); } - fn forget_resource(&self, expr_id: ZInt) { + fn forget_resource(&self, expr_id: u64) { zlock!(self.mapping).remove(&expr_id); } @@ -462,7 +462,7 @@ impl Primitives for ClientPrimitives { &self, _key_expr: &WireExpr, _parameters: &str, - _qid: ZInt, + _qid: u64, _target: QueryTarget, _consolidation: ConsolidationMode, _body: Option, @@ -472,21 +472,21 @@ impl Primitives for ClientPrimitives { fn send_reply_data( &self, - _qid: ZInt, + _qid: u64, _replier_id: ZenohId, _key_expr: WireExpr, _info: Option, _payload: ZBuf, ) { } - fn send_reply_final(&self, _qid: ZInt) {} + fn send_reply_final(&self, _qid: u64) {} fn send_pull( &self, _is_final: bool, _key_expr: &WireExpr, - _pull_id: ZInt, - _max_samples: &Option, + _pull_id: u64, + _max_samples: &Option, ) { } diff --git a/zenoh/src/prelude.rs b/zenoh/src/prelude.rs index dc6decff43..5f95b2e995 100644 --- a/zenoh/src/prelude.rs +++ b/zenoh/src/prelude.rs @@ -54,7 +54,6 @@ pub(crate) mod common { /// A [`Locator`] contains a choice of protocol, an address and port, as well as optional additional properties to work with. pub use zenoh_protocol::core::Locator; - pub use zenoh_protocol::core::ZInt; /// The global unique id of a zenoh peer. pub use zenoh_protocol::core::ZenohId; } diff --git a/zenoh/src/sample.rs b/zenoh/src/sample.rs index 08509c41da..82d02a0c36 100644 --- a/zenoh/src/sample.rs +++ b/zenoh/src/sample.rs @@ -21,8 +21,6 @@ use crate::time::{new_reception_timestamp, Timestamp}; #[zenoh_core::unstable] use serde::Serialize; use std::convert::TryInto; -#[zenoh_core::unstable] -use zenoh_protocol::core::ZInt; use zenoh_protocol::zenoh::DataInfo; /// The locality of samples to be received by subscribers or targeted by publishers. @@ -49,7 +47,7 @@ pub struct SourceInfo { /// The [`ZenohId`] of the zenoh instance that published the concerned [`Sample`]. pub source_id: Option, /// The sequence number of the [`Sample`] from the source. - pub source_sn: Option, + pub source_sn: Option, } #[test] diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 0c0502438f..6a71370b1f 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -54,14 +54,14 @@ use zenoh_core::{zconfigurable, zread, Resolve, ResolveClosure, ResolveFuture, S use zenoh_protocol::{ core::{ key_expr::{keyexpr, OwnedKeyExpr}, - Channel, CongestionControl, ExprId, WireExpr, ZInt, ZenohId, EMPTY_EXPR_ID, + Channel, CongestionControl, ExprId, WireExpr, ZenohId, EMPTY_EXPR_ID, }, zenoh::{DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo}, }; use zenoh_result::ZResult; use zenoh_util::core::AsyncResolve; -pub type AtomicZInt = AtomicU64; +pub type Atomicu64 = AtomicU64; zconfigurable! { pub(crate) static ref API_DATA_RECEPTION_CHANNEL_SIZE: usize = 256; @@ -74,14 +74,14 @@ zconfigurable! { pub(crate) struct SessionState { pub(crate) primitives: Option>, // @TODO replace with MaybeUninit ?? pub(crate) expr_id_counter: AtomicUsize, // @TODO: manage rollover and uniqueness - pub(crate) qid_counter: AtomicZInt, + pub(crate) qid_counter: Atomicu64, pub(crate) decl_id_counter: AtomicUsize, pub(crate) local_resources: HashMap, pub(crate) remote_resources: HashMap, pub(crate) publications: Vec, pub(crate) subscribers: HashMap>, pub(crate) queryables: HashMap>, - pub(crate) queries: HashMap, + pub(crate) queries: HashMap, pub(crate) aggregated_subscribers: Vec, pub(crate) aggregated_publishers: Vec, } @@ -94,7 +94,7 @@ impl SessionState { SessionState { primitives: None, expr_id_counter: AtomicUsize::new(1), // Note: start at 1 because 0 is reserved for NO_RESOURCE - qid_counter: AtomicZInt::new(0), + qid_counter: Atomicu64::new(0), decl_id_counter: AtomicUsize::new(0), local_resources: HashMap::new(), remote_resources: HashMap::new(), @@ -820,7 +820,7 @@ impl Session { { Some((expr_id, _res)) => *expr_id, None => { - let expr_id = state.expr_id_counter.fetch_add(1, Ordering::SeqCst) as ZInt; + let expr_id = state.expr_id_counter.fetch_add(1, Ordering::SeqCst) as u64; let mut res = Resource::new(Box::from(prefix)); if let Resource::Node(ResourceNode { key_expr, @@ -1124,7 +1124,7 @@ impl Session { if origin != Locality::SessionLocal && (!twin_qabl || (!complete_twin_qabl && complete)) { let primitives = state.primitives.as_ref().unwrap().clone(); - let complete = ZInt::from(!complete_twin_qabl && complete); + let complete = u64::from(!complete_twin_qabl && complete); drop(state); let qabl_info = QueryableInfo { complete, @@ -1155,7 +1155,7 @@ impl Session { } #[cfg(feature = "complete_n")] - pub(crate) fn complete_twin_qabls(state: &SessionState, key: &WireExpr) -> ZInt { + pub(crate) fn complete_twin_qabls(state: &SessionState, key: &WireExpr) -> u64 { state .queryables .values() @@ -1165,7 +1165,7 @@ impl Session { && state.local_wireexpr_to_expr(&q.key_expr).unwrap() == state.local_wireexpr_to_expr(key).unwrap() }) - .count() as ZInt + .count() as u64 } pub(crate) fn close_queryable(&self, qid: usize) -> ZResult<()> { let mut state = zwrite!(self.state); @@ -1400,7 +1400,7 @@ impl Session { local: bool, key_expr: &WireExpr, parameters: &str, - qid: ZInt, + qid: u64, _target: QueryTarget, _consolidation: ConsolidationMode, body: Option, @@ -1623,7 +1623,7 @@ impl SessionDeclarations for Arc { } impl Primitives for Session { - fn decl_resource(&self, expr_id: ZInt, wire_expr: &WireExpr) { + fn decl_resource(&self, expr_id: u64, wire_expr: &WireExpr) { trace!("recv Decl Resource {} {:?}", expr_id, wire_expr); let state = &mut zwrite!(self.state); match state.remote_key_to_expr(wire_expr) { @@ -1648,7 +1648,7 @@ impl Primitives for Session { } } - fn forget_resource(&self, _expr_id: ZInt) { + fn forget_resource(&self, _expr_id: u64) { trace!("recv Forget Resource {}", _expr_id); } @@ -1710,7 +1710,7 @@ impl Primitives for Session { &self, key_expr: &WireExpr, parameters: &str, - qid: ZInt, + qid: u64, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -1736,7 +1736,7 @@ impl Primitives for Session { fn send_reply_data( &self, - qid: ZInt, + qid: u64, replier_id: ZenohId, key_expr: WireExpr, data_info: Option, @@ -1849,7 +1849,7 @@ impl Primitives for Session { } } - fn send_reply_final(&self, qid: ZInt) { + fn send_reply_final(&self, qid: u64) { trace!("recv ReplyFinal {:?}", qid); let mut state = zwrite!(self.state); match state.queries.get_mut(&qid) { @@ -1876,8 +1876,8 @@ impl Primitives for Session { &self, _is_final: bool, _key_expr: &WireExpr, - _pull_id: ZInt, - _max_samples: &Option, + _pull_id: u64, + _max_samples: &Option, ) { trace!( "recv Pull {:?} {:?} {:?} {:?}", From a148fcb04c4ecb11f31fbd14e5c310badcbffc81 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 14 Mar 2023 19:51:50 +0100 Subject: [PATCH 088/203] Additional Z* impls --- commons/zenoh-codec/src/common/extension.rs | 2 +- commons/zenoh-codec/src/core/mod.rs | 51 ++------- commons/zenoh-codec/src/core/zint.rs | 115 ++++++++++++++++++++ commons/zenoh-codec/src/transport/init.rs | 5 +- commons/zenoh-codec/src/zenoh/linkstate.rs | 2 +- 5 files changed, 128 insertions(+), 47 deletions(-) diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index bdebdc8e4c..329e4146bf 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -183,7 +183,7 @@ where ZExtensionBody::Z64(u64) => { header |= iext::ENC_Z64; self.write(&mut *writer, header)?; - self.write(&mut *writer, u64)? + self.write(&mut *writer, *u64)? } ZExtensionBody::ZBuf(zbuf) => { header |= iext::ENC_ZBUF; diff --git a/commons/zenoh-codec/src/core/mod.rs b/commons/zenoh-codec/src/core/mod.rs index 884524e5c6..83e2657c24 100644 --- a/commons/zenoh-codec/src/core/mod.rs +++ b/commons/zenoh-codec/src/core/mod.rs @@ -31,74 +31,39 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; -// u8 -impl WCodec for Zenoh080 +// [u8; 2] +impl WCodec<[u8; 2], &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: u8) -> Self::Output { - writer.write_u8(x) - } -} - -impl WCodec<&u8, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &u8) -> Self::Output { - self.write(writer, *x) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - reader.read_u8() - } -} - -// u16 -impl WCodec for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: u16) -> Self::Output { - let x = x.to_le_bytes(); + fn write(self, writer: &mut W, x: [u8; 2]) -> Self::Output { writer.write_exact(x.as_slice()) } } -impl WCodec<&u16, &mut W> for Zenoh080 +impl WCodec<&[u8; 2], &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &u16) -> Self::Output { + fn write(self, writer: &mut W, x: &[u8; 2]) -> Self::Output { self.write(writer, *x) } } -impl RCodec for Zenoh080 +impl RCodec<[u8; 2], &mut R> for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result<[u8; 2], Self::Error> { let mut x = [0u8; 2]; reader.read_exact(&mut x)?; - Ok(u16::from_le_bytes(x)) + Ok(x) } } diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 8591008486..4d80a26593 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -20,6 +20,110 @@ use zenoh_buffers::{ const VLE_LEN: usize = 10; +// u8 +impl WCodec for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: u8) -> Self::Output { + writer.write_u8(x) + } +} + +impl WCodec<&u8, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &u8) -> Self::Output { + self.write(writer, *x) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + reader.read_u8() + } +} + +// u16 +impl WCodec for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: u16) -> Self::Output { + self.write(writer, x as u64) + } +} + +impl WCodec<&u16, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &u16) -> Self::Output { + self.write(writer, *x) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let x: u64 = self.read(reader)?; + x.try_into().map_err(|_| DidntRead) + } +} + +// u32 +impl WCodec for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: u32) -> Self::Output { + self.write(writer, x as u64) + } +} + +impl WCodec<&u32, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &u32) -> Self::Output { + self.write(writer, *x) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let x: u64 = self.read(reader)?; + x.try_into().map_err(|_| DidntRead) + } +} + // u64 impl WCodec for Zenoh080 where @@ -94,6 +198,17 @@ where } } +impl WCodec<&usize, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &usize) -> Self::Output { + self.write(writer, *x) + } +} + impl RCodec for Zenoh080 where R: Reader, diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index 42e0594f70..14a1f5fa7a 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -64,7 +64,7 @@ where if imsg::has_flag(header, flag::S) { self.write(&mut *writer, x.resolution.as_u8())?; - self.write(&mut *writer, x.batch_size)?; + self.write(&mut *writer, x.batch_size.to_le_bytes())?; } // Extensions @@ -128,12 +128,13 @@ where let zid: ZenohId = lodec.read(&mut *reader)?; let mut resolution = Resolution::default(); - let mut batch_size = u16::MAX; + let mut batch_size = u16::MAX.to_le_bytes(); if imsg::has_flag(self.header, flag::S) { let flags: u8 = self.codec.read(&mut *reader)?; resolution = Resolution::from(flags & 0b00111111); batch_size = self.codec.read(&mut *reader)?; } + let batch_size = u16::from_le_bytes(batch_size); // Extensions let mut ext_qos = None; diff --git a/commons/zenoh-codec/src/zenoh/linkstate.rs b/commons/zenoh-codec/src/zenoh/linkstate.rs index 12a75d18da..21bb05eb88 100644 --- a/commons/zenoh-codec/src/zenoh/linkstate.rs +++ b/commons/zenoh-codec/src/zenoh/linkstate.rs @@ -46,7 +46,7 @@ where self.write(&mut *writer, options)?; // Body - self.write(&mut *writer, &x.psid)?; + self.write(&mut *writer, x.psid)?; self.write(&mut *writer, x.sn)?; if let Some(zid) = x.zid.as_ref() { self.write(&mut *writer, zid)?; From d44c208f6b714157ddbd79884372f1ea2c4cb9cd Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 14 Mar 2023 20:09:09 +0100 Subject: [PATCH 089/203] Define uSN --- commons/zenoh-codec/benches/codec.rs | 8 +- commons/zenoh-codec/src/common/extension.rs | 16 ++-- commons/zenoh-codec/src/core/mod.rs | 81 ++++++++++++------- commons/zenoh-codec/src/core/zint.rs | 6 +- commons/zenoh-codec/src/transport/fragment.rs | 4 +- commons/zenoh-codec/src/transport/frame.rs | 10 +-- commons/zenoh-codec/src/transport/open.rs | 5 +- commons/zenoh-codec/tests/codec.rs | 2 +- .../zenoh-protocol/src/common/extension.rs | 14 ++-- .../zenoh-protocol/src/transport/fragment.rs | 9 ++- commons/zenoh-protocol/src/transport/frame.rs | 10 +-- commons/zenoh-protocol/src/transport/mod.rs | 7 +- commons/zenoh-protocol/src/transport/open.rs | 21 ++--- io/zenoh-transport/src/common/batch.rs | 6 +- io/zenoh-transport/src/common/conduit.rs | 6 +- .../src/common/defragmentation.rs | 5 +- io/zenoh-transport/src/common/seq_num.rs | 44 +++++----- .../src/unicast/establishment/accept.rs | 4 +- .../unicast/establishment/ext/auth/usrpwd.rs | 10 +-- .../src/unicast/establishment/mod.rs | 8 +- .../src/unicast/establishment/open.rs | 8 +- io/zenoh-transport/src/unicast/mod.rs | 4 +- io/zenoh-transport/src/unicast/rx.rs | 4 +- io/zenoh-transport/src/unicast/transport.rs | 4 +- 24 files changed, 163 insertions(+), 133 deletions(-) diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 2adc8f3f0a..6966c10e5c 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -24,7 +24,7 @@ use zenoh_codec::*; use zenoh_protocol::{ core::{CongestionControl, Reliability}, defaults::BATCH_SIZE, - transport::{Frame, FrameHeader}, + transport::{uSN, Frame, FrameHeader}, zenoh::Data, }; @@ -74,7 +74,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), - sn: u64::MIN, + sn: uSN::MIN, ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; @@ -111,7 +111,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), - sn: u64::MIN, + sn: uSN::MIN, ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; @@ -143,7 +143,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), - sn: u64::MIN, + sn: uSN::MIN, ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 329e4146bf..7b7121a6a6 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ ZBuf, }; use zenoh_protocol::common::{ - iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZBuf, ZExtensionBody, ZExtu64, + iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZ64, ZExtZBuf, ZExtensionBody, }; impl WCodec<(&ZExtUnit<{ ID }>, bool), &mut W> for Zenoh080 @@ -67,13 +67,13 @@ where } } -impl WCodec<(&ZExtu64<{ ID }>, bool), &mut W> for Zenoh080 +impl WCodec<(&ZExtZ64<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: (&ZExtu64<{ ID }>, bool)) -> Self::Output { + fn write(self, writer: &mut W, x: (&ZExtZ64<{ ID }>, bool)) -> Self::Output { let (x, more) = x; let mut header: u8 = ID | iext::ENC_Z64; if more { @@ -85,33 +85,33 @@ where } } -impl RCodec<(ZExtu64<{ ID }>, bool), &mut R> for Zenoh080 +impl RCodec<(ZExtZ64<{ ID }>, bool), &mut R> for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ZExtu64<{ ID }>, bool), Self::Error> { + fn read(self, reader: &mut R) -> Result<(ZExtZ64<{ ID }>, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); codec.read(&mut *reader) } } -impl RCodec<(ZExtu64<{ ID }>, bool), &mut R> for Zenoh080Header +impl RCodec<(ZExtZ64<{ ID }>, bool), &mut R> for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ZExtu64<{ ID }>, bool), Self::Error> { + fn read(self, reader: &mut R) -> Result<(ZExtZ64<{ ID }>, bool), Self::Error> { if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_Z64) { return Err(DidntRead); } let value: u64 = self.codec.read(&mut *reader)?; - Ok((ZExtu64::new(value), has_flag(self.header, iext::FLAG_Z))) + Ok((ZExtZ64::new(value), has_flag(self.header, iext::FLAG_Z))) } } diff --git a/commons/zenoh-codec/src/core/mod.rs b/commons/zenoh-codec/src/core/mod.rs index 83e2657c24..56742815ee 100644 --- a/commons/zenoh-codec/src/core/mod.rs +++ b/commons/zenoh-codec/src/core/mod.rs @@ -31,41 +31,62 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; -// [u8; 2] -impl WCodec<[u8; 2], &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; +// [u8; N] +macro_rules! array_impl { + ($n:expr) => { + impl WCodec<[u8; $n], &mut W> for Zenoh080 + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: [u8; $n]) -> Self::Output { + writer.write_exact(x.as_slice()) + } + } - fn write(self, writer: &mut W, x: [u8; 2]) -> Self::Output { - writer.write_exact(x.as_slice()) - } -} + impl WCodec<&[u8; $n], &mut W> for Zenoh080 + where + W: Writer, + { + type Output = Result<(), DidntWrite>; -impl WCodec<&[u8; 2], &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; + fn write(self, writer: &mut W, x: &[u8; $n]) -> Self::Output { + self.write(writer, *x) + } + } - fn write(self, writer: &mut W, x: &[u8; 2]) -> Self::Output { - self.write(writer, *x) - } + impl RCodec<[u8; $n], &mut R> for Zenoh080 + where + R: Reader, + { + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<[u8; $n], Self::Error> { + let mut x = [0u8; $n]; + reader.read_exact(&mut x)?; + Ok(x) + } + } + }; } -impl RCodec<[u8; 2], &mut R> for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<[u8; 2], Self::Error> { - let mut x = [0u8; 2]; - reader.read_exact(&mut x)?; - Ok(x) - } -} +array_impl!(1); +array_impl!(2); +array_impl!(3); +array_impl!(4); +array_impl!(5); +array_impl!(6); +array_impl!(7); +array_impl!(8); +array_impl!(9); +array_impl!(10); +array_impl!(11); +array_impl!(12); +array_impl!(13); +array_impl!(14); +array_impl!(15); +array_impl!(16); // &[u8] / Vec impl WCodec<&[u8], &mut W> for Zenoh080 diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 4d80a26593..98a8d65a14 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -85,7 +85,7 @@ where fn read(self, reader: &mut R) -> Result { let x: u64 = self.read(reader)?; - x.try_into().map_err(|_| DidntRead) + Ok(x as u16) } } @@ -120,7 +120,7 @@ where fn read(self, reader: &mut R) -> Result { let x: u64 = self.read(reader)?; - x.try_into().map_err(|_| DidntRead) + Ok(x as u32) } } @@ -217,7 +217,7 @@ where fn read(self, reader: &mut R) -> Result { let x: u64 = self.read(reader)?; - x.try_into().map_err(|_| DidntRead) + Ok(x as usize) } } diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index 38dfd7da92..d391922dfd 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -20,7 +20,7 @@ use zenoh_protocol::{ common::{imsg, ZExtUnknown}, core::Reliability, transport::{ - fragment::{ext, flag, Fragment, FragmentHeader}, + fragment::{ext, flag, uSN, Fragment, FragmentHeader}, id, }, }; @@ -87,7 +87,7 @@ where false => Reliability::BestEffort, }; let more = imsg::has_flag(self.header, flag::M); - let sn: u64 = self.codec.read(&mut *reader)?; + let sn: uSN = self.codec.read(&mut *reader)?; // Extensions let mut qos = ext::QoS::default(); diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 0e18250200..2b0cbb8509 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -20,11 +20,11 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown, ZExtu64}, + common::{imsg, ZExtUnknown, ZExtZ64}, core::{Priority, Reliability}, transport::{ frame::{ext, flag, Frame, FrameHeader}, - id, + id, uSN, }, zenoh::ZenohMessage, }; @@ -38,7 +38,7 @@ where fn write(self, writer: &mut W, x: (ext::QoS, bool)) -> Self::Output { let (qos, more) = x; - let ext: ZExtu64<{ ext::QOS }> = ZExtu64::new(qos.priority as u64); + let ext: ZExtZ64<{ ext::QOS }> = ZExtZ64::new(qos.priority as u64); self.write(&mut *writer, (&ext, more)) } } @@ -68,7 +68,7 @@ where return Err(DidntRead); } - let (ext, more): (ZExtu64<{ ext::QOS }>, bool) = self.read(&mut *reader)?; + let (ext, more): (ZExtZ64<{ ext::QOS }>, bool) = self.read(&mut *reader)?; let v: u8 = ext.value.try_into().map_err(|_| DidntRead)?; let priority: Priority = v.try_into().map_err(|_| DidntRead)?; @@ -134,7 +134,7 @@ where true => Reliability::Reliable, false => Reliability::BestEffort, }; - let sn: u64 = self.codec.read(&mut *reader)?; + let sn: uSN = self.codec.read(&mut *reader)?; // Extensions let mut qos = ext::QoS::default(); diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index fe16e57c65..8af86b1add 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -23,6 +23,7 @@ use zenoh_protocol::{ transport::{ id, open::{ext, flag, OpenAck, OpenSyn}, + uSN, }, }; @@ -110,7 +111,7 @@ where } else { Duration::from_millis(lease) }; - let initial_sn: u64 = self.codec.read(&mut *reader)?; + let initial_sn: uSN = self.codec.read(&mut *reader)?; let cookie: ZSlice = self.codec.read(&mut *reader)?; // Extensions @@ -248,7 +249,7 @@ where } else { Duration::from_millis(lease) }; - let initial_sn: u64 = self.codec.read(&mut *reader)?; + let initial_sn: uSN = self.codec.read(&mut *reader)?; // Extensions let mut ext_qos = None; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index ed97bffebd..16930aabdf 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -244,7 +244,7 @@ fn codec_extension() { } run_extension!(ZExtUnit<0>); - run_extension!(ZExtu64<1>); + run_extension!(ZExtZ64<1>); run_extension!(ZExtZBuf<2>); run_extension!(ZExtZBuf<3>); run_extension!(ZExtUnknown); diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index b7e9e4ab59..22f861e089 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -99,19 +99,19 @@ impl TryFrom for ZExtUnit<{ ID }> { } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct ZExtu64 { +pub struct ZExtZ64 { pub value: u64, } -impl ZExtu64<{ ID }> { +impl ZExtZ64<{ ID }> { pub const ID: u8 = ID; pub const fn new(value: u64) -> Self { Self { value } } - pub const fn transmute(self) -> ZExtu64<{ DI }> { - ZExtu64::new(self.value) + pub const fn transmute(self) -> ZExtZ64<{ DI }> { + ZExtZ64::new(self.value) } #[cfg(feature = "test")] @@ -124,7 +124,7 @@ impl ZExtu64<{ ID }> { } } -impl TryFrom for ZExtu64<{ ID }> { +impl TryFrom for ZExtZ64<{ ID }> { type Error = DidntConvert; fn try_from(v: ZExtUnknown) -> Result { @@ -219,8 +219,8 @@ impl From> for ZExtUnknown { } } -impl From> for ZExtUnknown { - fn from(e: ZExtu64<{ ID }>) -> Self { +impl From> for ZExtUnknown { + fn from(e: ZExtZ64<{ ID }>) -> Self { ZExtUnknown { id: ID, body: ZExtensionBody::Z64(e.value), diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs index a95aee95e2..bcc20faf12 100644 --- a/commons/zenoh-protocol/src/transport/fragment.rs +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::core::Reliability; +pub use crate::transport::uSN; use zenoh_buffers::ZSlice; /// # Fragment message @@ -70,7 +71,7 @@ pub mod flag { pub struct Fragment { pub reliability: Reliability, pub more: bool, - pub sn: u64, + pub sn: uSN, pub qos: ext::QoS, pub payload: ZSlice, } @@ -95,7 +96,7 @@ impl Fragment { Reliability::BestEffort }; let more = rng.gen_bool(0.5); - let sn: u64 = rng.gen(); + let sn: uSN = rng.gen(); let qos = ext::QoS::rand(); let payload = ZSlice::rand(rng.gen_range(8..128)); @@ -114,7 +115,7 @@ impl Fragment { pub struct FragmentHeader { pub reliability: Reliability, pub more: bool, - pub sn: u64, + pub sn: uSN, pub qos: ext::QoS, } @@ -131,7 +132,7 @@ impl FragmentHeader { Reliability::BestEffort }; let more = rng.gen_bool(0.5); - let sn: u64 = rng.gen(); + let sn: uSN = rng.gen(); let qos = ext::QoS::rand(); FragmentHeader { diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 04f79538c1..686dede1bb 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::Reliability, zenoh::ZenohMessage}; +use crate::{core::Reliability, transport::uSN, zenoh::ZenohMessage}; use alloc::vec::Vec; /// # Frame message @@ -69,7 +69,7 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Frame { pub reliability: Reliability, - pub sn: u64, + pub sn: uSN, pub ext_qos: ext::QoS, pub payload: Vec, } @@ -120,7 +120,7 @@ impl Frame { } else { Reliability::BestEffort }; - let sn: u64 = rng.gen(); + let sn: uSN = rng.gen(); let qos = ext::QoS::rand(); let mut payload = vec![]; for _ in 0..rng.gen_range(1..4) { @@ -143,7 +143,7 @@ impl Frame { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct FrameHeader { pub reliability: Reliability, - pub sn: u64, + pub sn: uSN, pub ext_qos: ext::QoS, } @@ -159,7 +159,7 @@ impl FrameHeader { } else { Reliability::BestEffort }; - let sn: u64 = rng.gen(); + let sn: uSN = rng.gen(); let qos = ext::QoS::rand(); FrameHeader { diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index fd0e5f2b79..f46ad4ec86 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -40,6 +40,9 @@ pub mod id { pub const FRAGMENT: u8 = 0x07; } +#[allow(non_camel_case_types)] +pub type uSN = u32; + #[derive(Debug, Clone, PartialEq, Eq)] pub enum ConduitSnList { Plain(ConduitSn), @@ -80,8 +83,8 @@ impl fmt::Display for ConduitSnList { /// The kind of reliability. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct ConduitSn { - pub reliable: u64, - pub best_effort: u64, + pub reliable: uSN, + pub best_effort: uSN, } // Zenoh messages at zenoh-transport level diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index b4586bf56f..9370583342 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // +use crate::transport::uSN; use core::time::Duration; use zenoh_buffers::ZSlice; @@ -74,7 +75,7 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpenSyn { pub lease: Duration, - pub initial_sn: u64, + pub initial_sn: uSN, pub cookie: ZSlice, pub ext_qos: Option, pub ext_shm: Option, @@ -84,7 +85,7 @@ pub struct OpenSyn { // Extensions pub mod ext { - use crate::common::{ZExtUnit, ZExtZBuf, ZExtu64}; + use crate::common::{ZExtUnit, ZExtZ64, ZExtZBuf}; pub const QOS: u8 = 0x01; pub const SHM: u8 = 0x02; @@ -97,7 +98,7 @@ pub mod ext { /// # Shm extension /// Used as challenge for probing shared memory capabilities - pub type Shm = ZExtu64; + pub type Shm = ZExtZ64; /// # Auth extension /// Used as challenge for probing authentication rights @@ -112,7 +113,7 @@ pub mod ext { impl OpenSyn { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::{ZExtUnit, ZExtZBuf, ZExtu64}; + use crate::common::{ZExtUnit, ZExtZ64, ZExtZBuf}; use rand::Rng; const MIN: usize = 32; @@ -126,10 +127,10 @@ impl OpenSyn { Duration::from_millis(rng.gen()) }; - let initial_sn: u64 = rng.gen(); + let initial_sn: uSN = rng.gen(); let cookie = ZSlice::rand(rng.gen_range(MIN..=MAX)); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - let ext_shm = rng.gen_bool(0.5).then_some(ZExtu64::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtZ64::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); let ext_mlink = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); @@ -148,7 +149,7 @@ impl OpenSyn { #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpenAck { pub lease: Duration, - pub initial_sn: u64, + pub initial_sn: uSN, pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, @@ -158,7 +159,7 @@ pub struct OpenAck { impl OpenAck { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::{ZExtUnit, ZExtZBuf, ZExtu64}; + use crate::common::{ZExtUnit, ZExtZ64, ZExtZBuf}; use rand::Rng; let mut rng = rand::thread_rng(); @@ -169,9 +170,9 @@ impl OpenAck { Duration::from_millis(rng.gen()) }; - let initial_sn: u64 = rng.gen(); + let initial_sn: uSN = rng.gen(); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); - let ext_shm = rng.gen_bool(0.5).then_some(ZExtu64::rand()); + let ext_shm = rng.gen_bool(0.5).then_some(ZExtZ64::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); let ext_mlink = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 3067298bbc..caea8f84d1 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -20,7 +20,7 @@ use zenoh_buffers::{ use zenoh_codec::{WCodec, Zenoh080}; use zenoh_protocol::{ core::Reliability, - transport::{fragment::FragmentHeader, frame::FrameHeader, TransportMessage}, + transport::{fragment::FragmentHeader, frame::FrameHeader, uSN, TransportMessage}, zenoh::ZenohMessage, }; @@ -46,8 +46,8 @@ pub(crate) enum CurrentFrame { #[derive(Clone, Copy, Debug)] pub(crate) struct LatestSn { - pub(crate) reliable: Option, - pub(crate) best_effort: Option, + pub(crate) reliable: Option, + pub(crate) best_effort: Option, } impl LatestSn { diff --git a/io/zenoh-transport/src/common/conduit.rs b/io/zenoh-transport/src/common/conduit.rs index 8ca51fe0df..7ecf7ac6b5 100644 --- a/io/zenoh-transport/src/common/conduit.rs +++ b/io/zenoh-transport/src/common/conduit.rs @@ -17,7 +17,7 @@ use std::sync::{Arc, Mutex}; use zenoh_core::zlock; use zenoh_protocol::{ core::{Bits, Reliability}, - transport::ConduitSn, + transport::{uSN, ConduitSn}, }; use zenoh_result::ZResult; @@ -34,7 +34,7 @@ impl TransportChannelTx { Ok(tch) } - pub(crate) fn sync(&mut self, sn: u64) -> ZResult<()> { + pub(crate) fn sync(&mut self, sn: uSN) -> ZResult<()> { self.sn.set(sn) } } @@ -57,7 +57,7 @@ impl TransportChannelRx { Ok(tch) } - pub(crate) fn sync(&mut self, sn: u64) -> ZResult<()> { + pub(crate) fn sync(&mut self, sn: uSN) -> ZResult<()> { // Set the sequence number in the state as it had received a message with sn - 1 let sn = if sn == 0 { self.sn.resolution() - 1 diff --git a/io/zenoh-transport/src/common/defragmentation.rs b/io/zenoh-transport/src/common/defragmentation.rs index c07ec5ac3e..791e93ecdc 100644 --- a/io/zenoh-transport/src/common/defragmentation.rs +++ b/io/zenoh-transport/src/common/defragmentation.rs @@ -16,6 +16,7 @@ use zenoh_buffers::{reader::HasReader, SplitBuffer, ZBuf, ZSlice}; use zenoh_codec::{RCodec, Zenoh080Reliability}; use zenoh_protocol::{ core::{Bits, Reliability}, + transport::uSN, zenoh::ZenohMessage, }; use zenoh_result::{bail, ZResult}; @@ -57,11 +58,11 @@ impl DefragBuffer { } #[inline(always)] - pub(crate) fn sync(&mut self, sn: u64) -> ZResult<()> { + pub(crate) fn sync(&mut self, sn: uSN) -> ZResult<()> { self.sn.set(sn) } - pub(crate) fn push(&mut self, sn: u64, zslice: ZSlice) -> ZResult<()> { + pub(crate) fn push(&mut self, sn: uSN, zslice: ZSlice) -> ZResult<()> { if sn != self.sn.get() { self.clear(); bail!("Expected SN {}, received {}", self.sn.get(), sn) diff --git a/io/zenoh-transport/src/common/seq_num.rs b/io/zenoh-transport/src/common/seq_num.rs index 6ceb66c30c..ae15de5bfe 100644 --- a/io/zenoh-transport/src/common/seq_num.rs +++ b/io/zenoh-transport/src/common/seq_num.rs @@ -11,15 +11,15 @@ // Contributors: // ZettaScale Zenoh Team, // -use zenoh_protocol::core::Bits; +use zenoh_protocol::{core::Bits, transport::uSN}; use zenoh_result::{bail, ZResult}; -const RES_U8: u64 = (u8::MAX >> 1) as u64; // 1 byte max when encoded -const RES_U16: u64 = (u16::MAX >> 2) as u64; // 2 bytes max when encoded -const RES_U32: u64 = (u32::MAX >> 4) as u64; // 4 bytes max when encoded -const RES_U64: u64 = u64::MAX >> 1; // 9 bytes max when encoded +const RES_U8: uSN = (u8::MAX >> 1) as uSN; // 1 byte max when encoded +const RES_U16: uSN = (u16::MAX >> 2) as uSN; // 2 bytes max when encoded +const RES_U32: uSN = (u32::MAX >> 4) as uSN; // 4 bytes max when encoded +const RES_U64: uSN = (u64::MAX >> 1) as uSN; // 9 bytes max when encoded -pub(crate) fn get_mask(resolution: Bits) -> u64 { +pub(crate) fn get_mask(resolution: Bits) -> uSN { match resolution { Bits::U8 => RES_U8, Bits::U16 => RES_U16, @@ -39,8 +39,8 @@ pub(crate) fn get_mask(resolution: Bits) -> u64 { /// #[derive(Clone, Copy, Debug)] pub(crate) struct SeqNum { - value: u64, - mask: u64, + value: uSN, + mask: uSN, } impl SeqNum { @@ -60,22 +60,22 @@ impl SeqNum { /// This funtion will panic if `value` is out of bound w.r.t. `resolution`. That is if /// `value` is greater or equal than `resolution`. /// - pub(crate) fn make(value: u64, resolution: Bits) -> ZResult { + pub(crate) fn make(value: uSN, resolution: Bits) -> ZResult { let mask = get_mask(resolution); let mut sn = SeqNum { value: 0, mask }; sn.set(value)?; Ok(sn) } - pub(crate) fn get(&self) -> u64 { + pub(crate) fn get(&self) -> uSN { self.value } - pub(crate) fn resolution(&self) -> u64 { + pub(crate) fn resolution(&self) -> uSN { self.mask } - pub(crate) fn set(&mut self, value: u64) -> ZResult<()> { + pub(crate) fn set(&mut self, value: uSN) -> ZResult<()> { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -107,7 +107,7 @@ impl SeqNum { /// # Arguments /// /// * `value` - The sequence number which should be checked for precedence relation. - pub(crate) fn precedes(&self, value: u64) -> ZResult { + pub(crate) fn precedes(&self, value: uSN) -> ZResult { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -117,7 +117,7 @@ impl SeqNum { /// Computes the modulo gap between two sequence numbers. #[cfg(test)] // @TODO: remove #[cfg(test)] once reliability is implemented - pub(crate) fn gap(&self, value: u64) -> ZResult { + pub(crate) fn gap(&self, value: uSN) -> ZResult { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -145,23 +145,23 @@ impl SeqNumGenerator { /// This funtion will panic if `value` is out of bound w.r.t. `resolution`. That is if /// `value` is greater or equal than `resolution`. /// - pub(crate) fn make(initial_sn: u64, resolution: Bits) -> ZResult { + pub(crate) fn make(initial_sn: uSN, resolution: Bits) -> ZResult { let sn = SeqNum::make(initial_sn, resolution)?; Ok(SeqNumGenerator(sn)) } - pub(crate) fn now(&mut self) -> u64 { + pub(crate) fn now(&mut self) -> uSN { self.0.get() } /// Generates the next sequence number - pub(crate) fn get(&mut self) -> u64 { + pub(crate) fn get(&mut self) -> uSN { let now = self.now(); self.0.increment(); now } - pub(crate) fn set(&mut self, sn: u64) -> ZResult<()> { + pub(crate) fn set(&mut self, sn: uSN) -> ZResult<()> { self.0.set(sn) } } @@ -172,7 +172,7 @@ mod tests { #[test] fn sn_set() { - let mask = (u8::MAX >> 1) as u64; + let mask = (u8::MAX >> 1) as uSN; let mut sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert_eq!(sn0a.get(), 0); @@ -193,7 +193,7 @@ mod tests { #[test] fn sn_gap() { - let mask = (u8::MAX >> 1) as u64; + let mask = (u8::MAX >> 1) as uSN; let mut sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert_eq!(sn0a.gap(0).unwrap(), 0); @@ -208,7 +208,7 @@ mod tests { #[test] fn sn_precedence() { - let mask = (u8::MAX >> 1) as u64; + let mask = (u8::MAX >> 1) as uSN; let sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert!(sn0a.precedes(1).unwrap()); @@ -222,7 +222,7 @@ mod tests { #[test] fn sn_generation() { - let mask = (u8::MAX >> 1) as u64; + let mask = (u8::MAX >> 1) as uSN; let mut sn0 = SeqNumGenerator::make(mask, Bits::U8).unwrap(); let mut sn1 = SeqNumGenerator::make(5, Bits::U8).unwrap(); diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 81bd8d6006..68d5b811d4 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -33,7 +33,7 @@ use zenoh_protocol::{ core::{Field, Resolution, WhatAmI, ZenohId}, transport::{ close::{self, Close}, - InitAck, OpenAck, TransportBody, TransportMessage, + uSN, InitAck, OpenAck, TransportBody, TransportMessage, }, }; use zenoh_result::ZResult; @@ -89,7 +89,7 @@ struct RecvOpenSynOut { other_zid: ZenohId, other_whatami: WhatAmI, other_lease: Duration, - other_initial_sn: u64, + other_initial_sn: uSN, } // OpenAck diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index 306132a1b7..ed7a82ec0a 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -25,7 +25,7 @@ use zenoh_collections::Properties; use zenoh_config::UsrPwdConf; use zenoh_core::{bail, zasyncread, zerror, Error as ZError, Result as ZResult}; use zenoh_crypto::hmac; -use zenoh_protocol::common::{ZExtUnit, ZExtZBuf, ZExtu64}; +use zenoh_protocol::common::{ZExtUnit, ZExtZ64, ZExtZBuf}; // Authenticator type User = Vec; @@ -199,7 +199,7 @@ impl<'a> AuthUsrPwdFsm<'a> { /// ~ nonce ~ /// +---------------+ /// -/// ZExtu64 +/// ZExtZ64 /*************************************/ /* OpenSyn */ @@ -269,7 +269,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { Ok(output) } - type RecvInitAckIn = (&'a mut StateOpen, Option>); + type RecvInitAckIn = (&'a mut StateOpen, Option>); type RecvInitAckOut = (); async fn recv_init_ack( &self, @@ -367,12 +367,12 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { } type SendInitAckIn = &'a StateAccept; - type SendInitAckOut = Option>; + type SendInitAckOut = Option>; async fn send_init_ack( &self, state: Self::SendInitAckIn, ) -> Result { - Ok(Some(ZExtu64::new(state.nonce))) + Ok(Some(ZExtZ64::new(state.nonce))) } type RecvOpenSynIn = (&'a mut StateAccept, Option>); diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 55c771a2b1..d939e0d28f 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -28,7 +28,7 @@ use std::time::Duration; use zenoh_link::{Link, LinkUnicast}; use zenoh_protocol::{ core::{Field, Resolution, ZenohId}, - transport::{Close, TransportMessage}, + transport::{uSN, Close, TransportMessage}, }; use zenoh_result::ZResult; @@ -104,16 +104,16 @@ pub trait AcceptFsm { /*************************************/ /* FUNCTIONS */ /*************************************/ -pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) -> u64 { +pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) -> uSN { // Create a random yet deterministic initial_sn. // In case of multilink it's important that the same initial_sn is used for every connection attempt. // Instead of storing the state everywhere, we make sure that the we always compute the same initial_sn. let mut hasher = Shake128::default(); hasher.update(zid1.as_slice()); hasher.update(zid2.as_slice()); - let mut array = 0_u64.to_le_bytes(); + let mut array = (0 as uSN).to_le_bytes(); hasher.finalize_xof().read(&mut array); - u64::from_le_bytes(array) & seq_num::get_mask(resolution.get(Field::FrameSN)) + uSN::from_le_bytes(array) & seq_num::get_mask(resolution.get(Field::FrameSN)) } pub(super) async fn close_link(link: &LinkUnicast, reason: Option) { diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index c5006fda41..88546b8c87 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -28,7 +28,9 @@ use zenoh_core::zasynclock; use zenoh_core::{zcondfeat, zerror}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::core::{Field, Resolution}; -use zenoh_protocol::transport::{close, Close, InitSyn, OpenSyn, TransportBody, TransportMessage}; +use zenoh_protocol::transport::{ + close, uSN, Close, InitSyn, OpenSyn, TransportBody, TransportMessage, +}; use zenoh_result::ZResult; type OpenError = (zenoh_result::Error, Option); @@ -76,13 +78,13 @@ struct SendOpenSynIn { } struct SendOpenSynOut { - mine_initial_sn: u64, + mine_initial_sn: uSN, } // OpenAck struct RecvOpenAckOut { other_lease: Duration, - other_initial_sn: u64, + other_initial_sn: uSN, } // FSM diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 09a3a24e59..9aa0d4a018 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -34,7 +34,7 @@ use zenoh_core::zcondfeat; use zenoh_link::Link; use zenoh_protocol::{ core::{Bits, WhatAmI, ZenohId}, - transport::close, + transport::{close, uSN}, zenoh::ZenohMessage, }; use zenoh_result::{zerror, ZResult}; @@ -88,7 +88,7 @@ pub(crate) struct TransportConfigUnicast { pub(crate) zid: ZenohId, pub(crate) whatami: WhatAmI, pub(crate) sn_resolution: Bits, - pub(crate) tx_initial_sn: u64, + pub(crate) tx_initial_sn: uSN, pub(crate) is_qos: bool, #[cfg(feature = "transport_multilink")] pub(crate) multilink: Option, diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index 1321a180d3..00c5babd4a 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -23,7 +23,7 @@ use zenoh_link::LinkUnicast; use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::{ core::{Priority, Reliability}, - transport::{Close, Fragment, Frame, KeepAlive, TransportBody, TransportMessage}, + transport::{uSN, Close, Fragment, Frame, KeepAlive, TransportBody, TransportMessage}, zenoh::ZenohMessage, }; use zenoh_result::{bail, zerror, ZResult}; @@ -183,7 +183,7 @@ impl TransportUnicastInner { Ok(()) } - fn verify_sn(&self, sn: u64, guard: &mut MutexGuard<'_, TransportChannelRx>) -> ZResult<()> { + fn verify_sn(&self, sn: uSN, guard: &mut MutexGuard<'_, TransportChannelRx>) -> ZResult<()> { let precedes = guard.sn.precedes(sn)?; if !precedes { log::debug!( diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index 411bbda3b3..de10b6565c 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -24,7 +24,7 @@ use zenoh_core::{zasynclock, zcondfeat, zread, zwrite}; use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ core::{Bits, Priority, WhatAmI, ZenohId}, - transport::{Close, ConduitSn, TransportMessage}, + transport::{uSN, Close, ConduitSn, TransportMessage}, }; use zenoh_result::{bail, zerror, ZResult}; @@ -125,7 +125,7 @@ impl TransportUnicastInner { /*************************************/ /* INITIATION */ /*************************************/ - pub(super) async fn sync(&self, initial_sn_rx: u64) -> ZResult<()> { + pub(super) async fn sync(&self, initial_sn_rx: uSN) -> ZResult<()> { // Mark the transport as alive and keep the lock // to avoid concurrent new_transport and closing/closed notifications let mut a_guard = zasynclock!(self.alive); From f953933b72bfae2adc975b6d4a308fbd5ed5cef9 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 14 Mar 2023 21:13:59 +0100 Subject: [PATCH 090/203] Change ExprId resolution --- commons/zenoh-codec/src/core/keyexpr.rs | 4 ++-- commons/zenoh-codec/src/zenoh/declare.rs | 6 +++--- commons/zenoh-protocol/src/core/wire_expr.rs | 2 +- commons/zenoh-protocol/src/zenoh/declare.rs | 13 ++++++++----- io/zenoh-transport/src/primitives/mod.rs | 10 +++++----- io/zenoh-transport/src/primitives/mux.rs | 6 +++--- zenoh/src/key_expr.rs | 6 +++--- zenoh/src/net/routing/face.rs | 14 +++++++------- zenoh/src/net/routing/resource.rs | 10 +++++----- zenoh/src/net/routing/router.rs | 4 ++-- zenoh/src/net/runtime/adminspace.rs | 10 +++++----- zenoh/src/net/tests/tables.rs | 10 +++++----- zenoh/src/session.rs | 15 +++++++++------ 13 files changed, 58 insertions(+), 52 deletions(-) diff --git a/commons/zenoh-codec/src/core/keyexpr.rs b/commons/zenoh-codec/src/core/keyexpr.rs index 3b97111b45..a455c3f1d6 100644 --- a/commons/zenoh-codec/src/core/keyexpr.rs +++ b/commons/zenoh-codec/src/core/keyexpr.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_protocol::core::WireExpr; +use zenoh_protocol::core::{ExprId, WireExpr}; impl WCodec<&WireExpr<'_>, &mut W> for Zenoh080 where @@ -41,7 +41,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result, Self::Error> { - let scope: u64 = self.codec.read(&mut *reader)?; + let scope: ExprId = self.codec.read(&mut *reader)?; let suffix: String = if self.condition { self.codec.read(&mut *reader)? } else { diff --git a/commons/zenoh-codec/src/zenoh/declare.rs b/commons/zenoh-codec/src/zenoh/declare.rs index 2cca388d90..f04c8c0a46 100644 --- a/commons/zenoh-codec/src/zenoh/declare.rs +++ b/commons/zenoh-codec/src/zenoh/declare.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - core::{Reliability, WireExpr}, + core::{ExprId, Reliability, WireExpr}, zenoh::{ zmsg, Declaration, Declare, ForgetPublisher, ForgetQueryable, ForgetResource, ForgetSubscriber, Publisher, Queryable, QueryableInfo, Resource, SubInfo, SubMode, @@ -184,7 +184,7 @@ where return Err(DidntRead); } - let expr_id: u64 = self.codec.read(&mut *reader)?; + let expr_id: ExprId = self.codec.read(&mut *reader)?; let ccond = Zenoh080Condition { condition: imsg::has_flag(self.header, zmsg::flag::K), codec: self.codec, @@ -239,7 +239,7 @@ where return Err(DidntRead); } - let expr_id: u64 = self.codec.read(&mut *reader)?; + let expr_id: ExprId = self.codec.read(&mut *reader)?; Ok(ForgetResource { expr_id }) } diff --git a/commons/zenoh-protocol/src/core/wire_expr.rs b/commons/zenoh-protocol/src/core/wire_expr.rs index deea670270..4842fcbdf1 100644 --- a/commons/zenoh-protocol/src/core/wire_expr.rs +++ b/commons/zenoh-protocol/src/core/wire_expr.rs @@ -21,7 +21,7 @@ use core::{convert::TryInto, fmt}; use zenoh_result::{bail, ZResult}; /// A numerical Id mapped to a key expression. -pub type ExprId = u64; +pub type ExprId = u16; pub const EMPTY_EXPR_ID: ExprId = 0; /// A zenoh **resource** is represented by a pair composed by a **key** and a diff --git a/commons/zenoh-protocol/src/zenoh/declare.rs b/commons/zenoh-protocol/src/zenoh/declare.rs index d1e786b21b..7703e00a36 100644 --- a/commons/zenoh-protocol/src/zenoh/declare.rs +++ b/commons/zenoh-protocol/src/zenoh/declare.rs @@ -11,7 +11,10 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, zenoh::Reliability}; +use crate::{ + core::{ExprId, WireExpr}, + zenoh::Reliability, +}; use alloc::vec::Vec; /// ```text @@ -90,7 +93,7 @@ impl Declaration { /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct Resource { - pub expr_id: u64, + pub expr_id: ExprId, pub key: WireExpr<'static>, } @@ -101,7 +104,7 @@ impl Resource { let mut rng = rand::thread_rng(); - let expr_id: u64 = rng.gen(); + let expr_id: ExprId = rng.gen(); let key = WireExpr::rand(); Self { expr_id, key } @@ -118,7 +121,7 @@ impl Resource { /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct ForgetResource { - pub expr_id: u64, + pub expr_id: ExprId, } impl ForgetResource { @@ -128,7 +131,7 @@ impl ForgetResource { let mut rng = rand::thread_rng(); - let expr_id: u64 = rng.gen(); + let expr_id: ExprId = rng.gen(); Self { expr_id } } diff --git a/io/zenoh-transport/src/primitives/mod.rs b/io/zenoh-transport/src/primitives/mod.rs index d686068bac..1ebd1bb4e2 100644 --- a/io/zenoh-transport/src/primitives/mod.rs +++ b/io/zenoh-transport/src/primitives/mod.rs @@ -18,15 +18,15 @@ pub use demux::*; pub use mux::*; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{Channel, CongestionControl, WireExpr, ZenohId}, + core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, zenoh::{ ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo, }, }; pub trait Primitives: Send + Sync { - fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr); - fn forget_resource(&self, expr_id: u64); + fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr); + fn forget_resource(&self, expr_id: ExprId); fn decl_publisher(&self, key_expr: &WireExpr, routing_context: Option); fn forget_publisher(&self, key_expr: &WireExpr, routing_context: Option); @@ -101,8 +101,8 @@ impl DummyPrimitives { } impl Primitives for DummyPrimitives { - fn decl_resource(&self, _expr_id: u64, _key_expr: &WireExpr) {} - fn forget_resource(&self, _expr_id: u64) {} + fn decl_resource(&self, _expr_id: ExprId, _key_expr: &WireExpr) {} + fn forget_resource(&self, _expr_id: ExprId) {} fn decl_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} fn forget_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index 9e31472275..9ba6c5905a 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -15,7 +15,7 @@ use super::super::TransportUnicast; use super::Primitives; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{Channel, CongestionControl, WireExpr, ZenohId}, + core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, zenoh::{ zmsg, ConsolidationMode, DataInfo, Declaration, ForgetPublisher, ForgetQueryable, ForgetResource, ForgetSubscriber, Publisher, QueryBody, QueryTarget, Queryable, @@ -35,7 +35,7 @@ impl Mux { } impl Primitives for Mux { - fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr) { + fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { let d = Declaration::Resource(Resource { expr_id, key: key_expr.to_owned(), @@ -46,7 +46,7 @@ impl Primitives for Mux { .handle_message(ZenohMessage::make_declare(decls, None)); } - fn forget_resource(&self, expr_id: u64) { + fn forget_resource(&self, expr_id: ExprId) { let d = Declaration::ForgetResource(ForgetResource { expr_id }); let decls = vec![d]; let _ = self diff --git a/zenoh/src/key_expr.rs b/zenoh/src/key_expr.rs index dde96a0ae4..03e78625d3 100644 --- a/zenoh/src/key_expr.rs +++ b/zenoh/src/key_expr.rs @@ -21,7 +21,7 @@ use std::{ }; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; pub use zenoh_protocol::core::key_expr::*; -use zenoh_protocol::core::{key_expr::canon::Canonizable, WireExpr}; +use zenoh_protocol::core::{key_expr::canon::Canonizable, ExprId, WireExpr}; use zenoh_result::ZResult; use zenoh_transport::Primitives; @@ -32,14 +32,14 @@ pub(crate) enum KeyExprInner<'a> { Borrowed(&'a keyexpr), BorrowedWire { key_expr: &'a keyexpr, - expr_id: u64, + expr_id: ExprId, prefix_len: u32, session_id: u16, }, Owned(OwnedKeyExpr), Wire { key_expr: OwnedKeyExpr, - expr_id: u64, + expr_id: ExprId, prefix_len: u32, session_id: u16, }, diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index 3949cd3289..ec624c2f59 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use std::sync::RwLock; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{Channel, CongestionControl, WhatAmI, WireExpr, ZenohId}, + core::{Channel, CongestionControl, ExprId, WhatAmI, WireExpr, ZenohId}, zenoh::{ ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo, }, @@ -31,8 +31,8 @@ pub struct FaceState { pub(super) whatami: WhatAmI, pub(super) primitives: Arc, pub(super) link_id: usize, - pub(super) local_mappings: HashMap>, - pub(super) remote_mappings: HashMap>, + pub(super) local_mappings: HashMap>, + pub(super) remote_mappings: HashMap>, pub(super) local_subs: HashSet>, pub(super) remote_subs: HashSet>, pub(super) local_qabls: HashMap, QueryableInfo>, @@ -68,14 +68,14 @@ impl FaceState { #[inline] #[allow(clippy::trivially_copy_pass_by_ref)] - pub(super) fn get_mapping(&self, prefixid: &u64) -> Option<&std::sync::Arc> { + pub(super) fn get_mapping(&self, prefixid: &ExprId) -> Option<&std::sync::Arc> { match self.remote_mappings.get(prefixid) { Some(prefix) => Some(prefix), None => self.local_mappings.get(prefixid), } } - pub(super) fn get_next_local_id(&self) -> u64 { + pub(super) fn get_next_local_id(&self) -> ExprId { let mut id = 1; while self.local_mappings.get(&id).is_some() || self.remote_mappings.get(&id).is_some() { id += 1; @@ -165,12 +165,12 @@ pub struct Face { } impl Primitives for Face { - fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr) { + fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { let mut tables = zwrite!(self.tables); register_expr(&mut tables, &mut self.state.clone(), expr_id, key_expr); } - fn forget_resource(&self, expr_id: u64) { + fn forget_resource(&self, expr_id: ExprId) { let mut tables = zwrite!(self.tables); unregister_expr(&mut tables, &mut self.state.clone(), expr_id); } diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index b98f30bd84..32065d6da6 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -19,7 +19,7 @@ use std::hash::{Hash, Hasher}; use std::sync::{Arc, Weak}; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{key_expr::keyexpr, WireExpr, ZenohId}, + core::{key_expr::keyexpr, ExprId, WireExpr, ZenohId}, zenoh::{DataInfo, QueryableInfo, RoutingContext, SubInfo}, }; use zenoh_sync::get_mut_unchecked; @@ -40,8 +40,8 @@ pub(super) type PullCaches = Vec>; pub(super) struct SessionContext { pub(super) face: Arc, - pub(super) local_expr_id: Option, - pub(super) remote_expr_id: Option, + pub(super) local_expr_id: Option, + pub(super) remote_expr_id: Option, pub(super) subs: Option, pub(super) qabl: Option, pub(super) last_values: HashMap, ZBuf)>, @@ -583,7 +583,7 @@ impl Resource { pub fn register_expr( tables: &mut Tables, face: &mut Arc, - expr_id: u64, + expr_id: ExprId, expr: &WireExpr, ) { match tables.get_mapping(face, &expr.scope).cloned() { @@ -633,7 +633,7 @@ pub fn register_expr( } } -pub fn unregister_expr(_tables: &mut Tables, face: &mut Arc, expr_id: u64) { +pub fn unregister_expr(_tables: &mut Tables, face: &mut Arc, expr_id: ExprId) { match get_mut_unchecked(face).remote_mappings.remove(&expr_id) { Some(mut res) => Resource::clean(&mut res), None => log::error!("Undeclare unknown resource!"), diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index ecca9fe192..4a6469fcea 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -29,7 +29,7 @@ use uhlc::HLC; use zenoh_config::whatami::WhatAmIMatcher; use zenoh_link::Link; use zenoh_protocol::{ - core::{WhatAmI, ZenohId}, + core::{ExprId, WhatAmI, ZenohId}, zenoh::{ZenohBody, ZenohMessage}, }; use zenoh_transport::{DeMux, Mux, Primitives, TransportPeerEventHandler, TransportUnicast}; @@ -138,7 +138,7 @@ impl Tables { pub(crate) fn get_mapping<'a>( &'a self, face: &'a FaceState, - expr_id: &u64, + expr_id: &ExprId, ) -> Option<&'a Arc> { match expr_id { 0 => Some(&self.root_res), diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 3770a5d991..02f4bf147a 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -27,8 +27,8 @@ use zenoh_config::ValidatedMap; use zenoh_config::WhatAmI; use zenoh_protocol::{ core::{ - key_expr::OwnedKeyExpr, Channel, CongestionControl, Encoding, KnownEncoding, WireExpr, - ZenohId, EMPTY_EXPR_ID, + key_expr::OwnedKeyExpr, Channel, CongestionControl, Encoding, ExprId, KnownEncoding, + WireExpr, ZenohId, EMPTY_EXPR_ID, }, zenoh::{ ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, @@ -54,7 +54,7 @@ type Handler = Box< pub struct AdminSpace { zid: ZenohId, primitives: Mutex>>, - mappings: Mutex>, + mappings: Mutex>, handlers: HashMap>, context: Arc, } @@ -243,7 +243,7 @@ impl AdminSpace { } impl Primitives for AdminSpace { - fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr) { + fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { trace!("recv Resource {} {:?}", expr_id, key_expr); match self.key_expr_to_string(key_expr) { Ok(s) => { @@ -253,7 +253,7 @@ impl Primitives for AdminSpace { } } - fn forget_resource(&self, _expr_id: u64) { + fn forget_resource(&self, _expr_id: ExprId) { trace!("recv Forget Resource {}", _expr_id); } diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index 941868caf9..2ceb8e2d79 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -20,8 +20,8 @@ use zenoh_buffers::ZBuf; use zenoh_core::zlock; use zenoh_protocol::{ core::{ - key_expr::keyexpr, Channel, CongestionControl, Reliability, WhatAmI, WireExpr, ZenohId, - EMPTY_EXPR_ID, + key_expr::keyexpr, Channel, CongestionControl, ExprId, Reliability, WhatAmI, WireExpr, + ZenohId, EMPTY_EXPR_ID, }, zenoh::{ ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, @@ -366,7 +366,7 @@ fn clean_test() { pub struct ClientPrimitives { data: std::sync::Mutex>>, - mapping: std::sync::Mutex>, + mapping: std::sync::Mutex>, } impl ClientPrimitives { @@ -416,12 +416,12 @@ impl ClientPrimitives { } impl Primitives for ClientPrimitives { - fn decl_resource(&self, expr_id: u64, key_expr: &WireExpr) { + fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { let name = self.get_name(key_expr); zlock!(self.mapping).insert(expr_id, name); } - fn forget_resource(&self, expr_id: u64) { + fn forget_resource(&self, expr_id: ExprId) { zlock!(self.mapping).remove(&expr_id); } diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 6a71370b1f..ec3a27208d 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -73,7 +73,7 @@ zconfigurable! { pub(crate) struct SessionState { pub(crate) primitives: Option>, // @TODO replace with MaybeUninit ?? - pub(crate) expr_id_counter: AtomicUsize, // @TODO: manage rollover and uniqueness + pub(crate) expr_id_counter: AtomicU16, // @TODO: manage rollover and uniqueness pub(crate) qid_counter: Atomicu64, pub(crate) decl_id_counter: AtomicUsize, pub(crate) local_resources: HashMap, @@ -93,7 +93,7 @@ impl SessionState { ) -> SessionState { SessionState { primitives: None, - expr_id_counter: AtomicUsize::new(1), // Note: start at 1 because 0 is reserved for NO_RESOURCE + expr_id_counter: AtomicU16::new(1), // Note: start at 1 because 0 is reserved for NO_RESOURCE qid_counter: Atomicu64::new(0), decl_id_counter: AtomicUsize::new(0), local_resources: HashMap::new(), @@ -809,7 +809,10 @@ impl Session { }) } - pub(crate) fn declare_prefix<'a>(&'a self, prefix: &'a str) -> impl Resolve + Send + 'a { + pub(crate) fn declare_prefix<'a>( + &'a self, + prefix: &'a str, + ) -> impl Resolve + Send + 'a { ResolveClosure::new(move || { trace!("declare_prefix({:?})", prefix); let mut state = zwrite!(self.state); @@ -820,7 +823,7 @@ impl Session { { Some((expr_id, _res)) => *expr_id, None => { - let expr_id = state.expr_id_counter.fetch_add(1, Ordering::SeqCst) as u64; + let expr_id = state.expr_id_counter.fetch_add(1, Ordering::SeqCst); let mut res = Resource::new(Box::from(prefix)); if let Resource::Node(ResourceNode { key_expr, @@ -1623,7 +1626,7 @@ impl SessionDeclarations for Arc { } impl Primitives for Session { - fn decl_resource(&self, expr_id: u64, wire_expr: &WireExpr) { + fn decl_resource(&self, expr_id: ExprId, wire_expr: &WireExpr) { trace!("recv Decl Resource {} {:?}", expr_id, wire_expr); let state = &mut zwrite!(self.state); match state.remote_key_to_expr(wire_expr) { @@ -1648,7 +1651,7 @@ impl Primitives for Session { } } - fn forget_resource(&self, _expr_id: u64) { + fn forget_resource(&self, _expr_id: ExprId) { trace!("recv Forget Resource {}", _expr_id); } From 85c3b60d2ded97fc31dca9b2a199f5547efce881 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 14 Mar 2023 21:21:04 +0100 Subject: [PATCH 091/203] Change source SN resolution --- commons/zenoh-codec/src/zenoh/data.rs | 21 +++++++++++---------- commons/zenoh-protocol/src/zenoh/data.rs | 13 ++++++++----- commons/zenoh-protocol/src/zenoh/mod.rs | 15 ++++++--------- zenoh/src/sample.rs | 4 ++-- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index cfe8a4b678..f81106f72e 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -24,6 +24,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, core::{CongestionControl, Encoding, WireExpr, ZenohId}, + transport::uSN, zenoh::{zmsg, Data, DataInfo, ReplierInfo, ReplyContext, SampleKind}, }; @@ -96,7 +97,7 @@ where fn write(self, writer: &mut W, x: &DataInfo) -> Self::Output { // Options - let mut options: u64 = 0; + let mut options: u8 = 0; #[cfg(feature = "shared-memory")] if x.sliced { options |= zmsg::data::info::SLICED; @@ -119,7 +120,7 @@ where self.write(&mut *writer, options)?; if x.kind != SampleKind::Put { - self.write(&mut *writer, x.kind as u64)?; + self.write(&mut *writer, x.kind as u8)?; } if let Some(enc) = x.encoding.as_ref() { self.write(&mut *writer, enc)?; @@ -146,29 +147,29 @@ where fn read(self, reader: &mut R) -> Result { let mut info = DataInfo::default(); - let options: u64 = self.read(&mut *reader)?; + let options: u8 = self.read(&mut *reader)?; #[cfg(feature = "shared-memory")] { info.sliced = imsg::has_option(options, zmsg::data::info::SLICED); } - if imsg::has_option(options, zmsg::data::info::KIND) { - let kind: u64 = self.read(&mut *reader)?; + if imsg::has_flag(options, zmsg::data::info::KIND) { + let kind: u8 = self.read(&mut *reader)?; info.kind = kind.try_into().map_err(|_| DidntRead)?; } - if imsg::has_option(options, zmsg::data::info::ENCODING) { + if imsg::has_flag(options, zmsg::data::info::ENCODING) { let encoding: Encoding = self.read(&mut *reader)?; info.encoding = Some(encoding); } - if imsg::has_option(options, zmsg::data::info::TIMESTAMP) { + if imsg::has_flag(options, zmsg::data::info::TIMESTAMP) { let timestamp: Timestamp = self.read(&mut *reader)?; info.timestamp = Some(timestamp); } - if imsg::has_option(options, zmsg::data::info::SRCID) { + if imsg::has_flag(options, zmsg::data::info::SRCID) { let source_id: ZenohId = self.read(&mut *reader)?; info.source_id = Some(source_id); } - if imsg::has_option(options, zmsg::data::info::SRCSN) { - let source_sn: u64 = self.read(&mut *reader)?; + if imsg::has_flag(options, zmsg::data::info::SRCSN) { + let source_sn: uSN = self.read(&mut *reader)?; info.source_sn = Some(source_sn); } diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs index 30b0f27e24..8efee38df0 100644 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ b/commons/zenoh-protocol/src/zenoh/data.rs @@ -11,7 +11,10 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{CongestionControl, Encoding, Timestamp, WireExpr, ZenohId}; +use crate::{ + core::{CongestionControl, Encoding, Timestamp, WireExpr, ZenohId}, + transport::uSN, +}; use core::{convert::TryFrom, fmt}; use zenoh_buffers::ZBuf; @@ -35,9 +38,9 @@ impl fmt::Display for SampleKind { } } -impl TryFrom for SampleKind { - type Error = u64; - fn try_from(kind: u64) -> Result { +impl TryFrom for SampleKind { + type Error = u8; + fn try_from(kind: u8) -> Result { match kind { 0 => Ok(SampleKind::Put), 1 => Ok(SampleKind::Delete), @@ -151,7 +154,7 @@ pub struct DataInfo { pub encoding: Option, pub timestamp: Option, pub source_id: Option, - pub source_sn: Option, + pub source_sn: Option, } impl DataInfo { diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index ce8740ca32..f2c0512b22 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -76,15 +76,12 @@ pub mod zmsg { pub mod data { pub mod info { #[cfg(feature = "shared-memory")] - pub const SLICED: u64 = 1 << 0; // 0x01 - pub const KIND: u64 = 1 << 1; // 0x02 - pub const ENCODING: u64 = 1 << 2; // 0x04 - pub const TIMESTAMP: u64 = 1 << 3; // 0x08 - // 0x10: Reserved - // 0x20: Reserved - // 0x40: Reserved - pub const SRCID: u64 = 1 << 7; // 0x80 - pub const SRCSN: u64 = 1 << 8; // 0x100 + pub const SLICED: u8 = 1 << 0; // 0x01 + pub const KIND: u8 = 1 << 1; // 0x02 + pub const ENCODING: u8 = 1 << 2; // 0x04 + pub const TIMESTAMP: u8 = 1 << 3; // 0x08 + pub const SRCID: u8 = 1 << 4; // 0x10 + pub const SRCSN: u8 = 1 << 5; // 0x20 } } diff --git a/zenoh/src/sample.rs b/zenoh/src/sample.rs index 82d02a0c36..90f08cb743 100644 --- a/zenoh/src/sample.rs +++ b/zenoh/src/sample.rs @@ -21,7 +21,7 @@ use crate::time::{new_reception_timestamp, Timestamp}; #[zenoh_core::unstable] use serde::Serialize; use std::convert::TryInto; -use zenoh_protocol::zenoh::DataInfo; +use zenoh_protocol::{transport::uSN, zenoh::DataInfo}; /// The locality of samples to be received by subscribers or targeted by publishers. #[zenoh_core::unstable] @@ -47,7 +47,7 @@ pub struct SourceInfo { /// The [`ZenohId`] of the zenoh instance that published the concerned [`Sample`]. pub source_id: Option, /// The sequence number of the [`Sample`] from the source. - pub source_sn: Option, + pub source_sn: Option, } #[test] From e88defaae2cc458ef509a73cb60521405b38fa2b Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 14 Mar 2023 21:28:18 +0100 Subject: [PATCH 092/203] Fix Encoding resolution --- commons/zenoh-codec/src/core/encoding.rs | 2 +- commons/zenoh-protocol/src/core/encoding.rs | 36 ++++----------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/commons/zenoh-codec/src/core/encoding.rs b/commons/zenoh-codec/src/core/encoding.rs index 9955320927..84530f41e3 100644 --- a/commons/zenoh-codec/src/core/encoding.rs +++ b/commons/zenoh-codec/src/core/encoding.rs @@ -26,7 +26,7 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Encoding) -> Self::Output { - self.write(&mut *writer, u64::from(*x.prefix()))?; + self.write(&mut *writer, *x.prefix() as u64)?; self.write(&mut *writer, x.suffix())?; Ok(()) } diff --git a/commons/zenoh-protocol/src/core/encoding.rs b/commons/zenoh-protocol/src/core/encoding.rs index 79b7d51f05..97a9618578 100644 --- a/commons/zenoh-protocol/src/core/encoding.rs +++ b/commons/zenoh-protocol/src/core/encoding.rs @@ -14,7 +14,7 @@ use crate::core::CowStr; use alloc::{borrow::Cow, string::String}; use core::{ - convert::TryFrom, + convert::{TryFrom, TryInto}, fmt::{self, Debug}, mem, }; @@ -74,25 +74,13 @@ pub enum KnownEncoding { impl From for u8 { fn from(val: KnownEncoding) -> Self { - unsafe { mem::transmute(val) } - } -} - -impl From for u64 { - fn from(val: KnownEncoding) -> Self { - u8::from(val) as u64 + val as u8 } } impl From for &str { fn from(val: KnownEncoding) -> Self { - consts::MIMES[usize::from(val)] - } -} - -impl From for usize { - fn from(val: KnownEncoding) -> Self { - u8::from(val) as usize + consts::MIMES[u8::from(val) as usize] } } @@ -107,23 +95,12 @@ impl TryFrom for KnownEncoding { } } -impl TryFrom for KnownEncoding { - type Error = (); - - fn try_from(value: u64) -> Result { - if value < consts::MIMES.len() as u64 + 1 { - Ok(unsafe { mem::transmute(value as u8) }) - } else { - Err(()) - } - } -} - impl AsRef for KnownEncoding { fn as_ref(&self) -> &str { - consts::MIMES[usize::from(*self)] + consts::MIMES[u8::from(*self) as usize] } } + /// The encoding of a zenoh `zenoh::Value`. /// /// A zenoh encoding is a HTTP Mime type represented, for wire efficiency, @@ -139,7 +116,8 @@ impl Encoding { where IntoCowStr: Into> + AsRef, { - let prefix = KnownEncoding::try_from(prefix).ok()?; + let e: u8 = prefix.try_into().ok()?; + let prefix = KnownEncoding::try_from(e).ok()?; if suffix.as_ref().is_empty() { Some(Encoding::Exact(prefix)) } else { From 5b2f56cd1c673830025e6ce2be429938cb7cbc6a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 14 Mar 2023 21:57:59 +0100 Subject: [PATCH 093/203] Query ID resolution --- commons/zenoh-codec/src/zenoh/data.rs | 2 +- commons/zenoh-codec/src/zenoh/query.rs | 3 ++- commons/zenoh-protocol/src/zenoh/data.rs | 6 +++--- commons/zenoh-protocol/src/zenoh/mod.rs | 3 ++- commons/zenoh-protocol/src/zenoh/query.rs | 6 +++--- io/zenoh-transport/src/primitives/mod.rs | 13 +++++++------ io/zenoh-transport/src/primitives/mux.rs | 7 ++++--- zenoh/src/net/routing/face.rs | 11 ++++++----- zenoh/src/net/routing/queries.rs | 13 +++++++------ zenoh/src/net/routing/resource.rs | 3 ++- zenoh/src/net/runtime/adminspace.rs | 7 ++++--- zenoh/src/net/tests/tables.rs | 7 ++++--- zenoh/src/session.rs | 17 +++++++++-------- 13 files changed, 54 insertions(+), 44 deletions(-) diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index f81106f72e..6160aeb189 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -77,7 +77,7 @@ where return Err(DidntRead); } - let qid: u64 = self.codec.read(&mut *reader)?; + let qid: uSN = self.codec.read(&mut *reader)?; let replier = if imsg::has_flag(self.header, zmsg::flag::F) { None } else { diff --git a/commons/zenoh-codec/src/zenoh/query.rs b/commons/zenoh-codec/src/zenoh/query.rs index 8b9836a824..d160ca33cb 100644 --- a/commons/zenoh-codec/src/zenoh/query.rs +++ b/commons/zenoh-codec/src/zenoh/query.rs @@ -21,6 +21,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, core::WireExpr, + transport::uSN, zenoh::{zmsg, ConsolidationMode, DataInfo, Query, QueryBody, QueryTarget}, }; @@ -202,7 +203,7 @@ where let key: WireExpr<'static> = ccond.read(&mut *reader)?; let parameters: String = self.codec.read(&mut *reader)?; - let qid: u64 = self.codec.read(&mut *reader)?; + let qid: uSN = self.codec.read(&mut *reader)?; let target = if imsg::has_flag(self.header, zmsg::flag::T) { let qt: QueryTarget = self.codec.read(&mut *reader)?; Some(qt) diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs index 8efee38df0..277994792e 100644 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ b/commons/zenoh-protocol/src/zenoh/data.rs @@ -75,13 +75,13 @@ pub struct ReplierInfo { } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ReplyContext { - pub qid: u64, + pub qid: uSN, pub replier: Option, } impl ReplyContext { // Note: id replier_id=None flag F is set, meaning it's a REPLY_FINAL - pub fn new(qid: u64, replier: Option) -> Self { + pub fn new(qid: uSN, replier: Option) -> Self { Self { qid, replier } } @@ -97,7 +97,7 @@ impl ReplyContext { let mut rng = rand::thread_rng(); - let qid: u64 = rng.gen(); + let qid: uSN = rng.gen(); let replier = if rng.gen_bool(0.5) { Some(ReplierInfo { id: ZenohId::default(), diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index f2c0512b22..dffb4f2899 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -20,6 +20,7 @@ mod routing; mod unit; use crate::core::{Channel, CongestionControl, Reliability, WireExpr}; +use crate::transport::uSN; use alloc::{string::String, vec::Vec}; use core::fmt; pub use data::*; @@ -279,7 +280,7 @@ impl ZenohMessage { pub fn make_query( key: WireExpr<'static>, parameters: String, - qid: u64, + qid: uSN, target: Option, consolidation: ConsolidationMode, body: Option, diff --git a/commons/zenoh-protocol/src/zenoh/query.rs b/commons/zenoh-protocol/src/zenoh/query.rs index 860d90e68f..5aa6528821 100644 --- a/commons/zenoh-protocol/src/zenoh/query.rs +++ b/commons/zenoh-protocol/src/zenoh/query.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, zenoh::DataInfo}; +use crate::{core::WireExpr, transport::uSN, zenoh::DataInfo}; use alloc::string::String; use zenoh_buffers::ZBuf; @@ -101,7 +101,7 @@ impl QueryBody { pub struct Query { pub key: WireExpr<'static>, pub parameters: String, - pub qid: u64, + pub qid: uSN, pub target: Option, pub consolidation: ConsolidationMode, pub body: Option, @@ -130,7 +130,7 @@ impl Query { String::new() }; - let qid: u64 = rng.gen(); + let qid: uSN = rng.gen(); let target = if rng.gen_bool(0.5) { let t = [ diff --git a/io/zenoh-transport/src/primitives/mod.rs b/io/zenoh-transport/src/primitives/mod.rs index 1ebd1bb4e2..8ab370c6b5 100644 --- a/io/zenoh-transport/src/primitives/mod.rs +++ b/io/zenoh-transport/src/primitives/mod.rs @@ -19,6 +19,7 @@ pub use mux::*; use zenoh_buffers::ZBuf; use zenoh_protocol::{ core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, + transport::uSN, zenoh::{ ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo, }, @@ -62,7 +63,7 @@ pub trait Primitives: Send + Sync { &self, key_expr: &WireExpr, parameters: &str, - qid: u64, + qid: uSN, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -71,14 +72,14 @@ pub trait Primitives: Send + Sync { fn send_reply_data( &self, - qid: u64, + qid: uSN, replier_id: ZenohId, key_expr: WireExpr, info: Option, payload: ZBuf, ); - fn send_reply_final(&self, qid: u64); + fn send_reply_final(&self, qid: uSN); fn send_pull( &self, @@ -139,7 +140,7 @@ impl Primitives for DummyPrimitives { &self, _key_expr: &WireExpr, _parameters: &str, - _qid: u64, + _qid: uSN, _target: QueryTarget, _consolidation: ConsolidationMode, _body: Option, @@ -148,14 +149,14 @@ impl Primitives for DummyPrimitives { } fn send_reply_data( &self, - _qid: u64, + _qid: uSN, _replier_id: ZenohId, _key_expr: WireExpr, _info: Option, _payload: ZBuf, ) { } - fn send_reply_final(&self, _qid: u64) {} + fn send_reply_final(&self, _qid: uSN) {} fn send_pull( &self, _is_final: bool, diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index 9ba6c5905a..3832054e9c 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -16,6 +16,7 @@ use super::Primitives; use zenoh_buffers::ZBuf; use zenoh_protocol::{ core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, + transport::uSN, zenoh::{ zmsg, ConsolidationMode, DataInfo, Declaration, ForgetPublisher, ForgetQueryable, ForgetResource, ForgetSubscriber, Publisher, QueryBody, QueryTarget, Queryable, @@ -150,7 +151,7 @@ impl Primitives for Mux { &self, key_expr: &WireExpr, parameters: &str, - qid: u64, + qid: uSN, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -174,7 +175,7 @@ impl Primitives for Mux { fn send_reply_data( &self, - qid: u64, + qid: uSN, replier_id: ZenohId, key_expr: WireExpr, data_info: Option, @@ -191,7 +192,7 @@ impl Primitives for Mux { )); } - fn send_reply_final(&self, qid: u64) { + fn send_reply_final(&self, qid: uSN) { let _ = self.handler.handle_message(ZenohMessage::make_unit( zmsg::default_channel::REPLY, zmsg::default_congestion_control::REPLY, diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index ec624c2f59..ed17a2d27b 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -17,6 +17,7 @@ use std::fmt; use std::sync::Arc; use std::sync::RwLock; use zenoh_buffers::ZBuf; +use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{Channel, CongestionControl, ExprId, WhatAmI, WireExpr, ZenohId}, zenoh::{ @@ -37,8 +38,8 @@ pub struct FaceState { pub(super) remote_subs: HashSet>, pub(super) local_qabls: HashMap, QueryableInfo>, pub(super) remote_qabls: HashSet>, - pub(super) next_qid: u64, - pub(super) pending_queries: HashMap>, + pub(super) next_qid: uSN, + pub(super) pending_queries: HashMap>, } impl FaceState { @@ -357,7 +358,7 @@ impl Primitives for Face { &self, key_expr: &WireExpr, parameters: &str, - qid: u64, + qid: uSN, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -378,7 +379,7 @@ impl Primitives for Face { fn send_reply_data( &self, - qid: u64, + qid: uSN, replier_id: ZenohId, key_expr: WireExpr, info: Option, @@ -395,7 +396,7 @@ impl Primitives for Face { ); } - fn send_reply_final(&self, qid: u64) { + fn send_reply_final(&self, qid: uSN) { route_send_reply_final(&self.tables, &mut self.state.clone(), qid); } diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 56907947b0..2697032e73 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -24,6 +24,7 @@ use std::convert::TryFrom; use std::sync::Arc; use std::sync::{RwLock, Weak}; use zenoh_buffers::ZBuf; +use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{ key_expr::{ @@ -39,7 +40,7 @@ use zenoh_util::Timed; pub(crate) struct Query { src_face: Arc, - src_qid: u64, + src_qid: uSN, } #[cfg(feature = "complete_n")] @@ -1316,7 +1317,7 @@ pub(crate) fn compute_matches_query_routes(tables: &mut Tables, res: &mut Arc, query: Arc) -> u64 { +fn insert_pending_query(outface: &mut Arc, query: Arc) -> uSN { let outface_mut = get_mut_unchecked(outface); outface_mut.next_qid += 1; let qid = outface_mut.next_qid; @@ -1485,7 +1486,7 @@ fn compute_final_route( struct QueryCleanup { tables: Arc>, face: Weak, - qid: u64, + qid: uSN, } #[async_trait] @@ -1591,7 +1592,7 @@ pub fn route_query( face: &Arc, expr: &WireExpr, parameters: &str, - qid: u64, + qid: uSN, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -1705,7 +1706,7 @@ pub fn route_query( pub(crate) fn route_send_reply_data( tables_ref: &RwLock, face: &mut Arc, - qid: u64, + qid: uSN, replier_id: ZenohId, key_expr: WireExpr, info: Option, @@ -1735,7 +1736,7 @@ pub(crate) fn route_send_reply_data( pub(crate) fn route_send_reply_final( tables_ref: &RwLock, face: &mut Arc, - qid: u64, + qid: uSN, ) { let tables_lock = zwrite!(tables_ref); match get_mut_unchecked(face).pending_queries.remove(&qid) { diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index 32065d6da6..e9ef940fb8 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -18,6 +18,7 @@ use std::convert::TryInto; use std::hash::{Hash, Hasher}; use std::sync::{Arc, Weak}; use zenoh_buffers::ZBuf; +use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{key_expr::keyexpr, ExprId, WireExpr, ZenohId}, zenoh::{DataInfo, QueryableInfo, RoutingContext, SubInfo}, @@ -29,7 +30,7 @@ pub(super) type Route = HashMap; #[cfg(feature = "complete_n")] pub(super) type QueryRoute = HashMap; #[cfg(not(feature = "complete_n"))] -pub(super) type QueryRoute = HashMap; +pub(super) type QueryRoute = HashMap; pub(super) struct QueryTargetQabl { pub(super) direction: Direction, pub(super) complete: u64, diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 02f4bf147a..f05a02f2b8 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -25,6 +25,7 @@ use std::sync::Mutex; use zenoh_buffers::{SplitBuffer, ZBuf}; use zenoh_config::ValidatedMap; use zenoh_config::WhatAmI; +use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{ key_expr::OwnedKeyExpr, Channel, CongestionControl, Encoding, ExprId, KnownEncoding, @@ -366,7 +367,7 @@ impl Primitives for AdminSpace { &self, key_expr: &WireExpr, parameters: &str, - qid: u64, + qid: uSN, target: QueryTarget, _consolidation: ConsolidationMode, _body: Option, @@ -473,7 +474,7 @@ impl Primitives for AdminSpace { fn send_reply_data( &self, - qid: u64, + qid: uSN, replier_id: ZenohId, key_expr: WireExpr, info: Option, @@ -489,7 +490,7 @@ impl Primitives for AdminSpace { ); } - fn send_reply_final(&self, qid: u64) { + fn send_reply_final(&self, qid: uSN) { trace!("recv ReplyFinal {:?}", qid); } diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index 2ceb8e2d79..a38e2b5407 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -18,6 +18,7 @@ use std::time::Duration; use uhlc::HLC; use zenoh_buffers::ZBuf; use zenoh_core::zlock; +use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{ key_expr::keyexpr, Channel, CongestionControl, ExprId, Reliability, WhatAmI, WireExpr, @@ -462,7 +463,7 @@ impl Primitives for ClientPrimitives { &self, _key_expr: &WireExpr, _parameters: &str, - _qid: u64, + _qid: uSN, _target: QueryTarget, _consolidation: ConsolidationMode, _body: Option, @@ -472,14 +473,14 @@ impl Primitives for ClientPrimitives { fn send_reply_data( &self, - _qid: u64, + _qid: uSN, _replier_id: ZenohId, _key_expr: WireExpr, _info: Option, _payload: ZBuf, ) { } - fn send_reply_final(&self, _qid: u64) {} + fn send_reply_final(&self, _qid: uSN) {} fn send_pull( &self, diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index ec3a27208d..f755ad2efb 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -42,7 +42,7 @@ use std::collections::HashMap; use std::convert::TryInto; use std::fmt; use std::ops::Deref; -use std::sync::atomic::{AtomicU16, AtomicU64, AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicU16, AtomicU32, AtomicU64, AtomicUsize, Ordering}; use std::sync::Arc; use std::sync::RwLock; use std::time::Duration; @@ -51,6 +51,7 @@ use zenoh_buffers::ZBuf; use zenoh_collections::SingleOrVec; use zenoh_config::unwrap_or_default; use zenoh_core::{zconfigurable, zread, Resolve, ResolveClosure, ResolveFuture, SyncResolve}; +use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{ key_expr::{keyexpr, OwnedKeyExpr}, @@ -74,14 +75,14 @@ zconfigurable! { pub(crate) struct SessionState { pub(crate) primitives: Option>, // @TODO replace with MaybeUninit ?? pub(crate) expr_id_counter: AtomicU16, // @TODO: manage rollover and uniqueness - pub(crate) qid_counter: Atomicu64, + pub(crate) qid_counter: AtomicU32, pub(crate) decl_id_counter: AtomicUsize, pub(crate) local_resources: HashMap, pub(crate) remote_resources: HashMap, pub(crate) publications: Vec, pub(crate) subscribers: HashMap>, pub(crate) queryables: HashMap>, - pub(crate) queries: HashMap, + pub(crate) queries: HashMap, pub(crate) aggregated_subscribers: Vec, pub(crate) aggregated_publishers: Vec, } @@ -94,7 +95,7 @@ impl SessionState { SessionState { primitives: None, expr_id_counter: AtomicU16::new(1), // Note: start at 1 because 0 is reserved for NO_RESOURCE - qid_counter: Atomicu64::new(0), + qid_counter: AtomicU32::new(0), decl_id_counter: AtomicUsize::new(0), local_resources: HashMap::new(), remote_resources: HashMap::new(), @@ -1403,7 +1404,7 @@ impl Session { local: bool, key_expr: &WireExpr, parameters: &str, - qid: u64, + qid: uSN, _target: QueryTarget, _consolidation: ConsolidationMode, body: Option, @@ -1713,7 +1714,7 @@ impl Primitives for Session { &self, key_expr: &WireExpr, parameters: &str, - qid: u64, + qid: uSN, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -1739,7 +1740,7 @@ impl Primitives for Session { fn send_reply_data( &self, - qid: u64, + qid: uSN, replier_id: ZenohId, key_expr: WireExpr, data_info: Option, @@ -1852,7 +1853,7 @@ impl Primitives for Session { } } - fn send_reply_final(&self, qid: u64) { + fn send_reply_final(&self, qid: uSN) { trace!("recv ReplyFinal {:?}", qid); let mut state = zwrite!(self.state); match state.queries.get_mut(&qid) { From 7c775320adbcb434292a09173f29dc11e49ac690 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 15 Mar 2023 12:28:24 +0100 Subject: [PATCH 094/203] Sn and Id typedef --- commons/zenoh-codec/benches/codec.rs | 11 +++-- commons/zenoh-codec/src/transport/fragment.rs | 4 +- commons/zenoh-codec/src/transport/frame.rs | 4 +- commons/zenoh-codec/src/transport/open.rs | 6 +-- commons/zenoh-codec/src/zenoh/data.rs | 8 ++-- commons/zenoh-codec/src/zenoh/query.rs | 5 +-- commons/zenoh-config/src/lib.rs | 14 +++--- commons/zenoh-protocol/src/core/resolution.rs | 30 +++++++++++-- commons/zenoh-protocol/src/core/wire_expr.rs | 3 +- commons/zenoh-protocol/src/defaults.rs | 24 ---------- commons/zenoh-protocol/src/lib.rs | 1 - .../zenoh-protocol/src/transport/fragment.rs | 10 ++--- commons/zenoh-protocol/src/transport/frame.rs | 10 ++--- commons/zenoh-protocol/src/transport/mod.rs | 15 +++++-- commons/zenoh-protocol/src/transport/open.rs | 10 ++--- commons/zenoh-protocol/src/zenoh/data.rs | 11 ++--- commons/zenoh-protocol/src/zenoh/mod.rs | 3 +- commons/zenoh-protocol/src/zenoh/query.rs | 11 +++-- io/zenoh-links/zenoh-link-quic/src/lib.rs | 7 ++- io/zenoh-transport/src/common/batch.rs | 16 ++++--- io/zenoh-transport/src/common/conduit.rs | 6 +-- .../src/common/defragmentation.rs | 6 +-- io/zenoh-transport/src/common/pipeline.rs | 25 +++++------ io/zenoh-transport/src/common/seq_num.rs | 44 +++++++++---------- io/zenoh-transport/src/manager.rs | 4 +- io/zenoh-transport/src/primitives/mod.rs | 16 +++---- io/zenoh-transport/src/primitives/mux.rs | 9 ++-- .../src/unicast/establishment/accept.rs | 6 +-- .../src/unicast/establishment/mod.rs | 8 ++-- .../src/unicast/establishment/open.rs | 15 ++++--- io/zenoh-transport/src/unicast/mod.rs | 4 +- io/zenoh-transport/src/unicast/rx.rs | 8 +++- io/zenoh-transport/src/unicast/transport.rs | 4 +- zenoh/src/info.rs | 2 +- zenoh/src/lib.rs | 2 +- zenoh/src/net/routing/face.rs | 14 +++--- zenoh/src/net/routing/network.rs | 3 +- zenoh/src/net/routing/queries.rs | 17 +++---- zenoh/src/net/routing/resource.rs | 5 +-- zenoh/src/net/routing/router.rs | 3 +- zenoh/src/net/runtime/adminspace.rs | 14 +++--- zenoh/src/net/runtime/orchestrator.rs | 4 +- zenoh/src/net/tests/tables.rs | 11 +++-- zenoh/src/prelude.rs | 4 +- zenoh/src/sample.rs | 4 +- zenoh/src/scouting.rs | 2 +- zenoh/src/session.rs | 30 ++++++------- zenohd/src/main.rs | 7 ++- 48 files changed, 248 insertions(+), 232 deletions(-) delete mode 100644 commons/zenoh-protocol/src/defaults.rs diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 6966c10e5c..99c7cc4d8d 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -23,8 +23,7 @@ use zenoh_buffers::{ use zenoh_codec::*; use zenoh_protocol::{ core::{CongestionControl, Reliability}, - defaults::BATCH_SIZE, - transport::{uSN, Frame, FrameHeader}, + transport::{BatchSize, Frame, FrameHeader, TransportSn}, zenoh::Data, }; @@ -43,7 +42,7 @@ fn criterion_benchmark(c: &mut Criterion) { }); // u64 BBuf - let mut buff = BBuf::with_capacity(BATCH_SIZE as usize); + let mut buff = BBuf::with_capacity(BatchSize::MAX as usize); let codec = Zenoh080::new(); c.bench_function("u64 BBuf", |b| { b.iter(|| { @@ -74,7 +73,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), - sn: uSN::MIN, + sn: TransportSn::MIN, ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; @@ -111,7 +110,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), - sn: uSN::MIN, + sn: TransportSn::MIN, ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; @@ -143,7 +142,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), - sn: uSN::MIN, + sn: TransportSn::MIN, ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), }; diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index d391922dfd..28b7eb75bd 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -20,7 +20,7 @@ use zenoh_protocol::{ common::{imsg, ZExtUnknown}, core::Reliability, transport::{ - fragment::{ext, flag, uSN, Fragment, FragmentHeader}, + fragment::{ext, flag, Fragment, FragmentHeader, TransportSn}, id, }, }; @@ -87,7 +87,7 @@ where false => Reliability::BestEffort, }; let more = imsg::has_flag(self.header, flag::M); - let sn: uSN = self.codec.read(&mut *reader)?; + let sn: TransportSn = self.codec.read(&mut *reader)?; // Extensions let mut qos = ext::QoS::default(); diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 2b0cbb8509..fd26fd7918 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -24,7 +24,7 @@ use zenoh_protocol::{ core::{Priority, Reliability}, transport::{ frame::{ext, flag, Frame, FrameHeader}, - id, uSN, + id, TransportSn, }, zenoh::ZenohMessage, }; @@ -134,7 +134,7 @@ where true => Reliability::Reliable, false => Reliability::BestEffort, }; - let sn: uSN = self.codec.read(&mut *reader)?; + let sn: TransportSn = self.codec.read(&mut *reader)?; // Extensions let mut qos = ext::QoS::default(); diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index 8af86b1add..c4a861cbfb 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -23,7 +23,7 @@ use zenoh_protocol::{ transport::{ id, open::{ext, flag, OpenAck, OpenSyn}, - uSN, + TransportSn, }, }; @@ -111,7 +111,7 @@ where } else { Duration::from_millis(lease) }; - let initial_sn: uSN = self.codec.read(&mut *reader)?; + let initial_sn: TransportSn = self.codec.read(&mut *reader)?; let cookie: ZSlice = self.codec.read(&mut *reader)?; // Extensions @@ -249,7 +249,7 @@ where } else { Duration::from_millis(lease) }; - let initial_sn: uSN = self.codec.read(&mut *reader)?; + let initial_sn: TransportSn = self.codec.read(&mut *reader)?; // Extensions let mut ext_qos = None; diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index 6160aeb189..4f523db8bd 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -24,8 +24,8 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, core::{CongestionControl, Encoding, WireExpr, ZenohId}, - transport::uSN, - zenoh::{zmsg, Data, DataInfo, ReplierInfo, ReplyContext, SampleKind}, + transport::TransportSn, + zenoh::{zmsg, Data, DataInfo, QueryId, ReplierInfo, ReplyContext, SampleKind}, }; // ReplyContext @@ -77,7 +77,7 @@ where return Err(DidntRead); } - let qid: uSN = self.codec.read(&mut *reader)?; + let qid: QueryId = self.codec.read(&mut *reader)?; let replier = if imsg::has_flag(self.header, zmsg::flag::F) { None } else { @@ -169,7 +169,7 @@ where info.source_id = Some(source_id); } if imsg::has_flag(options, zmsg::data::info::SRCSN) { - let source_sn: uSN = self.read(&mut *reader)?; + let source_sn: TransportSn = self.read(&mut *reader)?; info.source_sn = Some(source_sn); } diff --git a/commons/zenoh-codec/src/zenoh/query.rs b/commons/zenoh-codec/src/zenoh/query.rs index d160ca33cb..08104cf9fd 100644 --- a/commons/zenoh-codec/src/zenoh/query.rs +++ b/commons/zenoh-codec/src/zenoh/query.rs @@ -21,8 +21,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, core::WireExpr, - transport::uSN, - zenoh::{zmsg, ConsolidationMode, DataInfo, Query, QueryBody, QueryTarget}, + zenoh::{zmsg, ConsolidationMode, DataInfo, Query, QueryBody, QueryId, QueryTarget}, }; // QueryTarget @@ -203,7 +202,7 @@ where let key: WireExpr<'static> = ccond.read(&mut *reader)?; let parameters: String = self.codec.read(&mut *reader)?; - let qid: uSN = self.codec.read(&mut *reader)?; + let qid: QueryId = self.codec.read(&mut *reader)?; let target = if imsg::has_flag(self.header, zmsg::flag::T) { let qt: QueryTarget = self.codec.read(&mut *reader)?; Some(qt) diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index ef514264d9..fc611a3d42 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -34,12 +34,14 @@ use std::{ use validated_struct::ValidatedMapAssociatedTypes; pub use validated_struct::{GetError, ValidatedMap}; use zenoh_core::zlock; -use zenoh_protocol::core::{ - key_expr::OwnedKeyExpr, - whatami::{WhatAmIMatcher, WhatAmIMatcherVisitor}, - Bits, +use zenoh_protocol::{ + core::{ + key_expr::OwnedKeyExpr, + whatami::{self, WhatAmI, WhatAmIMatcher, WhatAmIMatcherVisitor}, + Bits, EndPoint, ZenohId, + }, + transport::BatchSize, }; -pub use zenoh_protocol::core::{whatami, EndPoint, Locator, Priority, WhatAmI, ZenohId}; use zenoh_result::{bail, zerror, ZResult}; use zenoh_util::LibLoader; @@ -241,7 +243,7 @@ validated_struct::validator! { /// Number fo keep-alive messages in a link lease duration (default: 4) keep_alive: Option, /// Zenoh's MTU equivalent (default: 2^16-1) - batch_size: Option, + batch_size: Option, pub queue: QueueConf { /// The size of each priority queue indicates the number of batches a given queue can contain. /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. diff --git a/commons/zenoh-protocol/src/core/resolution.rs b/commons/zenoh-protocol/src/core/resolution.rs index 74a3a78e00..2992b39521 100644 --- a/commons/zenoh-protocol/src/core/resolution.rs +++ b/commons/zenoh-protocol/src/core/resolution.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::defaults::{FRAME_SN_RESOLUTION, REQUEST_ID_RESOLUTION}; +use crate::{transport::TransportSn, zenoh::QueryId}; use alloc::string::String; use core::{fmt, str::FromStr}; use zenoh_result::{bail, ZError}; @@ -51,6 +51,30 @@ impl Bits { } } +impl From for Bits { + fn from(_: u8) -> Self { + Self::U8 + } +} + +impl From for Bits { + fn from(_: u16) -> Self { + Self::U16 + } +} + +impl From for Bits { + fn from(_: u32) -> Self { + Self::U32 + } +} + +impl From for Bits { + fn from(_: u64) -> Self { + Self::U64 + } +} + impl FromStr for Bits { type Err = ZError; @@ -116,8 +140,8 @@ impl Resolution { impl Default for Resolution { fn default() -> Self { - let frame_sn = FRAME_SN_RESOLUTION as u8; - let request_id = (REQUEST_ID_RESOLUTION as u8) << 2; + let frame_sn = Bits::from(TransportSn::MAX) as u8; + let request_id = (Bits::from(QueryId::MAX) as u8) << 2; Self(frame_sn | request_id) } } diff --git a/commons/zenoh-protocol/src/core/wire_expr.rs b/commons/zenoh-protocol/src/core/wire_expr.rs index 4842fcbdf1..35a374140e 100644 --- a/commons/zenoh-protocol/src/core/wire_expr.rs +++ b/commons/zenoh-protocol/src/core/wire_expr.rs @@ -17,11 +17,12 @@ use alloc::{ borrow::Cow, string::{String, ToString}, }; -use core::{convert::TryInto, fmt}; +use core::{convert::TryInto, fmt, sync::atomic::AtomicU16}; use zenoh_result::{bail, ZResult}; /// A numerical Id mapped to a key expression. pub type ExprId = u16; +pub type AtomicExprId = AtomicU16; pub const EMPTY_EXPR_ID: ExprId = 0; /// A zenoh **resource** is represented by a pair composed by a **key** and a diff --git a/commons/zenoh-protocol/src/defaults.rs b/commons/zenoh-protocol/src/defaults.rs deleted file mode 100644 index d9fcc95244..0000000000 --- a/commons/zenoh-protocol/src/defaults.rs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::core::Bits; - -pub const FRAME_SN_RESOLUTION: Bits = Bits::U32; -pub const REQUEST_ID_RESOLUTION: Bits = Bits::U32; - -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. -pub const BATCH_SIZE: u16 = u16::MAX; diff --git a/commons/zenoh-protocol/src/lib.rs b/commons/zenoh-protocol/src/lib.rs index b0e151e173..3c37291e70 100644 --- a/commons/zenoh-protocol/src/lib.rs +++ b/commons/zenoh-protocol/src/lib.rs @@ -22,7 +22,6 @@ extern crate alloc; pub mod common; pub mod core; -pub mod defaults; pub mod scouting; pub mod transport; pub mod zenoh; diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs index bcc20faf12..b3d241920d 100644 --- a/commons/zenoh-protocol/src/transport/fragment.rs +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use crate::core::Reliability; -pub use crate::transport::uSN; +pub use crate::transport::TransportSn; use zenoh_buffers::ZSlice; /// # Fragment message @@ -71,7 +71,7 @@ pub mod flag { pub struct Fragment { pub reliability: Reliability, pub more: bool, - pub sn: uSN, + pub sn: TransportSn, pub qos: ext::QoS, pub payload: ZSlice, } @@ -96,7 +96,7 @@ impl Fragment { Reliability::BestEffort }; let more = rng.gen_bool(0.5); - let sn: uSN = rng.gen(); + let sn: TransportSn = rng.gen(); let qos = ext::QoS::rand(); let payload = ZSlice::rand(rng.gen_range(8..128)); @@ -115,7 +115,7 @@ impl Fragment { pub struct FragmentHeader { pub reliability: Reliability, pub more: bool, - pub sn: uSN, + pub sn: TransportSn, pub qos: ext::QoS, } @@ -132,7 +132,7 @@ impl FragmentHeader { Reliability::BestEffort }; let more = rng.gen_bool(0.5); - let sn: uSN = rng.gen(); + let sn: TransportSn = rng.gen(); let qos = ext::QoS::rand(); FragmentHeader { diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 686dede1bb..776132fbed 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::Reliability, transport::uSN, zenoh::ZenohMessage}; +use crate::{core::Reliability, transport::TransportSn, zenoh::ZenohMessage}; use alloc::vec::Vec; /// # Frame message @@ -69,7 +69,7 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Frame { pub reliability: Reliability, - pub sn: uSN, + pub sn: TransportSn, pub ext_qos: ext::QoS, pub payload: Vec, } @@ -120,7 +120,7 @@ impl Frame { } else { Reliability::BestEffort }; - let sn: uSN = rng.gen(); + let sn: TransportSn = rng.gen(); let qos = ext::QoS::rand(); let mut payload = vec![]; for _ in 0..rng.gen_range(1..4) { @@ -143,7 +143,7 @@ impl Frame { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct FrameHeader { pub reliability: Reliability, - pub sn: uSN, + pub sn: TransportSn, pub ext_qos: ext::QoS, } @@ -159,7 +159,7 @@ impl FrameHeader { } else { Reliability::BestEffort }; - let sn: uSN = rng.gen(); + let sn: TransportSn = rng.gen(); let qos = ext::QoS::rand(); FrameHeader { diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index f46ad4ec86..026a77591c 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -30,6 +30,13 @@ pub use init::{InitAck, InitSyn}; pub use keepalive::KeepAlive; pub use open::{OpenAck, OpenSyn}; +/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length +/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. +/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve +/// the boundary of the serialized messages. The length is encoded as little-endian. +/// In any case, the length of a message must not exceed 65_535 bytes. +pub type BatchSize = u16; + pub mod id { // pub const JOIN: u8 = 0x01; // For multicast communications only pub const INIT: u8 = 0x02; // For unicast communications only @@ -40,8 +47,8 @@ pub mod id { pub const FRAGMENT: u8 = 0x07; } -#[allow(non_camel_case_types)] -pub type uSN = u32; +pub type TransportSn = u32; +// pub const TRANSPORT_SN_RESOLUTION: Bits = Bits::U32; #[derive(Debug, Clone, PartialEq, Eq)] pub enum ConduitSnList { @@ -83,8 +90,8 @@ impl fmt::Display for ConduitSnList { /// The kind of reliability. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct ConduitSn { - pub reliable: uSN, - pub best_effort: uSN, + pub reliable: TransportSn, + pub best_effort: TransportSn, } // Zenoh messages at zenoh-transport level diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 9370583342..4992f1bed4 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::transport::uSN; +use crate::transport::TransportSn; use core::time::Duration; use zenoh_buffers::ZSlice; @@ -75,7 +75,7 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpenSyn { pub lease: Duration, - pub initial_sn: uSN, + pub initial_sn: TransportSn, pub cookie: ZSlice, pub ext_qos: Option, pub ext_shm: Option, @@ -127,7 +127,7 @@ impl OpenSyn { Duration::from_millis(rng.gen()) }; - let initial_sn: uSN = rng.gen(); + let initial_sn: TransportSn = rng.gen(); let cookie = ZSlice::rand(rng.gen_range(MIN..=MAX)); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZ64::rand()); @@ -149,7 +149,7 @@ impl OpenSyn { #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpenAck { pub lease: Duration, - pub initial_sn: uSN, + pub initial_sn: TransportSn, pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, @@ -170,7 +170,7 @@ impl OpenAck { Duration::from_millis(rng.gen()) }; - let initial_sn: uSN = rng.gen(); + let initial_sn: TransportSn = rng.gen(); let ext_qos = rng.gen_bool(0.5).then_some(ZExtUnit::rand()); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZ64::rand()); let ext_auth = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs index 277994792e..5851f41935 100644 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ b/commons/zenoh-protocol/src/zenoh/data.rs @@ -13,7 +13,8 @@ // use crate::{ core::{CongestionControl, Encoding, Timestamp, WireExpr, ZenohId}, - transport::uSN, + transport::TransportSn, + zenoh::QueryId, }; use core::{convert::TryFrom, fmt}; use zenoh_buffers::ZBuf; @@ -75,13 +76,13 @@ pub struct ReplierInfo { } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ReplyContext { - pub qid: uSN, + pub qid: QueryId, pub replier: Option, } impl ReplyContext { // Note: id replier_id=None flag F is set, meaning it's a REPLY_FINAL - pub fn new(qid: uSN, replier: Option) -> Self { + pub fn new(qid: QueryId, replier: Option) -> Self { Self { qid, replier } } @@ -97,7 +98,7 @@ impl ReplyContext { let mut rng = rand::thread_rng(); - let qid: uSN = rng.gen(); + let qid: QueryId = rng.gen(); let replier = if rng.gen_bool(0.5) { Some(ReplierInfo { id: ZenohId::default(), @@ -154,7 +155,7 @@ pub struct DataInfo { pub encoding: Option, pub timestamp: Option, pub source_id: Option, - pub source_sn: Option, + pub source_sn: Option, } impl DataInfo { diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index dffb4f2899..19bed33002 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -20,7 +20,6 @@ mod routing; mod unit; use crate::core::{Channel, CongestionControl, Reliability, WireExpr}; -use crate::transport::uSN; use alloc::{string::String, vec::Vec}; use core::fmt; pub use data::*; @@ -280,7 +279,7 @@ impl ZenohMessage { pub fn make_query( key: WireExpr<'static>, parameters: String, - qid: uSN, + qid: QueryId, target: Option, consolidation: ConsolidationMode, body: Option, diff --git a/commons/zenoh-protocol/src/zenoh/query.rs b/commons/zenoh-protocol/src/zenoh/query.rs index 5aa6528821..cbe4531467 100644 --- a/commons/zenoh-protocol/src/zenoh/query.rs +++ b/commons/zenoh-protocol/src/zenoh/query.rs @@ -11,10 +11,15 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, transport::uSN, zenoh::DataInfo}; +use crate::{core::WireExpr, zenoh::DataInfo}; use alloc::string::String; +use core::sync::atomic::AtomicU32; use zenoh_buffers::ZBuf; +/// The resolution of a QueryId +pub type QueryId = u32; +pub type AtomicQueryId = AtomicU32; + /// The kind of consolidation. #[derive(Debug, Clone, PartialEq, Eq, Copy)] pub enum ConsolidationMode { @@ -101,7 +106,7 @@ impl QueryBody { pub struct Query { pub key: WireExpr<'static>, pub parameters: String, - pub qid: uSN, + pub qid: QueryId, pub target: Option, pub consolidation: ConsolidationMode, pub body: Option, @@ -130,7 +135,7 @@ impl Query { String::new() }; - let qid: uSN = rng.gen(); + let qid: QueryId = rng.gen(); let target = if rng.gen_bool(0.5) { let t = [ diff --git a/io/zenoh-links/zenoh-link-quic/src/lib.rs b/io/zenoh-links/zenoh-link-quic/src/lib.rs index 841e40aaaa..23a246b664 100644 --- a/io/zenoh-links/zenoh-link-quic/src/lib.rs +++ b/io/zenoh-links/zenoh-link-quic/src/lib.rs @@ -24,10 +24,13 @@ use config::{ }; use std::net::SocketAddr; use webpki::DnsNameRef; -use zenoh_config::{Config, Locator}; +use zenoh_config::Config; use zenoh_core::zconfigurable; use zenoh_link_commons::{ConfigurationInspector, LocatorInspector}; -use zenoh_protocol::core::endpoint::{self, Address}; +use zenoh_protocol::core::{ + endpoint::{self, Address}, + Locator, +}; use zenoh_result::{bail, zerror, ZResult}; mod unicast; diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index caea8f84d1..12dccca6d3 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -20,7 +20,9 @@ use zenoh_buffers::{ use zenoh_codec::{WCodec, Zenoh080}; use zenoh_protocol::{ core::Reliability, - transport::{fragment::FragmentHeader, frame::FrameHeader, uSN, TransportMessage}, + transport::{ + fragment::FragmentHeader, frame::FrameHeader, BatchSize, TransportMessage, TransportSn, + }, zenoh::ZenohMessage, }; @@ -46,8 +48,8 @@ pub(crate) enum CurrentFrame { #[derive(Clone, Copy, Debug)] pub(crate) struct LatestSn { - pub(crate) reliable: Option, - pub(crate) best_effort: Option, + pub(crate) reliable: Option, + pub(crate) best_effort: Option, } impl LatestSn { @@ -105,7 +107,7 @@ pub(crate) struct WBatch { } impl WBatch { - pub(crate) fn new(size: u16, is_streamed: bool) -> Self { + pub(crate) fn new(size: BatchSize, is_streamed: bool) -> Self { let mut batch = Self { buffer: BBuf::with_capacity(size as usize), is_streamed, @@ -132,10 +134,10 @@ impl WBatch { /// Get the total number of bytes that have been serialized on the [`SerializationBatch`][SerializationBatch]. #[inline(always)] - pub(crate) fn len(&self) -> u16 { - let len = self.buffer.len() as u16; + pub(crate) fn len(&self) -> BatchSize { + let len = self.buffer.len() as BatchSize; if self.is_streamed() { - len - (LENGTH_BYTES.len() as u16) + len - (LENGTH_BYTES.len() as BatchSize) } else { len } diff --git a/io/zenoh-transport/src/common/conduit.rs b/io/zenoh-transport/src/common/conduit.rs index 7ecf7ac6b5..f2192c362f 100644 --- a/io/zenoh-transport/src/common/conduit.rs +++ b/io/zenoh-transport/src/common/conduit.rs @@ -17,7 +17,7 @@ use std::sync::{Arc, Mutex}; use zenoh_core::zlock; use zenoh_protocol::{ core::{Bits, Reliability}, - transport::{uSN, ConduitSn}, + transport::{ConduitSn, TransportSn}, }; use zenoh_result::ZResult; @@ -34,7 +34,7 @@ impl TransportChannelTx { Ok(tch) } - pub(crate) fn sync(&mut self, sn: uSN) -> ZResult<()> { + pub(crate) fn sync(&mut self, sn: TransportSn) -> ZResult<()> { self.sn.set(sn) } } @@ -57,7 +57,7 @@ impl TransportChannelRx { Ok(tch) } - pub(crate) fn sync(&mut self, sn: uSN) -> ZResult<()> { + pub(crate) fn sync(&mut self, sn: TransportSn) -> ZResult<()> { // Set the sequence number in the state as it had received a message with sn - 1 let sn = if sn == 0 { self.sn.resolution() - 1 diff --git a/io/zenoh-transport/src/common/defragmentation.rs b/io/zenoh-transport/src/common/defragmentation.rs index 791e93ecdc..dae51f93a0 100644 --- a/io/zenoh-transport/src/common/defragmentation.rs +++ b/io/zenoh-transport/src/common/defragmentation.rs @@ -16,7 +16,7 @@ use zenoh_buffers::{reader::HasReader, SplitBuffer, ZBuf, ZSlice}; use zenoh_codec::{RCodec, Zenoh080Reliability}; use zenoh_protocol::{ core::{Bits, Reliability}, - transport::uSN, + transport::TransportSn, zenoh::ZenohMessage, }; use zenoh_result::{bail, ZResult}; @@ -58,11 +58,11 @@ impl DefragBuffer { } #[inline(always)] - pub(crate) fn sync(&mut self, sn: uSN) -> ZResult<()> { + pub(crate) fn sync(&mut self, sn: TransportSn) -> ZResult<()> { self.sn.set(sn) } - pub(crate) fn push(&mut self, sn: uSN, zslice: ZSlice) -> ZResult<()> { + pub(crate) fn push(&mut self, sn: TransportSn, zslice: ZSlice) -> ZResult<()> { if sn != self.sn.get() { self.clear(); bail!("Expected SN {}, received {}", self.sn.get(), sn) diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 517982bb8d..4d459d8914 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -36,7 +36,7 @@ use zenoh_protocol::{ transport::{ fragment::FragmentHeader, frame::{self, FrameHeader}, - TransportMessage, + BatchSize, TransportMessage, }, zenoh::ZenohMessage, }; @@ -74,7 +74,7 @@ struct StageInOut { impl StageInOut { #[inline] - fn notify(&self, bytes: u16) { + fn notify(&self, bytes: BatchSize) { self.bytes.store(bytes, Ordering::Relaxed); if !self.backoff.load(Ordering::Relaxed) { let _ = self.n_out_w.try_send(()); @@ -329,7 +329,7 @@ enum Pull { #[derive(Clone)] struct Backoff { retry_time: NanoSeconds, - last_bytes: u16, + last_bytes: BatchSize, bytes: Arc, backoff: Arc, } @@ -475,7 +475,7 @@ impl StageOut { #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) struct TransmissionPipelineConf { pub(crate) is_streamed: bool, - pub(crate) batch_size: u16, + pub(crate) batch_size: BatchSize, pub(crate) queue_size: [usize; Priority::NUM], pub(crate) backoff: Duration, } @@ -484,7 +484,7 @@ impl Default for TransmissionPipelineConf { fn default() -> Self { Self { is_streamed: false, - batch_size: u16::MAX, + batch_size: BatchSize::MAX, queue_size: [1; Priority::NUM], backoff: Duration::from_micros(1), } @@ -621,7 +621,7 @@ impl TransmissionPipelineProducer { // Unblock waiting pullers for ig in in_guards.iter_mut() { - ig.s_out.notify(u16::MAX); + ig.s_out.notify(BatchSize::MAX); } } } @@ -709,9 +709,8 @@ mod tests { }; use zenoh_codec::{RCodec, Zenoh080}; use zenoh_protocol::{ - core::{Channel, CongestionControl, Priority, Reliability}, - defaults::{BATCH_SIZE, FRAME_SN_RESOLUTION}, - transport::{Fragment, Frame, TransportBody}, + core::{Bits, Channel, CongestionControl, Priority, Reliability}, + transport::{BatchSize, Fragment, Frame, TransportBody, TransportSn}, zenoh::ZenohMessage, }; @@ -720,7 +719,7 @@ mod tests { const CONFIG: TransmissionPipelineConf = TransmissionPipelineConf { is_streamed: true, - batch_size: BATCH_SIZE, + batch_size: BatchSize::MAX, queue_size: [1; Priority::NUM], backoff: Duration::from_micros(1), }; @@ -812,7 +811,7 @@ mod tests { } // Pipeline conduits - let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION).unwrap(); + let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); let conduits = vec![tct]; // Total amount of bytes to send in each test @@ -898,7 +897,7 @@ mod tests { } // Pipeline - let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION).unwrap(); + let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); let conduits = vec![tct]; let (producer, mut consumer) = TransmissionPipeline::make(TransmissionPipelineConf::default(), conduits.as_slice()); @@ -950,7 +949,7 @@ mod tests { #[ignore] fn tx_pipeline_thr() { // Queue - let tct = TransportConduitTx::make(FRAME_SN_RESOLUTION).unwrap(); + let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); let conduits = vec![tct]; let (producer, mut consumer) = TransmissionPipeline::make(CONFIG, conduits.as_slice()); let count = Arc::new(AtomicUsize::new(0)); diff --git a/io/zenoh-transport/src/common/seq_num.rs b/io/zenoh-transport/src/common/seq_num.rs index ae15de5bfe..cf87b46b30 100644 --- a/io/zenoh-transport/src/common/seq_num.rs +++ b/io/zenoh-transport/src/common/seq_num.rs @@ -11,15 +11,15 @@ // Contributors: // ZettaScale Zenoh Team, // -use zenoh_protocol::{core::Bits, transport::uSN}; +use zenoh_protocol::{core::Bits, transport::TransportSn}; use zenoh_result::{bail, ZResult}; -const RES_U8: uSN = (u8::MAX >> 1) as uSN; // 1 byte max when encoded -const RES_U16: uSN = (u16::MAX >> 2) as uSN; // 2 bytes max when encoded -const RES_U32: uSN = (u32::MAX >> 4) as uSN; // 4 bytes max when encoded -const RES_U64: uSN = (u64::MAX >> 1) as uSN; // 9 bytes max when encoded +const RES_U8: TransportSn = (u8::MAX >> 1) as TransportSn; // 1 byte max when encoded +const RES_U16: TransportSn = (u16::MAX >> 2) as TransportSn; // 2 bytes max when encoded +const RES_U32: TransportSn = (u32::MAX >> 4) as TransportSn; // 4 bytes max when encoded +const RES_U64: TransportSn = (u64::MAX >> 1) as TransportSn; // 9 bytes max when encoded -pub(crate) fn get_mask(resolution: Bits) -> uSN { +pub(crate) fn get_mask(resolution: Bits) -> TransportSn { match resolution { Bits::U8 => RES_U8, Bits::U16 => RES_U16, @@ -39,8 +39,8 @@ pub(crate) fn get_mask(resolution: Bits) -> uSN { /// #[derive(Clone, Copy, Debug)] pub(crate) struct SeqNum { - value: uSN, - mask: uSN, + value: TransportSn, + mask: TransportSn, } impl SeqNum { @@ -60,22 +60,22 @@ impl SeqNum { /// This funtion will panic if `value` is out of bound w.r.t. `resolution`. That is if /// `value` is greater or equal than `resolution`. /// - pub(crate) fn make(value: uSN, resolution: Bits) -> ZResult { + pub(crate) fn make(value: TransportSn, resolution: Bits) -> ZResult { let mask = get_mask(resolution); let mut sn = SeqNum { value: 0, mask }; sn.set(value)?; Ok(sn) } - pub(crate) fn get(&self) -> uSN { + pub(crate) fn get(&self) -> TransportSn { self.value } - pub(crate) fn resolution(&self) -> uSN { + pub(crate) fn resolution(&self) -> TransportSn { self.mask } - pub(crate) fn set(&mut self, value: uSN) -> ZResult<()> { + pub(crate) fn set(&mut self, value: TransportSn) -> ZResult<()> { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -107,7 +107,7 @@ impl SeqNum { /// # Arguments /// /// * `value` - The sequence number which should be checked for precedence relation. - pub(crate) fn precedes(&self, value: uSN) -> ZResult { + pub(crate) fn precedes(&self, value: TransportSn) -> ZResult { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -117,7 +117,7 @@ impl SeqNum { /// Computes the modulo gap between two sequence numbers. #[cfg(test)] // @TODO: remove #[cfg(test)] once reliability is implemented - pub(crate) fn gap(&self, value: uSN) -> ZResult { + pub(crate) fn gap(&self, value: TransportSn) -> ZResult { if (value & !self.mask) != 0 { bail!("The sequence number value must be smaller than the resolution"); } @@ -145,23 +145,23 @@ impl SeqNumGenerator { /// This funtion will panic if `value` is out of bound w.r.t. `resolution`. That is if /// `value` is greater or equal than `resolution`. /// - pub(crate) fn make(initial_sn: uSN, resolution: Bits) -> ZResult { + pub(crate) fn make(initial_sn: TransportSn, resolution: Bits) -> ZResult { let sn = SeqNum::make(initial_sn, resolution)?; Ok(SeqNumGenerator(sn)) } - pub(crate) fn now(&mut self) -> uSN { + pub(crate) fn now(&mut self) -> TransportSn { self.0.get() } /// Generates the next sequence number - pub(crate) fn get(&mut self) -> uSN { + pub(crate) fn get(&mut self) -> TransportSn { let now = self.now(); self.0.increment(); now } - pub(crate) fn set(&mut self, sn: uSN) -> ZResult<()> { + pub(crate) fn set(&mut self, sn: TransportSn) -> ZResult<()> { self.0.set(sn) } } @@ -172,7 +172,7 @@ mod tests { #[test] fn sn_set() { - let mask = (u8::MAX >> 1) as uSN; + let mask = (u8::MAX >> 1) as TransportSn; let mut sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert_eq!(sn0a.get(), 0); @@ -193,7 +193,7 @@ mod tests { #[test] fn sn_gap() { - let mask = (u8::MAX >> 1) as uSN; + let mask = (u8::MAX >> 1) as TransportSn; let mut sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert_eq!(sn0a.gap(0).unwrap(), 0); @@ -208,7 +208,7 @@ mod tests { #[test] fn sn_precedence() { - let mask = (u8::MAX >> 1) as uSN; + let mask = (u8::MAX >> 1) as TransportSn; let sn0a = SeqNum::make(0, Bits::U8).unwrap(); assert!(sn0a.precedes(1).unwrap()); @@ -222,7 +222,7 @@ mod tests { #[test] fn sn_generation() { - let mask = (u8::MAX >> 1) as uSN; + let mask = (u8::MAX >> 1) as TransportSn; let mut sn0 = SeqNumGenerator::make(mask, Bits::U8).unwrap(); let mut sn1 = SeqNumGenerator::make(5, Bits::U8).unwrap(); diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index 0c85459657..395933df64 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -26,7 +26,7 @@ use zenoh_crypto::{BlockCipher, PseudoRng}; use zenoh_link::NewLinkChannelSender; use zenoh_protocol::{ core::{EndPoint, Field, Locator, Priority, Resolution, WhatAmI, ZenohId}, - defaults::BATCH_SIZE, + transport::BatchSize, VERSION, }; use zenoh_result::{bail, ZResult}; @@ -279,7 +279,7 @@ impl Default for TransportManagerBuilder { zid: ZenohId::rand(), whatami: zenoh_config::defaults::mode, resolution: Resolution::default(), - batch_size: BATCH_SIZE, + batch_size: BatchSize::MAX, queue_size: queue.size, queue_backoff: Duration::from_nanos(backoff), defrag_buff_size: link_rx.max_message_size().unwrap(), diff --git a/io/zenoh-transport/src/primitives/mod.rs b/io/zenoh-transport/src/primitives/mod.rs index 8ab370c6b5..c4eb006721 100644 --- a/io/zenoh-transport/src/primitives/mod.rs +++ b/io/zenoh-transport/src/primitives/mod.rs @@ -19,9 +19,9 @@ pub use mux::*; use zenoh_buffers::ZBuf; use zenoh_protocol::{ core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, - transport::uSN, zenoh::{ - ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo, + ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, + RoutingContext, SubInfo, }, }; @@ -63,7 +63,7 @@ pub trait Primitives: Send + Sync { &self, key_expr: &WireExpr, parameters: &str, - qid: uSN, + qid: QueryId, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -72,14 +72,14 @@ pub trait Primitives: Send + Sync { fn send_reply_data( &self, - qid: uSN, + qid: QueryId, replier_id: ZenohId, key_expr: WireExpr, info: Option, payload: ZBuf, ); - fn send_reply_final(&self, qid: uSN); + fn send_reply_final(&self, qid: QueryId); fn send_pull( &self, @@ -140,7 +140,7 @@ impl Primitives for DummyPrimitives { &self, _key_expr: &WireExpr, _parameters: &str, - _qid: uSN, + _qid: QueryId, _target: QueryTarget, _consolidation: ConsolidationMode, _body: Option, @@ -149,14 +149,14 @@ impl Primitives for DummyPrimitives { } fn send_reply_data( &self, - _qid: uSN, + _qid: QueryId, _replier_id: ZenohId, _key_expr: WireExpr, _info: Option, _payload: ZBuf, ) { } - fn send_reply_final(&self, _qid: uSN) {} + fn send_reply_final(&self, _qid: QueryId) {} fn send_pull( &self, _is_final: bool, diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index 3832054e9c..8ba03e3f78 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -16,10 +16,9 @@ use super::Primitives; use zenoh_buffers::ZBuf; use zenoh_protocol::{ core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, - transport::uSN, zenoh::{ zmsg, ConsolidationMode, DataInfo, Declaration, ForgetPublisher, ForgetQueryable, - ForgetResource, ForgetSubscriber, Publisher, QueryBody, QueryTarget, Queryable, + ForgetResource, ForgetSubscriber, Publisher, QueryBody, QueryId, QueryTarget, Queryable, QueryableInfo, ReplierInfo, ReplyContext, Resource, RoutingContext, SubInfo, Subscriber, ZenohMessage, }, @@ -151,7 +150,7 @@ impl Primitives for Mux { &self, key_expr: &WireExpr, parameters: &str, - qid: uSN, + qid: QueryId, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -175,7 +174,7 @@ impl Primitives for Mux { fn send_reply_data( &self, - qid: uSN, + qid: QueryId, replier_id: ZenohId, key_expr: WireExpr, data_info: Option, @@ -192,7 +191,7 @@ impl Primitives for Mux { )); } - fn send_reply_final(&self, qid: uSN) { + fn send_reply_final(&self, qid: QueryId) { let _ = self.handler.handle_message(ZenohMessage::make_unit( zmsg::default_channel::REPLY, zmsg::default_congestion_control::REPLY, diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 68d5b811d4..0b57a9e6b2 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -33,7 +33,7 @@ use zenoh_protocol::{ core::{Field, Resolution, WhatAmI, ZenohId}, transport::{ close::{self, Close}, - uSN, InitAck, OpenAck, TransportBody, TransportMessage, + BatchSize, InitAck, OpenAck, TransportBody, TransportMessage, TransportSn, }, }; use zenoh_result::ZResult; @@ -41,7 +41,7 @@ use zenoh_result::ZResult; pub(super) type AcceptError = (zenoh_result::Error, Option); struct StateZenoh { - batch_size: u16, + batch_size: BatchSize, resolution: Resolution, } @@ -89,7 +89,7 @@ struct RecvOpenSynOut { other_zid: ZenohId, other_whatami: WhatAmI, other_lease: Duration, - other_initial_sn: uSN, + other_initial_sn: TransportSn, } // OpenAck diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index d939e0d28f..828e5e6506 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -28,7 +28,7 @@ use std::time::Duration; use zenoh_link::{Link, LinkUnicast}; use zenoh_protocol::{ core::{Field, Resolution, ZenohId}, - transport::{uSN, Close, TransportMessage}, + transport::{Close, TransportMessage, TransportSn}, }; use zenoh_result::ZResult; @@ -104,16 +104,16 @@ pub trait AcceptFsm { /*************************************/ /* FUNCTIONS */ /*************************************/ -pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) -> uSN { +pub(super) fn compute_sn(zid1: ZenohId, zid2: ZenohId, resolution: Resolution) -> TransportSn { // Create a random yet deterministic initial_sn. // In case of multilink it's important that the same initial_sn is used for every connection attempt. // Instead of storing the state everywhere, we make sure that the we always compute the same initial_sn. let mut hasher = Shake128::default(); hasher.update(zid1.as_slice()); hasher.update(zid2.as_slice()); - let mut array = (0 as uSN).to_le_bytes(); + let mut array = (0 as TransportSn).to_le_bytes(); hasher.finalize_xof().read(&mut array); - uSN::from_le_bytes(array) & seq_num::get_mask(resolution.get(Field::FrameSN)) + TransportSn::from_le_bytes(array) & seq_num::get_mask(resolution.get(Field::FrameSN)) } pub(super) async fn close_link(link: &LinkUnicast, reason: Option) { diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 88546b8c87..832d042fec 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -22,21 +22,22 @@ use crate::{ use async_trait::async_trait; use std::time::Duration; use zenoh_buffers::ZSlice; -use zenoh_config::{WhatAmI, ZenohId}; #[cfg(feature = "transport_auth")] use zenoh_core::zasynclock; use zenoh_core::{zcondfeat, zerror}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; -use zenoh_protocol::core::{Field, Resolution}; -use zenoh_protocol::transport::{ - close, uSN, Close, InitSyn, OpenSyn, TransportBody, TransportMessage, +use zenoh_protocol::{ + core::{Field, Resolution, WhatAmI, ZenohId}, + transport::{ + close, BatchSize, Close, InitSyn, OpenSyn, TransportBody, TransportMessage, TransportSn, + }, }; use zenoh_result::ZResult; type OpenError = (zenoh_result::Error, Option); struct StateZenoh { - batch_size: u16, + batch_size: BatchSize, resolution: Resolution, } @@ -78,13 +79,13 @@ struct SendOpenSynIn { } struct SendOpenSynOut { - mine_initial_sn: uSN, + mine_initial_sn: TransportSn, } // OpenAck struct RecvOpenAckOut { other_lease: Duration, - other_initial_sn: uSN, + other_initial_sn: TransportSn, } // FSM diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 9aa0d4a018..1d97e2fd2f 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -34,7 +34,7 @@ use zenoh_core::zcondfeat; use zenoh_link::Link; use zenoh_protocol::{ core::{Bits, WhatAmI, ZenohId}, - transport::{close, uSN}, + transport::{close, TransportSn}, zenoh::ZenohMessage, }; use zenoh_result::{zerror, ZResult}; @@ -88,7 +88,7 @@ pub(crate) struct TransportConfigUnicast { pub(crate) zid: ZenohId, pub(crate) whatami: WhatAmI, pub(crate) sn_resolution: Bits, - pub(crate) tx_initial_sn: uSN, + pub(crate) tx_initial_sn: TransportSn, pub(crate) is_qos: bool, #[cfg(feature = "transport_multilink")] pub(crate) multilink: Option, diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index 00c5babd4a..ae27a68de5 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -23,7 +23,7 @@ use zenoh_link::LinkUnicast; use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::{ core::{Priority, Reliability}, - transport::{uSN, Close, Fragment, Frame, KeepAlive, TransportBody, TransportMessage}, + transport::{Close, Fragment, Frame, KeepAlive, TransportBody, TransportMessage, TransportSn}, zenoh::ZenohMessage, }; use zenoh_result::{bail, zerror, ZResult}; @@ -183,7 +183,11 @@ impl TransportUnicastInner { Ok(()) } - fn verify_sn(&self, sn: uSN, guard: &mut MutexGuard<'_, TransportChannelRx>) -> ZResult<()> { + fn verify_sn( + &self, + sn: TransportSn, + guard: &mut MutexGuard<'_, TransportChannelRx>, + ) -> ZResult<()> { let precedes = guard.sn.precedes(sn)?; if !precedes { log::debug!( diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index de10b6565c..07b39f494e 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -24,7 +24,7 @@ use zenoh_core::{zasynclock, zcondfeat, zread, zwrite}; use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ core::{Bits, Priority, WhatAmI, ZenohId}, - transport::{uSN, Close, ConduitSn, TransportMessage}, + transport::{Close, ConduitSn, TransportMessage, TransportSn}, }; use zenoh_result::{bail, zerror, ZResult}; @@ -125,7 +125,7 @@ impl TransportUnicastInner { /*************************************/ /* INITIATION */ /*************************************/ - pub(super) async fn sync(&self, initial_sn_rx: uSN) -> ZResult<()> { + pub(super) async fn sync(&self, initial_sn_rx: TransportSn) -> ZResult<()> { // Mark the transport as alive and keep the lock // to avoid concurrent new_transport and closing/closed notifications let mut a_guard = zasynclock!(self.alive); diff --git a/zenoh/src/info.rs b/zenoh/src/info.rs index cc89cac70f..067e7f4b20 100644 --- a/zenoh/src/info.rs +++ b/zenoh/src/info.rs @@ -15,8 +15,8 @@ //! Tools to access information about the current zenoh [`Session`](crate::Session). use crate::SessionRef; use std::future::Ready; -use zenoh_config::{WhatAmI, ZenohId}; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; +use zenoh_protocol::core::{WhatAmI, ZenohId}; /// A builder retuned by [`SessionInfo::zid()`](SessionInfo::zid) that allows /// to access the [`ZenohId`] of the current zenoh [`Session`](crate::Session). diff --git a/zenoh/src/lib.rs b/zenoh/src/lib.rs index b702d50d8a..a1e4070621 100644 --- a/zenoh/src/lib.rs +++ b/zenoh/src/lib.rs @@ -83,11 +83,11 @@ use git_version::git_version; use handlers::DefaultHandler; #[zenoh_core::unstable] use net::runtime::Runtime; -use prelude::config::whatami::WhatAmIMatcher; use prelude::*; use scouting::ScoutBuilder; use std::future::Ready; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; +use zenoh_protocol::core::WhatAmIMatcher; use zenoh_result::{zerror, ZResult}; /// A zenoh error. diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index ed17a2d27b..b366fd8b83 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -17,11 +17,11 @@ use std::fmt; use std::sync::Arc; use std::sync::RwLock; use zenoh_buffers::ZBuf; -use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{Channel, CongestionControl, ExprId, WhatAmI, WireExpr, ZenohId}, zenoh::{ - ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo, + ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, + RoutingContext, SubInfo, }, }; use zenoh_transport::Primitives; @@ -38,8 +38,8 @@ pub struct FaceState { pub(super) remote_subs: HashSet>, pub(super) local_qabls: HashMap, QueryableInfo>, pub(super) remote_qabls: HashSet>, - pub(super) next_qid: uSN, - pub(super) pending_queries: HashMap>, + pub(super) next_qid: QueryId, + pub(super) pending_queries: HashMap>, } impl FaceState { @@ -358,7 +358,7 @@ impl Primitives for Face { &self, key_expr: &WireExpr, parameters: &str, - qid: uSN, + qid: QueryId, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -379,7 +379,7 @@ impl Primitives for Face { fn send_reply_data( &self, - qid: uSN, + qid: QueryId, replier_id: ZenohId, key_expr: WireExpr, info: Option, @@ -396,7 +396,7 @@ impl Primitives for Face { ); } - fn send_reply_final(&self, qid: uSN) { + fn send_reply_final(&self, qid: QueryId) { route_send_reply_final(&self.tables, &mut self.state.clone(), qid); } diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index 48393ef3ad..a5bad55684 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -16,10 +16,9 @@ use petgraph::graph::NodeIndex; use petgraph::visit::{IntoNodeReferences, VisitMap, Visitable}; use std::convert::TryInto; use vec_map::VecMap; -use zenoh_config::whatami::WhatAmIMatcher; use zenoh_link::Locator; use zenoh_protocol::{ - core::{WhatAmI, ZenohId}, + core::{WhatAmI, WhatAmIMatcher, ZenohId}, zenoh::{LinkState, ZenohMessage}, }; use zenoh_transport::TransportUnicast; diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 2697032e73..3de44c6df2 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -24,7 +24,6 @@ use std::convert::TryFrom; use std::sync::Arc; use std::sync::{RwLock, Weak}; use zenoh_buffers::ZBuf; -use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{ key_expr::{ @@ -33,14 +32,16 @@ use zenoh_protocol::{ }, WhatAmI, WireExpr, ZenohId, }, - zenoh::{ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext}, + zenoh::{ + ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, RoutingContext, + }, }; use zenoh_sync::get_mut_unchecked; use zenoh_util::Timed; pub(crate) struct Query { src_face: Arc, - src_qid: uSN, + src_qid: QueryId, } #[cfg(feature = "complete_n")] @@ -1317,7 +1318,7 @@ pub(crate) fn compute_matches_query_routes(tables: &mut Tables, res: &mut Arc, query: Arc) -> uSN { +fn insert_pending_query(outface: &mut Arc, query: Arc) -> QueryId { let outface_mut = get_mut_unchecked(outface); outface_mut.next_qid += 1; let qid = outface_mut.next_qid; @@ -1486,7 +1487,7 @@ fn compute_final_route( struct QueryCleanup { tables: Arc>, face: Weak, - qid: uSN, + qid: QueryId, } #[async_trait] @@ -1592,7 +1593,7 @@ pub fn route_query( face: &Arc, expr: &WireExpr, parameters: &str, - qid: uSN, + qid: QueryId, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -1706,7 +1707,7 @@ pub fn route_query( pub(crate) fn route_send_reply_data( tables_ref: &RwLock, face: &mut Arc, - qid: uSN, + qid: QueryId, replier_id: ZenohId, key_expr: WireExpr, info: Option, @@ -1736,7 +1737,7 @@ pub(crate) fn route_send_reply_data( pub(crate) fn route_send_reply_final( tables_ref: &RwLock, face: &mut Arc, - qid: uSN, + qid: QueryId, ) { let tables_lock = zwrite!(tables_ref); match get_mut_unchecked(face).pending_queries.remove(&qid) { diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index e9ef940fb8..afe517e68a 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -18,10 +18,9 @@ use std::convert::TryInto; use std::hash::{Hash, Hasher}; use std::sync::{Arc, Weak}; use zenoh_buffers::ZBuf; -use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{key_expr::keyexpr, ExprId, WireExpr, ZenohId}, - zenoh::{DataInfo, QueryableInfo, RoutingContext, SubInfo}, + zenoh::{DataInfo, QueryId, QueryableInfo, RoutingContext, SubInfo}, }; use zenoh_sync::get_mut_unchecked; @@ -30,7 +29,7 @@ pub(super) type Route = HashMap; #[cfg(feature = "complete_n")] pub(super) type QueryRoute = HashMap; #[cfg(not(feature = "complete_n"))] -pub(super) type QueryRoute = HashMap; +pub(super) type QueryRoute = HashMap; pub(super) struct QueryTargetQabl { pub(super) direction: Direction, pub(super) complete: u64, diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index 4a6469fcea..14e7516139 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -26,10 +26,9 @@ use std::sync::{Arc, Weak}; use std::sync::{Mutex, RwLock}; use std::time::Duration; use uhlc::HLC; -use zenoh_config::whatami::WhatAmIMatcher; use zenoh_link::Link; use zenoh_protocol::{ - core::{ExprId, WhatAmI, ZenohId}, + core::{ExprId, WhatAmI, WhatAmIMatcher, ZenohId}, zenoh::{ZenohBody, ZenohMessage}, }; use zenoh_transport::{DeMux, Mux, Primitives, TransportPeerEventHandler, TransportUnicast}; diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index f05a02f2b8..4cf7b67c39 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -24,16 +24,14 @@ use std::sync::Arc; use std::sync::Mutex; use zenoh_buffers::{SplitBuffer, ZBuf}; use zenoh_config::ValidatedMap; -use zenoh_config::WhatAmI; -use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{ key_expr::OwnedKeyExpr, Channel, CongestionControl, Encoding, ExprId, KnownEncoding, - WireExpr, ZenohId, EMPTY_EXPR_ID, + WhatAmI, WireExpr, ZenohId, EMPTY_EXPR_ID, }, zenoh::{ - ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, - SampleKind, SubInfo, + ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, + RoutingContext, SampleKind, SubInfo, }, }; use zenoh_result::ZResult; @@ -367,7 +365,7 @@ impl Primitives for AdminSpace { &self, key_expr: &WireExpr, parameters: &str, - qid: uSN, + qid: QueryId, target: QueryTarget, _consolidation: ConsolidationMode, _body: Option, @@ -474,7 +472,7 @@ impl Primitives for AdminSpace { fn send_reply_data( &self, - qid: uSN, + qid: QueryId, replier_id: ZenohId, key_expr: WireExpr, info: Option, @@ -490,7 +488,7 @@ impl Primitives for AdminSpace { ); } - fn send_reply_final(&self, qid: uSN) { + fn send_reply_final(&self, qid: QueryId) { trace!("recv ReplyFinal {:?}", qid); } diff --git a/zenoh/src/net/runtime/orchestrator.rs b/zenoh/src/net/runtime/orchestrator.rs index a04b989658..55e2ec307a 100644 --- a/zenoh/src/net/runtime/orchestrator.rs +++ b/zenoh/src/net/runtime/orchestrator.rs @@ -21,10 +21,10 @@ use std::time::Duration; use zenoh_buffers::reader::DidntRead; use zenoh_buffers::{reader::HasReader, writer::HasWriter}; use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_config::{unwrap_or_default, EndPoint, ModeDependent}; +use zenoh_config::{unwrap_or_default, ModeDependent}; use zenoh_link::Locator; use zenoh_protocol::{ - core::{whatami::WhatAmIMatcher, WhatAmI, ZenohId}, + core::{whatami::WhatAmIMatcher, EndPoint, WhatAmI, ZenohId}, scouting::{Hello, Scout, ScoutingBody, ScoutingMessage}, }; use zenoh_result::{bail, zerror, ZResult}; diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index a38e2b5407..1de5c23637 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -18,15 +18,14 @@ use std::time::Duration; use uhlc::HLC; use zenoh_buffers::ZBuf; use zenoh_core::zlock; -use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{ key_expr::keyexpr, Channel, CongestionControl, ExprId, Reliability, WhatAmI, WireExpr, ZenohId, EMPTY_EXPR_ID, }, zenoh::{ - ConsolidationMode, DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, - SubInfo, SubMode, + ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, + RoutingContext, SubInfo, SubMode, }, }; use zenoh_transport::{DummyPrimitives, Primitives}; @@ -463,7 +462,7 @@ impl Primitives for ClientPrimitives { &self, _key_expr: &WireExpr, _parameters: &str, - _qid: uSN, + _qid: QueryId, _target: QueryTarget, _consolidation: ConsolidationMode, _body: Option, @@ -473,14 +472,14 @@ impl Primitives for ClientPrimitives { fn send_reply_data( &self, - _qid: uSN, + _qid: QueryId, _replier_id: ZenohId, _key_expr: WireExpr, _info: Option, _payload: ZBuf, ) { } - fn send_reply_final(&self, _qid: uSN) {} + fn send_reply_final(&self, _qid: QueryId) {} fn send_pull( &self, diff --git a/zenoh/src/prelude.rs b/zenoh/src/prelude.rs index 5f95b2e995..82dd345ea4 100644 --- a/zenoh/src/prelude.rs +++ b/zenoh/src/prelude.rs @@ -50,8 +50,10 @@ pub(crate) mod common { pub use zenoh_protocol::zenoh::{ConsolidationMode, SampleKind}; pub use crate::publication::Priority; - pub use zenoh_protocol::core::{CongestionControl, Reliability}; + pub use zenoh_protocol::core::{CongestionControl, WhatAmI, Reliability}; + /// A [`Locator`] contains a choice of protocol, an address and port, as well as optional additional properties to work with. + pub use zenoh_protocol::core::EndPoint; /// A [`Locator`] contains a choice of protocol, an address and port, as well as optional additional properties to work with. pub use zenoh_protocol::core::Locator; /// The global unique id of a zenoh peer. diff --git a/zenoh/src/sample.rs b/zenoh/src/sample.rs index 90f08cb743..6d6fccf421 100644 --- a/zenoh/src/sample.rs +++ b/zenoh/src/sample.rs @@ -21,7 +21,7 @@ use crate::time::{new_reception_timestamp, Timestamp}; #[zenoh_core::unstable] use serde::Serialize; use std::convert::TryInto; -use zenoh_protocol::{transport::uSN, zenoh::DataInfo}; +use zenoh_protocol::{transport::TransportSn, zenoh::DataInfo}; /// The locality of samples to be received by subscribers or targeted by publishers. #[zenoh_core::unstable] @@ -47,7 +47,7 @@ pub struct SourceInfo { /// The [`ZenohId`] of the zenoh instance that published the concerned [`Sample`]. pub source_id: Option, /// The sequence number of the [`Sample`] from the source. - pub source_sn: Option, + pub source_sn: Option, } #[test] diff --git a/zenoh/src/scouting.rs b/zenoh/src/scouting.rs index 803888da18..3b2277557a 100644 --- a/zenoh/src/scouting.rs +++ b/zenoh/src/scouting.rs @@ -17,8 +17,8 @@ use crate::net::runtime::{orchestrator::Loop, Runtime}; use async_std::net::UdpSocket; use futures::StreamExt; use std::{fmt, future::Ready, net::SocketAddr, ops::Deref}; -use zenoh_config::whatami::WhatAmIMatcher; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; +use zenoh_protocol::core::WhatAmIMatcher; use zenoh_result::ZResult; /// Constants and helpers for zenoh `whatami` flags. diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index f755ad2efb..d3ddcf6b27 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -42,7 +42,7 @@ use std::collections::HashMap; use std::convert::TryInto; use std::fmt; use std::ops::Deref; -use std::sync::atomic::{AtomicU16, AtomicU32, AtomicU64, AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicU16, AtomicUsize, Ordering}; use std::sync::Arc; use std::sync::RwLock; use std::time::Duration; @@ -51,19 +51,19 @@ use zenoh_buffers::ZBuf; use zenoh_collections::SingleOrVec; use zenoh_config::unwrap_or_default; use zenoh_core::{zconfigurable, zread, Resolve, ResolveClosure, ResolveFuture, SyncResolve}; -use zenoh_protocol::transport::uSN; use zenoh_protocol::{ core::{ key_expr::{keyexpr, OwnedKeyExpr}, - Channel, CongestionControl, ExprId, WireExpr, ZenohId, EMPTY_EXPR_ID, + AtomicExprId, Channel, CongestionControl, ExprId, WireExpr, ZenohId, EMPTY_EXPR_ID, + }, + zenoh::{ + AtomicQueryId, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, RoutingContext, + SubInfo, }, - zenoh::{DataInfo, QueryBody, QueryTarget, QueryableInfo, RoutingContext, SubInfo}, }; use zenoh_result::ZResult; use zenoh_util::core::AsyncResolve; -pub type Atomicu64 = AtomicU64; - zconfigurable! { pub(crate) static ref API_DATA_RECEPTION_CHANNEL_SIZE: usize = 256; pub(crate) static ref API_QUERY_RECEPTION_CHANNEL_SIZE: usize = 256; @@ -74,15 +74,15 @@ zconfigurable! { pub(crate) struct SessionState { pub(crate) primitives: Option>, // @TODO replace with MaybeUninit ?? - pub(crate) expr_id_counter: AtomicU16, // @TODO: manage rollover and uniqueness - pub(crate) qid_counter: AtomicU32, + pub(crate) expr_id_counter: AtomicExprId, // @TODO: manage rollover and uniqueness + pub(crate) qid_counter: AtomicQueryId, pub(crate) decl_id_counter: AtomicUsize, pub(crate) local_resources: HashMap, pub(crate) remote_resources: HashMap, pub(crate) publications: Vec, pub(crate) subscribers: HashMap>, pub(crate) queryables: HashMap>, - pub(crate) queries: HashMap, + pub(crate) queries: HashMap, pub(crate) aggregated_subscribers: Vec, pub(crate) aggregated_publishers: Vec, } @@ -94,8 +94,8 @@ impl SessionState { ) -> SessionState { SessionState { primitives: None, - expr_id_counter: AtomicU16::new(1), // Note: start at 1 because 0 is reserved for NO_RESOURCE - qid_counter: AtomicU32::new(0), + expr_id_counter: AtomicExprId::new(1), // Note: start at 1 because 0 is reserved for NO_RESOURCE + qid_counter: AtomicQueryId::new(0), decl_id_counter: AtomicUsize::new(0), local_resources: HashMap::new(), remote_resources: HashMap::new(), @@ -1404,7 +1404,7 @@ impl Session { local: bool, key_expr: &WireExpr, parameters: &str, - qid: uSN, + qid: QueryId, _target: QueryTarget, _consolidation: ConsolidationMode, body: Option, @@ -1714,7 +1714,7 @@ impl Primitives for Session { &self, key_expr: &WireExpr, parameters: &str, - qid: uSN, + qid: QueryId, target: QueryTarget, consolidation: ConsolidationMode, body: Option, @@ -1740,7 +1740,7 @@ impl Primitives for Session { fn send_reply_data( &self, - qid: uSN, + qid: QueryId, replier_id: ZenohId, key_expr: WireExpr, data_info: Option, @@ -1853,7 +1853,7 @@ impl Primitives for Session { } } - fn send_reply_final(&self, qid: uSN) { + fn send_reply_final(&self, qid: QueryId) { trace!("recv ReplyFinal {:?}", qid); let mut state = zwrite!(self.state); match state.queries.get_mut(&qid) { diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index dbd7272f51..d6161e097b 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -15,10 +15,9 @@ use async_std::task; use clap::{ArgMatches, Command}; use futures::future; use git_version::git_version; -use zenoh::config::{ - Config, EndPoint, ModeDependentValue, PermissionsConf, PluginLoad, ValidatedMap, -}; +use zenoh::config::{Config, ModeDependentValue, PermissionsConf, PluginLoad, ValidatedMap}; use zenoh::plugins::PluginsManager; +use zenoh::prelude::{EndPoint, WhatAmI}; use zenoh::runtime::{AdminSpace, Runtime}; const GIT_VERSION: &str = git_version!(prefix = "v", cargo_prefix = "v"); @@ -141,7 +140,7 @@ fn config_from_args(args: &ArgMatches) -> Config { }); if config.mode().is_none() { config - .set_mode(Some(zenoh::config::WhatAmI::Router)) + .set_mode(Some(WhatAmI::Router)) .unwrap(); } if args.occurrences_of("id") > 0 { From b3ac84aa27570ddeaf704e4d15c537e632109dc5 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 15 Mar 2023 17:11:12 +0100 Subject: [PATCH 095/203] Add bounded codec for ZInt, Vec, and String --- commons/zenoh-codec/src/core/endpoint.rs | 75 ------- commons/zenoh-codec/src/core/locator.rs | 8 +- commons/zenoh-codec/src/core/mod.rs | 122 ++++++++-- .../src/core/{keyexpr.rs => wire_expr.rs} | 18 +- commons/zenoh-codec/src/core/zint.rs | 211 ++++++++---------- commons/zenoh-codec/src/lib.rs | 12 + commons/zenoh-codec/src/zenoh/data.rs | 5 +- commons/zenoh-codec/tests/codec.rs | 94 ++++++-- commons/zenoh-protocol/src/core/endpoint.rs | 2 +- commons/zenoh-protocol/src/core/wire_expr.rs | 2 + commons/zenoh-protocol/src/zenoh/data.rs | 5 +- zenoh/src/sample.rs | 4 +- 12 files changed, 305 insertions(+), 253 deletions(-) delete mode 100644 commons/zenoh-codec/src/core/endpoint.rs rename commons/zenoh-codec/src/core/{keyexpr.rs => wire_expr.rs} (68%) diff --git a/commons/zenoh-codec/src/core/endpoint.rs b/commons/zenoh-codec/src/core/endpoint.rs deleted file mode 100644 index 0d0dd1e80e..0000000000 --- a/commons/zenoh-codec/src/core/endpoint.rs +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{RCodec, WCodec, Zenoh080}; -use alloc::{string::String, vec::Vec}; -use core::convert::TryFrom; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, -}; -use zenoh_protocol::core::EndPoint; - -impl WCodec<&EndPoint, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &EndPoint) -> Self::Output { - self.write(writer, x.as_str()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let loc: String = self.read(reader)?; - EndPoint::try_from(loc).map_err(|_| DidntRead) - } -} - -impl WCodec<&[EndPoint], &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &[EndPoint]) -> Self::Output { - self.write(&mut *writer, x.len())?; - for l in x { - self.write(&mut *writer, l)?; - } - Ok(()) - } -} - -impl RCodec, &mut R> for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result, Self::Error> { - let len = self.read(&mut *reader)?; - let mut vec: Vec = Vec::with_capacity(len); - for _ in 0..len { - vec.push(self.read(&mut *reader)?); - } - Ok(vec) - } -} diff --git a/commons/zenoh-codec/src/core/locator.rs b/commons/zenoh-codec/src/core/locator.rs index d5daab0916..49a254fbd5 100644 --- a/commons/zenoh-codec/src/core/locator.rs +++ b/commons/zenoh-codec/src/core/locator.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use alloc::{string::String, vec::Vec}; use core::convert::TryFrom; use zenoh_buffers::{ @@ -27,7 +27,8 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Locator) -> Self::Output { - self.write(writer, x.as_str()) + let zodec = Zenoh080Bounded::::new(); + zodec.write(writer, x.as_str()) } } @@ -38,7 +39,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let loc: String = self.read(reader)?; + let zodec = Zenoh080Bounded::::new(); + let loc: String = zodec.read(reader)?; Locator::try_from(loc).map_err(|_| DidntRead) } } diff --git a/commons/zenoh-codec/src/core/mod.rs b/commons/zenoh-codec/src/core/mod.rs index 56742815ee..be444a2fb7 100644 --- a/commons/zenoh-codec/src/core/mod.rs +++ b/commons/zenoh-codec/src/core/mod.rs @@ -12,19 +12,18 @@ // ZettaScale Zenoh Team, // mod encoding; -mod endpoint; -mod keyexpr; mod locator; mod property; #[cfg(feature = "shared-memory")] mod shm; mod timestamp; +mod wire_expr; mod zbuf; mod zenohid; mod zint; mod zslice; -use crate::{RCodec, WCodec, Zenoh080}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use alloc::{string::String, vec::Vec}; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -88,6 +87,50 @@ array_impl!(14); array_impl!(15); array_impl!(16); +// &[u8] / Vec - Bounded +macro_rules! vec_impl { + ($bound:ty) => { + impl WCodec<&[u8], &mut W> for Zenoh080Bounded<$bound> + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &[u8]) -> Self::Output { + self.write(&mut *writer, x.len())?; + if x.is_empty() { + Ok(()) + } else { + writer.write_exact(x) + } + } + } + + impl RCodec, &mut R> for Zenoh080Bounded<$bound> + where + R: Reader, + { + type Error = DidntRead; + + #[allow(clippy::uninit_vec)] + fn read(self, reader: &mut R) -> Result, Self::Error> { + let len: usize = self.read(&mut *reader)?; + let mut buff = zenoh_buffers::vec::uninit(len); + if len != 0 { + reader.read_exact(&mut buff[..])?; + } + Ok(buff) + } + } + }; +} + +vec_impl!(u8); +vec_impl!(u16); +vec_impl!(u32); +vec_impl!(u64); +vec_impl!(usize); + // &[u8] / Vec impl WCodec<&[u8], &mut W> for Zenoh080 where @@ -96,12 +139,8 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &[u8]) -> Self::Output { - self.write(&mut *writer, x.len())?; - if x.is_empty() { - Ok(()) - } else { - writer.write_exact(x) - } + let zcodec = Zenoh080Bounded::::new(); + zcodec.write(&mut *writer, x) } } @@ -111,17 +150,58 @@ where { type Error = DidntRead; - #[allow(clippy::uninit_vec)] fn read(self, reader: &mut R) -> Result, Self::Error> { - let len: usize = self.read(&mut *reader)?; - let mut buff = zenoh_buffers::vec::uninit(len); - if len != 0 { - reader.read_exact(&mut buff[..])?; - } - Ok(buff) + let zcodec = Zenoh080Bounded::::new(); + zcodec.read(&mut *reader) } } +// &str / String - Bounded +macro_rules! str_impl { + ($bound:ty) => { + impl WCodec<&str, &mut W> for Zenoh080Bounded<$bound> + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &str) -> Self::Output { + self.write(&mut *writer, x.as_bytes()) + } + } + + impl WCodec<&String, &mut W> for Zenoh080Bounded<$bound> + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &String) -> Self::Output { + self.write(&mut *writer, x.as_str()) + } + } + + impl RCodec for Zenoh080Bounded<$bound> + where + R: Reader, + { + type Error = DidntRead; + + #[allow(clippy::uninit_vec)] + fn read(self, reader: &mut R) -> Result { + let vec: Vec = self.read(&mut *reader)?; + String::from_utf8(vec).map_err(|_| DidntRead) + } + } + }; +} + +str_impl!(u8); +str_impl!(u16); +str_impl!(u32); +str_impl!(u64); +str_impl!(usize); + // &str / String impl WCodec<&str, &mut W> for Zenoh080 where @@ -130,7 +210,8 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &str) -> Self::Output { - self.write(&mut *writer, x.as_bytes()) + let zcodec = Zenoh080Bounded::::new(); + zcodec.write(&mut *writer, x) } } @@ -141,7 +222,8 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &String) -> Self::Output { - self.write(&mut *writer, x.as_str()) + let zcodec = Zenoh080Bounded::::new(); + zcodec.write(&mut *writer, x) } } @@ -152,7 +234,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let vec: Vec = self.read(&mut *reader)?; - String::from_utf8(vec).map_err(|_| DidntRead) + let zcodec = Zenoh080Bounded::::new(); + zcodec.read(&mut *reader) } } diff --git a/commons/zenoh-codec/src/core/keyexpr.rs b/commons/zenoh-codec/src/core/wire_expr.rs similarity index 68% rename from commons/zenoh-codec/src/core/keyexpr.rs rename to commons/zenoh-codec/src/core/wire_expr.rs index a455c3f1d6..a992470c55 100644 --- a/commons/zenoh-codec/src/core/keyexpr.rs +++ b/commons/zenoh-codec/src/core/wire_expr.rs @@ -11,13 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition}; +use crate::{core::Zenoh080Bounded, RCodec, WCodec, Zenoh080, Zenoh080Condition}; use alloc::string::String; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_protocol::core::{ExprId, WireExpr}; +use zenoh_protocol::core::{ExprId, ExprLen, WireExpr}; impl WCodec<&WireExpr<'_>, &mut W> for Zenoh080 where @@ -26,9 +26,12 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &WireExpr<'_>) -> Self::Output { - self.write(&mut *writer, x.scope)?; + let zodec = Zenoh080Bounded::::new(); + zodec.write(&mut *writer, x.scope)?; + if x.has_suffix() { - self.write(&mut *writer, x.suffix.as_ref())?; + let zodec = Zenoh080Bounded::::new(); + zodec.write(&mut *writer, x.suffix.as_ref())?; } Ok(()) } @@ -41,9 +44,12 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result, Self::Error> { - let scope: ExprId = self.codec.read(&mut *reader)?; + let zodec = Zenoh080Bounded::::new(); + let scope: ExprId = zodec.read(&mut *reader)?; + let suffix: String = if self.condition { - self.codec.read(&mut *reader)? + let zodec = Zenoh080Bounded::::new(); + zodec.read(&mut *reader)? } else { String::new() }; diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 98a8d65a14..c6beea7ef9 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use core::convert::TryInto; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -32,17 +32,6 @@ where } } -impl WCodec<&u8, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &u8) -> Self::Output { - self.write(writer, *x) - } -} - impl RCodec for Zenoh080 where R: Reader, @@ -54,76 +43,6 @@ where } } -// u16 -impl WCodec for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: u16) -> Self::Output { - self.write(writer, x as u64) - } -} - -impl WCodec<&u16, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &u16) -> Self::Output { - self.write(writer, *x) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let x: u64 = self.read(reader)?; - Ok(x as u16) - } -} - -// u32 -impl WCodec for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: u32) -> Self::Output { - self.write(writer, x as u64) - } -} - -impl WCodec<&u32, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &u32) -> Self::Output { - self.write(writer, *x) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let x: u64 = self.read(reader)?; - Ok(x as u32) - } -} - // u64 impl WCodec for Zenoh080 where @@ -147,17 +66,6 @@ where } } -impl WCodec<&u64, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &u64) -> Self::Output { - self.write(writer, *x) - } -} - impl RCodec for Zenoh080 where R: Reader, @@ -185,41 +93,104 @@ where } } -// usize -impl WCodec for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; +// Derive impls +macro_rules! uint_impl { + ($uint:ty) => { + impl WCodec<$uint, &mut W> for Zenoh080 + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: $uint) -> Self::Output { + let x: u64 = x.try_into().map_err(|_| DidntWrite)?; + self.write(writer, x) + } + } - fn write(self, writer: &mut W, x: usize) -> Self::Output { - let x: u64 = x.try_into().map_err(|_| DidntWrite)?; - self.write(writer, x) - } + impl RCodec<$uint, &mut R> for Zenoh080 + where + R: Reader, + { + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<$uint, Self::Error> { + let x: u64 = self.read(reader)?; + Ok(x as $uint) + } + } + }; } -impl WCodec<&usize, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; +uint_impl!(u16); +uint_impl!(u32); +uint_impl!(usize); - fn write(self, writer: &mut W, x: &usize) -> Self::Output { - self.write(writer, *x) - } +macro_rules! uint_ref_impl { + ($uint:ty) => { + impl WCodec<&$uint, &mut W> for Zenoh080 + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &$uint) -> Self::Output { + self.write(writer, *x) + } + } + }; } -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; +uint_ref_impl!(u8); +uint_ref_impl!(u16); +uint_ref_impl!(u32); +uint_ref_impl!(u64); +uint_ref_impl!(usize); + +// Encode unsigned integer and verify that the size boundaries are respected +macro_rules! zint_impl_codec { + ($zint:ty, $bound:ty) => { + impl WCodec<$zint, &mut W> for Zenoh080Bounded<$bound> + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: $zint) -> Self::Output { + let t: $bound = x.try_into().map_err(|_| DidntWrite)?; + Zenoh080.write(writer, t) + } + } - fn read(self, reader: &mut R) -> Result { - let x: u64 = self.read(reader)?; - Ok(x as usize) - } + impl RCodec<$zint, &mut R> for Zenoh080Bounded<$bound> + where + R: Reader, + { + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<$zint, Self::Error> { + let x: u64 = Zenoh080.read(reader)?; + let t: $bound = x.try_into().map_err(|_| DidntRead)?; + t.try_into().map_err(|_| DidntRead) + } + } + }; } +macro_rules! zint_impl { + ($zint:ty) => { + zint_impl_codec!($zint, u8); + zint_impl_codec!($zint, u16); + zint_impl_codec!($zint, u32); + zint_impl_codec!($zint, u64); + zint_impl_codec!($zint, usize); + }; +} + +zint_impl!(u8); +zint_impl!(u16); +zint_impl!(u32); +zint_impl!(u64); +zint_impl!(usize); // const MAX_LEN: usize = 9; // const VLE_THR: u64 = 0xf8; // 248 diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 30fb794f06..4a4c837ea5 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -20,6 +20,7 @@ mod scouting; mod transport; mod zenoh; +use ::core::marker::PhantomData; use zenoh_protocol::{core::Reliability, zenoh::ReplyContext}; pub trait WCodec { @@ -107,3 +108,14 @@ pub struct Zenoh080HeaderReplyContext { pub reply_context: Option, pub codec: Zenoh080, } + +#[derive(Clone, Copy)] +pub struct Zenoh080Bounded { + _t: PhantomData, +} + +impl Zenoh080Bounded { + pub const fn new() -> Self { + Self { _t: PhantomData } + } +} diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index 4f523db8bd..62f5053dca 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -24,8 +24,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, core::{CongestionControl, Encoding, WireExpr, ZenohId}, - transport::TransportSn, - zenoh::{zmsg, Data, DataInfo, QueryId, ReplierInfo, ReplyContext, SampleKind}, + zenoh::{zmsg, Data, DataInfo, QueryId, ReplierInfo, ReplyContext, SampleKind, SourceSn}, }; // ReplyContext @@ -169,7 +168,7 @@ where info.source_id = Some(source_id); } if imsg::has_flag(options, zmsg::data::info::SRCSN) { - let source_sn: TransportSn = self.read(&mut *reader)?; + let source_sn: SourceSn = self.read(&mut *reader)?; info.source_sn = Some(source_sn); } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 16930aabdf..c7cb86b39e 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -117,26 +117,58 @@ macro_rules! run { // Core #[test] -fn codec_u64() { - run!(u64, { thread_rng().gen::() as u64 }); - run!(u64, u8::MIN as u64); - run!(u64, u8::MAX as u64); +fn codec_zint() { + run!(u8, { thread_rng().gen::() }); + run!(u16, { thread_rng().gen::() }); + run!(u32, { thread_rng().gen::() }); + run!(u64, { thread_rng().gen::() }); + run!(usize, thread_rng().gen::()); +} - run!(u64, { thread_rng().gen::() as u64 }); - run!(u64, u16::MIN as u64); - run!(u64, u16::MAX as u64); +#[test] +fn codec_zint_bounded() { + use crate::Zenoh080Bounded; - run!(u64, { thread_rng().gen::() as u64 }); - run!(u64, u32::MIN as u64); - run!(u64, u32::MAX as u64); + // Check bounded encoding + for i in [ + u8::MAX as u64, + u16::MAX as u64, + u32::MAX as u64, + usize::MAX as u64, + u64::MAX, + ] { + let mut buff = vec![]; - run!(u64, { thread_rng().gen::() }); - run!(u64, u64::MIN); - run!(u64, u64::MAX); + let codec = Zenoh080::new(); + let mut writer = buff.writer(); + codec.write(&mut writer, i).unwrap(); + + macro_rules! check { + ($zint:ty) => { + let zodec = Zenoh080Bounded::<$zint>::new(); + + let mut btmp = vec![]; + let mut wtmp = btmp.writer(); + let w_res = zodec.write(&mut wtmp, i); + + let mut reader = buff.reader(); + let r_res: Result<$zint, _> = zodec.read(&mut reader); + if i <= <$zint>::MAX as u64 { + w_res.unwrap(); + assert_eq!(i, r_res.unwrap() as u64); + } else { + assert!(w_res.is_err()); + assert!(r_res.is_err()); + } + }; + } - run!(u64, thread_rng().gen::() as u64); - run!(u64, usize::MIN as u64); - run!(u64, usize::MAX as u64); + check!(u8); + check!(u16); + check!(u32); + check!(u64); + check!(usize); + } } #[test] @@ -148,6 +180,31 @@ fn codec_string() { }); } +#[test] +fn codec_string_bounded() { + use crate::Zenoh080Bounded; + + let mut rng = rand::thread_rng(); + let str = Alphanumeric.sample_string(&mut rng, 1 + u8::MAX as usize); + + let zodec = Zenoh080Bounded::::new(); + let codec = Zenoh080::new(); + + let mut buff = vec![]; + + let mut writer = buff.writer(); + assert!(zodec.write(&mut writer, &str).is_err()); + let mut writer = buff.writer(); + codec.write(&mut writer, &str).unwrap(); + + let mut reader = buff.reader(); + let r_res: Result = zodec.read(&mut reader); + assert!(r_res.is_err()); + let mut reader = buff.reader(); + let r_res: Result = codec.read(&mut reader); + assert_eq!(str, r_res.unwrap()); +} + #[test] fn codec_zid() { run!(ZenohId, ZenohId::default()); @@ -161,11 +218,6 @@ fn codec_zbuf() { ); } -#[test] -fn codec_endpoint() { - run!(EndPoint, EndPoint::rand()); -} - #[test] fn codec_locator() { run!(Locator, Locator::rand()); diff --git a/commons/zenoh-protocol/src/core/endpoint.rs b/commons/zenoh-protocol/src/core/endpoint.rs index 7a5317b58b..58388b44f3 100644 --- a/commons/zenoh-protocol/src/core/endpoint.rs +++ b/commons/zenoh-protocol/src/core/endpoint.rs @@ -619,7 +619,7 @@ impl EndPoint { }; const MIN: usize = 2; - const MAX: usize = 16; + const MAX: usize = 8; fn gen_hashmap(rng: &mut ThreadRng, endpoint: &mut String) { let num = rng.gen_range(MIN..MAX); diff --git a/commons/zenoh-protocol/src/core/wire_expr.rs b/commons/zenoh-protocol/src/core/wire_expr.rs index 35a374140e..f5984ebccb 100644 --- a/commons/zenoh-protocol/src/core/wire_expr.rs +++ b/commons/zenoh-protocol/src/core/wire_expr.rs @@ -22,6 +22,8 @@ use zenoh_result::{bail, ZResult}; /// A numerical Id mapped to a key expression. pub type ExprId = u16; +pub type ExprLen = u16; + pub type AtomicExprId = AtomicU16; pub const EMPTY_EXPR_ID: ExprId = 0; diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs index 5851f41935..7095deb008 100644 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ b/commons/zenoh-protocol/src/zenoh/data.rs @@ -13,7 +13,6 @@ // use crate::{ core::{CongestionControl, Encoding, Timestamp, WireExpr, ZenohId}, - transport::TransportSn, zenoh::QueryId, }; use core::{convert::TryFrom, fmt}; @@ -147,6 +146,8 @@ impl ReplyContext { /// - if options & (1 << 0) then the payload is sliced /// /// ``` +pub type SourceSn = u64; + #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct DataInfo { #[cfg(feature = "shared-memory")] @@ -155,7 +156,7 @@ pub struct DataInfo { pub encoding: Option, pub timestamp: Option, pub source_id: Option, - pub source_sn: Option, + pub source_sn: Option, } impl DataInfo { diff --git a/zenoh/src/sample.rs b/zenoh/src/sample.rs index 6d6fccf421..94e21dcf2b 100644 --- a/zenoh/src/sample.rs +++ b/zenoh/src/sample.rs @@ -21,7 +21,7 @@ use crate::time::{new_reception_timestamp, Timestamp}; #[zenoh_core::unstable] use serde::Serialize; use std::convert::TryInto; -use zenoh_protocol::{transport::TransportSn, zenoh::DataInfo}; +use zenoh_protocol::zenoh::{DataInfo, SourceSn}; /// The locality of samples to be received by subscribers or targeted by publishers. #[zenoh_core::unstable] @@ -47,7 +47,7 @@ pub struct SourceInfo { /// The [`ZenohId`] of the zenoh instance that published the concerned [`Sample`]. pub source_id: Option, /// The sequence number of the [`Sample`] from the source. - pub source_sn: Option, + pub source_sn: Option, } #[test] From 1fdbf903c684cabbff4588d1b1b1c441c7d73c31 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 15 Mar 2023 21:48:46 +0100 Subject: [PATCH 096/203] Fix format --- zenoh/src/prelude.rs | 2 +- zenohd/src/main.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/zenoh/src/prelude.rs b/zenoh/src/prelude.rs index 82dd345ea4..716fb39a3e 100644 --- a/zenoh/src/prelude.rs +++ b/zenoh/src/prelude.rs @@ -50,7 +50,7 @@ pub(crate) mod common { pub use zenoh_protocol::zenoh::{ConsolidationMode, SampleKind}; pub use crate::publication::Priority; - pub use zenoh_protocol::core::{CongestionControl, WhatAmI, Reliability}; + pub use zenoh_protocol::core::{CongestionControl, Reliability, WhatAmI}; /// A [`Locator`] contains a choice of protocol, an address and port, as well as optional additional properties to work with. pub use zenoh_protocol::core::EndPoint; diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index d6161e097b..067d63c0ec 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -139,9 +139,7 @@ fn config_from_args(args: &ArgMatches) -> Config { Config::from_file(conf_file).unwrap() }); if config.mode().is_none() { - config - .set_mode(Some(WhatAmI::Router)) - .unwrap(); + config.set_mode(Some(WhatAmI::Router)).unwrap(); } if args.occurrences_of("id") > 0 { config From 5b73d2c7d01df2095672e871302275c897df536f Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 17 Mar 2023 10:54:33 +0100 Subject: [PATCH 097/203] Config fix --- commons/zenoh-codec/src/core/encoding.rs | 14 +++-- commons/zenoh-codec/src/core/zbuf.rs | 55 ++++++++++++++---- commons/zenoh-codec/src/core/zslice.rs | 51 +++++++++++++--- commons/zenoh-codec/src/transport/init.rs | 18 +++--- commons/zenoh-codec/src/zenoh/pull.rs | 6 +- commons/zenoh-codec/tests/codec.rs | 58 ++++++++++++++++++- commons/zenoh-config/src/defaults.rs | 24 ++++---- commons/zenoh-config/src/lib.rs | 30 +++++----- commons/zenoh-protocol/src/core/encoding.rs | 28 +++++---- commons/zenoh-protocol/src/core/endpoint.rs | 7 ++- commons/zenoh-protocol/src/core/resolution.rs | 9 +++ commons/zenoh-protocol/src/transport/init.rs | 9 ++- commons/zenoh-protocol/src/zenoh/mod.rs | 4 +- commons/zenoh-protocol/src/zenoh/pull.rs | 9 ++- io/zenoh-link-commons/src/unicast.rs | 13 +++-- io/zenoh-link/src/lib.rs | 2 - io/zenoh-transport/src/manager.rs | 29 ++++------ io/zenoh-transport/src/primitives/mod.rs | 10 ++-- io/zenoh-transport/src/primitives/mux.rs | 10 ++-- io/zenoh-transport/src/unicast/manager.rs | 26 ++++----- zenoh/src/net/routing/face.rs | 6 +- zenoh/src/net/routing/pubsub.rs | 6 +- zenoh/src/net/runtime/adminspace.rs | 6 +- zenoh/src/net/tests/tables.rs | 6 +- zenoh/src/session.rs | 8 +-- 25 files changed, 299 insertions(+), 145 deletions(-) diff --git a/commons/zenoh-codec/src/core/encoding.rs b/commons/zenoh-codec/src/core/encoding.rs index 84530f41e3..36259b8b9f 100644 --- a/commons/zenoh-codec/src/core/encoding.rs +++ b/commons/zenoh-codec/src/core/encoding.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use alloc::string::String; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -26,8 +26,9 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &Encoding) -> Self::Output { - self.write(&mut *writer, *x.prefix() as u64)?; - self.write(&mut *writer, x.suffix())?; + let zodec = Zenoh080Bounded::::new(); + zodec.write(&mut *writer, *x.prefix() as u8)?; + zodec.write(&mut *writer, x.suffix())?; Ok(()) } } @@ -39,9 +40,10 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let prefix: u64 = self.read(&mut *reader)?; - let suffix: String = self.read(&mut *reader)?; - let encoding = Encoding::new(prefix, suffix).ok_or(DidntRead)?; + let zodec = Zenoh080Bounded::::new(); + let prefix: u8 = zodec.read(&mut *reader)?; + let suffix: String = zodec.read(&mut *reader)?; + let encoding = Encoding::new(prefix, suffix).map_err(|_| DidntRead)?; Ok(encoding) } } diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index 44998d50fc..8b2db98ea8 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -23,6 +23,46 @@ use { zenoh_shm::SharedMemoryBufInfoSerialized, }; +// ZBuf bounded +macro_rules! zbuf_impl { + ($bound:ty) => { + impl WCodec<&ZBuf, &mut W> for Zenoh080Bounded<$bound> + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ZBuf) -> Self::Output { + self.write(&mut *writer, x.len())?; + for s in x.zslices() { + writer.write_zslice(s)?; + } + Ok(()) + } + } + + impl RCodec for Zenoh080Bounded<$bound> + where + R: Reader, + { + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let len: usize = self.read(&mut *reader)?; + let mut zbuf = ZBuf::empty(); + reader.read_zslices(len, |s| zbuf.push_zslice(s))?; + Ok(zbuf) + } + } + }; +} + +zbuf_impl!(u8); +zbuf_impl!(u16); +zbuf_impl!(u32); +zbuf_impl!(u64); +zbuf_impl!(usize); + // ZBuf flat impl WCodec<&ZBuf, &mut W> for Zenoh080 where @@ -31,11 +71,8 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &ZBuf) -> Self::Output { - self.write(&mut *writer, x.len())?; - for s in x.zslices() { - writer.write_zslice(s)?; - } - Ok(()) + let zodec = Zenoh080Bounded::::new(); + zodec.write(&mut *writer, x) } } @@ -46,10 +83,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let len: usize = self.read(&mut *reader)?; - let mut zbuf = ZBuf::empty(); - reader.read_zslices(len, |s| zbuf.push_zslice(s))?; - Ok(zbuf) + let zodec = Zenoh080Bounded::::new(); + zodec.read(&mut *reader) } } diff --git a/commons/zenoh-codec/src/core/zslice.rs b/commons/zenoh-codec/src/core/zslice.rs index 2aa30ae615..9efa733689 100644 --- a/commons/zenoh-codec/src/core/zslice.rs +++ b/commons/zenoh-codec/src/core/zslice.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -24,6 +24,45 @@ pub(crate) mod kind { pub(crate) const SHM_INFO: u8 = 1; } +// ZSlice - Bounded +macro_rules! zslice_impl { + ($bound:ty) => { + impl WCodec<&ZSlice, &mut W> for Zenoh080Bounded<$bound> + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ZSlice) -> Self::Output { + self.write(&mut *writer, x.len())?; + writer.write_zslice(x)?; + Ok(()) + } + } + + impl RCodec for Zenoh080Bounded<$bound> + where + R: Reader, + { + type Error = DidntRead; + + #[allow(clippy::uninit_vec)] + fn read(self, reader: &mut R) -> Result { + let len: usize = self.read(&mut *reader)?; + let zslice = reader.read_zslice(len)?; + Ok(zslice) + } + } + }; +} + +zslice_impl!(u8); +zslice_impl!(u16); +zslice_impl!(u32); +zslice_impl!(u64); +zslice_impl!(usize); + +// ZSlice impl WCodec<&ZSlice, &mut W> for Zenoh080 where W: Writer, @@ -31,9 +70,8 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &ZSlice) -> Self::Output { - self.write(&mut *writer, x.len())?; - writer.write_zslice(x)?; - Ok(()) + let zodec = Zenoh080Bounded::::new(); + zodec.write(&mut *writer, x) } } @@ -44,8 +82,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let len: usize = self.read(&mut *reader)?; - let zslice = reader.read_zslice(len)?; - Ok(zslice) + let zodec = Zenoh080Bounded::::new(); + zodec.read(&mut *reader) } } diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index 14a1f5fa7a..11a3447691 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header, Zenoh080Length}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -23,6 +23,7 @@ use zenoh_protocol::{ transport::{ id, init::{ext, flag, InitAck, InitSyn}, + BatchSize, }, }; @@ -128,13 +129,13 @@ where let zid: ZenohId = lodec.read(&mut *reader)?; let mut resolution = Resolution::default(); - let mut batch_size = u16::MAX.to_le_bytes(); + let mut batch_size = BatchSize::MAX.to_le_bytes(); if imsg::has_flag(self.header, flag::S) { let flags: u8 = self.codec.read(&mut *reader)?; resolution = Resolution::from(flags & 0b00111111); batch_size = self.codec.read(&mut *reader)?; } - let batch_size = u16::from_le_bytes(batch_size); + let batch_size = BatchSize::from_le_bytes(batch_size); // Extensions let mut ext_qos = None; @@ -226,10 +227,11 @@ where if imsg::has_flag(header, flag::S) { self.write(&mut *writer, x.resolution.as_u8())?; - self.write(&mut *writer, x.batch_size)?; + self.write(&mut *writer, x.batch_size.to_le_bytes())?; } - self.write(&mut *writer, &x.cookie)?; + let zodec = Zenoh080Bounded::::new(); + zodec.write(&mut *writer, &x.cookie)?; // Extensions if let Some(qos) = x.ext_qos.as_ref() { @@ -292,14 +294,16 @@ where let zid: ZenohId = lodec.read(&mut *reader)?; let mut resolution = Resolution::default(); - let mut batch_size = u16::MAX; + let mut batch_size = BatchSize::MAX.to_le_bytes(); if imsg::has_flag(self.header, flag::S) { let flags: u8 = self.codec.read(&mut *reader)?; resolution = Resolution::from(flags & 0b00111111); batch_size = self.codec.read(&mut *reader)?; } + let batch_size = BatchSize::from_le_bytes(batch_size); - let cookie: ZSlice = self.codec.read(&mut *reader)?; + let zodec = Zenoh080Bounded::::new(); + let cookie: ZSlice = zodec.read(&mut *reader)?; // Extensions let mut ext_qos = None; diff --git a/commons/zenoh-codec/src/zenoh/pull.rs b/commons/zenoh-codec/src/zenoh/pull.rs index 4126370619..a46e27420e 100644 --- a/commons/zenoh-codec/src/zenoh/pull.rs +++ b/commons/zenoh-codec/src/zenoh/pull.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, core::WireExpr, - zenoh::{zmsg, Pull}, + zenoh::{zmsg, Pull, PullId}, }; impl WCodec<&Pull, &mut W> for Zenoh080 @@ -83,9 +83,9 @@ where codec: self.codec, }; let key: WireExpr<'static> = ccond.read(&mut *reader)?; - let pull_id: u64 = self.codec.read(&mut *reader)?; + let pull_id: PullId = self.codec.read(&mut *reader)?; let max_samples = if imsg::has_flag(self.header, zmsg::flag::N) { - let n: u64 = self.codec.read(&mut *reader)?; + let n: u16 = self.codec.read(&mut *reader)?; Some(n) } else { None diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index c7cb86b39e..93641b6766 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -210,14 +210,70 @@ fn codec_zid() { run!(ZenohId, ZenohId::default()); } +#[test] +fn codec_zslice() { + run!( + ZSlice, + ZSlice::rand(thread_rng().gen_range(1..=MAX_PAYLOAD_SIZE)) + ); +} + +#[test] +fn codec_zslice_bounded() { + use crate::Zenoh080Bounded; + + let zslice = ZSlice::rand(1 + u8::MAX as usize); + + let zodec = Zenoh080Bounded::::new(); + let codec = Zenoh080::new(); + + let mut buff = vec![]; + + let mut writer = buff.writer(); + assert!(zodec.write(&mut writer, &zslice).is_err()); + let mut writer = buff.writer(); + codec.write(&mut writer, &zslice).unwrap(); + + let mut reader = buff.reader(); + let r_res: Result = zodec.read(&mut reader); + assert!(r_res.is_err()); + let mut reader = buff.reader(); + let r_res: Result = codec.read(&mut reader); + assert_eq!(zslice, r_res.unwrap()); +} + #[test] fn codec_zbuf() { run!( ZBuf, - ZBuf::rand(thread_rng().gen_range(0..=MAX_PAYLOAD_SIZE)) + ZBuf::rand(thread_rng().gen_range(1..=MAX_PAYLOAD_SIZE)) ); } +#[test] +fn codec_zbuf_bounded() { + use crate::Zenoh080Bounded; + + let zbuf = ZBuf::rand(1 + u8::MAX as usize); + + let zodec = Zenoh080Bounded::::new(); + let codec = Zenoh080::new(); + + let mut buff = vec![]; + + let mut writer = buff.writer(); + assert!(zodec.write(&mut writer, &zbuf).is_err()); + let mut writer = buff.writer(); + codec.write(&mut writer, &zbuf).unwrap(); + + let mut reader = buff.reader(); + let r_res: Result = zodec.read(&mut reader); + assert!(r_res.is_err()); + let mut reader = buff.reader(); + let r_res: Result = codec.read(&mut reader); + assert_eq!(zbuf, r_res.unwrap()); +} + #[test] fn codec_locator() { run!(Locator, Locator::rand()); diff --git a/commons/zenoh-config/src/defaults.rs b/commons/zenoh-config/src/defaults.rs index c9d8c95847..3181937120 100644 --- a/commons/zenoh-config/src/defaults.rs +++ b/commons/zenoh-config/src/defaults.rs @@ -100,10 +100,10 @@ pub mod routing { impl Default for TransportUnicastConf { fn default() -> Self { Self { - accept_timeout: Some(10000), - accept_pending: Some(100), - max_sessions: Some(1000), - max_links: Some(1), + accept_timeout: 10_000, + accept_pending: 100, + max_sessions: 1_000, + max_links: 1, } } } @@ -135,12 +135,12 @@ impl Default for LinkTxConf { fn default() -> Self { let num = 1 + ((num_cpus::get() - 1) / 4); Self { - sequence_number_resolution: Some(Bits::U32), - lease: Some(10000), - keep_alive: Some(4), - batch_size: Some(u16::MAX), + sequence_number_resolution: Bits::from(TransportSn::MAX), + lease: 10_000, + keep_alive: 4, + batch_size: BatchSize::MAX, queue: QueueConf::default(), - threads: Some(num), + threads: num, } } } @@ -149,7 +149,7 @@ impl Default for QueueConf { fn default() -> Self { Self { size: QueueSizeConf::default(), - backoff: Some(100), + backoff: 100, } } } @@ -177,8 +177,8 @@ impl Default for QueueSizeConf { impl Default for LinkRxConf { fn default() -> Self { Self { - buffer_size: Some(u16::MAX as usize), - max_message_size: Some(2_usize.pow(30)), + buffer_size: BatchSize::MAX as usize, + max_message_size: 2_usize.pow(30), } } } diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index fc611a3d42..8985832413 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -40,7 +40,7 @@ use zenoh_protocol::{ whatami::{self, WhatAmI, WhatAmIMatcher, WhatAmIMatcherVisitor}, Bits, EndPoint, ZenohId, }, - transport::BatchSize, + transport::{BatchSize, TransportSn}, }; use zenoh_result::{bail, zerror, ZResult}; use zenoh_util::LibLoader; @@ -209,13 +209,13 @@ validated_struct::validator! { TransportConf { pub unicast: TransportUnicastConf { /// Timeout in milliseconds when opening a link (default: 10000). - accept_timeout: Option, + accept_timeout: u64, /// Number of links that may stay pending during accept phase (default: 100). - accept_pending: Option, + accept_pending: usize, /// Maximum number of unicast sessions (default: 1000) - max_sessions: Option, + max_sessions: usize, /// Maximum number of unicast incoming links per transport session (default: 1) - max_links: Option, + max_links: usize, }, pub multicast: TransportMulticastConf { /// Link join interval duration in milliseconds (default: 2500) @@ -237,13 +237,13 @@ validated_struct::validator! { /// The resolution in bits to be used for the message sequence numbers. /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. /// Accepted values: 8bit, 16bit, 32bit, 64bit. - sequence_number_resolution: Option, + sequence_number_resolution: Bits where (sequence_number_resolution_validator), /// Link lease duration in milliseconds (default: 10000) - lease: Option, + lease: u64, /// Number fo keep-alive messages in a link lease duration (default: 4) - keep_alive: Option, + keep_alive: usize, /// Zenoh's MTU equivalent (default: 2^16-1) - batch_size: Option, + batch_size: BatchSize, pub queue: QueueConf { /// The size of each priority queue indicates the number of batches a given queue can contain. /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. @@ -262,10 +262,10 @@ validated_struct::validator! { } where (queue_size_validator), /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. /// Higher values lead to a more aggressive batching but it will introduce additional latency. - backoff: Option + backoff: u64, }, // Number of threads used for TX - threads: Option, + threads: usize, }, pub rx: LinkRxConf { /// Receiving buffer size in bytes for each link @@ -273,10 +273,10 @@ validated_struct::validator! { /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate /// more in-flight data. This is particularly relevant when dealing with large messages. /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. - buffer_size: Option, + buffer_size: usize, /// Maximum size of the defragmentation buffer at receiver end (default: 1GiB). /// Fragmented messages that are larger than the configured size will be dropped. - max_message_size: Option, + max_message_size: usize, }, pub tls: #[derive(Default)] TLSConf { @@ -743,6 +743,10 @@ impl<'a, T> AsRef for GetGuard<'a, T> { } } +fn sequence_number_resolution_validator(b: &Bits) -> bool { + b <= &Bits::from(TransportSn::MAX) +} + fn queue_size_validator(q: &QueueSizeConf) -> bool { fn check(size: &usize) -> bool { (QueueSizeConf::MIN..=QueueSizeConf::MAX).contains(size) diff --git a/commons/zenoh-protocol/src/core/encoding.rs b/commons/zenoh-protocol/src/core/encoding.rs index 97a9618578..78b8cbf9a6 100644 --- a/commons/zenoh-protocol/src/core/encoding.rs +++ b/commons/zenoh-protocol/src/core/encoding.rs @@ -14,10 +14,11 @@ use crate::core::CowStr; use alloc::{borrow::Cow, string::String}; use core::{ - convert::{TryFrom, TryInto}, + convert::TryFrom, fmt::{self, Debug}, mem, }; +use zenoh_result::{bail, zerror, ZError, ZResult}; mod consts { pub(super) const MIMES: [&str; 21] = [ @@ -85,12 +86,12 @@ impl From for &str { } impl TryFrom for KnownEncoding { - type Error = (); + type Error = ZError; fn try_from(value: u8) -> Result { if value < consts::MIMES.len() as u8 + 1 { Ok(unsafe { mem::transmute(value) }) } else { - Err(()) + Err(zerror!("Unknown encoding")) } } } @@ -112,27 +113,30 @@ pub enum Encoding { } impl Encoding { - pub fn new(prefix: u64, suffix: IntoCowStr) -> Option + pub fn new(prefix: u8, suffix: IntoCowStr) -> ZResult where IntoCowStr: Into> + AsRef, { - let e: u8 = prefix.try_into().ok()?; - let prefix = KnownEncoding::try_from(e).ok()?; + let prefix = KnownEncoding::try_from(prefix)?; + let suffix = suffix.into(); + if suffix.as_bytes().len() > u8::MAX as usize { + bail!("Suffix length is limited to 255 characters") + } if suffix.as_ref().is_empty() { - Some(Encoding::Exact(prefix)) + Ok(Encoding::Exact(prefix)) } else { - Some(Encoding::WithSuffix(prefix, suffix.into().into())) + Ok(Encoding::WithSuffix(prefix, suffix.into())) } } /// Sets the suffix of this encoding. - pub fn with_suffix(self, suffix: IntoCowStr) -> Self + pub fn with_suffix(self, suffix: IntoCowStr) -> ZResult where IntoCowStr: Into> + AsRef, { match self { - Encoding::Exact(e) => Encoding::WithSuffix(e, suffix.into().into()), - Encoding::WithSuffix(e, s) => Encoding::WithSuffix(e, (s + suffix.as_ref()).into()), + Encoding::Exact(e) => Encoding::new(e as u8, suffix), + Encoding::WithSuffix(e, s) => Encoding::new(e as u8, s + suffix.as_ref()), } } @@ -274,7 +278,7 @@ impl Encoding { let mut rng = rand::thread_rng(); - let prefix: u64 = rng.gen_range(0..20); + let prefix: u8 = rng.gen_range(0..20); let suffix: String = if rng.gen_bool(0.5) { let len = rng.gen_range(MIN..MAX); Alphanumeric.sample_string(&mut rng, len) diff --git a/commons/zenoh-protocol/src/core/endpoint.rs b/commons/zenoh-protocol/src/core/endpoint.rs index 58388b44f3..aeccf15dd3 100644 --- a/commons/zenoh-protocol/src/core/endpoint.rs +++ b/commons/zenoh-protocol/src/core/endpoint.rs @@ -14,7 +14,7 @@ use super::locator::*; use alloc::{borrow::ToOwned, format, string::String, vec::Vec}; use core::{convert::TryFrom, fmt, str::FromStr}; -use zenoh_result::{zerror, Error as ZError, ZResult}; +use zenoh_result::{bail, zerror, Error as ZError, ZResult}; // Parsing chars pub const PROTO_SEPARATOR: char = '/'; @@ -449,6 +449,11 @@ impl EndPoint { let m: &str = metadata.as_ref(); let c: &str = config.as_ref(); + let len = p.as_bytes().len() + a.as_bytes().len() + m.as_bytes().len(); + if len > u8::MAX as usize { + bail!("Endpoint too big: {} bytes. Max: {} bytes. ", len, u8::MAX); + } + let s = match (m.is_empty(), c.is_empty()) { (true, true) => format!("{p}{PROTO_SEPARATOR}{a}"), (false, true) => format!("{p}{PROTO_SEPARATOR}{a}{METADATA_SEPARATOR}{m}"), diff --git a/commons/zenoh-protocol/src/core/resolution.rs b/commons/zenoh-protocol/src/core/resolution.rs index 2992b39521..6bb8f7c006 100644 --- a/commons/zenoh-protocol/src/core/resolution.rs +++ b/commons/zenoh-protocol/src/core/resolution.rs @@ -32,6 +32,15 @@ impl Bits { const S32: &str = "32bit"; const S64: &str = "64bit"; + pub const fn bits(&self) -> u32 { + match self { + Bits::U8 => u8::BITS, + Bits::U16 => u16::BITS, + Bits::U32 => u32::BITS, + Bits::U64 => u64::BITS, + } + } + pub const fn mask(&self) -> u64 { match self { Bits::U8 => u8::MAX as u64, diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index 8d74b62539..c08f518cf0 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -11,7 +11,10 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{Resolution, WhatAmI, ZenohId}; +use crate::{ + core::{Resolution, WhatAmI, ZenohId}, + transport::BatchSize, +}; use zenoh_buffers::ZSlice; /// # Init message @@ -109,7 +112,7 @@ pub struct InitSyn { pub whatami: WhatAmI, pub zid: ZenohId, pub resolution: Resolution, - pub batch_size: u16, + pub batch_size: BatchSize, pub ext_qos: Option, pub ext_shm: Option, pub ext_auth: Option, @@ -180,7 +183,7 @@ pub struct InitAck { pub whatami: WhatAmI, pub zid: ZenohId, pub resolution: Resolution, - pub batch_size: u16, + pub batch_size: BatchSize, pub cookie: ZSlice, pub ext_qos: Option, pub ext_shm: Option, diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index 19bed33002..d74d6c2fa5 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -257,8 +257,8 @@ impl ZenohMessage { pub fn make_pull( is_final: bool, key: WireExpr<'static>, - pull_id: u64, - max_samples: Option, + pull_id: PullId, + max_samples: Option, ) -> ZenohMessage { ZenohMessage { body: ZenohBody::Pull(Pull { diff --git a/commons/zenoh-protocol/src/zenoh/pull.rs b/commons/zenoh-protocol/src/zenoh/pull.rs index db2f673527..2d5cedef1d 100644 --- a/commons/zenoh-protocol/src/zenoh/pull.rs +++ b/commons/zenoh-protocol/src/zenoh/pull.rs @@ -13,6 +13,9 @@ // use crate::core::WireExpr; +/// The resolution of a PullId +pub type PullId = u32; + /// # Pull message /// /// ```text @@ -30,8 +33,8 @@ use crate::core::WireExpr; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Pull { pub key: WireExpr<'static>, - pub pull_id: u64, - pub max_samples: Option, + pub pull_id: PullId, + pub max_samples: Option, pub is_final: bool, } @@ -43,7 +46,7 @@ impl Pull { let mut rng = rand::thread_rng(); let key = WireExpr::rand(); - let pull_id: u64 = rng.gen(); + let pull_id: PullId = rng.gen(); let max_samples = if rng.gen_bool(0.5) { Some(rng.gen()) } else { diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index 3279f63486..7f3eb43518 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -26,7 +26,7 @@ use zenoh_buffers::{ use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_protocol::{ core::{EndPoint, Locator}, - transport::TransportMessage, + transport::{BatchSize, TransportMessage}, }; use zenoh_result::{zerror, ZResult}; @@ -79,7 +79,7 @@ impl LinkUnicast { // Reserve 16 bits to write the length if self.is_streamed() { writer - .write_exact(u16::MIN.to_le_bytes().as_slice()) + .write_exact(BatchSize::MIN.to_le_bytes().as_slice()) .map_err(|_| zerror!("{ERR}{self}"))?; } // Serialize the message @@ -89,8 +89,9 @@ impl LinkUnicast { // Write the length if self.is_streamed() { - let num = u16::MIN.to_le_bytes().len(); - let len = u16::try_from(writer.len() - num).map_err(|_| zerror!("{ERR}{self}"))?; + let num = BatchSize::MIN.to_le_bytes().len(); + let len = + BatchSize::try_from(writer.len() - num).map_err(|_| zerror!("{ERR}{self}"))?; buff[..num].copy_from_slice(len.to_le_bytes().as_slice()); } @@ -104,9 +105,9 @@ impl LinkUnicast { // Read from the link let buffer = if self.is_streamed() { // Read and decode the message length - let mut length_bytes = [0_u8; 2]; + let mut length_bytes = BatchSize::MIN.to_le_bytes(); self.read_exact(&mut length_bytes).await?; - let to_read = u16::from_le_bytes(length_bytes) as usize; + let to_read = BatchSize::from_le_bytes(length_bytes) as usize; // Read the message let mut buffer = zenoh_buffers::vec::uninit(to_read); self.read_exact(&mut buffer).await?; diff --git a/io/zenoh-link/src/lib.rs b/io/zenoh-link/src/lib.rs index ce3c50645c..318e1b8ead 100644 --- a/io/zenoh-link/src/lib.rs +++ b/io/zenoh-link/src/lib.rs @@ -192,5 +192,3 @@ impl LinkManagerBuilderMulticast { } } } - -pub const WBUF_SIZE: usize = 64; diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index 395933df64..f0ca35cae6 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -187,23 +187,16 @@ impl TransportManagerBuilder { self = self.whatami(*v); } + let link = config.transport().link(); let mut resolution = Resolution::default(); - resolution.set( - Field::FrameSN, - config - .transport() - .link() - .tx() - .sequence_number_resolution() - .unwrap(), - ); + resolution.set(Field::FrameSN, *link.tx().sequence_number_resolution()); self = self.resolution(resolution); - self = self.batch_size(config.transport().link().tx().batch_size().unwrap()); - self = self.defrag_buff_size(config.transport().link().rx().max_message_size().unwrap()); - self = self.link_rx_buffer_size(config.transport().link().rx().buffer_size().unwrap()); - self = self.queue_size(config.transport().link().tx().queue().size().clone()); - self = self.tx_threads(config.transport().link().tx().threads().unwrap()); - self = self.protocols(config.transport().link().protocols().clone()); + self = self.batch_size(*link.tx().batch_size()); + self = self.defrag_buff_size(*link.rx().max_message_size()); + self = self.link_rx_buffer_size(*link.rx().buffer_size()); + self = self.queue_size(link.tx().queue().size().clone()); + self = self.tx_threads(*link.tx().threads()); + self = self.protocols(link.protocols().clone()); let (c, errors) = zenoh_link::LinkConfigurator::default() .configurations(config) @@ -273,7 +266,7 @@ impl Default for TransportManagerBuilder { fn default() -> Self { let link_rx = LinkRxConf::default(); let queue = QueueConf::default(); - let backoff = queue.backoff().unwrap(); + let backoff = *queue.backoff(); Self { version: VERSION, zid: ZenohId::rand(), @@ -282,8 +275,8 @@ impl Default for TransportManagerBuilder { batch_size: BatchSize::MAX, queue_size: queue.size, queue_backoff: Duration::from_nanos(backoff), - defrag_buff_size: link_rx.max_message_size().unwrap(), - link_rx_buffer_size: link_rx.buffer_size().unwrap(), + defrag_buff_size: *link_rx.max_message_size(), + link_rx_buffer_size: *link_rx.buffer_size(), endpoints: HashMap::new(), unicast: TransportManagerBuilderUnicast::default(), tx_threads: 1, diff --git a/io/zenoh-transport/src/primitives/mod.rs b/io/zenoh-transport/src/primitives/mod.rs index c4eb006721..775ae22a59 100644 --- a/io/zenoh-transport/src/primitives/mod.rs +++ b/io/zenoh-transport/src/primitives/mod.rs @@ -20,7 +20,7 @@ use zenoh_buffers::ZBuf; use zenoh_protocol::{ core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, zenoh::{ - ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, + ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, RoutingContext, SubInfo, }, }; @@ -85,8 +85,8 @@ pub trait Primitives: Send + Sync { &self, is_final: bool, key_expr: &WireExpr, - pull_id: u64, - max_samples: &Option, + pull_id: PullId, + max_samples: &Option, ); fn send_close(&self); @@ -161,8 +161,8 @@ impl Primitives for DummyPrimitives { &self, _is_final: bool, _key_expr: &WireExpr, - _pull_id: u64, - _max_samples: &Option, + _pull_id: PullId, + _max_samples: &Option, ) { } diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index 8ba03e3f78..0160d99702 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -18,9 +18,9 @@ use zenoh_protocol::{ core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, zenoh::{ zmsg, ConsolidationMode, DataInfo, Declaration, ForgetPublisher, ForgetQueryable, - ForgetResource, ForgetSubscriber, Publisher, QueryBody, QueryId, QueryTarget, Queryable, - QueryableInfo, ReplierInfo, ReplyContext, Resource, RoutingContext, SubInfo, Subscriber, - ZenohMessage, + ForgetResource, ForgetSubscriber, Publisher, PullId, QueryBody, QueryId, QueryTarget, + Queryable, QueryableInfo, ReplierInfo, ReplyContext, Resource, RoutingContext, SubInfo, + Subscriber, ZenohMessage, }, }; @@ -203,8 +203,8 @@ impl Primitives for Mux { &self, is_final: bool, key_expr: &WireExpr, - pull_id: u64, - max_samples: &Option, + pull_id: PullId, + max_samples: &Option, ) { let _ = self.handler.handle_message(ZenohMessage::make_pull( is_final, diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 8c448530c8..05b7ef83cc 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -145,19 +145,19 @@ impl TransportManagerBuilderUnicast { pub async fn from_config(mut self, config: &Config) -> ZResult { self = self.lease(Duration::from_millis( - config.transport().link().tx().lease().unwrap(), + *config.transport().link().tx().lease(), )); - self = self.keep_alive(config.transport().link().tx().keep_alive().unwrap()); + self = self.keep_alive(*config.transport().link().tx().keep_alive()); self = self.accept_timeout(Duration::from_millis( - config.transport().unicast().accept_timeout().unwrap(), + *config.transport().unicast().accept_timeout(), )); - self = self.accept_pending(config.transport().unicast().accept_pending().unwrap()); - self = self.max_sessions(config.transport().unicast().max_sessions().unwrap()); + self = self.accept_pending(*config.transport().unicast().accept_pending()); + self = self.max_sessions(*config.transport().unicast().max_sessions()); self = self.qos(*config.transport().qos().enabled()); #[cfg(feature = "transport_multilink")] { - self = self.max_links(config.transport().unicast().max_links().unwrap()); + self = self.max_links(*config.transport().unicast().max_links()); } #[cfg(feature = "shared-memory")] { @@ -208,21 +208,21 @@ impl TransportManagerBuilderUnicast { impl Default for TransportManagerBuilderUnicast { fn default() -> Self { - let link_tx = LinkTxConf::default(); let transport = TransportUnicastConf::default(); + let link_tx = LinkTxConf::default(); let qos = QoSConf::default(); #[cfg(feature = "shared-memory")] let shm = SharedMemoryConf::default(); Self { - lease: Duration::from_millis(link_tx.lease().unwrap()), - keep_alive: link_tx.keep_alive().unwrap(), - accept_timeout: Duration::from_millis(transport.accept_timeout().unwrap()), - accept_pending: transport.accept_pending().unwrap(), - max_sessions: transport.max_sessions().unwrap(), + lease: Duration::from_millis(*link_tx.lease()), + keep_alive: *link_tx.keep_alive(), + accept_timeout: Duration::from_millis(*transport.accept_timeout()), + accept_pending: *transport.accept_pending(), + max_sessions: *transport.max_sessions(), is_qos: *qos.enabled(), #[cfg(feature = "transport_multilink")] - max_links: transport.max_links().unwrap(), + max_links: *transport.max_links(), #[cfg(feature = "shared-memory")] is_shm: *shm.enabled(), #[cfg(feature = "transport_auth")] diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index b366fd8b83..95e94726bb 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -20,7 +20,7 @@ use zenoh_buffers::ZBuf; use zenoh_protocol::{ core::{Channel, CongestionControl, ExprId, WhatAmI, WireExpr, ZenohId}, zenoh::{ - ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, + ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, RoutingContext, SubInfo, }, }; @@ -404,8 +404,8 @@ impl Primitives for Face { &self, is_final: bool, key_expr: &WireExpr, - pull_id: u64, - max_samples: &Option, + pull_id: PullId, + max_samples: &Option, ) { pull_data( &self.tables, diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index a803ab5b52..f72a2fcfee 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -28,7 +28,7 @@ use zenoh_protocol::{ key_expr::OwnedKeyExpr, Channel, CongestionControl, Priority, Reliability, WhatAmI, WireExpr, ZenohId, }, - zenoh::{DataInfo, RoutingContext, SubInfo, SubMode}, + zenoh::{DataInfo, PullId, RoutingContext, SubInfo, SubMode}, }; use zenoh_sync::get_mut_unchecked; @@ -1450,8 +1450,8 @@ pub fn pull_data( face: &Arc, _is_final: bool, expr: &WireExpr, - _pull_id: u64, - _max_samples: &Option, + _pull_id: PullId, + _max_samples: &Option, ) { let tables = zread!(tables_ref); match tables.get_mapping(face, &expr.scope) { diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 4cf7b67c39..5e781ca2b8 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -30,7 +30,7 @@ use zenoh_protocol::{ WhatAmI, WireExpr, ZenohId, EMPTY_EXPR_ID, }, zenoh::{ - ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, + ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, RoutingContext, SampleKind, SubInfo, }, }; @@ -496,8 +496,8 @@ impl Primitives for AdminSpace { &self, _is_final: bool, _key_expr: &WireExpr, - _pull_id: u64, - _max_samples: &Option, + _pull_id: PullId, + _max_samples: &Option, ) { trace!( "recv Pull {:?} {:?} {:?} {:?}", diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index 1de5c23637..e1b55edbdf 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -24,7 +24,7 @@ use zenoh_protocol::{ ZenohId, EMPTY_EXPR_ID, }, zenoh::{ - ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, + ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, RoutingContext, SubInfo, SubMode, }, }; @@ -485,8 +485,8 @@ impl Primitives for ClientPrimitives { &self, _is_final: bool, _key_expr: &WireExpr, - _pull_id: u64, - _max_samples: &Option, + _pull_id: PullId, + _max_samples: &Option, ) { } diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index d3ddcf6b27..d3e7be2b32 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -57,8 +57,8 @@ use zenoh_protocol::{ AtomicExprId, Channel, CongestionControl, ExprId, WireExpr, ZenohId, EMPTY_EXPR_ID, }, zenoh::{ - AtomicQueryId, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, RoutingContext, - SubInfo, + AtomicQueryId, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, + RoutingContext, SubInfo, }, }; use zenoh_result::ZResult; @@ -1880,8 +1880,8 @@ impl Primitives for Session { &self, _is_final: bool, _key_expr: &WireExpr, - _pull_id: u64, - _max_samples: &Option, + _pull_id: PullId, + _max_samples: &Option, ) { trace!( "recv Pull {:?} {:?} {:?} {:?}", From 4b103e7e7d0b90d0ae82728f319db10aa1f5c0e4 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 17 Mar 2023 18:23:20 +0100 Subject: [PATCH 098/203] Network protocol definition. Declare to be refined. --- commons/zenoh-codec/src/transport/fragment.rs | 16 +- commons/zenoh-codec/src/transport/frame.rs | 13 +- commons/zenoh-protocol/src/core/mod.rs | 31 +- commons/zenoh-protocol/src/lib.rs | 1 + commons/zenoh-protocol/src/network/declare.rs | 457 ++++++++++++++++++ commons/zenoh-protocol/src/network/mod.rs | 235 +++++++++ commons/zenoh-protocol/src/network/push.rs | 75 +++ commons/zenoh-protocol/src/network/request.rs | 122 +++++ .../zenoh-protocol/src/network/response.rs | 118 +++++ .../zenoh-protocol/src/transport/fragment.rs | 24 +- commons/zenoh-protocol/src/transport/frame.rs | 65 ++- commons/zenoh-protocol/src/transport/mod.rs | 2 + commons/zenoh-protocol/src/zenoh/declare.rs | 6 +- commons/zenoh-protocol/src/zenoh/mod.rs | 6 +- io/zenoh-transport/src/common/pipeline.rs | 4 +- io/zenoh-transport/src/unicast/link.rs | 46 +- io/zenoh-transport/src/unicast/rx.rs | 70 ++- 17 files changed, 1155 insertions(+), 136 deletions(-) create mode 100644 commons/zenoh-protocol/src/network/declare.rs create mode 100644 commons/zenoh-protocol/src/network/mod.rs create mode 100644 commons/zenoh-protocol/src/network/push.rs create mode 100644 commons/zenoh-protocol/src/network/request.rs create mode 100644 commons/zenoh-protocol/src/network/response.rs diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index 28b7eb75bd..52097c781a 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -41,7 +41,7 @@ where if x.more { header |= flag::M; } - if x.qos != ext::QoS::default() { + if x.ext_qos != ext::QoS::default() { header |= flag::Z; } self.write(&mut *writer, header)?; @@ -50,8 +50,8 @@ where self.write(&mut *writer, x.sn)?; // Extensions - if x.qos != ext::QoS::default() { - self.write(&mut *writer, (x.qos, false))?; + if x.ext_qos != ext::QoS::default() { + self.write(&mut *writer, (x.ext_qos, false))?; } Ok(()) @@ -90,7 +90,7 @@ where let sn: TransportSn = self.codec.read(&mut *reader)?; // Extensions - let mut qos = ext::QoS::default(); + let mut ext_qos = ext::QoS::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -99,7 +99,7 @@ where match imsg::mid(ext) { ext::QOS => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; - qos = q; + ext_qos = q; has_ext = ext; } _ => { @@ -113,7 +113,7 @@ where reliability, more, sn, - qos, + ext_qos, }) } } @@ -131,7 +131,7 @@ where reliability: x.reliability, more: x.more, sn: x.sn, - qos: x.qos, + ext_qos: x.ext_qos, }; self.write(&mut *writer, &header)?; @@ -169,7 +169,7 @@ where reliability: header.reliability, more: header.more, sn: header.sn, - qos: header.qos, + ext_qos: header.ext_qos, payload, }) } diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index fd26fd7918..fa885f888e 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -1,5 +1,3 @@ -use core::convert::TryInto; - // // Copyright (c) 2022 ZettaScale Technology // @@ -21,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{imsg, ZExtUnknown, ZExtZ64}, - core::{Priority, Reliability}, + core::Reliability, transport::{ frame::{ext, flag, Frame, FrameHeader}, id, TransportSn, @@ -38,7 +36,7 @@ where fn write(self, writer: &mut W, x: (ext::QoS, bool)) -> Self::Output { let (qos, more) = x; - let ext: ZExtZ64<{ ext::QOS }> = ZExtZ64::new(qos.priority as u64); + let ext: ZExtZ64<{ ext::QOS }> = qos.into(); self.write(&mut *writer, (&ext, more)) } } @@ -52,7 +50,6 @@ where fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); - codec.read(reader) } } @@ -67,12 +64,8 @@ where if imsg::mid(self.header) != ext::QOS { return Err(DidntRead); } - let (ext, more): (ZExtZ64<{ ext::QOS }>, bool) = self.read(&mut *reader)?; - - let v: u8 = ext.value.try_into().map_err(|_| DidntRead)?; - let priority: Priority = v.try_into().map_err(|_| DidntRead)?; - Ok((ext::QoS { priority }, more)) + Ok((ext.into(), more)) } } diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index 752c9ffd27..c3862b8b1f 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -54,6 +54,8 @@ pub use endpoint::*; pub mod resolution; pub use resolution::*; +use crate::transport::TransportSn; + #[derive(Debug, Clone, PartialEq, Eq)] pub struct Property { pub key: u64, @@ -312,8 +314,8 @@ impl<'de> serde::Deserialize<'de> for ZenohId { } } -#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)] #[repr(u8)] +#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)] pub enum Priority { Control = 0, RealTime = 1, @@ -366,6 +368,21 @@ pub enum Reliability { Reliable, } +impl Reliability { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + if rng.gen_bool(0.5) { + Reliability::Reliable + } else { + Reliability::BestEffort + } + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct Channel { pub priority: Priority, @@ -412,17 +429,17 @@ impl fmt::Display for ConduitSnList { /// The kind of reliability. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct ConduitSn { - pub reliable: u64, - pub best_effort: u64, + pub reliable: TransportSn, + pub best_effort: TransportSn, } /// The kind of congestion control. #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] #[repr(u8)] pub enum CongestionControl { - Block, #[default] - Drop, + Drop = 0, + Block = 1, } /// The subscription mode. @@ -430,8 +447,8 @@ pub enum CongestionControl { #[repr(u8)] pub enum SubMode { #[default] - Push, - Pull, + Push = 0, + Pull = 1, } #[derive(Debug, Clone, PartialEq, Eq, Default)] diff --git a/commons/zenoh-protocol/src/lib.rs b/commons/zenoh-protocol/src/lib.rs index 3c37291e70..35869e4d77 100644 --- a/commons/zenoh-protocol/src/lib.rs +++ b/commons/zenoh-protocol/src/lib.rs @@ -22,6 +22,7 @@ extern crate alloc; pub mod common; pub mod core; +pub mod network; pub mod scouting; pub mod transport; pub mod zenoh; diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs new file mode 100644 index 0000000000..10d81716ca --- /dev/null +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -0,0 +1,457 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::core::{ExprId, Reliability, WireExpr}; + +/// Flags: +/// - X: Reserved +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|X|X| DECLARE | +/// +-+-+-+---------+ +/// ~ declare_exts ~ if Z==1 +/// +---------------+ +/// ~ declaration ~ +/// +---------------+ +/// +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Declare { + pub ext_qos: ext::QoS, + pub ext_tstamp: Option, + pub body: DeclareBody, +} + +pub mod ext { + pub const QOS: u8 = crate::network::ext::QOS; + pub const TSTAMP: u8 = crate::network::ext::TSTAMP; + + pub type QoS = crate::network::ext::QoS; + pub type Timestamp = crate::network::ext::Timestamp; +} + +pub mod id { + pub const D_KEYEXPR: u8 = 0x01; + pub const F_KEYEXPR: u8 = 0x02; + + pub const D_PUBLISHER: u8 = 0x03; + pub const F_PUBLISHER: u8 = 0x04; + + pub const D_SUBSCRIBER: u8 = 0x05; + pub const F_SUBSCRIBER: u8 = 0x06; + + pub const D_QUERYABLE: u8 = 0x07; + pub const F_QUERYABLE: u8 = 0x08; + + // SubModes + pub const MODE_PUSH: u8 = 0x00; + pub const MODE_PULL: u8 = 0x01; +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DeclareBody { + DeclareKeyExpr(DeclareKeyExpr), + ForgetKeyExpr(ForgetKeyExpr), + DeclarePublisher(DeclarePublisher), + ForgetPublisher(ForgetPublisher), + DeclareSubscriber(DeclareSubscriber), + ForgetSubscriber(ForgetSubscriber), + DeclareQueryable(DeclareQueryable), + ForgetQueryable(ForgetQueryable), +} + +impl DeclareBody { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + match rng.gen_range(0..8) { + 0 => DeclareBody::DeclareKeyExpr(DeclareKeyExpr::rand()), + 1 => DeclareBody::ForgetKeyExpr(ForgetKeyExpr::rand()), + 2 => DeclareBody::DeclarePublisher(DeclarePublisher::rand()), + 3 => DeclareBody::ForgetPublisher(ForgetPublisher::rand()), + 4 => DeclareBody::DeclareSubscriber(DeclareSubscriber::rand()), + 5 => DeclareBody::ForgetSubscriber(ForgetSubscriber::rand()), + 6 => DeclareBody::DeclareQueryable(DeclareQueryable::rand()), + 7 => DeclareBody::ForgetQueryable(ForgetQueryable::rand()), + _ => unreachable!(), + } + } +} + +impl Declare { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let body = DeclareBody::rand(); + let ext_qos = ext::QoS::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + + Self { + body, + ext_qos, + ext_tstamp, + } + } +} + +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] +#[repr(u8)] +pub enum Mode { + #[default] + Push, + Pull, +} + +impl Mode { + #[cfg(feature = "test")] + fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + if rng.gen_bool(0.5) { + Mode::Push + } else { + Mode::Pull + } + } +} + +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|X|N| D_KEXPR | +/// +---------------+ +/// ~ expr_id:z16 ~ +/// +---------------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DeclareKeyExpr { + pub expr_id: ExprId, + pub wire_expr: WireExpr<'static>, +} + +impl DeclareKeyExpr { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let expr_id: ExprId = rng.gen(); + let wire_expr = WireExpr::rand(); + + Self { expr_id, wire_expr } + } +} + +/// ```text +/// Flags: +/// - X: Reserved +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|X|X| F_RES | +/// +---------------+ +/// ~ expr_id:z16 ~ +/// +---------------+ +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ForgetKeyExpr { + pub expr_id: ExprId, +} + +impl ForgetKeyExpr { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let expr_id: ExprId = rng.gen(); + + Self { expr_id } + } +} + +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| D_PUB | +/// +---------------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DeclarePublisher { + pub key: WireExpr<'static>, +} + +impl DeclarePublisher { + #[cfg(feature = "test")] + pub fn rand() -> Self { + let key = WireExpr::rand(); + + Self { key } + } +} + +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| F_PUB | +/// +---------------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ForgetPublisher { + pub wire_expr: WireExpr<'static>, +} + +impl ForgetPublisher { + #[cfg(feature = "test")] + pub fn rand() -> Self { + let key = WireExpr::rand(); + + Self { wire_expr: key } + } +} + +/// The subscription mode. +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct SubscriberInfo { + pub reliability: Reliability, + pub mode: Mode, +} + +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| D_SUB | +/// +---------------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// |X|X|X|X|X|X|P|R| (*) +/// +---------------+ +/// +/// - if R==1 then the subscription is reliable, else it is best effort +/// - if P==1 then the subscription is pull, else it is push +/// +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DeclareSubscriber { + pub key: WireExpr<'static>, + pub info: SubscriberInfo, +} + +impl DeclareSubscriber { + #[cfg(feature = "test")] + pub fn rand() -> Self { + let wire_expr = WireExpr::rand(); + let reliability = Reliability::rand(); + let mode = Mode::rand(); + let info = SubscriberInfo { reliability, mode }; + + Self { + key: wire_expr, + info, + } + } +} + +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| F_SUB | +/// +---------------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// |X|X|X|X|X|X|P|R| (*) +/// +---------------+ +/// +/// - if R==1 then the subscription is reliable, else it is best effort +/// - if P==1 then the subscription is pull, else it is push +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ForgetSubscriber { + pub wire_expr: WireExpr<'static>, + pub info: SubscriberInfo, +} + +impl ForgetSubscriber { + #[cfg(feature = "test")] + pub fn rand() -> Self { + let wire_expr = WireExpr::rand(); + let reliability = Reliability::rand(); + let mode = Mode::rand(); + let info = SubscriberInfo { reliability, mode }; + + Self { wire_expr, info } + } +} + +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct QueryableInfo { + pub reliability: Reliability, + pub mode: Mode, + pub complete: u32, // Default 0: incomplete + pub distance: u32, // Default 0: no distance +} + +/// ```text +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| D_QBL | +/// +---------------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// |X|X|X|X|D|C|P|R| (*) +/// +---------------+ +/// ~ complete_n ~ if C==1 +/// +---------------+ +/// ~ distance ~ if D==1 +/// +---------------+ +/// +/// - if R==1 then the queryable is reliable, else it is best effort +/// - if P==1 then the queryable is pull, else it is push +/// - if C==1 then the queryable is complete and the N parameter is present +/// - if D==1 then the queryable distance is present +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DeclareQueryable { + pub wire_expr: WireExpr<'static>, + pub info: QueryableInfo, +} + +impl DeclareQueryable { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let wire_expr = WireExpr::rand(); + let mode = Mode::rand(); + let reliability = Reliability::rand(); + let complete: u32 = rng.gen(); + let distance: u32 = rng.gen(); + let info = QueryableInfo { + reliability, + mode, + complete, + distance, + }; + + Self { wire_expr, info } + } +} + +/// ```text +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| F_QBL | +/// +---------------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// |X|X|X|X|D|C|P|R| (*) +/// +---------------+ +/// ~ complete_n ~ if C==1 +/// +---------------+ +/// ~ distance ~ if D==1 +/// +---------------+ +/// +/// - if R==1 then the queryable is reliable, else it is best effort +/// - if P==1 then the queryable is pull, else it is push +/// - if C==1 then the queryable is complete and the N parameter is present +/// - if D==1 then the queryable distance is present +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ForgetQueryable { + pub wire_expr: WireExpr<'static>, + pub info: QueryableInfo, +} + +impl ForgetQueryable { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let wire_expr = WireExpr::rand(); + let mode = Mode::rand(); + let reliability = Reliability::rand(); + let complete: u32 = rng.gen(); + let distance: u32 = rng.gen(); + let info = QueryableInfo { + reliability, + mode, + complete, + distance, + }; + + Self { wire_expr, info } + } +} diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs new file mode 100644 index 0000000000..ce76cb2589 --- /dev/null +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -0,0 +1,235 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +pub mod declare; +pub mod push; +pub mod request; +pub mod response; + +pub use declare::Declare; +pub use push::Push; +pub use request::{Request, RequestId}; +pub use response::{Response, ResponseFinal}; + +pub mod id { + // WARNING: it's crucial that these IDs do NOT collide with the IDs + // defined in `crate::transport::id`. + pub const DECLARE: u8 = 0x1f; + pub const PUSH: u8 = 0x1e; + pub const REQUEST: u8 = 0x1d; + pub const RESPONSE: u8 = 0x1c; + pub const RESPONSE_FINAL: u8 = 0x1b; +} + +// Zenoh messages at zenoh-network level +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum NetworkBody { + Declare(Declare), + Push(Push), + Request(Request), + Response(Response), + ResponseFinal(ResponseFinal), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct NetworkMessage { + pub body: NetworkBody, + #[cfg(feature = "stats")] + pub size: Option, +} + +impl NetworkMessage { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let body = match rng.gen_range(0..5) { + 0 => NetworkBody::Declare(Declare::rand()), + 1 => NetworkBody::Push(Push::rand()), + 2 => NetworkBody::Request(Request::rand()), + 3 => NetworkBody::Response(Response::rand()), + 4 => NetworkBody::ResponseFinal(ResponseFinal::rand()), + _ => unreachable!(), + }; + + Self { body } + } +} + +impl From for NetworkMessage { + fn from(body: NetworkBody) -> Self { + Self { + body, + #[cfg(feature = "stats")] + size: None, + } + } +} + +impl From for NetworkMessage { + fn from(declare: Declare) -> Self { + NetworkBody::Declare(declare).into() + } +} + +impl From for NetworkMessage { + fn from(push: Push) -> Self { + NetworkBody::Push(push).into() + } +} + +impl From for NetworkMessage { + fn from(request: Request) -> Self { + NetworkBody::Request(request).into() + } +} + +impl From for NetworkMessage { + fn from(response: Response) -> Self { + NetworkBody::Response(response).into() + } +} + +impl From for NetworkMessage { + fn from(final_response: ResponseFinal) -> Self { + NetworkBody::ResponseFinal(final_response).into() + } +} + +// Extensions +pub mod ext { + use crate::{ + common::{imsg, ZExtZ64}, + core::{CongestionControl, Priority}, + }; + + pub const QOS: u8 = 0x01; + pub const TSTAMP: u8 = 0x02; + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|0_1| ID | + /// +-+-+-+---------+ + /// %0|rsv|E|D|prio % + /// +---------------+ + /// + /// - prio: Priority class + /// - D: Don't drop. Don't drop the message for congestion control. + /// - E: Express. Don't batch this message. + /// - rsv: Reserved + #[repr(transparent)] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub struct QoS { + inner: u8, + } + + impl QoS { + const P_MASK: u8 = 0b00000111; + const D_FLAG: u8 = 0b00001000; + const E_FLAG: u8 = 0b00010000; + + pub const fn new( + priority: Priority, + congestion_control: CongestionControl, + is_express: bool, + ) -> Self { + let mut inner = priority as u8; + if let CongestionControl::Block = congestion_control { + inner |= Self::D_FLAG; + } + if is_express { + inner |= Self::E_FLAG; + } + Self { inner } + } + + pub const fn priority(&self) -> Priority { + unsafe { core::mem::transmute(self.inner & Self::P_MASK) } + } + + pub const fn congestion_control(&self) -> CongestionControl { + match imsg::has_flag(self.inner, Self::D_FLAG) { + true => CongestionControl::Block, + false => CongestionControl::Drop, + } + } + + pub const fn is_express(&self) -> bool { + imsg::has_flag(self.inner, Self::E_FLAG) + } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let inner: u8 = rng.gen(); + Self { inner } + } + } + + impl Default for QoS { + fn default() -> Self { + Self::new(Priority::default(), CongestionControl::default(), false) + } + } + + impl From> for QoS { + fn from(ext: ZExtZ64<{ QOS }>) -> Self { + Self { + inner: ext.value as u8, + } + } + } + + impl From for ZExtZ64<{ QOS }> { + fn from(ext: QoS) -> Self { + ZExtZ64::new(ext.inner as u64) + } + } + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|1_0| ID | + /// +-+-+-+---------+ + /// ~ ts: ~ + /// +---------------+ + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub struct Timestamp { + pub timestamp: uhlc::Timestamp, + } + + impl Timestamp { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use crate::core::ZenohId; + use core::convert::TryFrom; + use rand::Rng; + + let mut rng = rand::thread_rng(); + let time = uhlc::NTP64(rng.gen()); + let id = uhlc::ID::try_from(ZenohId::rand().as_slice()).unwrap(); + let timestamp = uhlc::Timestamp::new(time, id); + Self { timestamp } + } + } + + pub mod qos { + pub mod flag { + pub const D: u8 = 1 << 3; // 0x08 Don't drop. Don't drop the message for congestion control. + pub const E: u8 = 1 << 4; // 0x10 Express. Don't batch this message. + } + } +} diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs new file mode 100644 index 0000000000..24305a5eed --- /dev/null +++ b/commons/zenoh-protocol/src/network/push.rs @@ -0,0 +1,75 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{core::WireExpr, zenoh::ZenohMessage}; + +pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| PUSH | +/// +-+-+-+---------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// ~ [data_exts] ~ if Z==1 +/// +---------------+ +/// ~ ZenohMessage ~ +/// +---------------+ +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Push { + pub wire_expr: WireExpr<'static>, + pub payload: ZenohMessage, + pub ext_qos: ext::QoS, + pub ext_tstamp: Option, +} + +pub mod ext { + pub const QOS: u8 = crate::network::ext::QOS; + pub const TSTAMP: u8 = crate::network::ext::TSTAMP; + + pub type QoS = crate::network::ext::QoS; + pub type Timestamp = crate::network::ext::Timestamp; +} + +impl Push { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let wire_expr = WireExpr::rand(); + let payload = ZenohMessage::rand(); + let ext_qos = ext::QoS::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + + Self { + wire_expr, + payload, + ext_tstamp, + ext_qos, + } + } +} diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs new file mode 100644 index 0000000000..12757d6182 --- /dev/null +++ b/commons/zenoh-protocol/src/network/request.rs @@ -0,0 +1,122 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{core::WireExpr, zenoh::ZenohMessage}; +use core::sync::atomic::AtomicU32; + +/// The resolution of a RequestId +pub type RequestId = u32; +pub type AtomicRequestId = AtomicU32; + +/// # Request message +/// +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| Request | +/// +-+-+-+---------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// ~ rid ~ +/// +---------------+ +/// ~ [req_exts] ~ if Z==1 +/// +---------------+ +/// ~ ZenohMessage ~ -- Payload +/// +---------------+ +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Request { + pub wire_expr: WireExpr<'static>, + pub rid: RequestId, + pub payload: ZenohMessage, + pub ext_qos: ext::QoS, + pub ext_tstamp: Option, + pub ext_target: ext::RequestTarget, +} + +pub mod ext { + pub const QOS: u8 = crate::network::ext::QOS; + pub const TSTAMP: u8 = crate::network::ext::TSTAMP; + pub const TARGET: u8 = 0x03; + + pub type QoS = crate::network::ext::QoS; + pub type Timestamp = crate::network::ext::Timestamp; + + /// - Target (0x03) + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|ENC| ID | + /// +-+-+-+---------+ + /// % target % -> Queryable or Subscriber? + Query targeting (ALL, BEST_MATCHING, COMPLETE_ALL, ?COMPLETE_N?)? + /// +---------------+ + /// + /// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] + pub enum RequestTarget { + #[default] + BestMatching, + All, + AllComplete, + #[cfg(feature = "complete_n")] + Complete(u64), + } + + impl RequestTarget { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::prelude::SliceRandom; + let mut rng = rand::thread_rng(); + + *[ + RequestTarget::All, + RequestTarget::AllComplete, + RequestTarget::BestMatching, + #[cfg(feature = "complete_n")] + RequestTarget::Complete(rng.gen()), + ] + .choose(&mut rng) + .unwrap() + } + } +} + +impl Request { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let wire_expr = WireExpr::rand(); + let rid: RequestId = rng.gen(); + let payload = ZenohMessage::rand(); + let ext_qos = ext::QoS::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + let ext_target = ext::RequestTarget::rand(); + + Self { + wire_expr, + rid, + payload, + ext_qos, + ext_tstamp, + ext_target, + } + } +} diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs new file mode 100644 index 0000000000..2f5b693cec --- /dev/null +++ b/commons/zenoh-protocol/src/network/response.rs @@ -0,0 +1,118 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{core::WireExpr, network::RequestId, zenoh::ZenohMessage}; + +/// # Response message +/// +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| ResMore | +/// +-+-+-+---------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// ~ rid ~ +/// +---------------+ +/// ~ [reply_exts] ~ if Z==1 +/// +---------------+ +/// ~ ZenohMessage ~ -- Payload +/// +---------------+ +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Response { + pub wire_expr: WireExpr<'static>, + pub rid: RequestId, + pub payload: ZenohMessage, + pub ext_qos: ext::QoS, + pub ext_tstamp: Option, +} + +pub mod ext { + pub const QOS: u8 = crate::network::ext::QOS; + pub const TSTAMP: u8 = crate::network::ext::TSTAMP; + pub const TARGET: u8 = 0x03; + + pub type QoS = crate::network::ext::QoS; + pub type Timestamp = crate::network::ext::Timestamp; +} + +impl Response { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let wire_expr = WireExpr::rand(); + let rid: RequestId = rng.gen(); + let payload = ZenohMessage::rand(); + let ext_qos = ext::QoS::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + + Self { + wire_expr, + rid, + payload, + ext_qos, + ext_tstamp, + } + } +} + +/// # ResponseFinal message +/// +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| ResFinal| +/// +-+-+-+---------+ +/// ~ rid ~ +/// +---------------+ +/// ~ [reply_exts] ~ if Z==1 +/// +---------------+ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ResponseFinal { + pub rid: RequestId, + pub ext_qos: ext::QoS, + pub ext_tstamp: Option, +} + +impl ResponseFinal { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let rid: RequestId = rng.gen(); + let ext_qos = ext::QoS::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + + Self { + rid, + ext_qos, + ext_tstamp, + } + } +} diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs index b3d241920d..7e3a0bc2ff 100644 --- a/commons/zenoh-protocol/src/transport/fragment.rs +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -72,8 +72,8 @@ pub struct Fragment { pub reliability: Reliability, pub more: bool, pub sn: TransportSn, - pub qos: ext::QoS, pub payload: ZSlice, + pub ext_qos: ext::QoS, } // Extensions @@ -90,22 +90,18 @@ impl Fragment { let mut rng = rand::thread_rng(); - let reliability = if rng.gen_bool(0.5) { - Reliability::Reliable - } else { - Reliability::BestEffort - }; + let reliability = Reliability::rand(); let more = rng.gen_bool(0.5); let sn: TransportSn = rng.gen(); - let qos = ext::QoS::rand(); let payload = ZSlice::rand(rng.gen_range(8..128)); + let ext_qos = ext::QoS::rand(); Fragment { reliability, sn, more, - qos, payload, + ext_qos, } } } @@ -116,7 +112,7 @@ pub struct FragmentHeader { pub reliability: Reliability, pub more: bool, pub sn: TransportSn, - pub qos: ext::QoS, + pub ext_qos: ext::QoS, } impl FragmentHeader { @@ -126,20 +122,16 @@ impl FragmentHeader { let mut rng = rand::thread_rng(); - let reliability = if rng.gen_bool(0.5) { - Reliability::Reliable - } else { - Reliability::BestEffort - }; + let reliability = Reliability::rand(); let more = rng.gen_bool(0.5); let sn: TransportSn = rng.gen(); - let qos = ext::QoS::rand(); + let ext_qos = ext::QoS::rand(); FragmentHeader { reliability, more, sn, - qos, + ext_qos, } } } diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 776132fbed..884b328499 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -70,12 +70,13 @@ pub mod flag { pub struct Frame { pub reliability: Reliability, pub sn: TransportSn, - pub ext_qos: ext::QoS, pub payload: Vec, + pub ext_qos: ext::QoS, } // Extensions pub mod ext { + use crate::common::ZExtZ64; use crate::core::Priority; pub const QOS: u8 = 0x01; @@ -84,26 +85,56 @@ pub mod ext { /// +-+-+-+-+-+-+-+-+ /// |Z|0_1| QoS | /// +-+-+-+---------+ - /// % reserved|prio % + /// %0| rsv |prio % /// +---------------+ + /// + /// - prio: Priority class #[repr(transparent)] - #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QoS { - pub priority: Priority, + inner: u8, } impl QoS { + pub const P_MASK: u8 = 0b00000111; + + pub const fn new(priority: Priority) -> Self { + Self { + inner: priority as u8, + } + } + + pub const fn priority(&self) -> Priority { + unsafe { core::mem::transmute(self.inner & Self::P_MASK) } + } + #[cfg(feature = "test")] pub fn rand() -> Self { - use core::convert::TryInto; use rand::Rng; let mut rng = rand::thread_rng(); - let priority: Priority = rng - .gen_range(Priority::MAX as u8..=Priority::MIN as u8) - .try_into() - .unwrap(); - Self { priority } + let inner: u8 = rng.gen(); + Self { inner } + } + } + + impl Default for QoS { + fn default() -> Self { + Self::new(Priority::default()) + } + } + + impl From> for QoS { + fn from(ext: ZExtZ64<{ QOS }>) -> Self { + Self { + inner: ext.value as u8, + } + } + } + + impl From for ZExtZ64<{ QOS }> { + fn from(ext: QoS) -> Self { + ZExtZ64::new(ext.inner as u64) } } } @@ -115,18 +146,14 @@ impl Frame { let mut rng = rand::thread_rng(); - let reliability = if rng.gen_bool(0.5) { - Reliability::Reliable - } else { - Reliability::BestEffort - }; + let reliability = Reliability::rand(); let sn: TransportSn = rng.gen(); let qos = ext::QoS::rand(); let mut payload = vec![]; for _ in 0..rng.gen_range(1..4) { let mut m = ZenohMessage::rand(); m.channel.reliability = reliability; - m.channel.priority = qos.priority; + m.channel.priority = qos.priority(); payload.push(m); } @@ -154,11 +181,7 @@ impl FrameHeader { let mut rng = rand::thread_rng(); - let reliability = if rng.gen_bool(0.5) { - Reliability::Reliable - } else { - Reliability::BestEffort - }; + let reliability = Reliability::rand(); let sn: TransportSn = rng.gen(); let qos = ext::QoS::rand(); diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 026a77591c..3ba771214b 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -38,6 +38,8 @@ pub use open::{OpenAck, OpenSyn}; pub type BatchSize = u16; pub mod id { + // WARNING: it's crucial that these IDs do NOT collide with the IDs + // defined in `crate::network::id`. // pub const JOIN: u8 = 0x01; // For multicast communications only pub const INIT: u8 = 0x02; // For unicast communications only pub const OPEN: u8 = 0x03; // For unicast communications only diff --git a/commons/zenoh-protocol/src/zenoh/declare.rs b/commons/zenoh-protocol/src/zenoh/declare.rs index 7703e00a36..20eb223c9e 100644 --- a/commons/zenoh-protocol/src/zenoh/declare.rs +++ b/commons/zenoh-protocol/src/zenoh/declare.rs @@ -219,11 +219,7 @@ impl Subscriber { let mut rng = rand::thread_rng(); let key = WireExpr::rand(); - let reliability = if rng.gen_bool(0.5) { - Reliability::Reliable - } else { - Reliability::BestEffort - }; + let reliability = Reliability::rand(); let mode = if rng.gen_bool(0.5) { SubMode::Push } else { diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index d74d6c2fa5..4bc1ea0290 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -375,11 +375,7 @@ impl ZenohMessage { .gen_range(Priority::MAX as u8..=Priority::MIN as u8) .try_into() .unwrap(); - let reliability = if rng.gen_bool(0.5) { - Reliability::Reliable - } else { - Reliability::BestEffort - }; + let reliability = Reliability::rand(); let channel = Channel { priority, reliability, diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 4d459d8914..0755d4325f 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -186,7 +186,7 @@ impl StageIn { let frame = FrameHeader { reliability: msg.channel.reliability, sn, - ext_qos: frame::ext::QoS { priority }, + ext_qos: frame::ext::QoS::new(priority), }; if let WError::NewFrame = e { @@ -224,7 +224,7 @@ impl StageIn { reliability: frame.reliability, more: true, sn, - qos: frame.ext_qos, + ext_qos: frame.ext_qos, }; let mut reader = self.fragbuf.reader(); while reader.can_read() { diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/link.rs index b6ab274a74..8651276c3e 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/link.rs @@ -25,11 +25,9 @@ use async_std::task; use async_std::task::JoinHandle; use std::sync::Arc; use std::time::Duration; -use zenoh_buffers::reader::{HasReader, Reader}; use zenoh_buffers::ZSlice; -use zenoh_codec::{RCodec, Zenoh080}; use zenoh_link::{LinkUnicast, LinkUnicastDirection}; -use zenoh_protocol::transport::{KeepAlive, TransportMessage}; +use zenoh_protocol::transport::{BatchSize, KeepAlive, TransportMessage}; use zenoh_result::{bail, zerror, ZResult}; use zenoh_sync::{RecyclingObjectPool, Signal}; @@ -235,7 +233,7 @@ async fn rx_task_stream( transport: TransportUnicastInner, lease: Duration, signal: Signal, - rx_batch_size: u16, + rx_batch_size: BatchSize, rx_buffer_size: usize, ) -> ZResult<()> { enum Action { @@ -247,7 +245,7 @@ async fn rx_task_stream( // 16 bits for reading the batch length let mut length = [0_u8, 0_u8]; link.read_exact(&mut length).await?; - let n = u16::from_le_bytes(length) as usize; + let n = BatchSize::from_le_bytes(length) as usize; link.read_exact(&mut buffer[0..n]).await?; Ok(Action::Read(n)) } @@ -257,8 +255,6 @@ async fn rx_task_stream( Ok(Action::Stop) } - let codec = Zenoh080::new(); - // The pool of buffers let mtu = link.get_mtu().min(rx_batch_size) as usize; let mut n = rx_buffer_size / mtu; @@ -283,20 +279,8 @@ async fn rx_task_stream( } // Deserialize all the messages from the current ZBuf - let mut zslice = ZSlice::make(Arc::new(buffer), 0, n).unwrap(); - let mut reader = zslice.reader(); - while reader.can_read() { - let msg: TransportMessage = codec - .read(&mut reader) - .map_err(|_| zerror!("{}: decoding error", link))?; - - #[cfg(feature = "stats")] - { - transport.stats.inc_rx_t_msgs(1); - } - - transport.receive_message(msg, &link)? - } + let zslice = ZSlice::make(Arc::new(buffer), 0, n).unwrap(); + transport.read_messages(zslice, &link)?; } Action::Stop => break, } @@ -309,7 +293,7 @@ async fn rx_task_dgram( transport: TransportUnicastInner, lease: Duration, signal: Signal, - rx_batch_size: u16, + rx_batch_size: BatchSize, rx_buffer_size: usize, ) -> ZResult<()> { enum Action { @@ -327,8 +311,6 @@ async fn rx_task_dgram( Ok(Action::Stop) } - let codec = Zenoh080::new(); - // The pool of buffers let mtu = link.get_mtu().min(rx_batch_size) as usize; let mut n = rx_buffer_size / mtu; @@ -358,20 +340,8 @@ async fn rx_task_dgram( } // Deserialize all the messages from the current ZBuf - let mut zslice = ZSlice::make(Arc::new(buffer), 0, n).unwrap(); - let mut reader = zslice.reader(); - while reader.can_read() { - let msg: TransportMessage = codec - .read(&mut reader) - .map_err(|_| zerror!("{}: decoding error", link))?; - - #[cfg(feature = "stats")] - { - transport.stats.inc_rx_t_msgs(1); - } - - transport.receive_message(msg, &link)? - } + let zslice = ZSlice::make(Arc::new(buffer), 0, n).unwrap(); + transport.read_messages(zslice, &link)?; } Action::Stop => break, } diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index ae27a68de5..594b47f21a 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -17,6 +17,11 @@ use async_std::task; use std::sync::MutexGuard; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; +use zenoh_buffers::{ + reader::{HasReader, Reader}, + ZSlice, +}; +use zenoh_codec::{RCodec, Zenoh080}; use zenoh_core::{zlock, zread}; use zenoh_link::LinkUnicast; #[cfg(feature = "stats")] @@ -110,19 +115,20 @@ impl TransportUnicastInner { let Frame { reliability, sn, - ext_qos: qos, + ext_qos, mut payload, } = frame; + let priority = ext_qos.priority(); let c = if self.is_qos() { - &self.conduit_rx[qos.priority as usize] - } else if qos.priority == Priority::default() { + &self.conduit_rx[priority as usize] + } else if priority == Priority::default() { &self.conduit_rx[0] } else { bail!( "Transport: {}. Unknown conduit: {:?}.", self.config.zid, - qos.priority + priority ); }; @@ -144,19 +150,19 @@ impl TransportUnicastInner { reliability, more, sn, - qos, + ext_qos: qos, payload, } = fragment; let c = if self.is_qos() { - &self.conduit_rx[qos.priority as usize] - } else if qos.priority == Priority::default() { + &self.conduit_rx[qos.priority() as usize] + } else if qos.priority() == Priority::default() { &self.conduit_rx[0] } else { bail!( "Transport: {}. Unknown conduit: {:?}.", self.config.zid, - qos.priority + qos.priority() ); }; @@ -211,24 +217,40 @@ impl TransportUnicastInner { Ok(()) } - pub(super) fn receive_message(&self, msg: TransportMessage, link: &LinkUnicast) -> ZResult<()> { - log::trace!("Received: {:?}", msg); - // Process the received message - match msg.body { - TransportBody::Frame(msg) => self.handle_frame(msg), - TransportBody::Fragment(fragment) => self.handle_fragment(fragment), - TransportBody::Close(Close { reason, session }) => { - self.handle_close(link, reason, session) + pub(super) fn read_messages(&self, mut zslice: ZSlice, link: &LinkUnicast) -> ZResult<()> { + let codec = Zenoh080::new(); + let mut reader = zslice.reader(); + while reader.can_read() { + let msg: TransportMessage = codec + .read(&mut reader) + .map_err(|_| zerror!("{}: decoding error", link))?; + + log::trace!("Received: {:?}", msg); + + #[cfg(feature = "stats")] + { + transport.stats.inc_rx_t_msgs(1); } - TransportBody::KeepAlive(KeepAlive { .. }) => Ok(()), - _ => { - log::debug!( - "Transport: {}. Message handling not implemented: {:?}", - self.config.zid, - msg - ); - Ok(()) + + match msg.body { + TransportBody::Frame(msg) => self.handle_frame(msg)?, + TransportBody::Fragment(fragment) => self.handle_fragment(fragment)?, + TransportBody::Close(Close { reason, session }) => { + self.handle_close(link, reason, session)? + } + TransportBody::KeepAlive(KeepAlive { .. }) => {} + _ => { + log::debug!( + "Transport: {}. Message handling not implemented: {:?}", + self.config.zid, + msg + ); + } } } + + // Process the received message + + Ok(()) } } From 89eadd47e63cd1a46fe354e043117a99f6d63d80 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 17 Mar 2023 22:32:46 +0100 Subject: [PATCH 099/203] Push codec --- commons/zenoh-codec/src/common/extension.rs | 62 ++++++- commons/zenoh-codec/src/core/mod.rs | 14 +- commons/zenoh-codec/src/core/timestamp.rs | 8 +- commons/zenoh-codec/src/core/zint.rs | 61 ++++++- commons/zenoh-codec/src/lib.rs | 6 + commons/zenoh-codec/src/network/mod.rs | 159 ++++++++++++++++++ commons/zenoh-codec/src/network/push.rs | 138 +++++++++++++++ commons/zenoh-codec/src/transport/frame.rs | 3 - commons/zenoh-codec/tests/codec.rs | 6 + .../zenoh-protocol/src/common/extension.rs | 13 ++ commons/zenoh-protocol/src/network/mod.rs | 42 ++++- commons/zenoh-protocol/src/network/push.rs | 5 +- 12 files changed, 499 insertions(+), 18 deletions(-) create mode 100644 commons/zenoh-codec/src/network/mod.rs create mode 100644 commons/zenoh-codec/src/network/push.rs diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 7b7121a6a6..7102ff4594 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -19,9 +19,10 @@ use zenoh_buffers::{ ZBuf, }; use zenoh_protocol::common::{ - iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZ64, ZExtZBuf, ZExtensionBody, + iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZ64, ZExtZBuf, ZExtZBufHeader, ZExtensionBody, }; +// ZExtUnit impl WCodec<(&ZExtUnit<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, @@ -67,6 +68,7 @@ where } } +// ZExtZ64 impl WCodec<(&ZExtZ64<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, @@ -115,6 +117,7 @@ where } } +// ZExtZBuf impl WCodec<(&ZExtZBuf<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, @@ -123,7 +126,7 @@ where fn write(self, writer: &mut W, x: (&ZExtZBuf<{ ID }>, bool)) -> Self::Output { let (x, more) = x; - let mut header: u8 = ID | iext::ENC_Z64; + let mut header: u8 = ID | iext::ENC_ZBUF; if more { header |= iext::FLAG_Z; } @@ -153,7 +156,7 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result<(ZExtZBuf<{ ID }>, bool), Self::Error> { - if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_Z64) { + if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZBUF) { return Err(DidntRead); } @@ -163,6 +166,59 @@ where } } +// ZExtZBufHeader +impl WCodec<(&ZExtZBufHeader<{ ID }>, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ZExtZBufHeader<{ ID }>, bool)) -> Self::Output { + let (x, more) = x; + let mut header: u8 = ID | iext::ENC_ZBUF; + if more { + header |= iext::FLAG_Z; + } + self.write(&mut *writer, header)?; + self.write(&mut *writer, x.len)?; + Ok(()) + } +} + +impl RCodec<(ZExtZBufHeader<{ ID }>, bool), &mut R> for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ZExtZBufHeader<{ ID }>, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(&mut *reader) + } +} + +impl RCodec<(ZExtZBufHeader<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ZExtZBufHeader<{ ID }>, bool), Self::Error> { + if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZBUF) { + return Err(DidntRead); + } + + let len: usize = self.codec.read(&mut *reader)?; + + Ok(( + ZExtZBufHeader::new(len), + has_flag(self.header, iext::FLAG_Z), + )) + } +} + +// ZExtUnknown impl WCodec<(&ZExtUnknown, bool), &mut W> for Zenoh080 where W: Writer, diff --git a/commons/zenoh-codec/src/core/mod.rs b/commons/zenoh-codec/src/core/mod.rs index be444a2fb7..d1cd8b4c94 100644 --- a/commons/zenoh-codec/src/core/mod.rs +++ b/commons/zenoh-codec/src/core/mod.rs @@ -23,7 +23,7 @@ mod zenohid; mod zint; mod zslice; -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; +use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use alloc::{string::String, vec::Vec}; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -67,6 +67,12 @@ macro_rules! array_impl { Ok(x) } } + + impl LCodec<[u8; $n]> for Zenoh080 { + fn w_len(self, _: [u8; $n]) -> usize { + $n + } + } }; } @@ -132,6 +138,12 @@ vec_impl!(u64); vec_impl!(usize); // &[u8] / Vec +impl LCodec<&[u8]> for Zenoh080 { + fn w_len(self, x: &[u8]) -> usize { + self.w_len(x.len()) + x.len() + } +} + impl WCodec<&[u8], &mut W> for Zenoh080 where W: Writer, diff --git a/commons/zenoh-codec/src/core/timestamp.rs b/commons/zenoh-codec/src/core/timestamp.rs index 6bdd2c1f76..4c15403c75 100644 --- a/commons/zenoh-codec/src/core/timestamp.rs +++ b/commons/zenoh-codec/src/core/timestamp.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080}; +use crate::{LCodec, RCodec, WCodec, Zenoh080}; use core::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,6 +19,12 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::{Timestamp, ZenohId}; +impl LCodec<&Timestamp> for Zenoh080 { + fn w_len(self, x: &Timestamp) -> usize { + self.w_len(x.get_time().as_u64()) + self.w_len(x.get_id().as_slice()) + } +} + impl WCodec<&Timestamp, &mut W> for Zenoh080 where W: Writer, diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index c6beea7ef9..38d4cda3b4 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; +use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use core::convert::TryInto; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -20,6 +20,65 @@ use zenoh_buffers::{ const VLE_LEN: usize = 10; +impl LCodec for Zenoh080 { + fn w_len(self, x: u64) -> usize { + const B1: u64 = !(u64::MAX << 7); + const B2: u64 = !(u64::MAX << (7 * 2)); + const B3: u64 = !(u64::MAX << (7 * 3)); + const B4: u64 = !(u64::MAX << (7 * 4)); + const B5: u64 = !(u64::MAX << (7 * 5)); + const B6: u64 = !(u64::MAX << (7 * 6)); + const B7: u64 = !(u64::MAX << (7 * 7)); + const B8: u64 = !(u64::MAX << (7 * 8)); + const B9: u64 = !(u64::MAX << (7 * 9)); + + if (x & B1) == 0 { + 1 + } else if (x & B2) == 0 { + 2 + } else if (x & B3) == 0 { + 3 + } else if (x & B4) == 0 { + 4 + } else if (x & B5) == 0 { + 5 + } else if (x & B6) == 0 { + 6 + } else if (x & B7) == 0 { + 7 + } else if (x & B8) == 0 { + 8 + } else if (x & B9) == 0 { + 9 + } else { + 10 + } + } +} +impl LCodec for Zenoh080 { + fn w_len(self, x: usize) -> usize { + self.w_len(x as u64) + } +} + +impl LCodec for Zenoh080 { + fn w_len(self, x: u32) -> usize { + self.w_len(x as u64) + } +} + +impl LCodec for Zenoh080 { + fn w_len(self, x: u16) -> usize { + self.w_len(x as u64) + } +} + +impl LCodec for Zenoh080 { + fn w_len(self, _: u8) -> usize { + 1 + } +} + // u8 impl WCodec for Zenoh080 where diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 4a4c837ea5..8e66e6b569 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -16,6 +16,7 @@ extern crate alloc; mod common; mod core; +mod network; mod scouting; mod transport; mod zenoh; @@ -33,6 +34,11 @@ pub trait RCodec { fn read(self, buffer: Buffer) -> Result; } +// Calculate the length of the value once serialized +pub trait LCodec { + fn w_len(self, message: Message) -> usize; +} + #[derive(Clone, Copy)] pub struct Zenoh080; diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs new file mode 100644 index 0000000000..2236bc1c37 --- /dev/null +++ b/commons/zenoh-codec/src/network/mod.rs @@ -0,0 +1,159 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +mod push; + +use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{BacktrackableReader, DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{imsg, ZExtZ64, ZExtZBufHeader}, + network::*, + network::{NetworkBody, NetworkMessage}, +}; + +// NetworkMessage +impl WCodec<&NetworkMessage, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &NetworkMessage) -> Self::Output { + match &x.body { + NetworkBody::Push(b) => self.write(&mut *writer, b), + _ => Ok(()), //TODO + } + } +} + +impl RCodec for Zenoh080 +where + R: Reader + BacktrackableReader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + + let codec = Zenoh080Header::new(header); + let body = match imsg::mid(codec.header) { + id::PUSH => NetworkBody::Push(codec.read(&mut *reader)?), + // id::FRAGMENT => NetworkBody::Fragment(codec.read(&mut *reader)?), + // id::KEEP_ALIVE => NetworkBody::KeepAlive(codec.read(&mut *reader)?), + // id::INIT => { + // if !imsg::has_flag(codec.header, zenoh_protocol::transport::init::flag::A) { + // NetworkBody::InitSyn(codec.read(&mut *reader)?) + // } else { + // NetworkBody::InitAck(codec.read(&mut *reader)?) + // } + // } + // id::OPEN => { + // if !imsg::has_flag(codec.header, zenoh_protocol::transport::open::flag::A) { + // NetworkBody::OpenSyn(codec.read(&mut *reader)?) + // } else { + // NetworkBody::OpenAck(codec.read(&mut *reader)?) + // } + // } + // // id::JOIN => NetworkBody::Join(codec.read(&mut *reader)?), + // id::CLOSE => NetworkBody::Close(codec.read(&mut *reader)?), + _ => return Err(DidntRead), + }; + + Ok(NetworkMessage { body }) + } +} + +// Extensions: QoS +impl WCodec<(ext::QoS, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (ext::QoS, bool)) -> Self::Output { + let (qos, more) = x; + let ext: ZExtZ64<{ ext::QOS }> = qos.into(); + self.write(&mut *writer, (&ext, more)) + } +} + +impl RCodec<(ext::QoS, bool), &mut R> for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec<(ext::QoS, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { + let (ext, more): (ZExtZ64<{ ext::QOS }>, bool) = self.read(&mut *reader)?; + Ok((ext.into(), more)) + } +} + +// Extensions: Timestamp +impl WCodec<(&ext::Timestamp, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::Timestamp, bool)) -> Self::Output { + let (tstamp, more) = x; + let header: ZExtZBufHeader<{ ext::TSTAMP }> = + ZExtZBufHeader::new(self.w_len(&tstamp.timestamp)); + self.write(&mut *writer, (&header, more))?; + self.write(&mut *writer, &tstamp.timestamp) + } +} + +impl RCodec<(ext::Timestamp, bool), &mut R> for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::Timestamp, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec<(ext::Timestamp, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::Timestamp, bool), Self::Error> { + let codec = Zenoh080::new(); + let (_, more): (ZExtZBufHeader<{ ext::TSTAMP }>, bool) = self.read(&mut *reader)?; + let timestamp: uhlc::Timestamp = codec.read(&mut *reader)?; + Ok((ext::Timestamp { timestamp }, more)) + } +} diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs new file mode 100644 index 0000000000..88fd31f6ea --- /dev/null +++ b/commons/zenoh-codec/src/network/push.rs @@ -0,0 +1,138 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{imsg, ZExtUnknown}, + core::WireExpr, + network::{ext, id, push::flag, Mapping, Push}, + zenoh::ZenohMessage, +}; + +impl WCodec<&Push, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Push) -> Self::Output { + // Header + let mut header = id::PUSH; + let mut n_exts = + ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + if n_exts != 0 { + header |= flag::Z; + } + if x.mapping != Mapping::default() { + header |= flag::M; + } + if x.wire_expr.has_suffix() { + header |= flag::N; + } + self.write(&mut *writer, header)?; + + // KeyExpr + self.write(&mut *writer, &x.wire_expr)?; + + // Extensions + if x.ext_qos != ext::QoS::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + } + if let Some(ts) = x.ext_tstamp.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (ts, n_exts != 0))?; + } + + // Payload + self.write(&mut *writer, &x.payload)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::PUSH { + return Err(DidntRead); + } + + // KeyExpr + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); + let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + let mapping = if imsg::has_flag(self.header, flag::M) { + Mapping::Sender + } else { + Mapping::Receiver + }; + + // Extensions + let mut ext_qos = ext::QoS::default(); + let mut ext_tstamp = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QOS => { + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + ext_qos = q; + has_ext = ext; + } + ext::TSTAMP => { + let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext_tstamp = Some(t); + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + // Message + let payload: ZenohMessage = self.codec.read(&mut *reader)?; + + Ok(Push { + wire_expr, + mapping, + payload, + ext_qos, + ext_tstamp, + }) + } +} diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index fa885f888e..ce6cbd906a 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -61,9 +61,6 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { - if imsg::mid(self.header) != ext::QOS { - return Err(DidntRead); - } let (ext, more): (ZExtZ64<{ ext::QOS }>, bool) = self.read(&mut *reader)?; Ok((ext.into(), more)) } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 93641b6766..dd66653c18 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -435,6 +435,12 @@ fn codec_transport() { run!(TransportMessage, TransportMessage::rand()); } +// Network +// #[test] +// fn codec_push() { +// run!(Push, Push::rand()); +// } + // Zenoh #[test] fn codec_routing_context() { diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index 22f861e089..33fd8273da 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -178,6 +178,19 @@ impl TryFrom for ZExtZBuf<{ ID }> { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ZExtZBufHeader { + pub len: usize, +} + +impl ZExtZBufHeader<{ ID }> { + pub const ID: u8 = ID; + + pub const fn new(len: usize) -> Self { + Self { len } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ZExtUnknown { pub id: u8, diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index ce76cb2589..96cad42e66 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -31,6 +31,28 @@ pub mod id { pub const RESPONSE_FINAL: u8 = 0x1b; } +#[repr(u8)] +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub enum Mapping { + #[default] + Receiver = 0, + Sender = 1, +} + +impl Mapping { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + if rng.gen_bool(0.5) { + Mapping::Sender + } else { + Mapping::Receiver + } + } +} + // Zenoh messages at zenoh-network level #[derive(Debug, Clone, PartialEq, Eq)] pub enum NetworkBody { @@ -114,6 +136,7 @@ pub mod ext { common::{imsg, ZExtZ64}, core::{CongestionControl, Priority}, }; + use core::fmt; pub const QOS: u8 = 0x01; pub const TSTAMP: u8 = 0x02; @@ -130,7 +153,7 @@ pub mod ext { /// - E: Express. Don't batch this message. /// - rsv: Reserved #[repr(transparent)] - #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[derive(Clone, Copy, PartialEq, Eq)] pub struct QoS { inner: u8, } @@ -200,6 +223,16 @@ pub mod ext { } } + impl fmt::Debug for QoS { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("QoS") + .field("priority", &self.priority()) + .field("congestion", &self.congestion_control()) + .field("express", &self.is_express()) + .finish() + } + } + /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ /// |Z|1_0| ID | @@ -225,11 +258,4 @@ pub mod ext { Self { timestamp } } } - - pub mod qos { - pub mod flag { - pub const D: u8 = 1 << 3; // 0x08 Don't drop. Don't drop the message for congestion control. - pub const E: u8 = 1 << 4; // 0x10 Express. Don't batch this message. - } - } } diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs index 24305a5eed..4261948dbc 100644 --- a/commons/zenoh-protocol/src/network/push.rs +++ b/commons/zenoh-protocol/src/network/push.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, zenoh::ZenohMessage}; +use crate::{core::WireExpr, network::Mapping, zenoh::ZenohMessage}; pub mod flag { pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix @@ -41,6 +41,7 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Push { pub wire_expr: WireExpr<'static>, + pub mapping: Mapping, pub payload: ZenohMessage, pub ext_qos: ext::QoS, pub ext_tstamp: Option, @@ -61,12 +62,14 @@ impl Push { let mut rng = rand::thread_rng(); let wire_expr = WireExpr::rand(); + let mapping = Mapping::rand(); let payload = ZenohMessage::rand(); let ext_qos = ext::QoS::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); Self { wire_expr, + mapping, payload, ext_tstamp, ext_qos, From d7ac9bc5424b39f65f350e48c12dd4c8ccb40194 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 18 Mar 2023 11:26:38 +0100 Subject: [PATCH 100/203] Adding Pull message draft. Refinemenet of Declare messages --- commons/zenoh-protocol/src/network/declare.rs | 252 +++++++++--------- commons/zenoh-protocol/src/network/mod.rs | 5 +- commons/zenoh-protocol/src/network/pull.rs | 75 ++++++ commons/zenoh-protocol/src/network/request.rs | 11 +- .../zenoh-protocol/src/network/response.rs | 14 +- 5 files changed, 223 insertions(+), 134 deletions(-) create mode 100644 commons/zenoh-protocol/src/network/pull.rs diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index 10d81716ca..7a901bca6e 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -13,6 +13,10 @@ // use crate::core::{ExprId, Reliability, WireExpr}; +pub type SubscriberId = u32; +pub type QueryableId = u32; +pub type TokenId = u32; + /// Flags: /// - X: Reserved /// - X: Reserved @@ -22,7 +26,7 @@ use crate::core::{ExprId, Reliability, WireExpr}; /// +-+-+-+-+-+-+-+-+ /// |Z|X|X| DECLARE | /// +-+-+-+---------+ -/// ~ declare_exts ~ if Z==1 +/// ~ [decl_exts] ~ if Z==1 /// +---------------+ /// ~ declaration ~ /// +---------------+ @@ -46,14 +50,11 @@ pub mod id { pub const D_KEYEXPR: u8 = 0x01; pub const F_KEYEXPR: u8 = 0x02; - pub const D_PUBLISHER: u8 = 0x03; - pub const F_PUBLISHER: u8 = 0x04; - - pub const D_SUBSCRIBER: u8 = 0x05; - pub const F_SUBSCRIBER: u8 = 0x06; + pub const D_SUBSCRIBER: u8 = 0x03; + pub const F_SUBSCRIBER: u8 = 0x04; - pub const D_QUERYABLE: u8 = 0x07; - pub const F_QUERYABLE: u8 = 0x08; + pub const D_QUERYABLE: u8 = 0x05; + pub const F_QUERYABLE: u8 = 0x06; // SubModes pub const MODE_PUSH: u8 = 0x00; @@ -64,8 +65,6 @@ pub mod id { pub enum DeclareBody { DeclareKeyExpr(DeclareKeyExpr), ForgetKeyExpr(ForgetKeyExpr), - DeclarePublisher(DeclarePublisher), - ForgetPublisher(ForgetPublisher), DeclareSubscriber(DeclareSubscriber), ForgetSubscriber(ForgetSubscriber), DeclareQueryable(DeclareQueryable), @@ -79,15 +78,13 @@ impl DeclareBody { let mut rng = rand::thread_rng(); - match rng.gen_range(0..8) { + match rng.gen_range(0..6) { 0 => DeclareBody::DeclareKeyExpr(DeclareKeyExpr::rand()), 1 => DeclareBody::ForgetKeyExpr(ForgetKeyExpr::rand()), - 2 => DeclareBody::DeclarePublisher(DeclarePublisher::rand()), - 3 => DeclareBody::ForgetPublisher(ForgetPublisher::rand()), - 4 => DeclareBody::DeclareSubscriber(DeclareSubscriber::rand()), - 5 => DeclareBody::ForgetSubscriber(ForgetSubscriber::rand()), - 6 => DeclareBody::DeclareQueryable(DeclareQueryable::rand()), - 7 => DeclareBody::ForgetQueryable(ForgetQueryable::rand()), + 2 => DeclareBody::DeclareSubscriber(DeclareSubscriber::rand()), + 3 => DeclareBody::ForgetSubscriber(ForgetSubscriber::rand()), + 4 => DeclareBody::DeclareQueryable(DeclareQueryable::rand()), + 5 => DeclareBody::ForgetQueryable(ForgetQueryable::rand()), _ => unreachable!(), } } @@ -154,7 +151,7 @@ impl Mode { /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareKeyExpr { - pub expr_id: ExprId, + pub id: ExprId, pub wire_expr: WireExpr<'static>, } @@ -165,10 +162,10 @@ impl DeclareKeyExpr { let mut rng = rand::thread_rng(); - let expr_id: ExprId = rng.gen(); + let id: ExprId = rng.gen(); let wire_expr = WireExpr::rand(); - Self { expr_id, wire_expr } + Self { id, wire_expr } } } @@ -180,7 +177,7 @@ impl DeclareKeyExpr { /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|X|X| F_RES | +/// |Z|X|X| F_KEXPR | /// +---------------+ /// ~ expr_id:z16 ~ /// +---------------+ @@ -203,64 +200,6 @@ impl ForgetKeyExpr { } } -/// ```text -/// Flags: -/// - N: Named If N==1 then the key expr has name/suffix -/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| D_PUB | -/// +---------------+ -/// ~ key_scope:z16 ~ -/// +---------------+ -/// ~ key_suffix ~ if N==1 -- -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct DeclarePublisher { - pub key: WireExpr<'static>, -} - -impl DeclarePublisher { - #[cfg(feature = "test")] - pub fn rand() -> Self { - let key = WireExpr::rand(); - - Self { key } - } -} - -/// ```text -/// Flags: -/// - N: Named If N==1 then the key expr has name/suffix -/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| F_PUB | -/// +---------------+ -/// ~ key_scope:z16 ~ -/// +---------------+ -/// ~ key_suffix ~ if N==1 -- -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetPublisher { - pub wire_expr: WireExpr<'static>, -} - -impl ForgetPublisher { - #[cfg(feature = "test")] - pub fn rand() -> Self { - let key = WireExpr::rand(); - - Self { wire_expr: key } - } -} - /// The subscription mode. #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct SubscriberInfo { @@ -278,6 +217,8 @@ pub struct SubscriberInfo { /// +-+-+-+-+-+-+-+-+ /// |Z|M|N| D_SUB | /// +---------------+ +/// ~ subs_id:z32 ~ +/// +---------------+ /// ~ key_scope:z16 ~ /// +---------------+ /// ~ key_suffix ~ if N==1 -- @@ -291,20 +232,27 @@ pub struct SubscriberInfo { /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareSubscriber { - pub key: WireExpr<'static>, + pub id: SubscriberId, + pub wire_expr: WireExpr<'static>, pub info: SubscriberInfo, } impl DeclareSubscriber { #[cfg(feature = "test")] pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let id: SubscriberId = rng.gen(); let wire_expr = WireExpr::rand(); let reliability = Reliability::rand(); let mode = Mode::rand(); let info = SubscriberInfo { reliability, mode }; Self { - key: wire_expr, + id, + wire_expr, info, } } @@ -312,39 +260,32 @@ impl DeclareSubscriber { /// ```text /// Flags: -/// - N: Named If N==1 then the key expr has name/suffix -/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - X: Reserved +/// - X: Reserved /// - Z: Extension If Z==1 then at least one extension is present /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| F_SUB | +/// |Z|X|X| F_SUB | /// +---------------+ -/// ~ key_scope:z16 ~ +/// ~ subs_id:z32 ~ /// +---------------+ -/// ~ key_suffix ~ if N==1 -- -/// +---------------+ -/// |X|X|X|X|X|X|P|R| (*) -/// +---------------+ -/// -/// - if R==1 then the subscription is reliable, else it is best effort -/// - if P==1 then the subscription is pull, else it is push /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct ForgetSubscriber { - pub wire_expr: WireExpr<'static>, - pub info: SubscriberInfo, + pub id: SubscriberId, } impl ForgetSubscriber { #[cfg(feature = "test")] pub fn rand() -> Self { - let wire_expr = WireExpr::rand(); - let reliability = Reliability::rand(); - let mode = Mode::rand(); - let info = SubscriberInfo { reliability, mode }; + use rand::Rng; + + let mut rng = rand::thread_rng(); - Self { wire_expr, info } + let id: SubscriberId = rng.gen(); + + Self { id } } } @@ -357,10 +298,17 @@ pub struct QueryableInfo { } /// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ /// |Z|M|N| D_QBL | /// +---------------+ +/// ~ qbls_id:z32 ~ +/// +---------------+ /// ~ key_scope:z16 ~ /// +---------------+ /// ~ key_suffix ~ if N==1 -- @@ -379,6 +327,7 @@ pub struct QueryableInfo { /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareQueryable { + pub id: QueryableId, pub wire_expr: WireExpr<'static>, pub info: QueryableInfo, } @@ -390,6 +339,7 @@ impl DeclareQueryable { let mut rng = rand::thread_rng(); + let id: QueryableId = rng.gen(); let wire_expr = WireExpr::rand(); let mode = Mode::rand(); let reliability = Reliability::rand(); @@ -402,56 +352,110 @@ impl DeclareQueryable { distance, }; - Self { wire_expr, info } + Self { + id, + wire_expr, + info, + } } } /// ```text +/// Flags: +/// - X: Reserved +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| F_QBL | +/// |Z|X|X| F_QBL | /// +---------------+ -/// ~ key_scope:z16 ~ +/// ~ qbls_id:z32 ~ /// +---------------+ -/// ~ key_suffix ~ if N==1 -- +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ForgetQueryable { + pub id: QueryableId, +} + +impl ForgetQueryable { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let id: QueryableId = rng.gen(); + + Self { id } + } +} + +/// ```text +/// Flags: +/// - N: Named If N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| D_TKN | /// +---------------+ -/// |X|X|X|X|D|C|P|R| (*) +/// ~ token_id:z32 ~ /// +---------------+ -/// ~ complete_n ~ if C==1 +/// ~ key_scope:z16 ~ /// +---------------+ -/// ~ distance ~ if D==1 +/// ~ key_suffix ~ if N==1 -- /// +---------------+ /// -/// - if R==1 then the queryable is reliable, else it is best effort -/// - if P==1 then the queryable is pull, else it is push -/// - if C==1 then the queryable is complete and the N parameter is present -/// - if D==1 then the queryable distance is present /// ``` #[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetQueryable { +pub struct DeclareToken { + pub id: TokenId, pub wire_expr: WireExpr<'static>, - pub info: QueryableInfo, } -impl ForgetQueryable { +impl DeclareToken { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; let mut rng = rand::thread_rng(); + let id: TokenId = rng.gen(); let wire_expr = WireExpr::rand(); - let mode = Mode::rand(); - let reliability = Reliability::rand(); - let complete: u32 = rng.gen(); - let distance: u32 = rng.gen(); - let info = QueryableInfo { - reliability, - mode, - complete, - distance, - }; - Self { wire_expr, info } + Self { id, wire_expr } + } +} + +/// ```text +/// Flags: +/// - X: Reserved +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|X|X| F_TKN | +/// +---------------+ +/// ~ token_id:z32 ~ +/// +---------------+ +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ForgetToken { + pub id: TokenId, +} + +impl ForgetToken { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let id: TokenId = rng.gen(); + + Self { id } } } diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 96cad42e66..200bc2a61e 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // pub mod declare; +pub mod pull; pub mod push; pub mod request; pub mod response; @@ -22,8 +23,8 @@ pub use request::{Request, RequestId}; pub use response::{Response, ResponseFinal}; pub mod id { - // WARNING: it's crucial that these IDs do NOT collide with the IDs - // defined in `crate::transport::id`. + // WARNING: it's crucial for Zenoh to work that these IDs do NOT + // collide with the IDs defined in `crate::transport::id`. pub const DECLARE: u8 = 0x1f; pub const PUSH: u8 = 0x1e; pub const REQUEST: u8 = 0x1d; diff --git a/commons/zenoh-protocol/src/network/pull.rs b/commons/zenoh-protocol/src/network/pull.rs new file mode 100644 index 0000000000..d68289413a --- /dev/null +++ b/commons/zenoh-protocol/src/network/pull.rs @@ -0,0 +1,75 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +pub type PullId = u32; + +#[repr(u8)] +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub enum PullTarget { + #[default] + Push = 0x00, + Request = 0x01, +} + +impl PullTarget { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + match rng.gen_range(0..2) { + 0 => PullTarget::Push, + 1 => PullTarget::Request, + _ => unreachable!(), + } + } +} + +/// ```text +/// Flags: +/// - X: Reserved +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|X|X| PULL | +/// +-+-+-+---------+ +/// | target | +/// +---------------+ +/// ~ id:z32 ~ (*) +/// +---------------+ +/// +/// (*) ID refers to the ID used in a previous target declaration +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Pull { + pub target: PullTarget, + pub id: PullId, +} + +impl Pull { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + let target = PullTarget::rand(); + let id: PullId = rng.gen(); + + Self { target, id } + } +} diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index 12757d6182..49e0ff165c 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -30,21 +30,24 @@ pub type AtomicRequestId = AtomicU32; /// +-+-+-+-+-+-+-+-+ /// |Z|M|N| Request | /// +-+-+-+---------+ +/// ~ request_id:z32~ (*) +/// +---------------+ /// ~ key_scope:z16 ~ /// +---------------+ /// ~ key_suffix ~ if N==1 -- /// +---------------+ -/// ~ rid ~ -/// +---------------+ /// ~ [req_exts] ~ if Z==1 /// +---------------+ /// ~ ZenohMessage ~ -- Payload /// +---------------+ +/// +/// (*) The resolution of the request id is negotiated during the session establishment. +/// This implementation limits the resolution to 32bit. /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct Request { + pub id: RequestId, pub wire_expr: WireExpr<'static>, - pub rid: RequestId, pub payload: ZenohMessage, pub ext_qos: ext::QoS, pub ext_tstamp: Option, @@ -112,7 +115,7 @@ impl Request { Self { wire_expr, - rid, + id: rid, payload, ext_qos, ext_tstamp, diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index 2f5b693cec..8c5da20384 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -23,18 +23,21 @@ use crate::{core::WireExpr, network::RequestId, zenoh::ZenohMessage}; /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| ResMore | +/// |Z|M|N| Response| /// +-+-+-+---------+ +/// ~ request_id:z32~ (*) +/// +---------------+ /// ~ key_scope:z16 ~ /// +---------------+ /// ~ key_suffix ~ if N==1 -- /// +---------------+ -/// ~ rid ~ -/// +---------------+ /// ~ [reply_exts] ~ if Z==1 /// +---------------+ /// ~ ZenohMessage ~ -- Payload /// +---------------+ +/// +/// (*) The resolution of the request id is negotiated during the session establishment. +/// This implementation limits the resolution to 32bit. /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct Response { @@ -88,10 +91,13 @@ impl Response { /// +-+-+-+-+-+-+-+-+ /// |Z|M|N| ResFinal| /// +-+-+-+---------+ -/// ~ rid ~ +/// ~ request_id:z32~ (*) /// +---------------+ /// ~ [reply_exts] ~ if Z==1 /// +---------------+ +/// +/// (*) The resolution of the request id is negotiated during the session establishment. +/// This implementation limits the resolution to 32bit. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ResponseFinal { pub rid: RequestId, From 9b8ff4085e09f5f6a832e3694dc49f858ee0048e Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 21 Mar 2023 12:55:05 +0100 Subject: [PATCH 101/203] New network declare codec --- commons/zenoh-codec/src/common/extension.rs | 44 ++ commons/zenoh-codec/src/network/declare.rs | 585 ++++++++++++++ commons/zenoh-codec/src/network/mod.rs | 40 +- commons/zenoh-codec/src/network/push.rs | 58 +- commons/zenoh-codec/src/network/request.rs | 236 ++++++ commons/zenoh-codec/src/transport/frame.rs | 38 +- commons/zenoh-codec/tests/codec.rs | 75 +- commons/zenoh-protocol/src/common/mod.rs | 1 - commons/zenoh-protocol/src/core/wire_expr.rs | 2 +- commons/zenoh-protocol/src/network/declare.rs | 735 +++++++++++------- commons/zenoh-protocol/src/network/mod.rs | 4 +- commons/zenoh-protocol/src/network/push.rs | 35 +- commons/zenoh-protocol/src/network/request.rs | 66 +- .../zenoh-protocol/src/network/response.rs | 7 +- commons/zenoh-protocol/src/transport/frame.rs | 2 +- 15 files changed, 1516 insertions(+), 412 deletions(-) create mode 100644 commons/zenoh-codec/src/network/declare.rs create mode 100644 commons/zenoh-codec/src/network/request.rs diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 7102ff4594..f862af2568 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -326,3 +326,47 @@ where Ok(exts) } } + +// Macros +#[macro_export] +macro_rules! impl_zextz64 { + ($ext:ty, $id:expr) => { + impl WCodec<($ext, bool), &mut W> for Zenoh080 + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: ($ext, bool)) -> Self::Output { + let (qos, more) = x; + let ext: ZExtZ64<{ $id }> = qos.into(); + self.write(&mut *writer, (&ext, more)) + } + } + + impl RCodec<($ext, bool), &mut R> for Zenoh080 + where + R: Reader, + { + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<($ext, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } + } + + impl RCodec<($ext, bool), &mut R> for Zenoh080Header + where + R: Reader, + { + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<($ext, bool), Self::Error> { + let (ext, more): (ZExtZ64<{ $id }>, bool) = self.read(&mut *reader)?; + Ok((ext.into(), more)) + } + } + }; +} diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs new file mode 100644 index 0000000000..0549873b2b --- /dev/null +++ b/commons/zenoh-codec/src/network/declare.rs @@ -0,0 +1,585 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{imsg, ZExtUnknown, ZExtZ64}, + core::{ExprId, WireExpr}, + network::{ + declare::{self, keyexpr, queryable, subscriber, Declare, DeclareBody}, + id, Mapping, + }, +}; + +// Declaration +impl WCodec<&DeclareBody, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &DeclareBody) -> Self::Output { + match x { + DeclareBody::DeclareKeyExpr(r) => self.write(&mut *writer, r)?, + DeclareBody::ForgetKeyExpr(r) => self.write(&mut *writer, r)?, + DeclareBody::DeclareSubscriber(r) => self.write(&mut *writer, r)?, + DeclareBody::ForgetSubscriber(r) => self.write(&mut *writer, r)?, + DeclareBody::DeclareQueryable(r) => self.write(&mut *writer, r)?, + DeclareBody::ForgetQueryable(r) => self.write(&mut *writer, r)?, + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + use declare::id::*; + let d = match imsg::mid(codec.header) { + D_KEYEXPR => DeclareBody::DeclareKeyExpr(codec.read(&mut *reader)?), + F_KEYEXPR => DeclareBody::ForgetKeyExpr(codec.read(&mut *reader)?), + D_SUBSCRIBER => DeclareBody::DeclareSubscriber(codec.read(&mut *reader)?), + F_SUBSCRIBER => DeclareBody::ForgetSubscriber(codec.read(&mut *reader)?), + D_QUERYABLE => DeclareBody::DeclareQueryable(codec.read(&mut *reader)?), + F_QUERYABLE => DeclareBody::ForgetQueryable(codec.read(&mut *reader)?), + _ => return Err(DidntRead), + }; + + Ok(d) + } +} + +// Declare +impl WCodec<&Declare, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Declare) -> Self::Output { + // Header + let mut header = id::DECLARE; + let mut n_exts = + ((x.ext_qos != declare::ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + if n_exts != 0 { + header |= declare::flag::Z; + } + self.write(&mut *writer, header)?; + + // Extensions + if x.ext_qos != declare::ext::QoS::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + } + if let Some(ts) = x.ext_tstamp.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (ts, n_exts != 0))?; + } + + // Body + self.write(&mut *writer, &x.body)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::DECLARE { + return Err(DidntRead); + } + + // Extensions + let mut ext_qos = declare::ext::QoS::default(); + let mut ext_tstamp = None; + + let mut has_ext = imsg::has_flag(self.header, declare::flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + declare::ext::QOS => { + let (q, ext): (declare::ext::QoS, bool) = eodec.read(&mut *reader)?; + ext_qos = q; + has_ext = ext; + } + declare::ext::TSTAMP => { + let (t, ext): (declare::ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext_tstamp = Some(t); + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + // Body + let body: DeclareBody = self.codec.read(&mut *reader)?; + + Ok(Declare { + body, + ext_qos, + ext_tstamp, + }) + } +} + +// DeclareKeyExpr +impl WCodec<&keyexpr::DeclareKeyExpr, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &keyexpr::DeclareKeyExpr) -> Self::Output { + // Header + let mut header = declare::id::D_KEYEXPR; + if x.wire_expr.has_suffix() { + header |= keyexpr::flag::N; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + self.write(&mut *writer, &x.wire_expr)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::D_KEYEXPR { + return Err(DidntRead); + } + + let id: ExprId = self.codec.read(&mut *reader)?; + let ccond = Zenoh080Condition { + condition: imsg::has_flag(self.header, keyexpr::flag::N), + codec: self.codec, + }; + let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + + Ok(keyexpr::DeclareKeyExpr { id, wire_expr }) + } +} + +// ForgetKeyExpr +impl WCodec<&keyexpr::ForgetKeyExpr, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &keyexpr::ForgetKeyExpr) -> Self::Output { + // Header + let header = declare::id::F_KEYEXPR; + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::F_KEYEXPR { + return Err(DidntRead); + } + + let id: ExprId = self.codec.read(&mut *reader)?; + + Ok(keyexpr::ForgetKeyExpr { id }) + } +} + +// SubscriberInfo +crate::impl_zextz64!(subscriber::ext::SubscriberInfo, subscriber::ext::INFO); + +// DeclareSubscriber +impl WCodec<&subscriber::DeclareSubscriber, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &subscriber::DeclareSubscriber) -> Self::Output { + // Header + let mut header = declare::id::D_SUBSCRIBER; + let mut n_exts = (x.ext_info != subscriber::ext::SubscriberInfo::default()) as u8; + if n_exts != 0 { + header |= subscriber::flag::Z; + } + if x.mapping != Mapping::default() { + header |= subscriber::flag::M; + } + if x.wire_expr.has_suffix() { + header |= subscriber::flag::N; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + self.write(&mut *writer, &x.wire_expr)?; + + // Extensions + if x.ext_info != subscriber::ext::SubscriberInfo::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_info, n_exts != 0))?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::D_SUBSCRIBER { + return Err(DidntRead); + } + + // Body + let id: subscriber::SubscriberId = self.codec.read(&mut *reader)?; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, subscriber::flag::N)); + let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + let mapping = if imsg::has_flag(self.header, subscriber::flag::M) { + Mapping::Sender + } else { + Mapping::Receiver + }; + + // Extensions + let mut ext_info = subscriber::ext::SubscriberInfo::default(); + + let mut has_ext = imsg::has_flag(self.header, subscriber::flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + subscriber::ext::INFO => { + let (i, ext): (subscriber::ext::SubscriberInfo, bool) = + eodec.read(&mut *reader)?; + ext_info = i; + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + Ok(subscriber::DeclareSubscriber { + id, + wire_expr, + mapping, + ext_info, + }) + } +} + +// ForgetSubscriber +impl WCodec<&subscriber::ForgetSubscriber, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &subscriber::ForgetSubscriber) -> Self::Output { + // Header + let header = declare::id::F_SUBSCRIBER; + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::F_SUBSCRIBER { + return Err(DidntRead); + } + + // Body + let id: subscriber::SubscriberId = self.codec.read(&mut *reader)?; + + Ok(subscriber::ForgetSubscriber { id }) + } +} + +// SubscriberInfo +crate::impl_zextz64!(queryable::ext::QueryableInfo, queryable::ext::INFO); + +// DeclareQueryable +impl WCodec<&queryable::DeclareQueryable, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &queryable::DeclareQueryable) -> Self::Output { + // Header + let mut header = declare::id::D_QUERYABLE; + let mut n_exts = (x.ext_info != queryable::ext::QueryableInfo::default()) as u8; + if n_exts != 0 { + header |= subscriber::flag::Z; + } + if x.mapping != Mapping::default() { + header |= subscriber::flag::M; + } + if x.wire_expr.has_suffix() { + header |= subscriber::flag::N; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + self.write(&mut *writer, &x.wire_expr)?; + if x.ext_info != queryable::ext::QueryableInfo::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_info, n_exts != 0))?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::D_QUERYABLE { + return Err(DidntRead); + } + + // Body + let id: queryable::QueryableId = self.codec.read(&mut *reader)?; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, queryable::flag::N)); + let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + let mapping = if imsg::has_flag(self.header, queryable::flag::M) { + Mapping::Sender + } else { + Mapping::Receiver + }; + + // Extensions + let mut ext_info = queryable::ext::QueryableInfo::default(); + + let mut has_ext = imsg::has_flag(self.header, queryable::flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + queryable::ext::INFO => { + let (i, ext): (queryable::ext::QueryableInfo, bool) = + eodec.read(&mut *reader)?; + ext_info = i; + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + Ok(queryable::DeclareQueryable { + id, + wire_expr, + mapping, + ext_info, + }) + } +} + +// ForgetQueryable +impl WCodec<&queryable::ForgetQueryable, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &queryable::ForgetQueryable) -> Self::Output { + // Header + let header = declare::id::F_QUERYABLE; + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::F_QUERYABLE { + return Err(DidntRead); + } + + // Body + let id: subscriber::SubscriberId = self.codec.read(&mut *reader)?; + + Ok(queryable::ForgetQueryable { id }) + } +} diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 2236bc1c37..e350f2d110 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -11,7 +11,9 @@ // Contributors: // ZettaScale Zenoh Team, // +mod declare; mod push; +mod request; use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ @@ -77,43 +79,7 @@ where } // Extensions: QoS -impl WCodec<(ext::QoS, bool), &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: (ext::QoS, bool)) -> Self::Output { - let (qos, more) = x; - let ext: ZExtZ64<{ ext::QOS }> = qos.into(); - self.write(&mut *writer, (&ext, more)) - } -} - -impl RCodec<(ext::QoS, bool), &mut R> for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - codec.read(reader) - } -} - -impl RCodec<(ext::QoS, bool), &mut R> for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { - let (ext, more): (ZExtZ64<{ ext::QOS }>, bool) = self.read(&mut *reader)?; - Ok((ext.into(), more)) - } -} +crate::impl_zextz64!(ext::QoS, ext::QOS); // Extensions: Timestamp impl WCodec<(&ext::Timestamp, bool), &mut W> for Zenoh080 diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index 88fd31f6ea..ed44c0896f 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -17,12 +17,40 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown}, + common::{imsg, ZExtUnit, ZExtUnknown}, core::WireExpr, - network::{ext, id, push::flag, Mapping, Push}, - zenoh::ZenohMessage, + network::{ + id, + push::{ext, flag}, + Mapping, Push, + }, }; +impl WCodec<(ext::Destination, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (ext::Destination, bool)) -> Self::Output { + let (_, more) = x; + let ext: ZExtUnit<{ ext::DST }> = ZExtUnit::new(); + self.write(&mut *writer, (&ext, more)) + } +} + +impl RCodec<(ext::Destination, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::Destination, bool), Self::Error> { + let (_, more): (ZExtUnit<{ ext::DST }>, bool) = self.read(&mut *reader)?; + Ok((ext::Destination::Queryables, more)) + } +} + impl WCodec<&Push, &mut W> for Zenoh080 where W: Writer, @@ -32,8 +60,8 @@ where fn write(self, writer: &mut W, x: &Push) -> Self::Output { // Header let mut header = id::PUSH; - let mut n_exts = - ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + let mut n_exts = ((x.ext_qos != ext::QoS::default()) as u8) + + (x.ext_tstamp.is_some() as u8 + (x.ext_dst != ext::Destination::default()) as u8); if n_exts != 0 { header |= flag::Z; } @@ -45,7 +73,7 @@ where } self.write(&mut *writer, header)?; - // KeyExpr + // Body self.write(&mut *writer, &x.wire_expr)?; // Extensions @@ -57,6 +85,10 @@ where n_exts -= 1; self.write(&mut *writer, (ts, n_exts != 0))?; } + if x.ext_dst != ext::Destination::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_dst, n_exts != 0))?; + } // Payload self.write(&mut *writer, &x.payload)?; @@ -89,7 +121,7 @@ where return Err(DidntRead); } - // KeyExpr + // Body let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; let mapping = if imsg::has_flag(self.header, flag::M) { @@ -101,6 +133,7 @@ where // Extensions let mut ext_qos = ext::QoS::default(); let mut ext_tstamp = None; + let mut ext_dst = ext::Destination::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -117,6 +150,11 @@ where ext_tstamp = Some(t); has_ext = ext; } + ext::DST => { + let (d, ext): (ext::Destination, bool) = eodec.read(&mut *reader)?; + ext_dst = d; + has_ext = ext; + } _ => { let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; has_ext = ext; @@ -124,8 +162,9 @@ where } } - // Message - let payload: ZenohMessage = self.codec.read(&mut *reader)?; + // Payload + // let payload: ZenohMessage = self.codec.read(&mut *reader)?; + let payload: u8 = self.codec.read(&mut *reader)?; // @TODO Ok(Push { wire_expr, @@ -133,6 +172,7 @@ where payload, ext_qos, ext_tstamp, + ext_dst, }) } } diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs new file mode 100644 index 0000000000..1dcd7842b3 --- /dev/null +++ b/commons/zenoh-codec/src/network/request.rs @@ -0,0 +1,236 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{imsg, ZExtUnit, ZExtUnknown, ZExtZ64}, + core::WireExpr, + network::{ + id, + request::{ext, flag}, + Mapping, Request, RequestId, + }, +}; + +// Destination +impl WCodec<(ext::Destination, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (ext::Destination, bool)) -> Self::Output { + let (_, more) = x; + let ext: ZExtUnit<{ ext::DST }> = ZExtUnit::new(); + self.write(&mut *writer, (&ext, more)) + } +} + +impl RCodec<(ext::Destination, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::Destination, bool), Self::Error> { + let (_, more): (ZExtUnit<{ ext::DST }>, bool) = self.read(&mut *reader)?; + Ok((ext::Destination::Subscribers, more)) + } +} + +// Target +impl WCodec<(&ext::Target, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::Target, bool)) -> Self::Output { + let (rt, more) = x; + let v = match rt { + ext::Target::BestMatching => 0, + ext::Target::All => 1, + ext::Target::AllComplete => 2, + #[cfg(feature = "complete_n")] + ext::Target::Complete(n) => 3 + *n, + }; + let ext: ZExtZ64<{ ext::TARGET }> = ZExtZ64::new(v); + self.write(&mut *writer, (&ext, more)) + } +} + +impl RCodec<(ext::Target, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::Target, bool), Self::Error> { + let (ext, more): (ZExtZ64<{ ext::TARGET }>, bool) = self.read(&mut *reader)?; + let rt = match ext.value { + 0 => ext::Target::BestMatching, + 1 => ext::Target::All, + 2 => ext::Target::AllComplete, + #[cfg(feature = "complete_n")] + n => ext::Target::Complete(n - 3), + _ => return Err(DidntRead), + }; + Ok((rt, more)) + } +} + +impl WCodec<&Request, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Request) -> Self::Output { + // Header + let mut header = id::REQUEST; + let mut n_exts = ((x.ext_qos != ext::QoS::default()) as u8) + + (x.ext_tstamp.is_some() as u8) + + ((x.ext_dst != ext::Destination::default()) as u8) + + ((x.ext_target != ext::Target::default()) as u8); + if n_exts != 0 { + header |= flag::Z; + } + if x.mapping != Mapping::default() { + header |= flag::M; + } + if x.wire_expr.has_suffix() { + header |= flag::N; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + self.write(&mut *writer, &x.wire_expr)?; + + // Extensions + if x.ext_qos != ext::QoS::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + } + if let Some(ts) = x.ext_tstamp.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (ts, n_exts != 0))?; + } + if x.ext_dst != ext::Destination::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_dst, n_exts != 0))?; + } + if x.ext_target != ext::Target::default() { + n_exts -= 1; + self.write(&mut *writer, (&x.ext_target, n_exts != 0))?; + } + + // Payload + self.write(&mut *writer, &x.payload)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::REQUEST { + return Err(DidntRead); + } + + // Body + let id: RequestId = self.codec.read(&mut *reader)?; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); + let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + let mapping = if imsg::has_flag(self.header, flag::M) { + Mapping::Sender + } else { + Mapping::Receiver + }; + + // Extensions + let mut ext_qos = ext::QoS::default(); + let mut ext_tstamp = None; + let mut ext_dst = ext::Destination::default(); + let mut ext_target = ext::Target::default(); + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QOS => { + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + ext_qos = q; + has_ext = ext; + } + ext::TSTAMP => { + let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext_tstamp = Some(t); + has_ext = ext; + } + ext::DST => { + let (d, ext): (ext::Destination, bool) = eodec.read(&mut *reader)?; + ext_dst = d; + has_ext = ext; + } + ext::TARGET => { + let (rt, ext): (ext::Target, bool) = eodec.read(&mut *reader)?; + ext_target = rt; + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + // Message + // let payload: ZenohMessage = self.codec.read(&mut *reader)?; + let payload: u8 = self.codec.read(&mut *reader)?; // @TODO + + Ok(Request { + id, + wire_expr, + mapping, + payload, + ext_qos, + ext_tstamp, + ext_dst, + ext_target, + }) + } +} diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index ce6cbd906a..64f48f0ae2 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -28,43 +28,7 @@ use zenoh_protocol::{ }; // Extensions: QoS -impl WCodec<(ext::QoS, bool), &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: (ext::QoS, bool)) -> Self::Output { - let (qos, more) = x; - let ext: ZExtZ64<{ ext::QOS }> = qos.into(); - self.write(&mut *writer, (&ext, more)) - } -} - -impl RCodec<(ext::QoS, bool), &mut R> for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - codec.read(reader) - } -} - -impl RCodec<(ext::QoS, bool), &mut R> for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ext::QoS, bool), Self::Error> { - let (ext, more): (ZExtZ64<{ ext::QOS }>, bool) = self.read(&mut *reader)?; - Ok((ext.into(), more)) - } -} +crate::impl_zextz64!(ext::QoS, ext::QOS); // FrameHeader impl WCodec<&FrameHeader, &mut W> for Zenoh080 diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index dd66653c18..392841347b 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -23,7 +23,23 @@ use zenoh_buffers::{ BBuf, ZBuf, ZSlice, }; use zenoh_codec::*; -use zenoh_protocol::{common::*, core::*, scouting::*, transport::*, zenoh::*}; +use zenoh_protocol::{ + common::*, + core::*, + network::{ + self, + declare::{ + keyexpr::{DeclareKeyExpr, ForgetKeyExpr}, + queryable::{DeclareQueryable, ForgetQueryable}, + subscriber::{DeclareSubscriber, ForgetSubscriber}, + DeclareBody, + }, + Push, Request, + }, + scouting::*, + transport::*, + zenoh::*, +}; const NUM_ITER: usize = 100; const MAX_PAYLOAD_SIZE: usize = 256; @@ -436,10 +452,55 @@ fn codec_transport() { } // Network -// #[test] -// fn codec_push() { -// run!(Push, Push::rand()); -// } +#[test] +fn codec_push() { + run!(Push, Push::rand()); +} + +#[test] +fn codec_request() { + run!(Request, Request::rand()); +} + +#[test] +fn codec_declare() { + run!(network::Declare, network::Declare::rand()); +} + +#[test] +fn codec_declare_body() { + run!(DeclareBody, DeclareBody::rand()); +} + +#[test] +fn codec_declare_keyexpr() { + run!(DeclareKeyExpr, DeclareKeyExpr::rand()); +} + +#[test] +fn codec_forget_keyexpr() { + run!(ForgetKeyExpr, ForgetKeyExpr::rand()); +} + +#[test] +fn codec_declare_subscriber() { + run!(DeclareSubscriber, DeclareSubscriber::rand()); +} + +#[test] +fn codec_forget_subscriber() { + run!(ForgetSubscriber, ForgetSubscriber::rand()); +} + +#[test] +fn codec_declare_queryable() { + run!(DeclareQueryable, DeclareQueryable::rand()); +} + +#[test] +fn codec_forget_queryable() { + run!(ForgetQueryable, ForgetQueryable::rand()); +} // Zenoh #[test] @@ -518,12 +579,12 @@ fn codec_declaration_forget_queryable() { } #[test] -fn codec_declaration() { +fn codec_declaration_old() { run!(Declaration, Declaration::rand()); } #[test] -fn codec_declare() { +fn codec_declare_old() { run!(Declare, Declare::rand()); } diff --git a/commons/zenoh-protocol/src/common/mod.rs b/commons/zenoh-protocol/src/common/mod.rs index d2c3d4df36..ceaae6041a 100644 --- a/commons/zenoh-protocol/src/common/mod.rs +++ b/commons/zenoh-protocol/src/common/mod.rs @@ -19,7 +19,6 @@ pub use extension::*; /*************************************/ // Inner Message IDs pub mod imsg { - pub mod id { // Zenoh Messages pub const DECLARE: u8 = 0x0b; diff --git a/commons/zenoh-protocol/src/core/wire_expr.rs b/commons/zenoh-protocol/src/core/wire_expr.rs index f5984ebccb..d02e45e6a8 100644 --- a/commons/zenoh-protocol/src/core/wire_expr.rs +++ b/commons/zenoh-protocol/src/core/wire_expr.rs @@ -68,7 +68,7 @@ impl<'a> WireExpr<'a> { } pub fn try_as_str(&'a self) -> ZResult<&'a str> { - if self.scope == 0 { + if self.scope == EMPTY_EXPR_ID { Ok(self.suffix.as_ref()) } else { bail!("Scoped key expression") diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index 7a901bca6e..b7739d5e15 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -11,11 +11,17 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::{ExprId, Reliability, WireExpr}; - -pub type SubscriberId = u32; -pub type QueryableId = u32; -pub type TokenId = u32; +use crate::{ + common::{imsg, ZExtZ64}, + core::{ExprId, Reliability, WireExpr}, + network::Mapping, +}; + +pub mod flag { + // pub const X: u8 = 1 << 5; // 0x20 Reserved + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} /// Flags: /// - X: Reserved @@ -55,20 +61,16 @@ pub mod id { pub const D_QUERYABLE: u8 = 0x05; pub const F_QUERYABLE: u8 = 0x06; - - // SubModes - pub const MODE_PUSH: u8 = 0x00; - pub const MODE_PULL: u8 = 0x01; } #[derive(Debug, Clone, PartialEq, Eq)] pub enum DeclareBody { - DeclareKeyExpr(DeclareKeyExpr), - ForgetKeyExpr(ForgetKeyExpr), - DeclareSubscriber(DeclareSubscriber), - ForgetSubscriber(ForgetSubscriber), - DeclareQueryable(DeclareQueryable), - ForgetQueryable(ForgetQueryable), + DeclareKeyExpr(keyexpr::DeclareKeyExpr), + ForgetKeyExpr(keyexpr::ForgetKeyExpr), + DeclareSubscriber(subscriber::DeclareSubscriber), + ForgetSubscriber(subscriber::ForgetSubscriber), + DeclareQueryable(queryable::DeclareQueryable), + ForgetQueryable(queryable::ForgetQueryable), } impl DeclareBody { @@ -79,12 +81,12 @@ impl DeclareBody { let mut rng = rand::thread_rng(); match rng.gen_range(0..6) { - 0 => DeclareBody::DeclareKeyExpr(DeclareKeyExpr::rand()), - 1 => DeclareBody::ForgetKeyExpr(ForgetKeyExpr::rand()), - 2 => DeclareBody::DeclareSubscriber(DeclareSubscriber::rand()), - 3 => DeclareBody::ForgetSubscriber(ForgetSubscriber::rand()), - 4 => DeclareBody::DeclareQueryable(DeclareQueryable::rand()), - 5 => DeclareBody::ForgetQueryable(ForgetQueryable::rand()), + 0 => DeclareBody::DeclareKeyExpr(keyexpr::DeclareKeyExpr::rand()), + 1 => DeclareBody::ForgetKeyExpr(keyexpr::ForgetKeyExpr::rand()), + 2 => DeclareBody::DeclareSubscriber(subscriber::DeclareSubscriber::rand()), + 3 => DeclareBody::ForgetSubscriber(subscriber::ForgetSubscriber::rand()), + 4 => DeclareBody::DeclareQueryable(queryable::DeclareQueryable::rand()), + 5 => DeclareBody::ForgetQueryable(queryable::ForgetQueryable::rand()), _ => unreachable!(), } } @@ -132,330 +134,473 @@ impl Mode { } } -/// ```text -/// Flags: -/// - N: Named If N==1 then the key expr has name/suffix -/// - X: Reserved -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|X|N| D_KEXPR | -/// +---------------+ -/// ~ expr_id:z16 ~ -/// +---------------+ -/// ~ key_scope:z16 ~ -/// +---------------+ -/// ~ key_suffix ~ if N==1 -- -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct DeclareKeyExpr { - pub id: ExprId, - pub wire_expr: WireExpr<'static>, -} +pub mod keyexpr { + use super::*; -impl DeclareKeyExpr { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; + pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow + } - let mut rng = rand::thread_rng(); + /// ```text + /// Flags: + /// - N: Named If N==1 then the key expr has name/suffix + /// - X: Reserved + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|X|N| D_KEXPR | + /// +---------------+ + /// ~ expr_id:z16 ~ + /// +---------------+ + /// ~ key_scope:z16 ~ + /// +---------------+ + /// ~ key_suffix ~ if N==1 -- + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct DeclareKeyExpr { + pub id: ExprId, + pub wire_expr: WireExpr<'static>, + } + + impl DeclareKeyExpr { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: ExprId = rng.gen(); + let wire_expr = WireExpr::rand(); - let id: ExprId = rng.gen(); - let wire_expr = WireExpr::rand(); + Self { id, wire_expr } + } + } - Self { id, wire_expr } + /// ```text + /// Flags: + /// - X: Reserved + /// - X: Reserved + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|X|X| F_KEXPR | + /// +---------------+ + /// ~ expr_id:z16 ~ + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct ForgetKeyExpr { + pub id: ExprId, } -} -/// ```text -/// Flags: -/// - X: Reserved -/// - X: Reserved -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|X|X| F_KEXPR | -/// +---------------+ -/// ~ expr_id:z16 ~ -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetKeyExpr { - pub expr_id: ExprId, + impl ForgetKeyExpr { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: ExprId = rng.gen(); + + Self { id } + } + } } -impl ForgetKeyExpr { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; +pub mod subscriber { + use super::*; - let mut rng = rand::thread_rng(); + pub type SubscriberId = u32; - let expr_id: ExprId = rng.gen(); + pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow + } - Self { expr_id } + /// ```text + /// Flags: + /// - N: Named If N==1 then the key expr has name/suffix + /// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|M|N| D_SUB | + /// +---------------+ + /// ~ subs_id:z32 ~ + /// +---------------+ + /// ~ key_scope:z16 ~ + /// +---------------+ + /// ~ key_suffix ~ if N==1 -- + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// + /// - if R==1 then the subscription is reliable, else it is best effort + /// - if P==1 then the subscription is pull, else it is push + /// + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct DeclareSubscriber { + pub id: SubscriberId, + pub wire_expr: WireExpr<'static>, + pub mapping: Mapping, + pub ext_info: ext::SubscriberInfo, } -} -/// The subscription mode. -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct SubscriberInfo { - pub reliability: Reliability, - pub mode: Mode, -} + pub mod ext { + use super::*; + + pub const INFO: u8 = 0x01; + + /// # The subscription mode. + /// + /// ```text + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|0_1| ID | + /// +-+-+-+---------+ + /// % reserved |P|R% + /// +---------------+ + /// + /// - if R==1 then the subscription is reliable, else it is best effort + /// - if P==1 then the subscription is pull, else it is push + /// - rsv: Reserved + /// ``` + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] + pub struct SubscriberInfo { + pub reliability: Reliability, + pub mode: Mode, + } -/// ```text -/// Flags: -/// - N: Named If N==1 then the key expr has name/suffix -/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| D_SUB | -/// +---------------+ -/// ~ subs_id:z32 ~ -/// +---------------+ -/// ~ key_scope:z16 ~ -/// +---------------+ -/// ~ key_suffix ~ if N==1 -- -/// +---------------+ -/// |X|X|X|X|X|X|P|R| (*) -/// +---------------+ -/// -/// - if R==1 then the subscription is reliable, else it is best effort -/// - if P==1 then the subscription is pull, else it is push -/// -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct DeclareSubscriber { - pub id: SubscriberId, - pub wire_expr: WireExpr<'static>, - pub info: SubscriberInfo, -} + impl SubscriberInfo { + pub const R: u64 = 1; + pub const P: u64 = 1 << 1; -impl DeclareSubscriber { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; + #[cfg(feature = "test")] + pub fn rand() -> Self { + let reliability = Reliability::rand(); + let mode = Mode::rand(); - let mut rng = rand::thread_rng(); + Self { reliability, mode } + } + } - let id: SubscriberId = rng.gen(); - let wire_expr = WireExpr::rand(); - let reliability = Reliability::rand(); - let mode = Mode::rand(); - let info = SubscriberInfo { reliability, mode }; + impl From> for SubscriberInfo { + fn from(ext: ZExtZ64<{ INFO }>) -> Self { + let reliability = if imsg::has_option(ext.value, SubscriberInfo::R) { + Reliability::Reliable + } else { + Reliability::BestEffort + }; + let mode = if imsg::has_option(ext.value, SubscriberInfo::P) { + Mode::Pull + } else { + Mode::Push + }; + Self { reliability, mode } + } + } - Self { - id, - wire_expr, - info, + impl From for ZExtZ64<{ INFO }> { + fn from(ext: SubscriberInfo) -> Self { + let mut v: u64 = 0; + if ext.reliability == Reliability::Reliable { + v |= SubscriberInfo::R; + } + if ext.mode == Mode::Pull { + v |= SubscriberInfo::P; + } + ZExtZ64::new(v) + } } } -} -/// ```text -/// Flags: -/// - X: Reserved -/// - X: Reserved -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|X|X| F_SUB | -/// +---------------+ -/// ~ subs_id:z32 ~ -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetSubscriber { - pub id: SubscriberId, -} + impl DeclareSubscriber { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: SubscriberId = rng.gen(); + let wire_expr = WireExpr::rand(); + let mapping = Mapping::rand(); + let ext_info = ext::SubscriberInfo::rand(); + + Self { + id, + wire_expr, + ext_info, + mapping, + } + } + } -impl ForgetSubscriber { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; + /// ```text + /// Flags: + /// - X: Reserved + /// - X: Reserved + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|X|X| F_SUB | + /// +---------------+ + /// ~ subs_id:z32 ~ + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct ForgetSubscriber { + pub id: SubscriberId, + } - let mut rng = rand::thread_rng(); + impl ForgetSubscriber { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); - let id: SubscriberId = rng.gen(); + let id: SubscriberId = rng.gen(); - Self { id } + Self { id } + } } } -#[derive(Debug, Default, Clone, PartialEq, Eq)] -pub struct QueryableInfo { - pub reliability: Reliability, - pub mode: Mode, - pub complete: u32, // Default 0: incomplete - pub distance: u32, // Default 0: no distance -} - -/// ```text -/// Flags: -/// - N: Named If N==1 then the key expr has name/suffix -/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| D_QBL | -/// +---------------+ -/// ~ qbls_id:z32 ~ -/// +---------------+ -/// ~ key_scope:z16 ~ -/// +---------------+ -/// ~ key_suffix ~ if N==1 -- -/// +---------------+ -/// |X|X|X|X|D|C|P|R| (*) -/// +---------------+ -/// ~ complete_n ~ if C==1 -/// +---------------+ -/// ~ distance ~ if D==1 -/// +---------------+ -/// -/// - if R==1 then the queryable is reliable, else it is best effort -/// - if P==1 then the queryable is pull, else it is push -/// - if C==1 then the queryable is complete and the N parameter is present -/// - if D==1 then the queryable distance is present -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct DeclareQueryable { - pub id: QueryableId, - pub wire_expr: WireExpr<'static>, - pub info: QueryableInfo, -} +pub mod queryable { + use super::*; -impl DeclareQueryable { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; + pub type QueryableId = u32; - let mut rng = rand::thread_rng(); + pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow + } - let id: QueryableId = rng.gen(); - let wire_expr = WireExpr::rand(); - let mode = Mode::rand(); - let reliability = Reliability::rand(); - let complete: u32 = rng.gen(); - let distance: u32 = rng.gen(); - let info = QueryableInfo { - reliability, - mode, - complete, - distance, - }; + /// ```text + /// Flags: + /// - N: Named If N==1 then the key expr has name/suffix + /// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|M|N| D_QBL | + /// +---------------+ + /// ~ qbls_id:z32 ~ + /// +---------------+ + /// ~ key_scope:z16 ~ + /// +---------------+ + /// ~ key_suffix ~ if N==1 -- + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// + /// - if R==1 then the queryable is reliable, else it is best effort + /// - if P==1 then the queryable is pull, else it is push + /// - if C==1 then the queryable is complete and the N parameter is present + /// - if D==1 then the queryable distance is present + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct DeclareQueryable { + pub id: QueryableId, + pub wire_expr: WireExpr<'static>, + pub mapping: Mapping, + pub ext_info: ext::QueryableInfo, + } - Self { - id, - wire_expr, - info, + pub mod ext { + use super::*; + + pub const INFO: u8 = 0x01; + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|0_1| ID | + /// +-+-+-+---------+ + /// ~ complete_n ~ + /// +---------------+ + /// ~ distance ~ + /// +---------------+ + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] + pub struct QueryableInfo { + pub complete: u8, // Default 0: incomplete + pub distance: u8, // Default 0: no distance } - } -} -/// ```text -/// Flags: -/// - X: Reserved -/// - X: Reserved -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|X|X| F_QBL | -/// +---------------+ -/// ~ qbls_id:z32 ~ -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetQueryable { - pub id: QueryableId, -} + impl QueryableInfo { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + let complete: u8 = rng.gen(); + let distance: u8 = rng.gen(); -impl ForgetQueryable { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; + Self { complete, distance } + } + } - let mut rng = rand::thread_rng(); + impl From> for QueryableInfo { + fn from(ext: ZExtZ64<{ INFO }>) -> Self { + let complete = ext.value as u8; + let distance = (ext.value >> 8) as u8; - let id: QueryableId = rng.gen(); + Self { complete, distance } + } + } - Self { id } + impl From for ZExtZ64<{ INFO }> { + fn from(ext: QueryableInfo) -> Self { + let mut v: u64 = ext.complete as u64; + v |= (ext.distance as u64) << 8; + ZExtZ64::new(v) + } + } } -} -/// ```text -/// Flags: -/// - N: Named If N==1 then the key expr has name/suffix -/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| D_TKN | -/// +---------------+ -/// ~ token_id:z32 ~ -/// +---------------+ -/// ~ key_scope:z16 ~ -/// +---------------+ -/// ~ key_suffix ~ if N==1 -- -/// +---------------+ -/// -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct DeclareToken { - pub id: TokenId, - pub wire_expr: WireExpr<'static>, -} + impl DeclareQueryable { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: QueryableId = rng.gen(); + let wire_expr = WireExpr::rand(); + let mapping = Mapping::rand(); + let ext_info = ext::QueryableInfo::rand(); + + Self { + id, + wire_expr, + mapping, + ext_info, + } + } + } -impl DeclareToken { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; + /// ```text + /// Flags: + /// - X: Reserved + /// - X: Reserved + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|X|X| F_QBL | + /// +---------------+ + /// ~ qbls_id:z32 ~ + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct ForgetQueryable { + pub id: QueryableId, + } - let mut rng = rand::thread_rng(); + impl ForgetQueryable { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); - let id: TokenId = rng.gen(); - let wire_expr = WireExpr::rand(); + let id: QueryableId = rng.gen(); - Self { id, wire_expr } + Self { id } + } } } -/// ```text -/// Flags: -/// - X: Reserved -/// - X: Reserved -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|X|X| F_TKN | -/// +---------------+ -/// ~ token_id:z32 ~ -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetToken { - pub id: TokenId, -} +pub mod token { + use super::*; + + pub type TokenId = u32; + + /// ```text + /// Flags: + /// - N: Named If N==1 then the key expr has name/suffix + /// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|M|N| D_TKN | + /// +---------------+ + /// ~ token_id:z32 ~ + /// +---------------+ + /// ~ key_scope:z16 ~ + /// +---------------+ + /// ~ key_suffix ~ if N==1 -- + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct DeclareToken { + pub id: TokenId, + pub wire_expr: WireExpr<'static>, + pub mapping: Mapping, + } -impl ForgetToken { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; + impl DeclareToken { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: TokenId = rng.gen(); + let wire_expr = WireExpr::rand(); + let mapping = Mapping::rand(); + + Self { + id, + wire_expr, + mapping, + } + } + } - let mut rng = rand::thread_rng(); + /// ```text + /// Flags: + /// - X: Reserved + /// - X: Reserved + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|X|X| F_TKN | + /// +---------------+ + /// ~ token_id:z32 ~ + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct ForgetToken { + pub id: TokenId, + } - let id: TokenId = rng.gen(); + impl ForgetToken { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); - Self { id } + let id: TokenId = rng.gen(); + + Self { id } + } } } diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 200bc2a61e..e291b1b0e2 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -197,8 +197,8 @@ pub mod ext { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; - let mut rng = rand::thread_rng(); + let inner: u8 = rng.gen(); Self { inner } } @@ -251,8 +251,8 @@ pub mod ext { use crate::core::ZenohId; use core::convert::TryFrom; use rand::Rng; - let mut rng = rand::thread_rng(); + let time = uhlc::NTP64(rng.gen()); let id = uhlc::ID::try_from(ZenohId::rand().as_slice()).unwrap(); let timestamp = uhlc::Timestamp::new(time, id); diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs index 4261948dbc..f965527cf7 100644 --- a/commons/zenoh-protocol/src/network/push.rs +++ b/commons/zenoh-protocol/src/network/push.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, network::Mapping, zenoh::ZenohMessage}; +use crate::{core::WireExpr, network::Mapping}; pub mod flag { pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix @@ -33,7 +33,7 @@ pub mod flag { /// +---------------+ /// ~ key_suffix ~ if N==1 -- /// +---------------+ -/// ~ [data_exts] ~ if Z==1 +/// ~ [push_exts] ~ if Z==1 /// +---------------+ /// ~ ZenohMessage ~ /// +---------------+ @@ -42,17 +42,41 @@ pub mod flag { pub struct Push { pub wire_expr: WireExpr<'static>, pub mapping: Mapping, - pub payload: ZenohMessage, + pub payload: u8, // @TODO pub ext_qos: ext::QoS, pub ext_tstamp: Option, + pub ext_dst: ext::Destination, } pub mod ext { pub const QOS: u8 = crate::network::ext::QOS; pub const TSTAMP: u8 = crate::network::ext::TSTAMP; + pub const DST: u8 = 0x03; pub type QoS = crate::network::ext::QoS; pub type Timestamp = crate::network::ext::Timestamp; + + #[repr(u8)] + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] + pub enum Destination { + #[default] + Subscribers = 0x00, + Queryables = 0x01, + } + + impl Destination { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + match rng.gen_range(0..2) { + 0 => Destination::Subscribers, + 1 => Destination::Queryables, + _ => unreachable!(), + } + } + } } impl Push { @@ -63,9 +87,11 @@ impl Push { let mut rng = rand::thread_rng(); let wire_expr = WireExpr::rand(); let mapping = Mapping::rand(); - let payload = ZenohMessage::rand(); + // let payload = ZenohMessage::rand(); + let payload: u8 = rng.gen(); // @TODO let ext_qos = ext::QoS::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + let ext_dst = ext::Destination::rand(); Self { wire_expr, @@ -73,6 +99,7 @@ impl Push { payload, ext_tstamp, ext_qos, + ext_dst, } } } diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index 49e0ff165c..54a88ce32d 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -11,13 +11,19 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, zenoh::ZenohMessage}; +use crate::{core::WireExpr, network::Mapping}; use core::sync::atomic::AtomicU32; /// The resolution of a RequestId pub type RequestId = u32; pub type AtomicRequestId = AtomicU32; +pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + /// # Request message /// /// ```text @@ -48,31 +54,56 @@ pub type AtomicRequestId = AtomicU32; pub struct Request { pub id: RequestId, pub wire_expr: WireExpr<'static>, - pub payload: ZenohMessage, + pub mapping: Mapping, + pub payload: u8, // @TODO pub ext_qos: ext::QoS, pub ext_tstamp: Option, - pub ext_target: ext::RequestTarget, + pub ext_dst: ext::Destination, + pub ext_target: ext::Target, } pub mod ext { pub const QOS: u8 = crate::network::ext::QOS; pub const TSTAMP: u8 = crate::network::ext::TSTAMP; - pub const TARGET: u8 = 0x03; + pub const DST: u8 = 0x03; + pub const TARGET: u8 = 0x04; pub type QoS = crate::network::ext::QoS; pub type Timestamp = crate::network::ext::Timestamp; + #[repr(u8)] + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] + pub enum Destination { + Subscribers = 0x00, + #[default] + Queryables = 0x01, + } + + impl Destination { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + match rng.gen_range(0..2) { + 0 => Destination::Subscribers, + 1 => Destination::Queryables, + _ => unreachable!(), + } + } + } + /// - Target (0x03) /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ /// |Z|ENC| ID | /// +-+-+-+---------+ - /// % target % -> Queryable or Subscriber? + Query targeting (ALL, BEST_MATCHING, COMPLETE_ALL, ?COMPLETE_N?)? + /// % target % /// +---------------+ /// /// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] - pub enum RequestTarget { + pub enum Target { #[default] BestMatching, All, @@ -81,18 +112,18 @@ pub mod ext { Complete(u64), } - impl RequestTarget { + impl Target { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::prelude::SliceRandom; let mut rng = rand::thread_rng(); *[ - RequestTarget::All, - RequestTarget::AllComplete, - RequestTarget::BestMatching, + Target::All, + Target::AllComplete, + Target::BestMatching, #[cfg(feature = "complete_n")] - RequestTarget::Complete(rng.gen()), + Target::Complete(rng.gen()), ] .choose(&mut rng) .unwrap() @@ -107,18 +138,23 @@ impl Request { let mut rng = rand::thread_rng(); let wire_expr = WireExpr::rand(); - let rid: RequestId = rng.gen(); - let payload = ZenohMessage::rand(); + let mapping = Mapping::rand(); + let id: RequestId = rng.gen(); + // let payload = ZenohMessage::rand(); + let payload: u8 = rng.gen(); // @TODO let ext_qos = ext::QoS::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); - let ext_target = ext::RequestTarget::rand(); + let ext_dst = ext::Destination::rand(); + let ext_target = ext::Target::rand(); Self { wire_expr, - id: rid, + mapping, + id, payload, ext_qos, ext_tstamp, + ext_dst, ext_target, } } diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index 8c5da20384..6f5609c981 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, network::RequestId, zenoh::ZenohMessage}; +use crate::{core::WireExpr, network::RequestId}; /// # Response message /// @@ -43,7 +43,7 @@ use crate::{core::WireExpr, network::RequestId, zenoh::ZenohMessage}; pub struct Response { pub wire_expr: WireExpr<'static>, pub rid: RequestId, - pub payload: ZenohMessage, + pub payload: u8, // @TODO pub ext_qos: ext::QoS, pub ext_tstamp: Option, } @@ -65,7 +65,8 @@ impl Response { let mut rng = rand::thread_rng(); let wire_expr = WireExpr::rand(); let rid: RequestId = rng.gen(); - let payload = ZenohMessage::rand(); + // let payload = ZenohMessage::rand(); + let payload: u8 = rng.gen(); // @TODO let ext_qos = ext::QoS::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 884b328499..3e855ec8f7 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -111,8 +111,8 @@ pub mod ext { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; - let mut rng = rand::thread_rng(); + let inner: u8 = rng.gen(); Self { inner } } From ef29569893fcf1c4f1e8b9f62741e6a58590dcb1 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 21 Mar 2023 13:09:05 +0100 Subject: [PATCH 102/203] Draft Pull message and codec --- commons/zenoh-codec/src/network/mod.rs | 1 + commons/zenoh-codec/src/network/pull.rs | 81 ++++++++++++++++++++++ commons/zenoh-codec/tests/codec.rs | 9 ++- commons/zenoh-protocol/src/network/mod.rs | 9 ++- commons/zenoh-protocol/src/network/pull.rs | 31 ++------- 5 files changed, 101 insertions(+), 30 deletions(-) create mode 100644 commons/zenoh-codec/src/network/pull.rs diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index e350f2d110..98da4c9b09 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // mod declare; +mod pull; mod push; mod request; diff --git a/commons/zenoh-codec/src/network/pull.rs b/commons/zenoh-codec/src/network/pull.rs new file mode 100644 index 0000000000..0db0391246 --- /dev/null +++ b/commons/zenoh-codec/src/network/pull.rs @@ -0,0 +1,81 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{imsg, ZExtUnknown}, + network::{id, push::flag, Pull}, + zenoh::PullId, +}; + +impl WCodec<&Pull, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Pull) -> Self::Output { + // Header + let header = id::PULL; + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.target)?; + self.write(&mut *writer, x.id)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::PULL { + return Err(DidntRead); + } + + // Body + let target: u8 = self.codec.read(&mut *reader)?; + let id: PullId = self.codec.read(&mut *reader)?; + + // Extensions + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let (_, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + has_ext = ext; + } + + Ok(Pull { target, id }) + } +} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 392841347b..9ac8a23e46 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -34,7 +34,7 @@ use zenoh_protocol::{ subscriber::{DeclareSubscriber, ForgetSubscriber}, DeclareBody, }, - Push, Request, + Pull, Push, Request, }, scouting::*, transport::*, @@ -457,6 +457,11 @@ fn codec_push() { run!(Push, Push::rand()); } +#[test] +fn codec_pull() { + run!(Pull, Pull::rand()); +} + #[test] fn codec_request() { run!(Request, Request::rand()); @@ -529,7 +534,7 @@ fn codec_unit() { } #[test] -fn codec_pull() { +fn codec_pull_old() { run!(Pull, Pull::rand()); } diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index e291b1b0e2..4dde3b7064 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -18,6 +18,7 @@ pub mod request; pub mod response; pub use declare::Declare; +pub use pull::Pull; pub use push::Push; pub use request::{Request, RequestId}; pub use response::{Response, ResponseFinal}; @@ -27,9 +28,11 @@ pub mod id { // collide with the IDs defined in `crate::transport::id`. pub const DECLARE: u8 = 0x1f; pub const PUSH: u8 = 0x1e; - pub const REQUEST: u8 = 0x1d; - pub const RESPONSE: u8 = 0x1c; - pub const RESPONSE_FINAL: u8 = 0x1b; + pub const PULL: u8 = 0x1d; + pub const REQUEST: u8 = 0x1c; + pub const RESPONSE: u8 = 0x1b; + pub const RESPONSE_FINAL: u8 = 0x1a; + pub const OAM: u8 = 0x19; } #[repr(u8)] diff --git a/commons/zenoh-protocol/src/network/pull.rs b/commons/zenoh-protocol/src/network/pull.rs index d68289413a..6774abee54 100644 --- a/commons/zenoh-protocol/src/network/pull.rs +++ b/commons/zenoh-protocol/src/network/pull.rs @@ -14,29 +14,6 @@ pub type PullId = u32; -#[repr(u8)] -#[derive(Debug, Default, Clone, PartialEq, Eq)] -pub enum PullTarget { - #[default] - Push = 0x00, - Request = 0x01, -} - -impl PullTarget { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - match rng.gen_range(0..2) { - 0 => PullTarget::Push, - 1 => PullTarget::Request, - _ => unreachable!(), - } - } -} - /// ```text /// Flags: /// - X: Reserved @@ -51,23 +28,27 @@ impl PullTarget { /// +---------------+ /// ~ id:z32 ~ (*) /// +---------------+ +/// ~ [pull_exts] ~ (*) +/// +---------------+ /// /// (*) ID refers to the ID used in a previous target declaration /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct Pull { - pub target: PullTarget, + pub target: u8, pub id: PullId, } impl Pull { + pub const T_SUBSCRIBER: u8 = 0x01; + #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; let mut rng = rand::thread_rng(); - let target = PullTarget::rand(); + let target: u8 = rng.gen(); let id: PullId = rng.gen(); Self { target, id } From edfa444849448f7c0e70f3519052b78a6f408327 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 21 Mar 2023 14:11:29 +0100 Subject: [PATCH 103/203] Pull message and codec --- commons/zenoh-codec/src/network/pull.rs | 4 +- commons/zenoh-codec/tests/codec.rs | 80 +++++++++++----------- commons/zenoh-protocol/src/network/pull.rs | 7 +- 3 files changed, 42 insertions(+), 49 deletions(-) diff --git a/commons/zenoh-codec/src/network/pull.rs b/commons/zenoh-codec/src/network/pull.rs index 0db0391246..82089f6896 100644 --- a/commons/zenoh-codec/src/network/pull.rs +++ b/commons/zenoh-codec/src/network/pull.rs @@ -34,7 +34,6 @@ where self.write(&mut *writer, header)?; // Body - self.write(&mut *writer, x.target)?; self.write(&mut *writer, x.id)?; Ok(()) @@ -66,7 +65,6 @@ where } // Body - let target: u8 = self.codec.read(&mut *reader)?; let id: PullId = self.codec.read(&mut *reader)?; // Extensions @@ -76,6 +74,6 @@ where has_ext = ext; } - Ok(Pull { target, id }) + Ok(Pull { id }) } } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 9ac8a23e46..892966bef3 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -38,7 +38,7 @@ use zenoh_protocol::{ }, scouting::*, transport::*, - zenoh::*, + zenoh, }; const NUM_ITER: usize = 100; @@ -509,106 +509,106 @@ fn codec_forget_queryable() { // Zenoh #[test] -fn codec_routing_context() { - run!(RoutingContext, RoutingContext::rand()); +fn codec_routing_context_old() { + run!(zenoh::RoutingContext, zenoh::RoutingContext::rand()); } #[test] -fn codec_reply_context() { - run!(ReplyContext, ReplyContext::rand()); +fn codec_reply_context_old() { + run!(zenoh::ReplyContext, zenoh::ReplyContext::rand()); } #[test] -fn codec_data_info() { - run!(DataInfo, DataInfo::rand()); +fn codec_data_info_old() { + run!(zenoh::DataInfo, zenoh::DataInfo::rand()); } #[test] -fn codec_data() { - run!(Data, Data::rand()); +fn codec_data_old() { + run!(zenoh::Data, zenoh::Data::rand()); } #[test] -fn codec_unit() { - run!(Unit, Unit::rand()); +fn codec_unit_old() { + run!(zenoh::Unit, zenoh::Unit::rand()); } #[test] fn codec_pull_old() { - run!(Pull, Pull::rand()); + run!(zenoh::Pull, zenoh::Pull::rand()); } #[test] -fn codec_query() { - run!(Query, Query::rand()); +fn codec_query_old() { + run!(zenoh::Query, zenoh::Query::rand()); } #[test] -fn codec_declaration_resource() { - run!(Resource, Resource::rand()); +fn codec_declaration_resource_old() { + run!(zenoh::Resource, zenoh::Resource::rand()); } #[test] -fn codec_declaration_forget_resource() { - run!(ForgetResource, ForgetResource::rand()); +fn codec_declaration_forget_resource_old() { + run!(zenoh::ForgetResource, zenoh::ForgetResource::rand()); } #[test] -fn codec_declaration_publisher() { - run!(Publisher, Publisher::rand()); +fn codec_declaration_publisher_old() { + run!(zenoh::Publisher, zenoh::Publisher::rand()); } #[test] -fn codec_declaration_forget_publisher() { - run!(ForgetPublisher, ForgetPublisher::rand()); +fn codec_declaration_forget_publisher_old() { + run!(zenoh::ForgetPublisher, zenoh::ForgetPublisher::rand()); } #[test] -fn codec_declaration_subscriber() { - run!(Subscriber, Subscriber::rand()); +fn codec_declaration_subscriber_old() { + run!(zenoh::Subscriber, zenoh::Subscriber::rand()); } #[test] -fn codec_declaration_forget_subscriber() { - run!(ForgetSubscriber, ForgetSubscriber::rand()); +fn codec_declaration_forget_subscriber_old() { + run!(zenoh::ForgetSubscriber, zenoh::ForgetSubscriber::rand()); } #[test] -fn codec_declaration_queryable() { - run!(Queryable, Queryable::rand()); +fn codec_declaration_queryable_old() { + run!(zenoh::Queryable, zenoh::Queryable::rand()); } #[test] -fn codec_declaration_forget_queryable() { +fn codec_declaration_forget_queryable_old() { run!(ForgetQueryable, ForgetQueryable::rand()); } #[test] fn codec_declaration_old() { - run!(Declaration, Declaration::rand()); + run!(zenoh::Declaration, zenoh::Declaration::rand()); } #[test] fn codec_declare_old() { - run!(Declare, Declare::rand()); + run!(zenoh::Declare, zenoh::Declare::rand()); } #[test] -fn codec_link_state() { - run!(LinkState, LinkState::rand()); +fn codec_link_state_old() { + run!(zenoh::LinkState, zenoh::LinkState::rand()); } #[test] -fn codec_link_state_list() { - run!(LinkStateList, LinkStateList::rand()); +fn codec_link_state_list_old() { + run!(zenoh::LinkStateList, zenoh::LinkStateList::rand()); } #[test] -fn codec_zenoh() { +fn codec_zenoh_old() { run!( - ZenohMessage, + zenoh::ZenohMessage, { - let mut x = ZenohMessage::rand(); + let mut x = zenoh::ZenohMessage::rand(); x.channel.reliability = Reliability::Reliable; x }, @@ -616,9 +616,9 @@ fn codec_zenoh() { { Zenoh080Reliability::new(Reliability::Reliable) } ); run!( - ZenohMessage, + zenoh::ZenohMessage, { - let mut x = ZenohMessage::rand(); + let mut x = zenoh::ZenohMessage::rand(); x.channel.reliability = Reliability::BestEffort; x }, diff --git a/commons/zenoh-protocol/src/network/pull.rs b/commons/zenoh-protocol/src/network/pull.rs index 6774abee54..a6fe5ec7f2 100644 --- a/commons/zenoh-protocol/src/network/pull.rs +++ b/commons/zenoh-protocol/src/network/pull.rs @@ -24,8 +24,6 @@ pub type PullId = u32; /// +-+-+-+-+-+-+-+-+ /// |Z|X|X| PULL | /// +-+-+-+---------+ -/// | target | -/// +---------------+ /// ~ id:z32 ~ (*) /// +---------------+ /// ~ [pull_exts] ~ (*) @@ -35,7 +33,6 @@ pub type PullId = u32; /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct Pull { - pub target: u8, pub id: PullId, } @@ -45,12 +42,10 @@ impl Pull { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; - let mut rng = rand::thread_rng(); - let target: u8 = rng.gen(); let id: PullId = rng.gen(); - Self { target, id } + Self { id } } } From 309610eba276c902664b398748d686dbee216eae Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 21 Mar 2023 14:35:42 +0100 Subject: [PATCH 104/203] Response codec --- commons/zenoh-codec/src/network/mod.rs | 1 + commons/zenoh-codec/src/network/pull.rs | 2 +- commons/zenoh-codec/src/network/request.rs | 2 +- commons/zenoh-codec/src/network/response.rs | 241 ++++++++++++++++++ commons/zenoh-codec/tests/codec.rs | 42 +-- commons/zenoh-protocol/src/network/pull.rs | 6 + .../zenoh-protocol/src/network/response.rs | 25 +- 7 files changed, 293 insertions(+), 26 deletions(-) create mode 100644 commons/zenoh-codec/src/network/response.rs diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 98da4c9b09..ec22b6d9a1 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -15,6 +15,7 @@ mod declare; mod pull; mod push; mod request; +mod response; use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ diff --git a/commons/zenoh-codec/src/network/pull.rs b/commons/zenoh-codec/src/network/pull.rs index 82089f6896..c39ca3497b 100644 --- a/commons/zenoh-codec/src/network/pull.rs +++ b/commons/zenoh-codec/src/network/pull.rs @@ -18,7 +18,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{imsg, ZExtUnknown}, - network::{id, push::flag, Pull}, + network::{id, pull::flag, Pull}, zenoh::PullId, }; diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 1dcd7842b3..3f668d8225 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -218,7 +218,7 @@ where } } - // Message + // Payload // let payload: ZenohMessage = self.codec.read(&mut *reader)?; let payload: u8 = self.codec.read(&mut *reader)?; // @TODO diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs new file mode 100644 index 0000000000..e065d73950 --- /dev/null +++ b/commons/zenoh-codec/src/network/response.rs @@ -0,0 +1,241 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{imsg, ZExtUnknown}, + core::WireExpr, + network::{ + id, + response::{ext, flag}, + Mapping, RequestId, Response, ResponseFinal, + }, +}; + +// Response +impl WCodec<&Response, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Response) -> Self::Output { + // Header + let mut header = id::RESPONSE; + let mut n_exts = + ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + if n_exts != 0 { + header |= flag::Z; + } + if x.mapping != Mapping::default() { + header |= flag::M; + } + if x.wire_expr.has_suffix() { + header |= flag::N; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.rid)?; + self.write(&mut *writer, &x.wire_expr)?; + + // Extensions + if x.ext_qos != ext::QoS::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + } + if let Some(ts) = x.ext_tstamp.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (ts, n_exts != 0))?; + } + + // Payload + self.write(&mut *writer, &x.payload)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::RESPONSE { + return Err(DidntRead); + } + + // Body + let rid: RequestId = self.codec.read(&mut *reader)?; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); + let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + let mapping = if imsg::has_flag(self.header, flag::M) { + Mapping::Sender + } else { + Mapping::Receiver + }; + + // Extensions + let mut ext_qos = ext::QoS::default(); + let mut ext_tstamp = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QOS => { + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + ext_qos = q; + has_ext = ext; + } + ext::TSTAMP => { + let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext_tstamp = Some(t); + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + // Payload + // let payload: ZenohMessage = self.codec.read(&mut *reader)?; + let payload: u8 = self.codec.read(&mut *reader)?; // @TODO + + Ok(Response { + rid, + wire_expr, + mapping, + payload, + ext_qos, + ext_tstamp, + }) + } +} + +// ResponseFinal +impl WCodec<&ResponseFinal, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ResponseFinal) -> Self::Output { + // Header + let mut header = id::RESPONSE_FINAL; + let mut n_exts = + ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + if n_exts != 0 { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.rid)?; + + // Extensions + if x.ext_qos != ext::QoS::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + } + if let Some(ts) = x.ext_tstamp.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (ts, n_exts != 0))?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::RESPONSE_FINAL { + return Err(DidntRead); + } + + // Body + let rid: RequestId = self.codec.read(&mut *reader)?; + + // Extensions + let mut ext_qos = ext::QoS::default(); + let mut ext_tstamp = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QOS => { + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + ext_qos = q; + has_ext = ext; + } + ext::TSTAMP => { + let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext_tstamp = Some(t); + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + Ok(ResponseFinal { + rid, + ext_qos, + ext_tstamp, + }) + } +} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 892966bef3..20a480e595 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -34,7 +34,7 @@ use zenoh_protocol::{ subscriber::{DeclareSubscriber, ForgetSubscriber}, DeclareBody, }, - Pull, Push, Request, + Pull, Push, Request, Response, ResponseFinal, }, scouting::*, transport::*, @@ -452,21 +452,6 @@ fn codec_transport() { } // Network -#[test] -fn codec_push() { - run!(Push, Push::rand()); -} - -#[test] -fn codec_pull() { - run!(Pull, Pull::rand()); -} - -#[test] -fn codec_request() { - run!(Request, Request::rand()); -} - #[test] fn codec_declare() { run!(network::Declare, network::Declare::rand()); @@ -507,6 +492,31 @@ fn codec_forget_queryable() { run!(ForgetQueryable, ForgetQueryable::rand()); } +#[test] +fn codec_push() { + run!(Push, Push::rand()); +} + +#[test] +fn codec_pull() { + run!(Pull, Pull::rand()); +} + +#[test] +fn codec_request() { + run!(Request, Request::rand()); +} + +#[test] +fn codec_response() { + run!(Response, Response::rand()); +} + +#[test] +fn codec_response_final() { + run!(ResponseFinal, ResponseFinal::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { diff --git a/commons/zenoh-protocol/src/network/pull.rs b/commons/zenoh-protocol/src/network/pull.rs index a6fe5ec7f2..797196d044 100644 --- a/commons/zenoh-protocol/src/network/pull.rs +++ b/commons/zenoh-protocol/src/network/pull.rs @@ -14,6 +14,12 @@ pub type PullId = u32; +pub mod flag { + // pub const X: u8 = 1 << 5; // 0x20 Reserved + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + /// ```text /// Flags: /// - X: Reserved diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index 6f5609c981..e3509803bc 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -1,3 +1,4 @@ +use crate::network::Mapping; // // Copyright (c) 2022 ZettaScale Technology // @@ -13,6 +14,12 @@ // use crate::{core::WireExpr, network::RequestId}; +pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + /// # Response message /// /// ```text @@ -41,8 +48,9 @@ use crate::{core::WireExpr, network::RequestId}; /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct Response { - pub wire_expr: WireExpr<'static>, pub rid: RequestId, + pub wire_expr: WireExpr<'static>, + pub mapping: Mapping, pub payload: u8, // @TODO pub ext_qos: ext::QoS, pub ext_tstamp: Option, @@ -51,7 +59,6 @@ pub struct Response { pub mod ext { pub const QOS: u8 = crate::network::ext::QOS; pub const TSTAMP: u8 = crate::network::ext::TSTAMP; - pub const TARGET: u8 = 0x03; pub type QoS = crate::network::ext::QoS; pub type Timestamp = crate::network::ext::Timestamp; @@ -61,18 +68,20 @@ impl Response { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; - let mut rng = rand::thread_rng(); - let wire_expr = WireExpr::rand(); + let rid: RequestId = rng.gen(); + let wire_expr = WireExpr::rand(); + let mapping = Mapping::rand(); // let payload = ZenohMessage::rand(); let payload: u8 = rng.gen(); // @TODO let ext_qos = ext::QoS::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); Self { - wire_expr, rid, + wire_expr, + mapping, payload, ext_qos, ext_tstamp, @@ -84,13 +93,13 @@ impl Response { /// /// ```text /// Flags: -/// - N: Named If N==1 then the key expr has name/suffix -/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - X: Reserved +/// - X: Reserved /// - Z: Extension If Z==1 then at least one extension is present /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| ResFinal| +/// |Z|X|X| ResFinal| /// +-+-+-+---------+ /// ~ request_id:z32~ (*) /// +---------------+ From dfc6927ea05a4fd2ebbb4536721164d964fd8c78 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 21 Mar 2023 14:49:25 +0100 Subject: [PATCH 105/203] Declare Token codec --- commons/zenoh-codec/src/network/declare.rs | 134 +++++++++++++++++- commons/zenoh-codec/tests/codec.rs | 30 ++-- commons/zenoh-protocol/src/network/declare.rs | 55 ++++--- commons/zenoh-protocol/src/network/mod.rs | 10 +- 4 files changed, 185 insertions(+), 44 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index 0549873b2b..cd94638fbb 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -20,7 +20,7 @@ use zenoh_protocol::{ common::{imsg, ZExtUnknown, ZExtZ64}, core::{ExprId, WireExpr}, network::{ - declare::{self, keyexpr, queryable, subscriber, Declare, DeclareBody}, + declare::{self, keyexpr, queryable, subscriber, token, Declare, DeclareBody}, id, Mapping, }, }; @@ -40,6 +40,8 @@ where DeclareBody::ForgetSubscriber(r) => self.write(&mut *writer, r)?, DeclareBody::DeclareQueryable(r) => self.write(&mut *writer, r)?, DeclareBody::ForgetQueryable(r) => self.write(&mut *writer, r)?, + DeclareBody::DeclareToken(r) => self.write(&mut *writer, r)?, + DeclareBody::ForgetToken(r) => self.write(&mut *writer, r)?, } Ok(()) @@ -64,6 +66,8 @@ where F_SUBSCRIBER => DeclareBody::ForgetSubscriber(codec.read(&mut *reader)?), D_QUERYABLE => DeclareBody::DeclareQueryable(codec.read(&mut *reader)?), F_QUERYABLE => DeclareBody::ForgetQueryable(codec.read(&mut *reader)?), + D_TOKEN => DeclareBody::DeclareToken(codec.read(&mut *reader)?), + F_TOKEN => DeclareBody::ForgetToken(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; @@ -431,7 +435,7 @@ where } } -// SubscriberInfo +// QueryableInfo crate::impl_zextz64!(queryable::ext::QueryableInfo, queryable::ext::INFO); // DeclareQueryable @@ -583,3 +587,129 @@ where Ok(queryable::ForgetQueryable { id }) } } + +// DeclareToken +impl WCodec<&token::DeclareToken, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &token::DeclareToken) -> Self::Output { + // Header + let mut header = declare::id::D_TOKEN; + if x.mapping != Mapping::default() { + header |= subscriber::flag::M; + } + if x.wire_expr.has_suffix() { + header |= subscriber::flag::N; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + self.write(&mut *writer, &x.wire_expr)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::D_TOKEN { + return Err(DidntRead); + } + + // Body + let id: token::TokenId = self.codec.read(&mut *reader)?; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, token::flag::N)); + let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + let mapping = if imsg::has_flag(self.header, token::flag::M) { + Mapping::Sender + } else { + Mapping::Receiver + }; + + // Extensions + let mut has_ext = imsg::has_flag(self.header, subscriber::flag::Z); + while has_ext { + let (_, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + has_ext = ext; + } + + Ok(token::DeclareToken { + id, + wire_expr, + mapping, + }) + } +} + +// ForgetToken +impl WCodec<&token::ForgetToken, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &token::ForgetToken) -> Self::Output { + // Header + let header = declare::id::F_TOKEN; + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::F_TOKEN { + return Err(DidntRead); + } + + // Body + let id: token::TokenId = self.codec.read(&mut *reader)?; + + Ok(token::ForgetToken { id }) + } +} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 20a480e595..f0b886c7d9 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -23,23 +23,7 @@ use zenoh_buffers::{ BBuf, ZBuf, ZSlice, }; use zenoh_codec::*; -use zenoh_protocol::{ - common::*, - core::*, - network::{ - self, - declare::{ - keyexpr::{DeclareKeyExpr, ForgetKeyExpr}, - queryable::{DeclareQueryable, ForgetQueryable}, - subscriber::{DeclareSubscriber, ForgetSubscriber}, - DeclareBody, - }, - Pull, Push, Request, Response, ResponseFinal, - }, - scouting::*, - transport::*, - zenoh, -}; +use zenoh_protocol::{common::*, core::*, network::*, scouting::*, transport::*, zenoh}; const NUM_ITER: usize = 100; const MAX_PAYLOAD_SIZE: usize = 256; @@ -454,7 +438,7 @@ fn codec_transport() { // Network #[test] fn codec_declare() { - run!(network::Declare, network::Declare::rand()); + run!(Declare, Declare::rand()); } #[test] @@ -492,6 +476,16 @@ fn codec_forget_queryable() { run!(ForgetQueryable, ForgetQueryable::rand()); } +#[test] +fn codec_declare_token() { + run!(DeclareToken, DeclareToken::rand()); +} + +#[test] +fn codec_forget_token() { + run!(ForgetToken, ForgetToken::rand()); +} + #[test] fn codec_push() { run!(Push, Push::rand()); diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index b7739d5e15..d7be5f50c4 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -16,6 +16,10 @@ use crate::{ core::{ExprId, Reliability, WireExpr}, network::Mapping, }; +pub use keyexpr::*; +pub use queryable::*; +pub use subscriber::*; +pub use token::*; pub mod flag { // pub const X: u8 = 1 << 5; // 0x20 Reserved @@ -53,24 +57,29 @@ pub mod ext { } pub mod id { - pub const D_KEYEXPR: u8 = 0x01; - pub const F_KEYEXPR: u8 = 0x02; + pub const D_KEYEXPR: u8 = 0x00; + pub const F_KEYEXPR: u8 = 0x01; - pub const D_SUBSCRIBER: u8 = 0x03; - pub const F_SUBSCRIBER: u8 = 0x04; + pub const D_SUBSCRIBER: u8 = 0x02; + pub const F_SUBSCRIBER: u8 = 0x03; - pub const D_QUERYABLE: u8 = 0x05; - pub const F_QUERYABLE: u8 = 0x06; + pub const D_QUERYABLE: u8 = 0x04; + pub const F_QUERYABLE: u8 = 0x05; + + pub const D_TOKEN: u8 = 0x06; + pub const F_TOKEN: u8 = 0x07; } #[derive(Debug, Clone, PartialEq, Eq)] pub enum DeclareBody { - DeclareKeyExpr(keyexpr::DeclareKeyExpr), - ForgetKeyExpr(keyexpr::ForgetKeyExpr), - DeclareSubscriber(subscriber::DeclareSubscriber), - ForgetSubscriber(subscriber::ForgetSubscriber), - DeclareQueryable(queryable::DeclareQueryable), - ForgetQueryable(queryable::ForgetQueryable), + DeclareKeyExpr(DeclareKeyExpr), + ForgetKeyExpr(ForgetKeyExpr), + DeclareSubscriber(DeclareSubscriber), + ForgetSubscriber(ForgetSubscriber), + DeclareQueryable(DeclareQueryable), + ForgetQueryable(ForgetQueryable), + DeclareToken(DeclareToken), + ForgetToken(ForgetToken), } impl DeclareBody { @@ -80,13 +89,15 @@ impl DeclareBody { let mut rng = rand::thread_rng(); - match rng.gen_range(0..6) { - 0 => DeclareBody::DeclareKeyExpr(keyexpr::DeclareKeyExpr::rand()), - 1 => DeclareBody::ForgetKeyExpr(keyexpr::ForgetKeyExpr::rand()), - 2 => DeclareBody::DeclareSubscriber(subscriber::DeclareSubscriber::rand()), - 3 => DeclareBody::ForgetSubscriber(subscriber::ForgetSubscriber::rand()), - 4 => DeclareBody::DeclareQueryable(queryable::DeclareQueryable::rand()), - 5 => DeclareBody::ForgetQueryable(queryable::ForgetQueryable::rand()), + match rng.gen_range(0..8) { + 0 => DeclareBody::DeclareKeyExpr(DeclareKeyExpr::rand()), + 1 => DeclareBody::ForgetKeyExpr(ForgetKeyExpr::rand()), + 2 => DeclareBody::DeclareSubscriber(DeclareSubscriber::rand()), + 3 => DeclareBody::ForgetSubscriber(ForgetSubscriber::rand()), + 4 => DeclareBody::DeclareQueryable(DeclareQueryable::rand()), + 5 => DeclareBody::ForgetQueryable(ForgetQueryable::rand()), + 6 => DeclareBody::DeclareToken(DeclareToken::rand()), + 7 => DeclareBody::ForgetToken(ForgetToken::rand()), _ => unreachable!(), } } @@ -527,6 +538,12 @@ pub mod token { pub type TokenId = u32; + pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow + } + /// ```text /// Flags: /// - N: Named If N==1 then the key expr has name/suffix diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 4dde3b7064..24e08fc80c 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -17,11 +17,11 @@ pub mod push; pub mod request; pub mod response; -pub use declare::Declare; -pub use pull::Pull; -pub use push::Push; -pub use request::{Request, RequestId}; -pub use response::{Response, ResponseFinal}; +pub use declare::*; +pub use pull::*; +pub use push::*; +pub use request::*; +pub use response::*; pub mod id { // WARNING: it's crucial for Zenoh to work that these IDs do NOT From 8a3903f04c09f814d30fdbd7ceab5b2fc764d7ca Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 21 Mar 2023 16:15:29 +0100 Subject: [PATCH 106/203] OAM message definition and codec --- commons/zenoh-codec/src/network/mod.rs | 1 + commons/zenoh-codec/src/network/oam.rs | 128 +++++++++++++++++++++ commons/zenoh-codec/src/network/pull.rs | 52 ++++++++- commons/zenoh-codec/tests/codec.rs | 5 + commons/zenoh-protocol/src/network/mod.rs | 14 ++- commons/zenoh-protocol/src/network/oam.rs | 77 +++++++++++++ commons/zenoh-protocol/src/network/pull.rs | 19 ++- 7 files changed, 285 insertions(+), 11 deletions(-) create mode 100644 commons/zenoh-codec/src/network/oam.rs create mode 100644 commons/zenoh-protocol/src/network/oam.rs diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index ec22b6d9a1..6140b5b9da 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // mod declare; +mod oam; mod pull; mod push; mod request; diff --git a/commons/zenoh-codec/src/network/oam.rs b/commons/zenoh-codec/src/network/oam.rs new file mode 100644 index 0000000000..bf5a5bb040 --- /dev/null +++ b/commons/zenoh-codec/src/network/oam.rs @@ -0,0 +1,128 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, + ZBuf, +}; +use zenoh_protocol::{ + common::{imsg, ZExtUnknown}, + network::{ + id, + oam::{ext, flag}, + OAMId, OAM, + }, +}; + +impl WCodec<&OAM, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &OAM) -> Self::Output { + // Header + let mut header = id::OAM; + let mut n_exts = + ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + if n_exts != 0 { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + + // Extensions + if x.ext_qos != ext::QoS::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + } + if let Some(ts) = x.ext_tstamp.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (ts, n_exts != 0))?; + } + + // Payload + self.write(&mut *writer, &x.payload)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::OAM { + return Err(DidntRead); + } + + // Body + let id: OAMId = self.codec.read(&mut *reader)?; + + // Extensions + let mut ext_qos = ext::QoS::default(); + let mut ext_tstamp = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QOS => { + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + ext_qos = q; + has_ext = ext; + } + ext::TSTAMP => { + let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext_tstamp = Some(t); + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + // Payload + let payload: ZBuf = self.codec.read(&mut *reader)?; + + Ok(OAM { + id, + payload, + ext_qos, + ext_tstamp, + }) + } +} diff --git a/commons/zenoh-codec/src/network/pull.rs b/commons/zenoh-codec/src/network/pull.rs index c39ca3497b..c375679cdd 100644 --- a/commons/zenoh-codec/src/network/pull.rs +++ b/commons/zenoh-codec/src/network/pull.rs @@ -18,7 +18,11 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{imsg, ZExtUnknown}, - network::{id, pull::flag, Pull}, + network::{ + id, + pull::{ext, flag}, + Pull, + }, zenoh::PullId, }; @@ -30,12 +34,27 @@ where fn write(self, writer: &mut W, x: &Pull) -> Self::Output { // Header - let header = id::PULL; + let mut header = id::PULL; + let mut n_exts = + ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + if n_exts != 0 { + header |= flag::Z; + } self.write(&mut *writer, header)?; // Body self.write(&mut *writer, x.id)?; + // Extensions + if x.ext_qos != ext::QoS::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + } + if let Some(ts) = x.ext_tstamp.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (ts, n_exts != 0))?; + } + Ok(()) } } @@ -68,12 +87,35 @@ where let id: PullId = self.codec.read(&mut *reader)?; // Extensions + let mut ext_qos = ext::QoS::default(); + let mut ext_tstamp = None; + let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { - let (_, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - has_ext = ext; + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QOS => { + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + ext_qos = q; + has_ext = ext; + } + ext::TSTAMP => { + let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext_tstamp = Some(t); + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } } - Ok(Pull { id }) + Ok(Pull { + id, + ext_qos, + ext_tstamp, + }) } } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index f0b886c7d9..a224eb69b9 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -511,6 +511,11 @@ fn codec_response_final() { run!(ResponseFinal, ResponseFinal::rand()); } +#[test] +fn codec_oam() { + run!(OAM, OAM::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 24e08fc80c..22faacbd1b 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -12,12 +12,14 @@ // ZettaScale Zenoh Team, // pub mod declare; +pub mod oam; pub mod pull; pub mod push; pub mod request; pub mod response; pub use declare::*; +pub use oam::*; pub use pull::*; pub use push::*; pub use request::*; @@ -62,9 +64,11 @@ impl Mapping { pub enum NetworkBody { Declare(Declare), Push(Push), + Pull(Pull), Request(Request), Response(Response), ResponseFinal(ResponseFinal), + OAM(OAM), } #[derive(Debug, Clone, PartialEq, Eq)] @@ -81,12 +85,14 @@ impl NetworkMessage { let mut rng = rand::thread_rng(); - let body = match rng.gen_range(0..5) { + let body = match rng.gen_range(0..7) { 0 => NetworkBody::Declare(Declare::rand()), 1 => NetworkBody::Push(Push::rand()), - 2 => NetworkBody::Request(Request::rand()), - 3 => NetworkBody::Response(Response::rand()), - 4 => NetworkBody::ResponseFinal(ResponseFinal::rand()), + 2 => NetworkBody::Pull(Pull::rand()), + 3 => NetworkBody::Request(Request::rand()), + 4 => NetworkBody::Response(Response::rand()), + 5 => NetworkBody::ResponseFinal(ResponseFinal::rand()), + 6 => NetworkBody::OAM(OAM::rand()), _ => unreachable!(), }; diff --git a/commons/zenoh-protocol/src/network/oam.rs b/commons/zenoh-protocol/src/network/oam.rs new file mode 100644 index 0000000000..c42b210081 --- /dev/null +++ b/commons/zenoh-protocol/src/network/oam.rs @@ -0,0 +1,77 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use zenoh_buffers::ZBuf; + +pub type OAMId = u16; + +pub mod flag { + // pub const X: u8 = 1 << 5; // 0x20 Reserved + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +/// ```text +/// Flags: +/// - X: Reserved +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|X|X| OAM | +/// +-+-+-+---------+ +/// ~ id:z16 ~ (*) +/// +---------------+ +/// ~ [oam_exts] ~ +/// +---------------+ +/// ~ ~ +/// +---------------+ +/// +/// (*) ID refers to the ID used in a previous target declaration +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct OAM { + pub id: OAMId, + pub payload: ZBuf, + pub ext_qos: ext::QoS, + pub ext_tstamp: Option, +} + +pub mod ext { + pub const QOS: u8 = crate::network::ext::QOS; + pub const TSTAMP: u8 = crate::network::ext::TSTAMP; + + pub type QoS = crate::network::ext::QoS; + pub type Timestamp = crate::network::ext::Timestamp; +} + +impl OAM { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: OAMId = rng.gen(); + let payload = ZBuf::rand(rng.gen_range(1..=u8::MAX as usize)); + let ext_qos = ext::QoS::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + + Self { + id, + payload, + ext_qos, + ext_tstamp, + } + } +} diff --git a/commons/zenoh-protocol/src/network/pull.rs b/commons/zenoh-protocol/src/network/pull.rs index 797196d044..f23383b6ab 100644 --- a/commons/zenoh-protocol/src/network/pull.rs +++ b/commons/zenoh-protocol/src/network/pull.rs @@ -11,7 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // - pub type PullId = u32; pub mod flag { @@ -40,6 +39,8 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Pull { pub id: PullId, + pub ext_qos: ext::QoS, + pub ext_tstamp: Option, } impl Pull { @@ -51,7 +52,21 @@ impl Pull { let mut rng = rand::thread_rng(); let id: PullId = rng.gen(); + let ext_qos = ext::QoS::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); - Self { id } + Self { + id, + ext_qos, + ext_tstamp, + } } } + +pub mod ext { + pub const QOS: u8 = crate::network::ext::QOS; + pub const TSTAMP: u8 = crate::network::ext::TSTAMP; + + pub type QoS = crate::network::ext::QoS; + pub type Timestamp = crate::network::ext::Timestamp; +} From 50b9d6c0fcc0d0d4356f2be0aa939a4b2ab0d5c2 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 21 Mar 2023 16:27:10 +0100 Subject: [PATCH 107/203] Cleanup --- commons/zenoh-protocol/src/transport/join.rs | 37 +++++++++++ commons/zenoh-protocol/src/transport/mod.rs | 69 ++++---------------- 2 files changed, 51 insertions(+), 55 deletions(-) diff --git a/commons/zenoh-protocol/src/transport/join.rs b/commons/zenoh-protocol/src/transport/join.rs index 41d03a05a4..b110739a77 100644 --- a/commons/zenoh-protocol/src/transport/join.rs +++ b/commons/zenoh-protocol/src/transport/join.rs @@ -17,6 +17,43 @@ use crate::{ }; use core::time::Duration; +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ConduitSnList { + Plain(ConduitSn), + QoS(Box<[ConduitSn; Priority::NUM]>), +} + +impl fmt::Display for ConduitSnList { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "[ ")?; + match self { + ConduitSnList::Plain(sn) => { + write!( + f, + "{:?} {{ reliable: {}, best effort: {} }}", + Priority::default(), + sn.reliable, + sn.best_effort + )?; + } + ConduitSnList::QoS(ref sns) => { + for (prio, sn) in sns.iter().enumerate() { + let p: Priority = (prio as u8).try_into().unwrap(); + write!( + f, + "{:?} {{ reliable: {}, best effort: {} }}", + p, sn.reliable, sn.best_effort + )?; + if p != Priority::Background { + write!(f, ", ")?; + } + } + } + } + write!(f, " ]") + } +} + /// # Join message /// /// ```text diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 3ba771214b..757aa8e3a2 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -19,10 +19,7 @@ pub mod init; pub mod keepalive; pub mod open; -use crate::core::Priority; -use alloc::boxed::Box; pub use close::Close; -use core::{convert::TryInto, fmt}; pub use fragment::{Fragment, FragmentHeader}; pub use frame::{Frame, FrameHeader}; pub use init::{InitAck, InitSyn}; @@ -40,54 +37,16 @@ pub type BatchSize = u16; pub mod id { // WARNING: it's crucial that these IDs do NOT collide with the IDs // defined in `crate::network::id`. - // pub const JOIN: u8 = 0x01; // For multicast communications only - pub const INIT: u8 = 0x02; // For unicast communications only - pub const OPEN: u8 = 0x03; // For unicast communications only - pub const CLOSE: u8 = 0x04; - pub const KEEP_ALIVE: u8 = 0x05; - pub const FRAME: u8 = 0x06; - pub const FRAGMENT: u8 = 0x07; + pub const INIT: u8 = 0x00; // For unicast communications only + pub const OPEN: u8 = 0x01; // For unicast communications only + pub const CLOSE: u8 = 0x02; + pub const KEEP_ALIVE: u8 = 0x03; + pub const FRAME: u8 = 0x04; + pub const FRAGMENT: u8 = 0x05; + // pub const JOIN: u8 = 0x06; // For multicast communications only } pub type TransportSn = u32; -// pub const TRANSPORT_SN_RESOLUTION: Bits = Bits::U32; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ConduitSnList { - Plain(ConduitSn), - QoS(Box<[ConduitSn; Priority::NUM]>), -} - -impl fmt::Display for ConduitSnList { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "[ ")?; - match self { - ConduitSnList::Plain(sn) => { - write!( - f, - "{:?} {{ reliable: {}, best effort: {} }}", - Priority::default(), - sn.reliable, - sn.best_effort - )?; - } - ConduitSnList::QoS(ref sns) => { - for (prio, sn) in sns.iter().enumerate() { - let p: Priority = (prio as u8).try_into().unwrap(); - write!( - f, - "{:?} {{ reliable: {}, best effort: {} }}", - p, sn.reliable, sn.best_effort - )?; - if p != Priority::Background { - write!(f, ", ")?; - } - } - } - } - write!(f, " ]") - } -} /// The kind of reliability. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] @@ -129,11 +88,11 @@ impl TransportMessage { 1 => TransportBody::InitAck(InitAck::rand()), 2 => TransportBody::OpenSyn(OpenSyn::rand()), 3 => TransportBody::OpenAck(OpenAck::rand()), - // 4 => TransportBody::Join(Join::rand()), 4 => TransportBody::Close(Close::rand()), 5 => TransportBody::KeepAlive(KeepAlive::rand()), 6 => TransportBody::Frame(Frame::rand()), 7 => TransportBody::Fragment(Fragment::rand()), + // 8 => TransportBody::Join(Join::rand()), _ => unreachable!(), }; @@ -175,12 +134,6 @@ impl From for TransportMessage { } } -// impl From for TransportMessage { -// fn from(join: Join) -> Self { -// TransportBody::Join(join).into() -// } -// } - impl From for TransportMessage { fn from(close: Close) -> Self { TransportBody::Close(close).into() @@ -204,3 +157,9 @@ impl From for TransportMessage { TransportBody::Fragment(fragment).into() } } + +// impl From for TransportMessage { +// fn from(join: Join) -> Self { +// TransportBody::Join(join).into() +// } +// } From 63a0f3895688dab3e0efcf6a25c4a81073b84234 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Mar 2023 10:55:45 +0100 Subject: [PATCH 108/203] Oam message and codec --- commons/zenoh-codec/src/common/extension.rs | 14 +- commons/zenoh-codec/src/network/mod.rs | 1 - commons/zenoh-codec/src/network/oam.rs | 57 +++++-- commons/zenoh-codec/src/transport/mod.rs | 9 +- commons/zenoh-codec/src/transport/oam.rs | 141 ++++++++++++++++++ commons/zenoh-codec/tests/codec.rs | 18 ++- .../zenoh-protocol/src/common/extension.rs | 41 +++-- commons/zenoh-protocol/src/network/mod.rs | 58 +++---- commons/zenoh-protocol/src/network/oam.rs | 43 +++--- commons/zenoh-protocol/src/transport/mod.rs | 27 ++-- commons/zenoh-protocol/src/transport/oam.rs | 79 ++++++++++ 11 files changed, 388 insertions(+), 100 deletions(-) create mode 100644 commons/zenoh-codec/src/transport/oam.rs create mode 100644 commons/zenoh-protocol/src/transport/oam.rs diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index f862af2568..d51e262b24 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ ZBuf, }; use zenoh_protocol::common::{ - iext, imsg::has_flag, ZExtUnit, ZExtUnknown, ZExtZ64, ZExtZBuf, ZExtZBufHeader, ZExtensionBody, + iext, imsg::has_flag, ZExtBody, ZExtUnit, ZExtUnknown, ZExtZ64, ZExtZBuf, ZExtZBufHeader, }; // ZExtUnit @@ -232,16 +232,16 @@ where header |= iext::FLAG_Z; } match &x.body { - ZExtensionBody::Unit => { + ZExtBody::Unit => { header |= iext::ENC_UNIT; self.write(&mut *writer, header)? } - ZExtensionBody::Z64(u64) => { + ZExtBody::Z64(u64) => { header |= iext::ENC_Z64; self.write(&mut *writer, header)?; self.write(&mut *writer, *u64)? } - ZExtensionBody::ZBuf(zbuf) => { + ZExtBody::ZBuf(zbuf) => { header |= iext::ENC_ZBUF; self.write(&mut *writer, header)?; self.write(&mut *writer, zbuf)? @@ -272,14 +272,14 @@ where fn read(self, reader: &mut R) -> Result<(ZExtUnknown, bool), Self::Error> { let body = match self.header & iext::ENC_MASK { - iext::ENC_UNIT => ZExtensionBody::Unit, + iext::ENC_UNIT => ZExtBody::Unit, iext::ENC_Z64 => { let u64: u64 = self.codec.read(&mut *reader)?; - ZExtensionBody::Z64(u64) + ZExtBody::Z64(u64) } iext::ENC_ZBUF => { let zbuf: ZBuf = self.codec.read(&mut *reader)?; - ZExtensionBody::ZBuf(zbuf) + ZExtBody::ZBuf(zbuf) } _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 6140b5b9da..2331a1584e 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -26,7 +26,6 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::{imsg, ZExtZ64, ZExtZBufHeader}, network::*, - network::{NetworkBody, NetworkMessage}, }; // NetworkMessage diff --git a/commons/zenoh-codec/src/network/oam.rs b/commons/zenoh-codec/src/network/oam.rs index bf5a5bb040..44965168e8 100644 --- a/commons/zenoh-codec/src/network/oam.rs +++ b/commons/zenoh-codec/src/network/oam.rs @@ -18,23 +18,33 @@ use zenoh_buffers::{ ZBuf, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown}, + common::{iext, imsg, ZExtBody, ZExtUnknown}, network::{ id, - oam::{ext, flag}, - OAMId, OAM, + oam::{ext, flag, Oam, OamId}, }, }; -impl WCodec<&OAM, &mut W> for Zenoh080 +impl WCodec<&Oam, &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &OAM) -> Self::Output { + fn write(self, writer: &mut W, x: &Oam) -> Self::Output { // Header let mut header = id::OAM; + match &x.body { + ZExtBody::Unit => { + header |= iext::ENC_UNIT; + } + ZExtBody::Z64(_) => { + header |= iext::ENC_Z64; + } + ZExtBody::ZBuf(_) => { + header |= iext::ENC_ZBUF; + } + } let mut n_exts = ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); if n_exts != 0 { @@ -56,38 +66,46 @@ where } // Payload - self.write(&mut *writer, &x.payload)?; + match &x.body { + ZExtBody::Unit => {} + ZExtBody::Z64(u64) => { + self.write(&mut *writer, u64)?; + } + ZExtBody::ZBuf(zbuf) => { + self.write(&mut *writer, zbuf)?; + } + } Ok(()) } } -impl RCodec for Zenoh080 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); codec.read(reader) } } -impl RCodec for Zenoh080Header +impl RCodec for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result { if imsg::mid(self.header) != id::OAM { return Err(DidntRead); } // Body - let id: OAMId = self.codec.read(&mut *reader)?; + let id: OamId = self.codec.read(&mut *reader)?; // Extensions let mut ext_qos = ext::QoS::default(); @@ -116,11 +134,22 @@ where } // Payload - let payload: ZBuf = self.codec.read(&mut *reader)?; + let body = match self.header & iext::ENC_MASK { + iext::ENC_UNIT => ZExtBody::Unit, + iext::ENC_Z64 => { + let u64: u64 = self.codec.read(&mut *reader)?; + ZExtBody::Z64(u64) + } + iext::ENC_ZBUF => { + let zbuf: ZBuf = self.codec.read(&mut *reader)?; + ZExtBody::ZBuf(zbuf) + } + _ => return Err(DidntRead), + }; - Ok(OAM { + Ok(Oam { id, - payload, + body, ext_qos, ext_tstamp, }) diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index 7e3d7caf42..b27ac3a2aa 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -15,9 +15,10 @@ mod close; mod fragment; mod frame; mod init; -// mod join; mod keepalive; +mod oam; mod open; +// mod join; use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ @@ -42,8 +43,9 @@ where TransportBody::InitAck(b) => self.write(&mut *writer, b), TransportBody::OpenSyn(b) => self.write(&mut *writer, b), TransportBody::OpenAck(b) => self.write(&mut *writer, b), - // TransportBody::Join(b) => self.write(&mut *writer, b), TransportBody::Close(b) => self.write(&mut *writer, b), + TransportBody::OAM(b) => self.write(&mut *writer, b), + // TransportBody::Join(b) => self.write(&mut *writer, b), } } } @@ -76,8 +78,9 @@ where TransportBody::OpenAck(codec.read(&mut *reader)?) } } - // id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), id::CLOSE => TransportBody::Close(codec.read(&mut *reader)?), + id::OAM => TransportBody::OAM(codec.read(&mut *reader)?), + // id::JOIN => TransportBody::Join(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/src/transport/oam.rs b/commons/zenoh-codec/src/transport/oam.rs new file mode 100644 index 0000000000..3bc839f21b --- /dev/null +++ b/commons/zenoh-codec/src/transport/oam.rs @@ -0,0 +1,141 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, + ZBuf, +}; +use zenoh_protocol::{ + common::{iext, imsg, ZExtBody, ZExtUnknown}, + transport::{ + id, + oam::{ext, flag, Oam, OamId}, + }, +}; + +impl WCodec<&Oam, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Oam) -> Self::Output { + // Header + let mut header = id::OAM; + match &x.body { + ZExtBody::Unit => { + header |= iext::ENC_UNIT; + } + ZExtBody::Z64(_) => { + header |= iext::ENC_Z64; + } + ZExtBody::ZBuf(_) => { + header |= iext::ENC_ZBUF; + } + } + let mut n_exts = (x.ext_qos != ext::QoS::default()) as u8; + if n_exts != 0 { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + + // Extensions + if x.ext_qos != ext::QoS::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + } + + // Payload + match &x.body { + ZExtBody::Unit => {} + ZExtBody::Z64(u64) => { + self.write(&mut *writer, u64)?; + } + ZExtBody::ZBuf(zbuf) => { + self.write(&mut *writer, zbuf)?; + } + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::OAM { + return Err(DidntRead); + } + + // Body + let id: OamId = self.codec.read(&mut *reader)?; + + // Extensions + let mut ext_qos = ext::QoS::default(); + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match imsg::mid(ext) { + ext::QOS => { + let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + ext_qos = q; + has_ext = ext; + } + _ => { + let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + has_ext = ext; + } + } + } + + // Payload + let body = match self.header & iext::ENC_MASK { + iext::ENC_UNIT => ZExtBody::Unit, + iext::ENC_Z64 => { + let u64: u64 = self.codec.read(&mut *reader)?; + ZExtBody::Z64(u64) + } + iext::ENC_ZBUF => { + let zbuf: ZBuf = self.codec.read(&mut *reader)?; + ZExtBody::ZBuf(zbuf) + } + _ => return Err(DidntRead), + }; + + Ok(Oam { id, body, ext_qos }) + } +} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index a224eb69b9..6d1c4ab219 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -23,7 +23,14 @@ use zenoh_buffers::{ BBuf, ZBuf, ZSlice, }; use zenoh_codec::*; -use zenoh_protocol::{common::*, core::*, network::*, scouting::*, transport::*, zenoh}; +use zenoh_protocol::{ + common::*, + core::*, + network::{self, *}, + scouting::*, + transport::{self, *}, + zenoh, +}; const NUM_ITER: usize = 100; const MAX_PAYLOAD_SIZE: usize = 256; @@ -430,6 +437,11 @@ fn codec_fragment() { run!(Fragment, Fragment::rand()); } +#[test] +fn codec_transport_oam() { + run!(transport::Oam, transport::Oam::rand()); +} + #[test] fn codec_transport() { run!(TransportMessage, TransportMessage::rand()); @@ -512,8 +524,8 @@ fn codec_response_final() { } #[test] -fn codec_oam() { - run!(OAM, OAM::rand()); +fn codec_network_oam() { + run!(network::Oam, network::Oam::rand()); } // Zenoh diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index 33fd8273da..af557254f2 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -92,7 +92,7 @@ impl TryFrom for ZExtUnit<{ ID }> { return Err(DidntConvert); } match v.body { - ZExtensionBody::Unit => Ok(Self::new()), + ZExtBody::Unit => Ok(Self::new()), _ => Err(DidntConvert), } } @@ -132,7 +132,7 @@ impl TryFrom for ZExtZ64<{ ID }> { return Err(DidntConvert); } match v.body { - ZExtensionBody::Z64(v) => Ok(Self::new(v)), + ZExtBody::Z64(v) => Ok(Self::new(v)), _ => Err(DidntConvert), } } @@ -172,7 +172,7 @@ impl TryFrom for ZExtZBuf<{ ID }> { return Err(DidntConvert); } match v.body { - ZExtensionBody::ZBuf(v) => Ok(Self::new(v)), + ZExtBody::ZBuf(v) => Ok(Self::new(v)), _ => Err(DidntConvert), } } @@ -194,31 +194,40 @@ impl ZExtZBufHeader<{ ID }> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ZExtUnknown { pub id: u8, - pub body: ZExtensionBody, + pub body: ZExtBody, } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum ZExtensionBody { +pub enum ZExtBody { Unit, Z64(u64), ZBuf(ZBuf), } -impl ZExtUnknown { +impl ZExtBody { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::{seq::SliceRandom, Rng}; - let mut rng = rand::thread_rng(); - let id: u8 = rng.gen_range(0x00..=iext::ID_MASK); - let body = [ - ZExtensionBody::Unit, - ZExtensionBody::Z64(rng.gen()), - ZExtensionBody::ZBuf(ZBuf::rand(rng.gen_range(8..=64))), + [ + ZExtBody::Unit, + ZExtBody::Z64(rng.gen()), + ZExtBody::ZBuf(ZBuf::rand(rng.gen_range(8..=64))), ] .choose(&mut rng) .unwrap() - .clone(); + .clone() + } +} + +impl ZExtUnknown { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: u8 = rng.gen_range(0x00..=iext::ID_MASK); + let body = ZExtBody::rand(); Self { id, body } } } @@ -227,7 +236,7 @@ impl From> for ZExtUnknown { fn from(_: ZExtUnit<{ ID }>) -> Self { ZExtUnknown { id: ID, - body: ZExtensionBody::Unit, + body: ZExtBody::Unit, } } } @@ -236,7 +245,7 @@ impl From> for ZExtUnknown { fn from(e: ZExtZ64<{ ID }>) -> Self { ZExtUnknown { id: ID, - body: ZExtensionBody::Z64(e.value), + body: ZExtBody::Z64(e.value), } } } @@ -245,7 +254,7 @@ impl From> for ZExtUnknown { fn from(e: ZExtZBuf<{ ID }>) -> Self { ZExtUnknown { id: ID, - body: ZExtensionBody::ZBuf(e.value), + body: ZExtBody::ZBuf(e.value), } } } diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 22faacbd1b..da825bed89 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -26,15 +26,15 @@ pub use request::*; pub use response::*; pub mod id { - // WARNING: it's crucial for Zenoh to work that these IDs do NOT - // collide with the IDs defined in `crate::transport::id`. - pub const DECLARE: u8 = 0x1f; - pub const PUSH: u8 = 0x1e; - pub const PULL: u8 = 0x1d; - pub const REQUEST: u8 = 0x1c; - pub const RESPONSE: u8 = 0x1b; - pub const RESPONSE_FINAL: u8 = 0x1a; - pub const OAM: u8 = 0x19; + // WARNING: it's crucial that these IDs do NOT collide with the IDs + // defined in `crate::transport::id`. + pub const OAM: u8 = 0x1f; + pub const DECLARE: u8 = 0x1e; + pub const PUSH: u8 = 0x1d; + pub const PULL: u8 = 0x1c; + pub const REQUEST: u8 = 0x1b; + pub const RESPONSE: u8 = 0x1a; + pub const RESPONSE_FINAL: u8 = 0x19; } #[repr(u8)] @@ -68,7 +68,7 @@ pub enum NetworkBody { Request(Request), Response(Response), ResponseFinal(ResponseFinal), - OAM(OAM), + OAM(Oam), } #[derive(Debug, Clone, PartialEq, Eq)] @@ -92,7 +92,7 @@ impl NetworkMessage { 3 => NetworkBody::Request(Request::rand()), 4 => NetworkBody::Response(Response::rand()), 5 => NetworkBody::ResponseFinal(ResponseFinal::rand()), - 6 => NetworkBody::OAM(OAM::rand()), + 6 => NetworkBody::OAM(Oam::rand()), _ => unreachable!(), }; @@ -151,17 +151,19 @@ pub mod ext { pub const QOS: u8 = 0x01; pub const TSTAMP: u8 = 0x02; - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// |Z|0_1| ID | - /// +-+-+-+---------+ - /// %0|rsv|E|D|prio % - /// +---------------+ + /// ```text + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|0_1| ID | + /// +-+-+-+---------+ + /// %0|rsv|E|D|prio % + /// +---------------+ /// - /// - prio: Priority class - /// - D: Don't drop. Don't drop the message for congestion control. - /// - E: Express. Don't batch this message. - /// - rsv: Reserved + /// - prio: Priority class + /// - D: Don't drop. Don't drop the message for congestion control. + /// - E: Express. Don't batch this message. + /// - rsv: Reserved + /// ``` #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq)] pub struct QoS { @@ -243,12 +245,14 @@ pub mod ext { } } - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// |Z|1_0| ID | - /// +-+-+-+---------+ - /// ~ ts: ~ - /// +---------------+ + /// ```text + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|1_0| ID | + /// +-+-+-+---------+ + /// ~ ts: ~ + /// +---------------+ + /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Timestamp { pub timestamp: uhlc::Timestamp, diff --git a/commons/zenoh-protocol/src/network/oam.rs b/commons/zenoh-protocol/src/network/oam.rs index c42b210081..8dfff1a980 100644 --- a/commons/zenoh-protocol/src/network/oam.rs +++ b/commons/zenoh-protocol/src/network/oam.rs @@ -11,39 +11,46 @@ // Contributors: // ZettaScale Zenoh Team, // -use zenoh_buffers::ZBuf; +use crate::common::ZExtBody; -pub type OAMId = u16; +pub type OamId = u16; pub mod flag { - // pub const X: u8 = 1 << 5; // 0x20 Reserved - // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const T: u8 = 1 << 5; // 0x20 Transport + // pub const X: u8 = 1 << 6; // 0x40 Reserved pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow } /// ```text /// Flags: -/// - X: Reserved -/// - X: Reserved +/// - E |: Encoding The encoding of the extension +/// - E/ /// - Z: Extension If Z==1 then at least one extension is present /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|X|X| OAM | +/// |Z|ENC| OAM | /// +-+-+-+---------+ -/// ~ id:z16 ~ (*) +/// ~ id:z16 ~ /// +---------------+ /// ~ [oam_exts] ~ /// +---------------+ -/// ~ ~ +/// % length % -- If ENC == u64 || ENC == ZBuf +/// +---------------+ +/// ~ [u8] ~ -- If ENC == ZBuf /// +---------------+ -/// -/// (*) ID refers to the ID used in a previous target declaration /// ``` +/// +/// Encoding: +/// - 0b00: Unit +/// - 0b01: u64 +/// - 0b10: ZBuf +/// - 0b11: Reserved +/// #[derive(Debug, Clone, PartialEq, Eq)] -pub struct OAM { - pub id: OAMId, - pub payload: ZBuf, +pub struct Oam { + pub id: OamId, + pub body: ZExtBody, pub ext_qos: ext::QoS, pub ext_tstamp: Option, } @@ -56,20 +63,20 @@ pub mod ext { pub type Timestamp = crate::network::ext::Timestamp; } -impl OAM { +impl Oam { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; let mut rng = rand::thread_rng(); - let id: OAMId = rng.gen(); - let payload = ZBuf::rand(rng.gen_range(1..=u8::MAX as usize)); + let id: OamId = rng.gen(); + let body = ZExtBody::rand(); let ext_qos = ext::QoS::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); Self { id, - payload, + body, ext_qos, ext_tstamp, } diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 757aa8e3a2..1e628cc209 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -15,17 +15,19 @@ pub mod close; pub mod fragment; pub mod frame; pub mod init; -// pub mod join; pub mod keepalive; +pub mod oam; pub mod open; +// pub mod join; pub use close::Close; pub use fragment::{Fragment, FragmentHeader}; pub use frame::{Frame, FrameHeader}; pub use init::{InitAck, InitSyn}; -// pub use join::Join; pub use keepalive::KeepAlive; +pub use oam::Oam; pub use open::{OpenAck, OpenSyn}; +// pub use join::Join; /// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length /// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. @@ -37,13 +39,14 @@ pub type BatchSize = u16; pub mod id { // WARNING: it's crucial that these IDs do NOT collide with the IDs // defined in `crate::network::id`. - pub const INIT: u8 = 0x00; // For unicast communications only - pub const OPEN: u8 = 0x01; // For unicast communications only - pub const CLOSE: u8 = 0x02; - pub const KEEP_ALIVE: u8 = 0x03; - pub const FRAME: u8 = 0x04; - pub const FRAGMENT: u8 = 0x05; - // pub const JOIN: u8 = 0x06; // For multicast communications only + pub const OAM: u8 = 0x00; + pub const INIT: u8 = 0x01; // For unicast communications only + pub const OPEN: u8 = 0x02; // For unicast communications only + pub const CLOSE: u8 = 0x03; + pub const KEEP_ALIVE: u8 = 0x04; + pub const FRAME: u8 = 0x05; + pub const FRAGMENT: u8 = 0x06; + // pub const JOIN: u8 = 0x07; // For multicast communications only } pub type TransportSn = u32; @@ -62,11 +65,12 @@ pub enum TransportBody { InitAck(InitAck), OpenSyn(OpenSyn), OpenAck(OpenAck), - // Join(Join), Close(Close), KeepAlive(KeepAlive), Frame(Frame), Fragment(Fragment), + OAM(Oam), + // Join(Join), } #[derive(Debug, Clone, PartialEq, Eq)] @@ -83,7 +87,7 @@ impl TransportMessage { let mut rng = rand::thread_rng(); - let body = match rng.gen_range(0..8) { + let body = match rng.gen_range(0..9) { 0 => TransportBody::InitSyn(InitSyn::rand()), 1 => TransportBody::InitAck(InitAck::rand()), 2 => TransportBody::OpenSyn(OpenSyn::rand()), @@ -92,6 +96,7 @@ impl TransportMessage { 5 => TransportBody::KeepAlive(KeepAlive::rand()), 6 => TransportBody::Frame(Frame::rand()), 7 => TransportBody::Fragment(Fragment::rand()), + 8 => TransportBody::OAM(Oam::rand()), // 8 => TransportBody::Join(Join::rand()), _ => unreachable!(), }; diff --git a/commons/zenoh-protocol/src/transport/oam.rs b/commons/zenoh-protocol/src/transport/oam.rs new file mode 100644 index 0000000000..e2ecd07b17 --- /dev/null +++ b/commons/zenoh-protocol/src/transport/oam.rs @@ -0,0 +1,79 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::common::ZExtBody; + +pub type OamId = u16; + +pub mod flag { + pub const T: u8 = 1 << 5; // 0x20 Transport + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +/// ```text +/// Flags: +/// - E |: Encoding The encoding of the extension +/// - E/ +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|ENC| OAM | +/// +-+-+-+---------+ +/// ~ id:z16 ~ +/// +---------------+ +/// ~ [oam_exts] ~ +/// +---------------+ +/// % length % -- If ENC == u64 || ENC == ZBuf +/// +---------------+ +/// ~ [u8] ~ -- If ENC == ZBuf +/// +---------------+ +/// ``` +/// +/// Encoding: +/// - 0b00: Unit +/// - 0b01: u64 +/// - 0b10: ZBuf +/// - 0b11: Reserved +/// +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Oam { + pub id: OamId, + pub body: ZExtBody, + pub ext_qos: ext::QoS, +} + +pub mod ext { + pub const QOS: u8 = crate::transport::frame::ext::QOS; + + pub type QoS = crate::transport::frame::ext::QoS; +} + +impl Oam { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: OamId = rng.gen(); + let payload = ZExtBody::rand(); + let ext_qos = ext::QoS::rand(); + + Self { + id, + body: payload, + ext_qos, + } + } +} From 237f3e14b99f4a2c33d0ff29322c1b784d1882ce Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Mar 2023 14:59:32 +0100 Subject: [PATCH 109/203] Fix queryableinfo distance resolution --- commons/zenoh-protocol/src/core/whatami.rs | 2 +- commons/zenoh-protocol/src/network/declare.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/commons/zenoh-protocol/src/core/whatami.rs b/commons/zenoh-protocol/src/core/whatami.rs index 932640fe67..f907f3c381 100644 --- a/commons/zenoh-protocol/src/core/whatami.rs +++ b/commons/zenoh-protocol/src/core/whatami.rs @@ -44,8 +44,8 @@ impl WhatAmI { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::prelude::SliceRandom; - let mut rng = rand::thread_rng(); + *[Self::Router, Self::Peer, Self::Client] .choose(&mut rng) .unwrap() diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index d7be5f50c4..1bc639fe99 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -446,8 +446,8 @@ pub mod queryable { /// +---------------+ #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub struct QueryableInfo { - pub complete: u8, // Default 0: incomplete - pub distance: u8, // Default 0: no distance + pub complete: u8, // Default 0: incomplete // @TODO: maybe a bitflag + pub distance: u32, // Default 0: no distance } impl QueryableInfo { @@ -456,7 +456,7 @@ pub mod queryable { use rand::Rng; let mut rng = rand::thread_rng(); let complete: u8 = rng.gen(); - let distance: u8 = rng.gen(); + let distance: u32 = rng.gen(); Self { complete, distance } } @@ -465,7 +465,7 @@ pub mod queryable { impl From> for QueryableInfo { fn from(ext: ZExtZ64<{ INFO }>) -> Self { let complete = ext.value as u8; - let distance = (ext.value >> 8) as u8; + let distance = (ext.value >> 8) as u32; Self { complete, distance } } From d6271a88b3011180f8cb6f3d4bc60de181ec404a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Mar 2023 17:44:28 +0100 Subject: [PATCH 110/203] Extensions can be mandatory --- commons/zenoh-codec/benches/codec.rs | 6 +- commons/zenoh-codec/src/common/extension.rs | 35 ++--- commons/zenoh-codec/src/network/declare.rs | 32 ++--- commons/zenoh-codec/src/network/mod.rs | 20 +-- commons/zenoh-codec/src/network/oam.rs | 16 +-- commons/zenoh-codec/src/network/pull.rs | 18 +-- commons/zenoh-codec/src/network/push.rs | 42 +++--- commons/zenoh-codec/src/network/request.rs | 80 +++++------ commons/zenoh-codec/src/network/response.rs | 34 ++--- commons/zenoh-codec/src/transport/fragment.rs | 14 +- commons/zenoh-codec/src/transport/frame.rs | 16 +-- commons/zenoh-codec/src/transport/init.rs | 6 +- commons/zenoh-codec/src/transport/oam.rs | 12 +- commons/zenoh-codec/src/transport/open.rs | 6 +- commons/zenoh-codec/tests/codec.rs | 3 +- .../zenoh-protocol/src/common/extension.rs | 126 ++++++++++++++++-- commons/zenoh-protocol/src/network/declare.rs | 35 ++--- commons/zenoh-protocol/src/network/mod.rs | 29 ++-- commons/zenoh-protocol/src/network/oam.rs | 18 ++- commons/zenoh-protocol/src/network/pull.rs | 14 +- commons/zenoh-protocol/src/network/push.rs | 29 ++-- commons/zenoh-protocol/src/network/request.rs | 53 ++++---- .../zenoh-protocol/src/network/response.rs | 22 +-- .../zenoh-protocol/src/transport/fragment.rs | 12 +- commons/zenoh-protocol/src/transport/frame.rs | 33 ++--- commons/zenoh-protocol/src/transport/init.rs | 18 ++- commons/zenoh-protocol/src/transport/oam.rs | 8 +- commons/zenoh-protocol/src/transport/open.rs | 22 ++- io/zenoh-transport/src/common/batch.rs | 2 +- io/zenoh-transport/src/common/pipeline.rs | 2 +- .../src/unicast/establishment/ext/auth/mod.rs | 10 +- .../unicast/establishment/ext/auth/pubkey.rs | 31 +++-- .../unicast/establishment/ext/auth/usrpwd.rs | 28 ++-- 33 files changed, 473 insertions(+), 359 deletions(-) diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 99c7cc4d8d..2720498b85 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -74,7 +74,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), sn: TransportSn::MIN, - ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), + ext_qos: zenoh_protocol::transport::frame::ext::QoSType::default(), }; let data = Data { @@ -111,7 +111,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), sn: TransportSn::MIN, - ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), + ext_qos: zenoh_protocol::transport::frame::ext::QoSType::default(), }; let data = Data { @@ -143,7 +143,7 @@ fn criterion_benchmark(c: &mut Criterion) { let frame = FrameHeader { reliability: Reliability::default(), sn: TransportSn::MIN, - ext_qos: zenoh_protocol::transport::frame::ext::QoS::default(), + ext_qos: zenoh_protocol::transport::frame::ext::QoSType::default(), }; let data = Data { diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index d51e262b24..870760b52d 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -31,7 +31,7 @@ where fn write(self, writer: &mut W, x: (&ZExtUnit<{ ID }>, bool)) -> Self::Output { let (_x, more) = x; - let mut header: u8 = ID | iext::ENC_UNIT; + let mut header: u8 = ID; if more { header |= iext::FLAG_Z; } @@ -60,10 +60,9 @@ where type Error = DidntRead; fn read(self, _reader: &mut R) -> Result<(ZExtUnit<{ ID }>, bool), Self::Error> { - if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_UNIT) { + if iext::eid(self.header) != ID { return Err(DidntRead); } - Ok((ZExtUnit::new(), has_flag(self.header, iext::FLAG_Z))) } } @@ -77,7 +76,7 @@ where fn write(self, writer: &mut W, x: (&ZExtZ64<{ ID }>, bool)) -> Self::Output { let (x, more) = x; - let mut header: u8 = ID | iext::ENC_Z64; + let mut header: u8 = ID; if more { header |= iext::FLAG_Z; } @@ -107,12 +106,11 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result<(ZExtZ64<{ ID }>, bool), Self::Error> { - if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_Z64) { + if iext::eid(self.header) != ID { return Err(DidntRead); } let value: u64 = self.codec.read(&mut *reader)?; - Ok((ZExtZ64::new(value), has_flag(self.header, iext::FLAG_Z))) } } @@ -126,7 +124,7 @@ where fn write(self, writer: &mut W, x: (&ZExtZBuf<{ ID }>, bool)) -> Self::Output { let (x, more) = x; - let mut header: u8 = ID | iext::ENC_ZBUF; + let mut header: u8 = ID; if more { header |= iext::FLAG_Z; } @@ -156,12 +154,10 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result<(ZExtZBuf<{ ID }>, bool), Self::Error> { - if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZBUF) { + if iext::eid(self.header) != ID { return Err(DidntRead); } - let value: ZBuf = self.codec.read(&mut *reader)?; - Ok((ZExtZBuf::new(value), has_flag(self.header, iext::FLAG_Z))) } } @@ -175,7 +171,7 @@ where fn write(self, writer: &mut W, x: (&ZExtZBufHeader<{ ID }>, bool)) -> Self::Output { let (x, more) = x; - let mut header: u8 = ID | iext::ENC_ZBUF; + let mut header: u8 = ID; if more { header |= iext::FLAG_Z; } @@ -205,12 +201,11 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result<(ZExtZBufHeader<{ ID }>, bool), Self::Error> { - if (self.header & iext::ID_MASK != ID) || (self.header & iext::ENC_MASK != iext::ENC_ZBUF) { + if iext::eid(self.header) != ID { return Err(DidntRead); } let len: usize = self.codec.read(&mut *reader)?; - Ok(( ZExtZBufHeader::new(len), has_flag(self.header, iext::FLAG_Z), @@ -232,17 +227,12 @@ where header |= iext::FLAG_Z; } match &x.body { - ZExtBody::Unit => { - header |= iext::ENC_UNIT; - self.write(&mut *writer, header)? - } + ZExtBody::Unit => self.write(&mut *writer, header)?, ZExtBody::Z64(u64) => { - header |= iext::ENC_Z64; self.write(&mut *writer, header)?; self.write(&mut *writer, *u64)? } ZExtBody::ZBuf(zbuf) => { - header |= iext::ENC_ZBUF; self.write(&mut *writer, header)?; self.write(&mut *writer, zbuf)? } @@ -281,12 +271,15 @@ where let zbuf: ZBuf = self.codec.read(&mut *reader)?; ZExtBody::ZBuf(zbuf) } - _ => return Err(DidntRead), + _ => { + println!("CAZZO"); + return Err(DidntRead); + } }; Ok(( ZExtUnknown { - id: self.header & iext::ID_MASK, + id: self.header & !iext::FLAG_Z, body, }, has_flag(self.header, iext::FLAG_Z), diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index cd94638fbb..ef785d889a 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown, ZExtZ64}, + common::{iext, imsg, ZExtUnknown, ZExtZ64}, core::{ExprId, WireExpr}, network::{ declare::{self, keyexpr, queryable, subscriber, token, Declare, DeclareBody}, @@ -85,15 +85,15 @@ where fn write(self, writer: &mut W, x: &Declare) -> Self::Output { // Header let mut header = id::DECLARE; - let mut n_exts = - ((x.ext_qos != declare::ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + let mut n_exts = ((x.ext_qos != declare::ext::QoSType::default()) as u8) + + (x.ext_tstamp.is_some() as u8); if n_exts != 0 { header |= declare::flag::Z; } self.write(&mut *writer, header)?; // Extensions - if x.ext_qos != declare::ext::QoS::default() { + if x.ext_qos != declare::ext::QoSType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; } @@ -135,21 +135,21 @@ where } // Extensions - let mut ext_qos = declare::ext::QoS::default(); + let mut ext_qos = declare::ext::QoSType::default(); let mut ext_tstamp = None; let mut has_ext = imsg::has_flag(self.header, declare::flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - declare::ext::QOS => { - let (q, ext): (declare::ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + declare::ext::QoS::ID => { + let (q, ext): (declare::ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = q; has_ext = ext; } - declare::ext::TSTAMP => { - let (t, ext): (declare::ext::Timestamp, bool) = eodec.read(&mut *reader)?; + declare::ext::Timestamp::ID => { + let (t, ext): (declare::ext::TimestampType, bool) = eodec.read(&mut *reader)?; ext_tstamp = Some(t); has_ext = ext; } @@ -281,7 +281,7 @@ where } // SubscriberInfo -crate::impl_zextz64!(subscriber::ext::SubscriberInfo, subscriber::ext::INFO); +crate::impl_zextz64!(subscriber::ext::SubscriberInfo, subscriber::ext::Info::ID); // DeclareSubscriber impl WCodec<&subscriber::DeclareSubscriber, &mut W> for Zenoh080 @@ -361,8 +361,8 @@ where while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - subscriber::ext::INFO => { + match iext::eid(ext) { + subscriber::ext::Info::ID => { let (i, ext): (subscriber::ext::SubscriberInfo, bool) = eodec.read(&mut *reader)?; ext_info = i; @@ -436,7 +436,7 @@ where } // QueryableInfo -crate::impl_zextz64!(queryable::ext::QueryableInfo, queryable::ext::INFO); +crate::impl_zextz64!(queryable::ext::QueryableInfo, queryable::ext::Info::ID); // DeclareQueryable impl WCodec<&queryable::DeclareQueryable, &mut W> for Zenoh080 @@ -514,8 +514,8 @@ where while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - queryable::ext::INFO => { + match iext::eid(ext) { + queryable::ext::Info::ID => { let (i, ext): (queryable::ext::QueryableInfo, bool) = eodec.read(&mut *reader)?; ext_info = i; diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 2331a1584e..743bc7f1a6 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -81,47 +81,47 @@ where } // Extensions: QoS -crate::impl_zextz64!(ext::QoS, ext::QOS); +crate::impl_zextz64!(ext::QoSType, ext::QoS::ID); // Extensions: Timestamp -impl WCodec<(&ext::Timestamp, bool), &mut W> for Zenoh080 +impl WCodec<(&ext::TimestampType, bool), &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: (&ext::Timestamp, bool)) -> Self::Output { + fn write(self, writer: &mut W, x: (&ext::TimestampType, bool)) -> Self::Output { let (tstamp, more) = x; - let header: ZExtZBufHeader<{ ext::TSTAMP }> = + let header: ZExtZBufHeader<{ ext::Timestamp::ID }> = ZExtZBufHeader::new(self.w_len(&tstamp.timestamp)); self.write(&mut *writer, (&header, more))?; self.write(&mut *writer, &tstamp.timestamp) } } -impl RCodec<(ext::Timestamp, bool), &mut R> for Zenoh080 +impl RCodec<(ext::TimestampType, bool), &mut R> for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ext::Timestamp, bool), Self::Error> { + fn read(self, reader: &mut R) -> Result<(ext::TimestampType, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); codec.read(reader) } } -impl RCodec<(ext::Timestamp, bool), &mut R> for Zenoh080Header +impl RCodec<(ext::TimestampType, bool), &mut R> for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ext::Timestamp, bool), Self::Error> { + fn read(self, reader: &mut R) -> Result<(ext::TimestampType, bool), Self::Error> { let codec = Zenoh080::new(); - let (_, more): (ZExtZBufHeader<{ ext::TSTAMP }>, bool) = self.read(&mut *reader)?; + let (_, more): (ZExtZBufHeader<{ ext::Timestamp::ID }>, bool) = self.read(&mut *reader)?; let timestamp: uhlc::Timestamp = codec.read(&mut *reader)?; - Ok((ext::Timestamp { timestamp }, more)) + Ok((ext::TimestampType { timestamp }, more)) } } diff --git a/commons/zenoh-codec/src/network/oam.rs b/commons/zenoh-codec/src/network/oam.rs index 44965168e8..fa8b0578a9 100644 --- a/commons/zenoh-codec/src/network/oam.rs +++ b/commons/zenoh-codec/src/network/oam.rs @@ -46,7 +46,7 @@ where } } let mut n_exts = - ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); if n_exts != 0 { header |= flag::Z; } @@ -56,7 +56,7 @@ where self.write(&mut *writer, x.id)?; // Extensions - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; } @@ -108,21 +108,21 @@ where let id: OamId = self.codec.read(&mut *reader)?; // Extensions - let mut ext_qos = ext::QoS::default(); + let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - ext::QOS => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = q; has_ext = ext; } - ext::TSTAMP => { - let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext::Timestamp::ID => { + let (t, ext): (ext::TimestampType, bool) = eodec.read(&mut *reader)?; ext_tstamp = Some(t); has_ext = ext; } diff --git a/commons/zenoh-codec/src/network/pull.rs b/commons/zenoh-codec/src/network/pull.rs index c375679cdd..f81621f02e 100644 --- a/commons/zenoh-codec/src/network/pull.rs +++ b/commons/zenoh-codec/src/network/pull.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown}, + common::{iext, imsg, ZExtUnknown}, network::{ id, pull::{ext, flag}, @@ -36,7 +36,7 @@ where // Header let mut header = id::PULL; let mut n_exts = - ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); if n_exts != 0 { header |= flag::Z; } @@ -46,7 +46,7 @@ where self.write(&mut *writer, x.id)?; // Extensions - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; } @@ -87,21 +87,21 @@ where let id: PullId = self.codec.read(&mut *reader)?; // Extensions - let mut ext_qos = ext::QoS::default(); + let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - ext::QOS => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = q; has_ext = ext; } - ext::TSTAMP => { - let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext::Timestamp::ID => { + let (t, ext): (ext::TimestampType, bool) = eodec.read(&mut *reader)?; ext_tstamp = Some(t); has_ext = ext; } diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index ed44c0896f..4747f39c33 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnit, ZExtUnknown}, + common::{iext, imsg, ZExtUnknown}, core::WireExpr, network::{ id, @@ -26,28 +26,28 @@ use zenoh_protocol::{ }, }; -impl WCodec<(ext::Destination, bool), &mut W> for Zenoh080 +impl WCodec<(ext::DestinationType, bool), &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: (ext::Destination, bool)) -> Self::Output { + fn write(self, writer: &mut W, x: (ext::DestinationType, bool)) -> Self::Output { let (_, more) = x; - let ext: ZExtUnit<{ ext::DST }> = ZExtUnit::new(); + let ext = ext::Destination::new(); self.write(&mut *writer, (&ext, more)) } } -impl RCodec<(ext::Destination, bool), &mut R> for Zenoh080Header +impl RCodec<(ext::DestinationType, bool), &mut R> for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ext::Destination, bool), Self::Error> { - let (_, more): (ZExtUnit<{ ext::DST }>, bool) = self.read(&mut *reader)?; - Ok((ext::Destination::Queryables, more)) + fn read(self, reader: &mut R) -> Result<(ext::DestinationType, bool), Self::Error> { + let (_, more): (ext::Destination, bool) = self.read(&mut *reader)?; + Ok((ext::DestinationType::Queryables, more)) } } @@ -60,8 +60,8 @@ where fn write(self, writer: &mut W, x: &Push) -> Self::Output { // Header let mut header = id::PUSH; - let mut n_exts = ((x.ext_qos != ext::QoS::default()) as u8) - + (x.ext_tstamp.is_some() as u8 + (x.ext_dst != ext::Destination::default()) as u8); + let mut n_exts = ((x.ext_qos != ext::QoSType::default()) as u8) + + (x.ext_tstamp.is_some() as u8 + (x.ext_dst != ext::DestinationType::default()) as u8); if n_exts != 0 { header |= flag::Z; } @@ -77,7 +77,7 @@ where self.write(&mut *writer, &x.wire_expr)?; // Extensions - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; } @@ -85,7 +85,7 @@ where n_exts -= 1; self.write(&mut *writer, (ts, n_exts != 0))?; } - if x.ext_dst != ext::Destination::default() { + if x.ext_dst != ext::DestinationType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_dst, n_exts != 0))?; } @@ -131,27 +131,27 @@ where }; // Extensions - let mut ext_qos = ext::QoS::default(); + let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; - let mut ext_dst = ext::Destination::default(); + let mut ext_dst = ext::DestinationType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - ext::QOS => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = q; has_ext = ext; } - ext::TSTAMP => { - let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext::Timestamp::ID => { + let (t, ext): (ext::TimestampType, bool) = eodec.read(&mut *reader)?; ext_tstamp = Some(t); has_ext = ext; } - ext::DST => { - let (d, ext): (ext::Destination, bool) = eodec.read(&mut *reader)?; + ext::Destination::ID => { + let (d, ext): (ext::DestinationType, bool) = eodec.read(&mut *reader)?; ext_dst = d; has_ext = ext; } diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 3f668d8225..5a716f214f 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnit, ZExtUnknown, ZExtZ64}, + common::{iext, imsg, ZExtUnknown}, core::WireExpr, network::{ id, @@ -27,66 +27,66 @@ use zenoh_protocol::{ }; // Destination -impl WCodec<(ext::Destination, bool), &mut W> for Zenoh080 +impl WCodec<(ext::DestinationType, bool), &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: (ext::Destination, bool)) -> Self::Output { + fn write(self, writer: &mut W, x: (ext::DestinationType, bool)) -> Self::Output { let (_, more) = x; - let ext: ZExtUnit<{ ext::DST }> = ZExtUnit::new(); + let ext = ext::Destination::new(); self.write(&mut *writer, (&ext, more)) } } -impl RCodec<(ext::Destination, bool), &mut R> for Zenoh080Header +impl RCodec<(ext::DestinationType, bool), &mut R> for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ext::Destination, bool), Self::Error> { - let (_, more): (ZExtUnit<{ ext::DST }>, bool) = self.read(&mut *reader)?; - Ok((ext::Destination::Subscribers, more)) + fn read(self, reader: &mut R) -> Result<(ext::DestinationType, bool), Self::Error> { + let (_, more): (ext::Destination, bool) = self.read(&mut *reader)?; + Ok((ext::DestinationType::Subscribers, more)) } } // Target -impl WCodec<(&ext::Target, bool), &mut W> for Zenoh080 +impl WCodec<(&ext::TargetType, bool), &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: (&ext::Target, bool)) -> Self::Output { + fn write(self, writer: &mut W, x: (&ext::TargetType, bool)) -> Self::Output { let (rt, more) = x; let v = match rt { - ext::Target::BestMatching => 0, - ext::Target::All => 1, - ext::Target::AllComplete => 2, + ext::TargetType::BestMatching => 0, + ext::TargetType::All => 1, + ext::TargetType::AllComplete => 2, #[cfg(feature = "complete_n")] - ext::Target::Complete(n) => 3 + *n, + ext::TargetType::Complete(n) => 3 + *n, }; - let ext: ZExtZ64<{ ext::TARGET }> = ZExtZ64::new(v); + let ext = ext::Target::new(v); self.write(&mut *writer, (&ext, more)) } } -impl RCodec<(ext::Target, bool), &mut R> for Zenoh080Header +impl RCodec<(ext::TargetType, bool), &mut R> for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ext::Target, bool), Self::Error> { - let (ext, more): (ZExtZ64<{ ext::TARGET }>, bool) = self.read(&mut *reader)?; + fn read(self, reader: &mut R) -> Result<(ext::TargetType, bool), Self::Error> { + let (ext, more): (ext::Target, bool) = self.read(&mut *reader)?; let rt = match ext.value { - 0 => ext::Target::BestMatching, - 1 => ext::Target::All, - 2 => ext::Target::AllComplete, + 0 => ext::TargetType::BestMatching, + 1 => ext::TargetType::All, + 2 => ext::TargetType::AllComplete, #[cfg(feature = "complete_n")] - n => ext::Target::Complete(n - 3), + n => ext::TargetType::Complete(n - 3), _ => return Err(DidntRead), }; Ok((rt, more)) @@ -102,10 +102,10 @@ where fn write(self, writer: &mut W, x: &Request) -> Self::Output { // Header let mut header = id::REQUEST; - let mut n_exts = ((x.ext_qos != ext::QoS::default()) as u8) + let mut n_exts = ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8) - + ((x.ext_dst != ext::Destination::default()) as u8) - + ((x.ext_target != ext::Target::default()) as u8); + + ((x.ext_dst != ext::DestinationType::default()) as u8) + + ((x.ext_target != ext::TargetType::default()) as u8); if n_exts != 0 { header |= flag::Z; } @@ -122,7 +122,7 @@ where self.write(&mut *writer, &x.wire_expr)?; // Extensions - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; } @@ -130,11 +130,11 @@ where n_exts -= 1; self.write(&mut *writer, (ts, n_exts != 0))?; } - if x.ext_dst != ext::Destination::default() { + if x.ext_dst != ext::DestinationType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_dst, n_exts != 0))?; } - if x.ext_target != ext::Target::default() { + if x.ext_target != ext::TargetType::default() { n_exts -= 1; self.write(&mut *writer, (&x.ext_target, n_exts != 0))?; } @@ -181,33 +181,33 @@ where }; // Extensions - let mut ext_qos = ext::QoS::default(); + let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; - let mut ext_dst = ext::Destination::default(); - let mut ext_target = ext::Target::default(); + let mut ext_dst = ext::DestinationType::default(); + let mut ext_target = ext::TargetType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - ext::QOS => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = q; has_ext = ext; } - ext::TSTAMP => { - let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext::Timestamp::ID => { + let (t, ext): (ext::TimestampType, bool) = eodec.read(&mut *reader)?; ext_tstamp = Some(t); has_ext = ext; } - ext::DST => { - let (d, ext): (ext::Destination, bool) = eodec.read(&mut *reader)?; + ext::Destination::ID => { + let (d, ext): (ext::DestinationType, bool) = eodec.read(&mut *reader)?; ext_dst = d; has_ext = ext; } - ext::TARGET => { - let (rt, ext): (ext::Target, bool) = eodec.read(&mut *reader)?; + ext::Target::ID => { + let (rt, ext): (ext::TargetType, bool) = eodec.read(&mut *reader)?; ext_target = rt; has_ext = ext; } diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs index e065d73950..09cfa1e433 100644 --- a/commons/zenoh-codec/src/network/response.rs +++ b/commons/zenoh-codec/src/network/response.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown}, + common::{iext, imsg, ZExtUnknown}, core::WireExpr, network::{ id, @@ -37,7 +37,7 @@ where // Header let mut header = id::RESPONSE; let mut n_exts = - ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); if n_exts != 0 { header |= flag::Z; } @@ -54,7 +54,7 @@ where self.write(&mut *writer, &x.wire_expr)?; // Extensions - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; } @@ -105,21 +105,21 @@ where }; // Extensions - let mut ext_qos = ext::QoS::default(); + let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - ext::QOS => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = q; has_ext = ext; } - ext::TSTAMP => { - let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext::Timestamp::ID => { + let (t, ext): (ext::TimestampType, bool) = eodec.read(&mut *reader)?; ext_tstamp = Some(t); has_ext = ext; } @@ -156,7 +156,7 @@ where // Header let mut header = id::RESPONSE_FINAL; let mut n_exts = - ((x.ext_qos != ext::QoS::default()) as u8) + (x.ext_tstamp.is_some() as u8); + ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); if n_exts != 0 { header |= flag::Z; } @@ -166,7 +166,7 @@ where self.write(&mut *writer, x.rid)?; // Extensions - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; } @@ -207,21 +207,21 @@ where let rid: RequestId = self.codec.read(&mut *reader)?; // Extensions - let mut ext_qos = ext::QoS::default(); + let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - ext::QOS => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = q; has_ext = ext; } - ext::TSTAMP => { - let (t, ext): (ext::Timestamp, bool) = eodec.read(&mut *reader)?; + ext::Timestamp::ID => { + let (t, ext): (ext::TimestampType, bool) = eodec.read(&mut *reader)?; ext_tstamp = Some(t); has_ext = ext; } diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index 52097c781a..2a433a1cbb 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown}, + common::{iext, imsg, ZExtUnknown}, core::Reliability, transport::{ fragment::{ext, flag, Fragment, FragmentHeader, TransportSn}, @@ -41,7 +41,7 @@ where if x.more { header |= flag::M; } - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { header |= flag::Z; } self.write(&mut *writer, header)?; @@ -50,7 +50,7 @@ where self.write(&mut *writer, x.sn)?; // Extensions - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { self.write(&mut *writer, (x.ext_qos, false))?; } @@ -90,15 +90,15 @@ where let sn: TransportSn = self.codec.read(&mut *reader)?; // Extensions - let mut ext_qos = ext::QoS::default(); + let mut ext_qos = ext::QoSType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - ext::QOS => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = q; has_ext = ext; } diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 64f48f0ae2..85b39c4d0e 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -18,7 +18,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown, ZExtZ64}, + common::{iext, imsg, ZExtUnknown, ZExtZ64}, core::Reliability, transport::{ frame::{ext, flag, Frame, FrameHeader}, @@ -28,7 +28,7 @@ use zenoh_protocol::{ }; // Extensions: QoS -crate::impl_zextz64!(ext::QoS, ext::QOS); +crate::impl_zextz64!(ext::QoSType, ext::QoS::ID); // FrameHeader impl WCodec<&FrameHeader, &mut W> for Zenoh080 @@ -43,7 +43,7 @@ where if let Reliability::Reliable = x.reliability { header |= flag::R; } - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { header |= flag::Z; } self.write(&mut *writer, header)?; @@ -52,7 +52,7 @@ where self.write(&mut *writer, x.sn)?; // Extensions - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { self.write(&mut *writer, (x.ext_qos, false))?; } @@ -91,15 +91,15 @@ where let sn: TransportSn = self.codec.read(&mut *reader)?; // Extensions - let mut qos = ext::QoS::default(); + let mut qos = ext::QoSType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - ext::QOS => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; qos = q; has_ext = ext; } diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index 11a3447691..dbaf68c8ef 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -18,7 +18,7 @@ use zenoh_buffers::{ ZSlice, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown}, + common::{iext, imsg, ZExtUnknown}, core::{Resolution, WhatAmI, ZenohId}, transport::{ id, @@ -147,7 +147,7 @@ where while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { + match iext::eid(ext) { ext::QoS::ID => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; ext_qos = Some(q); @@ -315,7 +315,7 @@ where while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { + match iext::eid(ext) { ext::QoS::ID => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; ext_qos = Some(q); diff --git a/commons/zenoh-codec/src/transport/oam.rs b/commons/zenoh-codec/src/transport/oam.rs index 3bc839f21b..c21ba86c6e 100644 --- a/commons/zenoh-codec/src/transport/oam.rs +++ b/commons/zenoh-codec/src/transport/oam.rs @@ -45,7 +45,7 @@ where header |= iext::ENC_ZBUF; } } - let mut n_exts = (x.ext_qos != ext::QoS::default()) as u8; + let mut n_exts = (x.ext_qos != ext::QoSType::default()) as u8; if n_exts != 0 { header |= flag::Z; } @@ -55,7 +55,7 @@ where self.write(&mut *writer, x.id)?; // Extensions - if x.ext_qos != ext::QoS::default() { + if x.ext_qos != ext::QoSType::default() { n_exts -= 1; self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; } @@ -103,15 +103,15 @@ where let id: OamId = self.codec.read(&mut *reader)?; // Extensions - let mut ext_qos = ext::QoS::default(); + let mut ext_qos = ext::QoSType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { - ext::QOS => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = q; has_ext = ext; } diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index c4a861cbfb..8806afd2f9 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ ZSlice, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown}, + common::{iext, imsg, ZExtUnknown}, transport::{ id, open::{ext, flag, OpenAck, OpenSyn}, @@ -124,7 +124,7 @@ where while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { + match iext::eid(ext) { ext::QoS::ID => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; ext_qos = Some(q); @@ -261,7 +261,7 @@ where while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); - match imsg::mid(ext) { + match iext::eid(ext) { ext::QoS::ID => { let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; ext_qos = Some(q); diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 6d1c4ab219..e71eb082bf 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -325,7 +325,6 @@ fn codec_extension() { let codec = Zenoh080::new(); for _ in 0..NUM_ITER { let more: bool = thread_rng().gen(); - let x: (&$ext, bool) = (&<$ext>::rand(), more); $buff.clear(); @@ -358,7 +357,7 @@ fn codec_extension() { }; } - run_extension!(ZExtUnit<0>); + run_extension!(ZExtUnit::<0>); run_extension!(ZExtZ64<1>); run_extension!(ZExtZBuf<2>); run_extension!(ZExtZBuf<3>); diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index af557254f2..a5701a1b24 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -33,13 +33,12 @@ use zenoh_buffers::ZBuf; /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|ENC| ID | +/// |Z|ENC|M| ID | /// +-+-+-+---------+ /// % length % -- If ENC == u64 || ENC == ZBuf /// +---------------+ /// ~ [u8] ~ -- If ENC == ZBuf /// +---------------+ -/// ``` /// /// Encoding: /// - 0b00: Unit @@ -49,17 +48,46 @@ use zenoh_buffers::ZBuf; /// /// (*) If the zenoh extension is not understood, then it SHOULD NOT be dropped and it /// SHOULD be forwarded to the next hops. +/// ``` /// +#[repr(u8)] +pub enum ZExtEnc { + Unit = 0b00 << 5, + Z64 = 0b01 << 5, + ZBuf = 0b10 << 5, +} + pub mod iext { - pub const ID_BITS: u8 = 5; - pub const ID_MASK: u8 = !(u8::MAX << ID_BITS); + use super::ZExtEnc; - pub const ENC_UNIT: u8 = 0b00 << ID_BITS; - pub const ENC_Z64: u8 = 0b01 << ID_BITS; - pub const ENC_ZBUF: u8 = 0b10 << ID_BITS; - pub const ENC_MASK: u8 = 0b11 << ID_BITS; + pub const ID_BITS: u8 = 4; + pub const ID_MASK: u8 = !(u8::MAX << ID_BITS); + pub const FLAG_M: u8 = 1 << 4; + pub const ENC_UNIT: u8 = ZExtEnc::Unit as u8; + pub const ENC_Z64: u8 = ZExtEnc::Z64 as u8; + pub const ENC_ZBUF: u8 = ZExtEnc::ZBuf as u8; + pub const ENC_MASK: u8 = 0b11 << 5; pub const FLAG_Z: u8 = 1 << 7; + + pub const fn eid(header: u8) -> u8 { + header & !FLAG_Z + } + + pub(super) const fn id(id: u8, mandatory: bool, encoding: ZExtEnc) -> u8 { + let mut id = id & ID_MASK; + if mandatory { + id |= FLAG_M; + } else { + id &= !FLAG_M; + } + id |= encoding as u8; + id + } + + pub(super) const fn is_mandatory(id: u8) -> bool { + crate::common::imsg::has_flag(id, FLAG_M) + } } pub struct DidntConvert; @@ -74,6 +102,14 @@ impl ZExtUnit<{ ID }> { Self } + pub const fn id(mandatory: bool) -> u8 { + iext::id(ID, mandatory, ZExtEnc::Unit) + } + + pub const fn is_mandatory(&self) -> bool { + iext::is_mandatory(ID) + } + pub const fn transmute(self) -> ZExtUnit<{ DI }> { ZExtUnit::new() } @@ -110,6 +146,14 @@ impl ZExtZ64<{ ID }> { Self { value } } + pub const fn id(mandatory: bool) -> u8 { + iext::id(ID, mandatory, ZExtEnc::Z64) + } + + pub const fn is_mandatory(&self) -> bool { + iext::is_mandatory(ID) + } + pub const fn transmute(self) -> ZExtZ64<{ DI }> { ZExtZ64::new(self.value) } @@ -150,6 +194,14 @@ impl ZExtZBuf<{ ID }> { Self { value } } + pub const fn id(mandatory: bool) -> u8 { + iext::id(ID, mandatory, ZExtEnc::ZBuf) + } + + pub const fn is_mandatory(&self) -> bool { + iext::is_mandatory(ID) + } + pub fn transmute(self) -> ZExtZBuf<{ DI }> { ZExtZBuf::new(self.value) } @@ -189,12 +241,14 @@ impl ZExtZBufHeader<{ ID }> { pub const fn new(len: usize) -> Self { Self { len } } -} -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ZExtUnknown { - pub id: u8, - pub body: ZExtBody, + pub const fn id(mandatory: bool) -> u8 { + iext::id(ID, mandatory, ZExtEnc::ZBuf) + } + + pub const fn is_mandatory(&self) -> bool { + iext::is_mandatory(ID) + } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -220,15 +274,36 @@ impl ZExtBody { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ZExtUnknown { + pub id: u8, + pub body: ZExtBody, +} + impl ZExtUnknown { + pub const fn new(id: u8, mandatory: bool, body: ZExtBody) -> Self { + let enc = match &body { + ZExtBody::Unit => ZExtEnc::Unit, + ZExtBody::Z64(_) => ZExtEnc::Z64, + ZExtBody::ZBuf(_) => ZExtEnc::ZBuf, + }; + let id = iext::id(id, mandatory, enc); + Self { id, body } + } + + pub const fn is_mandatory(&self) -> bool { + iext::is_mandatory(self.id) + } + #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; let mut rng = rand::thread_rng(); let id: u8 = rng.gen_range(0x00..=iext::ID_MASK); + let mandatory: bool = rng.gen_bool(0.5); let body = ZExtBody::rand(); - Self { id, body } + Self::new(id, mandatory, body) } } @@ -258,3 +333,26 @@ impl From> for ZExtUnknown { } } } + +// Macros + +#[macro_export] +macro_rules! zextunit { + ($id:expr, $m:expr) => { + ZExtUnit<{ ZExtUnit::<$id>::id($m) }> + } +} + +#[macro_export] +macro_rules! zextz64 { + ($id:expr, $m:expr) => { + ZExtZ64<{ ZExtZ64::<$id>::id($m) }> + } +} + +#[macro_export] +macro_rules! zextzbuf { + ($id:expr, $m:expr) => { + ZExtZBuf<{ ZExtZBuf::<$id>::id($m) }> + } +} diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index 1bc639fe99..5c69be15cc 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -15,6 +15,7 @@ use crate::{ common::{imsg, ZExtZ64}, core::{ExprId, Reliability, WireExpr}, network::Mapping, + zextz64, }; pub use keyexpr::*; pub use queryable::*; @@ -43,17 +44,17 @@ pub mod flag { /// #[derive(Debug, Clone, PartialEq, Eq)] pub struct Declare { - pub ext_qos: ext::QoS, - pub ext_tstamp: Option, + pub ext_qos: ext::QoSType, + pub ext_tstamp: Option, pub body: DeclareBody, } pub mod ext { - pub const QOS: u8 = crate::network::ext::QOS; - pub const TSTAMP: u8 = crate::network::ext::TSTAMP; - pub type QoS = crate::network::ext::QoS; + pub type QoSType = crate::network::ext::QoSType; + pub type Timestamp = crate::network::ext::Timestamp; + pub type TimestampType = crate::network::ext::TimestampType; } pub mod id { @@ -111,8 +112,8 @@ impl Declare { let mut rng = rand::thread_rng(); let body = DeclareBody::rand(); - let ext_qos = ext::QoS::rand(); - let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + let ext_qos = ext::QoSType::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); Self { body, @@ -270,7 +271,7 @@ pub mod subscriber { pub mod ext { use super::*; - pub const INFO: u8 = 0x01; + pub type Info = zextz64!(0x01, false); /// # The subscription mode. /// @@ -305,8 +306,8 @@ pub mod subscriber { } } - impl From> for SubscriberInfo { - fn from(ext: ZExtZ64<{ INFO }>) -> Self { + impl From for SubscriberInfo { + fn from(ext: Info) -> Self { let reliability = if imsg::has_option(ext.value, SubscriberInfo::R) { Reliability::Reliable } else { @@ -321,7 +322,7 @@ pub mod subscriber { } } - impl From for ZExtZ64<{ INFO }> { + impl From for Info { fn from(ext: SubscriberInfo) -> Self { let mut v: u64 = 0; if ext.reliability == Reliability::Reliable { @@ -330,7 +331,7 @@ pub mod subscriber { if ext.mode == Mode::Pull { v |= SubscriberInfo::P; } - ZExtZ64::new(v) + Info::new(v) } } } @@ -434,7 +435,7 @@ pub mod queryable { pub mod ext { use super::*; - pub const INFO: u8 = 0x01; + pub type Info = zextz64!(0x01, false); /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ @@ -462,8 +463,8 @@ pub mod queryable { } } - impl From> for QueryableInfo { - fn from(ext: ZExtZ64<{ INFO }>) -> Self { + impl From for QueryableInfo { + fn from(ext: Info) -> Self { let complete = ext.value as u8; let distance = (ext.value >> 8) as u32; @@ -471,11 +472,11 @@ pub mod queryable { } } - impl From for ZExtZ64<{ INFO }> { + impl From for Info { fn from(ext: QueryableInfo) -> Self { let mut v: u64 = ext.complete as u64; v |= (ext.distance as u64) << 8; - ZExtZ64::new(v) + Info::new(v) } } } diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index da825bed89..e92305010d 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -143,13 +143,14 @@ impl From for NetworkMessage { // Extensions pub mod ext { use crate::{ - common::{imsg, ZExtZ64}, + common::{imsg, ZExtZ64, ZExtZBuf}, core::{CongestionControl, Priority}, + zextz64, zextzbuf, }; use core::fmt; - pub const QOS: u8 = 0x01; - pub const TSTAMP: u8 = 0x02; + pub type QoS = zextz64!(0x1, false); + pub type Timestamp = zextzbuf!(0x2, false); /// ```text /// 7 6 5 4 3 2 1 0 @@ -166,11 +167,11 @@ pub mod ext { /// ``` #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq)] - pub struct QoS { + pub struct QoSType { inner: u8, } - impl QoS { + impl QoSType { const P_MASK: u8 = 0b00000111; const D_FLAG: u8 = 0b00001000; const E_FLAG: u8 = 0b00010000; @@ -215,27 +216,27 @@ pub mod ext { } } - impl Default for QoS { + impl Default for QoSType { fn default() -> Self { Self::new(Priority::default(), CongestionControl::default(), false) } } - impl From> for QoS { - fn from(ext: ZExtZ64<{ QOS }>) -> Self { + impl From for QoSType { + fn from(ext: QoS) -> Self { Self { inner: ext.value as u8, } } } - impl From for ZExtZ64<{ QOS }> { - fn from(ext: QoS) -> Self { - ZExtZ64::new(ext.inner as u64) + impl From for QoS { + fn from(ext: QoSType) -> Self { + QoS::new(ext.inner as u64) } } - impl fmt::Debug for QoS { + impl fmt::Debug for QoSType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("QoS") .field("priority", &self.priority()) @@ -254,11 +255,11 @@ pub mod ext { /// +---------------+ /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub struct Timestamp { + pub struct TimestampType { pub timestamp: uhlc::Timestamp, } - impl Timestamp { + impl TimestampType { #[cfg(feature = "test")] pub fn rand() -> Self { use crate::core::ZenohId; diff --git a/commons/zenoh-protocol/src/network/oam.rs b/commons/zenoh-protocol/src/network/oam.rs index 8dfff1a980..56db363661 100644 --- a/commons/zenoh-protocol/src/network/oam.rs +++ b/commons/zenoh-protocol/src/network/oam.rs @@ -29,12 +29,10 @@ pub mod flag { /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|ENC| OAM | +/// |X|ENC| OAM | /// +-+-+-+---------+ /// ~ id:z16 ~ /// +---------------+ -/// ~ [oam_exts] ~ -/// +---------------+ /// % length % -- If ENC == u64 || ENC == ZBuf /// +---------------+ /// ~ [u8] ~ -- If ENC == ZBuf @@ -51,16 +49,16 @@ pub mod flag { pub struct Oam { pub id: OamId, pub body: ZExtBody, - pub ext_qos: ext::QoS, - pub ext_tstamp: Option, + pub ext_qos: ext::QoSType, + pub ext_tstamp: Option, } pub mod ext { - pub const QOS: u8 = crate::network::ext::QOS; - pub const TSTAMP: u8 = crate::network::ext::TSTAMP; - pub type QoS = crate::network::ext::QoS; + pub type QoSType = crate::network::ext::QoSType; + pub type Timestamp = crate::network::ext::Timestamp; + pub type TimestampType = crate::network::ext::TimestampType; } impl Oam { @@ -71,8 +69,8 @@ impl Oam { let id: OamId = rng.gen(); let body = ZExtBody::rand(); - let ext_qos = ext::QoS::rand(); - let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + let ext_qos = ext::QoSType::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); Self { id, diff --git a/commons/zenoh-protocol/src/network/pull.rs b/commons/zenoh-protocol/src/network/pull.rs index f23383b6ab..68655ccd73 100644 --- a/commons/zenoh-protocol/src/network/pull.rs +++ b/commons/zenoh-protocol/src/network/pull.rs @@ -39,8 +39,8 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Pull { pub id: PullId, - pub ext_qos: ext::QoS, - pub ext_tstamp: Option, + pub ext_qos: ext::QoSType, + pub ext_tstamp: Option, } impl Pull { @@ -52,8 +52,8 @@ impl Pull { let mut rng = rand::thread_rng(); let id: PullId = rng.gen(); - let ext_qos = ext::QoS::rand(); - let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + let ext_qos = ext::QoSType::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); Self { id, @@ -64,9 +64,9 @@ impl Pull { } pub mod ext { - pub const QOS: u8 = crate::network::ext::QOS; - pub const TSTAMP: u8 = crate::network::ext::TSTAMP; - pub type QoS = crate::network::ext::QoS; + pub type QoSType = crate::network::ext::QoSType; + pub type Timestamp = crate::network::ext::Timestamp; + pub type TimestampType = crate::network::ext::TimestampType; } diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs index f965527cf7..2a9de7c0d2 100644 --- a/commons/zenoh-protocol/src/network/push.rs +++ b/commons/zenoh-protocol/src/network/push.rs @@ -43,36 +43,39 @@ pub struct Push { pub wire_expr: WireExpr<'static>, pub mapping: Mapping, pub payload: u8, // @TODO - pub ext_qos: ext::QoS, - pub ext_tstamp: Option, - pub ext_dst: ext::Destination, + pub ext_qos: ext::QoSType, + pub ext_tstamp: Option, + pub ext_dst: ext::DestinationType, } pub mod ext { - pub const QOS: u8 = crate::network::ext::QOS; - pub const TSTAMP: u8 = crate::network::ext::TSTAMP; - pub const DST: u8 = 0x03; + use crate::{common::ZExtUnit, zextunit}; pub type QoS = crate::network::ext::QoS; + pub type QoSType = crate::network::ext::QoSType; + pub type Timestamp = crate::network::ext::Timestamp; + pub type TimestampType = crate::network::ext::TimestampType; + + pub type Destination = zextunit!(0x03, true); #[repr(u8)] #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] - pub enum Destination { + pub enum DestinationType { #[default] Subscribers = 0x00, Queryables = 0x01, } - impl Destination { + impl DestinationType { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; let mut rng = rand::thread_rng(); match rng.gen_range(0..2) { - 0 => Destination::Subscribers, - 1 => Destination::Queryables, + 0 => DestinationType::Subscribers, + 1 => DestinationType::Queryables, _ => unreachable!(), } } @@ -89,9 +92,9 @@ impl Push { let mapping = Mapping::rand(); // let payload = ZenohMessage::rand(); let payload: u8 = rng.gen(); // @TODO - let ext_qos = ext::QoS::rand(); - let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); - let ext_dst = ext::Destination::rand(); + let ext_qos = ext::QoSType::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); + let ext_dst = ext::DestinationType::rand(); Self { wire_expr, diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index 54a88ce32d..0ec13a05f6 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -56,54 +56,59 @@ pub struct Request { pub wire_expr: WireExpr<'static>, pub mapping: Mapping, pub payload: u8, // @TODO - pub ext_qos: ext::QoS, - pub ext_tstamp: Option, - pub ext_dst: ext::Destination, - pub ext_target: ext::Target, + pub ext_qos: ext::QoSType, + pub ext_tstamp: Option, + pub ext_dst: ext::DestinationType, + pub ext_target: ext::TargetType, } pub mod ext { - pub const QOS: u8 = crate::network::ext::QOS; - pub const TSTAMP: u8 = crate::network::ext::TSTAMP; - pub const DST: u8 = 0x03; - pub const TARGET: u8 = 0x04; + use crate::{ + common::{ZExtUnit, ZExtZ64}, + zextunit, zextz64, + }; pub type QoS = crate::network::ext::QoS; + pub type QoSType = crate::network::ext::QoSType; + pub type Timestamp = crate::network::ext::Timestamp; + pub type TimestampType = crate::network::ext::TimestampType; + + pub type Destination = zextunit!(0x03, true); #[repr(u8)] #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] - pub enum Destination { + pub enum DestinationType { Subscribers = 0x00, #[default] Queryables = 0x01, } - impl Destination { + impl DestinationType { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; let mut rng = rand::thread_rng(); match rng.gen_range(0..2) { - 0 => Destination::Subscribers, - 1 => Destination::Queryables, + 0 => DestinationType::Subscribers, + 1 => DestinationType::Queryables, _ => unreachable!(), } } } + pub type Target = zextz64!(0x4, true); + /// - Target (0x03) /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ - /// |Z|ENC| ID | - /// +-+-+-+---------+ /// % target % /// +---------------+ /// /// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] - pub enum Target { + pub enum TargetType { #[default] BestMatching, All, @@ -112,18 +117,18 @@ pub mod ext { Complete(u64), } - impl Target { + impl TargetType { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::prelude::SliceRandom; let mut rng = rand::thread_rng(); *[ - Target::All, - Target::AllComplete, - Target::BestMatching, + TargetType::All, + TargetType::AllComplete, + TargetType::BestMatching, #[cfg(feature = "complete_n")] - Target::Complete(rng.gen()), + TargetType::Complete(rng.gen()), ] .choose(&mut rng) .unwrap() @@ -142,10 +147,10 @@ impl Request { let id: RequestId = rng.gen(); // let payload = ZenohMessage::rand(); let payload: u8 = rng.gen(); // @TODO - let ext_qos = ext::QoS::rand(); - let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); - let ext_dst = ext::Destination::rand(); - let ext_target = ext::Target::rand(); + let ext_qos = ext::QoSType::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); + let ext_dst = ext::DestinationType::rand(); + let ext_target = ext::TargetType::rand(); Self { wire_expr, diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index e3509803bc..3f5237b874 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -52,16 +52,16 @@ pub struct Response { pub wire_expr: WireExpr<'static>, pub mapping: Mapping, pub payload: u8, // @TODO - pub ext_qos: ext::QoS, - pub ext_tstamp: Option, + pub ext_qos: ext::QoSType, + pub ext_tstamp: Option, } pub mod ext { - pub const QOS: u8 = crate::network::ext::QOS; - pub const TSTAMP: u8 = crate::network::ext::TSTAMP; - pub type QoS = crate::network::ext::QoS; + pub type QoSType = crate::network::ext::QoSType; + pub type Timestamp = crate::network::ext::Timestamp; + pub type TimestampType = crate::network::ext::TimestampType; } impl Response { @@ -75,8 +75,8 @@ impl Response { let mapping = Mapping::rand(); // let payload = ZenohMessage::rand(); let payload: u8 = rng.gen(); // @TODO - let ext_qos = ext::QoS::rand(); - let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + let ext_qos = ext::QoSType::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); Self { rid, @@ -111,8 +111,8 @@ impl Response { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ResponseFinal { pub rid: RequestId, - pub ext_qos: ext::QoS, - pub ext_tstamp: Option, + pub ext_qos: ext::QoSType, + pub ext_tstamp: Option, } impl ResponseFinal { @@ -122,8 +122,8 @@ impl ResponseFinal { let mut rng = rand::thread_rng(); let rid: RequestId = rng.gen(); - let ext_qos = ext::QoS::rand(); - let ext_tstamp = rng.gen_bool(0.5).then(ext::Timestamp::rand); + let ext_qos = ext::QoSType::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); Self { rid, diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs index 7e3a0bc2ff..55f6cd8a39 100644 --- a/commons/zenoh-protocol/src/transport/fragment.rs +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -73,14 +73,14 @@ pub struct Fragment { pub more: bool, pub sn: TransportSn, pub payload: ZSlice, - pub ext_qos: ext::QoS, + pub ext_qos: ext::QoSType, } // Extensions pub mod ext { - pub const QOS: u8 = crate::transport::frame::ext::QOS; - pub type QoS = crate::transport::frame::ext::QoS; + + pub type QoSType = crate::transport::frame::ext::QoSType; } impl Fragment { @@ -94,7 +94,7 @@ impl Fragment { let more = rng.gen_bool(0.5); let sn: TransportSn = rng.gen(); let payload = ZSlice::rand(rng.gen_range(8..128)); - let ext_qos = ext::QoS::rand(); + let ext_qos = ext::QoSType::rand(); Fragment { reliability, @@ -112,7 +112,7 @@ pub struct FragmentHeader { pub reliability: Reliability, pub more: bool, pub sn: TransportSn, - pub ext_qos: ext::QoS, + pub ext_qos: ext::QoSType, } impl FragmentHeader { @@ -125,7 +125,7 @@ impl FragmentHeader { let reliability = Reliability::rand(); let more = rng.gen_bool(0.5); let sn: TransportSn = rng.gen(); - let ext_qos = ext::QoS::rand(); + let ext_qos = ext::QoSType::rand(); FragmentHeader { reliability, diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 3e855ec8f7..848a4b4dd7 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -71,15 +71,16 @@ pub struct Frame { pub reliability: Reliability, pub sn: TransportSn, pub payload: Vec, - pub ext_qos: ext::QoS, + pub ext_qos: ext::QoSType, } // Extensions pub mod ext { use crate::common::ZExtZ64; use crate::core::Priority; + use crate::zextz64; - pub const QOS: u8 = 0x01; + pub type QoS = zextz64!(0x1, true); /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ @@ -91,11 +92,11 @@ pub mod ext { /// - prio: Priority class #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub struct QoS { + pub struct QoSType { inner: u8, } - impl QoS { + impl QoSType { pub const P_MASK: u8 = 0b00000111; pub const fn new(priority: Priority) -> Self { @@ -118,23 +119,23 @@ pub mod ext { } } - impl Default for QoS { + impl Default for QoSType { fn default() -> Self { Self::new(Priority::default()) } } - impl From> for QoS { - fn from(ext: ZExtZ64<{ QOS }>) -> Self { + impl From for QoSType { + fn from(ext: QoS) -> Self { Self { inner: ext.value as u8, } } } - impl From for ZExtZ64<{ QOS }> { - fn from(ext: QoS) -> Self { - ZExtZ64::new(ext.inner as u64) + impl From for QoS { + fn from(ext: QoSType) -> Self { + QoS::new(ext.inner as u64) } } } @@ -148,19 +149,19 @@ impl Frame { let reliability = Reliability::rand(); let sn: TransportSn = rng.gen(); - let qos = ext::QoS::rand(); + let ext_qos = ext::QoSType::rand(); let mut payload = vec![]; for _ in 0..rng.gen_range(1..4) { let mut m = ZenohMessage::rand(); m.channel.reliability = reliability; - m.channel.priority = qos.priority(); + m.channel.priority = ext_qos.priority(); payload.push(m); } Frame { reliability, sn, - ext_qos: qos, + ext_qos, payload, } } @@ -171,7 +172,7 @@ impl Frame { pub struct FrameHeader { pub reliability: Reliability, pub sn: TransportSn, - pub ext_qos: ext::QoS, + pub ext_qos: ext::QoSType, } impl FrameHeader { @@ -183,12 +184,12 @@ impl FrameHeader { let reliability = Reliability::rand(); let sn: TransportSn = rng.gen(); - let qos = ext::QoS::rand(); + let ext_qos = ext::QoSType::rand(); FrameHeader { reliability, sn, - ext_qos: qos, + ext_qos, } } } diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index c08f518cf0..ddbc4ce986 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -121,28 +121,26 @@ pub struct InitSyn { // Extensions pub mod ext { - use crate::common::{ZExtUnit, ZExtZBuf}; - - pub const QOS: u8 = 0x01; - pub const SHM: u8 = 0x02; - pub const AUTH: u8 = 0x03; - pub const MLINK: u8 = 0x04; + use crate::{ + common::{ZExtUnit, ZExtZBuf}, + zextunit, zextzbuf, + }; /// # QoS extension /// Used to negotiate the use of QoS - pub type QoS = ZExtUnit; + pub type QoS = zextunit!(0x1, false); /// # Shm extension /// Used as challenge for probing shared memory capabilities - pub type Shm = ZExtZBuf; + pub type Shm = zextzbuf!(0x2, false); /// # Auth extension /// Used as challenge for probing authentication rights - pub type Auth = ZExtZBuf; + pub type Auth = zextzbuf!(0x3, false); /// # Multilink extension /// Used as challenge for probing multilink capabilities - pub type MultiLink = ZExtZBuf; + pub type MultiLink = zextzbuf!(0x4, false); } impl InitSyn { diff --git a/commons/zenoh-protocol/src/transport/oam.rs b/commons/zenoh-protocol/src/transport/oam.rs index e2ecd07b17..9240d5ad60 100644 --- a/commons/zenoh-protocol/src/transport/oam.rs +++ b/commons/zenoh-protocol/src/transport/oam.rs @@ -51,13 +51,13 @@ pub mod flag { pub struct Oam { pub id: OamId, pub body: ZExtBody, - pub ext_qos: ext::QoS, + pub ext_qos: ext::QoSType, } pub mod ext { - pub const QOS: u8 = crate::transport::frame::ext::QOS; - pub type QoS = crate::transport::frame::ext::QoS; + + pub type QoSType = crate::transport::frame::ext::QoSType; } impl Oam { @@ -68,7 +68,7 @@ impl Oam { let id: OamId = rng.gen(); let payload = ZExtBody::rand(); - let ext_qos = ext::QoS::rand(); + let ext_qos = ext::QoSType::rand(); Self { id, diff --git a/commons/zenoh-protocol/src/transport/open.rs b/commons/zenoh-protocol/src/transport/open.rs index 4992f1bed4..6c7646cdaa 100644 --- a/commons/zenoh-protocol/src/transport/open.rs +++ b/commons/zenoh-protocol/src/transport/open.rs @@ -85,29 +85,27 @@ pub struct OpenSyn { // Extensions pub mod ext { - use crate::common::{ZExtUnit, ZExtZ64, ZExtZBuf}; - - pub const QOS: u8 = 0x01; - pub const SHM: u8 = 0x02; - pub const AUTH: u8 = 0x03; - pub const MLINK: u8 = 0x04; + use crate::{ + common::{ZExtUnit, ZExtZ64, ZExtZBuf}, + zextunit, zextz64, zextzbuf, + }; /// # QoS extension /// Used to negotiate the use of QoS - pub type QoS = ZExtUnit; + pub type QoS = zextunit!(0x1, false); /// # Shm extension /// Used as challenge for probing shared memory capabilities - pub type Shm = ZExtZ64; + pub type Shm = zextz64!(0x2, false); /// # Auth extension /// Used as challenge for probing authentication rights - pub type Auth = ZExtZBuf; + pub type Auth = zextzbuf!(0x3, false); - /// # MultiLink extension + /// # Multilink extension /// Used as challenge for probing multilink capabilities - pub type MultiLinkSyn = ZExtZBuf; - pub type MultiLinkAck = ZExtUnit; + pub type MultiLinkSyn = zextzbuf!(0x4, false); + pub type MultiLinkAck = zextunit!(0x4, false); } impl OpenSyn { diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 12dccca6d3..a8c0de1a44 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -382,7 +382,7 @@ mod tests { let mut frame = FrameHeader { reliability: zmsg.channel.reliability, sn: 0, - ext_qos: frame::ext::QoS::default(), + ext_qos: frame::ext::QoSType::default(), }; // Serialize with a frame diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 0755d4325f..0b6cb22439 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -186,7 +186,7 @@ impl StageIn { let frame = FrameHeader { reliability: msg.channel.reliability, sn, - ext_qos: frame::ext::QoS::new(priority), + ext_qos: frame::ext::QoSType::new(priority), }; if let WError::NewFrame = e { diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs index fae4e8058c..410400b907 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -37,15 +37,15 @@ use zenoh_config::Config; use zenoh_core::{bail, zerror, Error as ZError, Result as ZResult}; use zenoh_crypto::PseudoRng; use zenoh_protocol::{ - common::ZExtUnknown, + common::{iext, ZExtUnknown}, transport::{init, open}, }; pub(crate) mod id { #[cfg(feature = "auth_pubkey")] - pub(crate) const PUBKEY: u8 = 1; + pub(crate) const PUBKEY: u8 = 0x1; #[cfg(feature = "auth_usrpwd")] - pub(crate) const USRPWD: u8 = 2; + pub(crate) const USRPWD: u8 = 0x2; } #[derive(Debug, Default)] @@ -278,7 +278,9 @@ macro_rules! ztryinto { macro_rules! ztake { ($x:expr, $id:expr) => { - $x.iter().position(|x| x.id == $id).map(|i| $x.remove(i)) + $x.iter() + .position(|x| x.id & iext::ID_MASK == $id) + .map(|i| $x.remove(i)) }; } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs index 1bbbdf8f46..2f28396e5c 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/pubkey.rs @@ -11,10 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -// use super::{ -// AuthenticatedLink, TransportAuthenticator, TransportAuthenticatorTrait, ZNodeAuthenticatorId, -// }; -use crate::establishment::{AcceptFsm, OpenFsm}; +use crate::establishment::{ext::auth::id, AcceptFsm, OpenFsm}; use async_std::sync::{Mutex, RwLock}; use async_trait::async_trait; use rand::Rng; @@ -33,6 +30,16 @@ use zenoh_core::{bail, zasynclock, zasyncread, zerror, Error as ZError, Result a use zenoh_crypto::PseudoRng; use zenoh_protocol::common::{ZExtUnit, ZExtZBuf}; +mod ext { + use super::{id::PUBKEY, ZExtUnit, ZExtZBuf}; + use zenoh_protocol::{zextunit, zextzbuf}; + + pub(super) type InitSyn = zextzbuf!(PUBKEY, false); + pub(super) type InitAck = zextzbuf!(PUBKEY, false); + pub(super) type OpenSyn = zextzbuf!(PUBKEY, false); + pub(super) type OpenAck = zextunit!(PUBKEY, false); +} + // Authenticator #[derive(Debug)] pub struct AuthPubKey { @@ -359,7 +366,7 @@ impl<'a> OpenFsm for AuthPubKeyFsm<'a> { type Error = ZError; type SendInitSynIn = &'a StateOpen; - type SendInitSynOut = Option>; + type SendInitSynOut = Option; async fn send_init_syn( &self, _input: Self::SendInitSynIn, @@ -381,7 +388,7 @@ impl<'a> OpenFsm for AuthPubKeyFsm<'a> { Ok(Some(ZExtZBuf::new(buff.into()))) } - type RecvInitAckIn = (&'a mut StateOpen, Option>); + type RecvInitAckIn = (&'a mut StateOpen, Option); type RecvInitAckOut = (); async fn recv_init_ack( &self, @@ -428,7 +435,7 @@ impl<'a> OpenFsm for AuthPubKeyFsm<'a> { } type SendOpenSynIn = &'a StateOpen; - type SendOpenSynOut = Option>; + type SendOpenSynOut = Option; async fn send_open_syn( &self, state: Self::SendOpenSynIn, @@ -450,7 +457,7 @@ impl<'a> OpenFsm for AuthPubKeyFsm<'a> { Ok(Some(ZExtZBuf::new(buff.into()))) } - type RecvOpenAckIn = (&'a mut StateOpen, Option>); + type RecvOpenAckIn = (&'a mut StateOpen, Option); type RecvOpenAckOut = (); async fn recv_open_ack( &self, @@ -534,7 +541,7 @@ impl PartialEq for StateAccept { impl<'a> AcceptFsm for AuthPubKeyFsm<'a> { type Error = ZError; - type RecvInitSynIn = (&'a mut StateAccept, Option>); + type RecvInitSynIn = (&'a mut StateAccept, Option); type RecvInitSynOut = (); async fn recv_init_syn( &self, @@ -573,7 +580,7 @@ impl<'a> AcceptFsm for AuthPubKeyFsm<'a> { } type SendInitAckIn = &'a StateAccept; - type SendInitAckOut = Option>; + type SendInitAckOut = Option; async fn send_init_ack( &self, state: Self::SendInitAckIn, @@ -596,7 +603,7 @@ impl<'a> AcceptFsm for AuthPubKeyFsm<'a> { Ok(Some(ZExtZBuf::new(buff.into()))) } - type RecvOpenSynIn = (&'a mut StateAccept, Option>); + type RecvOpenSynIn = (&'a mut StateAccept, Option); type RecvOpenSynOut = (); async fn recv_open_syn( &self, @@ -636,7 +643,7 @@ impl<'a> AcceptFsm for AuthPubKeyFsm<'a> { } type SendOpenAckIn = &'a StateAccept; - type SendOpenAckOut = Option>; + type SendOpenAckOut = Option; async fn send_open_ack( &self, _input: Self::SendOpenAckIn, diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index ed7a82ec0a..22bfc4b296 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::establishment::{AcceptFsm, OpenFsm}; +use crate::establishment::{ext::auth::id, AcceptFsm, OpenFsm}; use async_std::{fs, sync::RwLock}; use async_trait::async_trait; use rand::{CryptoRng, Rng}; @@ -27,6 +27,16 @@ use zenoh_core::{bail, zasyncread, zerror, Error as ZError, Result as ZResult}; use zenoh_crypto::hmac; use zenoh_protocol::common::{ZExtUnit, ZExtZ64, ZExtZBuf}; +mod ext { + use super::{id::USRPWD, ZExtUnit, ZExtZ64, ZExtZBuf}; + use zenoh_protocol::{zextunit, zextz64, zextzbuf}; + + pub(super) type InitSyn = zextunit!(USRPWD, false); + pub(super) type InitAck = zextz64!(USRPWD, false); + pub(super) type OpenSyn = zextzbuf!(USRPWD, false); + pub(super) type OpenAck = zextunit!(USRPWD, false); +} + // Authenticator type User = Vec; type Password = Vec; @@ -257,7 +267,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { type Error = ZError; type SendInitSynIn = &'a StateOpen; - type SendInitSynOut = Option>; + type SendInitSynOut = Option; async fn send_init_syn( &self, _input: Self::SendInitSynIn, @@ -269,7 +279,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { Ok(output) } - type RecvInitAckIn = (&'a mut StateOpen, Option>); + type RecvInitAckIn = (&'a mut StateOpen, Option); type RecvInitAckOut = (); async fn recv_init_ack( &self, @@ -291,7 +301,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { } type SendOpenSynIn = &'a StateOpen; - type SendOpenSynOut = Option>; + type SendOpenSynOut = Option; async fn send_open_syn( &self, state: Self::SendOpenSynIn, @@ -326,7 +336,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { Ok(output) } - type RecvOpenAckIn = (&'a mut StateOpen, Option>); + type RecvOpenAckIn = (&'a mut StateOpen, Option); type RecvOpenAckOut = (); async fn recv_open_ack( &self, @@ -350,7 +360,7 @@ impl<'a> OpenFsm for AuthUsrPwdFsm<'a> { impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { type Error = ZError; - type RecvInitSynIn = (&'a mut StateAccept, Option>); + type RecvInitSynIn = (&'a mut StateAccept, Option); type RecvInitSynOut = (); async fn recv_init_syn( &self, @@ -367,7 +377,7 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { } type SendInitAckIn = &'a StateAccept; - type SendInitAckOut = Option>; + type SendInitAckOut = Option; async fn send_init_ack( &self, state: Self::SendInitAckIn, @@ -375,7 +385,7 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { Ok(Some(ZExtZ64::new(state.nonce))) } - type RecvOpenSynIn = (&'a mut StateAccept, Option>); + type RecvOpenSynIn = (&'a mut StateAccept, Option); type RecvOpenSynOut = (); async fn recv_open_syn( &self, @@ -411,7 +421,7 @@ impl<'a> AcceptFsm for AuthUsrPwdFsm<'a> { } type SendOpenAckIn = &'a StateAccept; - type SendOpenAckOut = Option>; + type SendOpenAckOut = Option; async fn send_open_ack( &self, _input: Self::SendOpenAckIn, From 73187c25a9235a41b9aab92e65f83f9c9dc53801 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 22 Mar 2023 20:00:15 +0100 Subject: [PATCH 111/203] Fix nostd check --- commons/zenoh-codec/src/common/extension.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 870760b52d..544c4806d5 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -272,7 +272,6 @@ where ZExtBody::ZBuf(zbuf) } _ => { - println!("CAZZO"); return Err(DidntRead); } }; From 58c8e3cce06296080e825889ec5d37bf8e453935 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 27 Mar 2023 12:02:36 +0200 Subject: [PATCH 112/203] Remove pull message --- commons/zenoh-codec/src/network/mod.rs | 1 - commons/zenoh-codec/src/network/pull.rs | 121 --------------------- commons/zenoh-codec/tests/codec.rs | 5 - commons/zenoh-protocol/src/network/mod.rs | 21 ++-- commons/zenoh-protocol/src/network/pull.rs | 72 ------------ 5 files changed, 8 insertions(+), 212 deletions(-) delete mode 100644 commons/zenoh-codec/src/network/pull.rs delete mode 100644 commons/zenoh-protocol/src/network/pull.rs diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 743bc7f1a6..6bbd6a318d 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -13,7 +13,6 @@ // mod declare; mod oam; -mod pull; mod push; mod request; mod response; diff --git a/commons/zenoh-codec/src/network/pull.rs b/commons/zenoh-codec/src/network/pull.rs deleted file mode 100644 index f81621f02e..0000000000 --- a/commons/zenoh-codec/src/network/pull.rs +++ /dev/null @@ -1,121 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, -}; -use zenoh_protocol::{ - common::{iext, imsg, ZExtUnknown}, - network::{ - id, - pull::{ext, flag}, - Pull, - }, - zenoh::PullId, -}; - -impl WCodec<&Pull, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Pull) -> Self::Output { - // Header - let mut header = id::PULL; - let mut n_exts = - ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); - if n_exts != 0 { - header |= flag::Z; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, x.id)?; - - // Extensions - if x.ext_qos != ext::QoSType::default() { - n_exts -= 1; - self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; - } - if let Some(ts) = x.ext_tstamp.as_ref() { - n_exts -= 1; - self.write(&mut *writer, (ts, n_exts != 0))?; - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != id::PULL { - return Err(DidntRead); - } - - // Body - let id: PullId = self.codec.read(&mut *reader)?; - - // Extensions - let mut ext_qos = ext::QoSType::default(); - let mut ext_tstamp = None; - - let mut has_ext = imsg::has_flag(self.header, flag::Z); - while has_ext { - let ext: u8 = self.codec.read(&mut *reader)?; - let eodec = Zenoh080Header::new(ext); - match iext::eid(ext) { - ext::QoS::ID => { - let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; - ext_qos = q; - has_ext = ext; - } - ext::Timestamp::ID => { - let (t, ext): (ext::TimestampType, bool) = eodec.read(&mut *reader)?; - ext_tstamp = Some(t); - has_ext = ext; - } - _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - has_ext = ext; - } - } - } - - Ok(Pull { - id, - ext_qos, - ext_tstamp, - }) - } -} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index e71eb082bf..b6e851c06a 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -502,11 +502,6 @@ fn codec_push() { run!(Push, Push::rand()); } -#[test] -fn codec_pull() { - run!(Pull, Pull::rand()); -} - #[test] fn codec_request() { run!(Request, Request::rand()); diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index e92305010d..f4ace32c9e 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -13,14 +13,12 @@ // pub mod declare; pub mod oam; -pub mod pull; pub mod push; pub mod request; pub mod response; pub use declare::*; pub use oam::*; -pub use pull::*; pub use push::*; pub use request::*; pub use response::*; @@ -31,10 +29,9 @@ pub mod id { pub const OAM: u8 = 0x1f; pub const DECLARE: u8 = 0x1e; pub const PUSH: u8 = 0x1d; - pub const PULL: u8 = 0x1c; - pub const REQUEST: u8 = 0x1b; - pub const RESPONSE: u8 = 0x1a; - pub const RESPONSE_FINAL: u8 = 0x19; + pub const REQUEST: u8 = 0x1c; + pub const RESPONSE: u8 = 0x1b; + pub const RESPONSE_FINAL: u8 = 0x1a; } #[repr(u8)] @@ -64,7 +61,6 @@ impl Mapping { pub enum NetworkBody { Declare(Declare), Push(Push), - Pull(Pull), Request(Request), Response(Response), ResponseFinal(ResponseFinal), @@ -85,14 +81,13 @@ impl NetworkMessage { let mut rng = rand::thread_rng(); - let body = match rng.gen_range(0..7) { + let body = match rng.gen_range(0..6) { 0 => NetworkBody::Declare(Declare::rand()), 1 => NetworkBody::Push(Push::rand()), - 2 => NetworkBody::Pull(Pull::rand()), - 3 => NetworkBody::Request(Request::rand()), - 4 => NetworkBody::Response(Response::rand()), - 5 => NetworkBody::ResponseFinal(ResponseFinal::rand()), - 6 => NetworkBody::OAM(Oam::rand()), + 2 => NetworkBody::Request(Request::rand()), + 3 => NetworkBody::Response(Response::rand()), + 4 => NetworkBody::ResponseFinal(ResponseFinal::rand()), + 5 => NetworkBody::OAM(Oam::rand()), _ => unreachable!(), }; diff --git a/commons/zenoh-protocol/src/network/pull.rs b/commons/zenoh-protocol/src/network/pull.rs deleted file mode 100644 index 68655ccd73..0000000000 --- a/commons/zenoh-protocol/src/network/pull.rs +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -pub type PullId = u32; - -pub mod flag { - // pub const X: u8 = 1 << 5; // 0x20 Reserved - // pub const X: u8 = 1 << 6; // 0x40 Reserved - pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow -} - -/// ```text -/// Flags: -/// - X: Reserved -/// - X: Reserved -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|X|X| PULL | -/// +-+-+-+---------+ -/// ~ id:z32 ~ (*) -/// +---------------+ -/// ~ [pull_exts] ~ (*) -/// +---------------+ -/// -/// (*) ID refers to the ID used in a previous target declaration -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Pull { - pub id: PullId, - pub ext_qos: ext::QoSType, - pub ext_tstamp: Option, -} - -impl Pull { - pub const T_SUBSCRIBER: u8 = 0x01; - - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - let mut rng = rand::thread_rng(); - - let id: PullId = rng.gen(); - let ext_qos = ext::QoSType::rand(); - let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); - - Self { - id, - ext_qos, - ext_tstamp, - } - } -} - -pub mod ext { - pub type QoS = crate::network::ext::QoS; - pub type QoSType = crate::network::ext::QoSType; - - pub type Timestamp = crate::network::ext::Timestamp; - pub type TimestampType = crate::network::ext::TimestampType; -} From 515be250095591f31c4a6d4a9a14811464e35004 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 27 Mar 2023 12:14:51 +0200 Subject: [PATCH 113/203] NetworkMessage codec --- commons/zenoh-codec/src/network/mod.rs | 33 ++++++++++---------------- commons/zenoh-codec/tests/codec.rs | 5 ++++ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 6bbd6a318d..b1a2f6dd8d 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -19,7 +19,7 @@ mod response; use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ - reader::{BacktrackableReader, DidntRead, Reader}, + reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ @@ -37,14 +37,18 @@ where fn write(self, writer: &mut W, x: &NetworkMessage) -> Self::Output { match &x.body { NetworkBody::Push(b) => self.write(&mut *writer, b), - _ => Ok(()), //TODO + NetworkBody::Request(b) => self.write(&mut *writer, b), + NetworkBody::Response(b) => self.write(&mut *writer, b), + NetworkBody::ResponseFinal(b) => self.write(&mut *writer, b), + NetworkBody::Declare(b) => self.write(&mut *writer, b), + NetworkBody::OAM(b) => self.write(&mut *writer, b), } } } impl RCodec for Zenoh080 where - R: Reader + BacktrackableReader, + R: Reader, { type Error = DidntRead; @@ -54,24 +58,11 @@ where let codec = Zenoh080Header::new(header); let body = match imsg::mid(codec.header) { id::PUSH => NetworkBody::Push(codec.read(&mut *reader)?), - // id::FRAGMENT => NetworkBody::Fragment(codec.read(&mut *reader)?), - // id::KEEP_ALIVE => NetworkBody::KeepAlive(codec.read(&mut *reader)?), - // id::INIT => { - // if !imsg::has_flag(codec.header, zenoh_protocol::transport::init::flag::A) { - // NetworkBody::InitSyn(codec.read(&mut *reader)?) - // } else { - // NetworkBody::InitAck(codec.read(&mut *reader)?) - // } - // } - // id::OPEN => { - // if !imsg::has_flag(codec.header, zenoh_protocol::transport::open::flag::A) { - // NetworkBody::OpenSyn(codec.read(&mut *reader)?) - // } else { - // NetworkBody::OpenAck(codec.read(&mut *reader)?) - // } - // } - // // id::JOIN => NetworkBody::Join(codec.read(&mut *reader)?), - // id::CLOSE => NetworkBody::Close(codec.read(&mut *reader)?), + id::REQUEST => NetworkBody::Request(codec.read(&mut *reader)?), + id::RESPONSE => NetworkBody::Response(codec.read(&mut *reader)?), + id::RESPONSE_FINAL => NetworkBody::ResponseFinal(codec.read(&mut *reader)?), + id::DECLARE => NetworkBody::Declare(codec.read(&mut *reader)?), + id::OAM => NetworkBody::OAM(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index b6e851c06a..65c0e90c8e 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -522,6 +522,11 @@ fn codec_network_oam() { run!(network::Oam, network::Oam::rand()); } +#[test] +fn codec_network() { + run!(NetworkMessage, NetworkMessage::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { From b76a14794346175d7d380b0f87df70588d2d5e4e Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 27 Mar 2023 18:10:29 +0200 Subject: [PATCH 114/203] Print log when unknown extension is detected --- Cargo.lock | 1 + commons/zenoh-codec/Cargo.toml | 2 + commons/zenoh-codec/src/network/declare.rs | 128 +++++++++++++++++- commons/zenoh-codec/src/network/oam.rs | 11 +- commons/zenoh-codec/src/network/push.rs | 11 +- commons/zenoh-codec/src/network/request.rs | 11 +- commons/zenoh-codec/src/network/response.rs | 22 ++- commons/zenoh-codec/src/transport/close.rs | 11 +- commons/zenoh-codec/src/transport/fragment.rs | 12 +- commons/zenoh-codec/src/transport/frame.rs | 17 ++- commons/zenoh-codec/src/transport/init.rs | 22 ++- .../zenoh-codec/src/transport/keepalive.rs | 11 +- commons/zenoh-codec/src/transport/oam.rs | 11 +- commons/zenoh-codec/src/transport/open.rs | 22 ++- .../zenoh-protocol/src/common/extension.rs | 114 ++++++++++++---- zenoh/Cargo.toml | 2 +- 16 files changed, 356 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34704bea79..4bd29beda5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3839,6 +3839,7 @@ name = "zenoh-codec" version = "0.8.0-rc" dependencies = [ "criterion", + "log", "rand 0.8.5", "serde", "uhlc", diff --git a/commons/zenoh-codec/Cargo.toml b/commons/zenoh-codec/Cargo.toml index f378aa1d4f..16fd9f3013 100644 --- a/commons/zenoh-codec/Cargo.toml +++ b/commons/zenoh-codec/Cargo.toml @@ -31,6 +31,7 @@ description = "Internal crate for zenoh." [features] default = ["std"] std = [ + "log", "serde/std", "uhlc/std", "zenoh-protocol/std" @@ -43,6 +44,7 @@ shared-memory = [ complete_n = ["zenoh-protocol/complete_n"] [dependencies] +log = { workspace = true, optional = true } serde = { workspace = true, features = ["alloc"] } uhlc = { workspace = true } zenoh-buffers = { path = "../zenoh-buffers/", default-features = false } diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index ef785d889a..46601e42b2 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -154,7 +154,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown Declare ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } @@ -226,6 +235,22 @@ where }; let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + // Extensions + let mut has_ext = imsg::has_flag(self.header, keyexpr::flag::Z); + while has_ext { + const S: &str = "Unknown DeclareKeyExpr ext"; + let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } + has_ext = ext; + } + Ok(keyexpr::DeclareKeyExpr { id, wire_expr }) } } @@ -276,6 +301,22 @@ where let id: ExprId = self.codec.read(&mut *reader)?; + // Extensions + let mut has_ext = imsg::has_flag(self.header, keyexpr::flag::Z); + while has_ext { + const S: &str = "Unknown ForgetKeyExpr ext"; + let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } + has_ext = ext; + } + Ok(keyexpr::ForgetKeyExpr { id }) } } @@ -369,7 +410,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown DeclareSubscriber ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } @@ -431,6 +481,22 @@ where // Body let id: subscriber::SubscriberId = self.codec.read(&mut *reader)?; + // Extensions + let mut has_ext = imsg::has_flag(self.header, subscriber::flag::Z); + while has_ext { + const S: &str = "Unknown ForgetSubscriber ext"; + let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } + has_ext = ext; + } + Ok(subscriber::ForgetSubscriber { id }) } } @@ -522,7 +588,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown DeclareQueryable ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } @@ -582,7 +657,23 @@ where } // Body - let id: subscriber::SubscriberId = self.codec.read(&mut *reader)?; + let id: queryable::QueryableId = self.codec.read(&mut *reader)?; + + // Extensions + let mut has_ext = imsg::has_flag(self.header, queryable::flag::Z); + while has_ext { + const S: &str = "Unknown ForgetQueryable ext"; + let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } + has_ext = ext; + } Ok(queryable::ForgetQueryable { id }) } @@ -649,9 +740,18 @@ where }; // Extensions - let mut has_ext = imsg::has_flag(self.header, subscriber::flag::Z); + let mut has_ext = imsg::has_flag(self.header, token::flag::Z); while has_ext { - let (_, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + const S: &str = "Unknown DeclareToken ext"; + let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } @@ -710,6 +810,22 @@ where // Body let id: token::TokenId = self.codec.read(&mut *reader)?; + // Extensions + let mut has_ext = imsg::has_flag(self.header, token::flag::Z); + while has_ext { + const S: &str = "Unknown ForgetToken ext"; + let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } + has_ext = ext; + } + Ok(token::ForgetToken { id }) } } diff --git a/commons/zenoh-codec/src/network/oam.rs b/commons/zenoh-codec/src/network/oam.rs index fa8b0578a9..037c01308f 100644 --- a/commons/zenoh-codec/src/network/oam.rs +++ b/commons/zenoh-codec/src/network/oam.rs @@ -127,7 +127,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown OAM ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index 4747f39c33..c1a39d6272 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -156,7 +156,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown Push ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 5a716f214f..4bed7310e8 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -212,7 +212,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown Request ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs index 09cfa1e433..072163f829 100644 --- a/commons/zenoh-codec/src/network/response.rs +++ b/commons/zenoh-codec/src/network/response.rs @@ -124,7 +124,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown Response ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } @@ -226,7 +235,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown ResponseFinal ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } diff --git a/commons/zenoh-codec/src/transport/close.rs b/commons/zenoh-codec/src/transport/close.rs index e0edff6f16..39c6155ab0 100644 --- a/commons/zenoh-codec/src/transport/close.rs +++ b/commons/zenoh-codec/src/transport/close.rs @@ -77,7 +77,16 @@ where // Extensions let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { - let (_, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + const S: &str = "Unknown Close ext"; + let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index 2a433a1cbb..c1ad42973c 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -103,7 +103,17 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown mandatory Fragment ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 85b39c4d0e..0da81bf1af 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -91,7 +91,7 @@ where let sn: TransportSn = self.codec.read(&mut *reader)?; // Extensions - let mut qos = ext::QoSType::default(); + let mut ext_qos = ext::QoSType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -100,11 +100,20 @@ where match iext::eid(ext) { ext::QoS::ID => { let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; - qos = q; + ext_qos = q; has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown Frame ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } @@ -113,7 +122,7 @@ where Ok(FrameHeader { reliability, sn, - ext_qos: qos, + ext_qos, }) } } diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index dbaf68c8ef..4a7662d1dd 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -169,7 +169,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown InitSyn ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } @@ -337,7 +346,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown InitAck ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } diff --git a/commons/zenoh-codec/src/transport/keepalive.rs b/commons/zenoh-codec/src/transport/keepalive.rs index 4b342f0d25..b1d76d709b 100644 --- a/commons/zenoh-codec/src/transport/keepalive.rs +++ b/commons/zenoh-codec/src/transport/keepalive.rs @@ -65,7 +65,16 @@ where // Extensions let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { - let (_, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + const S: &str = "Unknown KeepAlive ext"; + let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } diff --git a/commons/zenoh-codec/src/transport/oam.rs b/commons/zenoh-codec/src/transport/oam.rs index c21ba86c6e..68732bd738 100644 --- a/commons/zenoh-codec/src/transport/oam.rs +++ b/commons/zenoh-codec/src/transport/oam.rs @@ -116,7 +116,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown OAM ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index 8806afd2f9..c0750c54c5 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -146,7 +146,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown OpenSyn ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } @@ -283,7 +292,16 @@ where has_ext = ext; } _ => { - let (_, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + const S: &str = "Unknown OpenAck ext"; + let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("{S}: {:?}", u); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("{S}: {:?}", u); + } has_ext = ext; } } diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index a5701a1b24..2fea9be95f 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -11,7 +11,10 @@ // Contributors: // ZettaScale Zenoh Team, // -use core::convert::TryFrom; +use core::{ + convert::TryFrom, + fmt::{self, Debug}, +}; use zenoh_buffers::ZBuf; /// # Zenoh extensions @@ -34,7 +37,7 @@ use zenoh_buffers::ZBuf; /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ /// |Z|ENC|M| ID | -/// +-+-+-+---------+ +/// +-+---+-+-------+ /// % length % -- If ENC == u64 || ENC == ZBuf /// +---------------+ /// ~ [u8] ~ -- If ENC == ZBuf @@ -50,23 +53,16 @@ use zenoh_buffers::ZBuf; /// SHOULD be forwarded to the next hops. /// ``` /// -#[repr(u8)] -pub enum ZExtEnc { - Unit = 0b00 << 5, - Z64 = 0b01 << 5, - ZBuf = 0b10 << 5, -} - pub mod iext { - use super::ZExtEnc; + use core::fmt; pub const ID_BITS: u8 = 4; pub const ID_MASK: u8 = !(u8::MAX << ID_BITS); pub const FLAG_M: u8 = 1 << 4; - pub const ENC_UNIT: u8 = ZExtEnc::Unit as u8; - pub const ENC_Z64: u8 = ZExtEnc::Z64 as u8; - pub const ENC_ZBUF: u8 = ZExtEnc::ZBuf as u8; + pub const ENC_UNIT: u8 = 0b00 << 5; + pub const ENC_Z64: u8 = 0b01 << 5; + pub const ENC_ZBUF: u8 = 0b10 << 5; pub const ENC_MASK: u8 = 0b11 << 5; pub const FLAG_Z: u8 = 1 << 7; @@ -74,25 +70,39 @@ pub mod iext { header & !FLAG_Z } - pub(super) const fn id(id: u8, mandatory: bool, encoding: ZExtEnc) -> u8 { + pub(super) const fn id(id: u8, mandatory: bool, encoding: u8) -> u8 { let mut id = id & ID_MASK; if mandatory { id |= FLAG_M; } else { id &= !FLAG_M; } - id |= encoding as u8; + id |= encoding; id } pub(super) const fn is_mandatory(id: u8) -> bool { crate::common::imsg::has_flag(id, FLAG_M) } + + pub(super) fn fmt(f: &mut fmt::DebugStruct, id: u8) { + f.field("Id", &(id & ID_MASK)) + .field("Mandatory", &is_mandatory(id)) + .field( + "Encoding", + match id & ENC_MASK { + ENC_UNIT => &"Unit", + ENC_Z64 => &"Z64", + ENC_ZBUF => &"ZBuf", + _ => &"Unknown", + }, + ); + } } pub struct DidntConvert; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct ZExtUnit; impl ZExtUnit<{ ID }> { @@ -103,7 +113,7 @@ impl ZExtUnit<{ ID }> { } pub const fn id(mandatory: bool) -> u8 { - iext::id(ID, mandatory, ZExtEnc::Unit) + iext::id(ID, mandatory, iext::ENC_UNIT) } pub const fn is_mandatory(&self) -> bool { @@ -120,6 +130,14 @@ impl ZExtUnit<{ ID }> { } } +impl Debug for ZExtUnit<{ ID }> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = f.debug_struct("ZExtUnit"); + iext::fmt(&mut s, ID); + s.finish() + } +} + impl TryFrom for ZExtUnit<{ ID }> { type Error = DidntConvert; @@ -134,7 +152,7 @@ impl TryFrom for ZExtUnit<{ ID }> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct ZExtZ64 { pub value: u64, } @@ -147,7 +165,7 @@ impl ZExtZ64<{ ID }> { } pub const fn id(mandatory: bool) -> u8 { - iext::id(ID, mandatory, ZExtEnc::Z64) + iext::id(ID, mandatory, iext::ENC_Z64) } pub const fn is_mandatory(&self) -> bool { @@ -168,6 +186,14 @@ impl ZExtZ64<{ ID }> { } } +impl Debug for ZExtZ64<{ ID }> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = f.debug_struct("ZExtZ64"); + iext::fmt(&mut s, ID); + s.field("Value", &self.value).finish() + } +} + impl TryFrom for ZExtZ64<{ ID }> { type Error = DidntConvert; @@ -182,7 +208,7 @@ impl TryFrom for ZExtZ64<{ ID }> { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq)] pub struct ZExtZBuf { pub value: ZBuf, } @@ -195,7 +221,7 @@ impl ZExtZBuf<{ ID }> { } pub const fn id(mandatory: bool) -> u8 { - iext::id(ID, mandatory, ZExtEnc::ZBuf) + iext::id(ID, mandatory, iext::ENC_ZBUF) } pub const fn is_mandatory(&self) -> bool { @@ -216,6 +242,14 @@ impl ZExtZBuf<{ ID }> { } } +impl Debug for ZExtZBuf<{ ID }> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = f.debug_struct("ZExtZBuf"); + iext::fmt(&mut s, ID); + s.field("Value", &self.value).finish() + } +} + impl TryFrom for ZExtZBuf<{ ID }> { type Error = DidntConvert; @@ -230,7 +264,7 @@ impl TryFrom for ZExtZBuf<{ ID }> { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq)] pub struct ZExtZBufHeader { pub len: usize, } @@ -243,7 +277,7 @@ impl ZExtZBufHeader<{ ID }> { } pub const fn id(mandatory: bool) -> u8 { - iext::id(ID, mandatory, ZExtEnc::ZBuf) + iext::id(ID, mandatory, iext::ENC_ZBUF) } pub const fn is_mandatory(&self) -> bool { @@ -251,6 +285,14 @@ impl ZExtZBufHeader<{ ID }> { } } +impl Debug for ZExtZBufHeader<{ ID }> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = f.debug_struct("ZExtZBufHeader"); + iext::fmt(&mut s, ID); + s.field("Len", &self.len).finish() + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum ZExtBody { Unit, @@ -274,7 +316,7 @@ impl ZExtBody { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq)] pub struct ZExtUnknown { pub id: u8, pub body: ZExtBody, @@ -283,9 +325,9 @@ pub struct ZExtUnknown { impl ZExtUnknown { pub const fn new(id: u8, mandatory: bool, body: ZExtBody) -> Self { let enc = match &body { - ZExtBody::Unit => ZExtEnc::Unit, - ZExtBody::Z64(_) => ZExtEnc::Z64, - ZExtBody::ZBuf(_) => ZExtEnc::ZBuf, + ZExtBody::Unit => iext::ENC_UNIT, + ZExtBody::Z64(_) => iext::ENC_Z64, + ZExtBody::ZBuf(_) => iext::ENC_ZBUF, }; let id = iext::id(id, mandatory, enc); Self { id, body } @@ -307,6 +349,23 @@ impl ZExtUnknown { } } +impl Debug for ZExtUnknown { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = f.debug_struct("ZExtUnknown"); + iext::fmt(&mut s, self.id); + match &self.body { + ZExtBody::Unit => {} + ZExtBody::Z64(v) => { + s.field("Value", v); + } + ZExtBody::ZBuf(v) => { + s.field("Value", v); + } + }; + s.finish() + } +} + impl From> for ZExtUnknown { fn from(_: ZExtUnit<{ ID }>) -> Self { ZExtUnknown { @@ -335,7 +394,6 @@ impl From> for ZExtUnknown { } // Macros - #[macro_export] macro_rules! zextunit { ($id:expr, $m:expr) => { diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index eafb61d496..09865edeca 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -85,7 +85,7 @@ uhlc = { workspace = true, features = ["default"] } uuid = { workspace = true, features = ["default"] } vec_map = { workspace = true } zenoh-buffers = { path = "../commons/zenoh-buffers/" } -zenoh-codec = { path = "../commons/zenoh-codec/" } +zenoh-codec = { path = "../commons/zenoh-codec/", feature = "std" } zenoh-collections = { path = "../commons/zenoh-collections/" } zenoh-config = { path = "../commons/zenoh-config/" } zenoh-core = { path = "../commons/zenoh-core/" } From 43dcb8bf04f643a34b76360f264a715d9b95cf28 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 27 Mar 2023 19:18:33 +0200 Subject: [PATCH 115/203] Improve extension skip --- commons/zenoh-codec/src/common/extension.rs | 41 ++++++ commons/zenoh-codec/src/network/declare.rs | 136 +++--------------- commons/zenoh-codec/src/network/oam.rs | 16 +-- commons/zenoh-codec/src/network/push.rs | 16 +-- commons/zenoh-codec/src/network/request.rs | 16 +-- commons/zenoh-codec/src/network/response.rs | 28 +--- commons/zenoh-codec/src/transport/close.rs | 20 +-- commons/zenoh-codec/src/transport/fragment.rs | 17 +-- commons/zenoh-codec/src/transport/frame.rs | 16 +-- commons/zenoh-codec/src/transport/init.rs | 30 +--- .../zenoh-codec/src/transport/keepalive.rs | 20 +-- commons/zenoh-codec/src/transport/oam.rs | 16 +-- commons/zenoh-codec/src/transport/open.rs | 28 +--- 13 files changed, 106 insertions(+), 294 deletions(-) diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 544c4806d5..0dbac103e8 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -22,6 +22,47 @@ use zenoh_protocol::common::{ iext, imsg::has_flag, ZExtBody, ZExtUnit, ZExtUnknown, ZExtZ64, ZExtZBuf, ZExtZBufHeader, }; +fn skip_inner(reader: &mut R, _s: &str, header: u8) -> Result +where + R: Reader, +{ + let codec = Zenoh080Header::new(header); + let (u, has_ext): (ZExtUnknown, bool) = codec.read(&mut *reader)?; + if u.is_mandatory() { + #[cfg(feature = "std")] + log::error!("Unknown {_s} ext: {u:?}"); + return Err(DidntRead); + } else { + #[cfg(feature = "std")] + log::debug!("Unknown {_s} ext: {u:?}"); + } + Ok(has_ext) +} + +#[cold] +#[inline(never)] +pub(crate) fn skip(reader: &mut R, s: &str, header: u8) -> Result +where + R: Reader, +{ + skip_inner(reader, s, header) +} + +#[cold] +#[inline(never)] +pub(crate) fn skip_all(reader: &mut R, s: &str) -> Result<(), DidntRead> +where + R: Reader, +{ + let codec = Zenoh080::new(); + let mut has_ext = true; + while has_ext { + let header: u8 = codec.read(&mut *reader)?; + has_ext = skip_inner(reader, s, header)?; + } + Ok(()) +} + // ZExtUnit impl WCodec<(&ZExtUnit<{ ID }>, bool), &mut W> for Zenoh080 where diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index 46601e42b2..d3492d706a 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -11,13 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtUnknown, ZExtZ64}, + common::{iext, imsg, ZExtZ64}, core::{ExprId, WireExpr}, network::{ declare::{self, keyexpr, queryable, subscriber, token, Declare, DeclareBody}, @@ -154,17 +154,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown Declare ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "Declare", ext)?; } } } @@ -236,19 +226,9 @@ where let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; // Extensions - let mut has_ext = imsg::has_flag(self.header, keyexpr::flag::Z); - while has_ext { - const S: &str = "Unknown DeclareKeyExpr ext"; - let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + let has_ext = imsg::has_flag(self.header, keyexpr::flag::Z); + if has_ext { + extension::skip_all(reader, "DeclareKeyExpr")?; } Ok(keyexpr::DeclareKeyExpr { id, wire_expr }) @@ -302,19 +282,9 @@ where let id: ExprId = self.codec.read(&mut *reader)?; // Extensions - let mut has_ext = imsg::has_flag(self.header, keyexpr::flag::Z); - while has_ext { - const S: &str = "Unknown ForgetKeyExpr ext"; - let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + let has_ext = imsg::has_flag(self.header, keyexpr::flag::Z); + if has_ext { + extension::skip_all(reader, "ForgetKeyExpr")?; } Ok(keyexpr::ForgetKeyExpr { id }) @@ -410,17 +380,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown DeclareSubscriber ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "DeclareSubscriber", ext)?; } } } @@ -482,19 +442,9 @@ where let id: subscriber::SubscriberId = self.codec.read(&mut *reader)?; // Extensions - let mut has_ext = imsg::has_flag(self.header, subscriber::flag::Z); - while has_ext { - const S: &str = "Unknown ForgetSubscriber ext"; - let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + let has_ext = imsg::has_flag(self.header, subscriber::flag::Z); + if has_ext { + extension::skip_all(reader, "ForgetSubscriber")?; } Ok(subscriber::ForgetSubscriber { id }) @@ -588,17 +538,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown DeclareQueryable ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "DeclareQueryable", ext)?; } } } @@ -660,19 +600,9 @@ where let id: queryable::QueryableId = self.codec.read(&mut *reader)?; // Extensions - let mut has_ext = imsg::has_flag(self.header, queryable::flag::Z); - while has_ext { - const S: &str = "Unknown ForgetQueryable ext"; - let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + let has_ext = imsg::has_flag(self.header, queryable::flag::Z); + if has_ext { + extension::skip_all(reader, "ForgetQueryable")?; } Ok(queryable::ForgetQueryable { id }) @@ -740,19 +670,9 @@ where }; // Extensions - let mut has_ext = imsg::has_flag(self.header, token::flag::Z); - while has_ext { - const S: &str = "Unknown DeclareToken ext"; - let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + let has_ext = imsg::has_flag(self.header, token::flag::Z); + if has_ext { + extension::skip_all(reader, "DeclareToken")?; } Ok(token::DeclareToken { @@ -811,19 +731,9 @@ where let id: token::TokenId = self.codec.read(&mut *reader)?; // Extensions - let mut has_ext = imsg::has_flag(self.header, token::flag::Z); - while has_ext { - const S: &str = "Unknown ForgetToken ext"; - let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + let has_ext = imsg::has_flag(self.header, token::flag::Z); + if has_ext { + extension::skip_all(reader, "ForgetToken")?; } Ok(token::ForgetToken { id }) diff --git a/commons/zenoh-codec/src/network/oam.rs b/commons/zenoh-codec/src/network/oam.rs index 037c01308f..0e59421ba8 100644 --- a/commons/zenoh-codec/src/network/oam.rs +++ b/commons/zenoh-codec/src/network/oam.rs @@ -11,14 +11,14 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, ZBuf, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtBody, ZExtUnknown}, + common::{iext, imsg, ZExtBody}, network::{ id, oam::{ext, flag, Oam, OamId}, @@ -127,17 +127,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown OAM ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "OAM", ext)?; } } } diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index c1a39d6272..a49e9f4d3a 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -11,13 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtUnknown}, + common::{iext, imsg}, core::WireExpr, network::{ id, @@ -156,17 +156,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown Push ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "Push", ext)?; } } } diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 4bed7310e8..996ed05aca 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -11,13 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtUnknown}, + common::{iext, imsg, }, core::WireExpr, network::{ id, @@ -212,17 +212,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown Request ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "Request", ext)?; } } } diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs index 072163f829..63b7fb29cb 100644 --- a/commons/zenoh-codec/src/network/response.rs +++ b/commons/zenoh-codec/src/network/response.rs @@ -11,13 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtUnknown}, + common::{iext, imsg}, core::WireExpr, network::{ id, @@ -124,17 +124,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown Response ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "Response", ext)?; } } } @@ -235,17 +225,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown ResponseFinal ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "ResponseFinal", ext)?; } } } diff --git a/commons/zenoh-codec/src/transport/close.rs b/commons/zenoh-codec/src/transport/close.rs index 39c6155ab0..4a5cdb7f31 100644 --- a/commons/zenoh-codec/src/transport/close.rs +++ b/commons/zenoh-codec/src/transport/close.rs @@ -11,13 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown}, + common::imsg, transport::{ close::{flag, Close}, id, @@ -75,19 +75,9 @@ where let reason: u8 = self.codec.read(&mut *reader)?; // Extensions - let mut has_ext = imsg::has_flag(self.header, flag::Z); - while has_ext { - const S: &str = "Unknown Close ext"; - let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + let has_ext = imsg::has_flag(self.header, flag::Z); + if has_ext { + extension::skip_all(reader, "Close")?; } Ok(Close { reason, session }) diff --git a/commons/zenoh-codec/src/transport/fragment.rs b/commons/zenoh-codec/src/transport/fragment.rs index c1ad42973c..7cc827d378 100644 --- a/commons/zenoh-codec/src/transport/fragment.rs +++ b/commons/zenoh-codec/src/transport/fragment.rs @@ -11,13 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtUnknown}, + common::{iext, imsg}, core::Reliability, transport::{ fragment::{ext, flag, Fragment, FragmentHeader, TransportSn}, @@ -103,18 +103,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown mandatory Fragment ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "Fragment", ext)?; } } } diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 0da81bf1af..8c50048f11 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -11,14 +11,14 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Reliability}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Reliability}; use alloc::vec::Vec; use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtUnknown, ZExtZ64}, + common::{iext, imsg, ZExtZ64}, core::Reliability, transport::{ frame::{ext, flag, Frame, FrameHeader}, @@ -104,17 +104,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown Frame ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "Frame", ext)?; } } } diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index 4a7662d1dd..a4edfde343 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -11,14 +11,16 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header, Zenoh080Length}; +use crate::{ + common::extension, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header, Zenoh080Length, +}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, ZSlice, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtUnknown}, + common::{iext, imsg}, core::{Resolution, WhatAmI, ZenohId}, transport::{ id, @@ -169,17 +171,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown InitSyn ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "InitSyn", ext)?; } } } @@ -346,17 +338,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown InitAck ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "InitAck", ext)?; } } } diff --git a/commons/zenoh-codec/src/transport/keepalive.rs b/commons/zenoh-codec/src/transport/keepalive.rs index b1d76d709b..de69ad1a14 100644 --- a/commons/zenoh-codec/src/transport/keepalive.rs +++ b/commons/zenoh-codec/src/transport/keepalive.rs @@ -11,13 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{imsg, ZExtUnknown}, + common::imsg, transport::{ id, keepalive::{flag, KeepAlive}, @@ -63,19 +63,9 @@ where } // Extensions - let mut has_ext = imsg::has_flag(self.header, flag::Z); - while has_ext { - const S: &str = "Unknown KeepAlive ext"; - let (u, ext): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + let has_ext = imsg::has_flag(self.header, flag::Z); + if has_ext { + extension::skip_all(reader, "Unknown KeepAlive ext")?; } Ok(KeepAlive) diff --git a/commons/zenoh-codec/src/transport/oam.rs b/commons/zenoh-codec/src/transport/oam.rs index 68732bd738..46fe63345e 100644 --- a/commons/zenoh-codec/src/transport/oam.rs +++ b/commons/zenoh-codec/src/transport/oam.rs @@ -11,14 +11,14 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, ZBuf, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtBody, ZExtUnknown}, + common::{iext, imsg, ZExtBody}, transport::{ id, oam::{ext, flag, Oam, OamId}, @@ -116,17 +116,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown OAM ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "OAM", ext)?; } } } diff --git a/commons/zenoh-codec/src/transport/open.rs b/commons/zenoh-codec/src/transport/open.rs index c0750c54c5..4ff0339cb6 100644 --- a/commons/zenoh-codec/src/transport/open.rs +++ b/commons/zenoh-codec/src/transport/open.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use core::time::Duration; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,7 +19,7 @@ use zenoh_buffers::{ ZSlice, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtUnknown}, + common::{iext, imsg}, transport::{ id, open::{ext, flag, OpenAck, OpenSyn}, @@ -146,17 +146,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown OpenSyn ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "OpenSyn", ext)?; } } } @@ -292,17 +282,7 @@ where has_ext = ext; } _ => { - const S: &str = "Unknown OpenAck ext"; - let (u, ext): (ZExtUnknown, bool) = eodec.read(&mut *reader)?; - if u.is_mandatory() { - #[cfg(feature = "std")] - log::error!("{S}: {:?}", u); - return Err(DidntRead); - } else { - #[cfg(feature = "std")] - log::debug!("{S}: {:?}", u); - } - has_ext = ext; + has_ext = extension::skip(reader, "OpenAck", ext)?; } } } From 9b42ba0015cff7ad63a45eb957a03d3ec6ac348a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 27 Mar 2023 19:41:00 +0200 Subject: [PATCH 116/203] Fix code fmt --- commons/zenoh-codec/src/network/request.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 996ed05aca..5d3da5a722 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -17,7 +17,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{iext, imsg, }, + common::{iext, imsg}, core::WireExpr, network::{ id, From 97aa2248d31576dec673af3d2f88c25e9d7529ac Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 28 Mar 2023 10:30:07 +0200 Subject: [PATCH 117/203] Add skip extension test --- Cargo.lock | 1 + commons/zenoh-codec/Cargo.toml | 1 + commons/zenoh-codec/src/common/extension.rs | 4 ++-- commons/zenoh-codec/src/lib.rs | 12 ++++++------ commons/zenoh-codec/tests/codec.rs | 17 ++++++++++++----- zenoh/Cargo.toml | 2 +- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bd29beda5..a4a0084219 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3839,6 +3839,7 @@ name = "zenoh-codec" version = "0.8.0-rc" dependencies = [ "criterion", + "env_logger", "log", "rand 0.8.5", "serde", diff --git a/commons/zenoh-codec/Cargo.toml b/commons/zenoh-codec/Cargo.toml index 16fd9f3013..f77318c1de 100644 --- a/commons/zenoh-codec/Cargo.toml +++ b/commons/zenoh-codec/Cargo.toml @@ -54,6 +54,7 @@ zenoh-shm = { path = "../zenoh-shm/", optional = true } # INFO: May cause problems when testing no_std stuff. Check this tool: https://docs.rs/crate/cargo-no-dev-deps/0.1.0 [dev-dependencies] criterion = { workspace = true } +env_logger = { workspace = true } rand = { workspace = true, features = ["default"] } uuid = { workspace = true, features = ["default"] } zenoh-protocol = { path = "../zenoh-protocol/", features = ["test"] } diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 0dbac103e8..9785d16a71 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -41,7 +41,7 @@ where #[cold] #[inline(never)] -pub(crate) fn skip(reader: &mut R, s: &str, header: u8) -> Result +pub fn skip(reader: &mut R, s: &str, header: u8) -> Result where R: Reader, { @@ -50,7 +50,7 @@ where #[cold] #[inline(never)] -pub(crate) fn skip_all(reader: &mut R, s: &str) -> Result<(), DidntRead> +pub fn skip_all(reader: &mut R, s: &str) -> Result<(), DidntRead> where R: Reader, { diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 8e66e6b569..5bb21d95aa 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -14,12 +14,12 @@ #![cfg_attr(not(feature = "std"), no_std)] extern crate alloc; -mod common; -mod core; -mod network; -mod scouting; -mod transport; -mod zenoh; +pub mod common; +pub mod core; +pub mod network; +pub mod scouting; +pub mod transport; +pub mod zenoh; use ::core::marker::PhantomData; use zenoh_protocol::{core::Reliability, zenoh::ReplyContext}; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 65c0e90c8e..811ddabc4f 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -29,7 +29,7 @@ use zenoh_protocol::{ network::{self, *}, scouting::*, transport::{self, *}, - zenoh, + zenoh, zextunit, zextz64, zextzbuf, }; const NUM_ITER: usize = 100; @@ -320,6 +320,8 @@ fn codec_shm_info() { // Common #[test] fn codec_extension() { + let _ = env_logger::try_init(); + macro_rules! run_extension_single { ($ext:ty, $buff:expr) => { let codec = Zenoh080::new(); @@ -337,6 +339,9 @@ fn codec_extension() { assert_eq!(x.0, &y.0); assert_eq!(x.1, y.1); + + let mut reader = $buff.reader(); + let _ = zenoh_codec::common::extension::skip_all(&mut reader, "Test"); } }; } @@ -357,10 +362,12 @@ fn codec_extension() { }; } - run_extension!(ZExtUnit::<0>); - run_extension!(ZExtZ64<1>); - run_extension!(ZExtZBuf<2>); - run_extension!(ZExtZBuf<3>); + run_extension!(zextunit!(0x00, true)); + run_extension!(zextunit!(0x00, false)); + run_extension!(zextz64!(0x01, true)); + run_extension!(zextz64!(0x01, false)); + run_extension!(zextzbuf!(0x02, true)); + run_extension!(zextzbuf!(0x02, false)); run_extension!(ZExtUnknown); } diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 09865edeca..eafb61d496 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -85,7 +85,7 @@ uhlc = { workspace = true, features = ["default"] } uuid = { workspace = true, features = ["default"] } vec_map = { workspace = true } zenoh-buffers = { path = "../commons/zenoh-buffers/" } -zenoh-codec = { path = "../commons/zenoh-codec/", feature = "std" } +zenoh-codec = { path = "../commons/zenoh-codec/" } zenoh-collections = { path = "../commons/zenoh-collections/" } zenoh-config = { path = "../commons/zenoh-config/" } zenoh-core = { path = "../commons/zenoh-core/" } From 4e2719da110291260054c75be2f10c67a0ec0fbc Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 29 Mar 2023 14:26:57 +0200 Subject: [PATCH 118/203] Put message --- commons/zenoh-codec/src/core/zenohid.rs | 8 +- commons/zenoh-codec/src/core/zint.rs | 1 + commons/zenoh-codec/src/lib.rs | 1 + commons/zenoh-codec/src/network/mod.rs | 3 +- commons/zenoh-codec/src/network/push.rs | 4 +- commons/zenoh-codec/src/transport/init.rs | 4 +- commons/zenoh-codec/src/zenoh_new/mod.rs | 53 +++++ commons/zenoh-codec/src/zenoh_new/put.rs | 187 ++++++++++++++++++ commons/zenoh-codec/tests/codec.rs | 17 +- .../zenoh-protocol/src/common/extension.rs | 3 + commons/zenoh-protocol/src/lib.rs | 1 + commons/zenoh-protocol/src/network/push.rs | 7 +- commons/zenoh-protocol/src/transport/frame.rs | 13 +- commons/zenoh-protocol/src/zenoh_new/mod.rs | 47 +++++ commons/zenoh-protocol/src/zenoh_new/put.rs | 116 +++++++++++ 15 files changed, 439 insertions(+), 26 deletions(-) create mode 100644 commons/zenoh-codec/src/zenoh_new/mod.rs create mode 100644 commons/zenoh-codec/src/zenoh_new/put.rs create mode 100644 commons/zenoh-protocol/src/zenoh_new/mod.rs create mode 100644 commons/zenoh-protocol/src/zenoh_new/put.rs diff --git a/commons/zenoh-codec/src/core/zenohid.rs b/commons/zenoh-codec/src/core/zenohid.rs index f9d1c24a75..af18f0b2a2 100644 --- a/commons/zenoh-codec/src/core/zenohid.rs +++ b/commons/zenoh-codec/src/core/zenohid.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Length}; +use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Length}; use core::convert::TryFrom; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,6 +19,12 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::ZenohId; +impl LCodec<&ZenohId> for Zenoh080 { + fn w_len(self, x: &ZenohId) -> usize { + x.size() + } +} + impl WCodec<&ZenohId, &mut W> for Zenoh080 where W: Writer, diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 38d4cda3b4..428169b1cd 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -55,6 +55,7 @@ impl LCodec for Zenoh080 { } } } + impl LCodec for Zenoh080 { fn w_len(self, x: usize) -> usize { self.w_len(x as u64) diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 5bb21d95aa..ca135d9b7d 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -20,6 +20,7 @@ pub mod network; pub mod scouting; pub mod transport; pub mod zenoh; +pub mod zenoh_new; use ::core::marker::PhantomData; use zenoh_protocol::{core::Reliability, zenoh::ReplyContext}; diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index b1a2f6dd8d..b068bba7c9 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -109,9 +109,8 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result<(ext::TimestampType, bool), Self::Error> { - let codec = Zenoh080::new(); let (_, more): (ZExtZBufHeader<{ ext::Timestamp::ID }>, bool) = self.read(&mut *reader)?; - let timestamp: uhlc::Timestamp = codec.read(&mut *reader)?; + let timestamp: uhlc::Timestamp = self.codec.read(&mut *reader)?; Ok((ext::TimestampType { timestamp }, more)) } } diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index a49e9f4d3a..49b21e93a7 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -24,6 +24,7 @@ use zenoh_protocol::{ push::{ext, flag}, Mapping, Push, }, + zenoh_new::PushBody, }; impl WCodec<(ext::DestinationType, bool), &mut W> for Zenoh080 @@ -162,8 +163,7 @@ where } // Payload - // let payload: ZenohMessage = self.codec.read(&mut *reader)?; - let payload: u8 = self.codec.read(&mut *reader)?; // @TODO + let payload: PushBody = self.codec.read(&mut *reader)?; Ok(Push { wire_expr, diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index a4edfde343..6d1aea5911 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -59,7 +59,7 @@ where WhatAmI::Peer => 0b01, WhatAmI::Client => 0b10, }; - let flags = ((x.zid.size() as u8 - 1) << 4) | whatami; + let flags: u8 = ((x.zid.size() as u8 - 1) << 4) | whatami; self.write(&mut *writer, flags)?; let lodec = Zenoh080Length::new(x.zid.size()); @@ -220,7 +220,7 @@ where WhatAmI::Peer => 0b01, WhatAmI::Client => 0b10, }; - let flags = ((x.zid.size() as u8 - 1) << 4) | whatami; + let flags: u8 = ((x.zid.size() as u8 - 1) << 4) | whatami; self.write(&mut *writer, flags)?; let lodec = Zenoh080Length::new(x.zid.size()); diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs new file mode 100644 index 0000000000..c6863030f4 --- /dev/null +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -0,0 +1,53 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +pub mod put; +use zenoh_buffers::reader::{DidntRead, Reader}; +use zenoh_buffers::writer::{DidntWrite, Writer}; +use zenoh_protocol::common::imsg; +use zenoh_protocol::zenoh_new::{id, PushBody}; + +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; + +// PushBody +impl WCodec<&PushBody, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &PushBody) -> Self::Output { + match x { + PushBody::Put(b) => self.write(&mut *writer, b), + } + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + + let codec = Zenoh080Header::new(header); + let body = match imsg::mid(codec.header) { + id::PUT => PushBody::Put(codec.read(&mut *reader)?), + _ => return Err(DidntRead), + }; + + Ok(body) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/put.rs b/commons/zenoh-codec/src/zenoh_new/put.rs new file mode 100644 index 0000000000..708ea9effa --- /dev/null +++ b/commons/zenoh-codec/src/zenoh_new/put.rs @@ -0,0 +1,187 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, + ZBuf, +}; +use zenoh_protocol::{ + common::{iext, imsg, ZExtZBufHeader}, + core::{Encoding, ZenohId}, + zenoh_new::{ + id, + put::{ext, flag, Put}, + }, +}; + +impl LCodec<&ext::SourceInfoType> for Zenoh080 { + fn w_len(self, x: &ext::SourceInfoType) -> usize { + 1 + self.w_len(&x.zid) + self.w_len(x.eid) + self.w_len(x.sn) + } +} + +impl WCodec<(&ext::SourceInfoType, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::SourceInfoType, bool)) -> Self::Output { + let (sinfo, more) = x; + let header: ZExtZBufHeader<{ ext::SourceInfo::ID }> = + ZExtZBufHeader::new(self.w_len(sinfo)); + self.write(&mut *writer, (&header, more))?; + + let flags: u8 = (sinfo.zid.size() as u8 - 1) << 4; + self.write(&mut *writer, flags)?; + + let lodec = Zenoh080Length::new(sinfo.zid.size()); + lodec.write(&mut *writer, &sinfo.zid)?; + + self.write(&mut *writer, sinfo.eid)?; + self.write(&mut *writer, sinfo.sn)?; + Ok(()) + } +} + +impl RCodec<(ext::SourceInfoType, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::SourceInfoType, bool), Self::Error> { + let (_, more): (ZExtZBufHeader<{ ext::SourceInfo::ID }>, bool) = self.read(&mut *reader)?; + + let flags: u8 = self.codec.read(&mut *reader)?; + let length = 1 + ((flags >> 4) as usize); + + let lodec = Zenoh080Length::new(length); + let zid: ZenohId = lodec.read(&mut *reader)?; + + let eid: u32 = self.codec.read(&mut *reader)?; + let sn: u32 = self.codec.read(&mut *reader)?; + + Ok((ext::SourceInfoType { zid, eid, sn }, more)) + } +} + +impl WCodec<&Put, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Put) -> Self::Output { + // Header + let mut header = id::PUT; + if x.timestamp.is_some() { + header |= flag::T; + } + if x.encoding != Encoding::default() { + header |= flag::E; + } + let mut n_exts = (x.ext_sinfo.is_some()) as u8; + if n_exts != 0 { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + if let Some(ts) = x.timestamp.as_ref() { + self.write(&mut *writer, ts)?; + } + if x.encoding != Encoding::default() { + self.write(&mut *writer, &x.encoding)?; + } + + // Extensions + if let Some(sinfo) = x.ext_sinfo.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (sinfo, n_exts != 0))?; + } + + // Payload + self.write(&mut *writer, &x.payload)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::PUT { + return Err(DidntRead); + } + + // Body + let mut timestamp: Option = None; + if imsg::has_flag(self.header, flag::T) { + timestamp = Some(self.codec.read(&mut *reader)?); + } + + let mut encoding = Encoding::default(); + if imsg::has_flag(self.header, flag::E) { + encoding = self.codec.read(&mut *reader)?; + } + + // Extensions + let mut ext_sinfo: Option = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + ext::SourceInfo::ID => { + let (s, ext): (ext::SourceInfoType, bool) = eodec.read(&mut *reader)?; + ext_sinfo = Some(s); + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "Put", ext)?; + } + } + } + + // Payload + let payload: ZBuf = self.codec.read(&mut *reader)?; + + Ok(Put { + timestamp, + encoding, + ext_sinfo, + payload, + }) + } +} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 811ddabc4f..ca2f3b32a9 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -29,7 +29,7 @@ use zenoh_protocol::{ network::{self, *}, scouting::*, transport::{self, *}, - zenoh, zextunit, zextz64, zextzbuf, + zenoh, zenoh_new, zextunit, zextz64, zextzbuf, }; const NUM_ITER: usize = 100; @@ -46,9 +46,8 @@ macro_rules! run_single { let mut reader = $buff.reader(); let y: $type = $rcode.read(&mut reader).unwrap(); - assert!(!reader.can_read()); - assert_eq!(x, y); + assert!(!reader.can_read()); } }; } @@ -70,9 +69,8 @@ macro_rules! run_fragmented { let mut reader = zbuf.reader(); let y: $type = $rcode.read(&mut reader).unwrap(); - assert!(!reader.can_read()); - assert_eq!(x, y); + assert!(!reader.can_read()); } }; } @@ -102,9 +100,8 @@ macro_rules! run_buffers { let mut zslice = ZSlice::from(Arc::new(buffer)); let mut reader = zslice.reader(); let y: $type = $rcode.read(&mut reader).unwrap(); - assert!(!reader.can_read()); - assert_eq!(x, y); + assert!(!reader.can_read()); } println!("Fragmented: codec {}", std::any::type_name::<$type>()); @@ -534,6 +531,12 @@ fn codec_network() { run!(NetworkMessage, NetworkMessage::rand()); } +// Zenoh new +#[test] +fn codec_put() { + run!(zenoh_new::Put, zenoh_new::Put::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index 2fea9be95f..29dbdbb1d7 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -102,6 +102,7 @@ pub mod iext { pub struct DidntConvert; +#[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq)] pub struct ZExtUnit; @@ -152,6 +153,7 @@ impl TryFrom for ZExtUnit<{ ID }> { } } +#[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq)] pub struct ZExtZ64 { pub value: u64, @@ -208,6 +210,7 @@ impl TryFrom for ZExtZ64<{ ID }> { } } +#[repr(transparent)] #[derive(Clone, PartialEq, Eq)] pub struct ZExtZBuf { pub value: ZBuf, diff --git a/commons/zenoh-protocol/src/lib.rs b/commons/zenoh-protocol/src/lib.rs index 35869e4d77..8610d431fa 100644 --- a/commons/zenoh-protocol/src/lib.rs +++ b/commons/zenoh-protocol/src/lib.rs @@ -26,6 +26,7 @@ pub mod network; pub mod scouting; pub mod transport; pub mod zenoh; +pub mod zenoh_new; // Zenoh version pub const VERSION: u8 = 0x08; diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs index 2a9de7c0d2..cda27023de 100644 --- a/commons/zenoh-protocol/src/network/push.rs +++ b/commons/zenoh-protocol/src/network/push.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, network::Mapping}; +use crate::{core::WireExpr, network::Mapping, zenoh_new::PushBody}; pub mod flag { pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix @@ -42,7 +42,7 @@ pub mod flag { pub struct Push { pub wire_expr: WireExpr<'static>, pub mapping: Mapping, - pub payload: u8, // @TODO + pub payload: PushBody, // @TODO pub ext_qos: ext::QoSType, pub ext_tstamp: Option, pub ext_dst: ext::DestinationType, @@ -90,8 +90,7 @@ impl Push { let mut rng = rand::thread_rng(); let wire_expr = WireExpr::rand(); let mapping = Mapping::rand(); - // let payload = ZenohMessage::rand(); - let payload: u8 = rng.gen(); // @TODO + let payload = PushBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); let ext_dst = ext::DestinationType::rand(); diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 848a4b4dd7..9eb99bd7b1 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -82,14 +82,11 @@ pub mod ext { pub type QoS = zextz64!(0x1, true); - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// |Z|0_1| QoS | - /// +-+-+-+---------+ - /// %0| rsv |prio % - /// +---------------+ - /// - /// - prio: Priority class + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// %0| rsv |prio % + /// +---------------+ + /// - prio: Priority class #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QoSType { diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs new file mode 100644 index 0000000000..42035d4f46 --- /dev/null +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -0,0 +1,47 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +pub mod put; + +pub use put::*; + +pub mod id { + pub const OAM: u8 = 0x00; + pub const PUT: u8 = 0x01; + pub const DEL: u8 = 0x02; +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum PushBody { + Put(Put), +} + +impl PushBody { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + match rng.gen_range(0..1) { + 0 => PushBody::Put(Put::rand()), + _ => unreachable!(), + } + } +} + +impl From for PushBody { + fn from(p: Put) -> PushBody { + PushBody::Put(p) + } +} diff --git a/commons/zenoh-protocol/src/zenoh_new/put.rs b/commons/zenoh-protocol/src/zenoh_new/put.rs new file mode 100644 index 0000000000..7bf6ab5ff6 --- /dev/null +++ b/commons/zenoh-protocol/src/zenoh_new/put.rs @@ -0,0 +1,116 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::core::Encoding; +use uhlc::Timestamp; +use zenoh_buffers::ZBuf; + +/// # Put message +/// +/// ```text +/// Flags: +/// - T: Timestamp If T==1 then the timestamp if present +/// - E: Encoding If E==1 then the encoding is present +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|E|T| PUT | +/// +-+-+-+---------+ +/// ~ ts: ~ if T==1 +/// +---------------+ +/// ~ encoding ~ if E==1 +/// +---------------+ +/// ~ [put_exts] ~ if Z==1 +/// +---------------+ +/// ~ pl: ~ -- Payload +/// +---------------+ +/// ``` +pub mod flag { + pub const T: u8 = 1 << 5; // 0x20 Timestamp if T==0 then the timestamp if present + pub const E: u8 = 1 << 6; // 0x40 Encoding if E==1 then the encoding is present + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Put { + pub timestamp: Option, + pub encoding: Encoding, + pub ext_sinfo: Option, + pub payload: ZBuf, +} + +pub mod ext { + use crate::core::ZenohId; + use crate::{common::ZExtZBuf, zextzbuf}; + + /// # SourceInfo extension + /// Used to carry additional information about + pub type SourceInfo = zextzbuf!(0x1, false); + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |zid_len|X|X|X|X| + /// +-------+-+-+---+ + /// ~ zid ~ + /// +---------------+ + /// % eid % -- Counter decided by the Zenoh Node + /// +---------------+ + /// % sn % + /// +---------------+ + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct SourceInfoType { + pub zid: ZenohId, + pub eid: u32, + pub sn: u32, + } + + impl SourceInfoType { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let zid = ZenohId::rand(); + let eid: u32 = rng.gen(); + let sn: u32 = rng.gen(); + Self { zid, eid, sn } + } + } +} + +impl Put { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use crate::core::ZenohId; + use core::convert::TryFrom; + use rand::Rng; + let mut rng = rand::thread_rng(); + + let timestamp = rng.gen_bool(0.5).then_some({ + let time = uhlc::NTP64(rng.gen()); + let id = uhlc::ID::try_from(ZenohId::rand().as_slice()).unwrap(); + Timestamp::new(time, id) + }); + let encoding = Encoding::rand(); + let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + let payload = ZBuf::rand(rng.gen_range(1..=64)); + + Self { + timestamp, + encoding, + ext_sinfo, + payload, + } + } +} From 126ac024e9d3c3e29c651accad3622f78509fe5d Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 29 Mar 2023 14:42:57 +0200 Subject: [PATCH 119/203] Del message --- commons/zenoh-codec/src/zenoh_new/del.rs | 114 ++++++++++++++++++++ commons/zenoh-codec/src/zenoh_new/mod.rs | 15 ++- commons/zenoh-codec/tests/codec.rs | 5 + commons/zenoh-protocol/src/zenoh_new/del.rs | 72 +++++++++++++ commons/zenoh-protocol/src/zenoh_new/mod.rs | 12 ++- commons/zenoh-protocol/src/zenoh_new/put.rs | 2 +- 6 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 commons/zenoh-codec/src/zenoh_new/del.rs create mode 100644 commons/zenoh-protocol/src/zenoh_new/del.rs diff --git a/commons/zenoh-codec/src/zenoh_new/del.rs b/commons/zenoh-codec/src/zenoh_new/del.rs new file mode 100644 index 0000000000..e2570cda36 --- /dev/null +++ b/commons/zenoh-codec/src/zenoh_new/del.rs @@ -0,0 +1,114 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{iext, imsg}, + zenoh_new::{ + del::{ext, flag, Del}, + id, + }, +}; + +impl WCodec<&Del, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Del) -> Self::Output { + // Header + let mut header = id::DEL; + if x.timestamp.is_some() { + header |= flag::T; + } + let mut n_exts = (x.ext_sinfo.is_some()) as u8; + if n_exts != 0 { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + if let Some(ts) = x.timestamp.as_ref() { + self.write(&mut *writer, ts)?; + } + + // Extensions + if let Some(sinfo) = x.ext_sinfo.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (sinfo, n_exts != 0))?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::DEL { + return Err(DidntRead); + } + + // Body + let mut timestamp: Option = None; + if imsg::has_flag(self.header, flag::T) { + timestamp = Some(self.codec.read(&mut *reader)?); + } + + // Extensions + let mut ext_sinfo: Option = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + ext::SourceInfo::ID => { + let (s, ext): (ext::SourceInfoType, bool) = eodec.read(&mut *reader)?; + ext_sinfo = Some(s); + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "Del", ext)?; + } + } + } + + Ok(Del { + timestamp, + ext_sinfo, + }) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs index c6863030f4..376e2cb24a 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -11,13 +11,18 @@ // Contributors: // ZettaScale Zenoh Team, // +pub mod del; pub mod put; -use zenoh_buffers::reader::{DidntRead, Reader}; -use zenoh_buffers::writer::{DidntWrite, Writer}; -use zenoh_protocol::common::imsg; -use zenoh_protocol::zenoh_new::{id, PushBody}; use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::imsg, + zenoh_new::{id, PushBody}, +}; // PushBody impl WCodec<&PushBody, &mut W> for Zenoh080 @@ -29,6 +34,7 @@ where fn write(self, writer: &mut W, x: &PushBody) -> Self::Output { match x { PushBody::Put(b) => self.write(&mut *writer, b), + PushBody::Del(b) => self.write(&mut *writer, b), } } } @@ -45,6 +51,7 @@ where let codec = Zenoh080Header::new(header); let body = match imsg::mid(codec.header) { id::PUT => PushBody::Put(codec.read(&mut *reader)?), + id::DEL => PushBody::Del(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index ca2f3b32a9..ce4a43b334 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -537,6 +537,11 @@ fn codec_put() { run!(zenoh_new::Put, zenoh_new::Put::rand()); } +#[test] +fn codec_del() { + run!(zenoh_new::Del, zenoh_new::Del::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { diff --git a/commons/zenoh-protocol/src/zenoh_new/del.rs b/commons/zenoh-protocol/src/zenoh_new/del.rs new file mode 100644 index 0000000000..cfcc32706e --- /dev/null +++ b/commons/zenoh-protocol/src/zenoh_new/del.rs @@ -0,0 +1,72 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use uhlc::Timestamp; + +/// # Put message +/// +/// ```text +/// Flags: +/// - T: Timestamp If T==1 then the timestamp if present +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|X|T| PUT | +/// +-+-+-+---------+ +/// ~ ts: ~ if T==1 +/// +---------------+ +/// ~ [del_exts] ~ if Z==1 +/// +---------------+ +/// ``` +pub mod flag { + pub const T: u8 = 1 << 5; // 0x20 Timestamp if T==0 then the timestamp if present + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Del { + pub timestamp: Option, + pub ext_sinfo: Option, +} + +pub mod ext { + /// # SourceInfo extension + /// Used to carry additional information about the source of data + pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; + pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; +} + +impl Del { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use crate::core::ZenohId; + use core::convert::TryFrom; + use rand::Rng; + let mut rng = rand::thread_rng(); + + let timestamp = rng.gen_bool(0.5).then_some({ + let time = uhlc::NTP64(rng.gen()); + let id = uhlc::ID::try_from(ZenohId::rand().as_slice()).unwrap(); + Timestamp::new(time, id) + }); + let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + + Self { + timestamp, + ext_sinfo, + } + } +} diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index 42035d4f46..d7e965637b 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -11,8 +11,10 @@ // Contributors: // ZettaScale Zenoh Team, // +pub mod del; pub mod put; +pub use del::*; pub use put::*; pub mod id { @@ -24,6 +26,7 @@ pub mod id { #[derive(Debug, Clone, PartialEq, Eq)] pub enum PushBody { Put(Put), + Del(Del), } impl PushBody { @@ -33,8 +36,9 @@ impl PushBody { let mut rng = rand::thread_rng(); - match rng.gen_range(0..1) { + match rng.gen_range(0..2) { 0 => PushBody::Put(Put::rand()), + 1 => PushBody::Del(Del::rand()), _ => unreachable!(), } } @@ -45,3 +49,9 @@ impl From for PushBody { PushBody::Put(p) } } + +impl From for PushBody { + fn from(d: Del) -> PushBody { + PushBody::Del(d) + } +} diff --git a/commons/zenoh-protocol/src/zenoh_new/put.rs b/commons/zenoh-protocol/src/zenoh_new/put.rs index 7bf6ab5ff6..0c6b5535ad 100644 --- a/commons/zenoh-protocol/src/zenoh_new/put.rs +++ b/commons/zenoh-protocol/src/zenoh_new/put.rs @@ -55,7 +55,7 @@ pub mod ext { use crate::{common::ZExtZBuf, zextzbuf}; /// # SourceInfo extension - /// Used to carry additional information about + /// Used to carry additional information about the source of data pub type SourceInfo = zextzbuf!(0x1, false); /// 7 6 5 4 3 2 1 0 From 92e3abd6fbc587c85e9303ecc098fd677d4cb0c6 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 29 Mar 2023 18:39:07 +0200 Subject: [PATCH 120/203] New Query message --- commons/zenoh-codec/src/core/encoding.rs | 8 +- commons/zenoh-codec/src/core/mod.rs | 12 + commons/zenoh-codec/src/core/zint.rs | 18 +- commons/zenoh-codec/src/network/request.rs | 4 +- commons/zenoh-codec/src/zenoh_new/mod.rs | 42 +++- commons/zenoh-codec/src/zenoh_new/put.rs | 26 +- commons/zenoh-codec/src/zenoh_new/query.rs | 224 ++++++++++++++++++ commons/zenoh-codec/tests/codec.rs | 30 +++ commons/zenoh-protocol/src/network/request.rs | 6 +- commons/zenoh-protocol/src/zenoh_new/mod.rs | 46 ++++ commons/zenoh-protocol/src/zenoh_new/put.rs | 2 +- commons/zenoh-protocol/src/zenoh_new/query.rs | 147 ++++++++++++ 12 files changed, 536 insertions(+), 29 deletions(-) create mode 100644 commons/zenoh-codec/src/zenoh_new/query.rs create mode 100644 commons/zenoh-protocol/src/zenoh_new/query.rs diff --git a/commons/zenoh-codec/src/core/encoding.rs b/commons/zenoh-codec/src/core/encoding.rs index 36259b8b9f..ac4bb36844 100644 --- a/commons/zenoh-codec/src/core/encoding.rs +++ b/commons/zenoh-codec/src/core/encoding.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; +use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use alloc::string::String; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -19,6 +19,12 @@ use zenoh_buffers::{ }; use zenoh_protocol::core::Encoding; +impl LCodec<&Encoding> for Zenoh080 { + fn w_len(self, x: &Encoding) -> usize { + 1 + self.w_len(x.suffix()) + } +} + impl WCodec<&Encoding, &mut W> for Zenoh080 where W: Writer, diff --git a/commons/zenoh-codec/src/core/mod.rs b/commons/zenoh-codec/src/core/mod.rs index d1cd8b4c94..dba0e09c1c 100644 --- a/commons/zenoh-codec/src/core/mod.rs +++ b/commons/zenoh-codec/src/core/mod.rs @@ -215,6 +215,18 @@ str_impl!(u64); str_impl!(usize); // &str / String +impl LCodec<&str> for Zenoh080 { + fn w_len(self, x: &str) -> usize { + self.w_len(x.as_bytes()) + } +} + +impl LCodec<&String> for Zenoh080 { + fn w_len(self, x: &String) -> usize { + self.w_len(x.as_bytes()) + } +} + impl WCodec<&str, &mut W> for Zenoh080 where W: Writer, diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 428169b1cd..65c35ce38e 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -22,15 +22,15 @@ const VLE_LEN: usize = 10; impl LCodec for Zenoh080 { fn w_len(self, x: u64) -> usize { - const B1: u64 = !(u64::MAX << 7); - const B2: u64 = !(u64::MAX << (7 * 2)); - const B3: u64 = !(u64::MAX << (7 * 3)); - const B4: u64 = !(u64::MAX << (7 * 4)); - const B5: u64 = !(u64::MAX << (7 * 5)); - const B6: u64 = !(u64::MAX << (7 * 6)); - const B7: u64 = !(u64::MAX << (7 * 7)); - const B8: u64 = !(u64::MAX << (7 * 8)); - const B9: u64 = !(u64::MAX << (7 * 9)); + const B1: u64 = u64::MAX << 7; + const B2: u64 = u64::MAX << (7 * 2); + const B3: u64 = u64::MAX << (7 * 3); + const B4: u64 = u64::MAX << (7 * 4); + const B5: u64 = u64::MAX << (7 * 5); + const B6: u64 = u64::MAX << (7 * 6); + const B7: u64 = u64::MAX << (7 * 7); + const B8: u64 = u64::MAX << (7 * 8); + const B9: u64 = u64::MAX << (7 * 9); if (x & B1) == 0 { 1 diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 5d3da5a722..843ec02f1d 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -24,6 +24,7 @@ use zenoh_protocol::{ request::{ext, flag}, Mapping, Request, RequestId, }, + zenoh_new::RequestBody, }; // Destination @@ -218,8 +219,7 @@ where } // Payload - // let payload: ZenohMessage = self.codec.read(&mut *reader)?; - let payload: u8 = self.codec.read(&mut *reader)?; // @TODO + let payload: RequestBody = self.codec.read(&mut *reader)?; Ok(Request { id, diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs index 376e2cb24a..7f90a9d19c 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -13,6 +13,7 @@ // pub mod del; pub mod put; +pub mod query; use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ @@ -21,10 +22,10 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - zenoh_new::{id, PushBody}, + zenoh_new::{id, PushBody, RequestBody}, }; -// PushBody +// Push impl WCodec<&PushBody, &mut W> for Zenoh080 where W: Writer, @@ -58,3 +59,40 @@ where Ok(body) } } + +// Request +impl WCodec<&RequestBody, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &RequestBody) -> Self::Output { + match x { + RequestBody::Query(b) => self.write(&mut *writer, b), + RequestBody::Put(b) => self.write(&mut *writer, b), + RequestBody::Del(b) => self.write(&mut *writer, b), + } + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + + let codec = Zenoh080Header::new(header); + let body = match imsg::mid(codec.header) { + id::QUERY => RequestBody::Query(codec.read(&mut *reader)?), + id::PUT => RequestBody::Put(codec.read(&mut *reader)?), + id::DEL => RequestBody::Del(codec.read(&mut *reader)?), + _ => return Err(DidntRead), + }; + + Ok(body) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/put.rs b/commons/zenoh-codec/src/zenoh_new/put.rs index 708ea9effa..f1d3fbcbc4 100644 --- a/commons/zenoh-codec/src/zenoh_new/put.rs +++ b/commons/zenoh-codec/src/zenoh_new/put.rs @@ -11,7 +11,10 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; +use crate::{ + common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header, + Zenoh080Length, +}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -39,19 +42,18 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: (&ext::SourceInfoType, bool)) -> Self::Output { - let (sinfo, more) = x; - let header: ZExtZBufHeader<{ ext::SourceInfo::ID }> = - ZExtZBufHeader::new(self.w_len(sinfo)); + let (x, more) = x; + let header: ZExtZBufHeader<{ ext::SourceInfo::ID }> = ZExtZBufHeader::new(self.w_len(x)); self.write(&mut *writer, (&header, more))?; - let flags: u8 = (sinfo.zid.size() as u8 - 1) << 4; + let flags: u8 = (x.zid.size() as u8 - 1) << 4; self.write(&mut *writer, flags)?; - let lodec = Zenoh080Length::new(sinfo.zid.size()); - lodec.write(&mut *writer, &sinfo.zid)?; + let lodec = Zenoh080Length::new(x.zid.size()); + lodec.write(&mut *writer, &x.zid)?; - self.write(&mut *writer, sinfo.eid)?; - self.write(&mut *writer, sinfo.sn)?; + self.write(&mut *writer, x.eid)?; + self.write(&mut *writer, x.sn)?; Ok(()) } } @@ -114,7 +116,8 @@ where } // Payload - self.write(&mut *writer, &x.payload)?; + let bodec = Zenoh080Bounded::::new(); + bodec.write(&mut *writer, &x.payload)?; Ok(()) } @@ -175,7 +178,8 @@ where } // Payload - let payload: ZBuf = self.codec.read(&mut *reader)?; + let bodec = Zenoh080Bounded::::new(); + let payload: ZBuf = bodec.read(&mut *reader)?; Ok(Put { timestamp, diff --git a/commons/zenoh-codec/src/zenoh_new/query.rs b/commons/zenoh-codec/src/zenoh_new/query.rs new file mode 100644 index 0000000000..8e07f0c63f --- /dev/null +++ b/commons/zenoh-codec/src/zenoh_new/query.rs @@ -0,0 +1,224 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, + SplitBuffer, ZBuf, +}; +use zenoh_protocol::{ + common::{iext, imsg, ZExtZBufHeader}, + core::Encoding, + zenoh_new::{ + id, + query::{ext, flag, Query}, + ConsolidationMode, + }, +}; + +impl LCodec<&ext::QueryBodyType> for Zenoh080 { + fn w_len(self, x: &ext::QueryBodyType) -> usize { + self.w_len(&x.encoding) + x.payload.len() + } +} + +impl WCodec<(&ext::QueryBodyType, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::QueryBodyType, bool)) -> Self::Output { + let (x, more) = x; + let header: ZExtZBufHeader<{ ext::QueryBody::ID }> = ZExtZBufHeader::new(self.w_len(x)); + self.write(&mut *writer, (&header, more))?; + + self.write(&mut *writer, &x.encoding)?; + // Don't write the length since it is already included in the header + for s in x.payload.zslices() { + writer.write_zslice(s)?; + } + + Ok(()) + } +} + +impl RCodec<(ext::QueryBodyType, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QueryBodyType, bool), Self::Error> { + let (header, more): (ZExtZBufHeader<{ ext::QueryBody::ID }>, bool) = + self.read(&mut *reader)?; + + let start = reader.remaining(); + let encoding: Encoding = self.codec.read(&mut *reader)?; + let end = reader.remaining(); + // Calculate how many bytes are left in the payload + let len = header.len - (start - end); + let mut payload = ZBuf::empty(); + reader.read_zslices(len, |s| payload.push_zslice(s))?; + + Ok((ext::QueryBodyType { encoding, payload }, more)) + } +} + +// Consolidation +impl WCodec for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: ConsolidationMode) -> Self::Output { + let v: u8 = match x { + ConsolidationMode::None => 0, + ConsolidationMode::Monotonic => 1, + ConsolidationMode::Latest => 2, + }; + self.write(&mut *writer, v) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let v: u8 = self.read(&mut *reader)?; + let c = match v { + 0 => ConsolidationMode::None, + 1 => ConsolidationMode::Monotonic, + 2 => ConsolidationMode::Latest, + _ => return Err(DidntRead), + }; + Ok(c) + } +} + +impl WCodec<&Query, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Query) -> Self::Output { + // Header + let mut header = id::QUERY; + if !x.parameters.is_empty() { + header |= flag::P; + } + if x.consolidation != ConsolidationMode::default() { + header |= flag::C; + } + let mut n_exts = (x.ext_sinfo.is_some() as u8) + (x.ext_body.is_some() as u8); + if n_exts != 0 { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + if !x.parameters.is_empty() { + self.write(&mut *writer, &x.parameters)?; + } + if x.consolidation != ConsolidationMode::default() { + self.write(&mut *writer, x.consolidation)?; + } + + // Extensions + if let Some(sinfo) = x.ext_sinfo.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (sinfo, n_exts != 0))?; + } + if let Some(body) = x.ext_body.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (body, n_exts != 0))?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::QUERY { + return Err(DidntRead); + } + + // Body + let mut parameters = String::new(); + if imsg::has_flag(self.header, flag::P) { + parameters = self.codec.read(&mut *reader)?; + } + + let mut consolidation = ConsolidationMode::default(); + if imsg::has_flag(self.header, flag::C) { + consolidation = self.codec.read(&mut *reader)?; + } + + // Extensions + let mut ext_sinfo: Option = None; + let mut ext_body: Option = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + ext::SourceInfo::ID => { + let (s, ext): (ext::SourceInfoType, bool) = eodec.read(&mut *reader)?; + ext_sinfo = Some(s); + has_ext = ext; + } + ext::QueryBody::ID => { + let (s, ext): (ext::QueryBodyType, bool) = eodec.read(&mut *reader)?; + ext_body = Some(s); + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "Put", ext)?; + } + } + } + + Ok(Query { + parameters, + consolidation, + ext_sinfo, + ext_body, + }) + } +} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index ce4a43b334..7c0bc06c39 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -129,6 +129,31 @@ fn codec_zint() { run!(usize, thread_rng().gen::()); } +#[test] +fn codec_zint_len() { + let codec = Zenoh080::new(); + + let mut buff = vec![]; + let mut writer = buff.writer(); + let n: u64 = 0; + codec.write(&mut writer, n).unwrap(); + assert_eq!(codec.w_len(n), buff.len()); + + for i in 1..=9 { + let mut buff = vec![]; + let mut writer = buff.writer(); + let n: u64 = 1 << (7 * i); + codec.write(&mut writer, n).unwrap(); + assert_eq!(codec.w_len(n), buff.len()); + } + + let mut buff = vec![]; + let mut writer = buff.writer(); + let n = u64::MAX; + codec.write(&mut writer, n).unwrap(); + assert_eq!(codec.w_len(n), buff.len()); +} + #[test] fn codec_zint_bounded() { use crate::Zenoh080Bounded; @@ -542,6 +567,11 @@ fn codec_del() { run!(zenoh_new::Del, zenoh_new::Del::rand()); } +#[test] +fn codec_query() { + run!(zenoh_new::Query, zenoh_new::Query::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index 0ec13a05f6..ebef45733a 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -1,3 +1,4 @@ +use crate::zenoh_new::RequestBody; // // Copyright (c) 2022 ZettaScale Technology // @@ -55,7 +56,7 @@ pub struct Request { pub id: RequestId, pub wire_expr: WireExpr<'static>, pub mapping: Mapping, - pub payload: u8, // @TODO + pub payload: RequestBody, pub ext_qos: ext::QoSType, pub ext_tstamp: Option, pub ext_dst: ext::DestinationType, @@ -145,8 +146,7 @@ impl Request { let wire_expr = WireExpr::rand(); let mapping = Mapping::rand(); let id: RequestId = rng.gen(); - // let payload = ZenohMessage::rand(); - let payload: u8 = rng.gen(); // @TODO + let payload = RequestBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); let ext_dst = ext::DestinationType::rand(); diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index d7e965637b..ac0e866ead 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -13,16 +13,20 @@ // pub mod del; pub mod put; +pub mod query; pub use del::*; pub use put::*; +pub use query::*; pub mod id { pub const OAM: u8 = 0x00; pub const PUT: u8 = 0x01; pub const DEL: u8 = 0x02; + pub const QUERY: u8 = 0x03; } +// Push #[derive(Debug, Clone, PartialEq, Eq)] pub enum PushBody { Put(Put), @@ -55,3 +59,45 @@ impl From for PushBody { PushBody::Del(d) } } + +// Request +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum RequestBody { + Query(Query), + Put(Put), + Del(Del), +} + +impl RequestBody { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + match rng.gen_range(0..3) { + 0 => RequestBody::Query(Query::rand()), + 1 => RequestBody::Put(Put::rand()), + 2 => RequestBody::Del(Del::rand()), + _ => unreachable!(), + } + } +} + +impl From for RequestBody { + fn from(q: Query) -> RequestBody { + RequestBody::Query(q) + } +} + +impl From for RequestBody { + fn from(p: Put) -> RequestBody { + RequestBody::Put(p) + } +} + +impl From for RequestBody { + fn from(d: Del) -> RequestBody { + RequestBody::Del(d) + } +} diff --git a/commons/zenoh-protocol/src/zenoh_new/put.rs b/commons/zenoh-protocol/src/zenoh_new/put.rs index 0c6b5535ad..655bfb8145 100644 --- a/commons/zenoh-protocol/src/zenoh_new/put.rs +++ b/commons/zenoh-protocol/src/zenoh_new/put.rs @@ -33,7 +33,7 @@ use zenoh_buffers::ZBuf; /// +---------------+ /// ~ [put_exts] ~ if Z==1 /// +---------------+ -/// ~ pl: ~ -- Payload +/// ~ pl: ~ -- Payload /// +---------------+ /// ``` pub mod flag { diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs new file mode 100644 index 0000000000..f0badc7b33 --- /dev/null +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -0,0 +1,147 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +/// The kind of consolidation. +#[repr(u8)] +#[derive(Debug, Default, Clone, PartialEq, Eq, Copy)] +pub enum ConsolidationMode { + /// No consolidation applied: multiple samples may be received for the same key-timestamp. + None, + /// Monotonic consolidation immediately forwards samples, except if one with an equal or more recent timestamp + /// has already been sent with the same key. + /// + /// This optimizes latency while potentially reducing bandwidth. + /// + /// Note that this doesn't cause re-ordering, but drops the samples for which a more recent timestamp has already + /// been observed with the same key. + Monotonic, + /// Holds back samples to only send the set of samples that had the highest timestamp for their key. + #[default] + Latest, +} + +impl ConsolidationMode { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::prelude::SliceRandom; + let mut rng = rand::thread_rng(); + + *[Self::None, Self::Monotonic, Self::Latest] + .choose(&mut rng) + .unwrap() + } +} + +/// # Query message +/// +/// ```text +/// Flags: +/// - P: Parameters If P==1 then the parameters are present +/// - C: Consolidation If C==1 then the consolidation is present +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|C|P| QUERY | +/// +-+-+-+---------+ +/// ~ ps: ~ if P==1 +/// +---------------+ +/// ~ consolidation ~ if C==1 +/// +---------------+ +/// ~ [qry_exts] ~ if Z==1 +/// +---------------+ +/// ``` +pub mod flag { + pub const P: u8 = 1 << 5; // 0x20 Parameters if P==1 then the parameters are present + pub const C: u8 = 1 << 6; // 0x40 Consolidation if C==1 then the consolidation is present + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Query { + pub parameters: String, + pub consolidation: ConsolidationMode, + pub ext_sinfo: Option, + pub ext_body: Option, +} + +pub mod ext { + use crate::{common::ZExtZBuf, core::Encoding, zextzbuf}; + use zenoh_buffers::ZBuf; + + /// # SourceInfo extension + /// Used to carry additional information about the source of data + pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; + pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; + + /// # QueryBody extension + /// Used to carry a body attached to the query + pub type QueryBody = zextzbuf!(0x02, false); + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// ~ encoding ~ + /// +---------------+ + /// ~ pl: [u8;z32] ~ -- Payload + /// +---------------+ + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct QueryBodyType { + pub encoding: Encoding, + pub payload: ZBuf, + } + + impl QueryBodyType { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let encoding = Encoding::rand(); + let payload = ZBuf::rand(rng.gen_range(1..=64)); + + Self { encoding, payload } + } + } +} + +impl Query { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::{ + distributions::{Alphanumeric, DistString}, + Rng, + }; + let mut rng = rand::thread_rng(); + + const MIN: usize = 2; + const MAX: usize = 16; + + let parameters: String = if rng.gen_bool(0.5) { + let len = rng.gen_range(MIN..MAX); + Alphanumeric.sample_string(&mut rng, len) + } else { + String::new() + }; + let consolidation = ConsolidationMode::rand(); + let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + let ext_body = rng.gen_bool(0.5).then_some(ext::QueryBodyType::rand()); + + Self { + parameters, + consolidation, + ext_sinfo, + ext_body, + } + } +} From 2b8fd28ddd3b6daa8e57bec415d1798aa4f0afb2 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 29 Mar 2023 20:03:28 +0200 Subject: [PATCH 121/203] New Reply message --- commons/zenoh-codec/src/network/response.rs | 4 +- commons/zenoh-codec/src/zenoh_new/mod.rs | 36 ++++- commons/zenoh-codec/src/zenoh_new/reply.rs | 137 ++++++++++++++++++ commons/zenoh-codec/tests/codec.rs | 5 + .../zenoh-protocol/src/network/response.rs | 24 +-- commons/zenoh-protocol/src/zenoh_new/mod.rs | 29 ++++ commons/zenoh-protocol/src/zenoh_new/reply.rs | 84 +++++++++++ 7 files changed, 305 insertions(+), 14 deletions(-) create mode 100644 commons/zenoh-codec/src/zenoh_new/reply.rs create mode 100644 commons/zenoh-protocol/src/zenoh_new/reply.rs diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs index 63b7fb29cb..2ef71d0f71 100644 --- a/commons/zenoh-codec/src/network/response.rs +++ b/commons/zenoh-codec/src/network/response.rs @@ -24,6 +24,7 @@ use zenoh_protocol::{ response::{ext, flag}, Mapping, RequestId, Response, ResponseFinal, }, + zenoh_new::ResponseBody, }; // Response @@ -130,8 +131,7 @@ where } // Payload - // let payload: ZenohMessage = self.codec.read(&mut *reader)?; - let payload: u8 = self.codec.read(&mut *reader)?; // @TODO + let payload: ResponseBody = self.codec.read(&mut *reader)?; Ok(Response { rid, diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs index 7f90a9d19c..6a111d7d82 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -14,6 +14,7 @@ pub mod del; pub mod put; pub mod query; +pub mod reply; use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; use zenoh_buffers::{ @@ -22,7 +23,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::imsg, - zenoh_new::{id, PushBody, RequestBody}, + zenoh_new::{id, PushBody, RequestBody, ResponseBody}, }; // Push @@ -96,3 +97,36 @@ where Ok(body) } } + +// Response +impl WCodec<&ResponseBody, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ResponseBody) -> Self::Output { + match x { + ResponseBody::Reply(b) => self.write(&mut *writer, b), + } + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + + let codec = Zenoh080Header::new(header); + let body = match imsg::mid(codec.header) { + id::REPLY => ResponseBody::Reply(codec.read(&mut *reader)?), + _ => return Err(DidntRead), + }; + + Ok(body) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/reply.rs b/commons/zenoh-codec/src/zenoh_new/reply.rs new file mode 100644 index 0000000000..5892687485 --- /dev/null +++ b/commons/zenoh-codec/src/zenoh_new/reply.rs @@ -0,0 +1,137 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, + ZBuf, +}; +use zenoh_protocol::{ + common::{iext, imsg}, + core::Encoding, + zenoh_new::{ + id, + reply::{ext, flag, Reply}, + }, +}; + +impl WCodec<&Reply, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Reply) -> Self::Output { + // Header + let mut header = id::REPLY; + if x.timestamp.is_some() { + header |= flag::T; + } + if x.encoding != Encoding::default() { + header |= flag::E; + } + let mut n_exts = (x.ext_sinfo.is_some()) as u8; + if n_exts != 0 { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + if let Some(ts) = x.timestamp.as_ref() { + self.write(&mut *writer, ts)?; + } + if x.encoding != Encoding::default() { + self.write(&mut *writer, &x.encoding)?; + } + + // Extensions + if let Some(sinfo) = x.ext_sinfo.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (sinfo, n_exts != 0))?; + } + + // Payload + let bodec = Zenoh080Bounded::::new(); + bodec.write(&mut *writer, &x.payload)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::REPLY { + return Err(DidntRead); + } + + // Body + let mut timestamp: Option = None; + if imsg::has_flag(self.header, flag::T) { + timestamp = Some(self.codec.read(&mut *reader)?); + } + + let mut encoding = Encoding::default(); + if imsg::has_flag(self.header, flag::E) { + encoding = self.codec.read(&mut *reader)?; + } + + // Extensions + let mut ext_sinfo: Option = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + ext::SourceInfo::ID => { + let (s, ext): (ext::SourceInfoType, bool) = eodec.read(&mut *reader)?; + ext_sinfo = Some(s); + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "Reply", ext)?; + } + } + } + + // Payload + let bodec = Zenoh080Bounded::::new(); + let payload: ZBuf = bodec.read(&mut *reader)?; + + Ok(Reply { + timestamp, + encoding, + ext_sinfo, + payload, + }) + } +} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 7c0bc06c39..6cda985628 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -572,6 +572,11 @@ fn codec_query() { run!(zenoh_new::Query, zenoh_new::Query::rand()); } +#[test] +fn codec_reply() { + run!(zenoh_new::Reply, zenoh_new::Reply::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index 3f5237b874..e0c9b0d514 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -1,4 +1,3 @@ -use crate::network::Mapping; // // Copyright (c) 2022 ZettaScale Technology // @@ -12,13 +11,11 @@ use crate::network::Mapping; // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, network::RequestId}; - -pub mod flag { - pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix - pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver - pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow -} +use crate::{ + core::WireExpr, + network::{Mapping, RequestId}, + zenoh_new::ResponseBody, +}; /// # Response message /// @@ -46,12 +43,18 @@ pub mod flag { /// (*) The resolution of the request id is negotiated during the session establishment. /// This implementation limits the resolution to 32bit. /// ``` +pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct Response { pub rid: RequestId, pub wire_expr: WireExpr<'static>, pub mapping: Mapping, - pub payload: u8, // @TODO + pub payload: ResponseBody, pub ext_qos: ext::QoSType, pub ext_tstamp: Option, } @@ -73,8 +76,7 @@ impl Response { let rid: RequestId = rng.gen(); let wire_expr = WireExpr::rand(); let mapping = Mapping::rand(); - // let payload = ZenohMessage::rand(); - let payload: u8 = rng.gen(); // @TODO + let payload = ResponseBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index ac0e866ead..e124fc713b 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -14,16 +14,19 @@ pub mod del; pub mod put; pub mod query; +pub mod reply; pub use del::*; pub use put::*; pub use query::*; +pub use reply::*; pub mod id { pub const OAM: u8 = 0x00; pub const PUT: u8 = 0x01; pub const DEL: u8 = 0x02; pub const QUERY: u8 = 0x03; + pub const REPLY: u8 = 0x04; } // Push @@ -101,3 +104,29 @@ impl From for RequestBody { RequestBody::Del(d) } } + +// Response +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ResponseBody { + Reply(Reply), +} + +impl ResponseBody { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + + match rng.gen_range(0..1) { + 0 => ResponseBody::Reply(Reply::rand()), + _ => unreachable!(), + } + } +} + +impl From for ResponseBody { + fn from(r: Reply) -> ResponseBody { + ResponseBody::Reply(r) + } +} diff --git a/commons/zenoh-protocol/src/zenoh_new/reply.rs b/commons/zenoh-protocol/src/zenoh_new/reply.rs new file mode 100644 index 0000000000..3c91b849b5 --- /dev/null +++ b/commons/zenoh-protocol/src/zenoh_new/reply.rs @@ -0,0 +1,84 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::core::Encoding; +use uhlc::Timestamp; +use zenoh_buffers::ZBuf; + +/// # Reply message +/// +/// ```text +/// Flags: +/// - T: Timestamp If T==1 then the timestamp if present +/// - E: Encoding If E==1 then the encoding is present +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|E|T| REPLY | +/// +-+-+-+---------+ +/// ~ ts: ~ if T==1 +/// +---------------+ +/// ~ encoding ~ if E==1 +/// +---------------+ +/// ~ [repl_exts] ~ if Z==1 +/// +---------------+ +/// ~ pl: ~ -- Payload +/// +---------------+ +/// ``` +pub mod flag { + pub const T: u8 = 1 << 5; // 0x20 Timestamp if T==0 then the timestamp if present + pub const E: u8 = 1 << 6; // 0x40 Encoding if E==1 then the encoding is present + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Reply { + pub timestamp: Option, + pub encoding: Encoding, + pub ext_sinfo: Option, + pub payload: ZBuf, +} + +pub mod ext { + /// # SourceInfo extension + /// Used to carry additional information about the source of data + pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; + pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; +} + +impl Reply { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use crate::core::ZenohId; + use core::convert::TryFrom; + use rand::Rng; + let mut rng = rand::thread_rng(); + + let timestamp = rng.gen_bool(0.5).then_some({ + let time = uhlc::NTP64(rng.gen()); + let id = uhlc::ID::try_from(ZenohId::rand().as_slice()).unwrap(); + Timestamp::new(time, id) + }); + let encoding = Encoding::rand(); + let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + let payload = ZBuf::rand(rng.gen_range(1..=64)); + + Self { + timestamp, + encoding, + ext_sinfo, + payload, + } + } +} From f368f26b02a6d574a3092e2a03f399576c6c5935 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 30 Mar 2023 10:09:45 +0200 Subject: [PATCH 122/203] New Error message --- commons/zenoh-codec/src/zenoh_new/err.rs | 184 ++++++++++++++++++ commons/zenoh-codec/src/zenoh_new/mod.rs | 3 + commons/zenoh-codec/tests/codec.rs | 5 + commons/zenoh-protocol/src/zenoh_new/err.rs | 115 +++++++++++ commons/zenoh-protocol/src/zenoh_new/mod.rs | 13 +- commons/zenoh-protocol/src/zenoh_new/put.rs | 2 +- commons/zenoh-protocol/src/zenoh_new/query.rs | 2 +- commons/zenoh-protocol/src/zenoh_new/reply.rs | 2 +- 8 files changed, 322 insertions(+), 4 deletions(-) create mode 100644 commons/zenoh-codec/src/zenoh_new/err.rs create mode 100644 commons/zenoh-protocol/src/zenoh_new/err.rs diff --git a/commons/zenoh-codec/src/zenoh_new/err.rs b/commons/zenoh-codec/src/zenoh_new/err.rs new file mode 100644 index 0000000000..6a239aecd7 --- /dev/null +++ b/commons/zenoh-codec/src/zenoh_new/err.rs @@ -0,0 +1,184 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, + SplitBuffer, ZBuf, +}; +use zenoh_protocol::{ + common::{iext, imsg, ZExtZBufHeader}, + core::Encoding, + zenoh_new::{ + err::{ext, flag, Err}, + id, + }, +}; + +impl LCodec<&ext::ErrBodyType> for Zenoh080 { + fn w_len(self, x: &ext::ErrBodyType) -> usize { + self.w_len(&x.encoding) + x.payload.len() + } +} + +impl WCodec<(&ext::ErrBodyType, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::ErrBodyType, bool)) -> Self::Output { + let (x, more) = x; + let header: ZExtZBufHeader<{ ext::ErrBody::ID }> = ZExtZBufHeader::new(self.w_len(x)); + self.write(&mut *writer, (&header, more))?; + + self.write(&mut *writer, &x.encoding)?; + // Don't write the length since it is already included in the header + for s in x.payload.zslices() { + writer.write_zslice(s)?; + } + + Ok(()) + } +} + +impl RCodec<(ext::ErrBodyType, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::ErrBodyType, bool), Self::Error> { + let (header, more): (ZExtZBufHeader<{ ext::ErrBody::ID }>, bool) = + self.read(&mut *reader)?; + + let start = reader.remaining(); + let encoding: Encoding = self.codec.read(&mut *reader)?; + let end = reader.remaining(); + // Calculate how many bytes are left in the payload + let len = header.len - (start - end); + let mut payload = ZBuf::empty(); + reader.read_zslices(len, |s| payload.push_zslice(s))?; + + Ok((ext::ErrBodyType { encoding, payload }, more)) + } +} + +impl WCodec<&Err, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Err) -> Self::Output { + // Header + let mut header = id::ERR; + if x.timestamp.is_some() { + header |= flag::T; + } + if x.is_infrastructure { + header |= flag::I; + } + let mut n_exts = (x.ext_sinfo.is_some() as u8) + (x.ext_body.is_some() as u8); + if n_exts != 0 { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.code)?; + if let Some(ts) = x.timestamp.as_ref() { + self.write(&mut *writer, ts)?; + } + + // Extensions + if let Some(sinfo) = x.ext_sinfo.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (sinfo, n_exts != 0))?; + } + if let Some(body) = x.ext_body.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (body, n_exts != 0))?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::ERR { + return Err(DidntRead); + } + + // Body + let code: u16 = self.codec.read(&mut *reader)?; + let is_infrastructure = imsg::has_flag(self.header, flag::I); + let mut timestamp: Option = None; + if imsg::has_flag(self.header, flag::T) { + timestamp = Some(self.codec.read(&mut *reader)?); + } + + // Extensions + let mut ext_sinfo: Option = None; + let mut ext_body: Option = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + ext::SourceInfo::ID => { + let (s, ext): (ext::SourceInfoType, bool) = eodec.read(&mut *reader)?; + ext_sinfo = Some(s); + has_ext = ext; + } + ext::ErrBody::ID => { + let (s, ext): (ext::ErrBodyType, bool) = eodec.read(&mut *reader)?; + ext_body = Some(s); + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "Put", ext)?; + } + } + } + + Ok(Err { + code, + is_infrastructure, + timestamp, + ext_sinfo, + ext_body, + }) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs index 6a111d7d82..ed17814043 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // pub mod del; +pub mod err; pub mod put; pub mod query; pub mod reply; @@ -108,6 +109,7 @@ where fn write(self, writer: &mut W, x: &ResponseBody) -> Self::Output { match x { ResponseBody::Reply(b) => self.write(&mut *writer, b), + ResponseBody::Err(b) => self.write(&mut *writer, b), } } } @@ -124,6 +126,7 @@ where let codec = Zenoh080Header::new(header); let body = match imsg::mid(codec.header) { id::REPLY => ResponseBody::Reply(codec.read(&mut *reader)?), + id::ERR => ResponseBody::Err(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 6cda985628..c5a60933c7 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -577,6 +577,11 @@ fn codec_reply() { run!(zenoh_new::Reply, zenoh_new::Reply::rand()); } +#[test] +fn codec_err() { + run!(zenoh_new::Err, zenoh_new::Err::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { diff --git a/commons/zenoh-protocol/src/zenoh_new/err.rs b/commons/zenoh-protocol/src/zenoh_new/err.rs new file mode 100644 index 0000000000..500d8da99d --- /dev/null +++ b/commons/zenoh-protocol/src/zenoh_new/err.rs @@ -0,0 +1,115 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use uhlc::Timestamp; + +/// # Err message +/// +/// ```text +/// Flags: +/// - T: Timestamp If T==1 then the timestamp if present +/// - I: Infrastructure If I==1 then the error is related to the infrastructure +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|I|T| ERR | +/// +-+-+-+---------+ +/// % code:z16 % +/// +---------------+ +/// ~ ts: ~ if T==1 +/// +---------------+ +/// ~ [err_exts] ~ if Z==1 +/// +---------------+ +/// ``` +pub mod flag { + pub const T: u8 = 1 << 5; // 0x20 Timestamp if T==0 then the timestamp if present + pub const I: u8 = 1 << 6; // 0x40 Reserved if I==1 then the error is related to the infrastructure + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Err { + pub code: u16, + pub is_infrastructure: bool, + pub timestamp: Option, + pub ext_sinfo: Option, + pub ext_body: Option, +} + +pub mod ext { + use crate::{common::ZExtZBuf, core::Encoding, zextzbuf}; + use zenoh_buffers::ZBuf; + + /// # SourceInfo extension + /// Used to carry additional information about the source of data + pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; + pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; + + /// # ErrBody extension + /// Used to carry a body attached to the error + pub type ErrBody = zextzbuf!(0x02, false); + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// ~ encoding ~ + /// +---------------+ + /// ~ pl: [u8;z32] ~ -- Payload + /// +---------------+ + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct ErrBodyType { + pub encoding: Encoding, + pub payload: ZBuf, + } + + impl ErrBodyType { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let encoding = Encoding::rand(); + let payload = ZBuf::rand(rng.gen_range(1..=64)); + + Self { encoding, payload } + } + } +} + +impl Err { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use crate::core::ZenohId; + use core::convert::TryFrom; + use rand::Rng; + let mut rng = rand::thread_rng(); + + let code: u16 = rng.gen(); + let is_infrastructure = rng.gen_bool(0.5); + let timestamp = rng.gen_bool(0.5).then_some({ + let time = uhlc::NTP64(rng.gen()); + let id = uhlc::ID::try_from(ZenohId::rand().as_slice()).unwrap(); + Timestamp::new(time, id) + }); + let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + let ext_body = rng.gen_bool(0.5).then_some(ext::ErrBodyType::rand()); + + Self { + code, + is_infrastructure, + timestamp, + ext_sinfo, + ext_body, + } + } +} diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index e124fc713b..d47d8c30fc 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -12,11 +12,13 @@ // ZettaScale Zenoh Team, // pub mod del; +pub mod err; pub mod put; pub mod query; pub mod reply; pub use del::*; +pub use err::*; pub use put::*; pub use query::*; pub use reply::*; @@ -27,6 +29,7 @@ pub mod id { pub const DEL: u8 = 0x02; pub const QUERY: u8 = 0x03; pub const REPLY: u8 = 0x04; + pub const ERR: u8 = 0x05; } // Push @@ -109,6 +112,7 @@ impl From for RequestBody { #[derive(Debug, Clone, PartialEq, Eq)] pub enum ResponseBody { Reply(Reply), + Err(Err), } impl ResponseBody { @@ -118,8 +122,9 @@ impl ResponseBody { let mut rng = rand::thread_rng(); - match rng.gen_range(0..1) { + match rng.gen_range(0..2) { 0 => ResponseBody::Reply(Reply::rand()), + 1 => ResponseBody::Err(Err::rand()), _ => unreachable!(), } } @@ -130,3 +135,9 @@ impl From for ResponseBody { ResponseBody::Reply(r) } } + +impl From for ResponseBody { + fn from(r: Err) -> ResponseBody { + ResponseBody::Err(r) + } +} diff --git a/commons/zenoh-protocol/src/zenoh_new/put.rs b/commons/zenoh-protocol/src/zenoh_new/put.rs index 655bfb8145..db8872513a 100644 --- a/commons/zenoh-protocol/src/zenoh_new/put.rs +++ b/commons/zenoh-protocol/src/zenoh_new/put.rs @@ -33,7 +33,7 @@ use zenoh_buffers::ZBuf; /// +---------------+ /// ~ [put_exts] ~ if Z==1 /// +---------------+ -/// ~ pl: ~ -- Payload +/// ~ pl: ~ -- Payload /// +---------------+ /// ``` pub mod flag { diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs index f0badc7b33..b28cd18627 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -93,7 +93,7 @@ pub mod ext { /// +-+-+-+-+-+-+-+-+ /// ~ encoding ~ /// +---------------+ - /// ~ pl: [u8;z32] ~ -- Payload + /// ~ pl: [u8;z32] ~ -- Payload /// +---------------+ #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryBodyType { diff --git a/commons/zenoh-protocol/src/zenoh_new/reply.rs b/commons/zenoh-protocol/src/zenoh_new/reply.rs index 3c91b849b5..d21d0a2731 100644 --- a/commons/zenoh-protocol/src/zenoh_new/reply.rs +++ b/commons/zenoh-protocol/src/zenoh_new/reply.rs @@ -33,7 +33,7 @@ use zenoh_buffers::ZBuf; /// +---------------+ /// ~ [repl_exts] ~ if Z==1 /// +---------------+ -/// ~ pl: ~ -- Payload +/// ~ pl: ~ -- Payload /// +---------------+ /// ``` pub mod flag { From 932554471d92e59339493474bdf899db5a91d2ef Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 30 Mar 2023 10:37:03 +0200 Subject: [PATCH 123/203] New Ack message --- commons/zenoh-codec/src/zenoh_new/ack.rs | 114 ++++++++++++++++++++ commons/zenoh-codec/src/zenoh_new/mod.rs | 3 + commons/zenoh-codec/tests/codec.rs | 5 + commons/zenoh-protocol/src/zenoh_new/ack.rs | 72 +++++++++++++ commons/zenoh-protocol/src/zenoh_new/err.rs | 8 +- commons/zenoh-protocol/src/zenoh_new/mod.rs | 13 ++- 6 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 commons/zenoh-codec/src/zenoh_new/ack.rs create mode 100644 commons/zenoh-protocol/src/zenoh_new/ack.rs diff --git a/commons/zenoh-codec/src/zenoh_new/ack.rs b/commons/zenoh-codec/src/zenoh_new/ack.rs new file mode 100644 index 0000000000..332811ad03 --- /dev/null +++ b/commons/zenoh-codec/src/zenoh_new/ack.rs @@ -0,0 +1,114 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{iext, imsg}, + zenoh_new::{ + ack::{ext, flag, Ack}, + id, + }, +}; + +impl WCodec<&Ack, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Ack) -> Self::Output { + // Header + let mut header = id::ACK; + if x.timestamp.is_some() { + header |= flag::T; + } + let mut n_exts = (x.ext_sinfo.is_some()) as u8; + if n_exts != 0 { + header |= flag::Z; + } + self.write(&mut *writer, header)?; + + // Body + if let Some(ts) = x.timestamp.as_ref() { + self.write(&mut *writer, ts)?; + } + + // Extensions + if let Some(sinfo) = x.ext_sinfo.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (sinfo, n_exts != 0))?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::ACK { + return Err(DidntRead); + } + + // Body + let mut timestamp: Option = None; + if imsg::has_flag(self.header, flag::T) { + timestamp = Some(self.codec.read(&mut *reader)?); + } + + // Extensions + let mut ext_sinfo: Option = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + ext::SourceInfo::ID => { + let (s, ext): (ext::SourceInfoType, bool) = eodec.read(&mut *reader)?; + ext_sinfo = Some(s); + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "Ack", ext)?; + } + } + } + + Ok(Ack { + timestamp, + ext_sinfo, + }) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs index ed17814043..27a3f4c036 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // +pub mod ack; pub mod del; pub mod err; pub mod put; @@ -110,6 +111,7 @@ where match x { ResponseBody::Reply(b) => self.write(&mut *writer, b), ResponseBody::Err(b) => self.write(&mut *writer, b), + ResponseBody::Ack(b) => self.write(&mut *writer, b), } } } @@ -127,6 +129,7 @@ where let body = match imsg::mid(codec.header) { id::REPLY => ResponseBody::Reply(codec.read(&mut *reader)?), id::ERR => ResponseBody::Err(codec.read(&mut *reader)?), + id::ACK => ResponseBody::Ack(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index c5a60933c7..159294a300 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -582,6 +582,11 @@ fn codec_err() { run!(zenoh_new::Err, zenoh_new::Err::rand()); } +#[test] +fn codec_ack() { + run!(zenoh_new::Ack, zenoh_new::Ack::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { diff --git a/commons/zenoh-protocol/src/zenoh_new/ack.rs b/commons/zenoh-protocol/src/zenoh_new/ack.rs new file mode 100644 index 0000000000..97eccb1f57 --- /dev/null +++ b/commons/zenoh-protocol/src/zenoh_new/ack.rs @@ -0,0 +1,72 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use uhlc::Timestamp; + +/// # Ack message +/// +/// ```text +/// Flags: +/// - T: Timestamp If T==1 then the timestamp if present +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|X|T| ACK | +/// +-+-+-+---------+ +/// ~ ts: ~ if T==1 +/// +---------------+ +/// ~ [err_exts] ~ if Z==1 +/// +---------------+ +/// ``` +pub mod flag { + pub const T: u8 = 1 << 5; // 0x20 Timestamp if T==0 then the timestamp if present + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Ack { + pub timestamp: Option, + pub ext_sinfo: Option, +} + +pub mod ext { + /// # SourceInfo extension + /// Used to carry additional information about the source of data + pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; + pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; +} + +impl Ack { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use crate::core::ZenohId; + use core::convert::TryFrom; + use rand::Rng; + let mut rng = rand::thread_rng(); + + let timestamp = rng.gen_bool(0.5).then_some({ + let time = uhlc::NTP64(rng.gen()); + let id = uhlc::ID::try_from(ZenohId::rand().as_slice()).unwrap(); + Timestamp::new(time, id) + }); + let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + + Self { + timestamp, + ext_sinfo, + } + } +} diff --git a/commons/zenoh-protocol/src/zenoh_new/err.rs b/commons/zenoh-protocol/src/zenoh_new/err.rs index 500d8da99d..5f7939f147 100644 --- a/commons/zenoh-protocol/src/zenoh_new/err.rs +++ b/commons/zenoh-protocol/src/zenoh_new/err.rs @@ -18,7 +18,7 @@ use uhlc::Timestamp; /// ```text /// Flags: /// - T: Timestamp If T==1 then the timestamp if present -/// - I: Infrastructure If I==1 then the error is related to the infrastructure +/// - I: Infrastructure If I==1 then the error is related to the infrastructure else to the user /// - Z: Extension If Z==1 then at least one extension is present /// /// 7 6 5 4 3 2 1 0 @@ -33,9 +33,9 @@ use uhlc::Timestamp; /// +---------------+ /// ``` pub mod flag { - pub const T: u8 = 1 << 5; // 0x20 Timestamp if T==0 then the timestamp if present - pub const I: u8 = 1 << 6; // 0x40 Reserved if I==1 then the error is related to the infrastructure - pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow + pub const T: u8 = 1 << 5; // 0x20 Timestamp if T==0 then the timestamp if present + pub const I: u8 = 1 << 6; // 0x40 Infrastructure if I==1 then the error is related to the infrastructure else to the user + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index d47d8c30fc..7dd5e61df6 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -11,12 +11,14 @@ // Contributors: // ZettaScale Zenoh Team, // +pub mod ack; pub mod del; pub mod err; pub mod put; pub mod query; pub mod reply; +pub use ack::*; pub use del::*; pub use err::*; pub use put::*; @@ -30,6 +32,7 @@ pub mod id { pub const QUERY: u8 = 0x03; pub const REPLY: u8 = 0x04; pub const ERR: u8 = 0x05; + pub const ACK: u8 = 0x06; } // Push @@ -113,6 +116,7 @@ impl From for RequestBody { pub enum ResponseBody { Reply(Reply), Err(Err), + Ack(Ack), } impl ResponseBody { @@ -122,9 +126,10 @@ impl ResponseBody { let mut rng = rand::thread_rng(); - match rng.gen_range(0..2) { + match rng.gen_range(0..3) { 0 => ResponseBody::Reply(Reply::rand()), 1 => ResponseBody::Err(Err::rand()), + 2 => ResponseBody::Ack(Ack::rand()), _ => unreachable!(), } } @@ -141,3 +146,9 @@ impl From for ResponseBody { ResponseBody::Err(r) } } + +impl From for ResponseBody { + fn from(r: Ack) -> ResponseBody { + ResponseBody::Ack(r) + } +} From a38acb2133f978f8078e530eec51dd54a0204140 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 30 Mar 2023 17:26:26 +0200 Subject: [PATCH 124/203] Remove Destination extension as deemmed useless --- commons/zenoh-codec/src/network/push.rs | 40 ++-------------------- commons/zenoh-protocol/src/network/push.rs | 33 ++---------------- 2 files changed, 4 insertions(+), 69 deletions(-) diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index 49b21e93a7..07563a10e7 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -27,31 +27,6 @@ use zenoh_protocol::{ zenoh_new::PushBody, }; -impl WCodec<(ext::DestinationType, bool), &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: (ext::DestinationType, bool)) -> Self::Output { - let (_, more) = x; - let ext = ext::Destination::new(); - self.write(&mut *writer, (&ext, more)) - } -} - -impl RCodec<(ext::DestinationType, bool), &mut R> for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ext::DestinationType, bool), Self::Error> { - let (_, more): (ext::Destination, bool) = self.read(&mut *reader)?; - Ok((ext::DestinationType::Queryables, more)) - } -} - impl WCodec<&Push, &mut W> for Zenoh080 where W: Writer, @@ -61,8 +36,8 @@ where fn write(self, writer: &mut W, x: &Push) -> Self::Output { // Header let mut header = id::PUSH; - let mut n_exts = ((x.ext_qos != ext::QoSType::default()) as u8) - + (x.ext_tstamp.is_some() as u8 + (x.ext_dst != ext::DestinationType::default()) as u8); + let mut n_exts = + ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); if n_exts != 0 { header |= flag::Z; } @@ -86,10 +61,6 @@ where n_exts -= 1; self.write(&mut *writer, (ts, n_exts != 0))?; } - if x.ext_dst != ext::DestinationType::default() { - n_exts -= 1; - self.write(&mut *writer, (x.ext_dst, n_exts != 0))?; - } // Payload self.write(&mut *writer, &x.payload)?; @@ -134,7 +105,6 @@ where // Extensions let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; - let mut ext_dst = ext::DestinationType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -151,11 +121,6 @@ where ext_tstamp = Some(t); has_ext = ext; } - ext::Destination::ID => { - let (d, ext): (ext::DestinationType, bool) = eodec.read(&mut *reader)?; - ext_dst = d; - has_ext = ext; - } _ => { has_ext = extension::skip(reader, "Push", ext)?; } @@ -171,7 +136,6 @@ where payload, ext_qos, ext_tstamp, - ext_dst, }) } } diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs index cda27023de..8704f3da52 100644 --- a/commons/zenoh-protocol/src/network/push.rs +++ b/commons/zenoh-protocol/src/network/push.rs @@ -35,51 +35,24 @@ pub mod flag { /// +---------------+ /// ~ [push_exts] ~ if Z==1 /// +---------------+ -/// ~ ZenohMessage ~ +/// ~ PushBody ~ /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct Push { pub wire_expr: WireExpr<'static>, pub mapping: Mapping, - pub payload: PushBody, // @TODO pub ext_qos: ext::QoSType, pub ext_tstamp: Option, - pub ext_dst: ext::DestinationType, + pub payload: PushBody, } pub mod ext { - use crate::{common::ZExtUnit, zextunit}; - pub type QoS = crate::network::ext::QoS; pub type QoSType = crate::network::ext::QoSType; pub type Timestamp = crate::network::ext::Timestamp; pub type TimestampType = crate::network::ext::TimestampType; - - pub type Destination = zextunit!(0x03, true); - - #[repr(u8)] - #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] - pub enum DestinationType { - #[default] - Subscribers = 0x00, - Queryables = 0x01, - } - - impl DestinationType { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - let mut rng = rand::thread_rng(); - - match rng.gen_range(0..2) { - 0 => DestinationType::Subscribers, - 1 => DestinationType::Queryables, - _ => unreachable!(), - } - } - } } impl Push { @@ -93,7 +66,6 @@ impl Push { let payload = PushBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); - let ext_dst = ext::DestinationType::rand(); Self { wire_expr, @@ -101,7 +73,6 @@ impl Push { payload, ext_tstamp, ext_qos, - ext_dst, } } } From 51dea77e4c1dfe3bbb09cb63a1030f7f82054745 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 30 Mar 2023 17:27:48 +0200 Subject: [PATCH 125/203] Fix nostd check --- commons/zenoh-codec/src/zenoh_new/query.rs | 1 + commons/zenoh-protocol/src/zenoh_new/query.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/commons/zenoh-codec/src/zenoh_new/query.rs b/commons/zenoh-codec/src/zenoh_new/query.rs index 8e07f0c63f..fc51a49c68 100644 --- a/commons/zenoh-codec/src/zenoh_new/query.rs +++ b/commons/zenoh-codec/src/zenoh_new/query.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use alloc::string::String; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs index b28cd18627..6d4d7961da 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // +use alloc::string::String; /// The kind of consolidation. #[repr(u8)] From c7eb3e0bc5625d0e911d013a580485524419111c Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 30 Mar 2023 17:33:08 +0200 Subject: [PATCH 126/203] Renamed Forget* declarations to Undeclare* --- commons/zenoh-codec/src/network/declare.rs | 88 +++++++++---------- commons/zenoh-codec/tests/codec.rs | 10 +-- commons/zenoh-protocol/src/network/declare.rs | 48 +++++----- 3 files changed, 73 insertions(+), 73 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index d3492d706a..ec77cd31e7 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -35,13 +35,13 @@ where fn write(self, writer: &mut W, x: &DeclareBody) -> Self::Output { match x { DeclareBody::DeclareKeyExpr(r) => self.write(&mut *writer, r)?, - DeclareBody::ForgetKeyExpr(r) => self.write(&mut *writer, r)?, + DeclareBody::UndeclareKeyExpr(r) => self.write(&mut *writer, r)?, DeclareBody::DeclareSubscriber(r) => self.write(&mut *writer, r)?, - DeclareBody::ForgetSubscriber(r) => self.write(&mut *writer, r)?, + DeclareBody::UndeclareSubscriber(r) => self.write(&mut *writer, r)?, DeclareBody::DeclareQueryable(r) => self.write(&mut *writer, r)?, - DeclareBody::ForgetQueryable(r) => self.write(&mut *writer, r)?, + DeclareBody::UndeclareQueryable(r) => self.write(&mut *writer, r)?, DeclareBody::DeclareToken(r) => self.write(&mut *writer, r)?, - DeclareBody::ForgetToken(r) => self.write(&mut *writer, r)?, + DeclareBody::UndeclareToken(r) => self.write(&mut *writer, r)?, } Ok(()) @@ -61,13 +61,13 @@ where use declare::id::*; let d = match imsg::mid(codec.header) { D_KEYEXPR => DeclareBody::DeclareKeyExpr(codec.read(&mut *reader)?), - F_KEYEXPR => DeclareBody::ForgetKeyExpr(codec.read(&mut *reader)?), + U_KEYEXPR => DeclareBody::UndeclareKeyExpr(codec.read(&mut *reader)?), D_SUBSCRIBER => DeclareBody::DeclareSubscriber(codec.read(&mut *reader)?), - F_SUBSCRIBER => DeclareBody::ForgetSubscriber(codec.read(&mut *reader)?), + U_SUBSCRIBER => DeclareBody::UndeclareSubscriber(codec.read(&mut *reader)?), D_QUERYABLE => DeclareBody::DeclareQueryable(codec.read(&mut *reader)?), - F_QUERYABLE => DeclareBody::ForgetQueryable(codec.read(&mut *reader)?), + U_QUERYABLE => DeclareBody::UndeclareQueryable(codec.read(&mut *reader)?), D_TOKEN => DeclareBody::DeclareToken(codec.read(&mut *reader)?), - F_TOKEN => DeclareBody::ForgetToken(codec.read(&mut *reader)?), + U_TOKEN => DeclareBody::UndeclareToken(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; @@ -236,15 +236,15 @@ where } // ForgetKeyExpr -impl WCodec<&keyexpr::ForgetKeyExpr, &mut W> for Zenoh080 +impl WCodec<&keyexpr::UndeclareKeyExpr, &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &keyexpr::ForgetKeyExpr) -> Self::Output { + fn write(self, writer: &mut W, x: &keyexpr::UndeclareKeyExpr) -> Self::Output { // Header - let header = declare::id::F_KEYEXPR; + let header = declare::id::U_KEYEXPR; self.write(&mut *writer, header)?; // Body @@ -254,13 +254,13 @@ where } } -impl RCodec for Zenoh080 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); @@ -268,14 +268,14 @@ where } } -impl RCodec for Zenoh080Header +impl RCodec for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != declare::id::F_KEYEXPR { + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::U_KEYEXPR { return Err(DidntRead); } @@ -287,7 +287,7 @@ where extension::skip_all(reader, "ForgetKeyExpr")?; } - Ok(keyexpr::ForgetKeyExpr { id }) + Ok(keyexpr::UndeclareKeyExpr { id }) } } @@ -395,15 +395,15 @@ where } // ForgetSubscriber -impl WCodec<&subscriber::ForgetSubscriber, &mut W> for Zenoh080 +impl WCodec<&subscriber::UndeclareSubscriber, &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &subscriber::ForgetSubscriber) -> Self::Output { + fn write(self, writer: &mut W, x: &subscriber::UndeclareSubscriber) -> Self::Output { // Header - let header = declare::id::F_SUBSCRIBER; + let header = declare::id::U_SUBSCRIBER; self.write(&mut *writer, header)?; // Body @@ -413,13 +413,13 @@ where } } -impl RCodec for Zenoh080 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); @@ -427,14 +427,14 @@ where } } -impl RCodec for Zenoh080Header +impl RCodec for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != declare::id::F_SUBSCRIBER { + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::U_SUBSCRIBER { return Err(DidntRead); } @@ -447,7 +447,7 @@ where extension::skip_all(reader, "ForgetSubscriber")?; } - Ok(subscriber::ForgetSubscriber { id }) + Ok(subscriber::UndeclareSubscriber { id }) } } @@ -553,15 +553,15 @@ where } // ForgetQueryable -impl WCodec<&queryable::ForgetQueryable, &mut W> for Zenoh080 +impl WCodec<&queryable::UndeclareQueryable, &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &queryable::ForgetQueryable) -> Self::Output { + fn write(self, writer: &mut W, x: &queryable::UndeclareQueryable) -> Self::Output { // Header - let header = declare::id::F_QUERYABLE; + let header = declare::id::U_QUERYABLE; self.write(&mut *writer, header)?; // Body @@ -571,13 +571,13 @@ where } } -impl RCodec for Zenoh080 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); @@ -585,14 +585,14 @@ where } } -impl RCodec for Zenoh080Header +impl RCodec for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != declare::id::F_QUERYABLE { + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::U_QUERYABLE { return Err(DidntRead); } @@ -605,7 +605,7 @@ where extension::skip_all(reader, "ForgetQueryable")?; } - Ok(queryable::ForgetQueryable { id }) + Ok(queryable::UndeclareQueryable { id }) } } @@ -684,15 +684,15 @@ where } // ForgetToken -impl WCodec<&token::ForgetToken, &mut W> for Zenoh080 +impl WCodec<&token::UndeclareToken, &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: &token::ForgetToken) -> Self::Output { + fn write(self, writer: &mut W, x: &token::UndeclareToken) -> Self::Output { // Header - let header = declare::id::F_TOKEN; + let header = declare::id::U_TOKEN; self.write(&mut *writer, header)?; // Body @@ -702,13 +702,13 @@ where } } -impl RCodec for Zenoh080 +impl RCodec for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { + fn read(self, reader: &mut R) -> Result { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); @@ -716,14 +716,14 @@ where } } -impl RCodec for Zenoh080Header +impl RCodec for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != declare::id::F_TOKEN { + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::U_TOKEN { return Err(DidntRead); } @@ -736,6 +736,6 @@ where extension::skip_all(reader, "ForgetToken")?; } - Ok(token::ForgetToken { id }) + Ok(token::UndeclareToken { id }) } } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 159294a300..4db9ae039d 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -493,7 +493,7 @@ fn codec_declare_keyexpr() { #[test] fn codec_forget_keyexpr() { - run!(ForgetKeyExpr, ForgetKeyExpr::rand()); + run!(UndeclareKeyExpr, UndeclareKeyExpr::rand()); } #[test] @@ -503,7 +503,7 @@ fn codec_declare_subscriber() { #[test] fn codec_forget_subscriber() { - run!(ForgetSubscriber, ForgetSubscriber::rand()); + run!(UndeclareSubscriber, UndeclareSubscriber::rand()); } #[test] @@ -513,7 +513,7 @@ fn codec_declare_queryable() { #[test] fn codec_forget_queryable() { - run!(ForgetQueryable, ForgetQueryable::rand()); + run!(UndeclareQueryable, UndeclareQueryable::rand()); } #[test] @@ -523,7 +523,7 @@ fn codec_declare_token() { #[test] fn codec_forget_token() { - run!(ForgetToken, ForgetToken::rand()); + run!(UndeclareToken, UndeclareToken::rand()); } #[test] @@ -660,7 +660,7 @@ fn codec_declaration_queryable_old() { #[test] fn codec_declaration_forget_queryable_old() { - run!(ForgetQueryable, ForgetQueryable::rand()); + run!(UndeclareQueryable, UndeclareQueryable::rand()); } #[test] diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index 5c69be15cc..a76831b73b 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -59,28 +59,28 @@ pub mod ext { pub mod id { pub const D_KEYEXPR: u8 = 0x00; - pub const F_KEYEXPR: u8 = 0x01; + pub const U_KEYEXPR: u8 = 0x01; pub const D_SUBSCRIBER: u8 = 0x02; - pub const F_SUBSCRIBER: u8 = 0x03; + pub const U_SUBSCRIBER: u8 = 0x03; pub const D_QUERYABLE: u8 = 0x04; - pub const F_QUERYABLE: u8 = 0x05; + pub const U_QUERYABLE: u8 = 0x05; pub const D_TOKEN: u8 = 0x06; - pub const F_TOKEN: u8 = 0x07; + pub const U_TOKEN: u8 = 0x07; } #[derive(Debug, Clone, PartialEq, Eq)] pub enum DeclareBody { DeclareKeyExpr(DeclareKeyExpr), - ForgetKeyExpr(ForgetKeyExpr), + UndeclareKeyExpr(UndeclareKeyExpr), DeclareSubscriber(DeclareSubscriber), - ForgetSubscriber(ForgetSubscriber), + UndeclareSubscriber(UndeclareSubscriber), DeclareQueryable(DeclareQueryable), - ForgetQueryable(ForgetQueryable), + UndeclareQueryable(UndeclareQueryable), DeclareToken(DeclareToken), - ForgetToken(ForgetToken), + UndeclareToken(UndeclareToken), } impl DeclareBody { @@ -92,13 +92,13 @@ impl DeclareBody { match rng.gen_range(0..8) { 0 => DeclareBody::DeclareKeyExpr(DeclareKeyExpr::rand()), - 1 => DeclareBody::ForgetKeyExpr(ForgetKeyExpr::rand()), + 1 => DeclareBody::UndeclareKeyExpr(UndeclareKeyExpr::rand()), 2 => DeclareBody::DeclareSubscriber(DeclareSubscriber::rand()), - 3 => DeclareBody::ForgetSubscriber(ForgetSubscriber::rand()), + 3 => DeclareBody::UndeclareSubscriber(UndeclareSubscriber::rand()), 4 => DeclareBody::DeclareQueryable(DeclareQueryable::rand()), - 5 => DeclareBody::ForgetQueryable(ForgetQueryable::rand()), + 5 => DeclareBody::UndeclareQueryable(UndeclareQueryable::rand()), 6 => DeclareBody::DeclareToken(DeclareToken::rand()), - 7 => DeclareBody::ForgetToken(ForgetToken::rand()), + 7 => DeclareBody::UndeclareToken(UndeclareToken::rand()), _ => unreachable!(), } } @@ -201,7 +201,7 @@ pub mod keyexpr { /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ - /// |Z|X|X| F_KEXPR | + /// |Z|X|X| U_KEXPR | /// +---------------+ /// ~ expr_id:z16 ~ /// +---------------+ @@ -209,11 +209,11 @@ pub mod keyexpr { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] - pub struct ForgetKeyExpr { + pub struct UndeclareKeyExpr { pub id: ExprId, } - impl ForgetKeyExpr { + impl UndeclareKeyExpr { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; @@ -364,7 +364,7 @@ pub mod subscriber { /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ - /// |Z|X|X| F_SUB | + /// |Z|X|X| U_SUB | /// +---------------+ /// ~ subs_id:z32 ~ /// +---------------+ @@ -372,11 +372,11 @@ pub mod subscriber { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] - pub struct ForgetSubscriber { + pub struct UndeclareSubscriber { pub id: SubscriberId, } - impl ForgetSubscriber { + impl UndeclareSubscriber { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; @@ -509,7 +509,7 @@ pub mod queryable { /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ - /// |Z|X|X| F_QBL | + /// |Z|X|X| U_QBL | /// +---------------+ /// ~ qbls_id:z32 ~ /// +---------------+ @@ -517,11 +517,11 @@ pub mod queryable { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] - pub struct ForgetQueryable { + pub struct UndeclareQueryable { pub id: QueryableId, } - impl ForgetQueryable { + impl UndeclareQueryable { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; @@ -598,7 +598,7 @@ pub mod token { /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ - /// |Z|X|X| F_TKN | + /// |Z|X|X| U_TKN | /// +---------------+ /// ~ token_id:z32 ~ /// +---------------+ @@ -606,11 +606,11 @@ pub mod token { /// +---------------+ /// ``` #[derive(Debug, Clone, PartialEq, Eq)] - pub struct ForgetToken { + pub struct UndeclareToken { pub id: TokenId, } - impl ForgetToken { + impl UndeclareToken { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; From 4ac17366789c02738dba52658e8f2d826ed19ae7 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 30 Mar 2023 18:10:43 +0200 Subject: [PATCH 127/203] Extensions and payload are limited to 2^32 bytes --- commons/zenoh-codec/src/common/extension.rs | 20 +++++++----- commons/zenoh-codec/src/network/declare.rs | 5 +-- commons/zenoh-codec/src/zenoh/data.rs | 6 +--- commons/zenoh-codec/src/zenoh/declare.rs | 35 +++++---------------- commons/zenoh-codec/src/zenoh/query.rs | 5 +-- 5 files changed, 23 insertions(+), 48 deletions(-) diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 9785d16a71..9c3bc700dd 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header}; use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -170,7 +170,8 @@ where header |= iext::FLAG_Z; } self.write(&mut *writer, header)?; - self.write(&mut *writer, &x.value)?; + let bodec = Zenoh080Bounded::::new(); + bodec.write(&mut *writer, &x.value)?; Ok(()) } } @@ -198,7 +199,8 @@ where if iext::eid(self.header) != ID { return Err(DidntRead); } - let value: ZBuf = self.codec.read(&mut *reader)?; + let bodec = Zenoh080Bounded::::new(); + let value: ZBuf = bodec.read(&mut *reader)?; Ok((ZExtZBuf::new(value), has_flag(self.header, iext::FLAG_Z))) } } @@ -217,7 +219,8 @@ where header |= iext::FLAG_Z; } self.write(&mut *writer, header)?; - self.write(&mut *writer, x.len)?; + let bodec = Zenoh080Bounded::::new(); + bodec.write(&mut *writer, x.len)?; Ok(()) } } @@ -246,7 +249,8 @@ where return Err(DidntRead); } - let len: usize = self.codec.read(&mut *reader)?; + let bodec = Zenoh080Bounded::::new(); + let len: usize = bodec.read(&mut *reader)?; Ok(( ZExtZBufHeader::new(len), has_flag(self.header, iext::FLAG_Z), @@ -275,7 +279,8 @@ where } ZExtBody::ZBuf(zbuf) => { self.write(&mut *writer, header)?; - self.write(&mut *writer, zbuf)? + let bodec = Zenoh080Bounded::::new(); + bodec.write(&mut *writer, zbuf)? } } Ok(()) @@ -309,7 +314,8 @@ where ZExtBody::Z64(u64) } iext::ENC_ZBUF => { - let zbuf: ZBuf = self.codec.read(&mut *reader)?; + let bodec = Zenoh080Bounded::::new(); + let zbuf: ZBuf = bodec.read(&mut *reader)?; ZExtBody::ZBuf(zbuf) } _ => { diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index ec77cd31e7..832609622d 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -219,10 +219,7 @@ where } let id: ExprId = self.codec.read(&mut *reader)?; - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, keyexpr::flag::N), - codec: self.codec, - }; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, keyexpr::flag::N)); let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; // Extensions diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index 62f5053dca..f26bf5019f 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -268,11 +268,7 @@ where CongestionControl::Block }; - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; - + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; #[cfg(feature = "shared-memory")] diff --git a/commons/zenoh-codec/src/zenoh/declare.rs b/commons/zenoh-codec/src/zenoh/declare.rs index f04c8c0a46..f86aa68eac 100644 --- a/commons/zenoh-codec/src/zenoh/declare.rs +++ b/commons/zenoh-codec/src/zenoh/declare.rs @@ -185,10 +185,7 @@ where } let expr_id: ExprId = self.codec.read(&mut *reader)?; - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; Ok(Resource { expr_id, key }) @@ -292,10 +289,7 @@ where return Err(DidntRead); } - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; Ok(Publisher { key }) @@ -349,10 +343,7 @@ where return Err(DidntRead); } - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; Ok(ForgetPublisher { key }) @@ -461,10 +452,7 @@ where Reliability::BestEffort }; - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; let mode: SubMode = if imsg::has_flag(self.header, zmsg::flag::S) { @@ -527,10 +515,7 @@ where return Err(DidntRead); } - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; Ok(ForgetSubscriber { key }) @@ -619,10 +604,7 @@ where return Err(DidntRead); } - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; let info: QueryableInfo = if imsg::has_flag(self.header, zmsg::flag::Q) { @@ -682,10 +664,7 @@ where return Err(DidntRead); } - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; Ok(ForgetQueryable { key }) diff --git a/commons/zenoh-codec/src/zenoh/query.rs b/commons/zenoh-codec/src/zenoh/query.rs index 08104cf9fd..f43a9de9d0 100644 --- a/commons/zenoh-codec/src/zenoh/query.rs +++ b/commons/zenoh-codec/src/zenoh/query.rs @@ -195,10 +195,7 @@ where return Err(DidntRead); } - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; let parameters: String = self.codec.read(&mut *reader)?; From 6ea014a396c8cfc4cc9990a9a1b7b0032bc954e2 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 30 Mar 2023 19:05:44 +0200 Subject: [PATCH 128/203] Remove Destination ext from Request --- commons/zenoh-codec/src/network/request.rs | 38 ------------------- commons/zenoh-protocol/src/network/request.rs | 38 ++----------------- 2 files changed, 4 insertions(+), 72 deletions(-) diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 843ec02f1d..4372f7e947 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -27,32 +27,6 @@ use zenoh_protocol::{ zenoh_new::RequestBody, }; -// Destination -impl WCodec<(ext::DestinationType, bool), &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: (ext::DestinationType, bool)) -> Self::Output { - let (_, more) = x; - let ext = ext::Destination::new(); - self.write(&mut *writer, (&ext, more)) - } -} - -impl RCodec<(ext::DestinationType, bool), &mut R> for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ext::DestinationType, bool), Self::Error> { - let (_, more): (ext::Destination, bool) = self.read(&mut *reader)?; - Ok((ext::DestinationType::Subscribers, more)) - } -} - // Target impl WCodec<(&ext::TargetType, bool), &mut W> for Zenoh080 where @@ -105,7 +79,6 @@ where let mut header = id::REQUEST; let mut n_exts = ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8) - + ((x.ext_dst != ext::DestinationType::default()) as u8) + ((x.ext_target != ext::TargetType::default()) as u8); if n_exts != 0 { header |= flag::Z; @@ -131,10 +104,6 @@ where n_exts -= 1; self.write(&mut *writer, (ts, n_exts != 0))?; } - if x.ext_dst != ext::DestinationType::default() { - n_exts -= 1; - self.write(&mut *writer, (x.ext_dst, n_exts != 0))?; - } if x.ext_target != ext::TargetType::default() { n_exts -= 1; self.write(&mut *writer, (&x.ext_target, n_exts != 0))?; @@ -184,7 +153,6 @@ where // Extensions let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; - let mut ext_dst = ext::DestinationType::default(); let mut ext_target = ext::TargetType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); @@ -202,11 +170,6 @@ where ext_tstamp = Some(t); has_ext = ext; } - ext::Destination::ID => { - let (d, ext): (ext::DestinationType, bool) = eodec.read(&mut *reader)?; - ext_dst = d; - has_ext = ext; - } ext::Target::ID => { let (rt, ext): (ext::TargetType, bool) = eodec.read(&mut *reader)?; ext_target = rt; @@ -228,7 +191,6 @@ where payload, ext_qos, ext_tstamp, - ext_dst, ext_target, }) } diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index ebef45733a..3d6cadcb11 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -45,7 +45,7 @@ pub mod flag { /// +---------------+ /// ~ [req_exts] ~ if Z==1 /// +---------------+ -/// ~ ZenohMessage ~ -- Payload +/// ~ RequestBody ~ -- Payload /// +---------------+ /// /// (*) The resolution of the request id is negotiated during the session establishment. @@ -56,18 +56,14 @@ pub struct Request { pub id: RequestId, pub wire_expr: WireExpr<'static>, pub mapping: Mapping, - pub payload: RequestBody, pub ext_qos: ext::QoSType, pub ext_tstamp: Option, - pub ext_dst: ext::DestinationType, pub ext_target: ext::TargetType, + pub payload: RequestBody, } pub mod ext { - use crate::{ - common::{ZExtUnit, ZExtZ64}, - zextunit, zextz64, - }; + use crate::{common::ZExtZ64, zextz64}; pub type QoS = crate::network::ext::QoS; pub type QoSType = crate::network::ext::QoSType; @@ -75,31 +71,7 @@ pub mod ext { pub type Timestamp = crate::network::ext::Timestamp; pub type TimestampType = crate::network::ext::TimestampType; - pub type Destination = zextunit!(0x03, true); - - #[repr(u8)] - #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] - pub enum DestinationType { - Subscribers = 0x00, - #[default] - Queryables = 0x01, - } - - impl DestinationType { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - let mut rng = rand::thread_rng(); - - match rng.gen_range(0..2) { - 0 => DestinationType::Subscribers, - 1 => DestinationType::Queryables, - _ => unreachable!(), - } - } - } - - pub type Target = zextz64!(0x4, true); + pub type Target = zextz64!(0x3, true); /// - Target (0x03) /// 7 6 5 4 3 2 1 0 @@ -149,7 +121,6 @@ impl Request { let payload = RequestBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); - let ext_dst = ext::DestinationType::rand(); let ext_target = ext::TargetType::rand(); Self { @@ -159,7 +130,6 @@ impl Request { payload, ext_qos, ext_tstamp, - ext_dst, ext_target, } } From a1bd95c88748a15cf355c60d34654dcfcdc3b6ef Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 30 Mar 2023 19:57:22 +0200 Subject: [PATCH 129/203] Request Limit and Timeout extensions --- commons/zenoh-codec/src/network/request.rs | 35 +++++++++++++++++-- commons/zenoh-codec/src/network/response.rs | 10 ++++-- commons/zenoh-codec/tests/codec.rs | 16 ++++----- commons/zenoh-protocol/src/network/request.rs | 26 ++++++++++++-- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 4372f7e947..1caeb96313 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -11,7 +11,9 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use crate::{ + common::extension, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Condition, Zenoh080Header, +}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -79,7 +81,9 @@ where let mut header = id::REQUEST; let mut n_exts = ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8) - + ((x.ext_target != ext::TargetType::default()) as u8); + + ((x.ext_target != ext::TargetType::default()) as u8) + + (x.ext_limit.is_some() as u8) + + (x.ext_timeout.is_some() as u8); if n_exts != 0 { header |= flag::Z; } @@ -108,6 +112,16 @@ where n_exts -= 1; self.write(&mut *writer, (&x.ext_target, n_exts != 0))?; } + if let Some(l) = x.ext_limit.as_ref() { + n_exts -= 1; + let e = ext::Limit::new(l.get() as u64); + self.write(&mut *writer, (&e, n_exts != 0))?; + } + if let Some(to) = x.ext_timeout.as_ref() { + n_exts -= 1; + let e = ext::Timeout::new(to.as_millis() as u64); + self.write(&mut *writer, (&e, n_exts != 0))?; + } // Payload self.write(&mut *writer, &x.payload)?; @@ -141,7 +155,8 @@ where } // Body - let id: RequestId = self.codec.read(&mut *reader)?; + let bodec = Zenoh080Bounded::::new(); + let id: RequestId = bodec.read(&mut *reader)?; let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; let mapping = if imsg::has_flag(self.header, flag::M) { @@ -154,6 +169,8 @@ where let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; let mut ext_target = ext::TargetType::default(); + let mut ext_limit = None; + let mut ext_timeout = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -175,6 +192,16 @@ where ext_target = rt; has_ext = ext; } + ext::Limit::ID => { + let (l, ext): (ext::Limit, bool) = eodec.read(&mut *reader)?; + ext_limit = ext::LimitType::new(l.value as u32); + has_ext = ext; + } + ext::Timeout::ID => { + let (to, ext): (ext::Timeout, bool) = eodec.read(&mut *reader)?; + ext_timeout = Some(ext::TimeoutType::from_millis(to.value)); + has_ext = ext; + } _ => { has_ext = extension::skip(reader, "Request", ext)?; } @@ -192,6 +219,8 @@ where ext_qos, ext_tstamp, ext_target, + ext_limit, + ext_timeout, }) } } diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs index 2ef71d0f71..8711eb121f 100644 --- a/commons/zenoh-codec/src/network/response.rs +++ b/commons/zenoh-codec/src/network/response.rs @@ -11,7 +11,9 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use crate::{ + common::extension, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Condition, Zenoh080Header, +}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -96,7 +98,8 @@ where } // Body - let rid: RequestId = self.codec.read(&mut *reader)?; + let bodec = Zenoh080Bounded::::new(); + let rid: RequestId = bodec.read(&mut *reader)?; let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; let mapping = if imsg::has_flag(self.header, flag::M) { @@ -203,7 +206,8 @@ where } // Body - let rid: RequestId = self.codec.read(&mut *reader)?; + let bodec = Zenoh080Bounded::::new(); + let rid: RequestId = bodec.read(&mut *reader)?; // Extensions let mut ext_qos = ext::QoSType::default(); diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 4db9ae039d..c24fa1f1ea 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -492,7 +492,7 @@ fn codec_declare_keyexpr() { } #[test] -fn codec_forget_keyexpr() { +fn codec_undeclare_keyexpr() { run!(UndeclareKeyExpr, UndeclareKeyExpr::rand()); } @@ -502,7 +502,7 @@ fn codec_declare_subscriber() { } #[test] -fn codec_forget_subscriber() { +fn codec_undeclare_subscriber() { run!(UndeclareSubscriber, UndeclareSubscriber::rand()); } @@ -512,7 +512,7 @@ fn codec_declare_queryable() { } #[test] -fn codec_forget_queryable() { +fn codec_undeclare_queryable() { run!(UndeclareQueryable, UndeclareQueryable::rand()); } @@ -522,7 +522,7 @@ fn codec_declare_token() { } #[test] -fn codec_forget_token() { +fn codec_undeclare_token() { run!(UndeclareToken, UndeclareToken::rand()); } @@ -629,7 +629,7 @@ fn codec_declaration_resource_old() { } #[test] -fn codec_declaration_forget_resource_old() { +fn codec_declaration_undeclare_resource_old() { run!(zenoh::ForgetResource, zenoh::ForgetResource::rand()); } @@ -639,7 +639,7 @@ fn codec_declaration_publisher_old() { } #[test] -fn codec_declaration_forget_publisher_old() { +fn codec_declaration_undeclare_publisher_old() { run!(zenoh::ForgetPublisher, zenoh::ForgetPublisher::rand()); } @@ -649,7 +649,7 @@ fn codec_declaration_subscriber_old() { } #[test] -fn codec_declaration_forget_subscriber_old() { +fn codec_declaration_undeclare_subscriber_old() { run!(zenoh::ForgetSubscriber, zenoh::ForgetSubscriber::rand()); } @@ -659,7 +659,7 @@ fn codec_declaration_queryable_old() { } #[test] -fn codec_declaration_forget_queryable_old() { +fn codec_declaration_undeclare_queryable_old() { run!(UndeclareQueryable, UndeclareQueryable::rand()); } diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index 3d6cadcb11..fed504bd7d 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -1,4 +1,3 @@ -use crate::zenoh_new::RequestBody; // // Copyright (c) 2022 ZettaScale Technology // @@ -12,7 +11,7 @@ use crate::zenoh_new::RequestBody; // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, network::Mapping}; +use crate::{core::WireExpr, network::Mapping, zenoh_new::RequestBody}; use core::sync::atomic::AtomicU32; /// The resolution of a RequestId @@ -59,11 +58,14 @@ pub struct Request { pub ext_qos: ext::QoSType, pub ext_tstamp: Option, pub ext_target: ext::TargetType, + pub ext_limit: Option, + pub ext_timeout: Option, pub payload: RequestBody, } pub mod ext { use crate::{common::ZExtZ64, zextz64}; + use core::{num::NonZeroU32, time::Duration}; pub type QoS = crate::network::ext::QoS; pub type QoSType = crate::network::ext::QoSType; @@ -107,11 +109,19 @@ pub mod ext { .unwrap() } } + + pub type Limit = zextz64!(0x4, false); + pub type LimitType = NonZeroU32; + + pub type Timeout = zextz64!(0x5, false); + pub type TimeoutType = Duration; } impl Request { #[cfg(feature = "test")] pub fn rand() -> Self { + use core::num::NonZeroU32; + use rand::Rng; let mut rng = rand::thread_rng(); @@ -122,6 +132,16 @@ impl Request { let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); let ext_target = ext::TargetType::rand(); + let ext_limit = if rng.gen_bool(0.5) { + NonZeroU32::new(rng.gen()) + } else { + None + }; + let ext_timeout = if rng.gen_bool(0.5) { + Some(ext::TimeoutType::from_millis(rng.gen())) + } else { + None + }; Self { wire_expr, @@ -131,6 +151,8 @@ impl Request { ext_qos, ext_tstamp, ext_target, + ext_limit, + ext_timeout, } } } From 09ca712f66a9606d862ea5069b47067757fa8e8e Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 31 Mar 2023 11:31:33 +0200 Subject: [PATCH 130/203] Fix comment typos --- commons/zenoh-protocol/src/network/request.rs | 2 ++ commons/zenoh-protocol/src/network/response.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index fed504bd7d..7304c66ac1 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -110,9 +110,11 @@ pub mod ext { } } + // The maximum number of responses pub type Limit = zextz64!(0x4, false); pub type LimitType = NonZeroU32; + // The timeout of the request pub type Timeout = zextz64!(0x5, false); pub type TimeoutType = Duration; } diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index e0c9b0d514..919e616bf6 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -37,7 +37,7 @@ use crate::{ /// +---------------+ /// ~ [reply_exts] ~ if Z==1 /// +---------------+ -/// ~ ZenohMessage ~ -- Payload +/// ~ ResponseBody ~ -- Payload /// +---------------+ /// /// (*) The resolution of the request id is negotiated during the session establishment. From 3e1b3877a090ea33ea65eb55bc0d3772afae4b69 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 31 Mar 2023 17:44:49 +0200 Subject: [PATCH 131/203] Request/Query/Reply extension rework --- commons/zenoh-codec/src/network/request.rs | 14 +-- commons/zenoh-codec/src/zenoh_new/query.rs | 105 ++++++++++-------- commons/zenoh-codec/src/zenoh_new/reply.rs | 14 ++- commons/zenoh-protocol/src/network/oam.rs | 2 +- commons/zenoh-protocol/src/network/request.rs | 23 ++-- commons/zenoh-protocol/src/zenoh_new/query.rs | 50 ++++++--- commons/zenoh-protocol/src/zenoh_new/reply.rs | 8 ++ 7 files changed, 129 insertions(+), 87 deletions(-) diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 1caeb96313..003276cbbd 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -82,7 +82,7 @@ where let mut n_exts = ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8) + ((x.ext_target != ext::TargetType::default()) as u8) - + (x.ext_limit.is_some() as u8) + + (x.ext_budget.is_some() as u8) + (x.ext_timeout.is_some() as u8); if n_exts != 0 { header |= flag::Z; @@ -112,9 +112,9 @@ where n_exts -= 1; self.write(&mut *writer, (&x.ext_target, n_exts != 0))?; } - if let Some(l) = x.ext_limit.as_ref() { + if let Some(l) = x.ext_budget.as_ref() { n_exts -= 1; - let e = ext::Limit::new(l.get() as u64); + let e = ext::Budget::new(l.get() as u64); self.write(&mut *writer, (&e, n_exts != 0))?; } if let Some(to) = x.ext_timeout.as_ref() { @@ -192,9 +192,9 @@ where ext_target = rt; has_ext = ext; } - ext::Limit::ID => { - let (l, ext): (ext::Limit, bool) = eodec.read(&mut *reader)?; - ext_limit = ext::LimitType::new(l.value as u32); + ext::Budget::ID => { + let (l, ext): (ext::Budget, bool) = eodec.read(&mut *reader)?; + ext_limit = ext::BudgetType::new(l.value as u32); has_ext = ext; } ext::Timeout::ID => { @@ -219,7 +219,7 @@ where ext_qos, ext_tstamp, ext_target, - ext_limit, + ext_budget: ext_limit, ext_timeout, }) } diff --git a/commons/zenoh-codec/src/zenoh_new/query.rs b/commons/zenoh-codec/src/zenoh_new/query.rs index fc51a49c68..24a7f07a29 100644 --- a/commons/zenoh-codec/src/zenoh_new/query.rs +++ b/commons/zenoh-codec/src/zenoh_new/query.rs @@ -24,10 +24,51 @@ use zenoh_protocol::{ zenoh_new::{ id, query::{ext, flag, Query}, - ConsolidationMode, }, }; +// Extension Consolidation +impl WCodec<(ext::ConsolidationType, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (ext::ConsolidationType, bool)) -> Self::Output { + let (x, more) = x; + let v: u64 = match x { + ext::ConsolidationType::Auto => 0, + ext::ConsolidationType::None => 1, + ext::ConsolidationType::Monotonic => 2, + ext::ConsolidationType::Latest => 3, + ext::ConsolidationType::Unique => 4, + }; + let v = ext::Consolidation::new(v); + self.write(&mut *writer, (&v, more)) + } +} + +impl RCodec<(ext::ConsolidationType, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::ConsolidationType, bool), Self::Error> { + let (ext, more): (ext::Consolidation, bool) = self.read(&mut *reader)?; + let c = match ext.value { + 0 => ext::ConsolidationType::Auto, + 1 => ext::ConsolidationType::None, + 2 => ext::ConsolidationType::Monotonic, + 3 => ext::ConsolidationType::Latest, + 4 => ext::ConsolidationType::Unique, + _ => return Err(DidntRead), + }; + Ok((c, more)) + } +} + +// Extension QueryBody impl LCodec<&ext::QueryBodyType> for Zenoh080 { fn w_len(self, x: &ext::QueryBodyType) -> usize { self.w_len(&x.encoding) + x.payload.len() @@ -77,41 +118,6 @@ where } } -// Consolidation -impl WCodec for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: ConsolidationMode) -> Self::Output { - let v: u8 = match x { - ConsolidationMode::None => 0, - ConsolidationMode::Monotonic => 1, - ConsolidationMode::Latest => 2, - }; - self.write(&mut *writer, v) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let v: u8 = self.read(&mut *reader)?; - let c = match v { - 0 => ConsolidationMode::None, - 1 => ConsolidationMode::Monotonic, - 2 => ConsolidationMode::Latest, - _ => return Err(DidntRead), - }; - Ok(c) - } -} - impl WCodec<&Query, &mut W> for Zenoh080 where W: Writer, @@ -124,10 +130,9 @@ where if !x.parameters.is_empty() { header |= flag::P; } - if x.consolidation != ConsolidationMode::default() { - header |= flag::C; - } - let mut n_exts = (x.ext_sinfo.is_some() as u8) + (x.ext_body.is_some() as u8); + let mut n_exts = (x.ext_sinfo.is_some() as u8) + + ((x.ext_consolidation != ext::ConsolidationType::default()) as u8) + + (x.ext_body.is_some() as u8); if n_exts != 0 { header |= flag::Z; } @@ -137,15 +142,16 @@ where if !x.parameters.is_empty() { self.write(&mut *writer, &x.parameters)?; } - if x.consolidation != ConsolidationMode::default() { - self.write(&mut *writer, x.consolidation)?; - } // Extensions if let Some(sinfo) = x.ext_sinfo.as_ref() { n_exts -= 1; self.write(&mut *writer, (sinfo, n_exts != 0))?; } + if x.ext_consolidation != ext::ConsolidationType::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_consolidation, n_exts != 0))?; + } if let Some(body) = x.ext_body.as_ref() { n_exts -= 1; self.write(&mut *writer, (body, n_exts != 0))?; @@ -185,13 +191,9 @@ where parameters = self.codec.read(&mut *reader)?; } - let mut consolidation = ConsolidationMode::default(); - if imsg::has_flag(self.header, flag::C) { - consolidation = self.codec.read(&mut *reader)?; - } - // Extensions let mut ext_sinfo: Option = None; + let mut ext_consolidation = ext::ConsolidationType::default(); let mut ext_body: Option = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); @@ -204,6 +206,11 @@ where ext_sinfo = Some(s); has_ext = ext; } + ext::Consolidation::ID => { + let (c, ext): (ext::ConsolidationType, bool) = eodec.read(&mut *reader)?; + ext_consolidation = c; + has_ext = ext; + } ext::QueryBody::ID => { let (s, ext): (ext::QueryBodyType, bool) = eodec.read(&mut *reader)?; ext_body = Some(s); @@ -217,8 +224,8 @@ where Ok(Query { parameters, - consolidation, ext_sinfo, + ext_consolidation, ext_body, }) } diff --git a/commons/zenoh-codec/src/zenoh_new/reply.rs b/commons/zenoh-codec/src/zenoh_new/reply.rs index 5892687485..3a6afdfe33 100644 --- a/commons/zenoh-codec/src/zenoh_new/reply.rs +++ b/commons/zenoh-codec/src/zenoh_new/reply.rs @@ -41,7 +41,8 @@ where if x.encoding != Encoding::default() { header |= flag::E; } - let mut n_exts = (x.ext_sinfo.is_some()) as u8; + let mut n_exts = (x.ext_sinfo.is_some()) as u8 + + ((x.ext_consolidation != ext::ConsolidationType::default()) as u8); if n_exts != 0 { header |= flag::Z; } @@ -60,6 +61,10 @@ where n_exts -= 1; self.write(&mut *writer, (sinfo, n_exts != 0))?; } + if x.ext_consolidation != ext::ConsolidationType::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_consolidation, n_exts != 0))?; + } // Payload let bodec = Zenoh080Bounded::::new(); @@ -106,6 +111,7 @@ where // Extensions let mut ext_sinfo: Option = None; + let mut ext_consolidation = ext::ConsolidationType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -117,6 +123,11 @@ where ext_sinfo = Some(s); has_ext = ext; } + ext::Consolidation::ID => { + let (c, ext): (ext::ConsolidationType, bool) = eodec.read(&mut *reader)?; + ext_consolidation = c; + has_ext = ext; + } _ => { has_ext = extension::skip(reader, "Reply", ext)?; } @@ -131,6 +142,7 @@ where timestamp, encoding, ext_sinfo, + ext_consolidation, payload, }) } diff --git a/commons/zenoh-protocol/src/network/oam.rs b/commons/zenoh-protocol/src/network/oam.rs index 56db363661..3be918b8e8 100644 --- a/commons/zenoh-protocol/src/network/oam.rs +++ b/commons/zenoh-protocol/src/network/oam.rs @@ -44,7 +44,7 @@ pub mod flag { /// - 0b01: u64 /// - 0b10: ZBuf /// - 0b11: Reserved -/// +/// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct Oam { pub id: OamId, diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index 7304c66ac1..c559c0f56c 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -28,9 +28,9 @@ pub mod flag { /// /// ```text /// Flags: -/// - N: Named If N==1 then the key expr has name/suffix +/// - N: Named if N==1 then the key expr has name/suffix /// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver -/// - Z: Extension If Z==1 then at least one extension is present +/// - Z: Extension if Z==1 then at least one extension is present /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ @@ -58,7 +58,7 @@ pub struct Request { pub ext_qos: ext::QoSType, pub ext_tstamp: Option, pub ext_target: ext::TargetType, - pub ext_limit: Option, + pub ext_budget: Option, pub ext_timeout: Option, pub payload: RequestBody, } @@ -74,12 +74,11 @@ pub mod ext { pub type TimestampType = crate::network::ext::TimestampType; pub type Target = zextz64!(0x3, true); - /// - Target (0x03) - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// % target % - /// +---------------+ + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// % target % + /// +---------------+ /// /// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] @@ -111,8 +110,8 @@ pub mod ext { } // The maximum number of responses - pub type Limit = zextz64!(0x4, false); - pub type LimitType = NonZeroU32; + pub type Budget = zextz64!(0x4, false); + pub type BudgetType = NonZeroU32; // The timeout of the request pub type Timeout = zextz64!(0x5, false); @@ -134,7 +133,7 @@ impl Request { let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); let ext_target = ext::TargetType::rand(); - let ext_limit = if rng.gen_bool(0.5) { + let ext_budget = if rng.gen_bool(0.5) { NonZeroU32::new(rng.gen()) } else { None @@ -153,7 +152,7 @@ impl Request { ext_qos, ext_tstamp, ext_target, - ext_limit, + ext_budget, ext_timeout, } } diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs index 6d4d7961da..576b233bcc 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -16,7 +16,10 @@ use alloc::string::String; /// The kind of consolidation. #[repr(u8)] #[derive(Debug, Default, Clone, PartialEq, Eq, Copy)] -pub enum ConsolidationMode { +pub enum Consolidation { + /// Apply automatic consolidation based on queryable's preferences + #[default] + Auto, /// No consolidation applied: multiple samples may be received for the same key-timestamp. None, /// Monotonic consolidation immediately forwards samples, except if one with an equal or more recent timestamp @@ -27,20 +30,27 @@ pub enum ConsolidationMode { /// Note that this doesn't cause re-ordering, but drops the samples for which a more recent timestamp has already /// been observed with the same key. Monotonic, - /// Holds back samples to only send the set of samples that had the highest timestamp for their key. - #[default] + /// Holds back samples to only send the set of samples that had the highest timestamp for their key. Latest, + /// Remove the duplicates of any samples based on the their timestamp. + Unique, } -impl ConsolidationMode { +impl Consolidation { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::prelude::SliceRandom; let mut rng = rand::thread_rng(); - *[Self::None, Self::Monotonic, Self::Latest] - .choose(&mut rng) - .unwrap() + *[ + Self::None, + Self::Monotonic, + Self::Latest, + Self::Unique, + Self::Auto, + ] + .choose(&mut rng) + .unwrap() } } @@ -49,36 +59,38 @@ impl ConsolidationMode { /// ```text /// Flags: /// - P: Parameters If P==1 then the parameters are present -/// - C: Consolidation If C==1 then the consolidation is present +/// - X: Reserved /// - Z: Extension If Z==1 then at least one extension is present /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|C|P| QUERY | +/// |Z|X|P| QUERY | /// +-+-+-+---------+ /// ~ ps: ~ if P==1 /// +---------------+ -/// ~ consolidation ~ if C==1 -/// +---------------+ /// ~ [qry_exts] ~ if Z==1 /// +---------------+ /// ``` pub mod flag { pub const P: u8 = 1 << 5; // 0x20 Parameters if P==1 then the parameters are present - pub const C: u8 = 1 << 6; // 0x40 Consolidation if C==1 then the consolidation is present + // pub const X: u8 = 1 << 6; // 0x40 Reserved pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Query { pub parameters: String, - pub consolidation: ConsolidationMode, pub ext_sinfo: Option, + pub ext_consolidation: Consolidation, pub ext_body: Option, } pub mod ext { - use crate::{common::ZExtZBuf, core::Encoding, zextzbuf}; + use crate::{ + common::{ZExtZ64, ZExtZBuf}, + core::Encoding, + zextz64, zextzbuf, + }; use zenoh_buffers::ZBuf; /// # SourceInfo extension @@ -86,9 +98,13 @@ pub mod ext { pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; + /// # Consolidation extension + pub type Consolidation = zextz64!(0x2, false); + pub type ConsolidationType = crate::zenoh_new::query::Consolidation; + /// # QueryBody extension /// Used to carry a body attached to the query - pub type QueryBody = zextzbuf!(0x02, false); + pub type QueryBody = zextzbuf!(0x03, false); /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ @@ -134,14 +150,14 @@ impl Query { } else { String::new() }; - let consolidation = ConsolidationMode::rand(); let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + let ext_consolidation = Consolidation::rand(); let ext_body = rng.gen_bool(0.5).then_some(ext::QueryBodyType::rand()); Self { parameters, - consolidation, ext_sinfo, + ext_consolidation, ext_body, } } diff --git a/commons/zenoh-protocol/src/zenoh_new/reply.rs b/commons/zenoh-protocol/src/zenoh_new/reply.rs index d21d0a2731..7126841049 100644 --- a/commons/zenoh-protocol/src/zenoh_new/reply.rs +++ b/commons/zenoh-protocol/src/zenoh_new/reply.rs @@ -47,6 +47,7 @@ pub struct Reply { pub timestamp: Option, pub encoding: Encoding, pub ext_sinfo: Option, + pub ext_consolidation: ext::ConsolidationType, pub payload: ZBuf, } @@ -55,12 +56,17 @@ pub mod ext { /// Used to carry additional information about the source of data pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; + + /// # Consolidation extension + pub type Consolidation = crate::zenoh_new::query::ext::Consolidation; + pub type ConsolidationType = crate::zenoh_new::query::ext::ConsolidationType; } impl Reply { #[cfg(feature = "test")] pub fn rand() -> Self { use crate::core::ZenohId; + use crate::zenoh_new::Consolidation; use core::convert::TryFrom; use rand::Rng; let mut rng = rand::thread_rng(); @@ -72,12 +78,14 @@ impl Reply { }); let encoding = Encoding::rand(); let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + let ext_consolidation = Consolidation::rand(); let payload = ZBuf::rand(rng.gen_range(1..=64)); Self { timestamp, encoding, ext_sinfo, + ext_consolidation, payload, } } From 840a9c940704a3432e8fa965114048d5c30280e6 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 4 Apr 2023 15:13:02 +0200 Subject: [PATCH 132/203] Read/Write unknown extensions at Zenoh level --- commons/zenoh-codec/src/common/extension.rs | 19 +++++++++++++++++- commons/zenoh-codec/src/zenoh_new/ack.rs | 13 ++++++++++-- commons/zenoh-codec/src/zenoh_new/del.rs | 13 ++++++++++-- commons/zenoh-codec/src/zenoh_new/err.rs | 15 ++++++++++++-- commons/zenoh-codec/src/zenoh_new/put.rs | 13 ++++++++++-- commons/zenoh-codec/src/zenoh_new/query.rs | 16 ++++++++++++--- commons/zenoh-codec/src/zenoh_new/reply.rs | 14 +++++++++++-- .../zenoh-protocol/src/common/extension.rs | 20 ++++++++++++++++--- commons/zenoh-protocol/src/network/oam.rs | 5 ++--- commons/zenoh-protocol/src/zenoh_new/ack.rs | 13 +++++++++++- commons/zenoh-protocol/src/zenoh_new/del.rs | 13 +++++++++++- commons/zenoh-protocol/src/zenoh_new/err.rs | 9 ++++++++- commons/zenoh-protocol/src/zenoh_new/put.rs | 13 ++++++++++-- commons/zenoh-protocol/src/zenoh_new/query.rs | 10 +++++++++- commons/zenoh-protocol/src/zenoh_new/reply.rs | 14 ++++++++++--- 15 files changed, 171 insertions(+), 29 deletions(-) diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index 9c3bc700dd..b07eeaef45 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -22,7 +22,7 @@ use zenoh_protocol::common::{ iext, imsg::has_flag, ZExtBody, ZExtUnit, ZExtUnknown, ZExtZ64, ZExtZBuf, ZExtZBufHeader, }; -fn skip_inner(reader: &mut R, _s: &str, header: u8) -> Result +fn read_inner(reader: &mut R, _s: &str, header: u8) -> Result<(ZExtUnknown, bool), DidntRead> where R: Reader, { @@ -36,6 +36,23 @@ where #[cfg(feature = "std")] log::debug!("Unknown {_s} ext: {u:?}"); } + Ok((u, has_ext)) +} + +#[cold] +#[inline(never)] +pub fn read(reader: &mut R, s: &str, header: u8) -> Result<(ZExtUnknown, bool), DidntRead> +where + R: Reader, +{ + read_inner(&mut *reader, s, header) +} + +fn skip_inner(reader: &mut R, s: &str, header: u8) -> Result +where + R: Reader, +{ + let (_, has_ext): (ZExtUnknown, bool) = read_inner(&mut *reader, s, header)?; Ok(has_ext) } diff --git a/commons/zenoh-codec/src/zenoh_new/ack.rs b/commons/zenoh-codec/src/zenoh_new/ack.rs index 332811ad03..03f57fef2c 100644 --- a/commons/zenoh-codec/src/zenoh_new/ack.rs +++ b/commons/zenoh-codec/src/zenoh_new/ack.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -36,7 +37,7 @@ where if x.timestamp.is_some() { header |= flag::T; } - let mut n_exts = (x.ext_sinfo.is_some()) as u8; + let mut n_exts = ((x.ext_sinfo.is_some()) as u8) + (x.ext_unknown.len() as u8); if n_exts != 0 { header |= flag::Z; } @@ -52,6 +53,10 @@ where n_exts -= 1; self.write(&mut *writer, (sinfo, n_exts != 0))?; } + for u in x.ext_unknown.iter() { + n_exts -= 1; + self.write(&mut *writer, (u, n_exts != 0))?; + } Ok(()) } @@ -89,6 +94,7 @@ where // Extensions let mut ext_sinfo: Option = None; + let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -101,7 +107,9 @@ where has_ext = ext; } _ => { - has_ext = extension::skip(reader, "Ack", ext)?; + let (u, ext) = extension::read(reader, "Ack", ext)?; + ext_unknown.push(u); + has_ext = ext; } } } @@ -109,6 +117,7 @@ where Ok(Ack { timestamp, ext_sinfo, + ext_unknown, }) } } diff --git a/commons/zenoh-codec/src/zenoh_new/del.rs b/commons/zenoh-codec/src/zenoh_new/del.rs index e2570cda36..f1746a31e8 100644 --- a/commons/zenoh-codec/src/zenoh_new/del.rs +++ b/commons/zenoh-codec/src/zenoh_new/del.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -36,7 +37,7 @@ where if x.timestamp.is_some() { header |= flag::T; } - let mut n_exts = (x.ext_sinfo.is_some()) as u8; + let mut n_exts = (x.ext_sinfo.is_some()) as u8 + (x.ext_unknown.len() as u8); if n_exts != 0 { header |= flag::Z; } @@ -52,6 +53,10 @@ where n_exts -= 1; self.write(&mut *writer, (sinfo, n_exts != 0))?; } + for u in x.ext_unknown.iter() { + n_exts -= 1; + self.write(&mut *writer, (u, n_exts != 0))?; + } Ok(()) } @@ -89,6 +94,7 @@ where // Extensions let mut ext_sinfo: Option = None; + let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -101,7 +107,9 @@ where has_ext = ext; } _ => { - has_ext = extension::skip(reader, "Del", ext)?; + let (u, ext) = extension::read(reader, "Del", ext)?; + ext_unknown.push(u); + has_ext = ext; } } } @@ -109,6 +117,7 @@ where Ok(Del { timestamp, ext_sinfo, + ext_unknown, }) } } diff --git a/commons/zenoh-codec/src/zenoh_new/err.rs b/commons/zenoh-codec/src/zenoh_new/err.rs index 6a239aecd7..e3273abe72 100644 --- a/commons/zenoh-codec/src/zenoh_new/err.rs +++ b/commons/zenoh-codec/src/zenoh_new/err.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -90,7 +91,9 @@ where if x.is_infrastructure { header |= flag::I; } - let mut n_exts = (x.ext_sinfo.is_some() as u8) + (x.ext_body.is_some() as u8); + let mut n_exts = (x.ext_sinfo.is_some() as u8) + + (x.ext_body.is_some() as u8) + + (x.ext_unknown.len() as u8); if n_exts != 0 { header |= flag::Z; } @@ -111,6 +114,10 @@ where n_exts -= 1; self.write(&mut *writer, (body, n_exts != 0))?; } + for u in x.ext_unknown.iter() { + n_exts -= 1; + self.write(&mut *writer, (u, n_exts != 0))?; + } Ok(()) } @@ -151,6 +158,7 @@ where // Extensions let mut ext_sinfo: Option = None; let mut ext_body: Option = None; + let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -168,7 +176,9 @@ where has_ext = ext; } _ => { - has_ext = extension::skip(reader, "Put", ext)?; + let (u, ext) = extension::read(reader, "Err", ext)?; + ext_unknown.push(u); + has_ext = ext; } } } @@ -179,6 +189,7 @@ where timestamp, ext_sinfo, ext_body, + ext_unknown, }) } } diff --git a/commons/zenoh-codec/src/zenoh_new/put.rs b/commons/zenoh-codec/src/zenoh_new/put.rs index f1d3fbcbc4..53e510a870 100644 --- a/commons/zenoh-codec/src/zenoh_new/put.rs +++ b/commons/zenoh-codec/src/zenoh_new/put.rs @@ -15,6 +15,7 @@ use crate::{ common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header, Zenoh080Length, }; +use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -95,7 +96,7 @@ where if x.encoding != Encoding::default() { header |= flag::E; } - let mut n_exts = (x.ext_sinfo.is_some()) as u8; + let mut n_exts = (x.ext_sinfo.is_some()) as u8 + (x.ext_unknown.len() as u8); if n_exts != 0 { header |= flag::Z; } @@ -114,6 +115,10 @@ where n_exts -= 1; self.write(&mut *writer, (sinfo, n_exts != 0))?; } + for u in x.ext_unknown.iter() { + n_exts -= 1; + self.write(&mut *writer, (u, n_exts != 0))?; + } // Payload let bodec = Zenoh080Bounded::::new(); @@ -160,6 +165,7 @@ where // Extensions let mut ext_sinfo: Option = None; + let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -172,7 +178,9 @@ where has_ext = ext; } _ => { - has_ext = extension::skip(reader, "Put", ext)?; + let (u, ext) = extension::read(reader, "Put", ext)?; + ext_unknown.push(u); + has_ext = ext; } } } @@ -185,6 +193,7 @@ where timestamp, encoding, ext_sinfo, + ext_unknown, payload, }) } diff --git a/commons/zenoh-codec/src/zenoh_new/query.rs b/commons/zenoh-codec/src/zenoh_new/query.rs index 24a7f07a29..4f8cce9fdb 100644 --- a/commons/zenoh-codec/src/zenoh_new/query.rs +++ b/commons/zenoh-codec/src/zenoh_new/query.rs @@ -12,12 +12,13 @@ // ZettaScale Zenoh Team, // use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; -use alloc::string::String; +use alloc::{string::String, vec::Vec}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, SplitBuffer, ZBuf, }; + use zenoh_protocol::{ common::{iext, imsg, ZExtZBufHeader}, core::Encoding, @@ -132,7 +133,8 @@ where } let mut n_exts = (x.ext_sinfo.is_some() as u8) + ((x.ext_consolidation != ext::ConsolidationType::default()) as u8) - + (x.ext_body.is_some() as u8); + + (x.ext_body.is_some() as u8) + + (x.ext_unknown.len() as u8); if n_exts != 0 { header |= flag::Z; } @@ -156,6 +158,10 @@ where n_exts -= 1; self.write(&mut *writer, (body, n_exts != 0))?; } + for u in x.ext_unknown.iter() { + n_exts -= 1; + self.write(&mut *writer, (u, n_exts != 0))?; + } Ok(()) } @@ -195,6 +201,7 @@ where let mut ext_sinfo: Option = None; let mut ext_consolidation = ext::ConsolidationType::default(); let mut ext_body: Option = None; + let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -217,7 +224,9 @@ where has_ext = ext; } _ => { - has_ext = extension::skip(reader, "Put", ext)?; + let (u, ext) = extension::read(reader, "Query", ext)?; + ext_unknown.push(u); + has_ext = ext; } } } @@ -227,6 +236,7 @@ where ext_sinfo, ext_consolidation, ext_body, + ext_unknown, }) } } diff --git a/commons/zenoh-codec/src/zenoh_new/reply.rs b/commons/zenoh-codec/src/zenoh_new/reply.rs index 3a6afdfe33..ef4643210f 100644 --- a/commons/zenoh-codec/src/zenoh_new/reply.rs +++ b/commons/zenoh-codec/src/zenoh_new/reply.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header}; +use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -42,7 +43,8 @@ where header |= flag::E; } let mut n_exts = (x.ext_sinfo.is_some()) as u8 - + ((x.ext_consolidation != ext::ConsolidationType::default()) as u8); + + ((x.ext_consolidation != ext::ConsolidationType::default()) as u8) + + (x.ext_unknown.len() as u8); if n_exts != 0 { header |= flag::Z; } @@ -65,6 +67,10 @@ where n_exts -= 1; self.write(&mut *writer, (x.ext_consolidation, n_exts != 0))?; } + for u in x.ext_unknown.iter() { + n_exts -= 1; + self.write(&mut *writer, (u, n_exts != 0))?; + } // Payload let bodec = Zenoh080Bounded::::new(); @@ -112,6 +118,7 @@ where // Extensions let mut ext_sinfo: Option = None; let mut ext_consolidation = ext::ConsolidationType::default(); + let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -129,7 +136,9 @@ where has_ext = ext; } _ => { - has_ext = extension::skip(reader, "Reply", ext)?; + let (u, ext) = extension::read(reader, "Reply", ext)?; + ext_unknown.push(u); + has_ext = ext; } } } @@ -143,6 +152,7 @@ where encoding, ext_sinfo, ext_consolidation, + ext_unknown, payload, }) } diff --git a/commons/zenoh-protocol/src/common/extension.rs b/commons/zenoh-protocol/src/common/extension.rs index 29dbdbb1d7..f61df61cc6 100644 --- a/commons/zenoh-protocol/src/common/extension.rs +++ b/commons/zenoh-protocol/src/common/extension.rs @@ -38,14 +38,14 @@ use zenoh_buffers::ZBuf; /// +-+-+-+-+-+-+-+-+ /// |Z|ENC|M| ID | /// +-+---+-+-------+ -/// % length % -- If ENC == u64 || ENC == ZBuf +/// % length % -- If ENC == Z64 || ENC == ZBuf (z32) /// +---------------+ /// ~ [u8] ~ -- If ENC == ZBuf /// +---------------+ /// /// Encoding: /// - 0b00: Unit -/// - 0b01: u64 +/// - 0b01: Z64 /// - 0b10: ZBuf /// - 0b11: Reserved /// @@ -70,6 +70,10 @@ pub mod iext { header & !FLAG_Z } + pub const fn mid(header: u8) -> u8 { + header & ID_MASK + } + pub(super) const fn id(id: u8, mandatory: bool, encoding: u8) -> u8 { let mut id = id & ID_MASK; if mandatory { @@ -346,7 +350,17 @@ impl ZExtUnknown { let mut rng = rand::thread_rng(); let id: u8 = rng.gen_range(0x00..=iext::ID_MASK); - let mandatory: bool = rng.gen_bool(0.5); + let mandatory = rng.gen_bool(0.5); + let body = ZExtBody::rand(); + Self::new(id, mandatory, body) + } + + #[cfg(feature = "test")] + pub fn rand2(start: u8, mandatory: bool) -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: u8 = rng.gen_range(start..=iext::ID_MASK); let body = ZExtBody::rand(); Self::new(id, mandatory, body) } diff --git a/commons/zenoh-protocol/src/network/oam.rs b/commons/zenoh-protocol/src/network/oam.rs index 3be918b8e8..8fd2ba6044 100644 --- a/commons/zenoh-protocol/src/network/oam.rs +++ b/commons/zenoh-protocol/src/network/oam.rs @@ -33,15 +33,14 @@ pub mod flag { /// +-+-+-+---------+ /// ~ id:z16 ~ /// +---------------+ -/// % length % -- If ENC == u64 || ENC == ZBuf +/// % length % -- If ENC == Z64 || ENC == ZBuf (z32) /// +---------------+ /// ~ [u8] ~ -- If ENC == ZBuf /// +---------------+ -/// ``` /// /// Encoding: /// - 0b00: Unit -/// - 0b01: u64 +/// - 0b01: Z64 /// - 0b10: ZBuf /// - 0b11: Reserved /// ``` diff --git a/commons/zenoh-protocol/src/zenoh_new/ack.rs b/commons/zenoh-protocol/src/zenoh_new/ack.rs index 97eccb1f57..cd49daf304 100644 --- a/commons/zenoh-protocol/src/zenoh_new/ack.rs +++ b/commons/zenoh-protocol/src/zenoh_new/ack.rs @@ -11,6 +11,8 @@ // Contributors: // ZettaScale Zenoh Team, // +use crate::common::ZExtUnknown; +use alloc::vec::Vec; use uhlc::Timestamp; /// # Ack message @@ -40,6 +42,7 @@ pub mod flag { pub struct Ack { pub timestamp: Option, pub ext_sinfo: Option, + pub ext_unknown: Vec, } pub mod ext { @@ -52,7 +55,7 @@ pub mod ext { impl Ack { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::ZenohId; + use crate::{common::iext, core::ZenohId}; use core::convert::TryFrom; use rand::Rng; let mut rng = rand::thread_rng(); @@ -63,10 +66,18 @@ impl Ack { Timestamp::new(time, id) }); let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + let mut ext_unknown = Vec::new(); + for _ in 0..rng.gen_range(0..4) { + ext_unknown.push(ZExtUnknown::rand2( + iext::mid(ext::SourceInfo::ID) + 1, + false, + )); + } Self { timestamp, ext_sinfo, + ext_unknown, } } } diff --git a/commons/zenoh-protocol/src/zenoh_new/del.rs b/commons/zenoh-protocol/src/zenoh_new/del.rs index cfcc32706e..c76caa775e 100644 --- a/commons/zenoh-protocol/src/zenoh_new/del.rs +++ b/commons/zenoh-protocol/src/zenoh_new/del.rs @@ -13,6 +13,8 @@ // use uhlc::Timestamp; +use crate::common::ZExtUnknown; + /// # Put message /// /// ```text @@ -40,6 +42,7 @@ pub mod flag { pub struct Del { pub timestamp: Option, pub ext_sinfo: Option, + pub ext_unknown: Vec, } pub mod ext { @@ -52,7 +55,7 @@ pub mod ext { impl Del { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::ZenohId; + use crate::{common::iext, core::ZenohId}; use core::convert::TryFrom; use rand::Rng; let mut rng = rand::thread_rng(); @@ -63,10 +66,18 @@ impl Del { Timestamp::new(time, id) }); let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + let mut ext_unknown = Vec::new(); + for _ in 0..rng.gen_range(0..4) { + ext_unknown.push(ZExtUnknown::rand2( + iext::mid(ext::SourceInfo::ID) + 1, + false, + )); + } Self { timestamp, ext_sinfo, + ext_unknown, } } } diff --git a/commons/zenoh-protocol/src/zenoh_new/err.rs b/commons/zenoh-protocol/src/zenoh_new/err.rs index 5f7939f147..20540b33ab 100644 --- a/commons/zenoh-protocol/src/zenoh_new/err.rs +++ b/commons/zenoh-protocol/src/zenoh_new/err.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // +use crate::common::ZExtUnknown; use uhlc::Timestamp; /// # Err message @@ -45,6 +46,7 @@ pub struct Err { pub timestamp: Option, pub ext_sinfo: Option, pub ext_body: Option, + pub ext_unknown: Vec, } pub mod ext { @@ -89,7 +91,7 @@ pub mod ext { impl Err { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::ZenohId; + use crate::{common::iext, core::ZenohId}; use core::convert::TryFrom; use rand::Rng; let mut rng = rand::thread_rng(); @@ -103,6 +105,10 @@ impl Err { }); let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); let ext_body = rng.gen_bool(0.5).then_some(ext::ErrBodyType::rand()); + let mut ext_unknown = Vec::new(); + for _ in 0..rng.gen_range(0..4) { + ext_unknown.push(ZExtUnknown::rand2(iext::mid(ext::ErrBody::ID) + 1, false)); + } Self { code, @@ -110,6 +116,7 @@ impl Err { timestamp, ext_sinfo, ext_body, + ext_unknown, } } } diff --git a/commons/zenoh-protocol/src/zenoh_new/put.rs b/commons/zenoh-protocol/src/zenoh_new/put.rs index db8872513a..1869e5db21 100644 --- a/commons/zenoh-protocol/src/zenoh_new/put.rs +++ b/commons/zenoh-protocol/src/zenoh_new/put.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::Encoding; +use crate::{common::ZExtUnknown, core::Encoding}; use uhlc::Timestamp; use zenoh_buffers::ZBuf; @@ -47,6 +47,7 @@ pub struct Put { pub timestamp: Option, pub encoding: Encoding, pub ext_sinfo: Option, + pub ext_unknown: Vec, pub payload: ZBuf, } @@ -92,7 +93,7 @@ pub mod ext { impl Put { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::ZenohId; + use crate::{common::iext, core::ZenohId}; use core::convert::TryFrom; use rand::Rng; let mut rng = rand::thread_rng(); @@ -105,11 +106,19 @@ impl Put { let encoding = Encoding::rand(); let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); let payload = ZBuf::rand(rng.gen_range(1..=64)); + let mut ext_unknown = Vec::new(); + for _ in 0..rng.gen_range(0..4) { + ext_unknown.push(ZExtUnknown::rand2( + iext::mid(ext::SourceInfo::ID) + 1, + false, + )); + } Self { timestamp, encoding, ext_sinfo, + ext_unknown, payload, } } diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs index 576b233bcc..4752923612 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // +use crate::common::ZExtUnknown; use alloc::string::String; /// The kind of consolidation. @@ -83,6 +84,7 @@ pub struct Query { pub ext_sinfo: Option, pub ext_consolidation: Consolidation, pub ext_body: Option, + pub ext_unknown: Vec, } pub mod ext { @@ -99,7 +101,7 @@ pub mod ext { pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; /// # Consolidation extension - pub type Consolidation = zextz64!(0x2, false); + pub type Consolidation = zextz64!(0x2, true); pub type ConsolidationType = crate::zenoh_new::query::Consolidation; /// # QueryBody extension @@ -135,6 +137,7 @@ pub mod ext { impl Query { #[cfg(feature = "test")] pub fn rand() -> Self { + use crate::common::iext; use rand::{ distributions::{Alphanumeric, DistString}, Rng, @@ -153,12 +156,17 @@ impl Query { let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); let ext_consolidation = Consolidation::rand(); let ext_body = rng.gen_bool(0.5).then_some(ext::QueryBodyType::rand()); + let mut ext_unknown = Vec::new(); + for _ in 0..rng.gen_range(0..4) { + ext_unknown.push(ZExtUnknown::rand2(iext::mid(ext::QueryBody::ID) + 1, false)); + } Self { parameters, ext_sinfo, ext_consolidation, ext_body, + ext_unknown, } } } diff --git a/commons/zenoh-protocol/src/zenoh_new/reply.rs b/commons/zenoh-protocol/src/zenoh_new/reply.rs index 7126841049..e34895e814 100644 --- a/commons/zenoh-protocol/src/zenoh_new/reply.rs +++ b/commons/zenoh-protocol/src/zenoh_new/reply.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::core::Encoding; +use crate::{common::ZExtUnknown, core::Encoding}; use uhlc::Timestamp; use zenoh_buffers::ZBuf; @@ -48,6 +48,7 @@ pub struct Reply { pub encoding: Encoding, pub ext_sinfo: Option, pub ext_consolidation: ext::ConsolidationType, + pub ext_unknown: Vec, pub payload: ZBuf, } @@ -65,8 +66,7 @@ pub mod ext { impl Reply { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::ZenohId; - use crate::zenoh_new::Consolidation; + use crate::{common::iext, core::ZenohId, zenoh_new::Consolidation}; use core::convert::TryFrom; use rand::Rng; let mut rng = rand::thread_rng(); @@ -80,12 +80,20 @@ impl Reply { let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); let ext_consolidation = Consolidation::rand(); let payload = ZBuf::rand(rng.gen_range(1..=64)); + let mut ext_unknown = Vec::new(); + for _ in 0..rng.gen_range(0..4) { + ext_unknown.push(ZExtUnknown::rand2( + iext::mid(ext::Consolidation::ID) + 1, + false, + )); + } Self { timestamp, encoding, ext_sinfo, ext_consolidation, + ext_unknown, payload, } } From 0db8f6186e9b4f8cdbc52164abcea108639f3a71 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Wed, 5 Apr 2023 18:23:49 +0200 Subject: [PATCH 133/203] Add NodeId extention --- commons/zenoh-codec/src/network/declare.rs | 7 ++++ commons/zenoh-codec/src/network/mod.rs | 3 ++ commons/zenoh-codec/src/network/push.rs | 7 ++++ commons/zenoh-codec/src/network/request.rs | 7 ++++ commons/zenoh-protocol/src/network/declare.rs | 6 +++ commons/zenoh-protocol/src/network/mod.rs | 38 +++++++++++++++++++ commons/zenoh-protocol/src/network/push.rs | 6 +++ commons/zenoh-protocol/src/network/request.rs | 12 ++++-- 8 files changed, 83 insertions(+), 3 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index 832609622d..9a1bc1cddf 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -137,6 +137,7 @@ where // Extensions let mut ext_qos = declare::ext::QoSType::default(); let mut ext_tstamp = None; + let mut ext_nodeid = declare::ext::NodeIdType::default(); let mut has_ext = imsg::has_flag(self.header, declare::flag::Z); while has_ext { @@ -153,6 +154,11 @@ where ext_tstamp = Some(t); has_ext = ext; } + declare::ext::NodeId::ID => { + let (nid, ext): (declare::ext::NodeIdType, bool) = eodec.read(&mut *reader)?; + ext_nodeid = nid; + has_ext = ext; + } _ => { has_ext = extension::skip(reader, "Declare", ext)?; } @@ -166,6 +172,7 @@ where body, ext_qos, ext_tstamp, + ext_nodeid, }) } } diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index b068bba7c9..f95ead9676 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -114,3 +114,6 @@ where Ok((ext::TimestampType { timestamp }, more)) } } + +// Extensions: QoS +crate::impl_zextz64!(ext::NodeIdType, ext::NodeId::ID); diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index 07563a10e7..ed68567a8c 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -105,6 +105,7 @@ where // Extensions let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; + let mut ext_nodeid = ext::NodeIdType::default(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -121,6 +122,11 @@ where ext_tstamp = Some(t); has_ext = ext; } + ext::NodeId::ID => { + let (nid, ext): (ext::NodeIdType, bool) = eodec.read(&mut *reader)?; + ext_nodeid = nid; + has_ext = ext; + } _ => { has_ext = extension::skip(reader, "Push", ext)?; } @@ -136,6 +142,7 @@ where payload, ext_qos, ext_tstamp, + ext_nodeid, }) } } diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 003276cbbd..258c8d6af8 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -168,6 +168,7 @@ where // Extensions let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; + let mut ext_nodeid = ext::NodeIdType::default(); let mut ext_target = ext::TargetType::default(); let mut ext_limit = None; let mut ext_timeout = None; @@ -187,6 +188,11 @@ where ext_tstamp = Some(t); has_ext = ext; } + ext::NodeId::ID => { + let (nid, ext): (ext::NodeIdType, bool) = eodec.read(&mut *reader)?; + ext_nodeid = nid; + has_ext = ext; + } ext::Target::ID => { let (rt, ext): (ext::TargetType, bool) = eodec.read(&mut *reader)?; ext_target = rt; @@ -218,6 +224,7 @@ where payload, ext_qos, ext_tstamp, + ext_nodeid, ext_target, ext_budget: ext_limit, ext_timeout, diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index a76831b73b..204d4700b8 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -46,6 +46,7 @@ pub mod flag { pub struct Declare { pub ext_qos: ext::QoSType, pub ext_tstamp: Option, + pub ext_nodeid: ext::NodeIdType, pub body: DeclareBody, } @@ -55,6 +56,9 @@ pub mod ext { pub type Timestamp = crate::network::ext::Timestamp; pub type TimestampType = crate::network::ext::TimestampType; + + pub type NodeId = crate::network::ext::NodeId; + pub type NodeIdType = crate::network::ext::NodeIdType; } pub mod id { @@ -114,11 +118,13 @@ impl Declare { let body = DeclareBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); + let ext_nodeid = ext::NodeIdType::rand(); Self { body, ext_qos, ext_tstamp, + ext_nodeid, } } } diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index f4ace32c9e..1400c990b8 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -146,6 +146,7 @@ pub mod ext { pub type QoS = zextz64!(0x1, false); pub type Timestamp = zextzbuf!(0x2, false); + pub type NodeId = zextz64!(0x3, true); /// ```text /// 7 6 5 4 3 2 1 0 @@ -268,4 +269,41 @@ pub mod ext { Self { timestamp } } } + + /// ```text + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|0_1| ID | + /// +-+-+-+---------+ + /// % source_id % + /// +---------------+ + /// ``` + #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] + pub struct NodeIdType { + pub node_id: u16, + } + + impl NodeIdType { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + let node_id = rng.gen_range(1..20); + Self { node_id } + } + } + + impl From for NodeIdType { + fn from(ext: NodeId) -> Self { + Self { + node_id: ext.value as u16, + } + } + } + + impl From for NodeId { + fn from(ext: NodeIdType) -> Self { + NodeId::new(ext.node_id as u64) + } + } } diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs index 8704f3da52..4cede3556a 100644 --- a/commons/zenoh-protocol/src/network/push.rs +++ b/commons/zenoh-protocol/src/network/push.rs @@ -44,6 +44,7 @@ pub struct Push { pub mapping: Mapping, pub ext_qos: ext::QoSType, pub ext_tstamp: Option, + pub ext_nodeid: ext::NodeIdType, pub payload: PushBody, } @@ -53,6 +54,9 @@ pub mod ext { pub type Timestamp = crate::network::ext::Timestamp; pub type TimestampType = crate::network::ext::TimestampType; + + pub type NodeId = crate::network::ext::NodeId; + pub type NodeIdType = crate::network::ext::NodeIdType; } impl Push { @@ -66,6 +70,7 @@ impl Push { let payload = PushBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); + let ext_nodeid = ext::NodeIdType::rand(); Self { wire_expr, @@ -73,6 +78,7 @@ impl Push { payload, ext_tstamp, ext_qos, + ext_nodeid, } } } diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index c559c0f56c..38ab0b0964 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -57,6 +57,7 @@ pub struct Request { pub mapping: Mapping, pub ext_qos: ext::QoSType, pub ext_tstamp: Option, + pub ext_nodeid: ext::NodeIdType, pub ext_target: ext::TargetType, pub ext_budget: Option, pub ext_timeout: Option, @@ -73,7 +74,10 @@ pub mod ext { pub type Timestamp = crate::network::ext::Timestamp; pub type TimestampType = crate::network::ext::TimestampType; - pub type Target = zextz64!(0x3, true); + pub type NodeId = crate::network::ext::NodeId; + pub type NodeIdType = crate::network::ext::NodeIdType; + + pub type Target = zextz64!(0x4, true); /// - Target (0x03) /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ @@ -110,11 +114,11 @@ pub mod ext { } // The maximum number of responses - pub type Budget = zextz64!(0x4, false); + pub type Budget = zextz64!(0x5, false); pub type BudgetType = NonZeroU32; // The timeout of the request - pub type Timeout = zextz64!(0x5, false); + pub type Timeout = zextz64!(0x6, false); pub type TimeoutType = Duration; } @@ -132,6 +136,7 @@ impl Request { let payload = RequestBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); + let ext_nodeid = ext::NodeIdType::rand(); let ext_target = ext::TargetType::rand(); let ext_budget = if rng.gen_bool(0.5) { NonZeroU32::new(rng.gen()) @@ -151,6 +156,7 @@ impl Request { payload, ext_qos, ext_tstamp, + ext_nodeid, ext_target, ext_budget, ext_timeout, From 8cdf76468858e01be481fbce69d4a8c4aab89c55 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 6 Apr 2023 13:04:39 +0200 Subject: [PATCH 134/203] Fix nostd and codec --- commons/zenoh-codec/src/network/declare.rs | 7 ++++++- commons/zenoh-codec/src/network/mod.rs | 2 +- commons/zenoh-codec/src/network/push.rs | 9 +++++++-- commons/zenoh-codec/src/network/request.rs | 7 ++++++- commons/zenoh-protocol/src/zenoh_new/del.rs | 4 ++-- commons/zenoh-protocol/src/zenoh_new/err.rs | 1 + commons/zenoh-protocol/src/zenoh_new/put.rs | 1 + commons/zenoh-protocol/src/zenoh_new/query.rs | 2 +- commons/zenoh-protocol/src/zenoh_new/reply.rs | 1 + 9 files changed, 26 insertions(+), 8 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index 9a1bc1cddf..f2c93a494e 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -86,7 +86,8 @@ where // Header let mut header = id::DECLARE; let mut n_exts = ((x.ext_qos != declare::ext::QoSType::default()) as u8) - + (x.ext_tstamp.is_some() as u8); + + (x.ext_tstamp.is_some() as u8) + + ((x.ext_nodeid != declare::ext::NodeIdType::default()) as u8); if n_exts != 0 { header |= declare::flag::Z; } @@ -101,6 +102,10 @@ where n_exts -= 1; self.write(&mut *writer, (ts, n_exts != 0))?; } + if x.ext_nodeid != declare::ext::NodeIdType::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_nodeid, n_exts != 0))?; + } // Body self.write(&mut *writer, &x.body)?; diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index f95ead9676..359c77c74d 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -115,5 +115,5 @@ where } } -// Extensions: QoS +// Extensions: NodeId crate::impl_zextz64!(ext::NodeIdType, ext::NodeId::ID); diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index ed68567a8c..b83bb1d15e 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -36,8 +36,9 @@ where fn write(self, writer: &mut W, x: &Push) -> Self::Output { // Header let mut header = id::PUSH; - let mut n_exts = - ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); + let mut n_exts = ((x.ext_qos != ext::QoSType::default()) as u8) + + (x.ext_tstamp.is_some() as u8) + + ((x.ext_nodeid != ext::NodeIdType::default()) as u8); if n_exts != 0 { header |= flag::Z; } @@ -61,6 +62,10 @@ where n_exts -= 1; self.write(&mut *writer, (ts, n_exts != 0))?; } + if x.ext_nodeid != ext::NodeIdType::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_nodeid, n_exts != 0))?; + } // Payload self.write(&mut *writer, &x.payload)?; diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 258c8d6af8..2db45d49c5 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -83,7 +83,8 @@ where + (x.ext_tstamp.is_some() as u8) + ((x.ext_target != ext::TargetType::default()) as u8) + (x.ext_budget.is_some() as u8) - + (x.ext_timeout.is_some() as u8); + + (x.ext_timeout.is_some() as u8) + + ((x.ext_nodeid != ext::NodeIdType::default()) as u8); if n_exts != 0 { header |= flag::Z; } @@ -122,6 +123,10 @@ where let e = ext::Timeout::new(to.as_millis() as u64); self.write(&mut *writer, (&e, n_exts != 0))?; } + if x.ext_nodeid != ext::NodeIdType::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_nodeid, n_exts != 0))?; + } // Payload self.write(&mut *writer, &x.payload)?; diff --git a/commons/zenoh-protocol/src/zenoh_new/del.rs b/commons/zenoh-protocol/src/zenoh_new/del.rs index c76caa775e..57a01f3675 100644 --- a/commons/zenoh-protocol/src/zenoh_new/del.rs +++ b/commons/zenoh-protocol/src/zenoh_new/del.rs @@ -11,9 +11,9 @@ // Contributors: // ZettaScale Zenoh Team, // -use uhlc::Timestamp; - use crate::common::ZExtUnknown; +use alloc::vec::Vec; +use uhlc::Timestamp; /// # Put message /// diff --git a/commons/zenoh-protocol/src/zenoh_new/err.rs b/commons/zenoh-protocol/src/zenoh_new/err.rs index 20540b33ab..cc1959e79c 100644 --- a/commons/zenoh-protocol/src/zenoh_new/err.rs +++ b/commons/zenoh-protocol/src/zenoh_new/err.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::common::ZExtUnknown; +use alloc::vec::Vec; use uhlc::Timestamp; /// # Err message diff --git a/commons/zenoh-protocol/src/zenoh_new/put.rs b/commons/zenoh-protocol/src/zenoh_new/put.rs index 1869e5db21..11b2ac9b4d 100644 --- a/commons/zenoh-protocol/src/zenoh_new/put.rs +++ b/commons/zenoh-protocol/src/zenoh_new/put.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{common::ZExtUnknown, core::Encoding}; +use alloc::vec::Vec; use uhlc::Timestamp; use zenoh_buffers::ZBuf; diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs index 4752923612..85d410f3e6 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use crate::common::ZExtUnknown; -use alloc::string::String; +use alloc::{string::String, vec::Vec}; /// The kind of consolidation. #[repr(u8)] diff --git a/commons/zenoh-protocol/src/zenoh_new/reply.rs b/commons/zenoh-protocol/src/zenoh_new/reply.rs index e34895e814..d1743ba2aa 100644 --- a/commons/zenoh-protocol/src/zenoh_new/reply.rs +++ b/commons/zenoh-protocol/src/zenoh_new/reply.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{common::ZExtUnknown, core::Encoding}; +use alloc::vec::Vec; use uhlc::Timestamp; use zenoh_buffers::ZBuf; From 29ed1d08fa739e4e8d83d6f53fc337264ba2afb2 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 6 Apr 2023 15:55:40 +0200 Subject: [PATCH 135/203] Declare/Final/Undeclare-Interest message --- commons/zenoh-codec/src/network/declare.rs | 220 +++++++++++++++++- commons/zenoh-protocol/src/network/declare.rs | 183 ++++++++++++++- 2 files changed, 393 insertions(+), 10 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index f2c93a494e..79a9489b35 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -20,7 +20,7 @@ use zenoh_protocol::{ common::{iext, imsg, ZExtZ64}, core::{ExprId, WireExpr}, network::{ - declare::{self, keyexpr, queryable, subscriber, token, Declare, DeclareBody}, + declare::{self, interest, keyexpr, queryable, subscriber, token, Declare, DeclareBody}, id, Mapping, }, }; @@ -42,6 +42,9 @@ where DeclareBody::UndeclareQueryable(r) => self.write(&mut *writer, r)?, DeclareBody::DeclareToken(r) => self.write(&mut *writer, r)?, DeclareBody::UndeclareToken(r) => self.write(&mut *writer, r)?, + DeclareBody::DeclareInterest(r) => self.write(&mut *writer, r)?, + DeclareBody::FinalInterest(r) => self.write(&mut *writer, r)?, + DeclareBody::UndeclareInterest(r) => self.write(&mut *writer, r)?, } Ok(()) @@ -68,6 +71,9 @@ where U_QUERYABLE => DeclareBody::UndeclareQueryable(codec.read(&mut *reader)?), D_TOKEN => DeclareBody::DeclareToken(codec.read(&mut *reader)?), U_TOKEN => DeclareBody::UndeclareToken(codec.read(&mut *reader)?), + D_INTEREST => DeclareBody::DeclareInterest(codec.read(&mut *reader)?), + F_INTEREST => DeclareBody::FinalInterest(codec.read(&mut *reader)?), + U_INTEREST => DeclareBody::UndeclareInterest(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; @@ -244,7 +250,7 @@ where } } -// ForgetKeyExpr +// UndeclareKeyExpr impl WCodec<&keyexpr::UndeclareKeyExpr, &mut W> for Zenoh080 where W: Writer, @@ -293,7 +299,7 @@ where // Extensions let has_ext = imsg::has_flag(self.header, keyexpr::flag::Z); if has_ext { - extension::skip_all(reader, "ForgetKeyExpr")?; + extension::skip_all(reader, "UndeclareKeyExpr")?; } Ok(keyexpr::UndeclareKeyExpr { id }) @@ -403,7 +409,7 @@ where } } -// ForgetSubscriber +// UndeclareSubscriber impl WCodec<&subscriber::UndeclareSubscriber, &mut W> for Zenoh080 where W: Writer, @@ -453,7 +459,7 @@ where // Extensions let has_ext = imsg::has_flag(self.header, subscriber::flag::Z); if has_ext { - extension::skip_all(reader, "ForgetSubscriber")?; + extension::skip_all(reader, "UndeclareSubscriber")?; } Ok(subscriber::UndeclareSubscriber { id }) @@ -561,7 +567,7 @@ where } } -// ForgetQueryable +// UndeclareQueryable impl WCodec<&queryable::UndeclareQueryable, &mut W> for Zenoh080 where W: Writer, @@ -611,7 +617,7 @@ where // Extensions let has_ext = imsg::has_flag(self.header, queryable::flag::Z); if has_ext { - extension::skip_all(reader, "ForgetQueryable")?; + extension::skip_all(reader, "UndeclareQueryable")?; } Ok(queryable::UndeclareQueryable { id }) @@ -692,7 +698,7 @@ where } } -// ForgetToken +// UndeclareToken impl WCodec<&token::UndeclareToken, &mut W> for Zenoh080 where W: Writer, @@ -742,9 +748,205 @@ where // Extensions let has_ext = imsg::has_flag(self.header, token::flag::Z); if has_ext { - extension::skip_all(reader, "ForgetToken")?; + extension::skip_all(reader, "UndeclareToken")?; } Ok(token::UndeclareToken { id }) } } + +// DeclareInterest +impl WCodec<&interest::DeclareInterest, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &interest::DeclareInterest) -> Self::Output { + // Header + let mut header = declare::id::D_INTEREST; + if x.mapping != Mapping::default() { + header |= subscriber::flag::M; + } + if x.wire_expr.has_suffix() { + header |= subscriber::flag::N; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + self.write(&mut *writer, &x.wire_expr)?; + let mut b = imsg::mid(x.kind); + if x.aggregate { + b |= interest::flag::A; + } + self.write(&mut *writer, b)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::D_INTEREST { + return Err(DidntRead); + } + + // Body + let id: interest::InterestId = self.codec.read(&mut *reader)?; + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, token::flag::N)); + let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + let mapping = if imsg::has_flag(self.header, token::flag::M) { + Mapping::Sender + } else { + Mapping::Receiver + }; + let kind: u8 = self.codec.read(&mut *reader)?; + + // Extensions + let has_ext = imsg::has_flag(self.header, token::flag::Z); + if has_ext { + extension::skip_all(reader, "DeclareInterest")?; + } + + Ok(interest::DeclareInterest { + id, + wire_expr, + mapping, + kind: imsg::mid(kind), + aggregate: imsg::has_flag(kind, interest::flag::A), + }) + } +} + +// FinalInterest +impl WCodec<&interest::FinalInterest, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &interest::FinalInterest) -> Self::Output { + // Header + let header = declare::id::F_INTEREST; + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::F_INTEREST { + return Err(DidntRead); + } + + // Body + let id: interest::InterestId = self.codec.read(&mut *reader)?; + + // Extensions + let has_ext = imsg::has_flag(self.header, token::flag::Z); + if has_ext { + extension::skip_all(reader, "FinalInterest")?; + } + + Ok(interest::FinalInterest { id }) + } +} + +// UndeclareInterest +impl WCodec<&interest::UndeclareInterest, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &interest::UndeclareInterest) -> Self::Output { + // Header + let header = declare::id::U_INTEREST; + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, x.id)?; + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != declare::id::U_INTEREST { + return Err(DidntRead); + } + + // Body + let id: interest::InterestId = self.codec.read(&mut *reader)?; + + // Extensions + let has_ext = imsg::has_flag(self.header, token::flag::Z); + if has_ext { + extension::skip_all(reader, "UndeclareInterest")?; + } + + Ok(interest::UndeclareInterest { id }) + } +} diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index 204d4700b8..a83942a794 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -17,6 +17,7 @@ use crate::{ network::Mapping, zextz64, }; +pub use interest::*; pub use keyexpr::*; pub use queryable::*; pub use subscriber::*; @@ -73,6 +74,10 @@ pub mod id { pub const D_TOKEN: u8 = 0x06; pub const U_TOKEN: u8 = 0x07; + + pub const D_INTEREST: u8 = 0x08; + pub const F_INTEREST: u8 = 0x09; + pub const U_INTEREST: u8 = 0x10; } #[derive(Debug, Clone, PartialEq, Eq)] @@ -85,6 +90,9 @@ pub enum DeclareBody { UndeclareQueryable(UndeclareQueryable), DeclareToken(DeclareToken), UndeclareToken(UndeclareToken), + DeclareInterest(DeclareInterest), + FinalInterest(FinalInterest), + UndeclareInterest(UndeclareInterest), } impl DeclareBody { @@ -94,7 +102,7 @@ impl DeclareBody { let mut rng = rand::thread_rng(); - match rng.gen_range(0..8) { + match rng.gen_range(0..11) { 0 => DeclareBody::DeclareKeyExpr(DeclareKeyExpr::rand()), 1 => DeclareBody::UndeclareKeyExpr(UndeclareKeyExpr::rand()), 2 => DeclareBody::DeclareSubscriber(DeclareSubscriber::rand()), @@ -103,6 +111,9 @@ impl DeclareBody { 5 => DeclareBody::UndeclareQueryable(UndeclareQueryable::rand()), 6 => DeclareBody::DeclareToken(DeclareToken::rand()), 7 => DeclareBody::UndeclareToken(UndeclareToken::rand()), + 8 => DeclareBody::DeclareInterest(DeclareInterest::rand()), + 9 => DeclareBody::FinalInterest(FinalInterest::rand()), + 10 => DeclareBody::UndeclareInterest(UndeclareInterest::rand()), _ => unreachable!(), } } @@ -628,3 +639,173 @@ pub mod token { } } } + +pub mod interest { + use super::*; + + pub type InterestId = u32; + + pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow + + pub const A: u8 = 1 << 5; // 0x20 Aggregate if A==1 then the replies should be aggregated + } + + /// # Init message + /// + /// The DECLARE INTEREST message is sent to request the transmission of existing and future + /// declarations of a given kind matching a target keyexpr. E.g., a declare interest could be sent to + /// request the transmisison of all existing subscriptions matching `a/*`. A FINAL INTEREST is used to + /// mark the end of the transmission of exisiting matching declarations. + /// + /// E.g., the [`DeclareInterest`]/[`FinalInterest`]/[`UndeclareInterest`] message flow is the following: + /// + /// ```text + /// A B + /// | DECL INTEREST | + /// |------------------>| -- This is a DeclareInterest e.g. for subscriber declarations/undeclarations. + /// | | + /// | DECL SUBSCRIBER | + /// |<------------------| + /// | DECL SUBSCRIBER | + /// |<------------------| + /// | DECL SUBSCRIBER | + /// |<------------------| + /// | | + /// | FINAL INTEREST | + /// |<------------------| -- The FinalInterest signals that all known subscribers have been transmitted. + /// | | + /// | DECL SUBSCRIBER | + /// |<------------------| -- This is a new subscriber declaration. + /// | UNDECL SUBSCRIBER | + /// |<------------------| -- This is a new subscriber undeclaration. + /// | | + /// | ... | + /// | | + /// | UNDECL INTEREST | + /// |------------------>| -- This is an UndeclareInterest to stop receiving subscriber declarations/undeclarations. + /// | | + /// ``` + /// + /// The DECLARE INTEREST message structure is defined as follows: + /// + /// ```text + /// Flags: + /// - N: Named If N==1 then the key expr has name/suffix + /// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|M|N| D_INT | + /// +---------------+ + /// ~ intst_id:z32 ~ + /// +---------------+ + /// ~ key_scope:z16 ~ + /// +---------------+ + /// ~ key_suffix ~ if N==1 -- + /// +---------------+ + /// |X|X|A| ID | (*) if A==1 then the replies should be aggregated + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// + /// (*) ID: the ID of the declaration interest (i.e. keyexpr, subscriber, queryable, token) + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct DeclareInterest { + pub id: InterestId, + pub wire_expr: WireExpr<'static>, + pub mapping: Mapping, + pub kind: u8, + pub aggregate: bool, + } + + impl DeclareInterest { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: InterestId = rng.gen(); + let wire_expr = WireExpr::rand(); + let mapping = Mapping::rand(); + let kind = imsg::mid(rng.gen()); + let aggregate: bool = rng.gen(); + + Self { + id, + wire_expr, + mapping, + kind, + aggregate, + } + } + } + + /// ```text + /// Flags: + /// - X: Reserved + /// - X: Reserved + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|X|X| F_INT | + /// +---------------+ + /// ~ intst_id:z32 ~ + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct FinalInterest { + pub id: InterestId, + } + + impl FinalInterest { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: InterestId = rng.gen(); + + Self { id } + } + } + + /// ```text + /// Flags: + /// - X: Reserved + /// - X: Reserved + /// - Z: Extension If Z==1 then at least one extension is present + /// + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |Z|X|X| U_INT | + /// +---------------+ + /// ~ intst_id:z32 ~ + /// +---------------+ + /// ~ [decl_exts] ~ if Z==1 + /// +---------------+ + /// ``` + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct UndeclareInterest { + pub id: InterestId, + } + + impl UndeclareInterest { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let id: InterestId = rng.gen(); + + Self { id } + } + } +} From b45571bafdfa83c76a77a34f685baff3f25bba7b Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 7 Apr 2023 16:29:45 +0200 Subject: [PATCH 136/203] Add Oneshot flag on Interest --- commons/zenoh-codec/src/network/declare.rs | 4 ++++ commons/zenoh-protocol/src/network/declare.rs | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index 79a9489b35..a377d49439 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -780,6 +780,9 @@ where if x.aggregate { b |= interest::flag::A; } + if x.oneshot { + b |= interest::flag::O; + } self.write(&mut *writer, b)?; Ok(()) @@ -833,6 +836,7 @@ where mapping, kind: imsg::mid(kind), aggregate: imsg::has_flag(kind, interest::flag::A), + oneshot: imsg::has_flag(kind, interest::flag::O), }) } } diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index a83942a794..f71c31dd84 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -651,6 +651,7 @@ pub mod interest { pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow pub const A: u8 = 1 << 5; // 0x20 Aggregate if A==1 then the replies should be aggregated + pub const O: u8 = 1 << 6; // 0x40 Oneshot if O==1 should be oneshot and no replies should be sent after the FinalInterest } /// # Init message @@ -707,12 +708,14 @@ pub mod interest { /// +---------------+ /// ~ key_suffix ~ if N==1 -- /// +---------------+ - /// |X|X|A| ID | (*) if A==1 then the replies should be aggregated + /// |X|O|A| ID | (*) /// +---------------+ /// ~ [decl_exts] ~ if Z==1 /// +---------------+ /// - /// (*) ID: the ID of the declaration interest (i.e. keyexpr, subscriber, queryable, token) + /// (*) - ID: the ID of the declaration interest (i.e. keyexpr, subscriber, queryable, token) + /// - if A==1 then the replies should be aggregated + /// - if O==1 then the replies should be oneshot and no replies should be sent after the FinalInterest /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareInterest { @@ -721,6 +724,7 @@ pub mod interest { pub mapping: Mapping, pub kind: u8, pub aggregate: bool, + pub oneshot: bool, } impl DeclareInterest { @@ -734,6 +738,7 @@ pub mod interest { let mapping = Mapping::rand(); let kind = imsg::mid(rng.gen()); let aggregate: bool = rng.gen(); + let oneshot: bool = rng.gen(); Self { id, @@ -741,6 +746,7 @@ pub mod interest { mapping, kind, aggregate, + oneshot, } } } From a5106daeb271bdcc4636f2cc0ee82a382962b65a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 12 Apr 2023 17:40:59 +0200 Subject: [PATCH 137/203] More compact DeclareInterest message --- commons/zenoh-codec/src/network/declare.rs | 15 +-- commons/zenoh-protocol/src/network/declare.rs | 97 +++++++++++++++---- 2 files changed, 83 insertions(+), 29 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index a377d49439..c73737298f 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -776,14 +776,7 @@ where // Body self.write(&mut *writer, x.id)?; self.write(&mut *writer, &x.wire_expr)?; - let mut b = imsg::mid(x.kind); - if x.aggregate { - b |= interest::flag::A; - } - if x.oneshot { - b |= interest::flag::O; - } - self.write(&mut *writer, b)?; + self.write(&mut *writer, x.interest.as_u8())?; Ok(()) } @@ -822,7 +815,7 @@ where } else { Mapping::Receiver }; - let kind: u8 = self.codec.read(&mut *reader)?; + let interest: u8 = self.codec.read(&mut *reader)?; // Extensions let has_ext = imsg::has_flag(self.header, token::flag::Z); @@ -834,9 +827,7 @@ where id, wire_expr, mapping, - kind: imsg::mid(kind), - aggregate: imsg::has_flag(kind, interest::flag::A), - oneshot: imsg::has_flag(kind, interest::flag::O), + interest: interest.into(), }) } } diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index f71c31dd84..ddfdf0b3a2 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -17,6 +17,7 @@ use crate::{ network::Mapping, zextz64, }; +use core::ops::BitOr; pub use interest::*; pub use keyexpr::*; pub use queryable::*; @@ -649,12 +650,9 @@ pub mod interest { pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow - - pub const A: u8 = 1 << 5; // 0x20 Aggregate if A==1 then the replies should be aggregated - pub const O: u8 = 1 << 6; // 0x40 Oneshot if O==1 should be oneshot and no replies should be sent after the FinalInterest } - /// # Init message + /// # DeclareInterest message /// /// The DECLARE INTEREST message is sent to request the transmission of existing and future /// declarations of a given kind matching a target keyexpr. E.g., a declare interest could be sent to @@ -708,23 +706,92 @@ pub mod interest { /// +---------------+ /// ~ key_suffix ~ if N==1 -- /// +---------------+ - /// |X|O|A| ID | (*) + /// |O|A|X|X|T|Q|S|K| (*) /// +---------------+ /// ~ [decl_exts] ~ if Z==1 /// +---------------+ /// - /// (*) - ID: the ID of the declaration interest (i.e. keyexpr, subscriber, queryable, token) - /// - if A==1 then the replies should be aggregated - /// - if O==1 then the replies should be oneshot and no replies should be sent after the FinalInterest + /// (*) - if K==1 then the interest refers to key expressions + /// - if S==1 then the interest refers to subscribers + /// - if Q==1 then the interest refers to queryables + /// - if T==1 then the interest refers to tokens + /// - if A==1 then the replies SHOULD be aggregated + /// - if O==1 then the replies are oneshot and no replies SHOULD be sent after the FinalInterest. + /// Moreover, no UndeclareInterest SHOULD be sent after the FinalInterest. /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareInterest { pub id: InterestId, pub wire_expr: WireExpr<'static>, pub mapping: Mapping, - pub kind: u8, - pub aggregate: bool, - pub oneshot: bool, + pub interest: Interest, + } + + #[repr(transparent)] + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct Interest(u8); + + impl Interest { + pub const KEYEXPRS: Interest = Interest(1); + pub const SUBSCRIBERS: Interest = Interest(1 << 1); + pub const QUERYABLES: Interest = Interest(1 << 2); + pub const TOKENS: Interest = Interest(1 << 3); + // pub const X: Interest = Interest(1 << 4); + // pub const X: Interest = Interest(1 << 5); + pub const AGGREGATED: Interest = Interest(1 << 6); + pub const ONESHOT: Interest = Interest(1 << 7); + + pub const fn keyexprs(&self) -> bool { + imsg::has_flag(self.0, Self::KEYEXPRS.0) + } + + pub const fn subscribers(&self) -> bool { + imsg::has_flag(self.0, Self::SUBSCRIBERS.0) + } + + pub const fn queryables(&self) -> bool { + imsg::has_flag(self.0, Self::QUERYABLES.0) + } + + pub const fn tokens(&self) -> bool { + imsg::has_flag(self.0, Self::TOKENS.0) + } + + pub const fn aggregated(&self) -> bool { + imsg::has_flag(self.0, Self::AGGREGATED.0) + } + + pub const fn oneshot(&self) -> bool { + imsg::has_flag(self.0, Self::ONESHOT.0) + } + + pub const fn as_u8(&self) -> u8 { + self.0 + } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let inner: u8 = rng.gen(); + + Self(inner) + } + } + + impl BitOr for Interest { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self::Output { + Self(self.0 | rhs.0) + } + } + + impl From for Interest { + fn from(v: u8) -> Self { + Self(v) + } } impl DeclareInterest { @@ -736,17 +803,13 @@ pub mod interest { let id: InterestId = rng.gen(); let wire_expr = WireExpr::rand(); let mapping = Mapping::rand(); - let kind = imsg::mid(rng.gen()); - let aggregate: bool = rng.gen(); - let oneshot: bool = rng.gen(); + let interest = Interest::rand(); Self { id, wire_expr, mapping, - kind, - aggregate, - oneshot, + interest, } } } From 09c8ed00f1bef3d4f1582778e09613149a4ebebd Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 13 Apr 2023 10:49:57 +0200 Subject: [PATCH 138/203] Add Future flag in DeclareInterest message --- commons/zenoh-protocol/src/network/declare.rs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index ddfdf0b3a2..0b1f033120 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -706,7 +706,7 @@ pub mod interest { /// +---------------+ /// ~ key_suffix ~ if N==1 -- /// +---------------+ - /// |O|A|X|X|T|Q|S|K| (*) + /// |A|F|C|X|T|Q|S|K| (*) /// +---------------+ /// ~ [decl_exts] ~ if Z==1 /// +---------------+ @@ -715,9 +715,11 @@ pub mod interest { /// - if S==1 then the interest refers to subscribers /// - if Q==1 then the interest refers to queryables /// - if T==1 then the interest refers to tokens + /// - if C==1 then the interest refers to the current declarations. + /// - if F==1 then the interest refers to the future declarations. Note that if F==0 then: + /// - replies SHOULD NOT be sent after the FinalInterest + /// - UndeclareInterest SHOULD NOT be sent after the FinalInterest. /// - if A==1 then the replies SHOULD be aggregated - /// - if O==1 then the replies are oneshot and no replies SHOULD be sent after the FinalInterest. - /// Moreover, no UndeclareInterest SHOULD be sent after the FinalInterest. /// ``` #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareInterest { @@ -737,9 +739,9 @@ pub mod interest { pub const QUERYABLES: Interest = Interest(1 << 2); pub const TOKENS: Interest = Interest(1 << 3); // pub const X: Interest = Interest(1 << 4); - // pub const X: Interest = Interest(1 << 5); - pub const AGGREGATED: Interest = Interest(1 << 6); - pub const ONESHOT: Interest = Interest(1 << 7); + pub const CURRENT: Interest = Interest(1 << 5); + pub const FUTURE: Interest = Interest(1 << 6); + pub const AGGREGATE: Interest = Interest(1 << 7); pub const fn keyexprs(&self) -> bool { imsg::has_flag(self.0, Self::KEYEXPRS.0) @@ -757,12 +759,16 @@ pub mod interest { imsg::has_flag(self.0, Self::TOKENS.0) } - pub const fn aggregated(&self) -> bool { - imsg::has_flag(self.0, Self::AGGREGATED.0) + pub const fn current(&self) -> bool { + imsg::has_flag(self.0, Self::CURRENT.0) } - pub const fn oneshot(&self) -> bool { - imsg::has_flag(self.0, Self::ONESHOT.0) + pub const fn future(&self) -> bool { + imsg::has_flag(self.0, Self::FUTURE.0) + } + + pub const fn aggregate(&self) -> bool { + imsg::has_flag(self.0, Self::AGGREGATE.0) } pub const fn as_u8(&self) -> u8 { From 1128aa1e566b1e629bf2009a8b4bb6175a1b45db Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 13 Apr 2023 12:22:03 +0200 Subject: [PATCH 139/203] Explicit extension ID in all messages --- commons/zenoh-codec/src/common/extension.rs | 4 +- commons/zenoh-codec/src/network/mod.rs | 93 ++++++++++++++++--- commons/zenoh-codec/src/transport/frame.rs | 5 +- commons/zenoh-codec/src/transport/mod.rs | 44 ++++++++- commons/zenoh-codec/src/zenoh_new/mod.rs | 59 +++++++++++- commons/zenoh-codec/src/zenoh_new/put.rs | 60 +----------- commons/zenoh-protocol/src/network/declare.rs | 19 ++-- commons/zenoh-protocol/src/network/mod.rs | 43 ++++----- commons/zenoh-protocol/src/network/oam.rs | 13 ++- commons/zenoh-protocol/src/network/push.rs | 17 ++-- commons/zenoh-protocol/src/network/request.rs | 17 ++-- .../zenoh-protocol/src/network/response.rs | 12 ++- .../zenoh-protocol/src/transport/fragment.rs | 5 +- commons/zenoh-protocol/src/transport/frame.rs | 59 +----------- commons/zenoh-protocol/src/transport/mod.rs | 58 ++++++++++++ commons/zenoh-protocol/src/transport/oam.rs | 5 +- commons/zenoh-protocol/src/zenoh_new/ack.rs | 6 +- commons/zenoh-protocol/src/zenoh_new/del.rs | 6 +- commons/zenoh-protocol/src/zenoh_new/err.rs | 4 +- commons/zenoh-protocol/src/zenoh_new/mod.rs | 34 +++++++ commons/zenoh-protocol/src/zenoh_new/put.rs | 32 +------ commons/zenoh-protocol/src/zenoh_new/query.rs | 4 +- commons/zenoh-protocol/src/zenoh_new/reply.rs | 11 ++- 23 files changed, 377 insertions(+), 233 deletions(-) diff --git a/commons/zenoh-codec/src/common/extension.rs b/commons/zenoh-codec/src/common/extension.rs index b07eeaef45..4215711815 100644 --- a/commons/zenoh-codec/src/common/extension.rs +++ b/commons/zenoh-codec/src/common/extension.rs @@ -394,8 +394,8 @@ macro_rules! impl_zextz64 { type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: ($ext, bool)) -> Self::Output { - let (qos, more) = x; - let ext: ZExtZ64<{ $id }> = qos.into(); + let (x, more) = x; + let ext: ZExtZ64<{ $id }> = x.into(); self.write(&mut *writer, (&ext, more)) } } diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 359c77c74d..cb4bbd9aab 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -71,49 +71,120 @@ where } // Extensions: QoS -crate::impl_zextz64!(ext::QoSType, ext::QoS::ID); +impl WCodec<(ext::QoSType<{ ID }>, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (ext::QoSType<{ ID }>, bool)) -> Self::Output { + let (x, more) = x; + let ext: ZExtZ64<{ ID }> = x.into(); + self.write(&mut *writer, (&ext, more)) + } +} + +impl RCodec<(ext::QoSType<{ ID }>, bool), &mut R> for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoSType<{ ID }>, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec<(ext::QoSType<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoSType<{ ID }>, bool), Self::Error> { + let (ext, more): (ZExtZ64<{ ID }>, bool) = self.read(&mut *reader)?; + Ok((ext.into(), more)) + } +} // Extensions: Timestamp -impl WCodec<(&ext::TimestampType, bool), &mut W> for Zenoh080 +impl WCodec<(&ext::TimestampType<{ ID }>, bool), &mut W> for Zenoh080 where W: Writer, { type Output = Result<(), DidntWrite>; - fn write(self, writer: &mut W, x: (&ext::TimestampType, bool)) -> Self::Output { + fn write(self, writer: &mut W, x: (&ext::TimestampType<{ ID }>, bool)) -> Self::Output { let (tstamp, more) = x; - let header: ZExtZBufHeader<{ ext::Timestamp::ID }> = - ZExtZBufHeader::new(self.w_len(&tstamp.timestamp)); + let header: ZExtZBufHeader<{ ID }> = ZExtZBufHeader::new(self.w_len(&tstamp.timestamp)); self.write(&mut *writer, (&header, more))?; self.write(&mut *writer, &tstamp.timestamp) } } -impl RCodec<(ext::TimestampType, bool), &mut R> for Zenoh080 +impl RCodec<(ext::TimestampType<{ ID }>, bool), &mut R> for Zenoh080 where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ext::TimestampType, bool), Self::Error> { + fn read(self, reader: &mut R) -> Result<(ext::TimestampType<{ ID }>, bool), Self::Error> { let header: u8 = self.read(&mut *reader)?; let codec = Zenoh080Header::new(header); codec.read(reader) } } -impl RCodec<(ext::TimestampType, bool), &mut R> for Zenoh080Header +impl RCodec<(ext::TimestampType<{ ID }>, bool), &mut R> for Zenoh080Header where R: Reader, { type Error = DidntRead; - fn read(self, reader: &mut R) -> Result<(ext::TimestampType, bool), Self::Error> { - let (_, more): (ZExtZBufHeader<{ ext::Timestamp::ID }>, bool) = self.read(&mut *reader)?; + fn read(self, reader: &mut R) -> Result<(ext::TimestampType<{ ID }>, bool), Self::Error> { + let (_, more): (ZExtZBufHeader<{ ID }>, bool) = self.read(&mut *reader)?; let timestamp: uhlc::Timestamp = self.codec.read(&mut *reader)?; Ok((ext::TimestampType { timestamp }, more)) } } // Extensions: NodeId -crate::impl_zextz64!(ext::NodeIdType, ext::NodeId::ID); +impl WCodec<(ext::NodeIdType<{ ID }>, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (ext::NodeIdType<{ ID }>, bool)) -> Self::Output { + let (x, more) = x; + let ext: ZExtZ64<{ ID }> = x.into(); + self.write(&mut *writer, (&ext, more)) + } +} + +impl RCodec<(ext::NodeIdType<{ ID }>, bool), &mut R> for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::NodeIdType<{ ID }>, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec<(ext::NodeIdType<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::NodeIdType<{ ID }>, bool), Self::Error> { + let (ext, more): (ZExtZ64<{ ID }>, bool) = self.read(&mut *reader)?; + Ok((ext.into(), more)) + } +} diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index 8c50048f11..12b3bdf97f 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -18,7 +18,7 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtZ64}, + common::{iext, imsg}, core::Reliability, transport::{ frame::{ext, flag, Frame, FrameHeader}, @@ -27,9 +27,6 @@ use zenoh_protocol::{ zenoh::ZenohMessage, }; -// Extensions: QoS -crate::impl_zextz64!(ext::QoSType, ext::QoS::ID); - // FrameHeader impl WCodec<&FrameHeader, &mut W> for Zenoh080 where diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index b27ac3a2aa..b0ecbf06f6 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -25,7 +25,10 @@ use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_protocol::{common::imsg, transport::*}; +use zenoh_protocol::{ + common::{imsg, ZExtZ64}, + transport::*, +}; // TransportMessage impl WCodec<&TransportMessage, &mut W> for Zenoh080 @@ -87,3 +90,42 @@ where Ok(TransportMessage { body }) } } + +// Extensions: QoS +impl WCodec<(ext::QoSType<{ ID }>, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (ext::QoSType<{ ID }>, bool)) -> Self::Output { + let (x, more) = x; + let ext: ZExtZ64<{ ID }> = x.into(); + self.write(&mut *writer, (&ext, more)) + } +} + +impl RCodec<(ext::QoSType<{ ID }>, bool), &mut R> for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoSType<{ ID }>, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec<(ext::QoSType<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoSType<{ ID }>, bool), Self::Error> { + let (ext, more): (ZExtZ64<{ ID }>, bool) = self.read(&mut *reader)?; + Ok((ext.into(), more)) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs index 27a3f4c036..c5a0642690 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -18,14 +18,15 @@ pub mod put; pub mod query; pub mod reply; -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::imsg, - zenoh_new::{id, PushBody, RequestBody, ResponseBody}, + common::{imsg, ZExtZBufHeader}, + core::ZenohId, + zenoh_new::{ext, id, PushBody, RequestBody, ResponseBody}, }; // Push @@ -136,3 +137,55 @@ where Ok(body) } } + +// Extension: SourceInfo +impl LCodec<&ext::SourceInfoType<{ ID }>> for Zenoh080 { + fn w_len(self, x: &ext::SourceInfoType<{ ID }>) -> usize { + 1 + self.w_len(&x.zid) + self.w_len(x.eid) + self.w_len(x.sn) + } +} + +impl WCodec<(&ext::SourceInfoType<{ ID }>, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::SourceInfoType<{ ID }>, bool)) -> Self::Output { + let (x, more) = x; + let header: ZExtZBufHeader<{ ID }> = ZExtZBufHeader::new(self.w_len(x)); + self.write(&mut *writer, (&header, more))?; + + let flags: u8 = (x.zid.size() as u8 - 1) << 4; + self.write(&mut *writer, flags)?; + + let lodec = Zenoh080Length::new(x.zid.size()); + lodec.write(&mut *writer, &x.zid)?; + + self.write(&mut *writer, x.eid)?; + self.write(&mut *writer, x.sn)?; + Ok(()) + } +} + +impl RCodec<(ext::SourceInfoType<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::SourceInfoType<{ ID }>, bool), Self::Error> { + let (_, more): (ZExtZBufHeader<{ ID }>, bool) = self.read(&mut *reader)?; + + let flags: u8 = self.codec.read(&mut *reader)?; + let length = 1 + ((flags >> 4) as usize); + + let lodec = Zenoh080Length::new(length); + let zid: ZenohId = lodec.read(&mut *reader)?; + + let eid: u32 = self.codec.read(&mut *reader)?; + let sn: u32 = self.codec.read(&mut *reader)?; + + Ok((ext::SourceInfoType { zid, eid, sn }, more)) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/put.rs b/commons/zenoh-codec/src/zenoh_new/put.rs index 53e510a870..2e015268fb 100644 --- a/commons/zenoh-codec/src/zenoh_new/put.rs +++ b/commons/zenoh-codec/src/zenoh_new/put.rs @@ -11,10 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{ - common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header, - Zenoh080Length, -}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header}; use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -22,65 +19,14 @@ use zenoh_buffers::{ ZBuf, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtZBufHeader}, - core::{Encoding, ZenohId}, + common::{iext, imsg}, + core::Encoding, zenoh_new::{ id, put::{ext, flag, Put}, }, }; -impl LCodec<&ext::SourceInfoType> for Zenoh080 { - fn w_len(self, x: &ext::SourceInfoType) -> usize { - 1 + self.w_len(&x.zid) + self.w_len(x.eid) + self.w_len(x.sn) - } -} - -impl WCodec<(&ext::SourceInfoType, bool), &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: (&ext::SourceInfoType, bool)) -> Self::Output { - let (x, more) = x; - let header: ZExtZBufHeader<{ ext::SourceInfo::ID }> = ZExtZBufHeader::new(self.w_len(x)); - self.write(&mut *writer, (&header, more))?; - - let flags: u8 = (x.zid.size() as u8 - 1) << 4; - self.write(&mut *writer, flags)?; - - let lodec = Zenoh080Length::new(x.zid.size()); - lodec.write(&mut *writer, &x.zid)?; - - self.write(&mut *writer, x.eid)?; - self.write(&mut *writer, x.sn)?; - Ok(()) - } -} - -impl RCodec<(ext::SourceInfoType, bool), &mut R> for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ext::SourceInfoType, bool), Self::Error> { - let (_, more): (ZExtZBufHeader<{ ext::SourceInfo::ID }>, bool) = self.read(&mut *reader)?; - - let flags: u8 = self.codec.read(&mut *reader)?; - let length = 1 + ((flags >> 4) as usize); - - let lodec = Zenoh080Length::new(length); - let zid: ZenohId = lodec.read(&mut *reader)?; - - let eid: u32 = self.codec.read(&mut *reader)?; - let sn: u32 = self.codec.read(&mut *reader)?; - - Ok((ext::SourceInfoType { zid, eid, sn }, more)) - } -} - impl WCodec<&Put, &mut W> for Zenoh080 where W: Writer, diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index 0b1f033120..e1ee3ff72f 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -53,14 +53,19 @@ pub struct Declare { } pub mod ext { - pub type QoS = crate::network::ext::QoS; - pub type QoSType = crate::network::ext::QoSType; + use crate::{ + common::{ZExtZ64, ZExtZBuf}, + zextz64, zextzbuf, + }; - pub type Timestamp = crate::network::ext::Timestamp; - pub type TimestampType = crate::network::ext::TimestampType; + pub type QoS = zextz64!(0x1, false); + pub type QoSType = crate::network::ext::QoSType<{ QoS::ID }>; - pub type NodeId = crate::network::ext::NodeId; - pub type NodeIdType = crate::network::ext::NodeIdType; + pub type Timestamp = zextzbuf!(0x2, false); + pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>; + + pub type NodeId = zextz64!(0x3, true); + pub type NodeIdType = crate::network::ext::NodeIdType<{ NodeId::ID }>; } pub mod id { @@ -717,7 +722,7 @@ pub mod interest { /// - if T==1 then the interest refers to tokens /// - if C==1 then the interest refers to the current declarations. /// - if F==1 then the interest refers to the future declarations. Note that if F==0 then: - /// - replies SHOULD NOT be sent after the FinalInterest + /// - replies SHOULD NOT be sent after the FinalInterest; /// - UndeclareInterest SHOULD NOT be sent after the FinalInterest. /// - if A==1 then the replies SHOULD be aggregated /// ``` diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 1400c990b8..dfe20f194c 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -138,16 +138,11 @@ impl From for NetworkMessage { // Extensions pub mod ext { use crate::{ - common::{imsg, ZExtZ64, ZExtZBuf}, + common::{imsg, ZExtZ64}, core::{CongestionControl, Priority}, - zextz64, zextzbuf, }; use core::fmt; - pub type QoS = zextz64!(0x1, false); - pub type Timestamp = zextzbuf!(0x2, false); - pub type NodeId = zextz64!(0x3, true); - /// ```text /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ @@ -163,11 +158,11 @@ pub mod ext { /// ``` #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq)] - pub struct QoSType { + pub struct QoSType { inner: u8, } - impl QoSType { + impl QoSType<{ ID }> { const P_MASK: u8 = 0b00000111; const D_FLAG: u8 = 0b00001000; const E_FLAG: u8 = 0b00010000; @@ -212,27 +207,27 @@ pub mod ext { } } - impl Default for QoSType { + impl Default for QoSType<{ ID }> { fn default() -> Self { Self::new(Priority::default(), CongestionControl::default(), false) } } - impl From for QoSType { - fn from(ext: QoS) -> Self { + impl From> for QoSType<{ ID }> { + fn from(ext: ZExtZ64<{ ID }>) -> Self { Self { inner: ext.value as u8, } } } - impl From for QoS { - fn from(ext: QoSType) -> Self { - QoS::new(ext.inner as u64) + impl From> for ZExtZ64<{ ID }> { + fn from(ext: QoSType<{ ID }>) -> Self { + ZExtZ64::new(ext.inner as u64) } } - impl fmt::Debug for QoSType { + impl fmt::Debug for QoSType<{ ID }> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("QoS") .field("priority", &self.priority()) @@ -251,11 +246,11 @@ pub mod ext { /// +---------------+ /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub struct TimestampType { + pub struct TimestampType { pub timestamp: uhlc::Timestamp, } - impl TimestampType { + impl TimestampType<{ ID }> { #[cfg(feature = "test")] pub fn rand() -> Self { use crate::core::ZenohId; @@ -279,11 +274,11 @@ pub mod ext { /// +---------------+ /// ``` #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] - pub struct NodeIdType { + pub struct NodeIdType { pub node_id: u16, } - impl NodeIdType { + impl NodeIdType<{ ID }> { #[cfg(feature = "test")] pub fn rand() -> Self { use rand::Rng; @@ -293,17 +288,17 @@ pub mod ext { } } - impl From for NodeIdType { - fn from(ext: NodeId) -> Self { + impl From> for NodeIdType<{ ID }> { + fn from(ext: ZExtZ64<{ ID }>) -> Self { Self { node_id: ext.value as u16, } } } - impl From for NodeId { - fn from(ext: NodeIdType) -> Self { - NodeId::new(ext.node_id as u64) + impl From> for ZExtZ64<{ ID }> { + fn from(ext: NodeIdType<{ ID }>) -> Self { + ZExtZ64::new(ext.node_id as u64) } } } diff --git a/commons/zenoh-protocol/src/network/oam.rs b/commons/zenoh-protocol/src/network/oam.rs index 8fd2ba6044..7d7794b001 100644 --- a/commons/zenoh-protocol/src/network/oam.rs +++ b/commons/zenoh-protocol/src/network/oam.rs @@ -53,11 +53,16 @@ pub struct Oam { } pub mod ext { - pub type QoS = crate::network::ext::QoS; - pub type QoSType = crate::network::ext::QoSType; + use crate::{ + common::{ZExtZ64, ZExtZBuf}, + zextz64, zextzbuf, + }; - pub type Timestamp = crate::network::ext::Timestamp; - pub type TimestampType = crate::network::ext::TimestampType; + pub type QoS = zextz64!(0x1, false); + pub type QoSType = crate::network::ext::QoSType<{ QoS::ID }>; + + pub type Timestamp = zextzbuf!(0x2, false); + pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>; } impl Oam { diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs index 4cede3556a..76d9c3811c 100644 --- a/commons/zenoh-protocol/src/network/push.rs +++ b/commons/zenoh-protocol/src/network/push.rs @@ -49,14 +49,19 @@ pub struct Push { } pub mod ext { - pub type QoS = crate::network::ext::QoS; - pub type QoSType = crate::network::ext::QoSType; + use crate::{ + common::{ZExtZ64, ZExtZBuf}, + zextz64, zextzbuf, + }; - pub type Timestamp = crate::network::ext::Timestamp; - pub type TimestampType = crate::network::ext::TimestampType; + pub type QoS = zextz64!(0x1, false); + pub type QoSType = crate::network::ext::QoSType<{ QoS::ID }>; - pub type NodeId = crate::network::ext::NodeId; - pub type NodeIdType = crate::network::ext::NodeIdType; + pub type Timestamp = zextzbuf!(0x2, false); + pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>; + + pub type NodeId = zextz64!(0x3, true); + pub type NodeIdType = crate::network::ext::NodeIdType<{ NodeId::ID }>; } impl Push { diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index 38ab0b0964..fc180d273a 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -65,17 +65,20 @@ pub struct Request { } pub mod ext { - use crate::{common::ZExtZ64, zextz64}; + use crate::{ + common::{ZExtZ64, ZExtZBuf}, + zextz64, zextzbuf, + }; use core::{num::NonZeroU32, time::Duration}; - pub type QoS = crate::network::ext::QoS; - pub type QoSType = crate::network::ext::QoSType; + pub type QoS = zextz64!(0x1, false); + pub type QoSType = crate::network::ext::QoSType<{ QoS::ID }>; - pub type Timestamp = crate::network::ext::Timestamp; - pub type TimestampType = crate::network::ext::TimestampType; + pub type Timestamp = zextzbuf!(0x2, false); + pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>; - pub type NodeId = crate::network::ext::NodeId; - pub type NodeIdType = crate::network::ext::NodeIdType; + pub type NodeId = zextz64!(0x3, true); + pub type NodeIdType = crate::network::ext::NodeIdType<{ NodeId::ID }>; pub type Target = zextz64!(0x4, true); /// - Target (0x03) diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index 919e616bf6..91b59cb552 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -60,11 +60,15 @@ pub struct Response { } pub mod ext { - pub type QoS = crate::network::ext::QoS; - pub type QoSType = crate::network::ext::QoSType; + use crate::{ + common::{ZExtZ64, ZExtZBuf}, + zextz64, zextzbuf, + }; + pub type QoS = zextz64!(0x1, false); + pub type QoSType = crate::network::ext::QoSType<{ QoS::ID }>; - pub type Timestamp = crate::network::ext::Timestamp; - pub type TimestampType = crate::network::ext::TimestampType; + pub type Timestamp = zextzbuf!(0x2, false); + pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>; } impl Response { diff --git a/commons/zenoh-protocol/src/transport/fragment.rs b/commons/zenoh-protocol/src/transport/fragment.rs index 55f6cd8a39..3e80c9cfbf 100644 --- a/commons/zenoh-protocol/src/transport/fragment.rs +++ b/commons/zenoh-protocol/src/transport/fragment.rs @@ -78,9 +78,10 @@ pub struct Fragment { // Extensions pub mod ext { - pub type QoS = crate::transport::frame::ext::QoS; + use crate::{common::ZExtZ64, zextz64}; - pub type QoSType = crate::transport::frame::ext::QoSType; + pub type QoS = zextz64!(0x1, true); + pub type QoSType = crate::transport::ext::QoSType<{ QoS::ID }>; } impl Fragment { diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index 9eb99bd7b1..74a1fdf4d7 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -76,65 +76,10 @@ pub struct Frame { // Extensions pub mod ext { - use crate::common::ZExtZ64; - use crate::core::Priority; - use crate::zextz64; + use crate::{common::ZExtZ64, zextz64}; pub type QoS = zextz64!(0x1, true); - - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// %0| rsv |prio % - /// +---------------+ - /// - prio: Priority class - #[repr(transparent)] - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub struct QoSType { - inner: u8, - } - - impl QoSType { - pub const P_MASK: u8 = 0b00000111; - - pub const fn new(priority: Priority) -> Self { - Self { - inner: priority as u8, - } - } - - pub const fn priority(&self) -> Priority { - unsafe { core::mem::transmute(self.inner & Self::P_MASK) } - } - - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - let mut rng = rand::thread_rng(); - - let inner: u8 = rng.gen(); - Self { inner } - } - } - - impl Default for QoSType { - fn default() -> Self { - Self::new(Priority::default()) - } - } - - impl From for QoSType { - fn from(ext: QoS) -> Self { - Self { - inner: ext.value as u8, - } - } - } - - impl From for QoS { - fn from(ext: QoSType) -> Self { - QoS::new(ext.inner as u64) - } - } + pub type QoSType = crate::transport::ext::QoSType<{ QoS::ID }>; } impl Frame { diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 1e628cc209..981b688333 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -168,3 +168,61 @@ impl From for TransportMessage { // TransportBody::Join(join).into() // } // } + +pub mod ext { + use crate::{common::ZExtZ64, core::Priority}; + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// %0| rsv |prio % + /// +---------------+ + /// - prio: Priority class + #[repr(transparent)] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub struct QoSType { + inner: u8, + } + + impl QoSType<{ ID }> { + pub const P_MASK: u8 = 0b00000111; + + pub const fn new(priority: Priority) -> Self { + Self { + inner: priority as u8, + } + } + + pub const fn priority(&self) -> Priority { + unsafe { core::mem::transmute(self.inner & Self::P_MASK) } + } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let inner: u8 = rng.gen(); + Self { inner } + } + } + + impl Default for QoSType<{ ID }> { + fn default() -> Self { + Self::new(Priority::default()) + } + } + + impl From> for QoSType<{ ID }> { + fn from(ext: ZExtZ64<{ ID }>) -> Self { + Self { + inner: ext.value as u8, + } + } + } + + impl From> for ZExtZ64<{ ID }> { + fn from(ext: QoSType<{ ID }>) -> Self { + ZExtZ64::new(ext.inner as u64) + } + } +} diff --git a/commons/zenoh-protocol/src/transport/oam.rs b/commons/zenoh-protocol/src/transport/oam.rs index 9240d5ad60..9822139401 100644 --- a/commons/zenoh-protocol/src/transport/oam.rs +++ b/commons/zenoh-protocol/src/transport/oam.rs @@ -55,9 +55,10 @@ pub struct Oam { } pub mod ext { - pub type QoS = crate::transport::frame::ext::QoS; + use crate::{common::ZExtZ64, zextz64}; - pub type QoSType = crate::transport::frame::ext::QoSType; + pub type QoS = zextz64!(0x1, true); + pub type QoSType = crate::transport::ext::QoSType<{ QoS::ID }>; } impl Oam { diff --git a/commons/zenoh-protocol/src/zenoh_new/ack.rs b/commons/zenoh-protocol/src/zenoh_new/ack.rs index cd49daf304..e9e4b9a05f 100644 --- a/commons/zenoh-protocol/src/zenoh_new/ack.rs +++ b/commons/zenoh-protocol/src/zenoh_new/ack.rs @@ -46,10 +46,12 @@ pub struct Ack { } pub mod ext { + use crate::{common::ZExtZBuf, zextzbuf}; + /// # SourceInfo extension /// Used to carry additional information about the source of data - pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; - pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; + pub type SourceInfo = zextzbuf!(0x1, false); + pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; } impl Ack { diff --git a/commons/zenoh-protocol/src/zenoh_new/del.rs b/commons/zenoh-protocol/src/zenoh_new/del.rs index 57a01f3675..6130833fb3 100644 --- a/commons/zenoh-protocol/src/zenoh_new/del.rs +++ b/commons/zenoh-protocol/src/zenoh_new/del.rs @@ -46,10 +46,12 @@ pub struct Del { } pub mod ext { + use crate::{common::ZExtZBuf, zextzbuf}; + /// # SourceInfo extension /// Used to carry additional information about the source of data - pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; - pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; + pub type SourceInfo = zextzbuf!(0x1, false); + pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; } impl Del { diff --git a/commons/zenoh-protocol/src/zenoh_new/err.rs b/commons/zenoh-protocol/src/zenoh_new/err.rs index cc1959e79c..bf1a3834dd 100644 --- a/commons/zenoh-protocol/src/zenoh_new/err.rs +++ b/commons/zenoh-protocol/src/zenoh_new/err.rs @@ -56,8 +56,8 @@ pub mod ext { /// # SourceInfo extension /// Used to carry additional information about the source of data - pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; - pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; + pub type SourceInfo = zextzbuf!(0x1, false); + pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; /// # ErrBody extension /// Used to carry a body attached to the error diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index 7dd5e61df6..53d18a83fd 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -152,3 +152,37 @@ impl From for ResponseBody { ResponseBody::Ack(r) } } + +pub mod ext { + use crate::core::ZenohId; + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |zid_len|X|X|X|X| + /// +-------+-+-+---+ + /// ~ zid ~ + /// +---------------+ + /// % eid % -- Counter decided by the Zenoh Node + /// +---------------+ + /// % sn % + /// +---------------+ + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct SourceInfoType { + pub zid: ZenohId, + pub eid: u32, + pub sn: u32, + } + + impl SourceInfoType<{ ID }> { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let zid = ZenohId::rand(); + let eid: u32 = rng.gen(); + let sn: u32 = rng.gen(); + Self { zid, eid, sn } + } + } +} diff --git a/commons/zenoh-protocol/src/zenoh_new/put.rs b/commons/zenoh-protocol/src/zenoh_new/put.rs index 11b2ac9b4d..0f130135e0 100644 --- a/commons/zenoh-protocol/src/zenoh_new/put.rs +++ b/commons/zenoh-protocol/src/zenoh_new/put.rs @@ -53,42 +53,12 @@ pub struct Put { } pub mod ext { - use crate::core::ZenohId; use crate::{common::ZExtZBuf, zextzbuf}; /// # SourceInfo extension /// Used to carry additional information about the source of data pub type SourceInfo = zextzbuf!(0x1, false); - - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// |zid_len|X|X|X|X| - /// +-------+-+-+---+ - /// ~ zid ~ - /// +---------------+ - /// % eid % -- Counter decided by the Zenoh Node - /// +---------------+ - /// % sn % - /// +---------------+ - #[derive(Debug, Clone, PartialEq, Eq)] - pub struct SourceInfoType { - pub zid: ZenohId, - pub eid: u32, - pub sn: u32, - } - - impl SourceInfoType { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - let mut rng = rand::thread_rng(); - - let zid = ZenohId::rand(); - let eid: u32 = rng.gen(); - let sn: u32 = rng.gen(); - Self { zid, eid, sn } - } - } + pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; } impl Put { diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs index 85d410f3e6..b6f6d94142 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -97,8 +97,8 @@ pub mod ext { /// # SourceInfo extension /// Used to carry additional information about the source of data - pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; - pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; + pub type SourceInfo = zextzbuf!(0x1, false); + pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; /// # Consolidation extension pub type Consolidation = zextz64!(0x2, true); diff --git a/commons/zenoh-protocol/src/zenoh_new/reply.rs b/commons/zenoh-protocol/src/zenoh_new/reply.rs index d1743ba2aa..ee85d8cece 100644 --- a/commons/zenoh-protocol/src/zenoh_new/reply.rs +++ b/commons/zenoh-protocol/src/zenoh_new/reply.rs @@ -54,13 +54,18 @@ pub struct Reply { } pub mod ext { + use crate::{ + common::{ZExtZ64, ZExtZBuf}, + zextz64, zextzbuf, + }; + /// # SourceInfo extension /// Used to carry additional information about the source of data - pub type SourceInfo = crate::zenoh_new::put::ext::SourceInfo; - pub type SourceInfoType = crate::zenoh_new::put::ext::SourceInfoType; + pub type SourceInfo = zextzbuf!(0x1, false); + pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; /// # Consolidation extension - pub type Consolidation = crate::zenoh_new::query::ext::Consolidation; + pub type Consolidation = zextz64!(0x2, true); pub type ConsolidationType = crate::zenoh_new::query::ext::ConsolidationType; } From 42d9b2686e95d9a8649aa7d3fa9b72072ef1c402 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 15 Jun 2023 09:10:11 +0200 Subject: [PATCH 140/203] Fix cargo clippy --- commons/zenoh-codec/src/zenoh/data.rs | 2 +- io/zenoh-transport/src/unicast/establishment/ext/shm.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index 1dabbfa374..31ae2355ac 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -149,7 +149,7 @@ where let options: u8 = self.read(&mut *reader)?; #[cfg(feature = "shared-memory")] { - info.sliced = imsg::has_option(options, zmsg::data::info::SLICED); + info.sliced = imsg::has_flag(options, zmsg::data::info::SLICED); } if imsg::has_flag(options, zmsg::data::info::KIND) { let kind: u8 = self.read(&mut *reader)?; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index 220e86293d..d664067457 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -259,7 +259,7 @@ impl<'a> OpenFsm for ShmFsm<'a> { &self, input: Self::SendOpenSynIn, ) -> Result { - const S: &str = "Shm extension - Send OpenSyn."; + // const S: &str = "Shm extension - Send OpenSyn."; let (state, bob_challenge) = input; if !state.is_shm() { @@ -483,7 +483,7 @@ impl<'a> AcceptFsm for ShmFsm<'a> { &self, state: Self::SendOpenAckIn, ) -> Result { - const S: &str = "Shm extension - Recv OpenSyn."; + // const S: &str = "Shm extension - Send OpenAck."; if !state.is_shm() { return Ok(None); From ac3d9c975a8a1fe549c3f34ae2ee55a338c60436 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 16 Jun 2023 11:26:03 +0200 Subject: [PATCH 141/203] Add Pull message --- commons/zenoh-codec/src/network/mod.rs | 3 + commons/zenoh-codec/src/network/pull.rs | 133 +++++++++++++++++++++ commons/zenoh-codec/tests/codec.rs | 5 + commons/zenoh-protocol/src/network/mod.rs | 21 ++-- commons/zenoh-protocol/src/network/pull.rs | 81 +++++++++++++ 5 files changed, 235 insertions(+), 8 deletions(-) create mode 100644 commons/zenoh-codec/src/network/pull.rs create mode 100644 commons/zenoh-protocol/src/network/pull.rs diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index cb4bbd9aab..8fe4ee25c6 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -13,6 +13,7 @@ // mod declare; mod oam; +mod pull; mod push; mod request; mod response; @@ -40,6 +41,7 @@ where NetworkBody::Request(b) => self.write(&mut *writer, b), NetworkBody::Response(b) => self.write(&mut *writer, b), NetworkBody::ResponseFinal(b) => self.write(&mut *writer, b), + NetworkBody::Pull(b) => self.write(&mut *writer, b), NetworkBody::Declare(b) => self.write(&mut *writer, b), NetworkBody::OAM(b) => self.write(&mut *writer, b), } @@ -61,6 +63,7 @@ where id::REQUEST => NetworkBody::Request(codec.read(&mut *reader)?), id::RESPONSE => NetworkBody::Response(codec.read(&mut *reader)?), id::RESPONSE_FINAL => NetworkBody::ResponseFinal(codec.read(&mut *reader)?), + id::PULL => NetworkBody::Pull(codec.read(&mut *reader)?), id::DECLARE => NetworkBody::Declare(codec.read(&mut *reader)?), id::OAM => NetworkBody::OAM(codec.read(&mut *reader)?), _ => return Err(DidntRead), diff --git a/commons/zenoh-codec/src/network/pull.rs b/commons/zenoh-codec/src/network/pull.rs new file mode 100644 index 0000000000..421896227f --- /dev/null +++ b/commons/zenoh-codec/src/network/pull.rs @@ -0,0 +1,133 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_protocol::{ + common::{iext, imsg}, + core::WireExpr, + network::{ + id, + pull::{ext, flag}, + Mapping, Pull, + }, +}; + +impl WCodec<&Pull, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &Pull) -> Self::Output { + // Header + let mut header = id::PULL; + let mut n_exts = + ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); + if n_exts != 0 { + header |= flag::Z; + } + if x.mapping != Mapping::default() { + header |= flag::M; + } + if x.wire_expr.has_suffix() { + header |= flag::N; + } + self.write(&mut *writer, header)?; + + // Body + self.write(&mut *writer, &x.wire_expr)?; + + // Extensions + if x.ext_qos != ext::QoSType::default() { + n_exts -= 1; + self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + } + if let Some(ts) = x.ext_tstamp.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (ts, n_exts != 0))?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if imsg::mid(self.header) != id::PULL { + return Err(DidntRead); + } + + // Body + let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); + let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + let mapping = if imsg::has_flag(self.header, flag::M) { + Mapping::Sender + } else { + Mapping::Receiver + }; + + // Extensions + let mut ext_qos = ext::QoSType::default(); + let mut ext_tstamp = None; + + let mut has_ext = imsg::has_flag(self.header, flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + ext::QoS::ID => { + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; + ext_qos = q; + has_ext = ext; + } + ext::Timestamp::ID => { + let (t, ext): (ext::TimestampType, bool) = eodec.read(&mut *reader)?; + ext_tstamp = Some(t); + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "Pull", ext)?; + } + } + } + + Ok(Pull { + wire_expr, + mapping, + ext_qos, + ext_tstamp, + }) + } +} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 87d07e308f..27468ba3dc 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -546,6 +546,11 @@ fn codec_response_final() { run!(ResponseFinal, ResponseFinal::rand()); } +#[test] +fn codec_pull() { + run!(Pull, Pull::rand()); +} + #[test] fn codec_network_oam() { run!(network::Oam, network::Oam::rand()); diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 9dab61e30f..f2c3772f08 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -13,12 +13,14 @@ // pub mod declare; pub mod oam; +pub mod pull; pub mod push; pub mod request; pub mod response; pub use declare::*; pub use oam::*; +pub use pull::*; pub use push::*; pub use request::*; pub use response::*; @@ -32,6 +34,7 @@ pub mod id { pub const REQUEST: u8 = 0x1c; pub const RESPONSE: u8 = 0x1b; pub const RESPONSE_FINAL: u8 = 0x1a; + pub const PULL: u8 = 0x19; } #[repr(u8)] @@ -59,11 +62,12 @@ impl Mapping { // Zenoh messages at zenoh-network level #[derive(Debug, Clone, PartialEq, Eq)] pub enum NetworkBody { - Declare(Declare), Push(Push), Request(Request), Response(Response), ResponseFinal(ResponseFinal), + Pull(Pull), + Declare(Declare), OAM(Oam), } @@ -81,13 +85,14 @@ impl NetworkMessage { let mut rng = rand::thread_rng(); - let body = match rng.gen_range(0..6) { - 0 => NetworkBody::Declare(Declare::rand()), - 1 => NetworkBody::Push(Push::rand()), - 2 => NetworkBody::Request(Request::rand()), - 3 => NetworkBody::Response(Response::rand()), - 4 => NetworkBody::ResponseFinal(ResponseFinal::rand()), - 5 => NetworkBody::OAM(Oam::rand()), + let body = match rng.gen_range(0..7) { + 0 => NetworkBody::Push(Push::rand()), + 1 => NetworkBody::Request(Request::rand()), + 2 => NetworkBody::Response(Response::rand()), + 3 => NetworkBody::ResponseFinal(ResponseFinal::rand()), + 4 => NetworkBody::Pull(Pull::rand()), + 5 => NetworkBody::Declare(Declare::rand()), + 6 => NetworkBody::OAM(Oam::rand()), _ => unreachable!(), }; diff --git a/commons/zenoh-protocol/src/network/pull.rs b/commons/zenoh-protocol/src/network/pull.rs new file mode 100644 index 0000000000..41b0fc01cb --- /dev/null +++ b/commons/zenoh-protocol/src/network/pull.rs @@ -0,0 +1,81 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::{core::WireExpr, network::Mapping}; + +pub mod flag { + pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix + pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +/// # Request message +/// +/// ```text +/// Flags: +/// - N: Named if N==1 then the key expr has name/suffix +/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver +/// - Z: Extension if Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|M|N| PULL | +/// +-+-+-+---------+ +/// ~ key_scope:z16 ~ +/// +---------------+ +/// ~ key_suffix ~ if N==1 -- +/// +---------------+ +/// ~ [pull_exts] ~ if Z==1 +/// +---------------+ +/// +/// ``` +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Pull { + pub wire_expr: WireExpr<'static>, + pub mapping: Mapping, + pub ext_qos: ext::QoSType, + pub ext_tstamp: Option, +} + +pub mod ext { + use crate::{ + common::{ZExtZ64, ZExtZBuf}, + zextz64, zextzbuf, + }; + + pub type QoS = zextz64!(0x1, false); + pub type QoSType = crate::network::ext::QoSType<{ QoS::ID }>; + + pub type Timestamp = zextzbuf!(0x2, false); + pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>; +} + +impl Pull { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let wire_expr = WireExpr::rand(); + let mapping = Mapping::rand(); + let ext_qos = ext::QoSType::rand(); + let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); + + Self { + wire_expr, + mapping, + ext_qos, + ext_tstamp, + } + } +} From e2e521a2aee279033ad7906cbd49a834ffa63c8d Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 16 Jun 2023 15:36:03 +0200 Subject: [PATCH 142/203] Move Pull into Zenoh layer --- commons/zenoh-codec/src/network/mod.rs | 3 - commons/zenoh-codec/src/zenoh_new/mod.rs | 5 ++ .../src/{network => zenoh_new}/pull.rs | 64 +++++---------- commons/zenoh-codec/tests/codec.rs | 10 +-- commons/zenoh-protocol/src/network/mod.rs | 11 +-- commons/zenoh-protocol/src/network/pull.rs | 81 ------------------- commons/zenoh-protocol/src/zenoh_new/mod.rs | 8 +- commons/zenoh-protocol/src/zenoh_new/pull.rs | 74 +++++++++++++++++ 8 files changed, 114 insertions(+), 142 deletions(-) rename commons/zenoh-codec/src/{network => zenoh_new}/pull.rs (57%) delete mode 100644 commons/zenoh-protocol/src/network/pull.rs create mode 100644 commons/zenoh-protocol/src/zenoh_new/pull.rs diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 8fe4ee25c6..cb4bbd9aab 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -13,7 +13,6 @@ // mod declare; mod oam; -mod pull; mod push; mod request; mod response; @@ -41,7 +40,6 @@ where NetworkBody::Request(b) => self.write(&mut *writer, b), NetworkBody::Response(b) => self.write(&mut *writer, b), NetworkBody::ResponseFinal(b) => self.write(&mut *writer, b), - NetworkBody::Pull(b) => self.write(&mut *writer, b), NetworkBody::Declare(b) => self.write(&mut *writer, b), NetworkBody::OAM(b) => self.write(&mut *writer, b), } @@ -63,7 +61,6 @@ where id::REQUEST => NetworkBody::Request(codec.read(&mut *reader)?), id::RESPONSE => NetworkBody::Response(codec.read(&mut *reader)?), id::RESPONSE_FINAL => NetworkBody::ResponseFinal(codec.read(&mut *reader)?), - id::PULL => NetworkBody::Pull(codec.read(&mut *reader)?), id::DECLARE => NetworkBody::Declare(codec.read(&mut *reader)?), id::OAM => NetworkBody::OAM(codec.read(&mut *reader)?), _ => return Err(DidntRead), diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs index c5a0642690..c805164b82 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -14,6 +14,7 @@ pub mod ack; pub mod del; pub mod err; +pub mod pull; pub mod put; pub mod query; pub mod reply; @@ -76,6 +77,7 @@ where RequestBody::Query(b) => self.write(&mut *writer, b), RequestBody::Put(b) => self.write(&mut *writer, b), RequestBody::Del(b) => self.write(&mut *writer, b), + RequestBody::Pull(b) => self.write(&mut *writer, b), } } } @@ -94,6 +96,7 @@ where id::QUERY => RequestBody::Query(codec.read(&mut *reader)?), id::PUT => RequestBody::Put(codec.read(&mut *reader)?), id::DEL => RequestBody::Del(codec.read(&mut *reader)?), + id::PULL => RequestBody::Pull(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; @@ -113,6 +116,7 @@ where ResponseBody::Reply(b) => self.write(&mut *writer, b), ResponseBody::Err(b) => self.write(&mut *writer, b), ResponseBody::Ack(b) => self.write(&mut *writer, b), + ResponseBody::Put(b) => self.write(&mut *writer, b), } } } @@ -131,6 +135,7 @@ where id::REPLY => ResponseBody::Reply(codec.read(&mut *reader)?), id::ERR => ResponseBody::Err(codec.read(&mut *reader)?), id::ACK => ResponseBody::Ack(codec.read(&mut *reader)?), + id::PUT => ResponseBody::Put(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/src/network/pull.rs b/commons/zenoh-codec/src/zenoh_new/pull.rs similarity index 57% rename from commons/zenoh-codec/src/network/pull.rs rename to commons/zenoh-codec/src/zenoh_new/pull.rs index 421896227f..48358e4483 100644 --- a/commons/zenoh-codec/src/network/pull.rs +++ b/commons/zenoh-codec/src/zenoh_new/pull.rs @@ -11,18 +11,18 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; + use zenoh_protocol::{ common::{iext, imsg}, - core::WireExpr, - network::{ + zenoh_new::{ id, - pull::{ext, flag}, - Mapping, Pull, + pull::{ext, flag, Pull}, }, }; @@ -35,30 +35,20 @@ where fn write(self, writer: &mut W, x: &Pull) -> Self::Output { // Header let mut header = id::PULL; - let mut n_exts = - ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); + let mut n_exts = (x.ext_sinfo.is_some() as u8) + (x.ext_unknown.len() as u8); if n_exts != 0 { header |= flag::Z; } - if x.mapping != Mapping::default() { - header |= flag::M; - } - if x.wire_expr.has_suffix() { - header |= flag::N; - } self.write(&mut *writer, header)?; - // Body - self.write(&mut *writer, &x.wire_expr)?; - // Extensions - if x.ext_qos != ext::QoSType::default() { + if let Some(sinfo) = x.ext_sinfo.as_ref() { n_exts -= 1; - self.write(&mut *writer, (x.ext_qos, n_exts != 0))?; + self.write(&mut *writer, (sinfo, n_exts != 0))?; } - if let Some(ts) = x.ext_tstamp.as_ref() { + for u in x.ext_unknown.iter() { n_exts -= 1; - self.write(&mut *writer, (ts, n_exts != 0))?; + self.write(&mut *writer, (u, n_exts != 0))?; } Ok(()) @@ -89,45 +79,31 @@ where return Err(DidntRead); } - // Body - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); - let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; - let mapping = if imsg::has_flag(self.header, flag::M) { - Mapping::Sender - } else { - Mapping::Receiver - }; - // Extensions - let mut ext_qos = ext::QoSType::default(); - let mut ext_tstamp = None; + let mut ext_sinfo: Option = None; + let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; let eodec = Zenoh080Header::new(ext); match iext::eid(ext) { - ext::QoS::ID => { - let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; - ext_qos = q; - has_ext = ext; - } - ext::Timestamp::ID => { - let (t, ext): (ext::TimestampType, bool) = eodec.read(&mut *reader)?; - ext_tstamp = Some(t); + ext::SourceInfo::ID => { + let (s, ext): (ext::SourceInfoType, bool) = eodec.read(&mut *reader)?; + ext_sinfo = Some(s); has_ext = ext; } _ => { - has_ext = extension::skip(reader, "Pull", ext)?; + let (u, ext) = extension::read(reader, "Pull", ext)?; + ext_unknown.push(u); + has_ext = ext; } } } Ok(Pull { - wire_expr, - mapping, - ext_qos, - ext_tstamp, + ext_sinfo, + ext_unknown, }) } } diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 27468ba3dc..a92e18a2c6 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -546,11 +546,6 @@ fn codec_response_final() { run!(ResponseFinal, ResponseFinal::rand()); } -#[test] -fn codec_pull() { - run!(Pull, Pull::rand()); -} - #[test] fn codec_network_oam() { run!(network::Oam, network::Oam::rand()); @@ -592,6 +587,11 @@ fn codec_ack() { run!(zenoh_new::Ack, zenoh_new::Ack::rand()); } +#[test] +fn codec_pull() { + run!(zenoh_new::Pull, zenoh_new::Pull::rand()); +} + // Zenoh #[test] fn codec_routing_context_old() { diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index f2c3772f08..1a7f65cd22 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -13,14 +13,12 @@ // pub mod declare; pub mod oam; -pub mod pull; pub mod push; pub mod request; pub mod response; pub use declare::*; pub use oam::*; -pub use pull::*; pub use push::*; pub use request::*; pub use response::*; @@ -34,7 +32,6 @@ pub mod id { pub const REQUEST: u8 = 0x1c; pub const RESPONSE: u8 = 0x1b; pub const RESPONSE_FINAL: u8 = 0x1a; - pub const PULL: u8 = 0x19; } #[repr(u8)] @@ -66,7 +63,6 @@ pub enum NetworkBody { Request(Request), Response(Response), ResponseFinal(ResponseFinal), - Pull(Pull), Declare(Declare), OAM(Oam), } @@ -85,14 +81,13 @@ impl NetworkMessage { let mut rng = rand::thread_rng(); - let body = match rng.gen_range(0..7) { + let body = match rng.gen_range(0..6) { 0 => NetworkBody::Push(Push::rand()), 1 => NetworkBody::Request(Request::rand()), 2 => NetworkBody::Response(Response::rand()), 3 => NetworkBody::ResponseFinal(ResponseFinal::rand()), - 4 => NetworkBody::Pull(Pull::rand()), - 5 => NetworkBody::Declare(Declare::rand()), - 6 => NetworkBody::OAM(Oam::rand()), + 4 => NetworkBody::Declare(Declare::rand()), + 5 => NetworkBody::OAM(Oam::rand()), _ => unreachable!(), }; diff --git a/commons/zenoh-protocol/src/network/pull.rs b/commons/zenoh-protocol/src/network/pull.rs deleted file mode 100644 index 41b0fc01cb..0000000000 --- a/commons/zenoh-protocol/src/network/pull.rs +++ /dev/null @@ -1,81 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{core::WireExpr, network::Mapping}; - -pub mod flag { - pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix - pub const M: u8 = 1 << 6; // 0x40 Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver - pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow -} - -/// # Request message -/// -/// ```text -/// Flags: -/// - N: Named if N==1 then the key expr has name/suffix -/// - M: Mapping if M==1 then key expr mapping is the one declared by the sender, else it is the one declared by the receiver -/// - Z: Extension if Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|M|N| PULL | -/// +-+-+-+---------+ -/// ~ key_scope:z16 ~ -/// +---------------+ -/// ~ key_suffix ~ if N==1 -- -/// +---------------+ -/// ~ [pull_exts] ~ if Z==1 -/// +---------------+ -/// -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Pull { - pub wire_expr: WireExpr<'static>, - pub mapping: Mapping, - pub ext_qos: ext::QoSType, - pub ext_tstamp: Option, -} - -pub mod ext { - use crate::{ - common::{ZExtZ64, ZExtZBuf}, - zextz64, zextzbuf, - }; - - pub type QoS = zextz64!(0x1, false); - pub type QoSType = crate::network::ext::QoSType<{ QoS::ID }>; - - pub type Timestamp = zextzbuf!(0x2, false); - pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>; -} - -impl Pull { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - let wire_expr = WireExpr::rand(); - let mapping = Mapping::rand(); - let ext_qos = ext::QoSType::rand(); - let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); - - Self { - wire_expr, - mapping, - ext_qos, - ext_tstamp, - } - } -} diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index 53d18a83fd..6707f2fde1 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -14,6 +14,7 @@ pub mod ack; pub mod del; pub mod err; +pub mod pull; pub mod put; pub mod query; pub mod reply; @@ -21,6 +22,7 @@ pub mod reply; pub use ack::*; pub use del::*; pub use err::*; +pub use pull::*; pub use put::*; pub use query::*; pub use reply::*; @@ -33,6 +35,7 @@ pub mod id { pub const REPLY: u8 = 0x04; pub const ERR: u8 = 0x05; pub const ACK: u8 = 0x06; + pub const PULL: u8 = 0x07; } // Push @@ -75,6 +78,7 @@ pub enum RequestBody { Query(Query), Put(Put), Del(Del), + Pull(Pull), } impl RequestBody { @@ -117,6 +121,7 @@ pub enum ResponseBody { Reply(Reply), Err(Err), Ack(Ack), + Put(Put), } impl ResponseBody { @@ -126,10 +131,11 @@ impl ResponseBody { let mut rng = rand::thread_rng(); - match rng.gen_range(0..3) { + match rng.gen_range(0..4) { 0 => ResponseBody::Reply(Reply::rand()), 1 => ResponseBody::Err(Err::rand()), 2 => ResponseBody::Ack(Ack::rand()), + 3 => ResponseBody::Put(Put::rand()), _ => unreachable!(), } } diff --git a/commons/zenoh-protocol/src/zenoh_new/pull.rs b/commons/zenoh-protocol/src/zenoh_new/pull.rs new file mode 100644 index 0000000000..7af727ebc4 --- /dev/null +++ b/commons/zenoh-protocol/src/zenoh_new/pull.rs @@ -0,0 +1,74 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::common::ZExtUnknown; +use alloc::vec::Vec; + +/// # Pull message +/// +/// ```text +/// Flags: +/// - X: Reserved +/// - X: Reserved +/// - Z: Extension If Z==1 then at least one extension is present +/// +/// 7 6 5 4 3 2 1 0 +/// +-+-+-+-+-+-+-+-+ +/// |Z|X|X| PULL | +/// +-+-+-+---------+ +/// ~ [pull_exts] ~ if Z==1 +/// +---------------+ +/// ``` +pub mod flag { + // pub const X: u8 = 1 << 5; // 0x20 Reserved + // pub const X: u8 = 1 << 6; // 0x40 Reserved + pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Pull { + pub ext_sinfo: Option, + pub ext_unknown: Vec, +} + +pub mod ext { + use crate::{common::ZExtZBuf, zextzbuf}; + + /// # SourceInfo extension + /// Used to carry additional information about the source of data + pub type SourceInfo = zextzbuf!(0x1, false); + pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; +} + +impl Pull { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use crate::common::iext; + use rand::Rng; + let mut rng = rand::thread_rng(); + + let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); + let mut ext_unknown = Vec::new(); + for _ in 0..rng.gen_range(0..4) { + ext_unknown.push(ZExtUnknown::rand2( + iext::mid(ext::SourceInfo::ID) + 1, + false, + )); + } + + Self { + ext_sinfo, + ext_unknown, + } + } +} From 809532ada7676b88702b3422490dbee06fedb32f Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Tue, 27 Jun 2023 11:12:08 +0200 Subject: [PATCH 143/203] Add ResponderId extension --- commons/zenoh-codec/src/network/mod.rs | 54 ++++++++++++++++++- commons/zenoh-codec/src/network/response.rs | 7 +++ commons/zenoh-protocol/src/network/mod.rs | 29 +++++++++- .../zenoh-protocol/src/network/response.rs | 6 +++ 4 files changed, 92 insertions(+), 4 deletions(-) diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index cb4bbd9aab..21c3a8d915 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -17,14 +17,14 @@ mod push; mod request; mod response; -use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ common::{imsg, ZExtZ64, ZExtZBufHeader}, - network::*, + network::*, core::ZenohId, }; // NetworkMessage @@ -188,3 +188,53 @@ where Ok((ext.into(), more)) } } + +// Extension: EntityId +impl LCodec<&ext::EntityIdType<{ ID }>> for Zenoh080 { + fn w_len(self, x: &ext::EntityIdType<{ ID }>) -> usize { + 1 + self.w_len(&x.zid) + self.w_len(x.eid) + } +} + +impl WCodec<(&ext::EntityIdType<{ ID }>, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::EntityIdType<{ ID }>, bool)) -> Self::Output { + let (x, more) = x; + let header: ZExtZBufHeader<{ ID }> = ZExtZBufHeader::new(self.w_len(x)); + self.write(&mut *writer, (&header, more))?; + + let flags: u8 = (x.zid.size() as u8 - 1) << 4; + self.write(&mut *writer, flags)?; + + let lodec = Zenoh080Length::new(x.zid.size()); + lodec.write(&mut *writer, &x.zid)?; + + self.write(&mut *writer, x.eid)?; + Ok(()) + } +} + +impl RCodec<(ext::EntityIdType<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::EntityIdType<{ ID }>, bool), Self::Error> { + let (_, more): (ZExtZBufHeader<{ ID }>, bool) = self.read(&mut *reader)?; + + let flags: u8 = self.codec.read(&mut *reader)?; + let length = 1 + ((flags >> 4) as usize); + + let lodec = Zenoh080Length::new(length); + let zid: ZenohId = lodec.read(&mut *reader)?; + + let eid: u32 = self.codec.read(&mut *reader)?; + + Ok((ext::EntityIdType { zid, eid }, more)) + } +} diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs index 8711eb121f..9e1a93ef4b 100644 --- a/commons/zenoh-codec/src/network/response.rs +++ b/commons/zenoh-codec/src/network/response.rs @@ -111,6 +111,7 @@ where // Extensions let mut ext_qos = ext::QoSType::default(); let mut ext_tstamp = None; + let mut ext_respid = None; let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { @@ -127,6 +128,11 @@ where ext_tstamp = Some(t); has_ext = ext; } + ext::ResponderId::ID => { + let (t, ext): (ext::ResponderIdType, bool) = eodec.read(&mut *reader)?; + ext_respid = Some(t); + has_ext = ext; + } _ => { has_ext = extension::skip(reader, "Response", ext)?; } @@ -143,6 +149,7 @@ where payload, ext_qos, ext_tstamp, + ext_respid, }) } } diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 1a7f65cd22..735853a624 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -139,7 +139,7 @@ impl From for NetworkMessage { pub mod ext { use crate::{ common::{imsg, ZExtZ64}, - core::{CongestionControl, Priority}, + core::{CongestionControl, Priority, ZenohId}, }; use core::fmt; @@ -253,7 +253,6 @@ pub mod ext { impl TimestampType<{ ID }> { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::core::ZenohId; use rand::Rng; let mut rng = rand::thread_rng(); @@ -300,4 +299,30 @@ pub mod ext { ZExtZ64::new(ext.node_id as u64) } } + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// |zid_len|X|X|X|X| + /// +-------+-+-+---+ + /// ~ zid ~ + /// +---------------+ + /// % eid % + /// +---------------+ + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct EntityIdType { + pub zid: ZenohId, + pub eid: u32, + } + + impl EntityIdType<{ ID }> { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + let zid = ZenohId::rand(); + let eid: u32 = rng.gen(); + Self { zid, eid } + } + } } diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index 91b59cb552..a1a49f535e 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -57,6 +57,7 @@ pub struct Response { pub payload: ResponseBody, pub ext_qos: ext::QoSType, pub ext_tstamp: Option, + pub ext_respid: Option, } pub mod ext { @@ -69,6 +70,9 @@ pub mod ext { pub type Timestamp = zextzbuf!(0x2, false); pub type TimestampType = crate::network::ext::TimestampType<{ Timestamp::ID }>; + + pub type ResponderId = zextzbuf!(0x3, false); + pub type ResponderIdType = crate::network::ext::EntityIdType<{ ResponderId::ID }>; } impl Response { @@ -83,6 +87,7 @@ impl Response { let payload = ResponseBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); + let ext_respid = rng.gen_bool(0.5).then(ext::ResponderIdType::rand); Self { rid, @@ -91,6 +96,7 @@ impl Response { payload, ext_qos, ext_tstamp, + ext_respid, } } } From 560ce8bff2e9f82abe6654550475db7cc8456f75 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 27 Jun 2023 12:15:37 +0200 Subject: [PATCH 144/203] WireExpr extension for undeclarations --- commons/zenoh-codec/src/network/declare.rs | 171 +++++++++++++++--- commons/zenoh-codec/src/network/response.rs | 9 +- commons/zenoh-protocol/src/network/declare.rs | 62 ++++++- 3 files changed, 212 insertions(+), 30 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index c73737298f..f07a8df2e8 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -14,13 +14,16 @@ use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; use zenoh_buffers::{ reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, + writer::{DidntWrite, HasWriter, Writer}, + ZBuf, }; use zenoh_protocol::{ common::{iext, imsg, ZExtZ64}, core::{ExprId, WireExpr}, network::{ - declare::{self, interest, keyexpr, queryable, subscriber, token, Declare, DeclareBody}, + declare::{ + self, common, interest, keyexpr, queryable, subscriber, token, Declare, DeclareBody, + }, id, Mapping, }, }; @@ -418,12 +421,15 @@ where fn write(self, writer: &mut W, x: &subscriber::UndeclareSubscriber) -> Self::Output { // Header - let header = declare::id::U_SUBSCRIBER; + let header = declare::id::U_SUBSCRIBER | subscriber::flag::Z; self.write(&mut *writer, header)?; // Body self.write(&mut *writer, x.id)?; + // Extension + self.write(&mut *writer, (&x.ext_wire_expr, false))?; + Ok(()) } } @@ -457,12 +463,26 @@ where let id: subscriber::SubscriberId = self.codec.read(&mut *reader)?; // Extensions - let has_ext = imsg::has_flag(self.header, subscriber::flag::Z); - if has_ext { - extension::skip_all(reader, "UndeclareSubscriber")?; + // WARNING: this is a temporary and mandatory extension used for undeclarations + let mut ext_wire_expr = common::ext::WireExprType::null(); + + let mut has_ext = imsg::has_flag(self.header, subscriber::flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + common::ext::WireExprExt::ID => { + let (we, ext): (common::ext::WireExprType, bool) = eodec.read(&mut *reader)?; + ext_wire_expr = we; + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "UndeclareSubscriber", ext)?; + } + } } - Ok(subscriber::UndeclareSubscriber { id }) + Ok(subscriber::UndeclareSubscriber { id, ext_wire_expr }) } } @@ -576,12 +596,15 @@ where fn write(self, writer: &mut W, x: &queryable::UndeclareQueryable) -> Self::Output { // Header - let header = declare::id::U_QUERYABLE; + let header = declare::id::U_QUERYABLE | queryable::flag::Z; self.write(&mut *writer, header)?; // Body self.write(&mut *writer, x.id)?; + // Extension + self.write(&mut *writer, (&x.ext_wire_expr, false))?; + Ok(()) } } @@ -615,12 +638,26 @@ where let id: queryable::QueryableId = self.codec.read(&mut *reader)?; // Extensions - let has_ext = imsg::has_flag(self.header, queryable::flag::Z); - if has_ext { - extension::skip_all(reader, "UndeclareQueryable")?; + // WARNING: this is a temporary and mandatory extension used for undeclarations + let mut ext_wire_expr = common::ext::WireExprType::null(); + + let mut has_ext = imsg::has_flag(self.header, queryable::flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + common::ext::WireExprExt::ID => { + let (we, ext): (common::ext::WireExprType, bool) = eodec.read(&mut *reader)?; + ext_wire_expr = we; + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "UndeclareQueryable", ext)?; + } + } } - Ok(queryable::UndeclareQueryable { id }) + Ok(queryable::UndeclareQueryable { id, ext_wire_expr }) } } @@ -707,12 +744,15 @@ where fn write(self, writer: &mut W, x: &token::UndeclareToken) -> Self::Output { // Header - let header = declare::id::U_TOKEN; + let header = declare::id::U_TOKEN | token::flag::Z; self.write(&mut *writer, header)?; // Body self.write(&mut *writer, x.id)?; + // Extension + self.write(&mut *writer, (&x.ext_wire_expr, false))?; + Ok(()) } } @@ -746,12 +786,26 @@ where let id: token::TokenId = self.codec.read(&mut *reader)?; // Extensions - let has_ext = imsg::has_flag(self.header, token::flag::Z); - if has_ext { - extension::skip_all(reader, "UndeclareToken")?; + // WARNING: this is a temporary and mandatory extension used for undeclarations + let mut ext_wire_expr = common::ext::WireExprType::null(); + + let mut has_ext = imsg::has_flag(self.header, interest::flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + common::ext::WireExprExt::ID => { + let (we, ext): (common::ext::WireExprType, bool) = eodec.read(&mut *reader)?; + ext_wire_expr = we; + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "UndeclareToken", ext)?; + } + } } - Ok(token::UndeclareToken { id }) + Ok(token::UndeclareToken { id, ext_wire_expr }) } } @@ -898,12 +952,15 @@ where fn write(self, writer: &mut W, x: &interest::UndeclareInterest) -> Self::Output { // Header - let header = declare::id::U_INTEREST; + let header = declare::id::U_INTEREST | interest::flag::Z; self.write(&mut *writer, header)?; // Body self.write(&mut *writer, x.id)?; + // Extension + self.write(&mut *writer, (&x.ext_wire_expr, false))?; + Ok(()) } } @@ -937,11 +994,81 @@ where let id: interest::InterestId = self.codec.read(&mut *reader)?; // Extensions - let has_ext = imsg::has_flag(self.header, token::flag::Z); - if has_ext { - extension::skip_all(reader, "UndeclareInterest")?; + // WARNING: this is a temporary and mandatory extension used for undeclarations + let mut ext_wire_expr = common::ext::WireExprType::null(); + + let mut has_ext = imsg::has_flag(self.header, interest::flag::Z); + while has_ext { + let ext: u8 = self.codec.read(&mut *reader)?; + let eodec = Zenoh080Header::new(ext); + match iext::eid(ext) { + common::ext::WireExprExt::ID => { + let (we, ext): (common::ext::WireExprType, bool) = eodec.read(&mut *reader)?; + ext_wire_expr = we; + has_ext = ext; + } + _ => { + has_ext = extension::skip(reader, "UndeclareInterest", ext)?; + } + } } - Ok(interest::UndeclareInterest { id }) + Ok(interest::UndeclareInterest { id, ext_wire_expr }) + } +} + +// WARNING: this is a temporary extension used for undeclarations +impl WCodec<(&common::ext::WireExprType, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&common::ext::WireExprType, bool)) -> Self::Output { + let (x, more) = x; + + let codec = Zenoh080::new(); + let mut value = ZBuf::empty(); + let mut zriter = value.writer(); + + let mut flags: u8 = 0; + if x.wire_expr.has_suffix() { + flags |= 1; + } + if let Mapping::Receiver = x.mapping { + flags |= 1 << 1; + } + codec.write(&mut zriter, flags)?; + codec.write(&mut zriter, &x.wire_expr)?; + + let ext = common::ext::WireExprExt { value }; + codec.write(&mut *writer, (&ext, more))?; + + Ok(()) + } +} + +impl RCodec<(common::ext::WireExprType, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(common::ext::WireExprType, bool), Self::Error> { + use zenoh_buffers::reader::HasReader; + + let (ext, more): (common::ext::WireExprExt, bool) = self.read(&mut *reader)?; + let mut zeader = ext.value.reader(); + let flags: u8 = self.codec.read(&mut zeader)?; + + let codec = Zenoh080Condition::new(imsg::has_flag(flags, 1)); + let wire_expr: WireExpr<'_> = codec.read(&mut zeader)?; + let mapping = if imsg::has_flag(flags, 1 << 1) { + Mapping::Receiver + } else { + Mapping::Sender + }; + + Ok((common::ext::WireExprType { wire_expr, mapping }, more)) } } diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs index 9e1a93ef4b..70e9cfa1c7 100644 --- a/commons/zenoh-codec/src/network/response.rs +++ b/commons/zenoh-codec/src/network/response.rs @@ -39,8 +39,9 @@ where fn write(self, writer: &mut W, x: &Response) -> Self::Output { // Header let mut header = id::RESPONSE; - let mut n_exts = - ((x.ext_qos != ext::QoSType::default()) as u8) + (x.ext_tstamp.is_some() as u8); + let mut n_exts = ((x.ext_qos != ext::QoSType::default()) as u8) + + (x.ext_tstamp.is_some() as u8) + + (x.ext_respid.is_some() as u8); if n_exts != 0 { header |= flag::Z; } @@ -65,6 +66,10 @@ where n_exts -= 1; self.write(&mut *writer, (ts, n_exts != 0))?; } + if let Some(ri) = x.ext_respid.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (ri, n_exts != 0))?; + } // Payload self.write(&mut *writer, &x.payload)?; diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index e1ee3ff72f..d872d7d5c8 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -12,10 +12,10 @@ // ZettaScale Zenoh Team, // use crate::{ - common::{imsg, ZExtZ64}, + common::{imsg, ZExtZ64, ZExtZBuf}, core::{ExprId, Reliability, WireExpr}, network::Mapping, - zextz64, + zextz64, zextzbuf, }; use core::ops::BitOr; pub use interest::*; @@ -169,6 +169,44 @@ impl Mode { } } +pub mod common { + use super::*; + + pub mod ext { + use super::*; + + // WARNING: this is a temporary and mandatory extension used for undeclarations + pub type WireExprExt = zextzbuf!(0x0f, true); + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct WireExprType { + pub wire_expr: WireExpr<'static>, + pub mapping: Mapping, + } + + impl WireExprType { + pub fn null() -> Self { + use std::borrow::Cow; + + Self { + wire_expr: WireExpr { + scope: ExprId::MIN, + suffix: Cow::from(""), + }, + mapping: Mapping::Receiver, + } + } + + #[cfg(feature = "test")] + pub fn rand() -> Self { + Self { + wire_expr: WireExpr::rand(), + mapping: Mapping::rand(), + } + } + } + } +} + pub mod keyexpr { use super::*; @@ -397,6 +435,8 @@ pub mod subscriber { #[derive(Debug, Clone, PartialEq, Eq)] pub struct UndeclareSubscriber { pub id: SubscriberId, + // WARNING: this is a temporary and mandatory extension used for undeclarations + pub ext_wire_expr: common::ext::WireExprType, } impl UndeclareSubscriber { @@ -406,8 +446,9 @@ pub mod subscriber { let mut rng = rand::thread_rng(); let id: SubscriberId = rng.gen(); + let ext_wire_expr = common::ext::WireExprType::rand(); - Self { id } + Self { id, ext_wire_expr } } } } @@ -542,6 +583,8 @@ pub mod queryable { #[derive(Debug, Clone, PartialEq, Eq)] pub struct UndeclareQueryable { pub id: QueryableId, + // WARNING: this is a temporary and mandatory extension used for undeclarations + pub ext_wire_expr: common::ext::WireExprType, } impl UndeclareQueryable { @@ -551,8 +594,9 @@ pub mod queryable { let mut rng = rand::thread_rng(); let id: QueryableId = rng.gen(); + let ext_wire_expr = common::ext::WireExprType::rand(); - Self { id } + Self { id, ext_wire_expr } } } } @@ -631,6 +675,8 @@ pub mod token { #[derive(Debug, Clone, PartialEq, Eq)] pub struct UndeclareToken { pub id: TokenId, + // WARNING: this is a temporary and mandatory extension used for undeclarations + pub ext_wire_expr: common::ext::WireExprType, } impl UndeclareToken { @@ -640,8 +686,9 @@ pub mod token { let mut rng = rand::thread_rng(); let id: TokenId = rng.gen(); + let ext_wire_expr = common::ext::WireExprType::rand(); - Self { id } + Self { id, ext_wire_expr } } } } @@ -875,6 +922,8 @@ pub mod interest { #[derive(Debug, Clone, PartialEq, Eq)] pub struct UndeclareInterest { pub id: InterestId, + // WARNING: this is a temporary and mandatory extension used for undeclarations + pub ext_wire_expr: common::ext::WireExprType, } impl UndeclareInterest { @@ -884,8 +933,9 @@ pub mod interest { let mut rng = rand::thread_rng(); let id: InterestId = rng.gen(); + let ext_wire_expr = common::ext::WireExprType::rand(); - Self { id } + Self { id, ext_wire_expr } } } } From 52f1cbfeeb439bf02a316deb04e440f6fe60d988 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 27 Jun 2023 12:36:26 +0200 Subject: [PATCH 145/203] Improve WireExpr extension for undeclarations --- commons/zenoh-codec/src/network/declare.rs | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index f07a8df2e8..65da506063 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{iext, imsg, ZExtZ64}, - core::{ExprId, WireExpr}, + core::{ExprId, ExprLen, WireExpr}, network::{ declare::{ self, common, interest, keyexpr, queryable, subscriber, token, Declare, DeclareBody, @@ -1039,7 +1039,11 @@ where flags |= 1 << 1; } codec.write(&mut zriter, flags)?; - codec.write(&mut zriter, &x.wire_expr)?; + + codec.write(&mut zriter, x.wire_expr.scope)?; + if x.wire_expr.has_suffix() { + zriter.write_exact(x.wire_expr.suffix.as_bytes())?; + } let ext = common::ext::WireExprExt { value }; codec.write(&mut *writer, (&ext, more))?; @@ -1058,11 +1062,23 @@ where use zenoh_buffers::reader::HasReader; let (ext, more): (common::ext::WireExprExt, bool) = self.read(&mut *reader)?; + let mut zeader = ext.value.reader(); let flags: u8 = self.codec.read(&mut zeader)?; - let codec = Zenoh080Condition::new(imsg::has_flag(flags, 1)); - let wire_expr: WireExpr<'_> = codec.read(&mut zeader)?; + let scope: ExprLen = self.codec.read(&mut zeader)?; + let suffix = if imsg::has_flag(flags, 1) { + let mut buff = zenoh_buffers::vec::uninit(zeader.remaining()); + zeader.read_exact(&mut buff)?; + String::from_utf8(buff).map_err(|_| DidntRead)? + } else { + String::new() + }; + let wire_expr = WireExpr { + scope, + suffix: suffix.into(), + }; + let mapping = if imsg::has_flag(flags, 1 << 1) { Mapping::Receiver } else { From bc9a51029dfaf698aefca781277cec827468037c Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 27 Jun 2023 13:10:37 +0200 Subject: [PATCH 146/203] Fix cargo fmt --- commons/zenoh-codec/src/network/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 21c3a8d915..d2f99f3d83 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -24,7 +24,8 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{imsg, ZExtZ64, ZExtZBufHeader}, - network::*, core::ZenohId, + core::ZenohId, + network::*, }; // NetworkMessage From acae401e972d66287807c9c0d0e4661bbb8f9723 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Wed, 28 Jun 2023 16:32:19 +0200 Subject: [PATCH 147/203] Remove SourceInfo ext from Pull message --- commons/zenoh-codec/src/zenoh_new/pull.rs | 32 +++++--------------- commons/zenoh-protocol/src/zenoh_new/pull.rs | 22 ++------------ 2 files changed, 9 insertions(+), 45 deletions(-) diff --git a/commons/zenoh-codec/src/zenoh_new/pull.rs b/commons/zenoh-codec/src/zenoh_new/pull.rs index 48358e4483..49e91039eb 100644 --- a/commons/zenoh-codec/src/zenoh_new/pull.rs +++ b/commons/zenoh-codec/src/zenoh_new/pull.rs @@ -19,10 +19,10 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ - common::{iext, imsg}, + common::imsg, zenoh_new::{ id, - pull::{ext, flag, Pull}, + pull::{flag, Pull}, }, }; @@ -35,17 +35,13 @@ where fn write(self, writer: &mut W, x: &Pull) -> Self::Output { // Header let mut header = id::PULL; - let mut n_exts = (x.ext_sinfo.is_some() as u8) + (x.ext_unknown.len() as u8); + let mut n_exts = x.ext_unknown.len() as u8; if n_exts != 0 { header |= flag::Z; } self.write(&mut *writer, header)?; // Extensions - if let Some(sinfo) = x.ext_sinfo.as_ref() { - n_exts -= 1; - self.write(&mut *writer, (sinfo, n_exts != 0))?; - } for u in x.ext_unknown.iter() { n_exts -= 1; self.write(&mut *writer, (u, n_exts != 0))?; @@ -80,30 +76,16 @@ where } // Extensions - let mut ext_sinfo: Option = None; let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); while has_ext { let ext: u8 = self.codec.read(&mut *reader)?; - let eodec = Zenoh080Header::new(ext); - match iext::eid(ext) { - ext::SourceInfo::ID => { - let (s, ext): (ext::SourceInfoType, bool) = eodec.read(&mut *reader)?; - ext_sinfo = Some(s); - has_ext = ext; - } - _ => { - let (u, ext) = extension::read(reader, "Pull", ext)?; - ext_unknown.push(u); - has_ext = ext; - } - } + let (u, ext) = extension::read(reader, "Pull", ext)?; + ext_unknown.push(u); + has_ext = ext; } - Ok(Pull { - ext_sinfo, - ext_unknown, - }) + Ok(Pull { ext_unknown }) } } diff --git a/commons/zenoh-protocol/src/zenoh_new/pull.rs b/commons/zenoh-protocol/src/zenoh_new/pull.rs index 7af727ebc4..eb4f7eb55e 100644 --- a/commons/zenoh-protocol/src/zenoh_new/pull.rs +++ b/commons/zenoh-protocol/src/zenoh_new/pull.rs @@ -37,38 +37,20 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Pull { - pub ext_sinfo: Option, pub ext_unknown: Vec, } -pub mod ext { - use crate::{common::ZExtZBuf, zextzbuf}; - - /// # SourceInfo extension - /// Used to carry additional information about the source of data - pub type SourceInfo = zextzbuf!(0x1, false); - pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; -} - impl Pull { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::common::iext; use rand::Rng; let mut rng = rand::thread_rng(); - let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); let mut ext_unknown = Vec::new(); for _ in 0..rng.gen_range(0..4) { - ext_unknown.push(ZExtUnknown::rand2( - iext::mid(ext::SourceInfo::ID) + 1, - false, - )); + ext_unknown.push(ZExtUnknown::rand2(1, false)); } - Self { - ext_sinfo, - ext_unknown, - } + Self { ext_unknown } } } From 79559bb101a35b9b45c95fc8aefab3f198c7b953 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 29 Jun 2023 11:47:35 +0200 Subject: [PATCH 148/203] Fix UndeclareInterest ID --- commons/zenoh-protocol/src/network/declare.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index d872d7d5c8..e7ca85c795 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -83,7 +83,7 @@ pub mod id { pub const D_INTEREST: u8 = 0x08; pub const F_INTEREST: u8 = 0x09; - pub const U_INTEREST: u8 = 0x10; + pub const U_INTEREST: u8 = 0x0A; } #[derive(Debug, Clone, PartialEq, Eq)] From f8a05483df7a29b54ee82aed73969bbb89fd8fef Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Thu, 29 Jun 2023 15:02:48 +0200 Subject: [PATCH 149/203] Router layer uses new protocol --- commons/zenoh-codec/src/network/mod.rs | 20 +- commons/zenoh-codec/src/transport/frame.rs | 4 +- commons/zenoh-protocol/src/network/mod.rs | 46 + commons/zenoh-protocol/src/transport/frame.rs | 8 +- commons/zenoh-protocol/src/zenoh/query.rs | 27 +- io/zenoh-transport/src/common/batch.rs | 75 + .../src/common/defragmentation.rs | 6 +- io/zenoh-transport/src/common/pipeline.rs | 672 ++--- io/zenoh-transport/src/lib.rs | 6 +- io/zenoh-transport/src/primitives/demux.rs | 117 +- io/zenoh-transport/src/primitives/mod.rs | 136 +- io/zenoh-transport/src/primitives/mux.rs | 200 +- io/zenoh-transport/src/unicast/mod.rs | 6 +- io/zenoh-transport/src/unicast/rx.rs | 4 +- io/zenoh-transport/src/unicast/tx.rs | 8 +- io/zenoh-transport/tests/endpoints.rs | 4 +- .../tests/transport_whitelist.rs | 4 +- .../tests/unicast_authenticator.rs | 4 +- .../tests/unicast_concurrent.rs | 790 +++--- io/zenoh-transport/tests/unicast_conduits.rs | 686 ++--- .../tests/unicast_defragmentation.rs | 364 +-- .../tests/unicast_intermittent.rs | 746 +++--- .../tests/unicast_simultaneous.rs | 700 ++--- io/zenoh-transport/tests/unicast_transport.rs | 2260 ++++++++--------- zenoh/src/admin.rs | 5 +- zenoh/src/key_expr.rs | 12 +- zenoh/src/liveliness.rs | 4 +- zenoh/src/net/mod.rs | 4 + zenoh/src/net/routing/face.rs | 586 ++--- zenoh/src/net/routing/network.rs | 62 +- zenoh/src/net/routing/pubsub.rs | 412 +-- zenoh/src/net/routing/queries.rs | 361 ++- zenoh/src/net/routing/resource.rs | 40 +- zenoh/src/net/routing/router.rs | 150 +- zenoh/src/net/runtime/adminspace.rs | 302 +-- zenoh/src/net/runtime/mod.rs | 37 +- zenoh/src/net/tests/tables.rs | 1459 ++++++----- zenoh/src/publication.rs | 121 +- zenoh/src/queryable.rs | 46 +- zenoh/src/session.rs | 885 ++++--- zenoh/src/subscriber.rs | 19 +- 41 files changed, 5777 insertions(+), 5621 deletions(-) diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index d2f99f3d83..d37d7df497 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -17,14 +17,16 @@ mod push; mod request; mod response; -use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; +use crate::{ + LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length, Zenoh080Reliability, +}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ common::{imsg, ZExtZ64, ZExtZBufHeader}, - core::ZenohId, + core::{Reliability, ZenohId}, network::*, }; @@ -54,7 +56,19 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Reliability::new(Reliability::default()); + codec.read(reader) + } +} + +impl RCodec for Zenoh080Reliability +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.codec.read(&mut *reader)?; let codec = Zenoh080Header::new(header); let body = match imsg::mid(codec.header) { diff --git a/commons/zenoh-codec/src/transport/frame.rs b/commons/zenoh-codec/src/transport/frame.rs index ee4bf9b4ea..1293dc950c 100644 --- a/commons/zenoh-codec/src/transport/frame.rs +++ b/commons/zenoh-codec/src/transport/frame.rs @@ -20,11 +20,11 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::{iext, imsg}, core::Reliability, + network::NetworkMessage, transport::{ frame::{ext, flag, Frame, FrameHeader}, id, TransportSn, }, - zenoh::ZenohMessage, }; // FrameHeader @@ -165,7 +165,7 @@ where let mut payload = Vec::new(); while reader.can_read() { let mark = reader.mark(); - let res: Result = rcode.read(&mut *reader); + let res: Result = rcode.read(&mut *reader); match res { Ok(m) => payload.push(m), Err(_) => { diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 735853a624..752a995ef5 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -17,12 +17,16 @@ pub mod push; pub mod request; pub mod response; +use core::fmt; + pub use declare::*; pub use oam::*; pub use push::*; pub use request::*; pub use response::*; +use crate::core::{CongestionControl, Priority}; + pub mod id { // WARNING: it's crucial that these IDs do NOT collide with the IDs // defined in `crate::transport::id`. @@ -93,6 +97,48 @@ impl NetworkMessage { Self { body } } + + #[inline] + pub fn is_reliable(&self) -> bool { + // TODO + true + } + + #[inline] + pub fn is_droppable(&self) -> bool { + if !self.is_reliable() { + return true; + } + + let cc = match &self.body { + NetworkBody::Declare(msg) => msg.ext_qos.congestion_control(), + NetworkBody::Push(msg) => msg.ext_qos.congestion_control(), + NetworkBody::Request(msg) => msg.ext_qos.congestion_control(), + NetworkBody::Response(msg) => msg.ext_qos.congestion_control(), + NetworkBody::ResponseFinal(msg) => msg.ext_qos.congestion_control(), + NetworkBody::OAM(msg) => msg.ext_qos.congestion_control(), + }; + + cc == CongestionControl::Drop + } + + #[inline] + pub fn priority(&self) -> Priority { + match &self.body { + NetworkBody::Declare(msg) => msg.ext_qos.priority(), + NetworkBody::Push(msg) => msg.ext_qos.priority(), + NetworkBody::Request(msg) => msg.ext_qos.priority(), + NetworkBody::Response(msg) => msg.ext_qos.priority(), + NetworkBody::ResponseFinal(msg) => msg.ext_qos.priority(), + NetworkBody::OAM(msg) => msg.ext_qos.priority(), + } + } +} + +impl fmt::Display for NetworkMessage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self, f) + } } impl From for NetworkMessage { diff --git a/commons/zenoh-protocol/src/transport/frame.rs b/commons/zenoh-protocol/src/transport/frame.rs index f9991378c0..bcd01e7965 100644 --- a/commons/zenoh-protocol/src/transport/frame.rs +++ b/commons/zenoh-protocol/src/transport/frame.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::Reliability, transport::TransportSn, zenoh::ZenohMessage}; +use crate::{core::Reliability, network::NetworkMessage, transport::TransportSn}; use alloc::vec::Vec; /// # Frame message @@ -70,7 +70,7 @@ pub mod flag { pub struct Frame { pub reliability: Reliability, pub sn: TransportSn, - pub payload: Vec, + pub payload: Vec, pub ext_qos: ext::QoSType, } @@ -94,9 +94,7 @@ impl Frame { let ext_qos = ext::QoSType::rand(); let mut payload = vec![]; for _ in 0..rng.gen_range(1..4) { - let mut m = ZenohMessage::rand(); - m.channel.reliability = reliability; - m.channel.priority = ext_qos.priority(); + let m = NetworkMessage::rand(); payload.push(m); } diff --git a/commons/zenoh-protocol/src/zenoh/query.rs b/commons/zenoh-protocol/src/zenoh/query.rs index 579528922a..a173195605 100644 --- a/commons/zenoh-protocol/src/zenoh/query.rs +++ b/commons/zenoh-protocol/src/zenoh/query.rs @@ -11,7 +11,10 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, zenoh::DataInfo}; +use crate::{ + core::WireExpr, network::request::ext::TargetType, zenoh::DataInfo, + zenoh_new::query::ext::ConsolidationType, +}; use alloc::string::String; use core::sync::atomic::AtomicU32; use zenoh_buffers::ZBuf; @@ -37,6 +40,16 @@ pub enum ConsolidationMode { Latest, } +impl From for ConsolidationType { + fn from(val: ConsolidationMode) -> Self { + match val { + ConsolidationMode::None => ConsolidationType::None, + ConsolidationMode::Monotonic => ConsolidationType::Monotonic, + ConsolidationMode::Latest => ConsolidationType::Latest, + } + } +} + /// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub enum QueryTarget { @@ -48,6 +61,18 @@ pub enum QueryTarget { Complete(u64), } +impl From for TargetType { + fn from(val: QueryTarget) -> Self { + match val { + QueryTarget::BestMatching => TargetType::BestMatching, + QueryTarget::All => TargetType::All, + QueryTarget::AllComplete => TargetType::AllComplete, + #[cfg(feature = "complete_n")] + QueryTarget::Complete(n) => TargetType::Complete(n), + } + } +} + /// # QueryBody /// /// QueryBody data structure is optionally included in Query messages diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 15affb7355..ba0c089052 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -20,6 +20,7 @@ use zenoh_buffers::{ use zenoh_codec::{WCodec, Zenoh080}; use zenoh_protocol::{ core::Reliability, + network::NetworkMessage, transport::{ fragment::FragmentHeader, frame::FrameHeader, BatchSize, TransportMessage, TransportSn, }, @@ -219,6 +220,80 @@ pub(crate) enum WError { DidntWrite, } +impl Encode<&NetworkMessage> for &mut WBatch { + type Output = Result<(), WError>; + + /// Try to serialize a [`NetworkMessage`][NetworkMessage] on the [`SerializationBatch`][SerializationBatch]. + /// + /// # Arguments + /// * `message` - The [`NetworkMessage`][NetworkMessage] to serialize. + /// + fn encode(self, message: &NetworkMessage) -> Self::Output { + // Eventually update the current frame and sn based on the current status + if let (CurrentFrame::Reliable, false) + | (CurrentFrame::BestEffort, true) + | (CurrentFrame::None, _) = (self.current_frame, message.is_reliable()) + { + // We are not serializing on the right frame. + return Err(WError::NewFrame); + }; + + // Mark the write operation + let mut writer = self.buffer.writer(); + let mark = writer.mark(); + + let codec = Zenoh080::new(); + codec.write(&mut writer, message).map_err(|_| { + // Revert the write operation + writer.rewind(mark); + WError::DidntWrite + }) + } +} + +impl Encode<(&NetworkMessage, FrameHeader)> for &mut WBatch { + type Output = Result<(), DidntWrite>; + + /// Try to serialize a [`NetworkMessage`][NetworkMessage] on the [`SerializationBatch`][SerializationBatch]. + /// + /// # Arguments + /// * `message` - The [`NetworkMessage`][NetworkMessage] to serialize. + /// + fn encode(self, message: (&NetworkMessage, FrameHeader)) -> Self::Output { + let (message, frame) = message; + + // Mark the write operation + let mut writer = self.buffer.writer(); + let mark = writer.mark(); + + let codec = Zenoh080::new(); + // Write the frame header + codec.write(&mut writer, &frame).map_err(|e| { + // Revert the write operation + writer.rewind(mark); + e + })?; + // Write the zenoh message + codec.write(&mut writer, message).map_err(|e| { + // Revert the write operation + writer.rewind(mark); + e + })?; + // Update the frame + self.current_frame = match frame.reliability { + Reliability::Reliable => { + self.latest_sn.reliable = Some(frame.sn); + CurrentFrame::Reliable + } + Reliability::BestEffort => { + self.latest_sn.best_effort = Some(frame.sn); + CurrentFrame::BestEffort + } + }; + Ok(()) + } +} + impl Encode<&ZenohMessage> for &mut WBatch { type Output = Result<(), WError>; diff --git a/io/zenoh-transport/src/common/defragmentation.rs b/io/zenoh-transport/src/common/defragmentation.rs index caf1411f5d..be734cad45 100644 --- a/io/zenoh-transport/src/common/defragmentation.rs +++ b/io/zenoh-transport/src/common/defragmentation.rs @@ -16,8 +16,8 @@ use zenoh_buffers::{reader::HasReader, SplitBuffer, ZBuf, ZSlice}; use zenoh_codec::{RCodec, Zenoh080Reliability}; use zenoh_protocol::{ core::{Bits, Reliability}, + network::NetworkMessage, transport::TransportSn, - zenoh::ZenohMessage, }; use zenoh_result::{bail, ZResult}; @@ -86,10 +86,10 @@ impl DefragBuffer { } #[inline(always)] - pub(crate) fn defragment(&mut self) -> Option { + pub(crate) fn defragment(&mut self) -> Option { let mut reader = self.buffer.reader(); let rcodec = Zenoh080Reliability::new(self.reliability); - let res: Option = rcodec.read(&mut reader).ok(); + let res: Option = rcodec.read(&mut reader).ok(); self.clear(); res } diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 970121cfff..51e914db5f 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -31,6 +31,8 @@ use zenoh_buffers::{ use zenoh_codec::{WCodec, Zenoh080}; use zenoh_config::QueueSizeConf; use zenoh_core::zlock; +use zenoh_protocol::core::Reliability; +use zenoh_protocol::network::NetworkMessage; use zenoh_protocol::{ core::Priority, transport::{ @@ -38,7 +40,6 @@ use zenoh_protocol::{ frame::{self, FrameHeader}, BatchSize, TransportMessage, }, - zenoh::ZenohMessage, }; // It's faster to work directly with nanoseconds. @@ -120,7 +121,7 @@ struct StageIn { } impl StageIn { - fn push_zenoh_message(&mut self, msg: &mut ZenohMessage, priority: Priority) -> bool { + fn push_network_message(&mut self, msg: &mut NetworkMessage, priority: Priority) -> bool { // Lock the current serialization batch. let mut c_guard = self.mutex.current(); @@ -184,7 +185,7 @@ impl StageIn { // The Frame let frame = FrameHeader { - reliability: msg.channel.reliability, + reliability: Reliability::Reliable, // TODO sn, ext_qos: frame::ext::QoSType::new(priority), }; @@ -586,16 +587,17 @@ pub(crate) struct TransmissionPipelineProducer { impl TransmissionPipelineProducer { #[inline] - pub(crate) fn push_zenoh_message(&self, mut msg: ZenohMessage) -> bool { + pub(crate) fn push_network_message(&self, mut msg: NetworkMessage) -> bool { // If the queue is not QoS, it means that we only have one priority with index 0. let (idx, priority) = if self.stage_in.len() > 1 { - (msg.channel.priority as usize, msg.channel.priority) + let priority = msg.priority(); + (priority as usize, priority) } else { (0, Priority::default()) }; // Lock the channel. We are the only one that will be writing on it. let mut queue = zlock!(self.stage_in[idx]); - queue.push_zenoh_message(&mut msg, priority) + queue.push_network_message(&mut msg, priority) } #[inline] @@ -691,332 +693,332 @@ impl TransmissionPipelineConsumer { } } -#[cfg(test)] -mod tests { - use super::*; - use async_std::{prelude::FutureExt, task}; - use std::{ - convert::TryFrom, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, - }, - time::{Duration, Instant}, - }; - use zenoh_buffers::{ - reader::{DidntRead, HasReader}, - ZBuf, - }; - use zenoh_codec::{RCodec, Zenoh080}; - use zenoh_protocol::{ - core::{Bits, Channel, CongestionControl, Priority, Reliability}, - transport::{BatchSize, Fragment, Frame, TransportBody, TransportSn}, - zenoh::ZenohMessage, - }; - - const SLEEP: Duration = Duration::from_millis(100); - const TIMEOUT: Duration = Duration::from_secs(60); - - const CONFIG: TransmissionPipelineConf = TransmissionPipelineConf { - is_streamed: true, - batch_size: BatchSize::MAX, - queue_size: [1; Priority::NUM], - backoff: Duration::from_micros(1), - }; - - #[test] - fn tx_pipeline_flow() { - fn schedule(queue: TransmissionPipelineProducer, num_msg: usize, payload_size: usize) { - // Send reliable messages - let key = "test".into(); - let payload = ZBuf::from(vec![0_u8; payload_size]); - let data_info = None; - let routing_context = None; - let reply_context = None; - let channel = Channel { - priority: Priority::Control, - reliability: Reliability::Reliable, - }; - let congestion_control = CongestionControl::Block; - - let message = ZenohMessage::make_data( - key, - payload, - channel, - congestion_control, - data_info, - routing_context, - reply_context, - ); - - println!( - "Pipeline Flow [>>>]: Sending {num_msg} messages with payload size of {payload_size} bytes" - ); - for i in 0..num_msg { - println!( - "Pipeline Flow [>>>]: Pushed {} msgs ({payload_size} bytes)", - i + 1 - ); - queue.push_zenoh_message(message.clone()); - } - } - - async fn consume(mut queue: TransmissionPipelineConsumer, num_msg: usize) { - let mut batches: usize = 0; - let mut bytes: usize = 0; - let mut msgs: usize = 0; - let mut fragments: usize = 0; - - while msgs != num_msg { - let (batch, priority) = queue.pull().await.unwrap(); - batches += 1; - bytes += batch.len() as usize; - // Create a ZBuf for deserialization starting from the batch - let bytes = batch.as_bytes(); - // Deserialize the messages - let mut reader = bytes.reader(); - let codec = Zenoh080::new(); - - loop { - let res: Result = codec.read(&mut reader); - match res { - Ok(msg) => { - match msg.body { - TransportBody::Frame(Frame { payload, .. }) => { - msgs += payload.len() - } - TransportBody::Fragment(Fragment { more, .. }) => { - fragments += 1; - if !more { - msgs += 1; - } - } - _ => { - msgs += 1; - } - } - println!("Pipeline Flow [<<<]: Pulled {} msgs", msgs + 1); - } - Err(_) => break, - } - } - println!("Pipeline Flow [+++]: Refill {} msgs", msgs + 1); - // Reinsert the batch - queue.refill(batch, priority); - } - - println!( - "Pipeline Flow [<<<]: Received {msgs} messages, {bytes} bytes, {batches} batches, {fragments} fragments" - ); - } - - // Pipeline conduits - let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); - let conduits = vec![tct]; - - // Total amount of bytes to send in each test - let bytes: usize = 100_000_000; - let max_msgs: usize = 1_000; - // Payload size of the messages - let payload_sizes = [8, 64, 512, 4_096, 8_192, 32_768, 262_144, 2_097_152]; - - task::block_on(async { - for ps in payload_sizes.iter() { - if u64::try_from(*ps).is_err() { - break; - } - - // Compute the number of messages to send - let num_msg = max_msgs.min(bytes / ps); - - let (producer, consumer) = TransmissionPipeline::make( - TransmissionPipelineConf::default(), - conduits.as_slice(), - ); - - let t_c = task::spawn(async move { - consume(consumer, num_msg).await; - }); - - let c_ps = *ps; - let t_s = task::spawn(async move { - schedule(producer, num_msg, c_ps); - }); - - let res = t_c.join(t_s).timeout(TIMEOUT).await; - assert!(res.is_ok()); - } - }); - } - - #[test] - fn tx_pipeline_blocking() { - fn schedule(queue: TransmissionPipelineProducer, counter: Arc, id: usize) { - // Make sure to put only one message per batch: set the payload size - // to half of the batch in such a way the serialized zenoh message - // will be larger then half of the batch size (header + payload). - let payload_size = (CONFIG.batch_size / 2) as usize; - - // Send reliable messages - let key = "test".into(); - let payload = ZBuf::from(vec![0_u8; payload_size]); - let channel = Channel { - priority: Priority::Control, - reliability: Reliability::Reliable, - }; - let congestion_control = CongestionControl::Block; - let data_info = None; - let routing_context = None; - let reply_context = None; - - let message = ZenohMessage::make_data( - key, - payload, - channel, - congestion_control, - data_info, - routing_context, - reply_context, - ); - - // The last push should block since there shouldn't any more batches - // available for serialization. - let num_msg = 1 + CONFIG.queue_size[0]; - for i in 0..num_msg { - println!( - "Pipeline Blocking [>>>]: ({id}) Scheduling message #{i} with payload size of {payload_size} bytes" - ); - queue.push_zenoh_message(message.clone()); - let c = counter.fetch_add(1, Ordering::AcqRel); - println!( - "Pipeline Blocking [>>>]: ({}) Scheduled message #{} (tot {}) with payload size of {} bytes", - id, i, c + 1, - payload_size - ); - } - } - - // Pipeline - let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); - let conduits = vec![tct]; - let (producer, mut consumer) = - TransmissionPipeline::make(TransmissionPipelineConf::default(), conduits.as_slice()); - - let counter = Arc::new(AtomicUsize::new(0)); - - let c_producer = producer.clone(); - let c_counter = counter.clone(); - let h1 = task::spawn_blocking(move || { - schedule(c_producer, c_counter, 1); - }); - - let c_counter = counter.clone(); - let h2 = task::spawn_blocking(move || { - schedule(producer, c_counter, 2); - }); - - task::block_on(async { - // Wait to have sent enough messages and to have blocked - println!( - "Pipeline Blocking [---]: waiting to have {} messages being scheduled", - CONFIG.queue_size[Priority::MAX as usize] - ); - let check = async { - while counter.load(Ordering::Acquire) < CONFIG.queue_size[Priority::MAX as usize] { - task::sleep(SLEEP).await; - } - }; - check.timeout(TIMEOUT).await.unwrap(); - - // Disable and drain the queue - task::spawn_blocking(move || { - println!("Pipeline Blocking [---]: draining the queue"); - let _ = consumer.drain(); - }) - .timeout(TIMEOUT) - .await - .unwrap(); - - // Make sure that the tasks scheduling have been unblocked - println!("Pipeline Blocking [---]: waiting for schedule (1) to be unblocked"); - h1.timeout(TIMEOUT).await.unwrap(); - println!("Pipeline Blocking [---]: waiting for schedule (2) to be unblocked"); - h2.timeout(TIMEOUT).await.unwrap(); - }); - } - - #[test] - #[ignore] - fn tx_pipeline_thr() { - // Queue - let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); - let conduits = vec![tct]; - let (producer, mut consumer) = TransmissionPipeline::make(CONFIG, conduits.as_slice()); - let count = Arc::new(AtomicUsize::new(0)); - let size = Arc::new(AtomicUsize::new(0)); - - let c_size = size.clone(); - task::spawn(async move { - loop { - let payload_sizes: [usize; 16] = [ - 8, 16, 32, 64, 128, 256, 512, 1_024, 2_048, 4_096, 8_192, 16_384, 32_768, - 65_536, 262_144, 1_048_576, - ]; - for size in payload_sizes.iter() { - c_size.store(*size, Ordering::Release); - - // Send reliable messages - let key = "pipeline/thr".into(); - let payload = ZBuf::from(vec![0_u8; *size]); - let channel = Channel { - priority: Priority::Control, - reliability: Reliability::Reliable, - }; - let congestion_control = CongestionControl::Block; - let data_info = None; - let routing_context = None; - let reply_context = None; - - let message = ZenohMessage::make_data( - key, - payload, - channel, - congestion_control, - data_info, - routing_context, - reply_context, - ); - - let duration = Duration::from_millis(5_500); - let start = Instant::now(); - while start.elapsed() < duration { - producer.push_zenoh_message(message.clone()); - } - } - } - }); - - let c_count = count.clone(); - task::spawn(async move { - loop { - let (batch, priority) = consumer.pull().await.unwrap(); - c_count.fetch_add(batch.len() as usize, Ordering::AcqRel); - consumer.refill(batch, priority); - } - }); - - task::block_on(async { - let mut prev_size: usize = usize::MAX; - loop { - let received = count.swap(0, Ordering::AcqRel); - let current: usize = size.load(Ordering::Acquire); - if current == prev_size { - let thr = (8.0 * received as f64) / 1_000_000_000.0; - println!("{} bytes: {:.6} Gbps", current, 2.0 * thr); - } - prev_size = current; - task::sleep(Duration::from_millis(500)).await; - } - }); - } -} +// #[cfg(test)] +// mod tests { +// use super::*; +// use async_std::{prelude::FutureExt, task}; +// use std::{ +// convert::TryFrom, +// sync::{ +// atomic::{AtomicUsize, Ordering}, +// Arc, +// }, +// time::{Duration, Instant}, +// }; +// use zenoh_buffers::{ +// reader::{DidntRead, HasReader}, +// ZBuf, +// }; +// use zenoh_codec::{RCodec, Zenoh080}; +// use zenoh_protocol::{ +// core::{Bits, Channel, CongestionControl, Priority, Reliability}, +// transport::{BatchSize, Fragment, Frame, TransportBody, TransportSn}, +// zenoh::ZenohMessage, +// }; + +// const SLEEP: Duration = Duration::from_millis(100); +// const TIMEOUT: Duration = Duration::from_secs(60); + +// const CONFIG: TransmissionPipelineConf = TransmissionPipelineConf { +// is_streamed: true, +// batch_size: BatchSize::MAX, +// queue_size: [1; Priority::NUM], +// backoff: Duration::from_micros(1), +// }; + +// #[test] +// fn tx_pipeline_flow() { +// fn schedule(queue: TransmissionPipelineProducer, num_msg: usize, payload_size: usize) { +// // Send reliable messages +// let key = "test".into(); +// let payload = ZBuf::from(vec![0_u8; payload_size]); +// let data_info = None; +// let routing_context = None; +// let reply_context = None; +// let channel = Channel { +// priority: Priority::Control, +// reliability: Reliability::Reliable, +// }; +// let congestion_control = CongestionControl::Block; + +// let message = ZenohMessage::make_data( +// key, +// payload, +// channel, +// congestion_control, +// data_info, +// routing_context, +// reply_context, +// ); + +// println!( +// "Pipeline Flow [>>>]: Sending {num_msg} messages with payload size of {payload_size} bytes" +// ); +// for i in 0..num_msg { +// println!( +// "Pipeline Flow [>>>]: Pushed {} msgs ({payload_size} bytes)", +// i + 1 +// ); +// queue.push_zenoh_message(message.clone()); +// } +// } + +// async fn consume(mut queue: TransmissionPipelineConsumer, num_msg: usize) { +// let mut batches: usize = 0; +// let mut bytes: usize = 0; +// let mut msgs: usize = 0; +// let mut fragments: usize = 0; + +// while msgs != num_msg { +// let (batch, priority) = queue.pull().await.unwrap(); +// batches += 1; +// bytes += batch.len() as usize; +// // Create a ZBuf for deserialization starting from the batch +// let bytes = batch.as_bytes(); +// // Deserialize the messages +// let mut reader = bytes.reader(); +// let codec = Zenoh080::new(); + +// loop { +// let res: Result = codec.read(&mut reader); +// match res { +// Ok(msg) => { +// match msg.body { +// TransportBody::Frame(Frame { payload, .. }) => { +// msgs += payload.len() +// } +// TransportBody::Fragment(Fragment { more, .. }) => { +// fragments += 1; +// if !more { +// msgs += 1; +// } +// } +// _ => { +// msgs += 1; +// } +// } +// println!("Pipeline Flow [<<<]: Pulled {} msgs", msgs + 1); +// } +// Err(_) => break, +// } +// } +// println!("Pipeline Flow [+++]: Refill {} msgs", msgs + 1); +// // Reinsert the batch +// queue.refill(batch, priority); +// } + +// println!( +// "Pipeline Flow [<<<]: Received {msgs} messages, {bytes} bytes, {batches} batches, {fragments} fragments" +// ); +// } + +// // Pipeline conduits +// let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); +// let conduits = vec![tct]; + +// // Total amount of bytes to send in each test +// let bytes: usize = 100_000_000; +// let max_msgs: usize = 1_000; +// // Payload size of the messages +// let payload_sizes = [8, 64, 512, 4_096, 8_192, 32_768, 262_144, 2_097_152]; + +// task::block_on(async { +// for ps in payload_sizes.iter() { +// if u64::try_from(*ps).is_err() { +// break; +// } + +// // Compute the number of messages to send +// let num_msg = max_msgs.min(bytes / ps); + +// let (producer, consumer) = TransmissionPipeline::make( +// TransmissionPipelineConf::default(), +// conduits.as_slice(), +// ); + +// let t_c = task::spawn(async move { +// consume(consumer, num_msg).await; +// }); + +// let c_ps = *ps; +// let t_s = task::spawn(async move { +// schedule(producer, num_msg, c_ps); +// }); + +// let res = t_c.join(t_s).timeout(TIMEOUT).await; +// assert!(res.is_ok()); +// } +// }); +// } + +// #[test] +// fn tx_pipeline_blocking() { +// fn schedule(queue: TransmissionPipelineProducer, counter: Arc, id: usize) { +// // Make sure to put only one message per batch: set the payload size +// // to half of the batch in such a way the serialized zenoh message +// // will be larger then half of the batch size (header + payload). +// let payload_size = (CONFIG.batch_size / 2) as usize; + +// // Send reliable messages +// let key = "test".into(); +// let payload = ZBuf::from(vec![0_u8; payload_size]); +// let channel = Channel { +// priority: Priority::Control, +// reliability: Reliability::Reliable, +// }; +// let congestion_control = CongestionControl::Block; +// let data_info = None; +// let routing_context = None; +// let reply_context = None; + +// let message = ZenohMessage::make_data( +// key, +// payload, +// channel, +// congestion_control, +// data_info, +// routing_context, +// reply_context, +// ); + +// // The last push should block since there shouldn't any more batches +// // available for serialization. +// let num_msg = 1 + CONFIG.queue_size[0]; +// for i in 0..num_msg { +// println!( +// "Pipeline Blocking [>>>]: ({id}) Scheduling message #{i} with payload size of {payload_size} bytes" +// ); +// queue.push_zenoh_message(message.clone()); +// let c = counter.fetch_add(1, Ordering::AcqRel); +// println!( +// "Pipeline Blocking [>>>]: ({}) Scheduled message #{} (tot {}) with payload size of {} bytes", +// id, i, c + 1, +// payload_size +// ); +// } +// } + +// // Pipeline +// let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); +// let conduits = vec![tct]; +// let (producer, mut consumer) = +// TransmissionPipeline::make(TransmissionPipelineConf::default(), conduits.as_slice()); + +// let counter = Arc::new(AtomicUsize::new(0)); + +// let c_producer = producer.clone(); +// let c_counter = counter.clone(); +// let h1 = task::spawn_blocking(move || { +// schedule(c_producer, c_counter, 1); +// }); + +// let c_counter = counter.clone(); +// let h2 = task::spawn_blocking(move || { +// schedule(producer, c_counter, 2); +// }); + +// task::block_on(async { +// // Wait to have sent enough messages and to have blocked +// println!( +// "Pipeline Blocking [---]: waiting to have {} messages being scheduled", +// CONFIG.queue_size[Priority::MAX as usize] +// ); +// let check = async { +// while counter.load(Ordering::Acquire) < CONFIG.queue_size[Priority::MAX as usize] { +// task::sleep(SLEEP).await; +// } +// }; +// check.timeout(TIMEOUT).await.unwrap(); + +// // Disable and drain the queue +// task::spawn_blocking(move || { +// println!("Pipeline Blocking [---]: draining the queue"); +// let _ = consumer.drain(); +// }) +// .timeout(TIMEOUT) +// .await +// .unwrap(); + +// // Make sure that the tasks scheduling have been unblocked +// println!("Pipeline Blocking [---]: waiting for schedule (1) to be unblocked"); +// h1.timeout(TIMEOUT).await.unwrap(); +// println!("Pipeline Blocking [---]: waiting for schedule (2) to be unblocked"); +// h2.timeout(TIMEOUT).await.unwrap(); +// }); +// } + +// #[test] +// #[ignore] +// fn tx_pipeline_thr() { +// // Queue +// let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); +// let conduits = vec![tct]; +// let (producer, mut consumer) = TransmissionPipeline::make(CONFIG, conduits.as_slice()); +// let count = Arc::new(AtomicUsize::new(0)); +// let size = Arc::new(AtomicUsize::new(0)); + +// let c_size = size.clone(); +// task::spawn(async move { +// loop { +// let payload_sizes: [usize; 16] = [ +// 8, 16, 32, 64, 128, 256, 512, 1_024, 2_048, 4_096, 8_192, 16_384, 32_768, +// 65_536, 262_144, 1_048_576, +// ]; +// for size in payload_sizes.iter() { +// c_size.store(*size, Ordering::Release); + +// // Send reliable messages +// let key = "pipeline/thr".into(); +// let payload = ZBuf::from(vec![0_u8; *size]); +// let channel = Channel { +// priority: Priority::Control, +// reliability: Reliability::Reliable, +// }; +// let congestion_control = CongestionControl::Block; +// let data_info = None; +// let routing_context = None; +// let reply_context = None; + +// let message = ZenohMessage::make_data( +// key, +// payload, +// channel, +// congestion_control, +// data_info, +// routing_context, +// reply_context, +// ); + +// let duration = Duration::from_millis(5_500); +// let start = Instant::now(); +// while start.elapsed() < duration { +// producer.push_zenoh_message(message.clone()); +// } +// } +// } +// }); + +// let c_count = count.clone(); +// task::spawn(async move { +// loop { +// let (batch, priority) = consumer.pull().await.unwrap(); +// c_count.fetch_add(batch.len() as usize, Ordering::AcqRel); +// consumer.refill(batch, priority); +// } +// }); + +// task::block_on(async { +// let mut prev_size: usize = usize::MAX; +// loop { +// let received = count.swap(0, Ordering::AcqRel); +// let current: usize = size.load(Ordering::Acquire); +// if current == prev_size { +// let thr = (8.0 * received as f64) / 1_000_000_000.0; +// println!("{} bytes: {:.6} Gbps", current, 2.0 * thr); +// } +// prev_size = current; +// task::sleep(Duration::from_millis(500)).await; +// } +// }); +// } +// } diff --git a/io/zenoh-transport/src/lib.rs b/io/zenoh-transport/src/lib.rs index b8efd62c6c..0e060d6f27 100644 --- a/io/zenoh-transport/src/lib.rs +++ b/io/zenoh-transport/src/lib.rs @@ -32,7 +32,7 @@ use std::sync::Arc; pub use unicast::*; use zenoh_link::Link; use zenoh_protocol::core::{WhatAmI, ZenohId}; -use zenoh_protocol::zenoh::ZenohMessage; +use zenoh_protocol::network::NetworkMessage; use zenoh_result::ZResult; /*************************************/ @@ -75,7 +75,7 @@ pub struct TransportPeer { } pub trait TransportPeerEventHandler: Send + Sync { - fn handle_message(&self, msg: ZenohMessage) -> ZResult<()>; + fn handle_message(&self, msg: NetworkMessage) -> ZResult<()>; fn new_link(&self, src: Link); fn del_link(&self, link: Link); fn closing(&self); @@ -88,7 +88,7 @@ pub trait TransportPeerEventHandler: Send + Sync { pub struct DummyTransportPeerEventHandler; impl TransportPeerEventHandler for DummyTransportPeerEventHandler { - fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { + fn handle_message(&self, _message: NetworkMessage) -> ZResult<()> { Ok(()) } diff --git a/io/zenoh-transport/src/primitives/demux.rs b/io/zenoh-transport/src/primitives/demux.rs index 942b8c13d8..260fffa11d 100644 --- a/io/zenoh-transport/src/primitives/demux.rs +++ b/io/zenoh-transport/src/primitives/demux.rs @@ -15,10 +15,8 @@ use super::Primitives; use crate::TransportPeerEventHandler; use std::any::Any; use zenoh_link::Link; -use zenoh_protocol::zenoh::{ - Data, Declaration, Declare, LinkStateList, Pull, Query, Unit, ZenohBody, ZenohMessage, -}; -use zenoh_result::{bail, ZResult}; +use zenoh_protocol::network::{NetworkBody, NetworkMessage}; +use zenoh_result::ZResult; pub struct DeMux { primitives: P, @@ -31,111 +29,14 @@ impl DeMux

{ } impl TransportPeerEventHandler for DeMux

{ - fn handle_message(&self, msg: ZenohMessage) -> ZResult<()> { + fn handle_message(&self, msg: NetworkMessage) -> ZResult<()> { match msg.body { - ZenohBody::Declare(Declare { declarations, .. }) => { - for declaration in declarations { - match declaration { - Declaration::Resource(r) => { - self.primitives.decl_resource(r.expr_id, &r.key); - } - Declaration::Publisher(p) => { - self.primitives.decl_publisher(&p.key, msg.routing_context); - } - Declaration::Subscriber(s) => { - self.primitives - .decl_subscriber(&s.key, &s.info, msg.routing_context); - } - Declaration::Queryable(q) => { - self.primitives - .decl_queryable(&q.key, &q.info, msg.routing_context); - } - Declaration::ForgetResource(fr) => { - self.primitives.forget_resource(fr.expr_id); - } - Declaration::ForgetPublisher(fp) => { - self.primitives - .forget_publisher(&fp.key, msg.routing_context); - } - Declaration::ForgetSubscriber(fs) => { - self.primitives - .forget_subscriber(&fs.key, msg.routing_context); - } - Declaration::ForgetQueryable(q) => { - self.primitives - .forget_queryable(&q.key, msg.routing_context); - } - } - } - } - - ZenohBody::Data(Data { - key, - data_info, - payload, - congestion_control, - reply_context, - }) => match reply_context { - None => { - self.primitives.send_data( - &key, - payload, - msg.channel, - congestion_control, - data_info, - msg.routing_context, - ); - } - Some(rep) => match rep.replier { - Some(replier) => { - self.primitives - .send_reply_data(rep.qid, replier.id, key, data_info, payload); - } - None => { - bail!("ReplyData with no replier_id") - } - }, - }, - - ZenohBody::Unit(Unit { reply_context, .. }) => { - if let Some(rep) = reply_context { - if rep.is_final() { - self.primitives.send_reply_final(rep.qid); - } - } - } - - ZenohBody::Query(Query { - key, - parameters, - qid, - target, - consolidation, - body, - .. - }) => { - self.primitives.send_query( - &key, - ¶meters, - qid, - target.unwrap_or_default(), - consolidation, - body, - msg.routing_context, - ); - } - - ZenohBody::Pull(Pull { - key, - pull_id, - max_samples, - is_final, - }) => { - self.primitives - .send_pull(is_final, &key, pull_id, &max_samples); - } - - ZenohBody::LinkStateList(LinkStateList { .. }) => {} + NetworkBody::Declare(m) => self.primitives.send_declare(m), + NetworkBody::Push(m) => self.primitives.send_push(m), + NetworkBody::Request(m) => self.primitives.send_request(m), + NetworkBody::Response(m) => self.primitives.send_response(m), + NetworkBody::ResponseFinal(m) => self.primitives.send_response_final(m), + NetworkBody::OAM(_m) => (), } Ok(()) diff --git a/io/zenoh-transport/src/primitives/mod.rs b/io/zenoh-transport/src/primitives/mod.rs index 4206016b9e..b79682790f 100644 --- a/io/zenoh-transport/src/primitives/mod.rs +++ b/io/zenoh-transport/src/primitives/mod.rs @@ -16,78 +16,18 @@ mod mux; pub use demux::*; pub use mux::*; -use zenoh_buffers::ZBuf; -use zenoh_protocol::{ - core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, - zenoh::{ - ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, - RoutingContext, SubInfo, - }, -}; +use zenoh_protocol::network::{Declare, Push, Request, Response, ResponseFinal}; pub trait Primitives: Send + Sync { - fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr); - fn forget_resource(&self, expr_id: ExprId); + fn send_declare(&self, msg: Declare); - fn decl_publisher(&self, key_expr: &WireExpr, routing_context: Option); - fn forget_publisher(&self, key_expr: &WireExpr, routing_context: Option); + fn send_push(&self, msg: Push); - fn decl_subscriber( - &self, - key_expr: &WireExpr, - sub_info: &SubInfo, - routing_context: Option, - ); - fn forget_subscriber(&self, key_expr: &WireExpr, routing_context: Option); + fn send_request(&self, msg: Request); - fn decl_queryable( - &self, - key_expr: &WireExpr, - qabl_info: &QueryableInfo, - routing_context: Option, - ); - fn forget_queryable(&self, key_expr: &WireExpr, routing_context: Option); + fn send_response(&self, msg: Response); - fn send_data( - &self, - key_expr: &WireExpr, - payload: ZBuf, - channel: Channel, - cogestion_control: CongestionControl, - data_info: Option, - routing_context: Option, - ); - - #[allow(clippy::too_many_arguments)] - fn send_query( - &self, - key_expr: &WireExpr, - parameters: &str, - qid: QueryId, - target: QueryTarget, - consolidation: ConsolidationMode, - body: Option, - routing_context: Option, - ); - - fn send_reply_data( - &self, - qid: QueryId, - replier_id: ZenohId, - key_expr: WireExpr, - info: Option, - payload: ZBuf, - ); - - fn send_reply_final(&self, qid: QueryId); - - fn send_pull( - &self, - is_final: bool, - key_expr: &WireExpr, - pull_id: PullId, - max_samples: &Option, - ); + fn send_response_final(&self, msg: ResponseFinal); fn send_close(&self); } @@ -102,69 +42,15 @@ impl DummyPrimitives { } impl Primitives for DummyPrimitives { - fn decl_resource(&self, _expr_id: ExprId, _key_expr: &WireExpr) {} - fn forget_resource(&self, _expr_id: ExprId) {} + fn send_declare(&self, _msg: Declare) {} - fn decl_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} - fn forget_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} + fn send_push(&self, _msg: Push) {} - fn decl_subscriber( - &self, - _key_expr: &WireExpr, - _sub_info: &SubInfo, - _routing_context: Option, - ) { - } - fn forget_subscriber(&self, _key_expr: &WireExpr, _routing_context: Option) {} + fn send_request(&self, _msg: Request) {} - fn decl_queryable( - &self, - _key_expr: &WireExpr, - _qable_info: &QueryableInfo, - _routing_context: Option, - ) { - } - fn forget_queryable(&self, _key_expr: &WireExpr, _routing_context: Option) {} + fn send_response(&self, _msg: Response) {} - fn send_data( - &self, - _key_expr: &WireExpr, - _payload: ZBuf, - _channel: Channel, - _cogestion_control: CongestionControl, - _info: Option, - _routing_context: Option, - ) { - } - fn send_query( - &self, - _key_expr: &WireExpr, - _parameters: &str, - _qid: QueryId, - _target: QueryTarget, - _consolidation: ConsolidationMode, - _body: Option, - _routing_context: Option, - ) { - } - fn send_reply_data( - &self, - _qid: QueryId, - _replier_id: ZenohId, - _key_expr: WireExpr, - _info: Option, - _payload: ZBuf, - ) { - } - fn send_reply_final(&self, _qid: QueryId) {} - fn send_pull( - &self, - _is_final: bool, - _key_expr: &WireExpr, - _pull_id: PullId, - _max_samples: &Option, - ) { - } + fn send_response_final(&self, _msg: ResponseFinal) {} fn send_close(&self) {} } diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index e9823f2ffb..843aff04e1 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -13,15 +13,8 @@ // use super::super::TransportUnicast; use super::Primitives; -use zenoh_buffers::ZBuf; -use zenoh_protocol::{ - core::{Channel, CongestionControl, ExprId, WireExpr, ZenohId}, - zenoh::{ - zmsg, ConsolidationMode, DataInfo, Declaration, ForgetPublisher, ForgetQueryable, - ForgetResource, ForgetSubscriber, Publisher, PullId, QueryBody, QueryId, QueryTarget, - Queryable, QueryableInfo, ReplierInfo, ReplyContext, Resource, RoutingContext, SubInfo, - Subscriber, ZenohMessage, - }, +use zenoh_protocol::network::{ + Declare, NetworkBody, NetworkMessage, Push, Request, Response, ResponseFinal, }; pub struct Mux { @@ -35,183 +28,44 @@ impl Mux { } impl Primitives for Mux { - fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { - let d = Declaration::Resource(Resource { - expr_id, - key: key_expr.to_owned(), + fn send_declare(&self, msg: Declare) { + let _ = self.handler.handle_message(NetworkMessage { + body: NetworkBody::Declare(msg), + #[cfg(feature = "stats")] + size: None, }); - let decls = vec![d]; - let _ = self - .handler - .handle_message(ZenohMessage::make_declare(decls, None)); } - fn forget_resource(&self, expr_id: ExprId) { - let d = Declaration::ForgetResource(ForgetResource { expr_id }); - let decls = vec![d]; - let _ = self - .handler - .handle_message(ZenohMessage::make_declare(decls, None)); - } - - fn decl_subscriber( - &self, - key_expr: &WireExpr, - sub_info: &SubInfo, - routing_context: Option, - ) { - let d = Declaration::Subscriber(Subscriber { - key: key_expr.to_owned(), - info: sub_info.clone(), - }); - let decls = vec![d]; - let _ = self - .handler - .handle_message(ZenohMessage::make_declare(decls, routing_context)); - } - - fn forget_subscriber(&self, key_expr: &WireExpr, routing_context: Option) { - let d = Declaration::ForgetSubscriber(ForgetSubscriber { - key: key_expr.to_owned(), + fn send_push(&self, msg: Push) { + let _ = self.handler.handle_message(NetworkMessage { + body: NetworkBody::Push(msg), + #[cfg(feature = "stats")] + size: None, }); - let decls = vec![d]; - let _ = self - .handler - .handle_message(ZenohMessage::make_declare(decls, routing_context)); } - fn decl_publisher(&self, key_expr: &WireExpr, routing_context: Option) { - let d = Declaration::Publisher(Publisher { - key: key_expr.to_owned(), + fn send_request(&self, msg: Request) { + let _ = self.handler.handle_message(NetworkMessage { + body: NetworkBody::Request(msg), + #[cfg(feature = "stats")] + size: None, }); - let decls = vec![d]; - let _ = self - .handler - .handle_message(ZenohMessage::make_declare(decls, routing_context)); } - fn forget_publisher(&self, key_expr: &WireExpr, routing_context: Option) { - let d = Declaration::ForgetPublisher(ForgetPublisher { - key: key_expr.to_owned(), + fn send_response(&self, msg: Response) { + let _ = self.handler.handle_message(NetworkMessage { + body: NetworkBody::Response(msg), + #[cfg(feature = "stats")] + size: None, }); - let decls = vec![d]; - let _ = self - .handler - .handle_message(ZenohMessage::make_declare(decls, routing_context)); } - fn decl_queryable( - &self, - key_expr: &WireExpr, - qabl_info: &QueryableInfo, - routing_context: Option, - ) { - let d = Declaration::Queryable(Queryable { - key: key_expr.to_owned(), - info: qabl_info.clone(), + fn send_response_final(&self, msg: ResponseFinal) { + let _ = self.handler.handle_message(NetworkMessage { + body: NetworkBody::ResponseFinal(msg), + #[cfg(feature = "stats")] + size: None, }); - let decls = vec![d]; - let _ = self - .handler - .handle_message(ZenohMessage::make_declare(decls, routing_context)); - } - - fn forget_queryable(&self, key_expr: &WireExpr, routing_context: Option) { - let d = Declaration::ForgetQueryable(ForgetQueryable { - key: key_expr.to_owned(), - }); - let decls = vec![d]; - let _ = self - .handler - .handle_message(ZenohMessage::make_declare(decls, routing_context)); - } - - fn send_data( - &self, - key_expr: &WireExpr, - payload: ZBuf, - channel: Channel, - cogestion_control: CongestionControl, - data_info: Option, - routing_context: Option, - ) { - let _ = self.handler.handle_message(ZenohMessage::make_data( - key_expr.to_owned(), - payload, - channel, - cogestion_control, - data_info, - routing_context, - None, - )); - } - - fn send_query( - &self, - key_expr: &WireExpr, - parameters: &str, - qid: QueryId, - target: QueryTarget, - consolidation: ConsolidationMode, - body: Option, - routing_context: Option, - ) { - let target_opt = if target == QueryTarget::default() { - None - } else { - Some(target) - }; - let _ = self.handler.handle_message(ZenohMessage::make_query( - key_expr.to_owned(), - parameters.to_owned(), - qid, - target_opt, - consolidation, - body, - routing_context, - )); - } - - fn send_reply_data( - &self, - qid: QueryId, - replier_id: ZenohId, - key_expr: WireExpr, - data_info: Option, - payload: ZBuf, - ) { - let _ = self.handler.handle_message(ZenohMessage::make_data( - key_expr.to_owned(), - payload, - zmsg::default_channel::REPLY, - zmsg::default_congestion_control::REPLY, - data_info, - None, - Some(ReplyContext::new(qid, Some(ReplierInfo { id: replier_id }))), - )); - } - - fn send_reply_final(&self, qid: QueryId) { - let _ = self.handler.handle_message(ZenohMessage::make_unit( - zmsg::default_channel::REPLY, - zmsg::default_congestion_control::REPLY, - Some(ReplyContext::new(qid, None)), - )); - } - - fn send_pull( - &self, - is_final: bool, - key_expr: &WireExpr, - pull_id: PullId, - max_samples: &Option, - ) { - let _ = self.handler.handle_message(ZenohMessage::make_pull( - is_final, - key_expr.to_owned(), - pull_id, - *max_samples, - )); } fn send_close(&self) { diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 64b4b6c51b..71299bdb51 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -32,10 +32,10 @@ use std::sync::{Arc, Weak}; use transport::TransportUnicastInner; use zenoh_core::zcondfeat; use zenoh_link::Link; +use zenoh_protocol::network::NetworkMessage; use zenoh_protocol::{ core::{Bits, WhatAmI, ZenohId}, transport::{close, TransportSn}, - zenoh::ZenohMessage, }; use zenoh_result::{zerror, ZResult}; @@ -174,7 +174,7 @@ impl TransportUnicast { } #[inline(always)] - pub fn schedule(&self, message: ZenohMessage) -> ZResult<()> { + pub fn schedule(&self, message: NetworkMessage) -> ZResult<()> { let transport = self.get_inner()?; transport.schedule(message); Ok(()) @@ -202,7 +202,7 @@ impl TransportUnicast { } #[inline(always)] - pub fn handle_message(&self, message: ZenohMessage) -> ZResult<()> { + pub fn handle_message(&self, message: NetworkMessage) -> ZResult<()> { self.schedule(message) } diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index 21284382ab..f8a950e62e 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -28,8 +28,8 @@ use zenoh_link::LinkUnicast; use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::{ core::{Priority, Reliability}, + network::NetworkMessage, transport::{Close, Fragment, Frame, KeepAlive, TransportBody, TransportMessage, TransportSn}, - zenoh::ZenohMessage, }; use zenoh_result::{bail, zerror, ZResult}; @@ -40,7 +40,7 @@ impl TransportUnicastInner { fn trigger_callback( &self, #[allow(unused_mut)] // shared-memory feature requires mut - mut msg: ZenohMessage, + mut msg: NetworkMessage, ) -> ZResult<()> { #[cfg(feature = "stats")] { diff --git a/io/zenoh-transport/src/unicast/tx.rs b/io/zenoh-transport/src/unicast/tx.rs index 38358bcfa4..590fc8885f 100644 --- a/io/zenoh-transport/src/unicast/tx.rs +++ b/io/zenoh-transport/src/unicast/tx.rs @@ -15,12 +15,12 @@ use super::transport::TransportUnicastInner; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; use zenoh_core::zread; +use zenoh_protocol::network::NetworkMessage; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; -use zenoh_protocol::zenoh::ZenohMessage; impl TransportUnicastInner { - fn schedule_on_link(&self, msg: ZenohMessage) -> bool { + fn schedule_on_link(&self, msg: NetworkMessage) -> bool { macro_rules! zpush { ($guard:expr, $pipeline:expr, $msg:expr) => { // Drop the guard before the push_zenoh_message since @@ -29,7 +29,7 @@ impl TransportUnicastInner { let pl = $pipeline.clone(); drop($guard); log::trace!("Scheduled: {:?}", $msg); - return pl.push_zenoh_message($msg); + return pl.push_network_message($msg); }; } @@ -66,7 +66,7 @@ impl TransportUnicastInner { #[allow(unused_mut)] // When feature "shared-memory" is not enabled #[allow(clippy::let_and_return)] // When feature "stats" is not enabled #[inline(always)] - pub(crate) fn schedule(&self, mut msg: ZenohMessage) -> bool { + pub(crate) fn schedule(&self, mut msg: NetworkMessage) -> bool { #[cfg(feature = "shared-memory")] { let res = if self.config.is_shm { diff --git a/io/zenoh-transport/tests/endpoints.rs b/io/zenoh-transport/tests/endpoints.rs index 5857a44bd9..9ed9433b35 100644 --- a/io/zenoh-transport/tests/endpoints.rs +++ b/io/zenoh-transport/tests/endpoints.rs @@ -17,7 +17,7 @@ use zenoh_core::zasync_executor_init; use zenoh_link::{EndPoint, Link}; use zenoh_protocol::{ core::{WhatAmI, ZenohId}, - zenoh::ZenohMessage, + network::NetworkMessage, }; use zenoh_result::ZResult; use zenoh_transport::{ @@ -56,7 +56,7 @@ impl TransportEventHandler for SH { pub struct SC; impl TransportPeerEventHandler for SC { - fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { + fn handle_message(&self, _message: NetworkMessage) -> ZResult<()> { Ok(()) } fn new_link(&self, _link: Link) {} diff --git a/io/zenoh-transport/tests/transport_whitelist.rs b/io/zenoh-transport/tests/transport_whitelist.rs index 18b38a4424..a01224cd3a 100644 --- a/io/zenoh-transport/tests/transport_whitelist.rs +++ b/io/zenoh-transport/tests/transport_whitelist.rs @@ -17,7 +17,7 @@ use zenoh_core::zasync_executor_init; use zenoh_link::Link; use zenoh_protocol::{ core::{EndPoint, ZenohId}, - zenoh::ZenohMessage, + network::NetworkMessage, }; use zenoh_result::ZResult; use zenoh_transport::{ @@ -51,7 +51,7 @@ impl TransportEventHandler for SHRouter { pub struct SCRouter; impl TransportPeerEventHandler for SCRouter { - fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { + fn handle_message(&self, _message: NetworkMessage) -> ZResult<()> { Ok(()) } diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index 8e3556fb24..02037a9238 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -17,7 +17,7 @@ use zenoh_core::{zasync_executor_init, zasyncwrite}; use zenoh_link::Link; use zenoh_protocol::{ core::{EndPoint, WhatAmI, ZenohId}, - zenoh::ZenohMessage, + network::NetworkMessage, }; use zenoh_result::ZResult; use zenoh_transport::unicast::establishment::ext::auth::Auth; @@ -63,7 +63,7 @@ impl MHRouterAuthenticator { } impl TransportPeerEventHandler for MHRouterAuthenticator { - fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { + fn handle_message(&self, _msg: NetworkMessage) -> ZResult<()> { Ok(()) } fn new_link(&self, _link: Link) {} diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index f910b436e0..20784cdda5 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -11,398 +11,398 @@ // Contributors: // ZettaScale Zenoh Team, // -use async_std::prelude::FutureExt; -use async_std::sync::Barrier; -use async_std::task; -use std::any::Any; -use std::convert::TryFrom; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; -use std::time::Duration; -use zenoh_buffers::ZBuf; -use zenoh_core::zasync_executor_init; -use zenoh_link::Link; -use zenoh_protocol::{ - core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, - zenoh::ZenohMessage, -}; -use zenoh_result::ZResult; -use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, - TransportUnicast, -}; - -const MSG_COUNT: usize = 1_000; -const MSG_SIZE: usize = 1_024; -const TIMEOUT: Duration = Duration::from_secs(60); -const SLEEP: Duration = Duration::from_millis(100); - -macro_rules! ztimeout { - ($f:expr) => { - $f.timeout(TIMEOUT).await.unwrap() - }; -} - -// Transport Handler for the router -struct SHPeer { - count: Arc, -} - -impl SHPeer { - fn new() -> Self { - Self { - count: Arc::new(AtomicUsize::new(0)), - } - } - - fn get_count(&self) -> usize { - self.count.load(Ordering::SeqCst) - } -} - -impl TransportEventHandler for SHPeer { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - let mh = Arc::new(MHPeer::new(self.count.clone())); - Ok(mh) - } -} - -struct MHPeer { - count: Arc, -} - -impl MHPeer { - fn new(count: Arc) -> Self { - Self { count } - } -} - -impl TransportPeerEventHandler for MHPeer { - fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { - self.count.fetch_add(1, Ordering::AcqRel); - Ok(()) - } - - fn new_link(&self, _link: Link) {} - fn del_link(&self, _link: Link) {} - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } -} - -async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec) { - /* [Peers] */ - let peer_id01 = ZenohId::try_from([2]).unwrap(); - let peer_id02 = ZenohId::try_from([3]).unwrap(); - - // Create the peer01 transport manager - let peer_sh01 = Arc::new(SHPeer::new()); - let unicast01 = TransportManager::config_unicast().max_links(endpoint02.len()); - let peer01_manager = TransportManager::builder() - .whatami(WhatAmI::Peer) - .zid(peer_id01) - .unicast(unicast01) - .build(peer_sh01.clone()) - .unwrap(); - - // Create the peer01 transport manager - let peer_sh02 = Arc::new(SHPeer::new()); - let unicast02 = TransportManager::config_unicast().max_links(endpoint01.len()); - let peer02_manager = TransportManager::builder() - .whatami(WhatAmI::Peer) - .zid(peer_id02) - .unicast(unicast02) - .build(peer_sh02.clone()) - .unwrap(); - - // Barrier to synchronize the two tasks - let barrier_peer = Arc::new(Barrier::new(2)); - let barrier_open_wait = Arc::new(Barrier::new(endpoint01.len() + endpoint02.len())); - let barrier_open_done = Arc::new(Barrier::new(endpoint01.len() + endpoint02.len() + 2)); - - // Peer01 - let c_barp = barrier_peer.clone(); - let c_barow = barrier_open_wait.clone(); - let c_barod = barrier_open_done.clone(); - let c_zid02 = peer_id02; - let c_end01 = endpoint01.clone(); - let c_end02 = endpoint02.clone(); - let peer01_task = task::spawn(async move { - // Add the endpoints on the first peer - for e in c_end01.iter() { - let res = ztimeout!(peer01_manager.add_listener(e.clone())); - println!("[Transport Peer 01a] => Adding endpoint {e:?}: {res:?}"); - assert!(res.is_ok()); - } - let locs = peer01_manager.get_listeners(); - println!("[Transport Peer 01b] => Getting endpoints: {c_end01:?} {locs:?}"); - assert_eq!(c_end01.len(), locs.len()); - - // Open the transport with the second peer - for e in c_end02.iter() { - let cc_barow = c_barow.clone(); - let cc_barod = c_barod.clone(); - let c_p01m = peer01_manager.clone(); - let c_end = e.clone(); - task::spawn(async move { - println!("[Transport Peer 01c] => Waiting for opening transport"); - // Syncrhonize before opening the transports - ztimeout!(cc_barow.wait()); - let res = ztimeout!(c_p01m.open_transport(c_end.clone())); - println!("[Transport Peer 01d] => Opening transport with {c_end:?}: {res:?}"); - assert!(res.is_ok()); - - // Syncrhonize after opening the transports - ztimeout!(cc_barod.wait()); - }); - } - - // Syncrhonize after opening the transports - ztimeout!(c_barod.wait()); - println!("[Transport Peer 01e] => Waiting... OK"); - - // Verify that the transport has been correctly open - assert_eq!(peer01_manager.get_transports().len(), 1); - let s02 = peer01_manager.get_transport(&c_zid02).unwrap(); - assert_eq!( - s02.get_links().unwrap().len(), - c_end01.len() + c_end02.len() - ); - - // Create the message to send - let key = "test02".into(); - let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); - let channel = Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }; - let congestion_control = CongestionControl::Block; - let data_info = None; - let routing_context = None; - let reply_context = None; - - let message = ZenohMessage::make_data( - key, - payload, - channel, - congestion_control, - data_info, - routing_context, - reply_context, - ); - - // Synchronize wit the peer - ztimeout!(c_barp.wait()); - println!("[Transport Peer 01f] => Waiting... OK"); - - for i in 0..MSG_COUNT { - println!("[Transport Peer 01g] Scheduling message {}", i); - s02.schedule(message.clone()).unwrap(); - } - println!("[Transport Peer 01g] => Scheduling OK"); - - // Wait for the messages to arrive to the other side - ztimeout!(async { - while peer_sh02.get_count() != MSG_COUNT { - task::sleep(SLEEP).await; - } - }); - - // Synchronize wit the peer - ztimeout!(c_barp.wait()); - - println!("[Transport Peer 01h] => Closing {s02:?}..."); - let res = ztimeout!(s02.close()); - println!("[Transport Peer 01l] => Closing {s02:?}: {res:?}"); - assert!(res.is_ok()); - - // Close the transport - ztimeout!(peer01_manager.close()); - }); - - // Peer02 - let c_barp = barrier_peer; - let c_barow = barrier_open_wait.clone(); - let c_barod = barrier_open_done.clone(); - let c_zid01 = peer_id01; - let c_end01 = endpoint01.clone(); - let c_end02 = endpoint02.clone(); - let peer02_task = task::spawn(async move { - // Add the endpoints on the first peer - for e in c_end02.iter() { - let res = ztimeout!(peer02_manager.add_listener(e.clone())); - println!("[Transport Peer 02a] => Adding endpoint {e:?}: {res:?}"); - assert!(res.is_ok()); - } - let locs = peer02_manager.get_listeners(); - println!("[Transport Peer 02b] => Getting endpoints: {c_end02:?} {locs:?}"); - assert_eq!(c_end02.len(), locs.len()); - - // Open the transport with the first peer - for e in c_end01.iter() { - let cc_barow = c_barow.clone(); - let cc_barod = c_barod.clone(); - let c_p02m = peer02_manager.clone(); - let c_end = e.clone(); - task::spawn(async move { - println!("[Transport Peer 02c] => Waiting for opening transport"); - // Syncrhonize before opening the transports - ztimeout!(cc_barow.wait()); - - let res = ztimeout!(c_p02m.open_transport(c_end.clone())); - println!("[Transport Peer 02d] => Opening transport with {c_end:?}: {res:?}"); - assert!(res.is_ok()); - - // Syncrhonize after opening the transports - ztimeout!(cc_barod.wait()); - }); - } - - // Syncrhonize after opening the transports - ztimeout!(c_barod.wait()); - - // Verify that the transport has been correctly open - println!( - "[Transport Peer 02e] => Transports: {:?}", - peer02_manager.get_transports() - ); - assert_eq!(peer02_manager.get_transports().len(), 1); - let s01 = peer02_manager.get_transport(&c_zid01).unwrap(); - assert_eq!( - s01.get_links().unwrap().len(), - c_end01.len() + c_end02.len() - ); - - // Create the message to send - let key = "test02".into(); - let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); - let channel = Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }; - let congestion_control = CongestionControl::Block; - let data_info = None; - let routing_context = None; - let reply_context = None; - - let message = ZenohMessage::make_data( - key, - payload, - channel, - congestion_control, - data_info, - routing_context, - reply_context, - ); - - // Synchronize wit the peer - ztimeout!(c_barp.wait()); - println!("[Transport Peer 02f] => Waiting... OK"); - - for i in 0..MSG_COUNT { - println!("[Transport Peer 02g] Scheduling message {}", i); - s01.schedule(message.clone()).unwrap(); - } - println!("[Transport Peer 02g] => Scheduling OK"); - - // Wait for the messages to arrive to the other side - ztimeout!(async { - while peer_sh01.get_count() != MSG_COUNT { - task::sleep(SLEEP).await; - } - }); - - // Synchronize wit the peer - ztimeout!(c_barp.wait()); - - println!("[Transport Peer 02h] => Closing {s01:?}..."); - let res = ztimeout!(s01.close()); - println!("[Transport Peer 02l] => Closing {s01:?}: {res:?}"); - assert!(res.is_ok()); - - // Close the transport - ztimeout!(peer02_manager.close()); - }); - - println!("[Transport Current 01] => Starting..."); - peer01_task.join(peer02_task).await; - println!("[Transport Current 02] => ...Stopped"); - - // Wait a little bit - task::sleep(SLEEP).await; -} - -#[cfg(feature = "transport_tcp")] -#[test] -fn transport_tcp_concurrent() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint01: Vec = vec![ - format!("tcp/127.0.0.1:{}", 9000).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9001).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9002).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9003).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9004).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9005).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9006).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9007).parse().unwrap(), - ]; - let endpoint02: Vec = vec![ - format!("tcp/127.0.0.1:{}", 9010).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9011).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9012).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9013).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9014).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9015).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9016).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 9017).parse().unwrap(), - ]; - - task::block_on(async { - transport_concurrent(endpoint01, endpoint02).await; - }); -} - -#[cfg(feature = "transport_ws")] -#[test] -fn transport_ws_concurrent() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint01: Vec = vec![ - format!("ws/127.0.0.1:{}", 9020).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9021).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9022).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9023).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9024).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9025).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9026).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9027).parse().unwrap(), - ]; - let endpoint02: Vec = vec![ - format!("ws/127.0.0.1:{}", 9030).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9031).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9032).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9033).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9034).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9035).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9036).parse().unwrap(), - format!("ws/127.0.0.1:{}", 9037).parse().unwrap(), - ]; - - task::block_on(async { - transport_concurrent(endpoint01, endpoint02).await; - }); -} +// use async_std::prelude::FutureExt; +// use async_std::sync::Barrier; +// use async_std::task; +// use std::any::Any; +// use std::convert::TryFrom; +// use std::sync::atomic::{AtomicUsize, Ordering}; +// use std::sync::Arc; +// use std::time::Duration; +// use zenoh_buffers::ZBuf; +// use zenoh_core::zasync_executor_init; +// use zenoh_link::Link; +// use zenoh_protocol::{ +// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, +// zenoh::ZenohMessage, +// }; +// use zenoh_result::ZResult; +// use zenoh_transport::{ +// TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, +// TransportUnicast, +// }; + +// const MSG_COUNT: usize = 1_000; +// const MSG_SIZE: usize = 1_024; +// const TIMEOUT: Duration = Duration::from_secs(60); +// const SLEEP: Duration = Duration::from_millis(100); + +// macro_rules! ztimeout { +// ($f:expr) => { +// $f.timeout(TIMEOUT).await.unwrap() +// }; +// } + +// // Transport Handler for the router +// struct SHPeer { +// count: Arc, +// } + +// impl SHPeer { +// fn new() -> Self { +// Self { +// count: Arc::new(AtomicUsize::new(0)), +// } +// } + +// fn get_count(&self) -> usize { +// self.count.load(Ordering::SeqCst) +// } +// } + +// impl TransportEventHandler for SHPeer { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// let mh = Arc::new(MHPeer::new(self.count.clone())); +// Ok(mh) +// } +// } + +// struct MHPeer { +// count: Arc, +// } + +// impl MHPeer { +// fn new(count: Arc) -> Self { +// Self { count } +// } +// } + +// impl TransportPeerEventHandler for MHPeer { +// fn handle_message(&self, _msg: NetworkMessage) -> ZResult<()> { +// self.count.fetch_add(1, Ordering::AcqRel); +// Ok(()) +// } + +// fn new_link(&self, _link: Link) {} +// fn del_link(&self, _link: Link) {} +// fn closing(&self) {} +// fn closed(&self) {} + +// fn as_any(&self) -> &dyn Any { +// self +// } +// } + +// async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec) { +// /* [Peers] */ +// let peer_id01 = ZenohId::try_from([2]).unwrap(); +// let peer_id02 = ZenohId::try_from([3]).unwrap(); + +// // Create the peer01 transport manager +// let peer_sh01 = Arc::new(SHPeer::new()); +// let unicast01 = TransportManager::config_unicast().max_links(endpoint02.len()); +// let peer01_manager = TransportManager::builder() +// .whatami(WhatAmI::Peer) +// .zid(peer_id01) +// .unicast(unicast01) +// .build(peer_sh01.clone()) +// .unwrap(); + +// // Create the peer01 transport manager +// let peer_sh02 = Arc::new(SHPeer::new()); +// let unicast02 = TransportManager::config_unicast().max_links(endpoint01.len()); +// let peer02_manager = TransportManager::builder() +// .whatami(WhatAmI::Peer) +// .zid(peer_id02) +// .unicast(unicast02) +// .build(peer_sh02.clone()) +// .unwrap(); + +// // Barrier to synchronize the two tasks +// let barrier_peer = Arc::new(Barrier::new(2)); +// let barrier_open_wait = Arc::new(Barrier::new(endpoint01.len() + endpoint02.len())); +// let barrier_open_done = Arc::new(Barrier::new(endpoint01.len() + endpoint02.len() + 2)); + +// // Peer01 +// let c_barp = barrier_peer.clone(); +// let c_barow = barrier_open_wait.clone(); +// let c_barod = barrier_open_done.clone(); +// let c_zid02 = peer_id02; +// let c_end01 = endpoint01.clone(); +// let c_end02 = endpoint02.clone(); +// let peer01_task = task::spawn(async move { +// // Add the endpoints on the first peer +// for e in c_end01.iter() { +// let res = ztimeout!(peer01_manager.add_listener(e.clone())); +// println!("[Transport Peer 01a] => Adding endpoint {e:?}: {res:?}"); +// assert!(res.is_ok()); +// } +// let locs = peer01_manager.get_listeners(); +// println!("[Transport Peer 01b] => Getting endpoints: {c_end01:?} {locs:?}"); +// assert_eq!(c_end01.len(), locs.len()); + +// // Open the transport with the second peer +// for e in c_end02.iter() { +// let cc_barow = c_barow.clone(); +// let cc_barod = c_barod.clone(); +// let c_p01m = peer01_manager.clone(); +// let c_end = e.clone(); +// task::spawn(async move { +// println!("[Transport Peer 01c] => Waiting for opening transport"); +// // Syncrhonize before opening the transports +// ztimeout!(cc_barow.wait()); +// let res = ztimeout!(c_p01m.open_transport(c_end.clone())); +// println!("[Transport Peer 01d] => Opening transport with {c_end:?}: {res:?}"); +// assert!(res.is_ok()); + +// // Syncrhonize after opening the transports +// ztimeout!(cc_barod.wait()); +// }); +// } + +// // Syncrhonize after opening the transports +// ztimeout!(c_barod.wait()); +// println!("[Transport Peer 01e] => Waiting... OK"); + +// // Verify that the transport has been correctly open +// assert_eq!(peer01_manager.get_transports().len(), 1); +// let s02 = peer01_manager.get_transport(&c_zid02).unwrap(); +// assert_eq!( +// s02.get_links().unwrap().len(), +// c_end01.len() + c_end02.len() +// ); + +// // Create the message to send +// let key = "test02".into(); +// let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); +// let channel = Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }; +// let congestion_control = CongestionControl::Block; +// let data_info = None; +// let routing_context = None; +// let reply_context = None; + +// let message = ZenohMessage::make_data( +// key, +// payload, +// channel, +// congestion_control, +// data_info, +// routing_context, +// reply_context, +// ); + +// // Synchronize wit the peer +// ztimeout!(c_barp.wait()); +// println!("[Transport Peer 01f] => Waiting... OK"); + +// for i in 0..MSG_COUNT { +// println!("[Transport Peer 01g] Scheduling message {}", i); +// s02.schedule(message.clone()).unwrap(); +// } +// println!("[Transport Peer 01g] => Scheduling OK"); + +// // Wait for the messages to arrive to the other side +// ztimeout!(async { +// while peer_sh02.get_count() != MSG_COUNT { +// task::sleep(SLEEP).await; +// } +// }); + +// // Synchronize wit the peer +// ztimeout!(c_barp.wait()); + +// println!("[Transport Peer 01h] => Closing {s02:?}..."); +// let res = ztimeout!(s02.close()); +// println!("[Transport Peer 01l] => Closing {s02:?}: {res:?}"); +// assert!(res.is_ok()); + +// // Close the transport +// ztimeout!(peer01_manager.close()); +// }); + +// // Peer02 +// let c_barp = barrier_peer; +// let c_barow = barrier_open_wait.clone(); +// let c_barod = barrier_open_done.clone(); +// let c_zid01 = peer_id01; +// let c_end01 = endpoint01.clone(); +// let c_end02 = endpoint02.clone(); +// let peer02_task = task::spawn(async move { +// // Add the endpoints on the first peer +// for e in c_end02.iter() { +// let res = ztimeout!(peer02_manager.add_listener(e.clone())); +// println!("[Transport Peer 02a] => Adding endpoint {e:?}: {res:?}"); +// assert!(res.is_ok()); +// } +// let locs = peer02_manager.get_listeners(); +// println!("[Transport Peer 02b] => Getting endpoints: {c_end02:?} {locs:?}"); +// assert_eq!(c_end02.len(), locs.len()); + +// // Open the transport with the first peer +// for e in c_end01.iter() { +// let cc_barow = c_barow.clone(); +// let cc_barod = c_barod.clone(); +// let c_p02m = peer02_manager.clone(); +// let c_end = e.clone(); +// task::spawn(async move { +// println!("[Transport Peer 02c] => Waiting for opening transport"); +// // Syncrhonize before opening the transports +// ztimeout!(cc_barow.wait()); + +// let res = ztimeout!(c_p02m.open_transport(c_end.clone())); +// println!("[Transport Peer 02d] => Opening transport with {c_end:?}: {res:?}"); +// assert!(res.is_ok()); + +// // Syncrhonize after opening the transports +// ztimeout!(cc_barod.wait()); +// }); +// } + +// // Syncrhonize after opening the transports +// ztimeout!(c_barod.wait()); + +// // Verify that the transport has been correctly open +// println!( +// "[Transport Peer 02e] => Transports: {:?}", +// peer02_manager.get_transports() +// ); +// assert_eq!(peer02_manager.get_transports().len(), 1); +// let s01 = peer02_manager.get_transport(&c_zid01).unwrap(); +// assert_eq!( +// s01.get_links().unwrap().len(), +// c_end01.len() + c_end02.len() +// ); + +// // Create the message to send +// let key = "test02".into(); +// let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); +// let channel = Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }; +// let congestion_control = CongestionControl::Block; +// let data_info = None; +// let routing_context = None; +// let reply_context = None; + +// let message = ZenohMessage::make_data( +// key, +// payload, +// channel, +// congestion_control, +// data_info, +// routing_context, +// reply_context, +// ); + +// // Synchronize wit the peer +// ztimeout!(c_barp.wait()); +// println!("[Transport Peer 02f] => Waiting... OK"); + +// for i in 0..MSG_COUNT { +// println!("[Transport Peer 02g] Scheduling message {}", i); +// s01.schedule(message.clone()).unwrap(); +// } +// println!("[Transport Peer 02g] => Scheduling OK"); + +// // Wait for the messages to arrive to the other side +// ztimeout!(async { +// while peer_sh01.get_count() != MSG_COUNT { +// task::sleep(SLEEP).await; +// } +// }); + +// // Synchronize wit the peer +// ztimeout!(c_barp.wait()); + +// println!("[Transport Peer 02h] => Closing {s01:?}..."); +// let res = ztimeout!(s01.close()); +// println!("[Transport Peer 02l] => Closing {s01:?}: {res:?}"); +// assert!(res.is_ok()); + +// // Close the transport +// ztimeout!(peer02_manager.close()); +// }); + +// println!("[Transport Current 01] => Starting..."); +// peer01_task.join(peer02_task).await; +// println!("[Transport Current 02] => ...Stopped"); + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// #[cfg(feature = "transport_tcp")] +// #[test] +// fn transport_tcp_concurrent() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let endpoint01: Vec = vec![ +// format!("tcp/127.0.0.1:{}", 9000).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9001).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9002).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9003).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9004).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9005).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9006).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9007).parse().unwrap(), +// ]; +// let endpoint02: Vec = vec![ +// format!("tcp/127.0.0.1:{}", 9010).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9011).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9012).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9013).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9014).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9015).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9016).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 9017).parse().unwrap(), +// ]; + +// task::block_on(async { +// transport_concurrent(endpoint01, endpoint02).await; +// }); +// } + +// #[cfg(feature = "transport_ws")] +// #[test] +// fn transport_ws_concurrent() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let endpoint01: Vec = vec![ +// format!("ws/127.0.0.1:{}", 9020).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9021).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9022).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9023).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9024).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9025).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9026).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9027).parse().unwrap(), +// ]; +// let endpoint02: Vec = vec![ +// format!("ws/127.0.0.1:{}", 9030).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9031).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9032).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9033).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9034).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9035).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9036).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 9037).parse().unwrap(), +// ]; + +// task::block_on(async { +// transport_concurrent(endpoint01, endpoint02).await; +// }); +// } diff --git a/io/zenoh-transport/tests/unicast_conduits.rs b/io/zenoh-transport/tests/unicast_conduits.rs index 6ad9f01a9e..35d21dd011 100644 --- a/io/zenoh-transport/tests/unicast_conduits.rs +++ b/io/zenoh-transport/tests/unicast_conduits.rs @@ -11,346 +11,346 @@ // Contributors: // ZettaScale Zenoh Team, // -use async_std::prelude::FutureExt; -use async_std::task; -use std::any::Any; -use std::convert::TryFrom; -use std::fmt::Write as _; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; -use std::time::Duration; -use zenoh_buffers::ZBuf; -use zenoh_core::zasync_executor_init; -use zenoh_link::Link; -use zenoh_protocol::{ - core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, - zenoh::ZenohMessage, -}; -use zenoh_result::ZResult; -use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, - TransportUnicast, -}; - -const TIMEOUT: Duration = Duration::from_secs(60); -const SLEEP: Duration = Duration::from_secs(1); -const SLEEP_COUNT: Duration = Duration::from_millis(10); - -const MSG_COUNT: usize = 100; -const MSG_SIZE_ALL: [usize; 2] = [1_024, 131_072]; - -const PRIORITY_ALL: [Priority; 8] = [ - Priority::Control, - Priority::RealTime, - Priority::InteractiveHigh, - Priority::InteractiveLow, - Priority::DataHigh, - Priority::Data, - Priority::DataLow, - Priority::Background, -]; - -macro_rules! ztimeout { - ($f:expr) => { - $f.timeout(TIMEOUT).await.unwrap() - }; -} - -// Transport Handler for the router -struct SHRouter { - priority: Arc, - count: Arc, -} - -impl SHRouter { - fn new() -> Self { - Self { - priority: Arc::new(AtomicUsize::new(0)), - count: Arc::new(AtomicUsize::new(0)), - } - } - - fn set_priority(&self, priority: Priority) { - self.priority.store(priority as usize, Ordering::Relaxed) - } - - fn reset_count(&self) { - self.count.store(0, Ordering::Relaxed) - } - - fn get_count(&self) -> usize { - self.count.load(Ordering::Relaxed) - } -} - -impl TransportEventHandler for SHRouter { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - let arc = Arc::new(SCRouter::new(self.priority.clone(), self.count.clone())); - Ok(arc) - } -} - -// Transport Callback for the router -pub struct SCRouter { - priority: Arc, - count: Arc, -} - -impl SCRouter { - pub fn new(priority: Arc, count: Arc) -> Self { - Self { priority, count } - } -} - -impl TransportPeerEventHandler for SCRouter { - fn handle_message(&self, message: ZenohMessage) -> ZResult<()> { - assert_eq!( - self.priority.load(Ordering::Relaxed), - message.channel.priority as usize - ); - self.count.fetch_add(1, Ordering::Relaxed); - Ok(()) - } - - fn new_link(&self, _link: Link) {} - fn del_link(&self, _link: Link) {} - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } -} - -// Transport Handler for the client -struct SHClient; - -impl Default for SHClient { - fn default() -> Self { - Self - } -} - -impl TransportEventHandler for SHClient { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - Ok(Arc::new(SCClient::default())) - } -} - -// Transport Callback for the client -pub struct SCClient; - -impl Default for SCClient { - fn default() -> Self { - Self - } -} - -impl TransportPeerEventHandler for SCClient { - fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { - Ok(()) - } - - fn new_link(&self, _link: Link) {} - fn del_link(&self, _link: Link) {} - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } -} - -async fn open_transport( - endpoints: &[EndPoint], -) -> ( - TransportManager, - Arc, - TransportManager, - TransportUnicast, -) { - // Define client and router IDs - let client_id = ZenohId::try_from([1]).unwrap(); - let router_id = ZenohId::try_from([2]).unwrap(); - - // Create the router transport manager - let router_handler = Arc::new(SHRouter::new()); - let router_manager = TransportManager::builder() - .whatami(WhatAmI::Router) - .zid(router_id) - .build(router_handler.clone()) - .unwrap(); - - // Create the client transport manager - let client_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client_id) - .build(Arc::new(SHClient::default())) - .unwrap(); - - // Create the listener on the router - for e in endpoints.iter() { - println!("Add locator: {e}"); - let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); - } - - // Create an empty transport with the client - // Open transport -> This should be accepted - for e in endpoints.iter() { - println!("Opening transport with {e}"); - let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); - } - - let client_transport = client_manager.get_transport(&router_id).unwrap(); - - // Return the handlers - ( - router_manager, - router_handler, - client_manager, - client_transport, - ) -} - -async fn close_transport( - router_manager: TransportManager, - client_manager: TransportManager, - client_transport: TransportUnicast, - endpoints: &[EndPoint], -) { - // Close the client transport - let mut ee = String::new(); - for e in endpoints.iter() { - let _ = write!(ee, "{e} "); - } - println!("Closing transport with {ee}"); - ztimeout!(client_transport.close()).unwrap(); - - ztimeout!(async { - while !router_manager.get_transports().is_empty() { - task::sleep(SLEEP).await; - } - }); - - // Stop the locators on the manager - for e in endpoints.iter() { - println!("Del locator: {e}"); - ztimeout!(router_manager.del_listener(e)).unwrap(); - } - - // Wait a little bit - task::sleep(SLEEP).await; - - ztimeout!(router_manager.close()); - ztimeout!(client_manager.close()); - - // Wait a little bit - task::sleep(SLEEP).await; -} - -async fn single_run( - router_handler: Arc, - client_transport: TransportUnicast, - channel: &[Channel], - msg_size: &[usize], -) { - for ch in channel.iter() { - for ms in msg_size.iter() { - // Reset the counter and set priority on the router - router_handler.reset_count(); - router_handler.set_priority(ch.priority); - - // Create the message to send - let key = "test".into(); - let payload = ZBuf::from(vec![0_u8; *ms]); - let data_info = None; - let routing_context = None; - let reply_context = None; - let message = ZenohMessage::make_data( - key, - payload, - *ch, - CongestionControl::Block, - data_info, - routing_context, - reply_context, - ); - - println!("Sending {MSG_COUNT} messages... {ch:?} {ms}"); - for _ in 0..MSG_COUNT { - client_transport.schedule(message.clone()).unwrap(); - } - - // Wait for the messages to arrive to the other side - ztimeout!(async { - while router_handler.get_count() != MSG_COUNT { - task::sleep(SLEEP_COUNT).await; - } - }); - } - } - - // Wait a little bit - task::sleep(SLEEP).await; -} - -async fn run(endpoints: &[EndPoint], channel: &[Channel], msg_size: &[usize]) { - let (router_manager, router_handler, client_manager, client_transport) = - open_transport(endpoints).await; - single_run( - router_handler.clone(), - client_transport.clone(), - channel, - msg_size, - ) - .await; - close_transport(router_manager, client_manager, client_transport, endpoints).await; -} - -#[cfg(feature = "transport_tcp")] -#[test] -fn conduits_tcp_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - let mut channel = vec![]; - for p in PRIORITY_ALL.iter() { - channel.push(Channel { - priority: *p, - reliability: Reliability::Reliable, - }); - } - // Define the locators - let endpoints: Vec = vec![format!("tcp/127.0.0.1:{}", 10000).parse().unwrap()]; - // Run - task::block_on(run(&endpoints, &channel, &MSG_SIZE_ALL)); -} - -#[cfg(feature = "transport_ws")] -#[test] -fn conduits_ws_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - let mut channel = vec![]; - for p in PRIORITY_ALL.iter() { - channel.push(Channel { - priority: *p, - reliability: Reliability::Reliable, - }); - } - // Define the locators - let endpoints: Vec = vec![format!("ws/127.0.0.1:{}", 10010).parse().unwrap()]; - // Run - task::block_on(run(&endpoints, &channel, &MSG_SIZE_ALL)); -} +// use async_std::prelude::FutureExt; +// use async_std::task; +// use std::any::Any; +// use std::convert::TryFrom; +// use std::fmt::Write as _; +// use std::sync::atomic::{AtomicUsize, Ordering}; +// use std::sync::Arc; +// use std::time::Duration; +// use zenoh_buffers::ZBuf; +// use zenoh_core::zasync_executor_init; +// use zenoh_link::Link; +// use zenoh_protocol::{ +// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, +// zenoh::ZenohMessage, +// }; +// use zenoh_result::ZResult; +// use zenoh_transport::{ +// TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, +// TransportUnicast, +// }; + +// const TIMEOUT: Duration = Duration::from_secs(60); +// const SLEEP: Duration = Duration::from_secs(1); +// const SLEEP_COUNT: Duration = Duration::from_millis(10); + +// const MSG_COUNT: usize = 100; +// const MSG_SIZE_ALL: [usize; 2] = [1_024, 131_072]; + +// const PRIORITY_ALL: [Priority; 8] = [ +// Priority::Control, +// Priority::RealTime, +// Priority::InteractiveHigh, +// Priority::InteractiveLow, +// Priority::DataHigh, +// Priority::Data, +// Priority::DataLow, +// Priority::Background, +// ]; + +// macro_rules! ztimeout { +// ($f:expr) => { +// $f.timeout(TIMEOUT).await.unwrap() +// }; +// } + +// // Transport Handler for the router +// struct SHRouter { +// priority: Arc, +// count: Arc, +// } + +// impl SHRouter { +// fn new() -> Self { +// Self { +// priority: Arc::new(AtomicUsize::new(0)), +// count: Arc::new(AtomicUsize::new(0)), +// } +// } + +// fn set_priority(&self, priority: Priority) { +// self.priority.store(priority as usize, Ordering::Relaxed) +// } + +// fn reset_count(&self) { +// self.count.store(0, Ordering::Relaxed) +// } + +// fn get_count(&self) -> usize { +// self.count.load(Ordering::Relaxed) +// } +// } + +// impl TransportEventHandler for SHRouter { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// let arc = Arc::new(SCRouter::new(self.priority.clone(), self.count.clone())); +// Ok(arc) +// } +// } + +// // Transport Callback for the router +// pub struct SCRouter { +// priority: Arc, +// count: Arc, +// } + +// impl SCRouter { +// pub fn new(priority: Arc, count: Arc) -> Self { +// Self { priority, count } +// } +// } + +// impl TransportPeerEventHandler for SCRouter { +// fn handle_message(&self, message: ZenohMessage) -> ZResult<()> { +// assert_eq!( +// self.priority.load(Ordering::Relaxed), +// message.channel.priority as usize +// ); +// self.count.fetch_add(1, Ordering::Relaxed); +// Ok(()) +// } + +// fn new_link(&self, _link: Link) {} +// fn del_link(&self, _link: Link) {} +// fn closing(&self) {} +// fn closed(&self) {} + +// fn as_any(&self) -> &dyn Any { +// self +// } +// } + +// // Transport Handler for the client +// struct SHClient; + +// impl Default for SHClient { +// fn default() -> Self { +// Self +// } +// } + +// impl TransportEventHandler for SHClient { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// Ok(Arc::new(SCClient::default())) +// } +// } + +// // Transport Callback for the client +// pub struct SCClient; + +// impl Default for SCClient { +// fn default() -> Self { +// Self +// } +// } + +// impl TransportPeerEventHandler for SCClient { +// fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { +// Ok(()) +// } + +// fn new_link(&self, _link: Link) {} +// fn del_link(&self, _link: Link) {} +// fn closing(&self) {} +// fn closed(&self) {} + +// fn as_any(&self) -> &dyn Any { +// self +// } +// } + +// async fn open_transport( +// endpoints: &[EndPoint], +// ) -> ( +// TransportManager, +// Arc, +// TransportManager, +// TransportUnicast, +// ) { +// // Define client and router IDs +// let client_id = ZenohId::try_from([1]).unwrap(); +// let router_id = ZenohId::try_from([2]).unwrap(); + +// // Create the router transport manager +// let router_handler = Arc::new(SHRouter::new()); +// let router_manager = TransportManager::builder() +// .whatami(WhatAmI::Router) +// .zid(router_id) +// .build(router_handler.clone()) +// .unwrap(); + +// // Create the client transport manager +// let client_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client_id) +// .build(Arc::new(SHClient::default())) +// .unwrap(); + +// // Create the listener on the router +// for e in endpoints.iter() { +// println!("Add locator: {e}"); +// let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); +// } + +// // Create an empty transport with the client +// // Open transport -> This should be accepted +// for e in endpoints.iter() { +// println!("Opening transport with {e}"); +// let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); +// } + +// let client_transport = client_manager.get_transport(&router_id).unwrap(); + +// // Return the handlers +// ( +// router_manager, +// router_handler, +// client_manager, +// client_transport, +// ) +// } + +// async fn close_transport( +// router_manager: TransportManager, +// client_manager: TransportManager, +// client_transport: TransportUnicast, +// endpoints: &[EndPoint], +// ) { +// // Close the client transport +// let mut ee = String::new(); +// for e in endpoints.iter() { +// let _ = write!(ee, "{e} "); +// } +// println!("Closing transport with {ee}"); +// ztimeout!(client_transport.close()).unwrap(); + +// ztimeout!(async { +// while !router_manager.get_transports().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// // Stop the locators on the manager +// for e in endpoints.iter() { +// println!("Del locator: {e}"); +// ztimeout!(router_manager.del_listener(e)).unwrap(); +// } + +// // Wait a little bit +// task::sleep(SLEEP).await; + +// ztimeout!(router_manager.close()); +// ztimeout!(client_manager.close()); + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// async fn single_run( +// router_handler: Arc, +// client_transport: TransportUnicast, +// channel: &[Channel], +// msg_size: &[usize], +// ) { +// for ch in channel.iter() { +// for ms in msg_size.iter() { +// // Reset the counter and set priority on the router +// router_handler.reset_count(); +// router_handler.set_priority(ch.priority); + +// // Create the message to send +// let key = "test".into(); +// let payload = ZBuf::from(vec![0_u8; *ms]); +// let data_info = None; +// let routing_context = None; +// let reply_context = None; +// let message = ZenohMessage::make_data( +// key, +// payload, +// *ch, +// CongestionControl::Block, +// data_info, +// routing_context, +// reply_context, +// ); + +// println!("Sending {MSG_COUNT} messages... {ch:?} {ms}"); +// for _ in 0..MSG_COUNT { +// client_transport.schedule(message.clone()).unwrap(); +// } + +// // Wait for the messages to arrive to the other side +// ztimeout!(async { +// while router_handler.get_count() != MSG_COUNT { +// task::sleep(SLEEP_COUNT).await; +// } +// }); +// } +// } + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// async fn run(endpoints: &[EndPoint], channel: &[Channel], msg_size: &[usize]) { +// let (router_manager, router_handler, client_manager, client_transport) = +// open_transport(endpoints).await; +// single_run( +// router_handler.clone(), +// client_transport.clone(), +// channel, +// msg_size, +// ) +// .await; +// close_transport(router_manager, client_manager, client_transport, endpoints).await; +// } + +// #[cfg(feature = "transport_tcp")] +// #[test] +// fn conduits_tcp_only() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); +// let mut channel = vec![]; +// for p in PRIORITY_ALL.iter() { +// channel.push(Channel { +// priority: *p, +// reliability: Reliability::Reliable, +// }); +// } +// // Define the locators +// let endpoints: Vec = vec![format!("tcp/127.0.0.1:{}", 10000).parse().unwrap()]; +// // Run +// task::block_on(run(&endpoints, &channel, &MSG_SIZE_ALL)); +// } + +// #[cfg(feature = "transport_ws")] +// #[test] +// fn conduits_ws_only() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); +// let mut channel = vec![]; +// for p in PRIORITY_ALL.iter() { +// channel.push(Channel { +// priority: *p, +// reliability: Reliability::Reliable, +// }); +// } +// // Define the locators +// let endpoints: Vec = vec![format!("ws/127.0.0.1:{}", 10010).parse().unwrap()]; +// // Run +// task::block_on(run(&endpoints, &channel, &MSG_SIZE_ALL)); +// } diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index f3a42c070e..b907930e96 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -11,185 +11,185 @@ // Contributors: // ZettaScale Zenoh Team, // -use async_std::{prelude::FutureExt, task}; -use std::{convert::TryFrom, sync::Arc, time::Duration}; -use zenoh_buffers::ZBuf; -use zenoh_core::zasync_executor_init; -use zenoh_protocol::{ - core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, - zenoh::ZenohMessage, -}; -use zenoh_transport::{DummyTransportEventHandler, TransportManager}; - -const TIMEOUT: Duration = Duration::from_secs(60); -const SLEEP: Duration = Duration::from_secs(1); - -const MSG_SIZE: usize = 131_072; -const MSG_DEFRAG_BUF: usize = 128_000; - -macro_rules! ztimeout { - ($f:expr) => { - $f.timeout(TIMEOUT).await.unwrap() - }; -} - -async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { - // Define client and router IDs - let client_id = ZenohId::try_from([1]).unwrap(); - let router_id = ZenohId::try_from([2]).unwrap(); - - // Create the router transport manager - let router_manager = TransportManager::builder() - .zid(router_id) - .whatami(WhatAmI::Router) - .defrag_buff_size(MSG_DEFRAG_BUF) - .build(Arc::new(DummyTransportEventHandler::default())) - .unwrap(); - - // Create the client transport manager - let client_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client_id) - .defrag_buff_size(MSG_DEFRAG_BUF) - .build(Arc::new(DummyTransportEventHandler::default())) - .unwrap(); - - // Create the listener on the router - println!("Add locator: {endpoint}"); - let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); - - // Create an empty transport with the client - // Open transport -> This should be accepted - println!("Opening transport with {endpoint}"); - let _ = ztimeout!(client_manager.open_transport(endpoint.clone())).unwrap(); - - let client_transport = client_manager.get_transport(&router_id).unwrap(); - - // Create the message to send, this would trigger the transport closure - let key = "test".into(); - let payload = ZBuf::from(vec![0_u8; msg_size]); - let data_info = None; - let routing_context = None; - let reply_context = None; - let message = ZenohMessage::make_data( - key, - payload, - channel, - CongestionControl::Block, - data_info, - routing_context, - reply_context, - ); - - println!( - "Sending message of {msg_size} bytes while defragmentation buffer size is {MSG_DEFRAG_BUF} bytes" - ); - client_transport.schedule(message.clone()).unwrap(); - - // Wait that the client transport has been closed - ztimeout!(async { - while client_transport.get_zid().is_ok() { - task::sleep(SLEEP).await; - } - }); - - // Wait on the router manager that the transport has been closed - ztimeout!(async { - while !router_manager.get_transports_unicast().await.is_empty() { - task::sleep(SLEEP).await; - } - }); - - // Stop the locators on the manager - println!("Del locator: {endpoint}"); - ztimeout!(router_manager.del_listener(endpoint)).unwrap(); - - // Wait a little bit - ztimeout!(async { - while !router_manager.get_listeners_unicast().await.is_empty() { - task::sleep(SLEEP).await; - } - }); - - task::sleep(SLEEP).await; - - ztimeout!(router_manager.close()); - ztimeout!(client_manager.close()); - - // Wait a little bit - task::sleep(SLEEP).await; -} - -#[cfg(feature = "transport_tcp")] -#[test] -fn transport_unicast_defragmentation_tcp_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locators - let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 11000).parse().unwrap(); - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(async { - for ch in channel.iter() { - run(&endpoint, *ch, MSG_SIZE).await; - } - }); -} - -#[cfg(feature = "transport_ws")] -#[test] -fn transport_unicast_defragmentation_ws_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locators - let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 11010).parse().unwrap(); - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(async { - for ch in channel.iter() { - run(&endpoint, *ch, MSG_SIZE).await; - } - }); -} +// use async_std::{prelude::FutureExt, task}; +// use std::{convert::TryFrom, sync::Arc, time::Duration}; +// use zenoh_buffers::ZBuf; +// use zenoh_core::zasync_executor_init; +// use zenoh_protocol::{ +// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, +// zenoh::ZenohMessage, +// }; +// use zenoh_transport::{DummyTransportEventHandler, TransportManager}; + +// const TIMEOUT: Duration = Duration::from_secs(60); +// const SLEEP: Duration = Duration::from_secs(1); + +// const MSG_SIZE: usize = 131_072; +// const MSG_DEFRAG_BUF: usize = 128_000; + +// macro_rules! ztimeout { +// ($f:expr) => { +// $f.timeout(TIMEOUT).await.unwrap() +// }; +// } + +// async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { +// // Define client and router IDs +// let client_id = ZenohId::try_from([1]).unwrap(); +// let router_id = ZenohId::try_from([2]).unwrap(); + +// // Create the router transport manager +// let router_manager = TransportManager::builder() +// .zid(router_id) +// .whatami(WhatAmI::Router) +// .defrag_buff_size(MSG_DEFRAG_BUF) +// .build(Arc::new(DummyTransportEventHandler::default())) +// .unwrap(); + +// // Create the client transport manager +// let client_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client_id) +// .defrag_buff_size(MSG_DEFRAG_BUF) +// .build(Arc::new(DummyTransportEventHandler::default())) +// .unwrap(); + +// // Create the listener on the router +// println!("Add locator: {endpoint}"); +// let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); + +// // Create an empty transport with the client +// // Open transport -> This should be accepted +// println!("Opening transport with {endpoint}"); +// let _ = ztimeout!(client_manager.open_transport(endpoint.clone())).unwrap(); + +// let client_transport = client_manager.get_transport(&router_id).unwrap(); + +// // Create the message to send, this would trigger the transport closure +// let key = "test".into(); +// let payload = ZBuf::from(vec![0_u8; msg_size]); +// let data_info = None; +// let routing_context = None; +// let reply_context = None; +// let message = ZenohMessage::make_data( +// key, +// payload, +// channel, +// CongestionControl::Block, +// data_info, +// routing_context, +// reply_context, +// ); + +// println!( +// "Sending message of {msg_size} bytes while defragmentation buffer size is {MSG_DEFRAG_BUF} bytes" +// ); +// client_transport.schedule(message.clone()).unwrap(); + +// // Wait that the client transport has been closed +// ztimeout!(async { +// while client_transport.get_zid().is_ok() { +// task::sleep(SLEEP).await; +// } +// }); + +// // Wait on the router manager that the transport has been closed +// ztimeout!(async { +// while !router_manager.get_transports_unicast().await.is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// // Stop the locators on the manager +// println!("Del locator: {endpoint}"); +// ztimeout!(router_manager.del_listener(endpoint)).unwrap(); + +// // Wait a little bit +// ztimeout!(async { +// while !router_manager.get_listeners_unicast().await.is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// task::sleep(SLEEP).await; + +// ztimeout!(router_manager.close()); +// ztimeout!(client_manager.close()); + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// #[cfg(feature = "transport_tcp")] +// #[test] +// fn transport_unicast_defragmentation_tcp_only() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // Define the locators +// let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 11000).parse().unwrap(); +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(async { +// for ch in channel.iter() { +// run(&endpoint, *ch, MSG_SIZE).await; +// } +// }); +// } + +// #[cfg(feature = "transport_ws")] +// #[test] +// fn transport_unicast_defragmentation_ws_only() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // Define the locators +// let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 11010).parse().unwrap(); +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(async { +// for ch in channel.iter() { +// run(&endpoint, *ch, MSG_SIZE).await; +// } +// }); +// } diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index f655c40d30..1128bb53cb 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -11,376 +11,376 @@ // Contributors: // ZettaScale Zenoh Team, // -use async_std::prelude::FutureExt; -use async_std::task; -use std::any::Any; -use std::convert::TryFrom; -use std::io::Write; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; -use std::thread; -use std::time::Duration; -use zenoh_buffers::ZBuf; -use zenoh_core::zasync_executor_init; -use zenoh_link::Link; -use zenoh_protocol::{ - core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, - zenoh::ZenohMessage, -}; -use zenoh_result::ZResult; -use zenoh_transport::{ - DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportPeer, - TransportPeerEventHandler, TransportUnicast, -}; - -const MSG_SIZE: usize = 8; -const MSG_COUNT: usize = 100_000; -const TIMEOUT: Duration = Duration::from_secs(300); -const SLEEP: Duration = Duration::from_millis(100); -const USLEEP: Duration = Duration::from_millis(1); - -macro_rules! ztimeout { - ($f:expr) => { - $f.timeout(TIMEOUT).await.unwrap() - }; -} -#[cfg(test)] -#[derive(Default)] -struct SHRouterIntermittent; - -impl TransportEventHandler for SHRouterIntermittent { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) - } -} - -// Transport Handler for the intermittent clients -#[derive(Default)] -struct SHClientIntermittent; - -impl TransportEventHandler for SHClientIntermittent { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) - } -} - -// Transport Handler for the stable client -struct SHClientStable { - counter: Arc, -} - -impl SHClientStable { - fn new(counter: Arc) -> Self { - Self { counter } - } -} - -impl TransportEventHandler for SHClientStable { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - Ok(Arc::new(SCClient::new(self.counter.clone()))) - } -} - -// Transport Callback for the client -pub struct SCClient { - counter: Arc, -} - -impl SCClient { - pub fn new(counter: Arc) -> Self { - Self { counter } - } -} - -impl TransportPeerEventHandler for SCClient { - fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { - self.counter.fetch_add(1, Ordering::AcqRel); - Ok(()) - } - - fn new_link(&self, _link: Link) {} - fn del_link(&self, _link: Link) {} - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } -} - -async fn transport_intermittent(endpoint: &EndPoint) { - /* [ROUTER] */ - let router_id = ZenohId::try_from([1]).unwrap(); - - let router_handler = Arc::new(SHRouterIntermittent::default()); - // Create the router transport manager - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(3); - let router_manager = TransportManager::builder() - .whatami(WhatAmI::Router) - .zid(router_id) - .unicast(unicast) - .build(router_handler.clone()) - .unwrap(); - - /* [CLIENT] */ - let client01_id = ZenohId::try_from([2]).unwrap(); - let client02_id = ZenohId::try_from([3]).unwrap(); - let client03_id = ZenohId::try_from([4]).unwrap(); - - // Create the transport transport manager for the first client - let counter = Arc::new(AtomicUsize::new(0)); - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(3); - let client01_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client01_id) - .unicast(unicast) - .build(Arc::new(SHClientStable::new(counter.clone()))) - .unwrap(); - - // Create the transport transport manager for the second client - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(1); - let client02_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client02_id) - .unicast(unicast) - .build(Arc::new(SHClientIntermittent::default())) - .unwrap(); - - // Create the transport transport manager for the third client - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(1); - let client03_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client03_id) - .unicast(unicast) - .build(Arc::new(SHClientIntermittent::default())) - .unwrap(); - - /* [1] */ - // Add a listener to the router - println!("\nTransport Intermittent [1a1]"); - let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); - let locators = router_manager.get_listeners(); - println!("Transport Intermittent [1a2]: {locators:?}"); - assert_eq!(locators.len(), 1); - - /* [2] */ - // Open a transport from client01 to the router - let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); - assert_eq!(c_ses1.get_links().unwrap().len(), 1); - assert_eq!(client01_manager.get_transports().len(), 1); - assert_eq!(c_ses1.get_zid().unwrap(), router_id); - - /* [3] */ - // Continously open and close transport from client02 and client03 to the router - let c_client02_manager = client02_manager.clone(); - let c_endpoint = endpoint.clone(); - let c_router_id = router_id; - let c2_handle = task::spawn(async move { - loop { - print!("+"); - std::io::stdout().flush().unwrap(); - - let c_ses2 = ztimeout!(c_client02_manager.open_transport(c_endpoint.clone())).unwrap(); - assert_eq!(c_ses2.get_links().unwrap().len(), 1); - assert_eq!(c_client02_manager.get_transports().len(), 1); - assert_eq!(c_ses2.get_zid().unwrap(), c_router_id); - - task::sleep(SLEEP).await; - - print!("-"); - std::io::stdout().flush().unwrap(); - - ztimeout!(c_ses2.close()).unwrap(); - - task::sleep(SLEEP).await; - } - }); - - let c_client03_manager = client03_manager.clone(); - let c_endpoint = endpoint.clone(); - let c_router_id = router_id; - let c3_handle = task::spawn(async move { - loop { - print!("*"); - std::io::stdout().flush().unwrap(); - - let c_ses3 = ztimeout!(c_client03_manager.open_transport(c_endpoint.clone())).unwrap(); - assert_eq!(c_ses3.get_links().unwrap().len(), 1); - assert_eq!(c_client03_manager.get_transports().len(), 1); - assert_eq!(c_ses3.get_zid().unwrap(), c_router_id); - - task::sleep(SLEEP).await; - - print!(""); - std::io::stdout().flush().unwrap(); - - ztimeout!(c_ses3.close()).unwrap(); - - task::sleep(SLEEP).await; - } - }); - - /* [4] */ - println!("Transport Intermittent [4a1]"); - let c_router_manager = router_manager.clone(); - ztimeout!(task::spawn_blocking(move || { - // Create the message to send - let key = "test".into(); - let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); - let channel = Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }; - let congestion_control = CongestionControl::Block; - let data_info = None; - let routing_context = None; - let reply_context = None; - - let message = ZenohMessage::make_data( - key, - payload, - channel, - congestion_control, - data_info, - routing_context, - reply_context, - ); - - let mut ticks: Vec = (0..=MSG_COUNT).step_by(MSG_COUNT / 10).collect(); - ticks.remove(0); - - let mut count = 0; - while count < MSG_COUNT { - if count == ticks[0] { - println!("\nScheduled {count}"); - ticks.remove(0); - } - let transports = c_router_manager.get_transports(); - if !transports.is_empty() { - for s in transports.iter() { - if let Ok(ll) = s.get_links() { - if ll.is_empty() { - print!("#"); - } else { - assert_eq!(ll.len(), 1); - } - } - let res = s.schedule(message.clone()); - if res.is_err() { - print!("X"); - std::io::stdout().flush().unwrap(); - } - } - count += 1; - } else { - print!("O"); - thread::sleep(USLEEP); - } - } - })); - - // Stop the tasks - ztimeout!(c2_handle.cancel()); - ztimeout!(c3_handle.cancel()); - - // Check that client01 received all the messages - println!("Transport Intermittent [4b1]"); - ztimeout!(async { - loop { - let c = counter.load(Ordering::Acquire); - if c == MSG_COUNT { - break; - } - println!("Transport Intermittent [4b2]: Received {c}/{MSG_COUNT}"); - task::sleep(SLEEP).await; - } - }); - - /* [5] */ - // Close the open transport on the client - println!("Transport Intermittent [5a1]"); - for s in client01_manager.get_transports().iter() { - ztimeout!(s.close()).unwrap(); - } - println!("Transport Intermittent [5a2]"); - for s in client02_manager.get_transports().iter() { - ztimeout!(s.close()).unwrap(); - } - println!("Transport Intermittent [5a3]"); - for s in client03_manager.get_transports().iter() { - ztimeout!(s.close()).unwrap(); - } - - /* [6] */ - // Verify that the transport has been closed also on the router - println!("Transport Intermittent [6a1]"); - ztimeout!(async { - loop { - let transports = router_manager.get_transports(); - if transports.is_empty() { - break; - } - task::sleep(SLEEP).await; - } - }); - - /* [7] */ - // Perform clean up of the open locators - println!("\nTransport Intermittent [7a1]"); - ztimeout!(router_manager.del_listener(endpoint)).unwrap(); - - // Wait a little bit - task::sleep(SLEEP).await; - - ztimeout!(router_manager.close()); - ztimeout!(client01_manager.close()); - ztimeout!(client02_manager.close()); - ztimeout!(client03_manager.close()); - - // Wait a little bit - task::sleep(SLEEP).await; -} - -#[cfg(feature = "transport_tcp")] -#[test] -fn transport_tcp_intermittent() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 12000).parse().unwrap(); - task::block_on(transport_intermittent(&endpoint)); -} - -#[cfg(feature = "transport_ws")] -#[test] -fn transport_ws_intermittent() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 12010).parse().unwrap(); - task::block_on(transport_intermittent(&endpoint)); -} +// use async_std::prelude::FutureExt; +// use async_std::task; +// use std::any::Any; +// use std::convert::TryFrom; +// use std::io::Write; +// use std::sync::atomic::{AtomicUsize, Ordering}; +// use std::sync::Arc; +// use std::thread; +// use std::time::Duration; +// use zenoh_buffers::ZBuf; +// use zenoh_core::zasync_executor_init; +// use zenoh_link::Link; +// use zenoh_protocol::{ +// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, +// zenoh::ZenohMessage, +// }; +// use zenoh_result::ZResult; +// use zenoh_transport::{ +// DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportPeer, +// TransportPeerEventHandler, TransportUnicast, +// }; + +// const MSG_SIZE: usize = 8; +// const MSG_COUNT: usize = 100_000; +// const TIMEOUT: Duration = Duration::from_secs(300); +// const SLEEP: Duration = Duration::from_millis(100); +// const USLEEP: Duration = Duration::from_millis(1); + +// macro_rules! ztimeout { +// ($f:expr) => { +// $f.timeout(TIMEOUT).await.unwrap() +// }; +// } +// #[cfg(test)] +// #[derive(Default)] +// struct SHRouterIntermittent; + +// impl TransportEventHandler for SHRouterIntermittent { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// Ok(Arc::new(DummyTransportPeerEventHandler::default())) +// } +// } + +// // Transport Handler for the intermittent clients +// #[derive(Default)] +// struct SHClientIntermittent; + +// impl TransportEventHandler for SHClientIntermittent { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// Ok(Arc::new(DummyTransportPeerEventHandler::default())) +// } +// } + +// // Transport Handler for the stable client +// struct SHClientStable { +// counter: Arc, +// } + +// impl SHClientStable { +// fn new(counter: Arc) -> Self { +// Self { counter } +// } +// } + +// impl TransportEventHandler for SHClientStable { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// Ok(Arc::new(SCClient::new(self.counter.clone()))) +// } +// } + +// // Transport Callback for the client +// pub struct SCClient { +// counter: Arc, +// } + +// impl SCClient { +// pub fn new(counter: Arc) -> Self { +// Self { counter } +// } +// } + +// impl TransportPeerEventHandler for SCClient { +// fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { +// self.counter.fetch_add(1, Ordering::AcqRel); +// Ok(()) +// } + +// fn new_link(&self, _link: Link) {} +// fn del_link(&self, _link: Link) {} +// fn closing(&self) {} +// fn closed(&self) {} + +// fn as_any(&self) -> &dyn Any { +// self +// } +// } + +// async fn transport_intermittent(endpoint: &EndPoint) { +// /* [ROUTER] */ +// let router_id = ZenohId::try_from([1]).unwrap(); + +// let router_handler = Arc::new(SHRouterIntermittent::default()); +// // Create the router transport manager +// let unicast = TransportManager::config_unicast() +// .max_links(1) +// .max_sessions(3); +// let router_manager = TransportManager::builder() +// .whatami(WhatAmI::Router) +// .zid(router_id) +// .unicast(unicast) +// .build(router_handler.clone()) +// .unwrap(); + +// /* [CLIENT] */ +// let client01_id = ZenohId::try_from([2]).unwrap(); +// let client02_id = ZenohId::try_from([3]).unwrap(); +// let client03_id = ZenohId::try_from([4]).unwrap(); + +// // Create the transport transport manager for the first client +// let counter = Arc::new(AtomicUsize::new(0)); +// let unicast = TransportManager::config_unicast() +// .max_links(1) +// .max_sessions(3); +// let client01_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client01_id) +// .unicast(unicast) +// .build(Arc::new(SHClientStable::new(counter.clone()))) +// .unwrap(); + +// // Create the transport transport manager for the second client +// let unicast = TransportManager::config_unicast() +// .max_links(1) +// .max_sessions(1); +// let client02_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client02_id) +// .unicast(unicast) +// .build(Arc::new(SHClientIntermittent::default())) +// .unwrap(); + +// // Create the transport transport manager for the third client +// let unicast = TransportManager::config_unicast() +// .max_links(1) +// .max_sessions(1); +// let client03_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client03_id) +// .unicast(unicast) +// .build(Arc::new(SHClientIntermittent::default())) +// .unwrap(); + +// /* [1] */ +// // Add a listener to the router +// println!("\nTransport Intermittent [1a1]"); +// let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); +// let locators = router_manager.get_listeners(); +// println!("Transport Intermittent [1a2]: {locators:?}"); +// assert_eq!(locators.len(), 1); + +// /* [2] */ +// // Open a transport from client01 to the router +// let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); +// assert_eq!(c_ses1.get_links().unwrap().len(), 1); +// assert_eq!(client01_manager.get_transports().len(), 1); +// assert_eq!(c_ses1.get_zid().unwrap(), router_id); + +// /* [3] */ +// // Continously open and close transport from client02 and client03 to the router +// let c_client02_manager = client02_manager.clone(); +// let c_endpoint = endpoint.clone(); +// let c_router_id = router_id; +// let c2_handle = task::spawn(async move { +// loop { +// print!("+"); +// std::io::stdout().flush().unwrap(); + +// let c_ses2 = ztimeout!(c_client02_manager.open_transport(c_endpoint.clone())).unwrap(); +// assert_eq!(c_ses2.get_links().unwrap().len(), 1); +// assert_eq!(c_client02_manager.get_transports().len(), 1); +// assert_eq!(c_ses2.get_zid().unwrap(), c_router_id); + +// task::sleep(SLEEP).await; + +// print!("-"); +// std::io::stdout().flush().unwrap(); + +// ztimeout!(c_ses2.close()).unwrap(); + +// task::sleep(SLEEP).await; +// } +// }); + +// let c_client03_manager = client03_manager.clone(); +// let c_endpoint = endpoint.clone(); +// let c_router_id = router_id; +// let c3_handle = task::spawn(async move { +// loop { +// print!("*"); +// std::io::stdout().flush().unwrap(); + +// let c_ses3 = ztimeout!(c_client03_manager.open_transport(c_endpoint.clone())).unwrap(); +// assert_eq!(c_ses3.get_links().unwrap().len(), 1); +// assert_eq!(c_client03_manager.get_transports().len(), 1); +// assert_eq!(c_ses3.get_zid().unwrap(), c_router_id); + +// task::sleep(SLEEP).await; + +// print!(""); +// std::io::stdout().flush().unwrap(); + +// ztimeout!(c_ses3.close()).unwrap(); + +// task::sleep(SLEEP).await; +// } +// }); + +// /* [4] */ +// println!("Transport Intermittent [4a1]"); +// let c_router_manager = router_manager.clone(); +// ztimeout!(task::spawn_blocking(move || { +// // Create the message to send +// let key = "test".into(); +// let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); +// let channel = Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }; +// let congestion_control = CongestionControl::Block; +// let data_info = None; +// let routing_context = None; +// let reply_context = None; + +// let message = ZenohMessage::make_data( +// key, +// payload, +// channel, +// congestion_control, +// data_info, +// routing_context, +// reply_context, +// ); + +// let mut ticks: Vec = (0..=MSG_COUNT).step_by(MSG_COUNT / 10).collect(); +// ticks.remove(0); + +// let mut count = 0; +// while count < MSG_COUNT { +// if count == ticks[0] { +// println!("\nScheduled {count}"); +// ticks.remove(0); +// } +// let transports = c_router_manager.get_transports(); +// if !transports.is_empty() { +// for s in transports.iter() { +// if let Ok(ll) = s.get_links() { +// if ll.is_empty() { +// print!("#"); +// } else { +// assert_eq!(ll.len(), 1); +// } +// } +// let res = s.schedule(message.clone()); +// if res.is_err() { +// print!("X"); +// std::io::stdout().flush().unwrap(); +// } +// } +// count += 1; +// } else { +// print!("O"); +// thread::sleep(USLEEP); +// } +// } +// })); + +// // Stop the tasks +// ztimeout!(c2_handle.cancel()); +// ztimeout!(c3_handle.cancel()); + +// // Check that client01 received all the messages +// println!("Transport Intermittent [4b1]"); +// ztimeout!(async { +// loop { +// let c = counter.load(Ordering::Acquire); +// if c == MSG_COUNT { +// break; +// } +// println!("Transport Intermittent [4b2]: Received {c}/{MSG_COUNT}"); +// task::sleep(SLEEP).await; +// } +// }); + +// /* [5] */ +// // Close the open transport on the client +// println!("Transport Intermittent [5a1]"); +// for s in client01_manager.get_transports().iter() { +// ztimeout!(s.close()).unwrap(); +// } +// println!("Transport Intermittent [5a2]"); +// for s in client02_manager.get_transports().iter() { +// ztimeout!(s.close()).unwrap(); +// } +// println!("Transport Intermittent [5a3]"); +// for s in client03_manager.get_transports().iter() { +// ztimeout!(s.close()).unwrap(); +// } + +// /* [6] */ +// // Verify that the transport has been closed also on the router +// println!("Transport Intermittent [6a1]"); +// ztimeout!(async { +// loop { +// let transports = router_manager.get_transports(); +// if transports.is_empty() { +// break; +// } +// task::sleep(SLEEP).await; +// } +// }); + +// /* [7] */ +// // Perform clean up of the open locators +// println!("\nTransport Intermittent [7a1]"); +// ztimeout!(router_manager.del_listener(endpoint)).unwrap(); + +// // Wait a little bit +// task::sleep(SLEEP).await; + +// ztimeout!(router_manager.close()); +// ztimeout!(client01_manager.close()); +// ztimeout!(client02_manager.close()); +// ztimeout!(client03_manager.close()); + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// #[cfg(feature = "transport_tcp")] +// #[test] +// fn transport_tcp_intermittent() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 12000).parse().unwrap(); +// task::block_on(transport_intermittent(&endpoint)); +// } + +// #[cfg(feature = "transport_ws")] +// #[test] +// fn transport_ws_intermittent() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 12010).parse().unwrap(); +// task::block_on(transport_intermittent(&endpoint)); +// } diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index f8f166ec97..6df94d19c3 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -1,350 +1,350 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -#[cfg(target_family = "unix")] -mod tests { - use async_std::prelude::FutureExt; - use async_std::task; - use std::any::Any; - use std::convert::TryFrom; - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::sync::Arc; - use std::time::Duration; - use zenoh_buffers::ZBuf; - use zenoh_core::zasync_executor_init; - use zenoh_link::Link; - use zenoh_protocol::{ - core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, - zenoh::ZenohMessage, - }; - use zenoh_result::ZResult; - use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, - TransportUnicast, - }; - - const TIMEOUT: Duration = Duration::from_secs(60); - const SLEEP: Duration = Duration::from_millis(500); - - const MSG_COUNT: usize = 16; - const MSG_SIZE: usize = 1_024; - - macro_rules! ztimeout { - ($f:expr) => { - $f.timeout(TIMEOUT).await.unwrap() - }; - } - - // Transport Handler for the router - struct SHPeer { - zid: ZenohId, - count: Arc, - } - - impl SHPeer { - fn new(zid: ZenohId) -> Self { - Self { - zid, - count: Arc::new(AtomicUsize::new(0)), - } - } - - fn get_count(&self) -> usize { - self.count.load(Ordering::SeqCst) - } - } - - impl TransportEventHandler for SHPeer { - fn new_unicast( - &self, - _peer: TransportPeer, - transport: TransportUnicast, - ) -> ZResult> { - // Create the message to send - let key = "test".into(); - let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); - let channel = Channel { - priority: Priority::Control, - reliability: Reliability::Reliable, - }; - let congestion_control = CongestionControl::Block; - let data_info = None; - let routing_context = None; - let reply_context = None; - - let message = ZenohMessage::make_data( - key, - payload, - channel, - congestion_control, - data_info, - routing_context, - reply_context, - ); - - println!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); - for _ in 0..MSG_COUNT { - transport.handle_message(message.clone()).unwrap(); - } - println!("[Simultaneous {}] ... sent {}", self.zid, MSG_COUNT); - - let mh = Arc::new(MHPeer::new(self.count.clone())); - Ok(mh) - } - } - - struct MHPeer { - count: Arc, - } - - impl MHPeer { - fn new(count: Arc) -> Self { - Self { count } - } - } - - impl TransportPeerEventHandler for MHPeer { - fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { - self.count.fetch_add(1, Ordering::AcqRel); - Ok(()) - } - - fn new_link(&self, _link: Link) {} - fn del_link(&self, _link: Link) {} - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } - } - - async fn transport_simultaneous(endpoint01: Vec, endpoint02: Vec) { - /* [Peers] */ - let peer_id01 = ZenohId::try_from([2]).unwrap(); - let peer_id02 = ZenohId::try_from([3]).unwrap(); - - // Create the peer01 transport manager - let peer_sh01 = Arc::new(SHPeer::new(peer_id01)); - let unicast = TransportManager::config_unicast().max_links(endpoint01.len()); - let peer01_manager = TransportManager::builder() - .whatami(WhatAmI::Peer) - .zid(peer_id01) - .unicast(unicast) - .build(peer_sh01.clone()) - .unwrap(); - - // Create the peer02 transport manager - let peer_sh02 = Arc::new(SHPeer::new(peer_id02)); - let unicast = TransportManager::config_unicast().max_links(endpoint02.len()); - let peer02_manager = TransportManager::builder() - .whatami(WhatAmI::Peer) - .zid(peer_id02) - .unicast(unicast) - .build(peer_sh02.clone()) - .unwrap(); - - // Add the endpoints on the peer01 - for e in endpoint01.iter() { - let res = ztimeout!(peer01_manager.add_listener(e.clone())); - println!("[Simultaneous 01a] => Adding endpoint {e:?}: {res:?}"); - assert!(res.is_ok()); - } - let locs = peer01_manager.get_listeners(); - println!("[Simultaneous 01b] => Getting endpoints: {endpoint01:?} {locs:?}"); - assert_eq!(endpoint01.len(), locs.len()); - - // Add the endpoints on peer02 - for e in endpoint02.iter() { - let res = ztimeout!(peer02_manager.add_listener(e.clone())); - println!("[Simultaneous 02a] => Adding endpoint {e:?}: {res:?}"); - assert!(res.is_ok()); - } - let locs = peer02_manager.get_listeners(); - println!("[Simultaneous 02b] => Getting endpoints: {endpoint02:?} {locs:?}"); - assert_eq!(endpoint02.len(), locs.len()); - - // Endpoints - let c_ep01 = endpoint01.clone(); - let c_ep02 = endpoint02.clone(); - - // Peer01 - let c_p01m = peer01_manager.clone(); - let peer01_task = task::spawn(async move { - // Open the transport with the second peer - // These open should succeed - for e in c_ep02.iter() { - println!("[Simultaneous 01c] => Opening transport with {e:?}..."); - let _ = ztimeout!(c_p01m.open_transport(e.clone())).unwrap(); - } - - // These open should fails - for e in c_ep02.iter() { - println!("[Simultaneous 01d] => Exceeding transport with {e:?}..."); - let res = ztimeout!(c_p01m.open_transport(e.clone())); - assert!(res.is_err()); - } - - task::sleep(SLEEP).await; - - let tp02 = ztimeout!(async { - let mut tp02 = None; - while tp02.is_none() { - task::sleep(SLEEP).await; - println!( - "[Simultaneous 01e] => Transports: {:?}", - peer01_manager.get_transports() - ); - tp02 = peer01_manager.get_transport(&peer_id02); - } - - tp02.unwrap() - }); - - // Wait for the links to be properly established - ztimeout!(async { - let expected = endpoint01.len() + c_ep02.len(); - let mut tl02 = vec![]; - while tl02.len() != expected { - task::sleep(SLEEP).await; - tl02 = tp02.get_links().unwrap(); - println!("[Simultaneous 01f] => Links {}/{}", tl02.len(), expected); - } - }); - - // Wait for the messages to arrive to peer 01 - ztimeout!(async { - let mut check = 0; - while check != MSG_COUNT { - task::sleep(SLEEP).await; - check = peer_sh01.get_count(); - println!("[Simultaneous 01g] => Received {check:?}/{MSG_COUNT:?}"); - } - }); - }); - - // Peer02 - let c_p02m = peer02_manager.clone(); - let peer02_task = task::spawn(async move { - // Open the transport with the first peer - // These open should succeed - for e in c_ep01.iter() { - println!("[Simultaneous 02c] => Opening transport with {e:?}..."); - let _ = ztimeout!(c_p02m.open_transport(e.clone())).unwrap(); - } - - // These open should fails - for e in c_ep01.iter() { - println!("[Simultaneous 02d] => Exceeding transport with {e:?}..."); - let res = ztimeout!(c_p02m.open_transport(e.clone())); - assert!(res.is_err()); - } - - // Wait a little bit - task::sleep(SLEEP).await; - - let tp01 = ztimeout!(async { - let mut tp01 = None; - while tp01.is_none() { - task::sleep(SLEEP).await; - println!( - "[Simultaneous 02e] => Transports: {:?}", - peer02_manager.get_transports() - ); - tp01 = peer02_manager.get_transport(&peer_id01); - } - tp01.unwrap() - }); - - // Wait for the links to be properly established - ztimeout!(async { - let expected = c_ep01.len() + endpoint02.len(); - let mut tl01 = vec![]; - while tl01.len() != expected { - task::sleep(SLEEP).await; - tl01 = tp01.get_links().unwrap(); - println!("[Simultaneous 02f] => Links {}/{}", tl01.len(), expected); - } - }); - - // Wait for the messages to arrive to peer 02 - ztimeout!(async { - let mut check = 0; - while check != MSG_COUNT { - task::sleep(SLEEP).await; - check = peer_sh02.get_count(); - println!("[Simultaneous 02g] => Received {check:?}/{MSG_COUNT:?}"); - } - }); - }); - - println!("[Simultaneous] => Waiting for peer01 and peer02 tasks..."); - peer01_task.join(peer02_task).await; - println!("[Simultaneous] => Waiting for peer01 and peer02 tasks... DONE\n"); - - // Wait a little bit - task::sleep(SLEEP).await; - } - - #[cfg(feature = "transport_tcp")] - #[test] - fn transport_tcp_simultaneous() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint01: Vec = vec![ - format!("tcp/127.0.0.1:{}", 15000).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 15001).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 15002).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 15003).parse().unwrap(), - ]; - let endpoint02: Vec = vec![ - format!("tcp/127.0.0.1:{}", 15010).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 15011).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 15012).parse().unwrap(), - format!("tcp/127.0.0.1:{}", 15013).parse().unwrap(), - ]; - - task::block_on(async { - transport_simultaneous(endpoint01, endpoint02).await; - }); - } - - #[cfg(feature = "transport_ws")] - #[test] - fn transport_ws_simultaneous() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let endpoint01: Vec = vec![ - format!("ws/127.0.0.1:{}", 15020).parse().unwrap(), - format!("ws/127.0.0.1:{}", 15021).parse().unwrap(), - format!("ws/127.0.0.1:{}", 15022).parse().unwrap(), - format!("ws/127.0.0.1:{}", 15023).parse().unwrap(), - ]; - let endpoint02: Vec = vec![ - format!("ws/127.0.0.1:{}", 15030).parse().unwrap(), - format!("ws/127.0.0.1:{}", 15031).parse().unwrap(), - format!("ws/127.0.0.1:{}", 15032).parse().unwrap(), - format!("ws/127.0.0.1:{}", 15033).parse().unwrap(), - ]; - - task::block_on(async { - transport_simultaneous(endpoint01, endpoint02).await; - }); - } -} +// // +// // Copyright (c) 2023 ZettaScale Technology +// // +// // This program and the accompanying materials are made available under the +// // terms of the Eclipse Public License 2.0 which is available at +// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// // which is available at https://www.apache.org/licenses/LICENSE-2.0. +// // +// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// // +// // Contributors: +// // ZettaScale Zenoh Team, +// // +// #[cfg(target_family = "unix")] +// mod tests { +// use async_std::prelude::FutureExt; +// use async_std::task; +// use std::any::Any; +// use std::convert::TryFrom; +// use std::sync::atomic::{AtomicUsize, Ordering}; +// use std::sync::Arc; +// use std::time::Duration; +// use zenoh_buffers::ZBuf; +// use zenoh_core::zasync_executor_init; +// use zenoh_link::Link; +// use zenoh_protocol::{ +// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, +// zenoh::ZenohMessage, +// }; +// use zenoh_result::ZResult; +// use zenoh_transport::{ +// TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, +// TransportUnicast, +// }; + +// const TIMEOUT: Duration = Duration::from_secs(60); +// const SLEEP: Duration = Duration::from_millis(500); + +// const MSG_COUNT: usize = 16; +// const MSG_SIZE: usize = 1_024; + +// macro_rules! ztimeout { +// ($f:expr) => { +// $f.timeout(TIMEOUT).await.unwrap() +// }; +// } + +// // Transport Handler for the router +// struct SHPeer { +// zid: ZenohId, +// count: Arc, +// } + +// impl SHPeer { +// fn new(zid: ZenohId) -> Self { +// Self { +// zid, +// count: Arc::new(AtomicUsize::new(0)), +// } +// } + +// fn get_count(&self) -> usize { +// self.count.load(Ordering::SeqCst) +// } +// } + +// impl TransportEventHandler for SHPeer { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// transport: TransportUnicast, +// ) -> ZResult> { +// // Create the message to send +// let key = "test".into(); +// let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); +// let channel = Channel { +// priority: Priority::Control, +// reliability: Reliability::Reliable, +// }; +// let congestion_control = CongestionControl::Block; +// let data_info = None; +// let routing_context = None; +// let reply_context = None; + +// let message = ZenohMessage::make_data( +// key, +// payload, +// channel, +// congestion_control, +// data_info, +// routing_context, +// reply_context, +// ); + +// println!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); +// for _ in 0..MSG_COUNT { +// transport.handle_message(message.clone()).unwrap(); +// } +// println!("[Simultaneous {}] ... sent {}", self.zid, MSG_COUNT); + +// let mh = Arc::new(MHPeer::new(self.count.clone())); +// Ok(mh) +// } +// } + +// struct MHPeer { +// count: Arc, +// } + +// impl MHPeer { +// fn new(count: Arc) -> Self { +// Self { count } +// } +// } + +// impl TransportPeerEventHandler for MHPeer { +// fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { +// self.count.fetch_add(1, Ordering::AcqRel); +// Ok(()) +// } + +// fn new_link(&self, _link: Link) {} +// fn del_link(&self, _link: Link) {} +// fn closing(&self) {} +// fn closed(&self) {} + +// fn as_any(&self) -> &dyn Any { +// self +// } +// } + +// async fn transport_simultaneous(endpoint01: Vec, endpoint02: Vec) { +// /* [Peers] */ +// let peer_id01 = ZenohId::try_from([2]).unwrap(); +// let peer_id02 = ZenohId::try_from([3]).unwrap(); + +// // Create the peer01 transport manager +// let peer_sh01 = Arc::new(SHPeer::new(peer_id01)); +// let unicast = TransportManager::config_unicast().max_links(endpoint01.len()); +// let peer01_manager = TransportManager::builder() +// .whatami(WhatAmI::Peer) +// .zid(peer_id01) +// .unicast(unicast) +// .build(peer_sh01.clone()) +// .unwrap(); + +// // Create the peer02 transport manager +// let peer_sh02 = Arc::new(SHPeer::new(peer_id02)); +// let unicast = TransportManager::config_unicast().max_links(endpoint02.len()); +// let peer02_manager = TransportManager::builder() +// .whatami(WhatAmI::Peer) +// .zid(peer_id02) +// .unicast(unicast) +// .build(peer_sh02.clone()) +// .unwrap(); + +// // Add the endpoints on the peer01 +// for e in endpoint01.iter() { +// let res = ztimeout!(peer01_manager.add_listener(e.clone())); +// println!("[Simultaneous 01a] => Adding endpoint {e:?}: {res:?}"); +// assert!(res.is_ok()); +// } +// let locs = peer01_manager.get_listeners(); +// println!("[Simultaneous 01b] => Getting endpoints: {endpoint01:?} {locs:?}"); +// assert_eq!(endpoint01.len(), locs.len()); + +// // Add the endpoints on peer02 +// for e in endpoint02.iter() { +// let res = ztimeout!(peer02_manager.add_listener(e.clone())); +// println!("[Simultaneous 02a] => Adding endpoint {e:?}: {res:?}"); +// assert!(res.is_ok()); +// } +// let locs = peer02_manager.get_listeners(); +// println!("[Simultaneous 02b] => Getting endpoints: {endpoint02:?} {locs:?}"); +// assert_eq!(endpoint02.len(), locs.len()); + +// // Endpoints +// let c_ep01 = endpoint01.clone(); +// let c_ep02 = endpoint02.clone(); + +// // Peer01 +// let c_p01m = peer01_manager.clone(); +// let peer01_task = task::spawn(async move { +// // Open the transport with the second peer +// // These open should succeed +// for e in c_ep02.iter() { +// println!("[Simultaneous 01c] => Opening transport with {e:?}..."); +// let _ = ztimeout!(c_p01m.open_transport(e.clone())).unwrap(); +// } + +// // These open should fails +// for e in c_ep02.iter() { +// println!("[Simultaneous 01d] => Exceeding transport with {e:?}..."); +// let res = ztimeout!(c_p01m.open_transport(e.clone())); +// assert!(res.is_err()); +// } + +// task::sleep(SLEEP).await; + +// let tp02 = ztimeout!(async { +// let mut tp02 = None; +// while tp02.is_none() { +// task::sleep(SLEEP).await; +// println!( +// "[Simultaneous 01e] => Transports: {:?}", +// peer01_manager.get_transports() +// ); +// tp02 = peer01_manager.get_transport(&peer_id02); +// } + +// tp02.unwrap() +// }); + +// // Wait for the links to be properly established +// ztimeout!(async { +// let expected = endpoint01.len() + c_ep02.len(); +// let mut tl02 = vec![]; +// while tl02.len() != expected { +// task::sleep(SLEEP).await; +// tl02 = tp02.get_links().unwrap(); +// println!("[Simultaneous 01f] => Links {}/{}", tl02.len(), expected); +// } +// }); + +// // Wait for the messages to arrive to peer 01 +// ztimeout!(async { +// let mut check = 0; +// while check != MSG_COUNT { +// task::sleep(SLEEP).await; +// check = peer_sh01.get_count(); +// println!("[Simultaneous 01g] => Received {check:?}/{MSG_COUNT:?}"); +// } +// }); +// }); + +// // Peer02 +// let c_p02m = peer02_manager.clone(); +// let peer02_task = task::spawn(async move { +// // Open the transport with the first peer +// // These open should succeed +// for e in c_ep01.iter() { +// println!("[Simultaneous 02c] => Opening transport with {e:?}..."); +// let _ = ztimeout!(c_p02m.open_transport(e.clone())).unwrap(); +// } + +// // These open should fails +// for e in c_ep01.iter() { +// println!("[Simultaneous 02d] => Exceeding transport with {e:?}..."); +// let res = ztimeout!(c_p02m.open_transport(e.clone())); +// assert!(res.is_err()); +// } + +// // Wait a little bit +// task::sleep(SLEEP).await; + +// let tp01 = ztimeout!(async { +// let mut tp01 = None; +// while tp01.is_none() { +// task::sleep(SLEEP).await; +// println!( +// "[Simultaneous 02e] => Transports: {:?}", +// peer02_manager.get_transports() +// ); +// tp01 = peer02_manager.get_transport(&peer_id01); +// } +// tp01.unwrap() +// }); + +// // Wait for the links to be properly established +// ztimeout!(async { +// let expected = c_ep01.len() + endpoint02.len(); +// let mut tl01 = vec![]; +// while tl01.len() != expected { +// task::sleep(SLEEP).await; +// tl01 = tp01.get_links().unwrap(); +// println!("[Simultaneous 02f] => Links {}/{}", tl01.len(), expected); +// } +// }); + +// // Wait for the messages to arrive to peer 02 +// ztimeout!(async { +// let mut check = 0; +// while check != MSG_COUNT { +// task::sleep(SLEEP).await; +// check = peer_sh02.get_count(); +// println!("[Simultaneous 02g] => Received {check:?}/{MSG_COUNT:?}"); +// } +// }); +// }); + +// println!("[Simultaneous] => Waiting for peer01 and peer02 tasks..."); +// peer01_task.join(peer02_task).await; +// println!("[Simultaneous] => Waiting for peer01 and peer02 tasks... DONE\n"); + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// #[cfg(feature = "transport_tcp")] +// #[test] +// fn transport_tcp_simultaneous() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let endpoint01: Vec = vec![ +// format!("tcp/127.0.0.1:{}", 15000).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 15001).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 15002).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 15003).parse().unwrap(), +// ]; +// let endpoint02: Vec = vec![ +// format!("tcp/127.0.0.1:{}", 15010).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 15011).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 15012).parse().unwrap(), +// format!("tcp/127.0.0.1:{}", 15013).parse().unwrap(), +// ]; + +// task::block_on(async { +// transport_simultaneous(endpoint01, endpoint02).await; +// }); +// } + +// #[cfg(feature = "transport_ws")] +// #[test] +// fn transport_ws_simultaneous() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let endpoint01: Vec = vec![ +// format!("ws/127.0.0.1:{}", 15020).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 15021).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 15022).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 15023).parse().unwrap(), +// ]; +// let endpoint02: Vec = vec![ +// format!("ws/127.0.0.1:{}", 15030).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 15031).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 15032).parse().unwrap(), +// format!("ws/127.0.0.1:{}", 15033).parse().unwrap(), +// ]; + +// task::block_on(async { +// transport_simultaneous(endpoint01, endpoint02).await; +// }); +// } +// } diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 5ad1b79192..369e453d94 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -1,1130 +1,1130 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use async_std::{prelude::FutureExt, task}; -use std::fmt::Write as _; -use std::{ - any::Any, - convert::TryFrom, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, - }, - time::Duration, -}; -use zenoh_buffers::ZBuf; -use zenoh_core::zasync_executor_init; -use zenoh_link::Link; -use zenoh_protocol::{ - core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, - zenoh::ZenohMessage, -}; -use zenoh_result::ZResult; -use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, - TransportUnicast, -}; - -// These keys and certificates below are purposedly generated to run TLS and mTLS tests. -// -// With 2 way authentication (mTLS), using TLS 1.3, we need two pairs of keys and certificates: one -// for the "server" and another one for the "client". -// -// The keys and certificates below were auto-generated using https://github.com/jsha/minica and -// target the localhost domain, so it has no real mapping to any existing domain. -// -// The keys and certificates generated map as follows to the constants below: -// -// certificates -// ├── client -// │ ├── localhost -// │ │ ├── cert.pem <------- CLIENT_CERT -// │ │ └── key.pem <-------- CLIENT_KEY -// │ ├── minica-key.pem -// │ └── minica.pem <--------- CLIENT_CA -// └── server -// ├── localhost -// │ ├── cert.pem <------- SERVER_CERT -// │ └── key.pem <-------- SERVER_KEY -// ├── minica-key.pem -// └── minica.pem <--------- SERVER_CA -// -// The way it works is that the client's certificate authority will validate in front of the server -// the key and certificate brought in by the client. Similarly the server's certificate authority -// will validate the key and certificate brought in by the server in front of the client. -// -#[cfg(all(feature = "transport_tls", target_family = "unix"))] -const CLIENT_KEY: &str = "-----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi -qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy -aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU -cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha -Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr -Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 -2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 -lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU -WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX -Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI -9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak -r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn -qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY -CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu -fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj -4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih -XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 -38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT -Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV -jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R -5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H -n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm -qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD -tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v -F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== ------END RSA PRIVATE KEY-----"; - -#[cfg(all(feature = "transport_tls", target_family = "unix"))] -const CLIENT_CERT: &str = "-----BEGIN CERTIFICATE----- -MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw -MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT -He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ -Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj -eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 -eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M -tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud -DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE -DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 -3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD -wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q -GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC -9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ -p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ -abY= ------END CERTIFICATE-----"; - -#[cfg(all(feature = "transport_tls", target_family = "unix"))] -const CLIENT_CA: &str = "-----BEGIN CERTIFICATE----- -MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw -MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ -uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs -DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc -8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 -T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b -QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB -AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 -/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq -hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ -e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc -yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 -8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 -Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN -R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== ------END CERTIFICATE-----"; - -#[cfg(any(feature = "transport_tls", feature = "transport_quic"))] -const SERVER_KEY: &str = "-----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAmDCySqKHPmEZShDH3ldPaV/Zsh9+HlHFLk9H10vJZj5WfzVu -5puZQ8GvBFIOtVrl0L9qLkA6bZiHHXm/8OEVvd135ZMp4NV23fdTsEASXfvGVQY8 -y+4UkZN0Dw6sfwlQVPyNRplys2+nFs6tX05Dp9VizV39tSOqe/jd6hyzxSUHqFat -RwQRXAI04CZ6ckDb0Riw7i0yvjrFhBom9lPKq4IkXZGgS5MRl0pRgAZTqHEMlv8z -oX+KcG9mfyQIHtpkVuSHHsQjwVop7fMnT7KCQ3bPI+fgMmAg+h1IR19Dm0JM+9zl -u39j0IbkytrsystGM+pTRbdp7s2lgtOMCFt0+wIDAQABAoIBADNTSO2uvlmlOXgn -DKDJZTiuYKaXxFrJTOx/REUxg+x9XYJtLMeM9jVJnpKgceFrlFHAHDkY5BuN8xNX -ugmsfz6W8BZ2eQsgMoRNIuYv1YHopUyLW/mSg1FNHzjsw/Pb2kGvIp4Kpgopv3oL -naCkrmBtsHJ+Hk/2hUpl9cE8iMwVWcVevLzyHi98jNy1IDdIPhRtl0dhMiqC5MRr -4gLJ5gNkLYX7xf3tw5Hmfk/bVNProqZXDIQVI7rFvItX586nvQ3LNQkmW/D2ShZf -3FEqMu6EdA2Ycc4UZgAlQNGV0VBrWWVXizOQ+9gjLnBk3kJjqfigCU6NG94bTJ+H -0YIhsGECgYEAwdSSyuMSOXgzZQ7Vv+GsNn/7ivi/H8eb/lDzksqS/JroA2ciAmHG -2OF30eUJKRg+STqBTpOfXgS4QUa8QLSwBSnwcw6579x9bYGUhqD2Ypaw9uCnOukA -CwwggZ9cDmF0tb5rYjqkW3bFPqkCnTGb0ylMFaYRhRDU20iG5t8PQckCgYEAyQEM -KK18FLQUKivGrQgP5Ib6IC3myzlHGxDzfobXGpaQntFnHY7Cxp/6BBtmASzt9Jxu -etnrevmzrbKqsLTJSg3ivbiq0YTLAJ1FsZrCp71dx49YR/5o9QFiq0nQoKnwUVeb -/hrDjMAokNkjFL5vouXO711GSS6YyM4WzAKZAqMCgYEAhqGxaG06jmJ4SFx6ibIl -nSFeRhQrJNbP+mCeHrrIR98NArgS/laN+Lz7LfaJW1r0gIa7pCmTi4l5thV80vDu -RlfwJOr4qaucD4Du+mg5WxdSSdiXL6sBlarRtVdMaMy2dTqTegJDgShJLxHTt/3q -P0yzBWJ5TtT3FG0XDqum/EkCgYAYNHwWWe3bQGQ9P9BI/fOL/YUZYu2sA1XAuKXZ -0rsMhJ0dwvG76XkjGhitbe82rQZqsnvLZ3qn8HHmtOFBLkQfGtT3K8nGOUuI42eF -H7HZKUCly2lCIizZdDVBkz4AWvaJlRc/3lE2Hd3Es6E52kTvROVKhdz06xuS8t5j -6twqKQKBgQC01AeiWL6Rzo+yZNzVgbpeeDogaZz5dtmURDgCYH8yFX5eoCKLHfnI -2nDIoqpaHY0LuX+dinuH+jP4tlyndbc2muXnHd9r0atytxA69ay3sSA5WFtfi4ef -ESElGO6qXEA821RpQp+2+uhL90+iC294cPqlS5LDmvTMypVDHzrxPQ== ------END RSA PRIVATE KEY-----"; - -#[cfg(any(feature = "transport_tls", feature = "transport_quic"))] -const SERVER_CERT: &str = "-----BEGIN CERTIFICATE----- -MIIDLjCCAhagAwIBAgIIW1mAtJWJAJYwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw -MzA2MTY0MTA2WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCYMLJKooc+YRlKEMfeV09pX9myH34eUcUuT0fXS8lm -PlZ/NW7mm5lDwa8EUg61WuXQv2ouQDptmIcdeb/w4RW93Xflkyng1Xbd91OwQBJd -+8ZVBjzL7hSRk3QPDqx/CVBU/I1GmXKzb6cWzq1fTkOn1WLNXf21I6p7+N3qHLPF -JQeoVq1HBBFcAjTgJnpyQNvRGLDuLTK+OsWEGib2U8qrgiRdkaBLkxGXSlGABlOo -cQyW/zOhf4pwb2Z/JAge2mRW5IcexCPBWint8ydPsoJDds8j5+AyYCD6HUhHX0Ob -Qkz73OW7f2PQhuTK2uzKy0Yz6lNFt2nuzaWC04wIW3T7AgMBAAGjdjB0MA4GA1Ud -DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -AQH/BAIwADAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDAUBgNVHREE -DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAAxrmQPG54ybKgMVliN8 -Mg5povSdPIVVnlU/HOVG9yxzAOav/xQP003M4wqpatWxI8tR1PcLuZf0EPmcdJgb -tVl9nZMVZtveQnYMlU8PpkEVu56VM4Zr3rH9liPRlr0JEAXODdKw76kWKzmdqWZ/ -rzhup3Ek7iEX6T5j/cPUvTWtMD4VEK2I7fgoKSHIX8MIVzqM7cuboGWPtS3eRNXl -MgvahA4TwLEXPEe+V1WAq6nSb4g2qSXWIDpIsy/O1WGS/zzRnKvXu9/9NkXWqZMl -C1LSpiiQUaRSglOvYf/Zx6r+4BOS4OaaArwHkecZQqBSCcBLEAyb/FaaXdBowI0U -PQ4= ------END CERTIFICATE-----"; - -#[cfg(any(feature = "transport_tls", feature = "transport_quic"))] -const SERVER_CA: &str = "-----BEGIN CERTIFICATE----- -MIIDSzCCAjOgAwIBAgIITcwv1N10nqEwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw -MzA2MTY0MTA2WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSA0ZGNjMmYwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2WUgN7NMlXIknew1cXiTWGmS0 -1T1EjcNNDAq7DqZ7/ZVXrjD47yxTt5EOiOXK/cINKNw4Zq/MKQvq9qu+Oax4lwiV -Ha0i8ShGLSuYI1HBlXu4MmvdG+3/SjwYoGsGaShr0y/QGzD3cD+DQZg/RaaIPHlO -MdmiUXxkMcy4qa0hFJ1imlJdq/6Tlx46X+0vRCh8nkekvOZR+t7Z5U4jn4XE54Kl -0PiwcyX8vfDZ3epa/FSHZvVQieM/g5Yh9OjIKCkdWRg7tD0IEGsaW11tEPJ5SiQr -mDqdRneMzZKqY0xC+QqXSvIlzpOjiu8PYQx7xugaUFE/npKRQdvh8ojHJMdNAgMB -AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTX46+p+Po1npE6 -QLQ7mMI+83s6qDAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDANBgkq -hkiG9w0BAQsFAAOCAQEAaN0IvEC677PL/JXzMrXcyBV88IvimlYN0zCt48GYlhmx -vL1YUDFLJEB7J+dyERGE5N6BKKDGblC4WiTFgDMLcHFsMGRc0v7zKPF1PSBwRYJi -ubAmkwdunGG5pDPUYtTEDPXMlgClZ0YyqSFJMOqA4IzQg6exVjXtUxPqzxNhyC7S -vlgUwPbX46uNi581a9+Ls2V3fg0ZnhkTSctYZHGZNeh0Nsf7Am8xdUDYG/bZcVef -jbQ9gpChosdjF0Bgblo7HSUct/2Va+YlYwW+WFjJX8k4oN6ZU5W5xhdfO8Czmgwk -US5kJ/+1M0uR8zUhZHL61FbsdPxEj+fYKrHv4woo+A== ------END CERTIFICATE-----"; - -const TIMEOUT: Duration = Duration::from_secs(60); -const SLEEP: Duration = Duration::from_secs(1); -const SLEEP_COUNT: Duration = Duration::from_millis(10); - -const MSG_COUNT: usize = 1_000; -const MSG_SIZE_ALL: [usize; 2] = [1_024, 131_072]; -const MSG_SIZE_NOFRAG: [usize; 1] = [1_024]; - -macro_rules! ztimeout { - ($f:expr) => { - $f.timeout(TIMEOUT).await.unwrap() - }; -} - -// Transport Handler for the router -struct SHRouter { - count: Arc, -} - -impl Default for SHRouter { - fn default() -> Self { - Self { - count: Arc::new(AtomicUsize::new(0)), - } - } -} - -impl SHRouter { - fn get_count(&self) -> usize { - self.count.load(Ordering::SeqCst) - } -} - -impl TransportEventHandler for SHRouter { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - let arc = Arc::new(SCRouter::new(self.count.clone())); - Ok(arc) - } -} - -// Transport Callback for the router -pub struct SCRouter { - count: Arc, -} - -impl SCRouter { - pub fn new(count: Arc) -> Self { - Self { count } - } -} - -impl TransportPeerEventHandler for SCRouter { - fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { - self.count.fetch_add(1, Ordering::SeqCst); - Ok(()) - } - - fn new_link(&self, _link: Link) {} - fn del_link(&self, _link: Link) {} - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } -} - -// Transport Handler for the client -#[derive(Default)] -struct SHClient; - -impl TransportEventHandler for SHClient { - fn new_unicast( - &self, - _peer: TransportPeer, - _transport: TransportUnicast, - ) -> ZResult> { - Ok(Arc::new(SCClient::default())) - } -} - -// Transport Callback for the client -#[derive(Default)] -pub struct SCClient; - -impl TransportPeerEventHandler for SCClient { - fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { - Ok(()) - } - - fn new_link(&self, _link: Link) {} - fn del_link(&self, _link: Link) {} - fn closing(&self) {} - fn closed(&self) {} - - fn as_any(&self) -> &dyn Any { - self - } -} - -async fn open_transport( - client_endpoints: &[EndPoint], - server_endpoints: &[EndPoint], -) -> ( - TransportManager, - Arc, - TransportManager, - TransportUnicast, -) { - // Define client and router IDs - let client_id = ZenohId::try_from([1]).unwrap(); - let router_id = ZenohId::try_from([2]).unwrap(); - - // Create the router transport manager - let router_handler = Arc::new(SHRouter::default()); - let unicast = TransportManager::config_unicast().max_links(server_endpoints.len()); - - let router_manager = TransportManager::builder() - .zid(router_id) - .whatami(WhatAmI::Router) - .unicast(unicast) - .build(router_handler.clone()) - .unwrap(); - - // Create the listener on the router - for e in server_endpoints.iter() { - println!("Add endpoint: {}", e); - let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); - } - - // Create the client transport manager - let unicast = TransportManager::config_unicast().max_links(client_endpoints.len()); - let client_manager = TransportManager::builder() - .whatami(WhatAmI::Client) - .zid(client_id) - .unicast(unicast) - .build(Arc::new(SHClient::default())) - .unwrap(); - - // Create an empty transport with the client - // Open transport -> This should be accepted - for e in client_endpoints.iter() { - println!("Opening transport with {}", e); - let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); - } - - let client_transport = client_manager.get_transport(&router_id).unwrap(); - - // Return the handlers - ( - router_manager, - router_handler, - client_manager, - client_transport, - ) -} - -async fn close_transport( - router_manager: TransportManager, - client_manager: TransportManager, - client_transport: TransportUnicast, - endpoints: &[EndPoint], -) { - // Close the client transport - let mut ee = String::new(); - for e in endpoints.iter() { - let _ = write!(ee, "{e} "); - } - println!("Closing transport with {}", ee); - ztimeout!(client_transport.close()).unwrap(); - - ztimeout!(async { - while !router_manager.get_transports().is_empty() { - task::sleep(SLEEP).await; - } - }); - - // Stop the locators on the manager - for e in endpoints.iter() { - println!("Del locator: {}", e); - ztimeout!(router_manager.del_listener(e)).unwrap(); - } - - ztimeout!(async { - while !router_manager.get_listeners().is_empty() { - task::sleep(SLEEP).await; - } - }); - - // Wait a little bit - task::sleep(SLEEP).await; - - ztimeout!(router_manager.close()); - ztimeout!(client_manager.close()); - - // Wait a little bit - task::sleep(SLEEP).await; -} - -async fn test_transport( - router_handler: Arc, - client_transport: TransportUnicast, - channel: Channel, - msg_size: usize, -) { - // Create the message to send - let key = "test".into(); - let payload = ZBuf::from(vec![0_u8; msg_size]); - let data_info = None; - let routing_context = None; - let reply_context = None; - let message = ZenohMessage::make_data( - key, - payload, - channel, - CongestionControl::Block, - data_info, - routing_context, - reply_context, - ); - - println!( - "Sending {} messages... {:?} {}", - MSG_COUNT, channel, msg_size - ); - for _ in 0..MSG_COUNT { - client_transport.schedule(message.clone()).unwrap(); - } - - match channel.reliability { - Reliability::Reliable => { - ztimeout!(async { - while router_handler.get_count() != MSG_COUNT { - task::sleep(SLEEP_COUNT).await; - } - }); - } - Reliability::BestEffort => { - ztimeout!(async { - while router_handler.get_count() == 0 { - task::sleep(SLEEP_COUNT).await; - } - }); - } - }; - - // Wait a little bit - task::sleep(SLEEP).await; -} - -async fn run_single( - client_endpoints: &[EndPoint], - server_endpoints: &[EndPoint], - channel: Channel, - msg_size: usize, -) { - println!( - "\n>>> Running test for: {:?}, {:?}, {:?}, {}", - client_endpoints, server_endpoints, channel, msg_size - ); - - #[allow(unused_variables)] // Used when stats feature is enabled - let (router_manager, router_handler, client_manager, client_transport) = - open_transport(client_endpoints, server_endpoints).await; - - test_transport( - router_handler.clone(), - client_transport.clone(), - channel, - msg_size, - ) - .await; - - #[cfg(feature = "stats")] - { - let c_stats = client_transport.get_stats().unwrap(); - println!("\tClient: {:?}", c_stats); - let r_stats = router_manager - .get_transport_unicast(&client_manager.config.zid) - .unwrap() - .get_stats() - .unwrap(); - println!("\tRouter: {:?}", r_stats); - } - - close_transport( - router_manager, - client_manager, - client_transport, - client_endpoints, - ) - .await; -} - -async fn run( - client_endpoints: &[EndPoint], - server_endpoints: &[EndPoint], - channel: &[Channel], - msg_size: &[usize], -) { - for ch in channel.iter() { - for ms in msg_size.iter() { - run_single(client_endpoints, server_endpoints, *ch, *ms).await; - } - } -} - -#[cfg(feature = "transport_tcp")] -#[test] -fn transport_unicast_tcp_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locators - let endpoints: Vec = vec![ - format!("tcp/127.0.0.1:{}", 16000).parse().unwrap(), - format!("tcp/[::1]:{}", 16001).parse().unwrap(), - ]; - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -} - -#[cfg(feature = "transport_udp")] -#[test] -fn transport_unicast_udp_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locator - let endpoints: Vec = vec![ - format!("udp/127.0.0.1:{}", 16010).parse().unwrap(), - format!("udp/[::1]:{}", 16011).parse().unwrap(), - ]; - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); -} - -#[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] -#[test] -fn transport_unicast_unix_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let f1 = "zenoh-test-unix-socket-5.sock"; - let _ = std::fs::remove_file(f1); - // Define the locator - let endpoints: Vec = vec![format!("unixsock-stream/{f1}").parse().unwrap()]; - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); - let _ = std::fs::remove_file(f1); - let _ = std::fs::remove_file(format!("{f1}.lock")); -} - -#[cfg(feature = "transport_ws")] -#[test] -fn transport_unicast_ws_only() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locators - let endpoints: Vec = vec![ - format!("ws/127.0.0.1:{}", 16020).parse().unwrap(), - format!("ws/[::1]:{}", 16021).parse().unwrap(), - ]; - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -} - -#[cfg(all(feature = "transport_tcp", feature = "transport_udp"))] -#[test] -fn transport_unicast_tcp_udp() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locator - let endpoints: Vec = vec![ - format!("tcp/127.0.0.1:{}", 16030).parse().unwrap(), - format!("udp/127.0.0.1:{}", 16031).parse().unwrap(), - format!("tcp/[::1]:{}", 16032).parse().unwrap(), - format!("udp/[::1]:{}", 16033).parse().unwrap(), - ]; - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); -} - -#[cfg(all( - feature = "transport_tcp", - feature = "transport_unixsock-stream", - target_family = "unix" -))] -#[test] -fn transport_unicast_tcp_unix() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let f1 = "zenoh-test-unix-socket-6.sock"; - let _ = std::fs::remove_file(f1); - // Define the locator - let endpoints: Vec = vec![ - format!("tcp/127.0.0.1:{}", 16040).parse().unwrap(), - format!("tcp/[::1]:{}", 16041).parse().unwrap(), - format!("unixsock-stream/{f1}").parse().unwrap(), - ]; - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); - let _ = std::fs::remove_file(f1); - let _ = std::fs::remove_file(format!("{f1}.lock")); -} - -#[cfg(all( - feature = "transport_udp", - feature = "transport_unixsock-stream", - target_family = "unix" -))] -#[test] -fn transport_unicast_udp_unix() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let f1 = "zenoh-test-unix-socket-7.sock"; - let _ = std::fs::remove_file(f1); - // Define the locator - let endpoints: Vec = vec![ - format!("udp/127.0.0.1:{}", 16050).parse().unwrap(), - format!("udp/[::1]:{}", 16051).parse().unwrap(), - format!("unixsock-stream/{f1}").parse().unwrap(), - ]; - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); - let _ = std::fs::remove_file(f1); - let _ = std::fs::remove_file(format!("{f1}.lock")); -} - -#[cfg(all( - feature = "transport_tcp", - feature = "transport_udp", - feature = "transport_unixsock-stream", - target_family = "unix" -))] -#[test] -fn transport_unicast_tcp_udp_unix() { - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - let f1 = "zenoh-test-unix-socket-8.sock"; - let _ = std::fs::remove_file(f1); - // Define the locator - let endpoints: Vec = vec![ - format!("tcp/127.0.0.1:{}", 16060).parse().unwrap(), - format!("udp/127.0.0.1:{}", 16061).parse().unwrap(), - format!("tcp/[::1]:{}", 16062).parse().unwrap(), - format!("udp/[::1]:{}", 16063).parse().unwrap(), - format!("unixsock-stream/{f1}").parse().unwrap(), - ]; - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); - let _ = std::fs::remove_file(f1); - let _ = std::fs::remove_file(format!("{f1}.lock")); -} - -#[cfg(all(feature = "transport_tls", target_family = "unix"))] -#[test] -fn transport_unicast_tls_only_server() { - use zenoh_link::tls::config::*; - - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locator - let mut endpoint: EndPoint = format!("tls/localhost:{}", 16070).parse().unwrap(); - endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), - (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), - (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - let endpoints = vec![endpoint]; - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -} - -#[cfg(feature = "transport_quic")] -#[test] -fn transport_unicast_quic_only_server() { - use zenoh_link::quic::config::*; - - let _ = env_logger::try_init(); - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locator - let mut endpoint: EndPoint = format!("quic/localhost:{}", 16080).parse().unwrap(); - endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), - (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), - (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - let endpoints = vec![endpoint]; - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -} - -#[cfg(all(feature = "transport_tls", target_family = "unix"))] -#[test] -fn transport_unicast_tls_only_mutual_success() { - use zenoh_link::tls::config::*; - - task::block_on(async { - zasync_executor_init!(); - }); - - let client_auth = "true"; - - // Define the locator - let mut client_endpoint: EndPoint = ("tls/localhost:10461").parse().unwrap(); - client_endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), - (TLS_CLIENT_CERTIFICATE_RAW, CLIENT_CERT), - (TLS_CLIENT_PRIVATE_KEY_RAW, CLIENT_KEY), - (TLS_CLIENT_AUTH, client_auth), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - - // Define the locator - let mut server_endpoint: EndPoint = ("tls/localhost:10461").parse().unwrap(); - server_endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), - (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), - (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), - (TLS_CLIENT_AUTH, client_auth), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - let client_endpoints = vec![client_endpoint]; - let server_endpoints = vec![server_endpoint]; - task::block_on(run( - &client_endpoints, - &server_endpoints, - &channel, - &MSG_SIZE_ALL, - )); -} - -// Constants replicating the alert descriptions thrown by the Rustls library. -// These alert descriptions are internal of the library and cannot be reached from these tests -// as to do a proper comparison. For the sake of simplicity we verify these constants are contained -// in the expected error messages from the tests below. -// -// See: https://docs.rs/rustls/latest/src/rustls/msgs/enums.rs.html#128 -#[cfg(all(feature = "transport_tls", target_family = "unix"))] -const RUSTLS_UNKNOWN_CA_ALERT_DESCRIPTION: &str = "UnknownCA"; -#[cfg(all(feature = "transport_tls", target_family = "unix"))] -const RUSTLS_CERTIFICATE_REQUIRED_ALERT_DESCRIPTION: &str = "CertificateRequired"; - -#[cfg(all(feature = "transport_tls", target_family = "unix"))] -#[test] -fn transport_unicast_tls_only_mutual_no_client_certs_failure() { - use std::vec; - - use zenoh_link::tls::config::*; - - task::block_on(async { - zasync_executor_init!(); - }); - - // Define the locator - let mut client_endpoint: EndPoint = ("tls/localhost:10462").parse().unwrap(); - client_endpoint - .config_mut() - .extend( - [(TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA)] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - - // Define the locator - let mut server_endpoint: EndPoint = ("tls/localhost:10462").parse().unwrap(); - server_endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), - (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), - (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), - (TLS_CLIENT_AUTH, "true"), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - let client_endpoints = vec![client_endpoint]; - let server_endpoints = vec![server_endpoint]; - let result = std::panic::catch_unwind(|| { - task::block_on(run( - &client_endpoints, - &server_endpoints, - &channel, - &MSG_SIZE_ALL, - )) - }); - assert!(result.is_err()); - let err = result.unwrap_err(); - let error_msg = panic_message::panic_message(&err); - assert!(error_msg.contains(RUSTLS_CERTIFICATE_REQUIRED_ALERT_DESCRIPTION)); -} - -#[cfg(all(feature = "transport_tls", target_family = "unix"))] -#[test] -fn transport_unicast_tls_only_mutual_wrong_client_certs_failure() { - use zenoh_link::tls::config::*; - - task::block_on(async { - zasync_executor_init!(); - }); - - let client_auth = "true"; - - // Define the locator - let mut client_endpoint: EndPoint = ("tls/localhost:10463").parse().unwrap(); - client_endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), - // Using the SERVER_CERT and SERVER_KEY in the client to simulate the case the client has - // wrong certificates and keys. The SERVER_CA (cetificate authority) will not recognize - // these certificates as it is expecting to receive CLIENT_CERT and CLIENT_KEY from the - // client. - (TLS_CLIENT_CERTIFICATE_RAW, SERVER_CERT), - (TLS_CLIENT_PRIVATE_KEY_RAW, SERVER_KEY), - (TLS_CLIENT_AUTH, client_auth), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - - // Define the locator - let mut server_endpoint: EndPoint = ("tls/localhost:10463").parse().unwrap(); - server_endpoint - .config_mut() - .extend( - [ - (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), - (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), - (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), - (TLS_CLIENT_AUTH, client_auth), - ] - .iter() - .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), - ) - .unwrap(); - // Define the reliability and congestion control - let channel = [ - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::default(), - reliability: Reliability::BestEffort, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }, - Channel { - priority: Priority::RealTime, - reliability: Reliability::BestEffort, - }, - ]; - // Run - let client_endpoints = vec![client_endpoint]; - let server_endpoints = vec![server_endpoint]; - let result = std::panic::catch_unwind(|| { - task::block_on(run( - &client_endpoints, - &server_endpoints, - &channel, - &MSG_SIZE_ALL, - )) - }); - assert!(result.is_err()); - let err = result.unwrap_err(); - let error_msg = panic_message::panic_message(&err); - assert!(error_msg.contains(RUSTLS_UNKNOWN_CA_ALERT_DESCRIPTION)); -} +// // +// // Copyright (c) 2023 ZettaScale Technology +// // +// // This program and the accompanying materials are made available under the +// // terms of the Eclipse Public License 2.0 which is available at +// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// // which is available at https://www.apache.org/licenses/LICENSE-2.0. +// // +// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// // +// // Contributors: +// // ZettaScale Zenoh Team, +// // +// use async_std::{prelude::FutureExt, task}; +// use std::fmt::Write as _; +// use std::{ +// any::Any, +// convert::TryFrom, +// sync::{ +// atomic::{AtomicUsize, Ordering}, +// Arc, +// }, +// time::Duration, +// }; +// use zenoh_buffers::ZBuf; +// use zenoh_core::zasync_executor_init; +// use zenoh_link::Link; +// use zenoh_protocol::{ +// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, +// zenoh::ZenohMessage, +// }; +// use zenoh_result::ZResult; +// use zenoh_transport::{ +// TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, +// TransportUnicast, +// }; + +// // These keys and certificates below are purposedly generated to run TLS and mTLS tests. +// // +// // With 2 way authentication (mTLS), using TLS 1.3, we need two pairs of keys and certificates: one +// // for the "server" and another one for the "client". +// // +// // The keys and certificates below were auto-generated using https://github.com/jsha/minica and +// // target the localhost domain, so it has no real mapping to any existing domain. +// // +// // The keys and certificates generated map as follows to the constants below: +// // +// // certificates +// // ├── client +// // │ ├── localhost +// // │ │ ├── cert.pem <------- CLIENT_CERT +// // │ │ └── key.pem <-------- CLIENT_KEY +// // │ ├── minica-key.pem +// // │ └── minica.pem <--------- CLIENT_CA +// // └── server +// // ├── localhost +// // │ ├── cert.pem <------- SERVER_CERT +// // │ └── key.pem <-------- SERVER_KEY +// // ├── minica-key.pem +// // └── minica.pem <--------- SERVER_CA +// // +// // The way it works is that the client's certificate authority will validate in front of the server +// // the key and certificate brought in by the client. Similarly the server's certificate authority +// // will validate the key and certificate brought in by the server in front of the client. +// // +// #[cfg(all(feature = "transport_tls", target_family = "unix"))] +// const CLIENT_KEY: &str = "-----BEGIN RSA PRIVATE KEY----- +// MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi +// qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy +// aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU +// cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha +// Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr +// Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 +// 2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 +// lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU +// WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX +// Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI +// 9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak +// r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn +// qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY +// CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu +// fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj +// 4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih +// XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 +// 38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT +// Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV +// jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R +// 5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H +// n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm +// qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD +// tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v +// F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== +// -----END RSA PRIVATE KEY-----"; + +// #[cfg(all(feature = "transport_tls", target_family = "unix"))] +// const CLIENT_CERT: &str = "-----BEGIN CERTIFICATE----- +// MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +// AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw +// MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +// AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT +// He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ +// Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj +// eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 +// eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M +// tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud +// DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +// AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE +// DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 +// 3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD +// wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q +// GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC +// 9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ +// p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ +// abY= +// -----END CERTIFICATE-----"; + +// #[cfg(all(feature = "transport_tls", target_family = "unix"))] +// const CLIENT_CA: &str = "-----BEGIN CERTIFICATE----- +// MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +// AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw +// MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi +// MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ +// uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs +// DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc +// 8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 +// T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b +// QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB +// AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +// BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 +// /llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq +// hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ +// e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc +// yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 +// 8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 +// Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN +// R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== +// -----END CERTIFICATE-----"; + +// #[cfg(any(feature = "transport_tls", feature = "transport_quic"))] +// const SERVER_KEY: &str = "-----BEGIN RSA PRIVATE KEY----- +// MIIEpAIBAAKCAQEAmDCySqKHPmEZShDH3ldPaV/Zsh9+HlHFLk9H10vJZj5WfzVu +// 5puZQ8GvBFIOtVrl0L9qLkA6bZiHHXm/8OEVvd135ZMp4NV23fdTsEASXfvGVQY8 +// y+4UkZN0Dw6sfwlQVPyNRplys2+nFs6tX05Dp9VizV39tSOqe/jd6hyzxSUHqFat +// RwQRXAI04CZ6ckDb0Riw7i0yvjrFhBom9lPKq4IkXZGgS5MRl0pRgAZTqHEMlv8z +// oX+KcG9mfyQIHtpkVuSHHsQjwVop7fMnT7KCQ3bPI+fgMmAg+h1IR19Dm0JM+9zl +// u39j0IbkytrsystGM+pTRbdp7s2lgtOMCFt0+wIDAQABAoIBADNTSO2uvlmlOXgn +// DKDJZTiuYKaXxFrJTOx/REUxg+x9XYJtLMeM9jVJnpKgceFrlFHAHDkY5BuN8xNX +// ugmsfz6W8BZ2eQsgMoRNIuYv1YHopUyLW/mSg1FNHzjsw/Pb2kGvIp4Kpgopv3oL +// naCkrmBtsHJ+Hk/2hUpl9cE8iMwVWcVevLzyHi98jNy1IDdIPhRtl0dhMiqC5MRr +// 4gLJ5gNkLYX7xf3tw5Hmfk/bVNProqZXDIQVI7rFvItX586nvQ3LNQkmW/D2ShZf +// 3FEqMu6EdA2Ycc4UZgAlQNGV0VBrWWVXizOQ+9gjLnBk3kJjqfigCU6NG94bTJ+H +// 0YIhsGECgYEAwdSSyuMSOXgzZQ7Vv+GsNn/7ivi/H8eb/lDzksqS/JroA2ciAmHG +// 2OF30eUJKRg+STqBTpOfXgS4QUa8QLSwBSnwcw6579x9bYGUhqD2Ypaw9uCnOukA +// CwwggZ9cDmF0tb5rYjqkW3bFPqkCnTGb0ylMFaYRhRDU20iG5t8PQckCgYEAyQEM +// KK18FLQUKivGrQgP5Ib6IC3myzlHGxDzfobXGpaQntFnHY7Cxp/6BBtmASzt9Jxu +// etnrevmzrbKqsLTJSg3ivbiq0YTLAJ1FsZrCp71dx49YR/5o9QFiq0nQoKnwUVeb +// /hrDjMAokNkjFL5vouXO711GSS6YyM4WzAKZAqMCgYEAhqGxaG06jmJ4SFx6ibIl +// nSFeRhQrJNbP+mCeHrrIR98NArgS/laN+Lz7LfaJW1r0gIa7pCmTi4l5thV80vDu +// RlfwJOr4qaucD4Du+mg5WxdSSdiXL6sBlarRtVdMaMy2dTqTegJDgShJLxHTt/3q +// P0yzBWJ5TtT3FG0XDqum/EkCgYAYNHwWWe3bQGQ9P9BI/fOL/YUZYu2sA1XAuKXZ +// 0rsMhJ0dwvG76XkjGhitbe82rQZqsnvLZ3qn8HHmtOFBLkQfGtT3K8nGOUuI42eF +// H7HZKUCly2lCIizZdDVBkz4AWvaJlRc/3lE2Hd3Es6E52kTvROVKhdz06xuS8t5j +// 6twqKQKBgQC01AeiWL6Rzo+yZNzVgbpeeDogaZz5dtmURDgCYH8yFX5eoCKLHfnI +// 2nDIoqpaHY0LuX+dinuH+jP4tlyndbc2muXnHd9r0atytxA69ay3sSA5WFtfi4ef +// ESElGO6qXEA821RpQp+2+uhL90+iC294cPqlS5LDmvTMypVDHzrxPQ== +// -----END RSA PRIVATE KEY-----"; + +// #[cfg(any(feature = "transport_tls", feature = "transport_quic"))] +// const SERVER_CERT: &str = "-----BEGIN CERTIFICATE----- +// MIIDLjCCAhagAwIBAgIIW1mAtJWJAJYwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +// AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw +// MzA2MTY0MTA2WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +// AQUAA4IBDwAwggEKAoIBAQCYMLJKooc+YRlKEMfeV09pX9myH34eUcUuT0fXS8lm +// PlZ/NW7mm5lDwa8EUg61WuXQv2ouQDptmIcdeb/w4RW93Xflkyng1Xbd91OwQBJd +// +8ZVBjzL7hSRk3QPDqx/CVBU/I1GmXKzb6cWzq1fTkOn1WLNXf21I6p7+N3qHLPF +// JQeoVq1HBBFcAjTgJnpyQNvRGLDuLTK+OsWEGib2U8qrgiRdkaBLkxGXSlGABlOo +// cQyW/zOhf4pwb2Z/JAge2mRW5IcexCPBWint8ydPsoJDds8j5+AyYCD6HUhHX0Ob +// Qkz73OW7f2PQhuTK2uzKy0Yz6lNFt2nuzaWC04wIW3T7AgMBAAGjdjB0MA4GA1Ud +// DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +// AQH/BAIwADAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDAUBgNVHREE +// DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAAxrmQPG54ybKgMVliN8 +// Mg5povSdPIVVnlU/HOVG9yxzAOav/xQP003M4wqpatWxI8tR1PcLuZf0EPmcdJgb +// tVl9nZMVZtveQnYMlU8PpkEVu56VM4Zr3rH9liPRlr0JEAXODdKw76kWKzmdqWZ/ +// rzhup3Ek7iEX6T5j/cPUvTWtMD4VEK2I7fgoKSHIX8MIVzqM7cuboGWPtS3eRNXl +// MgvahA4TwLEXPEe+V1WAq6nSb4g2qSXWIDpIsy/O1WGS/zzRnKvXu9/9NkXWqZMl +// C1LSpiiQUaRSglOvYf/Zx6r+4BOS4OaaArwHkecZQqBSCcBLEAyb/FaaXdBowI0U +// PQ4= +// -----END CERTIFICATE-----"; + +// #[cfg(any(feature = "transport_tls", feature = "transport_quic"))] +// const SERVER_CA: &str = "-----BEGIN CERTIFICATE----- +// MIIDSzCCAjOgAwIBAgIITcwv1N10nqEwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +// AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw +// MzA2MTY0MTA2WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSA0ZGNjMmYwggEi +// MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2WUgN7NMlXIknew1cXiTWGmS0 +// 1T1EjcNNDAq7DqZ7/ZVXrjD47yxTt5EOiOXK/cINKNw4Zq/MKQvq9qu+Oax4lwiV +// Ha0i8ShGLSuYI1HBlXu4MmvdG+3/SjwYoGsGaShr0y/QGzD3cD+DQZg/RaaIPHlO +// MdmiUXxkMcy4qa0hFJ1imlJdq/6Tlx46X+0vRCh8nkekvOZR+t7Z5U4jn4XE54Kl +// 0PiwcyX8vfDZ3epa/FSHZvVQieM/g5Yh9OjIKCkdWRg7tD0IEGsaW11tEPJ5SiQr +// mDqdRneMzZKqY0xC+QqXSvIlzpOjiu8PYQx7xugaUFE/npKRQdvh8ojHJMdNAgMB +// AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +// BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTX46+p+Po1npE6 +// QLQ7mMI+83s6qDAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDANBgkq +// hkiG9w0BAQsFAAOCAQEAaN0IvEC677PL/JXzMrXcyBV88IvimlYN0zCt48GYlhmx +// vL1YUDFLJEB7J+dyERGE5N6BKKDGblC4WiTFgDMLcHFsMGRc0v7zKPF1PSBwRYJi +// ubAmkwdunGG5pDPUYtTEDPXMlgClZ0YyqSFJMOqA4IzQg6exVjXtUxPqzxNhyC7S +// vlgUwPbX46uNi581a9+Ls2V3fg0ZnhkTSctYZHGZNeh0Nsf7Am8xdUDYG/bZcVef +// jbQ9gpChosdjF0Bgblo7HSUct/2Va+YlYwW+WFjJX8k4oN6ZU5W5xhdfO8Czmgwk +// US5kJ/+1M0uR8zUhZHL61FbsdPxEj+fYKrHv4woo+A== +// -----END CERTIFICATE-----"; + +// const TIMEOUT: Duration = Duration::from_secs(60); +// const SLEEP: Duration = Duration::from_secs(1); +// const SLEEP_COUNT: Duration = Duration::from_millis(10); + +// const MSG_COUNT: usize = 1_000; +// const MSG_SIZE_ALL: [usize; 2] = [1_024, 131_072]; +// const MSG_SIZE_NOFRAG: [usize; 1] = [1_024]; + +// macro_rules! ztimeout { +// ($f:expr) => { +// $f.timeout(TIMEOUT).await.unwrap() +// }; +// } + +// // Transport Handler for the router +// struct SHRouter { +// count: Arc, +// } + +// impl Default for SHRouter { +// fn default() -> Self { +// Self { +// count: Arc::new(AtomicUsize::new(0)), +// } +// } +// } + +// impl SHRouter { +// fn get_count(&self) -> usize { +// self.count.load(Ordering::SeqCst) +// } +// } + +// impl TransportEventHandler for SHRouter { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// let arc = Arc::new(SCRouter::new(self.count.clone())); +// Ok(arc) +// } +// } + +// // Transport Callback for the router +// pub struct SCRouter { +// count: Arc, +// } + +// impl SCRouter { +// pub fn new(count: Arc) -> Self { +// Self { count } +// } +// } + +// impl TransportPeerEventHandler for SCRouter { +// fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { +// self.count.fetch_add(1, Ordering::SeqCst); +// Ok(()) +// } + +// fn new_link(&self, _link: Link) {} +// fn del_link(&self, _link: Link) {} +// fn closing(&self) {} +// fn closed(&self) {} + +// fn as_any(&self) -> &dyn Any { +// self +// } +// } + +// // Transport Handler for the client +// #[derive(Default)] +// struct SHClient; + +// impl TransportEventHandler for SHClient { +// fn new_unicast( +// &self, +// _peer: TransportPeer, +// _transport: TransportUnicast, +// ) -> ZResult> { +// Ok(Arc::new(SCClient::default())) +// } +// } + +// // Transport Callback for the client +// #[derive(Default)] +// pub struct SCClient; + +// impl TransportPeerEventHandler for SCClient { +// fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { +// Ok(()) +// } + +// fn new_link(&self, _link: Link) {} +// fn del_link(&self, _link: Link) {} +// fn closing(&self) {} +// fn closed(&self) {} + +// fn as_any(&self) -> &dyn Any { +// self +// } +// } + +// async fn open_transport( +// client_endpoints: &[EndPoint], +// server_endpoints: &[EndPoint], +// ) -> ( +// TransportManager, +// Arc, +// TransportManager, +// TransportUnicast, +// ) { +// // Define client and router IDs +// let client_id = ZenohId::try_from([1]).unwrap(); +// let router_id = ZenohId::try_from([2]).unwrap(); + +// // Create the router transport manager +// let router_handler = Arc::new(SHRouter::default()); +// let unicast = TransportManager::config_unicast().max_links(server_endpoints.len()); + +// let router_manager = TransportManager::builder() +// .zid(router_id) +// .whatami(WhatAmI::Router) +// .unicast(unicast) +// .build(router_handler.clone()) +// .unwrap(); + +// // Create the listener on the router +// for e in server_endpoints.iter() { +// println!("Add endpoint: {}", e); +// let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); +// } + +// // Create the client transport manager +// let unicast = TransportManager::config_unicast().max_links(client_endpoints.len()); +// let client_manager = TransportManager::builder() +// .whatami(WhatAmI::Client) +// .zid(client_id) +// .unicast(unicast) +// .build(Arc::new(SHClient::default())) +// .unwrap(); + +// // Create an empty transport with the client +// // Open transport -> This should be accepted +// for e in client_endpoints.iter() { +// println!("Opening transport with {}", e); +// let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); +// } + +// let client_transport = client_manager.get_transport(&router_id).unwrap(); + +// // Return the handlers +// ( +// router_manager, +// router_handler, +// client_manager, +// client_transport, +// ) +// } + +// async fn close_transport( +// router_manager: TransportManager, +// client_manager: TransportManager, +// client_transport: TransportUnicast, +// endpoints: &[EndPoint], +// ) { +// // Close the client transport +// let mut ee = String::new(); +// for e in endpoints.iter() { +// let _ = write!(ee, "{e} "); +// } +// println!("Closing transport with {}", ee); +// ztimeout!(client_transport.close()).unwrap(); + +// ztimeout!(async { +// while !router_manager.get_transports().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// // Stop the locators on the manager +// for e in endpoints.iter() { +// println!("Del locator: {}", e); +// ztimeout!(router_manager.del_listener(e)).unwrap(); +// } + +// ztimeout!(async { +// while !router_manager.get_listeners().is_empty() { +// task::sleep(SLEEP).await; +// } +// }); + +// // Wait a little bit +// task::sleep(SLEEP).await; + +// ztimeout!(router_manager.close()); +// ztimeout!(client_manager.close()); + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// async fn test_transport( +// router_handler: Arc, +// client_transport: TransportUnicast, +// channel: Channel, +// msg_size: usize, +// ) { +// // Create the message to send +// let key = "test".into(); +// let payload = ZBuf::from(vec![0_u8; msg_size]); +// let data_info = None; +// let routing_context = None; +// let reply_context = None; +// let message = ZenohMessage::make_data( +// key, +// payload, +// channel, +// CongestionControl::Block, +// data_info, +// routing_context, +// reply_context, +// ); + +// println!( +// "Sending {} messages... {:?} {}", +// MSG_COUNT, channel, msg_size +// ); +// for _ in 0..MSG_COUNT { +// client_transport.schedule(message.clone()).unwrap(); +// } + +// match channel.reliability { +// Reliability::Reliable => { +// ztimeout!(async { +// while router_handler.get_count() != MSG_COUNT { +// task::sleep(SLEEP_COUNT).await; +// } +// }); +// } +// Reliability::BestEffort => { +// ztimeout!(async { +// while router_handler.get_count() == 0 { +// task::sleep(SLEEP_COUNT).await; +// } +// }); +// } +// }; + +// // Wait a little bit +// task::sleep(SLEEP).await; +// } + +// async fn run_single( +// client_endpoints: &[EndPoint], +// server_endpoints: &[EndPoint], +// channel: Channel, +// msg_size: usize, +// ) { +// println!( +// "\n>>> Running test for: {:?}, {:?}, {:?}, {}", +// client_endpoints, server_endpoints, channel, msg_size +// ); + +// #[allow(unused_variables)] // Used when stats feature is enabled +// let (router_manager, router_handler, client_manager, client_transport) = +// open_transport(client_endpoints, server_endpoints).await; + +// test_transport( +// router_handler.clone(), +// client_transport.clone(), +// channel, +// msg_size, +// ) +// .await; + +// #[cfg(feature = "stats")] +// { +// let c_stats = client_transport.get_stats().unwrap(); +// println!("\tClient: {:?}", c_stats); +// let r_stats = router_manager +// .get_transport_unicast(&client_manager.config.zid) +// .unwrap() +// .get_stats() +// .unwrap(); +// println!("\tRouter: {:?}", r_stats); +// } + +// close_transport( +// router_manager, +// client_manager, +// client_transport, +// client_endpoints, +// ) +// .await; +// } + +// async fn run( +// client_endpoints: &[EndPoint], +// server_endpoints: &[EndPoint], +// channel: &[Channel], +// msg_size: &[usize], +// ) { +// for ch in channel.iter() { +// for ms in msg_size.iter() { +// run_single(client_endpoints, server_endpoints, *ch, *ms).await; +// } +// } +// } + +// #[cfg(feature = "transport_tcp")] +// #[test] +// fn transport_unicast_tcp_only() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // Define the locators +// let endpoints: Vec = vec![ +// format!("tcp/127.0.0.1:{}", 16000).parse().unwrap(), +// format!("tcp/[::1]:{}", 16001).parse().unwrap(), +// ]; +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +// } + +// #[cfg(feature = "transport_udp")] +// #[test] +// fn transport_unicast_udp_only() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // Define the locator +// let endpoints: Vec = vec![ +// format!("udp/127.0.0.1:{}", 16010).parse().unwrap(), +// format!("udp/[::1]:{}", 16011).parse().unwrap(), +// ]; +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); +// } + +// #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] +// #[test] +// fn transport_unicast_unix_only() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let f1 = "zenoh-test-unix-socket-5.sock"; +// let _ = std::fs::remove_file(f1); +// // Define the locator +// let endpoints: Vec = vec![format!("unixsock-stream/{f1}").parse().unwrap()]; +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +// let _ = std::fs::remove_file(f1); +// let _ = std::fs::remove_file(format!("{f1}.lock")); +// } + +// #[cfg(feature = "transport_ws")] +// #[test] +// fn transport_unicast_ws_only() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // Define the locators +// let endpoints: Vec = vec![ +// format!("ws/127.0.0.1:{}", 16020).parse().unwrap(), +// format!("ws/[::1]:{}", 16021).parse().unwrap(), +// ]; +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +// } + +// #[cfg(all(feature = "transport_tcp", feature = "transport_udp"))] +// #[test] +// fn transport_unicast_tcp_udp() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // Define the locator +// let endpoints: Vec = vec![ +// format!("tcp/127.0.0.1:{}", 16030).parse().unwrap(), +// format!("udp/127.0.0.1:{}", 16031).parse().unwrap(), +// format!("tcp/[::1]:{}", 16032).parse().unwrap(), +// format!("udp/[::1]:{}", 16033).parse().unwrap(), +// ]; +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); +// } + +// #[cfg(all( +// feature = "transport_tcp", +// feature = "transport_unixsock-stream", +// target_family = "unix" +// ))] +// #[test] +// fn transport_unicast_tcp_unix() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let f1 = "zenoh-test-unix-socket-6.sock"; +// let _ = std::fs::remove_file(f1); +// // Define the locator +// let endpoints: Vec = vec![ +// format!("tcp/127.0.0.1:{}", 16040).parse().unwrap(), +// format!("tcp/[::1]:{}", 16041).parse().unwrap(), +// format!("unixsock-stream/{f1}").parse().unwrap(), +// ]; +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +// let _ = std::fs::remove_file(f1); +// let _ = std::fs::remove_file(format!("{f1}.lock")); +// } + +// #[cfg(all( +// feature = "transport_udp", +// feature = "transport_unixsock-stream", +// target_family = "unix" +// ))] +// #[test] +// fn transport_unicast_udp_unix() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let f1 = "zenoh-test-unix-socket-7.sock"; +// let _ = std::fs::remove_file(f1); +// // Define the locator +// let endpoints: Vec = vec![ +// format!("udp/127.0.0.1:{}", 16050).parse().unwrap(), +// format!("udp/[::1]:{}", 16051).parse().unwrap(), +// format!("unixsock-stream/{f1}").parse().unwrap(), +// ]; +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); +// let _ = std::fs::remove_file(f1); +// let _ = std::fs::remove_file(format!("{f1}.lock")); +// } + +// #[cfg(all( +// feature = "transport_tcp", +// feature = "transport_udp", +// feature = "transport_unixsock-stream", +// target_family = "unix" +// ))] +// #[test] +// fn transport_unicast_tcp_udp_unix() { +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let f1 = "zenoh-test-unix-socket-8.sock"; +// let _ = std::fs::remove_file(f1); +// // Define the locator +// let endpoints: Vec = vec![ +// format!("tcp/127.0.0.1:{}", 16060).parse().unwrap(), +// format!("udp/127.0.0.1:{}", 16061).parse().unwrap(), +// format!("tcp/[::1]:{}", 16062).parse().unwrap(), +// format!("udp/[::1]:{}", 16063).parse().unwrap(), +// format!("unixsock-stream/{f1}").parse().unwrap(), +// ]; +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); +// let _ = std::fs::remove_file(f1); +// let _ = std::fs::remove_file(format!("{f1}.lock")); +// } + +// #[cfg(all(feature = "transport_tls", target_family = "unix"))] +// #[test] +// fn transport_unicast_tls_only_server() { +// use zenoh_link::tls::config::*; + +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // Define the locator +// let mut endpoint: EndPoint = format!("tls/localhost:{}", 16070).parse().unwrap(); +// endpoint +// .config_mut() +// .extend( +// [ +// (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), +// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), +// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), +// ] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); + +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// let endpoints = vec![endpoint]; +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +// } + +// #[cfg(feature = "transport_quic")] +// #[test] +// fn transport_unicast_quic_only_server() { +// use zenoh_link::quic::config::*; + +// let _ = env_logger::try_init(); +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // Define the locator +// let mut endpoint: EndPoint = format!("quic/localhost:{}", 16080).parse().unwrap(); +// endpoint +// .config_mut() +// .extend( +// [ +// (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), +// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), +// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), +// ] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); + +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// let endpoints = vec![endpoint]; +// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +// } + +// #[cfg(all(feature = "transport_tls", target_family = "unix"))] +// #[test] +// fn transport_unicast_tls_only_mutual_success() { +// use zenoh_link::tls::config::*; + +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let client_auth = "true"; + +// // Define the locator +// let mut client_endpoint: EndPoint = ("tls/localhost:10461").parse().unwrap(); +// client_endpoint +// .config_mut() +// .extend( +// [ +// (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), +// (TLS_CLIENT_CERTIFICATE_RAW, CLIENT_CERT), +// (TLS_CLIENT_PRIVATE_KEY_RAW, CLIENT_KEY), +// (TLS_CLIENT_AUTH, client_auth), +// ] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); + +// // Define the locator +// let mut server_endpoint: EndPoint = ("tls/localhost:10461").parse().unwrap(); +// server_endpoint +// .config_mut() +// .extend( +// [ +// (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), +// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), +// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), +// (TLS_CLIENT_AUTH, client_auth), +// ] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// let client_endpoints = vec![client_endpoint]; +// let server_endpoints = vec![server_endpoint]; +// task::block_on(run( +// &client_endpoints, +// &server_endpoints, +// &channel, +// &MSG_SIZE_ALL, +// )); +// } + +// // Constants replicating the alert descriptions thrown by the Rustls library. +// // These alert descriptions are internal of the library and cannot be reached from these tests +// // as to do a proper comparison. For the sake of simplicity we verify these constants are contained +// // in the expected error messages from the tests below. +// // +// // See: https://docs.rs/rustls/latest/src/rustls/msgs/enums.rs.html#128 +// #[cfg(all(feature = "transport_tls", target_family = "unix"))] +// const RUSTLS_UNKNOWN_CA_ALERT_DESCRIPTION: &str = "UnknownCA"; +// #[cfg(all(feature = "transport_tls", target_family = "unix"))] +// const RUSTLS_CERTIFICATE_REQUIRED_ALERT_DESCRIPTION: &str = "CertificateRequired"; + +// #[cfg(all(feature = "transport_tls", target_family = "unix"))] +// #[test] +// fn transport_unicast_tls_only_mutual_no_client_certs_failure() { +// use std::vec; + +// use zenoh_link::tls::config::*; + +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// // Define the locator +// let mut client_endpoint: EndPoint = ("tls/localhost:10462").parse().unwrap(); +// client_endpoint +// .config_mut() +// .extend( +// [(TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA)] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); + +// // Define the locator +// let mut server_endpoint: EndPoint = ("tls/localhost:10462").parse().unwrap(); +// server_endpoint +// .config_mut() +// .extend( +// [ +// (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), +// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), +// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), +// (TLS_CLIENT_AUTH, "true"), +// ] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// let client_endpoints = vec![client_endpoint]; +// let server_endpoints = vec![server_endpoint]; +// let result = std::panic::catch_unwind(|| { +// task::block_on(run( +// &client_endpoints, +// &server_endpoints, +// &channel, +// &MSG_SIZE_ALL, +// )) +// }); +// assert!(result.is_err()); +// let err = result.unwrap_err(); +// let error_msg = panic_message::panic_message(&err); +// assert!(error_msg.contains(RUSTLS_CERTIFICATE_REQUIRED_ALERT_DESCRIPTION)); +// } + +// #[cfg(all(feature = "transport_tls", target_family = "unix"))] +// #[test] +// fn transport_unicast_tls_only_mutual_wrong_client_certs_failure() { +// use zenoh_link::tls::config::*; + +// task::block_on(async { +// zasync_executor_init!(); +// }); + +// let client_auth = "true"; + +// // Define the locator +// let mut client_endpoint: EndPoint = ("tls/localhost:10463").parse().unwrap(); +// client_endpoint +// .config_mut() +// .extend( +// [ +// (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), +// // Using the SERVER_CERT and SERVER_KEY in the client to simulate the case the client has +// // wrong certificates and keys. The SERVER_CA (cetificate authority) will not recognize +// // these certificates as it is expecting to receive CLIENT_CERT and CLIENT_KEY from the +// // client. +// (TLS_CLIENT_CERTIFICATE_RAW, SERVER_CERT), +// (TLS_CLIENT_PRIVATE_KEY_RAW, SERVER_KEY), +// (TLS_CLIENT_AUTH, client_auth), +// ] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); + +// // Define the locator +// let mut server_endpoint: EndPoint = ("tls/localhost:10463").parse().unwrap(); +// server_endpoint +// .config_mut() +// .extend( +// [ +// (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), +// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), +// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), +// (TLS_CLIENT_AUTH, client_auth), +// ] +// .iter() +// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), +// ) +// .unwrap(); +// // Define the reliability and congestion control +// let channel = [ +// Channel { +// priority: Priority::default(), +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::default(), +// reliability: Reliability::BestEffort, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::Reliable, +// }, +// Channel { +// priority: Priority::RealTime, +// reliability: Reliability::BestEffort, +// }, +// ]; +// // Run +// let client_endpoints = vec![client_endpoint]; +// let server_endpoints = vec![server_endpoint]; +// let result = std::panic::catch_unwind(|| { +// task::block_on(run( +// &client_endpoints, +// &server_endpoints, +// &channel, +// &MSG_SIZE_ALL, +// )) +// }); +// assert!(result.is_err()); +// let err = result.unwrap_err(); +// let error_msg = panic_message::panic_message(&err); +// assert!(error_msg.contains(RUSTLS_UNKNOWN_CA_ALERT_DESCRIPTION)); +// } diff --git a/zenoh/src/admin.rs b/zenoh/src/admin.rs index 9f00bbae71..3cc6c01861 100644 --- a/zenoh/src/admin.rs +++ b/zenoh/src/admin.rs @@ -26,7 +26,8 @@ use crate::{ use zenoh_core::SyncResolve; use zenoh_protocol::{ core::{Encoding, KnownEncoding, WireExpr}, - zenoh::{DataInfo, SampleKind, ZenohMessage}, + network::NetworkMessage, + zenoh::{DataInfo, SampleKind}, }; use zenoh_transport::{TransportEventHandler, TransportPeerEventHandler}; @@ -148,7 +149,7 @@ pub(crate) struct PeerHandler { } impl TransportPeerEventHandler for PeerHandler { - fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { + fn handle_message(&self, _msg: NetworkMessage) -> ZResult<()> { Ok(()) } diff --git a/zenoh/src/key_expr.rs b/zenoh/src/key_expr.rs index 2cd105c167..0653afa1ac 100644 --- a/zenoh/src/key_expr.rs +++ b/zenoh/src/key_expr.rs @@ -21,7 +21,10 @@ use std::{ }; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; pub use zenoh_protocol::core::key_expr::*; -use zenoh_protocol::core::{key_expr::canon::Canonizable, ExprId, WireExpr}; +use zenoh_protocol::{ + core::{key_expr::canon::Canonizable, ExprId, WireExpr}, + network::{declare, DeclareBody, UndeclareKeyExpr}, +}; use zenoh_result::ZResult; use zenoh_transport::Primitives; @@ -594,7 +597,12 @@ impl SyncResolve for KeyExprUndeclaration<'_> { let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); - primitives.forget_resource(expr_id); + primitives.send_declare(zenoh_protocol::network::Declare { + ext_qos: declare::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::default(), + body: DeclareBody::UndeclareKeyExpr(UndeclareKeyExpr { id: expr_id }), + }); Ok(()) } diff --git a/zenoh/src/liveliness.rs b/zenoh/src/liveliness.rs index ea7bcfa9bf..082975f57f 100644 --- a/zenoh/src/liveliness.rs +++ b/zenoh/src/liveliness.rs @@ -36,7 +36,7 @@ use { zenoh_core::Resolvable, zenoh_core::Result as ZResult, zenoh_core::SyncResolve, - zenoh_protocol::zenoh::SubInfo, + zenoh_protocol::network::subscriber::ext::SubscriberInfo, }; #[zenoh_macros::unstable] @@ -544,7 +544,7 @@ where &Some(KeyExpr::from(*KE_PREFIX_LIVELINESS)), Locality::default(), callback, - &SubInfo::default(), + &SubscriberInfo::default(), ) .map(|sub_state| Subscriber { subscriber: SubscriberInner { diff --git a/zenoh/src/net/mod.rs b/zenoh/src/net/mod.rs index da063eb750..b0b4be3f14 100644 --- a/zenoh/src/net/mod.rs +++ b/zenoh/src/net/mod.rs @@ -18,6 +18,10 @@ //! //! [Click here for Zenoh's documentation](../zenoh/index.html) #[doc(hidden)] +pub(crate) mod codec; +#[doc(hidden)] +pub(crate) mod protocol; +#[doc(hidden)] pub(crate) mod routing; #[doc(hidden)] pub mod runtime; diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index 4c97fd19e9..064ed1f75f 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -15,14 +15,10 @@ use super::router::*; use std::collections::{HashMap, HashSet}; use std::fmt; use std::sync::Arc; -use zenoh_buffers::ZBuf; -use zenoh_protocol::{ - core::{Channel, CongestionControl, ExprId, WhatAmI, WireExpr, ZenohId}, - zenoh::{ - ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, - RoutingContext, SubInfo, - }, -}; +use zenoh_protocol::core::{ExprId, WhatAmI, ZenohId}; +use zenoh_protocol::network::queryable::ext::QueryableInfo; +use zenoh_protocol::network::{Push, Request, RequestId, Response, ResponseFinal}; +use zenoh_protocol::zenoh_new::RequestBody; use zenoh_transport::Primitives; pub struct FaceState { @@ -37,8 +33,8 @@ pub struct FaceState { pub(super) remote_subs: HashSet>, pub(super) local_qabls: HashMap, QueryableInfo>, pub(super) remote_qabls: HashSet>, - pub(super) next_qid: QueryId, - pub(super) pending_queries: HashMap>, + pub(super) next_qid: RequestId, + pub(super) pending_queries: HashMap>, } impl FaceState { @@ -83,69 +79,45 @@ impl FaceState { id } - pub(super) fn get_router( - &self, - tables: &Tables, - routing_context: Option, - ) -> Option { - match routing_context { - Some(routing_context) => { - match tables.routers_net.as_ref().unwrap().get_link(self.link_id) { - Some(link) => match link.get_zid(&routing_context.tree_id) { - Some(router) => Some(*router), - None => { - log::error!( - "Received router declaration with unknown routing context id {}", - routing_context.tree_id - ); - None - } - }, - None => { - log::error!( - "Could not find corresponding link in routers network for {}", - self - ); - None - } + pub(super) fn get_router(&self, tables: &Tables, nodeid: &u64) -> Option { + match tables.routers_net.as_ref().unwrap().get_link(self.link_id) { + Some(link) => match link.get_zid(nodeid) { + Some(router) => Some(*router), + None => { + log::error!( + "Received router declaration with unknown routing context id {}", + nodeid + ); + None } - } + }, None => { - log::error!("Received router declaration with no routing context"); + log::error!( + "Could not find corresponding link in routers network for {}", + self + ); None } } } - pub(super) fn get_peer( - &self, - tables: &Tables, - routing_context: Option, - ) -> Option { - match routing_context { - Some(routing_context) => { - match tables.peers_net.as_ref().unwrap().get_link(self.link_id) { - Some(link) => match link.get_zid(&routing_context.tree_id) { - Some(router) => Some(*router), - None => { - log::error!( - "Received peer declaration with unknown routing context id {}", - routing_context.tree_id - ); - None - } - }, - None => { - log::error!( - "Could not find corresponding link in peers network for {}", - self - ); - None - } + pub(super) fn get_peer(&self, tables: &Tables, nodeid: &u64) -> Option { + match tables.peers_net.as_ref().unwrap().get_link(self.link_id) { + Some(link) => match link.get_zid(nodeid) { + Some(router) => Some(*router), + None => { + log::error!( + "Received peer declaration with unknown routing context id {}", + nodeid + ); + None } - } + }, None => { - log::error!("Received peer declaration with no routing context"); + log::error!( + "Could not find corresponding link in peers network for {}", + self + ); None } } @@ -165,304 +137,280 @@ pub struct Face { } impl Primitives for Face { - fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { + fn send_declare(&self, msg: zenoh_protocol::network::Declare) { let ctrl_lock = zlock!(self.tables.ctrl_lock); - register_expr(&self.tables, &mut self.state.clone(), expr_id, key_expr); - drop(ctrl_lock); - } - - fn forget_resource(&self, expr_id: ExprId) { - let ctrl_lock = zlock!(self.tables.ctrl_lock); - unregister_expr(&self.tables, &mut self.state.clone(), expr_id); - drop(ctrl_lock); - } - - fn decl_subscriber( - &self, - key_expr: &WireExpr, - sub_info: &SubInfo, - routing_context: Option, - ) { - let ctrl_lock = zlock!(self.tables.ctrl_lock); - let rtables = zread!(self.tables.tables); - match (rtables.whatami, self.state.whatami) { - (WhatAmI::Router, WhatAmI::Router) => { - if let Some(router) = self.state.get_router(&rtables, routing_context) { - declare_router_subscription( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - sub_info, - router, - ); - } + match msg.body { + zenoh_protocol::network::DeclareBody::DeclareKeyExpr(m) => { + register_expr(&self.tables, &mut self.state.clone(), m.id, &m.wire_expr); } - (WhatAmI::Router, WhatAmI::Peer) - | (WhatAmI::Peer, WhatAmI::Router) - | (WhatAmI::Peer, WhatAmI::Peer) => { - if rtables.full_net(WhatAmI::Peer) { - if let Some(peer) = self.state.get_peer(&rtables, routing_context) { - declare_peer_subscription( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - sub_info, - peer, - ); - } - } else { - declare_client_subscription( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - sub_info, - ); - } - } - _ => { - declare_client_subscription( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - sub_info, - ); - } - } - drop(ctrl_lock); - } - - fn forget_subscriber(&self, key_expr: &WireExpr, routing_context: Option) { - let ctrl_lock = zlock!(self.tables.ctrl_lock); - let rtables = zread!(self.tables.tables); - match (rtables.whatami, self.state.whatami) { - (WhatAmI::Router, WhatAmI::Router) => { - if let Some(router) = self.state.get_router(&rtables, routing_context) { - forget_router_subscription( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - &router, - ) - } + zenoh_protocol::network::DeclareBody::UndeclareKeyExpr(m) => { + unregister_expr(&self.tables, &mut self.state.clone(), m.id); } - (WhatAmI::Router, WhatAmI::Peer) - | (WhatAmI::Peer, WhatAmI::Router) - | (WhatAmI::Peer, WhatAmI::Peer) => { - if rtables.full_net(WhatAmI::Peer) { - if let Some(peer) = self.state.get_peer(&rtables, routing_context) { - forget_peer_subscription( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - &peer, - ) + zenoh_protocol::network::DeclareBody::DeclareSubscriber(m) => { + let rtables = zread!(self.tables.tables); + match (rtables.whatami, self.state.whatami) { + (WhatAmI::Router, WhatAmI::Router) => { + if let Some(router) = self + .state + .get_router(&rtables, &(msg.ext_nodeid.node_id as u64)) + { + declare_router_subscription( + &self.tables, + rtables, + &mut self.state.clone(), + &m.wire_expr, + &m.ext_info, + router, + ) + } } - } else { - forget_client_subscription( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - ) - } - } - _ => { - forget_client_subscription(&self.tables, rtables, &mut self.state.clone(), key_expr) - } - } - drop(ctrl_lock); - } - - fn decl_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} - - fn forget_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} - - fn decl_queryable( - &self, - key_expr: &WireExpr, - qabl_info: &QueryableInfo, - routing_context: Option, - ) { - let ctrl_lock = zlock!(self.tables.ctrl_lock); - let rtables = zread!(self.tables.tables); - match (rtables.whatami, self.state.whatami) { - (WhatAmI::Router, WhatAmI::Router) => { - if let Some(router) = self.state.get_router(&rtables, routing_context) { - declare_router_queryable( + (WhatAmI::Router, WhatAmI::Peer) + | (WhatAmI::Peer, WhatAmI::Router) + | (WhatAmI::Peer, WhatAmI::Peer) => { + if rtables.full_net(WhatAmI::Peer) { + if let Some(peer) = self + .state + .get_peer(&rtables, &(msg.ext_nodeid.node_id as u64)) + { + declare_peer_subscription( + &self.tables, + rtables, + &mut self.state.clone(), + &m.wire_expr, + &m.ext_info, + peer, + ) + } + } else { + declare_client_subscription( + &self.tables, + rtables, + &mut self.state.clone(), + &m.wire_expr, + &m.ext_info, + ) + } + } + _ => declare_client_subscription( &self.tables, rtables, &mut self.state.clone(), - key_expr, - qabl_info, - router, - ) + &m.wire_expr, + &m.ext_info, + ), } } - (WhatAmI::Router, WhatAmI::Peer) - | (WhatAmI::Peer, WhatAmI::Router) - | (WhatAmI::Peer, WhatAmI::Peer) => { - if rtables.full_net(WhatAmI::Peer) { - if let Some(peer) = self.state.get_peer(&rtables, routing_context) { - declare_peer_queryable( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - qabl_info, - peer, - ) + zenoh_protocol::network::DeclareBody::UndeclareSubscriber(m) => { + let rtables = zread!(self.tables.tables); + match (rtables.whatami, self.state.whatami) { + (WhatAmI::Router, WhatAmI::Router) => { + if let Some(router) = self + .state + .get_router(&rtables, &(msg.ext_nodeid.node_id as u64)) + { + forget_router_subscription( + &self.tables, + rtables, + &mut self.state.clone(), + &m.ext_wire_expr.wire_expr, + &router, + ) + } } - } else { - declare_client_queryable( + (WhatAmI::Router, WhatAmI::Peer) + | (WhatAmI::Peer, WhatAmI::Router) + | (WhatAmI::Peer, WhatAmI::Peer) => { + if rtables.full_net(WhatAmI::Peer) { + if let Some(peer) = self + .state + .get_peer(&rtables, &(msg.ext_nodeid.node_id as u64)) + { + forget_peer_subscription( + &self.tables, + rtables, + &mut self.state.clone(), + &m.ext_wire_expr.wire_expr, + &peer, + ) + } + } else { + forget_client_subscription( + &self.tables, + rtables, + &mut self.state.clone(), + &m.ext_wire_expr.wire_expr, + ) + } + } + _ => forget_client_subscription( &self.tables, rtables, &mut self.state.clone(), - key_expr, - qabl_info, - ) + &m.ext_wire_expr.wire_expr, + ), } } - _ => declare_client_queryable( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - qabl_info, - ), - } - drop(ctrl_lock); - } - - fn forget_queryable(&self, key_expr: &WireExpr, routing_context: Option) { - let ctrl_lock = zlock!(self.tables.ctrl_lock); - let rtables = zread!(self.tables.tables); - match (rtables.whatami, self.state.whatami) { - (WhatAmI::Router, WhatAmI::Router) => { - if let Some(router) = self.state.get_router(&rtables, routing_context) { - forget_router_queryable( + zenoh_protocol::network::DeclareBody::DeclareQueryable(m) => { + let rtables = zread!(self.tables.tables); + match (rtables.whatami, self.state.whatami) { + (WhatAmI::Router, WhatAmI::Router) => { + if let Some(router) = self + .state + .get_router(&rtables, &(msg.ext_nodeid.node_id as u64)) + { + declare_router_queryable( + &self.tables, + rtables, + &mut self.state.clone(), + &m.wire_expr, + &m.ext_info, + router, + ) + } + } + (WhatAmI::Router, WhatAmI::Peer) + | (WhatAmI::Peer, WhatAmI::Router) + | (WhatAmI::Peer, WhatAmI::Peer) => { + if rtables.full_net(WhatAmI::Peer) { + if let Some(peer) = self + .state + .get_peer(&rtables, &(msg.ext_nodeid.node_id as u64)) + { + declare_peer_queryable( + &self.tables, + rtables, + &mut self.state.clone(), + &m.wire_expr, + &m.ext_info, + peer, + ) + } + } else { + declare_client_queryable( + &self.tables, + rtables, + &mut self.state.clone(), + &m.wire_expr, + &m.ext_info, + ) + } + } + _ => declare_client_queryable( &self.tables, rtables, &mut self.state.clone(), - key_expr, - &router, - ) + &m.wire_expr, + &m.ext_info, + ), } } - (WhatAmI::Router, WhatAmI::Peer) - | (WhatAmI::Peer, WhatAmI::Router) - | (WhatAmI::Peer, WhatAmI::Peer) => { - if rtables.full_net(WhatAmI::Peer) { - if let Some(peer) = self.state.get_peer(&rtables, routing_context) { - forget_peer_queryable( - &self.tables, - rtables, - &mut self.state.clone(), - key_expr, - &peer, - ) + zenoh_protocol::network::DeclareBody::UndeclareQueryable(m) => { + let rtables = zread!(self.tables.tables); + match (rtables.whatami, self.state.whatami) { + (WhatAmI::Router, WhatAmI::Router) => { + if let Some(router) = self + .state + .get_router(&rtables, &(msg.ext_nodeid.node_id as u64)) + { + forget_router_queryable( + &self.tables, + rtables, + &mut self.state.clone(), + &m.ext_wire_expr.wire_expr, + &router, + ) + } } - } else { - forget_client_queryable( + (WhatAmI::Router, WhatAmI::Peer) + | (WhatAmI::Peer, WhatAmI::Router) + | (WhatAmI::Peer, WhatAmI::Peer) => { + if rtables.full_net(WhatAmI::Peer) { + if let Some(peer) = self + .state + .get_peer(&rtables, &(msg.ext_nodeid.node_id as u64)) + { + forget_peer_queryable( + &self.tables, + rtables, + &mut self.state.clone(), + &m.ext_wire_expr.wire_expr, + &peer, + ) + } + } else { + forget_client_queryable( + &self.tables, + rtables, + &mut self.state.clone(), + &m.ext_wire_expr.wire_expr, + ) + } + } + _ => forget_client_queryable( &self.tables, rtables, &mut self.state.clone(), - key_expr, - ) + &m.ext_wire_expr.wire_expr, + ), } } - _ => forget_client_queryable(&self.tables, rtables, &mut self.state.clone(), key_expr), + zenoh_protocol::network::DeclareBody::DeclareToken(_m) => todo!(), + zenoh_protocol::network::DeclareBody::UndeclareToken(_m) => todo!(), + zenoh_protocol::network::DeclareBody::DeclareInterest(_m) => todo!(), + zenoh_protocol::network::DeclareBody::FinalInterest(_m) => todo!(), + zenoh_protocol::network::DeclareBody::UndeclareInterest(_m) => todo!(), } drop(ctrl_lock); } - fn send_data( - &self, - key_expr: &WireExpr, - payload: ZBuf, - channel: Channel, - congestion_control: CongestionControl, - data_info: Option, - routing_context: Option, - ) { + fn send_push(&self, msg: Push) { full_reentrant_route_data( &self.tables.tables, &self.state, - key_expr, - channel, - congestion_control, - data_info, - payload, - routing_context, + &msg.wire_expr, + msg.ext_qos, + msg.payload, + msg.ext_nodeid.node_id as u64, ); } - fn send_query( - &self, - key_expr: &WireExpr, - parameters: &str, - qid: QueryId, - target: QueryTarget, - consolidation: ConsolidationMode, - body: Option, - routing_context: Option, - ) { - route_query( - &self.tables, - &self.state, - key_expr, - parameters, - qid, - target, - consolidation, - body, - routing_context, - ); + fn send_request(&self, msg: Request) { + match msg.payload { + RequestBody::Query(_) => { + route_query( + &self.tables, + &self.state, + &msg.wire_expr, + // parameters, + msg.id, + msg.ext_target, + // consolidation, + msg.payload, + msg.ext_nodeid.node_id as u64, + ); + } + RequestBody::Pull(_) => { + pull_data(&self.tables.tables, &self.state.clone(), msg.wire_expr); + } + _ => { + log::error!("Unsupported request"); + } + } } - fn send_reply_data( - &self, - qid: QueryId, - replier_id: ZenohId, - key_expr: WireExpr, - info: Option, - payload: ZBuf, - ) { - route_send_reply_data( + fn send_response(&self, msg: Response) { + route_send_response( &self.tables, &mut self.state.clone(), - qid, - replier_id, - key_expr, - info, - payload, + msg.rid, + msg.ext_respid, + msg.wire_expr, + msg.payload, ); } - fn send_reply_final(&self, qid: QueryId) { - route_send_reply_final(&self.tables, &mut self.state.clone(), qid); - } - - fn send_pull( - &self, - is_final: bool, - key_expr: &WireExpr, - pull_id: PullId, - max_samples: &Option, - ) { - pull_data( - &self.tables.tables, - &self.state.clone(), - is_final, - key_expr, - pull_id, - max_samples, - ); + fn send_response_final(&self, msg: ResponseFinal) { + route_send_response_final(&self.tables, &mut self.state.clone(), msg.rid); } fn send_close(&self) { diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index 92abcafe7e..3d6a5b94a0 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -1,3 +1,4 @@ +use crate::net::codec::Zenoh080Routing; // // Copyright (c) 2023 ZettaScale Technology // @@ -11,16 +12,20 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::runtime::Runtime; +use crate::net::protocol::linkstate::{LinkState, LinkStateList}; +use crate::net::protocol::OAM_LINKSTATE; +use crate::net::runtime::Runtime; use petgraph::graph::NodeIndex; use petgraph::visit::{IntoNodeReferences, VisitMap, Visitable}; use std::convert::TryInto; use vec_map::VecMap; +use zenoh_buffers::writer::{DidntWrite, HasWriter}; +use zenoh_buffers::ZBuf; +use zenoh_codec::WCodec; use zenoh_link::Locator; -use zenoh_protocol::{ - core::{WhatAmI, WhatAmIMatcher, ZenohId}, - zenoh::{LinkState, ZenohMessage}, -}; +use zenoh_protocol::common::ZExtBody; +use zenoh_protocol::core::{WhatAmI, WhatAmIMatcher, ZenohId}; +use zenoh_protocol::network::{oam, NetworkBody, NetworkMessage, Oam}; use zenoh_transport::TransportUnicast; #[derive(Clone)] @@ -184,8 +189,7 @@ impl Network { } #[inline] - pub(crate) fn get_local_context(&self, context: Option, link_id: usize) -> usize { - let context = context.unwrap_or(0); + pub(crate) fn get_local_context(&self, context: u64, link_id: usize) -> usize { match self.get_link(link_id) { Some(link) => match link.get_local_psid(&context) { Some(psid) => (*psid).try_into().unwrap_or(0), @@ -259,19 +263,32 @@ impl Network { } } - fn make_msg(&self, idxs: Vec<(NodeIndex, Details)>) -> ZenohMessage { - let mut list = vec![]; + fn make_msg(&self, idxs: Vec<(NodeIndex, Details)>) -> Result { + let mut link_states = vec![]; for (idx, details) in idxs { - list.push(self.make_link_state(idx, details)); + link_states.push(self.make_link_state(idx, details)); } - ZenohMessage::make_link_state_list(list) + let codec = Zenoh080Routing::new(); + let mut buf = ZBuf::empty(); + codec.write(&mut buf.writer(), &LinkStateList { link_states })?; + Ok(NetworkMessage { + body: NetworkBody::OAM(Oam { + id: OAM_LINKSTATE, + body: ZExtBody::ZBuf(buf), + ext_qos: oam::ext::QoSType::default(), + ext_tstamp: None, + }), + }) } fn send_on_link(&self, idxs: Vec<(NodeIndex, Details)>, transport: &TransportUnicast) { - let msg = self.make_msg(idxs); - log::trace!("{} Send to {:?} {:?}", self.name, transport.get_zid(), msg); - if let Err(e) = transport.handle_message(msg) { - log::debug!("{} Error sending LinkStateList: {}", self.name, e); + if let Ok(msg) = self.make_msg(idxs) { + log::trace!("{} Send to {:?} {:?}", self.name, transport.get_zid(), msg); + if let Err(e) = transport.handle_message(msg) { + log::debug!("{} Error sending LinkStateList: {}", self.name, e); + } + } else { + log::error!("Failed to encode Linkstate message"); } } @@ -279,14 +296,17 @@ impl Network { where P: FnMut(&Link) -> bool, { - let msg = self.make_msg(idxs); - for link in self.links.values() { - if parameters(link) { - log::trace!("{} Send to {} {:?}", self.name, link.zid, msg); - if let Err(e) = link.transport.handle_message(msg.clone()) { - log::debug!("{} Error sending LinkStateList: {}", self.name, e); + if let Ok(msg) = self.make_msg(idxs) { + for link in self.links.values() { + if parameters(link) { + log::trace!("{} Send to {} {:?}", self.name, link.zid, msg); + if let Err(e) = link.transport.handle_message(msg.clone()) { + log::debug!("{} Error sending LinkStateList: {}", self.name, e); + } } } + } else { + log::error!("Failed to encode Linkstate message"); } } diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index db77bffa86..af13955357 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -21,15 +21,18 @@ use std::collections::{HashMap, HashSet}; use std::convert::TryFrom; use std::sync::RwLock; use std::sync::{Arc, RwLockReadGuard}; -use zenoh_buffers::ZBuf; use zenoh_core::zread; use zenoh_protocol::core::key_expr::keyexpr; +use zenoh_protocol::network::common::ext::WireExprType; +use zenoh_protocol::network::declare::ext; +use zenoh_protocol::network::subscriber::ext::SubscriberInfo; +use zenoh_protocol::network::{ + Declare, DeclareBody, DeclareSubscriber, Mapping, Mode, Push, UndeclareSubscriber, +}; +use zenoh_protocol::zenoh_new::PushBody; use zenoh_protocol::{ - core::{ - key_expr::OwnedKeyExpr, Channel, CongestionControl, Priority, Reliability, WhatAmI, - WireExpr, ZenohId, - }, - zenoh::{DataInfo, PullId, RoutingContext, SubInfo, SubMode}, + core::{key_expr::OwnedKeyExpr, Reliability, WhatAmI, WireExpr, ZenohId}, + zenoh::RoutingContext, }; use zenoh_sync::get_mut_unchecked; @@ -40,7 +43,7 @@ fn send_sourced_subscription_to_net_childs( childs: &[NodeIndex], res: &Arc, src_face: Option<&Arc>, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, routing_context: Option, ) { for child in childs { @@ -52,9 +55,19 @@ fn send_sourced_subscription_to_net_childs( log::debug!("Send subscription {} on {}", res.expr(), someface); - someface - .primitives - .decl_subscriber(&key_expr, sub_info, routing_context); + someface.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { + node_id: routing_context.map(|c| c.tree_id).unwrap_or(0) as u16, + }, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: *sub_info, + }), + }); } } None => log::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -68,7 +81,7 @@ fn propagate_simple_subscription_to( tables: &mut Tables, dst_face: &mut Arc, res: &Arc, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, src_face: &mut Arc, full_peer_net: bool, ) { @@ -97,16 +110,24 @@ fn propagate_simple_subscription_to( { get_mut_unchecked(dst_face).local_subs.insert(res.clone()); let key_expr = Resource::decl_key(res, dst_face); - dst_face - .primitives - .decl_subscriber(&key_expr, sub_info, None); + dst_face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: *sub_info, + }), + }); } } fn propagate_simple_subscription( tables: &mut Tables, res: &Arc, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, src_face: &mut Arc, ) { let full_peer_net = tables.full_net(WhatAmI::Peer); @@ -130,7 +151,7 @@ fn propagate_simple_subscription( fn propagate_sourced_subscription( tables: &Tables, res: &Arc, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, src_face: Option<&Arc>, source: &ZenohId, net_type: WhatAmI, @@ -169,7 +190,7 @@ fn register_router_subscription( tables: &mut Tables, face: &mut Arc, res: &mut Arc, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, router: ZenohId, ) { if !res.context().router_subs.contains(&router) { @@ -204,7 +225,7 @@ pub fn declare_router_subscription( rtables: RwLockReadGuard, face: &mut Arc, expr: &WireExpr, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, router: ZenohId, ) { match rtables.get_mapping(face, &expr.scope).cloned() { @@ -256,7 +277,7 @@ fn register_peer_subscription( tables: &mut Tables, face: &mut Arc, res: &mut Arc, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, peer: ZenohId, ) { if !res.context().peer_subs.contains(&peer) { @@ -282,7 +303,7 @@ pub fn declare_peer_subscription( rtables: RwLockReadGuard, face: &mut Arc, expr: &WireExpr, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, peer: ZenohId, ) { match rtables.get_mapping(face, &expr.scope).cloned() { @@ -309,8 +330,8 @@ pub fn declare_peer_subscription( }; register_peer_subscription(&mut wtables, face, &mut res, sub_info, peer); if wtables.whatami == WhatAmI::Router { - let mut propa_sub_info = sub_info.clone(); - propa_sub_info.mode = SubMode::Push; + let mut propa_sub_info = *sub_info; + propa_sub_info.mode = Mode::Push; let zid = wtables.zid; register_router_subscription(&mut wtables, face, &mut res, &propa_sub_info, zid); } @@ -340,7 +361,7 @@ fn register_client_subscription( _tables: &mut Tables, face: &mut Arc, res: &mut Arc, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, ) { // Register subscription { @@ -349,12 +370,12 @@ fn register_client_subscription( match res.session_ctxs.get_mut(&face.id) { Some(ctx) => match &ctx.subs { Some(info) => { - if SubMode::Pull == info.mode { - get_mut_unchecked(ctx).subs = Some(sub_info.clone()); + if Mode::Pull == info.mode { + get_mut_unchecked(ctx).subs = Some(*sub_info); } } None => { - get_mut_unchecked(ctx).subs = Some(sub_info.clone()); + get_mut_unchecked(ctx).subs = Some(*sub_info); } }, None => { @@ -364,7 +385,7 @@ fn register_client_subscription( face: face.clone(), local_expr_id: None, remote_expr_id: None, - subs: Some(sub_info.clone()), + subs: Some(*sub_info), qabl: None, last_values: HashMap::new(), }), @@ -380,7 +401,7 @@ pub fn declare_client_subscription( rtables: RwLockReadGuard, face: &mut Arc, expr: &WireExpr, - sub_info: &SubInfo, + sub_info: &SubscriberInfo, ) { log::debug!("Register client subscription"); match rtables.get_mapping(face, &expr.scope).cloned() { @@ -407,8 +428,8 @@ pub fn declare_client_subscription( }; register_client_subscription(&mut wtables, face, &mut res, sub_info); - let mut propa_sub_info = sub_info.clone(); - propa_sub_info.mode = SubMode::Push; + let mut propa_sub_info = *sub_info; + propa_sub_info.mode = Mode::Push; match wtables.whatami { WhatAmI::Router => { let zid = wtables.zid; @@ -505,13 +526,24 @@ fn send_forget_sourced_subscription_to_net_childs( match tables.get_face(&net.graph[*child].zid).cloned() { Some(mut someface) => { if src_face.is_none() || someface.id != src_face.unwrap().id { - let key_expr = Resource::decl_key(res, &mut someface); + let wire_expr = Resource::decl_key(res, &mut someface); log::debug!("Send forget subscription {} on {}", res.expr(), someface); - someface - .primitives - .forget_subscriber(&key_expr, routing_context); + someface.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { + node_id: routing_context.map(|c| c.tree_id).unwrap_or(0) as u16, + }, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); } } None => log::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -523,9 +555,19 @@ fn send_forget_sourced_subscription_to_net_childs( fn propagate_forget_simple_subscription(tables: &mut Tables, res: &Arc) { for face in tables.faces.values_mut() { if face.local_subs.contains(res) { - let key_expr = Resource::get_best_key(res, "", face.id); - face.primitives.forget_subscriber(&key_expr, None); - + let wire_expr = Resource::get_best_key(res, "", face.id); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); get_mut_unchecked(face).local_subs.remove(res); } } @@ -552,8 +594,19 @@ fn propagate_forget_simple_subscription_to_peers(tables: &mut Tables, res: &Arc< && tables.failover_brokering(s.face.zid, face.zid))) }) { - let key_expr = Resource::get_best_key(res, "", face.id); - face.primitives.forget_subscriber(&key_expr, None); + let wire_expr = Resource::get_best_key(res, "", face.id); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); get_mut_unchecked(&mut face).local_subs.remove(res); } @@ -783,8 +836,19 @@ pub(crate) fn undeclare_client_subscription( && !(face.whatami == WhatAmI::Client && res.expr().starts_with(super::PREFIX_LIVELINESS)) { - let key_expr = Resource::get_best_key(res, "", face.id); - face.primitives.forget_subscriber(&key_expr, None); + let wire_expr = Resource::get_best_key(res, "", face.id); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); get_mut_unchecked(face).local_subs.remove(res); } @@ -826,9 +890,9 @@ pub fn forget_client_subscription( } pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { - let sub_info = SubInfo { + let sub_info = SubscriberInfo { reliability: Reliability::Reliable, // @TODO - mode: SubMode::Push, + mode: Mode::Push, }; match tables.whatami { WhatAmI::Router => { @@ -836,7 +900,17 @@ pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { for sub in &tables.router_subs { get_mut_unchecked(face).local_subs.insert(sub.clone()); let key_expr = Resource::decl_key(sub, face); - face.primitives.decl_subscriber(&key_expr, &sub_info, None); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: sub_info, + }), + }); } } else if face.whatami == WhatAmI::Peer && !tables.full_net(WhatAmI::Peer) { for sub in &tables.router_subs { @@ -851,7 +925,17 @@ pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { { get_mut_unchecked(face).local_subs.insert(sub.clone()); let key_expr = Resource::decl_key(sub, face); - face.primitives.decl_subscriber(&key_expr, &sub_info, None); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: sub_info, + }), + }); } } } @@ -862,7 +946,17 @@ pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { for sub in &tables.peer_subs { get_mut_unchecked(face).local_subs.insert(sub.clone()); let key_expr = Resource::decl_key(sub, face); - face.primitives.decl_subscriber(&key_expr, &sub_info, None); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: sub_info, + }), + }); } } } else { @@ -985,9 +1079,9 @@ pub(crate) fn pubsub_tree_change( }; for sub in subs { if *sub == tree_id { - let sub_info = SubInfo { + let sub_info = SubscriberInfo { reliability: Reliability::Reliable, // @TODO - mode: SubMode::Push, + mode: Mode::Push, }; send_sourced_subscription_to_net_childs( tables, @@ -1045,8 +1139,21 @@ pub(crate) fn pubsub_linkstate_change(tables: &mut Tables, zid: &ZenohId, links: }) }; if forget { - let key_expr = Resource::get_best_key(res, "", dst_face.id); - dst_face.primitives.forget_subscriber(&key_expr, None); + let wire_expr = Resource::get_best_key(res, "", dst_face.id); + dst_face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareSubscriber( + UndeclareSubscriber { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }, + ), + }); get_mut_unchecked(dst_face).local_subs.remove(res); } @@ -1054,13 +1161,21 @@ pub(crate) fn pubsub_linkstate_change(tables: &mut Tables, zid: &ZenohId, links: let dst_face = &mut get_mut_unchecked(ctx).face; get_mut_unchecked(dst_face).local_subs.insert(res.clone()); let key_expr = Resource::decl_key(res, dst_face); - let sub_info = SubInfo { + let sub_info = SubscriberInfo { reliability: Reliability::Reliable, // TODO - mode: SubMode::Push, + mode: Mode::Push, }; - dst_face - .primitives - .decl_subscriber(&key_expr, &sub_info, None); + dst_face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: sub_info, + }), + }); } } } @@ -1206,7 +1321,7 @@ fn compute_data_route( source_type == WhatAmI::Client || context.face.whatami == WhatAmI::Client } - } && subinfo.mode == SubMode::Push + } && subinfo.mode == Mode::Push { route.entry(*sid).or_insert_with(|| { let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, *sid); @@ -1238,7 +1353,7 @@ fn compute_matching_pulls(tables: &Tables, expr: &mut RoutingExpr) -> Arc { + ($hlc:expr, $payload:expr, $drop:expr) => { // if an HLC was configured (via Config.add_timestamp), // check DataInfo and add a timestamp if there isn't - match $hlc { - Some(hlc) => { - if let Some(mut data_info) = $info { - if let Some(ref ts) = data_info.timestamp { - // Timestamp is present; update HLC with it (possibly raising error if delta exceed) - match hlc.update_with_timestamp(ts) { - Ok(()) => Some(data_info), - Err(e) => { - if $drop { - log::error!( - "Error treating timestamp for received Data ({}). Drop it!", - e - ); - return; - } else { - data_info.timestamp = Some(hlc.new_timestamp()); - log::error!( - "Error treating timestamp for received Data ({}). Replace timestamp: {:?}", - e, - data_info.timestamp); - Some(data_info) - } + if let Some(hlc) = $hlc { + if let PushBody::Put(data) = &mut $payload { + if let Some(ref ts) = data.timestamp { + // Timestamp is present; update HLC with it (possibly raising error if delta exceed) + match hlc.update_with_timestamp(ts) { + Ok(()) => (), + Err(e) => { + if $drop { + log::error!( + "Error treating timestamp for received Data ({}). Drop it!", + e + ); + return; + } else { + data.timestamp = Some(hlc.new_timestamp()); + log::error!( + "Error treating timestamp for received Data ({}). Replace timestamp: {:?}", + e, + data.timestamp); } } - } else { - // Timestamp not present; add one - data_info.timestamp = Some(hlc.new_timestamp()); - log::trace!("Adding timestamp to DataInfo: {:?}", data_info.timestamp); - Some(data_info) } } else { - // No DataInfo; add one with a Timestamp - let data_info = DataInfo { - timestamp: Some(hlc.new_timestamp()), - ..Default::default() - }; - Some(data_info) + // Timestamp not present; add one + data.timestamp = Some(hlc.new_timestamp()); + log::trace!("Adding timestamp to DataInfo: {:?}", data.timestamp); } - }, - None => $info, + } } } } @@ -1463,14 +1566,13 @@ fn get_data_route( face: &FaceState, res: &Option>, expr: &mut RoutingExpr, - routing_context: Option, + routing_context: u64, ) -> Arc { match tables.whatami { WhatAmI::Router => match face.whatami { WhatAmI::Router => { let routers_net = tables.routers_net.as_ref().unwrap(); - let local_context = routers_net - .get_local_context(routing_context.map(|rc| rc.tree_id), face.link_id); + let local_context = routers_net.get_local_context(routing_context, face.link_id); res.as_ref() .and_then(|res| res.routers_data_route(local_context)) .unwrap_or_else(|| { @@ -1480,8 +1582,7 @@ fn get_data_route( WhatAmI::Peer => { if tables.full_net(WhatAmI::Peer) { let peers_net = tables.peers_net.as_ref().unwrap(); - let local_context = peers_net - .get_local_context(routing_context.map(|rc| rc.tree_id), face.link_id); + let local_context = peers_net.get_local_context(routing_context, face.link_id); res.as_ref() .and_then(|res| res.peers_data_route(local_context)) .unwrap_or_else(|| { @@ -1503,8 +1604,8 @@ fn get_data_route( match face.whatami { WhatAmI::Router | WhatAmI::Peer => { let peers_net = tables.peers_net.as_ref().unwrap(); - let local_context = peers_net - .get_local_context(routing_context.map(|rc| rc.tree_id), face.link_id); + let local_context = + peers_net.get_local_context(routing_context, face.link_id); res.as_ref() .and_then(|res| res.peers_data_route(local_context)) .unwrap_or_else(|| { @@ -1548,14 +1649,12 @@ macro_rules! cache_data { ( $matching_pulls:expr, $expr:expr, - $payload:expr, - $info:expr + $payload:expr ) => { for context in $matching_pulls.iter() { - get_mut_unchecked(&mut context.clone()).last_values.insert( - $expr.full_expr().to_string(), - ($info.clone(), $payload.clone()), - ); + get_mut_unchecked(&mut context.clone()) + .last_values + .insert($expr.full_expr().to_string(), $payload.clone()); } }; } @@ -1588,11 +1687,9 @@ pub fn full_reentrant_route_data( tables_ref: &RwLock, face: &FaceState, expr: &WireExpr, - channel: Channel, - congestion_control: CongestionControl, - info: Option, - payload: ZBuf, - routing_context: Option, + ext_qos: ext::QoSType, + mut payload: PushBody, + routing_context: u64, ) { let tables = zread!(tables_ref); match tables.get_mapping(face, &expr.scope).cloned() { @@ -1615,26 +1712,27 @@ pub fn full_reentrant_route_data( let matching_pulls = get_matching_pulls(&tables, &res, &mut expr); if !(route.is_empty() && matching_pulls.is_empty()) { - let data_info = - treat_timestamp!(&tables.hlc, info, tables.drop_future_timestamp); + treat_timestamp!(&tables.hlc, payload, tables.drop_future_timestamp); if route.len() == 1 && matching_pulls.len() == 0 { let (outface, key_expr, context) = route.values().next().unwrap(); if should_route(&tables, face, outface, &mut expr) { drop(tables); - outface.primitives.send_data( - key_expr, + outface.primitives.send_push(Push { + wire_expr: key_expr.into(), + mapping: Mapping::default(), // TODO + ext_qos, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { + node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, + }, payload, - channel, // @TODO: Need to check the active subscriptions to determine the right reliability value - congestion_control, - data_info, - *context, - ) + }) } } else { if !matching_pulls.is_empty() { let lock = zlock!(tables.pull_caches_lock); - cache_data!(matching_pulls, expr, payload, data_info); + cache_data!(matching_pulls, expr, payload); drop(lock); } @@ -1649,27 +1747,31 @@ pub fn full_reentrant_route_data( drop(tables); for (outface, key_expr, context) in route { - outface.primitives.send_data( - &key_expr, - payload.clone(), - channel, // @TODO: Need to check the active subscriptions to determine the right reliability value - congestion_control, - data_info.clone(), - context, - ) + outface.primitives.send_push(Push { + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { + node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, + }, + payload: payload.clone(), + }) } } else { drop(tables); for (outface, key_expr, context) in route.values() { if face.id != outface.id { - outface.primitives.send_data( - key_expr, - payload.clone(), - channel, // @TODO: Need to check the active subscriptions to determine the right reliability value - congestion_control, - data_info.clone(), - *context, - ) + outface.primitives.send_push(Push { + wire_expr: key_expr.into(), + mapping: Mapping::default(), // TODO + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { + node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, + }, + payload: payload.clone(), + }) } } } @@ -1683,14 +1785,7 @@ pub fn full_reentrant_route_data( } } -pub fn pull_data( - tables_ref: &RwLock, - face: &Arc, - _is_final: bool, - expr: &WireExpr, - _pull_id: PullId, - _max_samples: &Option, -) { +pub fn pull_data(tables_ref: &RwLock, face: &Arc, expr: WireExpr) { let tables = zread!(tables_ref); match tables.get_mapping(face, &expr.scope) { Some(prefix) => match Resource::get_resource(prefix, expr.suffix.as_ref()) { @@ -1698,8 +1793,8 @@ pub fn pull_data( let res = get_mut_unchecked(&mut res); match res.session_ctxs.get_mut(&face.id) { Some(ctx) => match &ctx.subs { - Some(subinfo) => { - let reliability = subinfo.reliability; + Some(_subinfo) => { + // let reliability = subinfo.reliability; let lock = zlock!(tables.pull_caches_lock); let route = get_mut_unchecked(ctx) .last_values @@ -1711,21 +1806,18 @@ pub fn pull_data( sample, ) }) - .collect::, ZBuf))>>(); + .collect::>(); drop(lock); drop(tables); - for (key_expr, (info, data)) in route { - face.primitives.send_data( - &key_expr, - data, - Channel { - priority: Priority::default(), // @TODO: Default value for the time being - reliability, - }, - CongestionControl::default(), // @TODO: Default value for the time being - info, - None, - ); + for (key_expr, payload) in route { + face.primitives.send_push(Push { + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_qos: ext::QoSType::default(), // TODO + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload, + }); } } None => { diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 4314c57b75..6a01320afe 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -26,6 +26,17 @@ use std::convert::TryFrom; use std::sync::{Arc, RwLockReadGuard, Weak}; use zenoh_buffers::ZBuf; use zenoh_protocol::core::key_expr::keyexpr; +use zenoh_protocol::core::Encoding; +use zenoh_protocol::network::common::ext::WireExprType; +use zenoh_protocol::network::declare::ext; +use zenoh_protocol::network::request::ext::TargetType; +use zenoh_protocol::network::response::ext::ResponderIdType; +use zenoh_protocol::network::{ + response, Declare, DeclareBody, DeclareQueryable, Mapping, Request, RequestId, Response, + ResponseFinal, UndeclareQueryable, +}; +use zenoh_protocol::zenoh_new::reply::ext::ConsolidationType; +use zenoh_protocol::zenoh_new::{self, RequestBody, ResponseBody}; use zenoh_protocol::{ core::{ key_expr::{ @@ -34,9 +45,8 @@ use zenoh_protocol::{ }, WhatAmI, WireExpr, ZenohId, }, - zenoh::{ - ConsolidationMode, DataInfo, QueryBody, QueryId, QueryTarget, QueryableInfo, RoutingContext, - }, + network::queryable::ext::QueryableInfo, + zenoh::{QueryId, RoutingContext}, }; use zenoh_sync::get_mut_unchecked; use zenoh_util::Timed; @@ -57,7 +67,7 @@ fn merge_qabl_infos(mut this: QueryableInfo, info: &QueryableInfo) -> QueryableI #[cfg(not(feature = "complete_n"))] #[inline] fn merge_qabl_infos(mut this: QueryableInfo, info: &QueryableInfo) -> QueryableInfo { - this.complete = u64::from(this.complete != 0 || info.complete != 0); + this.complete = u8::from(this.complete != 0 || info.complete != 0); this.distance = std::cmp::min(this.distance, info.distance); this } @@ -69,7 +79,7 @@ fn local_router_qabl_info(tables: &Tables, res: &Arc) -> QueryableInfo if *zid != tables.zid { Some(match accu { Some(accu) => merge_qabl_infos(accu, info), - None => info.clone(), + None => *info, }) } else { accu @@ -85,7 +95,7 @@ fn local_router_qabl_info(tables: &Tables, res: &Arc) -> QueryableInfo if let Some(info) = ctx.qabl.as_ref() { Some(match accu { Some(accu) => merge_qabl_infos(accu, info), - None => info.clone(), + None => *info, }) } else { accu @@ -106,7 +116,7 @@ fn local_peer_qabl_info(tables: &Tables, res: &Arc) -> QueryableInfo { if *zid != tables.zid { Some(match accu { Some(accu) => merge_qabl_infos(accu, info), - None => info.clone(), + None => *info, }) } else { accu @@ -121,7 +131,7 @@ fn local_peer_qabl_info(tables: &Tables, res: &Arc) -> QueryableInfo { if let Some(info) = ctx.qabl.as_ref() { Some(match accu { Some(accu) => merge_qabl_infos(accu, info), - None => info.clone(), + None => *info, }) } else { accu @@ -142,7 +152,7 @@ fn local_qabl_info(tables: &Tables, res: &Arc, face: &Arc) if *zid != tables.zid { Some(match accu { Some(accu) => merge_qabl_infos(accu, info), - None => info.clone(), + None => *info, }) } else { accu @@ -160,7 +170,7 @@ fn local_qabl_info(tables: &Tables, res: &Arc, face: &Arc) if *zid != tables.zid { Some(match accu { Some(accu) => merge_qabl_infos(accu, info), - None => info.clone(), + None => *info, }) } else { accu @@ -177,7 +187,7 @@ fn local_qabl_info(tables: &Tables, res: &Arc, face: &Arc) if let Some(info) = ctx.qabl.as_ref() { Some(match accu { Some(accu) => merge_qabl_infos(accu, info), - None => info.clone(), + None => *info, }) } else { accu @@ -212,9 +222,19 @@ fn send_sourced_queryable_to_net_childs( log::debug!("Send queryable {} on {}", res.expr(), someface); - someface - .primitives - .decl_queryable(&key_expr, qabl_info, routing_context); + someface.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { + node_id: routing_context.map(|c| c.tree_id).unwrap_or(0) as u16, + }, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: *qabl_info, + }), + }); } } None => log::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -268,9 +288,19 @@ fn propagate_simple_queryable( { get_mut_unchecked(&mut dst_face) .local_qabls - .insert(res.clone(), info.clone()); + .insert(res.clone(), info); let key_expr = Resource::decl_key(res, &mut dst_face); - dst_face.primitives.decl_queryable(&key_expr, &info, None); + dst_face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: info, + }), + }); } } } @@ -332,7 +362,7 @@ fn register_router_queryable( get_mut_unchecked(res) .context_mut() .router_qabls - .insert(router, qabl_info.clone()); + .insert(router, *qabl_info); tables.router_qabls.insert(res.clone()); } @@ -378,6 +408,7 @@ pub fn declare_router_queryable( } else { let mut fullexpr = prefix.expr(); fullexpr.push_str(expr.suffix.as_ref()); + log::debug!("Register router queryable {}", fullexpr); let mut matches = keyexpr::new(fullexpr.as_str()) .map(|ke| Resource::get_matches(&rtables, ke)) .unwrap_or_default(); @@ -424,7 +455,7 @@ fn register_peer_queryable( get_mut_unchecked(res) .context_mut() .peer_qabls - .insert(peer, qabl_info.clone()); + .insert(peer, *qabl_info); tables.peer_qabls.insert(res.clone()); } @@ -464,6 +495,7 @@ pub fn declare_peer_queryable( } else { let mut fullexpr = prefix.expr(); fullexpr.push_str(expr.suffix.as_ref()); + log::debug!("Register peer queryable {}", fullexpr); let mut matches = keyexpr::new(fullexpr.as_str()) .map(|ke| Resource::get_matches(&rtables, ke)) .unwrap_or_default(); @@ -521,7 +553,7 @@ fn register_client_queryable( last_values: HashMap::new(), }) })) - .qabl = Some(qabl_info.clone()); + .qabl = Some(*qabl_info); } get_mut_unchecked(face).remote_qabls.insert(res.clone()); } @@ -544,6 +576,7 @@ pub fn declare_client_queryable( } else { let mut fullexpr = prefix.expr(); fullexpr.push_str(expr.suffix.as_ref()); + log::debug!("Register client queryable {}", fullexpr); let mut matches = keyexpr::new(fullexpr.as_str()) .map(|ke| Resource::get_matches(&rtables, ke)) .unwrap_or_default(); @@ -656,13 +689,24 @@ fn send_forget_sourced_queryable_to_net_childs( match tables.get_face(&net.graph[*child].zid).cloned() { Some(mut someface) => { if src_face.is_none() || someface.id != src_face.unwrap().id { - let key_expr = Resource::decl_key(res, &mut someface); + let wire_expr = Resource::decl_key(res, &mut someface); log::debug!("Send forget queryable {} on {}", res.expr(), someface); - someface - .primitives - .forget_queryable(&key_expr, routing_context); + someface.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { + node_id: routing_context.map(|c| c.tree_id).unwrap_or(0) as u16, + }, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); } } None => log::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -674,8 +718,19 @@ fn send_forget_sourced_queryable_to_net_childs( fn propagate_forget_simple_queryable(tables: &mut Tables, res: &mut Arc) { for face in tables.faces.values_mut() { if face.local_qabls.contains_key(res) { - let key_expr = Resource::get_best_key(res, "", face.id); - face.primitives.forget_queryable(&key_expr, None); + let wire_expr = Resource::get_best_key(res, "", face.id); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); get_mut_unchecked(face).local_qabls.remove(res); } @@ -703,8 +758,19 @@ fn propagate_forget_simple_queryable_to_peers(tables: &mut Tables, res: &mut Arc && tables.failover_brokering(s.face.zid, face.zid))) }) { - let key_expr = Resource::get_best_key(res, "", face.id); - face.primitives.forget_queryable(&key_expr, None); + let wire_expr = Resource::get_best_key(res, "", face.id); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); get_mut_unchecked(&mut face).local_qabls.remove(res); } @@ -942,8 +1008,19 @@ pub(crate) fn undeclare_client_queryable( if client_qabls.len() == 1 && !router_qabls && !peer_qabls { let face = &mut client_qabls[0]; if face.local_qabls.contains_key(res) { - let key_expr = Resource::get_best_key(res, "", face.id); - face.primitives.forget_queryable(&key_expr, None); + let wire_expr = Resource::get_best_key(res, "", face.id); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); get_mut_unchecked(face).local_qabls.remove(res); } @@ -993,9 +1070,19 @@ pub(crate) fn queries_new_face(tables: &mut Tables, face: &mut Arc) { let info = local_qabl_info(tables, qabl, face); get_mut_unchecked(face) .local_qabls - .insert(qabl.clone(), info.clone()); + .insert(qabl.clone(), info); let key_expr = Resource::decl_key(qabl, face); - face.primitives.decl_queryable(&key_expr, &info, None); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: info, + }), + }); } } } else if face.whatami == WhatAmI::Peer && !tables.full_net(WhatAmI::Peer) { @@ -1012,9 +1099,19 @@ pub(crate) fn queries_new_face(tables: &mut Tables, face: &mut Arc) { let info = local_qabl_info(tables, qabl, face); get_mut_unchecked(face) .local_qabls - .insert(qabl.clone(), info.clone()); + .insert(qabl.clone(), info); let key_expr = Resource::decl_key(qabl, face); - face.primitives.decl_queryable(&key_expr, &info, None); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: info, + }), + }); } } } @@ -1027,9 +1124,19 @@ pub(crate) fn queries_new_face(tables: &mut Tables, face: &mut Arc) { let info = local_qabl_info(tables, qabl, face); get_mut_unchecked(face) .local_qabls - .insert(qabl.clone(), info.clone()); + .insert(qabl.clone(), info); let key_expr = Resource::decl_key(qabl, face); - face.primitives.decl_queryable(&key_expr, &info, None); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: info, + }), + }); } } } @@ -1156,8 +1263,19 @@ pub(crate) fn queries_linkstate_change(tables: &mut Tables, zid: &ZenohId, links }) }; if forget { - let key_expr = Resource::get_best_key(res, "", dst_face.id); - dst_face.primitives.forget_queryable(&key_expr, None); + let wire_expr = Resource::get_best_key(res, "", dst_face.id); + dst_face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); get_mut_unchecked(dst_face).local_qabls.remove(res); } @@ -1166,9 +1284,19 @@ pub(crate) fn queries_linkstate_change(tables: &mut Tables, zid: &ZenohId, links let info = local_qabl_info(tables, res, dst_face); get_mut_unchecked(dst_face) .local_qabls - .insert(res.clone(), info.clone()); + .insert(res.clone(), info); let key_expr = Resource::decl_key(res, dst_face); - dst_face.primitives.decl_queryable(&key_expr, &info, None); + dst_face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: 0, // TODO + wire_expr: key_expr, + mapping: Mapping::default(), // TODO + ext_info: info, + }), + }); } } } @@ -1547,7 +1675,7 @@ pub(super) fn compute_matches_query_routes_( } #[inline] -fn insert_pending_query(outface: &mut Arc, query: Arc) -> QueryId { +fn insert_pending_query(outface: &mut Arc, query: Arc) -> RequestId { let outface_mut = get_mut_unchecked(outface); outface_mut.next_qid += 1; let qid = outface_mut.next_qid; @@ -1584,11 +1712,11 @@ fn compute_final_route( qabls: &Arc, src_face: &Arc, expr: &mut RoutingExpr, - target: &QueryTarget, + target: &TargetType, query: Arc, ) -> QueryRoute { match target { - QueryTarget::All => { + TargetType::All => { let mut route = HashMap::new(); for qabl in qabls.iter() { if should_route(tables, src_face, &qabl.direction.0, expr) { @@ -1612,7 +1740,7 @@ fn compute_final_route( } route } - QueryTarget::AllComplete => { + TargetType::AllComplete => { let mut route = HashMap::new(); for qabl in qabls.iter() { if qabl.complete > 0 && should_route(tables, src_face, &qabl.direction.0, expr) { @@ -1637,7 +1765,7 @@ fn compute_final_route( route } #[cfg(feature = "complete_n")] - QueryTarget::Complete(n) => { + TargetType::Complete(n) => { let mut route = HashMap::new(); let mut remaining = *n; if src_face.whatami == WhatAmI::Peer && !tables.full_net(WhatAmI::Peer) { @@ -1686,7 +1814,7 @@ fn compute_final_route( } route } - QueryTarget::BestMatching => { + TargetType::BestMatching => { if let Some(qabl) = qabls .iter() .find(|qabl| qabl.direction.0.id != src_face.id && qabl.complete > 0) @@ -1706,7 +1834,7 @@ fn compute_final_route( } route } else { - compute_final_route(tables, qabls, src_face, expr, &QueryTarget::All, query) + compute_final_route(tables, qabls, src_face, expr, &TargetType::All, query) } } } @@ -1757,7 +1885,7 @@ fn compute_local_replies( struct QueryCleanup { tables: Arc, face: Weak, - qid: QueryId, + qid: RequestId, } #[async_trait] @@ -1802,14 +1930,13 @@ fn get_query_route( face: &FaceState, res: &Option>, expr: &mut RoutingExpr, - routing_context: Option, + routing_context: u64, ) -> Arc { match tables.whatami { WhatAmI::Router => match face.whatami { WhatAmI::Router => { let routers_net = tables.routers_net.as_ref().unwrap(); - let local_context = routers_net - .get_local_context(routing_context.map(|rc| rc.tree_id), face.link_id); + let local_context = routers_net.get_local_context(routing_context, face.link_id); res.as_ref() .and_then(|res| res.routers_query_route(local_context)) .unwrap_or_else(|| { @@ -1819,8 +1946,7 @@ fn get_query_route( WhatAmI::Peer => { if tables.full_net(WhatAmI::Peer) { let peers_net = tables.peers_net.as_ref().unwrap(); - let local_context = peers_net - .get_local_context(routing_context.map(|rc| rc.tree_id), face.link_id); + let local_context = peers_net.get_local_context(routing_context, face.link_id); res.as_ref() .and_then(|res| res.peers_query_route(local_context)) .unwrap_or_else(|| { @@ -1842,8 +1968,8 @@ fn get_query_route( match face.whatami { WhatAmI::Router | WhatAmI::Peer => { let peers_net = tables.peers_net.as_ref().unwrap(); - let local_context = peers_net - .get_local_context(routing_context.map(|rc| rc.tree_id), face.link_id); + let local_context = + peers_net.get_local_context(routing_context, face.link_id); res.as_ref() .and_then(|res| res.peers_query_route(local_context)) .unwrap_or_else(|| { @@ -1876,12 +2002,10 @@ pub fn route_query( tables_ref: &Arc, face: &Arc, expr: &WireExpr, - parameters: &str, - qid: QueryId, - target: QueryTarget, - consolidation: ConsolidationMode, - body: Option, - routing_context: Option, + qid: RequestId, + target: TargetType, + body: RequestBody, + routing_context: u64, ) { let rtables = zread!(tables_ref.tables); match rtables.get_mapping(face, &expr.scope) { @@ -1919,9 +2043,25 @@ pub fn route_query( drop(rtables); for (expr, payload) in local_replies { - face.primitives - .clone() - .send_reply_data(qid, zid, expr, None, payload); + face.primitives.clone().send_response(Response { + rid: qid, + wire_expr: expr, + mapping: Mapping::default(), // TODO + payload: ResponseBody::Reply(zenoh_new::Reply { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_consolidation: ConsolidationType::default(), + ext_unknown: vec![], + payload, + }), + ext_qos: response::ext::QoSType::default(), + ext_tstamp: None, + ext_respid: Some(response::ext::ResponderIdType { + zid, + eid: 0, // TODO + }), + }); } if route.is_empty() { @@ -1930,7 +2070,11 @@ pub fn route_query( face, qid ); - face.primitives.clone().send_reply_final(qid) + face.primitives.clone().send_response_final(ResponseFinal { + rid: qid, + ext_qos: response::ext::QoSType::default(), + ext_tstamp: None, + }); } else { // let timer = tables.timer.clone(); // let timeout = tables.queries_default_timeout; @@ -1946,15 +2090,20 @@ pub fn route_query( // }, // )); log::trace!("Propagate query {}:{} to {}", face, qid, outface); - outface.primitives.send_query( - key_expr, - parameters, - *qid, - *t, - consolidation, - body.clone(), - *context, - ); + outface.primitives.send_request(Request { + id: *qid, + wire_expr: key_expr.into(), + mapping: Mapping::default(), // TODO + ext_qos: ext::QoSType::default(), // TODO + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { + node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, + }, + ext_target: t, + ext_budget: None, + ext_timeout: None, + payload: body.clone(), + }); } } @@ -1970,22 +2119,31 @@ pub fn route_query( // }, // )); log::trace!("Propagate query {}:{} to {}", face, qid, outface); - outface.primitives.send_query( - key_expr, - parameters, - *qid, - target, - consolidation, - body.clone(), - *context, - ); + outface.primitives.send_request(Request { + id: *qid, + wire_expr: key_expr.into(), + mapping: Mapping::default(), // TODO + ext_qos: ext::QoSType::default(), // TODO + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { + node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, + }, + ext_target: target, + ext_budget: None, + ext_timeout: None, + payload: body.clone(), + }); } } } } else { log::debug!("Send final reply {}:{} (not master)", face, qid); drop(rtables); - face.primitives.clone().send_reply_final(qid) + face.primitives.clone().send_response_final(ResponseFinal { + rid: qid, + ext_qos: response::ext::QoSType::default(), + ext_tstamp: None, + }); } } None => { @@ -1994,32 +2152,37 @@ pub fn route_query( expr.scope ); drop(rtables); - face.primitives.clone().send_reply_final(qid) + face.primitives.clone().send_response_final(ResponseFinal { + rid: qid, + ext_qos: response::ext::QoSType::default(), + ext_tstamp: None, + }); } } } #[allow(clippy::too_many_arguments)] -pub(crate) fn route_send_reply_data( +pub(crate) fn route_send_response( tables_ref: &Arc, face: &mut Arc, qid: QueryId, - replier_id: ZenohId, + ext_respid: Option, key_expr: WireExpr, - info: Option, - payload: ZBuf, + body: ResponseBody, ) { let queries_lock = zread!(tables_ref.queries_lock); match face.pending_queries.get(&qid) { Some(query) => { drop(queries_lock); - query.src_face.primitives.clone().send_reply_data( - query.src_qid, - replier_id, - key_expr, - info, - payload, - ); + query.src_face.primitives.clone().send_response(Response { + rid: query.src_qid, + wire_expr: key_expr.to_owned(), + mapping: Mapping::default(), // TODO + payload: body, + ext_qos: response::ext::QoSType::default(), + ext_tstamp: None, + ext_respid, + }); } None => log::warn!( "Route reply {}:{} from {}: Query nof found!", @@ -2030,7 +2193,7 @@ pub(crate) fn route_send_reply_data( } } -pub(crate) fn route_send_reply_final( +pub(crate) fn route_send_response_final( tables_ref: &Arc, face: &mut Arc, qid: QueryId, @@ -2071,6 +2234,10 @@ pub(crate) fn finalize_pending_query(query: Arc) { .src_face .primitives .clone() - .send_reply_final(query.src_qid); + .send_response_final(ResponseFinal { + rid: query.src_qid, + ext_qos: response::ext::QoSType::default(), + ext_tstamp: None, + }); } } diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index 14320d2a23..c10b8af2d1 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -17,22 +17,28 @@ use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use std::hash::{Hash, Hasher}; use std::sync::{Arc, Weak}; -use zenoh_buffers::ZBuf; +use zenoh_protocol::network::declare::ext; +use zenoh_protocol::network::queryable::ext::QueryableInfo; +#[cfg(feature = "complete_n")] +use zenoh_protocol::network::request::ext::TargetType; +use zenoh_protocol::network::subscriber::ext::SubscriberInfo; +use zenoh_protocol::network::{Declare, DeclareBody, DeclareKeyExpr}; +use zenoh_protocol::zenoh_new::PushBody; use zenoh_protocol::{ core::{key_expr::keyexpr, ExprId, WireExpr, ZenohId}, - zenoh::{DataInfo, QueryId, QueryableInfo, RoutingContext, SubInfo}, + zenoh::{QueryId, RoutingContext}, }; use zenoh_sync::get_mut_unchecked; pub(super) type Direction = (Arc, WireExpr<'static>, Option); pub(super) type Route = HashMap; #[cfg(feature = "complete_n")] -pub(super) type QueryRoute = HashMap; +pub(super) type QueryRoute = HashMap; #[cfg(not(feature = "complete_n"))] pub(super) type QueryRoute = HashMap; pub(super) struct QueryTargetQabl { pub(super) direction: Direction, - pub(super) complete: u64, + pub(super) complete: u8, pub(super) distance: f64, } pub(super) type QueryTargetQablSet = Vec; @@ -42,9 +48,9 @@ pub(super) struct SessionContext { pub(super) face: Arc, pub(super) local_expr_id: Option, pub(super) remote_expr_id: Option, - pub(super) subs: Option, + pub(super) subs: Option, pub(super) qabl: Option, - pub(super) last_values: HashMap, ZBuf)>, + pub(super) last_values: HashMap, } pub(super) struct DataRoutes { @@ -494,8 +500,15 @@ impl Resource { get_mut_unchecked(face) .local_mappings .insert(expr_id, nonwild_prefix.clone()); - face.primitives - .decl_resource(expr_id, &nonwild_prefix.expr().into()); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { + id: expr_id, + wire_expr: nonwild_prefix.expr().into(), + }), + }); expr_id } }; @@ -715,8 +728,15 @@ pub fn register_expr( .local_mappings .insert(local_expr_id, res.clone()); - face.primitives - .decl_resource(local_expr_id, &res.expr().into()); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { + id: local_expr_id, + wire_expr: res.expr().into(), + }), + }); } get_mut_unchecked(face) diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index befb0cc8b3..bda595bd9b 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -17,6 +17,8 @@ pub use super::pubsub::*; pub use super::queries::*; pub use super::resource::*; use super::runtime::Runtime; +use crate::net::codec::Zenoh080Routing; +use crate::net::protocol::{linkstate::LinkStateList, OAM_LINKSTATE}; use async_std::task::JoinHandle; use std::any::Any; use std::collections::hash_map::DefaultHasher; @@ -27,10 +29,9 @@ use std::sync::{Mutex, RwLock}; use std::time::Duration; use uhlc::HLC; use zenoh_link::Link; -use zenoh_protocol::{ - core::{ExprId, WhatAmI, WhatAmIMatcher, ZenohId}, - zenoh::{ZenohBody, ZenohMessage}, -}; +use zenoh_protocol::common::ZExtBody; +use zenoh_protocol::core::{ExprId, WhatAmI, WhatAmIMatcher, ZenohId}; +use zenoh_protocol::network::{NetworkBody, NetworkMessage}; use zenoh_transport::{DeMux, Mux, Primitives, TransportPeerEventHandler, TransportUnicast}; // use zenoh_collections::Timer; use zenoh_core::zconfigurable; @@ -611,88 +612,107 @@ impl LinkStateInterceptor { } impl TransportPeerEventHandler for LinkStateInterceptor { - fn handle_message(&self, msg: ZenohMessage) -> ZResult<()> { + fn handle_message(&self, msg: NetworkMessage) -> ZResult<()> { log::trace!("Recv {:?}", msg); match msg.body { - ZenohBody::LinkStateList(list) => { - if let Ok(zid) = self.transport.get_zid() { - let ctrl_lock = zlock!(self.tables.ctrl_lock); - let mut tables = zwrite!(self.tables.tables); - let whatami = self.transport.get_whatami()?; - match (tables.whatami, whatami) { - (WhatAmI::Router, WhatAmI::Router) => { - for (_, removed_node) in tables - .routers_net - .as_mut() - .unwrap() - .link_states(list.link_states, zid) - .removed_nodes - { - pubsub_remove_node(&mut tables, &removed_node.zid, WhatAmI::Router); - queries_remove_node( - &mut tables, - &removed_node.zid, - WhatAmI::Router, - ); - } - - if tables.full_net(WhatAmI::Peer) { - tables.shared_nodes = shared_nodes( - tables.routers_net.as_ref().unwrap(), - tables.peers_net.as_ref().unwrap(), - ); - } - - tables.schedule_compute_trees(self.tables.clone(), WhatAmI::Router); - } - (WhatAmI::Router, WhatAmI::Peer) - | (WhatAmI::Peer, WhatAmI::Router) - | (WhatAmI::Peer, WhatAmI::Peer) => { - if let Some(net) = tables.peers_net.as_mut() { - let changes = net.link_states(list.link_states, zid); - if tables.full_net(WhatAmI::Peer) { - for (_, removed_node) in changes.removed_nodes { + NetworkBody::OAM(oam) => { + if oam.id == OAM_LINKSTATE { + if let ZExtBody::ZBuf(buf) = oam.body { + if let Ok(zid) = self.transport.get_zid() { + use zenoh_buffers::reader::HasReader; + use zenoh_codec::RCodec; + let codec = Zenoh080Routing::new(); + let mut reader = buf.reader(); + let list: LinkStateList = codec.read(&mut reader).unwrap(); + + let ctrl_lock = zlock!(self.tables.ctrl_lock); + let mut tables = zwrite!(self.tables.tables); + let whatami = self.transport.get_whatami()?; + match (tables.whatami, whatami) { + (WhatAmI::Router, WhatAmI::Router) => { + for (_, removed_node) in tables + .routers_net + .as_mut() + .unwrap() + .link_states(list.link_states, zid) + .removed_nodes + { pubsub_remove_node( &mut tables, &removed_node.zid, - WhatAmI::Peer, + WhatAmI::Router, ); queries_remove_node( &mut tables, &removed_node.zid, - WhatAmI::Peer, + WhatAmI::Router, ); } - if tables.whatami == WhatAmI::Router { + if tables.full_net(WhatAmI::Peer) { tables.shared_nodes = shared_nodes( tables.routers_net.as_ref().unwrap(), tables.peers_net.as_ref().unwrap(), ); } - tables - .schedule_compute_trees(self.tables.clone(), WhatAmI::Peer); - } else { - for (_, updated_node) in changes.updated_nodes { - pubsub_linkstate_change( - &mut tables, - &updated_node.zid, - &updated_node.links, - ); - queries_linkstate_change( - &mut tables, - &updated_node.zid, - &updated_node.links, - ); + tables.schedule_compute_trees( + self.tables.clone(), + WhatAmI::Router, + ); + } + (WhatAmI::Router, WhatAmI::Peer) + | (WhatAmI::Peer, WhatAmI::Router) + | (WhatAmI::Peer, WhatAmI::Peer) => { + if let Some(net) = tables.peers_net.as_mut() { + let changes = net.link_states(list.link_states, zid); + if tables.full_net(WhatAmI::Peer) { + for (_, removed_node) in changes.removed_nodes { + pubsub_remove_node( + &mut tables, + &removed_node.zid, + WhatAmI::Peer, + ); + queries_remove_node( + &mut tables, + &removed_node.zid, + WhatAmI::Peer, + ); + } + + if tables.whatami == WhatAmI::Router { + tables.shared_nodes = shared_nodes( + tables.routers_net.as_ref().unwrap(), + tables.peers_net.as_ref().unwrap(), + ); + } + + tables.schedule_compute_trees( + self.tables.clone(), + WhatAmI::Peer, + ); + } else { + for (_, updated_node) in changes.updated_nodes { + pubsub_linkstate_change( + &mut tables, + &updated_node.zid, + &updated_node.links, + ); + queries_linkstate_change( + &mut tables, + &updated_node.zid, + &updated_node.links, + ); + } + } } } - } + _ => (), + }; + drop(tables); + drop(ctrl_lock); } - _ => (), - }; - drop(tables); - drop(ctrl_lock); + } } Ok(()) diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 30580cd83f..1fe3757df8 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -26,18 +26,18 @@ use std::convert::TryFrom; use std::convert::TryInto; use std::sync::Arc; use std::sync::Mutex; -use zenoh_buffers::{SplitBuffer, ZBuf}; +use zenoh_buffers::SplitBuffer; use zenoh_config::ValidatedMap; -use zenoh_protocol::{ - core::{ - key_expr::OwnedKeyExpr, Channel, CongestionControl, ExprId, KnownEncoding, WireExpr, - ZenohId, EMPTY_EXPR_ID, - }, - zenoh::{ - ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, - RoutingContext, SampleKind, SubInfo, - }, +use zenoh_protocol::core::{ + key_expr::OwnedKeyExpr, ExprId, KnownEncoding, WireExpr, ZenohId, EMPTY_EXPR_ID, }; +use zenoh_protocol::network::queryable::ext::QueryableInfo; +use zenoh_protocol::network::subscriber::ext::SubscriberInfo; +use zenoh_protocol::network::{ + ext, Declare, DeclareBody, DeclareQueryable, DeclareSubscriber, Mapping, Push, Request, + Response, ResponseFinal, +}; +use zenoh_protocol::zenoh_new::{PushBody, RequestBody}; use zenoh_result::ZResult; use zenoh_transport::{Primitives, TransportUnicast}; @@ -218,20 +218,32 @@ impl AdminSpace { let primitives = runtime.router.new_primitives(admin.clone()); zlock!(admin.primitives).replace(primitives.clone()); - primitives.decl_queryable( - &[&root_key, "/**"].concat().into(), - &QueryableInfo { - complete: 0, - distance: 0, - }, - None, - ); + primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: 0, // TODO + wire_expr: [&root_key, "/**"].concat().into(), + mapping: Mapping::default(), // TODO + ext_info: QueryableInfo { + complete: 0, + distance: 0, + }, + }), + }); - primitives.decl_subscriber( - &[&root_key, "/config/**"].concat().into(), - &SubInfo::default(), - None, - ); + primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // TODO + wire_expr: [&root_key, "/config/**"].concat().into(), + mapping: Mapping::default(), // TODO + ext_info: SubscriberInfo::default(), + }), + }); } pub fn key_expr_to_string<'a>(&self, key_expr: &'a WireExpr) -> ZResult> { @@ -252,102 +264,38 @@ impl AdminSpace { } impl Primitives for AdminSpace { - fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { - trace!("recv Resource {} {:?}", expr_id, key_expr); - match self.key_expr_to_string(key_expr) { - Ok(s) => { - zlock!(self.mappings).insert(expr_id, s.into()); + fn send_declare(&self, msg: Declare) { + log::trace!("Recv declare {:?}", msg); + if let DeclareBody::DeclareKeyExpr(m) = msg.body { + match self.key_expr_to_string(&m.wire_expr) { + Ok(s) => { + zlock!(self.mappings).insert(m.id, s.into()); + } + Err(e) => error!("Unknown expr_id {}! ({})", m.id, e), } - Err(e) => error!("Unknown expr_id {}! ({})", expr_id, e), } } - fn forget_resource(&self, _expr_id: ExprId) { - trace!("recv Forget Resource {}", _expr_id); - } - - fn decl_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) { - trace!("recv Publisher {:?}", _key_expr); - } - - fn forget_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) { - trace!("recv Forget Publisher {:?}", _key_expr); - } - - fn decl_subscriber( - &self, - _key_expr: &WireExpr, - _sub_info: &SubInfo, - _routing_context: Option, - ) { - trace!("recv Subscriber {:?} , {:?}", _key_expr, _sub_info); - } - - fn forget_subscriber(&self, _key_expr: &WireExpr, _routing_context: Option) { - trace!("recv Forget Subscriber {:?}", _key_expr); - } - - fn decl_queryable( - &self, - _key_expr: &WireExpr, - _qabl_info: &QueryableInfo, - _routing_context: Option, - ) { - trace!("recv Queryable {:?}", _key_expr); - } - - fn forget_queryable(&self, _key_expr: &WireExpr, _routing_context: Option) { - trace!("recv Forget Queryable {:?}", _key_expr); - } - - fn send_data( - &self, - key_expr: &WireExpr, - payload: ZBuf, - channel: Channel, - congestion_control: CongestionControl, - data_info: Option, - _routing_context: Option, - ) { - trace!( - "recv Data {:?} {:?} {:?} {:?} {:?}", - key_expr, - payload, - channel, - congestion_control, - data_info, - ); - + fn send_push(&self, msg: Push) { + trace!("recv Push {:?}", msg); { let conf = self.context.runtime.config.lock(); if !conf.adminspace.permissions().write { log::error!( "Received PUT on '{}' but adminspace.permissions.write=false in configuration", - key_expr + msg.wire_expr ); return; } } - if let Some(key) = key_expr + if let Some(key) = msg + .wire_expr .as_str() .strip_prefix(&format!("@/router/{}/config/", &self.context.zid_str)) { - if let Some(DataInfo { - kind: SampleKind::Delete, - .. - }) = data_info - { - log::trace!( - "Deleting conf value /@/router/{}/config/{}", - &self.context.zid_str, - key - ); - if let Err(e) = self.context.runtime.config.remove(key) { - log::error!("Error deleting conf value {} : {}", key_expr, e) - } - } else { - match std::str::from_utf8(&payload.contiguous()) { + match msg.payload { + PushBody::Put(put) => match std::str::from_utf8(&put.payload.contiguous()) { Ok(json) => { log::trace!( "Insert conf value /@/router/{}/config/{} : {}", @@ -366,109 +314,83 @@ impl Primitives for AdminSpace { "Received non utf8 conf value on /@/router/{}/config/{} : {}", &self.context.zid_str, key, e ), + }, + PushBody::Del(_) => { + log::trace!( + "Deleting conf value /@/router/{}/config/{}", + &self.context.zid_str, + key + ); + if let Err(e) = self.context.runtime.config.remove(key) { + log::error!("Error deleting conf value {} : {}", msg.wire_expr, e) + } } } } } - fn send_query( - &self, - key_expr: &WireExpr, - parameters: &str, - qid: QueryId, - target: QueryTarget, - _consolidation: ConsolidationMode, - body: Option, - _routing_context: Option, - ) { - trace!( - "recv Query {:?} {:?} {:?} {:?}", - key_expr, - parameters, - target, - _consolidation - ); - let primitives = zlock!(self.primitives).as_ref().unwrap().clone(); - - { - let conf = self.context.runtime.config.lock(); - if !conf.adminspace.permissions().read { - log::error!( - "Received GET on '{}' but adminspace.permissions.read=false in configuration", - key_expr - ); - primitives.send_reply_final(qid); - return; + fn send_request(&self, msg: Request) { + trace!("recv Request {:?}", msg); + if let RequestBody::Query(query) = msg.payload { + let primitives = zlock!(self.primitives).as_ref().unwrap().clone(); + { + let conf = self.context.runtime.config.lock(); + if !conf.adminspace.permissions().read { + log::error!( + "Received GET on '{}' but adminspace.permissions.read=false in configuration", + msg.wire_expr + ); + primitives.send_response_final(ResponseFinal { + rid: msg.id, + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + }); + return; + } } - } - let key_expr = match self.key_expr_to_string(key_expr) { - Ok(key_expr) => key_expr.into_owned(), - Err(e) => { - log::error!("Unknown KeyExpr: {}", e); - primitives.send_reply_final(qid); - return; - } - }; - - let zid = self.zid; - let parameters = parameters.to_owned(); - let query = Query { - inner: Arc::new(QueryInner { - key_expr: key_expr.clone(), - parameters, - value: body.map(|b| { - Value::from(b.payload).encoding(b.data_info.encoding.unwrap_or_default()) + let key_expr = match self.key_expr_to_string(&msg.wire_expr) { + Ok(key_expr) => key_expr.into_owned(), + Err(e) => { + log::error!("Unknown KeyExpr: {}", e); + primitives.send_response_final(ResponseFinal { + rid: msg.id, + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + }); + return; + } + }; + + let zid = self.zid; + let parameters = query.parameters.to_owned(); + let query = Query { + inner: Arc::new(QueryInner { + key_expr: key_expr.clone(), + parameters, + value: query + .ext_body + .map(|b| Value::from(b.payload).encoding(b.encoding)), + qid: msg.id, + zid, + primitives, }), - qid, - zid, - primitives, - }), - }; + }; - for (key, handler) in &self.handlers { - if key_expr.intersects(key) { - handler(&self.context, query.clone()); + for (key, handler) in &self.handlers { + if key_expr.intersects(key) { + handler(&self.context, query.clone()); + } } } } - fn send_reply_data( - &self, - qid: QueryId, - replier_id: ZenohId, - key_expr: WireExpr, - info: Option, - payload: ZBuf, - ) { - trace!( - "recv ReplyData {:?} {:?} {:?} {:?} {:?}", - qid, - replier_id, - key_expr, - info, - payload - ); - } - - fn send_reply_final(&self, qid: QueryId) { - trace!("recv ReplyFinal {:?}", qid); + fn send_response(&self, msg: Response) { + trace!("recv Response {:?}", msg); } - fn send_pull( - &self, - _is_final: bool, - _key_expr: &WireExpr, - _pull_id: PullId, - _max_samples: &Option, - ) { - trace!( - "recv Pull {:?} {:?} {:?} {:?}", - _is_final, - _key_expr, - _pull_id, - _max_samples - ); + fn send_response_final(&self, msg: ResponseFinal) { + trace!("recv ResponseFinal {:?}", msg); } fn send_close(&self) { diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index fe015d1a9d..7ec9ee4102 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -36,10 +36,8 @@ use stop_token::future::FutureExt; use stop_token::{StopSource, TimedOutError}; use uhlc::{HLCBuilder, HLC}; use zenoh_link::{EndPoint, Link}; -use zenoh_protocol::{ - core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}, - zenoh::{ZenohBody, ZenohMessage}, -}; +use zenoh_protocol::core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}; +use zenoh_protocol::network::{NetworkBody, NetworkMessage}; use zenoh_result::{bail, ZResult}; use zenoh_sync::get_mut_unchecked; use zenoh_transport::{ @@ -252,25 +250,20 @@ pub(super) struct RuntimeSession { } impl TransportPeerEventHandler for RuntimeSession { - fn handle_message(&self, mut msg: ZenohMessage) -> ZResult<()> { + fn handle_message(&self, msg: NetworkMessage) -> ZResult<()> { // critical path shortcut - if let ZenohBody::Data(data) = msg.body { - if data.reply_context.is_none() { - let face = &self.main_handler.face.state; - full_reentrant_route_data( - &self.main_handler.tables.tables, - face, - &data.key, - msg.channel, - data.congestion_control, - data.data_info, - data.payload, - msg.routing_context, - ); - return Ok(()); - } else { - msg.body = ZenohBody::Data(data); - } + if let NetworkBody::Push(data) = msg.body { + let face = &self.main_handler.face.state; + + full_reentrant_route_data( + &self.main_handler.tables.tables, + face, + &data.wire_expr, + data.ext_qos, + data.payload, + data.ext_nodeid.node_id.into(), + ); + return Ok(()); } self.main_handler.handle_message(msg) diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index a9347df571..5698265201 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -1,734 +1,725 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::net::routing::router::{self, *}; -use std::convert::{TryFrom, TryInto}; -use std::sync::{Arc, Mutex, RwLock}; -use std::time::Duration; -use uhlc::HLC; -use zenoh_buffers::ZBuf; -use zenoh_config::defaults::queries_default_timeout; -use zenoh_core::zlock; -use zenoh_protocol::{ - core::{ - key_expr::keyexpr, Channel, CongestionControl, ExprId, Reliability, WhatAmI, WireExpr, - ZenohId, EMPTY_EXPR_ID, - }, - zenoh::{ - ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, - RoutingContext, SubInfo, SubMode, - }, -}; -use zenoh_transport::{DummyPrimitives, Primitives}; - -#[test] -fn base_test() { - let tables = TablesLock { - tables: RwLock::new(Tables::new( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - Some(Arc::new(HLC::default())), - false, - true, - Duration::from_millis(queries_default_timeout), - )), - ctrl_lock: Mutex::new(()), - queries_lock: RwLock::new(()), - }; - - let primitives = Arc::new(DummyPrimitives::new()); - let face = zwrite!(tables.tables).open_face( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - primitives, - ); - register_expr( - &tables, - &mut face.upgrade().unwrap(), - 1, - &"one/two/three".into(), - ); - register_expr( - &tables, - &mut face.upgrade().unwrap(), - 2, - &"one/deux/trois".into(), - ); - - let sub_info = SubInfo { - reliability: Reliability::Reliable, - mode: SubMode::Push, - }; - declare_client_subscription( - &tables, - zread!(tables.tables), - &mut face.upgrade().unwrap(), - &WireExpr::from(1).with_suffix("four/five"), - &sub_info, - ); - - Tables::print(&zread!(tables.tables)); -} - -#[test] -fn match_test() { - let key_exprs = [ - "**", - "a", - "a/b", - "*", - "a/*", - "a/b$*", - "abc", - "xx", - "ab$*", - "abcd", - "ab$*d", - "ab", - "ab/*", - "a/*/c/*/e", - "a/b/c/d/e", - "a/$*b/c/$*d/e", - "a/xb/c/xd/e", - "a/c/e", - "a/b/c/d/x/e", - "ab$*cd", - "abxxcxxd", - "abxxcxxcd", - "abxxcxxcdx", - "a/b/c", - "ab/**", - "**/xyz", - "a/b/xyz/d/e/f/xyz", - "**/xyz$*xyz", - "a/b/xyz/d/e/f/xyz", - "a/**/c/**/e", - "a/b/b/b/c/d/d/d/e", - "a/**/c/*/e/*", - "a/b/b/b/c/d/d/c/d/e/f", - "a/**/c/*/e/*", - "x/abc", - "x/*", - "x/abc$*", - "x/$*abc", - "x/a$*", - "x/a$*de", - "x/abc$*de", - "x/a$*d$*e", - "x/a$*e", - "x/a$*c$*e", - "x/ade", - "x/c$*", - "x/$*d", - "x/$*e", - ] - .map(|s| keyexpr::new(s).unwrap()); - - let tables = TablesLock { - tables: RwLock::new(Tables::new( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - Some(Arc::new(HLC::default())), - false, - true, - Duration::from_millis(queries_default_timeout), - )), - ctrl_lock: Mutex::new(()), - queries_lock: RwLock::new(()), - }; - let primitives = Arc::new(DummyPrimitives::new()); - let face = zwrite!(tables.tables).open_face( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - primitives, - ); - for (i, key_expr) in key_exprs.iter().enumerate() { - register_expr( - &tables, - &mut face.upgrade().unwrap(), - i.try_into().unwrap(), - &(*key_expr).into(), - ); - } - - for key_expr1 in key_exprs.iter() { - let res_matches = Resource::get_matches(&zread!(tables.tables), key_expr1); - dbg!(res_matches.len()); - for key_expr2 in key_exprs.iter() { - if res_matches - .iter() - .map(|m| m.upgrade().unwrap().expr()) - .any(|x| x.as_str() == key_expr2.as_str()) - { - assert!(dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); - } else { - assert!(!dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); - } - } - } -} - -#[test] -fn clean_test() { - let tables = TablesLock { - tables: RwLock::new(Tables::new( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - Some(Arc::new(HLC::default())), - false, - true, - Duration::from_millis(queries_default_timeout), - )), - ctrl_lock: Mutex::new(()), - queries_lock: RwLock::new(()), - }; - - let primitives = Arc::new(DummyPrimitives::new()); - let face0 = zwrite!(tables.tables).open_face( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - primitives, - ); - assert!(face0.upgrade().is_some()); - - // -------------- - register_expr(&tables, &mut face0.upgrade().unwrap(), 1, &"todrop1".into()); - let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") - .map(|res| Arc::downgrade(&res)); - assert!(optres1.is_some()); - let res1 = optres1.unwrap(); - assert!(res1.upgrade().is_some()); - - register_expr( - &tables, - &mut face0.upgrade().unwrap(), - 2, - &"todrop1/todrop11".into(), - ); - let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") - .map(|res| Arc::downgrade(&res)); - assert!(optres2.is_some()); - let res2 = optres2.unwrap(); - assert!(res2.upgrade().is_some()); - - register_expr(&tables, &mut face0.upgrade().unwrap(), 3, &"**".into()); - let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "**") - .map(|res| Arc::downgrade(&res)); - assert!(optres3.is_some()); - let res3 = optres3.unwrap(); - assert!(res3.upgrade().is_some()); - - unregister_expr(&tables, &mut face0.upgrade().unwrap(), 1); - assert!(res1.upgrade().is_some()); - assert!(res2.upgrade().is_some()); - assert!(res3.upgrade().is_some()); - - unregister_expr(&tables, &mut face0.upgrade().unwrap(), 2); - assert!(res1.upgrade().is_none()); - assert!(res2.upgrade().is_none()); - assert!(res3.upgrade().is_some()); - - unregister_expr(&tables, &mut face0.upgrade().unwrap(), 3); - assert!(res1.upgrade().is_none()); - assert!(res2.upgrade().is_none()); - assert!(res3.upgrade().is_none()); - - // -------------- - register_expr(&tables, &mut face0.upgrade().unwrap(), 1, &"todrop1".into()); - let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") - .map(|res| Arc::downgrade(&res)); - assert!(optres1.is_some()); - let res1 = optres1.unwrap(); - assert!(res1.upgrade().is_some()); - - let sub_info = SubInfo { - reliability: Reliability::Reliable, - mode: SubMode::Push, - }; - - declare_client_subscription( - &tables, - zread!(tables.tables), - &mut face0.upgrade().unwrap(), - &"todrop1/todrop11".into(), - &sub_info, - ); - let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") - .map(|res| Arc::downgrade(&res)); - assert!(optres2.is_some()); - let res2 = optres2.unwrap(); - assert!(res2.upgrade().is_some()); - - declare_client_subscription( - &tables, - zread!(tables.tables), - &mut face0.upgrade().unwrap(), - &WireExpr::from(1).with_suffix("/todrop12"), - &sub_info, - ); - let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop12") - .map(|res| Arc::downgrade(&res)); - assert!(optres3.is_some()); - let res3 = optres3.unwrap(); - assert!(res3.upgrade().is_some()); - - forget_client_subscription( - &tables, - zread!(tables.tables), - &mut face0.upgrade().unwrap(), - &WireExpr::from(1).with_suffix("/todrop12"), - ); - assert!(res1.upgrade().is_some()); - assert!(res2.upgrade().is_some()); - assert!(res3.upgrade().is_none()); - - forget_client_subscription( - &tables, - zread!(tables.tables), - &mut face0.upgrade().unwrap(), - &"todrop1/todrop11".into(), - ); - assert!(res1.upgrade().is_some()); - assert!(res2.upgrade().is_none()); - assert!(res3.upgrade().is_none()); - - unregister_expr(&tables, &mut face0.upgrade().unwrap(), 1); - assert!(res1.upgrade().is_none()); - assert!(res2.upgrade().is_none()); - assert!(res3.upgrade().is_none()); - - // -------------- - register_expr(&tables, &mut face0.upgrade().unwrap(), 2, &"todrop3".into()); - declare_client_subscription( - &tables, - zread!(tables.tables), - &mut face0.upgrade().unwrap(), - &"todrop3".into(), - &sub_info, - ); - let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop3") - .map(|res| Arc::downgrade(&res)); - assert!(optres1.is_some()); - let res1 = optres1.unwrap(); - assert!(res1.upgrade().is_some()); - - forget_client_subscription( - &tables, - zread!(tables.tables), - &mut face0.upgrade().unwrap(), - &"todrop3".into(), - ); - assert!(res1.upgrade().is_some()); - - unregister_expr(&tables, &mut face0.upgrade().unwrap(), 2); - assert!(res1.upgrade().is_none()); - - // -------------- - register_expr(&tables, &mut face0.upgrade().unwrap(), 3, &"todrop4".into()); - register_expr(&tables, &mut face0.upgrade().unwrap(), 4, &"todrop5".into()); - declare_client_subscription( - &tables, - zread!(tables.tables), - &mut face0.upgrade().unwrap(), - &"todrop5".into(), - &sub_info, - ); - declare_client_subscription( - &tables, - zread!(tables.tables), - &mut face0.upgrade().unwrap(), - &"todrop6".into(), - &sub_info, - ); - - let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop4") - .map(|res| Arc::downgrade(&res)); - assert!(optres1.is_some()); - let res1 = optres1.unwrap(); - let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop5") - .map(|res| Arc::downgrade(&res)); - assert!(optres2.is_some()); - let res2 = optres2.unwrap(); - let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop6") - .map(|res| Arc::downgrade(&res)); - assert!(optres3.is_some()); - let res3 = optres3.unwrap(); - - assert!(res1.upgrade().is_some()); - assert!(res2.upgrade().is_some()); - assert!(res3.upgrade().is_some()); - - router::close_face(&tables, &face0); - assert!(face0.upgrade().is_none()); - assert!(res1.upgrade().is_none()); - assert!(res2.upgrade().is_none()); - assert!(res3.upgrade().is_none()); -} - -pub struct ClientPrimitives { - data: std::sync::Mutex>>, - mapping: std::sync::Mutex>, -} - -impl ClientPrimitives { - pub fn new() -> ClientPrimitives { - ClientPrimitives { - data: std::sync::Mutex::new(None), - mapping: std::sync::Mutex::new(std::collections::HashMap::new()), - } - } - - pub fn clear_data(&self) { - *self.data.lock().unwrap() = None; - } -} - -impl Default for ClientPrimitives { - fn default() -> Self { - Self::new() - } -} - -impl ClientPrimitives { - fn get_name(&self, key_expr: &WireExpr) -> String { - let mapping = self.mapping.lock().unwrap(); - let (scope, suffix) = key_expr.as_id_and_suffix(); - if scope == EMPTY_EXPR_ID { - suffix.to_string() - } else if suffix.is_empty() { - mapping.get(&scope).unwrap().clone() - } else { - format!("{}{}", mapping.get(&scope).unwrap(), suffix) - } - } - - fn get_last_name(&self) -> Option { - self.data - .lock() - .unwrap() - .as_ref() - .map(|data| self.get_name(data)) - } - - #[allow(dead_code)] - fn get_last_key(&self) -> Option { - self.data.lock().unwrap().as_ref().cloned() - } -} - -impl Primitives for ClientPrimitives { - fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { - let name = self.get_name(key_expr); - zlock!(self.mapping).insert(expr_id, name); - } - - fn forget_resource(&self, expr_id: ExprId) { - zlock!(self.mapping).remove(&expr_id); - } - - fn decl_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} - fn forget_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} - - fn decl_subscriber( - &self, - _key_expr: &WireExpr, - _sub_info: &SubInfo, - _routing_context: Option, - ) { - } - fn forget_subscriber(&self, _key_expr: &WireExpr, _routing_context: Option) {} - - fn decl_queryable( - &self, - _key_expr: &WireExpr, - _qabl_info: &QueryableInfo, - _routing_context: Option, - ) { - } - fn forget_queryable(&self, _key_expr: &WireExpr, _routing_context: Option) {} - - fn send_data( - &self, - key_expr: &WireExpr, - _payload: ZBuf, - _channel: Channel, - _congestion_control: CongestionControl, - _info: Option, - _routing_context: Option, - ) { - *zlock!(self.data) = Some(key_expr.to_owned()); - } - - fn send_query( - &self, - _key_expr: &WireExpr, - _parameters: &str, - _qid: QueryId, - _target: QueryTarget, - _consolidation: ConsolidationMode, - _body: Option, - _routing_context: Option, - ) { - } - - fn send_reply_data( - &self, - _qid: QueryId, - _replier_id: ZenohId, - _key_expr: WireExpr, - _info: Option, - _payload: ZBuf, - ) { - } - fn send_reply_final(&self, _qid: QueryId) {} - - fn send_pull( - &self, - _is_final: bool, - _key_expr: &WireExpr, - _pull_id: PullId, - _max_samples: &Option, - ) { - } - - fn send_close(&self) {} -} - -#[test] -fn client_test() { - let tables = TablesLock { - tables: RwLock::new(Tables::new( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - Some(Arc::new(HLC::default())), - false, - true, - Duration::from_millis(queries_default_timeout), - )), - ctrl_lock: Mutex::new(()), - queries_lock: RwLock::new(()), - }; - - let sub_info = SubInfo { - reliability: Reliability::Reliable, - mode: SubMode::Push, - }; - - let primitives0 = Arc::new(ClientPrimitives::new()); - - let face0 = zwrite!(tables.tables).open_face( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - primitives0.clone(), - ); - register_expr( - &tables, - &mut face0.upgrade().unwrap(), - 11, - &"test/client".into(), - ); - primitives0.decl_resource(11, &"test/client".into()); - declare_client_subscription( - &tables, - zread!(tables.tables), - &mut face0.upgrade().unwrap(), - &WireExpr::from(11).with_suffix("/**"), - &sub_info, - ); - register_expr( - &tables, - &mut face0.upgrade().unwrap(), - 12, - &WireExpr::from(11).with_suffix("/z1_pub1"), - ); - primitives0.decl_resource(12, &WireExpr::from(11).with_suffix("/z1_pub1")); - - let primitives1 = Arc::new(ClientPrimitives::new()); - let face1 = zwrite!(tables.tables).open_face( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - primitives1.clone(), - ); - register_expr( - &tables, - &mut face1.upgrade().unwrap(), - 21, - &"test/client".into(), - ); - primitives1.decl_resource(21, &"test/client".into()); - declare_client_subscription( - &tables, - zread!(tables.tables), - &mut face1.upgrade().unwrap(), - &WireExpr::from(21).with_suffix("/**"), - &sub_info, - ); - register_expr( - &tables, - &mut face1.upgrade().unwrap(), - 22, - &WireExpr::from(21).with_suffix("/z2_pub1"), - ); - primitives1.decl_resource(22, &WireExpr::from(21).with_suffix("/z2_pub1")); - - let primitives2 = Arc::new(ClientPrimitives::new()); - let face2 = zwrite!(tables.tables).open_face( - ZenohId::try_from([1]).unwrap(), - WhatAmI::Client, - primitives2.clone(), - ); - register_expr( - &tables, - &mut face2.upgrade().unwrap(), - 31, - &"test/client".into(), - ); - primitives2.decl_resource(31, &"test/client".into()); - declare_client_subscription( - &tables, - zread!(tables.tables), - &mut face2.upgrade().unwrap(), - &WireExpr::from(31).with_suffix("/**"), - &sub_info, - ); - - primitives0.clear_data(); - primitives1.clear_data(); - primitives2.clear_data(); - full_reentrant_route_data( - &tables.tables, - &face0.upgrade().unwrap(), - &"test/client/z1_wr1".into(), - Channel::default(), - CongestionControl::default(), - None, - ZBuf::empty(), - None, - ); - - // functionnal check - assert!(primitives1.get_last_name().is_some()); - assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_wr1"); - // mapping strategy check - // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_wr1".to_string())); - - // functionnal check - assert!(primitives2.get_last_name().is_some()); - assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_wr1"); - // mapping strategy check - // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_wr1".to_string())); - - primitives0.clear_data(); - primitives1.clear_data(); - primitives2.clear_data(); - full_reentrant_route_data( - &tables.tables, - &face0.upgrade().unwrap(), - &WireExpr::from(11).with_suffix("/z1_wr2"), - Channel::default(), - CongestionControl::default(), - None, - ZBuf::empty(), - None, - ); - - // functionnal check - assert!(primitives1.get_last_name().is_some()); - assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_wr2"); - // mapping strategy check - // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_wr2".to_string())); - - // functionnal check - assert!(primitives2.get_last_name().is_some()); - assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_wr2"); - // mapping strategy check - // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_wr2".to_string())); - - primitives0.clear_data(); - primitives1.clear_data(); - primitives2.clear_data(); - full_reentrant_route_data( - &tables.tables, - &face1.upgrade().unwrap(), - &"test/client/**".into(), - Channel::default(), - CongestionControl::default(), - None, - ZBuf::empty(), - None, - ); - - // functionnal check - assert!(primitives0.get_last_name().is_some()); - assert_eq!(primitives0.get_last_name().unwrap(), "test/client/**"); - // mapping strategy check - // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(11, "/**".to_string())); - - // functionnal check - assert!(primitives2.get_last_name().is_some()); - assert_eq!(primitives2.get_last_name().unwrap(), "test/client/**"); - // mapping strategy check - // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/**".to_string())); - - primitives0.clear_data(); - primitives1.clear_data(); - primitives2.clear_data(); - full_reentrant_route_data( - &tables.tables, - &face0.upgrade().unwrap(), - &12.into(), - Channel::default(), - CongestionControl::default(), - None, - ZBuf::empty(), - None, - ); - - // functionnal check - assert!(primitives1.get_last_name().is_some()); - assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_pub1"); - // mapping strategy check - // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_pub1".to_string())); - - // functionnal check - assert!(primitives2.get_last_name().is_some()); - assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_pub1"); - // mapping strategy check - // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_pub1".to_string())); - - primitives0.clear_data(); - primitives1.clear_data(); - primitives2.clear_data(); - full_reentrant_route_data( - &tables.tables, - &face1.upgrade().unwrap(), - &22.into(), - Channel::default(), - CongestionControl::default(), - None, - ZBuf::empty(), - None, - ); - - // functionnal check - assert!(primitives0.get_last_name().is_some()); - assert_eq!(primitives0.get_last_name().unwrap(), "test/client/z2_pub1"); - // mapping strategy check - // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(11, "/z2_pub1".to_string())); - - // functionnal check - assert!(primitives2.get_last_name().is_some()); - assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z2_pub1"); - // mapping strategy check - // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z2_pub1".to_string())); -} +// // +// // Copyright (c) 2023 ZettaScale Technology +// // +// // This program and the accompanying materials are made available under the +// // terms of the Eclipse Public License 2.0 which is available at +// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// // which is available at https://www.apache.org/licenses/LICENSE-2.0. +// // +// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// // +// // Contributors: +// // ZettaScale Zenoh Team, +// // +// use crate::net::routing::router::{self, *}; +// use std::convert::{TryFrom, TryInto}; +// use std::sync::{Arc, Mutex, RwLock}; +// use std::time::Duration; +// use uhlc::HLC; +// use zenoh_buffers::ZBuf; +// use zenoh_config::defaults::queries_default_timeout; +// use zenoh_core::zlock; +// use zenoh_protocol::{ +// core::{ +// key_expr::keyexpr, Channel, CongestionControl, ExprId, Reliability, WhatAmI, WireExpr, +// ZenohId, EMPTY_EXPR_ID, +// }, +// zenoh::{ +// ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, +// RoutingContext, SubInfo, SubMode, +// }, +// }; +// use zenoh_transport::{DummyPrimitives, Primitives}; + +// #[test] +// fn base_test() { +// let tables = TablesLock { +// tables: RwLock::new(Tables::new( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// Some(Arc::new(HLC::default())), +// false, +// true, +// Duration::from_millis(queries_default_timeout), +// )), +// ctrl_lock: Mutex::new(()), +// queries_lock: RwLock::new(()), +// }; + +// let primitives = Arc::new(DummyPrimitives::new()); +// let face = zwrite!(tables.tables).open_face( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// primitives, +// ); +// register_expr( +// &tables, +// &mut face.upgrade().unwrap(), +// 1, +// &"one/two/three".into(), +// ); +// register_expr( +// &tables, +// &mut face.upgrade().unwrap(), +// 2, +// &"one/deux/trois".into(), +// ); + +// let sub_info = SubInfo { +// reliability: Reliability::Reliable, +// mode: SubMode::Push, +// }; +// declare_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face.upgrade().unwrap(), +// &WireExpr::from(1).with_suffix("four/five"), +// &sub_info, +// ); + +// Tables::print(&zread!(tables.tables)); +// } + +// #[test] +// fn match_test() { +// let key_exprs = [ +// "**", +// "a", +// "a/b", +// "*", +// "a/*", +// "a/b$*", +// "abc", +// "xx", +// "ab$*", +// "abcd", +// "ab$*d", +// "ab", +// "ab/*", +// "a/*/c/*/e", +// "a/b/c/d/e", +// "a/$*b/c/$*d/e", +// "a/xb/c/xd/e", +// "a/c/e", +// "a/b/c/d/x/e", +// "ab$*cd", +// "abxxcxxd", +// "abxxcxxcd", +// "abxxcxxcdx", +// "a/b/c", +// "ab/**", +// "**/xyz", +// "a/b/xyz/d/e/f/xyz", +// "**/xyz$*xyz", +// "a/b/xyz/d/e/f/xyz", +// "a/**/c/**/e", +// "a/b/b/b/c/d/d/d/e", +// "a/**/c/*/e/*", +// "a/b/b/b/c/d/d/c/d/e/f", +// "a/**/c/*/e/*", +// "x/abc", +// "x/*", +// "x/abc$*", +// "x/$*abc", +// "x/a$*", +// "x/a$*de", +// "x/abc$*de", +// "x/a$*d$*e", +// "x/a$*e", +// "x/a$*c$*e", +// "x/ade", +// "x/c$*", +// "x/$*d", +// "x/$*e", +// ] +// .map(|s| keyexpr::new(s).unwrap()); + +// let tables = TablesLock { +// tables: RwLock::new(Tables::new( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// Some(Arc::new(HLC::default())), +// false, +// true, +// Duration::from_millis(queries_default_timeout), +// )), +// ctrl_lock: Mutex::new(()), +// queries_lock: RwLock::new(()), +// }; +// let primitives = Arc::new(DummyPrimitives::new()); +// let face = zwrite!(tables.tables).open_face( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// primitives, +// ); +// for (i, key_expr) in key_exprs.iter().enumerate() { +// register_expr( +// &tables, +// &mut face.upgrade().unwrap(), +// i.try_into().unwrap(), +// &(*key_expr).into(), +// ); +// } + +// for key_expr1 in key_exprs.iter() { +// let res_matches = Resource::get_matches(&zread!(tables.tables), key_expr1); +// dbg!(res_matches.len()); +// for key_expr2 in key_exprs.iter() { +// if res_matches +// .iter() +// .map(|m| m.upgrade().unwrap().expr()) +// .any(|x| x.as_str() == key_expr2.as_str()) +// { +// assert!(dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); +// } else { +// assert!(!dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); +// } +// } +// } +// } + +// #[test] +// fn clean_test() { +// let tables = TablesLock { +// tables: RwLock::new(Tables::new( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// Some(Arc::new(HLC::default())), +// false, +// true, +// Duration::from_millis(queries_default_timeout), +// )), +// ctrl_lock: Mutex::new(()), +// queries_lock: RwLock::new(()), +// }; + +// let primitives = Arc::new(DummyPrimitives::new()); +// let face0 = zwrite!(tables.tables).open_face( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// primitives, +// ); +// assert!(face0.upgrade().is_some()); + +// // -------------- +// register_expr(&tables, &mut face0.upgrade().unwrap(), 1, &"todrop1".into()); +// let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres1.is_some()); +// let res1 = optres1.unwrap(); +// assert!(res1.upgrade().is_some()); + +// register_expr( +// &tables, +// &mut face0.upgrade().unwrap(), +// 2, +// &"todrop1/todrop11".into(), +// ); +// let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres2.is_some()); +// let res2 = optres2.unwrap(); +// assert!(res2.upgrade().is_some()); + +// register_expr(&tables, &mut face0.upgrade().unwrap(), 3, &"**".into()); +// let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "**") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres3.is_some()); +// let res3 = optres3.unwrap(); +// assert!(res3.upgrade().is_some()); + +// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 1); +// assert!(res1.upgrade().is_some()); +// assert!(res2.upgrade().is_some()); +// assert!(res3.upgrade().is_some()); + +// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 2); +// assert!(res1.upgrade().is_none()); +// assert!(res2.upgrade().is_none()); +// assert!(res3.upgrade().is_some()); + +// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 3); +// assert!(res1.upgrade().is_none()); +// assert!(res2.upgrade().is_none()); +// assert!(res3.upgrade().is_none()); + +// // -------------- +// register_expr(&tables, &mut face0.upgrade().unwrap(), 1, &"todrop1".into()); +// let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres1.is_some()); +// let res1 = optres1.unwrap(); +// assert!(res1.upgrade().is_some()); + +// let sub_info = SubInfo { +// reliability: Reliability::Reliable, +// mode: SubMode::Push, +// }; + +// declare_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face0.upgrade().unwrap(), +// &"todrop1/todrop11".into(), +// &sub_info, +// ); +// let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres2.is_some()); +// let res2 = optres2.unwrap(); +// assert!(res2.upgrade().is_some()); + +// declare_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face0.upgrade().unwrap(), +// &WireExpr::from(1).with_suffix("/todrop12"), +// &sub_info, +// ); +// let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop12") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres3.is_some()); +// let res3 = optres3.unwrap(); +// assert!(res3.upgrade().is_some()); + +// forget_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face0.upgrade().unwrap(), +// &WireExpr::from(1).with_suffix("/todrop12"), +// ); +// assert!(res1.upgrade().is_some()); +// assert!(res2.upgrade().is_some()); +// assert!(res3.upgrade().is_none()); + +// forget_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face0.upgrade().unwrap(), +// &"todrop1/todrop11".into(), +// ); +// assert!(res1.upgrade().is_some()); +// assert!(res2.upgrade().is_none()); +// assert!(res3.upgrade().is_none()); + +// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 1); +// assert!(res1.upgrade().is_none()); +// assert!(res2.upgrade().is_none()); +// assert!(res3.upgrade().is_none()); + +// // -------------- +// register_expr(&tables, &mut face0.upgrade().unwrap(), 2, &"todrop3".into()); +// declare_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face0.upgrade().unwrap(), +// &"todrop3".into(), +// &sub_info, +// ); +// let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop3") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres1.is_some()); +// let res1 = optres1.unwrap(); +// assert!(res1.upgrade().is_some()); + +// forget_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face0.upgrade().unwrap(), +// &"todrop3".into(), +// ); +// assert!(res1.upgrade().is_some()); + +// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 2); +// assert!(res1.upgrade().is_none()); + +// // -------------- +// register_expr(&tables, &mut face0.upgrade().unwrap(), 3, &"todrop4".into()); +// register_expr(&tables, &mut face0.upgrade().unwrap(), 4, &"todrop5".into()); +// declare_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face0.upgrade().unwrap(), +// &"todrop5".into(), +// &sub_info, +// ); +// declare_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face0.upgrade().unwrap(), +// &"todrop6".into(), +// &sub_info, +// ); + +// let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop4") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres1.is_some()); +// let res1 = optres1.unwrap(); +// let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop5") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres2.is_some()); +// let res2 = optres2.unwrap(); +// let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop6") +// .map(|res| Arc::downgrade(&res)); +// assert!(optres3.is_some()); +// let res3 = optres3.unwrap(); + +// assert!(res1.upgrade().is_some()); +// assert!(res2.upgrade().is_some()); +// assert!(res3.upgrade().is_some()); + +// router::close_face(&tables, &face0); +// assert!(face0.upgrade().is_none()); +// assert!(res1.upgrade().is_none()); +// assert!(res2.upgrade().is_none()); +// assert!(res3.upgrade().is_none()); +// } + +// pub struct ClientPrimitives { +// data: std::sync::Mutex>>, +// mapping: std::sync::Mutex>, +// } + +// impl ClientPrimitives { +// pub fn new() -> ClientPrimitives { +// ClientPrimitives { +// data: std::sync::Mutex::new(None), +// mapping: std::sync::Mutex::new(std::collections::HashMap::new()), +// } +// } + +// pub fn clear_data(&self) { +// *self.data.lock().unwrap() = None; +// } +// } + +// impl Default for ClientPrimitives { +// fn default() -> Self { +// Self::new() +// } +// } + +// impl ClientPrimitives { +// fn get_name(&self, key_expr: &WireExpr) -> String { +// let mapping = self.mapping.lock().unwrap(); +// let (scope, suffix) = key_expr.as_id_and_suffix(); +// if scope == EMPTY_EXPR_ID { +// suffix.to_string() +// } else if suffix.is_empty() { +// mapping.get(&scope).unwrap().clone() +// } else { +// format!("{}{}", mapping.get(&scope).unwrap(), suffix) +// } +// } + +// fn get_last_name(&self) -> Option { +// self.data +// .lock() +// .unwrap() +// .as_ref() +// .map(|data| self.get_name(data)) +// } + +// #[allow(dead_code)] +// fn get_last_key(&self) -> Option { +// self.data.lock().unwrap().as_ref().cloned() +// } +// } + +// impl Primitives for ClientPrimitives { +// fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { +// let name = self.get_name(key_expr); +// zlock!(self.mapping).insert(expr_id, name); +// } + +// fn forget_resource(&self, expr_id: ExprId) { +// zlock!(self.mapping).remove(&expr_id); +// } + +// fn decl_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} +// fn forget_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} + +// fn decl_subscriber( +// &self, +// _key_expr: &WireExpr, +// _sub_info: &SubInfo, +// _routing_context: Option, +// ) { +// } +// fn forget_subscriber(&self, _key_expr: &WireExpr, _routing_context: Option) {} + +// fn decl_queryable( +// &self, +// _key_expr: &WireExpr, +// _qabl_info: &QueryableInfo, +// _routing_context: Option, +// ) { +// } +// fn forget_queryable(&self, _key_expr: &WireExpr, _routing_context: Option) {} + +// fn send_push( +// &self, +// key_expr: &WireExpr, +// _payload: ZBuf, +// _channel: Channel, +// _congestion_control: CongestionControl, +// _info: Option, +// _routing_context: Option, +// ) { +// *zlock!(self.data) = Some(key_expr.to_owned()); +// } + +// fn send_request( +// &self, +// _key_expr: &WireExpr, +// _parameters: &str, +// _qid: QueryId, +// _target: QueryTarget, +// _consolidation: ConsolidationMode, +// _body: Option, +// _routing_context: Option, +// ) { +// } + +// fn send_response( +// &self, +// _qid: QueryId, +// _replier_id: ZenohId, +// _key_expr: WireExpr, +// _info: Option, +// _payload: ZBuf, +// ) { +// } +// fn send_response_final(&self, _qid: QueryId) {} + +// fn send_close(&self) {} +// } + +// #[test] +// fn client_test() { +// let tables = TablesLock { +// tables: RwLock::new(Tables::new( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// Some(Arc::new(HLC::default())), +// false, +// true, +// Duration::from_millis(queries_default_timeout), +// )), +// ctrl_lock: Mutex::new(()), +// queries_lock: RwLock::new(()), +// }; + +// let sub_info = SubInfo { +// reliability: Reliability::Reliable, +// mode: SubMode::Push, +// }; + +// let primitives0 = Arc::new(ClientPrimitives::new()); + +// let face0 = zwrite!(tables.tables).open_face( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// primitives0.clone(), +// ); +// register_expr( +// &tables, +// &mut face0.upgrade().unwrap(), +// 11, +// &"test/client".into(), +// ); +// primitives0.decl_resource(11, &"test/client".into()); +// declare_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face0.upgrade().unwrap(), +// &WireExpr::from(11).with_suffix("/**"), +// &sub_info, +// ); +// register_expr( +// &tables, +// &mut face0.upgrade().unwrap(), +// 12, +// &WireExpr::from(11).with_suffix("/z1_pub1"), +// ); +// primitives0.decl_resource(12, &WireExpr::from(11).with_suffix("/z1_pub1")); + +// let primitives1 = Arc::new(ClientPrimitives::new()); +// let face1 = zwrite!(tables.tables).open_face( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// primitives1.clone(), +// ); +// register_expr( +// &tables, +// &mut face1.upgrade().unwrap(), +// 21, +// &"test/client".into(), +// ); +// primitives1.decl_resource(21, &"test/client".into()); +// declare_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face1.upgrade().unwrap(), +// &WireExpr::from(21).with_suffix("/**"), +// &sub_info, +// ); +// register_expr( +// &tables, +// &mut face1.upgrade().unwrap(), +// 22, +// &WireExpr::from(21).with_suffix("/z2_pub1"), +// ); +// primitives1.decl_resource(22, &WireExpr::from(21).with_suffix("/z2_pub1")); + +// let primitives2 = Arc::new(ClientPrimitives::new()); +// let face2 = zwrite!(tables.tables).open_face( +// ZenohId::try_from([1]).unwrap(), +// WhatAmI::Client, +// primitives2.clone(), +// ); +// register_expr( +// &tables, +// &mut face2.upgrade().unwrap(), +// 31, +// &"test/client".into(), +// ); +// primitives2.decl_resource(31, &"test/client".into()); +// declare_client_subscription( +// &tables, +// zread!(tables.tables), +// &mut face2.upgrade().unwrap(), +// &WireExpr::from(31).with_suffix("/**"), +// &sub_info, +// ); + +// primitives0.clear_data(); +// primitives1.clear_data(); +// primitives2.clear_data(); +// full_reentrant_route_data( +// &tables.tables, +// &face0.upgrade().unwrap(), +// &"test/client/z1_wr1".into(), +// Channel::default(), +// CongestionControl::default(), +// None, +// ZBuf::empty(), +// None, +// ); + +// // functionnal check +// assert!(primitives1.get_last_name().is_some()); +// assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_wr1"); +// // mapping strategy check +// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_wr1".to_string())); + +// // functionnal check +// assert!(primitives2.get_last_name().is_some()); +// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_wr1"); +// // mapping strategy check +// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_wr1".to_string())); + +// primitives0.clear_data(); +// primitives1.clear_data(); +// primitives2.clear_data(); +// full_reentrant_route_data( +// &tables.tables, +// &face0.upgrade().unwrap(), +// &WireExpr::from(11).with_suffix("/z1_wr2"), +// Channel::default(), +// CongestionControl::default(), +// None, +// ZBuf::empty(), +// None, +// ); + +// // functionnal check +// assert!(primitives1.get_last_name().is_some()); +// assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_wr2"); +// // mapping strategy check +// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_wr2".to_string())); + +// // functionnal check +// assert!(primitives2.get_last_name().is_some()); +// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_wr2"); +// // mapping strategy check +// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_wr2".to_string())); + +// primitives0.clear_data(); +// primitives1.clear_data(); +// primitives2.clear_data(); +// full_reentrant_route_data( +// &tables.tables, +// &face1.upgrade().unwrap(), +// &"test/client/**".into(), +// Channel::default(), +// CongestionControl::default(), +// None, +// ZBuf::empty(), +// None, +// ); + +// // functionnal check +// assert!(primitives0.get_last_name().is_some()); +// assert_eq!(primitives0.get_last_name().unwrap(), "test/client/**"); +// // mapping strategy check +// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(11, "/**".to_string())); + +// // functionnal check +// assert!(primitives2.get_last_name().is_some()); +// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/**"); +// // mapping strategy check +// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/**".to_string())); + +// primitives0.clear_data(); +// primitives1.clear_data(); +// primitives2.clear_data(); +// full_reentrant_route_data( +// &tables.tables, +// &face0.upgrade().unwrap(), +// &12.into(), +// Channel::default(), +// CongestionControl::default(), +// None, +// ZBuf::empty(), +// None, +// ); + +// // functionnal check +// assert!(primitives1.get_last_name().is_some()); +// assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_pub1"); +// // mapping strategy check +// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_pub1".to_string())); + +// // functionnal check +// assert!(primitives2.get_last_name().is_some()); +// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_pub1"); +// // mapping strategy check +// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_pub1".to_string())); + +// primitives0.clear_data(); +// primitives1.clear_data(); +// primitives2.clear_data(); +// full_reentrant_route_data( +// &tables.tables, +// &face1.upgrade().unwrap(), +// &22.into(), +// Channel::default(), +// CongestionControl::default(), +// None, +// ZBuf::empty(), +// None, +// ); + +// // functionnal check +// assert!(primitives0.get_last_name().is_some()); +// assert_eq!(primitives0.get_last_name().unwrap(), "test/client/z2_pub1"); +// // mapping strategy check +// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(11, "/z2_pub1".to_string())); + +// // functionnal check +// assert!(primitives2.get_last_name().is_some()); +// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z2_pub1"); +// // mapping strategy check +// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z2_pub1".to_string())); +// } diff --git a/zenoh/src/publication.rs b/zenoh/src/publication.rs index 5e901c714c..47f69c0d8b 100644 --- a/zenoh/src/publication.rs +++ b/zenoh/src/publication.rs @@ -16,13 +16,18 @@ use crate::net::transport::Primitives; use crate::prelude::*; -use crate::subscriber::Reliability; use crate::Encoding; use crate::SessionRef; use crate::Undeclarable; use std::future::Ready; use zenoh_core::{zread, AsyncResolve, Resolvable, Resolve, SyncResolve}; -use zenoh_protocol::{core::Channel, zenoh::DataInfo}; +use zenoh_protocol::network::push::ext; +use zenoh_protocol::network::Mapping; +use zenoh_protocol::network::Push; +use zenoh_protocol::zenoh::DataInfo; +use zenoh_protocol::zenoh_new::Del; +use zenoh_protocol::zenoh_new::PushBody; +use zenoh_protocol::zenoh_new::Put; use zenoh_result::ZResult; /// The kind of congestion control. @@ -129,41 +134,47 @@ impl SyncResolve for PutBuilder<'_, '_> { .as_ref() .unwrap() .clone(); - - let info = DataInfo { - kind, - encoding: if value.encoding != Encoding::default() { - Some(value.encoding) - } else { - None - }, - timestamp: publisher.session.runtime.new_timestamp(), - ..Default::default() - }; - let data_info = if info != DataInfo::default() { - Some(info) - } else { - None - }; + let timestamp = publisher.session.runtime.new_timestamp(); if publisher.destination != Locality::SessionLocal { - primitives.send_data( - &key_expr.to_wire(&publisher.session), - value.payload.clone(), - Channel { - priority: publisher.priority.into(), - reliability: Reliability::Reliable, // @TODO: need to check subscriptions to determine the right reliability value + primitives.send_push(Push { + wire_expr: key_expr.to_wire(&publisher.session).to_owned(), + mapping: Mapping::default(), // TODO + ext_qos: ext::QoSType::new( + publisher.priority.into(), + publisher.congestion_control, + false, + ), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: match kind { + SampleKind::Put => PushBody::Put(Put { + timestamp, + encoding: value.encoding.clone(), + ext_sinfo: None, + ext_unknown: vec![], + payload: value.payload.clone(), + }), + SampleKind::Delete => PushBody::Del(Del { + timestamp, + ext_sinfo: None, + ext_unknown: vec![], + }), }, - publisher.congestion_control, - data_info.clone(), - None, - ); + }); } if publisher.destination != Locality::Remote { + let data_info = DataInfo { + kind, + encoding: Some(value.encoding), + timestamp, + ..Default::default() + }; + publisher.session.handle_data( true, &key_expr.to_wire(&publisher.session), - data_info, + Some(data_info), value.payload, ); } @@ -416,40 +427,36 @@ impl SyncResolve for Publication<'_> { .unwrap() .clone(); - let info = DataInfo { - kind, - encoding: if value.encoding != Encoding::default() { - Some(value.encoding) - } else { - None - }, - timestamp: publisher.session.runtime.new_timestamp(), - ..Default::default() - }; - let data_info = if info != DataInfo::default() { - Some(info) - } else { - None - }; - if publisher.destination != Locality::SessionLocal { - primitives.send_data( - &publisher.key_expr.to_wire(&publisher.session), - value.payload.clone(), - Channel { - priority: publisher.priority.into(), - reliability: Reliability::Reliable, // @TODO: need to check subscriptions to determine the right reliability value - }, - publisher.congestion_control, - data_info.clone(), - None, - ); + primitives.send_push(Push { + wire_expr: publisher.key_expr.to_wire(&publisher.session).to_owned(), + mapping: Mapping::default(), // TODO + ext_qos: ext::QoSType::default(), // TODO + // use publisher.priority + // use publisher.congestion_control + // need to check subscriptions to determine the right reliability value + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: publisher.session.runtime.new_timestamp(), + encoding: value.encoding.clone(), + ext_sinfo: None, + ext_unknown: vec![], + payload: value.payload.clone(), + }), + }); } if publisher.destination != Locality::Remote { + let data_info = DataInfo { + kind, + encoding: Some(value.encoding), + timestamp: publisher.session.runtime.new_timestamp(), + ..Default::default() + }; publisher.session.handle_data( true, &publisher.key_expr.to_wire(&publisher.session), - data_info, + Some(data_info), value.payload, ); } diff --git a/zenoh/src/queryable.rs b/zenoh/src/queryable.rs index 1c3714d4ed..666a7f81a8 100644 --- a/zenoh/src/queryable.rs +++ b/zenoh/src/queryable.rs @@ -26,6 +26,9 @@ use std::future::Ready; use std::ops::Deref; use std::sync::Arc; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; +use zenoh_protocol::network::{response, Mapping, Response, ResponseFinal}; +use zenoh_protocol::zenoh_new::reply::ext::ConsolidationType; +use zenoh_protocol::zenoh_new::{self, ResponseBody}; use zenoh_protocol::{core::WireExpr, zenoh::QueryId}; use zenoh_result::ZResult; use zenoh_transport::Primitives; @@ -45,7 +48,11 @@ pub(crate) struct QueryInner { impl Drop for QueryInner { fn drop(&mut self) { - self.primitives.send_reply_final(self.qid); + self.primitives.send_response_final(ResponseFinal { + rid: self.qid, + ext_qos: response::ext::QoSType::default(), + ext_tstamp: None, + }); } } @@ -156,16 +163,37 @@ impl SyncResolve for ReplyBuilder<'_> { bail!("Attempted to reply on `{}`, which does not intersect with query `{}`, despite query only allowing replies on matching key expressions", sample.key_expr, self.query.key_expr()) } let (key_expr, payload, data_info) = sample.split(); - self.query.inner.primitives.send_reply_data( - self.query.inner.qid, - self.query.inner.zid, - WireExpr { + self.query.inner.primitives.send_response(Response { + rid: self.query.inner.qid, + wire_expr: WireExpr { scope: 0, - suffix: std::borrow::Cow::Borrowed(key_expr.as_str()), + suffix: std::borrow::Cow::Owned(key_expr.into()), }, - Some(data_info), - payload, - ); + mapping: Mapping::default(), // TODO + payload: ResponseBody::Reply(zenoh_new::Reply { + timestamp: data_info.timestamp, + encoding: data_info.encoding.unwrap_or_default(), + ext_sinfo: if data_info.source_id.is_some() || data_info.source_sn.is_some() + { + Some(zenoh_new::reply::ext::SourceInfoType { + zid: data_info.source_id.unwrap_or_default(), + eid: 0, // TODO + sn: data_info.source_sn.unwrap_or_default() as u32, + }) + } else { + None + }, + ext_consolidation: ConsolidationType::default(), + ext_unknown: vec![], + payload, + }), + ext_qos: response::ext::QoSType::default(), + ext_tstamp: None, + ext_respid: Some(response::ext::ResponderIdType { + zid: self.query.inner.zid, + eid: 0, // TODO + }), + }); Ok(()) } Err(_) => Err(zerror!("Replying errors is not yet supported!").into()), diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 2ce134efa1..15c453d11f 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -52,15 +52,39 @@ use zenoh_buffers::ZBuf; use zenoh_collections::SingleOrVec; use zenoh_config::unwrap_or_default; use zenoh_core::{zconfigurable, zread, Resolve, ResolveClosure, ResolveFuture, SyncResolve}; +use zenoh_protocol::network::common::ext::WireExprType; +use zenoh_protocol::network::declare; +use zenoh_protocol::network::ext; +use zenoh_protocol::network::queryable::ext::QueryableInfo; +use zenoh_protocol::network::request; +use zenoh_protocol::network::request::ext::TargetType; +use zenoh_protocol::network::subscriber::ext::SubscriberInfo; +use zenoh_protocol::network::Declare; +use zenoh_protocol::network::DeclareBody; +use zenoh_protocol::network::DeclareKeyExpr; +use zenoh_protocol::network::DeclareQueryable; +use zenoh_protocol::network::DeclareSubscriber; +use zenoh_protocol::network::Mapping; +use zenoh_protocol::network::Push; +use zenoh_protocol::network::Request; +use zenoh_protocol::network::Response; +use zenoh_protocol::network::ResponseFinal; +use zenoh_protocol::network::UndeclareQueryable; +use zenoh_protocol::network::UndeclareSubscriber; +use zenoh_protocol::zenoh_new; +use zenoh_protocol::zenoh_new::query; +use zenoh_protocol::zenoh_new::query::ext::ConsolidationType; +use zenoh_protocol::zenoh_new::query::ext::QueryBodyType; +use zenoh_protocol::zenoh_new::Pull; +use zenoh_protocol::zenoh_new::PushBody; +use zenoh_protocol::zenoh_new::RequestBody; +use zenoh_protocol::zenoh_new::ResponseBody; use zenoh_protocol::{ core::{ key_expr::{keyexpr, OwnedKeyExpr}, - AtomicExprId, Channel, CongestionControl, ExprId, WireExpr, ZenohId, EMPTY_EXPR_ID, - }, - zenoh::{ - AtomicQueryId, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, - RoutingContext, SubInfo, + AtomicExprId, CongestionControl, ExprId, WireExpr, ZenohId, EMPTY_EXPR_ID, }, + zenoh::{AtomicQueryId, DataInfo, QueryId, QueryTarget}, }; use zenoh_result::ZResult; use zenoh_util::core::AsyncResolve; @@ -80,20 +104,20 @@ pub(crate) struct SessionState { pub(crate) decl_id_counter: AtomicUsize, pub(crate) local_resources: HashMap, pub(crate) remote_resources: HashMap, - pub(crate) publications: Vec, + //pub(crate) publications: Vec, pub(crate) subscribers: HashMap>, pub(crate) queryables: HashMap>, #[cfg(feature = "unstable")] pub(crate) tokens: HashMap>, pub(crate) queries: HashMap, pub(crate) aggregated_subscribers: Vec, - pub(crate) aggregated_publishers: Vec, + //pub(crate) aggregated_publishers: Vec, } impl SessionState { pub(crate) fn new( aggregated_subscribers: Vec, - aggregated_publishers: Vec, + _aggregated_publishers: Vec, ) -> SessionState { SessionState { primitives: None, @@ -102,14 +126,14 @@ impl SessionState { decl_id_counter: AtomicUsize::new(0), local_resources: HashMap::new(), remote_resources: HashMap::new(), - publications: Vec::new(), + //publications: Vec::new(), subscribers: HashMap::new(), queryables: HashMap::new(), #[cfg(feature = "unstable")] tokens: HashMap::new(), queries: HashMap::new(), aggregated_subscribers, - aggregated_publishers, + //aggregated_publishers, } } } @@ -870,13 +894,18 @@ impl Session { state.local_resources.insert(expr_id, res); let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); - primitives.decl_resource( - expr_id, - &WireExpr { - scope: 0, - suffix: std::borrow::Cow::Borrowed(prefix), - }, - ); + primitives.send_declare(Declare { + ext_qos: declare::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::default(), + body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { + id: expr_id, + wire_expr: WireExpr { + scope: 0, + suffix: prefix.to_owned().into(), + }, + }), + }); expr_id } } @@ -893,30 +922,30 @@ impl Session { /// * `key_expr` - The key expression to publish pub(crate) fn declare_publication_intent<'a>( &'a self, - key_expr: KeyExpr<'a>, + _key_expr: KeyExpr<'a>, ) -> impl Resolve> + Send + 'a { ResolveClosure::new(move || { - log::trace!("declare_publication({:?})", key_expr); - let mut state = zwrite!(self.state); - if !state.publications.iter().any(|p| **p == **key_expr) { - let declared_pub = if let Some(join_pub) = state - .aggregated_publishers - .iter() - .find(|s| s.includes(&key_expr)) - { - let joined_pub = state.publications.iter().any(|p| join_pub.includes(p)); - (!joined_pub).then(|| join_pub.clone().into()) - } else { - Some(key_expr.clone()) - }; - state.publications.push(key_expr.into()); - - if let Some(res) = declared_pub { - let primitives = state.primitives.as_ref().unwrap().clone(); - drop(state); - primitives.decl_publisher(&res.to_wire(self), None); - } - } + // log::trace!("declare_publication({:?})", key_expr); + // let mut state = zwrite!(self.state); + // if !state.publications.iter().any(|p| **p == **key_expr) { + // let declared_pub = if let Some(join_pub) = state + // .aggregated_publishers + // .iter() + // .find(|s| s.includes(&key_expr)) + // { + // let joined_pub = state.publications.iter().any(|p| join_pub.includes(p)); + // (!joined_pub).then(|| join_pub.clone().into()) + // } else { + // Some(key_expr.clone()) + // }; + // state.publications.push(key_expr.into()); + + // if let Some(res) = declared_pub { + // let primitives = state.primitives.as_ref().unwrap().clone(); + // drop(state); + // primitives.decl_publisher(&res.to_wire(self), None); + // } + // } Ok(()) }) } @@ -929,36 +958,36 @@ impl Session { /// * `key_expr` - The key expression of the publication to undeclarte pub(crate) fn undeclare_publication_intent<'a>( &'a self, - key_expr: KeyExpr<'a>, + _key_expr: KeyExpr<'a>, ) -> impl Resolve> + 'a { ResolveClosure::new(move || { - let mut state = zwrite!(self.state); - if let Some(idx) = state.publications.iter().position(|p| **p == *key_expr) { - trace!("undeclare_publication({:?})", key_expr); - state.publications.remove(idx); - match state - .aggregated_publishers - .iter() - .find(|s| s.includes(&key_expr)) - { - Some(join_pub) => { - let joined_pub = state.publications.iter().any(|p| join_pub.includes(p)); - if !joined_pub { - let primitives = state.primitives.as_ref().unwrap().clone(); - let key_expr = WireExpr::from(join_pub).to_owned(); - drop(state); - primitives.forget_publisher(&key_expr, None); - } - } - None => { - let primitives = state.primitives.as_ref().unwrap().clone(); - drop(state); - primitives.forget_publisher(&key_expr.to_wire(self), None); - } - }; - } else { - bail!("Unable to find publication") - } + // let mut state = zwrite!(self.state); + // if let Some(idx) = state.publications.iter().position(|p| **p == *key_expr) { + // trace!("undeclare_publication({:?})", key_expr); + // state.publications.remove(idx); + // match state + // .aggregated_publishers + // .iter() + // .find(|s| s.includes(&key_expr)) + // { + // Some(join_pub) => { + // let joined_pub = state.publications.iter().any(|p| join_pub.includes(p)); + // if !joined_pub { + // let primitives = state.primitives.as_ref().unwrap().clone(); + // let key_expr = WireExpr::from(join_pub).to_owned(); + // drop(state); + // primitives.forget_publisher(&key_expr, None); + // } + // } + // None => { + // let primitives = state.primitives.as_ref().unwrap().clone(); + // drop(state); + // primitives.forget_publisher(&key_expr.to_wire(self), None); + // } + // }; + // } else { + // bail!("Unable to find publication") + // } Ok(()) }) } @@ -969,7 +998,7 @@ impl Session { scope: &Option, origin: Locality, callback: Callback<'static, Sample>, - info: &SubInfo, + info: &SubscriberInfo, ) -> ZResult> { let mut state = zwrite!(self.state); log::trace!("subscribe({:?})", key_expr); @@ -1065,7 +1094,17 @@ impl Session { // key_expr.to_wire(self) // }; - primitives.decl_subscriber(&key_expr.to_wire(self), info, None); + primitives.send_declare(Declare { + ext_qos: declare::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: id as u32, + wire_expr: key_expr.to_wire(self).to_owned(), + mapping: Mapping::default(), // TODO + ext_info: *info, + }), + }); } Ok(sub_state) @@ -1113,9 +1152,20 @@ impl Session { }); if !joined_sub { let primitives = state.primitives.as_ref().unwrap().clone(); - let key_expr = WireExpr::from(join_sub).to_owned(); + let wire_expr = WireExpr::from(join_sub).to_owned(); drop(state); - primitives.forget_subscriber(&key_expr, None); + primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr, + mapping: Mapping::default(), + }, + }), + }); } } None => { @@ -1126,7 +1176,18 @@ impl Session { if !twin_sub { let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); - primitives.forget_subscriber(&key_expr.to_wire(self), None); + primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr: key_expr.to_wire(self).to_owned(), + mapping: Mapping::default(), + }, + }), + }); } } }; @@ -1166,7 +1227,17 @@ impl Session { complete, distance: 0, }; - primitives.decl_queryable(key_expr, &qabl_info, None); + primitives.send_declare(Declare { + ext_qos: declare::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: id as u32, + wire_expr: key_expr.to_owned(), + mapping: Mapping::default(), // TODO + ext_info: qabl_info, + }), + }); } } #[cfg(not(feature = "complete_n"))] @@ -1179,13 +1250,23 @@ impl Session { if origin != Locality::SessionLocal && (!twin_qabl || (!complete_twin_qabl && complete)) { let primitives = state.primitives.as_ref().unwrap().clone(); - let complete = u64::from(!complete_twin_qabl && complete); + let complete = u8::from(!complete_twin_qabl && complete); drop(state); let qabl_info = QueryableInfo { complete, distance: 0, }; - primitives.decl_queryable(key_expr, &qabl_info, None); + primitives.send_declare(Declare { + ext_qos: declare::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: id as u32, + wire_expr: key_expr.to_owned(), + mapping: Mapping::default(), // TODO + ext_info: qabl_info, + }), + }); } } Ok(qable_state) @@ -1241,7 +1322,17 @@ impl Session { complete, distance: 0, }; - primitives.decl_queryable(&qable_state.key_expr, &qabl_info, None); + primitives.send_declare(Declare { + ext_qos: declare::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: 0, // TODO + wire_expr: qable_state.key_expr.clone(), + mapping: Mapping::default(), // TODO + ext_info: qabl_info, + }), + }); } #[cfg(not(feature = "complete_n"))] { @@ -1251,14 +1342,35 @@ impl Session { complete: 0, distance: 0, }; - primitives.decl_queryable(&qable_state.key_expr, &qabl_info, None); + primitives.send_declare(Declare { + ext_qos: declare::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id: 0, // TODO + wire_expr: qable_state.key_expr.clone(), + mapping: Mapping::default(), // TODO + ext_info: qabl_info, + }), + }); } } } } else { // There are no more Queryables on the same KeyExpr. drop(state); - primitives.forget_queryable(&qable_state.key_expr, None); + primitives.send_declare(Declare { + ext_qos: declare::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::default(), + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr: qable_state.key_expr.clone(), + mapping: Mapping::default(), + }, + }), + }); } } Ok(()) @@ -1284,8 +1396,17 @@ impl Session { state.tokens.insert(tok_state.id, tok_state.clone()); let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); - let sub_info = SubInfo::default(); - primitives.decl_subscriber(&key_expr.to_wire(self), &sub_info, None); + primitives.send_declare(Declare { + ext_qos: declare::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: id as u32, + wire_expr: key_expr.to_wire(self).to_owned(), + mapping: Mapping::default(), + ext_info: SubscriberInfo::default(), + }), + }); Ok(tok_state) } @@ -1300,7 +1421,18 @@ impl Session { if !twin_tok { let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); - primitives.forget_subscriber(&key_expr.to_wire(self), None); + primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id: 0, // TODO + ext_wire_expr: WireExprType { + wire_expr: key_expr.to_wire(self).to_owned(), + mapping: Mapping::default(), + }, + }), + }); } Ok(()) } else { @@ -1427,7 +1559,20 @@ impl Session { let state = zread!(self.state); let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); - primitives.send_pull(true, &key_expr.to_wire(self), 0, &None); + primitives.send_request(Request { + id: 0, // TODO + wire_expr: key_expr.to_wire(self).to_owned(), + mapping: Mapping::default(), // TODO + ext_qos: ext::QoSType::default(), // TODO + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + ext_target: request::ext::TargetType::default(), + ext_budget: None, + ext_timeout: None, + payload: RequestBody::Pull(Pull { + ext_unknown: vec![], + }), + }); Ok(()) }) } @@ -1492,7 +1637,7 @@ impl Session { }; log::trace!("Register query {} (nb_final = {})", qid, nb_final); - let wexpr = selector.key_expr.to_wire(self); + let wexpr = selector.key_expr.to_wire(self).to_owned(); state.queries.insert( qid, QueryState { @@ -1509,24 +1654,27 @@ impl Session { drop(state); if destination != Locality::SessionLocal { - primitives.send_query( - &wexpr, - selector.parameters(), - qid, - target, - consolidation, - value.as_ref().map(|v| { - let data_info = DataInfo { - encoding: Some(v.encoding.clone()), - ..Default::default() - }; - QueryBody { - data_info, + primitives.send_request(Request { + id: qid, + wire_expr: wexpr.clone(), + mapping: Mapping::default(), // TODO + ext_qos: request::ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: request::ext::NodeIdType::default(), + ext_target: target.into(), + ext_budget: None, + ext_timeout: Some(timeout), + payload: RequestBody::Query(zenoh_new::Query { + parameters: selector.parameters().to_string(), + ext_sinfo: None, + ext_consolidation: consolidation.into(), + ext_body: value.as_ref().map(|v| query::ext::QueryBodyType { + encoding: v.encoding.clone(), payload: v.payload.clone(), - } + }), + ext_unknown: vec![], }), - None, - ); + }); } if destination != Locality::Remote { self.handle_query( @@ -1534,17 +1682,11 @@ impl Session { &wexpr, selector.parameters(), qid, - target, - consolidation, - value.map(|v| { - let data_info = DataInfo { - encoding: Some(v.encoding), - ..Default::default() - }; - QueryBody { - data_info, - payload: v.payload, - } + target.into(), + consolidation.into(), + value.as_ref().map(|v| query::ext::QueryBodyType { + encoding: v.encoding.clone(), + payload: v.payload.clone(), }), ); } @@ -1558,9 +1700,9 @@ impl Session { key_expr: &WireExpr, parameters: &str, qid: QueryId, - _target: QueryTarget, - _consolidation: ConsolidationMode, - body: Option, + _target: TargetType, + _consolidation: ConsolidationType, + body: Option, ) { let (primitives, key_expr, callbacks) = { let state = zread!(self.state); @@ -1612,7 +1754,7 @@ impl Session { parameters, value: body.map(|b| Value { payload: b.payload, - encoding: b.data_info.encoding.unwrap_or_default(), + encoding: b.encoding, }), qid, zid, @@ -1776,333 +1918,312 @@ impl SessionDeclarations for Arc { } impl Primitives for Session { - fn decl_resource(&self, expr_id: ExprId, wire_expr: &WireExpr) { - trace!("recv Decl Resource {} {:?}", expr_id, wire_expr); - let state = &mut zwrite!(self.state); - match state.remote_key_to_expr(wire_expr) { - Ok(key_expr) => { - let mut subs = Vec::new(); - for sub in state.subscribers.values() { - if key_expr.intersects(&sub.key_expr) { - subs.push(sub.clone()); + fn send_declare(&self, msg: zenoh_protocol::network::Declare) { + match msg.body { + zenoh_protocol::network::DeclareBody::DeclareKeyExpr(m) => { + trace!("recv DeclareKeyExpr {} {:?}", m.id, m.wire_expr); + let state = &mut zwrite!(self.state); + match state.remote_key_to_expr(&m.wire_expr) { + Ok(key_expr) => { + let mut subs = Vec::new(); + for sub in state.subscribers.values() { + if key_expr.intersects(&sub.key_expr) { + subs.push(sub.clone()); + } + } + let res = Resource::Node(ResourceNode { + key_expr: key_expr.into(), + subscribers: subs, + }); + + state.remote_resources.insert(m.id, res); } + Err(e) => error!( + "Received Resource for invalid wire_expr `{}`: {}", + m.wire_expr, e + ), } - let res = Resource::Node(ResourceNode { - key_expr: key_expr.into(), - subscribers: subs, - }); - - state.remote_resources.insert(expr_id, res); } - Err(e) => error!( - "Received Resource for invalid wire_expr `{}`: {}", - wire_expr, e - ), - } - } - - fn forget_resource(&self, _expr_id: ExprId) { - trace!("recv Forget Resource {}", _expr_id); - } - - fn decl_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) { - trace!("recv Decl Publisher {:?}", _key_expr); - } - - fn forget_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) { - trace!("recv Forget Publisher {:?}", _key_expr); - } - - fn decl_subscriber( - &self, - key_expr: &WireExpr, - _sub_info: &SubInfo, - _routing_context: Option, - ) { - trace!("recv Decl Subscriber {:?} , {:?}", key_expr, _sub_info); - #[cfg(feature = "unstable")] - { - let state = zread!(self.state); - match state.wireexpr_to_keyexpr(key_expr, false) { - Ok(expr) => { - if expr - .as_str() - .starts_with(crate::liveliness::PREFIX_LIVELINESS) - { - drop(state); - self.handle_data(false, key_expr, None, ZBuf::default()); + zenoh_protocol::network::DeclareBody::UndeclareKeyExpr(m) => { + trace!("recv UndeclareKeyExpr {}", m.id); + } + zenoh_protocol::network::DeclareBody::DeclareSubscriber(m) => { + trace!("recv DeclareSubscriber {} {:?}", m.id, m.wire_expr); + #[cfg(feature = "unstable")] + { + let state = zread!(self.state); + match state.wireexpr_to_keyexpr(&m.wire_expr, false) { + Ok(expr) => { + if expr + .as_str() + .starts_with(crate::liveliness::PREFIX_LIVELINESS) + { + drop(state); + self.handle_data(false, &m.wire_expr, None, ZBuf::default()); + } + } + Err(err) => { + log::error!("Received DeclareSubscriber for unkown wire_expr: {}", err) + } } } - Err(err) => log::error!("Received Forget Subscriber for unkown key_expr: {}", err), } + zenoh_protocol::network::DeclareBody::UndeclareSubscriber(m) => { + trace!("recv UndeclareSubscriber {:?}", m.id); + // #[cfg(feature = "unstable")] + // { + // let state = zread!(self.state); + // match state.wireexpr_to_keyexpr(key_expr, false) { + // Ok(expr) => { + // if expr + // .as_str() + // .starts_with(crate::liveliness::PREFIX_LIVELINESS) + // { + // drop(state); + // let data_info = DataInfo { + // kind: SampleKind::Delete, + // ..Default::default() + // }; + // self.handle_data(false, key_expr, Some(data_info), ZBuf::default()); + // } + // } + // Err(err) => log::error!("Received Forget Subscriber for unkown key_expr: {}", err), + // } + // } + } + zenoh_protocol::network::DeclareBody::DeclareQueryable(m) => { + trace!("recv DeclareQueryable {} {:?}", m.id, m.wire_expr); + } + zenoh_protocol::network::DeclareBody::UndeclareQueryable(m) => { + trace!("recv UndeclareQueryable {:?}", m.id); + } + DeclareBody::DeclareToken(_) => todo!(), + DeclareBody::UndeclareToken(_) => todo!(), + DeclareBody::DeclareInterest(_) => todo!(), + DeclareBody::FinalInterest(_) => todo!(), + DeclareBody::UndeclareInterest(_) => todo!(), } } - fn forget_subscriber(&self, key_expr: &WireExpr, _routing_context: Option) { - trace!("recv Forget Subscriber {:?}", key_expr); - #[cfg(feature = "unstable")] - { - let state = zread!(self.state); - match state.wireexpr_to_keyexpr(key_expr, false) { - Ok(expr) => { - if expr - .as_str() - .starts_with(crate::liveliness::PREFIX_LIVELINESS) - { - drop(state); - let data_info = DataInfo { - kind: SampleKind::Delete, - ..Default::default() - }; - self.handle_data(false, key_expr, Some(data_info), ZBuf::default()); - } - } - Err(err) => log::error!("Received Forget Subscriber for unkown key_expr: {}", err), + fn send_push(&self, msg: Push) { + trace!("recv Push {:?}", msg); + match msg.payload { + PushBody::Put(m) => { + let info = DataInfo { + kind: SampleKind::Put, + encoding: Some(m.encoding), + timestamp: m.timestamp, + source_id: m.ext_sinfo.as_ref().map(|i| i.zid), + source_sn: m.ext_sinfo.as_ref().map(|i| i.sn as u64), + }; + self.handle_data(false, &msg.wire_expr, Some(info), m.payload) + } + PushBody::Del(m) => { + let info = DataInfo { + kind: SampleKind::Delete, + encoding: None, + timestamp: m.timestamp, + source_id: m.ext_sinfo.as_ref().map(|i| i.zid), + source_sn: m.ext_sinfo.as_ref().map(|i| i.sn as u64), + }; + self.handle_data(false, &msg.wire_expr, Some(info), ZBuf::empty()) } } } - fn decl_queryable( - &self, - _key_expr: &WireExpr, - _qabl_info: &QueryableInfo, - _routing_context: Option, - ) { - trace!("recv Decl Queryable {:?}", _key_expr); - } - - fn forget_queryable(&self, _key_expr: &WireExpr, _routing_context: Option) { - trace!("recv Forget Queryable {:?}", _key_expr); - } - - fn send_data( - &self, - key_expr: &WireExpr, - payload: ZBuf, - channel: Channel, - congestion_control: CongestionControl, - info: Option, - _routing_context: Option, - ) { - trace!( - "recv Data {:?} {:?} {:?} {:?} {:?}", - key_expr, - payload, - channel, - congestion_control, - info, - ); - self.handle_data(false, key_expr, info, payload) - } - - fn send_query( - &self, - key_expr: &WireExpr, - parameters: &str, - qid: QueryId, - target: QueryTarget, - consolidation: ConsolidationMode, - body: Option, - _routing_context: Option, - ) { - trace!( - "recv Query {:?} {:?} {:?} {:?}", - key_expr, - parameters, - target, - consolidation - ); - self.handle_query( - false, - key_expr, - parameters, - qid, - target, - consolidation, - body, - ) + fn send_request(&self, msg: Request) { + trace!("recv Request {:?}", msg); + match msg.payload { + RequestBody::Query(m) => self.handle_query( + false, + &msg.wire_expr, + &m.parameters, + msg.id, + msg.ext_target, + m.ext_consolidation, + m.ext_body, + ), + RequestBody::Put(_) => (), + RequestBody::Del(_) => (), + RequestBody::Pull(_) => todo!(), + } } - fn send_reply_data( - &self, - qid: QueryId, - replier_id: ZenohId, - key_expr: WireExpr, - data_info: Option, - payload: ZBuf, - ) { - trace!( - "recv ReplyData {:?} {:?} {:?} {:?} {:?}", - qid, - replier_id, - key_expr, - data_info, - payload - ); - let mut state = zwrite!(self.state); - let key_expr = match state.remote_key_to_expr(&key_expr) { - Ok(key) => key.into_owned(), - Err(e) => { - error!("Received ReplyData for unkown key_expr: {}", e); - return; - } - }; - match state.queries.get_mut(&qid) { - Some(query) => { - if !matches!( - query - .selector - .parameters() - .get_bools([crate::query::_REPLY_KEY_EXPR_ANY_SEL_PARAM]), - Ok([true]) - ) && !query.selector.key_expr.intersects(&key_expr) - { - log::warn!( - "Received ReplyData for `{}` from `{:?}, which didn't match query `{}`: dropping ReplyData.", - key_expr, - replier_id, - query.selector - ); + fn send_response(&self, msg: Response) { + trace!("recv Response {:?}", msg); + if let ResponseBody::Reply(m) = msg.payload { + let mut state = zwrite!(self.state); + let key_expr = match state.remote_key_to_expr(&msg.wire_expr) { + Ok(key) => key.into_owned(), + Err(e) => { + error!("Received ReplyData for unkown key_expr: {}", e); return; } - let key_expr = match &query.scope { - Some(scope) => { - if !key_expr.starts_with(&***scope) { - log::warn!( - "Received ReplyData for `{}` from `{:?}, which didn't start with scope `{}`: dropping ReplyData.", - key_expr, - replier_id, - scope, - ); - return; - } - match KeyExpr::try_from(&key_expr[(scope.len() + 1)..]) { - Ok(key_expr) => key_expr, - Err(e) => { + }; + match state.queries.get_mut(&msg.rid) { + Some(query) => { + if !matches!( + query + .selector + .parameters() + .get_bools([crate::query::_REPLY_KEY_EXPR_ANY_SEL_PARAM]), + Ok([true]) + ) && !query.selector.key_expr.intersects(&key_expr) + { + log::warn!( + "Received Reply for `{}` from `{:?}, which didn't match query `{}`: dropping Reply.", + key_expr, + msg.ext_respid, + query.selector + ); + return; + } + let key_expr = match &query.scope { + Some(scope) => { + if !key_expr.starts_with(&***scope) { log::warn!( - "Error unscoping received ReplyData for `{}` from `{:?}: {}", + "Received Reply for `{}` from `{:?}, which didn't start with scope `{}`: dropping Reply.", key_expr, - replier_id, - e, + msg.ext_respid, + scope, ); return; } + match KeyExpr::try_from(&key_expr[(scope.len() + 1)..]) { + Ok(key_expr) => key_expr, + Err(e) => { + log::warn!( + "Error unscoping received Reply for `{}` from `{:?}: {}", + key_expr, + msg.ext_respid, + e, + ); + return; + } + } } - } - None => key_expr, - }; - let new_reply = Reply { - sample: Ok(Sample::with_info(key_expr.into_owned(), payload, data_info)), - replier_id, - }; - let callback = match query.reception_mode { - ConsolidationMode::None => Some((query.callback.clone(), new_reply)), - ConsolidationMode::Monotonic => { - match query - .replies - .as_ref() - .unwrap() - .get(new_reply.sample.as_ref().unwrap().key_expr.as_keyexpr()) - { - Some(reply) => { - if new_reply.sample.as_ref().unwrap().timestamp - > reply.sample.as_ref().unwrap().timestamp - { + None => key_expr, + }; + let info = DataInfo { + kind: SampleKind::Put, + encoding: Some(m.encoding), + timestamp: m.timestamp, + source_id: m.ext_sinfo.as_ref().map(|i| i.zid), + source_sn: m.ext_sinfo.as_ref().map(|i| i.sn as u64), + }; + let new_reply = Reply { + sample: Ok(Sample::with_info( + key_expr.into_owned(), + m.payload, + Some(info), + )), + replier_id: ZenohId::rand(), // TOTO + }; + let callback = match query.reception_mode { + ConsolidationMode::None => Some((query.callback.clone(), new_reply)), + ConsolidationMode::Monotonic => { + match query + .replies + .as_ref() + .unwrap() + .get(new_reply.sample.as_ref().unwrap().key_expr.as_keyexpr()) + { + Some(reply) => { + if new_reply.sample.as_ref().unwrap().timestamp + > reply.sample.as_ref().unwrap().timestamp + { + query.replies.as_mut().unwrap().insert( + new_reply + .sample + .as_ref() + .unwrap() + .key_expr + .clone() + .into(), + new_reply.clone(), + ); + Some((query.callback.clone(), new_reply)) + } else { + None + } + } + None => { query.replies.as_mut().unwrap().insert( new_reply.sample.as_ref().unwrap().key_expr.clone().into(), new_reply.clone(), ); Some((query.callback.clone(), new_reply)) - } else { - None } } - None => { - query.replies.as_mut().unwrap().insert( - new_reply.sample.as_ref().unwrap().key_expr.clone().into(), - new_reply.clone(), - ); - Some((query.callback.clone(), new_reply)) - } } - } - ConsolidationMode::Latest => { - match query - .replies - .as_ref() - .unwrap() - .get(new_reply.sample.as_ref().unwrap().key_expr.as_keyexpr()) - { - Some(reply) => { - if new_reply.sample.as_ref().unwrap().timestamp - > reply.sample.as_ref().unwrap().timestamp - { + ConsolidationMode::Latest => { + match query + .replies + .as_ref() + .unwrap() + .get(new_reply.sample.as_ref().unwrap().key_expr.as_keyexpr()) + { + Some(reply) => { + if new_reply.sample.as_ref().unwrap().timestamp + > reply.sample.as_ref().unwrap().timestamp + { + query.replies.as_mut().unwrap().insert( + new_reply + .sample + .as_ref() + .unwrap() + .key_expr + .clone() + .into(), + new_reply, + ); + } + } + None => { query.replies.as_mut().unwrap().insert( new_reply.sample.as_ref().unwrap().key_expr.clone().into(), new_reply, ); } - } - None => { - query.replies.as_mut().unwrap().insert( - new_reply.sample.as_ref().unwrap().key_expr.clone().into(), - new_reply, - ); - } - }; - None + }; + None + } + }; + std::mem::drop(state); + if let Some((callback, new_reply)) = callback { + callback(new_reply); } - }; - std::mem::drop(state); - if let Some((callback, new_reply)) = callback { - callback(new_reply); } - } - None => { - log::warn!("Received ReplyData for unkown Query: {}", qid); + None => { + log::warn!("Received ReplyData for unkown Query: {}", msg.rid); + } } } } - fn send_reply_final(&self, qid: QueryId) { - trace!("recv ReplyFinal {:?}", qid); + fn send_response_final(&self, msg: ResponseFinal) { + trace!("recv ResponseFinal {:?}", msg); let mut state = zwrite!(self.state); - match state.queries.get_mut(&qid) { + match state.queries.get_mut(&msg.rid) { Some(mut query) => { query.nb_final -= 1; if query.nb_final == 0 { - let query = state.queries.remove(&qid).unwrap(); + let query = state.queries.remove(&msg.rid).unwrap(); std::mem::drop(state); if query.reception_mode == ConsolidationMode::Latest { for (_, reply) in query.replies.unwrap().into_iter() { (query.callback)(reply); } } - trace!("Close query {}", qid); + trace!("Close query {}", msg.rid); } } None => { - warn!("Received ReplyFinal for unkown Query: {}", qid); + warn!("Received ResponseFinal for unkown Request: {}", msg.rid); } } } - fn send_pull( - &self, - _is_final: bool, - _key_expr: &WireExpr, - _pull_id: PullId, - _max_samples: &Option, - ) { - trace!( - "recv Pull {:?} {:?} {:?} {:?}", - _is_final, - _key_expr, - _pull_id, - _max_samples - ); - } - fn send_close(&self) { trace!("recv Close"); } diff --git a/zenoh/src/subscriber.rs b/zenoh/src/subscriber.rs index c93de0b0c9..75068d0261 100644 --- a/zenoh/src/subscriber.rs +++ b/zenoh/src/subscriber.rs @@ -23,7 +23,8 @@ use std::future::Ready; use std::ops::{Deref, DerefMut}; use std::sync::Arc; use zenoh_core::{AsyncResolve, Resolvable, Resolve, SyncResolve}; -use zenoh_protocol::zenoh::SubInfo; +use zenoh_protocol::network::subscriber::ext::SubscriberInfo; +use zenoh_protocol::network::Mode; /// The subscription mode. pub use zenoh_protocol::zenoh::SubMode; @@ -257,6 +258,12 @@ impl From for SubMode { } } +impl From for Mode { + fn from(_: PullMode) -> Self { + Mode::Pull + } +} + /// The mode for push subscribers. #[non_exhaustive] #[derive(Debug, Clone, Copy)] @@ -268,6 +275,12 @@ impl From for SubMode { } } +impl From for Mode { + fn from(_: PushMode) -> Self { + Mode::Push + } +} + /// A builder for initializing a [`FlumeSubscriber`](FlumeSubscriber). /// /// # Examples @@ -530,7 +543,7 @@ where &None, self.origin, callback, - &SubInfo { + &SubscriberInfo { reliability: self.reliability, mode: self.mode.into(), }, @@ -582,7 +595,7 @@ where &None, self.origin, callback, - &SubInfo { + &SubscriberInfo { reliability: self.reliability, mode: self.mode.into(), }, From ba5243c99985df181d8967b7992abc21e3d145c7 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Thu, 29 Jun 2023 16:06:57 +0200 Subject: [PATCH 150/203] Add missing files --- zenoh/src/net/codec/linkstate.rs | 158 ++++++++++++++++++++++++++++ zenoh/src/net/codec/mod.rs | 23 ++++ zenoh/src/net/protocol/linkstate.rs | 117 ++++++++++++++++++++ zenoh/src/net/protocol/mod.rs | 16 +++ 4 files changed, 314 insertions(+) create mode 100644 zenoh/src/net/codec/linkstate.rs create mode 100644 zenoh/src/net/codec/mod.rs create mode 100644 zenoh/src/net/protocol/linkstate.rs create mode 100644 zenoh/src/net/protocol/mod.rs diff --git a/zenoh/src/net/codec/linkstate.rs b/zenoh/src/net/codec/linkstate.rs new file mode 100644 index 0000000000..4954062a3d --- /dev/null +++ b/zenoh/src/net/codec/linkstate.rs @@ -0,0 +1,158 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use super::Zenoh080Routing; +use crate::net::protocol::{ + linkstate, + linkstate::{LinkState, LinkStateList}, +}; +use core::convert::TryFrom; +use zenoh_buffers::{ + reader::{DidntRead, Reader}, + writer::{DidntWrite, Writer}, +}; +use zenoh_codec::{RCodec, WCodec, Zenoh080}; +use zenoh_protocol::{ + common::imsg, + core::{Locator, WhatAmI, ZenohId}, +}; + +// LinkState +impl WCodec<&LinkState, &mut W> for Zenoh080Routing +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &LinkState) -> Self::Output { + let codec = Zenoh080::new(); + // Options + let mut options = 0; + if x.zid.is_some() { + options |= linkstate::PID; + } + if x.whatami.is_some() { + options |= linkstate::WAI; + } + if x.locators.is_some() { + options |= linkstate::LOC; + } + codec.write(&mut *writer, options)?; + + // Body + codec.write(&mut *writer, x.psid)?; + codec.write(&mut *writer, x.sn)?; + if let Some(zid) = x.zid.as_ref() { + codec.write(&mut *writer, zid)?; + } + if let Some(wai) = x.whatami { + let wai: u8 = wai.into(); + codec.write(&mut *writer, wai)?; + } + if let Some(locators) = x.locators.as_ref() { + codec.write(&mut *writer, locators.as_slice())?; + } + codec.write(&mut *writer, x.links.len())?; + for l in x.links.iter() { + codec.write(&mut *writer, *l)?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080Routing +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let codec = Zenoh080::new(); + let options: u64 = codec.read(&mut *reader)?; + let psid: u64 = codec.read(&mut *reader)?; + let sn: u64 = codec.read(&mut *reader)?; + let zid = if imsg::has_option(options, linkstate::PID) { + let zid: ZenohId = codec.read(&mut *reader)?; + Some(zid) + } else { + None + }; + let whatami = if imsg::has_option(options, linkstate::WAI) { + let wai: u8 = codec.read(&mut *reader)?; + Some(WhatAmI::try_from(wai).map_err(|_| DidntRead)?) + } else { + None + }; + let locators = if imsg::has_option(options, linkstate::LOC) { + let locs: Vec = codec.read(&mut *reader)?; + Some(locs) + } else { + None + }; + let len: usize = codec.read(&mut *reader)?; + let mut links: Vec = Vec::with_capacity(len); + for _ in 0..len { + let l: u64 = codec.read(&mut *reader)?; + links.push(l); + } + + Ok(LinkState { + psid, + sn, + zid, + whatami, + locators, + links, + }) + } +} + +// LinkStateList +impl WCodec<&LinkStateList, &mut W> for Zenoh080Routing +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &LinkStateList) -> Self::Output { + let codec = Zenoh080::new(); + + codec.write(&mut *writer, x.link_states.len())?; + for ls in x.link_states.iter() { + self.write(&mut *writer, ls)?; + } + + Ok(()) + } +} + +impl RCodec for Zenoh080Routing +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let codec = Zenoh080::new(); + + let len: usize = codec.read(&mut *reader)?; + let mut link_states = Vec::with_capacity(len); + for _ in 0..len { + let ls: LinkState = self.read(&mut *reader)?; + link_states.push(ls); + } + + Ok(LinkStateList { link_states }) + } +} diff --git a/zenoh/src/net/codec/mod.rs b/zenoh/src/net/codec/mod.rs new file mode 100644 index 0000000000..06154cd02c --- /dev/null +++ b/zenoh/src/net/codec/mod.rs @@ -0,0 +1,23 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +pub(crate) mod linkstate; + +#[derive(Clone, Copy)] +pub struct Zenoh080Routing; + +impl Zenoh080Routing { + pub const fn new() -> Self { + Self + } +} diff --git a/zenoh/src/net/protocol/linkstate.rs b/zenoh/src/net/protocol/linkstate.rs new file mode 100644 index 0000000000..ccb5612011 --- /dev/null +++ b/zenoh/src/net/protocol/linkstate.rs @@ -0,0 +1,117 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use zenoh_protocol::core::{Locator, WhatAmI, ZenohId}; + +pub const PID: u64 = 1; // 0x01 +pub const WAI: u64 = 1 << 1; // 0x02 +pub const LOC: u64 = 1 << 2; // 0x04 + +// 7 6 5 4 3 2 1 0 +// +-+-+-+-+-+-+-+-+ +// ~X|X|X|X|X|L|W|P~ +// +-+-+-+-+-+-+-+-+ +// ~ psid ~ +// +---------------+ +// ~ sn ~ +// +---------------+ +// ~ zid ~ if P == 1 +// +---------------+ +// ~ whatami ~ if W == 1 +// +---------------+ +// ~ [locators] ~ if L == 1 +// +---------------+ +// ~ [links] ~ +// +---------------+ +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct LinkState { + pub(crate) psid: u64, + pub(crate) sn: u64, + pub(crate) zid: Option, + pub(crate) whatami: Option, + pub(crate) locators: Option>, + pub(crate) links: Vec, +} + +impl LinkState { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + const MIN: usize = 1; + const MAX: usize = 16; + + let mut rng = rand::thread_rng(); + + let psid: u64 = rng.gen(); + let sn: u64 = rng.gen(); + let zid = if rng.gen_bool(0.5) { + Some(ZenohId::default()) + } else { + None + }; + let whatami = if rng.gen_bool(0.5) { + Some(WhatAmI::rand()) + } else { + None + }; + let locators = if rng.gen_bool(0.5) { + let n = rng.gen_range(MIN..=MAX); + let locators = (0..n).map(|_| Locator::rand()).collect::>(); + Some(locators) + } else { + None + }; + let n = rng.gen_range(MIN..=MAX); + let links = (0..n).map(|_| rng.gen()).collect::>(); + + Self { + psid, + sn, + zid, + whatami, + locators, + links, + } + } +} + +// 7 6 5 4 3 2 1 0 +// +-+-+-+-+-+-+-+-+ +// |X|X|X|LK_ST_LS | +// +-+-+-+---------+ +// ~ [link_states] ~ +// +---------------+ +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct LinkStateList { + pub(crate) link_states: Vec, +} + +impl LinkStateList { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + + const MIN: usize = 1; + const MAX: usize = 16; + + let mut rng = rand::thread_rng(); + + let n = rng.gen_range(MIN..=MAX); + let link_states = (0..n) + .map(|_| LinkState::rand()) + .collect::>(); + + Self { link_states } + } +} diff --git a/zenoh/src/net/protocol/mod.rs b/zenoh/src/net/protocol/mod.rs new file mode 100644 index 0000000000..bdd05d2db1 --- /dev/null +++ b/zenoh/src/net/protocol/mod.rs @@ -0,0 +1,16 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +pub(crate) mod linkstate; + +pub(crate) const OAM_LINKSTATE: u16 = 0x0001; From f63e7be7d874a5d2641fc8bb8b86195db5f09e54 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Thu, 29 Jun 2023 17:19:44 +0200 Subject: [PATCH 151/203] Uncomment pipeline tests --- io/zenoh-transport/src/common/pipeline.rs | 657 +++++++++++----------- 1 file changed, 328 insertions(+), 329 deletions(-) diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 51e914db5f..9e9789bcdd 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -693,332 +693,331 @@ impl TransmissionPipelineConsumer { } } -// #[cfg(test)] -// mod tests { -// use super::*; -// use async_std::{prelude::FutureExt, task}; -// use std::{ -// convert::TryFrom, -// sync::{ -// atomic::{AtomicUsize, Ordering}, -// Arc, -// }, -// time::{Duration, Instant}, -// }; -// use zenoh_buffers::{ -// reader::{DidntRead, HasReader}, -// ZBuf, -// }; -// use zenoh_codec::{RCodec, Zenoh080}; -// use zenoh_protocol::{ -// core::{Bits, Channel, CongestionControl, Priority, Reliability}, -// transport::{BatchSize, Fragment, Frame, TransportBody, TransportSn}, -// zenoh::ZenohMessage, -// }; - -// const SLEEP: Duration = Duration::from_millis(100); -// const TIMEOUT: Duration = Duration::from_secs(60); - -// const CONFIG: TransmissionPipelineConf = TransmissionPipelineConf { -// is_streamed: true, -// batch_size: BatchSize::MAX, -// queue_size: [1; Priority::NUM], -// backoff: Duration::from_micros(1), -// }; - -// #[test] -// fn tx_pipeline_flow() { -// fn schedule(queue: TransmissionPipelineProducer, num_msg: usize, payload_size: usize) { -// // Send reliable messages -// let key = "test".into(); -// let payload = ZBuf::from(vec![0_u8; payload_size]); -// let data_info = None; -// let routing_context = None; -// let reply_context = None; -// let channel = Channel { -// priority: Priority::Control, -// reliability: Reliability::Reliable, -// }; -// let congestion_control = CongestionControl::Block; - -// let message = ZenohMessage::make_data( -// key, -// payload, -// channel, -// congestion_control, -// data_info, -// routing_context, -// reply_context, -// ); - -// println!( -// "Pipeline Flow [>>>]: Sending {num_msg} messages with payload size of {payload_size} bytes" -// ); -// for i in 0..num_msg { -// println!( -// "Pipeline Flow [>>>]: Pushed {} msgs ({payload_size} bytes)", -// i + 1 -// ); -// queue.push_zenoh_message(message.clone()); -// } -// } - -// async fn consume(mut queue: TransmissionPipelineConsumer, num_msg: usize) { -// let mut batches: usize = 0; -// let mut bytes: usize = 0; -// let mut msgs: usize = 0; -// let mut fragments: usize = 0; - -// while msgs != num_msg { -// let (batch, priority) = queue.pull().await.unwrap(); -// batches += 1; -// bytes += batch.len() as usize; -// // Create a ZBuf for deserialization starting from the batch -// let bytes = batch.as_bytes(); -// // Deserialize the messages -// let mut reader = bytes.reader(); -// let codec = Zenoh080::new(); - -// loop { -// let res: Result = codec.read(&mut reader); -// match res { -// Ok(msg) => { -// match msg.body { -// TransportBody::Frame(Frame { payload, .. }) => { -// msgs += payload.len() -// } -// TransportBody::Fragment(Fragment { more, .. }) => { -// fragments += 1; -// if !more { -// msgs += 1; -// } -// } -// _ => { -// msgs += 1; -// } -// } -// println!("Pipeline Flow [<<<]: Pulled {} msgs", msgs + 1); -// } -// Err(_) => break, -// } -// } -// println!("Pipeline Flow [+++]: Refill {} msgs", msgs + 1); -// // Reinsert the batch -// queue.refill(batch, priority); -// } - -// println!( -// "Pipeline Flow [<<<]: Received {msgs} messages, {bytes} bytes, {batches} batches, {fragments} fragments" -// ); -// } - -// // Pipeline conduits -// let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); -// let conduits = vec![tct]; - -// // Total amount of bytes to send in each test -// let bytes: usize = 100_000_000; -// let max_msgs: usize = 1_000; -// // Payload size of the messages -// let payload_sizes = [8, 64, 512, 4_096, 8_192, 32_768, 262_144, 2_097_152]; - -// task::block_on(async { -// for ps in payload_sizes.iter() { -// if u64::try_from(*ps).is_err() { -// break; -// } - -// // Compute the number of messages to send -// let num_msg = max_msgs.min(bytes / ps); - -// let (producer, consumer) = TransmissionPipeline::make( -// TransmissionPipelineConf::default(), -// conduits.as_slice(), -// ); - -// let t_c = task::spawn(async move { -// consume(consumer, num_msg).await; -// }); - -// let c_ps = *ps; -// let t_s = task::spawn(async move { -// schedule(producer, num_msg, c_ps); -// }); - -// let res = t_c.join(t_s).timeout(TIMEOUT).await; -// assert!(res.is_ok()); -// } -// }); -// } - -// #[test] -// fn tx_pipeline_blocking() { -// fn schedule(queue: TransmissionPipelineProducer, counter: Arc, id: usize) { -// // Make sure to put only one message per batch: set the payload size -// // to half of the batch in such a way the serialized zenoh message -// // will be larger then half of the batch size (header + payload). -// let payload_size = (CONFIG.batch_size / 2) as usize; - -// // Send reliable messages -// let key = "test".into(); -// let payload = ZBuf::from(vec![0_u8; payload_size]); -// let channel = Channel { -// priority: Priority::Control, -// reliability: Reliability::Reliable, -// }; -// let congestion_control = CongestionControl::Block; -// let data_info = None; -// let routing_context = None; -// let reply_context = None; - -// let message = ZenohMessage::make_data( -// key, -// payload, -// channel, -// congestion_control, -// data_info, -// routing_context, -// reply_context, -// ); - -// // The last push should block since there shouldn't any more batches -// // available for serialization. -// let num_msg = 1 + CONFIG.queue_size[0]; -// for i in 0..num_msg { -// println!( -// "Pipeline Blocking [>>>]: ({id}) Scheduling message #{i} with payload size of {payload_size} bytes" -// ); -// queue.push_zenoh_message(message.clone()); -// let c = counter.fetch_add(1, Ordering::AcqRel); -// println!( -// "Pipeline Blocking [>>>]: ({}) Scheduled message #{} (tot {}) with payload size of {} bytes", -// id, i, c + 1, -// payload_size -// ); -// } -// } - -// // Pipeline -// let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); -// let conduits = vec![tct]; -// let (producer, mut consumer) = -// TransmissionPipeline::make(TransmissionPipelineConf::default(), conduits.as_slice()); - -// let counter = Arc::new(AtomicUsize::new(0)); - -// let c_producer = producer.clone(); -// let c_counter = counter.clone(); -// let h1 = task::spawn_blocking(move || { -// schedule(c_producer, c_counter, 1); -// }); - -// let c_counter = counter.clone(); -// let h2 = task::spawn_blocking(move || { -// schedule(producer, c_counter, 2); -// }); - -// task::block_on(async { -// // Wait to have sent enough messages and to have blocked -// println!( -// "Pipeline Blocking [---]: waiting to have {} messages being scheduled", -// CONFIG.queue_size[Priority::MAX as usize] -// ); -// let check = async { -// while counter.load(Ordering::Acquire) < CONFIG.queue_size[Priority::MAX as usize] { -// task::sleep(SLEEP).await; -// } -// }; -// check.timeout(TIMEOUT).await.unwrap(); - -// // Disable and drain the queue -// task::spawn_blocking(move || { -// println!("Pipeline Blocking [---]: draining the queue"); -// let _ = consumer.drain(); -// }) -// .timeout(TIMEOUT) -// .await -// .unwrap(); - -// // Make sure that the tasks scheduling have been unblocked -// println!("Pipeline Blocking [---]: waiting for schedule (1) to be unblocked"); -// h1.timeout(TIMEOUT).await.unwrap(); -// println!("Pipeline Blocking [---]: waiting for schedule (2) to be unblocked"); -// h2.timeout(TIMEOUT).await.unwrap(); -// }); -// } - -// #[test] -// #[ignore] -// fn tx_pipeline_thr() { -// // Queue -// let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); -// let conduits = vec![tct]; -// let (producer, mut consumer) = TransmissionPipeline::make(CONFIG, conduits.as_slice()); -// let count = Arc::new(AtomicUsize::new(0)); -// let size = Arc::new(AtomicUsize::new(0)); - -// let c_size = size.clone(); -// task::spawn(async move { -// loop { -// let payload_sizes: [usize; 16] = [ -// 8, 16, 32, 64, 128, 256, 512, 1_024, 2_048, 4_096, 8_192, 16_384, 32_768, -// 65_536, 262_144, 1_048_576, -// ]; -// for size in payload_sizes.iter() { -// c_size.store(*size, Ordering::Release); - -// // Send reliable messages -// let key = "pipeline/thr".into(); -// let payload = ZBuf::from(vec![0_u8; *size]); -// let channel = Channel { -// priority: Priority::Control, -// reliability: Reliability::Reliable, -// }; -// let congestion_control = CongestionControl::Block; -// let data_info = None; -// let routing_context = None; -// let reply_context = None; - -// let message = ZenohMessage::make_data( -// key, -// payload, -// channel, -// congestion_control, -// data_info, -// routing_context, -// reply_context, -// ); - -// let duration = Duration::from_millis(5_500); -// let start = Instant::now(); -// while start.elapsed() < duration { -// producer.push_zenoh_message(message.clone()); -// } -// } -// } -// }); - -// let c_count = count.clone(); -// task::spawn(async move { -// loop { -// let (batch, priority) = consumer.pull().await.unwrap(); -// c_count.fetch_add(batch.len() as usize, Ordering::AcqRel); -// consumer.refill(batch, priority); -// } -// }); - -// task::block_on(async { -// let mut prev_size: usize = usize::MAX; -// loop { -// let received = count.swap(0, Ordering::AcqRel); -// let current: usize = size.load(Ordering::Acquire); -// if current == prev_size { -// let thr = (8.0 * received as f64) / 1_000_000_000.0; -// println!("{} bytes: {:.6} Gbps", current, 2.0 * thr); -// } -// prev_size = current; -// task::sleep(Duration::from_millis(500)).await; -// } -// }); -// } -// } +#[cfg(test)] +mod tests { + use super::*; + use async_std::{prelude::FutureExt, task}; + use std::{ + convert::TryFrom, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, + time::{Duration, Instant}, + }; + use zenoh_buffers::{ + reader::{DidntRead, HasReader}, + ZBuf, + }; + use zenoh_codec::{RCodec, Zenoh080}; + use zenoh_protocol::{ + core::{Bits, CongestionControl, Encoding, Priority}, + network::{ext, Mapping, Push}, + transport::{BatchSize, Fragment, Frame, TransportBody, TransportSn}, + zenoh_new::{PushBody, Put}, + }; + + const SLEEP: Duration = Duration::from_millis(100); + const TIMEOUT: Duration = Duration::from_secs(60); + + const CONFIG: TransmissionPipelineConf = TransmissionPipelineConf { + is_streamed: true, + batch_size: BatchSize::MAX, + queue_size: [1; Priority::NUM], + backoff: Duration::from_micros(1), + }; + + #[test] + fn tx_pipeline_flow() { + fn schedule(queue: TransmissionPipelineProducer, num_msg: usize, payload_size: usize) { + // Send reliable messages + let key = "test".into(); + let payload = ZBuf::from(vec![0_u8; payload_size]); + + let message: NetworkMessage = Push { + wire_expr: key, + mapping: Mapping::default(), + ext_qos: ext::QoSType::new(Priority::Control, CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + payload, + }), + } + .into(); + + println!( + "Pipeline Flow [>>>]: Sending {num_msg} messages with payload size of {payload_size} bytes" + ); + for i in 0..num_msg { + println!( + "Pipeline Flow [>>>]: Pushed {} msgs ({payload_size} bytes)", + i + 1 + ); + queue.push_network_message(message.clone()); + } + } + + async fn consume(mut queue: TransmissionPipelineConsumer, num_msg: usize) { + let mut batches: usize = 0; + let mut bytes: usize = 0; + let mut msgs: usize = 0; + let mut fragments: usize = 0; + + while msgs != num_msg { + let (batch, priority) = queue.pull().await.unwrap(); + batches += 1; + bytes += batch.len() as usize; + // Create a ZBuf for deserialization starting from the batch + let bytes = batch.as_bytes(); + // Deserialize the messages + let mut reader = bytes.reader(); + let codec = Zenoh080::new(); + + loop { + let res: Result = codec.read(&mut reader); + match res { + Ok(msg) => { + match msg.body { + TransportBody::Frame(Frame { payload, .. }) => { + msgs += payload.len() + } + TransportBody::Fragment(Fragment { more, .. }) => { + fragments += 1; + if !more { + msgs += 1; + } + } + _ => { + msgs += 1; + } + } + println!("Pipeline Flow [<<<]: Pulled {} msgs", msgs + 1); + } + Err(_) => break, + } + } + println!("Pipeline Flow [+++]: Refill {} msgs", msgs + 1); + // Reinsert the batch + queue.refill(batch, priority); + } + + println!( + "Pipeline Flow [<<<]: Received {msgs} messages, {bytes} bytes, {batches} batches, {fragments} fragments" + ); + } + + // Pipeline conduits + let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); + let conduits = vec![tct]; + + // Total amount of bytes to send in each test + let bytes: usize = 100_000_000; + let max_msgs: usize = 1_000; + // Payload size of the messages + let payload_sizes = [8, 64, 512, 4_096, 8_192, 32_768, 262_144, 2_097_152]; + + task::block_on(async { + for ps in payload_sizes.iter() { + if u64::try_from(*ps).is_err() { + break; + } + + // Compute the number of messages to send + let num_msg = max_msgs.min(bytes / ps); + + let (producer, consumer) = TransmissionPipeline::make( + TransmissionPipelineConf::default(), + conduits.as_slice(), + ); + + let t_c = task::spawn(async move { + consume(consumer, num_msg).await; + }); + + let c_ps = *ps; + let t_s = task::spawn(async move { + schedule(producer, num_msg, c_ps); + }); + + let res = t_c.join(t_s).timeout(TIMEOUT).await; + assert!(res.is_ok()); + } + }); + } + + #[test] + fn tx_pipeline_blocking() { + fn schedule(queue: TransmissionPipelineProducer, counter: Arc, id: usize) { + // Make sure to put only one message per batch: set the payload size + // to half of the batch in such a way the serialized zenoh message + // will be larger then half of the batch size (header + payload). + let payload_size = (CONFIG.batch_size / 2) as usize; + + // Send reliable messages + let key = "test".into(); + let payload = ZBuf::from(vec![0_u8; payload_size]); + + let message: NetworkMessage = Push { + wire_expr: key, + mapping: Mapping::default(), + ext_qos: ext::QoSType::new(Priority::Control, CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + payload, + }), + } + .into(); + + // The last push should block since there shouldn't any more batches + // available for serialization. + let num_msg = 1 + CONFIG.queue_size[0]; + for i in 0..num_msg { + println!( + "Pipeline Blocking [>>>]: ({id}) Scheduling message #{i} with payload size of {payload_size} bytes" + ); + queue.push_network_message(message.clone()); + let c = counter.fetch_add(1, Ordering::AcqRel); + println!( + "Pipeline Blocking [>>>]: ({}) Scheduled message #{} (tot {}) with payload size of {} bytes", + id, i, c + 1, + payload_size + ); + } + } + + // Pipeline + let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); + let conduits = vec![tct]; + let (producer, mut consumer) = + TransmissionPipeline::make(TransmissionPipelineConf::default(), conduits.as_slice()); + + let counter = Arc::new(AtomicUsize::new(0)); + + let c_producer = producer.clone(); + let c_counter = counter.clone(); + let h1 = task::spawn_blocking(move || { + schedule(c_producer, c_counter, 1); + }); + + let c_counter = counter.clone(); + let h2 = task::spawn_blocking(move || { + schedule(producer, c_counter, 2); + }); + + task::block_on(async { + // Wait to have sent enough messages and to have blocked + println!( + "Pipeline Blocking [---]: waiting to have {} messages being scheduled", + CONFIG.queue_size[Priority::MAX as usize] + ); + let check = async { + while counter.load(Ordering::Acquire) < CONFIG.queue_size[Priority::MAX as usize] { + task::sleep(SLEEP).await; + } + }; + check.timeout(TIMEOUT).await.unwrap(); + + // Disable and drain the queue + task::spawn_blocking(move || { + println!("Pipeline Blocking [---]: draining the queue"); + let _ = consumer.drain(); + }) + .timeout(TIMEOUT) + .await + .unwrap(); + + // Make sure that the tasks scheduling have been unblocked + println!("Pipeline Blocking [---]: waiting for schedule (1) to be unblocked"); + h1.timeout(TIMEOUT).await.unwrap(); + println!("Pipeline Blocking [---]: waiting for schedule (2) to be unblocked"); + h2.timeout(TIMEOUT).await.unwrap(); + }); + } + + #[test] + #[ignore] + fn tx_pipeline_thr() { + // Queue + let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); + let conduits = vec![tct]; + let (producer, mut consumer) = TransmissionPipeline::make(CONFIG, conduits.as_slice()); + let count = Arc::new(AtomicUsize::new(0)); + let size = Arc::new(AtomicUsize::new(0)); + + let c_size = size.clone(); + task::spawn(async move { + loop { + let payload_sizes: [usize; 16] = [ + 8, 16, 32, 64, 128, 256, 512, 1_024, 2_048, 4_096, 8_192, 16_384, 32_768, + 65_536, 262_144, 1_048_576, + ]; + for size in payload_sizes.iter() { + c_size.store(*size, Ordering::Release); + + // Send reliable messages + let key = "pipeline/thr".into(); + let payload = ZBuf::from(vec![0_u8; *size]); + + let message: NetworkMessage = Push { + wire_expr: key, + mapping: Mapping::default(), + ext_qos: ext::QoSType::new( + Priority::Control, + CongestionControl::Block, + false, + ), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + payload, + }), + } + .into(); + + let duration = Duration::from_millis(5_500); + let start = Instant::now(); + while start.elapsed() < duration { + producer.push_network_message(message.clone()); + } + } + } + }); + + let c_count = count.clone(); + task::spawn(async move { + loop { + let (batch, priority) = consumer.pull().await.unwrap(); + c_count.fetch_add(batch.len() as usize, Ordering::AcqRel); + consumer.refill(batch, priority); + } + }); + + task::block_on(async { + let mut prev_size: usize = usize::MAX; + loop { + let received = count.swap(0, Ordering::AcqRel); + let current: usize = size.load(Ordering::Acquire); + if current == prev_size { + let thr = (8.0 * received as f64) / 1_000_000_000.0; + println!("{} bytes: {:.6} Gbps", current, 2.0 * thr); + } + prev_size = current; + task::sleep(Duration::from_millis(500)).await; + } + }); + } +} From bfddfbb2110801e5544da1e825c5a6f9b692b588 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Fri, 30 Jun 2023 15:03:10 +0200 Subject: [PATCH 152/203] Uncomment token undeclaration mgt --- zenoh/src/session.rs | 47 +++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 15c453d11f..33cc9d8369 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -1970,26 +1970,33 @@ impl Primitives for Session { } zenoh_protocol::network::DeclareBody::UndeclareSubscriber(m) => { trace!("recv UndeclareSubscriber {:?}", m.id); - // #[cfg(feature = "unstable")] - // { - // let state = zread!(self.state); - // match state.wireexpr_to_keyexpr(key_expr, false) { - // Ok(expr) => { - // if expr - // .as_str() - // .starts_with(crate::liveliness::PREFIX_LIVELINESS) - // { - // drop(state); - // let data_info = DataInfo { - // kind: SampleKind::Delete, - // ..Default::default() - // }; - // self.handle_data(false, key_expr, Some(data_info), ZBuf::default()); - // } - // } - // Err(err) => log::error!("Received Forget Subscriber for unkown key_expr: {}", err), - // } - // } + #[cfg(feature = "unstable")] + { + let state = zread!(self.state); + match state.wireexpr_to_keyexpr(&m.ext_wire_expr.wire_expr, false) { + Ok(expr) => { + if expr + .as_str() + .starts_with(crate::liveliness::PREFIX_LIVELINESS) + { + drop(state); + let data_info = DataInfo { + kind: SampleKind::Delete, + ..Default::default() + }; + self.handle_data( + false, + &m.ext_wire_expr.wire_expr, + Some(data_info), + ZBuf::default(), + ); + } + } + Err(err) => { + log::error!("Received Forget Subscriber for unkown key_expr: {}", err) + } + } + } } zenoh_protocol::network::DeclareBody::DeclareQueryable(m) => { trace!("recv DeclareQueryable {} {:?}", m.id, m.wire_expr); From 1a3130d77296a977e813ca3ee8d5ffa5215f9fbf Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Fri, 30 Jun 2023 16:54:24 +0200 Subject: [PATCH 153/203] New key mapping --- commons/zenoh-codec/benches/codec.rs | 14 +-- commons/zenoh-codec/src/core/wire_expr.rs | 6 +- commons/zenoh-codec/src/network/declare.rs | 51 +++++------ commons/zenoh-codec/src/network/push.rs | 7 +- commons/zenoh-codec/src/network/request.rs | 7 +- commons/zenoh-codec/src/network/response.rs | 7 +- commons/zenoh-protocol/src/core/wire_expr.rs | 42 +++++---- commons/zenoh-protocol/src/network/declare.rs | 21 +---- commons/zenoh-protocol/src/network/mod.rs | 2 +- commons/zenoh-protocol/src/network/push.rs | 5 +- commons/zenoh-protocol/src/network/request.rs | 5 +- .../zenoh-protocol/src/network/response.rs | 9 +- io/zenoh-transport/src/common/batch.rs | 4 +- io/zenoh-transport/src/common/pipeline.rs | 5 +- zenoh/src/key_expr.rs | 41 ++++++++- zenoh/src/net/routing/face.rs | 14 +-- zenoh/src/net/routing/pubsub.rs | 62 +++++-------- zenoh/src/net/routing/queries.rs | 62 +++++-------- zenoh/src/net/routing/resource.rs | 88 +++++++++---------- zenoh/src/net/routing/router.rs | 5 +- zenoh/src/net/runtime/adminspace.rs | 6 +- zenoh/src/publication.rs | 4 +- zenoh/src/queryable.rs | 2 +- zenoh/src/session.rs | 37 +++----- 24 files changed, 229 insertions(+), 277 deletions(-) diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 1d8f38ff92..59dd472ac5 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -22,7 +22,7 @@ use zenoh_buffers::{ }; use zenoh_codec::*; use zenoh_protocol::{ - core::{CongestionControl, Reliability}, + core::{CongestionControl, Reliability, WireExpr}, transport::{BatchSize, Frame, FrameHeader, TransportSn}, zenoh::Data, }; @@ -78,7 +78,7 @@ fn criterion_benchmark(c: &mut Criterion) { }; let data = Data { - key: 0.into(), + key: WireExpr::empty(), data_info: None, payload: ZBuf::from(vec![0u8; 8]), congestion_control: CongestionControl::default(), @@ -115,7 +115,7 @@ fn criterion_benchmark(c: &mut Criterion) { }; let data = Data { - key: 0.into(), + key: WireExpr::empty(), data_info: None, payload: ZBuf::from(vec![0u8; 8]), congestion_control: CongestionControl::default(), @@ -147,7 +147,7 @@ fn criterion_benchmark(c: &mut Criterion) { }; let data = Data { - key: 0.into(), + key: WireExpr::empty(), data_info: None, payload: ZBuf::from(vec![0u8; 8]), congestion_control: CongestionControl::default(), @@ -179,7 +179,7 @@ fn criterion_benchmark(c: &mut Criterion) { let codec = Zenoh080::new(); let data = Data { - key: 0.into(), + key: WireExpr::empty(), data_info: None, payload: ZBuf::from(vec![0u8; 1_000_000]), congestion_control: CongestionControl::default(), @@ -197,7 +197,7 @@ fn criterion_benchmark(c: &mut Criterion) { let codec = Zenoh080::new(); let data = Data { - key: 0.into(), + key: WireExpr::empty(), data_info: None, payload: ZBuf::from(vec![0u8; 1_000_000]), congestion_control: CongestionControl::default(), @@ -227,7 +227,7 @@ fn criterion_benchmark(c: &mut Criterion) { let codec = Zenoh080::new(); let data = Data { - key: 0.into(), + key: WireExpr::empty(), data_info: None, payload: ZBuf::from(vec![0u8; 1_000_000]), congestion_control: CongestionControl::default(), diff --git a/commons/zenoh-codec/src/core/wire_expr.rs b/commons/zenoh-codec/src/core/wire_expr.rs index 5532367fde..bc484149ce 100644 --- a/commons/zenoh-codec/src/core/wire_expr.rs +++ b/commons/zenoh-codec/src/core/wire_expr.rs @@ -17,7 +17,10 @@ use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; -use zenoh_protocol::core::{ExprId, ExprLen, WireExpr}; +use zenoh_protocol::{ + core::{ExprId, ExprLen, WireExpr}, + network::Mapping, +}; impl WCodec<&WireExpr<'_>, &mut W> for Zenoh080 where @@ -56,6 +59,7 @@ where Ok(WireExpr { scope, suffix: suffix.into(), + mapping: Mapping::default(), }) } } diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index 65da506063..06f07ed5ad 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -326,7 +326,7 @@ where if n_exts != 0 { header |= subscriber::flag::Z; } - if x.mapping != Mapping::default() { + if x.wire_expr.mapping != Mapping::default() { header |= subscriber::flag::M; } if x.wire_expr.has_suffix() { @@ -376,8 +376,8 @@ where // Body let id: subscriber::SubscriberId = self.codec.read(&mut *reader)?; let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, subscriber::flag::N)); - let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; - let mapping = if imsg::has_flag(self.header, subscriber::flag::M) { + let mut wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + wire_expr.mapping = if imsg::has_flag(self.header, subscriber::flag::M) { Mapping::Sender } else { Mapping::Receiver @@ -406,7 +406,6 @@ where Ok(subscriber::DeclareSubscriber { id, wire_expr, - mapping, ext_info, }) } @@ -503,7 +502,7 @@ where if n_exts != 0 { header |= subscriber::flag::Z; } - if x.mapping != Mapping::default() { + if x.wire_expr.mapping != Mapping::default() { header |= subscriber::flag::M; } if x.wire_expr.has_suffix() { @@ -551,8 +550,8 @@ where // Body let id: queryable::QueryableId = self.codec.read(&mut *reader)?; let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, queryable::flag::N)); - let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; - let mapping = if imsg::has_flag(self.header, queryable::flag::M) { + let mut wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + wire_expr.mapping = if imsg::has_flag(self.header, queryable::flag::M) { Mapping::Sender } else { Mapping::Receiver @@ -581,7 +580,6 @@ where Ok(queryable::DeclareQueryable { id, wire_expr, - mapping, ext_info, }) } @@ -671,7 +669,7 @@ where fn write(self, writer: &mut W, x: &token::DeclareToken) -> Self::Output { // Header let mut header = declare::id::D_TOKEN; - if x.mapping != Mapping::default() { + if x.wire_expr.mapping != Mapping::default() { header |= subscriber::flag::M; } if x.wire_expr.has_suffix() { @@ -714,8 +712,8 @@ where // Body let id: token::TokenId = self.codec.read(&mut *reader)?; let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, token::flag::N)); - let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; - let mapping = if imsg::has_flag(self.header, token::flag::M) { + let mut wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + wire_expr.mapping = if imsg::has_flag(self.header, token::flag::M) { Mapping::Sender } else { Mapping::Receiver @@ -727,11 +725,7 @@ where extension::skip_all(reader, "DeclareToken")?; } - Ok(token::DeclareToken { - id, - wire_expr, - mapping, - }) + Ok(token::DeclareToken { id, wire_expr }) } } @@ -819,7 +813,7 @@ where fn write(self, writer: &mut W, x: &interest::DeclareInterest) -> Self::Output { // Header let mut header = declare::id::D_INTEREST; - if x.mapping != Mapping::default() { + if x.wire_expr.mapping != Mapping::default() { header |= subscriber::flag::M; } if x.wire_expr.has_suffix() { @@ -863,8 +857,8 @@ where // Body let id: interest::InterestId = self.codec.read(&mut *reader)?; let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, token::flag::N)); - let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; - let mapping = if imsg::has_flag(self.header, token::flag::M) { + let mut wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + wire_expr.mapping = if imsg::has_flag(self.header, token::flag::M) { Mapping::Sender } else { Mapping::Receiver @@ -880,7 +874,6 @@ where Ok(interest::DeclareInterest { id, wire_expr, - mapping, interest: interest.into(), }) } @@ -1035,7 +1028,7 @@ where if x.wire_expr.has_suffix() { flags |= 1; } - if let Mapping::Receiver = x.mapping { + if let Mapping::Receiver = x.wire_expr.mapping { flags |= 1 << 1; } codec.write(&mut zriter, flags)?; @@ -1074,17 +1067,21 @@ where } else { String::new() }; - let wire_expr = WireExpr { - scope, - suffix: suffix.into(), - }; - let mapping = if imsg::has_flag(flags, 1 << 1) { Mapping::Receiver } else { Mapping::Sender }; - Ok((common::ext::WireExprType { wire_expr, mapping }, more)) + Ok(( + common::ext::WireExprType { + wire_expr: WireExpr { + scope, + suffix: suffix.into(), + mapping, + }, + }, + more, + )) } } diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index b83bb1d15e..821be49899 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -42,7 +42,7 @@ where if n_exts != 0 { header |= flag::Z; } - if x.mapping != Mapping::default() { + if x.wire_expr.mapping != Mapping::default() { header |= flag::M; } if x.wire_expr.has_suffix() { @@ -100,8 +100,8 @@ where // Body let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); - let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; - let mapping = if imsg::has_flag(self.header, flag::M) { + let mut wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + wire_expr.mapping = if imsg::has_flag(self.header, flag::M) { Mapping::Sender } else { Mapping::Receiver @@ -143,7 +143,6 @@ where Ok(Push { wire_expr, - mapping, payload, ext_qos, ext_tstamp, diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 2db45d49c5..18ea0ae9e6 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -88,7 +88,7 @@ where if n_exts != 0 { header |= flag::Z; } - if x.mapping != Mapping::default() { + if x.wire_expr.mapping != Mapping::default() { header |= flag::M; } if x.wire_expr.has_suffix() { @@ -163,8 +163,8 @@ where let bodec = Zenoh080Bounded::::new(); let id: RequestId = bodec.read(&mut *reader)?; let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); - let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; - let mapping = if imsg::has_flag(self.header, flag::M) { + let mut wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + wire_expr.mapping = if imsg::has_flag(self.header, flag::M) { Mapping::Sender } else { Mapping::Receiver @@ -225,7 +225,6 @@ where Ok(Request { id, wire_expr, - mapping, payload, ext_qos, ext_tstamp, diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs index 70e9cfa1c7..5959294aac 100644 --- a/commons/zenoh-codec/src/network/response.rs +++ b/commons/zenoh-codec/src/network/response.rs @@ -45,7 +45,7 @@ where if n_exts != 0 { header |= flag::Z; } - if x.mapping != Mapping::default() { + if x.wire_expr.mapping != Mapping::default() { header |= flag::M; } if x.wire_expr.has_suffix() { @@ -106,8 +106,8 @@ where let bodec = Zenoh080Bounded::::new(); let rid: RequestId = bodec.read(&mut *reader)?; let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, flag::N)); - let wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; - let mapping = if imsg::has_flag(self.header, flag::M) { + let mut wire_expr: WireExpr<'static> = ccond.read(&mut *reader)?; + wire_expr.mapping = if imsg::has_flag(self.header, flag::M) { Mapping::Sender } else { Mapping::Receiver @@ -150,7 +150,6 @@ where Ok(Response { rid, wire_expr, - mapping, payload, ext_qos, ext_tstamp, diff --git a/commons/zenoh-protocol/src/core/wire_expr.rs b/commons/zenoh-protocol/src/core/wire_expr.rs index cbd02f5096..9522586e10 100644 --- a/commons/zenoh-protocol/src/core/wire_expr.rs +++ b/commons/zenoh-protocol/src/core/wire_expr.rs @@ -21,6 +21,8 @@ use core::{convert::TryInto, fmt, sync::atomic::AtomicU16}; use zenoh_keyexpr::{keyexpr, OwnedKeyExpr}; use zenoh_result::{bail, ZResult}; +use crate::network::Mapping; + /// A numerical Id mapped to a key expression. pub type ExprId = u16; pub type ExprLen = u16; @@ -57,9 +59,18 @@ pub const EMPTY_EXPR_ID: ExprId = 0; pub struct WireExpr<'a> { pub scope: ExprId, // 0 marks global scope pub suffix: Cow<'a, str>, + pub mapping: Mapping, } impl<'a> WireExpr<'a> { + pub fn empty() -> Self { + WireExpr { + scope: 0, + suffix: "".into(), + mapping: Mapping::Sender, + } + } + pub fn as_str(&'a self) -> &'a str { if self.scope == 0 { self.suffix.as_ref() @@ -100,6 +111,7 @@ impl<'a> WireExpr<'a> { WireExpr { scope: self.scope, suffix: self.suffix.to_string().into(), + mapping: self.mapping, } } @@ -136,6 +148,7 @@ impl<'a> From<&'a OwnedKeyExpr> for WireExpr<'a> { WireExpr { scope: 0, suffix: Cow::Borrowed(val.as_str()), + mapping: Mapping::Sender, } } } @@ -145,6 +158,7 @@ impl<'a> From<&'a keyexpr> for WireExpr<'a> { WireExpr { scope: 0, suffix: Cow::Borrowed(val.as_str()), + mapping: Mapping::Sender, } } } @@ -154,7 +168,7 @@ impl fmt::Debug for WireExpr<'_> { if self.scope == 0 { write!(f, "{}", self.suffix) } else { - write!(f, "{}:{}", self.scope, self.suffix) + write!(f, "{}:{:?}:{}", self.scope, self.mapping, self.suffix) } } } @@ -164,7 +178,7 @@ impl fmt::Display for WireExpr<'_> { if self.scope == 0 { write!(f, "{}", self.suffix) } else { - write!(f, "{}:{}", self.scope, self.suffix) + write!(f, "{}:{:?}:{}", self.scope, self.mapping, self.suffix) } } } @@ -176,32 +190,13 @@ impl<'a> From<&WireExpr<'a>> for WireExpr<'a> { } } -impl From for WireExpr<'_> { - #[inline] - fn from(rid: ExprId) -> WireExpr<'static> { - WireExpr { - scope: rid, - suffix: "".into(), - } - } -} - -impl From<&ExprId> for WireExpr<'_> { - #[inline] - fn from(rid: &ExprId) -> WireExpr<'static> { - WireExpr { - scope: *rid, - suffix: "".into(), - } - } -} - impl<'a> From<&'a str> for WireExpr<'a> { #[inline] fn from(name: &'a str) -> WireExpr<'a> { WireExpr { scope: 0, suffix: name.into(), + mapping: Mapping::Sender, } } } @@ -212,6 +207,7 @@ impl From for WireExpr<'_> { WireExpr { scope: 0, suffix: name.into(), + mapping: Mapping::Sender, } } } @@ -222,6 +218,7 @@ impl<'a> From<&'a String> for WireExpr<'a> { WireExpr { scope: 0, suffix: name.into(), + mapping: Mapping::Sender, } } } @@ -250,6 +247,7 @@ impl WireExpr<'_> { WireExpr { scope, suffix: suffix.into(), + mapping: Mapping::default(), } } } diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index e7ca85c795..f5298f394e 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -180,7 +180,6 @@ pub mod common { #[derive(Debug, Clone, PartialEq, Eq)] pub struct WireExprType { pub wire_expr: WireExpr<'static>, - pub mapping: Mapping, } impl WireExprType { @@ -191,8 +190,8 @@ pub mod common { wire_expr: WireExpr { scope: ExprId::MIN, suffix: Cow::from(""), + mapping: Mapping::Receiver, }, - mapping: Mapping::Receiver, } } @@ -200,7 +199,6 @@ pub mod common { pub fn rand() -> Self { Self { wire_expr: WireExpr::rand(), - mapping: Mapping::rand(), } } } @@ -325,7 +323,6 @@ pub mod subscriber { pub struct DeclareSubscriber { pub id: SubscriberId, pub wire_expr: WireExpr<'static>, - pub mapping: Mapping, pub ext_info: ext::SubscriberInfo, } @@ -405,14 +402,12 @@ pub mod subscriber { let id: SubscriberId = rng.gen(); let wire_expr = WireExpr::rand(); - let mapping = Mapping::rand(); let ext_info = ext::SubscriberInfo::rand(); Self { id, wire_expr, ext_info, - mapping, } } } @@ -492,7 +487,6 @@ pub mod queryable { pub struct DeclareQueryable { pub id: QueryableId, pub wire_expr: WireExpr<'static>, - pub mapping: Mapping, pub ext_info: ext::QueryableInfo, } @@ -553,13 +547,11 @@ pub mod queryable { let id: QueryableId = rng.gen(); let wire_expr = WireExpr::rand(); - let mapping = Mapping::rand(); let ext_info = ext::QueryableInfo::rand(); Self { id, wire_expr, - mapping, ext_info, } } @@ -636,7 +628,6 @@ pub mod token { pub struct DeclareToken { pub id: TokenId, pub wire_expr: WireExpr<'static>, - pub mapping: Mapping, } impl DeclareToken { @@ -647,13 +638,8 @@ pub mod token { let id: TokenId = rng.gen(); let wire_expr = WireExpr::rand(); - let mapping = Mapping::rand(); - Self { - id, - wire_expr, - mapping, - } + Self { id, wire_expr } } } @@ -777,7 +763,6 @@ pub mod interest { pub struct DeclareInterest { pub id: InterestId, pub wire_expr: WireExpr<'static>, - pub mapping: Mapping, pub interest: Interest, } @@ -860,13 +845,11 @@ pub mod interest { let id: InterestId = rng.gen(); let wire_expr = WireExpr::rand(); - let mapping = Mapping::rand(); let interest = Interest::rand(); Self { id, wire_expr, - mapping, interest, } } diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 752a995ef5..b53d1a298d 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -39,7 +39,7 @@ pub mod id { } #[repr(u8)] -#[derive(Debug, Default, Clone, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] pub enum Mapping { #[default] Receiver = 0, diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs index 76d9c3811c..19f790f7d5 100644 --- a/commons/zenoh-protocol/src/network/push.rs +++ b/commons/zenoh-protocol/src/network/push.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, network::Mapping, zenoh_new::PushBody}; +use crate::{core::WireExpr, zenoh_new::PushBody}; pub mod flag { pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix @@ -41,7 +41,6 @@ pub mod flag { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Push { pub wire_expr: WireExpr<'static>, - pub mapping: Mapping, pub ext_qos: ext::QoSType, pub ext_tstamp: Option, pub ext_nodeid: ext::NodeIdType, @@ -71,7 +70,6 @@ impl Push { let mut rng = rand::thread_rng(); let wire_expr = WireExpr::rand(); - let mapping = Mapping::rand(); let payload = PushBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); @@ -79,7 +77,6 @@ impl Push { Self { wire_expr, - mapping, payload, ext_tstamp, ext_qos, diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index fc180d273a..6bf878e8a3 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, network::Mapping, zenoh_new::RequestBody}; +use crate::{core::WireExpr, zenoh_new::RequestBody}; use core::sync::atomic::AtomicU32; /// The resolution of a RequestId @@ -54,7 +54,6 @@ pub mod flag { pub struct Request { pub id: RequestId, pub wire_expr: WireExpr<'static>, - pub mapping: Mapping, pub ext_qos: ext::QoSType, pub ext_tstamp: Option, pub ext_nodeid: ext::NodeIdType, @@ -134,7 +133,6 @@ impl Request { let mut rng = rand::thread_rng(); let wire_expr = WireExpr::rand(); - let mapping = Mapping::rand(); let id: RequestId = rng.gen(); let payload = RequestBody::rand(); let ext_qos = ext::QoSType::rand(); @@ -154,7 +152,6 @@ impl Request { Self { wire_expr, - mapping, id, payload, ext_qos, diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index a1a49f535e..9032971ddc 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -11,11 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{ - core::WireExpr, - network::{Mapping, RequestId}, - zenoh_new::ResponseBody, -}; +use crate::{core::WireExpr, network::RequestId, zenoh_new::ResponseBody}; /// # Response message /// @@ -53,7 +49,6 @@ pub mod flag { pub struct Response { pub rid: RequestId, pub wire_expr: WireExpr<'static>, - pub mapping: Mapping, pub payload: ResponseBody, pub ext_qos: ext::QoSType, pub ext_tstamp: Option, @@ -83,7 +78,6 @@ impl Response { let rid: RequestId = rng.gen(); let wire_expr = WireExpr::rand(); - let mapping = Mapping::rand(); let payload = ResponseBody::rand(); let ext_qos = ext::QoSType::rand(); let ext_tstamp = rng.gen_bool(0.5).then(ext::TimestampType::rand); @@ -92,7 +86,6 @@ impl Response { Self { rid, wire_expr, - mapping, payload, ext_qos, ext_tstamp, diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index ba0c089052..0a16c61331 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -420,7 +420,7 @@ mod tests { use super::*; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{Channel, CongestionControl, Priority, Reliability}, + core::{Channel, CongestionControl, Priority, Reliability, WireExpr}, transport::{ frame::{self, FrameHeader}, KeepAlive, TransportMessage, @@ -434,7 +434,7 @@ mod tests { let tmsg: TransportMessage = KeepAlive.into(); let mut zmsg = ZenohMessage::make_data( - 0.into(), + WireExpr::empty(), ZBuf::from(vec![0u8; 8]), Channel { priority: Priority::default(), diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 9e9789bcdd..727f9f32d5 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -712,7 +712,7 @@ mod tests { use zenoh_codec::{RCodec, Zenoh080}; use zenoh_protocol::{ core::{Bits, CongestionControl, Encoding, Priority}, - network::{ext, Mapping, Push}, + network::{ext, Push}, transport::{BatchSize, Fragment, Frame, TransportBody, TransportSn}, zenoh_new::{PushBody, Put}, }; @@ -736,7 +736,6 @@ mod tests { let message: NetworkMessage = Push { wire_expr: key, - mapping: Mapping::default(), ext_qos: ext::QoSType::new(Priority::Control, CongestionControl::Block, false), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), @@ -864,7 +863,6 @@ mod tests { let message: NetworkMessage = Push { wire_expr: key, - mapping: Mapping::default(), ext_qos: ext::QoSType::new(Priority::Control, CongestionControl::Block, false), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), @@ -970,7 +968,6 @@ mod tests { let message: NetworkMessage = Push { wire_expr: key, - mapping: Mapping::default(), ext_qos: ext::QoSType::new( Priority::Control, CongestionControl::Block, diff --git a/zenoh/src/key_expr.rs b/zenoh/src/key_expr.rs index 0653afa1ac..6ed616fd13 100644 --- a/zenoh/src/key_expr.rs +++ b/zenoh/src/key_expr.rs @@ -23,7 +23,7 @@ use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; pub use zenoh_protocol::core::key_expr::*; use zenoh_protocol::{ core::{key_expr::canon::Canonizable, ExprId, WireExpr}, - network::{declare, DeclareBody, UndeclareKeyExpr}, + network::{declare, DeclareBody, Mapping, UndeclareKeyExpr}, }; use zenoh_result::ZResult; use zenoh_transport::Primitives; @@ -36,6 +36,7 @@ pub(crate) enum KeyExprInner<'a> { BorrowedWire { key_expr: &'a keyexpr, expr_id: ExprId, + mapping: Mapping, prefix_len: u32, session_id: u16, }, @@ -43,6 +44,7 @@ pub(crate) enum KeyExprInner<'a> { Wire { key_expr: OwnedKeyExpr, expr_id: ExprId, + mapping: Mapping, prefix_len: u32, session_id: u16, }, @@ -110,11 +112,13 @@ impl<'a> KeyExpr<'a> { KeyExprInner::BorrowedWire { key_expr, expr_id, + mapping, prefix_len, session_id, } => KeyExprInner::BorrowedWire { key_expr, expr_id: *expr_id, + mapping: *mapping, prefix_len: *prefix_len, session_id: *session_id, }, @@ -122,11 +126,13 @@ impl<'a> KeyExpr<'a> { KeyExprInner::Wire { key_expr, expr_id, + mapping, prefix_len, session_id, } => KeyExprInner::BorrowedWire { key_expr, expr_id: *expr_id, + mapping: *mapping, prefix_len: *prefix_len, session_id: *session_id, }, @@ -167,22 +173,26 @@ impl<'a> KeyExpr<'a> { KeyExprInner::BorrowedWire { key_expr, expr_id, + mapping, prefix_len, session_id, } => KeyExpr(KeyExprInner::Wire { key_expr: key_expr.into(), expr_id, + mapping, prefix_len, session_id, }), KeyExprInner::Wire { key_expr, expr_id, + mapping, prefix_len, session_id, } => KeyExpr(KeyExprInner::Wire { key_expr, expr_id, + mapping, prefix_len, session_id, }), @@ -205,6 +215,7 @@ impl<'a> KeyExpr<'a> { let r = self.as_keyexpr().join(s)?; if let KeyExprInner::Wire { expr_id, + mapping, prefix_len, session_id, .. @@ -213,6 +224,7 @@ impl<'a> KeyExpr<'a> { Ok(KeyExpr(KeyExprInner::Wire { key_expr: r, expr_id: *expr_id, + mapping: *mapping, prefix_len: *prefix_len, session_id: *session_id, })) @@ -236,12 +248,14 @@ impl<'a> KeyExpr<'a> { let r = OwnedKeyExpr::try_from(format!("{self}{s}"))?; if let KeyExprInner::Wire { expr_id, + mapping, prefix_len, session_id, .. } | KeyExprInner::BorrowedWire { expr_id, + mapping, prefix_len, session_id, .. @@ -250,6 +264,7 @@ impl<'a> KeyExpr<'a> { Ok(KeyExpr(KeyExprInner::Wire { key_expr: r, expr_id: *expr_id, + mapping: *mapping, prefix_len: *prefix_len, session_id: *session_id, })) @@ -321,11 +336,13 @@ impl<'a> From<&'a KeyExpr<'a>> for KeyExpr<'a> { KeyExprInner::BorrowedWire { key_expr, expr_id, + mapping, prefix_len, session_id, } => Self(KeyExprInner::BorrowedWire { key_expr, expr_id: *expr_id, + mapping: *mapping, prefix_len: *prefix_len, session_id: *session_id, }), @@ -333,11 +350,13 @@ impl<'a> From<&'a KeyExpr<'a>> for KeyExpr<'a> { KeyExprInner::Wire { key_expr, expr_id, + mapping, prefix_len, session_id, } => Self(KeyExprInner::BorrowedWire { key_expr, expr_id: *expr_id, + mapping: *mapping, prefix_len: *prefix_len, session_id: *session_id, }), @@ -420,11 +439,13 @@ impl std::ops::Div<&keyexpr> for KeyExpr<'_> { KeyExprInner::BorrowedWire { key_expr, expr_id, + mapping, prefix_len, session_id, } => KeyExpr(KeyExprInner::Wire { key_expr: key_expr / rhs, expr_id, + mapping, prefix_len, session_id, }), @@ -432,11 +453,13 @@ impl std::ops::Div<&keyexpr> for KeyExpr<'_> { KeyExprInner::Wire { key_expr, expr_id, + mapping, prefix_len, session_id, } => KeyExpr(KeyExprInner::Wire { key_expr: key_expr / rhs, expr_id, + mapping, prefix_len, session_id, }), @@ -452,11 +475,13 @@ impl std::ops::Div<&keyexpr> for &KeyExpr<'_> { KeyExprInner::BorrowedWire { key_expr, expr_id, + mapping, prefix_len, session_id, } => KeyExpr(KeyExprInner::Wire { key_expr: *key_expr / rhs, expr_id: *expr_id, + mapping: *mapping, prefix_len: *prefix_len, session_id: *session_id, }), @@ -464,11 +489,13 @@ impl std::ops::Div<&keyexpr> for &KeyExpr<'_> { KeyExprInner::Wire { key_expr, expr_id, + mapping, prefix_len, session_id, } => KeyExpr(KeyExprInner::Wire { key_expr: key_expr / rhs, expr_id: *expr_id, + mapping: *mapping, prefix_len: *prefix_len, session_id: *session_id, }), @@ -502,29 +529,35 @@ impl<'a> KeyExpr<'a> { KeyExprInner::Wire { key_expr, expr_id, + mapping, prefix_len, session_id, } if session.id == *session_id => WireExpr { scope: *expr_id, suffix: std::borrow::Cow::Borrowed(&key_expr.as_str()[((*prefix_len) as usize)..]), + mapping: *mapping, }, KeyExprInner::BorrowedWire { key_expr, expr_id, + mapping, prefix_len, session_id, } if session.id == *session_id => WireExpr { scope: *expr_id, suffix: std::borrow::Cow::Borrowed(&key_expr.as_str()[((*prefix_len) as usize)..]), + mapping: *mapping, }, KeyExprInner::Owned(key_expr) | KeyExprInner::Wire { key_expr, .. } => WireExpr { scope: 0, suffix: std::borrow::Cow::Borrowed(key_expr.as_str()), + mapping: Mapping::Sender, }, KeyExprInner::Borrowed(key_expr) | KeyExprInner::BorrowedWire { key_expr, .. } => { WireExpr { scope: 0, suffix: std::borrow::Cow::Borrowed(key_expr.as_str()), + mapping: Mapping::Sender, } } } @@ -569,7 +602,8 @@ impl SyncResolve for KeyExprUndeclaration<'_> { key_expr, expr_id, prefix_len, - session_id + session_id, + .. } if *prefix_len as usize == key_expr.len() => { if *session_id == session.id { *expr_id @@ -581,7 +615,8 @@ impl SyncResolve for KeyExprUndeclaration<'_> { key_expr, expr_id, prefix_len, - session_id + session_id, + .. } if *prefix_len as usize == key_expr.len() => { if *session_id == session.id { *expr_id diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index 064ed1f75f..bcd2c71bba 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -17,7 +17,7 @@ use std::fmt; use std::sync::Arc; use zenoh_protocol::core::{ExprId, WhatAmI, ZenohId}; use zenoh_protocol::network::queryable::ext::QueryableInfo; -use zenoh_protocol::network::{Push, Request, RequestId, Response, ResponseFinal}; +use zenoh_protocol::network::{Mapping, Push, Request, RequestId, Response, ResponseFinal}; use zenoh_protocol::zenoh_new::RequestBody; use zenoh_transport::Primitives; @@ -64,10 +64,14 @@ impl FaceState { #[inline] #[allow(clippy::trivially_copy_pass_by_ref)] - pub(super) fn get_mapping(&self, prefixid: &ExprId) -> Option<&std::sync::Arc> { - match self.remote_mappings.get(prefixid) { - Some(prefix) => Some(prefix), - None => self.local_mappings.get(prefixid), + pub(super) fn get_mapping( + &self, + prefixid: &ExprId, + mapping: Mapping, + ) -> Option<&std::sync::Arc> { + match mapping { + Mapping::Sender => self.remote_mappings.get(prefixid), + Mapping::Receiver => self.local_mappings.get(prefixid), } } diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index af13955357..bee733a503 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -27,7 +27,7 @@ use zenoh_protocol::network::common::ext::WireExprType; use zenoh_protocol::network::declare::ext; use zenoh_protocol::network::subscriber::ext::SubscriberInfo; use zenoh_protocol::network::{ - Declare, DeclareBody, DeclareSubscriber, Mapping, Mode, Push, UndeclareSubscriber, + Declare, DeclareBody, DeclareSubscriber, Mode, Push, UndeclareSubscriber, }; use zenoh_protocol::zenoh_new::PushBody; use zenoh_protocol::{ @@ -64,7 +64,6 @@ fn send_sourced_subscription_to_net_childs( body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: *sub_info, }), }); @@ -117,7 +116,6 @@ fn propagate_simple_subscription_to( body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: *sub_info, }), }); @@ -228,7 +226,10 @@ pub fn declare_router_subscription( sub_info: &SubscriberInfo, router: ZenohId, ) { - match rtables.get_mapping(face, &expr.scope).cloned() { + match rtables + .get_mapping(face, &expr.scope, expr.mapping) + .cloned() + { Some(mut prefix) => { let res = Resource::get_resource(&prefix, &expr.suffix); let (mut res, mut wtables) = @@ -306,7 +307,10 @@ pub fn declare_peer_subscription( sub_info: &SubscriberInfo, peer: ZenohId, ) { - match rtables.get_mapping(face, &expr.scope).cloned() { + match rtables + .get_mapping(face, &expr.scope, expr.mapping) + .cloned() + { Some(mut prefix) => { let res = Resource::get_resource(&prefix, &expr.suffix); let (mut res, mut wtables) = @@ -404,7 +408,10 @@ pub fn declare_client_subscription( sub_info: &SubscriberInfo, ) { log::debug!("Register client subscription"); - match rtables.get_mapping(face, &expr.scope).cloned() { + match rtables + .get_mapping(face, &expr.scope, expr.mapping) + .cloned() + { Some(mut prefix) => { let res = Resource::get_resource(&prefix, &expr.suffix); let (mut res, mut wtables) = @@ -538,10 +545,7 @@ fn send_forget_sourced_subscription_to_net_childs( }, body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { id: 0, // TODO - ext_wire_expr: WireExprType { - wire_expr, - mapping: Mapping::default(), - }, + ext_wire_expr: WireExprType { wire_expr }, }), }); } @@ -562,10 +566,7 @@ fn propagate_forget_simple_subscription(tables: &mut Tables, res: &Arc ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { id: 0, // TODO - ext_wire_expr: WireExprType { - wire_expr, - mapping: Mapping::default(), - }, + ext_wire_expr: WireExprType { wire_expr }, }), }); get_mut_unchecked(face).local_subs.remove(res); @@ -601,10 +602,7 @@ fn propagate_forget_simple_subscription_to_peers(tables: &mut Tables, res: &Arc< ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { id: 0, // TODO - ext_wire_expr: WireExprType { - wire_expr, - mapping: Mapping::default(), - }, + ext_wire_expr: WireExprType { wire_expr }, }), }); @@ -692,7 +690,7 @@ pub fn forget_router_subscription( expr: &WireExpr, router: &ZenohId, ) { - match rtables.get_mapping(face, &expr.scope) { + match rtables.get_mapping(face, &expr.scope, expr.mapping) { Some(prefix) => match Resource::get_resource(prefix, expr.suffix.as_ref()) { Some(mut res) => { drop(rtables); @@ -758,7 +756,7 @@ pub fn forget_peer_subscription( expr: &WireExpr, peer: &ZenohId, ) { - match rtables.get_mapping(face, &expr.scope) { + match rtables.get_mapping(face, &expr.scope, expr.mapping) { Some(prefix) => match Resource::get_resource(prefix, expr.suffix.as_ref()) { Some(mut res) => { drop(rtables); @@ -843,10 +841,7 @@ pub(crate) fn undeclare_client_subscription( ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { id: 0, // TODO - ext_wire_expr: WireExprType { - wire_expr, - mapping: Mapping::default(), - }, + ext_wire_expr: WireExprType { wire_expr }, }), }); @@ -861,7 +856,7 @@ pub fn forget_client_subscription( face: &mut Arc, expr: &WireExpr, ) { - match rtables.get_mapping(face, &expr.scope) { + match rtables.get_mapping(face, &expr.scope, expr.mapping) { Some(prefix) => match Resource::get_resource(prefix, expr.suffix.as_ref()) { Some(mut res) => { drop(rtables); @@ -907,7 +902,6 @@ pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: sub_info, }), }); @@ -932,7 +926,6 @@ pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: sub_info, }), }); @@ -953,7 +946,6 @@ pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: sub_info, }), }); @@ -1147,10 +1139,7 @@ pub(crate) fn pubsub_linkstate_change(tables: &mut Tables, zid: &ZenohId, links: body: DeclareBody::UndeclareSubscriber( UndeclareSubscriber { id: 0, // TODO - ext_wire_expr: WireExprType { - wire_expr, - mapping: Mapping::default(), - }, + ext_wire_expr: WireExprType { wire_expr }, }, ), }); @@ -1172,7 +1161,6 @@ pub(crate) fn pubsub_linkstate_change(tables: &mut Tables, zid: &ZenohId, links: body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: sub_info, }), }); @@ -1692,7 +1680,7 @@ pub fn full_reentrant_route_data( routing_context: u64, ) { let tables = zread!(tables_ref); - match tables.get_mapping(face, &expr.scope).cloned() { + match tables.get_mapping(face, &expr.scope, expr.mapping).cloned() { Some(prefix) => { log::trace!( "Route data for res {}{}", @@ -1720,7 +1708,6 @@ pub fn full_reentrant_route_data( drop(tables); outface.primitives.send_push(Push { wire_expr: key_expr.into(), - mapping: Mapping::default(), // TODO ext_qos, ext_tstamp: None, ext_nodeid: ext::NodeIdType { @@ -1749,7 +1736,6 @@ pub fn full_reentrant_route_data( for (outface, key_expr, context) in route { outface.primitives.send_push(Push { wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_qos: ext::QoSType::default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { @@ -1764,7 +1750,6 @@ pub fn full_reentrant_route_data( if face.id != outface.id { outface.primitives.send_push(Push { wire_expr: key_expr.into(), - mapping: Mapping::default(), // TODO ext_qos: ext::QoSType::default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { @@ -1787,7 +1772,7 @@ pub fn full_reentrant_route_data( pub fn pull_data(tables_ref: &RwLock, face: &Arc, expr: WireExpr) { let tables = zread!(tables_ref); - match tables.get_mapping(face, &expr.scope) { + match tables.get_mapping(face, &expr.scope, expr.mapping) { Some(prefix) => match Resource::get_resource(prefix, expr.suffix.as_ref()) { Some(mut res) => { let res = get_mut_unchecked(&mut res); @@ -1812,7 +1797,6 @@ pub fn pull_data(tables_ref: &RwLock, face: &Arc, expr: WireE for (key_expr, payload) in route { face.primitives.send_push(Push { wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_qos: ext::QoSType::default(), // TODO ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 6a01320afe..54f55d06e1 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -32,8 +32,8 @@ use zenoh_protocol::network::declare::ext; use zenoh_protocol::network::request::ext::TargetType; use zenoh_protocol::network::response::ext::ResponderIdType; use zenoh_protocol::network::{ - response, Declare, DeclareBody, DeclareQueryable, Mapping, Request, RequestId, Response, - ResponseFinal, UndeclareQueryable, + response, Declare, DeclareBody, DeclareQueryable, Request, RequestId, Response, ResponseFinal, + UndeclareQueryable, }; use zenoh_protocol::zenoh_new::reply::ext::ConsolidationType; use zenoh_protocol::zenoh_new::{self, RequestBody, ResponseBody}; @@ -231,7 +231,6 @@ fn send_sourced_queryable_to_net_childs( body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: *qabl_info, }), }); @@ -297,7 +296,6 @@ fn propagate_simple_queryable( body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: info, }), }); @@ -397,7 +395,10 @@ pub fn declare_router_queryable( qabl_info: &QueryableInfo, router: ZenohId, ) { - match rtables.get_mapping(face, &expr.scope).cloned() { + match rtables + .get_mapping(face, &expr.scope, expr.mapping) + .cloned() + { Some(mut prefix) => { let res = Resource::get_resource(&prefix, &expr.suffix); let (mut res, mut wtables) = @@ -484,7 +485,10 @@ pub fn declare_peer_queryable( qabl_info: &QueryableInfo, peer: ZenohId, ) { - match rtables.get_mapping(face, &expr.scope).cloned() { + match rtables + .get_mapping(face, &expr.scope, expr.mapping) + .cloned() + { Some(mut prefix) => { let res = Resource::get_resource(&prefix, &expr.suffix); let (mut res, mut wtables) = @@ -565,7 +569,10 @@ pub fn declare_client_queryable( expr: &WireExpr, qabl_info: &QueryableInfo, ) { - match rtables.get_mapping(face, &expr.scope).cloned() { + match rtables + .get_mapping(face, &expr.scope, expr.mapping) + .cloned() + { Some(mut prefix) => { let res = Resource::get_resource(&prefix, &expr.suffix); let (mut res, mut wtables) = @@ -701,10 +708,7 @@ fn send_forget_sourced_queryable_to_net_childs( }, body: DeclareBody::UndeclareQueryable(UndeclareQueryable { id: 0, // TODO - ext_wire_expr: WireExprType { - wire_expr, - mapping: Mapping::default(), - }, + ext_wire_expr: WireExprType { wire_expr }, }), }); } @@ -725,10 +729,7 @@ fn propagate_forget_simple_queryable(tables: &mut Tables, res: &mut Arc match Resource::get_resource(prefix, expr.suffix.as_ref()) { Some(mut res) => { drop(rtables); @@ -916,7 +914,7 @@ pub fn forget_peer_queryable( expr: &WireExpr, peer: &ZenohId, ) { - match rtables.get_mapping(face, &expr.scope) { + match rtables.get_mapping(face, &expr.scope, expr.mapping) { Some(prefix) => match Resource::get_resource(prefix, expr.suffix.as_ref()) { Some(mut res) => { drop(rtables); @@ -1015,10 +1013,7 @@ pub(crate) fn undeclare_client_queryable( ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareQueryable(UndeclareQueryable { id: 0, // TODO - ext_wire_expr: WireExprType { - wire_expr, - mapping: Mapping::default(), - }, + ext_wire_expr: WireExprType { wire_expr }, }), }); @@ -1033,7 +1028,7 @@ pub fn forget_client_queryable( face: &mut Arc, expr: &WireExpr, ) { - match rtables.get_mapping(face, &expr.scope) { + match rtables.get_mapping(face, &expr.scope, expr.mapping) { Some(prefix) => match Resource::get_resource(prefix, expr.suffix.as_ref()) { Some(mut res) => { drop(rtables); @@ -1079,7 +1074,6 @@ pub(crate) fn queries_new_face(tables: &mut Tables, face: &mut Arc) { body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: info, }), }); @@ -1108,7 +1102,6 @@ pub(crate) fn queries_new_face(tables: &mut Tables, face: &mut Arc) { body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: info, }), }); @@ -1133,7 +1126,6 @@ pub(crate) fn queries_new_face(tables: &mut Tables, face: &mut Arc) { body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: info, }), }); @@ -1270,10 +1262,7 @@ pub(crate) fn queries_linkstate_change(tables: &mut Tables, zid: &ZenohId, links ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareQueryable(UndeclareQueryable { id: 0, // TODO - ext_wire_expr: WireExprType { - wire_expr, - mapping: Mapping::default(), - }, + ext_wire_expr: WireExprType { wire_expr }, }), }); @@ -1293,7 +1282,6 @@ pub(crate) fn queries_linkstate_change(tables: &mut Tables, zid: &ZenohId, links body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO wire_expr: key_expr, - mapping: Mapping::default(), // TODO ext_info: info, }), }); @@ -2008,7 +1996,7 @@ pub fn route_query( routing_context: u64, ) { let rtables = zread!(tables_ref.tables); - match rtables.get_mapping(face, &expr.scope) { + match rtables.get_mapping(face, &expr.scope, expr.mapping) { Some(prefix) => { log::debug!( "Route query {}:{} for res {}{}", @@ -2046,7 +2034,6 @@ pub fn route_query( face.primitives.clone().send_response(Response { rid: qid, wire_expr: expr, - mapping: Mapping::default(), // TODO payload: ResponseBody::Reply(zenoh_new::Reply { timestamp: None, encoding: Encoding::default(), @@ -2093,7 +2080,6 @@ pub fn route_query( outface.primitives.send_request(Request { id: *qid, wire_expr: key_expr.into(), - mapping: Mapping::default(), // TODO ext_qos: ext::QoSType::default(), // TODO ext_tstamp: None, ext_nodeid: ext::NodeIdType { @@ -2122,7 +2108,6 @@ pub fn route_query( outface.primitives.send_request(Request { id: *qid, wire_expr: key_expr.into(), - mapping: Mapping::default(), // TODO ext_qos: ext::QoSType::default(), // TODO ext_tstamp: None, ext_nodeid: ext::NodeIdType { @@ -2177,7 +2162,6 @@ pub(crate) fn route_send_response( query.src_face.primitives.clone().send_response(Response { rid: query.src_qid, wire_expr: key_expr.to_owned(), - mapping: Mapping::default(), // TODO payload: body, ext_qos: response::ext::QoSType::default(), ext_tstamp: None, diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index c10b8af2d1..b918f2ed42 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -22,7 +22,7 @@ use zenoh_protocol::network::queryable::ext::QueryableInfo; #[cfg(feature = "complete_n")] use zenoh_protocol::network::request::ext::TargetType; use zenoh_protocol::network::subscriber::ext::SubscriberInfo; -use zenoh_protocol::network::{Declare, DeclareBody, DeclareKeyExpr}; +use zenoh_protocol::network::{Declare, DeclareBody, DeclareKeyExpr, Mapping}; use zenoh_protocol::zenoh_new::PushBody; use zenoh_protocol::{ core::{key_expr::keyexpr, ExprId, WireExpr, ZenohId}, @@ -492,29 +492,38 @@ impl Resource { }) }); - let expr_id = match ctx.local_expr_id.or(ctx.remote_expr_id) { - Some(expr_id) => expr_id, - None => { - let expr_id = face.get_next_local_id(); - get_mut_unchecked(ctx).local_expr_id = Some(expr_id); - get_mut_unchecked(face) - .local_mappings - .insert(expr_id, nonwild_prefix.clone()); - face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { - id: expr_id, - wire_expr: nonwild_prefix.expr().into(), - }), - }); - expr_id + if let Some(expr_id) = ctx.remote_expr_id { + WireExpr { + scope: expr_id, + suffix: wildsuffix.into(), + mapping: Mapping::Receiver, + } + } else if let Some(expr_id) = ctx.local_expr_id { + WireExpr { + scope: expr_id, + suffix: wildsuffix.into(), + mapping: Mapping::Sender, + } + } else { + let expr_id = face.get_next_local_id(); + get_mut_unchecked(ctx).local_expr_id = Some(expr_id); + get_mut_unchecked(face) + .local_mappings + .insert(expr_id, nonwild_prefix.clone()); + face.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { + id: expr_id, + wire_expr: nonwild_prefix.expr().into(), + }), + }); + WireExpr { + scope: expr_id, + suffix: wildsuffix.into(), + mapping: Mapping::Sender, } - }; - WireExpr { - scope: expr_id, - suffix: wildsuffix.into(), } } None => wildsuffix.into(), @@ -536,15 +545,17 @@ impl Resource { } } if let Some(ctx) = prefix.session_ctxs.get(&sid) { - if let Some(expr_id) = ctx.local_expr_id { + if let Some(expr_id) = ctx.remote_expr_id { return WireExpr { scope: expr_id, suffix: suffix.into(), + mapping: Mapping::Receiver, }; - } else if let Some(expr_id) = ctx.remote_expr_id { + } else if let Some(expr_id) = ctx.local_expr_id { return WireExpr { scope: expr_id, suffix: suffix.into(), + mapping: Mapping::Sender, }; } } @@ -672,7 +683,10 @@ pub fn register_expr( expr: &WireExpr, ) { let rtables = zread!(tables.tables); - match rtables.get_mapping(face, &expr.scope).cloned() { + match rtables + .get_mapping(face, &expr.scope, expr.mapping) + .cloned() + { Some(mut prefix) => match face.remote_mappings.get(&expr_id) { Some(res) => { let mut fullexpr = prefix.expr(); @@ -705,7 +719,7 @@ pub fn register_expr( Resource::match_resource(&wtables, &mut res, matches); (res, wtables) }; - let mut ctx = get_mut_unchecked(&mut res) + get_mut_unchecked(&mut res) .session_ctxs .entry(face.id) .or_insert_with(|| { @@ -717,27 +731,7 @@ pub fn register_expr( qabl: None, last_values: HashMap::new(), }) - }) - .clone(); - - if face.local_mappings.get(&expr_id).is_some() && ctx.local_expr_id.is_none() { - let local_expr_id = get_mut_unchecked(face).get_next_local_id(); - get_mut_unchecked(&mut ctx).local_expr_id = Some(local_expr_id); - - get_mut_unchecked(face) - .local_mappings - .insert(local_expr_id, res.clone()); - - face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { - id: local_expr_id, - wire_expr: res.expr().into(), - }), }); - } get_mut_unchecked(face) .remote_mappings diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index bda595bd9b..ace5a5b1f8 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -31,7 +31,7 @@ use uhlc::HLC; use zenoh_link::Link; use zenoh_protocol::common::ZExtBody; use zenoh_protocol::core::{ExprId, WhatAmI, WhatAmIMatcher, ZenohId}; -use zenoh_protocol::network::{NetworkBody, NetworkMessage}; +use zenoh_protocol::network::{Mapping, NetworkBody, NetworkMessage}; use zenoh_transport::{DeMux, Mux, Primitives, TransportPeerEventHandler, TransportUnicast}; // use zenoh_collections::Timer; use zenoh_core::zconfigurable; @@ -139,10 +139,11 @@ impl Tables { &'a self, face: &'a FaceState, expr_id: &ExprId, + mapping: Mapping, ) -> Option<&'a Arc> { match expr_id { 0 => Some(&self.root_res), - expr_id => face.get_mapping(expr_id), + expr_id => face.get_mapping(expr_id, mapping), } } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 1fe3757df8..b8691f0fa0 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -34,8 +34,8 @@ use zenoh_protocol::core::{ use zenoh_protocol::network::queryable::ext::QueryableInfo; use zenoh_protocol::network::subscriber::ext::SubscriberInfo; use zenoh_protocol::network::{ - ext, Declare, DeclareBody, DeclareQueryable, DeclareSubscriber, Mapping, Push, Request, - Response, ResponseFinal, + ext, Declare, DeclareBody, DeclareQueryable, DeclareSubscriber, Push, Request, Response, + ResponseFinal, }; use zenoh_protocol::zenoh_new::{PushBody, RequestBody}; use zenoh_result::ZResult; @@ -225,7 +225,6 @@ impl AdminSpace { body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO wire_expr: [&root_key, "/**"].concat().into(), - mapping: Mapping::default(), // TODO ext_info: QueryableInfo { complete: 0, distance: 0, @@ -240,7 +239,6 @@ impl AdminSpace { body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: 0, // TODO wire_expr: [&root_key, "/config/**"].concat().into(), - mapping: Mapping::default(), // TODO ext_info: SubscriberInfo::default(), }), }); diff --git a/zenoh/src/publication.rs b/zenoh/src/publication.rs index 47f69c0d8b..9073bd115e 100644 --- a/zenoh/src/publication.rs +++ b/zenoh/src/publication.rs @@ -139,7 +139,6 @@ impl SyncResolve for PutBuilder<'_, '_> { if publisher.destination != Locality::SessionLocal { primitives.send_push(Push { wire_expr: key_expr.to_wire(&publisher.session).to_owned(), - mapping: Mapping::default(), // TODO ext_qos: ext::QoSType::new( publisher.priority.into(), publisher.congestion_control, @@ -430,7 +429,6 @@ impl SyncResolve for Publication<'_> { if publisher.destination != Locality::SessionLocal { primitives.send_push(Push { wire_expr: publisher.key_expr.to_wire(&publisher.session).to_owned(), - mapping: Mapping::default(), // TODO ext_qos: ext::QoSType::default(), // TODO // use publisher.priority // use publisher.congestion_control @@ -585,6 +583,7 @@ impl<'a, 'b> SyncResolve for PublisherBuilder<'a, 'b> { KeyExpr(crate::key_expr::KeyExprInner::BorrowedWire { key_expr, expr_id, + mapping: Mapping::Sender, prefix_len, session_id, }) @@ -594,6 +593,7 @@ impl<'a, 'b> SyncResolve for PublisherBuilder<'a, 'b> { KeyExpr(crate::key_expr::KeyExprInner::Wire { key_expr, expr_id, + mapping: Mapping::Sender, prefix_len, session_id, }) diff --git a/zenoh/src/queryable.rs b/zenoh/src/queryable.rs index 666a7f81a8..b19bdbdf8e 100644 --- a/zenoh/src/queryable.rs +++ b/zenoh/src/queryable.rs @@ -168,8 +168,8 @@ impl SyncResolve for ReplyBuilder<'_> { wire_expr: WireExpr { scope: 0, suffix: std::borrow::Cow::Owned(key_expr.into()), + mapping: Mapping::Sender, }, - mapping: Mapping::default(), // TODO payload: ResponseBody::Reply(zenoh_new::Reply { timestamp: data_info.timestamp, encoding: data_info.encoding.unwrap_or_default(), diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 33cc9d8369..05b39ffee6 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -145,19 +145,19 @@ impl SessionState { } #[inline] - fn get_remote_res(&self, id: &ExprId) -> Option<&Resource> { - match self.remote_resources.get(id) { - None => self.local_resources.get(id), - res => res, + fn get_remote_res(&self, id: &ExprId, mapping: Mapping) -> Option<&Resource> { + match mapping { + Mapping::Receiver => self.local_resources.get(id), + Mapping::Sender => self.remote_resources.get(id), } } #[inline] - fn get_res(&self, id: &ExprId, local: bool) -> Option<&Resource> { + fn get_res(&self, id: &ExprId, mapping: Mapping, local: bool) -> Option<&Resource> { if local { self.get_local_res(id) } else { - self.get_remote_res(id) + self.get_remote_res(id, mapping) } } @@ -165,7 +165,7 @@ impl SessionState { if key_expr.scope == EMPTY_EXPR_ID { Ok(unsafe { keyexpr::from_str_unchecked(key_expr.suffix.as_ref()) }.into()) } else if key_expr.suffix.is_empty() { - match self.get_remote_res(&key_expr.scope) { + match self.get_remote_res(&key_expr.scope, key_expr.mapping) { Some(Resource::Node(ResourceNode { key_expr, .. })) => Ok(key_expr.into()), Some(Resource::Prefix { prefix }) => bail!( "Received {:?}, where {} is `{}`, which isn't a valid key expression", @@ -177,7 +177,7 @@ impl SessionState { } } else { [ - match self.get_remote_res(&key_expr.scope) { + match self.get_remote_res(&key_expr.scope, key_expr.mapping) { Some(Resource::Node(ResourceNode { key_expr, .. })) => key_expr.as_str(), Some(Resource::Prefix { prefix }) => prefix.as_ref(), None => bail!("Remote resource {} not found", key_expr.scope), @@ -670,6 +670,7 @@ impl Session { KeyExpr(KeyExprInner::BorrowedWire { key_expr, expr_id, + mapping: Mapping::Sender, prefix_len, session_id: sid, }) @@ -678,6 +679,7 @@ impl Session { KeyExpr(KeyExprInner::Wire { key_expr, expr_id, + mapping: Mapping::Sender, prefix_len, session_id: sid, }) @@ -903,6 +905,7 @@ impl Session { wire_expr: WireExpr { scope: 0, suffix: prefix.to_owned().into(), + mapping: Mapping::Sender, }, }), }); @@ -1101,7 +1104,6 @@ impl Session { body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: id as u32, wire_expr: key_expr.to_wire(self).to_owned(), - mapping: Mapping::default(), // TODO ext_info: *info, }), }); @@ -1160,10 +1162,7 @@ impl Session { ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { id: 0, // TODO - ext_wire_expr: WireExprType { - wire_expr, - mapping: Mapping::default(), - }, + ext_wire_expr: WireExprType { wire_expr }, }), }); } @@ -1184,7 +1183,6 @@ impl Session { id: 0, // TODO ext_wire_expr: WireExprType { wire_expr: key_expr.to_wire(self).to_owned(), - mapping: Mapping::default(), }, }), }); @@ -1234,7 +1232,6 @@ impl Session { body: DeclareBody::DeclareQueryable(DeclareQueryable { id: id as u32, wire_expr: key_expr.to_owned(), - mapping: Mapping::default(), // TODO ext_info: qabl_info, }), }); @@ -1263,7 +1260,6 @@ impl Session { body: DeclareBody::DeclareQueryable(DeclareQueryable { id: id as u32, wire_expr: key_expr.to_owned(), - mapping: Mapping::default(), // TODO ext_info: qabl_info, }), }); @@ -1329,7 +1325,6 @@ impl Session { body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO wire_expr: qable_state.key_expr.clone(), - mapping: Mapping::default(), // TODO ext_info: qabl_info, }), }); @@ -1349,7 +1344,6 @@ impl Session { body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO wire_expr: qable_state.key_expr.clone(), - mapping: Mapping::default(), // TODO ext_info: qabl_info, }), }); @@ -1367,7 +1361,6 @@ impl Session { id: 0, // TODO ext_wire_expr: WireExprType { wire_expr: qable_state.key_expr.clone(), - mapping: Mapping::default(), }, }), }); @@ -1403,7 +1396,6 @@ impl Session { body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: id as u32, wire_expr: key_expr.to_wire(self).to_owned(), - mapping: Mapping::default(), ext_info: SubscriberInfo::default(), }), }); @@ -1429,7 +1421,6 @@ impl Session { id: 0, // TODO ext_wire_expr: WireExprType { wire_expr: key_expr.to_wire(self).to_owned(), - mapping: Mapping::default(), }, }), }); @@ -1450,7 +1441,7 @@ impl Session { let mut callbacks = SingleOrVec::default(); let state = zread!(self.state); if key_expr.suffix.is_empty() { - match state.get_res(&key_expr.scope, local) { + match state.get_res(&key_expr.scope, key_expr.mapping, local) { Some(Resource::Node(res)) => { for sub in &res.subscribers { if sub.origin == Locality::Any @@ -1562,7 +1553,6 @@ impl Session { primitives.send_request(Request { id: 0, // TODO wire_expr: key_expr.to_wire(self).to_owned(), - mapping: Mapping::default(), // TODO ext_qos: ext::QoSType::default(), // TODO ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), @@ -1657,7 +1647,6 @@ impl Session { primitives.send_request(Request { id: qid, wire_expr: wexpr.clone(), - mapping: Mapping::default(), // TODO ext_qos: request::ext::QoSType::default(), ext_tstamp: None, ext_nodeid: request::ext::NodeIdType::default(), From 2b52a67ef1be359bb6246bb49b747144be847e9d Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 30 Jun 2023 21:15:52 +0200 Subject: [PATCH 154/203] Renable unicast_transport tests --- commons/zenoh-protocol/src/common/mod.rs | 11 + commons/zenoh-protocol/src/network/mod.rs | 56 +- io/zenoh-transport/tests/unicast_transport.rs | 2273 +++++++++-------- 3 files changed, 1191 insertions(+), 1149 deletions(-) diff --git a/commons/zenoh-protocol/src/common/mod.rs b/commons/zenoh-protocol/src/common/mod.rs index e855c34841..d11d0b0c52 100644 --- a/commons/zenoh-protocol/src/common/mod.rs +++ b/commons/zenoh-protocol/src/common/mod.rs @@ -50,6 +50,17 @@ pub mod imsg { byte & flag != 0 } + pub const fn unset_flag(mut byte: u8, flag: u8) -> u8 { + byte &= !flag; + byte + } + + pub const fn set_flag(mut byte: u8, flag: u8) -> u8 { + byte = unset_flag(byte, flag); + byte |= flag; + byte + } + pub const fn has_option(options: u64, flag: u64) -> bool { options & flag != 0 } diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 752a995ef5..8787a0297a 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -111,12 +111,12 @@ impl NetworkMessage { } let cc = match &self.body { - NetworkBody::Declare(msg) => msg.ext_qos.congestion_control(), - NetworkBody::Push(msg) => msg.ext_qos.congestion_control(), - NetworkBody::Request(msg) => msg.ext_qos.congestion_control(), - NetworkBody::Response(msg) => msg.ext_qos.congestion_control(), - NetworkBody::ResponseFinal(msg) => msg.ext_qos.congestion_control(), - NetworkBody::OAM(msg) => msg.ext_qos.congestion_control(), + NetworkBody::Declare(msg) => msg.ext_qos.get_congestion_control(), + NetworkBody::Push(msg) => msg.ext_qos.get_congestion_control(), + NetworkBody::Request(msg) => msg.ext_qos.get_congestion_control(), + NetworkBody::Response(msg) => msg.ext_qos.get_congestion_control(), + NetworkBody::ResponseFinal(msg) => msg.ext_qos.get_congestion_control(), + NetworkBody::OAM(msg) => msg.ext_qos.get_congestion_control(), }; cc == CongestionControl::Drop @@ -125,12 +125,12 @@ impl NetworkMessage { #[inline] pub fn priority(&self) -> Priority { match &self.body { - NetworkBody::Declare(msg) => msg.ext_qos.priority(), - NetworkBody::Push(msg) => msg.ext_qos.priority(), - NetworkBody::Request(msg) => msg.ext_qos.priority(), - NetworkBody::Response(msg) => msg.ext_qos.priority(), - NetworkBody::ResponseFinal(msg) => msg.ext_qos.priority(), - NetworkBody::OAM(msg) => msg.ext_qos.priority(), + NetworkBody::Declare(msg) => msg.ext_qos.get_priority(), + NetworkBody::Push(msg) => msg.ext_qos.get_priority(), + NetworkBody::Request(msg) => msg.ext_qos.get_priority(), + NetworkBody::Response(msg) => msg.ext_qos.get_priority(), + NetworkBody::ResponseFinal(msg) => msg.ext_qos.get_priority(), + NetworkBody::OAM(msg) => msg.ext_qos.get_priority(), } } } @@ -228,11 +228,22 @@ pub mod ext { Self { inner } } - pub const fn priority(&self) -> Priority { + pub fn set_priority(&mut self, priority: Priority) { + self.inner = imsg::set_flag(self.inner, priority as u8); + } + + pub const fn get_priority(&self) -> Priority { unsafe { core::mem::transmute(self.inner & Self::P_MASK) } } - pub const fn congestion_control(&self) -> CongestionControl { + pub fn set_congestion_control(&mut self, cctrl: CongestionControl) { + match cctrl { + CongestionControl::Block => self.inner = imsg::set_flag(self.inner, Self::D_FLAG), + CongestionControl::Drop => self.inner = imsg::unset_flag(self.inner, Self::D_FLAG), + } + } + + pub const fn get_congestion_control(&self) -> CongestionControl { match imsg::has_flag(self.inner, Self::D_FLAG) { true => CongestionControl::Block, false => CongestionControl::Drop, @@ -276,8 +287,8 @@ pub mod ext { impl fmt::Debug for QoSType<{ ID }> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("QoS") - .field("priority", &self.priority()) - .field("congestion", &self.congestion_control()) + .field("priority", &self.get_priority()) + .field("congestion", &self.get_congestion_control()) .field("express", &self.is_express()) .finish() } @@ -314,10 +325,10 @@ pub mod ext { /// +-+-+-+-+-+-+-+-+ /// |Z|0_1| ID | /// +-+-+-+---------+ - /// % source_id % + /// % node_id % /// +---------------+ /// ``` - #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NodeIdType { pub node_id: u16, } @@ -327,11 +338,18 @@ pub mod ext { pub fn rand() -> Self { use rand::Rng; let mut rng = rand::thread_rng(); - let node_id = rng.gen_range(1..20); + let node_id = rng.gen(); Self { node_id } } } + impl Default for NodeIdType<{ ID }> { + fn default() -> Self { + // node_id == 0 means the message has been generated by the node itself + Self { node_id: 0 } + } + } + impl From> for NodeIdType<{ ID }> { fn from(ext: ZExtZ64<{ ID }>) -> Self { Self { diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 369e453d94..000eb3f2a7 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -1,1130 +1,1143 @@ -// // -// // Copyright (c) 2023 ZettaScale Technology -// // -// // This program and the accompanying materials are made available under the -// // terms of the Eclipse Public License 2.0 which is available at -// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// // which is available at https://www.apache.org/licenses/LICENSE-2.0. -// // -// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// // -// // Contributors: -// // ZettaScale Zenoh Team, -// // -// use async_std::{prelude::FutureExt, task}; -// use std::fmt::Write as _; -// use std::{ -// any::Any, -// convert::TryFrom, -// sync::{ -// atomic::{AtomicUsize, Ordering}, -// Arc, -// }, -// time::Duration, -// }; -// use zenoh_buffers::ZBuf; -// use zenoh_core::zasync_executor_init; -// use zenoh_link::Link; -// use zenoh_protocol::{ -// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, -// zenoh::ZenohMessage, -// }; -// use zenoh_result::ZResult; -// use zenoh_transport::{ -// TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, -// TransportUnicast, -// }; - -// // These keys and certificates below are purposedly generated to run TLS and mTLS tests. -// // -// // With 2 way authentication (mTLS), using TLS 1.3, we need two pairs of keys and certificates: one -// // for the "server" and another one for the "client". -// // -// // The keys and certificates below were auto-generated using https://github.com/jsha/minica and -// // target the localhost domain, so it has no real mapping to any existing domain. -// // -// // The keys and certificates generated map as follows to the constants below: -// // -// // certificates -// // ├── client -// // │ ├── localhost -// // │ │ ├── cert.pem <------- CLIENT_CERT -// // │ │ └── key.pem <-------- CLIENT_KEY -// // │ ├── minica-key.pem -// // │ └── minica.pem <--------- CLIENT_CA -// // └── server -// // ├── localhost -// // │ ├── cert.pem <------- SERVER_CERT -// // │ └── key.pem <-------- SERVER_KEY -// // ├── minica-key.pem -// // └── minica.pem <--------- SERVER_CA -// // -// // The way it works is that the client's certificate authority will validate in front of the server -// // the key and certificate brought in by the client. Similarly the server's certificate authority -// // will validate the key and certificate brought in by the server in front of the client. -// // -// #[cfg(all(feature = "transport_tls", target_family = "unix"))] -// const CLIENT_KEY: &str = "-----BEGIN RSA PRIVATE KEY----- -// MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi -// qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy -// aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU -// cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha -// Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr -// Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 -// 2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 -// lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU -// WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX -// Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI -// 9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak -// r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn -// qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY -// CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu -// fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj -// 4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih -// XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 -// 38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT -// Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV -// jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R -// 5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H -// n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm -// qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD -// tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v -// F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== -// -----END RSA PRIVATE KEY-----"; - -// #[cfg(all(feature = "transport_tls", target_family = "unix"))] -// const CLIENT_CERT: &str = "-----BEGIN CERTIFICATE----- -// MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -// AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw -// MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -// AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT -// He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ -// Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj -// eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 -// eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M -// tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud -// DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -// AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE -// DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 -// 3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD -// wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q -// GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC -// 9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ -// p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ -// abY= -// -----END CERTIFICATE-----"; - -// #[cfg(all(feature = "transport_tls", target_family = "unix"))] -// const CLIENT_CA: &str = "-----BEGIN CERTIFICATE----- -// MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -// AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw -// MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi -// MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ -// uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs -// DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc -// 8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 -// T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b -// QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB -// AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -// BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 -// /llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq -// hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ -// e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc -// yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 -// 8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 -// Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN -// R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== -// -----END CERTIFICATE-----"; - -// #[cfg(any(feature = "transport_tls", feature = "transport_quic"))] -// const SERVER_KEY: &str = "-----BEGIN RSA PRIVATE KEY----- -// MIIEpAIBAAKCAQEAmDCySqKHPmEZShDH3ldPaV/Zsh9+HlHFLk9H10vJZj5WfzVu -// 5puZQ8GvBFIOtVrl0L9qLkA6bZiHHXm/8OEVvd135ZMp4NV23fdTsEASXfvGVQY8 -// y+4UkZN0Dw6sfwlQVPyNRplys2+nFs6tX05Dp9VizV39tSOqe/jd6hyzxSUHqFat -// RwQRXAI04CZ6ckDb0Riw7i0yvjrFhBom9lPKq4IkXZGgS5MRl0pRgAZTqHEMlv8z -// oX+KcG9mfyQIHtpkVuSHHsQjwVop7fMnT7KCQ3bPI+fgMmAg+h1IR19Dm0JM+9zl -// u39j0IbkytrsystGM+pTRbdp7s2lgtOMCFt0+wIDAQABAoIBADNTSO2uvlmlOXgn -// DKDJZTiuYKaXxFrJTOx/REUxg+x9XYJtLMeM9jVJnpKgceFrlFHAHDkY5BuN8xNX -// ugmsfz6W8BZ2eQsgMoRNIuYv1YHopUyLW/mSg1FNHzjsw/Pb2kGvIp4Kpgopv3oL -// naCkrmBtsHJ+Hk/2hUpl9cE8iMwVWcVevLzyHi98jNy1IDdIPhRtl0dhMiqC5MRr -// 4gLJ5gNkLYX7xf3tw5Hmfk/bVNProqZXDIQVI7rFvItX586nvQ3LNQkmW/D2ShZf -// 3FEqMu6EdA2Ycc4UZgAlQNGV0VBrWWVXizOQ+9gjLnBk3kJjqfigCU6NG94bTJ+H -// 0YIhsGECgYEAwdSSyuMSOXgzZQ7Vv+GsNn/7ivi/H8eb/lDzksqS/JroA2ciAmHG -// 2OF30eUJKRg+STqBTpOfXgS4QUa8QLSwBSnwcw6579x9bYGUhqD2Ypaw9uCnOukA -// CwwggZ9cDmF0tb5rYjqkW3bFPqkCnTGb0ylMFaYRhRDU20iG5t8PQckCgYEAyQEM -// KK18FLQUKivGrQgP5Ib6IC3myzlHGxDzfobXGpaQntFnHY7Cxp/6BBtmASzt9Jxu -// etnrevmzrbKqsLTJSg3ivbiq0YTLAJ1FsZrCp71dx49YR/5o9QFiq0nQoKnwUVeb -// /hrDjMAokNkjFL5vouXO711GSS6YyM4WzAKZAqMCgYEAhqGxaG06jmJ4SFx6ibIl -// nSFeRhQrJNbP+mCeHrrIR98NArgS/laN+Lz7LfaJW1r0gIa7pCmTi4l5thV80vDu -// RlfwJOr4qaucD4Du+mg5WxdSSdiXL6sBlarRtVdMaMy2dTqTegJDgShJLxHTt/3q -// P0yzBWJ5TtT3FG0XDqum/EkCgYAYNHwWWe3bQGQ9P9BI/fOL/YUZYu2sA1XAuKXZ -// 0rsMhJ0dwvG76XkjGhitbe82rQZqsnvLZ3qn8HHmtOFBLkQfGtT3K8nGOUuI42eF -// H7HZKUCly2lCIizZdDVBkz4AWvaJlRc/3lE2Hd3Es6E52kTvROVKhdz06xuS8t5j -// 6twqKQKBgQC01AeiWL6Rzo+yZNzVgbpeeDogaZz5dtmURDgCYH8yFX5eoCKLHfnI -// 2nDIoqpaHY0LuX+dinuH+jP4tlyndbc2muXnHd9r0atytxA69ay3sSA5WFtfi4ef -// ESElGO6qXEA821RpQp+2+uhL90+iC294cPqlS5LDmvTMypVDHzrxPQ== -// -----END RSA PRIVATE KEY-----"; - -// #[cfg(any(feature = "transport_tls", feature = "transport_quic"))] -// const SERVER_CERT: &str = "-----BEGIN CERTIFICATE----- -// MIIDLjCCAhagAwIBAgIIW1mAtJWJAJYwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -// AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw -// MzA2MTY0MTA2WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -// AQUAA4IBDwAwggEKAoIBAQCYMLJKooc+YRlKEMfeV09pX9myH34eUcUuT0fXS8lm -// PlZ/NW7mm5lDwa8EUg61WuXQv2ouQDptmIcdeb/w4RW93Xflkyng1Xbd91OwQBJd -// +8ZVBjzL7hSRk3QPDqx/CVBU/I1GmXKzb6cWzq1fTkOn1WLNXf21I6p7+N3qHLPF -// JQeoVq1HBBFcAjTgJnpyQNvRGLDuLTK+OsWEGib2U8qrgiRdkaBLkxGXSlGABlOo -// cQyW/zOhf4pwb2Z/JAge2mRW5IcexCPBWint8ydPsoJDds8j5+AyYCD6HUhHX0Ob -// Qkz73OW7f2PQhuTK2uzKy0Yz6lNFt2nuzaWC04wIW3T7AgMBAAGjdjB0MA4GA1Ud -// DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -// AQH/BAIwADAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDAUBgNVHREE -// DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAAxrmQPG54ybKgMVliN8 -// Mg5povSdPIVVnlU/HOVG9yxzAOav/xQP003M4wqpatWxI8tR1PcLuZf0EPmcdJgb -// tVl9nZMVZtveQnYMlU8PpkEVu56VM4Zr3rH9liPRlr0JEAXODdKw76kWKzmdqWZ/ -// rzhup3Ek7iEX6T5j/cPUvTWtMD4VEK2I7fgoKSHIX8MIVzqM7cuboGWPtS3eRNXl -// MgvahA4TwLEXPEe+V1WAq6nSb4g2qSXWIDpIsy/O1WGS/zzRnKvXu9/9NkXWqZMl -// C1LSpiiQUaRSglOvYf/Zx6r+4BOS4OaaArwHkecZQqBSCcBLEAyb/FaaXdBowI0U -// PQ4= -// -----END CERTIFICATE-----"; - -// #[cfg(any(feature = "transport_tls", feature = "transport_quic"))] -// const SERVER_CA: &str = "-----BEGIN CERTIFICATE----- -// MIIDSzCCAjOgAwIBAgIITcwv1N10nqEwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -// AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw -// MzA2MTY0MTA2WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSA0ZGNjMmYwggEi -// MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2WUgN7NMlXIknew1cXiTWGmS0 -// 1T1EjcNNDAq7DqZ7/ZVXrjD47yxTt5EOiOXK/cINKNw4Zq/MKQvq9qu+Oax4lwiV -// Ha0i8ShGLSuYI1HBlXu4MmvdG+3/SjwYoGsGaShr0y/QGzD3cD+DQZg/RaaIPHlO -// MdmiUXxkMcy4qa0hFJ1imlJdq/6Tlx46X+0vRCh8nkekvOZR+t7Z5U4jn4XE54Kl -// 0PiwcyX8vfDZ3epa/FSHZvVQieM/g5Yh9OjIKCkdWRg7tD0IEGsaW11tEPJ5SiQr -// mDqdRneMzZKqY0xC+QqXSvIlzpOjiu8PYQx7xugaUFE/npKRQdvh8ojHJMdNAgMB -// AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -// BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTX46+p+Po1npE6 -// QLQ7mMI+83s6qDAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDANBgkq -// hkiG9w0BAQsFAAOCAQEAaN0IvEC677PL/JXzMrXcyBV88IvimlYN0zCt48GYlhmx -// vL1YUDFLJEB7J+dyERGE5N6BKKDGblC4WiTFgDMLcHFsMGRc0v7zKPF1PSBwRYJi -// ubAmkwdunGG5pDPUYtTEDPXMlgClZ0YyqSFJMOqA4IzQg6exVjXtUxPqzxNhyC7S -// vlgUwPbX46uNi581a9+Ls2V3fg0ZnhkTSctYZHGZNeh0Nsf7Am8xdUDYG/bZcVef -// jbQ9gpChosdjF0Bgblo7HSUct/2Va+YlYwW+WFjJX8k4oN6ZU5W5xhdfO8Czmgwk -// US5kJ/+1M0uR8zUhZHL61FbsdPxEj+fYKrHv4woo+A== -// -----END CERTIFICATE-----"; - -// const TIMEOUT: Duration = Duration::from_secs(60); -// const SLEEP: Duration = Duration::from_secs(1); -// const SLEEP_COUNT: Duration = Duration::from_millis(10); - -// const MSG_COUNT: usize = 1_000; -// const MSG_SIZE_ALL: [usize; 2] = [1_024, 131_072]; -// const MSG_SIZE_NOFRAG: [usize; 1] = [1_024]; - -// macro_rules! ztimeout { -// ($f:expr) => { -// $f.timeout(TIMEOUT).await.unwrap() -// }; -// } - -// // Transport Handler for the router -// struct SHRouter { -// count: Arc, -// } - -// impl Default for SHRouter { -// fn default() -> Self { -// Self { -// count: Arc::new(AtomicUsize::new(0)), -// } -// } -// } - -// impl SHRouter { -// fn get_count(&self) -> usize { -// self.count.load(Ordering::SeqCst) -// } -// } - -// impl TransportEventHandler for SHRouter { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// let arc = Arc::new(SCRouter::new(self.count.clone())); -// Ok(arc) -// } -// } - -// // Transport Callback for the router -// pub struct SCRouter { -// count: Arc, -// } - -// impl SCRouter { -// pub fn new(count: Arc) -> Self { -// Self { count } -// } -// } - -// impl TransportPeerEventHandler for SCRouter { -// fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { -// self.count.fetch_add(1, Ordering::SeqCst); -// Ok(()) -// } - -// fn new_link(&self, _link: Link) {} -// fn del_link(&self, _link: Link) {} -// fn closing(&self) {} -// fn closed(&self) {} - -// fn as_any(&self) -> &dyn Any { -// self -// } -// } - -// // Transport Handler for the client -// #[derive(Default)] -// struct SHClient; - -// impl TransportEventHandler for SHClient { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// Ok(Arc::new(SCClient::default())) -// } -// } - -// // Transport Callback for the client -// #[derive(Default)] -// pub struct SCClient; - -// impl TransportPeerEventHandler for SCClient { -// fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { -// Ok(()) -// } - -// fn new_link(&self, _link: Link) {} -// fn del_link(&self, _link: Link) {} -// fn closing(&self) {} -// fn closed(&self) {} - -// fn as_any(&self) -> &dyn Any { -// self -// } -// } - -// async fn open_transport( -// client_endpoints: &[EndPoint], -// server_endpoints: &[EndPoint], -// ) -> ( -// TransportManager, -// Arc, -// TransportManager, -// TransportUnicast, -// ) { -// // Define client and router IDs -// let client_id = ZenohId::try_from([1]).unwrap(); -// let router_id = ZenohId::try_from([2]).unwrap(); - -// // Create the router transport manager -// let router_handler = Arc::new(SHRouter::default()); -// let unicast = TransportManager::config_unicast().max_links(server_endpoints.len()); - -// let router_manager = TransportManager::builder() -// .zid(router_id) -// .whatami(WhatAmI::Router) -// .unicast(unicast) -// .build(router_handler.clone()) -// .unwrap(); - -// // Create the listener on the router -// for e in server_endpoints.iter() { -// println!("Add endpoint: {}", e); -// let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); -// } - -// // Create the client transport manager -// let unicast = TransportManager::config_unicast().max_links(client_endpoints.len()); -// let client_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client_id) -// .unicast(unicast) -// .build(Arc::new(SHClient::default())) -// .unwrap(); - -// // Create an empty transport with the client -// // Open transport -> This should be accepted -// for e in client_endpoints.iter() { -// println!("Opening transport with {}", e); -// let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); -// } - -// let client_transport = client_manager.get_transport(&router_id).unwrap(); - -// // Return the handlers -// ( -// router_manager, -// router_handler, -// client_manager, -// client_transport, -// ) -// } - -// async fn close_transport( -// router_manager: TransportManager, -// client_manager: TransportManager, -// client_transport: TransportUnicast, -// endpoints: &[EndPoint], -// ) { -// // Close the client transport -// let mut ee = String::new(); -// for e in endpoints.iter() { -// let _ = write!(ee, "{e} "); -// } -// println!("Closing transport with {}", ee); -// ztimeout!(client_transport.close()).unwrap(); - -// ztimeout!(async { -// while !router_manager.get_transports().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// // Stop the locators on the manager -// for e in endpoints.iter() { -// println!("Del locator: {}", e); -// ztimeout!(router_manager.del_listener(e)).unwrap(); -// } - -// ztimeout!(async { -// while !router_manager.get_listeners().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// // Wait a little bit -// task::sleep(SLEEP).await; - -// ztimeout!(router_manager.close()); -// ztimeout!(client_manager.close()); - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } - -// async fn test_transport( -// router_handler: Arc, -// client_transport: TransportUnicast, -// channel: Channel, -// msg_size: usize, -// ) { -// // Create the message to send -// let key = "test".into(); -// let payload = ZBuf::from(vec![0_u8; msg_size]); -// let data_info = None; -// let routing_context = None; -// let reply_context = None; -// let message = ZenohMessage::make_data( -// key, -// payload, -// channel, -// CongestionControl::Block, -// data_info, -// routing_context, -// reply_context, -// ); - -// println!( -// "Sending {} messages... {:?} {}", -// MSG_COUNT, channel, msg_size -// ); -// for _ in 0..MSG_COUNT { -// client_transport.schedule(message.clone()).unwrap(); -// } - -// match channel.reliability { -// Reliability::Reliable => { -// ztimeout!(async { -// while router_handler.get_count() != MSG_COUNT { -// task::sleep(SLEEP_COUNT).await; -// } -// }); -// } -// Reliability::BestEffort => { -// ztimeout!(async { -// while router_handler.get_count() == 0 { -// task::sleep(SLEEP_COUNT).await; -// } -// }); -// } -// }; - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } - -// async fn run_single( -// client_endpoints: &[EndPoint], -// server_endpoints: &[EndPoint], -// channel: Channel, -// msg_size: usize, -// ) { -// println!( -// "\n>>> Running test for: {:?}, {:?}, {:?}, {}", -// client_endpoints, server_endpoints, channel, msg_size -// ); - -// #[allow(unused_variables)] // Used when stats feature is enabled -// let (router_manager, router_handler, client_manager, client_transport) = -// open_transport(client_endpoints, server_endpoints).await; - -// test_transport( -// router_handler.clone(), -// client_transport.clone(), -// channel, -// msg_size, -// ) -// .await; - -// #[cfg(feature = "stats")] -// { -// let c_stats = client_transport.get_stats().unwrap(); -// println!("\tClient: {:?}", c_stats); -// let r_stats = router_manager -// .get_transport_unicast(&client_manager.config.zid) -// .unwrap() -// .get_stats() -// .unwrap(); -// println!("\tRouter: {:?}", r_stats); -// } - -// close_transport( -// router_manager, -// client_manager, -// client_transport, -// client_endpoints, -// ) -// .await; -// } - -// async fn run( -// client_endpoints: &[EndPoint], -// server_endpoints: &[EndPoint], -// channel: &[Channel], -// msg_size: &[usize], -// ) { -// for ch in channel.iter() { -// for ms in msg_size.iter() { -// run_single(client_endpoints, server_endpoints, *ch, *ms).await; -// } -// } -// } - -// #[cfg(feature = "transport_tcp")] -// #[test] -// fn transport_unicast_tcp_only() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// // Define the locators -// let endpoints: Vec = vec![ -// format!("tcp/127.0.0.1:{}", 16000).parse().unwrap(), -// format!("tcp/[::1]:{}", 16001).parse().unwrap(), -// ]; -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -// } - -// #[cfg(feature = "transport_udp")] -// #[test] -// fn transport_unicast_udp_only() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// // Define the locator -// let endpoints: Vec = vec![ -// format!("udp/127.0.0.1:{}", 16010).parse().unwrap(), -// format!("udp/[::1]:{}", 16011).parse().unwrap(), -// ]; -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); -// } - -// #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] -// #[test] -// fn transport_unicast_unix_only() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let f1 = "zenoh-test-unix-socket-5.sock"; -// let _ = std::fs::remove_file(f1); -// // Define the locator -// let endpoints: Vec = vec![format!("unixsock-stream/{f1}").parse().unwrap()]; -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -// let _ = std::fs::remove_file(f1); -// let _ = std::fs::remove_file(format!("{f1}.lock")); -// } - -// #[cfg(feature = "transport_ws")] -// #[test] -// fn transport_unicast_ws_only() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// // Define the locators -// let endpoints: Vec = vec![ -// format!("ws/127.0.0.1:{}", 16020).parse().unwrap(), -// format!("ws/[::1]:{}", 16021).parse().unwrap(), -// ]; -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -// } - -// #[cfg(all(feature = "transport_tcp", feature = "transport_udp"))] -// #[test] -// fn transport_unicast_tcp_udp() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// // Define the locator -// let endpoints: Vec = vec![ -// format!("tcp/127.0.0.1:{}", 16030).parse().unwrap(), -// format!("udp/127.0.0.1:{}", 16031).parse().unwrap(), -// format!("tcp/[::1]:{}", 16032).parse().unwrap(), -// format!("udp/[::1]:{}", 16033).parse().unwrap(), -// ]; -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); -// } - -// #[cfg(all( -// feature = "transport_tcp", -// feature = "transport_unixsock-stream", -// target_family = "unix" -// ))] -// #[test] -// fn transport_unicast_tcp_unix() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let f1 = "zenoh-test-unix-socket-6.sock"; -// let _ = std::fs::remove_file(f1); -// // Define the locator -// let endpoints: Vec = vec![ -// format!("tcp/127.0.0.1:{}", 16040).parse().unwrap(), -// format!("tcp/[::1]:{}", 16041).parse().unwrap(), -// format!("unixsock-stream/{f1}").parse().unwrap(), -// ]; -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -// let _ = std::fs::remove_file(f1); -// let _ = std::fs::remove_file(format!("{f1}.lock")); -// } - -// #[cfg(all( -// feature = "transport_udp", -// feature = "transport_unixsock-stream", -// target_family = "unix" -// ))] -// #[test] -// fn transport_unicast_udp_unix() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let f1 = "zenoh-test-unix-socket-7.sock"; -// let _ = std::fs::remove_file(f1); -// // Define the locator -// let endpoints: Vec = vec![ -// format!("udp/127.0.0.1:{}", 16050).parse().unwrap(), -// format!("udp/[::1]:{}", 16051).parse().unwrap(), -// format!("unixsock-stream/{f1}").parse().unwrap(), -// ]; -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); -// let _ = std::fs::remove_file(f1); -// let _ = std::fs::remove_file(format!("{f1}.lock")); -// } - -// #[cfg(all( -// feature = "transport_tcp", -// feature = "transport_udp", -// feature = "transport_unixsock-stream", -// target_family = "unix" -// ))] -// #[test] -// fn transport_unicast_tcp_udp_unix() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let f1 = "zenoh-test-unix-socket-8.sock"; -// let _ = std::fs::remove_file(f1); -// // Define the locator -// let endpoints: Vec = vec![ -// format!("tcp/127.0.0.1:{}", 16060).parse().unwrap(), -// format!("udp/127.0.0.1:{}", 16061).parse().unwrap(), -// format!("tcp/[::1]:{}", 16062).parse().unwrap(), -// format!("udp/[::1]:{}", 16063).parse().unwrap(), -// format!("unixsock-stream/{f1}").parse().unwrap(), -// ]; -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); -// let _ = std::fs::remove_file(f1); -// let _ = std::fs::remove_file(format!("{f1}.lock")); -// } - -// #[cfg(all(feature = "transport_tls", target_family = "unix"))] -// #[test] -// fn transport_unicast_tls_only_server() { -// use zenoh_link::tls::config::*; - -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// // Define the locator -// let mut endpoint: EndPoint = format!("tls/localhost:{}", 16070).parse().unwrap(); -// endpoint -// .config_mut() -// .extend( -// [ -// (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), -// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), -// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), -// ] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); - -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// let endpoints = vec![endpoint]; -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -// } - -// #[cfg(feature = "transport_quic")] -// #[test] -// fn transport_unicast_quic_only_server() { -// use zenoh_link::quic::config::*; - -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// // Define the locator -// let mut endpoint: EndPoint = format!("quic/localhost:{}", 16080).parse().unwrap(); -// endpoint -// .config_mut() -// .extend( -// [ -// (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), -// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), -// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), -// ] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); - -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// let endpoints = vec![endpoint]; -// task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); -// } - -// #[cfg(all(feature = "transport_tls", target_family = "unix"))] -// #[test] -// fn transport_unicast_tls_only_mutual_success() { -// use zenoh_link::tls::config::*; - -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let client_auth = "true"; - -// // Define the locator -// let mut client_endpoint: EndPoint = ("tls/localhost:10461").parse().unwrap(); -// client_endpoint -// .config_mut() -// .extend( -// [ -// (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), -// (TLS_CLIENT_CERTIFICATE_RAW, CLIENT_CERT), -// (TLS_CLIENT_PRIVATE_KEY_RAW, CLIENT_KEY), -// (TLS_CLIENT_AUTH, client_auth), -// ] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); - -// // Define the locator -// let mut server_endpoint: EndPoint = ("tls/localhost:10461").parse().unwrap(); -// server_endpoint -// .config_mut() -// .extend( -// [ -// (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), -// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), -// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), -// (TLS_CLIENT_AUTH, client_auth), -// ] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// let client_endpoints = vec![client_endpoint]; -// let server_endpoints = vec![server_endpoint]; -// task::block_on(run( -// &client_endpoints, -// &server_endpoints, -// &channel, -// &MSG_SIZE_ALL, -// )); -// } - -// // Constants replicating the alert descriptions thrown by the Rustls library. -// // These alert descriptions are internal of the library and cannot be reached from these tests -// // as to do a proper comparison. For the sake of simplicity we verify these constants are contained -// // in the expected error messages from the tests below. -// // -// // See: https://docs.rs/rustls/latest/src/rustls/msgs/enums.rs.html#128 -// #[cfg(all(feature = "transport_tls", target_family = "unix"))] -// const RUSTLS_UNKNOWN_CA_ALERT_DESCRIPTION: &str = "UnknownCA"; -// #[cfg(all(feature = "transport_tls", target_family = "unix"))] -// const RUSTLS_CERTIFICATE_REQUIRED_ALERT_DESCRIPTION: &str = "CertificateRequired"; - -// #[cfg(all(feature = "transport_tls", target_family = "unix"))] -// #[test] -// fn transport_unicast_tls_only_mutual_no_client_certs_failure() { -// use std::vec; - -// use zenoh_link::tls::config::*; - -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// // Define the locator -// let mut client_endpoint: EndPoint = ("tls/localhost:10462").parse().unwrap(); -// client_endpoint -// .config_mut() -// .extend( -// [(TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA)] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); - -// // Define the locator -// let mut server_endpoint: EndPoint = ("tls/localhost:10462").parse().unwrap(); -// server_endpoint -// .config_mut() -// .extend( -// [ -// (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), -// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), -// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), -// (TLS_CLIENT_AUTH, "true"), -// ] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// let client_endpoints = vec![client_endpoint]; -// let server_endpoints = vec![server_endpoint]; -// let result = std::panic::catch_unwind(|| { -// task::block_on(run( -// &client_endpoints, -// &server_endpoints, -// &channel, -// &MSG_SIZE_ALL, -// )) -// }); -// assert!(result.is_err()); -// let err = result.unwrap_err(); -// let error_msg = panic_message::panic_message(&err); -// assert!(error_msg.contains(RUSTLS_CERTIFICATE_REQUIRED_ALERT_DESCRIPTION)); -// } - -// #[cfg(all(feature = "transport_tls", target_family = "unix"))] -// #[test] -// fn transport_unicast_tls_only_mutual_wrong_client_certs_failure() { -// use zenoh_link::tls::config::*; - -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let client_auth = "true"; - -// // Define the locator -// let mut client_endpoint: EndPoint = ("tls/localhost:10463").parse().unwrap(); -// client_endpoint -// .config_mut() -// .extend( -// [ -// (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), -// // Using the SERVER_CERT and SERVER_KEY in the client to simulate the case the client has -// // wrong certificates and keys. The SERVER_CA (cetificate authority) will not recognize -// // these certificates as it is expecting to receive CLIENT_CERT and CLIENT_KEY from the -// // client. -// (TLS_CLIENT_CERTIFICATE_RAW, SERVER_CERT), -// (TLS_CLIENT_PRIVATE_KEY_RAW, SERVER_KEY), -// (TLS_CLIENT_AUTH, client_auth), -// ] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); - -// // Define the locator -// let mut server_endpoint: EndPoint = ("tls/localhost:10463").parse().unwrap(); -// server_endpoint -// .config_mut() -// .extend( -// [ -// (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), -// (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), -// (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), -// (TLS_CLIENT_AUTH, client_auth), -// ] -// .iter() -// .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), -// ) -// .unwrap(); -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// let client_endpoints = vec![client_endpoint]; -// let server_endpoints = vec![server_endpoint]; -// let result = std::panic::catch_unwind(|| { -// task::block_on(run( -// &client_endpoints, -// &server_endpoints, -// &channel, -// &MSG_SIZE_ALL, -// )) -// }); -// assert!(result.is_err()); -// let err = result.unwrap_err(); -// let error_msg = panic_message::panic_message(&err); -// assert!(error_msg.contains(RUSTLS_UNKNOWN_CA_ALERT_DESCRIPTION)); -// } +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use async_std::{prelude::FutureExt, task}; +use std::fmt::Write as _; +use std::{ + any::Any, + convert::TryFrom, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, + time::Duration, +}; +use zenoh_core::zasync_executor_init; +use zenoh_link::Link; +use zenoh_protocol::{ + core::{ + Channel, CongestionControl, Encoding, EndPoint, Priority, Reliability, WhatAmI, ZenohId, + }, + network::{ + push::ext::{NodeIdType, QoSType}, + Mapping, NetworkMessage, Push, + }, + zenoh_new::Put, +}; +use zenoh_result::ZResult; +use zenoh_transport::{ + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, +}; + +// These keys and certificates below are purposedly generated to run TLS and mTLS tests. +// +// With 2 way authentication (mTLS), using TLS 1.3, we need two pairs of keys and certificates: one +// for the "server" and another one for the "client". +// +// The keys and certificates below were auto-generated using https://github.com/jsha/minica and +// target the localhost domain, so it has no real mapping to any existing domain. +// +// The keys and certificates generated map as follows to the constants below: +// +// certificates +// ├── client +// │ ├── localhost +// │ │ ├── cert.pem <------- CLIENT_CERT +// │ │ └── key.pem <-------- CLIENT_KEY +// │ ├── minica-key.pem +// │ └── minica.pem <--------- CLIENT_CA +// └── server +// ├── localhost +// │ ├── cert.pem <------- SERVER_CERT +// │ └── key.pem <-------- SERVER_KEY +// ├── minica-key.pem +// └── minica.pem <--------- SERVER_CA +// +// The way it works is that the client's certificate authority will validate in front of the server +// the key and certificate brought in by the client. Similarly the server's certificate authority +// will validate the key and certificate brought in by the server in front of the client. +// +#[cfg(all(feature = "transport_tls", target_family = "unix"))] +const CLIENT_KEY: &str = "-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi +qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy +aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU +cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha +Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr +Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 +2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 +lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU +WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX +Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI +9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak +r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn +qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY +CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu +fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj +4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih +XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 +38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT +Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV +jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R +5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H +n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm +qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD +tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v +F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== +-----END RSA PRIVATE KEY-----"; + +#[cfg(all(feature = "transport_tls", target_family = "unix"))] +const CLIENT_CERT: &str = "-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw +MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT +He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ +Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj +eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 +eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M +tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE +DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 +3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD +wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q +GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC +9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ +p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ +abY= +-----END CERTIFICATE-----"; + +#[cfg(all(feature = "transport_tls", target_family = "unix"))] +const CLIENT_CA: &str = "-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw +MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ +uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs +DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc +8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 +T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b +QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB +AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 +/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq +hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ +e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc +yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 +8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 +Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN +R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== +-----END CERTIFICATE-----"; + +#[cfg(any(feature = "transport_tls", feature = "transport_quic"))] +const SERVER_KEY: &str = "-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAmDCySqKHPmEZShDH3ldPaV/Zsh9+HlHFLk9H10vJZj5WfzVu +5puZQ8GvBFIOtVrl0L9qLkA6bZiHHXm/8OEVvd135ZMp4NV23fdTsEASXfvGVQY8 +y+4UkZN0Dw6sfwlQVPyNRplys2+nFs6tX05Dp9VizV39tSOqe/jd6hyzxSUHqFat +RwQRXAI04CZ6ckDb0Riw7i0yvjrFhBom9lPKq4IkXZGgS5MRl0pRgAZTqHEMlv8z +oX+KcG9mfyQIHtpkVuSHHsQjwVop7fMnT7KCQ3bPI+fgMmAg+h1IR19Dm0JM+9zl +u39j0IbkytrsystGM+pTRbdp7s2lgtOMCFt0+wIDAQABAoIBADNTSO2uvlmlOXgn +DKDJZTiuYKaXxFrJTOx/REUxg+x9XYJtLMeM9jVJnpKgceFrlFHAHDkY5BuN8xNX +ugmsfz6W8BZ2eQsgMoRNIuYv1YHopUyLW/mSg1FNHzjsw/Pb2kGvIp4Kpgopv3oL +naCkrmBtsHJ+Hk/2hUpl9cE8iMwVWcVevLzyHi98jNy1IDdIPhRtl0dhMiqC5MRr +4gLJ5gNkLYX7xf3tw5Hmfk/bVNProqZXDIQVI7rFvItX586nvQ3LNQkmW/D2ShZf +3FEqMu6EdA2Ycc4UZgAlQNGV0VBrWWVXizOQ+9gjLnBk3kJjqfigCU6NG94bTJ+H +0YIhsGECgYEAwdSSyuMSOXgzZQ7Vv+GsNn/7ivi/H8eb/lDzksqS/JroA2ciAmHG +2OF30eUJKRg+STqBTpOfXgS4QUa8QLSwBSnwcw6579x9bYGUhqD2Ypaw9uCnOukA +CwwggZ9cDmF0tb5rYjqkW3bFPqkCnTGb0ylMFaYRhRDU20iG5t8PQckCgYEAyQEM +KK18FLQUKivGrQgP5Ib6IC3myzlHGxDzfobXGpaQntFnHY7Cxp/6BBtmASzt9Jxu +etnrevmzrbKqsLTJSg3ivbiq0YTLAJ1FsZrCp71dx49YR/5o9QFiq0nQoKnwUVeb +/hrDjMAokNkjFL5vouXO711GSS6YyM4WzAKZAqMCgYEAhqGxaG06jmJ4SFx6ibIl +nSFeRhQrJNbP+mCeHrrIR98NArgS/laN+Lz7LfaJW1r0gIa7pCmTi4l5thV80vDu +RlfwJOr4qaucD4Du+mg5WxdSSdiXL6sBlarRtVdMaMy2dTqTegJDgShJLxHTt/3q +P0yzBWJ5TtT3FG0XDqum/EkCgYAYNHwWWe3bQGQ9P9BI/fOL/YUZYu2sA1XAuKXZ +0rsMhJ0dwvG76XkjGhitbe82rQZqsnvLZ3qn8HHmtOFBLkQfGtT3K8nGOUuI42eF +H7HZKUCly2lCIizZdDVBkz4AWvaJlRc/3lE2Hd3Es6E52kTvROVKhdz06xuS8t5j +6twqKQKBgQC01AeiWL6Rzo+yZNzVgbpeeDogaZz5dtmURDgCYH8yFX5eoCKLHfnI +2nDIoqpaHY0LuX+dinuH+jP4tlyndbc2muXnHd9r0atytxA69ay3sSA5WFtfi4ef +ESElGO6qXEA821RpQp+2+uhL90+iC294cPqlS5LDmvTMypVDHzrxPQ== +-----END RSA PRIVATE KEY-----"; + +#[cfg(any(feature = "transport_tls", feature = "transport_quic"))] +const SERVER_CERT: &str = "-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIIW1mAtJWJAJYwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw +MzA2MTY0MTA2WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCYMLJKooc+YRlKEMfeV09pX9myH34eUcUuT0fXS8lm +PlZ/NW7mm5lDwa8EUg61WuXQv2ouQDptmIcdeb/w4RW93Xflkyng1Xbd91OwQBJd ++8ZVBjzL7hSRk3QPDqx/CVBU/I1GmXKzb6cWzq1fTkOn1WLNXf21I6p7+N3qHLPF +JQeoVq1HBBFcAjTgJnpyQNvRGLDuLTK+OsWEGib2U8qrgiRdkaBLkxGXSlGABlOo +cQyW/zOhf4pwb2Z/JAge2mRW5IcexCPBWint8ydPsoJDds8j5+AyYCD6HUhHX0Ob +Qkz73OW7f2PQhuTK2uzKy0Yz6lNFt2nuzaWC04wIW3T7AgMBAAGjdjB0MA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDAUBgNVHREE +DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAAxrmQPG54ybKgMVliN8 +Mg5povSdPIVVnlU/HOVG9yxzAOav/xQP003M4wqpatWxI8tR1PcLuZf0EPmcdJgb +tVl9nZMVZtveQnYMlU8PpkEVu56VM4Zr3rH9liPRlr0JEAXODdKw76kWKzmdqWZ/ +rzhup3Ek7iEX6T5j/cPUvTWtMD4VEK2I7fgoKSHIX8MIVzqM7cuboGWPtS3eRNXl +MgvahA4TwLEXPEe+V1WAq6nSb4g2qSXWIDpIsy/O1WGS/zzRnKvXu9/9NkXWqZMl +C1LSpiiQUaRSglOvYf/Zx6r+4BOS4OaaArwHkecZQqBSCcBLEAyb/FaaXdBowI0U +PQ4= +-----END CERTIFICATE-----"; + +#[cfg(any(feature = "transport_tls", feature = "transport_quic"))] +const SERVER_CA: &str = "-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIITcwv1N10nqEwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw +MzA2MTY0MTA2WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSA0ZGNjMmYwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2WUgN7NMlXIknew1cXiTWGmS0 +1T1EjcNNDAq7DqZ7/ZVXrjD47yxTt5EOiOXK/cINKNw4Zq/MKQvq9qu+Oax4lwiV +Ha0i8ShGLSuYI1HBlXu4MmvdG+3/SjwYoGsGaShr0y/QGzD3cD+DQZg/RaaIPHlO +MdmiUXxkMcy4qa0hFJ1imlJdq/6Tlx46X+0vRCh8nkekvOZR+t7Z5U4jn4XE54Kl +0PiwcyX8vfDZ3epa/FSHZvVQieM/g5Yh9OjIKCkdWRg7tD0IEGsaW11tEPJ5SiQr +mDqdRneMzZKqY0xC+QqXSvIlzpOjiu8PYQx7xugaUFE/npKRQdvh8ojHJMdNAgMB +AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTX46+p+Po1npE6 +QLQ7mMI+83s6qDAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDANBgkq +hkiG9w0BAQsFAAOCAQEAaN0IvEC677PL/JXzMrXcyBV88IvimlYN0zCt48GYlhmx +vL1YUDFLJEB7J+dyERGE5N6BKKDGblC4WiTFgDMLcHFsMGRc0v7zKPF1PSBwRYJi +ubAmkwdunGG5pDPUYtTEDPXMlgClZ0YyqSFJMOqA4IzQg6exVjXtUxPqzxNhyC7S +vlgUwPbX46uNi581a9+Ls2V3fg0ZnhkTSctYZHGZNeh0Nsf7Am8xdUDYG/bZcVef +jbQ9gpChosdjF0Bgblo7HSUct/2Va+YlYwW+WFjJX8k4oN6ZU5W5xhdfO8Czmgwk +US5kJ/+1M0uR8zUhZHL61FbsdPxEj+fYKrHv4woo+A== +-----END CERTIFICATE-----"; + +const TIMEOUT: Duration = Duration::from_secs(60); +const SLEEP: Duration = Duration::from_secs(1); +const SLEEP_COUNT: Duration = Duration::from_millis(10); + +const MSG_COUNT: usize = 1_000; +const MSG_SIZE_ALL: [usize; 2] = [1_024, 131_072]; +const MSG_SIZE_NOFRAG: [usize; 1] = [1_024]; + +macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; +} + +// Transport Handler for the router +struct SHRouter { + count: Arc, +} + +impl Default for SHRouter { + fn default() -> Self { + Self { + count: Arc::new(AtomicUsize::new(0)), + } + } +} + +impl SHRouter { + fn get_count(&self) -> usize { + self.count.load(Ordering::SeqCst) + } +} + +impl TransportEventHandler for SHRouter { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + let arc = Arc::new(SCRouter::new(self.count.clone())); + Ok(arc) + } +} + +// Transport Callback for the router +pub struct SCRouter { + count: Arc, +} + +impl SCRouter { + pub fn new(count: Arc) -> Self { + Self { count } + } +} + +impl TransportPeerEventHandler for SCRouter { + fn handle_message(&self, _message: NetworkMessage) -> ZResult<()> { + self.count.fetch_add(1, Ordering::SeqCst); + Ok(()) + } + + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } +} + +// Transport Handler for the client +#[derive(Default)] +struct SHClient; + +impl TransportEventHandler for SHClient { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + Ok(Arc::new(SCClient::default())) + } +} + +// Transport Callback for the client +#[derive(Default)] +pub struct SCClient; + +impl TransportPeerEventHandler for SCClient { + fn handle_message(&self, _message: NetworkMessage) -> ZResult<()> { + Ok(()) + } + + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } +} + +async fn open_transport( + client_endpoints: &[EndPoint], + server_endpoints: &[EndPoint], +) -> ( + TransportManager, + Arc, + TransportManager, + TransportUnicast, +) { + // Define client and router IDs + let client_id = ZenohId::try_from([1]).unwrap(); + let router_id = ZenohId::try_from([2]).unwrap(); + + // Create the router transport manager + let router_handler = Arc::new(SHRouter::default()); + let unicast = TransportManager::config_unicast().max_links(server_endpoints.len()); + + let router_manager = TransportManager::builder() + .zid(router_id) + .whatami(WhatAmI::Router) + .unicast(unicast) + .build(router_handler.clone()) + .unwrap(); + + // Create the listener on the router + for e in server_endpoints.iter() { + println!("Add endpoint: {}", e); + let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); + } + + // Create the client transport manager + let unicast = TransportManager::config_unicast().max_links(client_endpoints.len()); + let client_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client_id) + .unicast(unicast) + .build(Arc::new(SHClient::default())) + .unwrap(); + + // Create an empty transport with the client + // Open transport -> This should be accepted + for e in client_endpoints.iter() { + println!("Opening transport with {}", e); + let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); + } + + let client_transport = client_manager.get_transport(&router_id).unwrap(); + + // Return the handlers + ( + router_manager, + router_handler, + client_manager, + client_transport, + ) +} + +async fn close_transport( + router_manager: TransportManager, + client_manager: TransportManager, + client_transport: TransportUnicast, + endpoints: &[EndPoint], +) { + // Close the client transport + let mut ee = String::new(); + for e in endpoints.iter() { + let _ = write!(ee, "{e} "); + } + println!("Closing transport with {}", ee); + ztimeout!(client_transport.close()).unwrap(); + + ztimeout!(async { + while !router_manager.get_transports().is_empty() { + task::sleep(SLEEP).await; + } + }); + + // Stop the locators on the manager + for e in endpoints.iter() { + println!("Del locator: {}", e); + ztimeout!(router_manager.del_listener(e)).unwrap(); + } + + ztimeout!(async { + while !router_manager.get_listeners().is_empty() { + task::sleep(SLEEP).await; + } + }); + + // Wait a little bit + task::sleep(SLEEP).await; + + ztimeout!(router_manager.close()); + ztimeout!(client_manager.close()); + + // Wait a little bit + task::sleep(SLEEP).await; +} + +async fn test_transport( + router_handler: Arc, + client_transport: TransportUnicast, + channel: Channel, + msg_size: usize, +) { + println!( + "Sending {} messages... {:?} {}", + MSG_COUNT, channel, msg_size + ); + let cctrl = match channel.reliability { + Reliability::Reliable => CongestionControl::Block, + Reliability::BestEffort => CongestionControl::Drop, + }; + // Create the message to send + let message: NetworkMessage = Push { + wire_expr: "test".into(), + mapping: Mapping::Sender, + ext_qos: QoSType::new(channel.priority, cctrl, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: vec![0u8; msg_size].into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + for _ in 0..MSG_COUNT { + client_transport.schedule(message.clone()).unwrap(); + // print!("S-{i} "); + use std::io::Write; + std::io::stdout().flush().unwrap(); + } + + match channel.reliability { + Reliability::Reliable => { + ztimeout!(async { + while router_handler.get_count() != MSG_COUNT { + task::sleep(SLEEP_COUNT).await; + } + }); + } + Reliability::BestEffort => { + ztimeout!(async { + while router_handler.get_count() == 0 { + task::sleep(SLEEP_COUNT).await; + } + }); + } + }; + + // Wait a little bit + task::sleep(SLEEP).await; +} + +async fn run_single( + client_endpoints: &[EndPoint], + server_endpoints: &[EndPoint], + channel: Channel, + msg_size: usize, +) { + println!( + "\n>>> Running test for: {:?}, {:?}, {:?}, {}", + client_endpoints, server_endpoints, channel, msg_size + ); + + #[allow(unused_variables)] // Used when stats feature is enabled + let (router_manager, router_handler, client_manager, client_transport) = + open_transport(client_endpoints, server_endpoints).await; + + test_transport( + router_handler.clone(), + client_transport.clone(), + channel, + msg_size, + ) + .await; + + #[cfg(feature = "stats")] + { + let c_stats = client_transport.get_stats().unwrap(); + println!("\tClient: {:?}", c_stats); + let r_stats = router_manager + .get_transport_unicast(&client_manager.config.zid) + .unwrap() + .get_stats() + .unwrap(); + println!("\tRouter: {:?}", r_stats); + } + + close_transport( + router_manager, + client_manager, + client_transport, + client_endpoints, + ) + .await; +} + +async fn run( + client_endpoints: &[EndPoint], + server_endpoints: &[EndPoint], + channel: &[Channel], + msg_size: &[usize], +) { + for ch in channel.iter() { + for ms in msg_size.iter() { + run_single(client_endpoints, server_endpoints, *ch, *ms).await; + } + } +} + +#[cfg(feature = "transport_tcp")] +#[test] +fn transport_unicast_tcp_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoints: Vec = vec![ + format!("tcp/127.0.0.1:{}", 16000).parse().unwrap(), + format!("tcp/[::1]:{}", 16001).parse().unwrap(), + ]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + // Channel { + // priority: Priority::default(), + // reliability: Reliability::BestEffort, + // }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + // Channel { + // priority: Priority::RealTime, + // reliability: Reliability::BestEffort, + // }, + ]; + // Run + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +} + +#[cfg(feature = "transport_udp")] +#[test] +fn transport_unicast_udp_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locator + let endpoints: Vec = vec![ + format!("udp/127.0.0.1:{}", 16010).parse().unwrap(), + format!("udp/[::1]:{}", 16011).parse().unwrap(), + ]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); +} + +#[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] +#[test] +fn transport_unicast_unix_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let f1 = "zenoh-test-unix-socket-5.sock"; + let _ = std::fs::remove_file(f1); + // Define the locator + let endpoints: Vec = vec![format!("unixsock-stream/{f1}").parse().unwrap()]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); + let _ = std::fs::remove_file(f1); + let _ = std::fs::remove_file(format!("{f1}.lock")); +} + +#[cfg(feature = "transport_ws")] +#[test] +fn transport_unicast_ws_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoints: Vec = vec![ + format!("ws/127.0.0.1:{}", 16020).parse().unwrap(), + format!("ws/[::1]:{}", 16021).parse().unwrap(), + ]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +} + +#[cfg(all(feature = "transport_tcp", feature = "transport_udp"))] +#[test] +fn transport_unicast_tcp_udp() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locator + let endpoints: Vec = vec![ + format!("tcp/127.0.0.1:{}", 16030).parse().unwrap(), + format!("udp/127.0.0.1:{}", 16031).parse().unwrap(), + format!("tcp/[::1]:{}", 16032).parse().unwrap(), + format!("udp/[::1]:{}", 16033).parse().unwrap(), + ]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); +} + +#[cfg(all( + feature = "transport_tcp", + feature = "transport_unixsock-stream", + target_family = "unix" +))] +#[test] +fn transport_unicast_tcp_unix() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let f1 = "zenoh-test-unix-socket-6.sock"; + let _ = std::fs::remove_file(f1); + // Define the locator + let endpoints: Vec = vec![ + format!("tcp/127.0.0.1:{}", 16040).parse().unwrap(), + format!("tcp/[::1]:{}", 16041).parse().unwrap(), + format!("unixsock-stream/{f1}").parse().unwrap(), + ]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); + let _ = std::fs::remove_file(f1); + let _ = std::fs::remove_file(format!("{f1}.lock")); +} + +#[cfg(all( + feature = "transport_udp", + feature = "transport_unixsock-stream", + target_family = "unix" +))] +#[test] +fn transport_unicast_udp_unix() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let f1 = "zenoh-test-unix-socket-7.sock"; + let _ = std::fs::remove_file(f1); + // Define the locator + let endpoints: Vec = vec![ + format!("udp/127.0.0.1:{}", 16050).parse().unwrap(), + format!("udp/[::1]:{}", 16051).parse().unwrap(), + format!("unixsock-stream/{f1}").parse().unwrap(), + ]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); + let _ = std::fs::remove_file(f1); + let _ = std::fs::remove_file(format!("{f1}.lock")); +} + +#[cfg(all( + feature = "transport_tcp", + feature = "transport_udp", + feature = "transport_unixsock-stream", + target_family = "unix" +))] +#[test] +fn transport_unicast_tcp_udp_unix() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let f1 = "zenoh-test-unix-socket-8.sock"; + let _ = std::fs::remove_file(f1); + // Define the locator + let endpoints: Vec = vec![ + format!("tcp/127.0.0.1:{}", 16060).parse().unwrap(), + format!("udp/127.0.0.1:{}", 16061).parse().unwrap(), + format!("tcp/[::1]:{}", 16062).parse().unwrap(), + format!("udp/[::1]:{}", 16063).parse().unwrap(), + format!("unixsock-stream/{f1}").parse().unwrap(), + ]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); + let _ = std::fs::remove_file(f1); + let _ = std::fs::remove_file(format!("{f1}.lock")); +} + +#[cfg(all(feature = "transport_tls", target_family = "unix"))] +#[test] +fn transport_unicast_tls_only_server() { + use zenoh_link::tls::config::*; + + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locator + let mut endpoint: EndPoint = format!("tls/localhost:{}", 16070).parse().unwrap(); + endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), + (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), + (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + let endpoints = vec![endpoint]; + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +} + +#[cfg(feature = "transport_quic")] +#[test] +fn transport_unicast_quic_only_server() { + use zenoh_link::quic::config::*; + + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locator + let mut endpoint: EndPoint = format!("quic/localhost:{}", 16080).parse().unwrap(); + endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), + (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), + (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + let endpoints = vec![endpoint]; + task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); +} + +#[cfg(all(feature = "transport_tls", target_family = "unix"))] +#[test] +fn transport_unicast_tls_only_mutual_success() { + use zenoh_link::tls::config::*; + + task::block_on(async { + zasync_executor_init!(); + }); + + let client_auth = "true"; + + // Define the locator + let mut client_endpoint: EndPoint = ("tls/localhost:10461").parse().unwrap(); + client_endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), + (TLS_CLIENT_CERTIFICATE_RAW, CLIENT_CERT), + (TLS_CLIENT_PRIVATE_KEY_RAW, CLIENT_KEY), + (TLS_CLIENT_AUTH, client_auth), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + + // Define the locator + let mut server_endpoint: EndPoint = ("tls/localhost:10461").parse().unwrap(); + server_endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), + (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), + (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), + (TLS_CLIENT_AUTH, client_auth), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + let client_endpoints = vec![client_endpoint]; + let server_endpoints = vec![server_endpoint]; + task::block_on(run( + &client_endpoints, + &server_endpoints, + &channel, + &MSG_SIZE_ALL, + )); +} + +// Constants replicating the alert descriptions thrown by the Rustls library. +// These alert descriptions are internal of the library and cannot be reached from these tests +// as to do a proper comparison. For the sake of simplicity we verify these constants are contained +// in the expected error messages from the tests below. +// +// See: https://docs.rs/rustls/latest/src/rustls/msgs/enums.rs.html#128 +#[cfg(all(feature = "transport_tls", target_family = "unix"))] +const RUSTLS_UNKNOWN_CA_ALERT_DESCRIPTION: &str = "UnknownCA"; +#[cfg(all(feature = "transport_tls", target_family = "unix"))] +const RUSTLS_CERTIFICATE_REQUIRED_ALERT_DESCRIPTION: &str = "CertificateRequired"; + +#[cfg(all(feature = "transport_tls", target_family = "unix"))] +#[test] +fn transport_unicast_tls_only_mutual_no_client_certs_failure() { + use std::vec; + + use zenoh_link::tls::config::*; + + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locator + let mut client_endpoint: EndPoint = ("tls/localhost:10462").parse().unwrap(); + client_endpoint + .config_mut() + .extend( + [(TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA)] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + + // Define the locator + let mut server_endpoint: EndPoint = ("tls/localhost:10462").parse().unwrap(); + server_endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), + (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), + (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), + (TLS_CLIENT_AUTH, "true"), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + let client_endpoints = vec![client_endpoint]; + let server_endpoints = vec![server_endpoint]; + let result = std::panic::catch_unwind(|| { + task::block_on(run( + &client_endpoints, + &server_endpoints, + &channel, + &MSG_SIZE_ALL, + )) + }); + assert!(result.is_err()); + let err = result.unwrap_err(); + let error_msg = panic_message::panic_message(&err); + assert!(error_msg.contains(RUSTLS_CERTIFICATE_REQUIRED_ALERT_DESCRIPTION)); +} + +#[cfg(all(feature = "transport_tls", target_family = "unix"))] +#[test] +fn transport_unicast_tls_only_mutual_wrong_client_certs_failure() { + use zenoh_link::tls::config::*; + + task::block_on(async { + zasync_executor_init!(); + }); + + let client_auth = "true"; + + // Define the locator + let mut client_endpoint: EndPoint = ("tls/localhost:10463").parse().unwrap(); + client_endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, SERVER_CA), + // Using the SERVER_CERT and SERVER_KEY in the client to simulate the case the client has + // wrong certificates and keys. The SERVER_CA (cetificate authority) will not recognize + // these certificates as it is expecting to receive CLIENT_CERT and CLIENT_KEY from the + // client. + (TLS_CLIENT_CERTIFICATE_RAW, SERVER_CERT), + (TLS_CLIENT_PRIVATE_KEY_RAW, SERVER_KEY), + (TLS_CLIENT_AUTH, client_auth), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + + // Define the locator + let mut server_endpoint: EndPoint = ("tls/localhost:10463").parse().unwrap(); + server_endpoint + .config_mut() + .extend( + [ + (TLS_ROOT_CA_CERTIFICATE_RAW, CLIENT_CA), + (TLS_SERVER_CERTIFICATE_RAW, SERVER_CERT), + (TLS_SERVER_PRIVATE_KEY_RAW, SERVER_KEY), + (TLS_CLIENT_AUTH, client_auth), + ] + .iter() + .map(|(k, v)| ((*k).to_owned(), (*v).to_owned())), + ) + .unwrap(); + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + let client_endpoints = vec![client_endpoint]; + let server_endpoints = vec![server_endpoint]; + let result = std::panic::catch_unwind(|| { + task::block_on(run( + &client_endpoints, + &server_endpoints, + &channel, + &MSG_SIZE_ALL, + )) + }); + assert!(result.is_err()); + let err = result.unwrap_err(); + let error_msg = panic_message::panic_message(&err); + assert!(error_msg.contains(RUSTLS_UNKNOWN_CA_ALERT_DESCRIPTION)); +} From c59c0626ccc2789149a549b75e60b56cdbfba148 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 3 Jul 2023 16:53:03 +0200 Subject: [PATCH 155/203] Fix unicast_transport test --- io/zenoh-transport/tests/unicast_transport.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 000eb3f2a7..249e8736ce 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -30,7 +30,7 @@ use zenoh_protocol::{ }, network::{ push::ext::{NodeIdType, QoSType}, - Mapping, NetworkMessage, Push, + NetworkMessage, Push, }, zenoh_new::Put, }; @@ -434,7 +434,6 @@ async fn test_transport( // Create the message to send let message: NetworkMessage = Push { wire_expr: "test".into(), - mapping: Mapping::Sender, ext_qos: QoSType::new(channel.priority, cctrl, false), ext_tstamp: None, ext_nodeid: NodeIdType::default(), From 366b558a4920434d4feb03fdad6e520658b0c023 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 3 Jul 2023 17:26:15 +0200 Subject: [PATCH 156/203] Merge master into new-protocol --- zenoh/tests/routing.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/zenoh/tests/routing.rs b/zenoh/tests/routing.rs index 972893b194..ad8ea1d05a 100644 --- a/zenoh/tests/routing.rs +++ b/zenoh/tests/routing.rs @@ -18,12 +18,11 @@ use std::str::FromStr; use std::sync::atomic::Ordering; use std::sync::{atomic::AtomicUsize, Arc}; use std::time::Duration; -use zenoh::config::{whatami::WhatAmI, Config}; +use zenoh::config::{Config, ModeDependentValue}; use zenoh::prelude::r#async::*; use zenoh::{value::Value, Result}; -use zenoh_config::whatami::WhatAmIMatcher; -use zenoh_config::ModeDependentValue; use zenoh_core::zasync_executor_init; +use zenoh_protocol::core::{WhatAmI, WhatAmIMatcher}; use zenoh_result::{bail, zerror}; const TIMEOUT: Duration = Duration::from_secs(360); From 3845d54b1ff274b9fbb71e4d71b08869ab223c3f Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 3 Jul 2023 17:37:20 +0200 Subject: [PATCH 157/203] Re-enabling unicast_concurrent tests --- .../tests/unicast_concurrent.rs | 788 +++++++++--------- 1 file changed, 392 insertions(+), 396 deletions(-) diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index 20784cdda5..42caa7e39f 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -1,4 +1,3 @@ -// // Copyright (c) 2023 ZettaScale Technology // // This program and the accompanying materials are made available under the @@ -11,398 +10,395 @@ // Contributors: // ZettaScale Zenoh Team, // -// use async_std::prelude::FutureExt; -// use async_std::sync::Barrier; -// use async_std::task; -// use std::any::Any; -// use std::convert::TryFrom; -// use std::sync::atomic::{AtomicUsize, Ordering}; -// use std::sync::Arc; -// use std::time::Duration; -// use zenoh_buffers::ZBuf; -// use zenoh_core::zasync_executor_init; -// use zenoh_link::Link; -// use zenoh_protocol::{ -// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, -// zenoh::ZenohMessage, -// }; -// use zenoh_result::ZResult; -// use zenoh_transport::{ -// TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, -// TransportUnicast, -// }; - -// const MSG_COUNT: usize = 1_000; -// const MSG_SIZE: usize = 1_024; -// const TIMEOUT: Duration = Duration::from_secs(60); -// const SLEEP: Duration = Duration::from_millis(100); - -// macro_rules! ztimeout { -// ($f:expr) => { -// $f.timeout(TIMEOUT).await.unwrap() -// }; -// } - -// // Transport Handler for the router -// struct SHPeer { -// count: Arc, -// } - -// impl SHPeer { -// fn new() -> Self { -// Self { -// count: Arc::new(AtomicUsize::new(0)), -// } -// } - -// fn get_count(&self) -> usize { -// self.count.load(Ordering::SeqCst) -// } -// } - -// impl TransportEventHandler for SHPeer { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// let mh = Arc::new(MHPeer::new(self.count.clone())); -// Ok(mh) -// } -// } - -// struct MHPeer { -// count: Arc, -// } - -// impl MHPeer { -// fn new(count: Arc) -> Self { -// Self { count } -// } -// } - -// impl TransportPeerEventHandler for MHPeer { -// fn handle_message(&self, _msg: NetworkMessage) -> ZResult<()> { -// self.count.fetch_add(1, Ordering::AcqRel); -// Ok(()) -// } - -// fn new_link(&self, _link: Link) {} -// fn del_link(&self, _link: Link) {} -// fn closing(&self) {} -// fn closed(&self) {} - -// fn as_any(&self) -> &dyn Any { -// self -// } -// } - -// async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec) { -// /* [Peers] */ -// let peer_id01 = ZenohId::try_from([2]).unwrap(); -// let peer_id02 = ZenohId::try_from([3]).unwrap(); - -// // Create the peer01 transport manager -// let peer_sh01 = Arc::new(SHPeer::new()); -// let unicast01 = TransportManager::config_unicast().max_links(endpoint02.len()); -// let peer01_manager = TransportManager::builder() -// .whatami(WhatAmI::Peer) -// .zid(peer_id01) -// .unicast(unicast01) -// .build(peer_sh01.clone()) -// .unwrap(); - -// // Create the peer01 transport manager -// let peer_sh02 = Arc::new(SHPeer::new()); -// let unicast02 = TransportManager::config_unicast().max_links(endpoint01.len()); -// let peer02_manager = TransportManager::builder() -// .whatami(WhatAmI::Peer) -// .zid(peer_id02) -// .unicast(unicast02) -// .build(peer_sh02.clone()) -// .unwrap(); - -// // Barrier to synchronize the two tasks -// let barrier_peer = Arc::new(Barrier::new(2)); -// let barrier_open_wait = Arc::new(Barrier::new(endpoint01.len() + endpoint02.len())); -// let barrier_open_done = Arc::new(Barrier::new(endpoint01.len() + endpoint02.len() + 2)); - -// // Peer01 -// let c_barp = barrier_peer.clone(); -// let c_barow = barrier_open_wait.clone(); -// let c_barod = barrier_open_done.clone(); -// let c_zid02 = peer_id02; -// let c_end01 = endpoint01.clone(); -// let c_end02 = endpoint02.clone(); -// let peer01_task = task::spawn(async move { -// // Add the endpoints on the first peer -// for e in c_end01.iter() { -// let res = ztimeout!(peer01_manager.add_listener(e.clone())); -// println!("[Transport Peer 01a] => Adding endpoint {e:?}: {res:?}"); -// assert!(res.is_ok()); -// } -// let locs = peer01_manager.get_listeners(); -// println!("[Transport Peer 01b] => Getting endpoints: {c_end01:?} {locs:?}"); -// assert_eq!(c_end01.len(), locs.len()); - -// // Open the transport with the second peer -// for e in c_end02.iter() { -// let cc_barow = c_barow.clone(); -// let cc_barod = c_barod.clone(); -// let c_p01m = peer01_manager.clone(); -// let c_end = e.clone(); -// task::spawn(async move { -// println!("[Transport Peer 01c] => Waiting for opening transport"); -// // Syncrhonize before opening the transports -// ztimeout!(cc_barow.wait()); -// let res = ztimeout!(c_p01m.open_transport(c_end.clone())); -// println!("[Transport Peer 01d] => Opening transport with {c_end:?}: {res:?}"); -// assert!(res.is_ok()); - -// // Syncrhonize after opening the transports -// ztimeout!(cc_barod.wait()); -// }); -// } - -// // Syncrhonize after opening the transports -// ztimeout!(c_barod.wait()); -// println!("[Transport Peer 01e] => Waiting... OK"); - -// // Verify that the transport has been correctly open -// assert_eq!(peer01_manager.get_transports().len(), 1); -// let s02 = peer01_manager.get_transport(&c_zid02).unwrap(); -// assert_eq!( -// s02.get_links().unwrap().len(), -// c_end01.len() + c_end02.len() -// ); - -// // Create the message to send -// let key = "test02".into(); -// let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); -// let channel = Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }; -// let congestion_control = CongestionControl::Block; -// let data_info = None; -// let routing_context = None; -// let reply_context = None; - -// let message = ZenohMessage::make_data( -// key, -// payload, -// channel, -// congestion_control, -// data_info, -// routing_context, -// reply_context, -// ); - -// // Synchronize wit the peer -// ztimeout!(c_barp.wait()); -// println!("[Transport Peer 01f] => Waiting... OK"); - -// for i in 0..MSG_COUNT { -// println!("[Transport Peer 01g] Scheduling message {}", i); -// s02.schedule(message.clone()).unwrap(); -// } -// println!("[Transport Peer 01g] => Scheduling OK"); - -// // Wait for the messages to arrive to the other side -// ztimeout!(async { -// while peer_sh02.get_count() != MSG_COUNT { -// task::sleep(SLEEP).await; -// } -// }); - -// // Synchronize wit the peer -// ztimeout!(c_barp.wait()); - -// println!("[Transport Peer 01h] => Closing {s02:?}..."); -// let res = ztimeout!(s02.close()); -// println!("[Transport Peer 01l] => Closing {s02:?}: {res:?}"); -// assert!(res.is_ok()); - -// // Close the transport -// ztimeout!(peer01_manager.close()); -// }); - -// // Peer02 -// let c_barp = barrier_peer; -// let c_barow = barrier_open_wait.clone(); -// let c_barod = barrier_open_done.clone(); -// let c_zid01 = peer_id01; -// let c_end01 = endpoint01.clone(); -// let c_end02 = endpoint02.clone(); -// let peer02_task = task::spawn(async move { -// // Add the endpoints on the first peer -// for e in c_end02.iter() { -// let res = ztimeout!(peer02_manager.add_listener(e.clone())); -// println!("[Transport Peer 02a] => Adding endpoint {e:?}: {res:?}"); -// assert!(res.is_ok()); -// } -// let locs = peer02_manager.get_listeners(); -// println!("[Transport Peer 02b] => Getting endpoints: {c_end02:?} {locs:?}"); -// assert_eq!(c_end02.len(), locs.len()); - -// // Open the transport with the first peer -// for e in c_end01.iter() { -// let cc_barow = c_barow.clone(); -// let cc_barod = c_barod.clone(); -// let c_p02m = peer02_manager.clone(); -// let c_end = e.clone(); -// task::spawn(async move { -// println!("[Transport Peer 02c] => Waiting for opening transport"); -// // Syncrhonize before opening the transports -// ztimeout!(cc_barow.wait()); - -// let res = ztimeout!(c_p02m.open_transport(c_end.clone())); -// println!("[Transport Peer 02d] => Opening transport with {c_end:?}: {res:?}"); -// assert!(res.is_ok()); - -// // Syncrhonize after opening the transports -// ztimeout!(cc_barod.wait()); -// }); -// } - -// // Syncrhonize after opening the transports -// ztimeout!(c_barod.wait()); - -// // Verify that the transport has been correctly open -// println!( -// "[Transport Peer 02e] => Transports: {:?}", -// peer02_manager.get_transports() -// ); -// assert_eq!(peer02_manager.get_transports().len(), 1); -// let s01 = peer02_manager.get_transport(&c_zid01).unwrap(); -// assert_eq!( -// s01.get_links().unwrap().len(), -// c_end01.len() + c_end02.len() -// ); - -// // Create the message to send -// let key = "test02".into(); -// let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); -// let channel = Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }; -// let congestion_control = CongestionControl::Block; -// let data_info = None; -// let routing_context = None; -// let reply_context = None; - -// let message = ZenohMessage::make_data( -// key, -// payload, -// channel, -// congestion_control, -// data_info, -// routing_context, -// reply_context, -// ); - -// // Synchronize wit the peer -// ztimeout!(c_barp.wait()); -// println!("[Transport Peer 02f] => Waiting... OK"); - -// for i in 0..MSG_COUNT { -// println!("[Transport Peer 02g] Scheduling message {}", i); -// s01.schedule(message.clone()).unwrap(); -// } -// println!("[Transport Peer 02g] => Scheduling OK"); - -// // Wait for the messages to arrive to the other side -// ztimeout!(async { -// while peer_sh01.get_count() != MSG_COUNT { -// task::sleep(SLEEP).await; -// } -// }); - -// // Synchronize wit the peer -// ztimeout!(c_barp.wait()); - -// println!("[Transport Peer 02h] => Closing {s01:?}..."); -// let res = ztimeout!(s01.close()); -// println!("[Transport Peer 02l] => Closing {s01:?}: {res:?}"); -// assert!(res.is_ok()); - -// // Close the transport -// ztimeout!(peer02_manager.close()); -// }); - -// println!("[Transport Current 01] => Starting..."); -// peer01_task.join(peer02_task).await; -// println!("[Transport Current 02] => ...Stopped"); - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } - -// #[cfg(feature = "transport_tcp")] -// #[test] -// fn transport_tcp_concurrent() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let endpoint01: Vec = vec![ -// format!("tcp/127.0.0.1:{}", 9000).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9001).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9002).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9003).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9004).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9005).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9006).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9007).parse().unwrap(), -// ]; -// let endpoint02: Vec = vec![ -// format!("tcp/127.0.0.1:{}", 9010).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9011).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9012).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9013).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9014).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9015).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9016).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 9017).parse().unwrap(), -// ]; - -// task::block_on(async { -// transport_concurrent(endpoint01, endpoint02).await; -// }); -// } - -// #[cfg(feature = "transport_ws")] -// #[test] -// fn transport_ws_concurrent() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let endpoint01: Vec = vec![ -// format!("ws/127.0.0.1:{}", 9020).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9021).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9022).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9023).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9024).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9025).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9026).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9027).parse().unwrap(), -// ]; -// let endpoint02: Vec = vec![ -// format!("ws/127.0.0.1:{}", 9030).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9031).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9032).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9033).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9034).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9035).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9036).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 9037).parse().unwrap(), -// ]; - -// task::block_on(async { -// transport_concurrent(endpoint01, endpoint02).await; -// }); -// } +use async_std::prelude::FutureExt; +use async_std::sync::Barrier; +use async_std::task; +use std::any::Any; +use std::convert::TryFrom; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; +use std::time::Duration; +use zenoh_core::zasync_executor_init; +use zenoh_link::Link; +use zenoh_protocol::core::Encoding; +use zenoh_protocol::{ + core::{CongestionControl, EndPoint, Priority, WhatAmI, ZenohId}, + network::{ + push::{ + ext::{NodeIdType, QoSType}, + Push, + }, + NetworkMessage, + }, + zenoh_new::Put, +}; +use zenoh_result::ZResult; +use zenoh_transport::{ + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, +}; + +const MSG_COUNT: usize = 1_000; +const MSG_SIZE: usize = 1_024; +const TIMEOUT: Duration = Duration::from_secs(60); +const SLEEP: Duration = Duration::from_millis(100); + +macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; +} + +// Transport Handler for the router +struct SHPeer { + count: Arc, +} + +impl SHPeer { + fn new() -> Self { + Self { + count: Arc::new(AtomicUsize::new(0)), + } + } + + fn get_count(&self) -> usize { + self.count.load(Ordering::SeqCst) + } +} + +impl TransportEventHandler for SHPeer { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + let mh = Arc::new(MHPeer::new(self.count.clone())); + Ok(mh) + } +} + +struct MHPeer { + count: Arc, +} + +impl MHPeer { + fn new(count: Arc) -> Self { + Self { count } + } +} + +impl TransportPeerEventHandler for MHPeer { + fn handle_message(&self, _msg: NetworkMessage) -> ZResult<()> { + self.count.fetch_add(1, Ordering::AcqRel); + Ok(()) + } + + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } +} + +async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec) { + /* [Peers] */ + let peer_id01 = ZenohId::try_from([2]).unwrap(); + let peer_id02 = ZenohId::try_from([3]).unwrap(); + + // Create the peer01 transport manager + let peer_sh01 = Arc::new(SHPeer::new()); + let unicast01 = TransportManager::config_unicast().max_links(endpoint02.len()); + let peer01_manager = TransportManager::builder() + .whatami(WhatAmI::Peer) + .zid(peer_id01) + .unicast(unicast01) + .build(peer_sh01.clone()) + .unwrap(); + + // Create the peer01 transport manager + let peer_sh02 = Arc::new(SHPeer::new()); + let unicast02 = TransportManager::config_unicast().max_links(endpoint01.len()); + let peer02_manager = TransportManager::builder() + .whatami(WhatAmI::Peer) + .zid(peer_id02) + .unicast(unicast02) + .build(peer_sh02.clone()) + .unwrap(); + + // Barrier to synchronize the two tasks + let barrier_peer = Arc::new(Barrier::new(2)); + let barrier_open_wait = Arc::new(Barrier::new(endpoint01.len() + endpoint02.len())); + let barrier_open_done = Arc::new(Barrier::new(endpoint01.len() + endpoint02.len() + 2)); + + // Peer01 + let c_barp = barrier_peer.clone(); + let c_barow = barrier_open_wait.clone(); + let c_barod = barrier_open_done.clone(); + let c_zid02 = peer_id02; + let c_end01 = endpoint01.clone(); + let c_end02 = endpoint02.clone(); + let peer01_task = task::spawn(async move { + // Add the endpoints on the first peer + for e in c_end01.iter() { + let res = ztimeout!(peer01_manager.add_listener(e.clone())); + println!("[Transport Peer 01a] => Adding endpoint {e:?}: {res:?}"); + assert!(res.is_ok()); + } + let locs = peer01_manager.get_listeners(); + println!("[Transport Peer 01b] => Getting endpoints: {c_end01:?} {locs:?}"); + assert_eq!(c_end01.len(), locs.len()); + + // Open the transport with the second peer + for e in c_end02.iter() { + let cc_barow = c_barow.clone(); + let cc_barod = c_barod.clone(); + let c_p01m = peer01_manager.clone(); + let c_end = e.clone(); + task::spawn(async move { + println!("[Transport Peer 01c] => Waiting for opening transport"); + // Syncrhonize before opening the transports + ztimeout!(cc_barow.wait()); + let res = ztimeout!(c_p01m.open_transport(c_end.clone())); + println!("[Transport Peer 01d] => Opening transport with {c_end:?}: {res:?}"); + assert!(res.is_ok()); + + // Syncrhonize after opening the transports + ztimeout!(cc_barod.wait()); + }); + } + + // Syncrhonize after opening the transports + ztimeout!(c_barod.wait()); + println!("[Transport Peer 01e] => Waiting... OK"); + + // Verify that the transport has been correctly open + assert_eq!(peer01_manager.get_transports().len(), 1); + let s02 = peer01_manager.get_transport(&c_zid02).unwrap(); + assert_eq!( + s02.get_links().unwrap().len(), + c_end01.len() + c_end02.len() + ); + + // Create the message to send + let message: NetworkMessage = Push { + wire_expr: "test".into(), + ext_qos: QoSType::new(Priority::default(), CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: vec![0u8; MSG_SIZE].into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + + // Synchronize wit the peer + ztimeout!(c_barp.wait()); + println!("[Transport Peer 01f] => Waiting... OK"); + + for i in 0..MSG_COUNT { + println!("[Transport Peer 01g] Scheduling message {}", i); + s02.schedule(message.clone()).unwrap(); + } + println!("[Transport Peer 01g] => Scheduling OK"); + + // Wait for the messages to arrive to the other side + ztimeout!(async { + while peer_sh02.get_count() != MSG_COUNT { + task::sleep(SLEEP).await; + } + }); + + // Synchronize wit the peer + ztimeout!(c_barp.wait()); + + println!("[Transport Peer 01h] => Closing {s02:?}..."); + let res = ztimeout!(s02.close()); + println!("[Transport Peer 01l] => Closing {s02:?}: {res:?}"); + assert!(res.is_ok()); + + // Close the transport + ztimeout!(peer01_manager.close()); + }); + + // Peer02 + let c_barp = barrier_peer; + let c_barow = barrier_open_wait.clone(); + let c_barod = barrier_open_done.clone(); + let c_zid01 = peer_id01; + let c_end01 = endpoint01.clone(); + let c_end02 = endpoint02.clone(); + let peer02_task = task::spawn(async move { + // Add the endpoints on the first peer + for e in c_end02.iter() { + let res = ztimeout!(peer02_manager.add_listener(e.clone())); + println!("[Transport Peer 02a] => Adding endpoint {e:?}: {res:?}"); + assert!(res.is_ok()); + } + let locs = peer02_manager.get_listeners(); + println!("[Transport Peer 02b] => Getting endpoints: {c_end02:?} {locs:?}"); + assert_eq!(c_end02.len(), locs.len()); + + // Open the transport with the first peer + for e in c_end01.iter() { + let cc_barow = c_barow.clone(); + let cc_barod = c_barod.clone(); + let c_p02m = peer02_manager.clone(); + let c_end = e.clone(); + task::spawn(async move { + println!("[Transport Peer 02c] => Waiting for opening transport"); + // Syncrhonize before opening the transports + ztimeout!(cc_barow.wait()); + + let res = ztimeout!(c_p02m.open_transport(c_end.clone())); + println!("[Transport Peer 02d] => Opening transport with {c_end:?}: {res:?}"); + assert!(res.is_ok()); + + // Syncrhonize after opening the transports + ztimeout!(cc_barod.wait()); + }); + } + + // Syncrhonize after opening the transports + ztimeout!(c_barod.wait()); + + // Verify that the transport has been correctly open + println!( + "[Transport Peer 02e] => Transports: {:?}", + peer02_manager.get_transports() + ); + assert_eq!(peer02_manager.get_transports().len(), 1); + let s01 = peer02_manager.get_transport(&c_zid01).unwrap(); + assert_eq!( + s01.get_links().unwrap().len(), + c_end01.len() + c_end02.len() + ); + + // Create the message to send + let message: NetworkMessage = Push { + wire_expr: "test".into(), + ext_qos: QoSType::new(Priority::default(), CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: vec![0u8; MSG_SIZE].into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + + // Synchronize wit the peer + ztimeout!(c_barp.wait()); + println!("[Transport Peer 02f] => Waiting... OK"); + + for i in 0..MSG_COUNT { + println!("[Transport Peer 02g] Scheduling message {}", i); + s01.schedule(message.clone()).unwrap(); + } + println!("[Transport Peer 02g] => Scheduling OK"); + + // Wait for the messages to arrive to the other side + ztimeout!(async { + while peer_sh01.get_count() != MSG_COUNT { + task::sleep(SLEEP).await; + } + }); + + // Synchronize wit the peer + ztimeout!(c_barp.wait()); + + println!("[Transport Peer 02h] => Closing {s01:?}..."); + let res = ztimeout!(s01.close()); + println!("[Transport Peer 02l] => Closing {s01:?}: {res:?}"); + assert!(res.is_ok()); + + // Close the transport + ztimeout!(peer02_manager.close()); + }); + + println!("[Transport Current 01] => Starting..."); + peer01_task.join(peer02_task).await; + println!("[Transport Current 02] => ...Stopped"); + + // Wait a little bit + task::sleep(SLEEP).await; +} + +#[cfg(feature = "transport_tcp")] +#[test] +fn transport_tcp_concurrent() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint01: Vec = vec![ + format!("tcp/127.0.0.1:{}", 9000).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9001).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9002).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9003).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9004).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9005).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9006).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9007).parse().unwrap(), + ]; + let endpoint02: Vec = vec![ + format!("tcp/127.0.0.1:{}", 9010).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9011).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9012).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9013).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9014).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9015).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9016).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 9017).parse().unwrap(), + ]; + + task::block_on(async { + transport_concurrent(endpoint01, endpoint02).await; + }); +} + +#[cfg(feature = "transport_ws")] +#[test] +fn transport_ws_concurrent() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint01: Vec = vec![ + format!("ws/127.0.0.1:{}", 9020).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9021).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9022).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9023).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9024).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9025).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9026).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9027).parse().unwrap(), + ]; + let endpoint02: Vec = vec![ + format!("ws/127.0.0.1:{}", 9030).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9031).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9032).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9033).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9034).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9035).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9036).parse().unwrap(), + format!("ws/127.0.0.1:{}", 9037).parse().unwrap(), + ]; + + task::block_on(async { + transport_concurrent(endpoint01, endpoint02).await; + }); +} From 6d6c50486eb94ea49ff04824368aa1455a2e853c Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 3 Jul 2023 17:44:47 +0200 Subject: [PATCH 158/203] Re-enabling unicast_conduit tests --- .../tests/unicast_concurrent.rs | 3 +- io/zenoh-transport/tests/unicast_conduits.rs | 674 +++++++++--------- 2 files changed, 332 insertions(+), 345 deletions(-) diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index 42caa7e39f..e6aba3f7d4 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -20,9 +20,8 @@ use std::sync::Arc; use std::time::Duration; use zenoh_core::zasync_executor_init; use zenoh_link::Link; -use zenoh_protocol::core::Encoding; use zenoh_protocol::{ - core::{CongestionControl, EndPoint, Priority, WhatAmI, ZenohId}, + core::{CongestionControl, Encoding, EndPoint, Priority, WhatAmI, ZenohId}, network::{ push::{ ext::{NodeIdType, QoSType}, diff --git a/io/zenoh-transport/tests/unicast_conduits.rs b/io/zenoh-transport/tests/unicast_conduits.rs index 35d21dd011..dfa036bd1b 100644 --- a/io/zenoh-transport/tests/unicast_conduits.rs +++ b/io/zenoh-transport/tests/unicast_conduits.rs @@ -11,346 +11,334 @@ // Contributors: // ZettaScale Zenoh Team, // -// use async_std::prelude::FutureExt; -// use async_std::task; -// use std::any::Any; -// use std::convert::TryFrom; -// use std::fmt::Write as _; -// use std::sync::atomic::{AtomicUsize, Ordering}; -// use std::sync::Arc; -// use std::time::Duration; -// use zenoh_buffers::ZBuf; -// use zenoh_core::zasync_executor_init; -// use zenoh_link::Link; -// use zenoh_protocol::{ -// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, -// zenoh::ZenohMessage, -// }; -// use zenoh_result::ZResult; -// use zenoh_transport::{ -// TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, -// TransportUnicast, -// }; - -// const TIMEOUT: Duration = Duration::from_secs(60); -// const SLEEP: Duration = Duration::from_secs(1); -// const SLEEP_COUNT: Duration = Duration::from_millis(10); - -// const MSG_COUNT: usize = 100; -// const MSG_SIZE_ALL: [usize; 2] = [1_024, 131_072]; - -// const PRIORITY_ALL: [Priority; 8] = [ -// Priority::Control, -// Priority::RealTime, -// Priority::InteractiveHigh, -// Priority::InteractiveLow, -// Priority::DataHigh, -// Priority::Data, -// Priority::DataLow, -// Priority::Background, -// ]; - -// macro_rules! ztimeout { -// ($f:expr) => { -// $f.timeout(TIMEOUT).await.unwrap() -// }; -// } - -// // Transport Handler for the router -// struct SHRouter { -// priority: Arc, -// count: Arc, -// } - -// impl SHRouter { -// fn new() -> Self { -// Self { -// priority: Arc::new(AtomicUsize::new(0)), -// count: Arc::new(AtomicUsize::new(0)), -// } -// } - -// fn set_priority(&self, priority: Priority) { -// self.priority.store(priority as usize, Ordering::Relaxed) -// } - -// fn reset_count(&self) { -// self.count.store(0, Ordering::Relaxed) -// } - -// fn get_count(&self) -> usize { -// self.count.load(Ordering::Relaxed) -// } -// } - -// impl TransportEventHandler for SHRouter { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// let arc = Arc::new(SCRouter::new(self.priority.clone(), self.count.clone())); -// Ok(arc) -// } -// } - -// // Transport Callback for the router -// pub struct SCRouter { -// priority: Arc, -// count: Arc, -// } - -// impl SCRouter { -// pub fn new(priority: Arc, count: Arc) -> Self { -// Self { priority, count } -// } -// } - -// impl TransportPeerEventHandler for SCRouter { -// fn handle_message(&self, message: ZenohMessage) -> ZResult<()> { -// assert_eq!( -// self.priority.load(Ordering::Relaxed), -// message.channel.priority as usize -// ); -// self.count.fetch_add(1, Ordering::Relaxed); -// Ok(()) -// } - -// fn new_link(&self, _link: Link) {} -// fn del_link(&self, _link: Link) {} -// fn closing(&self) {} -// fn closed(&self) {} - -// fn as_any(&self) -> &dyn Any { -// self -// } -// } - -// // Transport Handler for the client -// struct SHClient; - -// impl Default for SHClient { -// fn default() -> Self { -// Self -// } -// } - -// impl TransportEventHandler for SHClient { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// Ok(Arc::new(SCClient::default())) -// } -// } - -// // Transport Callback for the client -// pub struct SCClient; - -// impl Default for SCClient { -// fn default() -> Self { -// Self -// } -// } - -// impl TransportPeerEventHandler for SCClient { -// fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { -// Ok(()) -// } - -// fn new_link(&self, _link: Link) {} -// fn del_link(&self, _link: Link) {} -// fn closing(&self) {} -// fn closed(&self) {} - -// fn as_any(&self) -> &dyn Any { -// self -// } -// } - -// async fn open_transport( -// endpoints: &[EndPoint], -// ) -> ( -// TransportManager, -// Arc, -// TransportManager, -// TransportUnicast, -// ) { -// // Define client and router IDs -// let client_id = ZenohId::try_from([1]).unwrap(); -// let router_id = ZenohId::try_from([2]).unwrap(); - -// // Create the router transport manager -// let router_handler = Arc::new(SHRouter::new()); -// let router_manager = TransportManager::builder() -// .whatami(WhatAmI::Router) -// .zid(router_id) -// .build(router_handler.clone()) -// .unwrap(); - -// // Create the client transport manager -// let client_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client_id) -// .build(Arc::new(SHClient::default())) -// .unwrap(); - -// // Create the listener on the router -// for e in endpoints.iter() { -// println!("Add locator: {e}"); -// let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); -// } - -// // Create an empty transport with the client -// // Open transport -> This should be accepted -// for e in endpoints.iter() { -// println!("Opening transport with {e}"); -// let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); -// } - -// let client_transport = client_manager.get_transport(&router_id).unwrap(); - -// // Return the handlers -// ( -// router_manager, -// router_handler, -// client_manager, -// client_transport, -// ) -// } - -// async fn close_transport( -// router_manager: TransportManager, -// client_manager: TransportManager, -// client_transport: TransportUnicast, -// endpoints: &[EndPoint], -// ) { -// // Close the client transport -// let mut ee = String::new(); -// for e in endpoints.iter() { -// let _ = write!(ee, "{e} "); -// } -// println!("Closing transport with {ee}"); -// ztimeout!(client_transport.close()).unwrap(); - -// ztimeout!(async { -// while !router_manager.get_transports().is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// // Stop the locators on the manager -// for e in endpoints.iter() { -// println!("Del locator: {e}"); -// ztimeout!(router_manager.del_listener(e)).unwrap(); -// } - -// // Wait a little bit -// task::sleep(SLEEP).await; - -// ztimeout!(router_manager.close()); -// ztimeout!(client_manager.close()); - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } - -// async fn single_run( -// router_handler: Arc, -// client_transport: TransportUnicast, -// channel: &[Channel], -// msg_size: &[usize], -// ) { -// for ch in channel.iter() { -// for ms in msg_size.iter() { -// // Reset the counter and set priority on the router -// router_handler.reset_count(); -// router_handler.set_priority(ch.priority); - -// // Create the message to send -// let key = "test".into(); -// let payload = ZBuf::from(vec![0_u8; *ms]); -// let data_info = None; -// let routing_context = None; -// let reply_context = None; -// let message = ZenohMessage::make_data( -// key, -// payload, -// *ch, -// CongestionControl::Block, -// data_info, -// routing_context, -// reply_context, -// ); - -// println!("Sending {MSG_COUNT} messages... {ch:?} {ms}"); -// for _ in 0..MSG_COUNT { -// client_transport.schedule(message.clone()).unwrap(); -// } - -// // Wait for the messages to arrive to the other side -// ztimeout!(async { -// while router_handler.get_count() != MSG_COUNT { -// task::sleep(SLEEP_COUNT).await; -// } -// }); -// } -// } - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } - -// async fn run(endpoints: &[EndPoint], channel: &[Channel], msg_size: &[usize]) { -// let (router_manager, router_handler, client_manager, client_transport) = -// open_transport(endpoints).await; -// single_run( -// router_handler.clone(), -// client_transport.clone(), -// channel, -// msg_size, -// ) -// .await; -// close_transport(router_manager, client_manager, client_transport, endpoints).await; -// } - -// #[cfg(feature = "transport_tcp")] -// #[test] -// fn conduits_tcp_only() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); -// let mut channel = vec![]; -// for p in PRIORITY_ALL.iter() { -// channel.push(Channel { -// priority: *p, -// reliability: Reliability::Reliable, -// }); -// } -// // Define the locators -// let endpoints: Vec = vec![format!("tcp/127.0.0.1:{}", 10000).parse().unwrap()]; -// // Run -// task::block_on(run(&endpoints, &channel, &MSG_SIZE_ALL)); -// } - -// #[cfg(feature = "transport_ws")] -// #[test] -// fn conduits_ws_only() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); -// let mut channel = vec![]; -// for p in PRIORITY_ALL.iter() { -// channel.push(Channel { -// priority: *p, -// reliability: Reliability::Reliable, -// }); -// } -// // Define the locators -// let endpoints: Vec = vec![format!("ws/127.0.0.1:{}", 10010).parse().unwrap()]; -// // Run -// task::block_on(run(&endpoints, &channel, &MSG_SIZE_ALL)); -// } +use async_std::prelude::FutureExt; +use async_std::task; +use std::any::Any; +use std::convert::TryFrom; +use std::fmt::Write as _; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; +use std::time::Duration; +use zenoh_core::zasync_executor_init; +use zenoh_link::Link; +use zenoh_protocol::network::NetworkBody; +use zenoh_protocol::{ + core::{CongestionControl, Encoding, EndPoint, Priority, WhatAmI, ZenohId}, + network::{ + push::{ + ext::{NodeIdType, QoSType}, + Push, + }, + NetworkMessage, + }, + zenoh_new::Put, +}; +use zenoh_result::ZResult; +use zenoh_transport::{ + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, +}; + +const TIMEOUT: Duration = Duration::from_secs(60); +const SLEEP: Duration = Duration::from_secs(1); +const SLEEP_COUNT: Duration = Duration::from_millis(10); + +const MSG_COUNT: usize = 100; +const MSG_SIZE_ALL: [usize; 2] = [1_024, 131_072]; + +const PRIORITY_ALL: [Priority; 8] = [ + Priority::Control, + Priority::RealTime, + Priority::InteractiveHigh, + Priority::InteractiveLow, + Priority::DataHigh, + Priority::Data, + Priority::DataLow, + Priority::Background, +]; + +macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; +} + +// Transport Handler for the router +struct SHRouter { + priority: Arc, + count: Arc, +} + +impl SHRouter { + fn new() -> Self { + Self { + priority: Arc::new(AtomicUsize::new(0)), + count: Arc::new(AtomicUsize::new(0)), + } + } + + fn set_priority(&self, priority: Priority) { + self.priority.store(priority as usize, Ordering::Relaxed) + } + + fn reset_count(&self) { + self.count.store(0, Ordering::Relaxed) + } + + fn get_count(&self) -> usize { + self.count.load(Ordering::Relaxed) + } +} + +impl TransportEventHandler for SHRouter { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + let arc = Arc::new(SCRouter::new(self.priority.clone(), self.count.clone())); + Ok(arc) + } +} + +// Transport Callback for the router +pub struct SCRouter { + priority: Arc, + count: Arc, +} + +impl SCRouter { + pub fn new(priority: Arc, count: Arc) -> Self { + Self { priority, count } + } +} + +impl TransportPeerEventHandler for SCRouter { + fn handle_message(&self, message: NetworkMessage) -> ZResult<()> { + match &message.body { + NetworkBody::Push(p) => { + assert_eq!( + self.priority.load(Ordering::Relaxed), + p.ext_qos.get_priority() as usize + ); + } + _ => panic!("Unexpected message"), + } + self.count.fetch_add(1, Ordering::Relaxed); + Ok(()) + } + + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } +} + +// Transport Handler for the client +struct SHClient; + +impl Default for SHClient { + fn default() -> Self { + Self + } +} + +impl TransportEventHandler for SHClient { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + Ok(Arc::new(SCClient::default())) + } +} + +// Transport Callback for the client +pub struct SCClient; + +impl Default for SCClient { + fn default() -> Self { + Self + } +} + +impl TransportPeerEventHandler for SCClient { + fn handle_message(&self, _message: NetworkMessage) -> ZResult<()> { + Ok(()) + } + + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } +} + +async fn open_transport( + endpoints: &[EndPoint], +) -> ( + TransportManager, + Arc, + TransportManager, + TransportUnicast, +) { + // Define client and router IDs + let client_id = ZenohId::try_from([1]).unwrap(); + let router_id = ZenohId::try_from([2]).unwrap(); + + // Create the router transport manager + let router_handler = Arc::new(SHRouter::new()); + let router_manager = TransportManager::builder() + .whatami(WhatAmI::Router) + .zid(router_id) + .build(router_handler.clone()) + .unwrap(); + + // Create the client transport manager + let client_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client_id) + .build(Arc::new(SHClient::default())) + .unwrap(); + + // Create the listener on the router + for e in endpoints.iter() { + println!("Add locator: {e}"); + let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); + } + + // Create an empty transport with the client + // Open transport -> This should be accepted + for e in endpoints.iter() { + println!("Opening transport with {e}"); + let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); + } + + let client_transport = client_manager.get_transport(&router_id).unwrap(); + + // Return the handlers + ( + router_manager, + router_handler, + client_manager, + client_transport, + ) +} + +async fn close_transport( + router_manager: TransportManager, + client_manager: TransportManager, + client_transport: TransportUnicast, + endpoints: &[EndPoint], +) { + // Close the client transport + let mut ee = String::new(); + for e in endpoints.iter() { + let _ = write!(ee, "{e} "); + } + println!("Closing transport with {ee}"); + ztimeout!(client_transport.close()).unwrap(); + + ztimeout!(async { + while !router_manager.get_transports().is_empty() { + task::sleep(SLEEP).await; + } + }); + + // Stop the locators on the manager + for e in endpoints.iter() { + println!("Del locator: {e}"); + ztimeout!(router_manager.del_listener(e)).unwrap(); + } + + // Wait a little bit + task::sleep(SLEEP).await; + + ztimeout!(router_manager.close()); + ztimeout!(client_manager.close()); + + // Wait a little bit + task::sleep(SLEEP).await; +} + +async fn single_run(router_handler: Arc, client_transport: TransportUnicast) { + for p in PRIORITY_ALL.iter() { + for ms in MSG_SIZE_ALL.iter() { + // Reset the counter and set priority on the router + router_handler.reset_count(); + router_handler.set_priority(*p); + + // Create the message to send + let message: NetworkMessage = Push { + wire_expr: "test".into(), + ext_qos: QoSType::new(*p, CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: vec![0u8; *ms].into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + + println!("Sending {MSG_COUNT} messages... {p:?} {ms}"); + for _ in 0..MSG_COUNT { + client_transport.schedule(message.clone()).unwrap(); + } + + // Wait for the messages to arrive to the other side + ztimeout!(async { + while router_handler.get_count() != MSG_COUNT { + task::sleep(SLEEP_COUNT).await; + } + }); + } + } + + // Wait a little bit + task::sleep(SLEEP).await; +} + +async fn run(endpoints: &[EndPoint]) { + let (router_manager, router_handler, client_manager, client_transport) = + open_transport(endpoints).await; + single_run(router_handler.clone(), client_transport.clone()).await; + close_transport(router_manager, client_manager, client_transport, endpoints).await; +} + +#[cfg(feature = "transport_tcp")] +#[test] +fn conduits_tcp_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + // Define the locators + let endpoints: Vec = vec![format!("tcp/127.0.0.1:{}", 10000).parse().unwrap()]; + // Run + task::block_on(run(&endpoints)); +} + +#[cfg(feature = "transport_ws")] +#[test] +fn conduits_ws_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + // Define the locators + let endpoints: Vec = vec![format!("ws/127.0.0.1:{}", 10010).parse().unwrap()]; + // Run + task::block_on(run(&endpoints)); +} From 48cdae231f072d6fff353adb3b0c098560da5660 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 3 Jul 2023 17:49:25 +0200 Subject: [PATCH 159/203] Re-enabling unicast_defragmentation tests --- .../tests/unicast_defragmentation.rs | 373 +++++++++--------- 1 file changed, 191 insertions(+), 182 deletions(-) diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index b907930e96..d352bcfa28 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -11,185 +11,194 @@ // Contributors: // ZettaScale Zenoh Team, // -// use async_std::{prelude::FutureExt, task}; -// use std::{convert::TryFrom, sync::Arc, time::Duration}; -// use zenoh_buffers::ZBuf; -// use zenoh_core::zasync_executor_init; -// use zenoh_protocol::{ -// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, -// zenoh::ZenohMessage, -// }; -// use zenoh_transport::{DummyTransportEventHandler, TransportManager}; - -// const TIMEOUT: Duration = Duration::from_secs(60); -// const SLEEP: Duration = Duration::from_secs(1); - -// const MSG_SIZE: usize = 131_072; -// const MSG_DEFRAG_BUF: usize = 128_000; - -// macro_rules! ztimeout { -// ($f:expr) => { -// $f.timeout(TIMEOUT).await.unwrap() -// }; -// } - -// async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { -// // Define client and router IDs -// let client_id = ZenohId::try_from([1]).unwrap(); -// let router_id = ZenohId::try_from([2]).unwrap(); - -// // Create the router transport manager -// let router_manager = TransportManager::builder() -// .zid(router_id) -// .whatami(WhatAmI::Router) -// .defrag_buff_size(MSG_DEFRAG_BUF) -// .build(Arc::new(DummyTransportEventHandler::default())) -// .unwrap(); - -// // Create the client transport manager -// let client_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client_id) -// .defrag_buff_size(MSG_DEFRAG_BUF) -// .build(Arc::new(DummyTransportEventHandler::default())) -// .unwrap(); - -// // Create the listener on the router -// println!("Add locator: {endpoint}"); -// let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); - -// // Create an empty transport with the client -// // Open transport -> This should be accepted -// println!("Opening transport with {endpoint}"); -// let _ = ztimeout!(client_manager.open_transport(endpoint.clone())).unwrap(); - -// let client_transport = client_manager.get_transport(&router_id).unwrap(); - -// // Create the message to send, this would trigger the transport closure -// let key = "test".into(); -// let payload = ZBuf::from(vec![0_u8; msg_size]); -// let data_info = None; -// let routing_context = None; -// let reply_context = None; -// let message = ZenohMessage::make_data( -// key, -// payload, -// channel, -// CongestionControl::Block, -// data_info, -// routing_context, -// reply_context, -// ); - -// println!( -// "Sending message of {msg_size} bytes while defragmentation buffer size is {MSG_DEFRAG_BUF} bytes" -// ); -// client_transport.schedule(message.clone()).unwrap(); - -// // Wait that the client transport has been closed -// ztimeout!(async { -// while client_transport.get_zid().is_ok() { -// task::sleep(SLEEP).await; -// } -// }); - -// // Wait on the router manager that the transport has been closed -// ztimeout!(async { -// while !router_manager.get_transports_unicast().await.is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// // Stop the locators on the manager -// println!("Del locator: {endpoint}"); -// ztimeout!(router_manager.del_listener(endpoint)).unwrap(); - -// // Wait a little bit -// ztimeout!(async { -// while !router_manager.get_listeners_unicast().await.is_empty() { -// task::sleep(SLEEP).await; -// } -// }); - -// task::sleep(SLEEP).await; - -// ztimeout!(router_manager.close()); -// ztimeout!(client_manager.close()); - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } - -// #[cfg(feature = "transport_tcp")] -// #[test] -// fn transport_unicast_defragmentation_tcp_only() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// // Define the locators -// let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 11000).parse().unwrap(); -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(async { -// for ch in channel.iter() { -// run(&endpoint, *ch, MSG_SIZE).await; -// } -// }); -// } - -// #[cfg(feature = "transport_ws")] -// #[test] -// fn transport_unicast_defragmentation_ws_only() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// // Define the locators -// let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 11010).parse().unwrap(); -// // Define the reliability and congestion control -// let channel = [ -// Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::default(), -// reliability: Reliability::BestEffort, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::Reliable, -// }, -// Channel { -// priority: Priority::RealTime, -// reliability: Reliability::BestEffort, -// }, -// ]; -// // Run -// task::block_on(async { -// for ch in channel.iter() { -// run(&endpoint, *ch, MSG_SIZE).await; -// } -// }); -// } +use async_std::{prelude::FutureExt, task}; +use std::{convert::TryFrom, sync::Arc, time::Duration}; +use zenoh_core::zasync_executor_init; +use zenoh_protocol::{ + core::{ + Channel, CongestionControl, Encoding, EndPoint, Priority, Reliability, WhatAmI, ZenohId, + }, + network::{ + push::{ + ext::{NodeIdType, QoSType}, + Push, + }, + NetworkMessage, + }, + zenoh_new::Put, +}; +use zenoh_transport::{DummyTransportEventHandler, TransportManager}; + +const TIMEOUT: Duration = Duration::from_secs(60); +const SLEEP: Duration = Duration::from_secs(1); + +const MSG_SIZE: usize = 131_072; +const MSG_DEFRAG_BUF: usize = 128_000; + +macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; +} + +async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { + // Define client and router IDs + let client_id = ZenohId::try_from([1]).unwrap(); + let router_id = ZenohId::try_from([2]).unwrap(); + + // Create the router transport manager + let router_manager = TransportManager::builder() + .zid(router_id) + .whatami(WhatAmI::Router) + .defrag_buff_size(MSG_DEFRAG_BUF) + .build(Arc::new(DummyTransportEventHandler::default())) + .unwrap(); + + // Create the client transport manager + let client_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client_id) + .defrag_buff_size(MSG_DEFRAG_BUF) + .build(Arc::new(DummyTransportEventHandler::default())) + .unwrap(); + + // Create the listener on the router + println!("Add locator: {endpoint}"); + let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); + + // Create an empty transport with the client + // Open transport -> This should be accepted + println!("Opening transport with {endpoint}"); + let _ = ztimeout!(client_manager.open_transport(endpoint.clone())).unwrap(); + + let client_transport = client_manager.get_transport(&router_id).unwrap(); + + // Create the message to send + let message: NetworkMessage = Push { + wire_expr: "test".into(), + ext_qos: QoSType::new(channel.priority, CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: vec![0u8; msg_size].into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + + println!( + "Sending message of {msg_size} bytes while defragmentation buffer size is {MSG_DEFRAG_BUF} bytes" + ); + client_transport.schedule(message.clone()).unwrap(); + + // Wait that the client transport has been closed + ztimeout!(async { + while client_transport.get_zid().is_ok() { + task::sleep(SLEEP).await; + } + }); + + // Wait on the router manager that the transport has been closed + ztimeout!(async { + while !router_manager.get_transports_unicast().await.is_empty() { + task::sleep(SLEEP).await; + } + }); + + // Stop the locators on the manager + println!("Del locator: {endpoint}"); + ztimeout!(router_manager.del_listener(endpoint)).unwrap(); + + // Wait a little bit + ztimeout!(async { + while !router_manager.get_listeners_unicast().await.is_empty() { + task::sleep(SLEEP).await; + } + }); + + task::sleep(SLEEP).await; + + ztimeout!(router_manager.close()); + ztimeout!(client_manager.close()); + + // Wait a little bit + task::sleep(SLEEP).await; +} + +#[cfg(feature = "transport_tcp")] +#[test] +fn transport_unicast_defragmentation_tcp_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 11000).parse().unwrap(); + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(async { + for ch in channel.iter() { + run(&endpoint, *ch, MSG_SIZE).await; + } + }); +} + +#[cfg(feature = "transport_ws")] +#[test] +fn transport_unicast_defragmentation_ws_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 11010).parse().unwrap(); + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(async { + for ch in channel.iter() { + run(&endpoint, *ch, MSG_SIZE).await; + } + }); +} From bee4eb9ad2586f9ed860ce33b8096e1b77694b9b Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 3 Jul 2023 17:52:08 +0200 Subject: [PATCH 160/203] Re-enabling unicast_intermittent tests --- .../tests/unicast_intermittent.rs | 747 +++++++++--------- 1 file changed, 374 insertions(+), 373 deletions(-) diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index 1128bb53cb..1e3af3ad9e 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -11,376 +11,377 @@ // Contributors: // ZettaScale Zenoh Team, // -// use async_std::prelude::FutureExt; -// use async_std::task; -// use std::any::Any; -// use std::convert::TryFrom; -// use std::io::Write; -// use std::sync::atomic::{AtomicUsize, Ordering}; -// use std::sync::Arc; -// use std::thread; -// use std::time::Duration; -// use zenoh_buffers::ZBuf; -// use zenoh_core::zasync_executor_init; -// use zenoh_link::Link; -// use zenoh_protocol::{ -// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, -// zenoh::ZenohMessage, -// }; -// use zenoh_result::ZResult; -// use zenoh_transport::{ -// DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportPeer, -// TransportPeerEventHandler, TransportUnicast, -// }; - -// const MSG_SIZE: usize = 8; -// const MSG_COUNT: usize = 100_000; -// const TIMEOUT: Duration = Duration::from_secs(300); -// const SLEEP: Duration = Duration::from_millis(100); -// const USLEEP: Duration = Duration::from_millis(1); - -// macro_rules! ztimeout { -// ($f:expr) => { -// $f.timeout(TIMEOUT).await.unwrap() -// }; -// } -// #[cfg(test)] -// #[derive(Default)] -// struct SHRouterIntermittent; - -// impl TransportEventHandler for SHRouterIntermittent { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// Ok(Arc::new(DummyTransportPeerEventHandler::default())) -// } -// } - -// // Transport Handler for the intermittent clients -// #[derive(Default)] -// struct SHClientIntermittent; - -// impl TransportEventHandler for SHClientIntermittent { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// Ok(Arc::new(DummyTransportPeerEventHandler::default())) -// } -// } - -// // Transport Handler for the stable client -// struct SHClientStable { -// counter: Arc, -// } - -// impl SHClientStable { -// fn new(counter: Arc) -> Self { -// Self { counter } -// } -// } - -// impl TransportEventHandler for SHClientStable { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// _transport: TransportUnicast, -// ) -> ZResult> { -// Ok(Arc::new(SCClient::new(self.counter.clone()))) -// } -// } - -// // Transport Callback for the client -// pub struct SCClient { -// counter: Arc, -// } - -// impl SCClient { -// pub fn new(counter: Arc) -> Self { -// Self { counter } -// } -// } - -// impl TransportPeerEventHandler for SCClient { -// fn handle_message(&self, _message: ZenohMessage) -> ZResult<()> { -// self.counter.fetch_add(1, Ordering::AcqRel); -// Ok(()) -// } - -// fn new_link(&self, _link: Link) {} -// fn del_link(&self, _link: Link) {} -// fn closing(&self) {} -// fn closed(&self) {} - -// fn as_any(&self) -> &dyn Any { -// self -// } -// } - -// async fn transport_intermittent(endpoint: &EndPoint) { -// /* [ROUTER] */ -// let router_id = ZenohId::try_from([1]).unwrap(); - -// let router_handler = Arc::new(SHRouterIntermittent::default()); -// // Create the router transport manager -// let unicast = TransportManager::config_unicast() -// .max_links(1) -// .max_sessions(3); -// let router_manager = TransportManager::builder() -// .whatami(WhatAmI::Router) -// .zid(router_id) -// .unicast(unicast) -// .build(router_handler.clone()) -// .unwrap(); - -// /* [CLIENT] */ -// let client01_id = ZenohId::try_from([2]).unwrap(); -// let client02_id = ZenohId::try_from([3]).unwrap(); -// let client03_id = ZenohId::try_from([4]).unwrap(); - -// // Create the transport transport manager for the first client -// let counter = Arc::new(AtomicUsize::new(0)); -// let unicast = TransportManager::config_unicast() -// .max_links(1) -// .max_sessions(3); -// let client01_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client01_id) -// .unicast(unicast) -// .build(Arc::new(SHClientStable::new(counter.clone()))) -// .unwrap(); - -// // Create the transport transport manager for the second client -// let unicast = TransportManager::config_unicast() -// .max_links(1) -// .max_sessions(1); -// let client02_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client02_id) -// .unicast(unicast) -// .build(Arc::new(SHClientIntermittent::default())) -// .unwrap(); - -// // Create the transport transport manager for the third client -// let unicast = TransportManager::config_unicast() -// .max_links(1) -// .max_sessions(1); -// let client03_manager = TransportManager::builder() -// .whatami(WhatAmI::Client) -// .zid(client03_id) -// .unicast(unicast) -// .build(Arc::new(SHClientIntermittent::default())) -// .unwrap(); - -// /* [1] */ -// // Add a listener to the router -// println!("\nTransport Intermittent [1a1]"); -// let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); -// let locators = router_manager.get_listeners(); -// println!("Transport Intermittent [1a2]: {locators:?}"); -// assert_eq!(locators.len(), 1); - -// /* [2] */ -// // Open a transport from client01 to the router -// let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); -// assert_eq!(c_ses1.get_links().unwrap().len(), 1); -// assert_eq!(client01_manager.get_transports().len(), 1); -// assert_eq!(c_ses1.get_zid().unwrap(), router_id); - -// /* [3] */ -// // Continously open and close transport from client02 and client03 to the router -// let c_client02_manager = client02_manager.clone(); -// let c_endpoint = endpoint.clone(); -// let c_router_id = router_id; -// let c2_handle = task::spawn(async move { -// loop { -// print!("+"); -// std::io::stdout().flush().unwrap(); - -// let c_ses2 = ztimeout!(c_client02_manager.open_transport(c_endpoint.clone())).unwrap(); -// assert_eq!(c_ses2.get_links().unwrap().len(), 1); -// assert_eq!(c_client02_manager.get_transports().len(), 1); -// assert_eq!(c_ses2.get_zid().unwrap(), c_router_id); - -// task::sleep(SLEEP).await; - -// print!("-"); -// std::io::stdout().flush().unwrap(); - -// ztimeout!(c_ses2.close()).unwrap(); - -// task::sleep(SLEEP).await; -// } -// }); - -// let c_client03_manager = client03_manager.clone(); -// let c_endpoint = endpoint.clone(); -// let c_router_id = router_id; -// let c3_handle = task::spawn(async move { -// loop { -// print!("*"); -// std::io::stdout().flush().unwrap(); - -// let c_ses3 = ztimeout!(c_client03_manager.open_transport(c_endpoint.clone())).unwrap(); -// assert_eq!(c_ses3.get_links().unwrap().len(), 1); -// assert_eq!(c_client03_manager.get_transports().len(), 1); -// assert_eq!(c_ses3.get_zid().unwrap(), c_router_id); - -// task::sleep(SLEEP).await; - -// print!(""); -// std::io::stdout().flush().unwrap(); - -// ztimeout!(c_ses3.close()).unwrap(); - -// task::sleep(SLEEP).await; -// } -// }); - -// /* [4] */ -// println!("Transport Intermittent [4a1]"); -// let c_router_manager = router_manager.clone(); -// ztimeout!(task::spawn_blocking(move || { -// // Create the message to send -// let key = "test".into(); -// let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); -// let channel = Channel { -// priority: Priority::default(), -// reliability: Reliability::Reliable, -// }; -// let congestion_control = CongestionControl::Block; -// let data_info = None; -// let routing_context = None; -// let reply_context = None; - -// let message = ZenohMessage::make_data( -// key, -// payload, -// channel, -// congestion_control, -// data_info, -// routing_context, -// reply_context, -// ); - -// let mut ticks: Vec = (0..=MSG_COUNT).step_by(MSG_COUNT / 10).collect(); -// ticks.remove(0); - -// let mut count = 0; -// while count < MSG_COUNT { -// if count == ticks[0] { -// println!("\nScheduled {count}"); -// ticks.remove(0); -// } -// let transports = c_router_manager.get_transports(); -// if !transports.is_empty() { -// for s in transports.iter() { -// if let Ok(ll) = s.get_links() { -// if ll.is_empty() { -// print!("#"); -// } else { -// assert_eq!(ll.len(), 1); -// } -// } -// let res = s.schedule(message.clone()); -// if res.is_err() { -// print!("X"); -// std::io::stdout().flush().unwrap(); -// } -// } -// count += 1; -// } else { -// print!("O"); -// thread::sleep(USLEEP); -// } -// } -// })); - -// // Stop the tasks -// ztimeout!(c2_handle.cancel()); -// ztimeout!(c3_handle.cancel()); - -// // Check that client01 received all the messages -// println!("Transport Intermittent [4b1]"); -// ztimeout!(async { -// loop { -// let c = counter.load(Ordering::Acquire); -// if c == MSG_COUNT { -// break; -// } -// println!("Transport Intermittent [4b2]: Received {c}/{MSG_COUNT}"); -// task::sleep(SLEEP).await; -// } -// }); - -// /* [5] */ -// // Close the open transport on the client -// println!("Transport Intermittent [5a1]"); -// for s in client01_manager.get_transports().iter() { -// ztimeout!(s.close()).unwrap(); -// } -// println!("Transport Intermittent [5a2]"); -// for s in client02_manager.get_transports().iter() { -// ztimeout!(s.close()).unwrap(); -// } -// println!("Transport Intermittent [5a3]"); -// for s in client03_manager.get_transports().iter() { -// ztimeout!(s.close()).unwrap(); -// } - -// /* [6] */ -// // Verify that the transport has been closed also on the router -// println!("Transport Intermittent [6a1]"); -// ztimeout!(async { -// loop { -// let transports = router_manager.get_transports(); -// if transports.is_empty() { -// break; -// } -// task::sleep(SLEEP).await; -// } -// }); - -// /* [7] */ -// // Perform clean up of the open locators -// println!("\nTransport Intermittent [7a1]"); -// ztimeout!(router_manager.del_listener(endpoint)).unwrap(); - -// // Wait a little bit -// task::sleep(SLEEP).await; - -// ztimeout!(router_manager.close()); -// ztimeout!(client01_manager.close()); -// ztimeout!(client02_manager.close()); -// ztimeout!(client03_manager.close()); - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } - -// #[cfg(feature = "transport_tcp")] -// #[test] -// fn transport_tcp_intermittent() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 12000).parse().unwrap(); -// task::block_on(transport_intermittent(&endpoint)); -// } - -// #[cfg(feature = "transport_ws")] -// #[test] -// fn transport_ws_intermittent() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 12010).parse().unwrap(); -// task::block_on(transport_intermittent(&endpoint)); -// } +use async_std::prelude::FutureExt; +use async_std::task; +use std::any::Any; +use std::convert::TryFrom; +use std::io::Write; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; +use std::thread; +use std::time::Duration; +use zenoh_core::zasync_executor_init; +use zenoh_link::Link; +use zenoh_protocol::{ + core::{CongestionControl, Encoding, EndPoint, Priority, WhatAmI, ZenohId}, + network::{ + push::{ + ext::{NodeIdType, QoSType}, + Push, + }, + NetworkMessage, + }, + zenoh_new::Put, +}; +use zenoh_result::ZResult; +use zenoh_transport::{ + DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportPeer, + TransportPeerEventHandler, TransportUnicast, +}; + +const MSG_SIZE: usize = 8; +const MSG_COUNT: usize = 100_000; +const TIMEOUT: Duration = Duration::from_secs(300); +const SLEEP: Duration = Duration::from_millis(100); +const USLEEP: Duration = Duration::from_millis(1); + +macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; +} +#[cfg(test)] +#[derive(Default)] +struct SHRouterIntermittent; + +impl TransportEventHandler for SHRouterIntermittent { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + Ok(Arc::new(DummyTransportPeerEventHandler::default())) + } +} + +// Transport Handler for the intermittent clients +#[derive(Default)] +struct SHClientIntermittent; + +impl TransportEventHandler for SHClientIntermittent { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + Ok(Arc::new(DummyTransportPeerEventHandler::default())) + } +} + +// Transport Handler for the stable client +struct SHClientStable { + counter: Arc, +} + +impl SHClientStable { + fn new(counter: Arc) -> Self { + Self { counter } + } +} + +impl TransportEventHandler for SHClientStable { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + Ok(Arc::new(SCClient::new(self.counter.clone()))) + } +} + +// Transport Callback for the client +pub struct SCClient { + counter: Arc, +} + +impl SCClient { + pub fn new(counter: Arc) -> Self { + Self { counter } + } +} + +impl TransportPeerEventHandler for SCClient { + fn handle_message(&self, _message: NetworkMessage) -> ZResult<()> { + self.counter.fetch_add(1, Ordering::AcqRel); + Ok(()) + } + + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } +} + +async fn transport_intermittent(endpoint: &EndPoint) { + /* [ROUTER] */ + let router_id = ZenohId::try_from([1]).unwrap(); + + let router_handler = Arc::new(SHRouterIntermittent::default()); + // Create the router transport manager + let unicast = TransportManager::config_unicast() + .max_links(1) + .max_sessions(3); + let router_manager = TransportManager::builder() + .whatami(WhatAmI::Router) + .zid(router_id) + .unicast(unicast) + .build(router_handler.clone()) + .unwrap(); + + /* [CLIENT] */ + let client01_id = ZenohId::try_from([2]).unwrap(); + let client02_id = ZenohId::try_from([3]).unwrap(); + let client03_id = ZenohId::try_from([4]).unwrap(); + + // Create the transport transport manager for the first client + let counter = Arc::new(AtomicUsize::new(0)); + let unicast = TransportManager::config_unicast() + .max_links(1) + .max_sessions(3); + let client01_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client01_id) + .unicast(unicast) + .build(Arc::new(SHClientStable::new(counter.clone()))) + .unwrap(); + + // Create the transport transport manager for the second client + let unicast = TransportManager::config_unicast() + .max_links(1) + .max_sessions(1); + let client02_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client02_id) + .unicast(unicast) + .build(Arc::new(SHClientIntermittent::default())) + .unwrap(); + + // Create the transport transport manager for the third client + let unicast = TransportManager::config_unicast() + .max_links(1) + .max_sessions(1); + let client03_manager = TransportManager::builder() + .whatami(WhatAmI::Client) + .zid(client03_id) + .unicast(unicast) + .build(Arc::new(SHClientIntermittent::default())) + .unwrap(); + + /* [1] */ + // Add a listener to the router + println!("\nTransport Intermittent [1a1]"); + let _ = ztimeout!(router_manager.add_listener(endpoint.clone())).unwrap(); + let locators = router_manager.get_listeners(); + println!("Transport Intermittent [1a2]: {locators:?}"); + assert_eq!(locators.len(), 1); + + /* [2] */ + // Open a transport from client01 to the router + let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); + assert_eq!(c_ses1.get_links().unwrap().len(), 1); + assert_eq!(client01_manager.get_transports().len(), 1); + assert_eq!(c_ses1.get_zid().unwrap(), router_id); + + /* [3] */ + // Continously open and close transport from client02 and client03 to the router + let c_client02_manager = client02_manager.clone(); + let c_endpoint = endpoint.clone(); + let c_router_id = router_id; + let c2_handle = task::spawn(async move { + loop { + print!("+"); + std::io::stdout().flush().unwrap(); + + let c_ses2 = ztimeout!(c_client02_manager.open_transport(c_endpoint.clone())).unwrap(); + assert_eq!(c_ses2.get_links().unwrap().len(), 1); + assert_eq!(c_client02_manager.get_transports().len(), 1); + assert_eq!(c_ses2.get_zid().unwrap(), c_router_id); + + task::sleep(SLEEP).await; + + print!("-"); + std::io::stdout().flush().unwrap(); + + ztimeout!(c_ses2.close()).unwrap(); + + task::sleep(SLEEP).await; + } + }); + + let c_client03_manager = client03_manager.clone(); + let c_endpoint = endpoint.clone(); + let c_router_id = router_id; + let c3_handle = task::spawn(async move { + loop { + print!("*"); + std::io::stdout().flush().unwrap(); + + let c_ses3 = ztimeout!(c_client03_manager.open_transport(c_endpoint.clone())).unwrap(); + assert_eq!(c_ses3.get_links().unwrap().len(), 1); + assert_eq!(c_client03_manager.get_transports().len(), 1); + assert_eq!(c_ses3.get_zid().unwrap(), c_router_id); + + task::sleep(SLEEP).await; + + print!(""); + std::io::stdout().flush().unwrap(); + + ztimeout!(c_ses3.close()).unwrap(); + + task::sleep(SLEEP).await; + } + }); + + /* [4] */ + println!("Transport Intermittent [4a1]"); + let c_router_manager = router_manager.clone(); + ztimeout!(task::spawn_blocking(move || { + // Create the message to send + let message: NetworkMessage = Push { + wire_expr: "test".into(), + ext_qos: QoSType::new(Priority::default(), CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: vec![0u8; MSG_SIZE].into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + + let mut ticks: Vec = (0..=MSG_COUNT).step_by(MSG_COUNT / 10).collect(); + ticks.remove(0); + + let mut count = 0; + while count < MSG_COUNT { + if count == ticks[0] { + println!("\nScheduled {count}"); + ticks.remove(0); + } + let transports = c_router_manager.get_transports(); + if !transports.is_empty() { + for s in transports.iter() { + if let Ok(ll) = s.get_links() { + if ll.is_empty() { + print!("#"); + } else { + assert_eq!(ll.len(), 1); + } + } + let res = s.schedule(message.clone()); + if res.is_err() { + print!("X"); + std::io::stdout().flush().unwrap(); + } + } + count += 1; + } else { + print!("O"); + thread::sleep(USLEEP); + } + } + })); + + // Stop the tasks + ztimeout!(c2_handle.cancel()); + ztimeout!(c3_handle.cancel()); + + // Check that client01 received all the messages + println!("Transport Intermittent [4b1]"); + ztimeout!(async { + loop { + let c = counter.load(Ordering::Acquire); + if c == MSG_COUNT { + break; + } + println!("Transport Intermittent [4b2]: Received {c}/{MSG_COUNT}"); + task::sleep(SLEEP).await; + } + }); + + /* [5] */ + // Close the open transport on the client + println!("Transport Intermittent [5a1]"); + for s in client01_manager.get_transports().iter() { + ztimeout!(s.close()).unwrap(); + } + println!("Transport Intermittent [5a2]"); + for s in client02_manager.get_transports().iter() { + ztimeout!(s.close()).unwrap(); + } + println!("Transport Intermittent [5a3]"); + for s in client03_manager.get_transports().iter() { + ztimeout!(s.close()).unwrap(); + } + + /* [6] */ + // Verify that the transport has been closed also on the router + println!("Transport Intermittent [6a1]"); + ztimeout!(async { + loop { + let transports = router_manager.get_transports(); + if transports.is_empty() { + break; + } + task::sleep(SLEEP).await; + } + }); + + /* [7] */ + // Perform clean up of the open locators + println!("\nTransport Intermittent [7a1]"); + ztimeout!(router_manager.del_listener(endpoint)).unwrap(); + + // Wait a little bit + task::sleep(SLEEP).await; + + ztimeout!(router_manager.close()); + ztimeout!(client01_manager.close()); + ztimeout!(client02_manager.close()); + ztimeout!(client03_manager.close()); + + // Wait a little bit + task::sleep(SLEEP).await; +} + +#[cfg(feature = "transport_tcp")] +#[test] +fn transport_tcp_intermittent() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 12000).parse().unwrap(); + task::block_on(transport_intermittent(&endpoint)); +} + +#[cfg(feature = "transport_ws")] +#[test] +fn transport_ws_intermittent() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 12010).parse().unwrap(); + task::block_on(transport_intermittent(&endpoint)); +} From a5564d690bb804098749e1aebf603a90eef9ce80 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 3 Jul 2023 17:54:44 +0200 Subject: [PATCH 161/203] Re-enabling unicast_simultaneous tests --- .../tests/unicast_simultaneous.rs | 698 +++++++++--------- 1 file changed, 348 insertions(+), 350 deletions(-) diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index 6df94d19c3..106f9447a9 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -1,350 +1,348 @@ -// // -// // Copyright (c) 2023 ZettaScale Technology -// // -// // This program and the accompanying materials are made available under the -// // terms of the Eclipse Public License 2.0 which is available at -// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// // which is available at https://www.apache.org/licenses/LICENSE-2.0. -// // -// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// // -// // Contributors: -// // ZettaScale Zenoh Team, -// // -// #[cfg(target_family = "unix")] -// mod tests { -// use async_std::prelude::FutureExt; -// use async_std::task; -// use std::any::Any; -// use std::convert::TryFrom; -// use std::sync::atomic::{AtomicUsize, Ordering}; -// use std::sync::Arc; -// use std::time::Duration; -// use zenoh_buffers::ZBuf; -// use zenoh_core::zasync_executor_init; -// use zenoh_link::Link; -// use zenoh_protocol::{ -// core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, -// zenoh::ZenohMessage, -// }; -// use zenoh_result::ZResult; -// use zenoh_transport::{ -// TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, -// TransportUnicast, -// }; - -// const TIMEOUT: Duration = Duration::from_secs(60); -// const SLEEP: Duration = Duration::from_millis(500); - -// const MSG_COUNT: usize = 16; -// const MSG_SIZE: usize = 1_024; - -// macro_rules! ztimeout { -// ($f:expr) => { -// $f.timeout(TIMEOUT).await.unwrap() -// }; -// } - -// // Transport Handler for the router -// struct SHPeer { -// zid: ZenohId, -// count: Arc, -// } - -// impl SHPeer { -// fn new(zid: ZenohId) -> Self { -// Self { -// zid, -// count: Arc::new(AtomicUsize::new(0)), -// } -// } - -// fn get_count(&self) -> usize { -// self.count.load(Ordering::SeqCst) -// } -// } - -// impl TransportEventHandler for SHPeer { -// fn new_unicast( -// &self, -// _peer: TransportPeer, -// transport: TransportUnicast, -// ) -> ZResult> { -// // Create the message to send -// let key = "test".into(); -// let payload = ZBuf::from(vec![0_u8; MSG_SIZE]); -// let channel = Channel { -// priority: Priority::Control, -// reliability: Reliability::Reliable, -// }; -// let congestion_control = CongestionControl::Block; -// let data_info = None; -// let routing_context = None; -// let reply_context = None; - -// let message = ZenohMessage::make_data( -// key, -// payload, -// channel, -// congestion_control, -// data_info, -// routing_context, -// reply_context, -// ); - -// println!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); -// for _ in 0..MSG_COUNT { -// transport.handle_message(message.clone()).unwrap(); -// } -// println!("[Simultaneous {}] ... sent {}", self.zid, MSG_COUNT); - -// let mh = Arc::new(MHPeer::new(self.count.clone())); -// Ok(mh) -// } -// } - -// struct MHPeer { -// count: Arc, -// } - -// impl MHPeer { -// fn new(count: Arc) -> Self { -// Self { count } -// } -// } - -// impl TransportPeerEventHandler for MHPeer { -// fn handle_message(&self, _msg: ZenohMessage) -> ZResult<()> { -// self.count.fetch_add(1, Ordering::AcqRel); -// Ok(()) -// } - -// fn new_link(&self, _link: Link) {} -// fn del_link(&self, _link: Link) {} -// fn closing(&self) {} -// fn closed(&self) {} - -// fn as_any(&self) -> &dyn Any { -// self -// } -// } - -// async fn transport_simultaneous(endpoint01: Vec, endpoint02: Vec) { -// /* [Peers] */ -// let peer_id01 = ZenohId::try_from([2]).unwrap(); -// let peer_id02 = ZenohId::try_from([3]).unwrap(); - -// // Create the peer01 transport manager -// let peer_sh01 = Arc::new(SHPeer::new(peer_id01)); -// let unicast = TransportManager::config_unicast().max_links(endpoint01.len()); -// let peer01_manager = TransportManager::builder() -// .whatami(WhatAmI::Peer) -// .zid(peer_id01) -// .unicast(unicast) -// .build(peer_sh01.clone()) -// .unwrap(); - -// // Create the peer02 transport manager -// let peer_sh02 = Arc::new(SHPeer::new(peer_id02)); -// let unicast = TransportManager::config_unicast().max_links(endpoint02.len()); -// let peer02_manager = TransportManager::builder() -// .whatami(WhatAmI::Peer) -// .zid(peer_id02) -// .unicast(unicast) -// .build(peer_sh02.clone()) -// .unwrap(); - -// // Add the endpoints on the peer01 -// for e in endpoint01.iter() { -// let res = ztimeout!(peer01_manager.add_listener(e.clone())); -// println!("[Simultaneous 01a] => Adding endpoint {e:?}: {res:?}"); -// assert!(res.is_ok()); -// } -// let locs = peer01_manager.get_listeners(); -// println!("[Simultaneous 01b] => Getting endpoints: {endpoint01:?} {locs:?}"); -// assert_eq!(endpoint01.len(), locs.len()); - -// // Add the endpoints on peer02 -// for e in endpoint02.iter() { -// let res = ztimeout!(peer02_manager.add_listener(e.clone())); -// println!("[Simultaneous 02a] => Adding endpoint {e:?}: {res:?}"); -// assert!(res.is_ok()); -// } -// let locs = peer02_manager.get_listeners(); -// println!("[Simultaneous 02b] => Getting endpoints: {endpoint02:?} {locs:?}"); -// assert_eq!(endpoint02.len(), locs.len()); - -// // Endpoints -// let c_ep01 = endpoint01.clone(); -// let c_ep02 = endpoint02.clone(); - -// // Peer01 -// let c_p01m = peer01_manager.clone(); -// let peer01_task = task::spawn(async move { -// // Open the transport with the second peer -// // These open should succeed -// for e in c_ep02.iter() { -// println!("[Simultaneous 01c] => Opening transport with {e:?}..."); -// let _ = ztimeout!(c_p01m.open_transport(e.clone())).unwrap(); -// } - -// // These open should fails -// for e in c_ep02.iter() { -// println!("[Simultaneous 01d] => Exceeding transport with {e:?}..."); -// let res = ztimeout!(c_p01m.open_transport(e.clone())); -// assert!(res.is_err()); -// } - -// task::sleep(SLEEP).await; - -// let tp02 = ztimeout!(async { -// let mut tp02 = None; -// while tp02.is_none() { -// task::sleep(SLEEP).await; -// println!( -// "[Simultaneous 01e] => Transports: {:?}", -// peer01_manager.get_transports() -// ); -// tp02 = peer01_manager.get_transport(&peer_id02); -// } - -// tp02.unwrap() -// }); - -// // Wait for the links to be properly established -// ztimeout!(async { -// let expected = endpoint01.len() + c_ep02.len(); -// let mut tl02 = vec![]; -// while tl02.len() != expected { -// task::sleep(SLEEP).await; -// tl02 = tp02.get_links().unwrap(); -// println!("[Simultaneous 01f] => Links {}/{}", tl02.len(), expected); -// } -// }); - -// // Wait for the messages to arrive to peer 01 -// ztimeout!(async { -// let mut check = 0; -// while check != MSG_COUNT { -// task::sleep(SLEEP).await; -// check = peer_sh01.get_count(); -// println!("[Simultaneous 01g] => Received {check:?}/{MSG_COUNT:?}"); -// } -// }); -// }); - -// // Peer02 -// let c_p02m = peer02_manager.clone(); -// let peer02_task = task::spawn(async move { -// // Open the transport with the first peer -// // These open should succeed -// for e in c_ep01.iter() { -// println!("[Simultaneous 02c] => Opening transport with {e:?}..."); -// let _ = ztimeout!(c_p02m.open_transport(e.clone())).unwrap(); -// } - -// // These open should fails -// for e in c_ep01.iter() { -// println!("[Simultaneous 02d] => Exceeding transport with {e:?}..."); -// let res = ztimeout!(c_p02m.open_transport(e.clone())); -// assert!(res.is_err()); -// } - -// // Wait a little bit -// task::sleep(SLEEP).await; - -// let tp01 = ztimeout!(async { -// let mut tp01 = None; -// while tp01.is_none() { -// task::sleep(SLEEP).await; -// println!( -// "[Simultaneous 02e] => Transports: {:?}", -// peer02_manager.get_transports() -// ); -// tp01 = peer02_manager.get_transport(&peer_id01); -// } -// tp01.unwrap() -// }); - -// // Wait for the links to be properly established -// ztimeout!(async { -// let expected = c_ep01.len() + endpoint02.len(); -// let mut tl01 = vec![]; -// while tl01.len() != expected { -// task::sleep(SLEEP).await; -// tl01 = tp01.get_links().unwrap(); -// println!("[Simultaneous 02f] => Links {}/{}", tl01.len(), expected); -// } -// }); - -// // Wait for the messages to arrive to peer 02 -// ztimeout!(async { -// let mut check = 0; -// while check != MSG_COUNT { -// task::sleep(SLEEP).await; -// check = peer_sh02.get_count(); -// println!("[Simultaneous 02g] => Received {check:?}/{MSG_COUNT:?}"); -// } -// }); -// }); - -// println!("[Simultaneous] => Waiting for peer01 and peer02 tasks..."); -// peer01_task.join(peer02_task).await; -// println!("[Simultaneous] => Waiting for peer01 and peer02 tasks... DONE\n"); - -// // Wait a little bit -// task::sleep(SLEEP).await; -// } - -// #[cfg(feature = "transport_tcp")] -// #[test] -// fn transport_tcp_simultaneous() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let endpoint01: Vec = vec![ -// format!("tcp/127.0.0.1:{}", 15000).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 15001).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 15002).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 15003).parse().unwrap(), -// ]; -// let endpoint02: Vec = vec![ -// format!("tcp/127.0.0.1:{}", 15010).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 15011).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 15012).parse().unwrap(), -// format!("tcp/127.0.0.1:{}", 15013).parse().unwrap(), -// ]; - -// task::block_on(async { -// transport_simultaneous(endpoint01, endpoint02).await; -// }); -// } - -// #[cfg(feature = "transport_ws")] -// #[test] -// fn transport_ws_simultaneous() { -// let _ = env_logger::try_init(); -// task::block_on(async { -// zasync_executor_init!(); -// }); - -// let endpoint01: Vec = vec![ -// format!("ws/127.0.0.1:{}", 15020).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 15021).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 15022).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 15023).parse().unwrap(), -// ]; -// let endpoint02: Vec = vec![ -// format!("ws/127.0.0.1:{}", 15030).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 15031).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 15032).parse().unwrap(), -// format!("ws/127.0.0.1:{}", 15033).parse().unwrap(), -// ]; - -// task::block_on(async { -// transport_simultaneous(endpoint01, endpoint02).await; -// }); -// } -// } +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#[cfg(target_family = "unix")] +mod tests { + use async_std::prelude::FutureExt; + use async_std::task; + use std::any::Any; + use std::convert::TryFrom; + use std::sync::atomic::{AtomicUsize, Ordering}; + use std::sync::Arc; + use std::time::Duration; + use zenoh_core::zasync_executor_init; + use zenoh_link::Link; + use zenoh_protocol::{ + core::{CongestionControl, Encoding, EndPoint, Priority, WhatAmI, ZenohId}, + network::{ + push::ext::{NodeIdType, QoSType}, + NetworkMessage, Push, + }, + zenoh_new::Put, + }; + use zenoh_result::ZResult; + use zenoh_transport::{ + TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, + TransportUnicast, + }; + + const TIMEOUT: Duration = Duration::from_secs(60); + const SLEEP: Duration = Duration::from_millis(500); + + const MSG_COUNT: usize = 16; + const MSG_SIZE: usize = 1_024; + + macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; + } + + // Transport Handler for the router + struct SHPeer { + zid: ZenohId, + count: Arc, + } + + impl SHPeer { + fn new(zid: ZenohId) -> Self { + Self { + zid, + count: Arc::new(AtomicUsize::new(0)), + } + } + + fn get_count(&self) -> usize { + self.count.load(Ordering::SeqCst) + } + } + + impl TransportEventHandler for SHPeer { + fn new_unicast( + &self, + _peer: TransportPeer, + transport: TransportUnicast, + ) -> ZResult> { + // Create the message to send + let message: NetworkMessage = Push { + wire_expr: "test".into(), + ext_qos: QoSType::new(Priority::Control, CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: vec![0u8; MSG_SIZE].into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + + println!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); + for _ in 0..MSG_COUNT { + transport.handle_message(message.clone()).unwrap(); + } + println!("[Simultaneous {}] ... sent {}", self.zid, MSG_COUNT); + + let mh = Arc::new(MHPeer::new(self.count.clone())); + Ok(mh) + } + } + + struct MHPeer { + count: Arc, + } + + impl MHPeer { + fn new(count: Arc) -> Self { + Self { count } + } + } + + impl TransportPeerEventHandler for MHPeer { + fn handle_message(&self, _msg: NetworkMessage) -> ZResult<()> { + self.count.fetch_add(1, Ordering::AcqRel); + Ok(()) + } + + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } + } + + async fn transport_simultaneous(endpoint01: Vec, endpoint02: Vec) { + /* [Peers] */ + let peer_id01 = ZenohId::try_from([2]).unwrap(); + let peer_id02 = ZenohId::try_from([3]).unwrap(); + + // Create the peer01 transport manager + let peer_sh01 = Arc::new(SHPeer::new(peer_id01)); + let unicast = TransportManager::config_unicast().max_links(endpoint01.len()); + let peer01_manager = TransportManager::builder() + .whatami(WhatAmI::Peer) + .zid(peer_id01) + .unicast(unicast) + .build(peer_sh01.clone()) + .unwrap(); + + // Create the peer02 transport manager + let peer_sh02 = Arc::new(SHPeer::new(peer_id02)); + let unicast = TransportManager::config_unicast().max_links(endpoint02.len()); + let peer02_manager = TransportManager::builder() + .whatami(WhatAmI::Peer) + .zid(peer_id02) + .unicast(unicast) + .build(peer_sh02.clone()) + .unwrap(); + + // Add the endpoints on the peer01 + for e in endpoint01.iter() { + let res = ztimeout!(peer01_manager.add_listener(e.clone())); + println!("[Simultaneous 01a] => Adding endpoint {e:?}: {res:?}"); + assert!(res.is_ok()); + } + let locs = peer01_manager.get_listeners(); + println!("[Simultaneous 01b] => Getting endpoints: {endpoint01:?} {locs:?}"); + assert_eq!(endpoint01.len(), locs.len()); + + // Add the endpoints on peer02 + for e in endpoint02.iter() { + let res = ztimeout!(peer02_manager.add_listener(e.clone())); + println!("[Simultaneous 02a] => Adding endpoint {e:?}: {res:?}"); + assert!(res.is_ok()); + } + let locs = peer02_manager.get_listeners(); + println!("[Simultaneous 02b] => Getting endpoints: {endpoint02:?} {locs:?}"); + assert_eq!(endpoint02.len(), locs.len()); + + // Endpoints + let c_ep01 = endpoint01.clone(); + let c_ep02 = endpoint02.clone(); + + // Peer01 + let c_p01m = peer01_manager.clone(); + let peer01_task = task::spawn(async move { + // Open the transport with the second peer + // These open should succeed + for e in c_ep02.iter() { + println!("[Simultaneous 01c] => Opening transport with {e:?}..."); + let _ = ztimeout!(c_p01m.open_transport(e.clone())).unwrap(); + } + + // These open should fails + for e in c_ep02.iter() { + println!("[Simultaneous 01d] => Exceeding transport with {e:?}..."); + let res = ztimeout!(c_p01m.open_transport(e.clone())); + assert!(res.is_err()); + } + + task::sleep(SLEEP).await; + + let tp02 = ztimeout!(async { + let mut tp02 = None; + while tp02.is_none() { + task::sleep(SLEEP).await; + println!( + "[Simultaneous 01e] => Transports: {:?}", + peer01_manager.get_transports() + ); + tp02 = peer01_manager.get_transport(&peer_id02); + } + + tp02.unwrap() + }); + + // Wait for the links to be properly established + ztimeout!(async { + let expected = endpoint01.len() + c_ep02.len(); + let mut tl02 = vec![]; + while tl02.len() != expected { + task::sleep(SLEEP).await; + tl02 = tp02.get_links().unwrap(); + println!("[Simultaneous 01f] => Links {}/{}", tl02.len(), expected); + } + }); + + // Wait for the messages to arrive to peer 01 + ztimeout!(async { + let mut check = 0; + while check != MSG_COUNT { + task::sleep(SLEEP).await; + check = peer_sh01.get_count(); + println!("[Simultaneous 01g] => Received {check:?}/{MSG_COUNT:?}"); + } + }); + }); + + // Peer02 + let c_p02m = peer02_manager.clone(); + let peer02_task = task::spawn(async move { + // Open the transport with the first peer + // These open should succeed + for e in c_ep01.iter() { + println!("[Simultaneous 02c] => Opening transport with {e:?}..."); + let _ = ztimeout!(c_p02m.open_transport(e.clone())).unwrap(); + } + + // These open should fails + for e in c_ep01.iter() { + println!("[Simultaneous 02d] => Exceeding transport with {e:?}..."); + let res = ztimeout!(c_p02m.open_transport(e.clone())); + assert!(res.is_err()); + } + + // Wait a little bit + task::sleep(SLEEP).await; + + let tp01 = ztimeout!(async { + let mut tp01 = None; + while tp01.is_none() { + task::sleep(SLEEP).await; + println!( + "[Simultaneous 02e] => Transports: {:?}", + peer02_manager.get_transports() + ); + tp01 = peer02_manager.get_transport(&peer_id01); + } + tp01.unwrap() + }); + + // Wait for the links to be properly established + ztimeout!(async { + let expected = c_ep01.len() + endpoint02.len(); + let mut tl01 = vec![]; + while tl01.len() != expected { + task::sleep(SLEEP).await; + tl01 = tp01.get_links().unwrap(); + println!("[Simultaneous 02f] => Links {}/{}", tl01.len(), expected); + } + }); + + // Wait for the messages to arrive to peer 02 + ztimeout!(async { + let mut check = 0; + while check != MSG_COUNT { + task::sleep(SLEEP).await; + check = peer_sh02.get_count(); + println!("[Simultaneous 02g] => Received {check:?}/{MSG_COUNT:?}"); + } + }); + }); + + println!("[Simultaneous] => Waiting for peer01 and peer02 tasks..."); + peer01_task.join(peer02_task).await; + println!("[Simultaneous] => Waiting for peer01 and peer02 tasks... DONE\n"); + + // Wait a little bit + task::sleep(SLEEP).await; + } + + #[cfg(feature = "transport_tcp")] + #[test] + fn transport_tcp_simultaneous() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint01: Vec = vec![ + format!("tcp/127.0.0.1:{}", 15000).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 15001).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 15002).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 15003).parse().unwrap(), + ]; + let endpoint02: Vec = vec![ + format!("tcp/127.0.0.1:{}", 15010).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 15011).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 15012).parse().unwrap(), + format!("tcp/127.0.0.1:{}", 15013).parse().unwrap(), + ]; + + task::block_on(async { + transport_simultaneous(endpoint01, endpoint02).await; + }); + } + + #[cfg(feature = "transport_ws")] + #[test] + fn transport_ws_simultaneous() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint01: Vec = vec![ + format!("ws/127.0.0.1:{}", 15020).parse().unwrap(), + format!("ws/127.0.0.1:{}", 15021).parse().unwrap(), + format!("ws/127.0.0.1:{}", 15022).parse().unwrap(), + format!("ws/127.0.0.1:{}", 15023).parse().unwrap(), + ]; + let endpoint02: Vec = vec![ + format!("ws/127.0.0.1:{}", 15030).parse().unwrap(), + format!("ws/127.0.0.1:{}", 15031).parse().unwrap(), + format!("ws/127.0.0.1:{}", 15032).parse().unwrap(), + format!("ws/127.0.0.1:{}", 15033).parse().unwrap(), + ]; + + task::block_on(async { + transport_simultaneous(endpoint01, endpoint02).await; + }); + } +} From 79f4520cb0c16c3a8a4ca4fe97ac3f36b8329415 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 4 Jul 2023 18:25:30 +0200 Subject: [PATCH 162/203] Add From for WireExpr<'_> --- commons/zenoh-protocol/src/core/wire_expr.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/commons/zenoh-protocol/src/core/wire_expr.rs b/commons/zenoh-protocol/src/core/wire_expr.rs index 9522586e10..7b0dee7471 100644 --- a/commons/zenoh-protocol/src/core/wire_expr.rs +++ b/commons/zenoh-protocol/src/core/wire_expr.rs @@ -143,6 +143,16 @@ impl TryInto for WireExpr<'_> { } } +impl From for WireExpr<'_> { + fn from(scope: ExprId) -> Self { + Self { + scope, + suffix: "".into(), + mapping: Mapping::Sender, + } + } +} + impl<'a> From<&'a OwnedKeyExpr> for WireExpr<'a> { fn from(val: &'a OwnedKeyExpr) -> Self { WireExpr { From 395bdac01536faeddbc909b073e90617dd4bb793 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 12 Jul 2023 14:57:57 +0200 Subject: [PATCH 163/203] Add SHM extension to Put message --- commons/zenoh-codec/src/zenoh_new/mod.rs | 31 +++++++++++++++++++++ commons/zenoh-codec/src/zenoh_new/put.rs | 19 +++++++++++++ commons/zenoh-protocol/src/zenoh_new/del.rs | 2 +- commons/zenoh-protocol/src/zenoh_new/mod.rs | 15 ++++++++++ commons/zenoh-protocol/src/zenoh_new/put.rs | 17 ++++++++++- 5 files changed, 82 insertions(+), 2 deletions(-) diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs index c805164b82..4d06a2bfb9 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -24,6 +24,8 @@ use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; +#[cfg(feature = "shared-memory")] +use zenoh_protocol::common::ZExtUnit; use zenoh_protocol::{ common::{imsg, ZExtZBufHeader}, core::ZenohId, @@ -194,3 +196,32 @@ where Ok((ext::SourceInfoType { zid, eid, sn }, more)) } } + +// Extension: Shm +#[cfg(feature = "shared-memory")] +impl WCodec<(&ext::ShmType<{ ID }>, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::ShmType<{ ID }>, bool)) -> Self::Output { + let (_, more) = x; + let header: ZExtUnit<{ ID }> = ZExtUnit::new(); + self.write(&mut *writer, (&header, more))?; + Ok(()) + } +} + +#[cfg(feature = "shared-memory")] +impl RCodec<(ext::ShmType<{ ID }>, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::ShmType<{ ID }>, bool), Self::Error> { + let (_, more): (ZExtUnit<{ ID }>, bool) = self.read(&mut *reader)?; + Ok((ext::ShmType, more)) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/put.rs b/commons/zenoh-codec/src/zenoh_new/put.rs index 2e015268fb..ea173d47cb 100644 --- a/commons/zenoh-codec/src/zenoh_new/put.rs +++ b/commons/zenoh-codec/src/zenoh_new/put.rs @@ -43,6 +43,10 @@ where header |= flag::E; } let mut n_exts = (x.ext_sinfo.is_some()) as u8 + (x.ext_unknown.len() as u8); + #[cfg(feature = "shared-memory")] + { + n_exts += x.ext_shm.is_some() as u8; + } if n_exts != 0 { header |= flag::Z; } @@ -61,6 +65,11 @@ where n_exts -= 1; self.write(&mut *writer, (sinfo, n_exts != 0))?; } + #[cfg(feature = "shared-memory")] + if let Some(eshm) = x.ext_shm.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (eshm, n_exts != 0))?; + } for u in x.ext_unknown.iter() { n_exts -= 1; self.write(&mut *writer, (u, n_exts != 0))?; @@ -111,6 +120,8 @@ where // Extensions let mut ext_sinfo: Option = None; + #[cfg(feature = "shared-memory")] + let mut ext_shm: Option = None; let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); @@ -123,6 +134,12 @@ where ext_sinfo = Some(s); has_ext = ext; } + #[cfg(feature = "shared-memory")] + ext::Shm::ID => { + let (s, ext): (ext::ShmType, bool) = eodec.read(&mut *reader)?; + ext_shm = Some(s); + has_ext = ext; + } _ => { let (u, ext) = extension::read(reader, "Put", ext)?; ext_unknown.push(u); @@ -139,6 +156,8 @@ where timestamp, encoding, ext_sinfo, + #[cfg(feature = "shared-memory")] + ext_shm, ext_unknown, payload, }) diff --git a/commons/zenoh-protocol/src/zenoh_new/del.rs b/commons/zenoh-protocol/src/zenoh_new/del.rs index 553ce3007a..6c67129516 100644 --- a/commons/zenoh-protocol/src/zenoh_new/del.rs +++ b/commons/zenoh-protocol/src/zenoh_new/del.rs @@ -25,7 +25,7 @@ use uhlc::Timestamp; /// /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ -/// |Z|X|T| PUT | +/// |Z|X|T| DEL | /// +-+-+-+---------+ /// ~ ts: ~ if T==1 /// +---------------+ diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index 6707f2fde1..ead3ac5a19 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -191,4 +191,19 @@ pub mod ext { Self { zid, eid, sn } } } + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// +-+-+-+-+-+-+-+-+ + #[cfg(feature = "shared-memory")] + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct ShmType; + + #[cfg(feature = "shared-memory")] + impl ShmType<{ ID }> { + #[cfg(feature = "test")] + pub const fn rand() -> Self { + Self + } + } } diff --git a/commons/zenoh-protocol/src/zenoh_new/put.rs b/commons/zenoh-protocol/src/zenoh_new/put.rs index dd5207fc24..83b5920461 100644 --- a/commons/zenoh-protocol/src/zenoh_new/put.rs +++ b/commons/zenoh-protocol/src/zenoh_new/put.rs @@ -48,17 +48,28 @@ pub struct Put { pub timestamp: Option, pub encoding: Encoding, pub ext_sinfo: Option, + #[cfg(feature = "shared-memory")] + pub ext_shm: Option, pub ext_unknown: Vec, pub payload: ZBuf, } pub mod ext { + #[cfg(feature = "shared-memory")] + use crate::{common::ZExtUnit, zextunit}; use crate::{common::ZExtZBuf, zextzbuf}; /// # SourceInfo extension /// Used to carry additional information about the source of data pub type SourceInfo = zextzbuf!(0x1, false); pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; + + /// # Shared Memory extension + /// Used to carry additional information about the shared-memory layour of data + #[cfg(feature = "shared-memory")] + pub type Shm = zextunit!(0x2, true); + #[cfg(feature = "shared-memory")] + pub type ShmType = crate::zenoh_new::ext::ShmType<{ Shm::ID }>; } impl Put { @@ -75,7 +86,8 @@ impl Put { }); let encoding = Encoding::rand(); let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); - let payload = ZBuf::rand(rng.gen_range(1..=64)); + #[cfg(feature = "shared-memory")] + let ext_shm = rng.gen_bool(0.5).then_some(ext::ShmType::rand()); let mut ext_unknown = Vec::new(); for _ in 0..rng.gen_range(0..4) { ext_unknown.push(ZExtUnknown::rand2( @@ -83,11 +95,14 @@ impl Put { false, )); } + let payload = ZBuf::rand(rng.gen_range(1..=64)); Self { timestamp, encoding, ext_sinfo, + #[cfg(feature = "shared-memory")] + ext_shm, ext_unknown, payload, } From 43521010b50905e22cd8599375ed58f953d0c415 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 12 Jul 2023 18:46:52 +0200 Subject: [PATCH 164/203] Renable SHM for Put operations --- commons/zenoh-codec/src/core/zbuf.rs | 108 ---------- commons/zenoh-codec/src/core/zslice.rs | 6 - commons/zenoh-codec/src/zenoh/data.rs | 45 +---- commons/zenoh-protocol/src/zenoh/data.rs | 6 - commons/zenoh-protocol/src/zenoh_new/mod.rs | 4 + commons/zenoh-shm/src/lib.rs | 37 ---- io/zenoh-transport/src/common/pipeline.rs | 6 + io/zenoh-transport/src/shm.rs | 191 +++++++----------- .../tests/unicast_concurrent.rs | 4 + io/zenoh-transport/tests/unicast_conduits.rs | 2 + .../tests/unicast_defragmentation.rs | 2 + .../tests/unicast_intermittent.rs | 2 + io/zenoh-transport/tests/unicast_shm.rs | 113 ++++++----- .../tests/unicast_simultaneous.rs | 2 + io/zenoh-transport/tests/unicast_transport.rs | 10 +- zenoh/src/publication.rs | 4 + zenoh/src/sample.rs | 2 - 17 files changed, 161 insertions(+), 383 deletions(-) diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index 0485f2d6d7..5bac30683a 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -17,11 +17,6 @@ use zenoh_buffers::{ writer::{DidntWrite, Writer}, SplitBuffer, ZBuf, }; -#[cfg(feature = "shared-memory")] -use { - crate::Zenoh080Condition, core::any::TypeId, zenoh_buffers::ZSlice, - zenoh_shm::SharedMemoryBufInfoSerialized, -}; // ZBuf bounded macro_rules! zbuf_impl { @@ -87,106 +82,3 @@ where zodec.read(&mut *reader) } } - -// ZBuf sliced -#[cfg(feature = "shared-memory")] -struct Zenoh080Sliced { - codec: Zenoh080, -} - -#[cfg(feature = "shared-memory")] -impl WCodec<&ZBuf, &mut W> for Zenoh080Sliced -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ZBuf) -> Self::Output { - self.codec.write(&mut *writer, x.zslices().count())?; - - for zs in x.zslices() { - if zs.buf.as_any().type_id() == TypeId::of::() { - self.codec - .write(&mut *writer, super::zslice::kind::SHM_INFO)?; - } else { - self.codec.write(&mut *writer, super::zslice::kind::RAW)?; - } - - self.codec.write(&mut *writer, zs)?; - } - - Ok(()) - } -} - -#[cfg(feature = "shared-memory")] -impl RCodec for Zenoh080Sliced -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let num: usize = self.codec.read(&mut *reader)?; - let mut zbuf = ZBuf::empty(); - for _ in 0..num { - let kind: u8 = self.codec.read(&mut *reader)?; - match kind { - super::zslice::kind::RAW => { - let len: usize = self.codec.read(&mut *reader)?; - reader.read_zslices(len, |s| zbuf.push_zslice(s))?; - } - super::zslice::kind::SHM_INFO => { - let bytes: Vec = self.codec.read(&mut *reader)?; - let shm_info: SharedMemoryBufInfoSerialized = bytes.into(); - let zslice: ZSlice = shm_info.into(); - zbuf.push_zslice(zslice); - } - _ => return Err(DidntRead), - } - } - Ok(zbuf) - } -} - -#[cfg(feature = "shared-memory")] -impl WCodec<&ZBuf, &mut W> for Zenoh080Condition -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ZBuf) -> Self::Output { - let is_sliced = self.condition; - - if is_sliced { - let codec = Zenoh080Sliced { - codec: Zenoh080::new(), - }; - codec.write(&mut *writer, x) - } else { - self.codec.write(&mut *writer, x) - } - } -} - -#[cfg(feature = "shared-memory")] -impl RCodec for Zenoh080Condition -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let is_sliced = self.condition; - - if is_sliced { - let codec = Zenoh080Sliced { - codec: Zenoh080::new(), - }; - codec.read(&mut *reader) - } else { - self.codec.read(&mut *reader) - } - } -} diff --git a/commons/zenoh-codec/src/core/zslice.rs b/commons/zenoh-codec/src/core/zslice.rs index c8cec740e3..cea0961b51 100644 --- a/commons/zenoh-codec/src/core/zslice.rs +++ b/commons/zenoh-codec/src/core/zslice.rs @@ -18,12 +18,6 @@ use zenoh_buffers::{ ZSlice, }; -#[cfg(feature = "shared-memory")] -pub(crate) mod kind { - pub(crate) const RAW: u8 = 0; - pub(crate) const SHM_INFO: u8 = 1; -} - // ZSlice - Bounded macro_rules! zslice_impl { ($bound:ty) => { diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs index 31ae2355ac..9833183cd0 100644 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ b/commons/zenoh-codec/src/zenoh/data.rs @@ -97,10 +97,6 @@ where fn write(self, writer: &mut W, x: &DataInfo) -> Self::Output { // Options let mut options: u8 = 0; - #[cfg(feature = "shared-memory")] - if x.sliced { - options |= zmsg::data::info::SLICED; - } if x.kind != SampleKind::Put { options |= zmsg::data::info::KIND; } @@ -147,10 +143,6 @@ where fn read(self, reader: &mut R) -> Result { let mut info = DataInfo::default(); let options: u8 = self.read(&mut *reader)?; - #[cfg(feature = "shared-memory")] - { - info.sliced = imsg::has_flag(options, zmsg::data::info::SLICED); - } if imsg::has_flag(options, zmsg::data::info::KIND) { let kind: u8 = self.read(&mut *reader)?; info.kind = kind.try_into().map_err(|_| DidntRead)?; @@ -204,27 +196,11 @@ where // Body self.write(&mut *writer, &x.key)?; - #[cfg(feature = "shared-memory")] - let mut sliced = false; - if let Some(data_info) = x.data_info.as_ref() { self.write(&mut *writer, data_info)?; - #[cfg(feature = "shared-memory")] - { - sliced = data_info.sliced; - } - } - - #[cfg(feature = "shared-memory")] - { - let codec = Zenoh080Condition::new(sliced); - codec.write(&mut *writer, &x.payload)?; } - #[cfg(not(feature = "shared-memory"))] - { - self.write(&mut *writer, &x.payload)?; - } + self.write(&mut *writer, &x.payload)?; Ok(()) } @@ -271,31 +247,14 @@ where let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); let key: WireExpr<'static> = ccond.read(&mut *reader)?; - #[cfg(feature = "shared-memory")] - let mut is_sliced = false; - let data_info = if imsg::has_flag(self.header, zmsg::flag::I) { let di: DataInfo = self.codec.read(&mut *reader)?; - #[cfg(feature = "shared-memory")] - { - is_sliced = di.sliced; - } Some(di) } else { None }; - let payload: ZBuf = { - #[cfg(feature = "shared-memory")] - { - let codec = Zenoh080Condition::new(is_sliced); - codec.read(&mut *reader)? - } - #[cfg(not(feature = "shared-memory"))] - { - self.codec.read(&mut *reader)? - } - }; + let payload: ZBuf = self.codec.read(&mut *reader)?; Ok(Data { key, diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs index 23d78d5691..2c770ee5fc 100644 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ b/commons/zenoh-protocol/src/zenoh/data.rs @@ -150,8 +150,6 @@ pub type SourceSn = u64; #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct DataInfo { - #[cfg(feature = "shared-memory")] - pub sliced: bool, pub kind: SampleKind, pub encoding: Option, pub timestamp: Option, @@ -166,8 +164,6 @@ impl DataInfo { let mut rng = rand::thread_rng(); - #[cfg(feature = "shared-memory")] - let sliced = rng.gen_bool(0.5); let kind = SampleKind::try_from(rng.gen_range(0..=1)).unwrap(); let encoding = rng.gen_bool(0.5).then(Encoding::rand); let timestamp = rng.gen_bool(0.5).then(|| { @@ -179,8 +175,6 @@ impl DataInfo { let source_sn = rng.gen_bool(0.5).then(|| rng.gen()); Self { - #[cfg(feature = "shared-memory")] - sliced, kind, encoding, timestamp, diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index ead3ac5a19..962bbd3094 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -201,6 +201,10 @@ pub mod ext { #[cfg(feature = "shared-memory")] impl ShmType<{ ID }> { + pub const fn new() -> Self { + Self + } + #[cfg(feature = "test")] pub const fn rand() -> Self { Self diff --git a/commons/zenoh-shm/src/lib.rs b/commons/zenoh-shm/src/lib.rs index fa267be7ae..f76d4c4f92 100644 --- a/commons/zenoh-shm/src/lib.rs +++ b/commons/zenoh-shm/src/lib.rs @@ -499,43 +499,6 @@ impl fmt::Debug for SharedMemoryManager { } // Buffer impls -// - SharedMemoryBufInfoSerialized -#[derive(Debug)] -#[repr(transparent)] -pub struct SharedMemoryBufInfoSerialized(Vec); - -impl AsRef<[u8]> for SharedMemoryBufInfoSerialized { - fn as_ref(&self) -> &[u8] { - self.0.as_slice() - } -} - -impl AsMut<[u8]> for SharedMemoryBufInfoSerialized { - fn as_mut(&mut self) -> &mut [u8] { - self.0.as_mut_slice() - } -} - -impl ZSliceBuffer for SharedMemoryBufInfoSerialized { - fn as_slice(&self) -> &[u8] { - self.as_ref() - } - - fn as_mut_slice(&mut self) -> &mut [u8] { - self.as_mut() - } - - fn as_any(&self) -> &dyn Any { - self - } -} - -impl From> for SharedMemoryBufInfoSerialized { - fn from(v: Vec) -> Self { - Self(v) - } -} - // - SharedMemoryBuf impl AsRef<[u8]> for SharedMemoryBuf { fn as_ref(&self) -> &[u8] { diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 727f9f32d5..f7a1585d14 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -743,6 +743,8 @@ mod tests { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload, }), @@ -870,6 +872,8 @@ mod tests { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload, }), @@ -979,6 +983,8 @@ mod tests { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload, }), diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index 18b0116eef..a8c75f683a 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -12,82 +12,46 @@ // ZettaScale Zenoh Team, // use async_std::{sync::RwLock, task}; -use std::any::TypeId; use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZBuf, ZSlice}; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_core::{zasyncread, zasyncwrite, zerror}; -use zenoh_protocol::zenoh::*; -use zenoh_result::ZResult; -use zenoh_shm::{ - SharedMemoryBuf, SharedMemoryBufInfo, SharedMemoryBufInfoSerialized, SharedMemoryReader, +use zenoh_protocol::{ + network::{NetworkBody, NetworkMessage, Push}, + zenoh_new::{ + put::{ext::ShmType, Put}, + PushBody, + }, }; +use zenoh_result::ZResult; +use zenoh_shm::{SharedMemoryBuf, SharedMemoryBufInfo, SharedMemoryReader}; -macro_rules! unset_sliced { - ($msg:expr, $data_info:expr) => { - // Set the right data info SHM parameters - if let Some(di) = $data_info { - di.sliced = false; - if di == &DataInfo::default() { - *$data_info = None; - } - } - }; -} +// ShmBuf -> ShmInfo +pub fn map_zmsg_to_shminfo(msg: &mut NetworkMessage) -> ZResult { + let mut res = false; -macro_rules! set_sliced { - ($msg:expr, $data_info:expr) => { - match $data_info { - Some(di) => { - // Just update the is_shm field. This field can be - // then used at receiver side to identify that the - // actual content is stored in shared memory - di.sliced = true; - } - None => { - // Create the DataInfo content - let di = DataInfo { - sliced: true, - ..Default::default() - }; - *$data_info = Some(di); - } + if let NetworkBody::Push(Push { + payload: PushBody::Put(Put { + payload, ext_shm, .. + }), + .. + }) = &mut msg.body + { + res |= map_zbuf_to_shminfo(payload)?; + if res { + *ext_shm = Some(ShmType::new()); } - }; -} - -#[cold] -#[inline(never)] -pub fn map_zslice_to_shmbuf( - zslice: &mut ZSlice, - shmr: &RwLock, -) -> ZResult { - let ZSlice { buf, .. } = zslice; - // Deserialize the shmb info into shm buff - let codec = Zenoh080::new(); - let mut reader = buf.as_slice().reader(); - let shmbinfo: SharedMemoryBufInfo = codec.read(&mut reader).map_err(|e| zerror!("{:?}", e))?; - - // First, try in read mode allowing concurrenct lookups - let r_guard = task::block_on(async { zasyncread!(shmr) }); - let smb = r_guard.try_read_shmbuf(&shmbinfo).or_else(|_| { - drop(r_guard); - let mut w_guard = task::block_on(async { zasyncwrite!(shmr) }); - w_guard.read_shmbuf(&shmbinfo) - })?; - - // Replace the content of the slice - let zs: ZSlice = smb.into(); - *zslice = zs; + } - Ok(true) + Ok(res) } -pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &RwLock) -> ZResult { +pub fn map_zbuf_to_shminfo(zbuf: &mut ZBuf) -> ZResult { let mut res = false; for zs in zbuf.zslices_mut() { let ZSlice { buf, .. } = zs; - if buf.as_any().type_id() == TypeId::of::() { - res |= map_zslice_to_shmbuf(zs, shmr)?; + if let Some(shmb) = buf.as_any().downcast_ref::() { + *zs = map_zslice_to_shminfo(shmb)?; + res = true; } } Ok(res) @@ -98,90 +62,71 @@ pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &RwLock) -> pub fn map_zslice_to_shminfo(shmb: &SharedMemoryBuf) -> ZResult { // Serialize the shmb info let codec = Zenoh080::new(); - let mut bytes = vec![]; - let mut writer = bytes.writer(); + let mut info = vec![]; + let mut writer = info.writer(); codec .write(&mut writer, &shmb.info) .map_err(|e| zerror!("{:?}", e))?; - let info: SharedMemoryBufInfoSerialized = bytes.into(); // Increase the reference count so to keep the SharedMemoryBuf valid shmb.inc_ref_count(); // Replace the content of the slice Ok(info.into()) } -pub fn map_zbuf_to_shminfo(zbuf: &mut ZBuf) -> ZResult { - let mut res = false; - for zs in zbuf.zslices_mut() { - let ZSlice { buf, .. } = zs; - if let Some(shmb) = buf.as_any().downcast_ref::() { - *zs = map_zslice_to_shminfo(shmb)?; - res = true; - } - } - Ok(res) -} - +// ShmInfo -> ShmBuf pub fn map_zmsg_to_shmbuf( - msg: &mut ZenohMessage, + msg: &mut NetworkMessage, shmr: &RwLock, ) -> ZResult { let mut res = false; - if let ZenohBody::Data(Data { - payload, data_info, .. - }) = &mut msg.body - { - res |= map_zbuf_to_shmbuf(payload, shmr)?; - if res { - unset_sliced!(msg, data_info); - } - } else if let ZenohBody::Query(Query { - body: Some(body), .. + if let NetworkBody::Push(Push { + payload: PushBody::Put(Put { + payload, ext_shm, .. + }), + .. }) = &mut msg.body { - res |= map_zbuf_to_shmbuf(&mut body.payload, shmr)?; - if res { - body.data_info.sliced = false; + if ext_shm.is_some() { + res |= map_zbuf_to_shmbuf(payload, shmr)?; + *ext_shm = None; } } Ok(res) } -pub fn map_zmsg_to_shminfo(msg: &mut ZenohMessage) -> ZResult { +pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &RwLock) -> ZResult { let mut res = false; - - if let ZenohBody::Data(Data { - payload, data_info, .. - }) = &mut msg.body - { - res |= map_zbuf_to_shminfo(payload)?; - if res { - set_sliced!(msg, data_info); - } - } else if let ZenohBody::Query(Query { - body: Some(body), .. - }) = &mut msg.body - { - res |= map_zbuf_to_shminfo(&mut body.payload)?; - if res { - body.data_info.sliced = true; - } + for zs in zbuf.zslices_mut() { + res |= map_zslice_to_shmbuf(zs, shmr)?; } - Ok(res) } -// Unused for the time being -// -// #[cfg(feature = "shared-memory")] -// impl TransportMessage { -// pub(crate) fn map_to_shmbuf(&mut self, shmr: Arc>) -> ZResult { -// Ok(false) -// } -// -// pub(crate) fn map_to_shminfo(&mut self) -> ZResult { -// Ok(false) -// } -// } +#[cold] +#[inline(never)] +pub fn map_zslice_to_shmbuf( + zslice: &mut ZSlice, + shmr: &RwLock, +) -> ZResult { + // Deserialize the shmb info into shm buff + let codec = Zenoh080::new(); + let mut reader = zslice.reader(); + + let shmbinfo: SharedMemoryBufInfo = codec.read(&mut reader).map_err(|e| zerror!("{:?}", e))?; + + // First, try in read mode allowing concurrenct lookups + let r_guard = task::block_on(async { zasyncread!(shmr) }); + let smb = r_guard.try_read_shmbuf(&shmbinfo).or_else(|_| { + drop(r_guard); + let mut w_guard = task::block_on(async { zasyncwrite!(shmr) }); + w_guard.read_shmbuf(&shmbinfo) + })?; + + // Replace the content of the slice + let zs: ZSlice = smb.into(); + *zslice = zs; + + Ok(true) +} diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index e6aba3f7d4..3586cd83d8 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -192,6 +192,8 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec, endpoint02: Vec, client_transport: TransportUn timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], } .into(), diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index d352bcfa28..7ca2748b68 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -84,6 +84,8 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], } .into(), diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index 1e3af3ad9e..a00d7e09c5 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -261,6 +261,8 @@ async fn transport_intermittent(endpoint: &EndPoint) { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], } .into(), diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index 680ef7c993..fe6ea5a034 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -23,15 +23,19 @@ mod tests { }, time::Duration, }; - use zenoh_buffers::{SplitBuffer, ZBuf}; + use zenoh_buffers::{SplitBuffer, ZSlice}; use zenoh_core::zasync_executor_init; use zenoh_link::Link; use zenoh_protocol::{ - core::{Channel, CongestionControl, EndPoint, Priority, Reliability, WhatAmI, ZenohId}, - zenoh::{Data, ZenohBody, ZenohMessage}, + core::{CongestionControl, Encoding, EndPoint, Priority, WhatAmI, ZenohId}, + network::{ + push::ext::{NodeIdType, QoSType}, + NetworkBody, NetworkMessage, Push, + }, + zenoh_new::{PushBody, Put}, }; use zenoh_result::ZResult; - use zenoh_shm::SharedMemoryManager; + use zenoh_shm::{SharedMemoryBuf, SharedMemoryManager}; use zenoh_transport::{ TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, TransportUnicast, @@ -93,14 +97,31 @@ mod tests { } impl TransportPeerEventHandler for SCPeer { - fn handle_message(&self, message: ZenohMessage) -> ZResult<()> { + fn handle_message(&self, message: NetworkMessage) -> ZResult<()> { if self.is_shm { print!("s"); } else { print!("n"); } let payload = match message.body { - ZenohBody::Data(Data { payload, .. }) => payload.contiguous().into_owned(), + NetworkBody::Push(m) => match m.payload { + PushBody::Put(Put { payload, .. }) => { + for zs in payload.zslices() { + let ZSlice { buf, .. } = zs; + if self.is_shm + && buf.as_any().downcast_ref::().is_none() + { + panic!("Expected SharedMemoryBuf"); + } else if !self.is_shm + && buf.as_any().downcast_ref::().is_some() + { + panic!("Not Expected SharedMemoryBuf"); + } + } + payload.contiguous().into_owned() + } + _ => panic!("Unsolicited message"), + }, _ => panic!("Unsolicited message"), }; assert_eq!(payload.len(), MSG_SIZE); @@ -210,28 +231,24 @@ mod tests { let bs = unsafe { sbuf.as_mut_slice() }; bs[0..8].copy_from_slice(&msg_count.to_le_bytes()); - let key = "test".into(); - let payload: ZBuf = sbuf.into(); - let channel = Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }; - let congestion_control = CongestionControl::Block; - let data_info = None; - let routing_context = None; - let reply_context = None; - - let message = ZenohMessage::make_data( - key, - payload, - channel, - congestion_control, - data_info, - routing_context, - reply_context, - ); - - peer_shm02_transport.schedule(message.clone()).unwrap(); + let message: NetworkMessage = Push { + wire_expr: "test".into(), + ext_qos: QoSType::new(Priority::default(), CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: sbuf.into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_shm: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + + peer_shm02_transport.schedule(message).unwrap(); } // Wait a little bit @@ -261,28 +278,24 @@ mod tests { let bs = unsafe { sbuf.as_mut_slice() }; bs[0..8].copy_from_slice(&msg_count.to_le_bytes()); - let key = "test".into(); - let payload: ZBuf = sbuf.into(); - let channel = Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }; - let congestion_control = CongestionControl::Block; - let data_info = None; - let routing_context = None; - let reply_context = None; - - let message = ZenohMessage::make_data( - key, - payload, - channel, - congestion_control, - data_info, - routing_context, - reply_context, - ); - - peer_net01_transport.schedule(message.clone()).unwrap(); + let message: NetworkMessage = Push { + wire_expr: "test".into(), + ext_qos: QoSType::new(Priority::default(), CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: sbuf.into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_shm: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + + peer_net01_transport.schedule(message).unwrap(); } // Wait a little bit diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index 106f9447a9..772478ea2b 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -84,6 +84,8 @@ mod tests { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], } .into(), diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 249e8736ce..e0699ce84e 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -442,6 +442,8 @@ async fn test_transport( timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], } .into(), @@ -551,18 +553,10 @@ fn transport_unicast_tcp_only() { priority: Priority::default(), reliability: Reliability::Reliable, }, - // Channel { - // priority: Priority::default(), - // reliability: Reliability::BestEffort, - // }, Channel { priority: Priority::RealTime, reliability: Reliability::Reliable, }, - // Channel { - // priority: Priority::RealTime, - // reliability: Reliability::BestEffort, - // }, ]; // Run task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); diff --git a/zenoh/src/publication.rs b/zenoh/src/publication.rs index 9073bd115e..452710bbfd 100644 --- a/zenoh/src/publication.rs +++ b/zenoh/src/publication.rs @@ -151,6 +151,8 @@ impl SyncResolve for PutBuilder<'_, '_> { timestamp, encoding: value.encoding.clone(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload: value.payload.clone(), }), @@ -439,6 +441,8 @@ impl SyncResolve for Publication<'_> { timestamp: publisher.session.runtime.new_timestamp(), encoding: value.encoding.clone(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload: value.payload.clone(), }), diff --git a/zenoh/src/sample.rs b/zenoh/src/sample.rs index d6c4daf021..a0c84f646a 100644 --- a/zenoh/src/sample.rs +++ b/zenoh/src/sample.rs @@ -188,8 +188,6 @@ impl Sample { kind: self.kind, encoding: Some(self.value.encoding), timestamp: self.timestamp, - #[cfg(feature = "shared-memory")] - sliced: false, #[cfg(feature = "unstable")] source_id: self.source_info.source_id, #[cfg(not(feature = "unstable"))] From a45be293f8221746c8b5ac6f88eda008589ff78f Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 13 Jul 2023 09:53:00 +0200 Subject: [PATCH 165/203] Fix nostd check --- commons/zenoh-codec/src/network/declare.rs | 1 + commons/zenoh-protocol/src/network/declare.rs | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/commons/zenoh-codec/src/network/declare.rs b/commons/zenoh-codec/src/network/declare.rs index 06f07ed5ad..ae3a3dd77c 100644 --- a/commons/zenoh-codec/src/network/declare.rs +++ b/commons/zenoh-codec/src/network/declare.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; +use alloc::string::String; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, HasWriter, Writer}, diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index f5298f394e..76415d52f5 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -17,6 +17,7 @@ use crate::{ network::Mapping, zextz64, zextzbuf, }; +use alloc::borrow::Cow; use core::ops::BitOr; pub use interest::*; pub use keyexpr::*; @@ -184,8 +185,6 @@ pub mod common { impl WireExprType { pub fn null() -> Self { - use std::borrow::Cow; - Self { wire_expr: WireExpr { scope: ExprId::MIN, From 18c8baff3e3c9776979b5d9032e2c2f7113b9427 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 19 Jul 2023 15:57:51 +0200 Subject: [PATCH 166/203] ZBuf sliced for SHM support --- .github/workflows/ci.yml | 15 ++-- commons/zenoh-buffers/Cargo.toml | 1 + commons/zenoh-buffers/src/zbuf.rs | 66 +++++++---------- commons/zenoh-buffers/src/zslice.rs | 53 ++++++++++---- commons/zenoh-buffers/tests/readwrite.rs | 3 +- commons/zenoh-codec/benches/codec.rs | 7 +- commons/zenoh-codec/src/core/zbuf.rs | 78 +++++++++++++++++++++ commons/zenoh-codec/src/lib.rs | 17 +++++ commons/zenoh-codec/src/zenoh_new/put.rs | 34 +++++++-- commons/zenoh-codec/tests/codec.rs | 3 +- commons/zenoh-protocol/Cargo.toml | 2 +- commons/zenoh-protocol/src/zenoh_new/mod.rs | 7 ++ commons/zenoh-sync/src/object_pool.rs | 2 - io/zenoh-transport/src/shm.rs | 11 +-- io/zenoh-transport/tests/unicast_shm.rs | 14 ++-- 15 files changed, 227 insertions(+), 86 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee5c725772..8961b33bf5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,12 +68,6 @@ jobs: command: clippy args: --all-targets --features shared-memory -- -D warnings - - name: Clippy shared-memory - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --all-targets --features shared-memory -- -D warnings - test: name: Run tests on ${{ matrix.os }} runs-on: ${{ matrix.os }} @@ -107,6 +101,15 @@ jobs: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse ASYNC_STD_THREAD_COUNT: 4 + - name: Run tests shared-memory + uses: actions-rs/cargo@v1 + with: + command: test + args: --features "transport_tcp,shared-memory" -p zenoh-transport --test unicast_shm + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + ASYNC_STD_THREAD_COUNT: 4 + - name: Run doctests uses: actions-rs/cargo@v1 with: diff --git a/commons/zenoh-buffers/Cargo.toml b/commons/zenoh-buffers/Cargo.toml index a2df1767b6..b7a7c87634 100644 --- a/commons/zenoh-buffers/Cargo.toml +++ b/commons/zenoh-buffers/Cargo.toml @@ -26,6 +26,7 @@ description = "Internal crate for zenoh." # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] default = ["std"] +shared-memory = [] std = [] test = ["rand"] diff --git a/commons/zenoh-buffers/src/zbuf.rs b/commons/zenoh-buffers/src/zbuf.rs index 0c9084f9cd..ce388f29fd 100644 --- a/commons/zenoh-buffers/src/zbuf.rs +++ b/commons/zenoh-buffers/src/zbuf.rs @@ -11,10 +11,12 @@ // Contributors: // ZettaScale Zenoh Team, // +#[cfg(feature = "shared-memory")] +use crate::ZSliceKind; use crate::{ reader::{BacktrackableReader, DidntRead, DidntSiphon, HasReader, Reader, SiphonableReader}, writer::{BacktrackableWriter, DidntWrite, HasWriter, Writer}, - SplitBuffer, ZSlice, ZSliceBuffer, + SplitBuffer, ZSlice, }; use alloc::{sync::Arc, vec::Vec}; use core::{cmp, iter, mem, num::NonZeroUsize, slice}; @@ -106,33 +108,17 @@ impl PartialEq for ZBuf { } // From impls -impl From for ZBuf { - fn from(zs: ZSlice) -> Self { - let mut zbuf = ZBuf::empty(); - zbuf.push_zslice(zs); - zbuf - } -} - -impl From> for ZBuf -where - T: ZSliceBuffer + 'static, -{ - fn from(buf: Arc) -> Self { - let zs: ZSlice = buf.into(); - Self::from(zs) - } -} - impl From for ZBuf where - T: ZSliceBuffer + 'static, + T: Into, { fn from(buf: T) -> Self { - Self::from(Arc::new(buf)) + let mut zbuf = ZBuf::empty(); + let zslice: ZSlice = buf.into(); + zbuf.push_zslice(zslice); + zbuf } } - // Reader #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct ZBufPos { @@ -240,7 +226,7 @@ impl<'a> Reader for ZBufReader<'a> { } cmp::Ordering::Equal => { let s = slice - .new_sub_slice(self.cursor.byte, slice.len()) + .subslice(self.cursor.byte, slice.len()) .ok_or(DidntRead)?; self.cursor.slice += 1; @@ -250,9 +236,7 @@ impl<'a> Reader for ZBufReader<'a> { cmp::Ordering::Greater => { let start = self.cursor.byte; self.cursor.byte += len; - slice - .new_sub_slice(start, self.cursor.byte) - .ok_or(DidntRead) + slice.subslice(start, self.cursor.byte).ok_or(DidntRead) } } } @@ -340,14 +324,14 @@ impl Iterator for ZBufSliceIterator<'_, '_> { match self.remaining.cmp(&len) { core::cmp::Ordering::Less => { let end = start + self.remaining; - let slice = slice.new_sub_slice(start, end); + let slice = slice.subslice(start, end); self.reader.cursor.byte = end; self.remaining = 0; slice } core::cmp::Ordering::Equal => { let end = start + self.remaining; - let slice = slice.new_sub_slice(start, end); + let slice = slice.subslice(start, end); self.reader.cursor.slice += 1; self.reader.cursor.byte = 0; self.remaining = 0; @@ -355,7 +339,7 @@ impl Iterator for ZBufSliceIterator<'_, '_> { } core::cmp::Ordering::Greater => { let end = start + len; - let slice = slice.new_sub_slice(start, end); + let slice = slice.subslice(start, end); self.reader.cursor.slice += 1; self.reader.cursor.byte = 0; self.remaining -= len; @@ -426,6 +410,8 @@ impl Writer for ZBufWriter<'_> { buf: self.cache.clone(), start: prev_cache_len, end: cache_len, + #[cfg(feature = "shared-memory")] + kind: ZSliceKind::Raw, }); Ok(()) } @@ -479,6 +465,8 @@ impl Writer for ZBufWriter<'_> { buf: self.cache.clone(), start: prev_cache_len, end: cache_len, + #[cfg(feature = "shared-memory")] + kind: ZSliceKind::Raw, }); NonZeroUsize::new(len).ok_or(DidntWrite) } @@ -543,24 +531,24 @@ mod tests { let slice: ZSlice = [0u8, 1, 2, 3, 4, 5, 6, 7].to_vec().into(); let mut zbuf1 = ZBuf::empty(); - zbuf1.push_zslice(slice.new_sub_slice(0, 4).unwrap()); - zbuf1.push_zslice(slice.new_sub_slice(4, 8).unwrap()); + zbuf1.push_zslice(slice.subslice(0, 4).unwrap()); + zbuf1.push_zslice(slice.subslice(4, 8).unwrap()); let mut zbuf2 = ZBuf::empty(); - zbuf2.push_zslice(slice.new_sub_slice(0, 1).unwrap()); - zbuf2.push_zslice(slice.new_sub_slice(1, 4).unwrap()); - zbuf2.push_zslice(slice.new_sub_slice(4, 8).unwrap()); + zbuf2.push_zslice(slice.subslice(0, 1).unwrap()); + zbuf2.push_zslice(slice.subslice(1, 4).unwrap()); + zbuf2.push_zslice(slice.subslice(4, 8).unwrap()); assert_eq!(zbuf1, zbuf2); let mut zbuf1 = ZBuf::empty(); - zbuf1.push_zslice(slice.new_sub_slice(2, 4).unwrap()); - zbuf1.push_zslice(slice.new_sub_slice(4, 8).unwrap()); + zbuf1.push_zslice(slice.subslice(2, 4).unwrap()); + zbuf1.push_zslice(slice.subslice(4, 8).unwrap()); let mut zbuf2 = ZBuf::empty(); - zbuf2.push_zslice(slice.new_sub_slice(2, 3).unwrap()); - zbuf2.push_zslice(slice.new_sub_slice(3, 6).unwrap()); - zbuf2.push_zslice(slice.new_sub_slice(6, 8).unwrap()); + zbuf2.push_zslice(slice.subslice(2, 3).unwrap()); + zbuf2.push_zslice(slice.subslice(3, 6).unwrap()); + zbuf2.push_zslice(slice.subslice(6, 8).unwrap()); assert_eq!(zbuf1, zbuf2); } diff --git a/commons/zenoh-buffers/src/zslice.rs b/commons/zenoh-buffers/src/zslice.rs index 92d016ef0c..5d75b104fb 100644 --- a/commons/zenoh-buffers/src/zslice.rs +++ b/commons/zenoh-buffers/src/zslice.rs @@ -69,12 +69,22 @@ impl ZSliceBuffer for [u8; N] { /*************************************/ /* ZSLICE */ /*************************************/ +#[cfg(feature = "shared-memory")] +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u8)] +pub enum ZSliceKind { + Raw = 0, + ShmPtr = 1, +} + /// A clonable wrapper to a contiguous slice of bytes. #[derive(Clone)] pub struct ZSlice { - pub buf: Arc, + pub(crate) buf: Arc, pub(crate) start: usize, pub(crate) end: usize, + #[cfg(feature = "shared-memory")] + pub kind: ZSliceKind, } impl ZSlice { @@ -83,13 +93,27 @@ impl ZSlice { start: usize, end: usize, ) -> Result> { - if end <= buf.as_slice().len() { - Ok(ZSlice { buf, start, end }) + if start <= end && end <= buf.as_slice().len() { + Ok(ZSlice { + buf, + start, + end, + #[cfg(feature = "shared-memory")] + kind: ZSliceKind::Raw, + }) } else { Err(buf) } } + #[inline] + pub fn downcast_ref(&self) -> Option<&T> + where + T: Any, + { + self.buf.as_any().downcast_ref::() + } + #[inline] pub fn range(&self) -> Range { self.start..self.end @@ -110,12 +134,14 @@ impl ZSlice { &self.buf.as_slice()[self.range()] } - pub(crate) fn new_sub_slice(&self, start: usize, end: usize) -> Option { - if end <= self.len() { + pub fn subslice(&self, start: usize, end: usize) -> Option { + if start <= end && end <= self.len() { Some(ZSlice { buf: self.buf.clone(), start: self.start + start, end: self.start + end, + #[cfg(feature = "shared-memory")] + kind: self.kind, }) } else { None @@ -220,7 +246,13 @@ where { fn from(buf: Arc) -> Self { let end = buf.as_slice().len(); - Self { buf, start: 0, end } + Self { + buf, + start: 0, + end, + #[cfg(feature = "shared-memory")] + kind: ZSliceKind::Raw, + } } } @@ -229,12 +261,7 @@ where T: ZSliceBuffer + 'static, { fn from(buf: T) -> Self { - let end = buf.as_slice().len(); - Self { - buf: Arc::new(buf), - start: 0, - end, - } + Self::from(Arc::new(buf)) } } @@ -276,7 +303,7 @@ impl Reader for &mut ZSlice { } fn read_zslice(&mut self, len: usize) -> Result { - let res = self.new_sub_slice(0, len).ok_or(DidntRead)?; + let res = self.subslice(0, len).ok_or(DidntRead)?; self.start += len; Ok(res) } diff --git a/commons/zenoh-buffers/tests/readwrite.rs b/commons/zenoh-buffers/tests/readwrite.rs index 420e2f81e8..b7ca43f5a9 100644 --- a/commons/zenoh-buffers/tests/readwrite.rs +++ b/commons/zenoh-buffers/tests/readwrite.rs @@ -11,7 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -use std::sync::Arc; use zenoh_buffers::reader::*; use zenoh_buffers::writer::*; use zenoh_buffers::*; @@ -204,7 +203,7 @@ fn buffer_zslice() { let mut vbuf = vec![]; run_write!(&mut vbuf); - let mut zslice = ZSlice::from(Arc::new(vbuf)); + let mut zslice = ZSlice::from(vbuf); run_read!(zslice); let mut zslice = ZSlice::from(vec![]); diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 59dd472ac5..a47982ff49 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -14,6 +14,8 @@ #[macro_use] extern crate criterion; +use std::sync::Arc; + use criterion::Criterion; use zenoh_buffers::{ reader::{DidntRead, HasReader}, @@ -237,7 +239,8 @@ fn criterion_benchmark(c: &mut Criterion) { let mut writer = buff.writer(); codec.write(&mut writer, &data).unwrap(); - let zslice: ZSlice = buff.into(); + let buff = Arc::new(buff); + let zslice: ZSlice = buff.clone().into(); c.bench_function("Fragmentation ZSlice ZBuf Read", |b| { b.iter(|| { @@ -246,7 +249,7 @@ fn criterion_benchmark(c: &mut Criterion) { let mut idx = 0; while idx < zslice.len() { let len = (zslice.len() - idx).min(chunk); - zbuf.push_zslice(ZSlice::make(zslice.buf.clone(), idx, idx + len).unwrap()); + zbuf.push_zslice(ZSlice::make(buff.clone(), idx, idx + len).unwrap()); idx += len; } diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index 5bac30683a..752792c5a8 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -82,3 +82,81 @@ where zodec.read(&mut *reader) } } + +// ZBuf sliced +#[cfg(feature = "shared-memory")] +mod shm { + use super::*; + use crate::Zenoh080Sliced; + use zenoh_buffers::{ZSlice, ZSliceKind}; + + const RAW: u8 = 0; + const SHM_PTR: u8 = 1; + + macro_rules! zbuf_sliced_impl { + ($bound:ty) => { + impl WCodec<&ZBuf, &mut W> for Zenoh080Sliced<$bound> + where + W: Writer, + { + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &ZBuf) -> Self::Output { + if self.is_sliced { + self.codec.write(&mut *writer, x.zslices().count())?; + + for zs in x.zslices() { + match zs.kind { + ZSliceKind::Raw => self.codec.write(&mut *writer, RAW)?, + ZSliceKind::ShmPtr => self.codec.write(&mut *writer, SHM_PTR)?, + } + self.codec.write(&mut *writer, zs)?; + } + } else { + self.codec.write(&mut *writer, x)?; + } + + Ok(()) + } + } + + impl RCodec for Zenoh080Sliced<$bound> + where + R: Reader, + { + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + if self.is_sliced { + let num: usize = self.codec.read(&mut *reader)?; + let mut zbuf = ZBuf::empty(); + for _ in 0..num { + let kind: u8 = self.codec.read(&mut *reader)?; + match kind { + RAW => { + let len: usize = self.codec.read(&mut *reader)?; + reader.read_zslices(len, |s| zbuf.push_zslice(s))?; + } + SHM_PTR => { + let mut zslice: ZSlice = self.codec.read(&mut *reader)?; + zslice.kind = ZSliceKind::ShmPtr; + zbuf.push_zslice(zslice); + } + _ => return Err(DidntRead), + } + } + Ok(zbuf) + } else { + self.codec.read(&mut *reader) + } + } + } + }; + } + + zbuf_sliced_impl!(u8); + zbuf_sliced_impl!(u16); + zbuf_sliced_impl!(u32); + zbuf_sliced_impl!(u64); + zbuf_sliced_impl!(usize); +} diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 7d9beb459c..8ea171aa15 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -132,3 +132,20 @@ impl Zenoh080Bounded { Self { _t: PhantomData } } } + +#[cfg(feature = "shared-memory")] +#[derive(Clone, Copy)] +pub struct Zenoh080Sliced { + is_sliced: bool, + codec: Zenoh080Bounded, +} + +#[cfg(feature = "shared-memory")] +impl Zenoh080Sliced { + pub const fn new(is_sliced: bool) -> Self { + Self { + is_sliced, + codec: Zenoh080Bounded::::new(), + } + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/put.rs b/commons/zenoh-codec/src/zenoh_new/put.rs index ea173d47cb..d9fcf2d352 100644 --- a/commons/zenoh-codec/src/zenoh_new/put.rs +++ b/commons/zenoh-codec/src/zenoh_new/put.rs @@ -11,7 +11,11 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header}; +#[cfg(not(feature = "shared-memory"))] +use crate::Zenoh080Bounded; +#[cfg(feature = "shared-memory")] +use crate::Zenoh080Sliced; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -76,8 +80,17 @@ where } // Payload - let bodec = Zenoh080Bounded::::new(); - bodec.write(&mut *writer, &x.payload)?; + #[cfg(feature = "shared-memory")] + { + let codec = Zenoh080Sliced::::new(x.ext_shm.is_some()); + codec.write(&mut *writer, &x.payload)?; + } + + #[cfg(not(feature = "shared-memory"))] + { + let bodec = Zenoh080Bounded::::new(); + bodec.write(&mut *writer, &x.payload)?; + } Ok(()) } @@ -149,8 +162,19 @@ where } // Payload - let bodec = Zenoh080Bounded::::new(); - let payload: ZBuf = bodec.read(&mut *reader)?; + let payload: ZBuf = { + #[cfg(feature = "shared-memory")] + { + let codec = Zenoh080Sliced::::new(ext_shm.is_some()); + codec.read(&mut *reader)? + } + + #[cfg(not(feature = "shared-memory"))] + { + let bodec = Zenoh080Bounded::::new(); + bodec.read(&mut *reader)? + } + }; Ok(Put { timestamp, diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index a92e18a2c6..2f9b776d04 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -16,7 +16,6 @@ use rand::{ *, }; use std::convert::TryFrom; -use std::sync::Arc; use zenoh_buffers::{ reader::{HasReader, Reader}, writer::HasWriter, @@ -97,7 +96,7 @@ macro_rules! run_buffers { let mut writer = buffer.writer(); $wcode.write(&mut writer, &x).unwrap(); - let mut zslice = ZSlice::from(Arc::new(buffer)); + let mut zslice = ZSlice::from(buffer); let mut reader = zslice.reader(); let y: $type = $rcode.read(&mut reader).unwrap(); assert_eq!(x, y); diff --git a/commons/zenoh-protocol/Cargo.toml b/commons/zenoh-protocol/Cargo.toml index f61b9c3e16..703dbbd6b7 100644 --- a/commons/zenoh-protocol/Cargo.toml +++ b/commons/zenoh-protocol/Cargo.toml @@ -36,7 +36,7 @@ std = [ "zenoh-result/std", ] test = ["rand", "zenoh-buffers/test"] -shared-memory = ["std"] +shared-memory = ["std", "zenoh-buffers/shared-memory"] complete_n = [] [dependencies] diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index 962bbd3094..256d6887f3 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -19,6 +19,7 @@ pub mod put; pub mod query; pub mod reply; +use crate::core::Encoding; pub use ack::*; pub use del::*; pub use err::*; @@ -38,6 +39,12 @@ pub mod id { pub const PULL: u8 = 0x07; } +// DataInfo +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DataInfo { + pub encoding: Encoding, +} + // Push #[derive(Debug, Clone, PartialEq, Eq)] pub enum PushBody { diff --git a/commons/zenoh-sync/src/object_pool.rs b/commons/zenoh-sync/src/object_pool.rs index 6b277d97da..d26bc7ea7c 100644 --- a/commons/zenoh-sync/src/object_pool.rs +++ b/commons/zenoh-sync/src/object_pool.rs @@ -142,11 +142,9 @@ impl ZSliceBuffer for RecyclingObject> { fn as_slice(&self) -> &[u8] { self.as_ref() } - fn as_mut_slice(&mut self) -> &mut [u8] { self.as_mut() } - fn as_any(&self) -> &dyn Any { self } diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index a8c75f683a..90bf5edc5c 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use async_std::{sync::RwLock, task}; -use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZBuf, ZSlice}; +use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZBuf, ZSlice, ZSliceKind}; use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_core::{zasyncread, zasyncwrite, zerror}; use zenoh_protocol::{ @@ -48,8 +48,7 @@ pub fn map_zmsg_to_shminfo(msg: &mut NetworkMessage) -> ZResult { pub fn map_zbuf_to_shminfo(zbuf: &mut ZBuf) -> ZResult { let mut res = false; for zs in zbuf.zslices_mut() { - let ZSlice { buf, .. } = zs; - if let Some(shmb) = buf.as_any().downcast_ref::() { + if let Some(shmb) = zs.downcast_ref::() { *zs = map_zslice_to_shminfo(shmb)?; res = true; } @@ -70,7 +69,9 @@ pub fn map_zslice_to_shminfo(shmb: &SharedMemoryBuf) -> ZResult { // Increase the reference count so to keep the SharedMemoryBuf valid shmb.inc_ref_count(); // Replace the content of the slice - Ok(info.into()) + let mut zslice: ZSlice = info.into(); + zslice.kind = ZSliceKind::ShmPtr; + Ok(zslice) } // ShmInfo -> ShmBuf @@ -98,7 +99,7 @@ pub fn map_zmsg_to_shmbuf( pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &RwLock) -> ZResult { let mut res = false; - for zs in zbuf.zslices_mut() { + for zs in zbuf.zslices_mut().filter(|x| x.kind == ZSliceKind::ShmPtr) { res |= map_zslice_to_shmbuf(zs, shmr)?; } Ok(res) diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index fe6ea5a034..abb4520bd6 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -23,7 +23,7 @@ mod tests { }, time::Duration, }; - use zenoh_buffers::{SplitBuffer, ZSlice}; + use zenoh_buffers::SplitBuffer; use zenoh_core::zasync_executor_init; use zenoh_link::Link; use zenoh_protocol::{ @@ -107,15 +107,11 @@ mod tests { NetworkBody::Push(m) => match m.payload { PushBody::Put(Put { payload, .. }) => { for zs in payload.zslices() { - let ZSlice { buf, .. } = zs; - if self.is_shm - && buf.as_any().downcast_ref::().is_none() + if self.is_shm && zs.downcast_ref::().is_none() { + panic!("Expected SharedMemoryBuf: {:?}", zs); + } else if !self.is_shm && zs.downcast_ref::().is_some() { - panic!("Expected SharedMemoryBuf"); - } else if !self.is_shm - && buf.as_any().downcast_ref::().is_some() - { - panic!("Not Expected SharedMemoryBuf"); + panic!("Not Expected SharedMemoryBuf: {:?}", zs); } } payload.contiguous().into_owned() From 599a7042c275c0daaa4449a6712c864578b02b27 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 24 Jul 2023 12:06:57 +0200 Subject: [PATCH 167/203] Improve ZInt bounded encoding --- commons/zenoh-codec/src/core/zint.rs | 12 ++++++++---- commons/zenoh-codec/tests/codec.rs | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 7f8413231a..f056344a71 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -218,8 +218,10 @@ macro_rules! zint_impl_codec { type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: $zint) -> Self::Output { - let t: $bound = x.try_into().map_err(|_| DidntWrite)?; - Zenoh080.write(writer, t) + if (x as u64 & !(<$bound>::MAX as u64)) == 0 { + return Err(DidntWrite); + } + Zenoh080.write(writer, x as u64) } } @@ -231,8 +233,10 @@ macro_rules! zint_impl_codec { fn read(self, reader: &mut R) -> Result<$zint, Self::Error> { let x: u64 = Zenoh080.read(reader)?; - let t: $bound = x.try_into().map_err(|_| DidntRead)?; - t.try_into().map_err(|_| DidntRead) + if (x & !(<$bound>::MAX as u64)) != 0 { + return Err(DidntRead); + } + Ok(x as $zint) } } }; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 2f9b776d04..9a35cd7163 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -173,6 +173,7 @@ fn codec_zint_bounded() { macro_rules! check { ($zint:ty) => { + println!("Bound: {}. Value: {}", std::any::type_name::<$zint>(), i); let zodec = Zenoh080Bounded::<$zint>::new(); let mut btmp = vec![]; From 4c36bb3bc4310b65d0cb9514c91d4575867c535f Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 24 Jul 2023 12:35:50 +0200 Subject: [PATCH 168/203] Revert "Improve ZInt bounded encoding" This reverts commit 599a7042c275c0daaa4449a6712c864578b02b27. --- commons/zenoh-codec/src/core/zint.rs | 12 ++++-------- commons/zenoh-codec/tests/codec.rs | 1 - 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index f056344a71..7f8413231a 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -218,10 +218,8 @@ macro_rules! zint_impl_codec { type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: $zint) -> Self::Output { - if (x as u64 & !(<$bound>::MAX as u64)) == 0 { - return Err(DidntWrite); - } - Zenoh080.write(writer, x as u64) + let t: $bound = x.try_into().map_err(|_| DidntWrite)?; + Zenoh080.write(writer, t) } } @@ -233,10 +231,8 @@ macro_rules! zint_impl_codec { fn read(self, reader: &mut R) -> Result<$zint, Self::Error> { let x: u64 = Zenoh080.read(reader)?; - if (x & !(<$bound>::MAX as u64)) != 0 { - return Err(DidntRead); - } - Ok(x as $zint) + let t: $bound = x.try_into().map_err(|_| DidntRead)?; + t.try_into().map_err(|_| DidntRead) } } }; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 9a35cd7163..2f9b776d04 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -173,7 +173,6 @@ fn codec_zint_bounded() { macro_rules! check { ($zint:ty) => { - println!("Bound: {}. Value: {}", std::any::type_name::<$zint>(), i); let zodec = Zenoh080Bounded::<$zint>::new(); let mut btmp = vec![]; From 326237917c64275045bbfa8c37f47fe09a16e3e7 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 24 Jul 2023 12:44:11 +0200 Subject: [PATCH 169/203] Improve ZInt bounded encoding --- commons/zenoh-codec/src/core/zint.rs | 16 +++++++++------- commons/zenoh-codec/tests/codec.rs | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 7f8413231a..5c7badb7f0 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -12,7 +12,6 @@ // ZettaScale Zenoh Team, // use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Bounded}; -use core::convert::TryInto; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -164,8 +163,7 @@ macro_rules! uint_impl { type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: $uint) -> Self::Output { - let x: u64 = x.try_into().map_err(|_| DidntWrite)?; - self.write(writer, x) + self.write(writer, x as u64) } } @@ -218,8 +216,10 @@ macro_rules! zint_impl_codec { type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: $zint) -> Self::Output { - let t: $bound = x.try_into().map_err(|_| DidntWrite)?; - Zenoh080.write(writer, t) + if (x as u64 & !(<$bound>::MAX as u64)) != 0 { + return Err(DidntWrite); + } + Zenoh080.write(writer, x as u64) } } @@ -231,8 +231,10 @@ macro_rules! zint_impl_codec { fn read(self, reader: &mut R) -> Result<$zint, Self::Error> { let x: u64 = Zenoh080.read(reader)?; - let t: $bound = x.try_into().map_err(|_| DidntRead)?; - t.try_into().map_err(|_| DidntRead) + if (x & !(<$bound>::MAX as u64)) != 0 { + return Err(DidntRead); + } + Ok(x as $zint) } } }; diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 2f9b776d04..9a35cd7163 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -173,6 +173,7 @@ fn codec_zint_bounded() { macro_rules! check { ($zint:ty) => { + println!("Bound: {}. Value: {}", std::any::type_name::<$zint>(), i); let zodec = Zenoh080Bounded::<$zint>::new(); let mut btmp = vec![]; From bdf35f363d154a8b9b300da05afa3102ac34b478 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 28 Jul 2023 10:00:39 +0200 Subject: [PATCH 170/203] Apply pedantic clippy to zenoh-colletions and zenoh-buffers --- commons/zenoh-buffers/src/bbuf.rs | 5 +++++ commons/zenoh-buffers/src/lib.rs | 6 +++--- commons/zenoh-buffers/src/vec.rs | 5 +++-- commons/zenoh-buffers/src/zbuf.rs | 21 ++++++++++--------- commons/zenoh-buffers/src/zslice.rs | 13 +++++++++--- commons/zenoh-buffers/tests/readwrite.rs | 8 ++++--- commons/zenoh-collections/src/properties.rs | 10 ++++----- commons/zenoh-collections/src/ring_buffer.rs | 5 +++++ .../zenoh-collections/src/single_or_vec.rs | 12 +++++------ commons/zenoh-collections/src/stack_buffer.rs | 5 +++++ 10 files changed, 58 insertions(+), 32 deletions(-) diff --git a/commons/zenoh-buffers/src/bbuf.rs b/commons/zenoh-buffers/src/bbuf.rs index 7342193902..cfa05cde5e 100644 --- a/commons/zenoh-buffers/src/bbuf.rs +++ b/commons/zenoh-buffers/src/bbuf.rs @@ -26,6 +26,7 @@ pub struct BBuf { } impl BBuf { + #[must_use] pub fn with_capacity(capacity: usize) -> Self { Self { buffer: vec::uninit(capacity).into_boxed_slice(), @@ -33,18 +34,22 @@ impl BBuf { } } + #[must_use] pub fn capacity(&self) -> usize { self.buffer.len() } + #[must_use] pub fn len(&self) -> usize { self.len } + #[must_use] pub fn is_empty(&self) -> bool { self.len == 0 } + #[must_use] pub fn as_slice(&self) -> &[u8] { &self.buffer[..self.len] } diff --git a/commons/zenoh-buffers/src/lib.rs b/commons/zenoh-buffers/src/lib.rs index bcf31835b5..10cb2bbfde 100644 --- a/commons/zenoh-buffers/src/lib.rs +++ b/commons/zenoh-buffers/src/lib.rs @@ -87,14 +87,14 @@ pub mod reader { fn read_exact(&mut self, into: &mut [u8]) -> Result<(), DidntRead>; fn remaining(&self) -> usize; - /// Returns an iterator of ZSlices such that the sum of their length is _exactly_ `len`. + /// Returns an iterator of `ZSlices` such that the sum of their length is _exactly_ `len`. fn read_zslices( &mut self, len: usize, for_each_slice: F, ) -> Result<(), DidntRead>; - /// Reads exactly `len` bytes, returning them as a single ZSlice. + /// Reads exactly `len` bytes, returning them as a single `ZSlice`. fn read_zslice(&mut self, len: usize) -> Result; fn read_u8(&mut self) -> Result { @@ -145,7 +145,7 @@ pub trait SplitBuffer<'a> { /// Returns `true` if the buffer has a length of 0. fn is_empty(&'a self) -> bool { - self.slices().all(|s| s.is_empty()) + self.slices().all(<[u8]>::is_empty) } /// Returns the number of bytes in the buffer. diff --git a/commons/zenoh-buffers/src/vec.rs b/commons/zenoh-buffers/src/vec.rs index 06774a7340..3c0c0a7c00 100644 --- a/commons/zenoh-buffers/src/vec.rs +++ b/commons/zenoh-buffers/src/vec.rs @@ -16,9 +16,10 @@ use crate::{ writer::{BacktrackableWriter, DidntWrite, HasWriter, Writer}, }; use alloc::vec::Vec; -use core::{mem, num::NonZeroUsize}; +use core::{num::NonZeroUsize, ptr}; /// Allocate a vector with a given capacity and sets the length to that capacity. +#[must_use] pub fn uninit(capacity: usize) -> Vec { let mut vbuf = Vec::with_capacity(capacity); #[allow(clippy::uninit_vec)] @@ -66,7 +67,7 @@ impl Writer for &mut Vec { { self.reserve(len); unsafe { - len = f(mem::transmute(&mut self.spare_capacity_mut()[..len])); + len = f(&mut *(ptr::addr_of_mut!(self.spare_capacity_mut()[..len]) as *mut [u8])); self.set_len(self.len() + len); } NonZeroUsize::new(len).ok_or(DidntWrite) diff --git a/commons/zenoh-buffers/src/zbuf.rs b/commons/zenoh-buffers/src/zbuf.rs index ce388f29fd..eb9a4a1968 100644 --- a/commons/zenoh-buffers/src/zbuf.rs +++ b/commons/zenoh-buffers/src/zbuf.rs @@ -19,7 +19,7 @@ use crate::{ SplitBuffer, ZSlice, }; use alloc::{sync::Arc, vec::Vec}; -use core::{cmp, iter, mem, num::NonZeroUsize, slice}; +use core::{cmp, iter, num::NonZeroUsize, ptr, slice}; use zenoh_collections::SingleOrVec; fn get_mut_unchecked(arc: &mut Arc) -> &mut T { @@ -32,6 +32,7 @@ pub struct ZBuf { } impl ZBuf { + #[must_use] pub fn empty() -> Self { Self::default() } @@ -92,14 +93,14 @@ impl PartialEq for ZBuf { return false; } if cmp_len == l.len() { - current_self = self_slices.next() + current_self = self_slices.next(); } else { - current_self = Some(&l[cmp_len..]) + current_self = Some(&l[cmp_len..]); } if cmp_len == r.len() { - current_other = other_slices.next() + current_other = other_slices.next(); } else { - current_other = Some(&r[cmp_len..]) + current_other = Some(&r[cmp_len..]); } } } @@ -112,9 +113,9 @@ impl From for ZBuf where T: Into, { - fn from(buf: T) -> Self { + fn from(t: T) -> Self { let mut zbuf = ZBuf::empty(); - let zslice: ZSlice = buf.into(); + let zslice: ZSlice = t.into(); zbuf.push_zslice(zslice); zbuf } @@ -437,7 +438,7 @@ impl Writer for ZBufWriter<'_> { let prev_cache_len = cache.len(); cache.reserve(len); unsafe { - len = f(mem::transmute(&mut cache.spare_capacity_mut()[..len])); + len = f(&mut *(ptr::addr_of_mut!(cache.spare_capacity_mut()[..len]) as *mut [u8])); cache.set_len(prev_cache_len + len); } let cache_len = cache.len(); @@ -489,9 +490,9 @@ impl BacktrackableWriter for ZBufWriter<'_> { fn rewind(&mut self, mark: Self::Mark) -> bool { self.inner .slices - .truncate(mark.slice + (mark.byte != 0) as usize); + .truncate(mark.slice + usize::from(mark.byte != 0)); if let Some(slice) = self.inner.slices.last_mut() { - slice.end = mark.byte + slice.end = mark.byte; } true } diff --git a/commons/zenoh-buffers/src/zslice.rs b/commons/zenoh-buffers/src/zslice.rs index 5d75b104fb..0337840e8f 100644 --- a/commons/zenoh-buffers/src/zslice.rs +++ b/commons/zenoh-buffers/src/zslice.rs @@ -107,6 +107,7 @@ impl ZSlice { } #[inline] + #[must_use] pub fn downcast_ref(&self) -> Option<&T> where T: Any, @@ -115,25 +116,31 @@ impl ZSlice { } #[inline] + #[must_use] pub fn range(&self) -> Range { self.start..self.end } #[inline] + #[must_use] pub fn len(&self) -> usize { self.end - self.start } #[inline] + #[must_use] pub fn is_empty(&self) -> bool { self.len() == 0 } #[inline] + #[must_use] pub fn as_slice(&self) -> &[u8] { - &self.buf.as_slice()[self.range()] + // &self.buf.as_slice()[self.range()] + unsafe { self.buf.as_slice().get_unchecked(self.range()) } } + #[must_use] pub fn subslice(&self, start: usize, end: usize) -> Option { if start <= end && end <= self.len() { Some(ZSlice { @@ -159,7 +166,7 @@ impl Deref for ZSlice { impl AsRef<[u8]> for ZSlice { fn as_ref(&self) -> &[u8] { - self.deref() + self } } @@ -191,7 +198,7 @@ impl Index for ZSlice { type Output = [u8]; fn index(&self, _range: RangeFull) -> &Self::Output { - self.deref() + self } } diff --git a/commons/zenoh-buffers/tests/readwrite.rs b/commons/zenoh-buffers/tests/readwrite.rs index b7ca43f5a9..ea48218a85 100644 --- a/commons/zenoh-buffers/tests/readwrite.rs +++ b/commons/zenoh-buffers/tests/readwrite.rs @@ -11,9 +11,11 @@ // Contributors: // ZettaScale Zenoh Team, // -use zenoh_buffers::reader::*; -use zenoh_buffers::writer::*; -use zenoh_buffers::*; +use zenoh_buffers::{ + reader::{HasReader, Reader, SiphonableReader}, + writer::{BacktrackableWriter, HasWriter, Writer}, +}; +use zenoh_buffers::{BBuf, ZBuf, ZSlice}; const BYTES: usize = 18; diff --git a/commons/zenoh-collections/src/properties.rs b/commons/zenoh-collections/src/properties.rs index 7c9291bbd6..441cf4c8be 100644 --- a/commons/zenoh-collections/src/properties.rs +++ b/commons/zenoh-collections/src/properties.rs @@ -53,13 +53,13 @@ impl fmt::Display for Properties { if v.is_empty() { write!(f, "{k}")? } else { - write!(f, "{}{}{}", k, KV_SEP, v)? + write!(f, "{k}{KV_SEP}{v}")? } for (k, v) in it { if v.is_empty() { write!(f, "{DEFAULT_PROP_SEP}{k}")? } else { - write!(f, "{}{}{}{}", DEFAULT_PROP_SEP, k, KV_SEP, v)? + write!(f, "{DEFAULT_PROP_SEP}{k}{KV_SEP}{v}")? } } } @@ -69,7 +69,7 @@ impl fmt::Display for Properties { impl fmt::Debug for Properties { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self) + write!(f, "{self}") } } @@ -82,7 +82,7 @@ impl From<&str> for Properties { .flat_map(|s| s.split(sep)) .collect::>(); } - props = props.into_iter().map(|s| s.trim()).collect::>(); + props = props.into_iter().map(str::trim).collect::>(); let inner = props .iter() .filter_map(|prop| { @@ -117,7 +117,7 @@ impl From<&[(&str, &str)]> for Properties { fn from(kvs: &[(&str, &str)]) -> Self { let inner = kvs .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) + .map(|(k, v)| ((*k).to_string(), (*v).to_string())) .collect(); Self(inner) } diff --git a/commons/zenoh-collections/src/ring_buffer.rs b/commons/zenoh-collections/src/ring_buffer.rs index 6a559dd3e1..fd60030ebc 100644 --- a/commons/zenoh-collections/src/ring_buffer.rs +++ b/commons/zenoh-collections/src/ring_buffer.rs @@ -20,6 +20,7 @@ pub struct RingBuffer { } impl RingBuffer { + #[must_use] pub fn new(capacity: usize) -> RingBuffer { let buffer = VecDeque::::with_capacity(capacity); RingBuffer { @@ -50,21 +51,25 @@ impl RingBuffer { #[allow(dead_code)] #[inline] + #[must_use] pub fn is_empty(&self) -> bool { self.buffer.is_empty() } #[inline] + #[must_use] pub fn is_full(&self) -> bool { self.len() == self.capacity() } #[inline] + #[must_use] pub fn len(&self) -> usize { self.len } #[inline] + #[must_use] pub fn capacity(&self) -> usize { self.capacity } diff --git a/commons/zenoh-collections/src/single_or_vec.rs b/commons/zenoh-collections/src/single_or_vec.rs index 558e2439bf..ea190395fb 100644 --- a/commons/zenoh-collections/src/single_or_vec.rs +++ b/commons/zenoh-collections/src/single_or_vec.rs @@ -31,7 +31,7 @@ impl SingleOrVecInner { SingleOrVecInner::Vec(vec) if vec.capacity() == 0 => *self = Self::Single(value), SingleOrVecInner::Single(first) => unsafe { let first = ptr::read(first); - ptr::write(self, Self::Vec(vec![first, value])) + ptr::write(self, Self::Vec(vec![first, value])); }, SingleOrVecInner::Vec(vec) => vec.push(value), } @@ -85,14 +85,14 @@ pub struct SingleOrVec(SingleOrVecInner); impl SingleOrVec { pub fn push(&mut self, value: T) { - self.0.push(value) + self.0.push(value); } pub fn truncate(&mut self, len: usize) { if let SingleOrVecInner::Vec(v) = &mut self.0 { - v.truncate(len) + v.truncate(len); } else if len == 0 { - self.0 = SingleOrVecInner::Vec(Vec::new()) + self.0 = SingleOrVecInner::Vec(Vec::new()); } } @@ -143,7 +143,7 @@ impl SingleOrVec { impl Default for SingleOrVec { fn default() -> Self { - Self(Default::default()) + Self(SingleOrVecInner::default()) } } @@ -192,7 +192,7 @@ impl IntoIterator for SingleOrVec { impl iter::Extend for SingleOrVec { fn extend>(&mut self, iter: I) { for value in iter { - self.push(value) + self.push(value); } } } diff --git a/commons/zenoh-collections/src/stack_buffer.rs b/commons/zenoh-collections/src/stack_buffer.rs index 893e40d401..dd3ae11d62 100644 --- a/commons/zenoh-collections/src/stack_buffer.rs +++ b/commons/zenoh-collections/src/stack_buffer.rs @@ -18,6 +18,7 @@ pub struct StackBuffer { } impl StackBuffer { + #[must_use] pub fn new(capacity: usize) -> StackBuffer { let buffer = VecDeque::::with_capacity(capacity); StackBuffer { buffer } @@ -40,21 +41,25 @@ impl StackBuffer { #[allow(dead_code)] #[inline] + #[must_use] pub fn is_empty(&self) -> bool { self.buffer.is_empty() } #[inline] + #[must_use] pub fn is_full(&self) -> bool { self.len() == self.capacity() } #[inline] + #[must_use] pub fn len(&self) -> usize { self.buffer.len() } #[inline] + #[must_use] pub fn capacity(&self) -> usize { self.buffer.capacity() } From 48d723072924d660d5c10d3126702b28e5db2325 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 28 Jul 2023 10:00:39 +0200 Subject: [PATCH 171/203] Apply pedantic clippy to zenoh-colletions and zenoh-buffers --- commons/zenoh-buffers/src/bbuf.rs | 5 +++++ commons/zenoh-buffers/src/lib.rs | 6 +++--- commons/zenoh-buffers/src/vec.rs | 5 +++-- commons/zenoh-buffers/src/zbuf.rs | 21 ++++++++++--------- commons/zenoh-buffers/src/zslice.rs | 10 +++++++-- commons/zenoh-buffers/tests/readwrite.rs | 8 ++++--- commons/zenoh-collections/src/properties.rs | 10 ++++----- commons/zenoh-collections/src/ring_buffer.rs | 5 +++++ .../zenoh-collections/src/single_or_vec.rs | 12 +++++------ commons/zenoh-collections/src/stack_buffer.rs | 5 +++++ 10 files changed, 56 insertions(+), 31 deletions(-) diff --git a/commons/zenoh-buffers/src/bbuf.rs b/commons/zenoh-buffers/src/bbuf.rs index 7342193902..cfa05cde5e 100644 --- a/commons/zenoh-buffers/src/bbuf.rs +++ b/commons/zenoh-buffers/src/bbuf.rs @@ -26,6 +26,7 @@ pub struct BBuf { } impl BBuf { + #[must_use] pub fn with_capacity(capacity: usize) -> Self { Self { buffer: vec::uninit(capacity).into_boxed_slice(), @@ -33,18 +34,22 @@ impl BBuf { } } + #[must_use] pub fn capacity(&self) -> usize { self.buffer.len() } + #[must_use] pub fn len(&self) -> usize { self.len } + #[must_use] pub fn is_empty(&self) -> bool { self.len == 0 } + #[must_use] pub fn as_slice(&self) -> &[u8] { &self.buffer[..self.len] } diff --git a/commons/zenoh-buffers/src/lib.rs b/commons/zenoh-buffers/src/lib.rs index bcf31835b5..10cb2bbfde 100644 --- a/commons/zenoh-buffers/src/lib.rs +++ b/commons/zenoh-buffers/src/lib.rs @@ -87,14 +87,14 @@ pub mod reader { fn read_exact(&mut self, into: &mut [u8]) -> Result<(), DidntRead>; fn remaining(&self) -> usize; - /// Returns an iterator of ZSlices such that the sum of their length is _exactly_ `len`. + /// Returns an iterator of `ZSlices` such that the sum of their length is _exactly_ `len`. fn read_zslices( &mut self, len: usize, for_each_slice: F, ) -> Result<(), DidntRead>; - /// Reads exactly `len` bytes, returning them as a single ZSlice. + /// Reads exactly `len` bytes, returning them as a single `ZSlice`. fn read_zslice(&mut self, len: usize) -> Result; fn read_u8(&mut self) -> Result { @@ -145,7 +145,7 @@ pub trait SplitBuffer<'a> { /// Returns `true` if the buffer has a length of 0. fn is_empty(&'a self) -> bool { - self.slices().all(|s| s.is_empty()) + self.slices().all(<[u8]>::is_empty) } /// Returns the number of bytes in the buffer. diff --git a/commons/zenoh-buffers/src/vec.rs b/commons/zenoh-buffers/src/vec.rs index 06774a7340..3c0c0a7c00 100644 --- a/commons/zenoh-buffers/src/vec.rs +++ b/commons/zenoh-buffers/src/vec.rs @@ -16,9 +16,10 @@ use crate::{ writer::{BacktrackableWriter, DidntWrite, HasWriter, Writer}, }; use alloc::vec::Vec; -use core::{mem, num::NonZeroUsize}; +use core::{num::NonZeroUsize, ptr}; /// Allocate a vector with a given capacity and sets the length to that capacity. +#[must_use] pub fn uninit(capacity: usize) -> Vec { let mut vbuf = Vec::with_capacity(capacity); #[allow(clippy::uninit_vec)] @@ -66,7 +67,7 @@ impl Writer for &mut Vec { { self.reserve(len); unsafe { - len = f(mem::transmute(&mut self.spare_capacity_mut()[..len])); + len = f(&mut *(ptr::addr_of_mut!(self.spare_capacity_mut()[..len]) as *mut [u8])); self.set_len(self.len() + len); } NonZeroUsize::new(len).ok_or(DidntWrite) diff --git a/commons/zenoh-buffers/src/zbuf.rs b/commons/zenoh-buffers/src/zbuf.rs index ce388f29fd..eb9a4a1968 100644 --- a/commons/zenoh-buffers/src/zbuf.rs +++ b/commons/zenoh-buffers/src/zbuf.rs @@ -19,7 +19,7 @@ use crate::{ SplitBuffer, ZSlice, }; use alloc::{sync::Arc, vec::Vec}; -use core::{cmp, iter, mem, num::NonZeroUsize, slice}; +use core::{cmp, iter, num::NonZeroUsize, ptr, slice}; use zenoh_collections::SingleOrVec; fn get_mut_unchecked(arc: &mut Arc) -> &mut T { @@ -32,6 +32,7 @@ pub struct ZBuf { } impl ZBuf { + #[must_use] pub fn empty() -> Self { Self::default() } @@ -92,14 +93,14 @@ impl PartialEq for ZBuf { return false; } if cmp_len == l.len() { - current_self = self_slices.next() + current_self = self_slices.next(); } else { - current_self = Some(&l[cmp_len..]) + current_self = Some(&l[cmp_len..]); } if cmp_len == r.len() { - current_other = other_slices.next() + current_other = other_slices.next(); } else { - current_other = Some(&r[cmp_len..]) + current_other = Some(&r[cmp_len..]); } } } @@ -112,9 +113,9 @@ impl From for ZBuf where T: Into, { - fn from(buf: T) -> Self { + fn from(t: T) -> Self { let mut zbuf = ZBuf::empty(); - let zslice: ZSlice = buf.into(); + let zslice: ZSlice = t.into(); zbuf.push_zslice(zslice); zbuf } @@ -437,7 +438,7 @@ impl Writer for ZBufWriter<'_> { let prev_cache_len = cache.len(); cache.reserve(len); unsafe { - len = f(mem::transmute(&mut cache.spare_capacity_mut()[..len])); + len = f(&mut *(ptr::addr_of_mut!(cache.spare_capacity_mut()[..len]) as *mut [u8])); cache.set_len(prev_cache_len + len); } let cache_len = cache.len(); @@ -489,9 +490,9 @@ impl BacktrackableWriter for ZBufWriter<'_> { fn rewind(&mut self, mark: Self::Mark) -> bool { self.inner .slices - .truncate(mark.slice + (mark.byte != 0) as usize); + .truncate(mark.slice + usize::from(mark.byte != 0)); if let Some(slice) = self.inner.slices.last_mut() { - slice.end = mark.byte + slice.end = mark.byte; } true } diff --git a/commons/zenoh-buffers/src/zslice.rs b/commons/zenoh-buffers/src/zslice.rs index 5d75b104fb..7a316d4b1d 100644 --- a/commons/zenoh-buffers/src/zslice.rs +++ b/commons/zenoh-buffers/src/zslice.rs @@ -107,6 +107,7 @@ impl ZSlice { } #[inline] + #[must_use] pub fn downcast_ref(&self) -> Option<&T> where T: Any, @@ -115,25 +116,30 @@ impl ZSlice { } #[inline] + #[must_use] pub fn range(&self) -> Range { self.start..self.end } #[inline] + #[must_use] pub fn len(&self) -> usize { self.end - self.start } #[inline] + #[must_use] pub fn is_empty(&self) -> bool { self.len() == 0 } #[inline] + #[must_use] pub fn as_slice(&self) -> &[u8] { &self.buf.as_slice()[self.range()] } + #[must_use] pub fn subslice(&self, start: usize, end: usize) -> Option { if start <= end && end <= self.len() { Some(ZSlice { @@ -159,7 +165,7 @@ impl Deref for ZSlice { impl AsRef<[u8]> for ZSlice { fn as_ref(&self) -> &[u8] { - self.deref() + self } } @@ -191,7 +197,7 @@ impl Index for ZSlice { type Output = [u8]; fn index(&self, _range: RangeFull) -> &Self::Output { - self.deref() + self } } diff --git a/commons/zenoh-buffers/tests/readwrite.rs b/commons/zenoh-buffers/tests/readwrite.rs index b7ca43f5a9..ea48218a85 100644 --- a/commons/zenoh-buffers/tests/readwrite.rs +++ b/commons/zenoh-buffers/tests/readwrite.rs @@ -11,9 +11,11 @@ // Contributors: // ZettaScale Zenoh Team, // -use zenoh_buffers::reader::*; -use zenoh_buffers::writer::*; -use zenoh_buffers::*; +use zenoh_buffers::{ + reader::{HasReader, Reader, SiphonableReader}, + writer::{BacktrackableWriter, HasWriter, Writer}, +}; +use zenoh_buffers::{BBuf, ZBuf, ZSlice}; const BYTES: usize = 18; diff --git a/commons/zenoh-collections/src/properties.rs b/commons/zenoh-collections/src/properties.rs index 7c9291bbd6..441cf4c8be 100644 --- a/commons/zenoh-collections/src/properties.rs +++ b/commons/zenoh-collections/src/properties.rs @@ -53,13 +53,13 @@ impl fmt::Display for Properties { if v.is_empty() { write!(f, "{k}")? } else { - write!(f, "{}{}{}", k, KV_SEP, v)? + write!(f, "{k}{KV_SEP}{v}")? } for (k, v) in it { if v.is_empty() { write!(f, "{DEFAULT_PROP_SEP}{k}")? } else { - write!(f, "{}{}{}{}", DEFAULT_PROP_SEP, k, KV_SEP, v)? + write!(f, "{DEFAULT_PROP_SEP}{k}{KV_SEP}{v}")? } } } @@ -69,7 +69,7 @@ impl fmt::Display for Properties { impl fmt::Debug for Properties { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self) + write!(f, "{self}") } } @@ -82,7 +82,7 @@ impl From<&str> for Properties { .flat_map(|s| s.split(sep)) .collect::>(); } - props = props.into_iter().map(|s| s.trim()).collect::>(); + props = props.into_iter().map(str::trim).collect::>(); let inner = props .iter() .filter_map(|prop| { @@ -117,7 +117,7 @@ impl From<&[(&str, &str)]> for Properties { fn from(kvs: &[(&str, &str)]) -> Self { let inner = kvs .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) + .map(|(k, v)| ((*k).to_string(), (*v).to_string())) .collect(); Self(inner) } diff --git a/commons/zenoh-collections/src/ring_buffer.rs b/commons/zenoh-collections/src/ring_buffer.rs index 6a559dd3e1..fd60030ebc 100644 --- a/commons/zenoh-collections/src/ring_buffer.rs +++ b/commons/zenoh-collections/src/ring_buffer.rs @@ -20,6 +20,7 @@ pub struct RingBuffer { } impl RingBuffer { + #[must_use] pub fn new(capacity: usize) -> RingBuffer { let buffer = VecDeque::::with_capacity(capacity); RingBuffer { @@ -50,21 +51,25 @@ impl RingBuffer { #[allow(dead_code)] #[inline] + #[must_use] pub fn is_empty(&self) -> bool { self.buffer.is_empty() } #[inline] + #[must_use] pub fn is_full(&self) -> bool { self.len() == self.capacity() } #[inline] + #[must_use] pub fn len(&self) -> usize { self.len } #[inline] + #[must_use] pub fn capacity(&self) -> usize { self.capacity } diff --git a/commons/zenoh-collections/src/single_or_vec.rs b/commons/zenoh-collections/src/single_or_vec.rs index 558e2439bf..ea190395fb 100644 --- a/commons/zenoh-collections/src/single_or_vec.rs +++ b/commons/zenoh-collections/src/single_or_vec.rs @@ -31,7 +31,7 @@ impl SingleOrVecInner { SingleOrVecInner::Vec(vec) if vec.capacity() == 0 => *self = Self::Single(value), SingleOrVecInner::Single(first) => unsafe { let first = ptr::read(first); - ptr::write(self, Self::Vec(vec![first, value])) + ptr::write(self, Self::Vec(vec![first, value])); }, SingleOrVecInner::Vec(vec) => vec.push(value), } @@ -85,14 +85,14 @@ pub struct SingleOrVec(SingleOrVecInner); impl SingleOrVec { pub fn push(&mut self, value: T) { - self.0.push(value) + self.0.push(value); } pub fn truncate(&mut self, len: usize) { if let SingleOrVecInner::Vec(v) = &mut self.0 { - v.truncate(len) + v.truncate(len); } else if len == 0 { - self.0 = SingleOrVecInner::Vec(Vec::new()) + self.0 = SingleOrVecInner::Vec(Vec::new()); } } @@ -143,7 +143,7 @@ impl SingleOrVec { impl Default for SingleOrVec { fn default() -> Self { - Self(Default::default()) + Self(SingleOrVecInner::default()) } } @@ -192,7 +192,7 @@ impl IntoIterator for SingleOrVec { impl iter::Extend for SingleOrVec { fn extend>(&mut self, iter: I) { for value in iter { - self.push(value) + self.push(value); } } } diff --git a/commons/zenoh-collections/src/stack_buffer.rs b/commons/zenoh-collections/src/stack_buffer.rs index 893e40d401..dd3ae11d62 100644 --- a/commons/zenoh-collections/src/stack_buffer.rs +++ b/commons/zenoh-collections/src/stack_buffer.rs @@ -18,6 +18,7 @@ pub struct StackBuffer { } impl StackBuffer { + #[must_use] pub fn new(capacity: usize) -> StackBuffer { let buffer = VecDeque::::with_capacity(capacity); StackBuffer { buffer } @@ -40,21 +41,25 @@ impl StackBuffer { #[allow(dead_code)] #[inline] + #[must_use] pub fn is_empty(&self) -> bool { self.buffer.is_empty() } #[inline] + #[must_use] pub fn is_full(&self) -> bool { self.len() == self.capacity() } #[inline] + #[must_use] pub fn len(&self) -> usize { self.buffer.len() } #[inline] + #[must_use] pub fn capacity(&self) -> usize { self.buffer.capacity() } From faa701e4f0e0f0ae65f48022afcbe78874b50fbe Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 28 Jul 2023 13:28:11 +0200 Subject: [PATCH 172/203] Remove slice boundaries check in zenoh-buffers --- commons/zenoh-buffers/src/bbuf.rs | 15 ++-- commons/zenoh-buffers/src/lib.rs | 40 +++++++++++ commons/zenoh-buffers/src/slice.rs | 70 +++++++++++++------ commons/zenoh-buffers/src/vec.rs | 18 +++-- commons/zenoh-buffers/src/zbuf.rs | 66 +++++++++++------ commons/zenoh-buffers/src/zslice.rs | 9 +-- commons/zenoh-codec/src/core/zint.rs | 2 +- commons/zenoh-config/src/lib.rs | 4 +- .../src/keyexpr_tree/arc_tree.rs | 2 +- commons/zenoh-protocol/src/core/mod.rs | 2 +- io/zenoh-transport/src/unicast/link.rs | 4 +- 11 files changed, 166 insertions(+), 66 deletions(-) diff --git a/commons/zenoh-buffers/src/bbuf.rs b/commons/zenoh-buffers/src/bbuf.rs index cfa05cde5e..bdb9e9a056 100644 --- a/commons/zenoh-buffers/src/bbuf.rs +++ b/commons/zenoh-buffers/src/bbuf.rs @@ -35,27 +35,29 @@ impl BBuf { } #[must_use] - pub fn capacity(&self) -> usize { + pub const fn capacity(&self) -> usize { self.buffer.len() } #[must_use] - pub fn len(&self) -> usize { + pub const fn len(&self) -> usize { self.len } #[must_use] - pub fn is_empty(&self) -> bool { + pub const fn is_empty(&self) -> bool { self.len == 0 } #[must_use] pub fn as_slice(&self) -> &[u8] { - &self.buffer[..self.len] + // SAFETY: self.len is ensured by the writer to be smaller than buffer length. + crate::unsafe_slice!(self.buffer, ..self.len) } pub fn as_mut_slice(&mut self) -> &mut [u8] { - &mut self.buffer[..self.len] + // SAFETY: self.len is ensured by the writer to be smaller than buffer length. + crate::unsafe_slice_mut!(self.buffer, ..self.len) } pub fn clear(&mut self) { @@ -63,7 +65,8 @@ impl BBuf { } fn as_writable_slice(&mut self) -> &mut [u8] { - &mut self.buffer[self.len..] + // SAFETY: self.len is ensured by the writer to be smaller than buffer length. + crate::unsafe_slice_mut!(self.buffer, self.len..) } } diff --git a/commons/zenoh-buffers/src/lib.rs b/commons/zenoh-buffers/src/lib.rs index 10cb2bbfde..718f486def 100644 --- a/commons/zenoh-buffers/src/lib.rs +++ b/commons/zenoh-buffers/src/lib.rs @@ -33,6 +33,46 @@ pub use bbuf::*; pub use zbuf::*; pub use zslice::*; +// SAFETY: this crate operates on eventually initialized slices for read and write. Because of that, internal buffers +// implementation keeps track of various slices indexes. Boundaries checks are performed by individual +// implementations every time they need to access a slices. This means, that accessing a slice with [] +// syntax after having already verified the indexes will force the compiler to verify again the slice +// boundaries. In case of access violation the program will panic. However, it is desirable to avoid redundant +// checks for performance reasons. Nevertheless, it is desirable to keep those checks for testing and debugging +// purposes. Hence, the macros below will allow to switch boundaries check in case of test and to avoid them in +// all the other cases. +#[cfg(any(test, feature = "test"))] +#[macro_export] +macro_rules! unsafe_slice { + ($s:expr,$r:expr) => { + &$s[$r] + }; +} + +#[cfg(any(test, feature = "test"))] +#[macro_export] +macro_rules! unsafe_slice_mut { + ($s:expr,$r:expr) => { + &mut $s[$r] + }; +} + +#[cfg(all(not(test), not(feature = "test")))] +#[macro_export] +macro_rules! unsafe_slice { + ($s:expr,$r:expr) => { + unsafe { $s.get_unchecked($r) } + }; +} + +#[cfg(all(not(test), not(feature = "test")))] +#[macro_export] +macro_rules! unsafe_slice_mut { + ($s:expr,$r:expr) => { + unsafe { $s.get_unchecked_mut($r) } + }; +} + pub mod writer { use crate::ZSlice; use core::num::NonZeroUsize; diff --git a/commons/zenoh-buffers/src/slice.rs b/commons/zenoh-buffers/src/slice.rs index bea36dd0b6..6056bb9606 100644 --- a/commons/zenoh-buffers/src/slice.rs +++ b/commons/zenoh-buffers/src/slice.rs @@ -34,12 +34,20 @@ impl Writer for &mut [u8] { return Err(DidntWrite); } - self[..len].copy_from_slice(&bytes[..len]); - // Safety: this doesn't compile with simple assignment because the compiler + // SAFETY: len is guaranteed to be the minimum between lhs and rhs length. + // We early return if length is 0. + let lhs = crate::unsafe_slice_mut!(self, ..len); + let rhs = crate::unsafe_slice!(bytes, ..len); + lhs.copy_from_slice(rhs); + + // SAFETY: len is guaranteed to be the minimum between lhs and rhs length. + let lhs = crate::unsafe_slice_mut!(self, len..); + // SAFETY: this doesn't compile with simple assignment because the compiler // doesn't believe that the subslice has the same lifetime as the original slice, // so we transmute to assure it that it does. - *self = unsafe { mem::transmute(&mut self[len..]) }; - // Safety: this operation is safe since we check if len is non-zero + *self = unsafe { mem::transmute(lhs) }; + + // SAFETY: this operation is safe since we check if len is non-zero. Ok(unsafe { NonZeroUsize::new_unchecked(len) }) } @@ -49,11 +57,18 @@ impl Writer for &mut [u8] { return Err(DidntWrite); } - self[..len].copy_from_slice(&bytes[..len]); - // Safety: this doesn't compile with simple assignment because the compiler + // SAFETY: len is guaranteed to be the smaller than lhs length. + let lhs = crate::unsafe_slice_mut!(self, ..len); + let rhs = crate::unsafe_slice!(bytes, ..len); + lhs.copy_from_slice(rhs); + + // SAFETY: len is guaranteed to be the minimum between lhs and rhs length. + let lhs = crate::unsafe_slice_mut!(self, len..); + // SAFETY: this doesn't compile with simple assignment because the compiler // doesn't believe that the subslice has the same lifetime as the original slice, // so we transmute to assure it that it does. - *self = unsafe { mem::transmute(&mut self[len..]) }; + *self = unsafe { mem::transmute(lhs) }; + Ok(()) } @@ -68,11 +83,15 @@ impl Writer for &mut [u8] { if len > self.len() { return Err(DidntWrite); } - len = f(&mut self[..len]); - // Safety: this doesn't compile with simple assignment because the compiler + // SAFETY: we early return in case len is greater than slice.len(). + let s = crate::unsafe_slice_mut!(self, ..len); + len = f(s); + // SAFETY: we early return in case len is greater than slice.len(). + let s = crate::unsafe_slice_mut!(self, len..); + // SAFETY: this doesn't compile with simple assignment because the compiler // doesn't believe that the subslice has the same lifetime as the original slice, // so we transmute to assure it that it does. - *self = unsafe { mem::transmute(&mut self[len..]) }; + *self = unsafe { mem::transmute(s) }; NonZeroUsize::new(len).ok_or(DidntWrite) } @@ -97,7 +116,7 @@ impl<'s> BacktrackableWriter for &'s mut [u8] { } fn rewind(&mut self, mark: Self::Mark) -> bool { - // Safety: SliceMark's lifetime is bound to the slice's lifetime + // SAFETY: SliceMark's lifetime is bound to the slice's lifetime *self = unsafe { slice::from_raw_parts_mut(mark.ptr as *mut u8, mark.len) }; true } @@ -115,8 +134,12 @@ impl<'a> HasReader for &'a [u8] { impl Reader for &[u8] { fn read(&mut self, into: &mut [u8]) -> Result { let len = self.len().min(into.len()); - into[..len].copy_from_slice(&self[..len]); - *self = &self[len..]; + // SAFETY: len is guaranteed to be the smaller than lhs length. + let lhs = crate::unsafe_slice_mut!(into, ..len); + let rhs = crate::unsafe_slice!(self, ..len); + lhs.copy_from_slice(rhs); + // SAFETY: len is guaranteed to be smaller than slice.len(). + *self = crate::unsafe_slice!(self, len..); NonZeroUsize::new(len).ok_or(DidntRead) } @@ -125,9 +148,12 @@ impl Reader for &[u8] { if self.len() < len { return Err(DidntRead); } - - into.copy_from_slice(&self[..len]); - *self = &self[len..]; + // SAFETY: len is guaranteed to be the smaller than lhs length. + let lhs = crate::unsafe_slice_mut!(into, ..len); + let rhs = crate::unsafe_slice!(self, ..len); + lhs.copy_from_slice(rhs); + // SAFETY: len is guaranteed to be smaller than slice.len(). + *self = crate::unsafe_slice!(self, len..); Ok(()) } @@ -135,8 +161,10 @@ impl Reader for &[u8] { if !self.can_read() { return Err(DidntRead); } - let ret = self[0]; - *self = &self[1..]; + // SAFETY: we early return in case the slice is empty. + // Therefore, there is at least one element in the slice. + let ret = *crate::unsafe_slice!(self, 0); + *self = crate::unsafe_slice!(self, 1..); Ok(ret) } @@ -147,7 +175,7 @@ impl Reader for &[u8] { } fn read_zslice(&mut self, len: usize) -> Result { - // Safety: the buffer is initialized by the `read_exact()` function. Should the `read_exact()` + // SAFETY: the buffer is initialized by the `read_exact()` function. Should the `read_exact()` // function fail, the `read_zslice()` will fail as well and return None. It is hence guaranteed // that any `ZSlice` returned by `read_zslice()` points to a fully initialized buffer. let mut buffer = crate::vec::uninit(len); @@ -184,7 +212,9 @@ impl<'a> SiphonableReader for &'a [u8] { { let res = writer.write(self).map_err(|_| DidntSiphon); if let Ok(len) = res { - *self = &self[len.get()..]; + // SAFETY: len is returned from the writer, therefore it means + // len amount of bytes have been written to the slice. + *self = crate::unsafe_slice!(self, len.get()..); } res } diff --git a/commons/zenoh-buffers/src/vec.rs b/commons/zenoh-buffers/src/vec.rs index 3c0c0a7c00..cbe1ee5801 100644 --- a/commons/zenoh-buffers/src/vec.rs +++ b/commons/zenoh-buffers/src/vec.rs @@ -16,12 +16,13 @@ use crate::{ writer::{BacktrackableWriter, DidntWrite, HasWriter, Writer}, }; use alloc::vec::Vec; -use core::{num::NonZeroUsize, ptr}; +use core::{mem, num::NonZeroUsize}; /// Allocate a vector with a given capacity and sets the length to that capacity. #[must_use] pub fn uninit(capacity: usize) -> Vec { let mut vbuf = Vec::with_capacity(capacity); + // SAFETY: this operation is safe since we are setting the length equal to the allocated capacity. #[allow(clippy::uninit_vec)] unsafe { vbuf.set_len(capacity); @@ -44,7 +45,7 @@ impl Writer for &mut Vec { return Err(DidntWrite); } self.extend_from_slice(bytes); - // Safety: this operation is safe since we early return if bytes is empty + // SAFETY: this operation is safe since we early return in case bytes is empty Ok(unsafe { NonZeroUsize::new_unchecked(bytes.len()) }) } @@ -66,10 +67,15 @@ impl Writer for &mut Vec { F: FnOnce(&mut [u8]) -> usize, { self.reserve(len); - unsafe { - len = f(&mut *(ptr::addr_of_mut!(self.spare_capacity_mut()[..len]) as *mut [u8])); - self.set_len(self.len() + len); - } + + // SAFETY: we already reserved len elements on the vector. + let s = crate::unsafe_slice_mut!(self.spare_capacity_mut(), ..len); + // SAFETY: converting MaybeUninit into [u8] is safe because we are going to write on it. + // The returned len tells us how many bytes have been written so as to update the len accordingly. + len = unsafe { f(&mut *(s as *mut [mem::MaybeUninit] as *mut [u8])) }; + // SAFETY: we already reserved len elements on the vector. + unsafe { self.set_len(self.len() + len) }; + NonZeroUsize::new(len).ok_or(DidntWrite) } } diff --git a/commons/zenoh-buffers/src/zbuf.rs b/commons/zenoh-buffers/src/zbuf.rs index eb9a4a1968..3f941f48e3 100644 --- a/commons/zenoh-buffers/src/zbuf.rs +++ b/commons/zenoh-buffers/src/zbuf.rs @@ -19,7 +19,7 @@ use crate::{ SplitBuffer, ZSlice, }; use alloc::{sync::Arc, vec::Vec}; -use core::{cmp, iter, num::NonZeroUsize, ptr, slice}; +use core::{cmp, iter, mem, num::NonZeroUsize, ptr, slice}; use zenoh_collections::SingleOrVec; fn get_mut_unchecked(arc: &mut Arc) -> &mut T { @@ -89,18 +89,25 @@ impl PartialEq for ZBuf { (None, _) | (_, None) => return false, (Some(l), Some(r)) => { let cmp_len = l.len().min(r.len()); - if l[..cmp_len] != r[..cmp_len] { + // SAFETY: cmp_len is the minimum lenght between l and r slices. + let lhs = crate::unsafe_slice!(l, ..cmp_len); + let rhs = crate::unsafe_slice!(r, ..cmp_len); + if lhs != rhs { return false; } if cmp_len == l.len() { current_self = self_slices.next(); } else { - current_self = Some(&l[cmp_len..]); + // SAFETY: cmp_len is the minimum lenght between l and r slices. + let lhs = crate::unsafe_slice!(l, cmp_len..); + current_self = Some(lhs); } if cmp_len == r.len() { current_other = other_slices.next(); } else { - current_other = Some(&r[cmp_len..]); + // SAFETY: cmp_len is the minimum lenght between l and r slices. + let rhs = crate::unsafe_slice!(r, cmp_len..); + current_other = Some(rhs); } } } @@ -149,13 +156,18 @@ impl<'a> Reader for ZBufReader<'a> { let mut read = 0; while let Some(slice) = self.inner.slices.get(self.cursor.slice) { // Subslice from the current read slice - let from = &slice.as_slice()[self.cursor.byte..]; + // SAFETY: validity of self.cursor.byte is ensured by the read logic. + let from = crate::unsafe_slice!(slice.as_slice(), self.cursor.byte..); // Take the minimum length among read and write slices let len = from.len().min(into.len()); // Copy the slice content - into[..len].copy_from_slice(&from[..len]); + // SAFETY: len is the minimum lenght between from and into slices. + let lhs = crate::unsafe_slice_mut!(into, ..len); + let rhs = crate::unsafe_slice!(from, ..len); + lhs.copy_from_slice(rhs); // Advance the write slice - into = &mut into[len..]; + // SAFETY: len is the minimum lenght between from and into slices. + into = crate::unsafe_slice_mut!(into, len..); // Update the counter read += len; // Move the byte cursor @@ -195,10 +207,9 @@ impl<'a> Reader for ZBufReader<'a> { } fn remaining(&self) -> usize { - self.inner.slices.as_ref()[self.cursor.slice..] - .iter() - .fold(0, |acc, it| acc + it.len()) - - self.cursor.byte + // SAFETY: self.cursor.slice validity is ensured by the reader + let s = crate::unsafe_slice!(self.inner.slices.as_ref(), self.cursor.slice..); + s.iter().fold(0, |acc, it| acc + it.len()) - self.cursor.byte } fn read_zslices(&mut self, len: usize, mut f: F) -> Result<(), DidntRead> { @@ -268,7 +279,8 @@ impl<'a> SiphonableReader for ZBufReader<'a> { let mut read = 0; while let Some(slice) = self.inner.slices.get(self.cursor.slice) { // Subslice from the current read slice - let from = &slice.as_slice()[self.cursor.byte..]; + // SAFETY: self.cursor.byte is ensured by the reader. + let from = crate::unsafe_slice!(slice.as_slice(), self.cursor.byte..); // Copy the slice content match writer.write(from) { Ok(len) => { @@ -318,19 +330,22 @@ impl Iterator for ZBufSliceIterator<'_, '_> { return None; } - let slice = &self.reader.inner.slices[self.reader.cursor.slice]; + // SAFETY: self.reader.cursor.slice is ensured by the reader. + let slice = + crate::unsafe_slice!(self.reader.inner.slices.as_ref(), self.reader.cursor.slice); let start = self.reader.cursor.byte; - let current = &slice[start..]; + // SAFETY: self.reader.cursor.byte is ensured by the reader. + let current = crate::unsafe_slice!(slice, start..); let len = current.len(); match self.remaining.cmp(&len) { - core::cmp::Ordering::Less => { + cmp::Ordering::Less => { let end = start + self.remaining; let slice = slice.subslice(start, end); self.reader.cursor.byte = end; self.remaining = 0; slice } - core::cmp::Ordering::Equal => { + cmp::Ordering::Equal => { let end = start + self.remaining; let slice = slice.subslice(start, end); self.reader.cursor.slice += 1; @@ -338,7 +353,7 @@ impl Iterator for ZBufSliceIterator<'_, '_> { self.remaining = 0; slice } - core::cmp::Ordering::Greater => { + cmp::Ordering::Greater => { let end = start + len; let slice = slice.subslice(start, end); self.reader.cursor.slice += 1; @@ -378,7 +393,7 @@ impl Writer for ZBufWriter<'_> { return Err(DidntWrite); } self.write_exact(bytes)?; - // Safety: this operation is safe since we check if bytes is empty + // SAFETY: this operation is safe since we check if bytes is empty Ok(unsafe { NonZeroUsize::new_unchecked(bytes.len()) }) } @@ -437,10 +452,15 @@ impl Writer for ZBufWriter<'_> { let cache = get_mut_unchecked(&mut self.cache); let prev_cache_len = cache.len(); cache.reserve(len); - unsafe { - len = f(&mut *(ptr::addr_of_mut!(cache.spare_capacity_mut()[..len]) as *mut [u8])); - cache.set_len(prev_cache_len + len); - } + + // SAFETY: we already reserved len elements on the vector. + let s = crate::unsafe_slice_mut!(cache.spare_capacity_mut(), ..len); + // SAFETY: converting MaybeUninit into [u8] is safe because we are going to write on it. + // The returned len tells us how many bytes have been written so as to update the len accordingly. + len = unsafe { f(&mut *(s as *mut [mem::MaybeUninit] as *mut [u8])) }; + // SAFETY: we already reserved len elements on the vector. + unsafe { cache.set_len(prev_cache_len + len) }; + let cache_len = cache.len(); // Verify we are writing on the cache @@ -453,7 +473,7 @@ impl Writer for ZBufWriter<'_> { // Verify the ZSlice is actually a Vec if let Some(b) = buf.as_any().downcast_ref::>() { // Verify the Vec of the ZSlice is exactly the one from the cache - if core::ptr::eq(cache.as_ptr(), b.as_ptr()) { + if ptr::eq(cache.as_ptr(), b.as_ptr()) { // Simply update the slice length *end = cache_len; return NonZeroUsize::new(len).ok_or(DidntWrite); diff --git a/commons/zenoh-buffers/src/zslice.rs b/commons/zenoh-buffers/src/zslice.rs index 7a316d4b1d..294092e682 100644 --- a/commons/zenoh-buffers/src/zslice.rs +++ b/commons/zenoh-buffers/src/zslice.rs @@ -117,26 +117,27 @@ impl ZSlice { #[inline] #[must_use] - pub fn range(&self) -> Range { + pub const fn range(&self) -> Range { self.start..self.end } #[inline] #[must_use] - pub fn len(&self) -> usize { + pub const fn len(&self) -> usize { self.end - self.start } #[inline] #[must_use] - pub fn is_empty(&self) -> bool { + pub const fn is_empty(&self) -> bool { self.len() == 0 } #[inline] #[must_use] pub fn as_slice(&self) -> &[u8] { - &self.buf.as_slice()[self.range()] + // SAFETY: bounds checks are performed at `ZSlice` construction via `make()` or `subslice()`. + crate::unsafe_slice!(self.buf.as_slice(), self.range()) } #[must_use] diff --git a/commons/zenoh-codec/src/core/zint.rs b/commons/zenoh-codec/src/core/zint.rs index 5c7badb7f0..1c2f5a28e4 100644 --- a/commons/zenoh-codec/src/core/zint.rs +++ b/commons/zenoh-codec/src/core/zint.rs @@ -269,7 +269,7 @@ zint_impl!(usize); // return 1; // } // x -= VLE_THR - 1; -// // Safety: +// // SAFETY // // The `if x < VLE_THR` check at the beginning followed by `x -= VLE_THR - 1` // // guarantees at this point that `x` is never `0`. Since `x` is 64bit, // // then `n` is guaranteed to have a value between 1 and 8, both inclusives. diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index c59f71b493..f33f6ddbb3 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -689,7 +689,7 @@ where ) -> Result<>::Accessor, GetError> { let guard: MutexGuard<'a, T> = zlock!(self.inner.inner); - // Safety: MutexGuard pins the mutex behind which the value is held. + // SAFETY: MutexGuard pins the mutex behind which the value is held. let subref = guard.get(key.as_ref())? as *const _; Ok(GetGuard { _guard: guard, @@ -729,7 +729,7 @@ where ) -> Result<>::Accessor, GetError> { let guard: MutexGuard<'a, T> = zlock!(self.inner.inner); - // Safety: MutexGuard pins the mutex behind which the value is held. + // SAFETY: MutexGuard pins the mutex behind which the value is held. let subref = guard.get(key.as_ref())? as *const _; Ok(GetGuard { _guard: guard, diff --git a/commons/zenoh-keyexpr/src/keyexpr_tree/arc_tree.rs b/commons/zenoh-keyexpr/src/keyexpr_tree/arc_tree.rs index 84a011a8bf..4571ab050e 100644 --- a/commons/zenoh-keyexpr/src/keyexpr_tree/arc_tree.rs +++ b/commons/zenoh-keyexpr/src/keyexpr_tree/arc_tree.rs @@ -414,7 +414,7 @@ pub(crate) mod sealed { fn next(&mut self) -> Option { self.iter.next().map(|i| { Tokenized(i, unsafe { - // Safety: while this makes it possible for multiple mutable references to the Token to exist, + // SAFETY: while this makes it possible for multiple mutable references to the Token to exist, // it prevents them from being extracted and thus used to create multiple mutable references to // a same memory address. core::mem::transmute_copy(&self.token) diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index 72531cbb30..fedd9d6a45 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -238,7 +238,7 @@ impl From<&ZenohId> for uhlc::ID { impl From for OwnedKeyExpr { fn from(zid: ZenohId) -> Self { - // Safety: zid.to_string() returns an stringified hexadecimal + // SAFETY: zid.to_string() returns an stringified hexadecimal // representation of the zid. Therefore, building a OwnedKeyExpr // by calling from_string_unchecked() is safe because it is // guaranteed that no wildcards nor reserved chars will be present. diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/link.rs index 2cf96335f6..0c8702f260 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/link.rs @@ -182,14 +182,14 @@ impl TransportLinkUnicast { log::trace!("{}: closing", self.link); self.stop_rx(); if let Some(handle) = self.handle_rx.take() { - // Safety: it is safe to unwrap the Arc since we have the ownership of the whole link + // SAFETY: it is safe to unwrap the Arc since we have the ownership of the whole link let handle_rx = Arc::try_unwrap(handle).unwrap(); handle_rx.await; } self.stop_tx(); if let Some(handle) = self.handle_tx.take() { - // Safety: it is safe to unwrap the Arc since we have the ownership of the whole link + // SAFETY: it is safe to unwrap the Arc since we have the ownership of the whole link let handle_tx = Arc::try_unwrap(handle).unwrap(); handle_tx.await; } From dafd2292a66e9e6fcda4bcc59d747c79840f22d9 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 29 Jul 2023 09:06:29 +0200 Subject: [PATCH 173/203] Value extension for Query and Err messages --- commons/zenoh-codec/src/core/zbuf.rs | 25 ++- commons/zenoh-codec/src/zenoh_new/err.rs | 57 +----- commons/zenoh-codec/src/zenoh_new/mod.rs | 146 ++++++++++++++- commons/zenoh-codec/src/zenoh_new/query.rs | 58 +----- commons/zenoh-protocol/src/zenoh_new/err.rs | 39 +--- commons/zenoh-protocol/src/zenoh_new/mod.rs | 41 ++++- commons/zenoh-protocol/src/zenoh_new/query.rs | 36 +--- io/zenoh-transport/src/shm.rs | 174 ++++++++++++++---- zenoh/src/session.rs | 4 + 9 files changed, 377 insertions(+), 203 deletions(-) diff --git a/commons/zenoh-codec/src/core/zbuf.rs b/commons/zenoh-codec/src/core/zbuf.rs index 752792c5a8..ccf5d595ce 100644 --- a/commons/zenoh-codec/src/core/zbuf.rs +++ b/commons/zenoh-codec/src/core/zbuf.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Bounded}; +use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Bounded}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, @@ -21,6 +21,12 @@ use zenoh_buffers::{ // ZBuf bounded macro_rules! zbuf_impl { ($bound:ty) => { + impl LCodec<&ZBuf> for Zenoh080Bounded<$bound> { + fn w_len(self, message: &ZBuf) -> usize { + message.len() + } + } + impl WCodec<&ZBuf, &mut W> for Zenoh080Bounded<$bound> where W: Writer, @@ -83,6 +89,13 @@ where } } +impl LCodec<&ZBuf> for Zenoh080 { + fn w_len(self, message: &ZBuf) -> usize { + let zodec = Zenoh080Bounded::::new(); + zodec.w_len(message) + } +} + // ZBuf sliced #[cfg(feature = "shared-memory")] mod shm { @@ -95,6 +108,16 @@ mod shm { macro_rules! zbuf_sliced_impl { ($bound:ty) => { + impl LCodec<&ZBuf> for Zenoh080Sliced<$bound> { + fn w_len(self, message: &ZBuf) -> usize { + if self.is_sliced { + message.zslices().fold(0, |acc, x| acc + 1 + x.len()) + } else { + self.codec.w_len(message) + } + } + } + impl WCodec<&ZBuf, &mut W> for Zenoh080Sliced<$bound> where W: Writer, diff --git a/commons/zenoh-codec/src/zenoh_new/err.rs b/commons/zenoh-codec/src/zenoh_new/err.rs index e3273abe72..fefb055654 100644 --- a/commons/zenoh-codec/src/zenoh_new/err.rs +++ b/commons/zenoh-codec/src/zenoh_new/err.rs @@ -11,71 +11,20 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, - SplitBuffer, ZBuf, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtZBufHeader}, - core::Encoding, + common::{iext, imsg}, zenoh_new::{ err::{ext, flag, Err}, id, }, }; -impl LCodec<&ext::ErrBodyType> for Zenoh080 { - fn w_len(self, x: &ext::ErrBodyType) -> usize { - self.w_len(&x.encoding) + x.payload.len() - } -} - -impl WCodec<(&ext::ErrBodyType, bool), &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: (&ext::ErrBodyType, bool)) -> Self::Output { - let (x, more) = x; - let header: ZExtZBufHeader<{ ext::ErrBody::ID }> = ZExtZBufHeader::new(self.w_len(x)); - self.write(&mut *writer, (&header, more))?; - - self.write(&mut *writer, &x.encoding)?; - // Don't write the length since it is already included in the header - for s in x.payload.zslices() { - writer.write_zslice(s)?; - } - - Ok(()) - } -} - -impl RCodec<(ext::ErrBodyType, bool), &mut R> for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ext::ErrBodyType, bool), Self::Error> { - let (header, more): (ZExtZBufHeader<{ ext::ErrBody::ID }>, bool) = - self.read(&mut *reader)?; - - let start = reader.remaining(); - let encoding: Encoding = self.codec.read(&mut *reader)?; - let end = reader.remaining(); - // Calculate how many bytes are left in the payload - let len = header.len - (start - end); - let mut payload = ZBuf::empty(); - reader.read_zslices(len, |s| payload.push_zslice(s))?; - - Ok((ext::ErrBodyType { encoding, payload }, more)) - } -} - impl WCodec<&Err, &mut W> for Zenoh080 where W: Writer, @@ -170,7 +119,7 @@ where ext_sinfo = Some(s); has_ext = ext; } - ext::ErrBody::ID => { + ext::ErrBodyType::VID | ext::ErrBodyType::SID => { let (s, ext): (ext::ErrBodyType, bool) = eodec.read(&mut *reader)?; ext_body = Some(s); has_ext = ext; diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh_new/mod.rs index 4d06a2bfb9..a5878a2425 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh_new/mod.rs @@ -19,16 +19,21 @@ pub mod put; pub mod query; pub mod reply; +#[cfg(not(feature = "shared-memory"))] +use crate::Zenoh080Bounded; +#[cfg(feature = "shared-memory")] +use crate::Zenoh080Sliced; use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, + ZBuf, }; #[cfg(feature = "shared-memory")] -use zenoh_protocol::common::ZExtUnit; +use zenoh_protocol::common::{iext, ZExtUnit}; use zenoh_protocol::{ common::{imsg, ZExtZBufHeader}, - core::ZenohId, + core::{Encoding, ZenohId}, zenoh_new::{ext, id, PushBody, RequestBody, ResponseBody}, }; @@ -225,3 +230,140 @@ where Ok((ext::ShmType, more)) } } + +// Extension ValueType +impl WCodec<(&ext::ValueType<{ VID }, { SID }>, bool), &mut W> + for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::ValueType<{ VID }, { SID }>, bool)) -> Self::Output { + let (x, more) = x; + + #[cfg(feature = "shared-memory")] // Write Shm extension if present + if let Some(eshm) = x.ext_shm.as_ref() { + self.write(&mut *writer, (eshm, true))?; + } + + // Compute extension length + let mut len = self.w_len(&x.encoding); + + #[cfg(feature = "shared-memory")] + { + let codec = Zenoh080Sliced::::new(x.ext_shm.is_some()); + len += codec.w_len(&x.payload); + } + + #[cfg(not(feature = "shared-memory"))] + { + let codec = Zenoh080Bounded::::new(); + len += codec.w_len(&x.payload); + } + + // Write ZExtBuf header + let header: ZExtZBufHeader<{ VID }> = ZExtZBufHeader::new(len); + self.write(&mut *writer, (&header, more))?; + + // Write encoding + self.write(&mut *writer, &x.encoding)?; + + // Write payload + fn write(writer: &mut W, payload: &ZBuf) -> Result<(), DidntWrite> + where + W: Writer, + { + // Don't write the length since it is already included in the header + for s in payload.zslices() { + writer.write_zslice(s)?; + } + Ok(()) + } + + #[cfg(feature = "shared-memory")] + { + if x.ext_shm.is_some() { + let codec = Zenoh080Sliced::::new(true); + codec.write(&mut *writer, &x.payload)?; + } else { + write(&mut *writer, &x.payload)?; + } + } + + #[cfg(not(feature = "shared-memory"))] + { + write(&mut *writer, &x.payload)?; + } + + Ok(()) + } +} + +impl RCodec<(ext::ValueType<{ VID }, { SID }>, bool), &mut R> + for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read( + #[allow(unused_mut)] mut self, + reader: &mut R, + ) -> Result<(ext::ValueType<{ VID }, { SID }>, bool), Self::Error> { + #[cfg(feature = "shared-memory")] + let ext_shm = if iext::eid(self.header) == SID { + self.header = self.codec.read(&mut *reader)?; + Some(ext::ShmType) + } else { + None + }; + let (header, more): (ZExtZBufHeader<{ VID }>, bool) = self.read(&mut *reader)?; + + // Read encoding + let start = reader.remaining(); + let encoding: Encoding = self.codec.read(&mut *reader)?; + let end = reader.remaining(); + + // Read payload + fn read(reader: &mut R, len: usize) -> Result + where + R: Reader, + { + let mut payload = ZBuf::empty(); + reader.read_zslices(len, |s| payload.push_zslice(s))?; + Ok(payload) + } + + // Calculate how many bytes are left in the payload + let len = header.len - (start - end); + + let payload: ZBuf = { + #[cfg(feature = "shared-memory")] + { + if ext_shm.is_some() { + let codec = Zenoh080Sliced::::new(true); + let payload: ZBuf = codec.read(&mut *reader)?; + payload + } else { + read(&mut *reader, len)? + } + } + + #[cfg(not(feature = "shared-memory"))] + { + read(&mut *reader, len)? + } + }; + + Ok(( + ext::ValueType { + #[cfg(feature = "shared-memory")] + ext_shm, + encoding, + payload, + }, + more, + )) + } +} diff --git a/commons/zenoh-codec/src/zenoh_new/query.rs b/commons/zenoh-codec/src/zenoh_new/query.rs index 4f8cce9fdb..dbff4d3e1a 100644 --- a/commons/zenoh-codec/src/zenoh_new/query.rs +++ b/commons/zenoh-codec/src/zenoh_new/query.rs @@ -11,17 +11,15 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header}; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use alloc::{string::String, vec::Vec}; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, - SplitBuffer, ZBuf, }; use zenoh_protocol::{ - common::{iext, imsg, ZExtZBufHeader}, - core::Encoding, + common::{iext, imsg}, zenoh_new::{ id, query::{ext, flag, Query}, @@ -69,56 +67,6 @@ where } } -// Extension QueryBody -impl LCodec<&ext::QueryBodyType> for Zenoh080 { - fn w_len(self, x: &ext::QueryBodyType) -> usize { - self.w_len(&x.encoding) + x.payload.len() - } -} - -impl WCodec<(&ext::QueryBodyType, bool), &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: (&ext::QueryBodyType, bool)) -> Self::Output { - let (x, more) = x; - let header: ZExtZBufHeader<{ ext::QueryBody::ID }> = ZExtZBufHeader::new(self.w_len(x)); - self.write(&mut *writer, (&header, more))?; - - self.write(&mut *writer, &x.encoding)?; - // Don't write the length since it is already included in the header - for s in x.payload.zslices() { - writer.write_zslice(s)?; - } - - Ok(()) - } -} - -impl RCodec<(ext::QueryBodyType, bool), &mut R> for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result<(ext::QueryBodyType, bool), Self::Error> { - let (header, more): (ZExtZBufHeader<{ ext::QueryBody::ID }>, bool) = - self.read(&mut *reader)?; - - let start = reader.remaining(); - let encoding: Encoding = self.codec.read(&mut *reader)?; - let end = reader.remaining(); - // Calculate how many bytes are left in the payload - let len = header.len - (start - end); - let mut payload = ZBuf::empty(); - reader.read_zslices(len, |s| payload.push_zslice(s))?; - - Ok((ext::QueryBodyType { encoding, payload }, more)) - } -} - impl WCodec<&Query, &mut W> for Zenoh080 where W: Writer, @@ -218,7 +166,7 @@ where ext_consolidation = c; has_ext = ext; } - ext::QueryBody::ID => { + ext::QueryBodyType::SID | ext::QueryBodyType::VID => { let (s, ext): (ext::QueryBodyType, bool) = eodec.read(&mut *reader)?; ext_body = Some(s); has_ext = ext; diff --git a/commons/zenoh-protocol/src/zenoh_new/err.rs b/commons/zenoh-protocol/src/zenoh_new/err.rs index cedcd4545e..3f689169df 100644 --- a/commons/zenoh-protocol/src/zenoh_new/err.rs +++ b/commons/zenoh-protocol/src/zenoh_new/err.rs @@ -51,8 +51,7 @@ pub struct Err { } pub mod ext { - use crate::{common::ZExtZBuf, core::Encoding, zextzbuf}; - use zenoh_buffers::ZBuf; + use crate::{common::ZExtZBuf, zextzbuf}; /// # SourceInfo extension /// Used to carry additional information about the source of data @@ -60,33 +59,10 @@ pub mod ext { pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; /// # ErrBody extension - /// Used to carry a body attached to the error - pub type ErrBody = zextzbuf!(0x02, false); - - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// ~ encoding ~ - /// +---------------+ - /// ~ pl: [u8;z32] ~ -- Payload - /// +---------------+ - #[derive(Debug, Clone, PartialEq, Eq)] - pub struct ErrBodyType { - pub encoding: Encoding, - pub payload: ZBuf, - } - - impl ErrBodyType { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - let mut rng = rand::thread_rng(); - - let encoding = Encoding::rand(); - let payload = ZBuf::rand(rng.gen_range(1..=64)); - - Self { encoding, payload } - } - } + /// Used to carry a body attached to the query + /// Shared Memory extension is automatically defined by ValueType extension if + /// #[cfg(feature = "shared-memory")] is defined. + pub type ErrBodyType = crate::zenoh_new::ext::ValueType<0x02, 0x03>; } impl Err { @@ -107,7 +83,10 @@ impl Err { let ext_body = rng.gen_bool(0.5).then_some(ext::ErrBodyType::rand()); let mut ext_unknown = Vec::new(); for _ in 0..rng.gen_range(0..4) { - ext_unknown.push(ZExtUnknown::rand2(iext::mid(ext::ErrBody::ID) + 1, false)); + ext_unknown.push(ZExtUnknown::rand2( + iext::mid(ext::ErrBodyType::SID) + 1, + false, + )); } Self { diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index 256d6887f3..50df892eac 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -167,7 +167,9 @@ impl From for ResponseBody { } pub mod ext { - use crate::core::ZenohId; + use zenoh_buffers::ZBuf; + + use crate::core::{Encoding, ZenohId}; /// 7 6 5 4 3 2 1 0 /// +-+-+-+-+-+-+-+-+ @@ -217,4 +219,41 @@ pub mod ext { Self } } + + /// 7 6 5 4 3 2 1 0 + /// +-+-+-+-+-+-+-+-+ + /// ~ encoding ~ + /// +---------------+ + /// ~ pl: [u8;z32] ~ -- Payload + /// +---------------+ + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct ValueType { + #[cfg(feature = "shared-memory")] + pub ext_shm: Option>, + pub encoding: Encoding, + pub payload: ZBuf, + } + + impl ValueType<{ VID }, { SID }> { + pub const VID: u8 = VID; + pub const SID: u8 = SID; + + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + #[cfg(feature = "shared-memory")] + let ext_shm = rng.gen_bool(0.5).then_some(ShmType::rand()); + let encoding = Encoding::rand(); + let payload = ZBuf::rand(rng.gen_range(1..=64)); + + Self { + #[cfg(feature = "shared-memory")] + ext_shm, + encoding, + payload, + } + } + } } diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs index b6f6d94142..97d2dd87fc 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -90,10 +90,8 @@ pub struct Query { pub mod ext { use crate::{ common::{ZExtZ64, ZExtZBuf}, - core::Encoding, zextz64, zextzbuf, }; - use zenoh_buffers::ZBuf; /// # SourceInfo extension /// Used to carry additional information about the source of data @@ -106,32 +104,9 @@ pub mod ext { /// # QueryBody extension /// Used to carry a body attached to the query - pub type QueryBody = zextzbuf!(0x03, false); - - /// 7 6 5 4 3 2 1 0 - /// +-+-+-+-+-+-+-+-+ - /// ~ encoding ~ - /// +---------------+ - /// ~ pl: [u8;z32] ~ -- Payload - /// +---------------+ - #[derive(Debug, Clone, PartialEq, Eq)] - pub struct QueryBodyType { - pub encoding: Encoding, - pub payload: ZBuf, - } - - impl QueryBodyType { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - let mut rng = rand::thread_rng(); - - let encoding = Encoding::rand(); - let payload = ZBuf::rand(rng.gen_range(1..=64)); - - Self { encoding, payload } - } - } + /// Shared Memory extension is automatically defined by ValueType extension if + /// #[cfg(feature = "shared-memory")] is defined. + pub type QueryBodyType = crate::zenoh_new::ext::ValueType<0x03, 0x04>; } impl Query { @@ -158,7 +133,10 @@ impl Query { let ext_body = rng.gen_bool(0.5).then_some(ext::QueryBodyType::rand()); let mut ext_unknown = Vec::new(); for _ in 0..rng.gen_range(0..4) { - ext_unknown.push(ZExtUnknown::rand2(iext::mid(ext::QueryBody::ID) + 1, false)); + ext_unknown.push(ZExtUnknown::rand2( + iext::mid(ext::QueryBodyType::SID) + 1, + false, + )); } Self { diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index 90bf5edc5c..e901cdde71 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -16,35 +16,145 @@ use zenoh_buffers::{reader::HasReader, writer::HasWriter, ZBuf, ZSlice, ZSliceKi use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_core::{zasyncread, zasyncwrite, zerror}; use zenoh_protocol::{ - network::{NetworkBody, NetworkMessage, Push}, + network::{NetworkBody, NetworkMessage, Push, Request, Response}, zenoh_new::{ - put::{ext::ShmType, Put}, - PushBody, + err::{ext::ErrBodyType, Err}, + ext::ShmType, + query::{ext::QueryBodyType, Query}, + PushBody, Put, RequestBody, ResponseBody, }, }; use zenoh_result::ZResult; use zenoh_shm::{SharedMemoryBuf, SharedMemoryBufInfo, SharedMemoryReader}; -// ShmBuf -> ShmInfo -pub fn map_zmsg_to_shminfo(msg: &mut NetworkMessage) -> ZResult { - let mut res = false; +// Traits +trait MapShm { + fn map_to_shminfo(&mut self) -> ZResult; + fn map_to_shmbuf(&mut self, shmr: &RwLock) -> ZResult; +} - if let NetworkBody::Push(Push { - payload: PushBody::Put(Put { - payload, ext_shm, .. - }), - .. - }) = &mut msg.body - { - res |= map_zbuf_to_shminfo(payload)?; +macro_rules! map_to_shminfo { + ($zbuf:expr, $ext_shm:expr) => {{ + let res = map_zbuf_to_shminfo($zbuf)?; if res { - *ext_shm = Some(ShmType::new()); + *$ext_shm = Some(ShmType::new()); } + Ok(res) + }}; +} + +macro_rules! map_to_shmbuf { + ($zbuf:expr, $ext_shm:expr, $shmr:expr) => {{ + if $ext_shm.is_some() { + *$ext_shm = None; + map_zbuf_to_shmbuf($zbuf, $shmr) + } else { + Ok(false) + } + }}; +} + +// Impl - Put +impl MapShm for Put { + fn map_to_shminfo(&mut self) -> ZResult { + let Self { + payload, ext_shm, .. + } = self; + map_to_shminfo!(payload, ext_shm) } - Ok(res) + fn map_to_shmbuf(&mut self, shmr: &RwLock) -> ZResult { + let Self { + payload, ext_shm, .. + } = self; + map_to_shmbuf!(payload, ext_shm, shmr) + } } +// Impl - Query +impl MapShm for Query { + fn map_to_shminfo(&mut self) -> ZResult { + if let Self { + ext_body: Some(QueryBodyType { + payload, ext_shm, .. + }), + .. + } = self + { + map_to_shminfo!(payload, ext_shm) + } else { + Ok(false) + } + } + + fn map_to_shmbuf(&mut self, shmr: &RwLock) -> ZResult { + if let Self { + ext_body: Some(QueryBodyType { + payload, ext_shm, .. + }), + .. + } = self + { + map_to_shmbuf!(payload, ext_shm, shmr) + } else { + Ok(false) + } + } +} + +// Impl - Err +impl MapShm for Err { + fn map_to_shminfo(&mut self) -> ZResult { + if let Self { + ext_body: Some(ErrBodyType { + payload, ext_shm, .. + }), + .. + } = self + { + map_to_shminfo!(payload, ext_shm) + } else { + Ok(false) + } + } + + fn map_to_shmbuf(&mut self, shmr: &RwLock) -> ZResult { + if let Self { + ext_body: Some(ErrBodyType { + payload, ext_shm, .. + }), + .. + } = self + { + map_to_shmbuf!(payload, ext_shm, shmr) + } else { + Ok(false) + } + } +} + +// ShmBuf -> ShmInfo +pub fn map_zmsg_to_shminfo(msg: &mut NetworkMessage) -> ZResult { + match &mut msg.body { + NetworkBody::Push(Push { payload, .. }) => match payload { + PushBody::Put(b) => b.map_to_shminfo(), + PushBody::Del(_) => Ok(false), + }, + NetworkBody::Request(Request { payload, .. }) => match payload { + RequestBody::Query(b) => b.map_to_shminfo(), + RequestBody::Put(b) => b.map_to_shminfo(), + RequestBody::Del(_) | RequestBody::Pull(_) => Ok(false), + }, + NetworkBody::Response(Response { payload, .. }) => match payload { + ResponseBody::Put(b) => b.map_to_shminfo(), + ResponseBody::Err(b) => b.map_to_shminfo(), + ResponseBody::Ack(_) | ResponseBody::Reply(_) => Ok(false), + }, + NetworkBody::ResponseFinal(_) | NetworkBody::Declare(_) | NetworkBody::OAM(_) => Ok(false), + } +} + +// Mapping pub fn map_zbuf_to_shminfo(zbuf: &mut ZBuf) -> ZResult { let mut res = false; for zs in zbuf.zslices_mut() { @@ -79,24 +189,26 @@ pub fn map_zmsg_to_shmbuf( msg: &mut NetworkMessage, shmr: &RwLock, ) -> ZResult { - let mut res = false; - - if let NetworkBody::Push(Push { - payload: PushBody::Put(Put { - payload, ext_shm, .. - }), - .. - }) = &mut msg.body - { - if ext_shm.is_some() { - res |= map_zbuf_to_shmbuf(payload, shmr)?; - *ext_shm = None; - } + match &mut msg.body { + NetworkBody::Push(Push { payload, .. }) => match payload { + PushBody::Put(b) => b.map_to_shmbuf(shmr), + PushBody::Del(_) => Ok(false), + }, + NetworkBody::Request(Request { payload, .. }) => match payload { + RequestBody::Query(b) => b.map_to_shmbuf(shmr), + RequestBody::Put(b) => b.map_to_shmbuf(shmr), + RequestBody::Del(_) | RequestBody::Pull(_) => Ok(false), + }, + NetworkBody::Response(Response { payload, .. }) => match payload { + ResponseBody::Put(b) => b.map_to_shmbuf(shmr), + ResponseBody::Err(b) => b.map_to_shmbuf(shmr), + ResponseBody::Ack(_) | ResponseBody::Reply(_) => Ok(false), + }, + NetworkBody::ResponseFinal(_) | NetworkBody::Declare(_) | NetworkBody::OAM(_) => Ok(false), } - - Ok(res) } +// Mapping pub fn map_zbuf_to_shmbuf(zbuf: &mut ZBuf, shmr: &RwLock) -> ZResult { let mut res = false; for zs in zbuf.zslices_mut().filter(|x| x.kind == ZSliceKind::ShmPtr) { diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 05b39ffee6..1c8fe571f9 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -1658,6 +1658,8 @@ impl Session { ext_sinfo: None, ext_consolidation: consolidation.into(), ext_body: value.as_ref().map(|v| query::ext::QueryBodyType { + #[cfg(feature = "shared-memory")] + ext_shm: None, encoding: v.encoding.clone(), payload: v.payload.clone(), }), @@ -1674,6 +1676,8 @@ impl Session { target.into(), consolidation.into(), value.as_ref().map(|v| query::ext::QueryBodyType { + #[cfg(feature = "shared-memory")] + ext_shm: None, encoding: v.encoding.clone(), payload: v.payload.clone(), }), From a1ec6c206d35031bdca3f4a2687de4b9d9a81218 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 29 Jul 2023 10:49:55 +0200 Subject: [PATCH 174/203] Add SHM support to Reply --- commons/zenoh-codec/src/zenoh_new/reply.rs | 53 +++++++++++++++++-- commons/zenoh-protocol/src/zenoh_new/reply.rs | 17 +++++- io/zenoh-transport/src/shm.rs | 25 +++++++-- zenoh/src/net/routing/queries.rs | 2 + zenoh/src/queryable.rs | 2 + 5 files changed, 90 insertions(+), 9 deletions(-) diff --git a/commons/zenoh-codec/src/zenoh_new/reply.rs b/commons/zenoh-codec/src/zenoh_new/reply.rs index ef4643210f..62de9d7343 100644 --- a/commons/zenoh-codec/src/zenoh_new/reply.rs +++ b/commons/zenoh-codec/src/zenoh_new/reply.rs @@ -11,7 +11,11 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Bounded, Zenoh080Header}; +#[cfg(not(feature = "shared-memory"))] +use crate::Zenoh080Bounded; +#[cfg(feature = "shared-memory")] +use crate::Zenoh080Sliced; +use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header}; use alloc::vec::Vec; use zenoh_buffers::{ reader::{DidntRead, Reader}, @@ -45,6 +49,10 @@ where let mut n_exts = (x.ext_sinfo.is_some()) as u8 + ((x.ext_consolidation != ext::ConsolidationType::default()) as u8) + (x.ext_unknown.len() as u8); + #[cfg(feature = "shared-memory")] + { + n_exts += x.ext_shm.is_some() as u8; + } if n_exts != 0 { header |= flag::Z; } @@ -67,14 +75,28 @@ where n_exts -= 1; self.write(&mut *writer, (x.ext_consolidation, n_exts != 0))?; } + #[cfg(feature = "shared-memory")] + if let Some(eshm) = x.ext_shm.as_ref() { + n_exts -= 1; + self.write(&mut *writer, (eshm, n_exts != 0))?; + } for u in x.ext_unknown.iter() { n_exts -= 1; self.write(&mut *writer, (u, n_exts != 0))?; } // Payload - let bodec = Zenoh080Bounded::::new(); - bodec.write(&mut *writer, &x.payload)?; + #[cfg(feature = "shared-memory")] + { + let codec = Zenoh080Sliced::::new(x.ext_shm.is_some()); + codec.write(&mut *writer, &x.payload)?; + } + + #[cfg(not(feature = "shared-memory"))] + { + let bodec = Zenoh080Bounded::::new(); + bodec.write(&mut *writer, &x.payload)?; + } Ok(()) } @@ -118,6 +140,8 @@ where // Extensions let mut ext_sinfo: Option = None; let mut ext_consolidation = ext::ConsolidationType::default(); + #[cfg(feature = "shared-memory")] + let mut ext_shm: Option = None; let mut ext_unknown = Vec::new(); let mut has_ext = imsg::has_flag(self.header, flag::Z); @@ -135,6 +159,12 @@ where ext_consolidation = c; has_ext = ext; } + #[cfg(feature = "shared-memory")] + ext::Shm::ID => { + let (s, ext): (ext::ShmType, bool) = eodec.read(&mut *reader)?; + ext_shm = Some(s); + has_ext = ext; + } _ => { let (u, ext) = extension::read(reader, "Reply", ext)?; ext_unknown.push(u); @@ -144,14 +174,27 @@ where } // Payload - let bodec = Zenoh080Bounded::::new(); - let payload: ZBuf = bodec.read(&mut *reader)?; + let payload: ZBuf = { + #[cfg(feature = "shared-memory")] + { + let codec = Zenoh080Sliced::::new(ext_shm.is_some()); + codec.read(&mut *reader)? + } + + #[cfg(not(feature = "shared-memory"))] + { + let bodec = Zenoh080Bounded::::new(); + bodec.read(&mut *reader)? + } + }; Ok(Reply { timestamp, encoding, ext_sinfo, ext_consolidation, + #[cfg(feature = "shared-memory")] + ext_shm, ext_unknown, payload, }) diff --git a/commons/zenoh-protocol/src/zenoh_new/reply.rs b/commons/zenoh-protocol/src/zenoh_new/reply.rs index e384681338..58322432ef 100644 --- a/commons/zenoh-protocol/src/zenoh_new/reply.rs +++ b/commons/zenoh-protocol/src/zenoh_new/reply.rs @@ -49,11 +49,15 @@ pub struct Reply { pub encoding: Encoding, pub ext_sinfo: Option, pub ext_consolidation: ext::ConsolidationType, + #[cfg(feature = "shared-memory")] + pub ext_shm: Option, pub ext_unknown: Vec, pub payload: ZBuf, } pub mod ext { + #[cfg(feature = "shared-memory")] + use crate::{common::ZExtUnit, zextunit}; use crate::{ common::{ZExtZ64, ZExtZBuf}, zextz64, zextzbuf, @@ -67,6 +71,13 @@ pub mod ext { /// # Consolidation extension pub type Consolidation = zextz64!(0x2, true); pub type ConsolidationType = crate::zenoh_new::query::ext::ConsolidationType; + + /// # Shared Memory extension + /// Used to carry additional information about the shared-memory layour of data + #[cfg(feature = "shared-memory")] + pub type Shm = zextunit!(0x3, true); + #[cfg(feature = "shared-memory")] + pub type ShmType = crate::zenoh_new::ext::ShmType<{ Shm::ID }>; } impl Reply { @@ -84,7 +95,8 @@ impl Reply { let encoding = Encoding::rand(); let ext_sinfo = rng.gen_bool(0.5).then_some(ext::SourceInfoType::rand()); let ext_consolidation = Consolidation::rand(); - let payload = ZBuf::rand(rng.gen_range(1..=64)); + #[cfg(feature = "shared-memory")] + let ext_shm = rng.gen_bool(0.5).then_some(ext::ShmType::rand()); let mut ext_unknown = Vec::new(); for _ in 0..rng.gen_range(0..4) { ext_unknown.push(ZExtUnknown::rand2( @@ -92,12 +104,15 @@ impl Reply { false, )); } + let payload = ZBuf::rand(rng.gen_range(1..=64)); Self { timestamp, encoding, ext_sinfo, ext_consolidation, + #[cfg(feature = "shared-memory")] + ext_shm, ext_unknown, payload, } diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index e901cdde71..ce01fd7d43 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -21,7 +21,7 @@ use zenoh_protocol::{ err::{ext::ErrBodyType, Err}, ext::ShmType, query::{ext::QueryBodyType, Query}, - PushBody, Put, RequestBody, ResponseBody, + PushBody, Put, Reply, RequestBody, ResponseBody, }, }; use zenoh_result::ZResult; @@ -102,6 +102,23 @@ impl MapShm for Query { } } +// Impl - Reply +impl MapShm for Reply { + fn map_to_shminfo(&mut self) -> ZResult { + let Self { + payload, ext_shm, .. + } = self; + map_to_shminfo!(payload, ext_shm) + } + + fn map_to_shmbuf(&mut self, shmr: &RwLock) -> ZResult { + let Self { + payload, ext_shm, .. + } = self; + map_to_shmbuf!(payload, ext_shm, shmr) + } +} + // Impl - Err impl MapShm for Err { fn map_to_shminfo(&mut self) -> ZResult { @@ -146,9 +163,10 @@ pub fn map_zmsg_to_shminfo(msg: &mut NetworkMessage) -> ZResult { RequestBody::Del(_) | RequestBody::Pull(_) => Ok(false), }, NetworkBody::Response(Response { payload, .. }) => match payload { + ResponseBody::Reply(b) => b.map_to_shminfo(), ResponseBody::Put(b) => b.map_to_shminfo(), ResponseBody::Err(b) => b.map_to_shminfo(), - ResponseBody::Ack(_) | ResponseBody::Reply(_) => Ok(false), + ResponseBody::Ack(_) => Ok(false), }, NetworkBody::ResponseFinal(_) | NetworkBody::Declare(_) | NetworkBody::OAM(_) => Ok(false), } @@ -202,7 +220,8 @@ pub fn map_zmsg_to_shmbuf( NetworkBody::Response(Response { payload, .. }) => match payload { ResponseBody::Put(b) => b.map_to_shmbuf(shmr), ResponseBody::Err(b) => b.map_to_shmbuf(shmr), - ResponseBody::Ack(_) | ResponseBody::Reply(_) => Ok(false), + ResponseBody::Reply(b) => b.map_to_shmbuf(shmr), + ResponseBody::Ack(_) => Ok(false), }, NetworkBody::ResponseFinal(_) | NetworkBody::Declare(_) | NetworkBody::OAM(_) => Ok(false), } diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 54f55d06e1..5a6e0c9dfc 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -2039,6 +2039,8 @@ pub fn route_query( encoding: Encoding::default(), ext_sinfo: None, ext_consolidation: ConsolidationType::default(), + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload, }), diff --git a/zenoh/src/queryable.rs b/zenoh/src/queryable.rs index b19bdbdf8e..e52bd68815 100644 --- a/zenoh/src/queryable.rs +++ b/zenoh/src/queryable.rs @@ -184,6 +184,8 @@ impl SyncResolve for ReplyBuilder<'_> { None }, ext_consolidation: ConsolidationType::default(), + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload, }), From b85f3b420b49348309c10f69c752cac81418eca4 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 31 Jul 2023 10:08:52 +0200 Subject: [PATCH 175/203] Fix cargo clippy --- commons/zenoh-protocol/src/network/mod.rs | 14 ++++-- commons/zenoh-protocol/src/zenoh_new/mod.rs | 14 +++--- io/zenoh-link/src/lib.rs | 2 +- io/zenoh-links/zenoh-link-tls/src/lib.rs | 4 +- io/zenoh-links/zenoh-link-tls/src/unicast.rs | 11 +++-- io/zenoh-transport/src/lib.rs | 2 +- .../unicast/establishment/ext/multilink.rs | 2 +- io/zenoh-transport/tests/endpoints.rs | 4 +- .../tests/unicast_authenticator.rs | 14 +++--- io/zenoh-transport/tests/unicast_conduits.rs | 4 +- .../tests/unicast_defragmentation.rs | 4 +- .../tests/unicast_intermittent.rs | 10 ++-- io/zenoh-transport/tests/unicast_multilink.rs | 8 ++-- io/zenoh-transport/tests/unicast_openclose.rs | 6 +-- io/zenoh-transport/tests/unicast_transport.rs | 4 +- .../src/replica/digest.rs | 6 +-- zenoh/src/liveliness.rs | 2 +- zenoh/src/net/routing/face.rs | 2 +- zenoh/src/net/routing/network.rs | 2 +- zenoh/src/net/routing/pubsub.rs | 21 ++++---- zenoh/src/net/routing/queries.rs | 28 +++++------ zenoh/src/net/routing/resource.rs | 11 +++-- zenoh/src/net/runtime/adminspace.rs | 17 ++++--- zenoh/src/session.rs | 48 ++++++++----------- zenoh/src/subscriber.rs | 3 +- 25 files changed, 120 insertions(+), 123 deletions(-) diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 573bd828f8..7b8df40fd5 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -19,11 +19,15 @@ pub mod response; use core::fmt; -pub use declare::*; -pub use oam::*; -pub use push::*; -pub use request::*; -pub use response::*; +pub use declare::{ + Declare, DeclareBody, DeclareInterest, DeclareKeyExpr, DeclareQueryable, DeclareSubscriber, + DeclareToken, UndeclareInterest, UndeclareKeyExpr, UndeclareQueryable, UndeclareSubscriber, + UndeclareToken, +}; +pub use oam::{Oam, OamId}; +pub use push::Push; +pub use request::{AtomicRequestId, Request, RequestId}; +pub use response::{Response, ResponseFinal}; use crate::core::{CongestionControl, Priority}; diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh_new/mod.rs index 50df892eac..740c7e8b0d 100644 --- a/commons/zenoh-protocol/src/zenoh_new/mod.rs +++ b/commons/zenoh-protocol/src/zenoh_new/mod.rs @@ -20,13 +20,13 @@ pub mod query; pub mod reply; use crate::core::Encoding; -pub use ack::*; -pub use del::*; -pub use err::*; -pub use pull::*; -pub use put::*; -pub use query::*; -pub use reply::*; +pub use ack::Ack; +pub use del::Del; +pub use err::Err; +pub use pull::Pull; +pub use put::Put; +pub use query::{Consolidation, Query}; +pub use reply::Reply; pub mod id { pub const OAM: u8 = 0x00; diff --git a/io/zenoh-link/src/lib.rs b/io/zenoh-link/src/lib.rs index 36cb1e2cc8..724a06bf9f 100644 --- a/io/zenoh-link/src/lib.rs +++ b/io/zenoh-link/src/lib.rs @@ -214,7 +214,7 @@ impl LinkManagerBuilderMulticast { pub fn make(protocol: &str) -> ZResult { match protocol { #[cfg(feature = "transport_udp")] - UDP_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerMulticastUdp::default())), + UDP_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerMulticastUdp)), _ => bail!("Multicast not supported for {} protocol", protocol), } } diff --git a/io/zenoh-links/zenoh-link-tls/src/lib.rs b/io/zenoh-links/zenoh-link-tls/src/lib.rs index 8949513424..5fb29c738b 100644 --- a/io/zenoh-links/zenoh-link-tls/src/lib.rs +++ b/io/zenoh-links/zenoh-link-tls/src/lib.rs @@ -17,14 +17,14 @@ //! This crate is intended for Zenoh's internal use. //! //! [Click here for Zenoh's documentation](../zenoh/index.html) -use std::{convert::TryFrom, net::SocketAddr}; - +use async_rustls::rustls::ServerName; use async_std::net::ToSocketAddrs; use async_trait::async_trait; use config::{ TLS_CLIENT_AUTH, TLS_CLIENT_CERTIFICATE_FILE, TLS_CLIENT_PRIVATE_KEY_FILE, TLS_ROOT_CA_CERTIFICATE_FILE, TLS_SERVER_CERTIFICATE_FILE, TLS_SERVER_PRIVATE_KEY_FILE, }; +use std::{convert::TryFrom, net::SocketAddr}; use zenoh_config::Config; use zenoh_core::zconfigurable; use zenoh_link_commons::{ConfigurationInspector, LocatorInspector}; diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast.rs b/io/zenoh-links/zenoh-link-tls/src/unicast.rs index c5d7f39182..90467b16a0 100644 --- a/io/zenoh-links/zenoh-link-tls/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tls/src/unicast.rs @@ -15,10 +15,13 @@ use crate::{ config::*, get_tls_addr, get_tls_host, get_tls_server_name, TLS_ACCEPT_THROTTLE_TIME, TLS_DEFAULT_MTU, TLS_LINGER_TIMEOUT, TLS_LOCATOR_PREFIX, }; -use async_rustls::rustls::server::AllowAnyAuthenticatedClient; -use async_rustls::rustls::version::TLS13; -pub use async_rustls::rustls::*; -use async_rustls::{TlsAcceptor, TlsConnector, TlsStream}; +use async_rustls::{ + rustls::{ + server::AllowAnyAuthenticatedClient, version::TLS13, Certificate, ClientConfig, + OwnedTrustAnchor, PrivateKey, RootCertStore, ServerConfig, + }, + TlsAcceptor, TlsConnector, TlsStream, +}; use async_std::fs; use async_std::net::{SocketAddr, TcpListener, TcpStream}; use async_std::prelude::FutureExt; diff --git a/io/zenoh-transport/src/lib.rs b/io/zenoh-transport/src/lib.rs index 0e060d6f27..82f8a91935 100644 --- a/io/zenoh-transport/src/lib.rs +++ b/io/zenoh-transport/src/lib.rs @@ -55,7 +55,7 @@ impl TransportEventHandler for DummyTransportEventHandler { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) + Ok(Arc::new(DummyTransportPeerEventHandler)) } } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs b/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs index 2e71bd4a02..6aa305c726 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/multilink.rs @@ -281,7 +281,7 @@ impl<'a> AcceptFsm for MultiLinkFsm<'a> { ) -> Result { const S: &str = "MultiLink extension - Recv InitSyn."; - let (mut state, mut ext) = input; + let (state, mut ext) = input; let mut pubkey = match state.pubkey.take() { Some(pubkey) => pubkey, None => return Ok(()), diff --git a/io/zenoh-transport/tests/endpoints.rs b/io/zenoh-transport/tests/endpoints.rs index 9ed9433b35..da28cae3ea 100644 --- a/io/zenoh-transport/tests/endpoints.rs +++ b/io/zenoh-transport/tests/endpoints.rs @@ -46,7 +46,7 @@ impl TransportEventHandler for SH { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - let arc = Arc::new(SC::default()); + let arc = Arc::new(SC); Ok(arc) } } @@ -74,7 +74,7 @@ async fn run(endpoints: &[EndPoint]) { let sm = TransportManager::builder() .whatami(WhatAmI::Peer) .zid(ZenohId::try_from([1]).unwrap()) - .build(Arc::new(SH::default())) + .build(Arc::new(SH)) .unwrap(); for _ in 0..RUNS { diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index 02037a9238..071c545f47 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -86,7 +86,7 @@ impl TransportEventHandler for SHClientAuthenticator { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) + Ok(Arc::new(DummyTransportPeerEventHandler)) } } @@ -147,7 +147,7 @@ async fn auth_pubkey(endpoint: &EndPoint) { .whatami(WhatAmI::Client) .zid(client01_id) .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) + .build(Arc::new(SHClientAuthenticator)) .unwrap(); // Create the transport transport manager for the client 02 @@ -201,7 +201,7 @@ async fn auth_pubkey(endpoint: &EndPoint) { .whatami(WhatAmI::Client) .zid(client02_id) .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) + .build(Arc::new(SHClientAuthenticator)) .unwrap(); // Create the transport transport manager for the client 03 with the same key as client 02 @@ -216,7 +216,7 @@ async fn auth_pubkey(endpoint: &EndPoint) { .whatami(WhatAmI::Client) .zid(client03_id) .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) + .build(Arc::new(SHClientAuthenticator)) .unwrap(); // Create the router transport manager @@ -424,7 +424,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { .whatami(WhatAmI::Client) .zid(client01_id) .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) + .build(Arc::new(SHClientAuthenticator)) .unwrap(); // Create the transport transport manager for the second client @@ -437,7 +437,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { .whatami(WhatAmI::Client) .zid(client02_id) .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) + .build(Arc::new(SHClientAuthenticator)) .unwrap(); // Create the transport transport manager for the third client @@ -450,7 +450,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { .whatami(WhatAmI::Client) .zid(client03_id) .unicast(unicast) - .build(Arc::new(SHClientAuthenticator::default())) + .build(Arc::new(SHClientAuthenticator)) .unwrap(); /* [1] */ diff --git a/io/zenoh-transport/tests/unicast_conduits.rs b/io/zenoh-transport/tests/unicast_conduits.rs index 4ab4d7b5ca..74db6ecae6 100644 --- a/io/zenoh-transport/tests/unicast_conduits.rs +++ b/io/zenoh-transport/tests/unicast_conduits.rs @@ -153,7 +153,7 @@ impl TransportEventHandler for SHClient { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(SCClient::default())) + Ok(Arc::new(SCClient)) } } @@ -205,7 +205,7 @@ async fn open_transport( let client_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client_id) - .build(Arc::new(SHClient::default())) + .build(Arc::new(SHClient)) .unwrap(); // Create the listener on the router diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index 7ca2748b68..1dc4d4684d 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -51,7 +51,7 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { .zid(router_id) .whatami(WhatAmI::Router) .defrag_buff_size(MSG_DEFRAG_BUF) - .build(Arc::new(DummyTransportEventHandler::default())) + .build(Arc::new(DummyTransportEventHandler)) .unwrap(); // Create the client transport manager @@ -59,7 +59,7 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { .whatami(WhatAmI::Client) .zid(client_id) .defrag_buff_size(MSG_DEFRAG_BUF) - .build(Arc::new(DummyTransportEventHandler::default())) + .build(Arc::new(DummyTransportEventHandler)) .unwrap(); // Create the listener on the router diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index a00d7e09c5..e9cec266dc 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -60,7 +60,7 @@ impl TransportEventHandler for SHRouterIntermittent { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) + Ok(Arc::new(DummyTransportPeerEventHandler)) } } @@ -74,7 +74,7 @@ impl TransportEventHandler for SHClientIntermittent { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) + Ok(Arc::new(DummyTransportPeerEventHandler)) } } @@ -130,7 +130,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { /* [ROUTER] */ let router_id = ZenohId::try_from([1]).unwrap(); - let router_handler = Arc::new(SHRouterIntermittent::default()); + let router_handler = Arc::new(SHRouterIntermittent); // Create the router transport manager let unicast = TransportManager::config_unicast() .max_links(1) @@ -167,7 +167,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { .whatami(WhatAmI::Client) .zid(client02_id) .unicast(unicast) - .build(Arc::new(SHClientIntermittent::default())) + .build(Arc::new(SHClientIntermittent)) .unwrap(); // Create the transport transport manager for the third client @@ -178,7 +178,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { .whatami(WhatAmI::Client) .zid(client03_id) .unicast(unicast) - .build(Arc::new(SHClientIntermittent::default())) + .build(Arc::new(SHClientIntermittent)) .unwrap(); /* [1] */ diff --git a/io/zenoh-transport/tests/unicast_multilink.rs b/io/zenoh-transport/tests/unicast_multilink.rs index 22dd67d46c..bb38175062 100644 --- a/io/zenoh-transport/tests/unicast_multilink.rs +++ b/io/zenoh-transport/tests/unicast_multilink.rs @@ -43,7 +43,7 @@ mod tests { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) + Ok(Arc::new(DummyTransportPeerEventHandler)) } } @@ -62,7 +62,7 @@ mod tests { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) + Ok(Arc::new(DummyTransportPeerEventHandler)) } } @@ -70,7 +70,7 @@ mod tests { /* [ROUTER] */ let router_id = ZenohId::try_from([1]).unwrap(); - let router_handler = Arc::new(SHRouterOpenClose::default()); + let router_handler = Arc::new(SHRouterOpenClose); // Create the router transport manager let unicast = TransportManager::config_unicast() .max_links(2) @@ -466,7 +466,7 @@ mod tests { task::sleep(SLEEP).await; } - #[cfg(all(feature = "transport_tcp"))] + #[cfg(feature = "transport_tcp")] #[test] fn multilink_tcp_only() { let _ = env_logger::try_init(); diff --git a/io/zenoh-transport/tests/unicast_openclose.rs b/io/zenoh-transport/tests/unicast_openclose.rs index 23d76d7575..2e5af05682 100644 --- a/io/zenoh-transport/tests/unicast_openclose.rs +++ b/io/zenoh-transport/tests/unicast_openclose.rs @@ -41,7 +41,7 @@ impl TransportEventHandler for SHRouterOpenClose { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) + Ok(Arc::new(DummyTransportPeerEventHandler)) } } @@ -60,7 +60,7 @@ impl TransportEventHandler for SHClientOpenClose { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(DummyTransportPeerEventHandler::default())) + Ok(Arc::new(DummyTransportPeerEventHandler)) } } @@ -68,7 +68,7 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [ROUTER] */ let router_id = ZenohId::try_from([1]).unwrap(); - let router_handler = Arc::new(SHRouterOpenClose::default()); + let router_handler = Arc::new(SHRouterOpenClose); // Create the router transport manager let unicast = TransportManager::config_unicast() .max_links(2) diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index e0699ce84e..8707edf2b0 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -295,7 +295,7 @@ impl TransportEventHandler for SHClient { _peer: TransportPeer, _transport: TransportUnicast, ) -> ZResult> { - Ok(Arc::new(SCClient::default())) + Ok(Arc::new(SCClient)) } } @@ -354,7 +354,7 @@ async fn open_transport( .whatami(WhatAmI::Client) .zid(client_id) .unicast(unicast) - .build(Arc::new(SHClient::default())) + .build(Arc::new(SHClient)) .unwrap(); // Create an empty transport with the client diff --git a/plugins/zenoh-plugin-storage-manager/src/replica/digest.rs b/plugins/zenoh-plugin-storage-manager/src/replica/digest.rs index bc759b14e0..98faa24aa2 100644 --- a/plugins/zenoh-plugin-storage-manager/src/replica/digest.rs +++ b/plugins/zenoh-plugin-storage-manager/src/replica/digest.rs @@ -293,7 +293,7 @@ impl Digest { // reconstruct updated parts of the digest for sub in subintervals_to_update { - let mut subinterval = subintervals.get_mut(&sub).unwrap(); + let subinterval = subintervals.get_mut(&sub).unwrap(); let content = &subinterval.content; if !content.is_empty() { // order the content, hash them @@ -308,7 +308,7 @@ impl Digest { } for int in intervals_to_update { - let mut interval = intervals.get_mut(&int).unwrap(); + let interval = intervals.get_mut(&int).unwrap(); let content = &interval.content; if !content.is_empty() { // order the content, hash them @@ -324,7 +324,7 @@ impl Digest { } for era_type in eras_to_update { - let mut era = eras.get_mut(&era_type).unwrap(); + let era = eras.get_mut(&era_type).unwrap(); let content = &era.content; if !content.is_empty() { // order the content, hash them diff --git a/zenoh/src/liveliness.rs b/zenoh/src/liveliness.rs index 082975f57f..5e9894c77c 100644 --- a/zenoh/src/liveliness.rs +++ b/zenoh/src/liveliness.rs @@ -36,7 +36,7 @@ use { zenoh_core::Resolvable, zenoh_core::Result as ZResult, zenoh_core::SyncResolve, - zenoh_protocol::network::subscriber::ext::SubscriberInfo, + zenoh_protocol::network::declare::subscriber::ext::SubscriberInfo, }; #[zenoh_macros::unstable] diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index bcd2c71bba..fd48a5dd42 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -16,7 +16,7 @@ use std::collections::{HashMap, HashSet}; use std::fmt; use std::sync::Arc; use zenoh_protocol::core::{ExprId, WhatAmI, ZenohId}; -use zenoh_protocol::network::queryable::ext::QueryableInfo; +use zenoh_protocol::network::declare::queryable::ext::QueryableInfo; use zenoh_protocol::network::{Mapping, Push, Request, RequestId, Response, ResponseFinal}; use zenoh_protocol::zenoh_new::RequestBody; use zenoh_transport::Primitives; diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index 3d6a5b94a0..f2b3fa3488 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -1,4 +1,3 @@ -use crate::net::codec::Zenoh080Routing; // // Copyright (c) 2023 ZettaScale Technology // @@ -12,6 +11,7 @@ use crate::net::codec::Zenoh080Routing; // Contributors: // ZettaScale Zenoh Team, // +use crate::net::codec::Zenoh080Routing; use crate::net::protocol::linkstate::{LinkState, LinkStateList}; use crate::net::protocol::OAM_LINKSTATE; use crate::net::runtime::Runtime; diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index bee733a503..51048af49a 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -22,17 +22,20 @@ use std::convert::TryFrom; use std::sync::RwLock; use std::sync::{Arc, RwLockReadGuard}; use zenoh_core::zread; -use zenoh_protocol::core::key_expr::keyexpr; -use zenoh_protocol::network::common::ext::WireExprType; -use zenoh_protocol::network::declare::ext; -use zenoh_protocol::network::subscriber::ext::SubscriberInfo; -use zenoh_protocol::network::{ - Declare, DeclareBody, DeclareSubscriber, Mode, Push, UndeclareSubscriber, -}; -use zenoh_protocol::zenoh_new::PushBody; use zenoh_protocol::{ - core::{key_expr::OwnedKeyExpr, Reliability, WhatAmI, WireExpr, ZenohId}, + core::{ + key_expr::{keyexpr, OwnedKeyExpr}, + Reliability, WhatAmI, WireExpr, ZenohId, + }, + network::{ + declare::{ + common::ext::WireExprType, ext, subscriber::ext::SubscriberInfo, Declare, DeclareBody, + DeclareSubscriber, Mode, UndeclareSubscriber, + }, + Push, + }, zenoh::RoutingContext, + zenoh_new::PushBody, }; use zenoh_sync::get_mut_unchecked; diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 5a6e0c9dfc..e21d0749fb 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -25,28 +25,24 @@ use std::collections::HashMap; use std::convert::TryFrom; use std::sync::{Arc, RwLockReadGuard, Weak}; use zenoh_buffers::ZBuf; -use zenoh_protocol::core::key_expr::keyexpr; -use zenoh_protocol::core::Encoding; -use zenoh_protocol::network::common::ext::WireExprType; -use zenoh_protocol::network::declare::ext; -use zenoh_protocol::network::request::ext::TargetType; -use zenoh_protocol::network::response::ext::ResponderIdType; -use zenoh_protocol::network::{ - response, Declare, DeclareBody, DeclareQueryable, Request, RequestId, Response, ResponseFinal, - UndeclareQueryable, -}; -use zenoh_protocol::zenoh_new::reply::ext::ConsolidationType; -use zenoh_protocol::zenoh_new::{self, RequestBody, ResponseBody}; use zenoh_protocol::{ core::{ key_expr::{ include::{Includer, DEFAULT_INCLUDER}, - OwnedKeyExpr, + keyexpr, OwnedKeyExpr, + }, + Encoding, WhatAmI, WireExpr, ZenohId, + }, + network::{ + declare::{ + common::ext::WireExprType, ext, queryable::ext::QueryableInfo, Declare, DeclareBody, + DeclareQueryable, UndeclareQueryable, }, - WhatAmI, WireExpr, ZenohId, + request::{ext::TargetType, Request, RequestId}, + response::{self, ext::ResponderIdType, Response, ResponseFinal}, }, - network::queryable::ext::QueryableInfo, zenoh::{QueryId, RoutingContext}, + zenoh_new::{reply::ext::ConsolidationType, Reply, RequestBody, ResponseBody}, }; use zenoh_sync::get_mut_unchecked; use zenoh_util::Timed; @@ -2034,7 +2030,7 @@ pub fn route_query( face.primitives.clone().send_response(Response { rid: qid, wire_expr: expr, - payload: ResponseBody::Reply(zenoh_new::Reply { + payload: ResponseBody::Reply(Reply { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index b918f2ed42..18417a4781 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -17,15 +17,18 @@ use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use std::hash::{Hash, Hasher}; use std::sync::{Arc, Weak}; -use zenoh_protocol::network::declare::ext; -use zenoh_protocol::network::queryable::ext::QueryableInfo; #[cfg(feature = "complete_n")] use zenoh_protocol::network::request::ext::TargetType; -use zenoh_protocol::network::subscriber::ext::SubscriberInfo; -use zenoh_protocol::network::{Declare, DeclareBody, DeclareKeyExpr, Mapping}; use zenoh_protocol::zenoh_new::PushBody; use zenoh_protocol::{ core::{key_expr::keyexpr, ExprId, WireExpr, ZenohId}, + network::{ + declare::{ + ext, queryable::ext::QueryableInfo, subscriber::ext::SubscriberInfo, Declare, + DeclareBody, DeclareKeyExpr, + }, + Mapping, + }, zenoh::{QueryId, RoutingContext}, }; use zenoh_sync::get_mut_unchecked; diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index b8691f0fa0..2138a2b3a4 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -28,16 +28,15 @@ use std::sync::Arc; use std::sync::Mutex; use zenoh_buffers::SplitBuffer; use zenoh_config::ValidatedMap; -use zenoh_protocol::core::{ - key_expr::OwnedKeyExpr, ExprId, KnownEncoding, WireExpr, ZenohId, EMPTY_EXPR_ID, +use zenoh_protocol::{ + core::{key_expr::OwnedKeyExpr, ExprId, KnownEncoding, WireExpr, ZenohId, EMPTY_EXPR_ID}, + network::{ + declare::{queryable::ext::QueryableInfo, subscriber::ext::SubscriberInfo}, + ext, Declare, DeclareBody, DeclareQueryable, DeclareSubscriber, Push, Request, Response, + ResponseFinal, + }, + zenoh_new::{PushBody, RequestBody}, }; -use zenoh_protocol::network::queryable::ext::QueryableInfo; -use zenoh_protocol::network::subscriber::ext::SubscriberInfo; -use zenoh_protocol::network::{ - ext, Declare, DeclareBody, DeclareQueryable, DeclareSubscriber, Push, Request, Response, - ResponseFinal, -}; -use zenoh_protocol::zenoh_new::{PushBody, RequestBody}; use zenoh_result::ZResult; use zenoh_transport::{Primitives, TransportUnicast}; diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 1c8fe571f9..df608af72c 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -52,39 +52,29 @@ use zenoh_buffers::ZBuf; use zenoh_collections::SingleOrVec; use zenoh_config::unwrap_or_default; use zenoh_core::{zconfigurable, zread, Resolve, ResolveClosure, ResolveFuture, SyncResolve}; -use zenoh_protocol::network::common::ext::WireExprType; -use zenoh_protocol::network::declare; -use zenoh_protocol::network::ext; -use zenoh_protocol::network::queryable::ext::QueryableInfo; -use zenoh_protocol::network::request; -use zenoh_protocol::network::request::ext::TargetType; -use zenoh_protocol::network::subscriber::ext::SubscriberInfo; -use zenoh_protocol::network::Declare; -use zenoh_protocol::network::DeclareBody; -use zenoh_protocol::network::DeclareKeyExpr; -use zenoh_protocol::network::DeclareQueryable; -use zenoh_protocol::network::DeclareSubscriber; -use zenoh_protocol::network::Mapping; -use zenoh_protocol::network::Push; -use zenoh_protocol::network::Request; -use zenoh_protocol::network::Response; -use zenoh_protocol::network::ResponseFinal; -use zenoh_protocol::network::UndeclareQueryable; -use zenoh_protocol::network::UndeclareSubscriber; -use zenoh_protocol::zenoh_new; -use zenoh_protocol::zenoh_new::query; -use zenoh_protocol::zenoh_new::query::ext::ConsolidationType; -use zenoh_protocol::zenoh_new::query::ext::QueryBodyType; -use zenoh_protocol::zenoh_new::Pull; -use zenoh_protocol::zenoh_new::PushBody; -use zenoh_protocol::zenoh_new::RequestBody; -use zenoh_protocol::zenoh_new::ResponseBody; use zenoh_protocol::{ core::{ key_expr::{keyexpr, OwnedKeyExpr}, AtomicExprId, CongestionControl, ExprId, WireExpr, ZenohId, EMPTY_EXPR_ID, }, + network::{ + declare::{ + self, common::ext::WireExprType, queryable::ext::QueryableInfo, + subscriber::ext::SubscriberInfo, Declare, DeclareBody, DeclareKeyExpr, + DeclareQueryable, DeclareSubscriber, UndeclareQueryable, UndeclareSubscriber, + }, + ext, + request::{self, ext::TargetType, Request}, + Mapping, Push, Response, ResponseFinal, + }, zenoh::{AtomicQueryId, DataInfo, QueryId, QueryTarget}, + zenoh_new::{ + query::{ + self, + ext::{ConsolidationType, QueryBodyType}, + }, + Pull, PushBody, RequestBody, ResponseBody, + }, }; use zenoh_result::ZResult; use zenoh_util::core::AsyncResolve; @@ -1653,7 +1643,7 @@ impl Session { ext_target: target.into(), ext_budget: None, ext_timeout: Some(timeout), - payload: RequestBody::Query(zenoh_new::Query { + payload: RequestBody::Query(zenoh_protocol::zenoh_new::Query { parameters: selector.parameters().to_string(), ext_sinfo: None, ext_consolidation: consolidation.into(), @@ -2205,7 +2195,7 @@ impl Primitives for Session { trace!("recv ResponseFinal {:?}", msg); let mut state = zwrite!(self.state); match state.queries.get_mut(&msg.rid) { - Some(mut query) => { + Some(query) => { query.nb_final -= 1; if query.nb_final == 0 { let query = state.queries.remove(&msg.rid).unwrap(); diff --git a/zenoh/src/subscriber.rs b/zenoh/src/subscriber.rs index 75068d0261..d510e2c10d 100644 --- a/zenoh/src/subscriber.rs +++ b/zenoh/src/subscriber.rs @@ -23,8 +23,7 @@ use std::future::Ready; use std::ops::{Deref, DerefMut}; use std::sync::Arc; use zenoh_core::{AsyncResolve, Resolvable, Resolve, SyncResolve}; -use zenoh_protocol::network::subscriber::ext::SubscriberInfo; -use zenoh_protocol::network::Mode; +use zenoh_protocol::network::declare::{subscriber::ext::SubscriberInfo, Mode}; /// The subscription mode. pub use zenoh_protocol::zenoh::SubMode; From c7dabae5e3a5aa126749bcc0ea669437fca0400b Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 31 Jul 2023 16:51:49 +0200 Subject: [PATCH 176/203] Fix shared memory clippy --- io/zenoh-transport/src/multicast/manager.rs | 36 ++++++++++++++++--- io/zenoh-transport/src/multicast/mod.rs | 3 +- io/zenoh-transport/src/multicast/rx.rs | 7 +++- io/zenoh-transport/src/multicast/transport.rs | 19 ---------- io/zenoh-transport/src/multicast/tx.rs | 16 ++++++++- .../src/unicast/establishment/ext/shm.rs | 4 +-- io/zenoh-transport/src/unicast/shm.rs | 2 +- 7 files changed, 58 insertions(+), 29 deletions(-) diff --git a/io/zenoh-transport/src/multicast/manager.rs b/io/zenoh-transport/src/multicast/manager.rs index 23be626989..0bfc4a3f07 100644 --- a/io/zenoh-transport/src/multicast/manager.rs +++ b/io/zenoh-transport/src/multicast/manager.rs @@ -11,12 +11,15 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::multicast::transport::TransportMulticastInner; -use crate::multicast::TransportMulticast; +#[cfg(feature = "shared-memory")] +use crate::multicast::shm::SharedMemoryMulticast; +use crate::multicast::{transport::TransportMulticastInner, TransportMulticast}; use crate::TransportManager; use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::time::Duration; +#[cfg(feature = "shared-memory")] +use zenoh_config::SharedMemoryConf; use zenoh_config::{Config, LinkTxConf}; use zenoh_core::zlock; use zenoh_link::*; @@ -32,6 +35,8 @@ pub struct TransportManagerConfigMulticast { pub join_interval: Duration, pub max_sessions: usize, pub is_qos: bool, + #[cfg(feature = "shared-memory")] + pub is_shm: bool, } pub struct TransportManagerBuilderMulticast { @@ -40,6 +45,8 @@ pub struct TransportManagerBuilderMulticast { join_interval: Duration, max_sessions: usize, is_qos: bool, + #[cfg(feature = "shared-memory")] + is_shm: bool, } pub struct TransportManagerStateMulticast { @@ -47,6 +54,9 @@ pub struct TransportManagerStateMulticast { pub(crate) protocols: Arc>>, // Established transports pub(crate) transports: Arc>>>, + // Shared memory + #[cfg(feature = "shared-memory")] + pub(super) shm: Arc, } pub struct TransportManagerParamsMulticast { @@ -80,6 +90,12 @@ impl TransportManagerBuilderMulticast { self } + #[cfg(feature = "shared-memory")] + pub fn shm(mut self, is_shm: bool) -> Self { + self.is_shm = is_shm; + self + } + pub async fn from_config( mut self, config: &Config, @@ -92,9 +108,13 @@ impl TransportManagerBuilderMulticast { config.transport().multicast().join_interval().unwrap(), )); self = self.max_sessions(config.transport().multicast().max_sessions().unwrap()); - // Force QoS deactivation in multicast - // self = self.qos(*config.transport().qos().enabled()); @TODO + // @TODO: Force QoS deactivation in multicast since it is not supported + // self = self.qos(*config.transport().qos().enabled()); self = self.qos(false); + #[cfg(feature = "shared-memory")] + { + self = self.shm(*config.transport().shared_memory().enabled()); + } Ok(self) } @@ -106,11 +126,15 @@ impl TransportManagerBuilderMulticast { join_interval: self.join_interval, max_sessions: self.max_sessions, is_qos: self.is_qos, + #[cfg(feature = "shared-memory")] + is_shm: self.is_shm, }; let state = TransportManagerStateMulticast { protocols: Arc::new(Mutex::new(HashMap::new())), transports: Arc::new(Mutex::new(HashMap::new())), + #[cfg(feature = "shared-memory")] + shm: Arc::new(SharedMemoryMulticast::make()?), }; let params = TransportManagerParamsMulticast { config, state }; @@ -122,6 +146,8 @@ impl TransportManagerBuilderMulticast { impl Default for TransportManagerBuilderMulticast { fn default() -> TransportManagerBuilderMulticast { let link_tx = LinkTxConf::default(); + #[cfg(feature = "shared-memory")] + let shm = SharedMemoryConf::default(); let tmb = TransportManagerBuilderMulticast { lease: Duration::from_millis(*link_tx.lease()), @@ -129,6 +155,8 @@ impl Default for TransportManagerBuilderMulticast { join_interval: Duration::from_millis(0), max_sessions: 0, is_qos: false, + #[cfg(feature = "shared-memory")] + is_shm: *shm.enabled(), }; async_std::task::block_on(tmb.from_config(&Config::default())).unwrap() } diff --git a/io/zenoh-transport/src/multicast/mod.rs b/io/zenoh-transport/src/multicast/mod.rs index 50e5ada09d..3eaa1f7fd2 100644 --- a/io/zenoh-transport/src/multicast/mod.rs +++ b/io/zenoh-transport/src/multicast/mod.rs @@ -10,11 +10,12 @@ // // Contributors: // ZettaScale Zenoh Team, -// pub(crate) mod authenticator; pub(crate) mod establishment; pub(crate) mod link; pub(crate) mod manager; pub(crate) mod rx; +#[cfg(feature = "shared-memory")] +pub(crate) mod shm; pub(crate) mod transport; pub(crate) mod tx; diff --git a/io/zenoh-transport/src/multicast/rx.rs b/io/zenoh-transport/src/multicast/rx.rs index ea861e7f90..4bb219fe2c 100644 --- a/io/zenoh-transport/src/multicast/rx.rs +++ b/io/zenoh-transport/src/multicast/rx.rs @@ -58,7 +58,12 @@ impl TransportMulticastInner { #[cfg(feature = "shared-memory")] { - let _ = crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.shmr)?; + if self._manager.config.multicast.is_shm { + crate::shm::map_zmsg_to_shmbuf( + &mut msg, + &self._manager.state.multicast.shm.reader, + )?; + } } peer.handler.handle_message(msg) diff --git a/io/zenoh-transport/src/multicast/transport.rs b/io/zenoh-transport/src/multicast/transport.rs index ccc82cd5ff..4eac92b3c0 100644 --- a/io/zenoh-transport/src/multicast/transport.rs +++ b/io/zenoh-transport/src/multicast/transport.rs @@ -33,7 +33,6 @@ use zenoh_protocol::core::Resolution; use zenoh_protocol::transport::TransportSn; use zenoh_protocol::{ core::{ConduitSnList, Priority, WhatAmI, ZenohId}, - network::NetworkMessage, transport::{close, Join}, }; use zenoh_result::{bail, ZResult}; @@ -241,24 +240,6 @@ impl TransportMulticastInner { todo!(); } - /*************************************/ - /* SCHEDULE AND SEND TX */ - /*************************************/ - /// Schedule a Zenoh message on the transmission queue - #[allow(unused_mut)] // Required with "shared-memory" feature - pub(crate) fn schedule(&self, mut msg: NetworkMessage) { - // Multicast transports do not support SHM for the time being - #[cfg(feature = "shared-memory")] - { - let res = crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.shmr); - if let Err(e) = res { - log::trace!("Failed SHM conversion: {}", e); - return; - } - } - self.schedule_first_fit(msg); - } - /*************************************/ /* LINK */ /*************************************/ diff --git a/io/zenoh-transport/src/multicast/tx.rs b/io/zenoh-transport/src/multicast/tx.rs index 11e1570f8e..2d08eb36ec 100644 --- a/io/zenoh-transport/src/multicast/tx.rs +++ b/io/zenoh-transport/src/multicast/tx.rs @@ -49,9 +49,23 @@ impl TransportMulticastInner { false } + #[allow(unused_mut)] // When feature "shared-memory" is not enabled #[allow(clippy::let_and_return)] // When feature "stats" is not enabled #[inline(always)] - pub(super) fn schedule_first_fit(&self, msg: NetworkMessage) -> bool { + pub(super) fn schedule(&self, mut msg: NetworkMessage) -> bool { + #[cfg(feature = "shared-memory")] + { + let res = if self._manager.config.multicast.is_shm { + crate::shm::map_zmsg_to_shminfo(&mut msg) + } else { + crate::shm::map_zmsg_to_shmbuf(&mut msg, &self._manager.state.multicast.shm.reader) + }; + if let Err(e) = res { + log::trace!("Failed SHM conversion: {}", e); + return false; + } + } + #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; #[cfg(feature = "stats")] diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index d664067457..ade6ee8fd8 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -11,9 +11,9 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{ +use crate::unicast::{ establishment::{AcceptFsm, OpenFsm}, - unicast::{shm::Challenge, shm::SharedMemoryUnicast}, + shm::{Challenge, SharedMemoryUnicast}, }; use async_trait::async_trait; use std::convert::TryInto; diff --git a/io/zenoh-transport/src/unicast/shm.rs b/io/zenoh-transport/src/unicast/shm.rs index b019f75fa2..ce940444af 100644 --- a/io/zenoh-transport/src/unicast/shm.rs +++ b/io/zenoh-transport/src/unicast/shm.rs @@ -38,7 +38,7 @@ impl SharedMemoryUnicast { pub fn make() -> ZResult { // Create a challenge for session establishment let mut prng = PseudoRng::from_entropy(); - let nonce = prng.gen::(); + let nonce = prng.gen::(); let size = std::mem::size_of::(); let mut _manager = SharedMemoryManager::make(format!("{NAME}.{nonce}"), size)?; From a43a37691b216f5a6361579e80271db1ad477609 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 31 Jul 2023 16:51:49 +0200 Subject: [PATCH 177/203] Fix shared memory clippy --- io/zenoh-transport/src/multicast/manager.rs | 36 +++++++++++++-- io/zenoh-transport/src/multicast/mod.rs | 3 +- io/zenoh-transport/src/multicast/rx.rs | 7 ++- io/zenoh-transport/src/multicast/shm.rs | 44 +++++++++++++++++++ io/zenoh-transport/src/multicast/transport.rs | 19 -------- io/zenoh-transport/src/multicast/tx.rs | 16 ++++++- .../src/unicast/establishment/ext/shm.rs | 4 +- io/zenoh-transport/src/unicast/shm.rs | 2 +- 8 files changed, 102 insertions(+), 29 deletions(-) create mode 100644 io/zenoh-transport/src/multicast/shm.rs diff --git a/io/zenoh-transport/src/multicast/manager.rs b/io/zenoh-transport/src/multicast/manager.rs index 23be626989..0bfc4a3f07 100644 --- a/io/zenoh-transport/src/multicast/manager.rs +++ b/io/zenoh-transport/src/multicast/manager.rs @@ -11,12 +11,15 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::multicast::transport::TransportMulticastInner; -use crate::multicast::TransportMulticast; +#[cfg(feature = "shared-memory")] +use crate::multicast::shm::SharedMemoryMulticast; +use crate::multicast::{transport::TransportMulticastInner, TransportMulticast}; use crate::TransportManager; use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::time::Duration; +#[cfg(feature = "shared-memory")] +use zenoh_config::SharedMemoryConf; use zenoh_config::{Config, LinkTxConf}; use zenoh_core::zlock; use zenoh_link::*; @@ -32,6 +35,8 @@ pub struct TransportManagerConfigMulticast { pub join_interval: Duration, pub max_sessions: usize, pub is_qos: bool, + #[cfg(feature = "shared-memory")] + pub is_shm: bool, } pub struct TransportManagerBuilderMulticast { @@ -40,6 +45,8 @@ pub struct TransportManagerBuilderMulticast { join_interval: Duration, max_sessions: usize, is_qos: bool, + #[cfg(feature = "shared-memory")] + is_shm: bool, } pub struct TransportManagerStateMulticast { @@ -47,6 +54,9 @@ pub struct TransportManagerStateMulticast { pub(crate) protocols: Arc>>, // Established transports pub(crate) transports: Arc>>>, + // Shared memory + #[cfg(feature = "shared-memory")] + pub(super) shm: Arc, } pub struct TransportManagerParamsMulticast { @@ -80,6 +90,12 @@ impl TransportManagerBuilderMulticast { self } + #[cfg(feature = "shared-memory")] + pub fn shm(mut self, is_shm: bool) -> Self { + self.is_shm = is_shm; + self + } + pub async fn from_config( mut self, config: &Config, @@ -92,9 +108,13 @@ impl TransportManagerBuilderMulticast { config.transport().multicast().join_interval().unwrap(), )); self = self.max_sessions(config.transport().multicast().max_sessions().unwrap()); - // Force QoS deactivation in multicast - // self = self.qos(*config.transport().qos().enabled()); @TODO + // @TODO: Force QoS deactivation in multicast since it is not supported + // self = self.qos(*config.transport().qos().enabled()); self = self.qos(false); + #[cfg(feature = "shared-memory")] + { + self = self.shm(*config.transport().shared_memory().enabled()); + } Ok(self) } @@ -106,11 +126,15 @@ impl TransportManagerBuilderMulticast { join_interval: self.join_interval, max_sessions: self.max_sessions, is_qos: self.is_qos, + #[cfg(feature = "shared-memory")] + is_shm: self.is_shm, }; let state = TransportManagerStateMulticast { protocols: Arc::new(Mutex::new(HashMap::new())), transports: Arc::new(Mutex::new(HashMap::new())), + #[cfg(feature = "shared-memory")] + shm: Arc::new(SharedMemoryMulticast::make()?), }; let params = TransportManagerParamsMulticast { config, state }; @@ -122,6 +146,8 @@ impl TransportManagerBuilderMulticast { impl Default for TransportManagerBuilderMulticast { fn default() -> TransportManagerBuilderMulticast { let link_tx = LinkTxConf::default(); + #[cfg(feature = "shared-memory")] + let shm = SharedMemoryConf::default(); let tmb = TransportManagerBuilderMulticast { lease: Duration::from_millis(*link_tx.lease()), @@ -129,6 +155,8 @@ impl Default for TransportManagerBuilderMulticast { join_interval: Duration::from_millis(0), max_sessions: 0, is_qos: false, + #[cfg(feature = "shared-memory")] + is_shm: *shm.enabled(), }; async_std::task::block_on(tmb.from_config(&Config::default())).unwrap() } diff --git a/io/zenoh-transport/src/multicast/mod.rs b/io/zenoh-transport/src/multicast/mod.rs index 50e5ada09d..3eaa1f7fd2 100644 --- a/io/zenoh-transport/src/multicast/mod.rs +++ b/io/zenoh-transport/src/multicast/mod.rs @@ -10,11 +10,12 @@ // // Contributors: // ZettaScale Zenoh Team, -// pub(crate) mod authenticator; pub(crate) mod establishment; pub(crate) mod link; pub(crate) mod manager; pub(crate) mod rx; +#[cfg(feature = "shared-memory")] +pub(crate) mod shm; pub(crate) mod transport; pub(crate) mod tx; diff --git a/io/zenoh-transport/src/multicast/rx.rs b/io/zenoh-transport/src/multicast/rx.rs index ea861e7f90..4bb219fe2c 100644 --- a/io/zenoh-transport/src/multicast/rx.rs +++ b/io/zenoh-transport/src/multicast/rx.rs @@ -58,7 +58,12 @@ impl TransportMulticastInner { #[cfg(feature = "shared-memory")] { - let _ = crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.shmr)?; + if self._manager.config.multicast.is_shm { + crate::shm::map_zmsg_to_shmbuf( + &mut msg, + &self._manager.state.multicast.shm.reader, + )?; + } } peer.handler.handle_message(msg) diff --git a/io/zenoh-transport/src/multicast/shm.rs b/io/zenoh-transport/src/multicast/shm.rs new file mode 100644 index 0000000000..4e4c84d2a7 --- /dev/null +++ b/io/zenoh-transport/src/multicast/shm.rs @@ -0,0 +1,44 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use async_std::sync::RwLock; +use rand::{Rng, SeedableRng}; +use zenoh_crypto::PseudoRng; +use zenoh_result::ZResult; +use zenoh_shm::{SharedMemoryManager, SharedMemoryReader}; + +pub(crate) type Challenge = u64; +const NAME: &str = "zshm_mcast"; + +pub(crate) struct SharedMemoryMulticast { + pub(crate) _manager: SharedMemoryManager, + pub(crate) reader: RwLock, +} + +unsafe impl Sync for SharedMemoryMulticast {} + +impl SharedMemoryMulticast { + pub fn make() -> ZResult { + let mut prng = PseudoRng::from_entropy(); + let nonce = prng.gen::(); + let size = std::mem::size_of::(); + + let mut _manager = SharedMemoryManager::make(format!("{NAME}.{nonce}"), size)?; + + let shmauth = SharedMemoryMulticast { + _manager, + reader: RwLock::new(SharedMemoryReader::new()), + }; + Ok(shmauth) + } +} diff --git a/io/zenoh-transport/src/multicast/transport.rs b/io/zenoh-transport/src/multicast/transport.rs index ccc82cd5ff..4eac92b3c0 100644 --- a/io/zenoh-transport/src/multicast/transport.rs +++ b/io/zenoh-transport/src/multicast/transport.rs @@ -33,7 +33,6 @@ use zenoh_protocol::core::Resolution; use zenoh_protocol::transport::TransportSn; use zenoh_protocol::{ core::{ConduitSnList, Priority, WhatAmI, ZenohId}, - network::NetworkMessage, transport::{close, Join}, }; use zenoh_result::{bail, ZResult}; @@ -241,24 +240,6 @@ impl TransportMulticastInner { todo!(); } - /*************************************/ - /* SCHEDULE AND SEND TX */ - /*************************************/ - /// Schedule a Zenoh message on the transmission queue - #[allow(unused_mut)] // Required with "shared-memory" feature - pub(crate) fn schedule(&self, mut msg: NetworkMessage) { - // Multicast transports do not support SHM for the time being - #[cfg(feature = "shared-memory")] - { - let res = crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.shmr); - if let Err(e) = res { - log::trace!("Failed SHM conversion: {}", e); - return; - } - } - self.schedule_first_fit(msg); - } - /*************************************/ /* LINK */ /*************************************/ diff --git a/io/zenoh-transport/src/multicast/tx.rs b/io/zenoh-transport/src/multicast/tx.rs index 11e1570f8e..2d08eb36ec 100644 --- a/io/zenoh-transport/src/multicast/tx.rs +++ b/io/zenoh-transport/src/multicast/tx.rs @@ -49,9 +49,23 @@ impl TransportMulticastInner { false } + #[allow(unused_mut)] // When feature "shared-memory" is not enabled #[allow(clippy::let_and_return)] // When feature "stats" is not enabled #[inline(always)] - pub(super) fn schedule_first_fit(&self, msg: NetworkMessage) -> bool { + pub(super) fn schedule(&self, mut msg: NetworkMessage) -> bool { + #[cfg(feature = "shared-memory")] + { + let res = if self._manager.config.multicast.is_shm { + crate::shm::map_zmsg_to_shminfo(&mut msg) + } else { + crate::shm::map_zmsg_to_shmbuf(&mut msg, &self._manager.state.multicast.shm.reader) + }; + if let Err(e) = res { + log::trace!("Failed SHM conversion: {}", e); + return false; + } + } + #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; #[cfg(feature = "stats")] diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index d664067457..ade6ee8fd8 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -11,9 +11,9 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{ +use crate::unicast::{ establishment::{AcceptFsm, OpenFsm}, - unicast::{shm::Challenge, shm::SharedMemoryUnicast}, + shm::{Challenge, SharedMemoryUnicast}, }; use async_trait::async_trait; use std::convert::TryInto; diff --git a/io/zenoh-transport/src/unicast/shm.rs b/io/zenoh-transport/src/unicast/shm.rs index b019f75fa2..ce940444af 100644 --- a/io/zenoh-transport/src/unicast/shm.rs +++ b/io/zenoh-transport/src/unicast/shm.rs @@ -38,7 +38,7 @@ impl SharedMemoryUnicast { pub fn make() -> ZResult { // Create a challenge for session establishment let mut prng = PseudoRng::from_entropy(); - let nonce = prng.gen::(); + let nonce = prng.gen::(); let size = std::mem::size_of::(); let mut _manager = SharedMemoryManager::make(format!("{NAME}.{nonce}"), size)?; From 05c690779158676b8f62b3672032c6032c336488 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 31 Jul 2023 17:11:18 +0200 Subject: [PATCH 178/203] Fix SHM test --- io/zenoh-transport/tests/unicast_shm.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index abb4520bd6..d8ef239a86 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -37,8 +37,8 @@ mod tests { use zenoh_result::ZResult; use zenoh_shm::{SharedMemoryBuf, SharedMemoryManager}; use zenoh_transport::{ - TransportEventHandler, TransportManager, TransportPeer, TransportPeerEventHandler, - TransportUnicast, + TransportEventHandler, TransportManager, TransportMulticast, + TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, }; const TIMEOUT: Duration = Duration::from_secs(60); @@ -82,6 +82,13 @@ mod tests { let arc = Arc::new(SCPeer::new(self.count.clone(), self.is_shm)); Ok(arc) } + + fn new_multicast( + &self, + _transport: TransportMulticast, + ) -> ZResult> { + panic!(); + } } // Transport Callback for the peer From d07437adfed896e97bf82395141d9817decd2f92 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 31 Jul 2023 18:21:32 +0200 Subject: [PATCH 179/203] Fix doc test --- io/zenoh-transport/src/manager.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index 19e22ee4c0..f49ac4e9b7 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -56,6 +56,13 @@ use zenoh_result::{bail, ZResult}; /// ) -> ZResult> { /// Ok(Arc::new(DummyTransportPeerEventHandler)) /// } +/// +/// fn new_multicast( +/// &self, +/// _transport: TransportMulticast, +/// ) -> ZResult> { +/// Ok(Arc::new(DummyTransportMulticastEventHandler)) +/// } /// } /// /// // Create the default TransportManager @@ -70,7 +77,6 @@ use zenoh_result::{bail, ZResult}; /// .keep_alive(4) // Send a KeepAlive every 250 ms /// .accept_timeout(Duration::from_secs(1)) /// .accept_pending(10) // Set to 10 the number of simultanous pending incoming transports -/// .max_links(1) // Allow max 1 inbound link per transport /// .max_sessions(5); // Allow max 5 transports open /// let mut resolution = Resolution::default(); /// resolution.set(Field::FrameSN, Bits::U8); From 1d9c1e4a86a0b45fbf4bfbe0dd4886804ec0006a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Mon, 7 Aug 2023 10:45:28 +0200 Subject: [PATCH 180/203] Multicast support (#526) --- commons/zenoh-codec/src/transport/join.rs | 109 +++- commons/zenoh-protocol/src/core/mod.rs | 50 +- commons/zenoh-protocol/src/core/resolution.rs | 2 +- commons/zenoh-protocol/src/transport/join.rs | 58 +-- commons/zenoh-protocol/src/transport/mod.rs | 16 +- commons/zenoh-protocol/src/zenoh/mod.rs | 2 +- io/zenoh-link-commons/src/lib.rs | 138 +----- io/zenoh-link-commons/src/multicast.rs | 7 + io/zenoh-transport/src/common/mod.rs | 2 +- io/zenoh-transport/src/common/pipeline.rs | 39 +- .../src/common/{conduit.rs => priority.rs} | 22 +- io/zenoh-transport/src/common/seq_num.rs | 2 +- io/zenoh-transport/src/lib.rs | 2 +- io/zenoh-transport/src/manager.rs | 71 +-- .../src/multicast/establishment.rs | 138 +++--- io/zenoh-transport/src/multicast/link.rs | 157 +++--- io/zenoh-transport/src/multicast/manager.rs | 91 ++-- io/zenoh-transport/src/multicast/mod.rs | 22 +- io/zenoh-transport/src/multicast/rx.rs | 438 ++++++++++------- io/zenoh-transport/src/multicast/transport.rs | 465 +++++++++--------- io/zenoh-transport/src/multicast/tx.rs | 4 +- io/zenoh-transport/src/unicast/link.rs | 12 +- io/zenoh-transport/src/unicast/manager.rs | 35 +- io/zenoh-transport/src/unicast/mod.rs | 6 +- io/zenoh-transport/src/unicast/rx.rs | 14 +- io/zenoh-transport/src/unicast/transport.rs | 36 +- .../tests/multicast_transport.rs | 359 ++++++++++++++ .../tests/transport_whitelist.rs | 8 +- .../tests/unicast_authenticator.rs | 26 +- .../tests/unicast_concurrent.rs | 20 +- .../tests/unicast_defragmentation.rs | 9 +- .../tests/unicast_intermittent.rs | 31 +- io/zenoh-transport/tests/unicast_multilink.rs | 56 +-- io/zenoh-transport/tests/unicast_openclose.rs | 48 +- ...cast_conduits.rs => unicast_priorities.rs} | 17 +- io/zenoh-transport/tests/unicast_shm.rs | 16 +- .../tests/unicast_simultaneous.rs | 16 +- io/zenoh-transport/tests/unicast_transport.rs | 13 +- zenoh/src/admin.rs | 16 +- zenoh/src/info.rs | 11 +- zenoh/src/net/routing/network.rs | 7 +- zenoh/src/net/runtime/adminspace.rs | 5 +- zenoh/src/net/runtime/orchestrator.rs | 11 +- zenoh/tests/session.rs | 82 ++- 44 files changed, 1528 insertions(+), 1161 deletions(-) rename io/zenoh-transport/src/common/{conduit.rs => priority.rs} (86%) create mode 100644 io/zenoh-transport/tests/multicast_transport.rs rename io/zenoh-transport/tests/{unicast_conduits.rs => unicast_priorities.rs} (95%) diff --git a/commons/zenoh-codec/src/transport/join.rs b/commons/zenoh-codec/src/transport/join.rs index 9054395ad4..ac7d8efbd8 100644 --- a/commons/zenoh-codec/src/transport/join.rs +++ b/commons/zenoh-codec/src/transport/join.rs @@ -11,22 +11,117 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; +use crate::{common::extension, LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length}; +use alloc::boxed::Box; use core::time::Duration; use zenoh_buffers::{ reader::{DidntRead, Reader}, writer::{DidntWrite, Writer}, }; use zenoh_protocol::{ - common::{iext, imsg}, - core::{Resolution, WhatAmI, ZenohId}, + common::{iext, imsg, ZExtZBufHeader}, + core::{Priority, Resolution, WhatAmI, ZenohId}, transport::{ id, join::{ext, flag, Join}, - BatchSize, TransportSn, + BatchSize, PrioritySn, TransportSn, }, }; +impl LCodec<&PrioritySn> for Zenoh080 { + fn w_len(self, p: &PrioritySn) -> usize { + self.w_len(p.best_effort) + self.w_len(p.reliable) + } +} + +impl WCodec<&PrioritySn, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &PrioritySn) -> Self::Output { + self.write(&mut *writer, x.best_effort)?; + self.write(&mut *writer, x.reliable)?; + Ok(()) + } +} + +impl RCodec for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let best_effort: TransportSn = self.read(&mut *reader)?; + let reliable: TransportSn = self.read(&mut *reader)?; + + Ok(PrioritySn { + best_effort, + reliable, + }) + } +} + +// Extension +impl WCodec<(&ext::QoSType, bool), &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: (&ext::QoSType, bool)) -> Self::Output { + let (x, more) = x; + + // Header + let len = x.iter().fold(0, |acc, p| acc + self.w_len(p)); + let header = ZExtZBufHeader::<{ ext::QoS::ID }>::new(len); + self.write(&mut *writer, (&header, more))?; + + // Body + for p in x.iter() { + self.write(&mut *writer, p)?; + } + + Ok(()) + } +} + +impl RCodec<(ext::QoSType, bool), &mut R> for Zenoh080 +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoSType, bool), Self::Error> { + let header: u8 = self.read(&mut *reader)?; + let codec = Zenoh080Header::new(header); + codec.read(reader) + } +} + +impl RCodec<(ext::QoSType, bool), &mut R> for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result<(ext::QoSType, bool), Self::Error> { + // Header + let (_, more): (ZExtZBufHeader<{ ext::QoS::ID }>, bool) = self.read(&mut *reader)?; + + // Body + let mut ext_qos = Box::new([PrioritySn::default(); Priority::NUM]); + for p in ext_qos.iter_mut() { + *p = self.codec.read(&mut *reader)?; + } + + Ok((ext_qos, more)) + } +} + +// Join impl WCodec<&Join, &mut W> for Zenoh080 where W: Writer, @@ -72,7 +167,7 @@ where } else { self.write(&mut *writer, x.lease.as_millis() as u64)?; } - self.write(&mut *writer, x.next_sn)?; + self.write(&mut *writer, &x.next_sn)?; // Extensions if let Some(qos) = x.ext_qos.as_ref() { @@ -141,7 +236,7 @@ where } else { Duration::from_millis(lease) }; - let next_sn: TransportSn = self.codec.read(&mut *reader)?; + let next_sn: PrioritySn = self.codec.read(&mut *reader)?; // Extensions let mut ext_qos = None; @@ -153,7 +248,7 @@ where let eodec = Zenoh080Header::new(ext); match iext::eid(ext) { ext::QoS::ID => { - let (q, ext): (ext::QoS, bool) = eodec.read(&mut *reader)?; + let (q, ext): (ext::QoSType, bool) = eodec.read(&mut *reader)?; ext_qos = Some(q); has_ext = ext; } diff --git a/commons/zenoh-protocol/src/core/mod.rs b/commons/zenoh-protocol/src/core/mod.rs index fedd9d6a45..2547034c44 100644 --- a/commons/zenoh-protocol/src/core/mod.rs +++ b/commons/zenoh-protocol/src/core/mod.rs @@ -54,8 +54,6 @@ pub use endpoint::*; pub mod resolution; pub use resolution::*; -use crate::transport::TransportSn; - #[derive(Debug, Clone, PartialEq, Eq)] pub struct Property { pub key: u64, @@ -327,8 +325,8 @@ impl Priority { impl TryFrom for Priority { type Error = zenoh_result::Error; - fn try_from(conduit: u8) -> Result { - match conduit { + fn try_from(v: u8) -> Result { + match v { 0 => Ok(Priority::Control), 1 => Ok(Priority::RealTime), 2 => Ok(Priority::InteractiveHigh), @@ -376,50 +374,6 @@ pub struct Channel { pub reliability: Reliability, } -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ConduitSnList { - Plain(ConduitSn), - QoS(Box<[ConduitSn; Priority::NUM]>), -} - -impl fmt::Display for ConduitSnList { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "[ ")?; - match self { - ConduitSnList::Plain(sn) => { - write!( - f, - "{:?} {{ reliable: {}, best effort: {} }}", - Priority::default(), - sn.reliable, - sn.best_effort - )?; - } - ConduitSnList::QoS(ref sns) => { - for (prio, sn) in sns.iter().enumerate() { - let p: Priority = (prio as u8).try_into().unwrap(); - write!( - f, - "{:?} {{ reliable: {}, best effort: {} }}", - p, sn.reliable, sn.best_effort - )?; - if p != Priority::Background { - write!(f, ", ")?; - } - } - } - } - write!(f, " ]") - } -} - -/// The kind of reliability. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] -pub struct ConduitSn { - pub reliable: TransportSn, - pub best_effort: TransportSn, -} - /// The kind of congestion control. #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] #[repr(u8)] diff --git a/commons/zenoh-protocol/src/core/resolution.rs b/commons/zenoh-protocol/src/core/resolution.rs index 6bb8f7c006..ebd65a5824 100644 --- a/commons/zenoh-protocol/src/core/resolution.rs +++ b/commons/zenoh-protocol/src/core/resolution.rs @@ -119,7 +119,7 @@ pub enum Field { } #[repr(transparent)] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Resolution(u8); impl Resolution { diff --git a/commons/zenoh-protocol/src/transport/join.rs b/commons/zenoh-protocol/src/transport/join.rs index 84222dc19c..ea06d3ba4a 100644 --- a/commons/zenoh-protocol/src/transport/join.rs +++ b/commons/zenoh-protocol/src/transport/join.rs @@ -12,49 +12,11 @@ // ZettaScale Zenoh Team, // use crate::{ - core::{Resolution, WhatAmI, ZenohId}, - transport::{BatchSize, TransportSn}, + core::{Priority, Resolution, WhatAmI, ZenohId}, + transport::{BatchSize, PrioritySn}, }; use core::time::Duration; -/// # Join message -/// -/// ```text -/// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length -/// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. -/// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve -/// the boundary of the serialized messages. The length is encoded as little-endian. -/// In any case, the length of a message must not exceed 65_535 bytes. -/// -/// The JOIN message is sent on a multicast Locator to advertise the transport parameters. -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |O|S|T| JOIN | -/// +-+-+-+-+-------+ -/// ~ |Q~ if O==1 -/// +---------------+ -/// | v_maj | v_min | -- Protocol Version VMaj.VMin -/// +-------+-------+ -/// ~ whatami ~ -- Router, Peer or a combination of them -/// +---------------+ -/// ~ node_id ~ -- PID of the sender of the JOIN message -/// +---------------+ -/// ~ lease ~ -- Lease period of the sender of the JOIN message(*) -/// +---------------+ -/// ~ sn_resolution ~ if S==1(*) -- Otherwise 2^28 is assumed(**) -/// +---------------+ -/// ~ [next_sn] ~ (***) -/// +---------------+ -/// -/// - if Q==1 then the sender supports QoS. -/// -/// (*) if T==1 then the lease period is expressed in seconds, otherwise in milliseconds -/// (**) if S==0 then 2^28 is assumed. -/// (***) if Q==1 then 8 sequence numbers are present: one for each priority. -/// if Q==0 then only one sequence number is present. -/// -/// ``` /// # Join message /// /// The JOIN message is sent on a multicast Locator to advertise the transport parameters. @@ -146,19 +108,21 @@ pub struct Join { pub resolution: Resolution, pub batch_size: BatchSize, pub lease: Duration, - pub next_sn: TransportSn, - pub ext_qos: Option, + pub next_sn: PrioritySn, + pub ext_qos: Option, pub ext_shm: Option, } // Extensions pub mod ext { - use crate::{common::ZExtZBuf, core::Priority, transport::TransportSn, zextzbuf}; + use super::{Priority, PrioritySn}; + use crate::{common::ZExtZBuf, zextzbuf}; + use alloc::boxed::Box; /// # QoS extension /// Used to announce next sn when QoS is enabled pub type QoS = zextzbuf!(0x1, true); - pub type QoSType = [TransportSn; Priority::NUM]; + pub type QoSType = Box<[PrioritySn; Priority::NUM]>; /// # Shm extension /// Used to advertise shared memory capabilities @@ -183,8 +147,10 @@ impl Join { } else { Duration::from_millis(rng.gen()) }; - let next_sn: TransportSn = rng.gen(); - let ext_qos = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); + let next_sn = PrioritySn::rand(); + let ext_qos = rng + .gen_bool(0.5) + .then_some(Box::new([PrioritySn::rand(); Priority::NUM])); let ext_shm = rng.gen_bool(0.5).then_some(ZExtZBuf::rand()); Self { diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 92933a691d..a02b1a7a83 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -51,13 +51,25 @@ pub mod id { pub type TransportSn = u32; -/// The kind of reliability. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] -pub struct ConduitSn { +pub struct PrioritySn { pub reliable: TransportSn, pub best_effort: TransportSn, } +impl PrioritySn { + #[cfg(feature = "test")] + pub fn rand() -> Self { + use rand::Rng; + let mut rng = rand::thread_rng(); + + Self { + reliable: rng.gen(), + best_effort: rng.gen(), + } + } +} + // Zenoh messages at zenoh-transport level #[derive(Debug, Clone, PartialEq, Eq)] pub enum TransportBody { diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index 2084f7f6fb..49674380c6 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -115,7 +115,7 @@ pub mod zmsg { pub const LOC: u64 = 1 << 2; // 0x04 } - pub mod conduit { + pub mod priority { use super::{imsg, Priority}; pub const CONTROL: u8 = (Priority::Control as u8) << imsg::HEADER_BITS; diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index 92ffb785e4..114990726a 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -20,35 +20,17 @@ #![no_std] extern crate alloc; -// mod multicast; +mod multicast; mod unicast; -use alloc::{ - borrow::{Cow, ToOwned}, - boxed::Box, - string::String, - sync::Arc, - vec::Vec, -}; +use alloc::{borrow::ToOwned, boxed::Box, string::String}; use async_trait::async_trait; -use core::{ - cmp::PartialEq, - fmt, - hash::{Hash, Hasher}, - ops::Deref, -}; +use core::{cmp::PartialEq, fmt, hash::Hash}; +pub use multicast::*; use serde::Serialize; pub use unicast::*; -use zenoh_buffers::{ - reader::{HasReader, Reader}, - writer::HasWriter, -}; -use zenoh_codec::{RCodec, WCodec, Zenoh080}; -use zenoh_protocol::{ - core::{EndPoint, Locator}, - transport::TransportMessage, -}; -use zenoh_result::{zerror, ZResult}; +use zenoh_protocol::core::Locator; +use zenoh_result::ZResult; /*************************************/ /* GENERAL */ @@ -117,111 +99,3 @@ impl From for Link { Link::from(&link) } } - -/*************************************/ -/* MULTICAST */ -/*************************************/ -#[async_trait] -pub trait LinkManagerMulticastTrait: Send + Sync { - async fn new_link(&self, endpoint: &EndPoint) -> ZResult; -} - -pub type LinkManagerMulticast = Arc; - -#[derive(Clone)] -pub struct LinkMulticast(pub Arc); - -#[async_trait] -pub trait LinkMulticastTrait: Send + Sync { - fn get_mtu(&self) -> u16; - fn get_src(&self) -> &Locator; - fn get_dst(&self) -> &Locator; - fn is_reliable(&self) -> bool; - async fn write(&self, buffer: &[u8]) -> ZResult; - async fn write_all(&self, buffer: &[u8]) -> ZResult<()>; - async fn read<'a>(&'a self, buffer: &mut [u8]) -> ZResult<(usize, Cow<'a, Locator>)>; - async fn close(&self) -> ZResult<()>; -} - -impl LinkMulticast { - pub async fn write_transport_message(&self, msg: &TransportMessage) -> ZResult { - // Create the buffer for serializing the message - let mut buff = Vec::new(); - let mut writer = buff.writer(); - let codec = Zenoh080::new(); - codec - .write(&mut writer, msg) - .map_err(|_| zerror!("Encoding error on link: {}", self))?; - - // Send the message on the link - self.0.write_all(buff.as_slice()).await?; - - Ok(buff.len()) - } - - pub async fn read_transport_message(&self) -> ZResult<(Vec, Locator)> { - // Read the message - let mut buffer = zenoh_buffers::vec::uninit(self.get_mtu() as usize); - let (n, locator) = self.read(&mut buffer).await?; - buffer.truncate(n); - - let mut reader = buffer.reader(); - let codec = Zenoh080::new(); - - let mut messages: Vec = Vec::with_capacity(1); - while reader.can_read() { - let msg: TransportMessage = codec - .read(&mut reader) - .map_err(|_| zerror!("Invalid Message: Decoding error on link: {}", self))?; - messages.push(msg); - } - - Ok((messages, locator.into_owned())) - } -} - -impl Deref for LinkMulticast { - type Target = Arc; - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl Eq for LinkMulticast {} - -impl PartialEq for LinkMulticast { - fn eq(&self, other: &Self) -> bool { - self.get_src() == other.get_src() && self.get_dst() == other.get_dst() - } -} - -impl Hash for LinkMulticast { - fn hash(&self, state: &mut H) { - self.get_src().hash(state); - self.get_dst().hash(state); - } -} - -impl fmt::Display for LinkMulticast { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{} => {}", self.get_src(), self.get_dst()) - } -} - -impl fmt::Debug for LinkMulticast { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Link") - .field("src", &self.get_src()) - .field("dst", &self.get_dst()) - .field("mtu", &self.get_mtu()) - .field("is_reliable", &self.is_reliable()) - .finish() - } -} - -impl From> for LinkMulticast { - fn from(link: Arc) -> LinkMulticast { - LinkMulticast(link) - } -} diff --git a/io/zenoh-link-commons/src/multicast.rs b/io/zenoh-link-commons/src/multicast.rs index 824bb0e800..65bc7195b6 100644 --- a/io/zenoh-link-commons/src/multicast.rs +++ b/io/zenoh-link-commons/src/multicast.rs @@ -25,6 +25,10 @@ use zenoh_protocol::{ transport::TransportMessage, }; use zenoh_result::{zerror, ZResult}; + +/*************************************/ +/* MANAGER */ +/*************************************/ #[async_trait] pub trait LinkManagerMulticastTrait: Send + Sync { async fn new_link(&self, endpoint: &EndPoint) -> ZResult; @@ -32,6 +36,9 @@ pub trait LinkManagerMulticastTrait: Send + Sync { pub type LinkManagerMulticast = Arc; +/*************************************/ +/* LINK */ +/*************************************/ #[derive(Clone)] pub struct LinkMulticast(pub Arc); diff --git a/io/zenoh-transport/src/common/mod.rs b/io/zenoh-transport/src/common/mod.rs index f13936f0e6..276fe0240c 100644 --- a/io/zenoh-transport/src/common/mod.rs +++ b/io/zenoh-transport/src/common/mod.rs @@ -12,9 +12,9 @@ // ZettaScale Zenoh Team, // pub(crate) mod batch; -pub(crate) mod conduit; pub(crate) mod defragmentation; pub(crate) mod pipeline; +pub(crate) mod priority; pub(crate) mod seq_num; #[cfg(feature = "stats")] pub(crate) mod stats; diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index f7a1585d14..d457e31dcf 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -1,5 +1,3 @@ -use crate::common::batch::WError; - // // Copyright (c) 2023 ZettaScale Technology // @@ -13,9 +11,8 @@ use crate::common::batch::WError; // Contributors: // ZettaScale Zenoh Team, // -// use super::batch::SerializationBatch; -use super::batch::{Encode, WBatch}; -use super::conduit::{TransportChannelTx, TransportConduitTx}; +use super::batch::{Encode, WBatch, WError}; +use super::priority::{TransportChannelTx, TransportPriorityTx}; use async_std::prelude::FutureExt; use flume::{bounded, Receiver, Sender}; use ringbuffer_spsc::{RingBuffer, RingBufferReader, RingBufferWriter}; @@ -93,7 +90,7 @@ impl StageInOut { // Inner structure containing mutexes for current serialization batch and SNs struct StageInMutex { current: Arc>>, - conduit: TransportConduitTx, + priority: TransportPriorityTx, } impl StageInMutex { @@ -105,9 +102,9 @@ impl StageInMutex { #[inline] fn channel(&self, is_reliable: bool) -> MutexGuard<'_, TransportChannelTx> { if is_reliable { - zlock!(self.conduit.reliable) + zlock!(self.priority.reliable) } else { - zlock!(self.conduit.best_effort) + zlock!(self.priority.best_effort) } } } @@ -498,13 +495,13 @@ impl TransmissionPipeline { // A MPSC pipeline pub(crate) fn make( config: TransmissionPipelineConf, - conduit: &[TransportConduitTx], + priority: &[TransportPriorityTx], ) -> (TransmissionPipelineProducer, TransmissionPipelineConsumer) { let mut stage_in = vec![]; let mut stage_out = vec![]; let default_queue_size = [config.queue_size[Priority::default() as usize]]; - let size_iter = if conduit.len() == 1 { + let size_iter = if priority.len() == 1 { default_queue_size.iter() } else { config.queue_size.iter() @@ -547,7 +544,7 @@ impl TransmissionPipeline { }, mutex: StageInMutex { current: current.clone(), - conduit: conduit[prio].clone(), + priority: priority[prio].clone(), }, fragbuf: ZBuf::empty(), })); @@ -812,9 +809,9 @@ mod tests { ); } - // Pipeline conduits - let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); - let conduits = vec![tct]; + // Pipeline priorities + let tct = TransportPriorityTx::make(Bits::from(TransportSn::MAX)).unwrap(); + let priorities = vec![tct]; // Total amount of bytes to send in each test let bytes: usize = 100_000_000; @@ -833,7 +830,7 @@ mod tests { let (producer, consumer) = TransmissionPipeline::make( TransmissionPipelineConf::default(), - conduits.as_slice(), + priorities.as_slice(), ); let t_c = task::spawn(async move { @@ -898,10 +895,10 @@ mod tests { } // Pipeline - let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); - let conduits = vec![tct]; + let tct = TransportPriorityTx::make(Bits::from(TransportSn::MAX)).unwrap(); + let priorities = vec![tct]; let (producer, mut consumer) = - TransmissionPipeline::make(TransmissionPipelineConf::default(), conduits.as_slice()); + TransmissionPipeline::make(TransmissionPipelineConf::default(), priorities.as_slice()); let counter = Arc::new(AtomicUsize::new(0)); @@ -950,9 +947,9 @@ mod tests { #[ignore] fn tx_pipeline_thr() { // Queue - let tct = TransportConduitTx::make(Bits::from(TransportSn::MAX)).unwrap(); - let conduits = vec![tct]; - let (producer, mut consumer) = TransmissionPipeline::make(CONFIG, conduits.as_slice()); + let tct = TransportPriorityTx::make(Bits::from(TransportSn::MAX)).unwrap(); + let priorities = vec![tct]; + let (producer, mut consumer) = TransmissionPipeline::make(CONFIG, priorities.as_slice()); let count = Arc::new(AtomicUsize::new(0)); let size = Arc::new(AtomicUsize::new(0)); diff --git a/io/zenoh-transport/src/common/conduit.rs b/io/zenoh-transport/src/common/priority.rs similarity index 86% rename from io/zenoh-transport/src/common/conduit.rs rename to io/zenoh-transport/src/common/priority.rs index 67be4f8990..8644cdacb7 100644 --- a/io/zenoh-transport/src/common/conduit.rs +++ b/io/zenoh-transport/src/common/priority.rs @@ -17,7 +17,7 @@ use std::sync::{Arc, Mutex}; use zenoh_core::zlock; use zenoh_protocol::{ core::{Bits, Reliability}, - transport::{ConduitSn, TransportSn}, + transport::{PrioritySn, TransportSn}, }; use zenoh_result::ZResult; @@ -71,46 +71,46 @@ impl TransportChannelRx { } #[derive(Clone, Debug)] -pub(crate) struct TransportConduitTx { +pub(crate) struct TransportPriorityTx { pub(crate) reliable: Arc>, pub(crate) best_effort: Arc>, } -impl TransportConduitTx { - pub(crate) fn make(resolution: Bits) -> ZResult { +impl TransportPriorityTx { + pub(crate) fn make(resolution: Bits) -> ZResult { let rch = TransportChannelTx::make(resolution)?; let bch = TransportChannelTx::make(resolution)?; - let ctx = TransportConduitTx { + let ctx = TransportPriorityTx { reliable: Arc::new(Mutex::new(rch)), best_effort: Arc::new(Mutex::new(bch)), }; Ok(ctx) } - pub(crate) fn sync(&self, sn: ConduitSn) -> ZResult<()> { + pub(crate) fn sync(&self, sn: PrioritySn) -> ZResult<()> { zlock!(self.reliable).sync(sn.reliable)?; zlock!(self.best_effort).sync(sn.best_effort) } } #[derive(Clone, Debug)] -pub(crate) struct TransportConduitRx { +pub(crate) struct TransportPriorityRx { pub(crate) reliable: Arc>, pub(crate) best_effort: Arc>, } -impl TransportConduitRx { - pub(crate) fn make(resolution: Bits, defrag_buff_size: usize) -> ZResult { +impl TransportPriorityRx { + pub(crate) fn make(resolution: Bits, defrag_buff_size: usize) -> ZResult { let rch = TransportChannelRx::make(Reliability::Reliable, resolution, defrag_buff_size)?; let bch = TransportChannelRx::make(Reliability::BestEffort, resolution, defrag_buff_size)?; - let ctr = TransportConduitRx { + let ctr = TransportPriorityRx { reliable: Arc::new(Mutex::new(rch)), best_effort: Arc::new(Mutex::new(bch)), }; Ok(ctr) } - pub(crate) fn sync(&self, sn: ConduitSn) -> ZResult<()> { + pub(crate) fn sync(&self, sn: PrioritySn) -> ZResult<()> { zlock!(self.reliable).sync(sn.reliable)?; zlock!(self.best_effort).sync(sn.best_effort) } diff --git a/io/zenoh-transport/src/common/seq_num.rs b/io/zenoh-transport/src/common/seq_num.rs index e698be198c..159fd56712 100644 --- a/io/zenoh-transport/src/common/seq_num.rs +++ b/io/zenoh-transport/src/common/seq_num.rs @@ -31,7 +31,7 @@ pub(crate) fn get_mask(resolution: Bits) -> TransportSn { /// Sequence Number /// /// Zenoh sequence numbers have a negotiable resolution. Each session can -/// ideally negotiate its resolution and use it across all conduits. +/// ideally negotiate its resolution and use it across all priorities. /// /// The [`SeqNum`][SeqNum] encapsulates the sequence numbers along with a /// the comparison operators that check whether two sequence numbers are diff --git a/io/zenoh-transport/src/lib.rs b/io/zenoh-transport/src/lib.rs index ede06b2181..cd9c21cbc8 100644 --- a/io/zenoh-transport/src/lib.rs +++ b/io/zenoh-transport/src/lib.rs @@ -101,7 +101,7 @@ impl TransportMulticastEventHandler for DummyTransportMulticastEventHandler { /*************************************/ /* CALLBACK */ /*************************************/ -#[derive(Clone, Serialize)] +#[derive(Clone, Debug, Serialize, PartialEq, Eq)] #[serde(rename = "Transport")] pub struct TransportPeer { pub zid: ZenohId, diff --git a/io/zenoh-transport/src/manager.rs b/io/zenoh-transport/src/manager.rs index f49ac4e9b7..c6a4ed5781 100644 --- a/io/zenoh-transport/src/manager.rs +++ b/io/zenoh-transport/src/manager.rs @@ -11,11 +11,8 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::unicast::{ - manager::{ - TransportManagerBuilderUnicast, TransportManagerConfigUnicast, TransportManagerStateUnicast, - }, - TransportUnicast, +use super::unicast::manager::{ + TransportManagerBuilderUnicast, TransportManagerConfigUnicast, TransportManagerStateUnicast, }; use super::TransportEventHandler; use crate::multicast::manager::{ @@ -406,7 +403,6 @@ impl TransportManager { } pub async fn close(&self) { - log::trace!("TransportManager::clear())"); self.close_unicast().await; self.tx_executor.stop().await; } @@ -415,27 +411,12 @@ impl TransportManager { /* LISTENER */ /*************************************/ pub async fn add_listener(&self, endpoint: EndPoint) -> ZResult { - let p = endpoint.protocol(); - if !self - .config - .protocols - .iter() - .any(|x| x.as_str() == p.as_str()) - { - bail!( - "Unsupported protocol: {}. Supported protocols are: {:?}", - p, - self.config.protocols - ); - } - if self .locator_inspector .is_multicast(&endpoint.to_locator()) .await? { - // @TODO: multicast - bail!("Unimplemented"); + self.add_listener_multicast(endpoint).await } else { self.add_listener_unicast(endpoint).await } @@ -447,51 +428,23 @@ impl TransportManager { .is_multicast(&endpoint.to_locator()) .await? { - // @TODO: multicast - bail!("Unimplemented"); + self.del_listener_multicast(endpoint).await } else { self.del_listener_unicast(endpoint).await } } pub fn get_listeners(&self) -> Vec { - task::block_on(self.get_listeners_unicast()) - // @TODO: multicast + let mut lsu = task::block_on(self.get_listeners_unicast()); + let mut lsm = task::block_on(self.get_listeners_multicast()); + lsu.append(&mut lsm); + lsu } pub fn get_locators(&self) -> Vec { - task::block_on(self.get_locators_unicast()) - // @TODO: multicast - } - - /*************************************/ - /* TRANSPORT */ - /*************************************/ - pub fn get_transport(&self, peer: &ZenohId) -> Option { - task::block_on(self.get_transport_unicast(peer)) - // @TODO: multicast - } - - pub fn get_transports(&self) -> Vec { - task::block_on(self.get_transports_unicast()) - // @TODO: multicast - } - - pub async fn open_transport(&self, endpoint: EndPoint) -> ZResult { - let p = endpoint.protocol(); - if !self - .config - .protocols - .iter() - .any(|x| x.as_str() == p.as_str()) - { - bail!( - "Unsupported protocol: {}. Supported protocols are: {:?}", - p, - self.config.protocols - ); - } - - self.open_transport_unicast(endpoint).await + let mut lsu = task::block_on(self.get_locators_unicast()); + let mut lsm = task::block_on(self.get_locators_multicast()); + lsu.append(&mut lsm); + lsu } } diff --git a/io/zenoh-transport/src/multicast/establishment.rs b/io/zenoh-transport/src/multicast/establishment.rs index de73ac7fd0..fc4ad21da3 100644 --- a/io/zenoh-transport/src/multicast/establishment.rs +++ b/io/zenoh-transport/src/multicast/establishment.rs @@ -11,75 +11,89 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::multicast::TransportMulticast; -use crate::TransportManager; -// use rand::Rng; -// use std::sync::Arc; -// use zenoh_core::{zasynclock, zlock}; +use crate::{ + common::seq_num, + multicast::{transport::TransportMulticastInner, TransportMulticast}, + TransportConfigMulticast, TransportManager, +}; +use rand::Rng; +use std::sync::Arc; +use zenoh_core::zasynclock; use zenoh_link::LinkMulticast; -// use zenoh_protocol::core::{ConduitSn, ConduitSnList, Priority}; -use zenoh_result::ZResult; +use zenoh_protocol::{ + core::{Field, Priority}, + transport::PrioritySn, +}; +use zenoh_result::{bail, ZResult}; pub(crate) async fn open_link( - _manager: &TransportManager, - _link: LinkMulticast, + manager: &TransportManager, + link: LinkMulticast, ) -> ZResult { - todo!(); - // // Create and configure the multicast transport - // let mut prng = zasynclock!(manager.prng); + // Create and configure the multicast transport + let mut prng = zasynclock!(manager.prng); - // macro_rules! zgen_conduit_sn { - // () => { - // ConduitSn { - // reliable: prng.gen_range(0..manager.config.sn_resolution), - // best_effort: prng.gen_range(0..manager.config.sn_resolution), - // } - // }; - // } + // Generate initial SNs + let sn_resolution = manager.config.resolution.get(Field::FrameSN); + let max = seq_num::get_mask(sn_resolution); + macro_rules! zgen_prioritysn { + () => { + PrioritySn { + reliable: prng.gen_range(0..=max), + best_effort: prng.gen_range(0..=max), + } + }; + } - // let locator = link.get_dst(); - // let initial_sns = if manager.config.multicast.is_qos { - // let mut initial_sns = [ConduitSn::default(); Priority::NUM]; - // for isn in initial_sns.iter_mut() { - // *isn = zgen_conduit_sn!(); - // } - // ConduitSnList::QoS(initial_sns.into()) - // } else { - // ConduitSnList::Plain(zgen_conduit_sn!()) - // }; - // let config = TransportMulticastConfig { - // manager: manager.clone(), - // initial_sns, - // link: link.clone(), - // }; - // let ti = Arc::new(TransportMulticastInner::make(config)?); + let initial_sns = if manager.config.multicast.is_qos { + (0..Priority::NUM).map(|_| zgen_prioritysn!()).collect() + } else { + vec![zgen_prioritysn!()] + } + .into_boxed_slice(); - // // Store the active transport - // let transport: TransportMulticast = (&ti).into(); - // zlock!(manager.state.multicast.transports).insert(locator.to_owned(), ti.clone()); + // Release the lock + drop(prng); - // // Notify the transport event handler - // let batch_size = manager.config.batch_size.min(link.get_mtu()); - // ti.start_tx(batch_size).map_err(|e| { - // zlock!(manager.state.multicast.transports).remove(locator); - // let _ = ti.stop_tx(); - // e - // })?; - // let callback = manager - // .config - // .handler - // .new_multicast(transport.clone()) - // .map_err(|e| { - // zlock!(manager.state.multicast.transports).remove(locator); - // let _ = ti.stop_tx(); - // e - // })?; - // ti.set_callback(callback); - // ti.start_rx().map_err(|e| { - // zlock!(manager.state.multicast.transports).remove(locator); - // let _ = ti.stop_rx(); - // e - // })?; + // Create the transport + let locator = link.get_dst().to_owned(); + let config = TransportConfigMulticast { + link, + sn_resolution, + initial_sns, + #[cfg(feature = "shared-memory")] + is_shm: manager.config.multicast.is_shm, + }; + let ti = Arc::new(TransportMulticastInner::make(manager.clone(), config)?); - // Ok(transport) + // Add the link + ti.start_tx()?; + + // Store the active transport + let mut w_guard = zasynclock!(manager.state.multicast.transports); + if w_guard.get(&locator).is_some() { + bail!("A Multicast transport on {} already exist!", locator); + } + w_guard.insert(locator.clone(), ti.clone()); + drop(w_guard); + + // Notify the transport event handler + let transport: TransportMulticast = (&ti).into(); + + let callback = match manager.config.handler.new_multicast(transport.clone()) { + Ok(c) => c, + Err(e) => { + zasynclock!(manager.state.multicast.transports).remove(&locator); + let _ = ti.stop_tx(); + return Err(e); + } + }; + ti.set_callback(callback); + if let Err(e) = ti.start_rx() { + zasynclock!(manager.state.multicast.transports).remove(&locator); + let _ = ti.stop_rx(); + return Err(e); + } + + Ok(transport) } diff --git a/io/zenoh-transport/src/multicast/link.rs b/io/zenoh-transport/src/multicast/link.rs index 9ee7191d63..dee6a1e3b8 100644 --- a/io/zenoh-transport/src/multicast/link.rs +++ b/io/zenoh-transport/src/multicast/link.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::common::{conduit::TransportConduitTx, pipeline::TransmissionPipeline}; +use super::common::{pipeline::TransmissionPipeline, priority::TransportPriorityTx}; use super::transport::TransportMulticastInner; #[cfg(feature = "stats")] use super::TransportMulticastStatsAtomic; @@ -25,29 +25,25 @@ use async_std::task::JoinHandle; use std::convert::TryInto; use std::sync::Arc; use std::time::{Duration, Instant}; -use zenoh_buffers::reader::{HasReader, Reader}; -use zenoh_codec::{RCodec, Zenoh080}; +use zenoh_buffers::ZSlice; use zenoh_core::zlock; use zenoh_link::{LinkMulticast, Locator}; -use zenoh_protocol::core::Resolution; -use zenoh_protocol::transport::{Join, KeepAlive}; use zenoh_protocol::{ - core::{ConduitSn, ConduitSnList, Priority, WhatAmI, ZenohId}, - transport::{TransportMessage, TransportSn}, + core::{Bits, Priority, Resolution, WhatAmI, ZenohId}, + transport::{BatchSize, Join, KeepAlive, PrioritySn, TransportMessage, TransportSn}, }; use zenoh_result::{bail, zerror, ZResult}; -use zenoh_sync::RecyclingObjectPool; -use zenoh_sync::Signal; +use zenoh_sync::{RecyclingObjectPool, Signal}; -pub(super) struct _TransportLinkMulticastConfig { +pub(super) struct TransportLinkMulticastConfig { pub(super) version: u8, pub(super) zid: ZenohId, pub(super) whatami: WhatAmI, pub(super) lease: Duration, pub(super) keep_alive: usize, pub(super) join_interval: Duration, - pub(super) sn_resolution: TransportSn, - pub(super) batch_size: u16, + pub(super) sn_resolution: Bits, + pub(super) batch_size: BatchSize, } #[derive(Clone)] @@ -57,42 +53,42 @@ pub(super) struct TransportLinkMulticast { // The transmission pipeline pub(super) pipeline: Option, // The transport this link is associated to - _transport: TransportMulticastInner, + transport: TransportMulticastInner, // The signals to stop TX/RX tasks - _handle_tx: Option>>, - _signal_rx: Signal, - _handle_rx: Option>>, + handle_tx: Option>>, + signal_rx: Signal, + handle_rx: Option>>, } impl TransportLinkMulticast { - pub(super) fn _new( + pub(super) fn new( transport: TransportMulticastInner, link: LinkMulticast, ) -> TransportLinkMulticast { TransportLinkMulticast { - _transport: transport, + transport, link, pipeline: None, - _handle_tx: None, - _signal_rx: Signal::new(), - _handle_rx: None, + handle_tx: None, + signal_rx: Signal::new(), + handle_rx: None, } } } impl TransportLinkMulticast { - pub(super) fn _start_tx( + pub(super) fn start_tx( &mut self, - config: _TransportLinkMulticastConfig, - conduit_tx: Arc<[TransportConduitTx]>, + config: TransportLinkMulticastConfig, + priority_tx: Arc<[TransportPriorityTx]>, ) { - let initial_sns: Vec = conduit_tx + let initial_sns: Vec = priority_tx .iter() - .map(|x| ConduitSn { + .map(|x| PrioritySn { reliable: { let sn = zlock!(x.reliable).sn.now(); if sn == 0 { - config.sn_resolution - 1 + config.sn_resolution.mask() as TransportSn } else { sn - 1 } @@ -100,7 +96,7 @@ impl TransportLinkMulticast { best_effort: { let sn = zlock!(x.best_effort).sn.now(); if sn == 0 { - config.sn_resolution - 1 + config.sn_resolution.mask() as TransportSn } else { sn - 1 } @@ -108,60 +104,60 @@ impl TransportLinkMulticast { }) .collect(); - if self._handle_tx.is_none() { + if self.handle_tx.is_none() { let tpc = TransmissionPipelineConf { is_streamed: false, - batch_size: config.batch_size.min(self.link.get_mtu()), - queue_size: self._transport._manager.config.queue_size, - backoff: self._transport._manager.config.queue_backoff, + batch_size: config.batch_size, + queue_size: self.transport.manager.config.queue_size, + backoff: self.transport.manager.config.queue_backoff, }; // The pipeline - let (producer, consumer) = TransmissionPipeline::make(tpc, &conduit_tx); + let (producer, consumer) = TransmissionPipeline::make(tpc, &priority_tx); self.pipeline = Some(producer); // Spawn the TX task let c_link = self.link.clone(); - let c_transport = self._transport.clone(); + let ctransport = self.transport.clone(); let handle = task::spawn(async move { - let res = _tx_task( + let res = tx_task( consumer, c_link.clone(), config, initial_sns, #[cfg(feature = "stats")] - c_transport.stats.clone(), + ctransport.stats.clone(), ) .await; if let Err(e) = res { log::debug!("{}", e); // Spawn a task to avoid a deadlock waiting for this same task // to finish in the close() joining its handle - task::spawn(async move { c_transport._delete().await }); + task::spawn(async move { ctransport.delete().await }); } }); - self._handle_tx = Some(Arc::new(handle)); + self.handle_tx = Some(Arc::new(handle)); } } - pub(super) fn _stop_tx(&mut self) { + pub(super) fn stop_tx(&mut self) { if let Some(pipeline) = self.pipeline.as_ref() { pipeline.disable(); } } - pub(super) fn _start_rx(&mut self) { - if self._handle_rx.is_none() { + pub(super) fn start_rx(&mut self) { + if self.handle_rx.is_none() { // Spawn the RX task let c_link = self.link.clone(); - let c_transport = self._transport.clone(); - let c_signal = self._signal_rx.clone(); - let c_rx_buffer_size = self._transport._manager.config.link_rx_buffer_size; + let ctransport = self.transport.clone(); + let c_signal = self.signal_rx.clone(); + let c_rx_buffer_size = self.transport.manager.config.link_rx_buffer_size; let handle = task::spawn(async move { // Start the consume task - let res = _rx_task( + let res = rx_task( c_link.clone(), - c_transport.clone(), + ctransport.clone(), c_signal.clone(), c_rx_buffer_size, ) @@ -171,28 +167,28 @@ impl TransportLinkMulticast { log::debug!("{}", e); // Spawn a task to avoid a deadlock waiting for this same task // to finish in the close() joining its handle - task::spawn(async move { c_transport._delete().await }); + task::spawn(async move { ctransport.delete().await }); } }); - self._handle_rx = Some(Arc::new(handle)); + self.handle_rx = Some(Arc::new(handle)); } } - pub(super) fn _stop_rx(&mut self) { - self._signal_rx.trigger(); + pub(super) fn stop_rx(&mut self) { + self.signal_rx.trigger(); } - pub(super) async fn _close(mut self) -> ZResult<()> { + pub(super) async fn close(mut self) -> ZResult<()> { log::trace!("{}: closing", self.link); - self._stop_rx(); - if let Some(handle) = self._handle_rx.take() { + self.stop_rx(); + if let Some(handle) = self.handle_rx.take() { // It is safe to unwrap the Arc since we have the ownership of the whole link let handle_rx = Arc::try_unwrap(handle).unwrap(); handle_rx.await; } - self._stop_tx(); - if let Some(handle) = self._handle_tx.take() { + self.stop_tx(); + if let Some(handle) = self.handle_tx.take() { // It is safe to unwrap the Arc since we have the ownership of the whole link let handle_tx = Arc::try_unwrap(handle).unwrap(); handle_tx.await; @@ -205,11 +201,11 @@ impl TransportLinkMulticast { /*************************************/ /* TASKS */ /*************************************/ -async fn _tx_task( +async fn tx_task( mut pipeline: TransmissionPipelineConsumer, link: LinkMulticast, - config: _TransportLinkMulticastConfig, - mut last_sns: Vec, + config: TransportLinkMulticastConfig, + mut last_sns: Vec, #[cfg(feature = "stats")] stats: Arc, ) -> ZResult<()> { enum Action { @@ -268,17 +264,17 @@ async fn _tx_task( Action::Join => { let next_sns = last_sns .iter() - .map(|c| ConduitSn { - reliable: (1 + c.reliable) % config.sn_resolution, - best_effort: (1 + c.best_effort) % config.sn_resolution, + .map(|c| PrioritySn { + reliable: (1 + c.reliable) & config.sn_resolution.mask() as TransportSn, + best_effort: (1 + c.best_effort) + & config.sn_resolution.mask() as TransportSn, }) - .collect::>(); - let _next_sns = if next_sns.len() == Priority::NUM { - let tmp: [ConduitSn; Priority::NUM] = next_sns.try_into().unwrap(); - ConduitSnList::QoS(tmp.into()) + .collect::>(); + let (next_sn, ext_qos) = if next_sns.len() == Priority::NUM { + let tmp: [PrioritySn; Priority::NUM] = next_sns.try_into().unwrap(); + (PrioritySn::default(), Some(Box::new(tmp))) } else { - assert_eq!(next_sns.len(), 1); - ConduitSnList::Plain(next_sns[0]) + (next_sns[0], None) }; let message: TransportMessage = Join { version: config.version, @@ -287,14 +283,14 @@ async fn _tx_task( resolution: Resolution::default(), batch_size: config.batch_size, lease: config.lease, - next_sn: 0, // @TODO - ext_qos: None, // @TODO + next_sn, + ext_qos, ext_shm: None, } .into(); #[allow(unused_variables)] // Used when stats feature is enabled - let n = link.write_transport_message(&message).await?; + let n = link.send(&message).await?; #[cfg(feature = "stats")] { stats.inc_tx_t_msgs(1); @@ -307,7 +303,7 @@ async fn _tx_task( let message: TransportMessage = KeepAlive.into(); #[allow(unused_variables)] // Used when stats feature is enabled - let n = link.write_transport_message(&message).await?; + let n = link.send(&message).await?; #[cfg(feature = "stats")] { stats.inc_tx_t_msgs(1); @@ -343,7 +339,7 @@ async fn _tx_task( Ok(()) } -async fn _rx_task( +async fn rx_task( link: LinkMulticast, transport: TransportMulticastInner, signal: Signal, @@ -364,9 +360,6 @@ async fn _rx_task( Ok(Action::Stop) } - // The codec - let codec = Zenoh080::new(); - // The pool of buffers let mtu = link.get_mtu() as usize; let mut n = rx_buffer_size / mtu; @@ -390,17 +383,9 @@ async fn _rx_task( transport.stats.inc_rx_bytes(n); // Deserialize all the messages from the current ZBuf - let mut reader = buffer[0..n].reader(); - while reader.can_read() { - let msg: TransportMessage = codec - .read(&mut reader) - .map_err(|_| zerror!("{}: decoding error", link))?; - - #[cfg(feature = "stats")] - transport.stats.inc_rx_t_msgs(1); - - transport._receive_message(msg, &loc)? - } + let zslice = ZSlice::make(Arc::new(buffer), 0, n) + .map_err(|_| zerror!("Read {} bytes but buffer is {} bytes", n, mtu))?; + transport.read_messages(zslice, &link, &loc)?; } Action::Stop => break, } diff --git a/io/zenoh-transport/src/multicast/manager.rs b/io/zenoh-transport/src/multicast/manager.rs index 0bfc4a3f07..e84e45d15d 100644 --- a/io/zenoh-transport/src/multicast/manager.rs +++ b/io/zenoh-transport/src/multicast/manager.rs @@ -15,18 +15,16 @@ use crate::multicast::shm::SharedMemoryMulticast; use crate::multicast::{transport::TransportMulticastInner, TransportMulticast}; use crate::TransportManager; +use async_std::sync::Mutex; use std::collections::HashMap; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::time::Duration; #[cfg(feature = "shared-memory")] use zenoh_config::SharedMemoryConf; use zenoh_config::{Config, LinkTxConf}; -use zenoh_core::zlock; +use zenoh_core::zasynclock; use zenoh_link::*; -use zenoh_protocol::{ - core::endpoint::{self, Protocol}, - transport::close, -}; +use zenoh_protocol::{core::endpoint, transport::close}; use zenoh_result::{bail, zerror, ZResult}; pub struct TransportManagerConfigMulticast { @@ -170,13 +168,9 @@ impl TransportManager { pub async fn close_multicast(&self) { log::trace!("TransportManagerMulticast::clear())"); - zlock!(self.state.multicast.protocols).clear(); + zasynclock!(self.state.multicast.protocols).clear(); - let mut tm_guard = zlock!(self.state.multicast.transports) - .drain() - .map(|(_, v)| v) - .collect::>>(); - for tm in tm_guard.drain(..) { + for (_, tm) in zasynclock!(self.state.multicast.transports).drain() { let _ = tm.close(close::reason::GENERIC).await; } } @@ -184,20 +178,28 @@ impl TransportManager { /*************************************/ /* LINK MANAGER */ /*************************************/ - fn new_link_manager_multicast(&self, protocol: &Protocol) -> ZResult { - let mut w_guard = zlock!(self.state.multicast.protocols); - match w_guard.get(protocol.as_str()) { + async fn new_link_manager_multicast(&self, protocol: &str) -> ZResult { + if !self.config.protocols.iter().any(|x| x.as_str() == protocol) { + bail!( + "Unsupported protocol: {}. Supported protocols are: {:?}", + protocol, + self.config.protocols + ); + } + + let mut w_guard = zasynclock!(self.state.multicast.protocols); + match w_guard.get(protocol) { Some(lm) => Ok(lm.clone()), None => { - let lm = LinkManagerBuilderMulticast::make(protocol.as_str())?; + let lm = LinkManagerBuilderMulticast::make(protocol)?; w_guard.insert(protocol.to_string(), lm.clone()); Ok(lm) } } } - fn _del_link_manager_multicast(&self, protocol: &Protocol) -> ZResult<()> { - match zlock!(self.state.multicast.protocols).remove(protocol.as_str()) { + async fn del_link_manager_multicast(&self, protocol: &str) -> ZResult<()> { + match zasynclock!(self.state.multicast.protocols).remove(protocol) { Some(_) => Ok(()), None => bail!( "Can not delete the link manager for protocol ({}) because it has not been found.", @@ -232,13 +234,15 @@ impl TransportManager { .await? { bail!( - "Can not open a multicast transport with a unicast unicast: {}.", + "Can not open a multicast transport with a unicast endpoint: {}.", endpoint ) } // Automatically create a new link manager for the protocol if it does not exist - let manager = self.new_link_manager_multicast(&endpoint.protocol())?; + let manager = self + .new_link_manager_multicast(endpoint.protocol().as_str()) + .await?; // Fill and merge the endpoint configuration if let Some(config) = self.config.endpoints.get(endpoint.protocol().as_str()) { endpoint @@ -251,26 +255,30 @@ impl TransportManager { super::establishment::open_link(self, link).await } - pub fn get_transport_multicast(&self, locator: &Locator) -> Option { - zlock!(self.state.multicast.transports) + pub async fn get_transport_multicast(&self, locator: &Locator) -> Option { + zasynclock!(self.state.multicast.transports) .get(locator) .map(|t| t.into()) } - pub fn get_transports_multicast(&self) -> Vec { - zlock!(self.state.multicast.transports) + pub async fn get_transports_multicast(&self) -> Vec { + zasynclock!(self.state.multicast.transports) .values() .map(|t| t.into()) .collect() } - pub(super) fn _del_transport_multicast(&self, locator: &Locator) -> ZResult<()> { - let mut guard = zlock!(self.state.multicast.transports); + pub(super) async fn del_transport_multicast(&self, locator: &Locator) -> ZResult<()> { + let mut guard = zasynclock!(self.state.multicast.transports); let res = guard.remove(locator); - let proto = locator.protocol(); - if !guard.iter().any(|(l, _)| l.protocol() == proto) { - let _ = self._del_link_manager_multicast(&proto); + if !guard + .iter() + .any(|(l, _)| l.protocol() == locator.protocol()) + { + let _ = self + .del_link_manager_multicast(locator.protocol().as_str()) + .await; } res.map(|_| ()).ok_or_else(|| { @@ -279,4 +287,29 @@ impl TransportManager { e.into() }) } + + /*************************************/ + /* LISTENER */ + /*************************************/ + const ERR: &str = + "Listeners are not supperted on multicast endpoints. This may be caused by a wrong configuration: use `connect.endpoints` instead of `listen.endpoints` for"; + pub async fn add_listener_multicast(&self, endpoint: EndPoint) -> ZResult { + bail!("{}: {}", Self::ERR, endpoint) + } + + pub async fn del_listener_multicast(&self, endpoint: &EndPoint) -> ZResult<()> { + bail!("{}: {}", Self::ERR, endpoint) + } + + pub async fn get_listeners_multicast(&self) -> Vec { + // Multicast has no listeners, only locators + vec![] + } + + pub async fn get_locators_multicast(&self) -> Vec { + zasynclock!(self.state.multicast.transports) + .values() + .map(|t| t.locator.clone()) + .collect() + } } diff --git a/io/zenoh-transport/src/multicast/mod.rs b/io/zenoh-transport/src/multicast/mod.rs index 3eaa1f7fd2..650e773462 100644 --- a/io/zenoh-transport/src/multicast/mod.rs +++ b/io/zenoh-transport/src/multicast/mod.rs @@ -32,11 +32,12 @@ use std::{ sync::{Arc, Weak}, }; use transport::TransportMulticastInner; -use zenoh_core::zread; -use zenoh_link::Link; +use zenoh_core::{zcondfeat, zread}; +use zenoh_link::{Link, LinkMulticast}; use zenoh_protocol::{ + core::Bits, network::NetworkMessage, - transport::{close, TransportSn}, + transport::{close, PrioritySn}, }; use zenoh_result::{zerror, ZResult}; @@ -84,6 +85,15 @@ stats_struct! { /*************************************/ /* TRANSPORT MULTICAST */ /*************************************/ +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) struct TransportConfigMulticast { + pub(crate) sn_resolution: Bits, + pub(crate) initial_sns: Box<[PrioritySn]>, + pub(crate) link: LinkMulticast, + #[cfg(feature = "shared-memory")] + pub(crate) is_shm: bool, +} + #[derive(Clone)] pub struct TransportMulticast(Weak); @@ -96,11 +106,12 @@ impl TransportMulticast { } #[inline(always)] - pub fn get_sn_resolution(&self) -> ZResult { + pub fn get_sn_resolution(&self) -> ZResult { let transport = self.get_transport()?; Ok(transport.get_sn_resolution()) } + #[cfg(feature = "shared-memory")] #[inline(always)] pub fn is_shm(&self) -> ZResult { let transport = self.get_transport()?; @@ -176,6 +187,7 @@ impl fmt::Debug for TransportMulticast { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.get_transport() { Ok(transport) => { + let is_shm = zcondfeat!("shared-memory", transport.is_shm(), false); let peers: String = zread!(transport.peers) .iter() .map(|(l, p)| { @@ -186,7 +198,7 @@ impl fmt::Debug for TransportMulticast { f.debug_struct("Transport Multicast") .field("sn_resolution", &transport.get_sn_resolution()) .field("is_qos", &transport.is_qos()) - .field("is_shm", &transport.is_shm()) + .field("is_shm", &is_shm) .field("peers", &peers) .finish() } diff --git a/io/zenoh-transport/src/multicast/rx.rs b/io/zenoh-transport/src/multicast/rx.rs index 4bb219fe2c..d182e6a593 100644 --- a/io/zenoh-transport/src/multicast/rx.rs +++ b/io/zenoh-transport/src/multicast/rx.rs @@ -12,18 +12,28 @@ // ZettaScale Zenoh Team, // use super::transport::{TransportMulticastInner, TransportMulticastPeer}; -use zenoh_protocol::network::NetworkMessage; +use crate::common::priority::TransportChannelRx; +use std::sync::MutexGuard; +use zenoh_buffers::reader::{HasReader, Reader}; +use zenoh_buffers::ZSlice; +use zenoh_codec::{RCodec, Zenoh080}; +use zenoh_core::{zlock, zread}; +use zenoh_link::LinkMulticast; +use zenoh_protocol::core::{Priority, Reliability}; +use zenoh_protocol::transport::{ + Close, Fragment, Frame, Join, KeepAlive, TransportBody, TransportSn, +}; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; -use zenoh_protocol::{core::Locator, transport::TransportMessage}; -use zenoh_result::ZResult; +use zenoh_protocol::{core::Locator, network::NetworkMessage, transport::TransportMessage}; +use zenoh_result::{bail, zerror, ZResult}; /*************************************/ /* TRANSPORT RX */ /*************************************/ //noinspection ALL impl TransportMulticastInner { - fn _trigger_callback( + fn trigger_callback( &self, #[allow(unused_mut)] // shared-memory feature requires mut mut msg: NetworkMessage, @@ -58,197 +68,249 @@ impl TransportMulticastInner { #[cfg(feature = "shared-memory")] { - if self._manager.config.multicast.is_shm { - crate::shm::map_zmsg_to_shmbuf( - &mut msg, - &self._manager.state.multicast.shm.reader, - )?; + if self.manager.config.multicast.is_shm { + crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.state.multicast.shm.reader)?; } } peer.handler.handle_message(msg) } - // fn handle_frame( - // &self, - // sn: ZInt, - // payload: FramePayload, - // mut guard: MutexGuard<'_, TransportChannelRx>, - // peer: &TransportMulticastPeer, - // ) -> ZResult<()> { - // let precedes = guard.sn.precedes(sn)?; - // if !precedes { - // log::debug!( - // "Transport: {}. Frame with invalid SN dropped: {}. Expected: {}.", - // self.manager.config.zid, - // sn, - // guard.sn.next(), - // ); - // // Drop the fragments if needed - // if !guard.defrag.is_empty() { - // guard.defrag.clear(); - // } - // // Keep reading - // return Ok(()); - // } - - // // Set will always return OK because we have already checked - // // with precedes() that the sn has the right resolution - // let _ = guard.sn.set(sn); - // match payload { - // FramePayload::Fragment { buffer, is_final } => { - // if guard.defrag.is_empty() { - // let _ = guard.defrag.sync(sn); - // } - // guard.defrag.push(sn, buffer)?; - // if is_final { - // // When shared-memory feature is disabled, msg does not need to be mutable - // let msg = guard.defrag.defragment().ok_or_else(|| { - // zerror!( - // "Transport {}: {}. Defragmentation error.", - // self.manager.config.zid, - // self.locator - // ) - // })?; - // self.trigger_callback(msg, peer) - // } else { - // Ok(()) - // } - // } - // FramePayload::Messages { mut messages } => { - // for msg in messages.drain(..) { - // self.trigger_callback(msg, peer)?; - // } - // Ok(()) - // } - // } - // } - - // pub(super) fn handle_join_from_peer( - // &self, - // join: Join, - // peer: &TransportMulticastPeer, - // ) -> ZResult<()> { - // // Check if parameters are ok - // if join.version != peer.version - // || join.zid != peer.zid - // || join.whatami != peer.whatami - // || join.sn_resolution != peer.sn_resolution - // || join.lease != peer.lease - // || join.is_qos() != peer.is_qos() - // { - // let e = format!( - // "Ingoring Join on {} of peer: {}. Inconsistent parameters. Version", - // peer.locator, peer.zid, - // ); - // log::debug!("{}", e); - // bail!("{}", e); - // } - - // Ok(()) - // } - - // pub(super) fn handle_join_from_unknown(&self, join: Join, locator: &Locator) -> ZResult<()> { - // if zread!(self.peers).len() >= self.manager.config.multicast.max_sessions { - // log::debug!( - // "Ingoring Join on {} from peer: {}. Max sessions reached: {}.", - // locator, - // join.zid, - // self.manager.config.multicast.max_sessions, - // ); - // return Ok(()); - // } - - // if join.version != self.manager.config.version { - // log::debug!( - // "Ingoring Join on {} from peer: {}. Unsupported version: {}. Expected: {}.", - // locator, - // join.zid, - // join.version, - // self.manager.config.version, - // ); - // return Ok(()); - // } - - // if join.sn_resolution > self.manager.config.sn_resolution { - // log::debug!( - // "Ingoring Join on {} from peer: {}. Unsupported SN resolution: {}. Expected: <= {}.", - // locator, - // join.zid, - // join.sn_resolution, - // self.manager.config.sn_resolution, - // ); - // return Ok(()); - // } - - // if !self.manager.config.multicast.is_qos && join.is_qos() { - // log::debug!( - // "Ingoring Join on {} from peer: {}. QoS is not supported.", - // locator, - // join.zid, - // ); - // return Ok(()); - // } - - // let _ = self.new_peer(locator, join); - - // Ok(()) - // } - - pub(super) fn _receive_message( + pub(super) fn handle_join_from_peer( &self, - _msg: TransportMessage, - _locator: &Locator, + join: Join, + peer: &TransportMulticastPeer, ) -> ZResult<()> { - // // Process the received message - // let r_guard = zread!(self.peers); - // match r_guard.get(locator) { - // Some(peer) => { - // peer.active(); - - // match msg.body { - // TransportBody::Frame(Frame { - // channel, - // sn, - // payload, - // }) => { - // let c = if self.is_qos() { - // &peer.conduit_rx[channel.priority as usize] - // } else if channel.priority == Priority::default() { - // &peer.conduit_rx[0] - // } else { - // bail!( - // "Transport {}: {}. Unknown conduit {:?} from {}.", - // self.manager.config.zid, - // self.locator, - // channel.priority, - // peer.locator - // ); - // }; - - // let guard = match channel.reliability { - // Reliability::Reliable => zlock!(c.reliable), - // Reliability::BestEffort => zlock!(c.best_effort), - // }; - // self.handle_frame(sn, payload, guard, peer) - // } - // TransportBody::Join(join) => self.handle_join_from_peer(join, peer), - // TransportBody::Close(close) => { - // drop(r_guard); - // self.del_peer(locator, close.reason) - // } - // _ => Ok(()), - // } - // } - // None => { - // drop(r_guard); - // match msg.body { - // TransportBody::Join(join) => self.handle_join_from_unknown(join, locator), - // _ => Ok(()), - // } - // } - // } - // } - todo!(); + // Check if parameters are ok + if join.version != peer.version + || join.zid != peer.zid + || join.whatami != peer.whatami + || join.resolution != peer.resolution + || join.lease != peer.lease + || join.ext_qos.is_some() != peer.is_qos() + { + let e = format!( + "Ingoring Join on {} of peer: {}. Inconsistent parameters.", + peer.locator, peer.zid, + ); + log::debug!("{}", e); + bail!("{}", e); + } + + Ok(()) + } + + pub(super) fn handle_join_from_unknown(&self, join: Join, locator: &Locator) -> ZResult<()> { + if zread!(self.peers).len() >= self.manager.config.multicast.max_sessions { + log::debug!( + "Ingoring Join on {} from peer: {}. Max sessions reached: {}.", + locator, + join.zid, + self.manager.config.multicast.max_sessions, + ); + return Ok(()); + } + + if join.version != self.manager.config.version { + log::debug!( + "Ingoring Join on {} from peer: {}. Unsupported version: {}. Expected: {}.", + locator, + join.zid, + join.version, + self.manager.config.version, + ); + return Ok(()); + } + + if join.resolution != self.manager.config.resolution { + log::debug!( + "Ingoring Join on {} from peer: {}. Unsupported SN resolution: {:?}. Expected: <= {:?}.", + locator, + join.zid, + join.resolution, + self.manager.config.resolution, + ); + return Ok(()); + } + + if !self.manager.config.multicast.is_qos && join.ext_qos.is_some() { + log::debug!( + "Ingoring Join on {} from peer: {}. QoS is not supported.", + locator, + join.zid, + ); + return Ok(()); + } + + self.new_peer(locator, join) + } + + fn handle_frame(&self, frame: Frame, peer: &TransportMulticastPeer) -> ZResult<()> { + let Frame { + reliability, + sn, + ext_qos, + mut payload, + } = frame; + + let priority = ext_qos.priority(); + let c = if self.is_qos() { + &peer.priority_rx[priority as usize] + } else if priority == Priority::default() { + &peer.priority_rx[0] + } else { + bail!( + "Transport: {}. Peer: {}. Unknown priority: {:?}.", + self.manager.config.zid, + peer.zid, + priority + ); + }; + + let mut guard = match reliability { + Reliability::Reliable => zlock!(c.reliable), + Reliability::BestEffort => zlock!(c.best_effort), + }; + + self.verify_sn(sn, &mut guard)?; + + for msg in payload.drain(..) { + self.trigger_callback(msg, peer)?; + } + Ok(()) + } + + fn handle_fragment(&self, fragment: Fragment, peer: &TransportMulticastPeer) -> ZResult<()> { + let Fragment { + reliability, + more, + sn, + ext_qos, + payload, + } = fragment; + + let priority = ext_qos.priority(); + let c = if self.is_qos() { + &peer.priority_rx[priority as usize] + } else if priority == Priority::default() { + &peer.priority_rx[0] + } else { + bail!( + "Transport: {}. Peer: {}. Unknown priority: {:?}.", + self.manager.config.zid, + peer.zid, + priority + ); + }; + + let mut guard = match reliability { + Reliability::Reliable => zlock!(c.reliable), + Reliability::BestEffort => zlock!(c.best_effort), + }; + + self.verify_sn(sn, &mut guard)?; + + if guard.defrag.is_empty() { + let _ = guard.defrag.sync(sn); + } + guard.defrag.push(sn, payload)?; + if !more { + // When shared-memory feature is disabled, msg does not need to be mutable + let msg = guard.defrag.defragment().ok_or_else(|| { + zerror!( + "Transport: {}. Peer: {}. Priority: {:?}. Defragmentation error.", + self.manager.config.zid, + peer.zid, + priority + ) + })?; + return self.trigger_callback(msg, peer); + } + + Ok(()) + } + + fn verify_sn( + &self, + sn: TransportSn, + guard: &mut MutexGuard<'_, TransportChannelRx>, + ) -> ZResult<()> { + let precedes = guard.sn.precedes(sn)?; + if !precedes { + log::debug!( + "Transport: {}. Frame with invalid SN dropped: {}. Expected: {}.", + self.manager.config.zid, + sn, + guard.sn.next() + ); + // Drop the fragments if needed + if !guard.defrag.is_empty() { + guard.defrag.clear(); + } + // Keep reading + return Ok(()); + } + + // Set will always return OK because we have already checked + // with precedes() that the sn has the right resolution + let _ = guard.sn.set(sn); + + Ok(()) + } + + pub(super) fn read_messages( + &self, + mut zslice: ZSlice, + link: &LinkMulticast, + locator: &Locator, + ) -> ZResult<()> { + let codec = Zenoh080::new(); + let mut reader = zslice.reader(); + while reader.can_read() { + let msg: TransportMessage = codec + .read(&mut reader) + .map_err(|_| zerror!("{}: decoding error", link))?; + + log::trace!("Received: {:?}", msg); + + #[cfg(feature = "stats")] + { + transport.stats.inc_rx_t_msgs(1); + } + + let r_guard = zread!(self.peers); + match r_guard.get(locator) { + Some(peer) => { + peer.active(); + match msg.body { + TransportBody::Frame(msg) => self.handle_frame(msg, peer)?, + TransportBody::Fragment(fragment) => { + self.handle_fragment(fragment, peer)? + } + TransportBody::Join(join) => self.handle_join_from_peer(join, peer)?, + TransportBody::KeepAlive(KeepAlive { .. }) => {} + TransportBody::Close(Close { reason, .. }) => { + drop(r_guard); + self.del_peer(locator, reason)?; + } + _ => { + log::debug!( + "Transport: {}. Message handling not implemented: {:?}", + self.manager.config.zid, + msg + ); + } + } + } + None => { + drop(r_guard); + if let TransportBody::Join(join) = msg.body { + self.handle_join_from_unknown(join, locator)?; + } + } + } + } + + Ok(()) } } diff --git a/io/zenoh-transport/src/multicast/transport.rs b/io/zenoh-transport/src/multicast/transport.rs index 4eac92b3c0..06f54e37fc 100644 --- a/io/zenoh-transport/src/multicast/transport.rs +++ b/io/zenoh-transport/src/multicast/transport.rs @@ -11,12 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::common::conduit::{TransportConduitRx, TransportConduitTx}; -use super::link::TransportLinkMulticast; +use super::common::priority::{TransportPriorityRx, TransportPriorityTx}; +use super::link::{TransportLinkMulticast, TransportLinkMulticastConfig}; #[cfg(feature = "stats")] use super::TransportMulticastStatsAtomic; use crate::{ - TransportManager, TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, + TransportConfigMulticast, TransportManager, TransportMulticastEventHandler, TransportPeer, + TransportPeerEventHandler, }; use async_trait::async_trait; use std::{ @@ -27,41 +28,41 @@ use std::{ }, time::Duration, }; -use zenoh_core::{zread, zwrite}; -use zenoh_link::{LinkMulticast, Locator}; +use zenoh_core::{zcondfeat, zread, zwrite}; +use zenoh_link::{Link, LinkMulticast, Locator}; use zenoh_protocol::core::Resolution; -use zenoh_protocol::transport::TransportSn; +use zenoh_protocol::transport::{Close, TransportMessage}; use zenoh_protocol::{ - core::{ConduitSnList, Priority, WhatAmI, ZenohId}, + core::{Bits, Field, Priority, WhatAmI, ZenohId}, transport::{close, Join}, }; use zenoh_result::{bail, ZResult}; -use zenoh_util::{Timed, TimedHandle, Timer}; +use zenoh_util::{Timed, TimedEvent, TimedHandle, Timer}; /*************************************/ /* TRANSPORT */ /*************************************/ #[derive(Clone)] pub(super) struct TransportMulticastPeer { - pub(super) _version: u8, - pub(super) _locator: Locator, + pub(super) version: u8, + pub(super) locator: Locator, pub(super) zid: ZenohId, pub(super) whatami: WhatAmI, - pub(super) _resolution: Resolution, - pub(super) _lease: Duration, - pub(super) _whatchdog: Arc, + pub(super) resolution: Resolution, + pub(super) lease: Duration, + pub(super) whatchdog: Arc, pub(super) handle: TimedHandle, - pub(super) _conduit_rx: Box<[TransportConduitRx]>, + pub(super) priority_rx: Box<[TransportPriorityRx]>, pub(super) handler: Arc, } impl TransportMulticastPeer { - pub(super) fn _active(&self) { - self._whatchdog.store(true, Ordering::Release); + pub(super) fn active(&self) { + self.whatchdog.store(true, Ordering::Release); } - pub(super) fn _is_qos(&self) -> bool { - self._conduit_rx.len() == Priority::NUM + pub(super) fn is_qos(&self) -> bool { + self.priority_rx.len() == Priority::NUM } } @@ -87,70 +88,61 @@ impl Timed for TransportMulticastPeerLeaseTimer { #[derive(Clone)] pub(crate) struct TransportMulticastInner { // The manager this channel is associated to - pub(super) _manager: TransportManager, - // The multicast locator - pub(super) locator: Locator, - // Tx conduits - pub(super) conduit_tx: Arc<[TransportConduitTx]>, + pub(super) manager: TransportManager, + // Tx priorities + pub(super) priority_tx: Arc<[TransportPriorityTx]>, // Remote peers pub(super) peers: Arc>>, + // The multicast locator - Convenience for logging + pub(super) locator: Locator, // The multicast link pub(super) link: Arc>>, // The callback pub(super) callback: Arc>>>, // The timer for peer leases - pub(super) _timer: Arc, + pub(super) timer: Arc, // Transport statistics #[cfg(feature = "stats")] pub(super) stats: Arc, } -pub(crate) struct _TransportMulticastConfig { - pub(crate) manager: TransportManager, - pub(crate) initial_sns: ConduitSnList, - pub(crate) link: LinkMulticast, -} - impl TransportMulticastInner { - pub(super) fn _make(_config: _TransportMulticastConfig) -> ZResult { - // let mut conduit_tx = vec![]; - - // match config.initial_sns { - // ConduitSnList::Plain(sn) => { - // let tct = TransportConduitTx::make(config.manager.config.resolution)?; - // tct.sync(sn)?; - // conduit_tx.push(tct); - // } - // ConduitSnList::QoS(sns) => { - // for (_, sn) in sns.iter().enumerate() { - // let tct = TransportConduitTx::make(config.manager.config.resolution)?; - // tct.sync(*sn)?; - // conduit_tx.push(tct); - // } - // } - // } - - // let ti = TransportMulticastInner { - // manager: config.manager, - // locator: config.link.get_dst().to_owned(), - // conduit_tx: conduit_tx.into_boxed_slice().into(), - // peers: Arc::new(RwLock::new(HashMap::new())), - // link: Arc::new(RwLock::new(None)), - // callback: Arc::new(RwLock::new(None)), - // timer: Arc::new(Timer::new(false)), - // #[cfg(feature = "stats")] - // stats: Arc::new(TransportMulticastStatsAtomic::default()), - // }; - - // let mut w_guard = zwrite!(ti.link); - // *w_guard = Some(TransportLinkMulticast::new(ti.clone(), config.link)); - // drop(w_guard); - - // Ok(ti) - todo!(); + pub(super) fn make( + manager: TransportManager, + config: TransportConfigMulticast, + ) -> ZResult { + let mut priority_tx = vec![]; + if (config.initial_sns.len() != 1) != (config.initial_sns.len() != Priority::NUM) { + for (_, sn) in config.initial_sns.iter().enumerate() { + let tct = TransportPriorityTx::make(config.sn_resolution)?; + tct.sync(*sn)?; + priority_tx.push(tct); + } + } else { + bail!("Invalid QoS configuration"); + } + + let ti = TransportMulticastInner { + manager, + priority_tx: priority_tx.into_boxed_slice().into(), + peers: Arc::new(RwLock::new(HashMap::new())), + locator: config.link.get_dst().to_owned(), + link: Arc::new(RwLock::new(None)), + callback: Arc::new(RwLock::new(None)), + timer: Arc::new(Timer::new(false)), + #[cfg(feature = "stats")] + stats: Arc::new(TransportMulticastStatsAtomic::default()), + }; + + let link = TransportLinkMulticast::new(ti.clone(), config.link); + let mut guard = zwrite!(ti.link); + *guard = Some(link); + drop(guard); + + Ok(ti) } - pub(super) fn _set_callback(&self, callback: Arc) { + pub(super) fn set_callback(&self, callback: Arc) { let mut guard = zwrite!(self.callback); *guard = Some(callback); } @@ -158,17 +150,17 @@ impl TransportMulticastInner { /*************************************/ /* ACCESSORS */ /*************************************/ - pub(crate) fn get_sn_resolution(&self) -> TransportSn { - // self.manager.config.sn_resolution - todo!(); + pub(crate) fn get_sn_resolution(&self) -> Bits { + self.manager.config.resolution.get(Field::FrameSN) } pub(crate) fn is_qos(&self) -> bool { - self.conduit_tx.len() > 1 + self.priority_tx.len() == Priority::NUM } + #[cfg(feature = "shared-memory")] pub(crate) fn is_shm(&self) -> bool { - false + self.manager.config.multicast.is_shm } pub(crate) fn get_callback(&self) -> Option> { @@ -182,8 +174,8 @@ impl TransportMulticastInner { /*************************************/ /* TERMINATION */ /*************************************/ - pub(super) async fn _delete(&self) -> ZResult<()> { - log::debug!("Closing multicast transport on {}", self.locator); + pub(super) async fn delete(&self) -> ZResult<()> { + log::debug!("Closing multicast transport on {:?}", self.locator); // Notify the callback that we are going to close the transport let callback = zwrite!(self.callback).take(); @@ -192,12 +184,12 @@ impl TransportMulticastInner { } // Delete the transport on the manager - let _ = self._manager._del_transport_multicast(&self.locator); + let _ = self.manager.del_transport_multicast(&self.locator).await; // Close all the links let mut link = zwrite!(self.link).take(); if let Some(l) = link.take() { - let _ = l._close().await; + let _ = l.close().await; } // Notify the callback that we have closed the transport @@ -208,115 +200,110 @@ impl TransportMulticastInner { Ok(()) } - pub(crate) async fn close(&self, _reason: u8) -> ZResult<()> { - // log::trace!( - // "Closing multicast transport of peer {}: {}", - // self.manager.config.zid, - // self.locator - // ); - - // let pipeline = zread!(self.link) - // .as_ref() - // .unwrap() - // .pipeline - // .as_ref() - // .unwrap() - // .clone(); - - // // Close message to be sent on all the links - // let peer_id = Some(self.manager.zid()); - // let reason_id = reason; - // // link_only should always be false for user-triggered close. However, in case of - // // multiple links, it is safer to close all the links first. When no links are left, - // // the transport is then considered closed. - // let link_only = true; - // let attachment = None; // No attachment here - // let msg = TransportMessage::make_close(peer_id, reason_id, link_only, attachment); - - // pipeline.push_transport_message(msg, Priority::Background); - - // // Terminate and clean up the transport - // self.delete().await - todo!(); + pub(crate) async fn close(&self, reason: u8) -> ZResult<()> { + log::trace!( + "Closing multicast transport of peer {}: {}", + self.manager.config.zid, + self.locator + ); + + { + let r_guard = zread!(self.link); + if let Some(link) = r_guard.as_ref() { + if let Some(pipeline) = link.pipeline.as_ref() { + let pipeline = pipeline.clone(); + drop(r_guard); + // Close message to be sent on all the links + let msg: TransportMessage = Close { + reason, + session: false, + } + .into(); + pipeline.push_transport_message(msg, Priority::Background); + } + } + } + + // Terminate and clean up the transport + self.delete().await } /*************************************/ /* LINK */ /*************************************/ - pub(super) fn _start_tx(&self, _batch_size: u16) -> ZResult<()> { - // let mut guard = zwrite!(self.link); - // match guard.as_mut() { - // Some(l) => { - // assert!(!self.conduit_tx.is_empty()); - // let config = TransportLinkMulticastConfig { - // version: self.manager.config.version, - // zid: self.manager.config.zid, - // whatami: self.manager.config.whatami, - // lease: self.manager.config.multicast.lease, - // keep_alive: self.manager.config.multicast.keep_alive, - // join_interval: self.manager.config.multicast.join_interval, - // sn_resolution: self.manager.config.sn_resolution, - // batch_size, - // }; - // l.start_tx(config, self.conduit_tx.clone()); - // Ok(()) - // } - // None => { - // bail!( - // "Can not start multicast Link TX of peer {}: {}", - // self.manager.config.zid, - // self.locator - // ) - // } - // } - todo!(); + pub(super) fn start_tx(&self) -> ZResult<()> { + let mut guard = zwrite!(self.link); + match guard.as_mut() { + Some(l) => { + assert!(!self.priority_tx.is_empty()); + let config = TransportLinkMulticastConfig { + version: self.manager.config.version, + zid: self.manager.config.zid, + whatami: self.manager.config.whatami, + lease: self.manager.config.multicast.lease, + keep_alive: self.manager.config.multicast.keep_alive, + join_interval: self.manager.config.multicast.join_interval, + sn_resolution: self.manager.config.resolution.get(Field::FrameSN), + batch_size: self.manager.config.batch_size.min(l.link.get_mtu()), + }; + l.start_tx(config, self.priority_tx.clone()); + Ok(()) + } + None => { + bail!( + "Can not start multicast Link TX of peer {}: {}", + self.manager.config.zid, + self.locator + ) + } + } } - pub(super) fn _stop_tx(&self) -> ZResult<()> { + pub(super) fn stop_tx(&self) -> ZResult<()> { let mut guard = zwrite!(self.link); match guard.as_mut() { Some(l) => { - l._stop_tx(); + l.stop_tx(); Ok(()) } None => { bail!( "Can not stop multicast Link TX of peer {}: {}", - self._manager.config.zid, + self.manager.config.zid, self.locator ) } } } - pub(super) fn _start_rx(&self) -> ZResult<()> { + pub(super) fn start_rx(&self) -> ZResult<()> { let mut guard = zwrite!(self.link); match guard.as_mut() { Some(l) => { - l._start_rx(); + l.start_rx(); Ok(()) } None => { bail!( "Can not start multicast Link RX of peer {}: {}", - self._manager.config.zid, + self.manager.config.zid, self.locator ) } } } - pub(super) fn _stop_rx(&self) -> ZResult<()> { + pub(super) fn stop_rx(&self) -> ZResult<()> { let mut guard = zwrite!(self.link); match guard.as_mut() { Some(l) => { - l._stop_rx(); + l.stop_rx(); Ok(()) } None => { bail!( "Can not stop multicast Link RX of peer {}: {}", - self._manager.config.zid, + self.manager.config.zid, self.locator ) } @@ -326,90 +313,84 @@ impl TransportMulticastInner { /*************************************/ /* PEER */ /*************************************/ - pub(super) fn _new_peer(&self, _locator: &Locator, _join: Join) -> ZResult<()> { - // let mut link = Link::from(self.get_link()); - // link.dst = locator.clone(); - - // let peer = TransportPeer { - // zid: join.zid, - // whatami: join.whatami, - // is_qos: join.is_qos(), - // is_shm: self.is_shm(), - // links: vec![link], - // }; - - // let handler = match zread!(self.callback).as_ref() { - // Some(cb) => cb.new_peer(peer.clone())?, - // None => return Ok(()), - // }; - - // let conduit_rx = match join.next_sns { - // ConduitSnList::Plain(sn) => { - // let tcr = TransportConduitRx::make( - // join.sn_resolution, - // self.manager.config.defrag_buff_size, - // )?; - // tcr.sync(sn)?; - // vec![tcr] - // } - // ConduitSnList::QoS(ref sns) => { - // let mut tcrs = Vec::with_capacity(sns.len()); - // for (_, sn) in sns.iter().enumerate() { - // let tcr = TransportConduitRx::make( - // join.sn_resolution, - // self.manager.config.defrag_buff_size, - // )?; - // tcr.sync(*sn)?; - // tcrs.push(tcr); - // } - // tcrs - // } - // } - // .into_boxed_slice(); - - // // Create lease event - // let whatchdog = Arc::new(AtomicBool::new(false)); - // let event = TransportMulticastPeerLeaseTimer { - // whatchdog: whatchdog.clone(), - // locator: locator.clone(), - // transport: self.clone(), - // }; - // let event = TimedEvent::periodic(join.lease, event); - // let handle = event.get_handle(); - - // // Store the new peer - // let peer = TransportMulticastPeer { - // version: join.version, - // locator: locator.clone(), - // zid: peer.zid, - // whatami: peer.whatami, - // sn_resolution: join.sn_resolution, - // lease: join.lease, - // whatchdog, - // handle, - // conduit_rx, - // handler, - // }; - // { - // zwrite!(self.peers).insert(locator.clone(), peer); - // } - - // // Add the event to the timer - // self.timer.add(event); - - // log::debug!( - // "New transport joined on {}: zid {}, whatami {}, sn resolution {}, locator {}, qos {}, initial sn: {}", - // self.locator, - // join.zid, - // join.whatami, - // join.sn_resolution, - // locator, - // join.is_qos(), - // join.next_sns, - // ); - - // Ok(()) - todo!(); + pub(super) fn new_peer(&self, locator: &Locator, join: Join) -> ZResult<()> { + let mut link = Link::from(self.get_link()); + link.dst = locator.clone(); + + let is_shm = zcondfeat!("shared-memory", join.ext_shm.is_some(), false); + let peer = TransportPeer { + zid: join.zid, + whatami: join.whatami, + is_qos: join.ext_qos.is_some(), + #[cfg(feature = "shared-memory")] + is_shm, + links: vec![link], + }; + + let handler = match zread!(self.callback).as_ref() { + Some(cb) => cb.new_peer(peer.clone())?, + None => return Ok(()), + }; + + // Build next SNs + let next_sns = match join.ext_qos.as_ref() { + Some(sns) => sns.to_vec(), + None => vec![join.next_sn], + } + .into_boxed_slice(); + + let mut priority_rx = Vec::with_capacity(next_sns.len()); + for (_, sn) in next_sns.iter().enumerate() { + let tprx = TransportPriorityRx::make( + join.resolution.get(Field::FrameSN), + self.manager.config.defrag_buff_size, + )?; + tprx.sync(*sn)?; + priority_rx.push(tprx); + } + let priority_rx = priority_rx.into_boxed_slice(); + + log::debug!( + "New transport joined on {}: zid {}, whatami {}, resolution {:?}, locator {}, is_qos {}, is_shm {}, initial sn: {:?}", + self.locator, + peer.zid, + peer.whatami, + join.resolution, + locator, + peer.is_qos, + is_shm, + next_sns, + ); + + // Create lease event + let whatchdog = Arc::new(AtomicBool::new(false)); + let event = TransportMulticastPeerLeaseTimer { + whatchdog: whatchdog.clone(), + locator: locator.clone(), + transport: self.clone(), + }; + let event = TimedEvent::periodic(join.lease, event); + let handle = event.get_handle(); + + // Store the new peer + let peer = TransportMulticastPeer { + version: join.version, + locator: locator.clone(), + zid: peer.zid, + whatami: peer.whatami, + resolution: join.resolution, + lease: join.lease, + whatchdog, + handle, + priority_rx, + handler, + }; + zwrite!(self.peers).insert(locator.clone(), peer); + + // Add the event to the timer + self.timer.add(event); + + Ok(()) } pub(super) fn del_peer(&self, locator: &Locator, reason: u8) -> ZResult<()> { @@ -433,21 +414,21 @@ impl TransportMulticastInner { } pub(super) fn get_peers(&self) -> Vec { - // zread!(self.peers) - // .values() - // .map(|p| { - // let mut link = Link::from(self.get_link()); - // link.dst = p.locator.clone(); - - // TransportPeer { - // zid: p.zid, - // whatami: p.whatami, - // is_qos: p.is_qos(), - // is_shm: self.is_shm(), - // links: vec![link], - // } - // }) - // .collect() - todo!(); + zread!(self.peers) + .values() + .map(|p| { + let mut link = Link::from(self.get_link()); + link.dst = p.locator.clone(); + + TransportPeer { + zid: p.zid, + whatami: p.whatami, + is_qos: p.is_qos(), + #[cfg(feature = "shared-memory")] + is_shm: self.is_shm(), + links: vec![link], + } + }) + .collect() } } diff --git a/io/zenoh-transport/src/multicast/tx.rs b/io/zenoh-transport/src/multicast/tx.rs index 2d08eb36ec..96dab0a876 100644 --- a/io/zenoh-transport/src/multicast/tx.rs +++ b/io/zenoh-transport/src/multicast/tx.rs @@ -55,10 +55,10 @@ impl TransportMulticastInner { pub(super) fn schedule(&self, mut msg: NetworkMessage) -> bool { #[cfg(feature = "shared-memory")] { - let res = if self._manager.config.multicast.is_shm { + let res = if self.manager.config.multicast.is_shm { crate::shm::map_zmsg_to_shminfo(&mut msg) } else { - crate::shm::map_zmsg_to_shmbuf(&mut msg, &self._manager.state.multicast.shm.reader) + crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.state.multicast.shm.reader) }; if let Err(e) = res { log::trace!("Failed SHM conversion: {}", e); diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/link.rs index 8b8a7f148c..c4100dd3e9 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/link.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::common::conduit::TransportConduitTx; +use super::common::priority::TransportPriorityTx; use super::transport::TransportUnicastInner; #[cfg(feature = "stats")] use super::TransportUnicastStatsAtomic; @@ -95,7 +95,7 @@ impl TransportLinkUnicast { executor: &TransportExecutor, keep_alive: Duration, batch_size: u16, - conduit_tx: &[TransportConduitTx], + priority_tx: &[TransportPriorityTx], ) { if self.handle_tx.is_none() { let config = TransmissionPipelineConf { @@ -109,7 +109,7 @@ impl TransportLinkUnicast { let is_compressed = self.transport.config.manager.config.unicast.is_compressed; // The pipeline - let (producer, consumer) = TransmissionPipeline::make(config, conduit_tx); + let (producer, consumer) = TransmissionPipeline::make(config, priority_tx); self.pipeline = Some(producer); // Spawn the TX task @@ -337,7 +337,8 @@ async fn rx_task_stream( rx_decompress(&mut buffer, &pool, n, &mut start_pos, &mut end_pos)?; // Deserialize all the messages from the current ZBuf - let zslice = ZSlice::make(Arc::new(buffer), start_pos, end_pos).unwrap(); + let zslice = ZSlice::make(Arc::new(buffer), start_pos, end_pos) + .map_err(|_| zerror!("Read {} bytes but buffer is {} bytes", n, mtu))?; transport.read_messages(zslice, &link)?; } Action::Stop => break, @@ -408,7 +409,8 @@ async fn rx_task_dgram( rx_decompress(&mut buffer, &pool, n, &mut start_pos, &mut end_pos)?; // Deserialize all the messages from the current ZBuf - let zslice = ZSlice::make(Arc::new(buffer), start_pos, end_pos).unwrap(); + let zslice = ZSlice::make(Arc::new(buffer), start_pos, end_pos) + .map_err(|_| zerror!("Read {} bytes but buffer is {} bytes", n, mtu))?; transport.read_messages(zslice, &link)?; } Action::Stop => break, diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index aac33ca339..4dede34769 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -276,6 +276,14 @@ impl TransportManager { /* LINK MANAGER */ /*************************************/ async fn new_link_manager_unicast(&self, protocol: &str) -> ZResult { + if !self.config.protocols.iter().any(|x| x.as_str() == protocol) { + bail!( + "Unsupported protocol: {}. Supported protocols are: {:?}", + protocol, + self.config.protocols + ); + } + let mut w_guard = zasynclock!(self.state.unicast.protocols); if let Some(lm) = w_guard.get(protocol) { Ok(lm.clone()) @@ -311,6 +319,17 @@ impl TransportManager { /* LISTENER */ /*************************************/ pub async fn add_listener_unicast(&self, mut endpoint: EndPoint) -> ZResult { + if self + .locator_inspector + .is_multicast(&endpoint.to_locator()) + .await? + { + bail!( + "Can not listen on unicast endpoint with a multicast endpoint: {}.", + endpoint + ) + } + let manager = self .new_link_manager_unicast(endpoint.protocol().as_str()) .await?; @@ -432,19 +451,6 @@ impl TransportManager { &self, mut endpoint: EndPoint, ) -> ZResult { - let p = endpoint.protocol(); - if !self - .config - .protocols - .iter() - .any(|x| x.as_str() == p.as_str()) - { - bail!( - "Unsupported protocol: {}. Supported protocols are: {:?}", - p, - self.config.protocols - ); - } if self .locator_inspector .is_multicast(&endpoint.to_locator()) @@ -487,14 +493,13 @@ impl TransportManager { } pub(super) async fn del_transport_unicast(&self, peer: &ZenohId) -> ZResult<()> { - let _ = zasynclock!(self.state.unicast.transports) + zasynclock!(self.state.unicast.transports) .remove(peer) .ok_or_else(|| { let e = zerror!("Can not delete the transport of peer: {}", peer); log::trace!("{}", e); e })?; - Ok(()) } diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index efc884bdbe..a3a6eb673f 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -122,9 +122,9 @@ impl TransportUnicast { } #[inline(always)] - pub fn get_sn_resolution(&self) -> ZResult { + pub fn get_sn_resolution(&self) -> ZResult { let transport = self.get_inner()?; - Ok(transport.get_sn_resolution().mask()) + Ok(transport.get_sn_resolution()) } #[cfg(feature = "shared-memory")] @@ -234,7 +234,7 @@ impl fmt::Debug for TransportUnicast { f.debug_struct("Transport Unicast") .field("zid", &transport.get_zid()) .field("whatami", &transport.get_whatami()) - .field("sn_resolution", &transport.get_sn_resolution()) + .field("resolution", &transport.get_sn_resolution()) .field("is_qos", &transport.is_qos()) .field("is_shm", &is_shm) .field("links", &transport.get_links()) diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/rx.rs index f8a950e62e..e6d8bfd42c 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/rx.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::common::conduit::TransportChannelRx; +use super::common::priority::TransportChannelRx; use super::transport::TransportUnicastInner; use async_std::task; use std::sync::MutexGuard; @@ -121,12 +121,12 @@ impl TransportUnicastInner { let priority = ext_qos.priority(); let c = if self.is_qos() { - &self.conduit_rx[priority as usize] + &self.priority_rx[priority as usize] } else if priority == Priority::default() { - &self.conduit_rx[0] + &self.priority_rx[0] } else { bail!( - "Transport: {}. Unknown conduit: {:?}.", + "Transport: {}. Unknown priority: {:?}.", self.config.zid, priority ); @@ -155,12 +155,12 @@ impl TransportUnicastInner { } = fragment; let c = if self.is_qos() { - &self.conduit_rx[qos.priority() as usize] + &self.priority_rx[qos.priority() as usize] } else if qos.priority() == Priority::default() { - &self.conduit_rx[0] + &self.priority_rx[0] } else { bail!( - "Transport: {}. Unknown conduit: {:?}.", + "Transport: {}. Unknown priority: {:?}.", self.config.zid, qos.priority() ); diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/transport.rs index ddcdbb52ba..73820d1f4b 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/transport.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use super::super::{TransportExecutor, TransportManager, TransportPeerEventHandler}; -use super::common::conduit::{TransportConduitRx, TransportConduitTx}; +use super::common::priority::{TransportPriorityRx, TransportPriorityTx}; use super::link::TransportLinkUnicast; #[cfg(feature = "stats")] use super::TransportUnicastStatsAtomic; @@ -24,7 +24,7 @@ use zenoh_core::{zasynclock, zcondfeat, zread, zwrite}; use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ core::{Bits, Priority, WhatAmI, ZenohId}, - transport::{Close, ConduitSn, TransportMessage, TransportSn}, + transport::{Close, PrioritySn, TransportMessage, TransportSn}, }; use zenoh_result::{bail, zerror, ZResult}; @@ -55,10 +55,10 @@ pub(crate) struct TransportUnicastInner { pub(crate) manager: TransportManager, // Transport config pub(super) config: TransportConfigUnicast, - // Tx conduits - pub(super) conduit_tx: Arc<[TransportConduitTx]>, - // Rx conduits - pub(super) conduit_rx: Arc<[TransportConduitRx]>, + // Tx priorities + pub(super) priority_tx: Arc<[TransportPriorityTx]>, + // Rx priorities + pub(super) priority_rx: Arc<[TransportPriorityRx]>, // The links associated to the channel pub(super) links: Arc>>, // The callback @@ -75,34 +75,34 @@ impl TransportUnicastInner { manager: TransportManager, config: TransportConfigUnicast, ) -> ZResult { - let mut conduit_tx = vec![]; - let mut conduit_rx = vec![]; + let mut priority_tx = vec![]; + let mut priority_rx = vec![]; let num = if config.is_qos { Priority::NUM } else { 1 }; for _ in 0..num { - conduit_tx.push(TransportConduitTx::make(config.sn_resolution)?); + priority_tx.push(TransportPriorityTx::make(config.sn_resolution)?); } for _ in 0..Priority::NUM { - conduit_rx.push(TransportConduitRx::make( + priority_rx.push(TransportPriorityRx::make( config.sn_resolution, manager.config.defrag_buff_size, )?); } - let initial_sn = ConduitSn { + let initial_sn = PrioritySn { reliable: config.tx_initial_sn, best_effort: config.tx_initial_sn, }; - for c in conduit_tx.iter() { + for c in priority_tx.iter() { c.sync(initial_sn)?; } let t = TransportUnicastInner { manager, config, - conduit_tx: conduit_tx.into_boxed_slice().into(), - conduit_rx: conduit_rx.into_boxed_slice().into(), + priority_tx: priority_tx.into_boxed_slice().into(), + priority_rx: priority_rx.into_boxed_slice().into(), links: Arc::new(RwLock::new(vec![].into_boxed_slice())), callback: Arc::new(RwLock::new(None)), alive: Arc::new(AsyncMutex::new(false)), @@ -137,11 +137,11 @@ impl TransportUnicastInner { *a_guard = true; - let csn = ConduitSn { + let csn = PrioritySn { reliable: initial_sn_rx, best_effort: initial_sn_rx, }; - for c in self.conduit_rx.iter() { + for c in self.priority_rx.iter() { c.sync(csn)?; } @@ -247,8 +247,8 @@ impl TransportUnicastInner { let mut guard = zwrite!(self.links); match zlinkgetmut!(guard, link) { Some(l) => { - assert!(!self.conduit_tx.is_empty()); - l.start_tx(executor, keep_alive, batch_size, &self.conduit_tx); + assert!(!self.priority_tx.is_empty()); + l.start_tx(executor, keep_alive, batch_size, &self.priority_tx); Ok(()) } None => { diff --git a/io/zenoh-transport/tests/multicast_transport.rs b/io/zenoh-transport/tests/multicast_transport.rs new file mode 100644 index 0000000000..a27cf2a355 --- /dev/null +++ b/io/zenoh-transport/tests/multicast_transport.rs @@ -0,0 +1,359 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +// Restricting to macos by default because of no IPv6 support +// on GitHub CI actions on Linux and Windows. +#[cfg(target_family = "unix")] +mod tests { + use async_std::{prelude::FutureExt, task}; + use std::{ + any::Any, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, + time::Duration, + }; + use zenoh_core::zasync_executor_init; + use zenoh_link::Link; + use zenoh_protocol::{ + core::{ + Channel, CongestionControl, Encoding, EndPoint, Priority, Reliability, WhatAmI, ZenohId, + }, + network::{ + push::{ + ext::{NodeIdType, QoSType}, + Push, + }, + NetworkMessage, + }, + zenoh_new::Put, + }; + use zenoh_result::ZResult; + use zenoh_transport::{ + TransportEventHandler, TransportManager, TransportMulticast, + TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, + }; + + const TIMEOUT: Duration = Duration::from_secs(60); + const SLEEP: Duration = Duration::from_secs(1); + const SLEEP_COUNT: Duration = Duration::from_millis(10); + + const MSG_COUNT: usize = 1_000; + const MSG_SIZE_NOFRAG: [usize; 1] = [1_024]; + + macro_rules! ztimeout { + ($f:expr) => { + $f.timeout(TIMEOUT).await.unwrap() + }; + } + + // Transport Handler for the peer02 + struct SHPeer { + count: Arc, + } + + impl Default for SHPeer { + fn default() -> Self { + Self { + count: Arc::new(AtomicUsize::new(0)), + } + } + } + + impl SHPeer { + fn get_count(&self) -> usize { + self.count.load(Ordering::Relaxed) + } + } + + impl TransportEventHandler for SHPeer { + fn new_unicast( + &self, + _peer: TransportPeer, + _transport: TransportUnicast, + ) -> ZResult> { + panic!(); + } + + fn new_multicast( + &self, + _transport: TransportMulticast, + ) -> ZResult> { + let arc = Arc::new(SCPeer::new(self.count.clone())); + Ok(arc) + } + } + + // Transport Callback for the peer02 + pub struct SCPeer { + count: Arc, + } + + impl SCPeer { + pub fn new(count: Arc) -> Self { + Self { count } + } + } + + impl TransportMulticastEventHandler for SCPeer { + fn new_peer(&self, peer: TransportPeer) -> ZResult> { + println!("\tNew peer: {:?}", peer); + Ok(Arc::new(SCPeer { + count: self.count.clone(), + })) + } + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } + } + + impl TransportPeerEventHandler for SCPeer { + fn handle_message(&self, _msg: NetworkMessage) -> ZResult<()> { + self.count.fetch_add(1, Ordering::Relaxed); + Ok(()) + } + + fn new_link(&self, _link: Link) {} + fn del_link(&self, _link: Link) {} + fn closing(&self) {} + fn closed(&self) {} + + fn as_any(&self) -> &dyn Any { + self + } + } + + struct TransportMulticastPeer { + manager: TransportManager, + handler: Arc, + transport: TransportMulticast, + } + + async fn open_transport( + endpoint: &EndPoint, + ) -> (TransportMulticastPeer, TransportMulticastPeer) { + // Define peer01 and peer02 IDs + let peer01_id = ZenohId::try_from([1]).unwrap(); + let peer02_id = ZenohId::try_from([2]).unwrap(); + + // Create the peer01 transport manager + let peer01_handler = Arc::new(SHPeer::default()); + let peer01_manager = TransportManager::builder() + .zid(peer01_id) + .whatami(WhatAmI::Peer) + .build(peer01_handler.clone()) + .unwrap(); + + // Create the peer02 transport manager + let peer02_handler = Arc::new(SHPeer::default()); + let peer02_manager = TransportManager::builder() + .whatami(WhatAmI::Peer) + .zid(peer02_id) + .build(peer02_handler.clone()) + .unwrap(); + + // Create an empty transport with the peer01 + // Open transport -> This should be accepted + println!("Opening transport with {endpoint}"); + let _ = ztimeout!(peer01_manager.open_transport_multicast(endpoint.clone())).unwrap(); + assert!(peer01_manager + .get_transport_multicast(&endpoint.to_locator()) + .await + .is_some()); + println!("\t{:?}", peer01_manager.get_transports_multicast().await); + + println!("Opening transport with {endpoint}"); + let _ = ztimeout!(peer02_manager.open_transport_multicast(endpoint.clone())).unwrap(); + assert!(peer02_manager + .get_transport_multicast(&endpoint.to_locator()) + .await + .is_some()); + println!("\t{:?}", peer02_manager.get_transports_multicast().await); + + // Wait to for peer 01 and 02 to join each other + let peer01_transport = peer01_manager + .get_transport_multicast(&endpoint.to_locator()) + .await + .unwrap(); + ztimeout!(async { + while peer01_transport.get_peers().unwrap().is_empty() { + task::sleep(SLEEP_COUNT).await; + } + }); + println!( + "\tPeer01 peers: {:?}", + peer01_transport.get_peers().unwrap() + ); + + let peer02_transport = peer02_manager + .get_transport_multicast(&endpoint.to_locator()) + .await + .unwrap(); + ztimeout!(async { + while peer02_transport.get_peers().unwrap().is_empty() { + task::sleep(SLEEP_COUNT).await; + } + }); + println!( + "\tPeer02 peers: {:?}", + peer02_transport.get_peers().unwrap() + ); + + ( + TransportMulticastPeer { + manager: peer01_manager, + handler: peer01_handler, + transport: peer01_transport, + }, + TransportMulticastPeer { + manager: peer02_manager, + handler: peer02_handler, + transport: peer02_transport, + }, + ) + } + + async fn close_transport( + peer01: TransportMulticastPeer, + peer02: TransportMulticastPeer, + endpoint: &EndPoint, + ) { + // Close the peer01 transport + println!("Closing transport with {endpoint}"); + ztimeout!(peer01.transport.close()).unwrap(); + assert!(peer01.manager.get_transports_multicast().await.is_empty()); + assert!(peer02.transport.get_peers().unwrap().is_empty()); + + // Close the peer02 transport + println!("Closing transport with {endpoint}"); + ztimeout!(peer02.transport.close()).unwrap(); + assert!(peer02.manager.get_transports_multicast().await.is_empty()); + + // Wait a little bit + task::sleep(SLEEP).await; + } + + async fn test_transport( + peer01: &TransportMulticastPeer, + peer02: &TransportMulticastPeer, + channel: Channel, + msg_size: usize, + ) { + // Create the message to send + let message: NetworkMessage = Push { + wire_expr: "test".into(), + ext_qos: QoSType::new(channel.priority, CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: NodeIdType::default(), + payload: Put { + payload: vec![0u8; msg_size].into(), + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, + ext_unknown: vec![], + } + .into(), + } + .into(); + + println!("Sending {MSG_COUNT} messages... {channel:?} {msg_size}"); + for _ in 0..MSG_COUNT { + peer01.transport.schedule(message.clone()).unwrap(); + } + + match channel.reliability { + Reliability::Reliable => { + ztimeout!(async { + while peer02.handler.get_count() != MSG_COUNT { + task::sleep(SLEEP_COUNT).await; + } + }); + } + Reliability::BestEffort => { + ztimeout!(async { + while peer02.handler.get_count() == 0 { + task::sleep(SLEEP_COUNT).await; + } + }); + } + }; + + // Wait a little bit + task::sleep(SLEEP).await; + } + + async fn run_single(endpoint: &EndPoint, channel: Channel, msg_size: usize) { + let (peer01, peer02) = open_transport(endpoint).await; + test_transport(&peer01, &peer02, channel, msg_size).await; + + #[cfg(feature = "stats")] + { + let stats = peer01.transport.get_stats().unwrap(); + println!("\tPeer 01: {:?}", stats); + let stats = peer02.transport.get_stats().unwrap(); + println!("\tPeer 02: {:?}", stats); + } + + close_transport(peer01, peer02, endpoint).await; + } + + async fn run(endpoints: &[EndPoint], channel: &[Channel], msg_size: &[usize]) { + for e in endpoints.iter() { + for ch in channel.iter() { + for ms in msg_size.iter() { + run_single(e, *ch, *ms).await; + } + } + } + } + + #[cfg(feature = "transport_udp")] + #[test] + fn transport_multicast_udp_only() { + env_logger::init(); + + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locator + let endpoints: Vec = vec![ + "udp/224.0.0.1:7447".parse().unwrap(), + // Disabling by default because of no IPv6 support + // on GitHub CI actions. + // format!("udp/{}", ZN_MULTICAST_IPV6_ADDRESS_DEFAULT) + // .parse() + // .unwrap(), + ]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run(&endpoints, &channel, &MSG_SIZE_NOFRAG)); + } +} diff --git a/io/zenoh-transport/tests/transport_whitelist.rs b/io/zenoh-transport/tests/transport_whitelist.rs index 001b4c530c..d589ed24cf 100644 --- a/io/zenoh-transport/tests/transport_whitelist.rs +++ b/io/zenoh-transport/tests/transport_whitelist.rs @@ -87,11 +87,11 @@ async fn run(endpoints: &[EndPoint]) { // Create the listener on the router for e in endpoints.iter() { println!("Listener endpoint: {e}"); - let res = ztimeout!(router_manager.add_listener(e.clone())); + let res = ztimeout!(router_manager.add_listener_unicast(e.clone())); assert!(res.is_err()); println!("Open endpoint: {e}"); - let res = ztimeout!(router_manager.open_transport(e.clone())); + let res = ztimeout!(router_manager.open_transport_unicast(e.clone())); assert!(res.is_err()); } @@ -110,12 +110,12 @@ async fn run(endpoints: &[EndPoint]) { // Create the listener on the router for e in endpoints.iter() { println!("Listener endpoint: {e}"); - let _ = ztimeout!(router_manager.add_listener(e.clone())).unwrap(); + let _ = ztimeout!(router_manager.add_listener_unicast(e.clone())).unwrap(); task::sleep(SLEEP).await; println!("Open endpoint: {e}"); - let _ = ztimeout!(router_manager.open_transport(e.clone())).unwrap(); + let _ = ztimeout!(router_manager.open_transport_unicast(e.clone())).unwrap(); task::sleep(SLEEP).await; } diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index 2ff0e23b0f..aaf4376aba 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -304,14 +304,14 @@ async fn auth_pubkey(endpoint: &EndPoint) { // Open a first transport from client01 to the router // -> This should be accepted println!("Transport Authenticator PubKey [2a1]"); - let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); + let c_ses1 = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())).unwrap(); assert_eq!(c_ses1.get_links().unwrap().len(), 1); /* [2b] */ // Open a first transport from client02 to the router // -> This should be rejected println!("Transport Authenticator PubKey [2b1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client02_manager.open_transport_unicast(endpoint.clone())); println!("Transport Authenticator PubKey [2b2]: {res:?}"); assert!(res.is_err()); @@ -319,7 +319,7 @@ async fn auth_pubkey(endpoint: &EndPoint) { // Open a first transport from client03 to the router // -> This should be rejected println!("Transport Authenticator PubKey [2c1]"); - let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client03_manager.open_transport_unicast(endpoint.clone())); println!("Transport Authenticator PubKey [2c2]: {res:?}"); assert!(res.is_err()); @@ -334,13 +334,13 @@ async fn auth_pubkey(endpoint: &EndPoint) { // Open a first transport from client02 to the router // -> This should be accepted println!("Transport Authenticator PubKey [3a1]"); - let c_ses2 = ztimeout!(client02_manager.open_transport(endpoint.clone())).unwrap(); + let c_ses2 = ztimeout!(client02_manager.open_transport_unicast(endpoint.clone())).unwrap(); assert_eq!(c_ses2.get_links().unwrap().len(), 1); // Open a first transport from client03 to the router // -> This should be accepted println!("Transport Authenticator PubKey [3b1]"); - let c_ses3 = ztimeout!(client03_manager.open_transport(endpoint.clone())).unwrap(); + let c_ses3 = ztimeout!(client03_manager.open_transport_unicast(endpoint.clone())).unwrap(); assert_eq!(c_ses3.get_links().unwrap().len(), 1); // /* [4a] */ @@ -361,7 +361,7 @@ async fn auth_pubkey(endpoint: &EndPoint) { assert!(res.is_ok()); ztimeout!(async { - while !router_manager.get_transports().is_empty() { + while !router_manager.get_transports_unicast().await.is_empty() { task::sleep(SLEEP).await; } }); @@ -484,7 +484,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { // Open a first transport from the client to the router // -> This should be accepted println!("Transport Authenticator UserPassword [2a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Authenticator UserPassword [2a1]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); @@ -496,7 +496,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { assert!(res.is_ok()); ztimeout!(async { - while !router_manager.get_transports().is_empty() { + while !router_manager.get_transports_unicast().await.is_empty() { task::sleep(SLEEP).await; } }); @@ -505,7 +505,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { // Open a second transport from the client to the router // -> This should be rejected println!("Transport Authenticator UserPassword [4a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client02_manager.open_transport_unicast(endpoint.clone())); println!("Transport Authenticator UserPassword [4a1]: {res:?}"); assert!(res.is_err()); @@ -513,7 +513,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { // Open a third transport from the client to the router // -> This should be accepted println!("Transport Authenticator UserPassword [5a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Authenticator UserPassword [5a1]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); @@ -529,7 +529,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { // Open a fourth transport from the client to the router // -> This should be accepted println!("Transport Authenticator UserPassword [6a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client02_manager.open_transport_unicast(endpoint.clone())); println!("Transport Authenticator UserPassword [6a1]: {res:?}"); assert!(res.is_ok()); let c_ses2 = res.unwrap(); @@ -538,7 +538,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { // Open a fourth transport from the client to the router // -> This should be rejected println!("Transport Authenticator UserPassword [7a1]"); - let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client03_manager.open_transport_unicast(endpoint.clone())); println!("Transport Authenticator UserPassword [7a1]: {res:?}"); assert!(res.is_err()); @@ -553,7 +553,7 @@ async fn auth_usrpwd(endpoint: &EndPoint) { assert!(res.is_ok()); ztimeout!(async { - while !router_manager.get_transports().is_empty() { + while !router_manager.get_transports_unicast().await.is_empty() { task::sleep(SLEEP).await; } }); diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index f4a70e505f..81a912defc 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -167,7 +167,7 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting for opening transport"); // Syncrhonize before opening the transports ztimeout!(cc_barow.wait()); - let res = ztimeout!(c_p01m.open_transport(c_end.clone())); + let res = ztimeout!(c_p01m.open_transport_unicast(c_end.clone())); println!("[Transport Peer 01d] => Opening transport with {c_end:?}: {res:?}"); assert!(res.is_ok()); @@ -181,8 +181,11 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Waiting... OK"); // Verify that the transport has been correctly open - assert_eq!(peer01_manager.get_transports().len(), 1); - let s02 = peer01_manager.get_transport(&c_zid02).unwrap(); + assert_eq!(peer01_manager.get_transports_unicast().await.len(), 1); + let s02 = peer01_manager + .get_transport_unicast(&c_zid02) + .await + .unwrap(); assert_eq!( s02.get_links().unwrap().len(), c_end01.len() + c_end02.len() @@ -265,7 +268,7 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Opening transport with {c_end:?}: {res:?}"); assert!(res.is_ok()); @@ -280,10 +283,13 @@ async fn transport_concurrent(endpoint01: Vec, endpoint02: Vec Transports: {:?}", - peer02_manager.get_transports() + peer02_manager.get_transports_unicast().await ); - assert_eq!(peer02_manager.get_transports().len(), 1); - let s01 = peer02_manager.get_transport(&c_zid01).unwrap(); + assert_eq!(peer02_manager.get_transports_unicast().await.len(), 1); + let s01 = peer02_manager + .get_transport_unicast(&c_zid01) + .await + .unwrap(); assert_eq!( s01.get_links().unwrap().len(), c_end01.len() + c_end02.len() diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index 1dc4d4684d..1c6fe39395 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -69,9 +69,12 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { // Create an empty transport with the client // Open transport -> This should be accepted println!("Opening transport with {endpoint}"); - let _ = ztimeout!(client_manager.open_transport(endpoint.clone())).unwrap(); + let _ = ztimeout!(client_manager.open_transport_unicast(endpoint.clone())).unwrap(); - let client_transport = client_manager.get_transport(&router_id).unwrap(); + let client_transport = client_manager + .get_transport_unicast(&router_id) + .await + .unwrap(); // Create the message to send let message: NetworkMessage = Push { @@ -117,7 +120,7 @@ async fn run(endpoint: &EndPoint, channel: Channel, msg_size: usize) { // Wait a little bit ztimeout!(async { - while !router_manager.get_listeners_unicast().await.is_empty() { + while !router_manager.get_listeners().is_empty() { task::sleep(SLEEP).await; } }); diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index 3e68c5fc51..8949fb05cf 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -18,7 +18,6 @@ use std::convert::TryFrom; use std::io::Write; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; -use std::thread; use std::time::Duration; use zenoh_core::zasync_executor_init; use zenoh_link::Link; @@ -212,9 +211,9 @@ async fn transport_intermittent(endpoint: &EndPoint) { /* [2] */ // Open a transport from client01 to the router - let c_ses1 = ztimeout!(client01_manager.open_transport(endpoint.clone())).unwrap(); + let c_ses1 = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())).unwrap(); assert_eq!(c_ses1.get_links().unwrap().len(), 1); - assert_eq!(client01_manager.get_transports().len(), 1); + assert_eq!(client01_manager.get_transports_unicast().await.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); /* [3] */ @@ -227,9 +226,10 @@ async fn transport_intermittent(endpoint: &EndPoint) { print!("+"); std::io::stdout().flush().unwrap(); - let c_ses2 = ztimeout!(c_client02_manager.open_transport(c_endpoint.clone())).unwrap(); + let c_ses2 = + ztimeout!(c_client02_manager.open_transport_unicast(c_endpoint.clone())).unwrap(); assert_eq!(c_ses2.get_links().unwrap().len(), 1); - assert_eq!(c_client02_manager.get_transports().len(), 1); + assert_eq!(c_client02_manager.get_transports_unicast().await.len(), 1); assert_eq!(c_ses2.get_zid().unwrap(), c_router_id); task::sleep(SLEEP).await; @@ -251,9 +251,10 @@ async fn transport_intermittent(endpoint: &EndPoint) { print!("*"); std::io::stdout().flush().unwrap(); - let c_ses3 = ztimeout!(c_client03_manager.open_transport(c_endpoint.clone())).unwrap(); + let c_ses3 = + ztimeout!(c_client03_manager.open_transport_unicast(c_endpoint.clone())).unwrap(); assert_eq!(c_ses3.get_links().unwrap().len(), 1); - assert_eq!(c_client03_manager.get_transports().len(), 1); + assert_eq!(c_client03_manager.get_transports_unicast().await.len(), 1); assert_eq!(c_ses3.get_zid().unwrap(), c_router_id); task::sleep(SLEEP).await; @@ -270,7 +271,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { /* [4] */ println!("Transport Intermittent [4a1]"); let c_router_manager = router_manager.clone(); - ztimeout!(task::spawn_blocking(move || { + ztimeout!(task::spawn_blocking(move || task::block_on(async { // Create the message to send let message: NetworkMessage = Push { wire_expr: "test".into(), @@ -299,7 +300,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { println!("\nScheduled {count}"); ticks.remove(0); } - let transports = c_router_manager.get_transports(); + let transports = c_router_manager.get_transports_unicast().await; if !transports.is_empty() { for s in transports.iter() { if let Ok(ll) = s.get_links() { @@ -318,10 +319,10 @@ async fn transport_intermittent(endpoint: &EndPoint) { count += 1; } else { print!("O"); - thread::sleep(USLEEP); + task::sleep(USLEEP).await; } } - })); + }))); // Stop the tasks ztimeout!(c2_handle.cancel()); @@ -343,15 +344,15 @@ async fn transport_intermittent(endpoint: &EndPoint) { /* [5] */ // Close the open transport on the client println!("Transport Intermittent [5a1]"); - for s in client01_manager.get_transports().iter() { + for s in client01_manager.get_transports_unicast().await.iter() { ztimeout!(s.close()).unwrap(); } println!("Transport Intermittent [5a2]"); - for s in client02_manager.get_transports().iter() { + for s in client02_manager.get_transports_unicast().await.iter() { ztimeout!(s.close()).unwrap(); } println!("Transport Intermittent [5a3]"); - for s in client03_manager.get_transports().iter() { + for s in client03_manager.get_transports_unicast().await.iter() { ztimeout!(s.close()).unwrap(); } @@ -360,7 +361,7 @@ async fn transport_intermittent(endpoint: &EndPoint) { println!("Transport Intermittent [6a1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; if transports.is_empty() { break; } diff --git a/io/zenoh-transport/tests/unicast_multilink.rs b/io/zenoh-transport/tests/unicast_multilink.rs index 8d8dc2852e..8583482e7e 100644 --- a/io/zenoh-transport/tests/unicast_multilink.rs +++ b/io/zenoh-transport/tests/unicast_multilink.rs @@ -150,12 +150,12 @@ mod tests { let mut links_num = 1; println!("Transport Open Close [1c1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [1c2]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); println!("Transport Open Close [1d1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [1d2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); @@ -168,7 +168,7 @@ mod tests { println!("Transport Open Close [1f1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; let s = transports .iter() .find(|s| s.get_zid().unwrap() == client01_id); @@ -190,12 +190,12 @@ mod tests { links_num = 2; println!("\nTransport Open Close [2a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [2a2]: {res:?}"); assert!(res.is_ok()); let c_ses2 = res.unwrap(); println!("Transport Open Close [2b1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [2b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses2.get_zid().unwrap(), router_id); @@ -209,7 +209,7 @@ mod tests { println!("Transport Open Close [2d1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; let s = transports .iter() .find(|s| s.get_zid().unwrap() == client01_id) @@ -227,11 +227,11 @@ mod tests { // Open transport -> This should be rejected because // of the maximum limit of links per transport println!("\nTransport Open Close [3a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [3a2]: {res:?}"); assert!(res.is_err()); println!("Transport Open Close [3b1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [3b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); @@ -244,7 +244,7 @@ mod tests { println!("Transport Open Close [3d1]"); ztimeout!(async { task::sleep(SLEEP).await; - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; assert_eq!(transports.len(), 1); let s = transports .iter() @@ -261,7 +261,7 @@ mod tests { println!("Transport Open Close [4a2]: {res:?}"); assert!(res.is_ok()); println!("Transport Open Close [4b1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [4b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -269,7 +269,7 @@ mod tests { println!("Transport Open Close [4c1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; let index = transports .iter() .find(|s| s.get_zid().unwrap() == client01_id); @@ -286,12 +286,12 @@ mod tests { links_num = 1; println!("\nTransport Open Close [5a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [5a2]: {res:?}"); assert!(res.is_ok()); let c_ses3 = res.unwrap(); println!("Transport Open Close [5b1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [5b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses3.get_zid().unwrap(), router_id); @@ -304,7 +304,7 @@ mod tests { println!("Transport Open Close [5d1]"); ztimeout!(async { task::sleep(SLEEP).await; - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; assert_eq!(transports.len(), 1); let s = transports .iter() @@ -318,12 +318,12 @@ mod tests { // Open transport -> This should be rejected because // of the maximum limit of transports println!("\nTransport Open Close [6a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client02_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [6a2]: {res:?}"); assert!(res.is_ok()); let c_ses4 = res.unwrap(); println!("Transport Open Close [6b1]"); - let transports = client02_manager.get_transports(); + let transports = client02_manager.get_transports_unicast().await; println!("Transport Open Close [6b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses4.get_zid().unwrap(), router_id); @@ -335,11 +335,11 @@ mod tests { // Open transport -> This should be rejected because // of the maximum limit of transports println!("\nTransport Open Close [6d1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client02_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [6d2]: {res:?}"); assert!(res.is_err()); println!("Transport Open Close [6e1]"); - let transports = client02_manager.get_transports(); + let transports = client02_manager.get_transports_unicast().await; println!("Transport Open Close [6e2]: {transports:?}"); assert_eq!(transports.len(), 1); @@ -347,7 +347,7 @@ mod tests { println!("Transport Open Close [6f1]"); ztimeout!(async { task::sleep(SLEEP).await; - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; assert_eq!(transports.len(), 2); let s = transports .iter() @@ -361,11 +361,11 @@ mod tests { // Try to spoof the first client // -> This should be rejected println!("\nTransport Open Close [7a1]"); - let res = ztimeout!(client03_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client03_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [7a2]: {res:?}"); assert!(res.is_err()); println!("Transport Open Close [7b1]"); - let transports = client03_manager.get_transports(); + let transports = client03_manager.get_transports_unicast().await; println!("Transport Open Close [7b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -380,7 +380,7 @@ mod tests { println!("Transport Open Close [8b2]: {res:?}"); assert!(res.is_ok()); println!("Transport Open Close [8c1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [8c2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -388,7 +388,7 @@ mod tests { println!("Transport Open Close [8d1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; if transports.is_empty() { break; } @@ -402,12 +402,12 @@ mod tests { links_num = 1; println!("\nTransport Open Close [9a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client02_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [9a2]: {res:?}"); assert!(res.is_ok()); let c_ses4 = res.unwrap(); println!("Transport Open Close [9b1]"); - let transports = client02_manager.get_transports(); + let transports = client02_manager.get_transports_unicast().await; println!("Transport Open Close [9b2]: {transports:?}"); assert_eq!(transports.len(), 1); println!("Transport Open Close [9c1]"); @@ -419,7 +419,7 @@ mod tests { println!("Transport Open Close [9d1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; let s = transports .iter() .find(|s| s.get_zid().unwrap() == client02_id); @@ -441,7 +441,7 @@ mod tests { println!("Transport Open Close [9a2]: {res:?}"); assert!(res.is_ok()); println!("Transport Open Close [9b1]"); - let transports = client02_manager.get_transports(); + let transports = client02_manager.get_transports_unicast().await; println!("Transport Open Close [9b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -449,7 +449,7 @@ mod tests { println!("Transport Open Close [9c1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; if transports.is_empty() { break; } diff --git a/io/zenoh-transport/tests/unicast_openclose.rs b/io/zenoh-transport/tests/unicast_openclose.rs index 464edbe236..eddad39cea 100644 --- a/io/zenoh-transport/tests/unicast_openclose.rs +++ b/io/zenoh-transport/tests/unicast_openclose.rs @@ -136,12 +136,12 @@ async fn openclose_transport(endpoint: &EndPoint) { let mut links_num = 1; println!("Transport Open Close [1c1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [1c2]: {res:?}"); assert!(res.is_ok()); let c_ses1 = res.unwrap(); println!("Transport Open Close [1d1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [1d2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); @@ -154,7 +154,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [1f1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; let s = transports .iter() .find(|s| s.get_zid().unwrap() == client01_id); @@ -176,12 +176,12 @@ async fn openclose_transport(endpoint: &EndPoint) { links_num = 2; println!("\nTransport Open Close [2a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [2a2]: {res:?}"); assert!(res.is_ok()); let c_ses2 = res.unwrap(); println!("Transport Open Close [2b1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [2b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses2.get_zid().unwrap(), router_id); @@ -195,7 +195,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [2d1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; let s = transports .iter() .find(|s| s.get_zid().unwrap() == client01_id) @@ -213,11 +213,11 @@ async fn openclose_transport(endpoint: &EndPoint) { // Open transport -> This should be rejected because // of the maximum limit of links per transport println!("\nTransport Open Close [3a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [3a2]: {res:?}"); assert!(res.is_err()); println!("Transport Open Close [3b1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [3b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); @@ -230,7 +230,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [3d1]"); ztimeout!(async { task::sleep(SLEEP).await; - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; assert_eq!(transports.len(), 1); let s = transports .iter() @@ -247,7 +247,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [4a2]: {res:?}"); assert!(res.is_ok()); println!("Transport Open Close [4b1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [4b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -255,7 +255,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [4c1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; let index = transports .iter() .find(|s| s.get_zid().unwrap() == client01_id); @@ -272,12 +272,12 @@ async fn openclose_transport(endpoint: &EndPoint) { links_num = 1; println!("\nTransport Open Close [5a1]"); - let res = ztimeout!(client01_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [5a2]: {res:?}"); assert!(res.is_ok()); let c_ses3 = res.unwrap(); println!("Transport Open Close [5b1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [5b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses3.get_zid().unwrap(), router_id); @@ -290,7 +290,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [5d1]"); ztimeout!(async { task::sleep(SLEEP).await; - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; assert_eq!(transports.len(), 1); let s = transports .iter() @@ -304,11 +304,11 @@ async fn openclose_transport(endpoint: &EndPoint) { // Open transport -> This should be rejected because // of the maximum limit of transports println!("\nTransport Open Close [6a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client02_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [6a2]: {res:?}"); assert!(res.is_err()); println!("Transport Open Close [6b1]"); - let transports = client02_manager.get_transports(); + let transports = client02_manager.get_transports_unicast().await; println!("Transport Open Close [6b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -316,7 +316,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [6c1]"); ztimeout!(async { task::sleep(SLEEP).await; - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; assert_eq!(transports.len(), 1); let s = transports .iter() @@ -333,7 +333,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [7a2]: {res:?}"); assert!(res.is_ok()); println!("Transport Open Close [7b1]"); - let transports = client01_manager.get_transports(); + let transports = client01_manager.get_transports_unicast().await; println!("Transport Open Close [7b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -341,7 +341,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [7c1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; if transports.is_empty() { break; } @@ -355,12 +355,12 @@ async fn openclose_transport(endpoint: &EndPoint) { links_num = 1; println!("\nTransport Open Close [8a1]"); - let res = ztimeout!(client02_manager.open_transport(endpoint.clone())); + let res = ztimeout!(client02_manager.open_transport_unicast(endpoint.clone())); println!("Transport Open Close [8a2]: {res:?}"); assert!(res.is_ok()); let c_ses4 = res.unwrap(); println!("Transport Open Close [8b1]"); - let transports = client02_manager.get_transports(); + let transports = client02_manager.get_transports_unicast().await; println!("Transport Open Close [8b2]: {transports:?}"); assert_eq!(transports.len(), 1); println!("Transport Open Close [8c1]"); @@ -372,7 +372,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [8d1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; let s = transports .iter() .find(|s| s.get_zid().unwrap() == client02_id); @@ -394,7 +394,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [9a2]: {res:?}"); assert!(res.is_ok()); println!("Transport Open Close [9b1]"); - let transports = client02_manager.get_transports(); + let transports = client02_manager.get_transports_unicast().await; println!("Transport Open Close [9b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -402,7 +402,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [9c1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports(); + let transports = router_manager.get_transports_unicast().await; if transports.is_empty() { break; } diff --git a/io/zenoh-transport/tests/unicast_conduits.rs b/io/zenoh-transport/tests/unicast_priorities.rs similarity index 95% rename from io/zenoh-transport/tests/unicast_conduits.rs rename to io/zenoh-transport/tests/unicast_priorities.rs index d21b30d23c..d76bbc69fc 100644 --- a/io/zenoh-transport/tests/unicast_conduits.rs +++ b/io/zenoh-transport/tests/unicast_priorities.rs @@ -195,7 +195,7 @@ impl TransportPeerEventHandler for SCClient { } } -async fn open_transport( +async fn open_transport_unicast( endpoints: &[EndPoint], ) -> ( TransportManager, @@ -232,10 +232,13 @@ async fn open_transport( // Open transport -> This should be accepted for e in endpoints.iter() { println!("Opening transport with {e}"); - let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); + let _ = ztimeout!(client_manager.open_transport_unicast(e.clone())).unwrap(); } - let client_transport = client_manager.get_transport(&router_id).unwrap(); + let client_transport = client_manager + .get_transport_unicast(&router_id) + .await + .unwrap(); // Return the handlers ( @@ -261,7 +264,7 @@ async fn close_transport( ztimeout!(client_transport.close()).unwrap(); ztimeout!(async { - while !router_manager.get_transports().is_empty() { + while !router_manager.get_transports_unicast().await.is_empty() { task::sleep(SLEEP).await; } }); @@ -328,14 +331,14 @@ async fn single_run(router_handler: Arc, client_transport: TransportUn async fn run(endpoints: &[EndPoint]) { let (router_manager, router_handler, client_manager, client_transport) = - open_transport(endpoints).await; + open_transport_unicast(endpoints).await; single_run(router_handler.clone(), client_transport.clone()).await; close_transport(router_manager, client_manager, client_transport, endpoints).await; } #[cfg(feature = "transport_tcp")] #[test] -fn conduits_tcp_only() { +fn priorities_tcp_only() { let _ = env_logger::try_init(); task::block_on(async { zasync_executor_init!(); @@ -348,7 +351,7 @@ fn conduits_tcp_only() { #[cfg(feature = "transport_ws")] #[test] -fn conduits_ws_only() { +fn priorities_ws_only() { let _ = env_logger::try_init(); task::block_on(async { zasync_executor_init!(); diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index d8ef239a86..30a3bcfecf 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -199,22 +199,28 @@ mod tests { // Create a transport with the peer println!("Transport SHM [1b]"); let peer_shm01_transport = - ztimeout!(peer_shm02_manager.open_transport(endpoint.clone())).unwrap(); + ztimeout!(peer_shm02_manager.open_transport_unicast(endpoint.clone())).unwrap(); assert!(peer_shm01_transport.is_shm().unwrap()); // Create a transport with the peer println!("Transport SHM [1c]"); let peer_net02_transport = - ztimeout!(peer_net01_manager.open_transport(endpoint.clone())).unwrap(); + ztimeout!(peer_net01_manager.open_transport_unicast(endpoint.clone())).unwrap(); assert!(!peer_net02_transport.is_shm().unwrap()); // Retrieve the transports println!("Transport SHM [2a]"); - let peer_shm02_transport = peer_shm01_manager.get_transport(&peer_shm02).unwrap(); + let peer_shm02_transport = peer_shm01_manager + .get_transport_unicast(&peer_shm02) + .await + .unwrap(); assert!(peer_shm02_transport.is_shm().unwrap()); println!("Transport SHM [2b]"); - let peer_net01_transport = peer_shm01_manager.get_transport(&peer_net01).unwrap(); + let peer_net01_transport = peer_shm01_manager + .get_transport_unicast(&peer_net01) + .await + .unwrap(); assert!(!peer_net01_transport.is_shm().unwrap()); // Send the message @@ -323,7 +329,7 @@ mod tests { ztimeout!(peer_net01_transport.close()).unwrap(); ztimeout!(async { - while !peer_shm01_manager.get_transports().is_empty() { + while !peer_shm01_manager.get_transports_unicast().await.is_empty() { task::sleep(SLEEP).await; } }); diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index 72d9d9bb4d..617280cf4f 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -192,13 +192,13 @@ mod tests { // These open should succeed for e in c_ep02.iter() { println!("[Simultaneous 01c] => Opening transport with {e:?}..."); - let _ = ztimeout!(c_p01m.open_transport(e.clone())).unwrap(); + let _ = ztimeout!(c_p01m.open_transport_unicast(e.clone())).unwrap(); } // These open should fails for e in c_ep02.iter() { println!("[Simultaneous 01d] => Exceeding transport with {e:?}..."); - let res = ztimeout!(c_p01m.open_transport(e.clone())); + let res = ztimeout!(c_p01m.open_transport_unicast(e.clone())); assert!(res.is_err()); } @@ -210,9 +210,9 @@ mod tests { task::sleep(SLEEP).await; println!( "[Simultaneous 01e] => Transports: {:?}", - peer01_manager.get_transports() + peer01_manager.get_transports_unicast().await ); - tp02 = peer01_manager.get_transport(&peer_id02); + tp02 = peer01_manager.get_transport_unicast(&peer_id02).await; } tp02.unwrap() @@ -247,13 +247,13 @@ mod tests { // These open should succeed for e in c_ep01.iter() { println!("[Simultaneous 02c] => Opening transport with {e:?}..."); - let _ = ztimeout!(c_p02m.open_transport(e.clone())).unwrap(); + let _ = ztimeout!(c_p02m.open_transport_unicast(e.clone())).unwrap(); } // These open should fails for e in c_ep01.iter() { println!("[Simultaneous 02d] => Exceeding transport with {e:?}..."); - let res = ztimeout!(c_p02m.open_transport(e.clone())); + let res = ztimeout!(c_p02m.open_transport_unicast(e.clone())); assert!(res.is_err()); } @@ -266,9 +266,9 @@ mod tests { task::sleep(SLEEP).await; println!( "[Simultaneous 02e] => Transports: {:?}", - peer02_manager.get_transports() + peer02_manager.get_transports_unicast().await ); - tp01 = peer02_manager.get_transport(&peer_id01); + tp01 = peer02_manager.get_transport_unicast(&peer_id01).await; } tp01.unwrap() }); diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 0cd4a6efd4..905039f04f 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -332,7 +332,7 @@ impl TransportPeerEventHandler for SCClient { } } -async fn open_transport( +async fn open_transport_unicast( client_endpoints: &[EndPoint], server_endpoints: &[EndPoint], ) -> ( @@ -375,10 +375,13 @@ async fn open_transport( // Open transport -> This should be accepted for e in client_endpoints.iter() { println!("Opening transport with {}", e); - let _ = ztimeout!(client_manager.open_transport(e.clone())).unwrap(); + let _ = ztimeout!(client_manager.open_transport_unicast(e.clone())).unwrap(); } - let client_transport = client_manager.get_transport(&router_id).unwrap(); + let client_transport = client_manager + .get_transport_unicast(&router_id) + .await + .unwrap(); // Return the handlers ( @@ -404,7 +407,7 @@ async fn close_transport( ztimeout!(client_transport.close()).unwrap(); ztimeout!(async { - while !router_manager.get_transports().is_empty() { + while !router_manager.get_transports_unicast().await.is_empty() { task::sleep(SLEEP).await; } }); @@ -504,7 +507,7 @@ async fn run_single( #[allow(unused_variables)] // Used when stats feature is enabled let (router_manager, router_handler, client_manager, client_transport) = - open_transport(client_endpoints, server_endpoints).await; + open_transport_unicast(client_endpoints, server_endpoints).await; test_transport( router_handler.clone(), diff --git a/zenoh/src/admin.rs b/zenoh/src/admin.rs index 2431a2449d..a39cc79f45 100644 --- a/zenoh/src/admin.rs +++ b/zenoh/src/admin.rs @@ -1,9 +1,3 @@ -use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, - sync::Arc, -}; - // // Copyright (c) 2023 ZettaScale Technology // @@ -23,6 +17,12 @@ use crate::{ queryable::Query, Sample, Session, ZResult, }; +use async_std::task; +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, + sync::Arc, +}; use zenoh_core::SyncResolve; use zenoh_protocol::{ core::{Encoding, KnownEncoding, WireExpr}, @@ -92,12 +92,12 @@ pub(crate) fn on_admin_query(session: &Session, query: Query) { } if let Ok(own_zid) = keyexpr::new(&session.zid().to_string()) { - for transport in session.runtime.manager().get_transports() { + for transport in task::block_on(session.runtime.manager().get_transports_unicast()) { if let Ok(peer) = transport.get_peer() { reply_peer(own_zid, &query, peer); } } - for transport in session.runtime.manager().get_transports_multicast() { + for transport in task::block_on(session.runtime.manager().get_transports_multicast()) { for peer in transport.get_peers().unwrap_or_default() { reply_peer(own_zid, &query, peer); } diff --git a/zenoh/src/info.rs b/zenoh/src/info.rs index ea54f1f4a7..b8b3d0bd88 100644 --- a/zenoh/src/info.rs +++ b/zenoh/src/info.rs @@ -14,6 +14,7 @@ //! Tools to access information about the current zenoh [`Session`](crate::Session). use crate::SessionRef; +use async_std::task; use std::future::Ready; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; use zenoh_protocol::core::{WhatAmI, ZenohId}; @@ -77,10 +78,7 @@ impl<'a> Resolvable for RoutersZidBuilder<'a> { impl<'a> SyncResolve for RoutersZidBuilder<'a> { fn res_sync(self) -> Self::To { Box::new( - self.session - .runtime - .manager() - .get_transports() + task::block_on(self.session.runtime.manager().get_transports_unicast()) .into_iter() .filter_map(|s| { s.get_whatami() @@ -125,10 +123,7 @@ impl<'a> Resolvable for PeersZidBuilder<'a> { impl<'a> SyncResolve for PeersZidBuilder<'a> { fn res_sync(self) -> ::To { Box::new( - self.session - .runtime - .manager() - .get_transports() + task::block_on(self.session.runtime.manager().get_transports_unicast()) .into_iter() .filter_map(|s| { s.get_whatami() diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index f2b3fa3488..2cdea8629a 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -15,6 +15,7 @@ use crate::net::codec::Zenoh080Routing; use crate::net::protocol::linkstate::{LinkState, LinkStateList}; use crate::net::protocol::OAM_LINKSTATE; use crate::net::runtime::Runtime; +use async_std::task; use petgraph::graph::NodeIndex; use petgraph::visit::{IntoNodeReferences, VisitMap, Visitable}; use std::convert::TryInto; @@ -493,7 +494,8 @@ impl Network { if !self.autoconnect.is_empty() { // Connect discovered peers - if self.runtime.manager().get_transport(&zid).is_none() + if task::block_on(self.runtime.manager().get_transport_unicast(&zid)) + .is_none() && self.autoconnect.matches(whatami) { if let Some(locators) = locators { @@ -611,7 +613,8 @@ impl Network { for (_, idx, _) in &link_states { let node = &self.graph[*idx]; if let Some(whatami) = node.whatami { - if self.runtime.manager().get_transport(&node.zid).is_none() + if task::block_on(self.runtime.manager().get_transport_unicast(&node.zid)) + .is_none() && self.autoconnect.matches(whatami) { if let Some(locators) = &node.locators { diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 2138a2b3a4..f4482534db 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -413,7 +413,7 @@ fn router_data(context: &AdminContext, query: Query) { let locators: Vec = transport_mgr .get_locators() .iter() - .map(|locator| json!(locator.to_string())) + .map(|locator| json!(locator.as_str())) .collect(); // transports info @@ -442,8 +442,7 @@ fn router_data(context: &AdminContext, query: Query) { } json }; - let transports: Vec = transport_mgr - .get_transports() + let transports: Vec = task::block_on(transport_mgr.get_transports_unicast()) .iter() .map(transport_to_json) .collect(); diff --git a/zenoh/src/net/runtime/orchestrator.rs b/zenoh/src/net/runtime/orchestrator.rs index 0673aaedc2..9f64ac9259 100644 --- a/zenoh/src/net/runtime/orchestrator.rs +++ b/zenoh/src/net/runtime/orchestrator.rs @@ -14,6 +14,7 @@ use super::{Runtime, RuntimeSession}; use async_std::net::UdpSocket; use async_std::prelude::FutureExt; +use async_std::task; use futures::prelude::*; use socket2::{Domain, Socket, Type}; use std::net::{IpAddr, Ipv6Addr, SocketAddr}; @@ -93,7 +94,7 @@ impl Runtime { for locator in &peers { match self .manager() - .open_transport(locator.clone()) + .open_transport_unicast(locator.clone()) .timeout(CONNECTION_TIMEOUT) .await { @@ -245,7 +246,7 @@ impl Runtime { pub(crate) async fn update_peers(&self) -> ZResult<()> { let peers = { self.config.lock().connect().endpoints().clone() }; - let tranports = self.manager().get_transports(); + let tranports = task::block_on(self.manager().get_transports_unicast()); if self.whatami == WhatAmI::Client { for transport in tranports { @@ -501,7 +502,7 @@ impl Runtime { } else { match self .manager() - .open_transport(endpoint) + .open_transport_unicast(endpoint) .timeout(CONNECTION_TIMEOUT) .await { @@ -642,7 +643,7 @@ impl Runtime { let endpoint = locator.clone().into(); match self .manager() - .open_transport(endpoint) + .open_transport_unicast(endpoint) .timeout(CONNECTION_TIMEOUT) .await { @@ -656,7 +657,7 @@ impl Runtime { pub async fn connect_peer(&self, zid: &ZenohId, locators: &[Locator]) { if zid != &self.manager().zid() { - if self.manager().get_transport(zid).is_none() { + if task::block_on(self.manager().get_transport_unicast(zid)).is_none() { log::debug!("Try to connect to peer {} via any of {:?}", zid, locators); if let Some(transport) = self.connect(locators).await { log::debug!( diff --git a/zenoh/tests/session.rs b/zenoh/tests/session.rs index 23b84e2309..3e9a9c84eb 100644 --- a/zenoh/tests/session.rs +++ b/zenoh/tests/session.rs @@ -31,7 +31,7 @@ macro_rules! ztimeout { }; } -async fn open_session(endpoints: &[&str]) -> (Session, Session) { +async fn open_session_unicast(endpoints: &[&str]) -> (Session, Session) { // Open the sessions let mut config = config::peer(); config.listen.endpoints = endpoints @@ -39,7 +39,7 @@ async fn open_session(endpoints: &[&str]) -> (Session, Session) { .map(|e| e.parse().unwrap()) .collect::>(); config.scouting.multicast.set_enabled(Some(false)).unwrap(); - println!("[ ][01a] Opening peer01 session"); + println!("[ ][01a] Opening peer01 session: {:?}", endpoints); let peer01 = ztimeout!(zenoh::open(config).res_async()).unwrap(); let mut config = config::peer(); @@ -48,7 +48,24 @@ async fn open_session(endpoints: &[&str]) -> (Session, Session) { .map(|e| e.parse().unwrap()) .collect::>(); config.scouting.multicast.set_enabled(Some(false)).unwrap(); - println!("[ ][02a] Opening peer02 session"); + println!("[ ][02a] Opening peer02 session: {:?}", endpoints); + let peer02 = ztimeout!(zenoh::open(config).res_async()).unwrap(); + + (peer01, peer02) +} + +async fn open_session_multicast(endpoint01: &str, endpoint02: &str) -> (Session, Session) { + // Open the sessions + let mut config = config::peer(); + config.connect.endpoints = vec![endpoint01.parse().unwrap()]; + config.scouting.multicast.set_enabled(Some(true)).unwrap(); + println!("[ ][01a] Opening peer01 session: {}", endpoint01); + let peer01 = ztimeout!(zenoh::open(config).res_async()).unwrap(); + + let mut config = config::peer(); + config.connect.endpoints = vec![endpoint02.parse().unwrap()]; + config.scouting.multicast.set_enabled(Some(true)).unwrap(); + println!("[ ][02a] Opening peer02 session: {}", endpoint02); let peer02 = ztimeout!(zenoh::open(config).res_async()).unwrap(); (peer01, peer02) @@ -61,9 +78,12 @@ async fn close_session(peer01: Session, peer02: Session) { ztimeout!(peer02.close().res_async()).unwrap(); } -async fn test_session_pubsub(peer01: &Session, peer02: &Session) { +async fn test_session_pubsub(peer01: &Session, peer02: &Session, reliability: Reliability) { let key_expr = "test/session"; - + let msg_count = match reliability { + Reliability::Reliable => MSG_COUNT, + Reliability::BestEffort => 1, + }; let msgs = Arc::new(AtomicUsize::new(0)); for size in MSG_SIZE { @@ -76,7 +96,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { .declare_subscriber(key_expr) .callback(move |sample| { assert_eq!(sample.value.payload.len(), size); - c_msgs.fetch_add(1, Ordering::SeqCst); + c_msgs.fetch_add(1, Ordering::Relaxed); }) .res_async()) .unwrap(); @@ -86,7 +106,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { // Put data println!("[PS][02b] Putting on peer02 session. {MSG_COUNT} msgs of {size} bytes."); - for _ in 0..MSG_COUNT { + for _ in 0..msg_count { ztimeout!(peer02 .put(key_expr, vec![0u8; size]) .congestion_control(CongestionControl::Block) @@ -96,9 +116,9 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { ztimeout!(async { loop { - let cnt = msgs.load(Ordering::SeqCst); - println!("[PS][03b] Received {cnt}/{MSG_COUNT}."); - if cnt < MSG_COUNT { + let cnt = msgs.load(Ordering::Relaxed); + println!("[PS][03b] Received {cnt}/{msg_count}."); + if cnt < msg_count { task::sleep(SLEEP).await; } else { break; @@ -114,13 +134,16 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session) { } } -async fn test_session_qryrep(peer01: &Session, peer02: &Session) { +async fn test_session_qryrep(peer01: &Session, peer02: &Session, reliability: Reliability) { let key_expr = "test/session"; - + let msg_count = match reliability { + Reliability::Reliable => MSG_COUNT, + Reliability::BestEffort => 1, + }; let msgs = Arc::new(AtomicUsize::new(0)); for size in MSG_SIZE { - msgs.store(0, Ordering::SeqCst); + msgs.store(0, Ordering::Relaxed); // Queryable to data println!("[QR][01c] Queryable on peer01 session"); @@ -128,7 +151,7 @@ async fn test_session_qryrep(peer01: &Session, peer02: &Session) { let qbl = ztimeout!(peer01 .declare_queryable(key_expr) .callback(move |sample| { - c_msgs.fetch_add(1, Ordering::SeqCst); + c_msgs.fetch_add(1, Ordering::Relaxed); let rep = Sample::try_from(key_expr, vec![0u8; size]).unwrap(); task::block_on(async { ztimeout!(sample.reply(Ok(rep)).res_async()).unwrap() }); }) @@ -139,18 +162,18 @@ async fn test_session_qryrep(peer01: &Session, peer02: &Session) { task::sleep(SLEEP).await; // Get data - println!("[QR][02c] Getting on peer02 session. {MSG_COUNT} msgs."); + println!("[QR][02c] Getting on peer02 session. {msg_count} msgs."); let mut cnt = 0; - for _ in 0..MSG_COUNT { + for _ in 0..msg_count { let rs = ztimeout!(peer02.get(key_expr).res_async()).unwrap(); while let Ok(s) = ztimeout!(rs.recv_async()) { assert_eq!(s.sample.unwrap().value.payload.len(), size); cnt += 1; } } - println!("[QR][02c] Got on peer02 session. {cnt}/{MSG_COUNT} msgs."); - assert_eq!(msgs.load(Ordering::SeqCst), MSG_COUNT); - assert_eq!(cnt, MSG_COUNT); + println!("[QR][02c] Got on peer02 session. {cnt}/{msg_count} msgs."); + assert_eq!(msgs.load(Ordering::Relaxed), msg_count); + assert_eq!(cnt, msg_count); println!("[PS][03c] Unqueryable on peer01 session"); ztimeout!(qbl.undeclare().res_async()).unwrap(); @@ -161,14 +184,27 @@ async fn test_session_qryrep(peer01: &Session, peer02: &Session) { } #[test] -fn zenoh_session() { +fn zenoh_session_unicast() { + task::block_on(async { + zasync_executor_init!(); + let _ = env_logger::try_init(); + + let (peer01, peer02) = open_session_unicast(&["tcp/127.0.0.1:17447"]).await; + test_session_pubsub(&peer01, &peer02, Reliability::Reliable).await; + test_session_qryrep(&peer01, &peer02, Reliability::Reliable).await; + close_session(peer01, peer02).await; + }); +} + +#[test] +fn zenoh_session_multicast() { task::block_on(async { zasync_executor_init!(); let _ = env_logger::try_init(); - let (peer01, peer02) = open_session(&["tcp/127.0.0.1:17447"]).await; - test_session_pubsub(&peer01, &peer02).await; - test_session_qryrep(&peer01, &peer02).await; + let (peer01, peer02) = + open_session_multicast("udp/224.0.0.1:17448", "udp/224.0.0.1:17449").await; + test_session_pubsub(&peer01, &peer02, Reliability::BestEffort).await; close_session(peer01, peer02).await; }); } From 2c4f676d6c44a49829a276e9b5f9088b5daf2615 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 8 Aug 2023 16:31:35 +0200 Subject: [PATCH 181/203] Impl Debug for EndPoint and Locator --- commons/zenoh-protocol/src/core/endpoint.rs | 73 ++++++++++++++++++--- commons/zenoh-protocol/src/core/locator.rs | 8 ++- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/commons/zenoh-protocol/src/core/endpoint.rs b/commons/zenoh-protocol/src/core/endpoint.rs index 81c3ff72c6..316e007476 100644 --- a/commons/zenoh-protocol/src/core/endpoint.rs +++ b/commons/zenoh-protocol/src/core/endpoint.rs @@ -125,7 +125,7 @@ impl Parameters { // Protocol #[repr(transparent)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Protocol<'a>(pub(super) &'a str); impl<'a> Protocol<'a> { @@ -146,8 +146,14 @@ impl fmt::Display for Protocol<'_> { } } +impl fmt::Debug for Protocol<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + #[repr(transparent)] -#[derive(Debug, PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash)] pub struct ProtocolMut<'a>(&'a mut EndPoint); impl<'a> ProtocolMut<'a> { @@ -175,9 +181,15 @@ impl fmt::Display for ProtocolMut<'_> { } } +impl fmt::Debug for ProtocolMut<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + // Address #[repr(transparent)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Address<'a>(pub(super) &'a str); impl<'a> Address<'a> { @@ -198,8 +210,14 @@ impl fmt::Display for Address<'_> { } } +impl fmt::Debug for Address<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + #[repr(transparent)] -#[derive(Debug, PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash)] pub struct AddressMut<'a>(&'a mut EndPoint); impl<'a> AddressMut<'a> { @@ -227,9 +245,15 @@ impl fmt::Display for AddressMut<'_> { } } +impl fmt::Debug for AddressMut<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + // Metadata #[repr(transparent)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Metadata<'a>(pub(super) &'a str); impl<'a> Metadata<'a> { @@ -262,8 +286,14 @@ impl fmt::Display for Metadata<'_> { } } +impl fmt::Debug for Metadata<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + #[repr(transparent)] -#[derive(Debug, PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash)] pub struct MetadataMut<'a>(&'a mut EndPoint); impl<'a> MetadataMut<'a> { @@ -328,9 +358,15 @@ impl fmt::Display for MetadataMut<'_> { } } +impl fmt::Debug for MetadataMut<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + // Config #[repr(transparent)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Config<'a>(pub(super) &'a str); impl<'a> Config<'a> { @@ -363,8 +399,14 @@ impl fmt::Display for Config<'_> { } } +impl fmt::Debug for Config<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + #[repr(transparent)] -#[derive(Debug, PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash)] pub struct ConfigMut<'a>(&'a mut EndPoint); impl<'a> ConfigMut<'a> { @@ -428,8 +470,15 @@ impl fmt::Display for ConfigMut<'_> { f.write_str(self.as_str()) } } + +impl fmt::Debug for ConfigMut<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + /// A `String` that respects the [`EndPoint`] canon form: `#`, such that `` is a valid [`Locator`] `` is of the form `=;...;=` where keys are alphabetically sorted. -#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] #[serde(into = "String")] #[serde(try_from = "String")] pub struct EndPoint { @@ -528,6 +577,12 @@ impl fmt::Display for EndPoint { } } +impl fmt::Debug for EndPoint { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + impl From for String { fn from(v: EndPoint) -> String { v.inner diff --git a/commons/zenoh-protocol/src/core/locator.rs b/commons/zenoh-protocol/src/core/locator.rs index db250ba991..cdd3dfa64c 100644 --- a/commons/zenoh-protocol/src/core/locator.rs +++ b/commons/zenoh-protocol/src/core/locator.rs @@ -19,7 +19,7 @@ use zenoh_result::{Error as ZError, ZResult}; // Locator /// A `String` that respects the [`Locator`] canon form: `/

[?]`, /// such that `` is of the form `=;...;=` where keys are alphabetically sorted. -#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] #[serde(into = "String")] #[serde(try_from = "String")] pub struct Locator(pub(super) EndPoint); @@ -110,6 +110,12 @@ impl fmt::Display for Locator { } } +impl fmt::Debug for Locator { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } +} + impl Locator { #[cfg(feature = "test")] pub fn rand() -> Self { From 9763417dfe501892630f27e73ca513fd9eca0bbb Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 8 Aug 2023 16:39:13 +0200 Subject: [PATCH 182/203] Open multicast transport on scouting --- DEFAULT_CONFIG.json5 | 15 +-- io/zenoh-transport/src/multicast/manager.rs | 44 +++++-- .../tests/multicast_transport.rs | 38 +++--- zenoh/src/net/runtime/orchestrator.rs | 110 ++++++++++++------ 4 files changed, 132 insertions(+), 75 deletions(-) diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index d36647c02d..e76fa6f475 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -110,11 +110,6 @@ /// Configure internal transport parameters transport: { - // /// An optional whitelist of protocols to be used for accepting and opening sessions. - // /// If not configured, all the supported protocols are automatically whitelisted. - // /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] - // /// For example, to only enable "tls" and "quic": - // protocols: ["tls", "quic"], unicast: { /// Timeout in milliseconds when opening a link accept_timeout: 10000, @@ -128,11 +123,11 @@ qos: { enabled: true, }, - link: { - // /// An optional whitelist of protocols to be used for accepting and opening sessions. - // /// If not configured, all the supported protocols are automatically whitelisted. - // /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] - // /// For example, to only enable "tls" and "quic": + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": // protocols: ["tls", "quic"], /// Configure the zenoh TX parameters of a link tx: { diff --git a/io/zenoh-transport/src/multicast/manager.rs b/io/zenoh-transport/src/multicast/manager.rs index e84e45d15d..5d996d25ad 100644 --- a/io/zenoh-transport/src/multicast/manager.rs +++ b/io/zenoh-transport/src/multicast/manager.rs @@ -24,6 +24,7 @@ use zenoh_config::SharedMemoryConf; use zenoh_config::{Config, LinkTxConf}; use zenoh_core::zasynclock; use zenoh_link::*; +use zenoh_protocol::core::ZenohId; use zenoh_protocol::{core::endpoint, transport::close}; use zenoh_result::{bail, zerror, ZResult}; @@ -255,10 +256,13 @@ impl TransportManager { super::establishment::open_link(self, link).await } - pub async fn get_transport_multicast(&self, locator: &Locator) -> Option { - zasynclock!(self.state.multicast.transports) - .get(locator) - .map(|t| t.into()) + pub async fn get_transport_multicast(&self, zid: &ZenohId) -> Option { + for t in zasynclock!(self.state.multicast.transports).values() { + if t.get_peers().iter().any(|p| p.zid == *zid) { + return Some(t.into()); + } + } + None } pub async fn get_transports_multicast(&self) -> Vec { @@ -291,19 +295,39 @@ impl TransportManager { /*************************************/ /* LISTENER */ /*************************************/ - const ERR: &str = - "Listeners are not supperted on multicast endpoints. This may be caused by a wrong configuration: use `connect.endpoints` instead of `listen.endpoints` for"; pub async fn add_listener_multicast(&self, endpoint: EndPoint) -> ZResult { - bail!("{}: {}", Self::ERR, endpoint) + let locator = endpoint.to_locator().to_owned(); + self.open_transport_multicast(endpoint).await?; + Ok(locator) } pub async fn del_listener_multicast(&self, endpoint: &EndPoint) -> ZResult<()> { - bail!("{}: {}", Self::ERR, endpoint) + let locator = endpoint.to_locator(); + + let mut guard = zasynclock!(self.state.multicast.transports); + let res = guard.remove(&locator); + + if !guard + .iter() + .any(|(l, _)| l.protocol() == locator.protocol()) + { + let _ = self + .del_link_manager_multicast(locator.protocol().as_str()) + .await; + } + + res.map(|_| ()).ok_or_else(|| { + let e = zerror!("Can not delete the transport for locator: {}", locator); + log::trace!("{}", e); + e.into() + }) } pub async fn get_listeners_multicast(&self) -> Vec { - // Multicast has no listeners, only locators - vec![] + zasynclock!(self.state.multicast.transports) + .values() + .map(|t| t.locator.clone().into()) + .collect() } pub async fn get_locators_multicast(&self) -> Vec { diff --git a/io/zenoh-transport/tests/multicast_transport.rs b/io/zenoh-transport/tests/multicast_transport.rs index a27cf2a355..e9f3fbdd63 100644 --- a/io/zenoh-transport/tests/multicast_transport.rs +++ b/io/zenoh-transport/tests/multicast_transport.rs @@ -171,44 +171,46 @@ mod tests { // Open transport -> This should be accepted println!("Opening transport with {endpoint}"); let _ = ztimeout!(peer01_manager.open_transport_multicast(endpoint.clone())).unwrap(); - assert!(peer01_manager - .get_transport_multicast(&endpoint.to_locator()) - .await - .is_some()); + assert!(!peer01_manager.get_transports_multicast().await.is_empty()); println!("\t{:?}", peer01_manager.get_transports_multicast().await); println!("Opening transport with {endpoint}"); let _ = ztimeout!(peer02_manager.open_transport_multicast(endpoint.clone())).unwrap(); - assert!(peer02_manager - .get_transport_multicast(&endpoint.to_locator()) - .await - .is_some()); + assert!(!peer02_manager.get_transports_multicast().await.is_empty()); println!("\t{:?}", peer02_manager.get_transports_multicast().await); // Wait to for peer 01 and 02 to join each other - let peer01_transport = peer01_manager - .get_transport_multicast(&endpoint.to_locator()) - .await - .unwrap(); ztimeout!(async { - while peer01_transport.get_peers().unwrap().is_empty() { + while peer01_manager + .get_transport_multicast(&peer02_id) + .await + .is_none() + { task::sleep(SLEEP_COUNT).await; } }); + let peer01_transport = peer01_manager + .get_transport_multicast(&peer02_id) + .await + .unwrap(); println!( "\tPeer01 peers: {:?}", peer01_transport.get_peers().unwrap() ); - let peer02_transport = peer02_manager - .get_transport_multicast(&endpoint.to_locator()) - .await - .unwrap(); ztimeout!(async { - while peer02_transport.get_peers().unwrap().is_empty() { + while peer02_manager + .get_transport_multicast(&peer01_id) + .await + .is_none() + { task::sleep(SLEEP_COUNT).await; } }); + let peer02_transport = peer02_manager + .get_transport_multicast(&peer01_id) + .await + .unwrap(); println!( "\tPeer02 peers: {:?}", peer02_transport.get_peers().unwrap() diff --git a/zenoh/src/net/runtime/orchestrator.rs b/zenoh/src/net/runtime/orchestrator.rs index 9f64ac9259..3aef55b4fe 100644 --- a/zenoh/src/net/runtime/orchestrator.rs +++ b/zenoh/src/net/runtime/orchestrator.rs @@ -14,7 +14,6 @@ use super::{Runtime, RuntimeSession}; use async_std::net::UdpSocket; use async_std::prelude::FutureExt; -use async_std::task; use futures::prelude::*; use socket2::{Domain, Socket, Type}; use std::net::{IpAddr, Ipv6Addr, SocketAddr}; @@ -29,7 +28,6 @@ use zenoh_protocol::{ scouting::{Hello, Scout, ScoutingBody, ScoutingMessage}, }; use zenoh_result::{bail, zerror, ZResult}; -use zenoh_transport::TransportUnicast; const RCV_BUF_SIZE: usize = u16::MAX as usize; const SCOUT_INITIAL_PERIOD: Duration = Duration::from_millis(1_000); @@ -246,7 +244,7 @@ impl Runtime { pub(crate) async fn update_peers(&self) -> ZResult<()> { let peers = { self.config.lock().connect().endpoints().clone() }; - let tranports = task::block_on(self.manager().get_transports_unicast()); + let tranports = self.manager().get_transports_unicast().await; if self.whatami == WhatAmI::Client { for transport in tranports { @@ -638,40 +636,84 @@ impl Runtime { async_std::prelude::FutureExt::race(send, recvs).await; } - async fn connect(&self, locators: &[Locator]) -> Option { + #[must_use] + async fn connect(&self, zid: &ZenohId, locators: &[Locator]) -> bool { + const ERR: &str = "Unable to connect to newly scouted peer "; + + let inspector = LocatorInspector::default(); for locator in locators { - let endpoint = locator.clone().into(); - match self - .manager() - .open_transport_unicast(endpoint) - .timeout(CONNECTION_TIMEOUT) - .await - { - Ok(Ok(transport)) => return Some(transport), - Ok(Err(e)) => log::trace!("Unable to connect to {}! {}", locator, e), - Err(e) => log::trace!("Unable to connect to {}! {}", locator, e), + let is_multicast = match inspector.is_multicast(locator).await { + Ok(im) => im, + Err(e) => { + log::trace!("{} {} on {}: {}", ERR, zid, locator, e); + continue; + } + }; + + let endpoint = locator.to_owned().into(); + let manager = self.manager(); + if is_multicast { + match manager + .open_transport_multicast(endpoint) + .timeout(CONNECTION_TIMEOUT) + .await + { + Ok(Ok(transport)) => { + log::debug!( + "Successfully connected to newly scouted peer: {:?}", + transport + ); + return true; + } + Ok(Err(e)) => log::trace!("{} {} on {}: {}", ERR, zid, locator, e), + Err(e) => log::trace!("{} {} on {}: {}", ERR, zid, locator, e), + } + } else { + match manager + .open_transport_unicast(endpoint) + .timeout(CONNECTION_TIMEOUT) + .await + { + Ok(Ok(transport)) => { + log::debug!( + "Successfully connected to newly scouted peer: {:?}", + transport + ); + return true; + } + Ok(Err(e)) => log::trace!("{} {} on {}: {}", ERR, zid, locator, e), + Err(e) => log::trace!("{} {} on {}: {}", ERR, zid, locator, e), + } } } - None + + log::warn!( + "Unable to connect to any locator of scouted peer {}: {:?}", + zid, + locators + ); + false } pub async fn connect_peer(&self, zid: &ZenohId, locators: &[Locator]) { - if zid != &self.manager().zid() { - if task::block_on(self.manager().get_transport_unicast(zid)).is_none() { - log::debug!("Try to connect to peer {} via any of {:?}", zid, locators); - if let Some(transport) = self.connect(locators).await { - log::debug!( - "Successfully connected to newly scouted peer {} via {:?}", - zid, - transport - ); - } else { - log::warn!( - "Unable to connect any locator of scouted peer {}: {:?}", - zid, - locators - ); + let manager = self.manager(); + if zid != &manager.zid() { + let has_unicast = manager.get_transport_unicast(zid).await.is_some(); + let has_multicast = { + let mut hm = manager.get_transport_multicast(zid).await.is_some(); + for t in manager.get_transports_multicast().await { + if let Ok(l) = t.get_link() { + if let Some(g) = l.group.as_ref() { + hm |= locators.iter().any(|l| l == g); + } + } } + hm + }; + + if !has_unicast && !has_multicast { + log::debug!("Try to connect to peer {} via any of {:?}", zid, locators); + let _ = self.connect(zid, locators).await; } else { log::trace!("Already connected scouted peer: {}", zid); } @@ -689,15 +731,9 @@ impl Runtime { Runtime::scout(sockets, what, addr, move |hello| async move { log::info!("Found {:?}", hello); if !hello.locators.is_empty() { - if let Some(transport) = self.connect(&hello.locators).await { - log::debug!( - "Successfully connected to newly scouted {:?} via {:?}", - hello, - transport - ); + if self.connect(&hello.zid, &hello.locators).await { return Loop::Break; } - log::warn!("Unable to connect to scouted {:?}", hello); } else { log::warn!("Received Hello with no locators: {:?}", hello); } From 29be5cb739844a4f6ec51f505d5aad594c9a2a3c Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 9 Aug 2023 17:56:58 +0200 Subject: [PATCH 183/203] Set default multicast batch size to 8192 --- commons/zenoh-codec/src/transport/init.rs | 10 ++++---- commons/zenoh-codec/src/transport/join.rs | 6 ++--- commons/zenoh-protocol/src/transport/init.rs | 2 +- commons/zenoh-protocol/src/transport/join.rs | 4 +-- commons/zenoh-protocol/src/transport/mod.rs | 7 ++++++ io/zenoh-transport/src/multicast/link.rs | 6 +++-- io/zenoh-transport/src/multicast/rx.rs | 25 ++++++++++++++++--- io/zenoh-transport/src/multicast/transport.rs | 23 ++++++++++++++--- .../src/unicast/establishment/accept.rs | 7 +++++- .../src/unicast/establishment/mod.rs | 4 +-- .../src/unicast/establishment/open.rs | 5 ++-- 11 files changed, 73 insertions(+), 26 deletions(-) diff --git a/commons/zenoh-codec/src/transport/init.rs b/commons/zenoh-codec/src/transport/init.rs index e61676d062..2f5dae25c9 100644 --- a/commons/zenoh-codec/src/transport/init.rs +++ b/commons/zenoh-codec/src/transport/init.rs @@ -23,7 +23,7 @@ use zenoh_protocol::{ common::{iext, imsg}, core::{Resolution, WhatAmI, ZenohId}, transport::{ - id, + batch_size, id, init::{ext, flag, InitAck, InitSyn}, BatchSize, }, @@ -39,7 +39,7 @@ where fn write(self, writer: &mut W, x: &InitSyn) -> Self::Output { // Header let mut header = id::INIT; - if x.resolution != Resolution::default() || x.batch_size != BatchSize::MAX { + if x.resolution != Resolution::default() || x.batch_size != batch_size::UNICAST { header |= flag::S; } let mut n_exts = (x.ext_qos.is_some() as u8) @@ -131,7 +131,7 @@ where let zid: ZenohId = lodec.read(&mut *reader)?; let mut resolution = Resolution::default(); - let mut batch_size = BatchSize::MAX.to_le_bytes(); + let mut batch_size = batch_size::UNICAST.to_le_bytes(); if imsg::has_flag(self.header, flag::S) { let flags: u8 = self.codec.read(&mut *reader)?; resolution = Resolution::from(flags & 0b00111111); @@ -200,7 +200,7 @@ where fn write(self, writer: &mut W, x: &InitAck) -> Self::Output { // Header let mut header = id::INIT | flag::A; - if x.resolution != Resolution::default() || x.batch_size != BatchSize::MAX { + if x.resolution != Resolution::default() || x.batch_size != batch_size::UNICAST { header |= flag::S; } let mut n_exts = (x.ext_qos.is_some() as u8) @@ -295,7 +295,7 @@ where let zid: ZenohId = lodec.read(&mut *reader)?; let mut resolution = Resolution::default(); - let mut batch_size = BatchSize::MAX.to_le_bytes(); + let mut batch_size = batch_size::UNICAST.to_le_bytes(); if imsg::has_flag(self.header, flag::S) { let flags: u8 = self.codec.read(&mut *reader)?; resolution = Resolution::from(flags & 0b00111111); diff --git a/commons/zenoh-codec/src/transport/join.rs b/commons/zenoh-codec/src/transport/join.rs index ac7d8efbd8..9f8a5bb3f6 100644 --- a/commons/zenoh-codec/src/transport/join.rs +++ b/commons/zenoh-codec/src/transport/join.rs @@ -22,7 +22,7 @@ use zenoh_protocol::{ common::{iext, imsg, ZExtZBufHeader}, core::{Priority, Resolution, WhatAmI, ZenohId}, transport::{ - id, + batch_size, id, join::{ext, flag, Join}, BatchSize, PrioritySn, TransportSn, }, @@ -134,7 +134,7 @@ where if x.lease.as_millis() % 1_000 == 0 { header |= flag::T; } - if x.resolution != Resolution::default() || x.batch_size != BatchSize::MAX { + if x.resolution != Resolution::default() || x.batch_size != batch_size::MULTICAST { header |= flag::S; } let mut n_exts = (x.ext_qos.is_some() as u8) + (x.ext_shm.is_some() as u8); @@ -222,7 +222,7 @@ where let zid: ZenohId = lodec.read(&mut *reader)?; let mut resolution = Resolution::default(); - let mut batch_size = BatchSize::MAX.to_le_bytes(); + let mut batch_size = batch_size::MULTICAST.to_le_bytes(); if imsg::has_flag(self.header, flag::S) { let flags: u8 = self.codec.read(&mut *reader)?; resolution = Resolution::from(flags & 0b00111111); diff --git a/commons/zenoh-protocol/src/transport/init.rs b/commons/zenoh-protocol/src/transport/init.rs index 277917a68f..566b6c91b1 100644 --- a/commons/zenoh-protocol/src/transport/init.rs +++ b/commons/zenoh-protocol/src/transport/init.rs @@ -90,7 +90,7 @@ use zenoh_buffers::ZSlice; /// - 0b11: 64 bits /// /// ($) Batch Size. It indicates the maximum size of a batch the sender of the INIT message is willing -/// to accept when reading from the network. +/// to accept when reading from the network. Default on unicast: 65535. /// /// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length /// in bytes of the message, resulting in the maximum length of a message being 65535 bytes. diff --git a/commons/zenoh-protocol/src/transport/join.rs b/commons/zenoh-protocol/src/transport/join.rs index ea06d3ba4a..00920c17ee 100644 --- a/commons/zenoh-protocol/src/transport/join.rs +++ b/commons/zenoh-protocol/src/transport/join.rs @@ -87,8 +87,8 @@ use core::time::Duration; /// - 0b10: 32 bits /// - 0b11: 64 bits /// -/// ($) Batch Size. It indicates the maximum size of a batch the sender of the INIT message is willing -/// to accept when reading from the network. +/// ($) Batch Size. It indicates the maximum size of a batch the sender of the JOIN message is willing +/// to accept when reading from the network. Default on multicast: 8192. /// /// (^) The next sequence number MUST be compatible with the adverstised Sequence Number resolution /// ``` diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index a02b1a7a83..61a2bd88b7 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -36,6 +36,13 @@ pub use open::{OpenAck, OpenSyn}; /// In any case, the length of a message must not exceed 65_535 bytes. pub type BatchSize = u16; +pub mod batch_size { + use super::BatchSize; + + pub const UNICAST: BatchSize = BatchSize::MAX; + pub const MULTICAST: BatchSize = 8_192; +} + pub mod id { // WARNING: it's crucial that these IDs do NOT collide with the IDs // defined in `crate::network::id`. diff --git a/io/zenoh-transport/src/multicast/link.rs b/io/zenoh-transport/src/multicast/link.rs index dee6a1e3b8..fe99de9bf0 100644 --- a/io/zenoh-transport/src/multicast/link.rs +++ b/io/zenoh-transport/src/multicast/link.rs @@ -145,7 +145,7 @@ impl TransportLinkMulticast { } } - pub(super) fn start_rx(&mut self) { + pub(super) fn start_rx(&mut self, batch_size: BatchSize) { if self.handle_rx.is_none() { // Spawn the RX task let c_link = self.link.clone(); @@ -160,6 +160,7 @@ impl TransportLinkMulticast { ctransport.clone(), c_signal.clone(), c_rx_buffer_size, + batch_size, ) .await; c_signal.trigger(); @@ -344,6 +345,7 @@ async fn rx_task( transport: TransportMulticastInner, signal: Signal, rx_buffer_size: usize, + batch_size: BatchSize, ) -> ZResult<()> { enum Action { Read((usize, Locator)), @@ -385,7 +387,7 @@ async fn rx_task( // Deserialize all the messages from the current ZBuf let zslice = ZSlice::make(Arc::new(buffer), 0, n) .map_err(|_| zerror!("Read {} bytes but buffer is {} bytes", n, mtu))?; - transport.read_messages(zslice, &link, &loc)?; + transport.read_messages(zslice, &link, batch_size, &loc)?; } Action::Stop => break, } diff --git a/io/zenoh-transport/src/multicast/rx.rs b/io/zenoh-transport/src/multicast/rx.rs index d182e6a593..0a74e7e6f4 100644 --- a/io/zenoh-transport/src/multicast/rx.rs +++ b/io/zenoh-transport/src/multicast/rx.rs @@ -21,7 +21,7 @@ use zenoh_core::{zlock, zread}; use zenoh_link::LinkMulticast; use zenoh_protocol::core::{Priority, Reliability}; use zenoh_protocol::transport::{ - Close, Fragment, Frame, Join, KeepAlive, TransportBody, TransportSn, + BatchSize, Close, Fragment, Frame, Join, KeepAlive, TransportBody, TransportSn, }; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; @@ -100,7 +100,12 @@ impl TransportMulticastInner { Ok(()) } - pub(super) fn handle_join_from_unknown(&self, join: Join, locator: &Locator) -> ZResult<()> { + pub(super) fn handle_join_from_unknown( + &self, + join: Join, + locator: &Locator, + batch_size: BatchSize, + ) -> ZResult<()> { if zread!(self.peers).len() >= self.manager.config.multicast.max_sessions { log::debug!( "Ingoring Join on {} from peer: {}. Max sessions reached: {}.", @@ -124,7 +129,7 @@ impl TransportMulticastInner { if join.resolution != self.manager.config.resolution { log::debug!( - "Ingoring Join on {} from peer: {}. Unsupported SN resolution: {:?}. Expected: <= {:?}.", + "Ingoring Join on {} from peer: {}. Unsupported SN resolution: {:?}. Expected: {:?}.", locator, join.zid, join.resolution, @@ -133,6 +138,17 @@ impl TransportMulticastInner { return Ok(()); } + if join.batch_size != batch_size { + log::debug!( + "Ingoring Join on {} from peer: {}. Unsupported Batch Size: {:?}. Expected: {:?}.", + locator, + join.zid, + join.batch_size, + batch_size, + ); + return Ok(()); + } + if !self.manager.config.multicast.is_qos && join.ext_qos.is_some() { log::debug!( "Ingoring Join on {} from peer: {}. QoS is not supported.", @@ -262,6 +278,7 @@ impl TransportMulticastInner { &self, mut zslice: ZSlice, link: &LinkMulticast, + batch_size: BatchSize, locator: &Locator, ) -> ZResult<()> { let codec = Zenoh080::new(); @@ -305,7 +322,7 @@ impl TransportMulticastInner { None => { drop(r_guard); if let TransportBody::Join(join) = msg.body { - self.handle_join_from_unknown(join, locator)?; + self.handle_join_from_unknown(join, locator, batch_size)?; } } } diff --git a/io/zenoh-transport/src/multicast/transport.rs b/io/zenoh-transport/src/multicast/transport.rs index 06f54e37fc..7173bc677d 100644 --- a/io/zenoh-transport/src/multicast/transport.rs +++ b/io/zenoh-transport/src/multicast/transport.rs @@ -31,7 +31,7 @@ use std::{ use zenoh_core::{zcondfeat, zread, zwrite}; use zenoh_link::{Link, LinkMulticast, Locator}; use zenoh_protocol::core::Resolution; -use zenoh_protocol::transport::{Close, TransportMessage}; +use zenoh_protocol::transport::{batch_size, Close, TransportMessage}; use zenoh_protocol::{ core::{Bits, Field, Priority, WhatAmI, ZenohId}, transport::{close, Join}, @@ -235,7 +235,14 @@ impl TransportMulticastInner { let mut guard = zwrite!(self.link); match guard.as_mut() { Some(l) => { - assert!(!self.priority_tx.is_empty()); + // For cross-system compatibility reasons we set the default minimal + // batch size to 8192 bytes unless explicitly configured smaller. + let batch_size = self + .manager + .config + .batch_size + .min(l.link.get_mtu()) + .min(batch_size::MULTICAST); let config = TransportLinkMulticastConfig { version: self.manager.config.version, zid: self.manager.config.zid, @@ -244,7 +251,7 @@ impl TransportMulticastInner { keep_alive: self.manager.config.multicast.keep_alive, join_interval: self.manager.config.multicast.join_interval, sn_resolution: self.manager.config.resolution.get(Field::FrameSN), - batch_size: self.manager.config.batch_size.min(l.link.get_mtu()), + batch_size, }; l.start_tx(config, self.priority_tx.clone()); Ok(()) @@ -280,7 +287,15 @@ impl TransportMulticastInner { let mut guard = zwrite!(self.link); match guard.as_mut() { Some(l) => { - l.start_rx(); + // For cross-system compatibility reasons we set the default minimal + // batch size to 8192 bytes unless explicitly configured smaller. + let batch_size = self + .manager + .config + .batch_size + .min(l.link.get_mtu()) + .min(batch_size::MULTICAST); + l.start_rx(batch_size); Ok(()) } None => { diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 0b57a9e6b2..86c79099ab 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -32,6 +32,7 @@ use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ core::{Field, Resolution, WhatAmI, ZenohId}, transport::{ + batch_size, close::{self, Close}, BatchSize, InitAck, OpenAck, TransportBody, TransportMessage, TransportSn, }, @@ -174,7 +175,11 @@ impl<'a> AcceptFsm for AcceptLink<'a> { }; // Compute the minimum batch size - state.zenoh.batch_size = state.zenoh.batch_size.min(init_syn.batch_size); + state.zenoh.batch_size = state + .zenoh + .batch_size + .min(init_syn.batch_size) + .min(batch_size::UNICAST); // Extension QoS self.ext_qos diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index 2a91ea638c..6bc8c898e8 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -28,7 +28,7 @@ use std::time::Duration; use zenoh_link::{Link, LinkUnicast}; use zenoh_protocol::{ core::{Field, Resolution, ZenohId}, - transport::{Close, TransportMessage, TransportSn}, + transport::{BatchSize, Close, TransportMessage, TransportSn}, }; use zenoh_result::ZResult; @@ -135,7 +135,7 @@ pub(super) async fn close_link(link: &LinkUnicast, reason: Option) { pub(super) struct InputFinalize { pub(super) transport: TransportUnicast, pub(super) other_lease: Duration, - pub(super) agreed_batch_size: u16, + pub(super) agreed_batch_size: BatchSize, } // Finalize the transport, notify the callback and start the link tasks pub(super) async fn finalize_transport( diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 832d042fec..89bfd12ee8 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -29,7 +29,8 @@ use zenoh_link::{LinkUnicast, LinkUnicastDirection}; use zenoh_protocol::{ core::{Field, Resolution, WhatAmI, ZenohId}, transport::{ - close, BatchSize, Close, InitSyn, OpenSyn, TransportBody, TransportMessage, TransportSn, + batch_size, close, BatchSize, Close, InitSyn, OpenSyn, TransportBody, TransportMessage, + TransportSn, }, }; use zenoh_result::ZResult; @@ -445,7 +446,7 @@ pub(crate) async fn open_link( let mut state = State { zenoh: StateZenoh { - batch_size: manager.config.batch_size, + batch_size: manager.config.batch_size.min(batch_size::UNICAST), resolution: manager.config.resolution, }, ext_qos: ext::qos::StateOpen::new(manager.config.unicast.is_qos), From ec5d09f705e0641b146ea266933f74bcfa81e555 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 10 Aug 2023 18:51:23 +0200 Subject: [PATCH 184/203] Fix join SN codec order (#530) --- commons/zenoh-codec/src/transport/join.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/commons/zenoh-codec/src/transport/join.rs b/commons/zenoh-codec/src/transport/join.rs index 9f8a5bb3f6..197190946a 100644 --- a/commons/zenoh-codec/src/transport/join.rs +++ b/commons/zenoh-codec/src/transport/join.rs @@ -30,7 +30,7 @@ use zenoh_protocol::{ impl LCodec<&PrioritySn> for Zenoh080 { fn w_len(self, p: &PrioritySn) -> usize { - self.w_len(p.best_effort) + self.w_len(p.reliable) + self.w_len(p.reliable) + self.w_len(p.best_effort) } } @@ -41,8 +41,8 @@ where type Output = Result<(), DidntWrite>; fn write(self, writer: &mut W, x: &PrioritySn) -> Self::Output { - self.write(&mut *writer, x.best_effort)?; self.write(&mut *writer, x.reliable)?; + self.write(&mut *writer, x.best_effort)?; Ok(()) } } @@ -54,12 +54,12 @@ where type Error = DidntRead; fn read(self, reader: &mut R) -> Result { - let best_effort: TransportSn = self.read(&mut *reader)?; let reliable: TransportSn = self.read(&mut *reader)?; + let best_effort: TransportSn = self.read(&mut *reader)?; Ok(PrioritySn { - best_effort, reliable, + best_effort, }) } } From fa0bc23f713b8d2c60c50307b20f47a7f5aa1685 Mon Sep 17 00:00:00 2001 From: yellowhatter <104833606+yellowhatter@users.noreply.github.com> Date: Wed, 16 Aug 2023 10:28:45 +0300 Subject: [PATCH 185/203] Zenoh shm link layer and tests (#509) --- .github/workflows/ci.yml | 27 +- .github/workflows/crates_check.sh | 1 - .github/workflows/crates_publish.sh | 1 - Cargo.lock | 652 ++++++++---------- Cargo.toml | 3 +- commons/zenoh-codec/src/network/mod.rs | 25 +- commons/zenoh-codec/src/transport/mod.rs | 42 ++ commons/zenoh-config/src/lib.rs | 4 + commons/zenoh-core/src/macros.rs | 14 + commons/zenoh-protocol/src/network/mod.rs | 2 +- commons/zenoh-protocol/src/network/oam.rs | 6 + commons/zenoh-protocol/src/transport/mod.rs | 16 + examples/Cargo.toml | 10 + examples/examples/z_ping.rs | 13 + examples/examples/z_pong.rs | 12 + examples/examples/z_pub_thr.rs | 13 + examples/examples/z_sub_thr.rs | 12 + io/zenoh-link/Cargo.toml | 2 + io/zenoh-link/src/lib.rs | 24 + io/zenoh-links/zenoh-link-shm/Cargo.toml | 49 ++ io/zenoh-links/zenoh-link-shm/src/lib.rs | 24 + io/zenoh-links/zenoh-link-shm/src/unix/mod.rs | 74 ++ .../zenoh-link-shm/src/unix/unicast.rs | 586 ++++++++++++++++ io/zenoh-transport/Cargo.toml | 3 +- io/zenoh-transport/src/lib.rs | 3 +- io/zenoh-transport/src/primitives/mux.rs | 10 +- .../src/unicast/establishment/accept.rs | 17 +- .../src/unicast/establishment/ext/shm.rs | 2 +- .../src/unicast/establishment/open.rs | 20 +- io/zenoh-transport/src/unicast/manager.rs | 128 +++- io/zenoh-transport/src/unicast/mod.rs | 63 +- .../src/unicast/{ => net}/link.rs | 14 +- io/zenoh-transport/src/unicast/net/mod.rs | 18 + .../src/unicast/{ => net}/reliability.rs | 0 .../src/unicast/{ => net}/rx.rs | 8 +- .../src/unicast/{ => net}/transport.rs | 367 +++++----- .../src/unicast/{ => net}/tx.rs | 8 +- .../{shm.rs => shared_memory_unicast.rs} | 0 io/zenoh-transport/src/unicast/shm/link.rs | 276 ++++++++ io/zenoh-transport/src/unicast/shm/mod.rs | 18 + io/zenoh-transport/src/unicast/shm/rx.rs | 114 +++ .../src/unicast/shm/transport.rs | 306 ++++++++ io/zenoh-transport/src/unicast/shm/tx.rs | 79 +++ .../src/unicast/test_helpers.rs | 50 ++ .../src/unicast/transport_unicast_inner.rs | 87 +++ io/zenoh-transport/tests/endpoints.rs | 18 + .../tests/transport_whitelist.rs | 18 + .../tests/unicast_authenticator.rs | 160 ++++- .../tests/unicast_concurrent.rs | 36 + .../tests/unicast_defragmentation.rs | 41 ++ .../tests/unicast_intermittent.rs | 118 +++- io/zenoh-transport/tests/unicast_multilink.rs | 25 +- io/zenoh-transport/tests/unicast_openclose.rs | 238 +++++-- .../tests/unicast_priorities.rs | 14 + io/zenoh-transport/tests/unicast_shm.rs | 12 + .../tests/unicast_simultaneous.rs | 30 +- io/zenoh-transport/tests/unicast_transport.rs | 349 +++++++++- zenoh/Cargo.toml | 1 + zenoh/src/net/protocol/mod.rs | 2 - zenoh/src/net/routing/network.rs | 6 +- zenoh/src/net/routing/router.rs | 3 +- 61 files changed, 3493 insertions(+), 781 deletions(-) create mode 100644 io/zenoh-links/zenoh-link-shm/Cargo.toml create mode 100644 io/zenoh-links/zenoh-link-shm/src/lib.rs create mode 100644 io/zenoh-links/zenoh-link-shm/src/unix/mod.rs create mode 100644 io/zenoh-links/zenoh-link-shm/src/unix/unicast.rs rename io/zenoh-transport/src/unicast/{ => net}/link.rs (98%) create mode 100644 io/zenoh-transport/src/unicast/net/mod.rs rename io/zenoh-transport/src/unicast/{ => net}/reliability.rs (100%) rename io/zenoh-transport/src/unicast/{ => net}/rx.rs (97%) rename io/zenoh-transport/src/unicast/{ => net}/transport.rs (85%) rename io/zenoh-transport/src/unicast/{ => net}/tx.rs (95%) rename io/zenoh-transport/src/unicast/{shm.rs => shared_memory_unicast.rs} (100%) create mode 100644 io/zenoh-transport/src/unicast/shm/link.rs create mode 100644 io/zenoh-transport/src/unicast/shm/mod.rs create mode 100644 io/zenoh-transport/src/unicast/shm/rx.rs create mode 100644 io/zenoh-transport/src/unicast/shm/transport.rs create mode 100644 io/zenoh-transport/src/unicast/shm/tx.rs create mode 100644 io/zenoh-transport/src/unicast/test_helpers.rs create mode 100644 io/zenoh-transport/src/unicast/transport_unicast_inner.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8961b33bf5..8212e01c3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,10 +63,11 @@ jobs: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - name: Clippy shared-memory + if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'macOS-latest' }} uses: actions-rs/cargo@v1 with: command: clippy - args: --all-targets --features shared-memory -- -D warnings + args: --all-targets --features shared-memory --features transport_shm -- -D warnings test: name: Run tests on ${{ matrix.os }} @@ -101,11 +102,31 @@ jobs: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse ASYNC_STD_THREAD_COUNT: 4 - - name: Run tests shared-memory + - name: Run tests with SHM + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions-rs/cargo@v1 + with: + command: nextest + args: run -F shared-memory -F transport_shm -p zenoh-transport + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + ASYNC_STD_THREAD_COUNT: 4 + + - name: Run doctests uses: actions-rs/cargo@v1 with: command: test - args: --features "transport_tcp,shared-memory" -p zenoh-transport --test unicast_shm + args: --doc + env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + ASYNC_STD_THREAD_COUNT: 4 + + - name: Run tests with SHM for macOS + if: ${{ matrix.os == 'macOS-latest' }} + uses: actions-rs/cargo@v1 + with: + command: nextest + args: run -F shared-memory -F transport_tcp -p zenoh-transport env: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse ASYNC_STD_THREAD_COUNT: 4 diff --git a/.github/workflows/crates_check.sh b/.github/workflows/crates_check.sh index 734ce04383..e8ec76cbce 100755 --- a/.github/workflows/crates_check.sh +++ b/.github/workflows/crates_check.sh @@ -1,7 +1,6 @@ cargo check -p zenoh-result --manifest-path commons/zenoh-result/Cargo.toml && cargo check -p zenoh-core --manifest-path commons/zenoh-core/Cargo.toml && cargo check -p zenoh-keyexpr --manifest-path commons/zenoh-keyexpr/Cargo.toml && -cargo check -p zenoh-cfg-properties --manifest-path commons/zenoh-cfg-properties/Cargo.toml && cargo check -p zenoh-collections --manifest-path commons/zenoh-collections/Cargo.toml && cargo check -p zenoh-crypto --manifest-path commons/zenoh-crypto/Cargo.toml && cargo check -p zenoh-buffers --manifest-path commons/zenoh-buffers/Cargo.toml && diff --git a/.github/workflows/crates_publish.sh b/.github/workflows/crates_publish.sh index 32c31b5bcc..4e8b93b856 100755 --- a/.github/workflows/crates_publish.sh +++ b/.github/workflows/crates_publish.sh @@ -2,7 +2,6 @@ cargo login $1 (cd commons/zenoh-result && cargo publish) (cd commons/zenoh-core && cargo publish) (cd commons/zenoh-keyexpr && cargo publish) -(cd commons/zenoh-cfg-properties && cargo publish) (cd commons/zenoh-collections && cargo publish) (cd commons/zenoh-crypto && cargo publish) (cd commons/zenoh-buffers && cargo publish) diff --git a/Cargo.lock b/Cargo.lock index aeed2c0590..002c3e5278 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,21 +23,6 @@ dependencies = [ "mach", ] -[[package]] -name = "addr2line" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "aead" version = "0.3.2" @@ -60,9 +45,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" dependencies = [ "cfg-if 1.0.0", "cipher 0.4.4", @@ -116,9 +101,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -146,9 +131,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "array-init" @@ -180,9 +165,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "1.9.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" dependencies = [ "concurrent-queue", "event-listener", @@ -289,7 +274,7 @@ dependencies = [ "futures-lite", "rustix", "signal-hook", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -359,7 +344,7 @@ dependencies = [ "log", "memchr", "once_cell", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.9", "pin-utils", "slab", "wasm-bindgen-futures", @@ -373,13 +358,13 @@ checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", ] [[package]] @@ -405,21 +390,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" -dependencies = [ - "addr2line", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base-x" version = "0.2.11" @@ -551,12 +521,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.81" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0" -dependencies = [ - "libc", -] +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -641,7 +608,7 @@ dependencies = [ "atty", "bitflags 1.3.2", "clap_lex", - "indexmap 1.9.3", + "indexmap", "strsim", "termcolor", "textwrap", @@ -673,9 +640,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.4" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "const_fn" @@ -750,9 +717,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -837,22 +804,22 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if 1.0.0", "crossbeam-utils", - "memoffset 0.9.0", + "memoffset 0.8.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if 1.0.0", ] @@ -907,12 +874,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "deranged" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" - [[package]] name = "derive-new" version = "0.5.9" @@ -976,7 +937,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -987,9 +948,9 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "either" -version = "1.9.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "env_logger" @@ -1004,30 +965,24 @@ dependencies = [ "termcolor", ] -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - [[package]] name = "erased-serde" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da96524cc884f6558f1769b6c46686af2fe8e8b4cd253bd5a3cdba8181b8e070" +checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" dependencies = [ "serde", ] [[package]] name = "errno" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1098,9 +1053,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ "percent-encoding", ] @@ -1164,7 +1119,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.9", "waker-fn", ] @@ -1176,7 +1131,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", ] [[package]] @@ -1204,7 +1159,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.9", "pin-utils", "slab", ] @@ -1232,9 +1187,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -1253,12 +1208,6 @@ dependencies = [ "polyval", ] -[[package]] -name = "gimli" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" - [[package]] name = "git-version" version = "0.3.5" @@ -1321,25 +1270,28 @@ dependencies = [ ] [[package]] -name = "hashbrown" -version = "0.14.0" +name = "hermit-abi" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "hex" @@ -1392,7 +1344,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1431,7 +1383,7 @@ dependencies = [ "cookie", "futures-lite", "infer", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.9", "rand 0.7.3", "serde", "serde_json", @@ -1454,9 +1406,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1477,9 +1429,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1495,16 +1447,6 @@ dependencies = [ "hashbrown 0.12.3", ] -[[package]] -name = "indexmap" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" -dependencies = [ - "equivalent", - "hashbrown 0.14.0", -] - [[package]] name = "infer" version = "0.2.3" @@ -1535,9 +1477,9 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.1", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1555,10 +1497,10 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1572,15 +1514,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" dependencies = [ "wasm-bindgen", ] @@ -1634,9 +1576,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libloading" @@ -1662,9 +1604,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -1672,9 +1614,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" dependencies = [ "serde", "value-bag", @@ -1733,22 +1675,13 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - [[package]] name = "mio" version = "0.8.8" @@ -1758,7 +1691,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1780,7 +1713,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.9", ] [[package]] @@ -1818,9 +1751,9 @@ checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" [[package]] name = "num-bigint-dig" -version = "0.8.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" dependencies = [ "byteorder", "lazy_static", @@ -1856,9 +1789,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", "libm", @@ -1866,28 +1799,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.2.6", "libc", ] -[[package]] -name = "object" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" -version = "1.18.0" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" [[package]] name = "oorandom" @@ -1924,9 +1848,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.5.1" +version = "6.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" +checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "panic-message" @@ -1942,9 +1866,9 @@ checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" [[package]] name = "paste" -version = "1.0.14" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pem" @@ -1966,15 +1890,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.7.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" dependencies = [ "thiserror", "ucd-trie", @@ -1982,9 +1906,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" +checksum = "6b79d4c71c865a25a4322296122e3924d30bc8ee0834c8bfc8b95f7f054afbfb" dependencies = [ "pest", "pest_generator", @@ -1992,26 +1916,26 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" +checksum = "6c435bf1076437b851ebc8edc3a18442796b30f1728ffea6262d59bbe28b077e" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", ] [[package]] name = "pest_meta" -version = "2.7.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" +checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411" dependencies = [ "once_cell", "pest", - "sha2 0.10.7", + "sha2 0.10.6", ] [[package]] @@ -2021,27 +1945,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", - "indexmap 1.9.3", + "indexmap", ] [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", ] [[package]] @@ -2052,9 +1976,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -2086,9 +2010,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" dependencies = [ "num-traits", "plotters-backend", @@ -2099,15 +2023,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] @@ -2215,8 +2139,8 @@ dependencies = [ "concurrent-queue", "libc", "log", - "pin-project-lite 0.2.10", - "windows-sys", + "pin-project-lite 0.2.9", + "windows-sys 0.48.0", ] [[package]] @@ -2244,21 +2168,21 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" dependencies = [ "unicode-ident", ] [[package]] name = "quinn" -version = "0.10.2" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +checksum = "21252f1c0fc131f1b69182db8f34837e8a69737b8251dff75636a9be0518c324" dependencies = [ "bytes", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.9", "quinn-proto", "quinn-udp", "rustc-hash", @@ -2270,9 +2194,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.2" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c8bb234e70c863204303507d841e7fa2295e95c822b2bb4ca8ebf57f17b1cb" +checksum = "85af4ed6ee5a89f26a26086e9089a6643650544c025158449a3626ebf72884b3" dependencies = [ "bytes", "rand 0.8.5", @@ -2296,14 +2220,14 @@ dependencies = [ "libc", "socket2 0.5.3", "tracing", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "quote" -version = "1.0.32" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -2367,7 +2291,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.9", ] [[package]] @@ -2409,7 +2333,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring", - "time 0.3.25", + "time 0.3.21", "yasna", ] @@ -2428,28 +2352,16 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.9", "redox_syscall", "thiserror", ] [[package]] name = "regex" -version = "1.9.1" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" +checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" dependencies = [ "aho-corasick", "memchr", @@ -2458,9 +2370,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "ring" @@ -2513,12 +2425,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -2540,28 +2446,28 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.18", + "semver 1.0.17", ] [[package]] name = "rustix" -version = "0.37.23" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags 1.3.2", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.21.6" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" +checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" dependencies = [ "log", "ring", @@ -2571,9 +2477,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -2583,18 +2489,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ "base64 0.21.2", ] [[package]] name = "rustls-webpki" -version = "0.101.2" +version = "0.100.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" +checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" dependencies = [ "ring", "untrusted", @@ -2602,9 +2508,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "same-file" @@ -2617,18 +2523,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "windows-sys", + "windows-sys 0.42.0", ] [[package]] name = "scopeguard" -version = "1.2.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sct" @@ -2642,9 +2548,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -2655,9 +2561,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -2674,9 +2580,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "semver-parser" @@ -2686,22 +2592,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.180" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.180" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e744d7782b686ab3b73267ef05697159cc0e5abbed3f47f9933165e5219036" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", ] [[package]] @@ -2715,9 +2621,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -2749,11 +2655,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.25" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" +checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c" dependencies = [ - "indexmap 2.0.0", + "indexmap", "itoa", "ryu", "serde", @@ -2818,9 +2724,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -2861,9 +2767,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.17" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" dependencies = [ "libc", "signal-hook-registry", @@ -2908,9 +2814,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" @@ -2929,7 +2835,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3030,7 +2936,7 @@ dependencies = [ "async-channel", "cfg-if 1.0.0", "futures-core", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.9", ] [[package]] @@ -3047,15 +2953,15 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "sval" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1" +checksum = "0e6aa16ce8d9e472e21a528a52c875a76a49190f3968f2ec7e9b550ccc28b410" [[package]] name = "sval_buffer" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028" +checksum = "905c4373621186ee9637464b0aaa026389ea9e7f841f2225f160a32ba5d5bac4" dependencies = [ "sval", "sval_ref", @@ -3063,18 +2969,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf" +checksum = "ad6b4988322c5f22859a6a7649fa1249aa3dd01514caf8ed57d83735f997bb8b" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" +checksum = "9d3ccd10346f925c2fbd97b75e8573b38e34431bfba04cc531cd23aad0fbabb8" dependencies = [ "itoa", "ryu", @@ -3083,9 +2989,9 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" +checksum = "6a12e1488defd6344e23243c17ea4a1b185c547968749e8a281373fde0bde2d5" dependencies = [ "itoa", "ryu", @@ -3094,18 +3000,18 @@ dependencies = [ [[package]] name = "sval_ref" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c" +checksum = "b797fc4b284dd0e45f7ec424479e604ea5be9bb191a1ef4e96c20c7685649938" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046" +checksum = "810fa9a837e67a23e0efa7536250fc4d24043306cc1efd076f1943ba2fc2e62d" dependencies = [ "serde", "sval", @@ -3126,9 +3032,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -3152,22 +3058,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", ] [[package]] @@ -3187,7 +3093,7 @@ dependencies = [ "http-types", "kv-log-macro", "log", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.9", "route-recognizer", "serde", "serde_json", @@ -3221,11 +3127,10 @@ dependencies = [ [[package]] name = "time" -version = "0.3.25" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" dependencies = [ - "deranged", "serde", "time-core", ] @@ -3295,20 +3200,19 @@ dependencies = [ [[package]] name = "tokio" -version = "1.29.1" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", - "backtrace", "bytes", "libc", "mio", "num_cpus", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.9", "socket2 0.4.9", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3319,7 +3223,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", ] [[package]] @@ -3355,20 +3259,20 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.9", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", ] [[package]] @@ -3417,9 +3321,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "uhlc" @@ -3444,9 +3348,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-normalization" @@ -3475,9 +3379,9 @@ dependencies = [ [[package]] name = "unsafe-libyaml" -version = "0.2.9" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" +checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6" [[package]] name = "untrusted" @@ -3498,9 +3402,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", @@ -3510,9 +3414,9 @@ dependencies = [ [[package]] name = "urlencoding" -version = "2.1.3" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" +checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" [[package]] name = "utf-8" @@ -3522,11 +3426,11 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.4.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.9", ] [[package]] @@ -3555,9 +3459,9 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.4.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +checksum = "a4d330786735ea358f3bc09eea4caa098569c1c93f342d9aca0514915022fe7e" dependencies = [ "value-bag-serde1", "value-bag-sval2", @@ -3565,9 +3469,9 @@ dependencies = [ [[package]] name = "value-bag-serde1" -version = "1.4.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394" +checksum = "4735c95b4cca1447b448e2e2e87e98d7e7498f4da27e355cf7af02204521001d" dependencies = [ "erased-serde", "serde", @@ -3576,9 +3480,9 @@ dependencies = [ [[package]] name = "value-bag-sval2" -version = "1.4.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d" +checksum = "859cb4f0ce7da6a118b559ba74b0e63bf569bea867c20ba457a6b1c886a04e97" dependencies = [ "sval", "sval_buffer", @@ -3637,9 +3541,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" dependencies = [ "cfg-if 1.0.0", "serde", @@ -3649,24 +3553,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3676,9 +3580,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3686,28 +3590,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.18", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" dependencies = [ "js-sys", "wasm-bindgen", @@ -3794,6 +3698,21 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -3805,19 +3724,25 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.48.0", "windows_aarch64_msvc 0.48.0", "windows_i686_gnu 0.48.0", "windows_i686_msvc 0.48.0", "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.48.0", "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" @@ -3830,6 +3755,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" @@ -3842,6 +3773,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.0" @@ -3854,6 +3791,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.0" @@ -3866,12 +3809,24 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" @@ -3884,6 +3839,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" @@ -3896,7 +3857,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.25", + "time 0.3.21", ] [[package]] @@ -4016,7 +3977,7 @@ dependencies = [ name = "zenoh-crypto" version = "0.10.0-dev" dependencies = [ - "aes 0.8.3", + "aes 0.8.2", "hmac 0.12.1", "rand 0.8.5", "rand_chacha 0.3.1", @@ -4178,7 +4139,6 @@ dependencies = [ "async-trait", "futures", "log", - "rustls", "rustls-pemfile", "webpki", "webpki-roots", diff --git a/Cargo.toml b/Cargo.toml index 61fcb2d45a..a0c64cad9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ members = [ "io/zenoh-links/zenoh-link-udp/", "io/zenoh-links/zenoh-link-unixsock_stream/", "io/zenoh-links/zenoh-link-ws/", + "io/zenoh-links/zenoh-link-shm/", "io/zenoh-transport", "plugins/example-plugin", "plugins/zenoh-backend-traits", @@ -167,7 +168,6 @@ zenoh-codec = { version = "0.10.0-dev", path = "commons/zenoh-codec" } zenoh-sync = { version = "0.10.0-dev", path = "commons/zenoh-sync" } zenoh-collections = { version = "0.10.0-dev", path = "commons/zenoh-collections", default-features = false } zenoh-macros = { version = "0.10.0-dev", path = "commons/zenoh-macros" } -zenoh-cfg-properties = { version = "0.10.0-dev", path = "commons/zenoh-cfg-properties" } zenoh-plugin-trait = { version = "0.10.0-dev", path = "plugins/zenoh-plugin-trait", default-features = false } zenoh_backend_traits = { version = "0.10.0-dev", path = "plugins/zenoh-backend-traits" } zenoh-transport = { version = "0.10.0-dev", path = "io/zenoh-transport" } @@ -177,6 +177,7 @@ zenoh-link-unixsock_stream = { version = "0.10.0-dev", path = "io/zenoh-links/ze zenoh-link-quic = { version = "0.10.0-dev", path = "io/zenoh-links/zenoh-link-quic" } zenoh-link-udp = { version = "0.10.0-dev", path = "io/zenoh-links/zenoh-link-udp" } zenoh-link-ws = { version = "0.10.0-dev", path = "io/zenoh-links/zenoh-link-ws" } +zenoh-link-shm = { version = "0.10.0-dev", path = "io/zenoh-links/zenoh-link-shm" } zenoh-link-serial = { version = "0.10.0-dev", path = "io/zenoh-links/zenoh-link-serial" } zenoh-link = { version = "0.10.0-dev", path = "io/zenoh-link" } zenoh-link-commons = { version = "0.10.0-dev", path = "io/zenoh-link-commons" } diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index d37d7df497..6a1ee3e01e 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -71,13 +71,24 @@ where let header: u8 = self.codec.read(&mut *reader)?; let codec = Zenoh080Header::new(header); - let body = match imsg::mid(codec.header) { - id::PUSH => NetworkBody::Push(codec.read(&mut *reader)?), - id::REQUEST => NetworkBody::Request(codec.read(&mut *reader)?), - id::RESPONSE => NetworkBody::Response(codec.read(&mut *reader)?), - id::RESPONSE_FINAL => NetworkBody::ResponseFinal(codec.read(&mut *reader)?), - id::DECLARE => NetworkBody::Declare(codec.read(&mut *reader)?), - id::OAM => NetworkBody::OAM(codec.read(&mut *reader)?), + codec.read(&mut *reader) + } +} + +impl RCodec for Zenoh080Header +where + R: Reader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let body = match imsg::mid(self.header) { + id::PUSH => NetworkBody::Push(self.read(&mut *reader)?), + id::REQUEST => NetworkBody::Request(self.read(&mut *reader)?), + id::RESPONSE => NetworkBody::Response(self.read(&mut *reader)?), + id::RESPONSE_FINAL => NetworkBody::ResponseFinal(self.read(&mut *reader)?), + id::DECLARE => NetworkBody::Declare(self.read(&mut *reader)?), + id::OAM => NetworkBody::OAM(self.read(&mut *reader)?), _ => return Err(DidntRead), }; diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index be9d32fd7a..c3bbbbc86e 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -25,11 +25,53 @@ use zenoh_buffers::{ reader::{BacktrackableReader, DidntRead, Reader}, writer::{DidntWrite, Writer}, }; +#[cfg(feature = "shared-memory")] +use zenoh_protocol::network::NetworkMessage; use zenoh_protocol::{ common::{imsg, ZExtZ64}, transport::*, }; +// TransportMessageShm +#[cfg(feature = "shared-memory")] +impl WCodec<&TransportMessageShm, &mut W> for Zenoh080 +where + W: Writer, +{ + type Output = Result<(), DidntWrite>; + + fn write(self, writer: &mut W, x: &TransportMessageShm) -> Self::Output { + match &x.body { + TransportBodyShm::Network(b) => self.write(&mut *writer, b.as_ref()), + TransportBodyShm::KeepAlive(b) => self.write(&mut *writer, b), + TransportBodyShm::Close(b) => self.write(&mut *writer, b), + } + } +} +#[cfg(feature = "shared-memory")] +impl RCodec for Zenoh080 +where + R: Reader + BacktrackableReader, +{ + type Error = DidntRead; + + fn read(self, reader: &mut R) -> Result { + let header: u8 = self.read(&mut *reader)?; + + let codec = Zenoh080Header::new(header); + let body = match imsg::mid(codec.header) { + id::KEEP_ALIVE => TransportBodyShm::KeepAlive(codec.read(&mut *reader)?), + id::CLOSE => TransportBodyShm::Close(codec.read(&mut *reader)?), + _ => { + let nw: NetworkMessage = codec.read(&mut *reader)?; + TransportBodyShm::Network(Box::new(nw)) + } + }; + + Ok(TransportMessageShm { body }) + } +} + // TransportMessage impl WCodec<&TransportMessage, &mut W> for Zenoh080 where diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 399a8de717..422c20d54e 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -288,6 +288,10 @@ validated_struct::validator! { client_certificate: Option, server_name_verification: Option }, + pub shared_memory: #[derive(Default)] + SHMConf { + shm_access_mask: Option + }, pub compression: #[derive(Default)] /// **Experimental** compression feature. /// Will compress the batches hop to hop (as opposed to end to end). May cause errors when diff --git a/commons/zenoh-core/src/macros.rs b/commons/zenoh-core/src/macros.rs index 4dba6adf29..b0cbb24963 100644 --- a/commons/zenoh-core/src/macros.rs +++ b/commons/zenoh-core/src/macros.rs @@ -64,6 +64,20 @@ macro_rules! zasyncread { }; } +// This macro performs an async read with upgrade to write option on RwLock +// For performance reasons, it first performs a try_upgradable_read() and, +// if it fails, it falls back on upgradable_read().await +#[macro_export] +macro_rules! zasyncread_upgradable { + ($var:expr) => { + if let Some(g) = $var.try_upgradable_read() { + g + } else { + $var.upgradable_read().await + } + }; +} + // This macro performs an async write on RwLock // For performance reasons, it first performs a try_write() and, // if it fails, it falls back on write().await diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index 7b8df40fd5..b415bd02e8 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -24,7 +24,7 @@ pub use declare::{ DeclareToken, UndeclareInterest, UndeclareKeyExpr, UndeclareQueryable, UndeclareSubscriber, UndeclareToken, }; -pub use oam::{Oam, OamId}; +pub use oam::Oam; pub use push::Push; pub use request::{AtomicRequestId, Request, RequestId}; pub use response::{Response, ResponseFinal}; diff --git a/commons/zenoh-protocol/src/network/oam.rs b/commons/zenoh-protocol/src/network/oam.rs index 7d7794b001..814257c1e1 100644 --- a/commons/zenoh-protocol/src/network/oam.rs +++ b/commons/zenoh-protocol/src/network/oam.rs @@ -21,6 +21,12 @@ pub mod flag { pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow } +pub mod id { + use super::OamId; + + pub const OAM_LINKSTATE: OamId = 0x0001; +} + /// ```text /// Flags: /// - E |: Encoding The encoding of the extension diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index 61a2bd88b7..b61070e50a 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -29,6 +29,9 @@ pub use keepalive::KeepAlive; pub use oam::Oam; pub use open::{OpenAck, OpenSyn}; +#[cfg(feature = "shared-memory")] +use crate::network::NetworkMessage; + /// NOTE: 16 bits (2 bytes) may be prepended to the serialized message indicating the total length /// in bytes of the message, resulting in the maximum length of a message being 65_535 bytes. /// This is necessary in those stream-oriented transports (e.g., TCP) that do not preserve @@ -56,6 +59,19 @@ pub mod id { pub const JOIN: u8 = 0x07; // For multicast communications only } +#[cfg(feature = "shared-memory")] +#[derive(Debug)] +pub struct TransportMessageShm { + pub body: TransportBodyShm, +} +#[cfg(feature = "shared-memory")] +#[derive(Debug)] +pub enum TransportBodyShm { + Close(Close), + KeepAlive(KeepAlive), + Network(Box), +} + pub type TransportSn = u32; #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 3f6fcbafe3..a07febd43f 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -28,6 +28,16 @@ readme = "README.md" [features] shared-memory = ["zenoh/shared-memory"] unstable = ["zenoh/unstable"] +transport_shm = ["zenoh/transport_shm"] + +# Unfortunately, the feature "transport_shm" is always +# enabled for the lines below. It looks like a Cargo bug :( +# +# [target.'cfg(unix)'.dependencies] +# zenoh = { workspace = true, features = ["transport_shm"] } +# +# [target.'cfg(not(unix))'.dependencies] +# zenoh = { workspace = true } [dependencies] async-std = { workspace = true, features = ["attributes"] } diff --git a/examples/examples/z_ping.rs b/examples/examples/z_ping.rs index 2eadbc02d2..173d270a83 100644 --- a/examples/examples/z_ping.rs +++ b/examples/examples/z_ping.rs @@ -12,6 +12,8 @@ // ZettaScale Zenoh Team, // use clap::{App, Arg}; +#[cfg(not(feature = "shared-memory"))] +use std::process::exit; use std::time::{Duration, Instant}; use zenoh::config::Config; use zenoh::prelude::sync::*; @@ -98,6 +100,7 @@ fn parse_args() -> (Config, Duration, usize, usize) { .arg(Arg::from_usage( "--no-multicast-scouting 'Disable the multicast-based scouting mechanism.'", )) + .arg(Arg::from_usage("--enable-shm 'Enable SHM transport.'")) .arg(Arg::from_usage( "-c, --config=[FILE] 'A configuration file.'", )) @@ -123,6 +126,16 @@ fn parse_args() -> (Config, Duration, usize, usize) { if args.is_present("no-multicast-scouting") { config.scouting.multicast.set_enabled(Some(false)).unwrap(); } + if args.is_present("enable-shm") { + #[cfg(feature = "shared-memory")] + config.transport.shared_memory.set_enabled(true).unwrap(); + #[cfg(not(feature = "shared-memory"))] + { + println!("enable-shm argument: SHM cannot be enabled, because Zenoh is compiled without shared-memory feature!"); + exit(-1); + } + } + let n: usize = args.value_of("samples").unwrap().parse().unwrap(); let w: f64 = args.value_of("warmup").unwrap().parse().unwrap(); let size: usize = args.value_of("PAYLOAD_SIZE").unwrap().parse().unwrap(); diff --git a/examples/examples/z_pong.rs b/examples/examples/z_pong.rs index 273245ccac..d1c7bbb867 100644 --- a/examples/examples/z_pong.rs +++ b/examples/examples/z_pong.rs @@ -14,6 +14,8 @@ use std::io::{stdin, Read}; // ZettaScale Zenoh Team, // use clap::{App, Arg}; +#[cfg(not(feature = "shared-memory"))] +use std::process::exit; use zenoh::config::Config; use zenoh::prelude::sync::*; use zenoh::publication::CongestionControl; @@ -61,6 +63,7 @@ fn parse_args() -> Config { .arg(Arg::from_usage( "--no-multicast-scouting 'Disable the multicast-based scouting mechanism.'", )) + .arg(Arg::from_usage("--enable-shm 'Enable SHM transport.'")) .arg(Arg::from_usage( "-c, --config=[FILE] 'A configuration file.'", )) @@ -83,6 +86,15 @@ fn parse_args() -> Config { if args.is_present("no-multicast-scouting") { config.scouting.multicast.set_enabled(Some(false)).unwrap(); } + if args.is_present("enable-shm") { + #[cfg(feature = "shared-memory")] + config.transport.shared_memory.set_enabled(true).unwrap(); + #[cfg(not(feature = "shared-memory"))] + { + println!("enable-shm argument: SHM cannot be enabled, because Zenoh is compiled without shared-memory feature!"); + exit(-1); + } + } config } diff --git a/examples/examples/z_pub_thr.rs b/examples/examples/z_pub_thr.rs index 89c7e5db29..b761128f3f 100644 --- a/examples/examples/z_pub_thr.rs +++ b/examples/examples/z_pub_thr.rs @@ -13,6 +13,8 @@ // use clap::{App, Arg}; use std::convert::TryInto; +#[cfg(not(feature = "shared-memory"))] +use std::process::exit; use zenoh::config::Config; use zenoh::prelude::sync::*; use zenoh::publication::CongestionControl; @@ -82,6 +84,7 @@ fn parse_args() -> (Config, usize, Priority, bool, usize) { .arg(Arg::from_usage( "--no-multicast-scouting 'Disable the multicast-based scouting mechanism.'", )) + .arg(Arg::from_usage("--enable-shm 'Enable SHM transport.'")) .arg(Arg::from_usage( " 'Sets the size of the payload to publish'", )) @@ -106,9 +109,19 @@ fn parse_args() -> (Config, usize, Priority, bool, usize) { if let Some(values) = args.values_of("listen") { config.listen.endpoints = values.map(|v| v.parse().unwrap()).collect(); } + if args.is_present("no-multicast-scouting") { config.scouting.multicast.set_enabled(Some(false)).unwrap(); } + if args.is_present("enable-shm") { + #[cfg(feature = "shared-memory")] + config.transport.shared_memory.set_enabled(true).unwrap(); + #[cfg(not(feature = "shared-memory"))] + { + println!("enable-shm argument: SHM cannot be enabled, because Zenoh is compiled without shared-memory feature!"); + exit(-1); + } + } let number: usize = args.value_of("number").unwrap().parse().unwrap(); diff --git a/examples/examples/z_sub_thr.rs b/examples/examples/z_sub_thr.rs index f77e2c1ef4..3db5a82203 100644 --- a/examples/examples/z_sub_thr.rs +++ b/examples/examples/z_sub_thr.rs @@ -13,6 +13,8 @@ // use clap::{App, Arg}; use std::io::{stdin, Read}; +#[cfg(not(feature = "shared-memory"))] +use std::process::exit; use std::time::Instant; use zenoh::config::Config; use zenoh::prelude::sync::*; @@ -119,6 +121,7 @@ fn parse_args() -> (Config, usize, usize) { .arg(Arg::from_usage( "-c, --config=[FILE] 'A configuration file.'", )) + .arg(Arg::from_usage("--enable-shm 'Enable SHM transport.'")) .arg(Arg::from_usage( "--no-multicast-scouting 'Disable the multicast-based scouting mechanism.'", )) @@ -141,6 +144,15 @@ fn parse_args() -> (Config, usize, usize) { if args.is_present("no-multicast-scouting") { config.scouting.multicast.set_enabled(Some(false)).unwrap(); } + if args.is_present("enable-shm") { + #[cfg(feature = "shared-memory")] + config.transport.shared_memory.set_enabled(true).unwrap(); + #[cfg(not(feature = "shared-memory"))] + { + println!("enable-shm argument: SHM cannot be enabled, because Zenoh is compiled without shared-memory feature!"); + exit(-1); + } + } let samples: usize = args.value_of("samples").unwrap().parse().unwrap(); let number: usize = args.value_of("number").unwrap().parse().unwrap(); diff --git a/io/zenoh-link/Cargo.toml b/io/zenoh-link/Cargo.toml index 3f90a5a43c..79129740da 100644 --- a/io/zenoh-link/Cargo.toml +++ b/io/zenoh-link/Cargo.toml @@ -32,6 +32,7 @@ transport_udp = ["zenoh-link-udp"] transport_unixsock-stream = ["zenoh-link-unixsock_stream"] transport_ws = ["zenoh-link-ws"] transport_serial = ["zenoh-link-serial"] +transport_shm = ["zenoh-link-shm", "zenoh-link-shm/transport_shm"] [dependencies] async-std = { workspace = true } @@ -46,5 +47,6 @@ zenoh-link-tls = { workspace = true, optional = true } zenoh-link-udp = { workspace = true, optional = true } zenoh-link-unixsock_stream = { workspace = true, optional = true } zenoh-link-ws = { workspace = true, optional = true } +zenoh-link-shm = { workspace = true, optional = true } zenoh-protocol = { workspace = true } zenoh-result = { workspace = true } diff --git a/io/zenoh-link/src/lib.rs b/io/zenoh-link/src/lib.rs index 724a06bf9f..26efdd814c 100644 --- a/io/zenoh-link/src/lib.rs +++ b/io/zenoh-link/src/lib.rs @@ -66,6 +66,13 @@ pub use zenoh_link_serial as serial; #[cfg(feature = "transport_serial")] use zenoh_link_serial::{LinkManagerUnicastSerial, SerialLocatorInspector, SERIAL_LOCATOR_PREFIX}; +#[cfg(feature = "transport_shm")] +pub use zenoh_link_shm as shm; +#[cfg(feature = "transport_shm")] +use zenoh_link_shm::{ + LinkManagerUnicastPipe, ShmConfigurator, ShmLocatorInspector, SHM_LOCATOR_PREFIX, +}; + pub use zenoh_link_commons::*; pub use zenoh_protocol::core::{EndPoint, Locator}; @@ -84,6 +91,8 @@ pub const PROTOCOLS: &[&str] = &[ unixsock_stream::UNIXSOCKSTREAM_LOCATOR_PREFIX, #[cfg(feature = "transport_serial")] serial::SERIAL_LOCATOR_PREFIX, + #[cfg(feature = "transport_shm")] + shm::SHM_LOCATOR_PREFIX, ]; #[derive(Default, Clone)] @@ -102,6 +111,8 @@ pub struct LocatorInspector { unixsock_stream_inspector: UnixSockStreamLocatorInspector, #[cfg(feature = "transport_serial")] serial_inspector: SerialLocatorInspector, + #[cfg(feature = "transport_shm")] + shm_inspector: ShmLocatorInspector, } impl LocatorInspector { pub async fn is_multicast(&self, locator: &Locator) -> ZResult { @@ -125,6 +136,8 @@ impl LocatorInspector { WS_LOCATOR_PREFIX => self.ws_inspector.is_multicast(locator).await, #[cfg(feature = "transport_serial")] SERIAL_LOCATOR_PREFIX => self.serial_inspector.is_multicast(locator).await, + #[cfg(feature = "transport_shm")] + SHM_LOCATOR_PREFIX => self.shm_inspector.is_multicast(locator).await, _ => bail!("Unsupported protocol: {}.", protocol), } } @@ -135,6 +148,8 @@ pub struct LinkConfigurator { quic_inspector: QuicConfigurator, #[cfg(feature = "transport_tls")] tls_inspector: TlsConfigurator, + #[cfg(feature = "transport_shm")] + shm_inspector: ShmConfigurator, } impl LinkConfigurator { @@ -170,6 +185,13 @@ impl LinkConfigurator { self.tls_inspector.inspect_config(config).await, ); } + #[cfg(feature = "transport_shm")] + { + insert_config( + SHM_LOCATOR_PREFIX.into(), + self.shm_inspector.inspect_config(config).await, + ); + } (configs, errors) } } @@ -199,6 +221,8 @@ impl LinkManagerBuilderUnicast { WS_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastWs::new(_manager))), #[cfg(feature = "transport_serial")] SERIAL_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastSerial::new(_manager))), + #[cfg(feature = "transport_shm")] + SHM_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastPipe::new(_manager))), _ => bail!("Unicast not supported for {} protocol", protocol), } } diff --git a/io/zenoh-links/zenoh-link-shm/Cargo.toml b/io/zenoh-links/zenoh-link-shm/Cargo.toml new file mode 100644 index 0000000000..f29be5ade8 --- /dev/null +++ b/io/zenoh-links/zenoh-link-shm/Cargo.toml @@ -0,0 +1,49 @@ +# +# Copyright (c) 2023 ZettaScale Technology +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +# which is available at https://www.apache.org/licenses/LICENSE-2.0. +# +# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +# +# Contributors: +# ZettaScale Zenoh Team, +# +[package] +rust-version = { workspace = true } +name = "zenoh-link-shm" +version = { workspace = true } +repository = { workspace = true } +homepage = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +categories = { workspace = true } +description = "Internal crate for zenoh." +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[features] +transport_shm = [] + +[dependencies] +async-std = { workspace = true } +async-trait = { workspace = true } +async-io = ">= 1.13.0" +log = { workspace = true } +rand = { workspace = true } +zenoh-buffers = { workspace = true } +zenoh-core = { workspace = true } +zenoh-config = { workspace = true } +zenoh-link-commons = { workspace = true } +zenoh-protocol = { workspace = true } +zenoh-result = { workspace = true } + +[target.'cfg(unix)'.dependencies] +unix-named-pipe = ">= 0.2.0" +nix = { workspace = true } +filepath = ">=0.1.2" + +[target.'cfg(all(not(target_os="macos"), unix))'.dependencies] +advisory-lock = ">= 0.3.0" diff --git a/io/zenoh-links/zenoh-link-shm/src/lib.rs b/io/zenoh-links/zenoh-link-shm/src/lib.rs new file mode 100644 index 0000000000..96e373a66d --- /dev/null +++ b/io/zenoh-links/zenoh-link-shm/src/lib.rs @@ -0,0 +1,24 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +//! ⚠️ WARNING ⚠️ +//! +//! This crate is intended for Zenoh's internal use. +//! +//! [Click here for Zenoh's documentation](../zenoh/index.html) + +#[cfg(unix)] +mod unix; +#[cfg(unix)] +pub use unix::*; diff --git a/io/zenoh-links/zenoh-link-shm/src/unix/mod.rs b/io/zenoh-links/zenoh-link-shm/src/unix/mod.rs new file mode 100644 index 0000000000..81a02633c1 --- /dev/null +++ b/io/zenoh-links/zenoh-link-shm/src/unix/mod.rs @@ -0,0 +1,74 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +//! ⚠️ WARNING ⚠️ +//! +//! This crate is intended for Zenoh's internal use. +//! +//! [Click here for Zenoh's documentation](../zenoh/index.html) +pub mod unicast; + +use async_trait::async_trait; +pub use unicast::*; +use zenoh_config::Config; +use zenoh_core::zconfigurable; +use zenoh_link_commons::{ConfigurationInspector, LocatorInspector}; +use zenoh_protocol::core::{Locator, Parameters}; +use zenoh_result::ZResult; + +pub const SHM_LOCATOR_PREFIX: &str = "shm"; + +#[derive(Default, Clone, Copy)] +pub struct ShmLocatorInspector; +#[async_trait] +impl LocatorInspector for ShmLocatorInspector { + fn protocol(&self) -> &str { + SHM_LOCATOR_PREFIX + } + + async fn is_multicast(&self, _locator: &Locator) -> ZResult { + Ok(false) + } +} + +#[derive(Default, Clone, Copy, Debug)] +pub struct ShmConfigurator; +#[async_trait] +impl ConfigurationInspector for ShmConfigurator { + async fn inspect_config(&self, config: &Config) -> ZResult { + let mut properties: Vec<(&str, &str)> = vec![]; + + let c = config.transport().link().shared_memory(); + let shm_access_mask_; + if let Some(shm_access_mask) = c.shm_access_mask() { + shm_access_mask_ = shm_access_mask.to_string(); + properties.push((config::SHM_ACCESS_MASK, &shm_access_mask_)); + } + + let mut s = String::new(); + Parameters::extend(properties.drain(..), &mut s); + + Ok(s) + } +} + +zconfigurable! { + // Default access mask for SHM resources + static ref SHM_ACCESS_MASK: u32 = config::SHM_ACCESS_MASK_DEFAULT; +} + +pub mod config { + pub const SHM_ACCESS_MASK: &str = "shm_mask"; + pub const SHM_ACCESS_MASK_DEFAULT: u32 = 0o777; +} diff --git a/io/zenoh-links/zenoh-link-shm/src/unix/unicast.rs b/io/zenoh-links/zenoh-link-shm/src/unix/unicast.rs new file mode 100644 index 0000000000..27a9f0e037 --- /dev/null +++ b/io/zenoh-links/zenoh-link-shm/src/unix/unicast.rs @@ -0,0 +1,586 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::config; +#[cfg(not(target_os = "macos"))] +use advisory_lock::{AdvisoryFileLock, FileLockMode}; +use async_io::Async; +use async_std::fs::remove_file; +use async_std::task::JoinHandle; +use async_trait::async_trait; +use filepath::FilePath; +use nix::unistd::unlink; +use rand::Rng; +use std::cell::UnsafeCell; +use std::collections::HashMap; +use std::fmt; +use std::fs::File; +use std::io::{Read, Write}; +use std::sync::Arc; +use zenoh_core::{zasyncread, zasyncwrite}; +use zenoh_protocol::core::{EndPoint, Locator}; + +use unix_named_pipe::{create, open_read, open_write}; + +use zenoh_link_commons::{ + ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, + NewLinkChannelSender, +}; +use zenoh_result::{bail, ZResult}; + +use super::SHM_ACCESS_MASK; + +const LINUX_PIPE_MAX_MTU: u16 = 65_535; +const LINUX_PIPE_DEDICATE_TRIES: usize = 100; + +static PIPE_INVITATION: &[u8] = &[0xDE, 0xAD, 0xBE, 0xEF]; + +struct Invitation; +impl Invitation { + async fn send(suffix: u32, pipe: &mut PipeW) -> ZResult<()> { + let msg: [u8; 8] = { + let mut msg: [u8; 8] = [0; 8]; + let (one, two) = msg.split_at_mut(PIPE_INVITATION.len()); + one.copy_from_slice(PIPE_INVITATION); + two.copy_from_slice(&suffix.to_ne_bytes()); + msg + }; + pipe.write_all(&msg).await + } + + async fn receive(pipe: &mut PipeR) -> ZResult { + let mut msg: [u8; 8] = [0; 8]; + pipe.read_exact(&mut msg).await?; + if !msg.starts_with(PIPE_INVITATION) { + bail!("Unexpected invitation received during pipe handshake!") + } + + let suffix_bytes: &[u8; 4] = &msg[4..].try_into()?; + let suffix = u32::from_ne_bytes(*suffix_bytes); + Ok(suffix) + } + + async fn confirm(suffix: u32, pipe: &mut PipeW) -> ZResult<()> { + Self::send(suffix, pipe).await + } + + async fn expect(expected_suffix: u32, pipe: &mut PipeR) -> ZResult<()> { + let recived_suffix = Self::receive(pipe).await?; + if recived_suffix != expected_suffix { + bail!( + "Suffix mismatch: expected {} got {}", + expected_suffix, + recived_suffix + ) + } + Ok(()) + } +} + +struct PipeR { + pipe: Async, +} + +impl Drop for PipeR { + fn drop(&mut self) { + if let Ok(path) = self.pipe.as_mut().path() { + let _ = unlink(&path); + } + } +} +impl PipeR { + async fn new(path: &str, access_mode: u32) -> ZResult { + // create, open and lock named pipe + let pipe_file = Self::create_and_open_unique_pipe_for_read(path, access_mode).await?; + // create async_io wrapper for pipe's file descriptor + let pipe = Async::new(pipe_file)?; + Ok(Self { pipe }) + } + + async fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ZResult { + let result = self + .pipe + .read_with_mut(|pipe| match pipe.read(&mut buf[..]) { + Ok(0) => Err(async_std::io::ErrorKind::WouldBlock.into()), + Ok(val) => Ok(val), + Err(e) => Err(e), + }) + .await?; + ZResult::Ok(result) + } + + async fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ZResult<()> { + let mut r: usize = 0; + self.pipe + .read_with_mut(|pipe| match pipe.read(&mut buf[r..]) { + Ok(0) => Err(async_std::io::ErrorKind::WouldBlock.into()), + Ok(val) => { + r += val; + if r == buf.len() { + return Ok(()); + } + Err(async_std::io::ErrorKind::WouldBlock.into()) + } + Err(e) => Err(e), + }) + .await?; + ZResult::Ok(()) + } + + async fn create_and_open_unique_pipe_for_read(path_r: &str, access_mode: u32) -> ZResult { + let r_was_created = create(path_r, Some(access_mode)); + let open_result = Self::open_unique_pipe_for_read(path_r); + match (open_result.as_ref(), r_was_created) { + (Err(_), Ok(_)) => { + // clean-up in case of failure + let _ = remove_file(path_r).await; + } + (Ok(mut pipe_file), Err(_)) => { + // drop all the data from the pipe in case if it already exists + let mut buf: [u8; 1] = [0; 1]; + while let Ok(val) = pipe_file.read(&mut buf) { + if val == 0 { + break; + } + } + } + _ => {} + } + + open_result + } + + fn open_unique_pipe_for_read(path: &str) -> ZResult { + let read = open_read(path)?; + #[cfg(not(target_os = "macos"))] + read.try_lock(FileLockMode::Exclusive)?; + Ok(read) + } +} + +struct PipeW { + pipe: Async, +} +impl PipeW { + async fn new(path: &str) -> ZResult { + // create, open and lock named pipe + let pipe_file = Self::open_unique_pipe_for_write(path)?; + // create async_io wrapper for pipe's file descriptor + let pipe = Async::new(pipe_file)?; + Ok(Self { pipe }) + } + + async fn write<'a>(&'a mut self, buf: &'a [u8]) -> ZResult { + let result = self + .pipe + .write_with_mut(|pipe| match pipe.write(buf) { + Ok(0) => Err(async_std::io::ErrorKind::WouldBlock.into()), + Ok(val) => Ok(val), + Err(e) => Err(e), + }) + .await?; + ZResult::Ok(result) + } + + async fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> ZResult<()> { + let mut r: usize = 0; + self.pipe + .write_with_mut(|pipe| match pipe.write(&buf[r..]) { + Ok(0) => Err(async_std::io::ErrorKind::WouldBlock.into()), + Ok(val) => { + r += val; + if r == buf.len() { + return Ok(()); + } + Err(async_std::io::ErrorKind::WouldBlock.into()) + } + Err(e) => Err(e), + }) + .await?; + ZResult::Ok(()) + } + + fn open_unique_pipe_for_write(path: &str) -> ZResult { + let write = open_write(path)?; + // the file must be already locked at the other side... + #[cfg(not(target_os = "macos"))] + if write.try_lock(FileLockMode::Exclusive).is_ok() { + let _ = write.unlock(); + bail!("no listener...") + } + Ok(write) + } +} + +async fn handle_incoming_connections( + endpoint: &EndPoint, + manager: &Arc, + request_channel: &mut PipeR, + path_downlink: &str, + path_uplink: &str, + access_mode: u32, +) -> ZResult<()> { + // read invitation from the request channel + let suffix = Invitation::receive(request_channel).await?; + + // gererate uplink and downlink names + let (dedicated_downlink_path, dedicated_uplink_path) = + get_dedicated_pipe_names(path_downlink, path_uplink, suffix); + + // create dedicated downlink and uplink + let mut dedicated_downlink = PipeW::new(&dedicated_downlink_path).await?; + let mut dedicated_uplink = PipeR::new(&dedicated_uplink_path, access_mode).await?; + + // confirm over the dedicated chanel + Invitation::confirm(suffix, &mut dedicated_downlink).await?; + + // got confirmation over the dedicated chanel + Invitation::expect(suffix, &mut dedicated_uplink).await?; + + // create Locators + let local = Locator::new( + endpoint.protocol(), + dedicated_uplink_path, + endpoint.metadata(), + )?; + let remote = Locator::new( + endpoint.protocol(), + dedicated_downlink_path, + endpoint.metadata(), + )?; + + // send newly established link to manager + manager + .send_async(LinkUnicast(Arc::new(UnicastPipe { + r: UnsafeCell::new(dedicated_uplink), + w: UnsafeCell::new(dedicated_downlink), + local, + remote, + }))) + .await?; + + ZResult::Ok(()) +} + +struct UnicastPipeListener { + listening_task_handle: JoinHandle>, + uplink_locator: Locator, +} +impl UnicastPipeListener { + async fn listen(endpoint: EndPoint, manager: Arc) -> ZResult { + let (path_uplink, path_downlink, access_mode) = parse_pipe_endpoint(&endpoint); + let local = Locator::new( + endpoint.protocol(), + path_uplink.as_str(), + endpoint.metadata(), + )?; + + // create request channel + let mut request_channel = PipeR::new(&path_uplink, access_mode).await?; + + // create listening task + let listening_task_handle = async_std::task::spawn(async move { + loop { + let _ = handle_incoming_connections( + &endpoint, + &manager, + &mut request_channel, + &path_downlink, + &path_uplink, + access_mode, + ) + .await; + } + }); + + Ok(Self { + listening_task_handle, + uplink_locator: local, + }) + } + + async fn stop_listening(self) { + self.listening_task_handle.cancel().await; + } +} + +fn get_dedicated_pipe_names( + path_downlink: &str, + path_uplink: &str, + suffix: u32, +) -> (String, String) { + let suffix_str = suffix.to_string(); + let path_uplink = path_uplink.to_string() + &suffix_str; + let path_downlink = path_downlink.to_string() + &suffix_str; + (path_downlink, path_uplink) +} + +async fn create_pipe( + path_uplink: &str, + path_downlink: &str, + access_mode: u32, +) -> ZResult<(PipeR, u32, String, String)> { + // generate random suffix + let suffix: u32 = rand::thread_rng().gen(); + + // gererate uplink and downlink names + let (path_downlink, path_uplink) = get_dedicated_pipe_names(path_downlink, path_uplink, suffix); + + // try create uplink and downlink pipes to ensure that the selected suffix is available + let downlink = PipeR::new(&path_downlink, access_mode).await?; + let _uplink = PipeR::new(&path_uplink, access_mode).await?; // uplink would be dropped, that is OK! + + Ok((downlink, suffix, path_downlink, path_uplink)) +} + +async fn dedicate_pipe( + path_uplink: &str, + path_downlink: &str, + access_mode: u32, +) -> ZResult<(PipeR, u32, String, String)> { + for _ in 0..LINUX_PIPE_DEDICATE_TRIES { + match create_pipe(path_uplink, path_downlink, access_mode).await { + Err(_) => {} + val => { + return val; + } + } + } + bail!("Unabe to dedicate pipe!") +} + +struct UnicastPipeClient; +impl UnicastPipeClient { + async fn connect_to(endpoint: EndPoint) -> ZResult { + let (path_uplink, path_downlink, access_mode) = parse_pipe_endpoint(&endpoint); + + // open the request channel + // this channel would be used to invite listener to the dedicated channel + // listener owns the request channel, so failure of this call means that there is nobody listening on the provided endpoint + let mut request_channel = PipeW::new(&path_uplink).await?; + + // create dedicated channel prerequisities. The creation code also ensures that nobody else would use the same channel concurrently + let ( + mut dedicated_downlink, + dedicated_suffix, + dedicated_donlink_path, + dedicated_uplink_path, + ) = dedicate_pipe(&path_uplink, &path_downlink, access_mode).await?; + + // invite the listener to our dedicated channel over the requet channel + Invitation::send(dedicated_suffix, &mut request_channel).await?; + + // read responce that should be sent over the dedicated channel, confirming that everything is OK + // on the listener's side and it is already working with the dedicated channel + Invitation::expect(dedicated_suffix, &mut dedicated_downlink).await?; + + // open dedicated uplink + let mut dedicated_uplink = PipeW::new(&dedicated_uplink_path).await?; + + // final confirmation over the dedicated uplink + Invitation::confirm(dedicated_suffix, &mut dedicated_uplink).await?; + + // create Locators + let local = Locator::new( + endpoint.protocol(), + dedicated_donlink_path, + endpoint.metadata(), + )?; + let remote = Locator::new( + endpoint.protocol(), + dedicated_uplink_path, + endpoint.metadata(), + )?; + + Ok(UnicastPipe { + r: UnsafeCell::new(dedicated_downlink), + w: UnsafeCell::new(dedicated_uplink), + local, + remote, + }) + } +} + +struct UnicastPipe { + // The underlying pipes wrapped into async_io + // SAFETY: Async requires &mut for read and write operations. This means + // that concurrent reads and writes are not possible. To achieve that, + // we use an UnsafeCell for interior mutability. Using an UnsafeCell + // is safe in our case since the transmission and reception logic + // already ensures that no concurrent reads or writes can happen on + // the same stream: there is only one task at the time that writes on + // the stream and only one task at the time that reads from the stream. + r: UnsafeCell, + w: UnsafeCell, + local: Locator, + remote: Locator, +} + +impl UnicastPipe { + // SAFETY: It is safe to suppress Clippy warning since no concurrent access will ever happen. + // The write and read pipes are independent and support full-duplex operation, + // and single-direction operations are aligned at the transport side and will never access link concurrently + #[allow(clippy::mut_from_ref)] + fn get_r_mut(&self) -> &mut PipeR { + unsafe { &mut *self.r.get() } + } + + #[allow(clippy::mut_from_ref)] + fn get_w_mut(&self) -> &mut PipeW { + unsafe { &mut *self.w.get() } + } +} +// Promise that proper synchronization exists *around accesses*. +unsafe impl Sync for UnicastPipe {} + +impl Drop for UnicastPipe { + fn drop(&mut self) {} +} + +#[async_trait] +impl LinkUnicastTrait for UnicastPipe { + async fn close(&self) -> ZResult<()> { + log::trace!("Closing SHM Pipe link: {}", self); + Ok(()) + } + + async fn write(&self, buffer: &[u8]) -> ZResult { + self.get_w_mut().write(buffer).await + } + + async fn write_all(&self, buffer: &[u8]) -> ZResult<()> { + self.get_w_mut().write_all(buffer).await + } + + async fn read(&self, buffer: &mut [u8]) -> ZResult { + self.get_r_mut().read(buffer).await + } + + async fn read_exact(&self, buffer: &mut [u8]) -> ZResult<()> { + self.get_r_mut().read_exact(buffer).await + } + + #[inline(always)] + fn get_src(&self) -> &Locator { + &self.local + } + + #[inline(always)] + fn get_dst(&self) -> &Locator { + &self.remote + } + + #[inline(always)] + fn get_mtu(&self) -> u16 { + LINUX_PIPE_MAX_MTU + } + + #[inline(always)] + fn is_reliable(&self) -> bool { + true + } + + #[inline(always)] + fn is_streamed(&self) -> bool { + true + } +} + +impl fmt::Display for UnicastPipe { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} => {}", self.local, self.remote)?; + Ok(()) + } +} + +impl fmt::Debug for UnicastPipe { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Shm") + .field("src", &self.local) + .field("dst", &self.remote) + .finish() + } +} + +pub struct LinkManagerUnicastPipe { + manager: Arc, + listeners: async_std::sync::RwLock>, +} + +impl LinkManagerUnicastPipe { + pub fn new(manager: NewLinkChannelSender) -> Self { + Self { + manager: Arc::new(manager), + listeners: async_std::sync::RwLock::new(HashMap::new()), + } + } +} +impl ConstructibleLinkManagerUnicast<()> for LinkManagerUnicastPipe { + fn new(new_link_sender: NewLinkChannelSender, _: ()) -> ZResult { + Ok(Self::new(new_link_sender)) + } +} + +#[async_trait] +impl LinkManagerUnicastTrait for LinkManagerUnicastPipe { + async fn new_link(&self, endpoint: EndPoint) -> ZResult { + let pipe = UnicastPipeClient::connect_to(endpoint).await?; + Ok(LinkUnicast(Arc::new(pipe))) + } + + async fn new_listener(&self, endpoint: EndPoint) -> ZResult { + let listener = UnicastPipeListener::listen(endpoint.clone(), self.manager.clone()).await?; + let locator = listener.uplink_locator.clone(); + zasyncwrite!(self.listeners).insert(endpoint, listener); + Ok(locator) + } + + async fn del_listener(&self, endpoint: &EndPoint) -> ZResult<()> { + let removed = zasyncwrite!(self.listeners).remove(endpoint); + match removed { + Some(val) => { + val.stop_listening().await; + Ok(()) + } + None => bail!("No listener found for endpoint {}", endpoint), + } + } + + fn get_listeners(&self) -> Vec { + async_std::task::block_on(async { zasyncread!(self.listeners) }) + .keys() + .cloned() + .collect() + } + + fn get_locators(&self) -> Vec { + async_std::task::block_on(async { zasyncread!(self.listeners) }) + .values() + .map(|v| v.uplink_locator.clone()) + .collect() + } +} + +fn parse_pipe_endpoint(endpoint: &EndPoint) -> (String, String, u32) { + let address = endpoint.address(); + let path = address.as_str(); + let path_uplink = path.to_string() + "_uplink"; + let path_downlink = path.to_string() + "_downlink"; + let access_mode = endpoint + .config() + .get(config::SHM_ACCESS_MASK) + .map_or(*SHM_ACCESS_MASK, |val| { + val.parse().unwrap_or(*SHM_ACCESS_MASK) + }); + (path_uplink, path_downlink, access_mode) +} diff --git a/io/zenoh-transport/Cargo.toml b/io/zenoh-transport/Cargo.toml index d108a2779d..96ead9b1af 100644 --- a/io/zenoh-transport/Cargo.toml +++ b/io/zenoh-transport/Cargo.toml @@ -42,6 +42,7 @@ transport_unixsock-stream = ["zenoh-link/transport_unixsock-stream"] transport_ws = ["zenoh-link/transport_ws"] transport_serial = ["zenoh-link/transport_serial"] transport_compression = [] +transport_shm = ["zenoh-link/transport_shm"] stats = [] test = [] unstable = [] @@ -77,5 +78,5 @@ zenoh-util = { workspace = true } env_logger = { workspace = true } panic-message = { workspace = true } zenoh-protocol = { workspace = true, features = ["test"] } -zenoh-transport = { workspace = true, features = ["test"] } +zenoh-transport = { workspace = true, features = ["test", "transport_multilink"] } diff --git a/io/zenoh-transport/src/lib.rs b/io/zenoh-transport/src/lib.rs index cd9c21cbc8..6a1457c8ac 100644 --- a/io/zenoh-transport/src/lib.rs +++ b/io/zenoh-transport/src/lib.rs @@ -21,9 +21,10 @@ mod common; mod manager; mod multicast; mod primitives; +pub mod unicast; + #[cfg(feature = "shared-memory")] mod shm; -pub mod unicast; pub use manager::*; pub use multicast::*; diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index f4bc768ee3..6bc5048a23 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -29,7 +29,7 @@ impl Mux { impl Primitives for Mux { fn send_declare(&self, msg: Declare) { - let _ = self.handler.handle_message(NetworkMessage { + let _ = self.handler.schedule(NetworkMessage { body: NetworkBody::Declare(msg), #[cfg(feature = "stats")] size: None, @@ -37,7 +37,7 @@ impl Primitives for Mux { } fn send_push(&self, msg: Push) { - let _ = self.handler.handle_message(NetworkMessage { + let _ = self.handler.schedule(NetworkMessage { body: NetworkBody::Push(msg), #[cfg(feature = "stats")] size: None, @@ -45,7 +45,7 @@ impl Primitives for Mux { } fn send_request(&self, msg: Request) { - let _ = self.handler.handle_message(NetworkMessage { + let _ = self.handler.schedule(NetworkMessage { body: NetworkBody::Request(msg), #[cfg(feature = "stats")] size: None, @@ -53,7 +53,7 @@ impl Primitives for Mux { } fn send_response(&self, msg: Response) { - let _ = self.handler.handle_message(NetworkMessage { + let _ = self.handler.schedule(NetworkMessage { body: NetworkBody::Response(msg), #[cfg(feature = "stats")] size: None, @@ -61,7 +61,7 @@ impl Primitives for Mux { } fn send_response_final(&self, msg: ResponseFinal) { - let _ = self.handler.handle_message(NetworkMessage { + let _ = self.handler.schedule(NetworkMessage { body: NetworkBody::ResponseFinal(msg), #[cfg(feature = "stats")] size: None, diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 86c79099ab..01b5f4af61 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // #[cfg(feature = "shared-memory")] -use crate::unicast::shm::Challenge; +use crate::unicast::shared_memory_unicast::Challenge; use crate::{ unicast::establishment::{ close_link, compute_sn, ext, finalize_transport, AcceptFsm, Cookie, InputFinalize, @@ -592,17 +592,12 @@ pub(crate) async fn accept_link(link: &LinkUnicast, manager: &TransportManager) #[cfg(feature = "shared-memory")] is_shm: state.ext_shm.is_shm(), }; - let transport = step!(manager - .init_transport_unicast(config) - .await - .map_err(|e| (e, Some(close::reason::INVALID)))); - // Add the link to the transport - step!(step!(transport - .get_inner() - .map_err(|e| (e, Some(close::reason::INVALID)))) - .add_link(link.clone(), LinkUnicastDirection::Inbound) - .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); + let transport = step!( + manager + .init_transport_unicast(config, link.clone(), LinkUnicastDirection::Inbound) + .await + ); // Send the open_ack on the link step!(link diff --git a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs index ade6ee8fd8..131c0b5186 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/shm.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/shm.rs @@ -13,7 +13,7 @@ // use crate::unicast::{ establishment::{AcceptFsm, OpenFsm}, - shm::{Challenge, SharedMemoryUnicast}, + shared_memory_unicast::{Challenge, SharedMemoryUnicast}, }; use async_trait::async_trait; use std::convert::TryInto; diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 89bfd12ee8..e7d78c6537 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // #[cfg(feature = "shared-memory")] -use crate::unicast::shm::Challenge; +use crate::unicast::shared_memory_unicast::Challenge; use crate::{ unicast::establishment::{ close_link, compute_sn, ext, finalize_transport, InputFinalize, OpenFsm, @@ -513,18 +513,12 @@ pub(crate) async fn open_link( #[cfg(feature = "shared-memory")] is_shm: state.ext_shm.is_shm(), }; - let transport = step!(manager - .init_transport_unicast(config) - .await - .map_err(|e| (e, Some(close::reason::INVALID)))); - - // Finalize the transport - // Add the link to the transport - step!(step!(transport - .get_inner() - .map_err(|e| (e, Some(close::reason::INVALID)))) - .add_link(link.clone(), LinkUnicastDirection::Outbound) - .map_err(|e| (e, Some(close::reason::MAX_LINKS)))); + + let transport = step!( + manager + .init_transport_unicast(config, link.clone(), LinkUnicastDirection::Outbound) + .await + ); // Sync the RX sequence number let _ = step!(transport diff --git a/io/zenoh-transport/src/unicast/manager.rs b/io/zenoh-transport/src/unicast/manager.rs index 4dede34769..8ba61150c0 100644 --- a/io/zenoh-transport/src/unicast/manager.rs +++ b/io/zenoh-transport/src/unicast/manager.rs @@ -11,14 +11,18 @@ // Contributors: // ZettaScale Zenoh Team, // +#[cfg(feature = "shared-memory")] +use super::shared_memory_unicast::SharedMemoryUnicast; +#[cfg(feature = "shared-memory")] +use super::shm::transport::TransportUnicastShm; #[cfg(feature = "transport_auth")] use crate::unicast::establishment::ext::auth::Auth; #[cfg(feature = "transport_multilink")] use crate::unicast::establishment::ext::multilink::MultiLink; -#[cfg(feature = "shared-memory")] -use crate::unicast::shm::SharedMemoryUnicast; use crate::{ - unicast::{transport::TransportUnicastInner, TransportConfigUnicast, TransportUnicast}, + net::transport::TransportUnicastNet, + transport_unicast_inner::TransportUnicastTrait, + unicast::{TransportConfigUnicast, TransportUnicast}, TransportManager, }; use async_std::{prelude::FutureExt, sync::Mutex, task}; @@ -33,7 +37,7 @@ use zenoh_protocol::{ core::{endpoint, ZenohId}, transport::close, }; -use zenoh_result::{bail, zerror, ZResult}; +use zenoh_result::{bail, zerror, Error, ZResult}; /*************************************/ /* TRANSPORT CONFIG */ @@ -59,7 +63,7 @@ pub struct TransportManagerStateUnicast { // Established listeners pub(super) protocols: Arc>>, // Established transports - pub(super) transports: Arc>>>, + pub(super) transports: Arc>>>, // Multilink #[cfg(feature = "transport_multilink")] pub(super) multilink: Arc, @@ -249,6 +253,11 @@ impl TransportManager { TransportManagerBuilderUnicast::default() } + #[cfg(feature = "shared-memory")] + pub(crate) fn shm(&self) -> &Arc { + &self.state.unicast.shm + } + pub async fn close_unicast(&self) { log::trace!("TransportManagerUnicast::clear())"); @@ -266,7 +275,7 @@ impl TransportManager { let mut tu_guard = zasynclock!(self.state.unicast.transports) .drain() .map(|(_, v)| v) - .collect::>>(); + .collect::>>(); for tu in tu_guard.drain(..) { let _ = tu.close(close::reason::GENERIC).await; } @@ -376,26 +385,35 @@ impl TransportManager { pub(super) async fn init_transport_unicast( &self, config: TransportConfigUnicast, - ) -> ZResult { + link: LinkUnicast, + direction: LinkUnicastDirection, + ) -> Result)> { let mut guard = zasynclock!(self.state.unicast.transports); // First verify if the transport already exists match guard.get(&config.zid) { Some(transport) => { + let existing_config = transport.get_config(); // If it exists, verify that fundamental parameters like are correct. // Ignore the non fundamental parameters like initial SN. - if transport.config != config { + if *existing_config != config { let e = zerror!( "Transport with peer {} already exist. Invalid config: {:?}. Expected: {:?}.", config.zid, config, - transport.config + existing_config ); log::trace!("{}", e); - return Err(e.into()); + return Err((e.into(), Some(close::reason::INVALID))); } - Ok(transport.into()) + // Add the link to the transport + transport + .add_link(link, direction) + .await + .map_err(|e| (e, Some(close::reason::MAX_LINKS)))?; + + Ok(TransportUnicast(Arc::downgrade(transport))) } None => { // Then verify that we haven't reached the transport number limit @@ -406,13 +424,12 @@ impl TransportManager { config.zid ); log::trace!("{}", e); - return Err(e.into()); + return Err((e.into(), Some(close::reason::INVALID))); } // Create the transport let is_multilink = zcondfeat!("transport_multilink", config.multilink.is_some(), false); - let is_shm = zcondfeat!("shared-memory", config.is_shm, false); let stc = TransportConfigUnicast { zid: config.zid, @@ -425,21 +442,72 @@ impl TransportManager { #[cfg(feature = "shared-memory")] is_shm: config.is_shm, }; - let a_t = Arc::new(TransportUnicastInner::make(self.clone(), stc)?); + + async fn make_net_transport( + manager: &TransportManager, + stc: TransportConfigUnicast, + link: LinkUnicast, + direction: LinkUnicastDirection, + ) -> Result, (Error, Option)> { + log::debug!("Will use NET transport!"); + let t: Arc = + TransportUnicastNet::make(manager.clone(), stc) + .map_err(|e| (e, Some(close::reason::INVALID))) + .map(|v| Arc::new(v) as Arc)?; + // Add the link to the transport + t.add_link(link, direction) + .await + .map_err(|e| (e, Some(close::reason::MAX_LINKS)))?; + Ok(t) + } + + // select and create transport implementation depending on the cfg and enabled features + let a_t: Arc = zcondfeat!( + "shared-memory", + { + if stc.is_shm { + log::debug!("Will use SHM transport!"); + TransportUnicastShm::make(self.clone(), stc, link) + .map_err(|e| (e, Some(close::reason::INVALID))) + .map(|v| Arc::new(v) as Arc)? + } else { + make_net_transport(self, stc, link, direction).await? + } + }, + make_net_transport(self, stc, link, direction).await? + ); // Add the transport transport to the list of active transports - let transport: TransportUnicast = (&a_t).into(); + let transport = TransportUnicast(Arc::downgrade(&a_t)); guard.insert(config.zid, a_t); - log::debug!( - "New transport opened between {} and {} - whatami: {}, sn resolution: {:?}, initial sn: {:?}, qos: {}, shm: {}, multilink: {}", - self.config.zid, - config.zid, - config.whatami, - config.sn_resolution, - config.tx_initial_sn, - config.is_qos, - is_multilink, is_shm + zcondfeat!( + "shared-memory", + { + log::debug!( + "New transport opened between {} and {} - whatami: {}, sn resolution: {:?}, initial sn: {:?}, qos: {}, shm: {}, multilink: {}", + self.config.zid, + config.zid, + config.whatami, + config.sn_resolution, + config.tx_initial_sn, + config.is_qos, + config.is_shm, + is_multilink + ); + }, + { + log::debug!( + "New transport opened between {} and {} - whatami: {}, sn resolution: {:?}, initial sn: {:?}, qos: {}, multilink: {}", + self.config.zid, + config.zid, + config.whatami, + config.sn_resolution, + config.tx_initial_sn, + config.is_qos, + is_multilink + ); + } ); Ok(transport) @@ -482,13 +550,21 @@ impl TransportManager { pub async fn get_transport_unicast(&self, peer: &ZenohId) -> Option { zasynclock!(self.state.unicast.transports) .get(peer) - .map(|t| t.into()) + .map(|t| { + // todo: I cannot find a way to make transport.into() work for TransportUnicastTrait + let weak = Arc::downgrade(t); + TransportUnicast(weak) + }) } pub async fn get_transports_unicast(&self) -> Vec { zasynclock!(self.state.unicast.transports) .values() - .map(|t| t.into()) + .map(|t| { + // todo: I cannot find a way to make transport.into() work for TransportUnicastTrait + let weak = Arc::downgrade(t); + TransportUnicast(weak) + }) .collect() } diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index a3a6eb673f..b0d9e265e1 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -12,15 +12,20 @@ // ZettaScale Zenoh Team, // pub mod establishment; -pub(crate) mod link; pub(crate) mod manager; -pub(crate) mod rx; +pub(crate) mod net; +pub(crate) mod transport_unicast_inner; + +#[cfg(feature = "test")] +pub mod test_helpers; + +#[cfg(feature = "shared-memory")] +pub(crate) mod shared_memory_unicast; #[cfg(feature = "shared-memory")] pub(crate) mod shm; -pub(crate) mod transport; -pub(crate) mod tx; -use super::common; +use self::transport_unicast_inner::TransportUnicastTrait; + #[cfg(feature = "stats")] use super::common::stats::stats_struct; use super::{TransportPeer, TransportPeerEventHandler}; @@ -29,7 +34,6 @@ use establishment::ext::auth::ZPublicKey; pub use manager::*; use std::fmt; use std::sync::{Arc, Weak}; -use transport::TransportUnicastInner; use zenoh_core::zcondfeat; use zenoh_link::Link; use zenoh_protocol::network::NetworkMessage; @@ -99,11 +103,11 @@ pub(crate) struct TransportConfigUnicast { /// [`TransportUnicast`] is the transport handler returned /// when opening a new unicast transport #[derive(Clone)] -pub struct TransportUnicast(Weak); +pub struct TransportUnicast(Weak); impl TransportUnicast { #[inline(always)] - pub(super) fn get_inner(&self) -> ZResult> { + pub(super) fn get_inner(&self) -> ZResult> { self.0 .upgrade() .ok_or_else(|| zerror!("Transport unicast closed").into()) @@ -121,12 +125,6 @@ impl TransportUnicast { Ok(transport.get_whatami()) } - #[inline(always)] - pub fn get_sn_resolution(&self) -> ZResult { - let transport = self.get_inner()?; - Ok(transport.get_sn_resolution()) - } - #[cfg(feature = "shared-memory")] #[inline(always)] pub fn is_shm(&self) -> ZResult { @@ -134,12 +132,6 @@ impl TransportUnicast { Ok(transport.is_shm()) } - #[inline(always)] - pub fn is_qos(&self) -> ZResult { - let transport = self.get_inner()?; - Ok(transport.is_qos()) - } - #[inline(always)] pub fn get_callback(&self) -> ZResult>> { let transport = self.get_inner()?; @@ -176,8 +168,7 @@ impl TransportUnicast { #[inline(always)] pub fn schedule(&self, message: NetworkMessage) -> ZResult<()> { let transport = self.get_inner()?; - transport.schedule(message); - Ok(()) + transport.schedule(message) } #[inline(always)] @@ -201,20 +192,15 @@ impl TransportUnicast { } } - #[inline(always)] - pub fn handle_message(&self, message: NetworkMessage) -> ZResult<()> { - self.schedule(message) - } - #[cfg(feature = "stats")] pub fn get_stats(&self) -> ZResult { Ok(self.get_inner()?.stats.snapshot()) } } -impl From<&Arc> for TransportUnicast { - fn from(s: &Arc) -> TransportUnicast { - TransportUnicast(Arc::downgrade(s)) +impl From<&Arc> for TransportUnicast { + fn from(link: &Arc) -> TransportUnicast { + TransportUnicast(Arc::downgrade(link)) } } @@ -231,13 +217,16 @@ impl fmt::Debug for TransportUnicast { match self.get_inner() { Ok(transport) => { let is_shm = zcondfeat!("shared-memory", transport.is_shm(), false); - f.debug_struct("Transport Unicast") - .field("zid", &transport.get_zid()) - .field("whatami", &transport.get_whatami()) - .field("resolution", &transport.get_sn_resolution()) - .field("is_qos", &transport.is_qos()) - .field("is_shm", &is_shm) - .field("links", &transport.get_links()) + + transport + .add_debug_fields( + f.debug_struct("Transport Unicast") + .field("zid", &transport.get_zid()) + .field("whatami", &transport.get_whatami()) + .field("is_qos", &transport.is_qos()) + .field("is_shm", &is_shm) + .field("links", &transport.get_links()), + ) .finish() } Err(e) => { diff --git a/io/zenoh-transport/src/unicast/link.rs b/io/zenoh-transport/src/unicast/net/link.rs similarity index 98% rename from io/zenoh-transport/src/unicast/link.rs rename to io/zenoh-transport/src/unicast/net/link.rs index c4100dd3e9..7cbaa3e9d5 100644 --- a/io/zenoh-transport/src/unicast/link.rs +++ b/io/zenoh-transport/src/unicast/net/link.rs @@ -11,14 +11,14 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::common::priority::TransportPriorityTx; -use super::transport::TransportUnicastInner; +use super::transport::TransportUnicastNet; #[cfg(feature = "stats")] use super::TransportUnicastStatsAtomic; use crate::common::pipeline::{ TransmissionPipeline, TransmissionPipelineConf, TransmissionPipelineConsumer, TransmissionPipelineProducer, }; +use crate::common::priority::TransportPriorityTx; use crate::TransportExecutor; use async_std::prelude::FutureExt; use async_std::task; @@ -64,7 +64,7 @@ pub(super) struct TransportLinkUnicast { // The transmission pipeline pub(super) pipeline: Option, // The transport this link is associated to - transport: TransportUnicastInner, + transport: TransportUnicastNet, // The signals to stop TX/RX tasks handle_tx: Option>>, signal_rx: Signal, @@ -73,7 +73,7 @@ pub(super) struct TransportLinkUnicast { impl TransportLinkUnicast { pub(super) fn new( - transport: TransportUnicastInner, + transport: TransportUnicastNet, link: LinkUnicast, direction: LinkUnicastDirection, ) -> TransportLinkUnicast { @@ -278,7 +278,7 @@ async fn tx_task( async fn rx_task_stream( link: LinkUnicast, - transport: TransportUnicastInner, + transport: TransportUnicastNet, lease: Duration, signal: Signal, rx_batch_size: BatchSize, @@ -349,7 +349,7 @@ async fn rx_task_stream( async fn rx_task_dgram( link: LinkUnicast, - transport: TransportUnicastInner, + transport: TransportUnicastNet, lease: Duration, signal: Signal, rx_batch_size: BatchSize, @@ -421,7 +421,7 @@ async fn rx_task_dgram( async fn rx_task( link: LinkUnicast, - transport: TransportUnicastInner, + transport: TransportUnicastNet, lease: Duration, signal: Signal, rx_batch_size: u16, diff --git a/io/zenoh-transport/src/unicast/net/mod.rs b/io/zenoh-transport/src/unicast/net/mod.rs new file mode 100644 index 0000000000..7cb4274baa --- /dev/null +++ b/io/zenoh-transport/src/unicast/net/mod.rs @@ -0,0 +1,18 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +pub(crate) mod transport; + +mod link; +mod rx; +mod tx; diff --git a/io/zenoh-transport/src/unicast/reliability.rs b/io/zenoh-transport/src/unicast/net/reliability.rs similarity index 100% rename from io/zenoh-transport/src/unicast/reliability.rs rename to io/zenoh-transport/src/unicast/net/reliability.rs diff --git a/io/zenoh-transport/src/unicast/rx.rs b/io/zenoh-transport/src/unicast/net/rx.rs similarity index 97% rename from io/zenoh-transport/src/unicast/rx.rs rename to io/zenoh-transport/src/unicast/net/rx.rs index e6d8bfd42c..5ee7552ebe 100644 --- a/io/zenoh-transport/src/unicast/rx.rs +++ b/io/zenoh-transport/src/unicast/net/rx.rs @@ -1,3 +1,5 @@ +use crate::transport_unicast_inner::TransportUnicastTrait; + // // Copyright (c) 2023 ZettaScale Technology // @@ -11,8 +13,8 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::common::priority::TransportChannelRx; -use super::transport::TransportUnicastInner; +use super::transport::TransportUnicastNet; +use crate::common::priority::TransportChannelRx; use async_std::task; use std::sync::MutexGuard; #[cfg(feature = "stats")] @@ -36,7 +38,7 @@ use zenoh_result::{bail, zerror, ZResult}; /*************************************/ /* TRANSPORT RX */ /*************************************/ -impl TransportUnicastInner { +impl TransportUnicastNet { fn trigger_callback( &self, #[allow(unused_mut)] // shared-memory feature requires mut diff --git a/io/zenoh-transport/src/unicast/transport.rs b/io/zenoh-transport/src/unicast/net/transport.rs similarity index 85% rename from io/zenoh-transport/src/unicast/transport.rs rename to io/zenoh-transport/src/unicast/net/transport.rs index 73820d1f4b..cadd85ba10 100644 --- a/io/zenoh-transport/src/unicast/transport.rs +++ b/io/zenoh-transport/src/unicast/net/transport.rs @@ -11,19 +11,23 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::super::{TransportExecutor, TransportManager, TransportPeerEventHandler}; -use super::common::priority::{TransportPriorityRx, TransportPriorityTx}; use super::link::TransportLinkUnicast; #[cfg(feature = "stats")] use super::TransportUnicastStatsAtomic; +use crate::common::priority::{TransportPriorityRx, TransportPriorityTx}; +use crate::transport_unicast_inner::TransportUnicastTrait; use crate::TransportConfigUnicast; +use crate::{TransportExecutor, TransportManager, TransportPeerEventHandler}; use async_std::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; +use async_trait::async_trait; +use std::fmt::DebugStruct; use std::sync::{Arc, RwLock}; use std::time::Duration; use zenoh_core::{zasynclock, zcondfeat, zread, zwrite}; use zenoh_link::{Link, LinkUnicast, LinkUnicastDirection}; +use zenoh_protocol::network::NetworkMessage; use zenoh_protocol::{ - core::{Bits, Priority, WhatAmI, ZenohId}, + core::{Priority, WhatAmI, ZenohId}, transport::{Close, PrioritySn, TransportMessage, TransportSn}, }; use zenoh_result::{bail, zerror, ZResult}; @@ -50,7 +54,7 @@ macro_rules! zlinkindex { /* TRANSPORT */ /*************************************/ #[derive(Clone)] -pub(crate) struct TransportUnicastInner { +pub(crate) struct TransportUnicastNet { // Transport Manager pub(crate) manager: TransportManager, // Transport config @@ -70,11 +74,11 @@ pub(crate) struct TransportUnicastInner { pub(super) stats: Arc, } -impl TransportUnicastInner { - pub(super) fn make( +impl TransportUnicastNet { + pub fn make( manager: TransportManager, config: TransportConfigUnicast, - ) -> ZResult { + ) -> ZResult { let mut priority_tx = vec![]; let mut priority_rx = vec![]; @@ -98,7 +102,7 @@ impl TransportUnicastInner { c.sync(initial_sn)?; } - let t = TransportUnicastInner { + let t = TransportUnicastNet { manager, config, priority_tx: priority_tx.into_boxed_slice().into(), @@ -113,41 +117,6 @@ impl TransportUnicastInner { Ok(t) } - pub(super) fn set_callback(&self, callback: Arc) { - let mut guard = zwrite!(self.callback); - *guard = Some(callback); - } - - pub(super) async fn get_alive(&self) -> AsyncMutexGuard<'_, bool> { - zasynclock!(self.alive) - } - - /*************************************/ - /* INITIATION */ - /*************************************/ - pub(super) async fn sync(&self, initial_sn_rx: TransportSn) -> ZResult<()> { - // Mark the transport as alive and keep the lock - // to avoid concurrent new_transport and closing/closed notifications - let mut a_guard = zasynclock!(self.alive); - if *a_guard { - let e = zerror!("Transport already synched with peer: {}", self.config.zid); - log::trace!("{}", e); - return Err(e.into()); - } - - *a_guard = true; - - let csn = PrioritySn { - reliable: initial_sn_rx, - best_effort: initial_sn_rx, - }; - for c in self.priority_rx.iter() { - c.sync(csn)?; - } - - Ok(()) - } - /*************************************/ /* TERMINATION */ /*************************************/ @@ -190,109 +159,60 @@ impl TransportUnicastInner { Ok(()) } - /*************************************/ - /* LINK */ - /*************************************/ - pub(super) fn add_link( - &self, - link: LinkUnicast, - direction: LinkUnicastDirection, - ) -> ZResult<()> { - // Add the link to the channel - let mut guard = zwrite!(self.links); - - // Check if we can add more inbound links - if let LinkUnicastDirection::Inbound = direction { - let count = guard.iter().filter(|l| l.direction == direction).count(); - - let limit = zcondfeat!( - "transport_multilink", - match self.config.multilink { - Some(_) => self.manager.config.unicast.max_links, - None => 1, - }, - 1 - ); - - if count >= limit { - let e = zerror!( - "Can not add Link {} with peer {}: max num of links reached {}/{}", - link, - self.config.zid, - count, - limit - ); - return Err(e.into()); - } + pub(crate) async fn del_link(&self, link: &LinkUnicast) -> ZResult<()> { + enum Target { + Transport, + Link(Box), } - // Create a channel link from a link - let link = TransportLinkUnicast::new(self.clone(), link, direction); - - let mut links = Vec::with_capacity(guard.len() + 1); - links.extend_from_slice(&guard); - links.push(link); - *guard = links.into_boxed_slice(); - - Ok(()) - } + // Try to remove the link + let target = { + let mut guard = zwrite!(self.links); - pub(super) fn start_tx( - &self, - link: &LinkUnicast, - executor: &TransportExecutor, - keep_alive: Duration, - batch_size: u16, - ) -> ZResult<()> { - let mut guard = zwrite!(self.links); - match zlinkgetmut!(guard, link) { - Some(l) => { - assert!(!self.priority_tx.is_empty()); - l.start_tx(executor, keep_alive, batch_size, &self.priority_tx); - Ok(()) - } - None => { + if let Some(index) = zlinkindex!(guard, link) { + let is_last = guard.len() == 1; + if is_last { + // Close the whole transport + drop(guard); + Target::Transport + } else { + // Remove the link + let mut links = guard.to_vec(); + let stl = links.remove(index); + *guard = links.into_boxed_slice(); + drop(guard); + Target::Link(stl.into()) + } + } else { bail!( - "Can not start Link TX {} with peer: {}", + "Can not delete Link {} with peer: {}", link, self.config.zid ) } + }; + + // Notify the callback + if let Some(callback) = zread!(self.callback).as_ref() { + callback.del_link(Link::from(link)); } - } - pub(super) fn stop_tx(&self, link: &LinkUnicast) -> ZResult<()> { - let mut guard = zwrite!(self.links); - match zlinkgetmut!(guard, link) { - Some(l) => { - l.stop_tx(); - Ok(()) - } - None => { - bail!( - "Can not stop Link TX {} with peer: {}", - link, - self.config.zid - ) - } + match target { + Target::Transport => self.delete().await, + Target::Link(stl) => stl.close().await, } } - pub(super) fn start_rx( - &self, - link: &LinkUnicast, - lease: Duration, - batch_size: u16, - ) -> ZResult<()> { + pub(crate) fn stop_tx(&self, link: &LinkUnicast) -> ZResult<()> { let mut guard = zwrite!(self.links); match zlinkgetmut!(guard, link) { Some(l) => { - l.start_rx(lease, batch_size); + l.stop_tx(); Ok(()) } None => { bail!( - "Can not start Link RX {} with peer: {}", + "Can not stop Link TX {} with peer: {}", link, self.config.zid ) @@ -300,7 +220,7 @@ impl TransportUnicastInner { } } - pub(super) fn stop_rx(&self, link: &LinkUnicast) -> ZResult<()> { + pub(crate) fn stop_rx(&self, link: &LinkUnicast) -> ZResult<()> { let mut guard = zwrite!(self.links); match zlinkgetmut!(guard, link) { Some(l) => { @@ -316,85 +236,120 @@ impl TransportUnicastInner { } } } +} - pub(crate) async fn del_link(&self, link: &LinkUnicast) -> ZResult<()> { - enum Target { - Transport, - Link(Box), - } +#[async_trait] +impl TransportUnicastTrait for TransportUnicastNet { + /*************************************/ + /* LINK */ + /*************************************/ + async fn add_link(&self, link: LinkUnicast, direction: LinkUnicastDirection) -> ZResult<()> { + // Add the link to the channel + let mut guard = zwrite!(self.links); - // Try to remove the link - let target = { - let mut guard = zwrite!(self.links); + // Check if we can add more inbound links + if let LinkUnicastDirection::Inbound = direction { + let count = guard.iter().filter(|l| l.direction == direction).count(); - if let Some(index) = zlinkindex!(guard, link) { - let is_last = guard.len() == 1; - if is_last { - // Close the whole transport - drop(guard); - Target::Transport - } else { - // Remove the link - let mut links = guard.to_vec(); - let stl = links.remove(index); - *guard = links.into_boxed_slice(); - drop(guard); - Target::Link(stl.into()) - } - } else { - bail!( - "Can not delete Link {} with peer: {}", + let limit = zcondfeat!( + "transport_multilink", + match self.config.multilink { + Some(_) => self.manager.config.unicast.max_links, + None => 1, + }, + 1 + ); + + if count >= limit { + let e = zerror!( + "Can not add Link {} with peer {}: max num of links reached {}/{}", link, - self.config.zid - ) + self.config.zid, + count, + limit + ); + return Err(e.into()); } - }; - - // Notify the callback - if let Some(callback) = zread!(self.callback).as_ref() { - callback.del_link(Link::from(link)); } - match target { - Target::Transport => self.delete().await, - Target::Link(stl) => stl.close().await, - } + // Create a channel link from a link + let link = TransportLinkUnicast::new(self.clone(), link, direction); + + let mut links = Vec::with_capacity(guard.len() + 1); + links.extend_from_slice(&guard); + links.push(link); + *guard = links.into_boxed_slice(); + + Ok(()) } -} -impl TransportUnicastInner { /*************************************/ /* ACCESSORS */ /*************************************/ - pub(crate) fn get_zid(&self) -> ZenohId { - self.config.zid + fn set_callback(&self, callback: Arc) { + let mut guard = zwrite!(self.callback); + *guard = Some(callback); } - pub(crate) fn get_whatami(&self) -> WhatAmI { - self.config.whatami + async fn get_alive(&self) -> AsyncMutexGuard<'_, bool> { + zasynclock!(self.alive) } - pub(crate) fn get_sn_resolution(&self) -> Bits { - self.config.sn_resolution + fn get_zid(&self) -> ZenohId { + self.config.zid + } + + fn get_whatami(&self) -> WhatAmI { + self.config.whatami } #[cfg(feature = "shared-memory")] - pub(crate) fn is_shm(&self) -> bool { + fn is_shm(&self) -> bool { self.config.is_shm } - pub(crate) fn is_qos(&self) -> bool { + fn is_qos(&self) -> bool { self.config.is_qos } - pub(crate) fn get_callback(&self) -> Option> { + fn get_callback(&self) -> Option> { zread!(self.callback).clone() } + fn get_config(&self) -> &TransportConfigUnicast { + &self.config + } + + /*************************************/ + /* INITIATION */ + /*************************************/ + async fn sync(&self, initial_sn_rx: TransportSn) -> ZResult<()> { + // Mark the transport as alive and keep the lock + // to avoid concurrent new_transport and closing/closed notifications + let mut a_guard = zasynclock!(self.alive); + if *a_guard { + let e = zerror!("Transport already synched with peer: {}", self.config.zid); + log::trace!("{}", e); + return Err(e.into()); + } + + *a_guard = true; + + let csn = PrioritySn { + reliable: initial_sn_rx, + best_effort: initial_sn_rx, + }; + for c in self.priority_rx.iter() { + c.sync(csn)?; + } + + Ok(()) + } + /*************************************/ /* TERMINATION */ /*************************************/ - pub(crate) async fn close_link(&self, link: &LinkUnicast, reason: u8) -> ZResult<()> { + async fn close_link(&self, link: &LinkUnicast, reason: u8) -> ZResult<()> { log::trace!("Closing link {} with peer: {}", link, self.config.zid); let mut pipeline = zlinkget!(zread!(self.links), link) @@ -416,7 +371,7 @@ impl TransportUnicastInner { self.del_link(link).await } - pub(crate) async fn close(&self, reason: u8) -> ZResult<()> { + async fn close(&self, reason: u8) -> ZResult<()> { log::trace!("Closing transport with peer: {}", self.config.zid); let mut pipelines = zread!(self.links) @@ -440,7 +395,65 @@ impl TransportUnicastInner { self.delete().await } - pub(crate) fn get_links(&self) -> Vec { + fn get_links(&self) -> Vec { zread!(self.links).iter().map(|l| l.link.clone()).collect() } + + /*************************************/ + /* TX */ + /*************************************/ + fn schedule(&self, msg: NetworkMessage) -> ZResult<()> { + match self.internal_schedule(msg) { + true => Ok(()), + false => bail!("error scheduling message!"), + } + } + + fn start_tx( + &self, + link: &LinkUnicast, + executor: &TransportExecutor, + keep_alive: Duration, + batch_size: u16, + ) -> ZResult<()> { + let mut guard = zwrite!(self.links); + match zlinkgetmut!(guard, link) { + Some(l) => { + assert!(!self.priority_tx.is_empty()); + l.start_tx(executor, keep_alive, batch_size, &self.priority_tx); + Ok(()) + } + None => { + bail!( + "Can not start Link TX {} with peer: {}", + link, + self.config.zid + ) + } + } + } + + fn start_rx(&self, link: &LinkUnicast, lease: Duration, batch_size: u16) -> ZResult<()> { + let mut guard = zwrite!(self.links); + match zlinkgetmut!(guard, link) { + Some(l) => { + l.start_rx(lease, batch_size); + Ok(()) + } + None => { + bail!( + "Can not start Link RX {} with peer: {}", + link, + self.config.zid + ) + } + } + } + + fn add_debug_fields<'a, 'b: 'a, 'c>( + &self, + s: &'c mut DebugStruct<'a, 'b>, + ) -> &'c mut DebugStruct<'a, 'b> { + s.field("sn_resolution", &self.config.sn_resolution) + } } diff --git a/io/zenoh-transport/src/unicast/tx.rs b/io/zenoh-transport/src/unicast/net/tx.rs similarity index 95% rename from io/zenoh-transport/src/unicast/tx.rs rename to io/zenoh-transport/src/unicast/net/tx.rs index 590fc8885f..6479444d76 100644 --- a/io/zenoh-transport/src/unicast/tx.rs +++ b/io/zenoh-transport/src/unicast/net/tx.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::transport::TransportUnicastInner; +use super::transport::TransportUnicastNet; #[cfg(feature = "stats")] use zenoh_buffers::SplitBuffer; use zenoh_core::zread; @@ -19,7 +19,7 @@ use zenoh_protocol::network::NetworkMessage; #[cfg(feature = "stats")] use zenoh_protocol::zenoh::ZenohBody; -impl TransportUnicastInner { +impl TransportUnicastNet { fn schedule_on_link(&self, msg: NetworkMessage) -> bool { macro_rules! zpush { ($guard:expr, $pipeline:expr, $msg:expr) => { @@ -66,13 +66,13 @@ impl TransportUnicastInner { #[allow(unused_mut)] // When feature "shared-memory" is not enabled #[allow(clippy::let_and_return)] // When feature "stats" is not enabled #[inline(always)] - pub(crate) fn schedule(&self, mut msg: NetworkMessage) -> bool { + pub(crate) fn internal_schedule(&self, mut msg: NetworkMessage) -> bool { #[cfg(feature = "shared-memory")] { let res = if self.config.is_shm { crate::shm::map_zmsg_to_shminfo(&mut msg) } else { - crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.state.unicast.shm.reader) + crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.shm().reader) }; if let Err(e) = res { log::trace!("Failed SHM conversion: {}", e); diff --git a/io/zenoh-transport/src/unicast/shm.rs b/io/zenoh-transport/src/unicast/shared_memory_unicast.rs similarity index 100% rename from io/zenoh-transport/src/unicast/shm.rs rename to io/zenoh-transport/src/unicast/shared_memory_unicast.rs diff --git a/io/zenoh-transport/src/unicast/shm/link.rs b/io/zenoh-transport/src/unicast/shm/link.rs new file mode 100644 index 0000000000..ad10e9b950 --- /dev/null +++ b/io/zenoh-transport/src/unicast/shm/link.rs @@ -0,0 +1,276 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use super::transport::TransportUnicastShm; +#[cfg(feature = "stats")] +use super::TransportUnicastStatsAtomic; +use crate::TransportExecutor; +use async_std::task; +use async_std::{prelude::FutureExt, sync::RwLock}; +use zenoh_codec::*; +use zenoh_core::{zasyncread, zasyncwrite}; + +use std::sync::Arc; +use std::time::Duration; +use zenoh_buffers::{writer::HasWriter, ZSlice}; +use zenoh_link::LinkUnicast; +use zenoh_protocol::transport::{BatchSize, KeepAlive, TransportBodyShm, TransportMessageShm}; +use zenoh_result::{zerror, ZResult}; +use zenoh_sync::RecyclingObjectPool; + +pub(crate) async fn send_with_link(link: &LinkUnicast, msg: TransportMessageShm) -> ZResult<()> { + if link.is_streamed() { + let mut buffer = vec![0, 0, 0, 0]; + let codec = Zenoh080::new(); + let mut writer = buffer.writer(); + codec + .write(&mut writer, &msg) + .map_err(|_| zerror!("Error serializing message {:?}", msg))?; + + let len = (buffer.len() - 4) as u32; + let le = len.to_le_bytes(); + + buffer[0..4].copy_from_slice(&le); + + link.write_all(&buffer).await?; + } else { + let mut buffer = vec![]; + let codec = Zenoh080::new(); + let mut writer = buffer.writer(); + codec + .write(&mut writer, &msg) + .map_err(|_| zerror!("Error serializing message {:?}", msg))?; + + link.write_all(&buffer).await?; + } + log::trace!("Sent: {:?}", msg); + + #[cfg(feature = "stats")] + { + stats.inc_tx_t_msgs(1); + stats.inc_tx_bytes(buff.len() + 2); + } + + Ok(()) +} + +impl TransportUnicastShm { + pub(super) fn send(&self, msg: TransportMessageShm) -> ZResult<()> { + async_std::task::block_on(self.send_async(msg)) + } + + pub(super) async fn send_async(&self, msg: TransportMessageShm) -> ZResult<()> { + let guard = zasyncwrite!(self.link); + send_with_link(&guard, msg).await + } + + pub(super) fn start_keepalive(&self, executor: &TransportExecutor, keep_alive: Duration) { + let mut guard = async_std::task::block_on(async { zasyncwrite!(self.handle_keepalive) }); + let c_transport = self.clone(); + let handle = executor.spawn(async move { + let res = keepalive_task( + c_transport.link.clone(), + keep_alive, + #[cfg(feature = "stats")] + c_transport.stats, + ) + .await; + log::debug!( + "[{}] Keepalive task finished with result {:?}", + c_transport.manager.config.zid, + res + ); + if res.is_err() { + log::debug!( + "[{}] finalizing transport with peer: {}", + c_transport.manager.config.zid, + c_transport.config.zid + ); + let _ = c_transport.finalize(0).await; + } + }); + *guard = Some(handle); + } + + pub(super) async fn stop_keepalive(&self) { + let zid = self.manager.config.zid; + log::debug!("[{}] Stopping keepalive task...", zid,); + let mut guard = zasyncwrite!(self.handle_keepalive); + let handle = guard.take(); + drop(guard); + + if let Some(handle) = handle { + let _ = handle.cancel().await; + log::debug!("[{}] keepalive task stopped...", zid,); + } + } + + pub(super) fn internal_start_rx(&self, lease: Duration, batch_size: u16) { + let mut guard = async_std::task::block_on(async { zasyncwrite!(self.handle_rx) }); + let c_transport = self.clone(); + let handle = task::spawn(async move { + let guard = zasyncread!(c_transport.link); + let link = guard.clone(); + drop(guard); + let rx_buffer_size = c_transport.manager.config.link_rx_buffer_size; + + // Start the rx task + let res = rx_task(link, c_transport.clone(), lease, batch_size, rx_buffer_size).await; + log::debug!( + "[{}] Rx task finished with result {:?}", + c_transport.manager.config.zid, + res + ); + if res.is_err() { + log::debug!( + "[{}] finalizing transport with peer: {}", + c_transport.manager.config.zid, + c_transport.config.zid + ); + let _ = c_transport.finalize(0).await; + } + }); + *guard = Some(handle); + } + + pub(super) async fn stop_rx(&self) { + let zid = self.manager.config.zid; + log::debug!("[{}] Stopping rx task...", zid,); + let mut guard = zasyncwrite!(self.handle_rx); + let handle = guard.take(); + drop(guard); + + if let Some(handle) = handle { + let _ = handle.cancel().await; + log::debug!("[{}] rx task stopped...", zid,); + } + } +} + +/*************************************/ +/* TASKS */ +/*************************************/ +async fn keepalive_task( + link: Arc>, + keep_alive: Duration, + #[cfg(feature = "stats")] stats: Arc, +) -> ZResult<()> { + loop { + async_std::task::sleep(keep_alive).await; + + let keepailve = TransportMessageShm { + body: TransportBodyShm::KeepAlive(KeepAlive), + }; + + let guard = zasyncwrite!(link); + let _ = send_with_link( + &guard, + keepailve, + #[cfg(feature = "stats")] + &stats, + ) + .await; + drop(guard); + } +} + +async fn rx_task_stream( + link: LinkUnicast, + transport: TransportUnicastShm, + lease: Duration, + rx_batch_size: BatchSize, + rx_buffer_size: usize, +) -> ZResult<()> { + async fn read(link: &LinkUnicast, buffer: &mut [u8]) -> ZResult { + // 16 bits for reading the batch length + let mut length = [0_u8, 0_u8, 0_u8, 0_u8]; + link.read_exact(&mut length).await?; + let n = u32::from_le_bytes(length) as usize; + + link.read_exact(&mut buffer[0..n]).await?; + Ok(n) + } + + // The pool of buffers + let mtu = link.get_mtu().min(rx_batch_size) as usize; + let mut n = rx_buffer_size / mtu; + if rx_buffer_size % mtu != 0 { + n += 1; + } + + let pool = RecyclingObjectPool::new(n, || vec![0_u8; mtu].into_boxed_slice()); + loop { + // Retrieve one buffer + let mut buffer = pool.try_take().unwrap_or_else(|| pool.alloc()); + + // Async read from the underlying link + let bytes = read(&link, &mut buffer) + .timeout(lease) + .await + .map_err(|_| zerror!("{}: expired after {} milliseconds", link, lease.as_millis()))??; + #[cfg(feature = "stats")] + transport.stats.inc_rx_bytes(2 + bytes); // Account for the batch len encoding (16 bits) + + // Deserialize all the messages from the current ZBuf + let zslice = ZSlice::make(Arc::new(buffer), 0, bytes).unwrap(); + transport.read_messages(zslice, &link).await?; + } +} + +async fn rx_task_dgram( + link: LinkUnicast, + transport: TransportUnicastShm, + lease: Duration, + rx_batch_size: BatchSize, + rx_buffer_size: usize, +) -> ZResult<()> { + // The pool of buffers + let mtu = link.get_mtu().min(rx_batch_size) as usize; + let mut n = rx_buffer_size / mtu; + if rx_buffer_size % mtu != 0 { + n += 1; + } + + let pool = RecyclingObjectPool::new(n, || vec![0_u8; mtu].into_boxed_slice()); + loop { + // Retrieve one buffer + let mut buffer = pool.try_take().unwrap_or_else(|| pool.alloc()); + + // Async read from the underlying link + let bytes = + link.read(&mut buffer).timeout(lease).await.map_err(|_| { + zerror!("{}: expired after {} milliseconds", link, lease.as_millis()) + })??; + + #[cfg(feature = "stats")] + transport.stats.inc_rx_bytes(bytes); + + // Deserialize all the messages from the current ZBuf + let zslice = ZSlice::make(Arc::new(buffer), 0, bytes).unwrap(); + transport.read_messages(zslice, &link).await?; + } +} + +async fn rx_task( + link: LinkUnicast, + transport: TransportUnicastShm, + lease: Duration, + rx_batch_size: u16, + rx_buffer_size: usize, +) -> ZResult<()> { + if link.is_streamed() { + rx_task_stream(link, transport, lease, rx_batch_size, rx_buffer_size).await + } else { + rx_task_dgram(link, transport, lease, rx_batch_size, rx_buffer_size).await + } +} diff --git a/io/zenoh-transport/src/unicast/shm/mod.rs b/io/zenoh-transport/src/unicast/shm/mod.rs new file mode 100644 index 0000000000..7cb4274baa --- /dev/null +++ b/io/zenoh-transport/src/unicast/shm/mod.rs @@ -0,0 +1,18 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +pub(crate) mod transport; + +mod link; +mod rx; +mod tx; diff --git a/io/zenoh-transport/src/unicast/shm/rx.rs b/io/zenoh-transport/src/unicast/shm/rx.rs new file mode 100644 index 0000000000..4e888a9e9c --- /dev/null +++ b/io/zenoh-transport/src/unicast/shm/rx.rs @@ -0,0 +1,114 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use super::transport::TransportUnicastShm; +#[cfg(feature = "stats")] +use zenoh_buffers::SplitBuffer; +use zenoh_buffers::{ + reader::{HasReader, Reader}, + ZSlice, +}; +use zenoh_codec::{RCodec, Zenoh080}; +use zenoh_core::zread; +use zenoh_link::LinkUnicast; +#[cfg(feature = "stats")] +use zenoh_protocol::zenoh::ZenohBody; +use zenoh_protocol::{network::NetworkMessage, transport::TransportMessageShm}; +use zenoh_result::{zerror, ZResult}; + +/*************************************/ +/* TRANSPORT RX */ +/*************************************/ +impl TransportUnicastShm { + fn trigger_callback( + &self, + #[allow(unused_mut)] // shared-memory feature requires mut + mut msg: NetworkMessage, + ) -> ZResult<()> { + #[cfg(feature = "stats")] + { + self.stats.inc_rx_z_msgs(1); + match &msg.body { + ZenohBody::Data(data) => match data.reply_context { + Some(_) => { + self.stats.inc_rx_z_data_reply_msgs(1); + self.stats + .inc_rx_z_data_reply_payload_bytes(data.payload.len()); + } + None => { + self.stats.inc_rx_z_data_msgs(1); + self.stats.inc_rx_z_data_payload_bytes(data.payload.len()); + } + }, + ZenohBody::Unit(unit) => match unit.reply_context { + Some(_) => self.stats.inc_rx_z_unit_reply_msgs(1), + None => self.stats.inc_rx_z_unit_msgs(1), + }, + ZenohBody::Pull(_) => self.stats.inc_rx_z_pull_msgs(1), + ZenohBody::Query(_) => self.stats.inc_rx_z_query_msgs(1), + ZenohBody::Declare(_) => self.stats.inc_rx_z_declare_msgs(1), + ZenohBody::LinkStateList(_) => self.stats.inc_rx_z_linkstate_msgs(1), + } + } + + let callback = zread!(self.callback).clone(); + if let Some(callback) = callback.as_ref() { + #[cfg(feature = "shared-memory")] + { + if self.config.is_shm { + crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.shm().reader)?; + } + } + callback.handle_message(msg) + } else { + log::debug!( + "Transport: {}. No callback available, dropping message: {}", + self.config.zid, + msg + ); + Ok(()) + } + } + + pub(super) async fn read_messages( + &self, + mut zslice: ZSlice, + link: &LinkUnicast, + ) -> ZResult<()> { + let codec = Zenoh080::new(); + let mut reader = zslice.reader(); + while reader.can_read() { + let msg: TransportMessageShm = codec + .read(&mut reader) + .map_err(|_| zerror!("{}: decoding error", link))?; + + log::trace!("Received: {:?}", msg); + + #[cfg(feature = "stats")] + { + transport.stats.inc_rx_t_msgs(1); + } + + match msg.body { + zenoh_protocol::transport::TransportBodyShm::Close(_) => { + let _ = self.delete().await; + } + zenoh_protocol::transport::TransportBodyShm::KeepAlive(_) => {} + zenoh_protocol::transport::TransportBodyShm::Network(msg) => { + let _ = self.trigger_callback(*msg); + } + } + } + Ok(()) + } +} diff --git a/io/zenoh-transport/src/unicast/shm/transport.rs b/io/zenoh-transport/src/unicast/shm/transport.rs new file mode 100644 index 0000000000..ccaa6e2cdc --- /dev/null +++ b/io/zenoh-transport/src/unicast/shm/transport.rs @@ -0,0 +1,306 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#[cfg(feature = "transport_shm")] +use super::link::send_with_link; +#[cfg(feature = "stats")] +use super::TransportUnicastStatsAtomic; +use crate::transport_unicast_inner::TransportUnicastTrait; +use crate::TransportConfigUnicast; +use crate::TransportManager; +use crate::{TransportExecutor, TransportPeerEventHandler}; +use async_executor::Task; +#[cfg(feature = "transport_shm")] +use async_std::sync::RwLockUpgradableReadGuard; +use async_std::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard, RwLock}; +use async_std::task::JoinHandle; +use async_trait::async_trait; +use std::sync::{Arc, RwLock as SyncRwLock}; +use std::time::Duration; +#[cfg(feature = "transport_shm")] +use zenoh_core::zasyncread_upgradable; +use zenoh_core::{zasynclock, zasyncread, zread, zwrite}; +#[cfg(feature = "transport_shm")] +use zenoh_link::Link; +use zenoh_link::{LinkUnicast, LinkUnicastDirection}; +use zenoh_protocol::core::{WhatAmI, ZenohId}; +use zenoh_protocol::network::NetworkMessage; +use zenoh_protocol::transport::TransportBodyShm; +use zenoh_protocol::transport::TransportMessageShm; +use zenoh_protocol::transport::{Close, TransportSn}; +#[cfg(not(feature = "transport_shm"))] +use zenoh_result::bail; +use zenoh_result::{zerror, ZResult}; + +/*************************************/ +/* TRANSPORT */ +/*************************************/ +#[derive(Clone)] +pub(crate) struct TransportUnicastShm { + // Transport Manager + pub(super) manager: TransportManager, + // Transport config + pub(super) config: TransportConfigUnicast, + // The link associated to the transport + pub(super) link: Arc>, + // The callback + pub(super) callback: Arc>>>, + // Mutex for notification + alive: Arc>, + // Transport statistics + #[cfg(feature = "stats")] + pub(super) stats: Arc, + + // The flags to stop TX/RX tasks + pub(crate) handle_keepalive: Arc>>>, + pub(crate) handle_rx: Arc>>>, +} + +impl TransportUnicastShm { + pub fn make( + manager: TransportManager, + config: TransportConfigUnicast, + link: LinkUnicast, + ) -> ZResult { + let t = TransportUnicastShm { + manager, + config, + link: Arc::new(RwLock::new(link)), + callback: Arc::new(SyncRwLock::new(None)), + alive: Arc::new(AsyncMutex::new(false)), + #[cfg(feature = "stats")] + stats: Arc::new(TransportUnicastStatsAtomic::default()), + handle_keepalive: Arc::new(RwLock::new(None)), + handle_rx: Arc::new(RwLock::new(None)), + }; + + Ok(t) + } + + /*************************************/ + /* TERMINATION */ + /*************************************/ + pub(super) async fn finalize(&self, reason: u8) -> ZResult<()> { + log::debug!( + "[{}] Finalizing transport with peer: {}", + self.manager.config.zid, + self.config.zid + ); + + // Send close message on the link + let close = TransportMessageShm { + body: TransportBodyShm::Close(Close { + reason, + session: false, + }), + }; + let _ = self.send_async(close).await; + + // Terminate and clean up the transport + self.delete().await + } + + pub(super) async fn delete(&self) -> ZResult<()> { + log::debug!( + "[{}] Deleting transport with peer: {}", + self.manager.config.zid, + self.config.zid + ); + // Mark the transport as no longer alive and keep the lock + // to avoid concurrent new_transport and closing/closed notifications + let mut a_guard = self.get_alive().await; + *a_guard = false; + + // Notify the callback that we are going to close the transport + let callback = zwrite!(self.callback).take(); + if let Some(cb) = callback.as_ref() { + cb.closing(); + } + + // Delete the transport on the manager + let _ = self.manager.del_transport_unicast(&self.config.zid).await; + + // Close and drop the link + self.stop_keepalive().await; + self.stop_rx().await; + let _ = zasyncread!(self.link).close().await; + + // Notify the callback that we have closed the transport + if let Some(cb) = callback.as_ref() { + cb.closed(); + } + + Ok(()) + } +} + +#[async_trait] +impl TransportUnicastTrait for TransportUnicastShm { + /*************************************/ + /* ACCESSORS */ + /*************************************/ + fn set_callback(&self, callback: Arc) { + let mut guard = zwrite!(self.callback); + *guard = Some(callback); + } + + async fn get_alive(&self) -> AsyncMutexGuard<'_, bool> { + zasynclock!(self.alive) + } + + fn get_links(&self) -> Vec { + let guard = async_std::task::block_on(async { zasyncread!(self.link) }); + [guard.clone()].to_vec() + } + + fn get_zid(&self) -> ZenohId { + self.config.zid + } + + fn get_whatami(&self) -> WhatAmI { + self.config.whatami + } + + #[cfg(feature = "shared-memory")] + fn is_shm(&self) -> bool { + self.config.is_shm + } + + fn is_qos(&self) -> bool { + self.config.is_qos + } + + fn get_callback(&self) -> Option> { + zread!(self.callback).clone() + } + + fn get_config(&self) -> &TransportConfigUnicast { + &self.config + } + + /*************************************/ + /* TX */ + /*************************************/ + fn schedule(&self, msg: NetworkMessage) -> ZResult<()> { + self.internal_schedule(msg) + } + + fn start_tx( + &self, + _link: &LinkUnicast, + executor: &TransportExecutor, + keep_alive: Duration, + _batch_size: u16, + ) -> ZResult<()> { + self.start_keepalive(executor, keep_alive); + Ok(()) + } + + fn start_rx(&self, _link: &LinkUnicast, lease: Duration, batch_size: u16) -> ZResult<()> { + self.internal_start_rx(lease, batch_size); + Ok(()) + } + + /*************************************/ + /* LINK */ + /*************************************/ + async fn add_link(&self, link: LinkUnicast, _direction: LinkUnicastDirection) -> ZResult<()> { + log::trace!("Adding link: {}", link); + + #[cfg(not(feature = "transport_shm"))] + bail!( + "Can not add Link {} with peer {}: link already exists and only unique link is supported!", + link, + self.config.zid, + ); + + #[cfg(feature = "transport_shm")] + { + let guard = zasyncread_upgradable!(self.link); + + let shm_protocol = "shm"; + let existing_shm = guard.get_dst().protocol().as_str() == shm_protocol; + let new_shm = link.get_dst().protocol().as_str() == shm_protocol; + match (existing_shm, new_shm) { + (false, true) => { + // SHM transport suports only a single link, but code here also handles upgrade from non-shm link to shm link! + log::trace!( + "Upgrading {} SHM transport's link from {} to {}", + self.config.zid, + guard, + link + ); + + // Prepare and send close message on old link + { + let close = TransportMessageShm { + body: TransportBodyShm::Close(Close { + reason: 0, + session: false, + }), + }; + let _ = send_with_link(&guard, close).await; + }; + // Notify the callback + if let Some(callback) = zread!(self.callback).as_ref() { + callback.del_link(Link::from(guard.clone())); + } + + // Set the new link + let mut write_guard = RwLockUpgradableReadGuard::upgrade(guard).await; + *write_guard = link; + + Ok(()) + } + _ => { + let e = zerror!( + "Can not add Link {} with peer {}: link already exists and only unique link is supported!", + link, + self.config.zid, + ); + Err(e.into()) + } + } + } + } + + /*************************************/ + /* INITIATION */ + /*************************************/ + async fn sync(&self, _initial_sn_rx: TransportSn) -> ZResult<()> { + // Mark the transport as alive + let mut a_guard = zasynclock!(self.alive); + if *a_guard { + let e = zerror!("Transport already synched with peer: {}", self.config.zid); + log::trace!("{}", e); + return Err(e.into()); + } + + *a_guard = true; + + Ok(()) + } + + /*************************************/ + /* TERMINATION */ + /*************************************/ + async fn close_link(&self, link: &LinkUnicast, reason: u8) -> ZResult<()> { + log::trace!("Closing link {} with peer: {}", link, self.config.zid); + self.finalize(reason).await + } + + async fn close(&self, reason: u8) -> ZResult<()> { + log::trace!("Closing transport with peer: {}", self.config.zid); + self.finalize(reason).await + } +} diff --git a/io/zenoh-transport/src/unicast/shm/tx.rs b/io/zenoh-transport/src/unicast/shm/tx.rs new file mode 100644 index 0000000000..d54b4281dd --- /dev/null +++ b/io/zenoh-transport/src/unicast/shm/tx.rs @@ -0,0 +1,79 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use super::transport::TransportUnicastShm; +#[cfg(feature = "stats")] +use zenoh_buffers::SplitBuffer; +#[cfg(feature = "stats")] +use zenoh_protocol::zenoh::ZenohBody; +use zenoh_protocol::{ + network::NetworkMessage, + transport::{TransportBodyShm, TransportMessageShm}, +}; +use zenoh_result::{bail, ZResult}; + +impl TransportUnicastShm { + #[allow(unused_mut)] // When feature "shared-memory" is not enabled + #[allow(clippy::let_and_return)] // When feature "stats" is not enabled + #[inline(always)] + pub(crate) fn internal_schedule(&self, mut msg: NetworkMessage) -> ZResult<()> { + #[cfg(feature = "shared-memory")] + { + let res = if self.config.is_shm { + crate::shm::map_zmsg_to_shminfo(&mut msg) + } else { + crate::shm::map_zmsg_to_shmbuf(&mut msg, &self.manager.shm().reader) + }; + if let Err(e) = res { + bail!("Failed SHM conversion: {}", e); + } + } + + #[cfg(feature = "stats")] + match &msg.body { + ZenohBody::Data(data) => match data.reply_context { + Some(_) => { + self.stats.inc_tx_z_data_reply_msgs(1); + self.stats + .inc_tx_z_data_reply_payload_bytes(data.payload.len()); + } + None => { + self.stats.inc_tx_z_data_msgs(1); + self.stats.inc_tx_z_data_payload_bytes(data.payload.len()); + } + }, + ZenohBody::Unit(unit) => match unit.reply_context { + Some(_) => self.stats.inc_tx_z_unit_reply_msgs(1), + None => self.stats.inc_tx_z_unit_msgs(1), + }, + ZenohBody::Pull(_) => self.stats.inc_tx_z_pull_msgs(1), + ZenohBody::Query(_) => self.stats.inc_tx_z_query_msgs(1), + ZenohBody::Declare(_) => self.stats.inc_tx_z_declare_msgs(1), + ZenohBody::LinkStateList(_) => self.stats.inc_tx_z_linkstate_msgs(1), + } + + let msg = TransportMessageShm { + body: TransportBodyShm::Network(Box::new(msg)), + }; + let res = self.send(msg); + + #[cfg(feature = "stats")] + if res { + self.stats.inc_tx_z_msgs(1); + } else { + self.stats.inc_tx_z_dropped(1); + } + + res + } +} diff --git a/io/zenoh-transport/src/unicast/test_helpers.rs b/io/zenoh-transport/src/unicast/test_helpers.rs new file mode 100644 index 0000000000..8e054e977a --- /dev/null +++ b/io/zenoh-transport/src/unicast/test_helpers.rs @@ -0,0 +1,50 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use zenoh_core::zcondfeat; + +use crate::{TransportManager, TransportManagerBuilderUnicast}; + +pub fn make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] max_links: usize, + #[cfg(feature = "shared-memory")] shm_transport: bool, +) -> TransportManagerBuilderUnicast { + let transport = make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] + shm_transport, + ); + + zcondfeat!( + "transport_multilink", + { + println!("...with max links: {}...", max_links); + transport.max_links(max_links) + }, + transport + ) +} + +pub fn make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] shm_transport: bool, +) -> TransportManagerBuilderUnicast { + println!("Create transport manager builder..."); + zcondfeat!( + "shared-memory", + { + println!("...with SHM..."); + TransportManager::config_unicast().shm(shm_transport) + }, + TransportManager::config_unicast() + ) +} diff --git a/io/zenoh-transport/src/unicast/transport_unicast_inner.rs b/io/zenoh-transport/src/unicast/transport_unicast_inner.rs new file mode 100644 index 0000000000..83e7b22dbe --- /dev/null +++ b/io/zenoh-transport/src/unicast/transport_unicast_inner.rs @@ -0,0 +1,87 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::{fmt::DebugStruct, sync::Arc, time::Duration}; + +use async_std::sync::MutexGuard as AsyncMutexGuard; +use async_trait::async_trait; +use zenoh_link::{LinkUnicast, LinkUnicastDirection}; +use zenoh_protocol::{ + core::{WhatAmI, ZenohId}, + network::NetworkMessage, + transport::TransportSn, +}; +use zenoh_result::ZResult; + +use crate::{TransportConfigUnicast, TransportExecutor, TransportPeerEventHandler}; + +/*************************************/ +/* UNICAST TRANSPORT TRAIT */ +/*************************************/ +#[async_trait] +pub(crate) trait TransportUnicastTrait: Send + Sync { + /*************************************/ + /* ACCESSORS */ + /*************************************/ + fn set_callback(&self, callback: Arc); + async fn get_alive(&self) -> AsyncMutexGuard<'_, bool>; + fn get_zid(&self) -> ZenohId; + fn get_whatami(&self) -> WhatAmI; + fn get_callback(&self) -> Option>; + fn get_links(&self) -> Vec; + #[cfg(feature = "shared-memory")] + fn is_shm(&self) -> bool; + fn is_qos(&self) -> bool; + fn get_config(&self) -> &TransportConfigUnicast; + + /*************************************/ + /* LINK */ + /*************************************/ + async fn add_link(&self, link: LinkUnicast, direction: LinkUnicastDirection) -> ZResult<()>; + + /*************************************/ + /* TX */ + /*************************************/ + fn schedule(&self, msg: NetworkMessage) -> ZResult<()>; + fn start_tx( + &self, + link: &LinkUnicast, + executor: &TransportExecutor, + keep_alive: Duration, + batch_size: u16, + ) -> ZResult<()>; + + /*************************************/ + /* RX */ + /*************************************/ + fn start_rx(&self, link: &LinkUnicast, lease: Duration, batch_size: u16) -> ZResult<()>; + + /*************************************/ + /* INITIATION */ + /*************************************/ + async fn sync(&self, _initial_sn_rx: TransportSn) -> ZResult<()>; + + /*************************************/ + /* TERMINATION */ + /*************************************/ + async fn close_link(&self, link: &LinkUnicast, reason: u8) -> ZResult<()>; + async fn close(&self, reason: u8) -> ZResult<()>; + + fn add_debug_fields<'a, 'b: 'a, 'c>( + &self, + s: &'c mut DebugStruct<'a, 'b>, + ) -> &'c mut DebugStruct<'a, 'b> { + s + } +} diff --git a/io/zenoh-transport/tests/endpoints.rs b/io/zenoh-transport/tests/endpoints.rs index 2072002b62..089f8cc7f9 100644 --- a/io/zenoh-transport/tests/endpoints.rs +++ b/io/zenoh-transport/tests/endpoints.rs @@ -179,6 +179,24 @@ fn endpoint_ws() { task::block_on(run(&endpoints)); } +#[cfg(feature = "transport_shm")] +#[test] +fn endpoint_shm() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoints: Vec = vec![ + "shm/endpoint_shm".parse().unwrap(), + "shm/endpoint_shm2".parse().unwrap(), + "shm/endpoint_shm3".parse().unwrap(), + "shm/endpoint_shm4".parse().unwrap(), + ]; + task::block_on(run(&endpoints)); +} + #[cfg(all(feature = "transport_tcp", feature = "transport_udp"))] #[test] fn endpoint_tcp_udp() { diff --git a/io/zenoh-transport/tests/transport_whitelist.rs b/io/zenoh-transport/tests/transport_whitelist.rs index d589ed24cf..338cf12429 100644 --- a/io/zenoh-transport/tests/transport_whitelist.rs +++ b/io/zenoh-transport/tests/transport_whitelist.rs @@ -137,3 +137,21 @@ fn transport_whitelist_tcp() { // Run task::block_on(run(&endpoints)); } + +#[cfg(feature = "transport_shm")] +#[test] +#[ignore] +fn transport_whitelist_shm() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoints: Vec = vec![ + "shm/transport_whitelist_shm".parse().unwrap(), + "shm/transport_whitelist_shm2".parse().unwrap(), + ]; + // Run + task::block_on(run(&endpoints)); +} diff --git a/io/zenoh-transport/tests/unicast_authenticator.rs b/io/zenoh-transport/tests/unicast_authenticator.rs index aaf4376aba..33b35d52d2 100644 --- a/io/zenoh-transport/tests/unicast_authenticator.rs +++ b/io/zenoh-transport/tests/unicast_authenticator.rs @@ -107,8 +107,9 @@ impl TransportEventHandler for SHClientAuthenticator { } #[cfg(feature = "auth_pubkey")] -async fn auth_pubkey(endpoint: &EndPoint) { +async fn auth_pubkey(endpoint: &EndPoint, #[cfg(feature = "shared-memory")] shm_transport: bool) { use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; + use zenoh_transport::test_helpers::make_basic_transport_manager_builder; use zenoh_transport::unicast::establishment::ext::auth::AuthPubKey; use zenoh_transport::TransportManager; @@ -158,7 +159,11 @@ async fn auth_pubkey(endpoint: &EndPoint) { client01_pub_key.clone().into(), client01_pri_key.into(), ))); - let unicast = TransportManager::config_unicast().authenticator(auth); + let unicast = make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .authenticator(auth); let client01_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client01_id) @@ -212,7 +217,11 @@ async fn auth_pubkey(endpoint: &EndPoint) { client02_pub_key.clone().into(), client02_pri_key.clone().into(), ))); - let unicast = TransportManager::config_unicast().authenticator(auth); + let unicast = make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .authenticator(auth); let client02_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client02_id) @@ -227,7 +236,11 @@ async fn auth_pubkey(endpoint: &EndPoint) { client02_pub_key.clone().into(), client02_pri_key.clone().into(), ))); - let unicast = TransportManager::config_unicast().authenticator(auth); + let unicast = make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .authenticator(auth); let client03_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client03_id) @@ -283,7 +296,11 @@ async fn auth_pubkey(endpoint: &EndPoint) { .unwrap(); let mut auth = Auth::empty(); auth.set_pubkey(Some(auth_pubkey)); - let unicast = TransportManager::config_unicast().authenticator(auth); + let unicast = make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .authenticator(auth); let router_manager = TransportManager::builder() .whatami(WhatAmI::Router) .zid(router_id) @@ -389,7 +406,8 @@ async fn auth_pubkey(endpoint: &EndPoint) { } #[cfg(feature = "auth_usrpwd")] -async fn auth_usrpwd(endpoint: &EndPoint) { +async fn auth_usrpwd(endpoint: &EndPoint, #[cfg(feature = "shared-memory")] shm_transport: bool) { + use zenoh_transport::test_helpers::make_basic_transport_manager_builder; use zenoh_transport::unicast::establishment::ext::auth::AuthUsrPwd; use zenoh_transport::TransportManager; @@ -422,7 +440,11 @@ async fn auth_usrpwd(endpoint: &EndPoint) { let mut auth_router = Auth::empty(); auth_router.set_usrpwd(Some(auth_usrpwd_router)); - let unicast = TransportManager::config_unicast().authenticator(auth_router); + let unicast = make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .authenticator(auth_router); let router_manager = TransportManager::builder() .whatami(WhatAmI::Router) .zid(router_id) @@ -435,7 +457,11 @@ async fn auth_usrpwd(endpoint: &EndPoint) { AuthUsrPwd::new(Some((user01.clone().into(), password01.clone().into()))); let mut auth_client01 = Auth::empty(); auth_client01.set_usrpwd(Some(auth_usrpwdr_client01)); - let unicast = TransportManager::config_unicast().authenticator(auth_client01); + let unicast = make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .authenticator(auth_client01); let client01_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client01_id) @@ -448,7 +474,11 @@ async fn auth_usrpwd(endpoint: &EndPoint) { AuthUsrPwd::new(Some((user02.clone().into(), password02.clone().into()))); let mut auth_client02 = Auth::empty(); auth_client02.set_usrpwd(Some(auth_usrpwdr_client02)); - let unicast = TransportManager::config_unicast().authenticator(auth_client02); + let unicast = make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .authenticator(auth_client02); let client02_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client02_id) @@ -461,7 +491,11 @@ async fn auth_usrpwd(endpoint: &EndPoint) { AuthUsrPwd::new(Some((user03.clone().into(), password03.clone().into()))); let mut auth_client03 = Auth::empty(); auth_client03.set_usrpwd(Some(auth_usrpwdr_client03)); - let unicast = TransportManager::config_unicast().authenticator(auth_client03); + let unicast = make_basic_transport_manager_builder( + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .authenticator(auth_client03); let client03_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client03_id) @@ -575,11 +609,35 @@ async fn auth_usrpwd(endpoint: &EndPoint) { task::sleep(SLEEP).await; } -async fn run(endpoint: &EndPoint) { +async fn run(endpoint: &EndPoint, #[cfg(feature = "shared-memory")] shm_transport: bool) { #[cfg(feature = "auth_pubkey")] - auth_pubkey(endpoint).await; + auth_pubkey( + endpoint, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .await; #[cfg(feature = "auth_usrpwd")] - auth_usrpwd(endpoint).await; + auth_usrpwd( + endpoint, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .await; +} + +async fn run_with_net(endpoint: &EndPoint) { + run( + endpoint, + #[cfg(feature = "shared-memory")] + false, + ) + .await +} + +#[cfg(feature = "shared-memory")] +async fn run_with_shm(endpoint: &EndPoint) { + run(endpoint, true).await } #[cfg(feature = "transport_tcp")] @@ -591,7 +649,19 @@ fn authenticator_tcp() { }); let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 8000).parse().unwrap(); - task::block_on(run(&endpoint)); + task::block_on(run_with_net(&endpoint)); +} + +#[cfg(all(feature = "transport_tcp", feature = "shared-memory"))] +#[test] +fn authenticator_tcp_with_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 8100).parse().unwrap(); + task::block_on(run_with_shm(&endpoint)); } #[cfg(feature = "transport_udp")] @@ -603,11 +673,50 @@ fn authenticator_udp() { }); let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 8010).parse().unwrap(); - task::block_on(run(&endpoint)); + task::block_on(run_with_net(&endpoint)); +} + +#[cfg(all(feature = "transport_udp", feature = "shared-memory"))] +#[test] +fn authenticator_udp_with_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 8110).parse().unwrap(); + task::block_on(run_with_shm(&endpoint)); +} + +#[cfg(feature = "transport_shm")] +#[test] +#[ignore] +fn authenticator_shm() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = "shm/authenticator_shm_test".parse().unwrap(); + task::block_on(run_with_net(&endpoint)); +} + +#[cfg(all(feature = "transport_shm", feature = "shared-memory"))] +#[test] +#[ignore] +fn authenticator_shm_with_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = "shm/authenticator_shm_with_shm_transport".parse().unwrap(); + task::block_on(run_with_shm(&endpoint)); } #[cfg(feature = "transport_ws")] #[test] +#[ignore] fn authenticator_ws() { let _ = env_logger::try_init(); task::block_on(async { @@ -615,7 +724,20 @@ fn authenticator_ws() { }); let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 8020).parse().unwrap(); - task::block_on(run(&endpoint)); + task::block_on(run_with_net(&endpoint)); +} + +#[cfg(all(feature = "transport_ws", feature = "shared-memory"))] +#[test] +#[ignore] +fn authenticator_ws_with_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 8120).parse().unwrap(); + task::block_on(run_with_shm(&endpoint)); } #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] @@ -629,7 +751,7 @@ fn authenticator_unix() { let f1 = "zenoh-test-unix-socket-10.sock"; let _ = std::fs::remove_file(f1); let endpoint: EndPoint = format!("unixsock-stream/{f1}").parse().unwrap(); - task::block_on(run(&endpoint)); + task::block_on(run_with_net(&endpoint)); let _ = std::fs::remove_file(f1); let _ = std::fs::remove_file(format!("{f1}.lock")); } @@ -734,7 +856,7 @@ R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== ) .unwrap(); - task::block_on(run(&endpoint)); + task::block_on(run_with_net(&endpoint)); } #[cfg(feature = "transport_quic")] @@ -837,5 +959,5 @@ R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== ) .unwrap(); - task::block_on(run(&endpoint)); + task::block_on(run_with_net(&endpoint)); } diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index 81a912defc..4bda1aa6a1 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -387,6 +387,7 @@ fn transport_tcp_concurrent() { #[cfg(feature = "transport_ws")] #[test] +#[ignore] fn transport_ws_concurrent() { let _ = env_logger::try_init(); task::block_on(async { @@ -418,3 +419,38 @@ fn transport_ws_concurrent() { transport_concurrent(endpoint01, endpoint02).await; }); } + +#[cfg(feature = "transport_shm")] +#[test] +#[ignore] +fn transport_shm_concurrent() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint01: Vec = vec![ + "shm/transport_shm_concurrent".parse().unwrap(), + "shm/transport_shm_concurrent2".parse().unwrap(), + "shm/transport_shm_concurrent3".parse().unwrap(), + "shm/transport_shm_concurrent4".parse().unwrap(), + "shm/transport_shm_concurrent5".parse().unwrap(), + "shm/transport_shm_concurrent6".parse().unwrap(), + "shm/transport_shm_concurrent7".parse().unwrap(), + "shm/transport_shm_concurrent8".parse().unwrap(), + ]; + let endpoint02: Vec = vec![ + "shm/transport_shm_concurrent9".parse().unwrap(), + "shm/transport_shm_concurrent10".parse().unwrap(), + "shm/transport_shm_concurrent11".parse().unwrap(), + "shm/transport_shm_concurrent12".parse().unwrap(), + "shm/transport_shm_concurrent13".parse().unwrap(), + "shm/transport_shm_concurrent14".parse().unwrap(), + "shm/transport_shm_concurrent15".parse().unwrap(), + "shm/transport_shm_concurrent16".parse().unwrap(), + ]; + + task::block_on(async { + transport_concurrent(endpoint01, endpoint02).await; + }); +} diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index 1c6fe39395..c4e8e07a13 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -173,6 +173,7 @@ fn transport_unicast_defragmentation_tcp_only() { #[cfg(feature = "transport_ws")] #[test] +#[ignore] fn transport_unicast_defragmentation_ws_only() { let _ = env_logger::try_init(); task::block_on(async { @@ -207,3 +208,43 @@ fn transport_unicast_defragmentation_ws_only() { } }); } + +#[cfg(feature = "transport_shm")] +#[test] +#[ignore] +fn transport_unicast_defragmentation_shm_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoint: EndPoint = "shm/transport_unicast_defragmentation_shm_only" + .parse() + .unwrap(); + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(async { + for ch in channel.iter() { + run(&endpoint, *ch, MSG_SIZE).await; + } + }); +} diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index 8949fb05cf..41b60caec7 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -33,6 +33,7 @@ use zenoh_protocol::{ zenoh_new::Put, }; use zenoh_result::ZResult; +use zenoh_transport::test_helpers::make_transport_manager_builder; use zenoh_transport::{ DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportMulticast, TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, @@ -146,15 +147,22 @@ impl TransportPeerEventHandler for SCClient { } } -async fn transport_intermittent(endpoint: &EndPoint) { +async fn transport_intermittent( + endpoint: &EndPoint, + #[cfg(feature = "shared-memory")] shm_transport: bool, +) { /* [ROUTER] */ let router_id = ZenohId::try_from([1]).unwrap(); let router_handler = Arc::new(SHRouterIntermittent); // Create the router transport manager - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(3); + let unicast = make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] + 1, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .max_sessions(3); let router_manager = TransportManager::builder() .whatami(WhatAmI::Router) .zid(router_id) @@ -169,9 +177,13 @@ async fn transport_intermittent(endpoint: &EndPoint) { // Create the transport transport manager for the first client let counter = Arc::new(AtomicUsize::new(0)); - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(3); + let unicast = make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] + 1, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .max_sessions(3); let client01_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client01_id) @@ -180,9 +192,13 @@ async fn transport_intermittent(endpoint: &EndPoint) { .unwrap(); // Create the transport transport manager for the second client - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(1); + let unicast = make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] + 1, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .max_sessions(1); let client02_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client02_id) @@ -191,9 +207,13 @@ async fn transport_intermittent(endpoint: &EndPoint) { .unwrap(); // Create the transport transport manager for the third client - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(1); + let unicast = make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] + 1, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .max_sessions(1); let client03_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client03_id) @@ -386,6 +406,20 @@ async fn transport_intermittent(endpoint: &EndPoint) { task::sleep(SLEEP).await; } +async fn net_transport_intermittent(endpoint: &EndPoint) { + transport_intermittent( + endpoint, + #[cfg(feature = "shared-memory")] + false, + ) + .await +} + +#[cfg(feature = "shared-memory")] +async fn shm_transport_intermittent(endpoint: &EndPoint) { + transport_intermittent(endpoint, true).await +} + #[cfg(feature = "transport_tcp")] #[test] fn transport_tcp_intermittent() { @@ -395,11 +429,24 @@ fn transport_tcp_intermittent() { }); let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 12000).parse().unwrap(); - task::block_on(transport_intermittent(&endpoint)); + task::block_on(net_transport_intermittent(&endpoint)); +} + +#[cfg(all(feature = "transport_tcp", feature = "shared-memory"))] +#[test] +fn transport_tcp_intermittent_for_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 12100).parse().unwrap(); + task::block_on(shm_transport_intermittent(&endpoint)); } #[cfg(feature = "transport_ws")] #[test] +#[ignore] fn transport_ws_intermittent() { let _ = env_logger::try_init(); task::block_on(async { @@ -407,5 +454,46 @@ fn transport_ws_intermittent() { }); let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 12010).parse().unwrap(); - task::block_on(transport_intermittent(&endpoint)); + task::block_on(net_transport_intermittent(&endpoint)); +} + +#[cfg(all(feature = "transport_ws", feature = "shared-memory"))] +#[test] +#[ignore] +fn transport_ws_intermittent_for_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 12110).parse().unwrap(); + task::block_on(shm_transport_intermittent(&endpoint)); +} + +#[cfg(feature = "transport_shm")] +#[test] +#[ignore] +fn transport_shm_intermittent() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = "shm/transport_shm_intermittent".parse().unwrap(); + task::block_on(net_transport_intermittent(&endpoint)); +} + +#[cfg(all(feature = "transport_shm", feature = "shared-memory"))] +#[test] +#[ignore] +fn transport_shm_intermittent_for_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = "shm/transport_shm_intermittent_for_shm_transport" + .parse() + .unwrap(); + task::block_on(shm_transport_intermittent(&endpoint)); } diff --git a/io/zenoh-transport/tests/unicast_multilink.rs b/io/zenoh-transport/tests/unicast_multilink.rs index 8583482e7e..fcfb6cd492 100644 --- a/io/zenoh-transport/tests/unicast_multilink.rs +++ b/io/zenoh-transport/tests/unicast_multilink.rs @@ -489,7 +489,7 @@ mod tests { zasync_executor_init!(); }); - let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 13000).parse().unwrap(); + let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 18000).parse().unwrap(); task::block_on(multilink_transport(&endpoint)); } @@ -501,24 +501,39 @@ mod tests { zasync_executor_init!(); }); - let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 13010).parse().unwrap(); + let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 18010).parse().unwrap(); task::block_on(multilink_transport(&endpoint)); } #[cfg(feature = "transport_ws")] #[test] + #[ignore] fn multilink_ws_only() { let _ = env_logger::try_init(); task::block_on(async { zasync_executor_init!(); }); - let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 13020).parse().unwrap(); + let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 18020).parse().unwrap(); + task::block_on(multilink_transport(&endpoint)); + } + + #[cfg(feature = "transport_shm")] + #[test] + #[ignore] + fn multilink_shm_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = "shm/multilink_shm_only".parse().unwrap(); task::block_on(multilink_transport(&endpoint)); } #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] #[test] + #[ignore] fn multilink_unix_only() { let _ = env_logger::try_init(); task::block_on(async { @@ -618,7 +633,7 @@ Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== -----END CERTIFICATE-----"; - let mut endpoint: EndPoint = format!("tls/localhost:{}", 13030).parse().unwrap(); + let mut endpoint: EndPoint = format!("tls/localhost:{}", 18030).parse().unwrap(); endpoint .config_mut() .extend( @@ -720,7 +735,7 @@ R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== -----END CERTIFICATE-----"; // Define the locator - let mut endpoint: EndPoint = format!("quic/localhost:{}", 13040).parse().unwrap(); + let mut endpoint: EndPoint = format!("quic/localhost:{}", 18040).parse().unwrap(); endpoint .config_mut() .extend( diff --git a/io/zenoh-transport/tests/unicast_openclose.rs b/io/zenoh-transport/tests/unicast_openclose.rs index eddad39cea..b992a747a3 100644 --- a/io/zenoh-transport/tests/unicast_openclose.rs +++ b/io/zenoh-transport/tests/unicast_openclose.rs @@ -13,13 +13,14 @@ // use async_std::{prelude::FutureExt, task}; use std::{convert::TryFrom, sync::Arc, time::Duration}; -use zenoh_core::zasync_executor_init; +use zenoh_core::{zasync_executor_init, zcondfeat}; use zenoh_link::EndPoint; use zenoh_protocol::core::{WhatAmI, ZenohId}; use zenoh_result::ZResult; use zenoh_transport::{ - DummyTransportPeerEventHandler, TransportEventHandler, TransportManager, TransportMulticast, - TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, + test_helpers::make_transport_manager_builder, DummyTransportPeerEventHandler, + TransportEventHandler, TransportManager, TransportMulticast, TransportMulticastEventHandler, + TransportPeer, TransportPeerEventHandler, TransportUnicast, }; const TIMEOUT: Duration = Duration::from_secs(60); @@ -78,15 +79,22 @@ impl TransportEventHandler for SHClientOpenClose { } } -async fn openclose_transport(endpoint: &EndPoint) { +async fn openclose_transport( + endpoint: &EndPoint, + #[cfg(feature = "shared-memory")] shm_transport: bool, +) { /* [ROUTER] */ let router_id = ZenohId::try_from([1]).unwrap(); let router_handler = Arc::new(SHRouterOpenClose); // Create the router transport manager - let unicast = TransportManager::config_unicast() - .max_links(2) - .max_sessions(1); + let unicast = make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] + 2, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .max_sessions(1); let router_manager = TransportManager::builder() .whatami(WhatAmI::Router) .zid(router_id) @@ -99,9 +107,13 @@ async fn openclose_transport(endpoint: &EndPoint) { let client02_id = ZenohId::try_from([3]).unwrap(); // Create the transport transport manager for the first client - let unicast = TransportManager::config_unicast() - .max_links(2) - .max_sessions(1); + let unicast = make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] + 2, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .max_sessions(1); let client01_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client01_id) @@ -110,9 +122,13 @@ async fn openclose_transport(endpoint: &EndPoint) { .unwrap(); // Create the transport transport manager for the second client - let unicast = TransportManager::config_unicast() - .max_links(1) - .max_sessions(1); + let unicast = make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] + 1, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .max_sessions(1); let client02_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client02_id) @@ -141,7 +157,7 @@ async fn openclose_transport(endpoint: &EndPoint) { assert!(res.is_ok()); let c_ses1 = res.unwrap(); println!("Transport Open Close [1d1]"); - let transports = client01_manager.get_transports_unicast().await; + let transports = ztimeout!(client01_manager.get_transports_unicast()); println!("Transport Open Close [1d2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); @@ -154,7 +170,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [1f1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports_unicast().await; + let transports = ztimeout!(router_manager.get_transports_unicast()); let s = transports .iter() .find(|s| s.get_zid().unwrap() == client01_id); @@ -173,41 +189,46 @@ async fn openclose_transport(endpoint: &EndPoint) { /* [2] */ // Open a second transport from the client to the router // -> This should be accepted - links_num = 2; - - println!("\nTransport Open Close [2a1]"); - let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); - println!("Transport Open Close [2a2]: {res:?}"); - assert!(res.is_ok()); - let c_ses2 = res.unwrap(); - println!("Transport Open Close [2b1]"); - let transports = client01_manager.get_transports_unicast().await; - println!("Transport Open Close [2b2]: {transports:?}"); - assert_eq!(transports.len(), 1); - assert_eq!(c_ses2.get_zid().unwrap(), router_id); - println!("Transport Open Close [2c1]"); - let links = c_ses2.get_links().unwrap(); - println!("Transport Open Close [2c2]: {links:?}"); - assert_eq!(links.len(), links_num); - assert_eq!(c_ses2, c_ses1); - - // Verify that the transport has been open on the router - println!("Transport Open Close [2d1]"); - ztimeout!(async { - loop { - let transports = router_manager.get_transports_unicast().await; - let s = transports - .iter() - .find(|s| s.get_zid().unwrap() == client01_id) - .unwrap(); - - let links = s.get_links().unwrap(); - if links.len() == links_num { - break; + // (this stage is ignored for SHM transport, because it supports only one link) + if zcondfeat!("shared-memory", !shm_transport, true) { + links_num = 2; + + println!("\nTransport Open Close [2a1]"); + let res = ztimeout!(client01_manager.open_transport_unicast(endpoint.clone())); + println!("Transport Open Close [2a2]: {res:?}"); + assert!(res.is_ok()); + let c_ses2 = res.unwrap(); + println!("Transport Open Close [2b1]"); + let transports = ztimeout!(client01_manager.get_transports_unicast()); + println!("Transport Open Close [2b2]: {transports:?}"); + assert_eq!(transports.len(), 1); + assert_eq!(c_ses2.get_zid().unwrap(), router_id); + println!("Transport Open Close [2c1]"); + let links = c_ses2.get_links().unwrap(); + println!("Transport Open Close [2c2]: {links:?}"); + assert_eq!(links.len(), links_num); + assert_eq!(c_ses2, c_ses1); + + // Verify that the transport has been open on the router + println!("Transport Open Close [2d1]"); + ztimeout!(async { + loop { + let transports = ztimeout!(router_manager.get_transports_unicast()); + let s = transports + .iter() + .find(|s| s.get_zid().unwrap() == client01_id) + .unwrap(); + + let links = s.get_links().unwrap(); + if links.len() == links_num { + break; + } + task::sleep(SLEEP).await; } - task::sleep(SLEEP).await; - } - }); + }); + } else { + println!("\nTransport Open Close [2a*]: step ignored for SHM transport!"); + } /* [3] */ // Open transport -> This should be rejected because @@ -217,7 +238,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [3a2]: {res:?}"); assert!(res.is_err()); println!("Transport Open Close [3b1]"); - let transports = client01_manager.get_transports_unicast().await; + let transports = ztimeout!(client01_manager.get_transports_unicast()); println!("Transport Open Close [3b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses1.get_zid().unwrap(), router_id); @@ -230,7 +251,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [3d1]"); ztimeout!(async { task::sleep(SLEEP).await; - let transports = router_manager.get_transports_unicast().await; + let transports = ztimeout!(router_manager.get_transports_unicast()); assert_eq!(transports.len(), 1); let s = transports .iter() @@ -247,7 +268,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [4a2]: {res:?}"); assert!(res.is_ok()); println!("Transport Open Close [4b1]"); - let transports = client01_manager.get_transports_unicast().await; + let transports = ztimeout!(client01_manager.get_transports_unicast()); println!("Transport Open Close [4b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -255,7 +276,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [4c1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports_unicast().await; + let transports = ztimeout!(router_manager.get_transports_unicast()); let index = transports .iter() .find(|s| s.get_zid().unwrap() == client01_id); @@ -277,7 +298,7 @@ async fn openclose_transport(endpoint: &EndPoint) { assert!(res.is_ok()); let c_ses3 = res.unwrap(); println!("Transport Open Close [5b1]"); - let transports = client01_manager.get_transports_unicast().await; + let transports = ztimeout!(client01_manager.get_transports_unicast()); println!("Transport Open Close [5b2]: {transports:?}"); assert_eq!(transports.len(), 1); assert_eq!(c_ses3.get_zid().unwrap(), router_id); @@ -290,7 +311,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [5d1]"); ztimeout!(async { task::sleep(SLEEP).await; - let transports = router_manager.get_transports_unicast().await; + let transports = ztimeout!(router_manager.get_transports_unicast()); assert_eq!(transports.len(), 1); let s = transports .iter() @@ -308,7 +329,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [6a2]: {res:?}"); assert!(res.is_err()); println!("Transport Open Close [6b1]"); - let transports = client02_manager.get_transports_unicast().await; + let transports = ztimeout!(client02_manager.get_transports_unicast()); println!("Transport Open Close [6b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -316,7 +337,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [6c1]"); ztimeout!(async { task::sleep(SLEEP).await; - let transports = router_manager.get_transports_unicast().await; + let transports = ztimeout!(router_manager.get_transports_unicast()); assert_eq!(transports.len(), 1); let s = transports .iter() @@ -333,7 +354,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [7a2]: {res:?}"); assert!(res.is_ok()); println!("Transport Open Close [7b1]"); - let transports = client01_manager.get_transports_unicast().await; + let transports = ztimeout!(client01_manager.get_transports_unicast()); println!("Transport Open Close [7b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -341,7 +362,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [7c1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports_unicast().await; + let transports = ztimeout!(router_manager.get_transports_unicast()); if transports.is_empty() { break; } @@ -360,7 +381,7 @@ async fn openclose_transport(endpoint: &EndPoint) { assert!(res.is_ok()); let c_ses4 = res.unwrap(); println!("Transport Open Close [8b1]"); - let transports = client02_manager.get_transports_unicast().await; + let transports = ztimeout!(client02_manager.get_transports_unicast()); println!("Transport Open Close [8b2]: {transports:?}"); assert_eq!(transports.len(), 1); println!("Transport Open Close [8c1]"); @@ -372,7 +393,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [8d1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports_unicast().await; + let transports = ztimeout!(router_manager.get_transports_unicast()); let s = transports .iter() .find(|s| s.get_zid().unwrap() == client02_id); @@ -394,7 +415,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [9a2]: {res:?}"); assert!(res.is_ok()); println!("Transport Open Close [9b1]"); - let transports = client02_manager.get_transports_unicast().await; + let transports = ztimeout!(client02_manager.get_transports_unicast()); println!("Transport Open Close [9b2]: {transports:?}"); assert_eq!(transports.len(), 0); @@ -402,7 +423,7 @@ async fn openclose_transport(endpoint: &EndPoint) { println!("Transport Open Close [9c1]"); ztimeout!(async { loop { - let transports = router_manager.get_transports_unicast().await; + let transports = ztimeout!(router_manager.get_transports_unicast()); if transports.is_empty() { break; } @@ -434,6 +455,20 @@ async fn openclose_transport(endpoint: &EndPoint) { task::sleep(SLEEP).await; } +async fn openclose_net_transport(endpoint: &EndPoint) { + openclose_transport( + endpoint, + #[cfg(feature = "shared-memory")] + false, + ) + .await +} + +#[cfg(feature = "shared-memory")] +async fn openclose_shm_transport(endpoint: &EndPoint) { + openclose_transport(endpoint, true).await +} + #[cfg(feature = "transport_tcp")] #[test] fn openclose_tcp_only() { @@ -443,7 +478,19 @@ fn openclose_tcp_only() { }); let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 13000).parse().unwrap(); - task::block_on(openclose_transport(&endpoint)); + task::block_on(openclose_net_transport(&endpoint)); +} + +#[cfg(all(feature = "transport_tcp", feature = "shared-memory"))] +#[test] +fn openclose_tcp_only_with_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("tcp/127.0.0.1:{}", 13100).parse().unwrap(); + task::block_on(openclose_shm_transport(&endpoint)); } #[cfg(feature = "transport_udp")] @@ -455,11 +502,24 @@ fn openclose_udp_only() { }); let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 13010).parse().unwrap(); - task::block_on(openclose_transport(&endpoint)); + task::block_on(openclose_net_transport(&endpoint)); +} + +#[cfg(all(feature = "transport_udp", feature = "shared-memory"))] +#[test] +fn openclose_udp_only_with_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("udp/127.0.0.1:{}", 13110).parse().unwrap(); + task::block_on(openclose_shm_transport(&endpoint)); } #[cfg(feature = "transport_ws")] #[test] +#[ignore] fn openclose_ws_only() { let _ = env_logger::try_init(); task::block_on(async { @@ -467,11 +527,51 @@ fn openclose_ws_only() { }); let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 13020).parse().unwrap(); - task::block_on(openclose_transport(&endpoint)); + task::block_on(openclose_net_transport(&endpoint)); +} + +#[cfg(all(feature = "transport_ws", feature = "shared-memory"))] +#[test] +#[ignore] +fn openclose_ws_only_with_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 13120).parse().unwrap(); + task::block_on(openclose_shm_transport(&endpoint)); +} + +#[cfg(feature = "transport_shm")] +#[test] +#[ignore] +fn openclose_shm_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = "shm/openclose_shm_only".parse().unwrap(); + task::block_on(openclose_net_transport(&endpoint)); +} + +#[cfg(all(feature = "transport_shm", feature = "shared-memory"))] +#[test] +#[ignore] +fn openclose_shm_only_with_shm_transport() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = "shm/openclose_shm_only_with_shm_transport".parse().unwrap(); + task::block_on(openclose_shm_transport(&endpoint)); } #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] #[test] +#[ignore] fn openclose_unix_only() { let _ = env_logger::try_init(); task::block_on(async { @@ -481,7 +581,7 @@ fn openclose_unix_only() { let f1 = "zenoh-test-unix-socket-9.sock"; let _ = std::fs::remove_file(f1); let endpoint: EndPoint = format!("unixsock-stream/{f1}").parse().unwrap(); - task::block_on(openclose_transport(&endpoint)); + task::block_on(openclose_net_transport(&endpoint)); let _ = std::fs::remove_file(f1); let _ = std::fs::remove_file(format!("{f1}.lock")); } @@ -585,7 +685,7 @@ R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== ) .unwrap(); - task::block_on(openclose_transport(&endpoint)); + task::block_on(openclose_net_transport(&endpoint)); } #[cfg(feature = "transport_quic")] @@ -687,5 +787,5 @@ R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== ) .unwrap(); - task::block_on(openclose_transport(&endpoint)); + task::block_on(openclose_net_transport(&endpoint)); } diff --git a/io/zenoh-transport/tests/unicast_priorities.rs b/io/zenoh-transport/tests/unicast_priorities.rs index d76bbc69fc..13d8c4b55f 100644 --- a/io/zenoh-transport/tests/unicast_priorities.rs +++ b/io/zenoh-transport/tests/unicast_priorities.rs @@ -349,6 +349,20 @@ fn priorities_tcp_only() { task::block_on(run(&endpoints)); } +#[cfg(feature = "transport_shm")] +#[test] +#[ignore] +fn conduits_shm_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + // Define the locators + let endpoints: Vec = vec!["shm/conduits_shm_only".to_string().parse().unwrap()]; + // Run + task::block_on(run(&endpoints)); +} + #[cfg(feature = "transport_ws")] #[test] fn priorities_ws_only() { diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index 30a3bcfecf..930a139d85 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -377,4 +377,16 @@ mod tests { let endpoint: EndPoint = format!("ws/127.0.0.1:{}", 14010).parse().unwrap(); task::block_on(run(&endpoint)); } + + #[cfg(all(feature = "transport_shm", feature = "shared-memory"))] + #[test] + fn transport_shm_shm() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint: EndPoint = "shm/transport_shm_shm".parse().unwrap(); + task::block_on(run(&endpoint)); + } } diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index 617280cf4f..3b0ef3cad8 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -94,7 +94,7 @@ mod tests { println!("[Simultaneous {}] Sending {}...", self.zid, MSG_COUNT); for _ in 0..MSG_COUNT { - transport.handle_message(message.clone()).unwrap(); + transport.schedule(message.clone()).unwrap(); } println!("[Simultaneous {}] ... sent {}", self.zid, MSG_COUNT); @@ -329,8 +329,36 @@ mod tests { }); } + #[cfg(feature = "transport_shm")] + #[test] + #[ignore] + fn transport_shm_simultaneous() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let endpoint01: Vec = vec![ + "shm/transport_shm_simultaneous".parse().unwrap(), + "shm/transport_shm_simultaneous2".parse().unwrap(), + "shm/transport_shm_simultaneous3".parse().unwrap(), + "shm/transport_shm_simultaneous4".parse().unwrap(), + ]; + let endpoint02: Vec = vec![ + "shm/transport_shm_simultaneous5".parse().unwrap(), + "shm/transport_shm_simultaneous6".parse().unwrap(), + "shm/transport_shm_simultaneous7".parse().unwrap(), + "shm/transport_shm_simultaneous8".parse().unwrap(), + ]; + + task::block_on(async { + transport_simultaneous(endpoint01, endpoint02).await; + }); + } + #[cfg(feature = "transport_ws")] #[test] + #[ignore] fn transport_ws_simultaneous() { let _ = env_logger::try_init(); task::block_on(async { diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 905039f04f..adf143038d 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -35,6 +35,7 @@ use zenoh_protocol::{ zenoh_new::Put, }; use zenoh_result::ZResult; +use zenoh_transport::test_helpers::make_transport_manager_builder; use zenoh_transport::{ TransportEventHandler, TransportManager, TransportMulticast, TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, @@ -220,6 +221,8 @@ const SLEEP_COUNT: Duration = Duration::from_millis(10); const MSG_COUNT: usize = 1_000; const MSG_SIZE_ALL: [usize; 2] = [1_024, 131_072]; +#[cfg(feature = "shared-memory")] +const MSG_SIZE_SHM: [usize; 2] = [1_024, 65000]; const MSG_SIZE_NOFRAG: [usize; 1] = [1_024]; macro_rules! ztimeout { @@ -335,6 +338,7 @@ impl TransportPeerEventHandler for SCClient { async fn open_transport_unicast( client_endpoints: &[EndPoint], server_endpoints: &[EndPoint], + #[cfg(feature = "shared-memory")] shm_transport: bool, ) -> ( TransportManager, Arc, @@ -347,8 +351,12 @@ async fn open_transport_unicast( // Create the router transport manager let router_handler = Arc::new(SHRouter::default()); - let unicast = TransportManager::config_unicast().max_links(server_endpoints.len()); - + let unicast = make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] + server_endpoints.len(), + #[cfg(feature = "shared-memory")] + shm_transport, + ); let router_manager = TransportManager::builder() .zid(router_id) .whatami(WhatAmI::Router) @@ -363,7 +371,12 @@ async fn open_transport_unicast( } // Create the client transport manager - let unicast = TransportManager::config_unicast().max_links(client_endpoints.len()); + let unicast = make_transport_manager_builder( + #[cfg(feature = "transport_multilink")] + client_endpoints.len(), + #[cfg(feature = "shared-memory")] + shm_transport, + ); let client_manager = TransportManager::builder() .whatami(WhatAmI::Client) .zid(client_id) @@ -467,7 +480,7 @@ async fn test_transport( } .into(); for _ in 0..MSG_COUNT { - client_transport.schedule(message.clone()).unwrap(); + let _ = client_transport.schedule(message.clone()); // print!("S-{i} "); use std::io::Write; std::io::stdout().flush().unwrap(); @@ -499,6 +512,7 @@ async fn run_single( server_endpoints: &[EndPoint], channel: Channel, msg_size: usize, + #[cfg(feature = "shared-memory")] shm_transport: bool, ) { println!( "\n>>> Running test for: {:?}, {:?}, {:?}, {}", @@ -507,7 +521,13 @@ async fn run_single( #[allow(unused_variables)] // Used when stats feature is enabled let (router_manager, router_handler, client_manager, client_transport) = - open_transport_unicast(client_endpoints, server_endpoints).await; + open_transport_unicast( + client_endpoints, + server_endpoints, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .await; test_transport( router_handler.clone(), @@ -538,19 +558,59 @@ async fn run_single( .await; } -async fn run( +async fn run_internal( client_endpoints: &[EndPoint], server_endpoints: &[EndPoint], channel: &[Channel], msg_size: &[usize], + #[cfg(feature = "shared-memory")] shm_transport: bool, ) { for ch in channel.iter() { for ms in msg_size.iter() { - run_single(client_endpoints, server_endpoints, *ch, *ms).await; + run_single( + client_endpoints, + server_endpoints, + *ch, + *ms, + #[cfg(feature = "shared-memory")] + shm_transport, + ) + .await; } } } +async fn run_with_net( + client_endpoints: &[EndPoint], + server_endpoints: &[EndPoint], + channel: &[Channel], + msg_size: &[usize], +) { + run_internal( + client_endpoints, + server_endpoints, + channel, + msg_size, + #[cfg(feature = "shared-memory")] + false, + ) + .await; +} + +#[cfg(feature = "shared-memory")] +async fn run_with_shm( + client_endpoints: &[EndPoint], + server_endpoints: &[EndPoint], + channel: &[Channel], + msg_size: &[usize], +) { + if client_endpoints.len() > 1 || server_endpoints.len() > 1 { + println!("SHM transport doesn't support more than one link, so this test would produce MAX_LINKS error!"); + panic!(); + } + run_internal(client_endpoints, server_endpoints, channel, msg_size, true).await; +} + #[cfg(feature = "transport_tcp")] #[test] fn transport_unicast_tcp_only() { @@ -576,7 +636,42 @@ fn transport_unicast_tcp_only() { }, ]; // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_ALL, + )); +} + +#[cfg(all(feature = "transport_tcp", feature = "shared-memory",))] +#[test] +fn transport_unicast_tcp_only_with_shm() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoints: Vec = vec![format!("tcp/127.0.0.1:{}", 16100).parse().unwrap()]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + ]; + // Run + task::block_on(run_with_shm( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_SHM, + )); } #[cfg(feature = "transport_udp")] @@ -604,7 +699,42 @@ fn transport_unicast_udp_only() { }, ]; // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_NOFRAG, + )); +} + +#[cfg(all(feature = "transport_udp", feature = "shared-memory",))] +#[test] +fn transport_unicast_udp_only_with_shm() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locator + let endpoints: Vec = vec![format!("udp/127.0.0.1:{}", 16110).parse().unwrap()]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run_with_shm( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_NOFRAG, + )); } #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] @@ -631,7 +761,50 @@ fn transport_unicast_unix_only() { }, ]; // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_ALL, + )); + let _ = std::fs::remove_file(f1); + let _ = std::fs::remove_file(format!("{f1}.lock")); +} + +#[cfg(all( + feature = "transport_unixsock-stream", + feature = "shared-memory", + target_family = "unix" +))] +#[test] +fn transport_unicast_unix_only_with_shm() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + let f1 = "zenoh-test-unix-socket-5-shm.sock"; + let _ = std::fs::remove_file(f1); + // Define the locator + let endpoints: Vec = vec![format!("unixsock-stream/{f1}").parse().unwrap()]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run_with_shm( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_SHM, + )); let _ = std::fs::remove_file(f1); let _ = std::fs::remove_file(format!("{f1}.lock")); } @@ -669,7 +842,113 @@ fn transport_unicast_ws_only() { }, ]; // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_ALL, + )); +} + +#[cfg(all(feature = "transport_ws", feature = "shared-memory",))] +#[test] +fn transport_unicast_ws_only_with_shm() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locators + let endpoints: Vec = vec![format!("ws/127.0.0.1:{}", 16120).parse().unwrap()]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::default(), + reliability: Reliability::BestEffort, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::BestEffort, + }, + ]; + // Run + task::block_on(run_with_shm( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_SHM, + )); +} + +#[cfg(feature = "transport_shm")] +#[test] +fn transport_unicast_shm_only() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locator + let endpoints: Vec = vec![ + "shm/transport_unicast_shm_only".parse().unwrap(), + "shm/transport_unicast_shm_only2".parse().unwrap(), + ]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + ]; + // Run + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_ALL, + )); +} + +#[cfg(all(feature = "transport_shm", feature = "shared-memory",))] +#[test] +fn transport_unicast_shm_only_with_shm() { + let _ = env_logger::try_init(); + task::block_on(async { + zasync_executor_init!(); + }); + + // Define the locator + let endpoints: Vec = vec!["shm/transport_unicast_shm_only_with_shm".parse().unwrap()]; + // Define the reliability and congestion control + let channel = [ + Channel { + priority: Priority::default(), + reliability: Reliability::Reliable, + }, + Channel { + priority: Priority::RealTime, + reliability: Reliability::Reliable, + }, + ]; + // Run + task::block_on(run_with_shm( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_SHM, + )); } #[cfg(all(feature = "transport_tcp", feature = "transport_udp"))] @@ -699,7 +978,12 @@ fn transport_unicast_tcp_udp() { }, ]; // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_NOFRAG, + )); } #[cfg(all( @@ -734,7 +1018,12 @@ fn transport_unicast_tcp_unix() { }, ]; // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_ALL, + )); let _ = std::fs::remove_file(f1); let _ = std::fs::remove_file(format!("{f1}.lock")); } @@ -771,7 +1060,12 @@ fn transport_unicast_udp_unix() { }, ]; // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_NOFRAG, + )); let _ = std::fs::remove_file(f1); let _ = std::fs::remove_file(format!("{f1}.lock")); } @@ -811,7 +1105,12 @@ fn transport_unicast_tcp_udp_unix() { }, ]; // Run - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_NOFRAG)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_NOFRAG, + )); let _ = std::fs::remove_file(f1); let _ = std::fs::remove_file(format!("{f1}.lock")); } @@ -862,7 +1161,12 @@ fn transport_unicast_tls_only_server() { ]; // Run let endpoints = vec![endpoint]; - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_ALL, + )); } #[cfg(feature = "transport_quic")] @@ -911,7 +1215,12 @@ fn transport_unicast_quic_only_server() { ]; // Run let endpoints = vec![endpoint]; - task::block_on(run(&endpoints, &endpoints, &channel, &MSG_SIZE_ALL)); + task::block_on(run_with_net( + &endpoints, + &endpoints, + &channel, + &MSG_SIZE_ALL, + )); } #[cfg(all(feature = "transport_tls", target_family = "unix"))] @@ -978,7 +1287,7 @@ fn transport_unicast_tls_only_mutual_success() { // Run let client_endpoints = vec![client_endpoint]; let server_endpoints = vec![server_endpoint]; - task::block_on(run( + task::block_on(run_with_net( &client_endpoints, &server_endpoints, &channel, @@ -1057,7 +1366,7 @@ fn transport_unicast_tls_only_mutual_no_client_certs_failure() { let client_endpoints = vec![client_endpoint]; let server_endpoints = vec![server_endpoint]; let result = std::panic::catch_unwind(|| { - task::block_on(run( + task::block_on(run_with_net( &client_endpoints, &server_endpoints, &channel, @@ -1139,7 +1448,7 @@ fn transport_unicast_tls_only_mutual_wrong_client_certs_failure() { let client_endpoints = vec![client_endpoint]; let server_endpoints = vec![server_endpoint]; let result = std::panic::catch_unwind(|| { - task::block_on(run( + task::block_on(run_with_net( &client_endpoints, &server_endpoints, &channel, diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 629b862ad7..54ec0a9859 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -41,6 +41,7 @@ stats = ["zenoh-transport/stats"] transport_multilink = ["zenoh-transport/transport_multilink"] transport_quic = ["zenoh-transport/transport_quic"] transport_serial = ["zenoh-transport/transport_serial"] +transport_shm = ["zenoh-transport/transport_shm"] transport_tcp = ["zenoh-transport/transport_tcp"] transport_tls = ["zenoh-transport/transport_tls"] transport_udp = ["zenoh-transport/transport_udp"] diff --git a/zenoh/src/net/protocol/mod.rs b/zenoh/src/net/protocol/mod.rs index bdd05d2db1..7343a07fd0 100644 --- a/zenoh/src/net/protocol/mod.rs +++ b/zenoh/src/net/protocol/mod.rs @@ -12,5 +12,3 @@ // ZettaScale Zenoh Team, // pub(crate) mod linkstate; - -pub(crate) const OAM_LINKSTATE: u16 = 0x0001; diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index 2cdea8629a..01554f08b3 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -13,7 +13,6 @@ // use crate::net::codec::Zenoh080Routing; use crate::net::protocol::linkstate::{LinkState, LinkStateList}; -use crate::net::protocol::OAM_LINKSTATE; use crate::net::runtime::Runtime; use async_std::task; use petgraph::graph::NodeIndex; @@ -26,6 +25,7 @@ use zenoh_codec::WCodec; use zenoh_link::Locator; use zenoh_protocol::common::ZExtBody; use zenoh_protocol::core::{WhatAmI, WhatAmIMatcher, ZenohId}; +use zenoh_protocol::network::oam::id::OAM_LINKSTATE; use zenoh_protocol::network::{oam, NetworkBody, NetworkMessage, Oam}; use zenoh_transport::TransportUnicast; @@ -285,7 +285,7 @@ impl Network { fn send_on_link(&self, idxs: Vec<(NodeIndex, Details)>, transport: &TransportUnicast) { if let Ok(msg) = self.make_msg(idxs) { log::trace!("{} Send to {:?} {:?}", self.name, transport.get_zid(), msg); - if let Err(e) = transport.handle_message(msg) { + if let Err(e) = transport.schedule(msg) { log::debug!("{} Error sending LinkStateList: {}", self.name, e); } } else { @@ -301,7 +301,7 @@ impl Network { for link in self.links.values() { if parameters(link) { log::trace!("{} Send to {} {:?}", self.name, link.zid, msg); - if let Err(e) = link.transport.handle_message(msg.clone()) { + if let Err(e) = link.transport.schedule(msg.clone()) { log::debug!("{} Error sending LinkStateList: {}", self.name, e); } } diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index a0d2ca8a61..5d6a1f206d 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -18,7 +18,7 @@ pub use super::queries::*; pub use super::resource::*; use super::runtime::Runtime; use crate::net::codec::Zenoh080Routing; -use crate::net::protocol::{linkstate::LinkStateList, OAM_LINKSTATE}; +use crate::net::protocol::linkstate::LinkStateList; use async_std::task::JoinHandle; use std::any::Any; use std::collections::hash_map::DefaultHasher; @@ -32,6 +32,7 @@ use uhlc::HLC; use zenoh_link::Link; use zenoh_protocol::common::ZExtBody; use zenoh_protocol::core::{ExprId, WhatAmI, WhatAmIMatcher, ZenohId}; +use zenoh_protocol::network::oam::id::OAM_LINKSTATE; use zenoh_protocol::network::{Mapping, NetworkBody, NetworkMessage}; use zenoh_transport::{ DeMux, DummyPrimitives, McastMux, Mux, Primitives, TransportMulticast, TransportPeer, From f4feef2493c817ded253e7644077e9f9c028e2c6 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Tue, 22 Aug 2023 15:44:56 +0200 Subject: [PATCH 186/203] Uncomment tables tests --- zenoh/src/net/tests/tables.rs | 1467 +++++++++++++++++---------------- 1 file changed, 742 insertions(+), 725 deletions(-) diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index 5698265201..de39955047 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -1,725 +1,742 @@ -// // -// // Copyright (c) 2023 ZettaScale Technology -// // -// // This program and the accompanying materials are made available under the -// // terms of the Eclipse Public License 2.0 which is available at -// // http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// // which is available at https://www.apache.org/licenses/LICENSE-2.0. -// // -// // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// // -// // Contributors: -// // ZettaScale Zenoh Team, -// // -// use crate::net::routing::router::{self, *}; -// use std::convert::{TryFrom, TryInto}; -// use std::sync::{Arc, Mutex, RwLock}; -// use std::time::Duration; -// use uhlc::HLC; -// use zenoh_buffers::ZBuf; -// use zenoh_config::defaults::queries_default_timeout; -// use zenoh_core::zlock; -// use zenoh_protocol::{ -// core::{ -// key_expr::keyexpr, Channel, CongestionControl, ExprId, Reliability, WhatAmI, WireExpr, -// ZenohId, EMPTY_EXPR_ID, -// }, -// zenoh::{ -// ConsolidationMode, DataInfo, PullId, QueryBody, QueryId, QueryTarget, QueryableInfo, -// RoutingContext, SubInfo, SubMode, -// }, -// }; -// use zenoh_transport::{DummyPrimitives, Primitives}; - -// #[test] -// fn base_test() { -// let tables = TablesLock { -// tables: RwLock::new(Tables::new( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// Some(Arc::new(HLC::default())), -// false, -// true, -// Duration::from_millis(queries_default_timeout), -// )), -// ctrl_lock: Mutex::new(()), -// queries_lock: RwLock::new(()), -// }; - -// let primitives = Arc::new(DummyPrimitives::new()); -// let face = zwrite!(tables.tables).open_face( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// primitives, -// ); -// register_expr( -// &tables, -// &mut face.upgrade().unwrap(), -// 1, -// &"one/two/three".into(), -// ); -// register_expr( -// &tables, -// &mut face.upgrade().unwrap(), -// 2, -// &"one/deux/trois".into(), -// ); - -// let sub_info = SubInfo { -// reliability: Reliability::Reliable, -// mode: SubMode::Push, -// }; -// declare_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face.upgrade().unwrap(), -// &WireExpr::from(1).with_suffix("four/five"), -// &sub_info, -// ); - -// Tables::print(&zread!(tables.tables)); -// } - -// #[test] -// fn match_test() { -// let key_exprs = [ -// "**", -// "a", -// "a/b", -// "*", -// "a/*", -// "a/b$*", -// "abc", -// "xx", -// "ab$*", -// "abcd", -// "ab$*d", -// "ab", -// "ab/*", -// "a/*/c/*/e", -// "a/b/c/d/e", -// "a/$*b/c/$*d/e", -// "a/xb/c/xd/e", -// "a/c/e", -// "a/b/c/d/x/e", -// "ab$*cd", -// "abxxcxxd", -// "abxxcxxcd", -// "abxxcxxcdx", -// "a/b/c", -// "ab/**", -// "**/xyz", -// "a/b/xyz/d/e/f/xyz", -// "**/xyz$*xyz", -// "a/b/xyz/d/e/f/xyz", -// "a/**/c/**/e", -// "a/b/b/b/c/d/d/d/e", -// "a/**/c/*/e/*", -// "a/b/b/b/c/d/d/c/d/e/f", -// "a/**/c/*/e/*", -// "x/abc", -// "x/*", -// "x/abc$*", -// "x/$*abc", -// "x/a$*", -// "x/a$*de", -// "x/abc$*de", -// "x/a$*d$*e", -// "x/a$*e", -// "x/a$*c$*e", -// "x/ade", -// "x/c$*", -// "x/$*d", -// "x/$*e", -// ] -// .map(|s| keyexpr::new(s).unwrap()); - -// let tables = TablesLock { -// tables: RwLock::new(Tables::new( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// Some(Arc::new(HLC::default())), -// false, -// true, -// Duration::from_millis(queries_default_timeout), -// )), -// ctrl_lock: Mutex::new(()), -// queries_lock: RwLock::new(()), -// }; -// let primitives = Arc::new(DummyPrimitives::new()); -// let face = zwrite!(tables.tables).open_face( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// primitives, -// ); -// for (i, key_expr) in key_exprs.iter().enumerate() { -// register_expr( -// &tables, -// &mut face.upgrade().unwrap(), -// i.try_into().unwrap(), -// &(*key_expr).into(), -// ); -// } - -// for key_expr1 in key_exprs.iter() { -// let res_matches = Resource::get_matches(&zread!(tables.tables), key_expr1); -// dbg!(res_matches.len()); -// for key_expr2 in key_exprs.iter() { -// if res_matches -// .iter() -// .map(|m| m.upgrade().unwrap().expr()) -// .any(|x| x.as_str() == key_expr2.as_str()) -// { -// assert!(dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); -// } else { -// assert!(!dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); -// } -// } -// } -// } - -// #[test] -// fn clean_test() { -// let tables = TablesLock { -// tables: RwLock::new(Tables::new( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// Some(Arc::new(HLC::default())), -// false, -// true, -// Duration::from_millis(queries_default_timeout), -// )), -// ctrl_lock: Mutex::new(()), -// queries_lock: RwLock::new(()), -// }; - -// let primitives = Arc::new(DummyPrimitives::new()); -// let face0 = zwrite!(tables.tables).open_face( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// primitives, -// ); -// assert!(face0.upgrade().is_some()); - -// // -------------- -// register_expr(&tables, &mut face0.upgrade().unwrap(), 1, &"todrop1".into()); -// let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres1.is_some()); -// let res1 = optres1.unwrap(); -// assert!(res1.upgrade().is_some()); - -// register_expr( -// &tables, -// &mut face0.upgrade().unwrap(), -// 2, -// &"todrop1/todrop11".into(), -// ); -// let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres2.is_some()); -// let res2 = optres2.unwrap(); -// assert!(res2.upgrade().is_some()); - -// register_expr(&tables, &mut face0.upgrade().unwrap(), 3, &"**".into()); -// let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "**") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres3.is_some()); -// let res3 = optres3.unwrap(); -// assert!(res3.upgrade().is_some()); - -// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 1); -// assert!(res1.upgrade().is_some()); -// assert!(res2.upgrade().is_some()); -// assert!(res3.upgrade().is_some()); - -// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 2); -// assert!(res1.upgrade().is_none()); -// assert!(res2.upgrade().is_none()); -// assert!(res3.upgrade().is_some()); - -// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 3); -// assert!(res1.upgrade().is_none()); -// assert!(res2.upgrade().is_none()); -// assert!(res3.upgrade().is_none()); - -// // -------------- -// register_expr(&tables, &mut face0.upgrade().unwrap(), 1, &"todrop1".into()); -// let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres1.is_some()); -// let res1 = optres1.unwrap(); -// assert!(res1.upgrade().is_some()); - -// let sub_info = SubInfo { -// reliability: Reliability::Reliable, -// mode: SubMode::Push, -// }; - -// declare_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face0.upgrade().unwrap(), -// &"todrop1/todrop11".into(), -// &sub_info, -// ); -// let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres2.is_some()); -// let res2 = optres2.unwrap(); -// assert!(res2.upgrade().is_some()); - -// declare_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face0.upgrade().unwrap(), -// &WireExpr::from(1).with_suffix("/todrop12"), -// &sub_info, -// ); -// let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop12") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres3.is_some()); -// let res3 = optres3.unwrap(); -// assert!(res3.upgrade().is_some()); - -// forget_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face0.upgrade().unwrap(), -// &WireExpr::from(1).with_suffix("/todrop12"), -// ); -// assert!(res1.upgrade().is_some()); -// assert!(res2.upgrade().is_some()); -// assert!(res3.upgrade().is_none()); - -// forget_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face0.upgrade().unwrap(), -// &"todrop1/todrop11".into(), -// ); -// assert!(res1.upgrade().is_some()); -// assert!(res2.upgrade().is_none()); -// assert!(res3.upgrade().is_none()); - -// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 1); -// assert!(res1.upgrade().is_none()); -// assert!(res2.upgrade().is_none()); -// assert!(res3.upgrade().is_none()); - -// // -------------- -// register_expr(&tables, &mut face0.upgrade().unwrap(), 2, &"todrop3".into()); -// declare_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face0.upgrade().unwrap(), -// &"todrop3".into(), -// &sub_info, -// ); -// let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop3") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres1.is_some()); -// let res1 = optres1.unwrap(); -// assert!(res1.upgrade().is_some()); - -// forget_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face0.upgrade().unwrap(), -// &"todrop3".into(), -// ); -// assert!(res1.upgrade().is_some()); - -// unregister_expr(&tables, &mut face0.upgrade().unwrap(), 2); -// assert!(res1.upgrade().is_none()); - -// // -------------- -// register_expr(&tables, &mut face0.upgrade().unwrap(), 3, &"todrop4".into()); -// register_expr(&tables, &mut face0.upgrade().unwrap(), 4, &"todrop5".into()); -// declare_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face0.upgrade().unwrap(), -// &"todrop5".into(), -// &sub_info, -// ); -// declare_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face0.upgrade().unwrap(), -// &"todrop6".into(), -// &sub_info, -// ); - -// let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop4") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres1.is_some()); -// let res1 = optres1.unwrap(); -// let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop5") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres2.is_some()); -// let res2 = optres2.unwrap(); -// let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop6") -// .map(|res| Arc::downgrade(&res)); -// assert!(optres3.is_some()); -// let res3 = optres3.unwrap(); - -// assert!(res1.upgrade().is_some()); -// assert!(res2.upgrade().is_some()); -// assert!(res3.upgrade().is_some()); - -// router::close_face(&tables, &face0); -// assert!(face0.upgrade().is_none()); -// assert!(res1.upgrade().is_none()); -// assert!(res2.upgrade().is_none()); -// assert!(res3.upgrade().is_none()); -// } - -// pub struct ClientPrimitives { -// data: std::sync::Mutex>>, -// mapping: std::sync::Mutex>, -// } - -// impl ClientPrimitives { -// pub fn new() -> ClientPrimitives { -// ClientPrimitives { -// data: std::sync::Mutex::new(None), -// mapping: std::sync::Mutex::new(std::collections::HashMap::new()), -// } -// } - -// pub fn clear_data(&self) { -// *self.data.lock().unwrap() = None; -// } -// } - -// impl Default for ClientPrimitives { -// fn default() -> Self { -// Self::new() -// } -// } - -// impl ClientPrimitives { -// fn get_name(&self, key_expr: &WireExpr) -> String { -// let mapping = self.mapping.lock().unwrap(); -// let (scope, suffix) = key_expr.as_id_and_suffix(); -// if scope == EMPTY_EXPR_ID { -// suffix.to_string() -// } else if suffix.is_empty() { -// mapping.get(&scope).unwrap().clone() -// } else { -// format!("{}{}", mapping.get(&scope).unwrap(), suffix) -// } -// } - -// fn get_last_name(&self) -> Option { -// self.data -// .lock() -// .unwrap() -// .as_ref() -// .map(|data| self.get_name(data)) -// } - -// #[allow(dead_code)] -// fn get_last_key(&self) -> Option { -// self.data.lock().unwrap().as_ref().cloned() -// } -// } - -// impl Primitives for ClientPrimitives { -// fn decl_resource(&self, expr_id: ExprId, key_expr: &WireExpr) { -// let name = self.get_name(key_expr); -// zlock!(self.mapping).insert(expr_id, name); -// } - -// fn forget_resource(&self, expr_id: ExprId) { -// zlock!(self.mapping).remove(&expr_id); -// } - -// fn decl_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} -// fn forget_publisher(&self, _key_expr: &WireExpr, _routing_context: Option) {} - -// fn decl_subscriber( -// &self, -// _key_expr: &WireExpr, -// _sub_info: &SubInfo, -// _routing_context: Option, -// ) { -// } -// fn forget_subscriber(&self, _key_expr: &WireExpr, _routing_context: Option) {} - -// fn decl_queryable( -// &self, -// _key_expr: &WireExpr, -// _qabl_info: &QueryableInfo, -// _routing_context: Option, -// ) { -// } -// fn forget_queryable(&self, _key_expr: &WireExpr, _routing_context: Option) {} - -// fn send_push( -// &self, -// key_expr: &WireExpr, -// _payload: ZBuf, -// _channel: Channel, -// _congestion_control: CongestionControl, -// _info: Option, -// _routing_context: Option, -// ) { -// *zlock!(self.data) = Some(key_expr.to_owned()); -// } - -// fn send_request( -// &self, -// _key_expr: &WireExpr, -// _parameters: &str, -// _qid: QueryId, -// _target: QueryTarget, -// _consolidation: ConsolidationMode, -// _body: Option, -// _routing_context: Option, -// ) { -// } - -// fn send_response( -// &self, -// _qid: QueryId, -// _replier_id: ZenohId, -// _key_expr: WireExpr, -// _info: Option, -// _payload: ZBuf, -// ) { -// } -// fn send_response_final(&self, _qid: QueryId) {} - -// fn send_close(&self) {} -// } - -// #[test] -// fn client_test() { -// let tables = TablesLock { -// tables: RwLock::new(Tables::new( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// Some(Arc::new(HLC::default())), -// false, -// true, -// Duration::from_millis(queries_default_timeout), -// )), -// ctrl_lock: Mutex::new(()), -// queries_lock: RwLock::new(()), -// }; - -// let sub_info = SubInfo { -// reliability: Reliability::Reliable, -// mode: SubMode::Push, -// }; - -// let primitives0 = Arc::new(ClientPrimitives::new()); - -// let face0 = zwrite!(tables.tables).open_face( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// primitives0.clone(), -// ); -// register_expr( -// &tables, -// &mut face0.upgrade().unwrap(), -// 11, -// &"test/client".into(), -// ); -// primitives0.decl_resource(11, &"test/client".into()); -// declare_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face0.upgrade().unwrap(), -// &WireExpr::from(11).with_suffix("/**"), -// &sub_info, -// ); -// register_expr( -// &tables, -// &mut face0.upgrade().unwrap(), -// 12, -// &WireExpr::from(11).with_suffix("/z1_pub1"), -// ); -// primitives0.decl_resource(12, &WireExpr::from(11).with_suffix("/z1_pub1")); - -// let primitives1 = Arc::new(ClientPrimitives::new()); -// let face1 = zwrite!(tables.tables).open_face( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// primitives1.clone(), -// ); -// register_expr( -// &tables, -// &mut face1.upgrade().unwrap(), -// 21, -// &"test/client".into(), -// ); -// primitives1.decl_resource(21, &"test/client".into()); -// declare_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face1.upgrade().unwrap(), -// &WireExpr::from(21).with_suffix("/**"), -// &sub_info, -// ); -// register_expr( -// &tables, -// &mut face1.upgrade().unwrap(), -// 22, -// &WireExpr::from(21).with_suffix("/z2_pub1"), -// ); -// primitives1.decl_resource(22, &WireExpr::from(21).with_suffix("/z2_pub1")); - -// let primitives2 = Arc::new(ClientPrimitives::new()); -// let face2 = zwrite!(tables.tables).open_face( -// ZenohId::try_from([1]).unwrap(), -// WhatAmI::Client, -// primitives2.clone(), -// ); -// register_expr( -// &tables, -// &mut face2.upgrade().unwrap(), -// 31, -// &"test/client".into(), -// ); -// primitives2.decl_resource(31, &"test/client".into()); -// declare_client_subscription( -// &tables, -// zread!(tables.tables), -// &mut face2.upgrade().unwrap(), -// &WireExpr::from(31).with_suffix("/**"), -// &sub_info, -// ); - -// primitives0.clear_data(); -// primitives1.clear_data(); -// primitives2.clear_data(); -// full_reentrant_route_data( -// &tables.tables, -// &face0.upgrade().unwrap(), -// &"test/client/z1_wr1".into(), -// Channel::default(), -// CongestionControl::default(), -// None, -// ZBuf::empty(), -// None, -// ); - -// // functionnal check -// assert!(primitives1.get_last_name().is_some()); -// assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_wr1"); -// // mapping strategy check -// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_wr1".to_string())); - -// // functionnal check -// assert!(primitives2.get_last_name().is_some()); -// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_wr1"); -// // mapping strategy check -// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_wr1".to_string())); - -// primitives0.clear_data(); -// primitives1.clear_data(); -// primitives2.clear_data(); -// full_reentrant_route_data( -// &tables.tables, -// &face0.upgrade().unwrap(), -// &WireExpr::from(11).with_suffix("/z1_wr2"), -// Channel::default(), -// CongestionControl::default(), -// None, -// ZBuf::empty(), -// None, -// ); - -// // functionnal check -// assert!(primitives1.get_last_name().is_some()); -// assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_wr2"); -// // mapping strategy check -// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_wr2".to_string())); - -// // functionnal check -// assert!(primitives2.get_last_name().is_some()); -// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_wr2"); -// // mapping strategy check -// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_wr2".to_string())); - -// primitives0.clear_data(); -// primitives1.clear_data(); -// primitives2.clear_data(); -// full_reentrant_route_data( -// &tables.tables, -// &face1.upgrade().unwrap(), -// &"test/client/**".into(), -// Channel::default(), -// CongestionControl::default(), -// None, -// ZBuf::empty(), -// None, -// ); - -// // functionnal check -// assert!(primitives0.get_last_name().is_some()); -// assert_eq!(primitives0.get_last_name().unwrap(), "test/client/**"); -// // mapping strategy check -// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(11, "/**".to_string())); - -// // functionnal check -// assert!(primitives2.get_last_name().is_some()); -// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/**"); -// // mapping strategy check -// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/**".to_string())); - -// primitives0.clear_data(); -// primitives1.clear_data(); -// primitives2.clear_data(); -// full_reentrant_route_data( -// &tables.tables, -// &face0.upgrade().unwrap(), -// &12.into(), -// Channel::default(), -// CongestionControl::default(), -// None, -// ZBuf::empty(), -// None, -// ); - -// // functionnal check -// assert!(primitives1.get_last_name().is_some()); -// assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_pub1"); -// // mapping strategy check -// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_pub1".to_string())); - -// // functionnal check -// assert!(primitives2.get_last_name().is_some()); -// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_pub1"); -// // mapping strategy check -// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_pub1".to_string())); - -// primitives0.clear_data(); -// primitives1.clear_data(); -// primitives2.clear_data(); -// full_reentrant_route_data( -// &tables.tables, -// &face1.upgrade().unwrap(), -// &22.into(), -// Channel::default(), -// CongestionControl::default(), -// None, -// ZBuf::empty(), -// None, -// ); - -// // functionnal check -// assert!(primitives0.get_last_name().is_some()); -// assert_eq!(primitives0.get_last_name().unwrap(), "test/client/z2_pub1"); -// // mapping strategy check -// // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(11, "/z2_pub1".to_string())); - -// // functionnal check -// assert!(primitives2.get_last_name().is_some()); -// assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z2_pub1"); -// // mapping strategy check -// // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z2_pub1".to_string())); -// } +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::net::routing::router::{self, *}; +use std::convert::{TryFrom, TryInto}; +use std::sync::{Arc, Mutex, RwLock}; +use std::time::Duration; +use uhlc::HLC; +use zenoh_buffers::ZBuf; +use zenoh_config::defaults::queries_default_timeout; +use zenoh_core::zlock; +use zenoh_protocol::core::Encoding; +use zenoh_protocol::core::{ + key_expr::keyexpr, ExprId, Reliability, WhatAmI, WireExpr, ZenohId, EMPTY_EXPR_ID, +}; +use zenoh_protocol::network::declare::subscriber::ext::SubscriberInfo; +use zenoh_protocol::network::declare::Mode; +use zenoh_protocol::network::{ext, Declare, DeclareBody, DeclareKeyExpr}; +use zenoh_protocol::zenoh_new::{PushBody, Put}; +use zenoh_transport::{DummyPrimitives, Primitives}; + +#[test] +fn base_test() { + let tables = TablesLock { + tables: RwLock::new(Tables::new( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + Some(Arc::new(HLC::default())), + false, + true, + Duration::from_millis(queries_default_timeout), + )), + ctrl_lock: Mutex::new(()), + queries_lock: RwLock::new(()), + }; + + let primitives = Arc::new(DummyPrimitives::new()); + let face = zwrite!(tables.tables).open_face( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + primitives, + ); + register_expr( + &tables, + &mut face.upgrade().unwrap(), + 1, + &"one/two/three".into(), + ); + register_expr( + &tables, + &mut face.upgrade().unwrap(), + 2, + &"one/deux/trois".into(), + ); + + let sub_info = SubscriberInfo { + reliability: Reliability::Reliable, + mode: Mode::Push, + }; + declare_client_subscription( + &tables, + zread!(tables.tables), + &mut face.upgrade().unwrap(), + &WireExpr::from(1).with_suffix("four/five"), + &sub_info, + ); + + Tables::print(&zread!(tables.tables)); +} + +#[test] +fn match_test() { + let key_exprs = [ + "**", + "a", + "a/b", + "*", + "a/*", + "a/b$*", + "abc", + "xx", + "ab$*", + "abcd", + "ab$*d", + "ab", + "ab/*", + "a/*/c/*/e", + "a/b/c/d/e", + "a/$*b/c/$*d/e", + "a/xb/c/xd/e", + "a/c/e", + "a/b/c/d/x/e", + "ab$*cd", + "abxxcxxd", + "abxxcxxcd", + "abxxcxxcdx", + "a/b/c", + "ab/**", + "**/xyz", + "a/b/xyz/d/e/f/xyz", + "**/xyz$*xyz", + "a/b/xyz/d/e/f/xyz", + "a/**/c/**/e", + "a/b/b/b/c/d/d/d/e", + "a/**/c/*/e/*", + "a/b/b/b/c/d/d/c/d/e/f", + "a/**/c/*/e/*", + "x/abc", + "x/*", + "x/abc$*", + "x/$*abc", + "x/a$*", + "x/a$*de", + "x/abc$*de", + "x/a$*d$*e", + "x/a$*e", + "x/a$*c$*e", + "x/ade", + "x/c$*", + "x/$*d", + "x/$*e", + ] + .map(|s| keyexpr::new(s).unwrap()); + + let tables = TablesLock { + tables: RwLock::new(Tables::new( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + Some(Arc::new(HLC::default())), + false, + true, + Duration::from_millis(queries_default_timeout), + )), + ctrl_lock: Mutex::new(()), + queries_lock: RwLock::new(()), + }; + let primitives = Arc::new(DummyPrimitives::new()); + let face = zwrite!(tables.tables).open_face( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + primitives, + ); + for (i, key_expr) in key_exprs.iter().enumerate() { + register_expr( + &tables, + &mut face.upgrade().unwrap(), + i.try_into().unwrap(), + &(*key_expr).into(), + ); + } + + for key_expr1 in key_exprs.iter() { + let res_matches = Resource::get_matches(&zread!(tables.tables), key_expr1); + dbg!(res_matches.len()); + for key_expr2 in key_exprs.iter() { + if res_matches + .iter() + .map(|m| m.upgrade().unwrap().expr()) + .any(|x| x.as_str() == key_expr2.as_str()) + { + assert!(dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); + } else { + assert!(!dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); + } + } + } +} + +#[test] +fn clean_test() { + let tables = TablesLock { + tables: RwLock::new(Tables::new( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + Some(Arc::new(HLC::default())), + false, + true, + Duration::from_millis(queries_default_timeout), + )), + ctrl_lock: Mutex::new(()), + queries_lock: RwLock::new(()), + }; + + let primitives = Arc::new(DummyPrimitives::new()); + let face0 = zwrite!(tables.tables).open_face( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + primitives, + ); + assert!(face0.upgrade().is_some()); + + // -------------- + register_expr(&tables, &mut face0.upgrade().unwrap(), 1, &"todrop1".into()); + let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") + .map(|res| Arc::downgrade(&res)); + assert!(optres1.is_some()); + let res1 = optres1.unwrap(); + assert!(res1.upgrade().is_some()); + + register_expr( + &tables, + &mut face0.upgrade().unwrap(), + 2, + &"todrop1/todrop11".into(), + ); + let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") + .map(|res| Arc::downgrade(&res)); + assert!(optres2.is_some()); + let res2 = optres2.unwrap(); + assert!(res2.upgrade().is_some()); + + register_expr(&tables, &mut face0.upgrade().unwrap(), 3, &"**".into()); + let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "**") + .map(|res| Arc::downgrade(&res)); + assert!(optres3.is_some()); + let res3 = optres3.unwrap(); + assert!(res3.upgrade().is_some()); + + unregister_expr(&tables, &mut face0.upgrade().unwrap(), 1); + assert!(res1.upgrade().is_some()); + assert!(res2.upgrade().is_some()); + assert!(res3.upgrade().is_some()); + + unregister_expr(&tables, &mut face0.upgrade().unwrap(), 2); + assert!(res1.upgrade().is_none()); + assert!(res2.upgrade().is_none()); + assert!(res3.upgrade().is_some()); + + unregister_expr(&tables, &mut face0.upgrade().unwrap(), 3); + assert!(res1.upgrade().is_none()); + assert!(res2.upgrade().is_none()); + assert!(res3.upgrade().is_none()); + + // -------------- + register_expr(&tables, &mut face0.upgrade().unwrap(), 1, &"todrop1".into()); + let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") + .map(|res| Arc::downgrade(&res)); + assert!(optres1.is_some()); + let res1 = optres1.unwrap(); + assert!(res1.upgrade().is_some()); + + let sub_info = SubscriberInfo { + reliability: Reliability::Reliable, + mode: Mode::Push, + }; + + declare_client_subscription( + &tables, + zread!(tables.tables), + &mut face0.upgrade().unwrap(), + &"todrop1/todrop11".into(), + &sub_info, + ); + let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") + .map(|res| Arc::downgrade(&res)); + assert!(optres2.is_some()); + let res2 = optres2.unwrap(); + assert!(res2.upgrade().is_some()); + + declare_client_subscription( + &tables, + zread!(tables.tables), + &mut face0.upgrade().unwrap(), + &WireExpr::from(1).with_suffix("/todrop12"), + &sub_info, + ); + let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop12") + .map(|res| Arc::downgrade(&res)); + assert!(optres3.is_some()); + let res3 = optres3.unwrap(); + assert!(res3.upgrade().is_some()); + + forget_client_subscription( + &tables, + zread!(tables.tables), + &mut face0.upgrade().unwrap(), + &WireExpr::from(1).with_suffix("/todrop12"), + ); + assert!(res1.upgrade().is_some()); + assert!(res2.upgrade().is_some()); + assert!(res3.upgrade().is_none()); + + forget_client_subscription( + &tables, + zread!(tables.tables), + &mut face0.upgrade().unwrap(), + &"todrop1/todrop11".into(), + ); + assert!(res1.upgrade().is_some()); + assert!(res2.upgrade().is_none()); + assert!(res3.upgrade().is_none()); + + unregister_expr(&tables, &mut face0.upgrade().unwrap(), 1); + assert!(res1.upgrade().is_none()); + assert!(res2.upgrade().is_none()); + assert!(res3.upgrade().is_none()); + + // -------------- + register_expr(&tables, &mut face0.upgrade().unwrap(), 2, &"todrop3".into()); + declare_client_subscription( + &tables, + zread!(tables.tables), + &mut face0.upgrade().unwrap(), + &"todrop3".into(), + &sub_info, + ); + let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop3") + .map(|res| Arc::downgrade(&res)); + assert!(optres1.is_some()); + let res1 = optres1.unwrap(); + assert!(res1.upgrade().is_some()); + + forget_client_subscription( + &tables, + zread!(tables.tables), + &mut face0.upgrade().unwrap(), + &"todrop3".into(), + ); + assert!(res1.upgrade().is_some()); + + unregister_expr(&tables, &mut face0.upgrade().unwrap(), 2); + assert!(res1.upgrade().is_none()); + + // -------------- + register_expr(&tables, &mut face0.upgrade().unwrap(), 3, &"todrop4".into()); + register_expr(&tables, &mut face0.upgrade().unwrap(), 4, &"todrop5".into()); + declare_client_subscription( + &tables, + zread!(tables.tables), + &mut face0.upgrade().unwrap(), + &"todrop5".into(), + &sub_info, + ); + declare_client_subscription( + &tables, + zread!(tables.tables), + &mut face0.upgrade().unwrap(), + &"todrop6".into(), + &sub_info, + ); + + let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop4") + .map(|res| Arc::downgrade(&res)); + assert!(optres1.is_some()); + let res1 = optres1.unwrap(); + let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop5") + .map(|res| Arc::downgrade(&res)); + assert!(optres2.is_some()); + let res2 = optres2.unwrap(); + let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop6") + .map(|res| Arc::downgrade(&res)); + assert!(optres3.is_some()); + let res3 = optres3.unwrap(); + + assert!(res1.upgrade().is_some()); + assert!(res2.upgrade().is_some()); + assert!(res3.upgrade().is_some()); + + router::close_face(&tables, &face0); + assert!(face0.upgrade().is_none()); + assert!(res1.upgrade().is_none()); + assert!(res2.upgrade().is_none()); + assert!(res3.upgrade().is_none()); +} + +pub struct ClientPrimitives { + data: std::sync::Mutex>>, + mapping: std::sync::Mutex>, +} + +impl ClientPrimitives { + pub fn new() -> ClientPrimitives { + ClientPrimitives { + data: std::sync::Mutex::new(None), + mapping: std::sync::Mutex::new(std::collections::HashMap::new()), + } + } + + pub fn clear_data(&self) { + *self.data.lock().unwrap() = None; + } +} + +impl Default for ClientPrimitives { + fn default() -> Self { + Self::new() + } +} + +impl ClientPrimitives { + fn get_name(&self, key_expr: &WireExpr) -> String { + let mapping = self.mapping.lock().unwrap(); + let (scope, suffix) = key_expr.as_id_and_suffix(); + if scope == EMPTY_EXPR_ID { + suffix.to_string() + } else if suffix.is_empty() { + mapping.get(&scope).unwrap().clone() + } else { + format!("{}{}", mapping.get(&scope).unwrap(), suffix) + } + } + + fn get_last_name(&self) -> Option { + self.data + .lock() + .unwrap() + .as_ref() + .map(|data| self.get_name(data)) + } + + #[allow(dead_code)] + fn get_last_key(&self) -> Option { + self.data.lock().unwrap().as_ref().cloned() + } +} + +impl Primitives for ClientPrimitives { + fn send_declare(&self, msg: zenoh_protocol::network::Declare) { + match msg.body { + DeclareBody::DeclareKeyExpr(d) => { + let name = self.get_name(&d.wire_expr); + zlock!(self.mapping).insert(d.id, name); + } + DeclareBody::UndeclareKeyExpr(u) => { + zlock!(self.mapping).remove(&u.id); + } + _ => (), + } + } + + fn send_push(&self, msg: zenoh_protocol::network::Push) { + *zlock!(self.data) = Some(msg.wire_expr.to_owned()); + } + + fn send_request(&self, _msg: zenoh_protocol::network::Request) {} + + fn send_response(&self, _msg: zenoh_protocol::network::Response) {} + + fn send_response_final(&self, _msg: zenoh_protocol::network::ResponseFinal) {} + + fn send_close(&self) {} +} + +#[test] +fn client_test() { + let tables = TablesLock { + tables: RwLock::new(Tables::new( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + Some(Arc::new(HLC::default())), + false, + true, + Duration::from_millis(queries_default_timeout), + )), + ctrl_lock: Mutex::new(()), + queries_lock: RwLock::new(()), + }; + + let sub_info = SubscriberInfo { + reliability: Reliability::Reliable, + mode: Mode::Push, + }; + + let primitives0 = Arc::new(ClientPrimitives::new()); + + let face0 = zwrite!(tables.tables).open_face( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + primitives0.clone(), + ); + register_expr( + &tables, + &mut face0.upgrade().unwrap(), + 11, + &"test/client".into(), + ); + primitives0.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { + id: 11, + wire_expr: "test/client".into(), + }), + }); + declare_client_subscription( + &tables, + zread!(tables.tables), + &mut face0.upgrade().unwrap(), + &WireExpr::from(11).with_suffix("/**"), + &sub_info, + ); + register_expr( + &tables, + &mut face0.upgrade().unwrap(), + 12, + &WireExpr::from(11).with_suffix("/z1_pub1"), + ); + primitives0.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { + id: 12, + wire_expr: WireExpr::from(11).with_suffix("/z1_pub1"), + }), + }); + + let primitives1 = Arc::new(ClientPrimitives::new()); + let face1 = zwrite!(tables.tables).open_face( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + primitives1.clone(), + ); + register_expr( + &tables, + &mut face1.upgrade().unwrap(), + 21, + &"test/client".into(), + ); + primitives1.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { + id: 21, + wire_expr: "test/client".into(), + }), + }); + declare_client_subscription( + &tables, + zread!(tables.tables), + &mut face1.upgrade().unwrap(), + &WireExpr::from(21).with_suffix("/**"), + &sub_info, + ); + register_expr( + &tables, + &mut face1.upgrade().unwrap(), + 22, + &WireExpr::from(21).with_suffix("/z2_pub1"), + ); + primitives1.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { + id: 22, + wire_expr: WireExpr::from(21).with_suffix("/z2_pub1"), + }), + }); + + let primitives2 = Arc::new(ClientPrimitives::new()); + let face2 = zwrite!(tables.tables).open_face( + ZenohId::try_from([1]).unwrap(), + WhatAmI::Client, + primitives2.clone(), + ); + register_expr( + &tables, + &mut face2.upgrade().unwrap(), + 31, + &"test/client".into(), + ); + primitives2.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { + id: 31, + wire_expr: "test/client".into(), + }), + }); + declare_client_subscription( + &tables, + zread!(tables.tables), + &mut face2.upgrade().unwrap(), + &WireExpr::from(31).with_suffix("/**"), + &sub_info, + ); + + primitives0.clear_data(); + primitives1.clear_data(); + primitives2.clear_data(); + + full_reentrant_route_data( + &tables.tables, + &face0.upgrade().unwrap(), + &"test/client/z1_wr1".into(), + ext::QoSType::default(), + PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + payload: ZBuf::empty(), + }), + 0, + ); + + // functionnal check + assert!(primitives1.get_last_name().is_some()); + assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_wr1"); + // mapping strategy check + // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_wr1".to_string())); + + // functionnal check + assert!(primitives2.get_last_name().is_some()); + assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_wr1"); + // mapping strategy check + // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_wr1".to_string())); + + primitives0.clear_data(); + primitives1.clear_data(); + primitives2.clear_data(); + full_reentrant_route_data( + &tables.tables, + &face0.upgrade().unwrap(), + &WireExpr::from(11).with_suffix("/z1_wr2"), + ext::QoSType::default(), + PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + payload: ZBuf::empty(), + }), + 0, + ); + + // functionnal check + assert!(primitives1.get_last_name().is_some()); + assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_wr2"); + // mapping strategy check + // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_wr2".to_string())); + + // functionnal check + assert!(primitives2.get_last_name().is_some()); + assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_wr2"); + // mapping strategy check + // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_wr2".to_string())); + + primitives0.clear_data(); + primitives1.clear_data(); + primitives2.clear_data(); + full_reentrant_route_data( + &tables.tables, + &face1.upgrade().unwrap(), + &"test/client/**".into(), + ext::QoSType::default(), + PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + payload: ZBuf::empty(), + }), + 0, + ); + + // functionnal check + assert!(primitives0.get_last_name().is_some()); + assert_eq!(primitives0.get_last_name().unwrap(), "test/client/**"); + // mapping strategy check + // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(11, "/**".to_string())); + + // functionnal check + assert!(primitives2.get_last_name().is_some()); + assert_eq!(primitives2.get_last_name().unwrap(), "test/client/**"); + // mapping strategy check + // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/**".to_string())); + + primitives0.clear_data(); + primitives1.clear_data(); + primitives2.clear_data(); + full_reentrant_route_data( + &tables.tables, + &face0.upgrade().unwrap(), + &12.into(), + ext::QoSType::default(), + PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + payload: ZBuf::empty(), + }), + 0, + ); + + // functionnal check + assert!(primitives1.get_last_name().is_some()); + assert_eq!(primitives1.get_last_name().unwrap(), "test/client/z1_pub1"); + // mapping strategy check + // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(21, "/z1_pub1".to_string())); + + // functionnal check + assert!(primitives2.get_last_name().is_some()); + assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z1_pub1"); + // mapping strategy check + // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z1_pub1".to_string())); + + primitives0.clear_data(); + primitives1.clear_data(); + primitives2.clear_data(); + full_reentrant_route_data( + &tables.tables, + &face1.upgrade().unwrap(), + &22.into(), + ext::QoSType::default(), + PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_unknown: vec![], + payload: ZBuf::empty(), + }), + 0, + ); + + // functionnal check + assert!(primitives0.get_last_name().is_some()); + assert_eq!(primitives0.get_last_name().unwrap(), "test/client/z2_pub1"); + // mapping strategy check + // assert_eq!(primitives1.get_last_key().unwrap(), KeyExpr::IdWithSuffix(11, "/z2_pub1".to_string())); + + // functionnal check + assert!(primitives2.get_last_name().is_some()); + assert_eq!(primitives2.get_last_name().unwrap(), "test/client/z2_pub1"); + // mapping strategy check + // assert_eq!(primitives2.get_last_key().unwrap(), KeyExpr::IdWithSuffix(31, "/z2_pub1".to_string())); +} From 30e88cc7f41fa0c1c7ecda1890cf979c486b992a Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Tue, 22 Aug 2023 15:55:01 +0200 Subject: [PATCH 187/203] Fix build with shared-memory feature --- zenoh/src/net/tests/tables.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index de39955047..90d3d6f25c 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -602,6 +602,8 @@ fn client_test() { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload: ZBuf::empty(), }), @@ -632,6 +634,8 @@ fn client_test() { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload: ZBuf::empty(), }), @@ -662,6 +666,8 @@ fn client_test() { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload: ZBuf::empty(), }), @@ -692,6 +698,8 @@ fn client_test() { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload: ZBuf::empty(), }), @@ -722,6 +730,8 @@ fn client_test() { timestamp: None, encoding: Encoding::default(), ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, ext_unknown: vec![], payload: ZBuf::empty(), }), From 98a14278a98f243e2c0f469876b1e683f87bf115 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Thu, 24 Aug 2023 15:23:42 +0200 Subject: [PATCH 188/203] Don't run zenoh_session_unicast concurrently --- .config/nextest.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .config/nextest.toml diff --git a/.config/nextest.toml b/.config/nextest.toml new file mode 100644 index 0000000000..601660c929 --- /dev/null +++ b/.config/nextest.toml @@ -0,0 +1,3 @@ +[[profile.default.overrides]] +filter = 'test(/zenoh_session_unicast/)' +threads-required = 'num-cpus' From 5ffe205714f1a7f668cd63b9cb26e91b957b5e79 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Fri, 25 Aug 2023 16:13:26 +0200 Subject: [PATCH 189/203] Reenable stats feature --- commons/zenoh-codec/src/network/mod.rs | 2 +- commons/zenoh-codec/src/scouting/mod.rs | 2 +- commons/zenoh-codec/src/transport/mod.rs | 2 +- commons/zenoh-codec/src/zenoh/mod.rs | 6 +- commons/zenoh-protocol/Cargo.toml | 1 + commons/zenoh-protocol/src/network/mod.rs | 3 +- commons/zenoh-protocol/src/transport/mod.rs | 6 +- commons/zenoh-protocol/src/zenoh/mod.rs | 13 +++ io/zenoh-transport/src/multicast/link.rs | 9 +- io/zenoh-transport/src/multicast/mod.rs | 55 +++++++----- io/zenoh-transport/src/multicast/rx.rs | 59 +++++++++---- io/zenoh-transport/src/multicast/tx.rs | 75 ++++++++++------ io/zenoh-transport/src/unicast/mod.rs | 57 +++++++----- io/zenoh-transport/src/unicast/net/link.rs | 4 +- io/zenoh-transport/src/unicast/net/rx.rs | 63 +++++++++----- .../src/unicast/net/transport.rs | 11 ++- io/zenoh-transport/src/unicast/net/tx.rs | 75 ++++++++++------ io/zenoh-transport/src/unicast/shm/link.rs | 25 +++--- io/zenoh-transport/src/unicast/shm/rx.rs | 69 ++++++++++----- .../src/unicast/shm/transport.rs | 9 +- io/zenoh-transport/src/unicast/shm/tx.rs | 87 ++++++++++++------- .../src/unicast/transport_unicast_inner.rs | 2 + io/zenoh-transport/tests/unicast_transport.rs | 1 + zenoh/Cargo.toml | 2 +- zenoh/src/net/routing/network.rs | 13 ++- 25 files changed, 419 insertions(+), 232 deletions(-) diff --git a/commons/zenoh-codec/src/network/mod.rs b/commons/zenoh-codec/src/network/mod.rs index 6a1ee3e01e..7263c3fe27 100644 --- a/commons/zenoh-codec/src/network/mod.rs +++ b/commons/zenoh-codec/src/network/mod.rs @@ -92,7 +92,7 @@ where _ => return Err(DidntRead), }; - Ok(NetworkMessage { body }) + Ok(body.into()) } } diff --git a/commons/zenoh-codec/src/scouting/mod.rs b/commons/zenoh-codec/src/scouting/mod.rs index cf2dba1c43..70f6fb8065 100644 --- a/commons/zenoh-codec/src/scouting/mod.rs +++ b/commons/zenoh-codec/src/scouting/mod.rs @@ -53,6 +53,6 @@ where id::HELLO => ScoutingBody::Hello(codec.read(&mut *reader)?), _ => return Err(DidntRead), }; - Ok(ScoutingMessage { body }) + Ok(body.into()) } } diff --git a/commons/zenoh-codec/src/transport/mod.rs b/commons/zenoh-codec/src/transport/mod.rs index c3bbbbc86e..8cb74d7d77 100644 --- a/commons/zenoh-codec/src/transport/mod.rs +++ b/commons/zenoh-codec/src/transport/mod.rs @@ -129,7 +129,7 @@ where _ => return Err(DidntRead), }; - Ok(TransportMessage { body }) + Ok(body.into()) } } diff --git a/commons/zenoh-codec/src/zenoh/mod.rs b/commons/zenoh-codec/src/zenoh/mod.rs index 6421d6dc23..44ae033748 100644 --- a/commons/zenoh-codec/src/zenoh/mod.rs +++ b/commons/zenoh-codec/src/zenoh/mod.rs @@ -125,13 +125,13 @@ where _ => return Err(DidntRead), }; - Ok(ZenohMessage { + Ok(ZenohMessage::new( body, - channel: Channel { + Channel { priority, reliability: self.reliability, }, routing_context, - }) + )) } } diff --git a/commons/zenoh-protocol/Cargo.toml b/commons/zenoh-protocol/Cargo.toml index 703dbbd6b7..829c275804 100644 --- a/commons/zenoh-protocol/Cargo.toml +++ b/commons/zenoh-protocol/Cargo.toml @@ -37,6 +37,7 @@ std = [ ] test = ["rand", "zenoh-buffers/test"] shared-memory = ["std", "zenoh-buffers/shared-memory"] +stats = [] complete_n = [] [dependencies] diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index b415bd02e8..cbda7f578b 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -99,7 +99,7 @@ impl NetworkMessage { _ => unreachable!(), }; - Self { body } + body.into() } #[inline] @@ -146,6 +146,7 @@ impl fmt::Display for NetworkMessage { } impl From for NetworkMessage { + #[inline] fn from(body: NetworkBody) -> Self { Self { body, diff --git a/commons/zenoh-protocol/src/transport/mod.rs b/commons/zenoh-protocol/src/transport/mod.rs index b61070e50a..5a1025fb36 100644 --- a/commons/zenoh-protocol/src/transport/mod.rs +++ b/commons/zenoh-protocol/src/transport/mod.rs @@ -136,7 +136,11 @@ impl TransportMessage { _ => unreachable!(), }; - Self { body } + Self { + body, + #[cfg(feature = "stats")] + size: None, + } } } diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs index 49674380c6..18fdad9692 100644 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ b/commons/zenoh-protocol/src/zenoh/mod.rs @@ -198,6 +198,17 @@ pub struct ZenohMessage { } impl ZenohMessage { + #[inline] + pub fn new(body: ZenohBody, channel: Channel, routing_context: Option) -> Self { + Self { + body, + channel, + routing_context, + #[cfg(feature = "stats")] + size: None, + } + } + pub fn make_declare( declarations: Vec, routing_context: Option, @@ -391,6 +402,8 @@ impl ZenohMessage { Self { body, + #[cfg(feature = "stats")] + size: None, channel, routing_context, } diff --git a/io/zenoh-transport/src/multicast/link.rs b/io/zenoh-transport/src/multicast/link.rs index fe99de9bf0..e41133f221 100644 --- a/io/zenoh-transport/src/multicast/link.rs +++ b/io/zenoh-transport/src/multicast/link.rs @@ -387,7 +387,14 @@ async fn rx_task( // Deserialize all the messages from the current ZBuf let zslice = ZSlice::make(Arc::new(buffer), 0, n) .map_err(|_| zerror!("Read {} bytes but buffer is {} bytes", n, mtu))?; - transport.read_messages(zslice, &link, batch_size, &loc)?; + transport.read_messages( + zslice, + &link, + batch_size, + &loc, + #[cfg(feature = "stats")] + &transport, + )?; } Action::Stop => break, } diff --git a/io/zenoh-transport/src/multicast/mod.rs b/io/zenoh-transport/src/multicast/mod.rs index 650e773462..3fca8edd52 100644 --- a/io/zenoh-transport/src/multicast/mod.rs +++ b/io/zenoh-transport/src/multicast/mod.rs @@ -53,31 +53,40 @@ stats_struct! { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct TransportMulticastStats { pub tx_t_msgs, - pub tx_z_msgs, - pub tx_z_dropped, - pub tx_z_data_msgs, - pub tx_z_data_payload_bytes, - pub tx_z_data_reply_msgs, - pub tx_z_data_reply_payload_bytes, - pub tx_z_pull_msgs, - pub tx_z_query_msgs, - pub tx_z_declare_msgs, - pub tx_z_linkstate_msgs, - pub tx_z_unit_msgs, - pub tx_z_unit_reply_msgs, + pub tx_n_msgs, + pub tx_n_dropped, + pub tx_z_put_user_msgs, + pub tx_z_put_user_pl_bytes, + // pub tx_z_put_admin_msgs, + // pub tx_z_put_admin_pl_bytes, + pub tx_z_del_user_msgs, + // pub tx_z_del_admin_msgs, + pub tx_z_query_user_msgs, + pub tx_z_query_user_pl_bytes, + // pub tx_z_query_admin_msgs, + // pub tx_z_query_admin_pl_bytes, + pub tx_z_reply_user_msgs, + pub tx_z_reply_user_pl_bytes, + // pub tx_z_reply_admin_msgs, + // pub tx_z_reply_admin_pl_bytes, pub tx_bytes, + pub rx_t_msgs, - pub rx_z_msgs, - pub rx_z_data_msgs, - pub rx_z_data_payload_bytes, - pub rx_z_data_reply_msgs, - pub rx_z_data_reply_payload_bytes, - pub rx_z_pull_msgs, - pub rx_z_query_msgs, - pub rx_z_declare_msgs, - pub rx_z_linkstate_msgs, - pub rx_z_unit_msgs, - pub rx_z_unit_reply_msgs, + pub rx_n_msgs, + pub rx_z_put_user_msgs, + pub rx_z_put_user_pl_bytes, + // pub rx_z_put_admin_msgs, + // pub rx_z_put_admin_pl_bytes, + pub rx_z_del_user_msgs, + // pub rx_z_del_admin_msgs, + pub rx_z_query_user_msgs, + pub rx_z_query_user_pl_bytes, + // pub rx_z_query_admin_msgs, + // pub rx_z_query_admin_pl_bytes, + pub rx_z_reply_user_msgs, + pub rx_z_reply_user_pl_bytes, + // pub rx_z_reply_admin_msgs, + // pub rx_z_reply_admin_pl_bytes, pub rx_bytes, } } diff --git a/io/zenoh-transport/src/multicast/rx.rs b/io/zenoh-transport/src/multicast/rx.rs index 0a74e7e6f4..6aa64644ed 100644 --- a/io/zenoh-transport/src/multicast/rx.rs +++ b/io/zenoh-transport/src/multicast/rx.rs @@ -23,8 +23,6 @@ use zenoh_protocol::core::{Priority, Reliability}; use zenoh_protocol::transport::{ BatchSize, Close, Fragment, Frame, Join, KeepAlive, TransportBody, TransportSn, }; -#[cfg(feature = "stats")] -use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::{core::Locator, network::NetworkMessage, transport::TransportMessage}; use zenoh_result::{bail, zerror, ZResult}; @@ -42,27 +40,51 @@ impl TransportMulticastInner { #[cfg(feature = "stats")] { use zenoh_buffers::SplitBuffer; - self.stats.inc_rx_z_msgs(1); + use zenoh_protocol::network::NetworkBody; + use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; + self.stats.inc_rx_n_msgs(1); match &msg.body { - ZenohBody::Data(data) => match data.reply_context { - Some(_) => { - self.stats.inc_rx_z_data_reply_msgs(1); - self.stats - .inc_rx_z_data_reply_payload_bytes(data.payload.len()); + NetworkBody::Push(push) => match &push.payload { + PushBody::Put(p) => { + self.stats.inc_rx_z_put_user_msgs(1); + self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); } - None => { - self.stats.inc_rx_z_data_msgs(1); - self.stats.inc_rx_z_data_payload_bytes(data.payload.len()); + PushBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), + }, + NetworkBody::Request(req) => match &req.payload { + RequestBody::Put(p) => { + self.stats.inc_rx_z_put_user_msgs(1); + self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); + } + RequestBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), + RequestBody::Query(q) => { + self.stats.inc_rx_z_query_user_msgs(1); + self.stats.inc_rx_z_query_user_pl_bytes( + q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); } + RequestBody::Pull(_) => (), }, - ZenohBody::Unit(unit) => match unit.reply_context { - Some(_) => self.stats.inc_rx_z_unit_reply_msgs(1), - None => self.stats.inc_rx_z_unit_msgs(1), + NetworkBody::Response(res) => match &res.payload { + ResponseBody::Put(p) => { + self.stats.inc_rx_z_put_user_msgs(1); + self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); + } + ResponseBody::Reply(r) => { + self.stats.inc_rx_z_reply_user_msgs(1); + self.stats.inc_rx_z_reply_user_pl_bytes(r.payload.len()); + } + ResponseBody::Err(e) => { + self.stats.inc_rx_z_reply_user_msgs(1); + self.stats.inc_rx_z_reply_user_pl_bytes( + e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); + } + ResponseBody::Ack(_) => (), }, - ZenohBody::Pull(_) => self.stats.inc_rx_z_pull_msgs(1), - ZenohBody::Query(_) => self.stats.inc_rx_z_query_msgs(1), - ZenohBody::Declare(_) => self.stats.inc_rx_z_declare_msgs(1), - ZenohBody::LinkStateList(_) => self.stats.inc_rx_z_linkstate_msgs(1), + NetworkBody::ResponseFinal(_) => (), + NetworkBody::Declare(_) => (), + NetworkBody::OAM(_) => (), } } @@ -280,6 +302,7 @@ impl TransportMulticastInner { link: &LinkMulticast, batch_size: BatchSize, locator: &Locator, + #[cfg(feature = "stats")] transport: &TransportMulticastInner, ) -> ZResult<()> { let codec = Zenoh080::new(); let mut reader = zslice.reader(); diff --git a/io/zenoh-transport/src/multicast/tx.rs b/io/zenoh-transport/src/multicast/tx.rs index 96dab0a876..b1e1eaa04f 100644 --- a/io/zenoh-transport/src/multicast/tx.rs +++ b/io/zenoh-transport/src/multicast/tx.rs @@ -14,8 +14,6 @@ use super::transport::TransportMulticastInner; use zenoh_core::zread; use zenoh_protocol::network::NetworkMessage; -#[cfg(feature = "stats")] -use zenoh_protocol::zenoh::ZenohBody; //noinspection ALL impl TransportMulticastInner { @@ -67,37 +65,62 @@ impl TransportMulticastInner { } #[cfg(feature = "stats")] - use zenoh_buffers::SplitBuffer; - #[cfg(feature = "stats")] - match &msg.body { - ZenohBody::Data(data) => match data.reply_context { - Some(_) => { - self.stats.inc_tx_z_data_reply_msgs(1); - self.stats - .inc_tx_z_data_reply_payload_bytes(data.payload.len()); - } - None => { - self.stats.inc_tx_z_data_msgs(1); - self.stats.inc_tx_z_data_payload_bytes(data.payload.len()); - } - }, - ZenohBody::Unit(unit) => match unit.reply_context { - Some(_) => self.stats.inc_tx_z_unit_reply_msgs(1), - None => self.stats.inc_tx_z_unit_msgs(1), - }, - ZenohBody::Pull(_) => self.stats.inc_tx_z_pull_msgs(1), - ZenohBody::Query(_) => self.stats.inc_tx_z_query_msgs(1), - ZenohBody::Declare(_) => self.stats.inc_tx_z_declare_msgs(1), - ZenohBody::LinkStateList(_) => self.stats.inc_tx_z_linkstate_msgs(1), + { + use zenoh_buffers::SplitBuffer; + use zenoh_protocol::network::NetworkBody; + use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; + match &msg.body { + NetworkBody::Push(push) => match &push.payload { + PushBody::Put(p) => { + self.stats.inc_tx_z_put_user_msgs(1); + self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); + } + PushBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), + }, + NetworkBody::Request(req) => match &req.payload { + RequestBody::Put(p) => { + self.stats.inc_tx_z_put_user_msgs(1); + self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); + } + RequestBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), + RequestBody::Query(q) => { + self.stats.inc_tx_z_query_user_msgs(1); + self.stats.inc_tx_z_query_user_pl_bytes( + q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); + } + RequestBody::Pull(_) => (), + }, + NetworkBody::Response(res) => match &res.payload { + ResponseBody::Put(p) => { + self.stats.inc_tx_z_put_user_msgs(1); + self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); + } + ResponseBody::Reply(r) => { + self.stats.inc_tx_z_reply_user_msgs(1); + self.stats.inc_tx_z_reply_user_pl_bytes(r.payload.len()); + } + ResponseBody::Err(e) => { + self.stats.inc_tx_z_reply_user_msgs(1); + self.stats.inc_tx_z_reply_user_pl_bytes( + e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); + } + ResponseBody::Ack(_) => (), + }, + NetworkBody::ResponseFinal(_) => (), + NetworkBody::Declare(_) => (), + NetworkBody::OAM(_) => (), + } } let res = self.schedule_on_link(msg); #[cfg(feature = "stats")] if res { - self.stats.inc_tx_z_msgs(1); + self.stats.inc_tx_n_msgs(1); } else { - self.stats.inc_tx_z_dropped(1); + self.stats.inc_tx_n_dropped(1); } res diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index b0d9e265e1..f3b9535854 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -55,31 +55,40 @@ stats_struct! { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct TransportUnicastStats { pub tx_t_msgs, - pub tx_z_msgs, - pub tx_z_dropped, - pub tx_z_data_msgs, - pub tx_z_data_payload_bytes, - pub tx_z_data_reply_msgs, - pub tx_z_data_reply_payload_bytes, - pub tx_z_pull_msgs, - pub tx_z_query_msgs, - pub tx_z_declare_msgs, - pub tx_z_linkstate_msgs, - pub tx_z_unit_msgs, - pub tx_z_unit_reply_msgs, + pub tx_n_msgs, + pub tx_n_dropped, + pub tx_z_put_user_msgs, + pub tx_z_put_user_pl_bytes, + // pub tx_z_put_admin_msgs, + // pub tx_z_put_admin_pl_bytes, + pub tx_z_del_user_msgs, + // pub tx_z_del_admin_msgs, + pub tx_z_query_user_msgs, + pub tx_z_query_user_pl_bytes, + // pub tx_z_query_admin_msgs, + // pub tx_z_query_admin_pl_bytes, + pub tx_z_reply_user_msgs, + pub tx_z_reply_user_pl_bytes, + // pub tx_z_reply_admin_msgs, + // pub tx_z_reply_admin_pl_bytes, pub tx_bytes, + pub rx_t_msgs, - pub rx_z_msgs, - pub rx_z_data_msgs, - pub rx_z_data_payload_bytes, - pub rx_z_data_reply_msgs, - pub rx_z_data_reply_payload_bytes, - pub rx_z_pull_msgs, - pub rx_z_query_msgs, - pub rx_z_declare_msgs, - pub rx_z_linkstate_msgs, - pub rx_z_unit_msgs, - pub rx_z_unit_reply_msgs, + pub rx_n_msgs, + pub rx_z_put_user_msgs, + pub rx_z_put_user_pl_bytes, + // pub rx_z_put_admin_msgs, + // pub rx_z_put_admin_pl_bytes, + pub rx_z_del_user_msgs, + // pub rx_z_del_admin_msgs, + pub rx_z_query_user_msgs, + pub rx_z_query_user_pl_bytes, + // pub rx_z_query_admin_msgs, + // pub rx_z_query_admin_pl_bytes, + pub rx_z_reply_user_msgs, + pub rx_z_reply_user_pl_bytes, + // pub rx_z_reply_admin_msgs, + // pub rx_z_reply_admin_pl_bytes, pub rx_bytes, } } @@ -194,7 +203,7 @@ impl TransportUnicast { #[cfg(feature = "stats")] pub fn get_stats(&self) -> ZResult { - Ok(self.get_inner()?.stats.snapshot()) + Ok(self.get_inner()?.stats()) } } diff --git a/io/zenoh-transport/src/unicast/net/link.rs b/io/zenoh-transport/src/unicast/net/link.rs index 7cbaa3e9d5..5d24dc9459 100644 --- a/io/zenoh-transport/src/unicast/net/link.rs +++ b/io/zenoh-transport/src/unicast/net/link.rs @@ -12,13 +12,13 @@ // ZettaScale Zenoh Team, // use super::transport::TransportUnicastNet; -#[cfg(feature = "stats")] -use super::TransportUnicastStatsAtomic; use crate::common::pipeline::{ TransmissionPipeline, TransmissionPipelineConf, TransmissionPipelineConsumer, TransmissionPipelineProducer, }; use crate::common::priority::TransportPriorityTx; +#[cfg(feature = "stats")] +use crate::unicast::TransportUnicastStatsAtomic; use crate::TransportExecutor; use async_std::prelude::FutureExt; use async_std::task; diff --git a/io/zenoh-transport/src/unicast/net/rx.rs b/io/zenoh-transport/src/unicast/net/rx.rs index 5ee7552ebe..0f9817f9bc 100644 --- a/io/zenoh-transport/src/unicast/net/rx.rs +++ b/io/zenoh-transport/src/unicast/net/rx.rs @@ -17,8 +17,6 @@ use super::transport::TransportUnicastNet; use crate::common::priority::TransportChannelRx; use async_std::task; use std::sync::MutexGuard; -#[cfg(feature = "stats")] -use zenoh_buffers::SplitBuffer; use zenoh_buffers::{ reader::{HasReader, Reader}, ZSlice, @@ -26,8 +24,6 @@ use zenoh_buffers::{ use zenoh_codec::{RCodec, Zenoh080}; use zenoh_core::{zlock, zread}; use zenoh_link::LinkUnicast; -#[cfg(feature = "stats")] -use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::{ core::{Priority, Reliability}, network::NetworkMessage, @@ -46,27 +42,52 @@ impl TransportUnicastNet { ) -> ZResult<()> { #[cfg(feature = "stats")] { - self.stats.inc_rx_z_msgs(1); + use zenoh_buffers::SplitBuffer; + use zenoh_protocol::network::NetworkBody; + use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; + self.stats.inc_rx_n_msgs(1); match &msg.body { - ZenohBody::Data(data) => match data.reply_context { - Some(_) => { - self.stats.inc_rx_z_data_reply_msgs(1); - self.stats - .inc_rx_z_data_reply_payload_bytes(data.payload.len()); + NetworkBody::Push(push) => match &push.payload { + PushBody::Put(p) => { + self.stats.inc_rx_z_put_user_msgs(1); + self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); } - None => { - self.stats.inc_rx_z_data_msgs(1); - self.stats.inc_rx_z_data_payload_bytes(data.payload.len()); + PushBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), + }, + NetworkBody::Request(req) => match &req.payload { + RequestBody::Put(p) => { + self.stats.inc_rx_z_put_user_msgs(1); + self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); + } + RequestBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), + RequestBody::Query(q) => { + self.stats.inc_rx_z_query_user_msgs(1); + self.stats.inc_rx_z_query_user_pl_bytes( + q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); } + RequestBody::Pull(_) => (), }, - ZenohBody::Unit(unit) => match unit.reply_context { - Some(_) => self.stats.inc_rx_z_unit_reply_msgs(1), - None => self.stats.inc_rx_z_unit_msgs(1), + NetworkBody::Response(res) => match &res.payload { + ResponseBody::Put(p) => { + self.stats.inc_rx_z_put_user_msgs(1); + self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); + } + ResponseBody::Reply(r) => { + self.stats.inc_rx_z_reply_user_msgs(1); + self.stats.inc_rx_z_reply_user_pl_bytes(r.payload.len()); + } + ResponseBody::Err(e) => { + self.stats.inc_rx_z_reply_user_msgs(1); + self.stats.inc_rx_z_reply_user_pl_bytes( + e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); + } + ResponseBody::Ack(_) => (), }, - ZenohBody::Pull(_) => self.stats.inc_rx_z_pull_msgs(1), - ZenohBody::Query(_) => self.stats.inc_rx_z_query_msgs(1), - ZenohBody::Declare(_) => self.stats.inc_rx_z_declare_msgs(1), - ZenohBody::LinkStateList(_) => self.stats.inc_rx_z_linkstate_msgs(1), + NetworkBody::ResponseFinal(_) => (), + NetworkBody::Declare(_) => (), + NetworkBody::OAM(_) => (), } } @@ -231,7 +252,7 @@ impl TransportUnicastNet { #[cfg(feature = "stats")] { - transport.stats.inc_rx_t_msgs(1); + self.stats.inc_rx_t_msgs(1); } match msg.body { diff --git a/io/zenoh-transport/src/unicast/net/transport.rs b/io/zenoh-transport/src/unicast/net/transport.rs index cadd85ba10..22da062556 100644 --- a/io/zenoh-transport/src/unicast/net/transport.rs +++ b/io/zenoh-transport/src/unicast/net/transport.rs @@ -11,11 +11,11 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::link::TransportLinkUnicast; -#[cfg(feature = "stats")] -use super::TransportUnicastStatsAtomic; use crate::common::priority::{TransportPriorityRx, TransportPriorityTx}; use crate::transport_unicast_inner::TransportUnicastTrait; +use crate::unicast::net::link::TransportLinkUnicast; +#[cfg(feature = "stats")] +use crate::unicast::TransportUnicastStatsAtomic; use crate::TransportConfigUnicast; use crate::{TransportExecutor, TransportManager, TransportPeerEventHandler}; use async_std::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; @@ -320,6 +320,11 @@ impl TransportUnicastTrait for TransportUnicastNet { &self.config } + #[cfg(feature = "stats")] + fn stats(&self) -> crate::TransportUnicastStats { + self.stats.snapshot() + } + /*************************************/ /* INITIATION */ /*************************************/ diff --git a/io/zenoh-transport/src/unicast/net/tx.rs b/io/zenoh-transport/src/unicast/net/tx.rs index 6479444d76..8fda2ac893 100644 --- a/io/zenoh-transport/src/unicast/net/tx.rs +++ b/io/zenoh-transport/src/unicast/net/tx.rs @@ -12,12 +12,8 @@ // ZettaScale Zenoh Team, // use super::transport::TransportUnicastNet; -#[cfg(feature = "stats")] -use zenoh_buffers::SplitBuffer; use zenoh_core::zread; use zenoh_protocol::network::NetworkMessage; -#[cfg(feature = "stats")] -use zenoh_protocol::zenoh::ZenohBody; impl TransportUnicastNet { fn schedule_on_link(&self, msg: NetworkMessage) -> bool { @@ -81,35 +77,62 @@ impl TransportUnicastNet { } #[cfg(feature = "stats")] - match &msg.body { - ZenohBody::Data(data) => match data.reply_context { - Some(_) => { - self.stats.inc_tx_z_data_reply_msgs(1); - self.stats - .inc_tx_z_data_reply_payload_bytes(data.payload.len()); - } - None => { - self.stats.inc_tx_z_data_msgs(1); - self.stats.inc_tx_z_data_payload_bytes(data.payload.len()); - } - }, - ZenohBody::Unit(unit) => match unit.reply_context { - Some(_) => self.stats.inc_tx_z_unit_reply_msgs(1), - None => self.stats.inc_tx_z_unit_msgs(1), - }, - ZenohBody::Pull(_) => self.stats.inc_tx_z_pull_msgs(1), - ZenohBody::Query(_) => self.stats.inc_tx_z_query_msgs(1), - ZenohBody::Declare(_) => self.stats.inc_tx_z_declare_msgs(1), - ZenohBody::LinkStateList(_) => self.stats.inc_tx_z_linkstate_msgs(1), + { + use zenoh_buffers::SplitBuffer; + use zenoh_protocol::network::NetworkBody; + use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; + match &msg.body { + NetworkBody::Push(push) => match &push.payload { + PushBody::Put(p) => { + self.stats.inc_tx_z_put_user_msgs(1); + self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); + } + PushBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), + }, + NetworkBody::Request(req) => match &req.payload { + RequestBody::Put(p) => { + self.stats.inc_tx_z_put_user_msgs(1); + self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); + } + RequestBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), + RequestBody::Query(q) => { + self.stats.inc_tx_z_query_user_msgs(1); + self.stats.inc_tx_z_query_user_pl_bytes( + q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); + } + RequestBody::Pull(_) => (), + }, + NetworkBody::Response(res) => match &res.payload { + ResponseBody::Put(p) => { + self.stats.inc_tx_z_put_user_msgs(1); + self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); + } + ResponseBody::Reply(r) => { + self.stats.inc_tx_z_reply_user_msgs(1); + self.stats.inc_tx_z_reply_user_pl_bytes(r.payload.len()); + } + ResponseBody::Err(e) => { + self.stats.inc_tx_z_reply_user_msgs(1); + self.stats.inc_tx_z_reply_user_pl_bytes( + e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); + } + ResponseBody::Ack(_) => (), + }, + NetworkBody::ResponseFinal(_) => (), + NetworkBody::Declare(_) => (), + NetworkBody::OAM(_) => (), + } } let res = self.schedule_on_link(msg); #[cfg(feature = "stats")] if res { - self.stats.inc_tx_z_msgs(1); + self.stats.inc_tx_n_msgs(1); } else { - self.stats.inc_tx_z_dropped(1); + self.stats.inc_tx_n_dropped(1); } res diff --git a/io/zenoh-transport/src/unicast/shm/link.rs b/io/zenoh-transport/src/unicast/shm/link.rs index ad10e9b950..5b5c9b764b 100644 --- a/io/zenoh-transport/src/unicast/shm/link.rs +++ b/io/zenoh-transport/src/unicast/shm/link.rs @@ -12,8 +12,6 @@ // ZettaScale Zenoh Team, // use super::transport::TransportUnicastShm; -#[cfg(feature = "stats")] -use super::TransportUnicastStatsAtomic; use crate::TransportExecutor; use async_std::task; use async_std::{prelude::FutureExt, sync::RwLock}; @@ -55,11 +53,11 @@ pub(crate) async fn send_with_link(link: &LinkUnicast, msg: TransportMessageShm) } log::trace!("Sent: {:?}", msg); - #[cfg(feature = "stats")] - { - stats.inc_tx_t_msgs(1); - stats.inc_tx_bytes(buff.len() + 2); - } + // #[cfg(feature = "stats")] + // { + // stats.inc_tx_t_msgs(1); + // stats.inc_tx_bytes(buff.len() + 2); + // } Ok(()) } @@ -81,8 +79,8 @@ impl TransportUnicastShm { let res = keepalive_task( c_transport.link.clone(), keep_alive, - #[cfg(feature = "stats")] - c_transport.stats, + // #[cfg(feature = "stats")] + // c_transport.stats, ) .await; log::debug!( @@ -163,7 +161,7 @@ impl TransportUnicastShm { async fn keepalive_task( link: Arc>, keep_alive: Duration, - #[cfg(feature = "stats")] stats: Arc, + // #[cfg(feature = "stats")] stats: Arc, ) -> ZResult<()> { loop { async_std::task::sleep(keep_alive).await; @@ -174,10 +172,9 @@ async fn keepalive_task( let guard = zasyncwrite!(link); let _ = send_with_link( - &guard, - keepailve, - #[cfg(feature = "stats")] - &stats, + &guard, keepailve, + // #[cfg(feature = "stats")] + // &stats, ) .await; drop(guard); diff --git a/io/zenoh-transport/src/unicast/shm/rx.rs b/io/zenoh-transport/src/unicast/shm/rx.rs index 4e888a9e9c..01c211241a 100644 --- a/io/zenoh-transport/src/unicast/shm/rx.rs +++ b/io/zenoh-transport/src/unicast/shm/rx.rs @@ -12,8 +12,6 @@ // ZettaScale Zenoh Team, // use super::transport::TransportUnicastShm; -#[cfg(feature = "stats")] -use zenoh_buffers::SplitBuffer; use zenoh_buffers::{ reader::{HasReader, Reader}, ZSlice, @@ -21,8 +19,6 @@ use zenoh_buffers::{ use zenoh_codec::{RCodec, Zenoh080}; use zenoh_core::zread; use zenoh_link::LinkUnicast; -#[cfg(feature = "stats")] -use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::{network::NetworkMessage, transport::TransportMessageShm}; use zenoh_result::{zerror, ZResult}; @@ -37,27 +33,52 @@ impl TransportUnicastShm { ) -> ZResult<()> { #[cfg(feature = "stats")] { - self.stats.inc_rx_z_msgs(1); + use zenoh_buffers::SplitBuffer; + use zenoh_protocol::network::NetworkBody; + use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; + self.stats.inc_rx_n_msgs(1); match &msg.body { - ZenohBody::Data(data) => match data.reply_context { - Some(_) => { - self.stats.inc_rx_z_data_reply_msgs(1); - self.stats - .inc_rx_z_data_reply_payload_bytes(data.payload.len()); + NetworkBody::Push(push) => match &push.payload { + PushBody::Put(p) => { + self.stats.inc_rx_z_put_user_msgs(1); + self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); } - None => { - self.stats.inc_rx_z_data_msgs(1); - self.stats.inc_rx_z_data_payload_bytes(data.payload.len()); + PushBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), + }, + NetworkBody::Request(req) => match &req.payload { + RequestBody::Put(p) => { + self.stats.inc_rx_z_put_user_msgs(1); + self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); + } + RequestBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), + RequestBody::Query(q) => { + self.stats.inc_rx_z_query_user_msgs(1); + self.stats.inc_rx_z_query_user_pl_bytes( + q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); } + RequestBody::Pull(_) => (), }, - ZenohBody::Unit(unit) => match unit.reply_context { - Some(_) => self.stats.inc_rx_z_unit_reply_msgs(1), - None => self.stats.inc_rx_z_unit_msgs(1), + NetworkBody::Response(res) => match &res.payload { + ResponseBody::Put(p) => { + self.stats.inc_rx_z_put_user_msgs(1); + self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); + } + ResponseBody::Reply(r) => { + self.stats.inc_rx_z_reply_user_msgs(1); + self.stats.inc_rx_z_reply_user_pl_bytes(r.payload.len()); + } + ResponseBody::Err(e) => { + self.stats.inc_rx_z_reply_user_msgs(1); + self.stats.inc_rx_z_reply_user_pl_bytes( + e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); + } + ResponseBody::Ack(_) => (), }, - ZenohBody::Pull(_) => self.stats.inc_rx_z_pull_msgs(1), - ZenohBody::Query(_) => self.stats.inc_rx_z_query_msgs(1), - ZenohBody::Declare(_) => self.stats.inc_rx_z_declare_msgs(1), - ZenohBody::LinkStateList(_) => self.stats.inc_rx_z_linkstate_msgs(1), + NetworkBody::ResponseFinal(_) => (), + NetworkBody::Declare(_) => (), + NetworkBody::OAM(_) => (), } } @@ -94,10 +115,10 @@ impl TransportUnicastShm { log::trace!("Received: {:?}", msg); - #[cfg(feature = "stats")] - { - transport.stats.inc_rx_t_msgs(1); - } + // #[cfg(feature = "stats")] + // { + // transport.stats.inc_rx_t_msgs(1); + // } match msg.body { zenoh_protocol::transport::TransportBodyShm::Close(_) => { diff --git a/io/zenoh-transport/src/unicast/shm/transport.rs b/io/zenoh-transport/src/unicast/shm/transport.rs index ccaa6e2cdc..ca7470ad9e 100644 --- a/io/zenoh-transport/src/unicast/shm/transport.rs +++ b/io/zenoh-transport/src/unicast/shm/transport.rs @@ -13,9 +13,9 @@ // #[cfg(feature = "transport_shm")] use super::link::send_with_link; -#[cfg(feature = "stats")] -use super::TransportUnicastStatsAtomic; use crate::transport_unicast_inner::TransportUnicastTrait; +#[cfg(feature = "stats")] +use crate::unicast::TransportUnicastStatsAtomic; use crate::TransportConfigUnicast; use crate::TransportManager; use crate::{TransportExecutor, TransportPeerEventHandler}; @@ -188,6 +188,11 @@ impl TransportUnicastTrait for TransportUnicastShm { &self.config } + #[cfg(feature = "stats")] + fn stats(&self) -> crate::TransportUnicastStats { + self.stats.snapshot() + } + /*************************************/ /* TX */ /*************************************/ diff --git a/io/zenoh-transport/src/unicast/shm/tx.rs b/io/zenoh-transport/src/unicast/shm/tx.rs index d54b4281dd..c333a42384 100644 --- a/io/zenoh-transport/src/unicast/shm/tx.rs +++ b/io/zenoh-transport/src/unicast/shm/tx.rs @@ -12,10 +12,6 @@ // ZettaScale Zenoh Team, // use super::transport::TransportUnicastShm; -#[cfg(feature = "stats")] -use zenoh_buffers::SplitBuffer; -#[cfg(feature = "stats")] -use zenoh_protocol::zenoh::ZenohBody; use zenoh_protocol::{ network::NetworkMessage, transport::{TransportBodyShm, TransportMessageShm}, @@ -39,40 +35,67 @@ impl TransportUnicastShm { } } - #[cfg(feature = "stats")] - match &msg.body { - ZenohBody::Data(data) => match data.reply_context { - Some(_) => { - self.stats.inc_tx_z_data_reply_msgs(1); - self.stats - .inc_tx_z_data_reply_payload_bytes(data.payload.len()); - } - None => { - self.stats.inc_tx_z_data_msgs(1); - self.stats.inc_tx_z_data_payload_bytes(data.payload.len()); - } - }, - ZenohBody::Unit(unit) => match unit.reply_context { - Some(_) => self.stats.inc_tx_z_unit_reply_msgs(1), - None => self.stats.inc_tx_z_unit_msgs(1), - }, - ZenohBody::Pull(_) => self.stats.inc_tx_z_pull_msgs(1), - ZenohBody::Query(_) => self.stats.inc_tx_z_query_msgs(1), - ZenohBody::Declare(_) => self.stats.inc_tx_z_declare_msgs(1), - ZenohBody::LinkStateList(_) => self.stats.inc_tx_z_linkstate_msgs(1), - } + // #[cfg(feature = "stats")] + // { + // use zenoh_buffers::SplitBuffer; + // use zenoh_protocol::network::NetworkBody; + // use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; + // match &msg.body { + // NetworkBody::Push(push) => match &push.payload { + // PushBody::Put(p) => { + // self.stats.inc_tx_z_put_user_msgs(1); + // self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); + // } + // PushBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), + // }, + // NetworkBody::Request(req) => match &req.payload { + // RequestBody::Put(p) => { + // self.stats.inc_tx_z_put_user_msgs(1); + // self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); + // } + // RequestBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), + // RequestBody::Query(q) => { + // self.stats.inc_tx_z_query_user_msgs(1); + // self.stats.inc_tx_z_query_user_pl_bytes( + // q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + // ); + // } + // RequestBody::Pull(_) => (), + // }, + // NetworkBody::Response(res) => match &res.payload { + // ResponseBody::Put(p) => { + // self.stats.inc_tx_z_put_user_msgs(1); + // self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); + // } + // ResponseBody::Reply(r) => { + // self.stats.inc_tx_z_reply_user_msgs(1); + // self.stats.inc_tx_z_reply_user_pl_bytes(r.payload.len()); + // } + // ResponseBody::Err(e) => { + // self.stats.inc_tx_z_reply_user_msgs(1); + // self.stats.inc_tx_z_reply_user_pl_bytes( + // e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + // ); + // } + // ResponseBody::Ack(_) => (), + // }, + // NetworkBody::ResponseFinal(_) => (), + // NetworkBody::Declare(_) => (), + // NetworkBody::OAM(_) => (), + // } + // } let msg = TransportMessageShm { body: TransportBodyShm::Network(Box::new(msg)), }; let res = self.send(msg); - #[cfg(feature = "stats")] - if res { - self.stats.inc_tx_z_msgs(1); - } else { - self.stats.inc_tx_z_dropped(1); - } + // #[cfg(feature = "stats")] + // if res { + // self.stats.inc_tx_z_msgs(1); + // } else { + // self.stats.inc_tx_z_dropped(1); + // } res } diff --git a/io/zenoh-transport/src/unicast/transport_unicast_inner.rs b/io/zenoh-transport/src/unicast/transport_unicast_inner.rs index 83e7b22dbe..54069b4ea3 100644 --- a/io/zenoh-transport/src/unicast/transport_unicast_inner.rs +++ b/io/zenoh-transport/src/unicast/transport_unicast_inner.rs @@ -44,6 +44,8 @@ pub(crate) trait TransportUnicastTrait: Send + Sync { fn is_shm(&self) -> bool; fn is_qos(&self) -> bool; fn get_config(&self) -> &TransportConfigUnicast; + #[cfg(feature = "stats")] + fn stats(&self) -> crate::TransportUnicastStats; /*************************************/ /* LINK */ diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index adf143038d..3f579cd91a 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -543,6 +543,7 @@ async fn run_single( println!("\tClient: {:?}", c_stats); let r_stats = router_manager .get_transport_unicast(&client_manager.config.zid) + .await .unwrap() .get_stats() .unwrap(); diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 54ec0a9859..da80f8ee9d 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -37,7 +37,7 @@ shared-memory = [ "zenoh-protocol/shared-memory", "zenoh-transport/shared-memory", ] -stats = ["zenoh-transport/stats"] +stats = ["zenoh-transport/stats", "zenoh-protocol/stats"] transport_multilink = ["zenoh-transport/transport_multilink"] transport_quic = ["zenoh-transport/transport_quic"] transport_serial = ["zenoh-transport/transport_serial"] diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index 01554f08b3..37493831bb 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -272,14 +272,13 @@ impl Network { let codec = Zenoh080Routing::new(); let mut buf = ZBuf::empty(); codec.write(&mut buf.writer(), &LinkStateList { link_states })?; - Ok(NetworkMessage { - body: NetworkBody::OAM(Oam { - id: OAM_LINKSTATE, - body: ZExtBody::ZBuf(buf), - ext_qos: oam::ext::QoSType::default(), - ext_tstamp: None, - }), + Ok(NetworkBody::OAM(Oam { + id: OAM_LINKSTATE, + body: ZExtBody::ZBuf(buf), + ext_qos: oam::ext::QoSType::default(), + ext_tstamp: None, }) + .into()) } fn send_on_link(&self, idxs: Vec<(NodeIndex, Details)>, transport: &TransportUnicast) { From 10d3c221c673136c0eb842ad9c1497921760bb85 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Mon, 28 Aug 2023 10:29:42 +0200 Subject: [PATCH 190/203] Fix build with no features --- zenoh/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 391c4ba9c9..dedbdc8192 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -87,7 +87,7 @@ uuid = { workspace = true, features = ["default"] } vec_map = { workspace = true } zenoh-buffers = { workspace = true, features = ["std"] } zenoh-codec = { workspace = true } -zenoh-collections = { workspace = true } +zenoh-collections = { workspace = true, features = ["std"] } zenoh-config = { workspace = true } zenoh-core = { workspace = true } zenoh-crypto = { workspace = true } From 684019b66a2b65235d23f8088685116e6357dee3 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Mon, 28 Aug 2023 11:33:05 +0200 Subject: [PATCH 191/203] Fix build with complete_n feature --- commons/zenoh-codec/src/network/request.rs | 1 + zenoh/src/net/routing/queries.rs | 18 +++++++++++++----- zenoh/src/net/routing/resource.rs | 4 ++-- zenoh/src/session.rs | 4 ++-- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 18ea0ae9e6..841ca1bbd6 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -64,6 +64,7 @@ where 2 => ext::TargetType::AllComplete, #[cfg(feature = "complete_n")] n => ext::TargetType::Complete(n - 3), + #[cfg(not(feature = "complete_n"))] _ => return Err(DidntRead), }; Ok((rt, more)) diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 46b6164400..ed7f899a65 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -1364,7 +1364,11 @@ fn insert_target_for_qabls( None }, ), - complete: if complete { qabl_info.complete } else { 0 }, + complete: if complete { + qabl_info.complete as u64 + } else { + 0 + }, distance: net.distances[qabl_idx.index()], }); } @@ -1483,7 +1487,11 @@ fn compute_query_route( if let Some(qabl_info) = context.qabl.as_ref() { route.push(QueryTargetQabl { direction: (context.face.clone(), key_expr.to_owned(), None), - complete: if complete { qabl_info.complete } else { 0 }, + complete: if complete { + qabl_info.complete as u64 + } else { + 0 + }, distance: 0.5, }); } @@ -1772,7 +1780,7 @@ fn compute_final_route( route.entry(qabl.direction.0.id).or_insert_with(|| { let mut direction = qabl.direction.clone(); let qid = insert_pending_query(&mut direction.0, query.clone()); - (direction, qid, QueryTarget::Complete(nb)) + (direction, qid, TargetType::Complete(nb)) }); remaining -= nb; if remaining == 0 { @@ -1787,7 +1795,7 @@ fn compute_final_route( route.entry(qabl.direction.0.id).or_insert_with(|| { let mut direction = qabl.direction.clone(); let qid = insert_pending_query(&mut direction.0, query.clone()); - (direction, qid, QueryTarget::Complete(nb)) + (direction, qid, TargetType::Complete(nb)) }); remaining -= nb; if remaining == 0 { @@ -2083,7 +2091,7 @@ pub fn route_query( ext_nodeid: ext::NodeIdType { node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, }, - ext_target: t, + ext_target: *t, ext_budget: None, ext_timeout: None, payload: body.clone(), diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index 18417a4781..38898a35b5 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -36,12 +36,12 @@ use zenoh_sync::get_mut_unchecked; pub(super) type Direction = (Arc, WireExpr<'static>, Option); pub(super) type Route = HashMap; #[cfg(feature = "complete_n")] -pub(super) type QueryRoute = HashMap; +pub(super) type QueryRoute = HashMap; #[cfg(not(feature = "complete_n"))] pub(super) type QueryRoute = HashMap; pub(super) struct QueryTargetQabl { pub(super) direction: Direction, - pub(super) complete: u8, + pub(super) complete: u64, pub(super) distance: f64, } pub(super) type QueryTargetQablSet = Vec; diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 2ccfa79174..6986f51316 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -1277,7 +1277,7 @@ impl Session { } #[cfg(feature = "complete_n")] - pub(crate) fn complete_twin_qabls(state: &SessionState, key: &WireExpr) -> u64 { + pub(crate) fn complete_twin_qabls(state: &SessionState, key: &WireExpr) -> u8 { state .queryables .values() @@ -1287,7 +1287,7 @@ impl Session { && state.local_wireexpr_to_expr(&q.key_expr).unwrap() == state.local_wireexpr_to_expr(key).unwrap() }) - .count() as u64 + .count() as u8 } pub(crate) fn close_queryable(&self, qid: usize) -> ZResult<()> { From 896143082331a4f3295e507f9df2a9114d8b3553 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Tue, 29 Aug 2023 16:06:56 +0200 Subject: [PATCH 192/203] Reexport public types in zenoh-config --- commons/zenoh-config/src/lib.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 7fd673ee98..5f4082e74d 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -36,12 +36,11 @@ use std::{ use validated_struct::ValidatedMapAssociatedTypes; pub use validated_struct::{GetError, ValidatedMap}; use zenoh_core::zlock; +pub use zenoh_protocol::core::{ + whatami, EndPoint, Locator, Priority, WhatAmI, WhatAmIMatcher, WhatAmIMatcherVisitor, ZenohId, +}; use zenoh_protocol::{ - core::{ - key_expr::OwnedKeyExpr, - whatami::{self, WhatAmI, WhatAmIMatcher, WhatAmIMatcherVisitor}, - Bits, EndPoint, ZenohId, - }, + core::{key_expr::OwnedKeyExpr, Bits}, transport::{BatchSize, TransportSn}, }; use zenoh_result::{bail, zerror, ZResult}; From b46da434e1fa2f80f07bc431c3e4c52e189d26d3 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Tue, 29 Aug 2023 17:49:27 +0200 Subject: [PATCH 193/203] Implement Properties into HashMap --- commons/zenoh-collections/src/properties.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/commons/zenoh-collections/src/properties.rs b/commons/zenoh-collections/src/properties.rs index 441cf4c8be..6da7178c57 100644 --- a/commons/zenoh-collections/src/properties.rs +++ b/commons/zenoh-collections/src/properties.rs @@ -131,6 +131,12 @@ impl TryFrom<&std::path::Path> for Properties { } } +impl From for HashMap { + fn from(props: Properties) -> Self { + props.0 + } +} + #[cfg(test)] mod tests { use super::*; From 6b38103e5f82016a59fc994cb6bf61089329a932 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Mon, 4 Sep 2023 16:43:54 +0200 Subject: [PATCH 194/203] Peers send sub declarations to multicast --- zenoh/src/net/routing/pubsub.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index 7544f25a6f..9765d8f9f6 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -463,10 +463,34 @@ pub fn declare_client_subscription( ); } else { propagate_simple_subscription(&mut wtables, &res, &propa_sub_info, face); + for mcast_group in &wtables.mcast_groups { + mcast_group.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // TODO + wire_expr: res.expr().into(), + ext_info: *sub_info, + }), + }) + } } } _ => { propagate_simple_subscription(&mut wtables, &res, &propa_sub_info, face); + for mcast_group in &wtables.mcast_groups { + mcast_group.primitives.send_declare(Declare { + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // TODO + wire_expr: res.expr().into(), + ext_info: *sub_info, + }), + }) + } } } disable_matches_data_routes(&mut wtables, &mut res); From 57cb492bbc6eed07ceb8e25a75d00c8afc65b97c Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Tue, 5 Sep 2023 16:16:39 +0200 Subject: [PATCH 195/203] Fix ValueType encoding --- commons/zenoh-protocol/src/zenoh_new/err.rs | 2 +- commons/zenoh-protocol/src/zenoh_new/query.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/commons/zenoh-protocol/src/zenoh_new/err.rs b/commons/zenoh-protocol/src/zenoh_new/err.rs index 3f689169df..721d6a6830 100644 --- a/commons/zenoh-protocol/src/zenoh_new/err.rs +++ b/commons/zenoh-protocol/src/zenoh_new/err.rs @@ -62,7 +62,7 @@ pub mod ext { /// Used to carry a body attached to the query /// Shared Memory extension is automatically defined by ValueType extension if /// #[cfg(feature = "shared-memory")] is defined. - pub type ErrBodyType = crate::zenoh_new::ext::ValueType<0x02, 0x03>; + pub type ErrBodyType = crate::zenoh_new::ext::ValueType<{ ZExtZBuf::<0x02>::id(false) }, 0x03>; } impl Err { diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs index 97d2dd87fc..d50649ff41 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -106,7 +106,8 @@ pub mod ext { /// Used to carry a body attached to the query /// Shared Memory extension is automatically defined by ValueType extension if /// #[cfg(feature = "shared-memory")] is defined. - pub type QueryBodyType = crate::zenoh_new::ext::ValueType<0x03, 0x04>; + pub type QueryBodyType = + crate::zenoh_new::ext::ValueType<{ ZExtZBuf::<0x03>::id(false) }, 0x04>; } impl Query { From 9ae659aa255c52e28192637d691761ee69525d15 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Thu, 7 Sep 2023 14:26:27 +0200 Subject: [PATCH 196/203] New protocol stats (#546) * Update TransportStats API * Discriminate admin and user traffic in stats * Fix build with stats and shared-memory features enabled * Code format --- Cargo.lock | 1 + io/zenoh-transport/Cargo.toml | 2 +- io/zenoh-transport/src/common/mod.rs | 2 +- io/zenoh-transport/src/common/stats.rs | 69 +++++++-- io/zenoh-transport/src/lib.rs | 3 + io/zenoh-transport/src/multicast/link.rs | 6 +- io/zenoh-transport/src/multicast/mod.rs | 56 +------- io/zenoh-transport/src/multicast/rx.rs | 51 ------- io/zenoh-transport/src/multicast/transport.rs | 6 +- io/zenoh-transport/src/multicast/tx.rs | 50 ------- io/zenoh-transport/src/unicast/mod.rs | 54 +------- io/zenoh-transport/src/unicast/net/link.rs | 4 +- io/zenoh-transport/src/unicast/net/rx.rs | 51 ------- .../src/unicast/net/transport.rs | 12 +- io/zenoh-transport/src/unicast/net/tx.rs | 50 ------- io/zenoh-transport/src/unicast/shm/rx.rs | 51 ------- .../src/unicast/shm/transport.rs | 12 +- io/zenoh-transport/src/unicast/shm/tx.rs | 50 ------- .../src/unicast/transport_unicast_inner.rs | 2 +- .../tests/multicast_transport.rs | 4 +- io/zenoh-transport/tests/unicast_transport.rs | 3 +- zenoh/Cargo.toml | 1 + zenoh/src/net/routing/face.rs | 7 + zenoh/src/net/routing/pubsub.rs | 53 +++++++ zenoh/src/net/routing/queries.rs | 131 ++++++++++++++++-- zenoh/src/net/routing/router.rs | 47 ++++++- zenoh/src/net/runtime/adminspace.rs | 2 +- 27 files changed, 318 insertions(+), 462 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5e124ce02..1e392260ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4432,6 +4432,7 @@ dependencies = [ "lazy_static", "log", "ordered-float", + "paste", "petgraph", "rand 0.8.5", "regex", diff --git a/io/zenoh-transport/Cargo.toml b/io/zenoh-transport/Cargo.toml index 96ead9b1af..7476da7196 100644 --- a/io/zenoh-transport/Cargo.toml +++ b/io/zenoh-transport/Cargo.toml @@ -43,7 +43,7 @@ transport_ws = ["zenoh-link/transport_ws"] transport_serial = ["zenoh-link/transport_serial"] transport_compression = [] transport_shm = ["zenoh-link/transport_shm"] -stats = [] +stats = ["zenoh-protocol/stats"] test = [] unstable = [] diff --git a/io/zenoh-transport/src/common/mod.rs b/io/zenoh-transport/src/common/mod.rs index 276fe0240c..0837ced4f7 100644 --- a/io/zenoh-transport/src/common/mod.rs +++ b/io/zenoh-transport/src/common/mod.rs @@ -17,4 +17,4 @@ pub(crate) mod pipeline; pub(crate) mod priority; pub(crate) mod seq_num; #[cfg(feature = "stats")] -pub(crate) mod stats; +pub mod stats; diff --git a/io/zenoh-transport/src/common/stats.rs b/io/zenoh-transport/src/common/stats.rs index e7fb0f5c3e..287018aeb0 100644 --- a/io/zenoh-transport/src/common/stats.rs +++ b/io/zenoh-transport/src/common/stats.rs @@ -22,42 +22,42 @@ macro_rules! stats_struct { } ) => { paste::paste! { - $(#[$meta])* $vis struct $struct_name { $( $(#[$field_meta:meta])* - $field_vis $field_name: usize, + $field_vis $field_name: AtomicUsize, )* } - struct [<$struct_name Atomic>] { + $(#[$meta])* + $vis struct [<$struct_name Report>] { $( $(#[$field_meta:meta])* - $field_name: AtomicUsize, + $field_vis $field_name: usize, )* } - impl [<$struct_name Atomic>] { - fn snapshot(&self) -> $struct_name { - $struct_name { + impl $struct_name { + $vis fn report(&self) -> [<$struct_name Report>] { + [<$struct_name Report>] { $($field_name: self.[](),)* } } $( - fn [](&self) -> usize { + $vis fn [](&self) -> usize { self.$field_name.load(Ordering::Relaxed) } - fn [](&self, nb: usize) { + $vis fn [](&self, nb: usize) { self.$field_name.fetch_add(nb, Ordering::Relaxed); } )* } - impl Default for [<$struct_name Atomic>] { - fn default() -> [<$struct_name Atomic>] { - [<$struct_name Atomic>] { + impl Default for $struct_name { + fn default() -> $struct_name { + $struct_name { $($field_name: AtomicUsize::new(0),)* } } @@ -65,4 +65,47 @@ macro_rules! stats_struct { } } } -pub(crate) use stats_struct; + +use serde::{Deserialize, Serialize}; +use std::sync::atomic::{AtomicUsize, Ordering}; +stats_struct! { + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct TransportStats { + pub tx_t_msgs, + pub tx_n_msgs, + pub tx_n_dropped, + pub tx_z_put_user_msgs, + pub tx_z_put_user_pl_bytes, + pub tx_z_put_admin_msgs, + pub tx_z_put_admin_pl_bytes, + pub tx_z_del_user_msgs, + pub tx_z_del_admin_msgs, + pub tx_z_query_user_msgs, + pub tx_z_query_user_pl_bytes, + pub tx_z_query_admin_msgs, + pub tx_z_query_admin_pl_bytes, + pub tx_z_reply_user_msgs, + pub tx_z_reply_user_pl_bytes, + pub tx_z_reply_admin_msgs, + pub tx_z_reply_admin_pl_bytes, + pub tx_bytes, + + pub rx_t_msgs, + pub rx_n_msgs, + pub rx_z_put_user_msgs, + pub rx_z_put_user_pl_bytes, + pub rx_z_put_admin_msgs, + pub rx_z_put_admin_pl_bytes, + pub rx_z_del_user_msgs, + pub rx_z_del_admin_msgs, + pub rx_z_query_user_msgs, + pub rx_z_query_user_pl_bytes, + pub rx_z_query_admin_msgs, + pub rx_z_query_admin_pl_bytes, + pub rx_z_reply_user_msgs, + pub rx_z_reply_user_pl_bytes, + pub rx_z_reply_admin_msgs, + pub rx_z_reply_admin_pl_bytes, + pub rx_bytes, + } +} diff --git a/io/zenoh-transport/src/lib.rs b/io/zenoh-transport/src/lib.rs index 6a1457c8ac..05240710f6 100644 --- a/io/zenoh-transport/src/lib.rs +++ b/io/zenoh-transport/src/lib.rs @@ -23,6 +23,9 @@ mod multicast; mod primitives; pub mod unicast; +#[cfg(feature = "stats")] +pub use common::stats; + #[cfg(feature = "shared-memory")] mod shm; diff --git a/io/zenoh-transport/src/multicast/link.rs b/io/zenoh-transport/src/multicast/link.rs index e41133f221..95d3b90036 100644 --- a/io/zenoh-transport/src/multicast/link.rs +++ b/io/zenoh-transport/src/multicast/link.rs @@ -13,12 +13,12 @@ // use super::common::{pipeline::TransmissionPipeline, priority::TransportPriorityTx}; use super::transport::TransportMulticastInner; -#[cfg(feature = "stats")] -use super::TransportMulticastStatsAtomic; use crate::common::batch::WBatch; use crate::common::pipeline::{ TransmissionPipelineConf, TransmissionPipelineConsumer, TransmissionPipelineProducer, }; +#[cfg(feature = "stats")] +use crate::stats::TransportStats; use async_std::prelude::FutureExt; use async_std::task; use async_std::task::JoinHandle; @@ -207,7 +207,7 @@ async fn tx_task( link: LinkMulticast, config: TransportLinkMulticastConfig, mut last_sns: Vec, - #[cfg(feature = "stats")] stats: Arc, + #[cfg(feature = "stats")] stats: Arc, ) -> ZResult<()> { enum Action { Pull((WBatch, usize)), diff --git a/io/zenoh-transport/src/multicast/mod.rs b/io/zenoh-transport/src/multicast/mod.rs index 3fca8edd52..9c1d8646f3 100644 --- a/io/zenoh-transport/src/multicast/mod.rs +++ b/io/zenoh-transport/src/multicast/mod.rs @@ -20,8 +20,6 @@ pub(crate) mod transport; pub(crate) mod tx; use super::common; -#[cfg(feature = "stats")] -use super::common::stats::stats_struct; use crate::{TransportMulticastEventHandler, TransportPeer}; pub use manager::{ TransportManagerBuilderMulticast, TransportManagerConfigMulticast, @@ -41,56 +39,6 @@ use zenoh_protocol::{ }; use zenoh_result::{zerror, ZResult}; -/*************************************/ -/* STATS */ -/*************************************/ -#[cfg(feature = "stats")] -use serde::{Deserialize, Serialize}; -#[cfg(feature = "stats")] -use std::sync::atomic::{AtomicUsize, Ordering}; -#[cfg(feature = "stats")] -stats_struct! { - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct TransportMulticastStats { - pub tx_t_msgs, - pub tx_n_msgs, - pub tx_n_dropped, - pub tx_z_put_user_msgs, - pub tx_z_put_user_pl_bytes, - // pub tx_z_put_admin_msgs, - // pub tx_z_put_admin_pl_bytes, - pub tx_z_del_user_msgs, - // pub tx_z_del_admin_msgs, - pub tx_z_query_user_msgs, - pub tx_z_query_user_pl_bytes, - // pub tx_z_query_admin_msgs, - // pub tx_z_query_admin_pl_bytes, - pub tx_z_reply_user_msgs, - pub tx_z_reply_user_pl_bytes, - // pub tx_z_reply_admin_msgs, - // pub tx_z_reply_admin_pl_bytes, - pub tx_bytes, - - pub rx_t_msgs, - pub rx_n_msgs, - pub rx_z_put_user_msgs, - pub rx_z_put_user_pl_bytes, - // pub rx_z_put_admin_msgs, - // pub rx_z_put_admin_pl_bytes, - pub rx_z_del_user_msgs, - // pub rx_z_del_admin_msgs, - pub rx_z_query_user_msgs, - pub rx_z_query_user_pl_bytes, - // pub rx_z_query_admin_msgs, - // pub rx_z_query_admin_pl_bytes, - pub rx_z_reply_user_msgs, - pub rx_z_reply_user_pl_bytes, - // pub rx_z_reply_admin_msgs, - // pub rx_z_reply_admin_pl_bytes, - pub rx_bytes, - } -} - /*************************************/ /* TRANSPORT MULTICAST */ /*************************************/ @@ -173,8 +121,8 @@ impl TransportMulticast { } #[cfg(feature = "stats")] - pub fn get_stats(&self) -> ZResult { - Ok(self.get_transport()?.stats.snapshot()) + pub fn get_stats(&self) -> ZResult> { + Ok(self.get_transport()?.stats.clone()) } } diff --git a/io/zenoh-transport/src/multicast/rx.rs b/io/zenoh-transport/src/multicast/rx.rs index 6aa64644ed..8dd4882ded 100644 --- a/io/zenoh-transport/src/multicast/rx.rs +++ b/io/zenoh-transport/src/multicast/rx.rs @@ -37,57 +37,6 @@ impl TransportMulticastInner { mut msg: NetworkMessage, peer: &TransportMulticastPeer, ) -> ZResult<()> { - #[cfg(feature = "stats")] - { - use zenoh_buffers::SplitBuffer; - use zenoh_protocol::network::NetworkBody; - use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; - self.stats.inc_rx_n_msgs(1); - match &msg.body { - NetworkBody::Push(push) => match &push.payload { - PushBody::Put(p) => { - self.stats.inc_rx_z_put_user_msgs(1); - self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); - } - PushBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), - }, - NetworkBody::Request(req) => match &req.payload { - RequestBody::Put(p) => { - self.stats.inc_rx_z_put_user_msgs(1); - self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); - } - RequestBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), - RequestBody::Query(q) => { - self.stats.inc_rx_z_query_user_msgs(1); - self.stats.inc_rx_z_query_user_pl_bytes( - q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - RequestBody::Pull(_) => (), - }, - NetworkBody::Response(res) => match &res.payload { - ResponseBody::Put(p) => { - self.stats.inc_rx_z_put_user_msgs(1); - self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); - } - ResponseBody::Reply(r) => { - self.stats.inc_rx_z_reply_user_msgs(1); - self.stats.inc_rx_z_reply_user_pl_bytes(r.payload.len()); - } - ResponseBody::Err(e) => { - self.stats.inc_rx_z_reply_user_msgs(1); - self.stats.inc_rx_z_reply_user_pl_bytes( - e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - ResponseBody::Ack(_) => (), - }, - NetworkBody::ResponseFinal(_) => (), - NetworkBody::Declare(_) => (), - NetworkBody::OAM(_) => (), - } - } - #[cfg(feature = "shared-memory")] { if self.manager.config.multicast.is_shm { diff --git a/io/zenoh-transport/src/multicast/transport.rs b/io/zenoh-transport/src/multicast/transport.rs index 7173bc677d..67c3ac268d 100644 --- a/io/zenoh-transport/src/multicast/transport.rs +++ b/io/zenoh-transport/src/multicast/transport.rs @@ -14,7 +14,7 @@ use super::common::priority::{TransportPriorityRx, TransportPriorityTx}; use super::link::{TransportLinkMulticast, TransportLinkMulticastConfig}; #[cfg(feature = "stats")] -use super::TransportMulticastStatsAtomic; +use crate::stats::TransportStats; use crate::{ TransportConfigMulticast, TransportManager, TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, @@ -103,7 +103,7 @@ pub(crate) struct TransportMulticastInner { pub(super) timer: Arc, // Transport statistics #[cfg(feature = "stats")] - pub(super) stats: Arc, + pub(super) stats: Arc, } impl TransportMulticastInner { @@ -131,7 +131,7 @@ impl TransportMulticastInner { callback: Arc::new(RwLock::new(None)), timer: Arc::new(Timer::new(false)), #[cfg(feature = "stats")] - stats: Arc::new(TransportMulticastStatsAtomic::default()), + stats: Arc::new(TransportStats::default()), }; let link = TransportLinkMulticast::new(ti.clone(), config.link); diff --git a/io/zenoh-transport/src/multicast/tx.rs b/io/zenoh-transport/src/multicast/tx.rs index b1e1eaa04f..74238c7e71 100644 --- a/io/zenoh-transport/src/multicast/tx.rs +++ b/io/zenoh-transport/src/multicast/tx.rs @@ -64,56 +64,6 @@ impl TransportMulticastInner { } } - #[cfg(feature = "stats")] - { - use zenoh_buffers::SplitBuffer; - use zenoh_protocol::network::NetworkBody; - use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; - match &msg.body { - NetworkBody::Push(push) => match &push.payload { - PushBody::Put(p) => { - self.stats.inc_tx_z_put_user_msgs(1); - self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); - } - PushBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), - }, - NetworkBody::Request(req) => match &req.payload { - RequestBody::Put(p) => { - self.stats.inc_tx_z_put_user_msgs(1); - self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); - } - RequestBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), - RequestBody::Query(q) => { - self.stats.inc_tx_z_query_user_msgs(1); - self.stats.inc_tx_z_query_user_pl_bytes( - q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - RequestBody::Pull(_) => (), - }, - NetworkBody::Response(res) => match &res.payload { - ResponseBody::Put(p) => { - self.stats.inc_tx_z_put_user_msgs(1); - self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); - } - ResponseBody::Reply(r) => { - self.stats.inc_tx_z_reply_user_msgs(1); - self.stats.inc_tx_z_reply_user_pl_bytes(r.payload.len()); - } - ResponseBody::Err(e) => { - self.stats.inc_tx_z_reply_user_msgs(1); - self.stats.inc_tx_z_reply_user_pl_bytes( - e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - ResponseBody::Ack(_) => (), - }, - NetworkBody::ResponseFinal(_) => (), - NetworkBody::Declare(_) => (), - NetworkBody::OAM(_) => (), - } - } - let res = self.schedule_on_link(msg); #[cfg(feature = "stats")] diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index f3b9535854..c7f6038bbe 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -26,8 +26,6 @@ pub(crate) mod shm; use self::transport_unicast_inner::TransportUnicastTrait; -#[cfg(feature = "stats")] -use super::common::stats::stats_struct; use super::{TransportPeer, TransportPeerEventHandler}; #[cfg(feature = "transport_multilink")] use establishment::ext::auth::ZPublicKey; @@ -43,56 +41,6 @@ use zenoh_protocol::{ }; use zenoh_result::{zerror, ZResult}; -/*************************************/ -/* STATS */ -/*************************************/ -#[cfg(feature = "stats")] -use serde::{Deserialize, Serialize}; -#[cfg(feature = "stats")] -use std::sync::atomic::{AtomicUsize, Ordering}; -#[cfg(feature = "stats")] -stats_struct! { - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct TransportUnicastStats { - pub tx_t_msgs, - pub tx_n_msgs, - pub tx_n_dropped, - pub tx_z_put_user_msgs, - pub tx_z_put_user_pl_bytes, - // pub tx_z_put_admin_msgs, - // pub tx_z_put_admin_pl_bytes, - pub tx_z_del_user_msgs, - // pub tx_z_del_admin_msgs, - pub tx_z_query_user_msgs, - pub tx_z_query_user_pl_bytes, - // pub tx_z_query_admin_msgs, - // pub tx_z_query_admin_pl_bytes, - pub tx_z_reply_user_msgs, - pub tx_z_reply_user_pl_bytes, - // pub tx_z_reply_admin_msgs, - // pub tx_z_reply_admin_pl_bytes, - pub tx_bytes, - - pub rx_t_msgs, - pub rx_n_msgs, - pub rx_z_put_user_msgs, - pub rx_z_put_user_pl_bytes, - // pub rx_z_put_admin_msgs, - // pub rx_z_put_admin_pl_bytes, - pub rx_z_del_user_msgs, - // pub rx_z_del_admin_msgs, - pub rx_z_query_user_msgs, - pub rx_z_query_user_pl_bytes, - // pub rx_z_query_admin_msgs, - // pub rx_z_query_admin_pl_bytes, - pub rx_z_reply_user_msgs, - pub rx_z_reply_user_pl_bytes, - // pub rx_z_reply_admin_msgs, - // pub rx_z_reply_admin_pl_bytes, - pub rx_bytes, - } -} - /*************************************/ /* TRANSPORT UNICAST */ /*************************************/ @@ -202,7 +150,7 @@ impl TransportUnicast { } #[cfg(feature = "stats")] - pub fn get_stats(&self) -> ZResult { + pub fn get_stats(&self) -> ZResult> { Ok(self.get_inner()?.stats()) } } diff --git a/io/zenoh-transport/src/unicast/net/link.rs b/io/zenoh-transport/src/unicast/net/link.rs index 5d24dc9459..144f07db1d 100644 --- a/io/zenoh-transport/src/unicast/net/link.rs +++ b/io/zenoh-transport/src/unicast/net/link.rs @@ -18,7 +18,7 @@ use crate::common::pipeline::{ }; use crate::common::priority::TransportPriorityTx; #[cfg(feature = "stats")] -use crate::unicast::TransportUnicastStatsAtomic; +use crate::common::stats::TransportStats; use crate::TransportExecutor; use async_std::prelude::FutureExt; use async_std::task; @@ -205,7 +205,7 @@ async fn tx_task( mut pipeline: TransmissionPipelineConsumer, link: LinkUnicast, keep_alive: Duration, - #[cfg(feature = "stats")] stats: Arc, + #[cfg(feature = "stats")] stats: Arc, #[cfg(all(feature = "unstable", feature = "transport_compression"))] is_compressed: bool, ) -> ZResult<()> { #[cfg(all(feature = "unstable", feature = "transport_compression"))] diff --git a/io/zenoh-transport/src/unicast/net/rx.rs b/io/zenoh-transport/src/unicast/net/rx.rs index 0f9817f9bc..2ca7406a89 100644 --- a/io/zenoh-transport/src/unicast/net/rx.rs +++ b/io/zenoh-transport/src/unicast/net/rx.rs @@ -40,57 +40,6 @@ impl TransportUnicastNet { #[allow(unused_mut)] // shared-memory feature requires mut mut msg: NetworkMessage, ) -> ZResult<()> { - #[cfg(feature = "stats")] - { - use zenoh_buffers::SplitBuffer; - use zenoh_protocol::network::NetworkBody; - use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; - self.stats.inc_rx_n_msgs(1); - match &msg.body { - NetworkBody::Push(push) => match &push.payload { - PushBody::Put(p) => { - self.stats.inc_rx_z_put_user_msgs(1); - self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); - } - PushBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), - }, - NetworkBody::Request(req) => match &req.payload { - RequestBody::Put(p) => { - self.stats.inc_rx_z_put_user_msgs(1); - self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); - } - RequestBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), - RequestBody::Query(q) => { - self.stats.inc_rx_z_query_user_msgs(1); - self.stats.inc_rx_z_query_user_pl_bytes( - q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - RequestBody::Pull(_) => (), - }, - NetworkBody::Response(res) => match &res.payload { - ResponseBody::Put(p) => { - self.stats.inc_rx_z_put_user_msgs(1); - self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); - } - ResponseBody::Reply(r) => { - self.stats.inc_rx_z_reply_user_msgs(1); - self.stats.inc_rx_z_reply_user_pl_bytes(r.payload.len()); - } - ResponseBody::Err(e) => { - self.stats.inc_rx_z_reply_user_msgs(1); - self.stats.inc_rx_z_reply_user_pl_bytes( - e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - ResponseBody::Ack(_) => (), - }, - NetworkBody::ResponseFinal(_) => (), - NetworkBody::Declare(_) => (), - NetworkBody::OAM(_) => (), - } - } - let callback = zread!(self.callback).clone(); if let Some(callback) = callback.as_ref() { #[cfg(feature = "shared-memory")] diff --git a/io/zenoh-transport/src/unicast/net/transport.rs b/io/zenoh-transport/src/unicast/net/transport.rs index 22da062556..95919a5f3a 100644 --- a/io/zenoh-transport/src/unicast/net/transport.rs +++ b/io/zenoh-transport/src/unicast/net/transport.rs @@ -12,10 +12,10 @@ // ZettaScale Zenoh Team, // use crate::common::priority::{TransportPriorityRx, TransportPriorityTx}; +#[cfg(feature = "stats")] +use crate::stats::TransportStats; use crate::transport_unicast_inner::TransportUnicastTrait; use crate::unicast::net::link::TransportLinkUnicast; -#[cfg(feature = "stats")] -use crate::unicast::TransportUnicastStatsAtomic; use crate::TransportConfigUnicast; use crate::{TransportExecutor, TransportManager, TransportPeerEventHandler}; use async_std::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; @@ -71,7 +71,7 @@ pub(crate) struct TransportUnicastNet { pub(super) alive: Arc>, // Transport statistics #[cfg(feature = "stats")] - pub(super) stats: Arc, + pub(super) stats: Arc, } impl TransportUnicastNet { @@ -111,7 +111,7 @@ impl TransportUnicastNet { callback: Arc::new(RwLock::new(None)), alive: Arc::new(AsyncMutex::new(false)), #[cfg(feature = "stats")] - stats: Arc::new(TransportUnicastStatsAtomic::default()), + stats: Arc::new(TransportStats::default()), }; Ok(t) @@ -321,8 +321,8 @@ impl TransportUnicastTrait for TransportUnicastNet { } #[cfg(feature = "stats")] - fn stats(&self) -> crate::TransportUnicastStats { - self.stats.snapshot() + fn stats(&self) -> std::sync::Arc { + self.stats.clone() } /*************************************/ diff --git a/io/zenoh-transport/src/unicast/net/tx.rs b/io/zenoh-transport/src/unicast/net/tx.rs index 8fda2ac893..36e67f1f18 100644 --- a/io/zenoh-transport/src/unicast/net/tx.rs +++ b/io/zenoh-transport/src/unicast/net/tx.rs @@ -76,56 +76,6 @@ impl TransportUnicastNet { } } - #[cfg(feature = "stats")] - { - use zenoh_buffers::SplitBuffer; - use zenoh_protocol::network::NetworkBody; - use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; - match &msg.body { - NetworkBody::Push(push) => match &push.payload { - PushBody::Put(p) => { - self.stats.inc_tx_z_put_user_msgs(1); - self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); - } - PushBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), - }, - NetworkBody::Request(req) => match &req.payload { - RequestBody::Put(p) => { - self.stats.inc_tx_z_put_user_msgs(1); - self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); - } - RequestBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), - RequestBody::Query(q) => { - self.stats.inc_tx_z_query_user_msgs(1); - self.stats.inc_tx_z_query_user_pl_bytes( - q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - RequestBody::Pull(_) => (), - }, - NetworkBody::Response(res) => match &res.payload { - ResponseBody::Put(p) => { - self.stats.inc_tx_z_put_user_msgs(1); - self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); - } - ResponseBody::Reply(r) => { - self.stats.inc_tx_z_reply_user_msgs(1); - self.stats.inc_tx_z_reply_user_pl_bytes(r.payload.len()); - } - ResponseBody::Err(e) => { - self.stats.inc_tx_z_reply_user_msgs(1); - self.stats.inc_tx_z_reply_user_pl_bytes( - e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - ResponseBody::Ack(_) => (), - }, - NetworkBody::ResponseFinal(_) => (), - NetworkBody::Declare(_) => (), - NetworkBody::OAM(_) => (), - } - } - let res = self.schedule_on_link(msg); #[cfg(feature = "stats")] diff --git a/io/zenoh-transport/src/unicast/shm/rx.rs b/io/zenoh-transport/src/unicast/shm/rx.rs index 01c211241a..75ddd31586 100644 --- a/io/zenoh-transport/src/unicast/shm/rx.rs +++ b/io/zenoh-transport/src/unicast/shm/rx.rs @@ -31,57 +31,6 @@ impl TransportUnicastShm { #[allow(unused_mut)] // shared-memory feature requires mut mut msg: NetworkMessage, ) -> ZResult<()> { - #[cfg(feature = "stats")] - { - use zenoh_buffers::SplitBuffer; - use zenoh_protocol::network::NetworkBody; - use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; - self.stats.inc_rx_n_msgs(1); - match &msg.body { - NetworkBody::Push(push) => match &push.payload { - PushBody::Put(p) => { - self.stats.inc_rx_z_put_user_msgs(1); - self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); - } - PushBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), - }, - NetworkBody::Request(req) => match &req.payload { - RequestBody::Put(p) => { - self.stats.inc_rx_z_put_user_msgs(1); - self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); - } - RequestBody::Del(_) => self.stats.inc_rx_z_del_user_msgs(1), - RequestBody::Query(q) => { - self.stats.inc_rx_z_query_user_msgs(1); - self.stats.inc_rx_z_query_user_pl_bytes( - q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - RequestBody::Pull(_) => (), - }, - NetworkBody::Response(res) => match &res.payload { - ResponseBody::Put(p) => { - self.stats.inc_rx_z_put_user_msgs(1); - self.stats.inc_rx_z_put_user_pl_bytes(p.payload.len()); - } - ResponseBody::Reply(r) => { - self.stats.inc_rx_z_reply_user_msgs(1); - self.stats.inc_rx_z_reply_user_pl_bytes(r.payload.len()); - } - ResponseBody::Err(e) => { - self.stats.inc_rx_z_reply_user_msgs(1); - self.stats.inc_rx_z_reply_user_pl_bytes( - e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - ); - } - ResponseBody::Ack(_) => (), - }, - NetworkBody::ResponseFinal(_) => (), - NetworkBody::Declare(_) => (), - NetworkBody::OAM(_) => (), - } - } - let callback = zread!(self.callback).clone(); if let Some(callback) = callback.as_ref() { #[cfg(feature = "shared-memory")] diff --git a/io/zenoh-transport/src/unicast/shm/transport.rs b/io/zenoh-transport/src/unicast/shm/transport.rs index ca7470ad9e..f5fe683041 100644 --- a/io/zenoh-transport/src/unicast/shm/transport.rs +++ b/io/zenoh-transport/src/unicast/shm/transport.rs @@ -13,9 +13,9 @@ // #[cfg(feature = "transport_shm")] use super::link::send_with_link; -use crate::transport_unicast_inner::TransportUnicastTrait; #[cfg(feature = "stats")] -use crate::unicast::TransportUnicastStatsAtomic; +use crate::stats::TransportStats; +use crate::transport_unicast_inner::TransportUnicastTrait; use crate::TransportConfigUnicast; use crate::TransportManager; use crate::{TransportExecutor, TransportPeerEventHandler}; @@ -59,7 +59,7 @@ pub(crate) struct TransportUnicastShm { alive: Arc>, // Transport statistics #[cfg(feature = "stats")] - pub(super) stats: Arc, + pub(super) stats: Arc, // The flags to stop TX/RX tasks pub(crate) handle_keepalive: Arc>>>, @@ -79,7 +79,7 @@ impl TransportUnicastShm { callback: Arc::new(SyncRwLock::new(None)), alive: Arc::new(AsyncMutex::new(false)), #[cfg(feature = "stats")] - stats: Arc::new(TransportUnicastStatsAtomic::default()), + stats: Arc::new(TransportStats::default()), handle_keepalive: Arc::new(RwLock::new(None)), handle_rx: Arc::new(RwLock::new(None)), }; @@ -189,8 +189,8 @@ impl TransportUnicastTrait for TransportUnicastShm { } #[cfg(feature = "stats")] - fn stats(&self) -> crate::TransportUnicastStats { - self.stats.snapshot() + fn stats(&self) -> std::sync::Arc { + self.stats.clone() } /*************************************/ diff --git a/io/zenoh-transport/src/unicast/shm/tx.rs b/io/zenoh-transport/src/unicast/shm/tx.rs index c333a42384..b93acc65fd 100644 --- a/io/zenoh-transport/src/unicast/shm/tx.rs +++ b/io/zenoh-transport/src/unicast/shm/tx.rs @@ -35,56 +35,6 @@ impl TransportUnicastShm { } } - // #[cfg(feature = "stats")] - // { - // use zenoh_buffers::SplitBuffer; - // use zenoh_protocol::network::NetworkBody; - // use zenoh_protocol::zenoh_new::{PushBody, RequestBody, ResponseBody}; - // match &msg.body { - // NetworkBody::Push(push) => match &push.payload { - // PushBody::Put(p) => { - // self.stats.inc_tx_z_put_user_msgs(1); - // self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); - // } - // PushBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), - // }, - // NetworkBody::Request(req) => match &req.payload { - // RequestBody::Put(p) => { - // self.stats.inc_tx_z_put_user_msgs(1); - // self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); - // } - // RequestBody::Del(_) => self.stats.inc_tx_z_del_user_msgs(1), - // RequestBody::Query(q) => { - // self.stats.inc_tx_z_query_user_msgs(1); - // self.stats.inc_tx_z_query_user_pl_bytes( - // q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - // ); - // } - // RequestBody::Pull(_) => (), - // }, - // NetworkBody::Response(res) => match &res.payload { - // ResponseBody::Put(p) => { - // self.stats.inc_tx_z_put_user_msgs(1); - // self.stats.inc_tx_z_put_user_pl_bytes(p.payload.len()); - // } - // ResponseBody::Reply(r) => { - // self.stats.inc_tx_z_reply_user_msgs(1); - // self.stats.inc_tx_z_reply_user_pl_bytes(r.payload.len()); - // } - // ResponseBody::Err(e) => { - // self.stats.inc_tx_z_reply_user_msgs(1); - // self.stats.inc_tx_z_reply_user_pl_bytes( - // e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), - // ); - // } - // ResponseBody::Ack(_) => (), - // }, - // NetworkBody::ResponseFinal(_) => (), - // NetworkBody::Declare(_) => (), - // NetworkBody::OAM(_) => (), - // } - // } - let msg = TransportMessageShm { body: TransportBodyShm::Network(Box::new(msg)), }; diff --git a/io/zenoh-transport/src/unicast/transport_unicast_inner.rs b/io/zenoh-transport/src/unicast/transport_unicast_inner.rs index 54069b4ea3..acb6503c30 100644 --- a/io/zenoh-transport/src/unicast/transport_unicast_inner.rs +++ b/io/zenoh-transport/src/unicast/transport_unicast_inner.rs @@ -45,7 +45,7 @@ pub(crate) trait TransportUnicastTrait: Send + Sync { fn is_qos(&self) -> bool; fn get_config(&self) -> &TransportConfigUnicast; #[cfg(feature = "stats")] - fn stats(&self) -> crate::TransportUnicastStats; + fn stats(&self) -> Arc; /*************************************/ /* LINK */ diff --git a/io/zenoh-transport/tests/multicast_transport.rs b/io/zenoh-transport/tests/multicast_transport.rs index e9f3fbdd63..e930238d81 100644 --- a/io/zenoh-transport/tests/multicast_transport.rs +++ b/io/zenoh-transport/tests/multicast_transport.rs @@ -307,9 +307,9 @@ mod tests { #[cfg(feature = "stats")] { - let stats = peer01.transport.get_stats().unwrap(); + let stats = peer01.transport.get_stats().unwrap().report(); println!("\tPeer 01: {:?}", stats); - let stats = peer02.transport.get_stats().unwrap(); + let stats = peer02.transport.get_stats().unwrap().report(); println!("\tPeer 02: {:?}", stats); } diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 3f579cd91a..434309c0c0 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -539,13 +539,14 @@ async fn run_single( #[cfg(feature = "stats")] { - let c_stats = client_transport.get_stats().unwrap(); + let c_stats = client_transport.get_stats().unwrap().report(); println!("\tClient: {:?}", c_stats); let r_stats = router_manager .get_transport_unicast(&client_manager.config.zid) .await .unwrap() .get_stats() + .map(|s| s.report()) .unwrap(); println!("\tRouter: {:?}", r_stats); } diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index dedbdc8192..c1e1fed7d0 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -75,6 +75,7 @@ hex = { workspace = true, features = ["default"] } lazy_static = { workspace = true } log = { workspace = true } ordered-float = { workspace = true } +paste = { workspace = true } petgraph = { workspace = true } rand = { workspace = true, features = ["default"] } regex = { workspace = true } diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index d9f6ed6f2a..8ca0e6f7cc 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -23,12 +23,16 @@ use zenoh_protocol::{ ResponseFinal, }, }; +#[cfg(feature = "stats")] +use zenoh_transport::stats::TransportStats; use zenoh_transport::{Primitives, TransportMulticast}; pub struct FaceState { pub(super) id: usize, pub(super) zid: ZenohId, pub(super) whatami: WhatAmI, + #[cfg(feature = "stats")] + pub(super) stats: Option>, pub(super) primitives: Arc, pub(super) link_id: usize, pub(super) local_mappings: HashMap>, @@ -47,6 +51,7 @@ impl FaceState { id: usize, zid: ZenohId, whatami: WhatAmI, + #[cfg(feature = "stats")] stats: Option>, primitives: Arc, link_id: usize, mcast_group: Option, @@ -55,6 +60,8 @@ impl FaceState { id, zid, whatami, + #[cfg(feature = "stats")] + stats, primitives, link_id, local_mappings: HashMap::new(), diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index 9765d8f9f6..456f348a94 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -1712,6 +1712,29 @@ fn should_route( false } +#[cfg(feature = "stats")] +macro_rules! inc_stats { + ( + $face:expr, + $txrx:ident, + $space:ident, + $body:expr + ) => { + paste::paste! { + if let Some(stats) = $face.stats.as_ref() { + use zenoh_buffers::SplitBuffer; + match &$body { + PushBody::Put(p) => { + stats.[](1); + stats.[](p.payload.len()); + } + PushBody::Del(_) => stats.[](1), + } + } + } + }; +} + #[allow(clippy::too_many_arguments)] pub fn full_reentrant_route_data( tables_ref: &RwLock, @@ -1731,6 +1754,15 @@ pub fn full_reentrant_route_data( ); let mut expr = RoutingExpr::new(&prefix, expr.suffix.as_ref()); + #[cfg(feature = "stats")] + let admin = expr.full_expr().starts_with("@/"); + #[cfg(feature = "stats")] + if !admin { + inc_stats!(face, rx, user, payload) + } else { + inc_stats!(face, rx, admin, payload) + } + if tables.whatami != WhatAmI::Router || face.whatami != WhatAmI::Peer || tables.peers_net.is_none() @@ -1748,6 +1780,13 @@ pub fn full_reentrant_route_data( let (outface, key_expr, context) = route.values().next().unwrap(); if should_route(&tables, face, outface, &mut expr) { drop(tables); + #[cfg(feature = "stats")] + if !admin { + inc_stats!(face, tx, user, payload) + } else { + inc_stats!(face, tx, admin, payload) + } + outface.primitives.send_push(Push { wire_expr: key_expr.into(), ext_qos, @@ -1776,6 +1815,13 @@ pub fn full_reentrant_route_data( drop(tables); for (outface, key_expr, context) in route { + #[cfg(feature = "stats")] + if !admin { + inc_stats!(face, tx, user, payload) + } else { + inc_stats!(face, tx, admin, payload) + } + outface.primitives.send_push(Push { wire_expr: key_expr, ext_qos: ext::QoSType::default(), @@ -1798,6 +1844,13 @@ pub fn full_reentrant_route_data( _ => true, } { + #[cfg(feature = "stats")] + if !admin { + inc_stats!(face, tx, user, payload) + } else { + inc_stats!(face, tx, admin, payload) + } + outface.primitives.send_push(Push { wire_expr: key_expr.into(), ext_qos: ext::QoSType::default(), diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index ed7f899a65..ddf813bd82 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -1989,6 +1989,69 @@ fn get_query_route( } } +#[cfg(feature = "stats")] +macro_rules! inc_req_stats { + ( + $face:expr, + $txrx:ident, + $space:ident, + $body:expr + ) => { + paste::paste! { + if let Some(stats) = $face.stats.as_ref() { + use zenoh_buffers::SplitBuffer; + match &$body { + RequestBody::Put(p) => { + stats.[](1); + stats.[](p.payload.len()); + } + RequestBody::Del(_) => stats.[](1), + RequestBody::Query(q) => { + stats.[](1); + stats.[]( + q.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); + } + RequestBody::Pull(_) => (), + } + } + } + }; +} + +#[cfg(feature = "stats")] +macro_rules! inc_res_stats { + ( + $face:expr, + $txrx:ident, + $space:ident, + $body:expr + ) => { + paste::paste! { + if let Some(stats) = $face.stats.as_ref() { + use zenoh_buffers::SplitBuffer; + match &$body { + ResponseBody::Put(p) => { + stats.[](1); + stats.[](p.payload.len()); + } + ResponseBody::Reply(r) => { + stats.[](1); + stats.[](r.payload.len()); + } + ResponseBody::Err(e) => { + stats.[](1); + stats.[]( + e.ext_body.as_ref().map(|b| b.payload.len()).unwrap_or(0), + ); + } + ResponseBody::Ack(_) => (), + } + } + } + }; +} + #[allow(clippy::too_many_arguments)] pub fn route_query( tables_ref: &Arc, @@ -2012,6 +2075,15 @@ pub fn route_query( let prefix = prefix.clone(); let mut expr = RoutingExpr::new(&prefix, expr.suffix.as_ref()); + #[cfg(feature = "stats")] + let admin = expr.full_expr().starts_with("@/"); + #[cfg(feature = "stats")] + if !admin { + inc_req_stats!(face, rx, user, body) + } else { + inc_req_stats!(face, rx, admin, body) + } + if rtables.whatami != WhatAmI::Router || face.whatami != WhatAmI::Peer || rtables.peers_net.is_none() @@ -2035,19 +2107,27 @@ pub fn route_query( drop(rtables); for (expr, payload) in local_replies { + let payload = ResponseBody::Reply(Reply { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + ext_consolidation: ConsolidationType::default(), + #[cfg(feature = "shared-memory")] + ext_shm: None, + ext_unknown: vec![], + payload, + }); + #[cfg(feature = "stats")] + if !admin { + inc_res_stats!(face, tx, user, payload) + } else { + inc_res_stats!(face, tx, admin, payload) + } + face.primitives.clone().send_response(Response { rid: qid, wire_expr: expr, - payload: ResponseBody::Reply(Reply { - timestamp: None, - encoding: Encoding::default(), - ext_sinfo: None, - ext_consolidation: ConsolidationType::default(), - #[cfg(feature = "shared-memory")] - ext_shm: None, - ext_unknown: vec![], - payload, - }), + payload, ext_qos: response::ext::QoSType::default(), ext_tstamp: None, ext_respid: Some(response::ext::ResponderIdType { @@ -2082,6 +2162,13 @@ pub fn route_query( // *qid, // }, // )); + #[cfg(feature = "stats")] + if !admin { + inc_req_stats!(outface, tx, user, body) + } else { + inc_req_stats!(outface, tx, admin, body) + } + log::trace!("Propagate query {}:{} to {}", face, qid, outface); outface.primitives.send_request(Request { id: *qid, @@ -2110,6 +2197,13 @@ pub fn route_query( // *qid, // }, // )); + #[cfg(feature = "stats")] + if !admin { + inc_req_stats!(outface, tx, user, body) + } else { + inc_req_stats!(outface, tx, admin, body) + } + log::trace!("Propagate query {}:{} to {}", face, qid, outface); outface.primitives.send_request(Request { id: *qid, @@ -2162,9 +2256,26 @@ pub(crate) fn route_send_response( body: ResponseBody, ) { let queries_lock = zread!(tables_ref.queries_lock); + #[cfg(feature = "stats")] + let admin = key_expr.as_str().starts_with("@/"); + #[cfg(feature = "stats")] + if !admin { + inc_res_stats!(face, rx, user, body) + } else { + inc_res_stats!(face, rx, admin, body) + } + match face.pending_queries.get(&qid) { Some(query) => { drop(queries_lock); + + #[cfg(feature = "stats")] + if !admin { + inc_res_stats!(query.src_face, tx, user, body) + } else { + inc_res_stats!(query.src_face, tx, admin, body) + } + query.src_face.primitives.clone().send_response(Response { rid: query.src_qid, wire_expr: key_expr.to_owned(), diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index 5d6a1f206d..dbf687ba79 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -34,6 +34,8 @@ use zenoh_protocol::common::ZExtBody; use zenoh_protocol::core::{ExprId, WhatAmI, WhatAmIMatcher, ZenohId}; use zenoh_protocol::network::oam::id::OAM_LINKSTATE; use zenoh_protocol::network::{Mapping, NetworkBody, NetworkMessage}; +#[cfg(feature = "stats")] +use zenoh_transport::stats::TransportStats; use zenoh_transport::{ DeMux, DummyPrimitives, McastMux, Mux, Primitives, TransportMulticast, TransportPeer, TransportPeerEventHandler, TransportUnicast, @@ -256,6 +258,7 @@ impl Tables { &mut self, zid: ZenohId, whatami: WhatAmI, + #[cfg(feature = "stats")] stats: Arc, primitives: Arc, link_id: usize, ) -> Weak { @@ -264,7 +267,18 @@ impl Tables { let mut newface = self .faces .entry(fid) - .or_insert_with(|| FaceState::new(fid, zid, whatami, primitives.clone(), link_id, None)) + .or_insert_with(|| { + FaceState::new( + fid, + zid, + whatami, + #[cfg(feature = "stats")] + Some(stats), + primitives.clone(), + link_id, + None, + ) + }) .clone(); log::debug!("New {}", newface); @@ -280,7 +294,30 @@ impl Tables { whatami: WhatAmI, primitives: Arc, ) -> Weak { - self.open_net_face(zid, whatami, primitives, 0) + let fid = self.face_counter; + self.face_counter += 1; + let mut newface = self + .faces + .entry(fid) + .or_insert_with(|| { + FaceState::new( + fid, + zid, + whatami, + #[cfg(feature = "stats")] + None, + primitives.clone(), + 0, + None, + ) + }) + .clone(); + log::debug!("New {}", newface); + + pubsub_new_face(self, &mut newface); + queries_new_face(self, &mut newface); + + Arc::downgrade(&newface) } fn compute_routes(&mut self, res: &mut Arc) { @@ -576,6 +613,8 @@ impl Router { .open_net_face( transport.get_zid().unwrap(), whatami, + #[cfg(feature = "stats")] + transport.get_stats().unwrap(), Arc::new(Mux::new(transport)), link_id, ) @@ -610,6 +649,8 @@ impl Router { fid, ZenohId::from_str("1").unwrap(), WhatAmI::Peer, + #[cfg(feature = "stats")] + None, Arc::new(McastMux::new(transport.clone())), 0, Some(transport), @@ -633,6 +674,8 @@ impl Router { fid, peer.zid, WhatAmI::Client, // Quick hack + #[cfg(feature = "stats")] + Some(transport.get_stats().unwrap()), Arc::new(DummyPrimitives), 0, Some(transport), diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 8570ddfd91..89a8e21150 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -439,7 +439,7 @@ fn router_data(context: &AdminContext, query: Query) { "stats".to_string(), transport .get_stats() - .map_or_else(|_| json!({}), |p| json!(p)), + .map_or_else(|_| json!({}), |p| json!(p.report())), ); } } From e21469cfa7b2d65a9908bcb9d8c6952f7b271568 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Thu, 7 Sep 2023 17:26:35 +0200 Subject: [PATCH 197/203] Remove old zenoh messages --- commons/zenoh-codec/benches/codec.rs | 132 ++-- commons/zenoh-codec/src/lib.rs | 10 +- commons/zenoh-codec/src/zenoh/data.rs | 267 ------- commons/zenoh-codec/src/zenoh/declare.rs | 672 ------------------ commons/zenoh-codec/src/zenoh/linkstate.rs | 172 ----- commons/zenoh-codec/src/zenoh/mod.rs | 137 ---- commons/zenoh-codec/src/zenoh/pull.rs | 102 --- commons/zenoh-codec/src/zenoh/query.rs | 226 ------ commons/zenoh-codec/src/zenoh/routing.rs | 69 -- commons/zenoh-codec/src/zenoh/unit.rs | 90 --- commons/zenoh-codec/tests/codec.rs | 122 +--- commons/zenoh-protocol/src/core/resolution.rs | 4 +- commons/zenoh-protocol/src/lib.rs | 1 - commons/zenoh-protocol/src/network/request.rs | 11 +- commons/zenoh-protocol/src/zenoh/data.rs | 249 ------- commons/zenoh-protocol/src/zenoh/declare.rs | 314 -------- commons/zenoh-protocol/src/zenoh/linkstate.rs | 114 --- commons/zenoh-protocol/src/zenoh/mod.rs | 411 ----------- commons/zenoh-protocol/src/zenoh/pull.rs | 64 -- commons/zenoh-protocol/src/zenoh/query.rs | 201 ------ commons/zenoh-protocol/src/zenoh/routing.rs | 48 -- commons/zenoh-protocol/src/zenoh/unit.rs | 54 -- commons/zenoh-protocol/src/zenoh_new/query.rs | 12 +- io/zenoh-transport/src/common/batch.rs | 135 +--- io/zenoh-transport/src/primitives/mux.rs | 188 ----- .../src/replica/storage.rs | 1 + zenoh/src/admin.rs | 4 +- zenoh/src/net/routing/pubsub.rs | 23 +- zenoh/src/net/routing/queries.rs | 24 +- zenoh/src/net/routing/resource.rs | 8 +- zenoh/src/prelude.rs | 2 +- zenoh/src/publication.rs | 2 +- zenoh/src/query.rs | 4 +- zenoh/src/queryable.rs | 6 +- zenoh/src/sample.rs | 13 +- zenoh/src/session.rs | 16 +- zenoh/src/subscriber.rs | 2 +- 37 files changed, 199 insertions(+), 3711 deletions(-) delete mode 100644 commons/zenoh-codec/src/zenoh/data.rs delete mode 100644 commons/zenoh-codec/src/zenoh/declare.rs delete mode 100644 commons/zenoh-codec/src/zenoh/linkstate.rs delete mode 100644 commons/zenoh-codec/src/zenoh/mod.rs delete mode 100644 commons/zenoh-codec/src/zenoh/pull.rs delete mode 100644 commons/zenoh-codec/src/zenoh/query.rs delete mode 100644 commons/zenoh-codec/src/zenoh/routing.rs delete mode 100644 commons/zenoh-codec/src/zenoh/unit.rs delete mode 100644 commons/zenoh-protocol/src/zenoh/data.rs delete mode 100644 commons/zenoh-protocol/src/zenoh/declare.rs delete mode 100644 commons/zenoh-protocol/src/zenoh/linkstate.rs delete mode 100644 commons/zenoh-protocol/src/zenoh/mod.rs delete mode 100644 commons/zenoh-protocol/src/zenoh/pull.rs delete mode 100644 commons/zenoh-protocol/src/zenoh/query.rs delete mode 100644 commons/zenoh-protocol/src/zenoh/routing.rs delete mode 100644 commons/zenoh-protocol/src/zenoh/unit.rs diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index a47982ff49..7db9449f42 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -24,9 +24,10 @@ use zenoh_buffers::{ }; use zenoh_codec::*; use zenoh_protocol::{ - core::{CongestionControl, Reliability, WireExpr}, + core::{Encoding, Reliability, WireExpr}, + network::{ext, Push}, transport::{BatchSize, Frame, FrameHeader, TransportSn}, - zenoh::Data, + zenoh_new::{PushBody, Put}, }; fn criterion_benchmark(c: &mut Criterion) { @@ -79,12 +80,20 @@ fn criterion_benchmark(c: &mut Criterion) { ext_qos: zenoh_protocol::transport::frame::ext::QoSType::default(), }; - let data = Data { - key: WireExpr::empty(), - data_info: None, - payload: ZBuf::from(vec![0u8; 8]), - congestion_control: CongestionControl::default(), - reply_context: None, + let data = Push { + wire_expr: WireExpr::empty(), + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, + ext_unknown: vec![], + payload: ZBuf::from(vec![0u8; 8]), + }), }; // Calculate the number of messages @@ -116,12 +125,20 @@ fn criterion_benchmark(c: &mut Criterion) { ext_qos: zenoh_protocol::transport::frame::ext::QoSType::default(), }; - let data = Data { - key: WireExpr::empty(), - data_info: None, - payload: ZBuf::from(vec![0u8; 8]), - congestion_control: CongestionControl::default(), - reply_context: None, + let data = Push { + wire_expr: WireExpr::empty(), + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, + ext_unknown: vec![], + payload: ZBuf::from(vec![0u8; 8]), + }), }; let mut writer = buff.writer(); @@ -148,12 +165,20 @@ fn criterion_benchmark(c: &mut Criterion) { ext_qos: zenoh_protocol::transport::frame::ext::QoSType::default(), }; - let data = Data { - key: WireExpr::empty(), - data_info: None, - payload: ZBuf::from(vec![0u8; 8]), - congestion_control: CongestionControl::default(), - reply_context: None, + let data = Push { + wire_expr: WireExpr::empty(), + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, + ext_unknown: vec![], + payload: ZBuf::from(vec![0u8; 8]), + }), }; let mut writer = buff.writer(); @@ -168,7 +193,7 @@ fn criterion_benchmark(c: &mut Criterion) { let _header: FrameHeader = codec.read(&mut reader).unwrap(); loop { - let res: Result = codec.read(&mut reader); + let res: Result = codec.read(&mut reader); if res.is_err() { break; } @@ -180,13 +205,22 @@ fn criterion_benchmark(c: &mut Criterion) { let mut buff = ZBuf::empty(); let codec = Zenoh080::new(); - let data = Data { - key: WireExpr::empty(), - data_info: None, - payload: ZBuf::from(vec![0u8; 1_000_000]), - congestion_control: CongestionControl::default(), - reply_context: None, + let data = Push { + wire_expr: WireExpr::empty(), + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, + ext_unknown: vec![], + payload: ZBuf::from(vec![0u8; 1_000_000]), + }), }; + c.bench_function("Fragmentation ZBuf Write", |b| { b.iter(|| { let mut writer = buff.writer(); @@ -198,12 +232,20 @@ fn criterion_benchmark(c: &mut Criterion) { let mut buff = vec![]; let codec = Zenoh080::new(); - let data = Data { - key: WireExpr::empty(), - data_info: None, - payload: ZBuf::from(vec![0u8; 1_000_000]), - congestion_control: CongestionControl::default(), - reply_context: None, + let data = Push { + wire_expr: WireExpr::empty(), + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, + ext_unknown: vec![], + payload: ZBuf::from(vec![0u8; 1_000_000]), + }), }; let mut writer = buff.writer(); @@ -220,7 +262,7 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("Fragmentation ZBuf Read", |b| { b.iter(|| { let mut reader = zbuf.reader(); - let _data: Data = codec.read(&mut reader).unwrap(); + let _data: Push = codec.read(&mut reader).unwrap(); }) }); @@ -228,12 +270,20 @@ fn criterion_benchmark(c: &mut Criterion) { let mut buff = vec![]; let codec = Zenoh080::new(); - let data = Data { - key: WireExpr::empty(), - data_info: None, - payload: ZBuf::from(vec![0u8; 1_000_000]), - congestion_control: CongestionControl::default(), - reply_context: None, + let data = Push { + wire_expr: WireExpr::empty(), + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, + ext_unknown: vec![], + payload: ZBuf::from(vec![0u8; 1_000_000]), + }), }; let mut writer = buff.writer(); @@ -254,7 +304,7 @@ fn criterion_benchmark(c: &mut Criterion) { } let mut reader = zbuf.reader(); - let _data: Data = codec.read(&mut reader).unwrap(); + let _data: Push = codec.read(&mut reader).unwrap(); }) }); } diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index 8ea171aa15..d604acaaf0 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -25,11 +25,10 @@ pub mod core; pub mod network; pub mod scouting; pub mod transport; -pub mod zenoh; pub mod zenoh_new; use ::core::marker::PhantomData; -use zenoh_protocol::{core::Reliability, zenoh::ReplyContext}; +use zenoh_protocol::core::Reliability; pub trait WCodec { type Output; @@ -115,13 +114,6 @@ impl Zenoh080Reliability { } } -#[derive(Clone)] -pub struct Zenoh080HeaderReplyContext { - pub header: u8, - pub reply_context: Option, - pub codec: Zenoh080, -} - #[derive(Clone, Copy)] pub struct Zenoh080Bounded { _t: PhantomData, diff --git a/commons/zenoh-codec/src/zenoh/data.rs b/commons/zenoh-codec/src/zenoh/data.rs deleted file mode 100644 index 9833183cd0..0000000000 --- a/commons/zenoh-codec/src/zenoh/data.rs +++ /dev/null @@ -1,267 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{ - RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header, Zenoh080HeaderReplyContext, -}; -use core::convert::TryInto; -use uhlc::Timestamp; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, - ZBuf, -}; -use zenoh_protocol::{ - common::imsg, - core::{CongestionControl, Encoding, WireExpr, ZenohId}, - zenoh::{zmsg, Data, DataInfo, QueryId, ReplierInfo, ReplyContext, SampleKind, SourceSn}, -}; - -// ReplyContext -impl WCodec<&ReplyContext, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ReplyContext) -> Self::Output { - // Header - let mut header = zmsg::id::REPLY_CONTEXT; - if x.is_final() { - header |= zmsg::flag::F; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, x.qid)?; - if let Some(replier) = x.replier.as_ref() { - self.write(&mut *writer, &replier.id)?; - } - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::id::REPLY_CONTEXT { - return Err(DidntRead); - } - - let qid: QueryId = self.codec.read(&mut *reader)?; - let replier = if imsg::has_flag(self.header, zmsg::flag::F) { - None - } else { - let id: ZenohId = self.codec.read(&mut *reader)?; - Some(ReplierInfo { id }) - }; - Ok(ReplyContext { qid, replier }) - } -} - -// DataInfo -impl WCodec<&DataInfo, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &DataInfo) -> Self::Output { - // Options - let mut options: u8 = 0; - if x.kind != SampleKind::Put { - options |= zmsg::data::info::KIND; - } - if x.encoding.is_some() { - options |= zmsg::data::info::ENCODING; - } - if x.timestamp.is_some() { - options |= zmsg::data::info::TIMESTAMP; - } - if x.source_id.is_some() { - options |= zmsg::data::info::SRCID; - } - if x.source_sn.is_some() { - options |= zmsg::data::info::SRCSN; - } - self.write(&mut *writer, options)?; - - if x.kind != SampleKind::Put { - self.write(&mut *writer, x.kind as u8)?; - } - if let Some(enc) = x.encoding.as_ref() { - self.write(&mut *writer, enc)?; - } - if let Some(ts) = x.timestamp.as_ref() { - self.write(&mut *writer, ts)?; - } - if let Some(si) = x.source_id.as_ref() { - self.write(&mut *writer, si)?; - } - if let Some(sn) = x.source_sn { - self.write(&mut *writer, sn)?; - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let mut info = DataInfo::default(); - let options: u8 = self.read(&mut *reader)?; - if imsg::has_flag(options, zmsg::data::info::KIND) { - let kind: u8 = self.read(&mut *reader)?; - info.kind = kind.try_into().map_err(|_| DidntRead)?; - } - if imsg::has_flag(options, zmsg::data::info::ENCODING) { - let encoding: Encoding = self.read(&mut *reader)?; - info.encoding = Some(encoding); - } - if imsg::has_flag(options, zmsg::data::info::TIMESTAMP) { - let timestamp: Timestamp = self.read(&mut *reader)?; - info.timestamp = Some(timestamp); - } - if imsg::has_flag(options, zmsg::data::info::SRCID) { - let source_id: ZenohId = self.read(&mut *reader)?; - info.source_id = Some(source_id); - } - if imsg::has_flag(options, zmsg::data::info::SRCSN) { - let source_sn: SourceSn = self.read(&mut *reader)?; - info.source_sn = Some(source_sn); - } - - Ok(info) - } -} - -// Data -impl WCodec<&Data, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Data) -> Self::Output { - if let Some(reply_context) = x.reply_context.as_ref() { - self.write(&mut *writer, reply_context)?; - } - - // Header - let mut header = zmsg::id::DATA; - if x.data_info.is_some() { - header |= zmsg::flag::I; - } - if x.key.has_suffix() { - header |= zmsg::flag::K; - } - if x.congestion_control == CongestionControl::Drop { - header |= zmsg::flag::D; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, &x.key)?; - - if let Some(data_info) = x.data_info.as_ref() { - self.write(&mut *writer, data_info)?; - } - - self.write(&mut *writer, &x.payload)?; - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh080HeaderReplyContext { - header: self.read(&mut *reader)?, - reply_context: None, - codec: Zenoh080::new(), - }; - if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { - let hodec = Zenoh080Header::new(codec.header); - codec.reply_context = Some(hodec.read(&mut *reader)?); - codec.header = self.read(&mut *reader)?; - } - codec.read(reader) - } -} - -impl RCodec for Zenoh080HeaderReplyContext -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::id::DATA { - return Err(DidntRead); - } - - let congestion_control = if imsg::has_flag(self.header, zmsg::flag::D) { - CongestionControl::Drop - } else { - CongestionControl::Block - }; - - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - - let data_info = if imsg::has_flag(self.header, zmsg::flag::I) { - let di: DataInfo = self.codec.read(&mut *reader)?; - Some(di) - } else { - None - }; - - let payload: ZBuf = self.codec.read(&mut *reader)?; - - Ok(Data { - key, - data_info, - payload, - congestion_control, - reply_context: self.reply_context, - }) - } -} diff --git a/commons/zenoh-codec/src/zenoh/declare.rs b/commons/zenoh-codec/src/zenoh/declare.rs deleted file mode 100644 index 429b16dd20..0000000000 --- a/commons/zenoh-codec/src/zenoh/declare.rs +++ /dev/null @@ -1,672 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; -use alloc::vec::Vec; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, -}; -use zenoh_protocol::{ - common::imsg, - core::{ExprId, Reliability, WireExpr}, - zenoh::{ - zmsg, Declaration, Declare, ForgetPublisher, ForgetQueryable, ForgetResource, - ForgetSubscriber, Publisher, Queryable, QueryableInfo, Resource, SubInfo, SubMode, - Subscriber, - }, -}; - -// Declaration -impl WCodec<&Declaration, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Declaration) -> Self::Output { - match x { - Declaration::Resource(r) => self.write(&mut *writer, r)?, - Declaration::ForgetResource(r) => self.write(&mut *writer, r)?, - Declaration::Publisher(r) => self.write(&mut *writer, r)?, - Declaration::ForgetPublisher(r) => self.write(&mut *writer, r)?, - Declaration::Subscriber(r) => self.write(&mut *writer, r)?, - Declaration::ForgetSubscriber(r) => self.write(&mut *writer, r)?, - Declaration::Queryable(r) => self.write(&mut *writer, r)?, - Declaration::ForgetQueryable(r) => self.write(&mut *writer, r)?, - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - use super::zmsg::declaration::id::*; - - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - let d = match imsg::mid(codec.header) { - RESOURCE => Declaration::Resource(codec.read(&mut *reader)?), - FORGET_RESOURCE => Declaration::ForgetResource(codec.read(&mut *reader)?), - PUBLISHER => Declaration::Publisher(codec.read(&mut *reader)?), - FORGET_PUBLISHER => Declaration::ForgetPublisher(codec.read(&mut *reader)?), - SUBSCRIBER => Declaration::Subscriber(codec.read(&mut *reader)?), - FORGET_SUBSCRIBER => Declaration::ForgetSubscriber(codec.read(&mut *reader)?), - QUERYABLE => Declaration::Queryable(codec.read(&mut *reader)?), - FORGET_QUERYABLE => Declaration::ForgetQueryable(codec.read(&mut *reader)?), - _ => return Err(DidntRead), - }; - - Ok(d) - } -} - -// Declare -impl WCodec<&Declare, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Declare) -> Self::Output { - // Header - let header = zmsg::id::DECLARE; - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, x.declarations.len())?; - for d in x.declarations.iter() { - self.write(&mut *writer, d)?; - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::id::DECLARE { - return Err(DidntRead); - } - - let len: usize = self.codec.read(&mut *reader)?; - let mut declarations = Vec::with_capacity(len); - for _ in 0..len { - let d: Declaration = self.codec.read(&mut *reader)?; - declarations.push(d); - } - - Ok(Declare { declarations }) - } -} - -// Resource -impl WCodec<&Resource, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Resource) -> Self::Output { - // Header - let mut header = zmsg::declaration::id::RESOURCE; - if x.key.has_suffix() { - header |= zmsg::flag::K; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, x.expr_id)?; - self.write(&mut *writer, &x.key)?; - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::declaration::id::RESOURCE { - return Err(DidntRead); - } - - let expr_id: ExprId = self.codec.read(&mut *reader)?; - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - - Ok(Resource { expr_id, key }) - } -} - -// ForgetResource -impl WCodec<&ForgetResource, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ForgetResource) -> Self::Output { - // Header - let header = zmsg::declaration::id::FORGET_RESOURCE; - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, x.expr_id)?; - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::declaration::id::FORGET_RESOURCE { - return Err(DidntRead); - } - - let expr_id: ExprId = self.codec.read(&mut *reader)?; - - Ok(ForgetResource { expr_id }) - } -} - -// Publisher -impl WCodec<&Publisher, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Publisher) -> Self::Output { - // Header - let mut header = zmsg::declaration::id::PUBLISHER; - if x.key.has_suffix() { - header |= zmsg::flag::K; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, &x.key)?; - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::declaration::id::PUBLISHER { - return Err(DidntRead); - } - - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - - Ok(Publisher { key }) - } -} - -// ForgetPublisher -impl WCodec<&ForgetPublisher, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ForgetPublisher) -> Self::Output { - // Header - let mut header = zmsg::declaration::id::FORGET_PUBLISHER; - if x.key.has_suffix() { - header |= zmsg::flag::K; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, &x.key)?; - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::declaration::id::FORGET_PUBLISHER { - return Err(DidntRead); - } - - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - - Ok(ForgetPublisher { key }) - } -} - -// SubMode -impl WCodec<&SubMode, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &SubMode) -> Self::Output { - // Header - let header = match x { - SubMode::Push => zmsg::declaration::id::MODE_PUSH, - SubMode::Pull => zmsg::declaration::id::MODE_PULL, - }; - self.write(&mut *writer, header)?; - - // Body - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - - let mode = match header { - zmsg::declaration::id::MODE_PUSH => SubMode::Push, - zmsg::declaration::id::MODE_PULL => SubMode::Pull, - _ => return Err(DidntRead), - }; - - Ok(mode) - } -} - -// Subscriber -impl WCodec<&Subscriber, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Subscriber) -> Self::Output { - // Header - let mut header = zmsg::declaration::id::SUBSCRIBER; - if x.info.reliability == Reliability::Reliable { - header |= zmsg::flag::R; - } - if x.info.mode != SubMode::Push { - header |= zmsg::flag::S; - } - if x.key.has_suffix() { - header |= zmsg::flag::K; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, &x.key)?; - if imsg::has_flag(header, zmsg::flag::S) { - self.write(&mut *writer, &x.info.mode)?; - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::declaration::id::SUBSCRIBER { - return Err(DidntRead); - } - - let reliability = if imsg::has_flag(self.header, zmsg::flag::R) { - Reliability::Reliable - } else { - Reliability::BestEffort - }; - - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - - let mode: SubMode = if imsg::has_flag(self.header, zmsg::flag::S) { - self.codec.read(&mut *reader)? - } else { - SubMode::Push - }; - - Ok(Subscriber { - key, - info: SubInfo { reliability, mode }, - }) - } -} - -// ForgetSubscriber -impl WCodec<&ForgetSubscriber, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ForgetSubscriber) -> Self::Output { - // Header - let mut header = zmsg::declaration::id::FORGET_SUBSCRIBER; - if x.key.has_suffix() { - header |= zmsg::flag::K; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, &x.key)?; - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::declaration::id::FORGET_SUBSCRIBER { - return Err(DidntRead); - } - - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - - Ok(ForgetSubscriber { key }) - } -} - -// QueryableInfo -impl WCodec<&QueryableInfo, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &QueryableInfo) -> Self::Output { - self.write(&mut *writer, x.complete)?; - self.write(&mut *writer, x.distance)?; - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let complete: u64 = self.read(&mut *reader)?; - let distance: u64 = self.read(&mut *reader)?; - - Ok(QueryableInfo { complete, distance }) - } -} - -// Queryable -impl WCodec<&Queryable, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Queryable) -> Self::Output { - // Header - let mut header = zmsg::declaration::id::QUERYABLE; - if x.info != QueryableInfo::default() { - header |= zmsg::flag::Q; - } - if x.key.has_suffix() { - header |= zmsg::flag::K; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, &x.key)?; - if imsg::has_flag(header, zmsg::flag::Q) { - self.write(&mut *writer, &x.info)?; - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::declaration::id::QUERYABLE { - return Err(DidntRead); - } - - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - - let info: QueryableInfo = if imsg::has_flag(self.header, zmsg::flag::Q) { - self.codec.read(&mut *reader)? - } else { - QueryableInfo::default() - }; - - Ok(Queryable { key, info }) - } -} - -// ForgetQueryable -impl WCodec<&ForgetQueryable, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ForgetQueryable) -> Self::Output { - // Header - let mut header = zmsg::declaration::id::FORGET_QUERYABLE; - if x.key.has_suffix() { - header |= zmsg::flag::K - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, &x.key)?; - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::declaration::id::FORGET_QUERYABLE { - return Err(DidntRead); - } - - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - - Ok(ForgetQueryable { key }) - } -} diff --git a/commons/zenoh-codec/src/zenoh/linkstate.rs b/commons/zenoh-codec/src/zenoh/linkstate.rs deleted file mode 100644 index 066220ce4f..0000000000 --- a/commons/zenoh-codec/src/zenoh/linkstate.rs +++ /dev/null @@ -1,172 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; -use alloc::vec::Vec; -use core::convert::TryFrom; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, -}; -use zenoh_protocol::{ - common::imsg, - core::{Locator, WhatAmI, ZenohId}, - zenoh::{zmsg, LinkState, LinkStateList}, -}; - -// LinkState -impl WCodec<&LinkState, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &LinkState) -> Self::Output { - // Options - let mut options = 0; - if x.zid.is_some() { - options |= zmsg::link_state::PID; - } - if x.whatami.is_some() { - options |= zmsg::link_state::WAI; - } - if x.locators.is_some() { - options |= zmsg::link_state::LOC; - } - self.write(&mut *writer, options)?; - - // Body - self.write(&mut *writer, x.psid)?; - self.write(&mut *writer, x.sn)?; - if let Some(zid) = x.zid.as_ref() { - self.write(&mut *writer, zid)?; - } - if let Some(wai) = x.whatami { - let wai: u8 = wai.into(); - self.write(&mut *writer, wai)?; - } - if let Some(locators) = x.locators.as_ref() { - self.write(&mut *writer, locators.as_slice())?; - } - self.write(&mut *writer, x.links.len())?; - for l in x.links.iter() { - self.write(&mut *writer, *l)?; - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let options: u64 = self.read(&mut *reader)?; - let psid: u64 = self.read(&mut *reader)?; - let sn: u64 = self.read(&mut *reader)?; - let zid = if imsg::has_option(options, zmsg::link_state::PID) { - let zid: ZenohId = self.read(&mut *reader)?; - Some(zid) - } else { - None - }; - let whatami = if imsg::has_option(options, zmsg::link_state::WAI) { - let wai: u8 = self.read(&mut *reader)?; - Some(WhatAmI::try_from(wai).map_err(|_| DidntRead)?) - } else { - None - }; - let locators = if imsg::has_option(options, zmsg::link_state::LOC) { - let locs: Vec = self.read(&mut *reader)?; - Some(locs) - } else { - None - }; - let len: usize = self.read(&mut *reader)?; - let mut links: Vec = Vec::with_capacity(len); - for _ in 0..len { - let l: u64 = self.read(&mut *reader)?; - links.push(l); - } - - Ok(LinkState { - psid, - sn, - zid, - whatami, - locators, - links, - }) - } -} - -// LinkStateList -impl WCodec<&LinkStateList, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &LinkStateList) -> Self::Output { - // Header - let header = zmsg::id::LINK_STATE_LIST; - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, x.link_states.len())?; - for ls in x.link_states.iter() { - self.write(&mut *writer, ls)?; - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::id::LINK_STATE_LIST { - return Err(DidntRead); - } - - let len: usize = self.codec.read(&mut *reader)?; - let mut link_states = Vec::with_capacity(len); - for _ in 0..len { - let ls: LinkState = self.codec.read(&mut *reader)?; - link_states.push(ls); - } - - Ok(LinkStateList { link_states }) - } -} diff --git a/commons/zenoh-codec/src/zenoh/mod.rs b/commons/zenoh-codec/src/zenoh/mod.rs deleted file mode 100644 index 44ae033748..0000000000 --- a/commons/zenoh-codec/src/zenoh/mod.rs +++ /dev/null @@ -1,137 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -mod data; -mod declare; -mod linkstate; -mod pull; -mod query; -mod routing; -mod unit; - -use crate::{ - RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080HeaderReplyContext, Zenoh080Reliability, -}; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, -}; -use zenoh_protocol::{ - common::imsg, - core::{Channel, Priority, Reliability}, - zenoh::{zmsg, ReplyContext, RoutingContext, ZenohBody, ZenohMessage}, -}; - -impl WCodec<&ZenohMessage, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ZenohMessage) -> Self::Output { - if let Some(r) = x.routing_context.as_ref() { - self.write(&mut *writer, r)?; - } - if x.channel.priority != Priority::default() { - self.write(&mut *writer, &x.channel.priority)?; - } - - match &x.body { - ZenohBody::Data(d) => self.write(&mut *writer, d), - ZenohBody::Unit(u) => self.write(&mut *writer, u), - ZenohBody::Pull(p) => self.write(&mut *writer, p), - ZenohBody::Query(q) => self.write(&mut *writer, q), - ZenohBody::Declare(d) => self.write(&mut *writer, d), - ZenohBody::LinkStateList(l) => self.write(&mut *writer, l), - } - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let codec = Zenoh080Reliability::new(Reliability::default()); - codec.read(reader) - } -} - -impl RCodec for Zenoh080Reliability -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.codec.read(&mut *reader)?; - let mut codec = Zenoh080Header::new(header); - - let routing_context = if imsg::mid(codec.header) == zmsg::id::ROUTING_CONTEXT { - let r: RoutingContext = codec.read(&mut *reader)?; - codec.header = self.codec.read(&mut *reader)?; - Some(r) - } else { - None - }; - let priority = if imsg::mid(codec.header) == zmsg::id::PRIORITY { - let p: Priority = codec.read(&mut *reader)?; - codec.header = self.codec.read(&mut *reader)?; - p - } else { - Priority::default() - }; - let reply_context = if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { - let rc: ReplyContext = codec.read(&mut *reader)?; - codec.header = self.codec.read(&mut *reader)?; - Some(rc) - } else { - None - }; - - let body = match imsg::mid(codec.header) { - zmsg::id::DATA => { - let rodec = Zenoh080HeaderReplyContext { - header: codec.header, - reply_context, - codec: Zenoh080::new(), - }; - ZenohBody::Data(rodec.read(&mut *reader)?) - } - zmsg::id::UNIT => { - let rodec = Zenoh080HeaderReplyContext { - header: codec.header, - reply_context, - codec: Zenoh080::new(), - }; - ZenohBody::Unit(rodec.read(&mut *reader)?) - } - zmsg::id::PULL => ZenohBody::Pull(codec.read(&mut *reader)?), - zmsg::id::QUERY => ZenohBody::Query(codec.read(&mut *reader)?), - zmsg::id::DECLARE => ZenohBody::Declare(codec.read(&mut *reader)?), - zmsg::id::LINK_STATE_LIST => ZenohBody::LinkStateList(codec.read(&mut *reader)?), - _ => return Err(DidntRead), - }; - - Ok(ZenohMessage::new( - body, - Channel { - priority, - reliability: self.reliability, - }, - routing_context, - )) - } -} diff --git a/commons/zenoh-codec/src/zenoh/pull.rs b/commons/zenoh-codec/src/zenoh/pull.rs deleted file mode 100644 index 554ce586d9..0000000000 --- a/commons/zenoh-codec/src/zenoh/pull.rs +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, -}; -use zenoh_protocol::{ - common::imsg, - core::WireExpr, - zenoh::{zmsg, Pull, PullId}, -}; - -impl WCodec<&Pull, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Pull) -> Self::Output { - // Header - let mut header = zmsg::id::PULL; - if x.is_final { - header |= zmsg::flag::F; - } - if x.max_samples.is_some() { - header |= zmsg::flag::N; - } - if x.key.has_suffix() { - header |= zmsg::flag::K; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, &x.key)?; - self.write(&mut *writer, x.pull_id)?; - if let Some(n) = x.max_samples { - self.write(&mut *writer, n)?; - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::id::PULL { - return Err(DidntRead); - } - - let ccond = Zenoh080Condition { - condition: imsg::has_flag(self.header, zmsg::flag::K), - codec: self.codec, - }; - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - let pull_id: PullId = self.codec.read(&mut *reader)?; - let max_samples = if imsg::has_flag(self.header, zmsg::flag::N) { - let n: u16 = self.codec.read(&mut *reader)?; - Some(n) - } else { - None - }; - let is_final = imsg::has_flag(self.header, zmsg::flag::F); - - Ok(Pull { - key, - pull_id, - max_samples, - is_final, - }) - } -} diff --git a/commons/zenoh-codec/src/zenoh/query.rs b/commons/zenoh-codec/src/zenoh/query.rs deleted file mode 100644 index 67be8dd555..0000000000 --- a/commons/zenoh-codec/src/zenoh/query.rs +++ /dev/null @@ -1,226 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Condition, Zenoh080Header}; -use alloc::string::String; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, - ZBuf, -}; -use zenoh_protocol::{ - common::imsg, - core::WireExpr, - zenoh::{zmsg, ConsolidationMode, DataInfo, Query, QueryBody, QueryId, QueryTarget}, -}; - -// QueryTarget -impl WCodec<&QueryTarget, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &QueryTarget) -> Self::Output { - #![allow(clippy::unnecessary_cast)] - match x { - QueryTarget::BestMatching => self.write(&mut *writer, 0 as u64)?, - QueryTarget::All => self.write(&mut *writer, 1 as u64)?, - QueryTarget::AllComplete => self.write(&mut *writer, 2 as u64)?, - #[cfg(feature = "complete_n")] - QueryTarget::Complete(n) => { - self.write(&mut *writer, 3 as u64)?; - self.write(&mut *writer, *n)?; - } - } - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let t: u64 = self.read(&mut *reader)?; - let t = match t { - 0 => QueryTarget::BestMatching, - 1 => QueryTarget::All, - 2 => QueryTarget::AllComplete, - #[cfg(feature = "complete_n")] - 3 => { - let n: u64 = self.read(&mut *reader)?; - QueryTarget::Complete(n) - } - _ => return Err(DidntRead), - }; - Ok(t) - } -} - -// ConsolidationMode -impl WCodec<&ConsolidationMode, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &ConsolidationMode) -> Self::Output { - let cm: u64 = match x { - ConsolidationMode::None => 0, - ConsolidationMode::Monotonic => 1, - ConsolidationMode::Latest => 2, - }; - self.write(&mut *writer, cm)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let cm: u64 = self.read(&mut *reader)?; - let cm = match cm { - 0 => ConsolidationMode::None, - 1 => ConsolidationMode::Monotonic, - 2 => ConsolidationMode::Latest, - _ => return Err(DidntRead), - }; - Ok(cm) - } -} - -// QueryBody -impl WCodec<&QueryBody, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &QueryBody) -> Self::Output { - self.write(&mut *writer, &x.data_info)?; - self.write(&mut *writer, &x.payload)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let data_info: DataInfo = self.read(&mut *reader)?; - let payload: ZBuf = self.read(&mut *reader)?; - Ok(QueryBody { data_info, payload }) - } -} - -// Query -impl WCodec<&Query, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Query) -> Self::Output { - // Header - let mut header = zmsg::id::QUERY; - if x.target.is_some() { - header |= zmsg::flag::T; - } - if x.body.is_some() { - header |= zmsg::flag::B; - } - if x.key.has_suffix() { - header |= zmsg::flag::K; - } - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, &x.key)?; - self.write(&mut *writer, x.parameters.as_str())?; - self.write(&mut *writer, x.qid)?; - if let Some(t) = x.target.as_ref() { - self.write(&mut *writer, t)?; - } - self.write(&mut *writer, &x.consolidation)?; - if let Some(b) = x.body.as_ref() { - self.write(&mut *writer, b)?; - } - - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::id::QUERY { - return Err(DidntRead); - } - - let ccond = Zenoh080Condition::new(imsg::has_flag(self.header, zmsg::flag::K)); - let key: WireExpr<'static> = ccond.read(&mut *reader)?; - - let parameters: String = self.codec.read(&mut *reader)?; - let qid: QueryId = self.codec.read(&mut *reader)?; - let target = if imsg::has_flag(self.header, zmsg::flag::T) { - let qt: QueryTarget = self.codec.read(&mut *reader)?; - Some(qt) - } else { - None - }; - let consolidation: ConsolidationMode = self.codec.read(&mut *reader)?; - let body = if imsg::has_flag(self.header, zmsg::flag::B) { - let qb: QueryBody = self.codec.read(&mut *reader)?; - Some(qb) - } else { - None - }; - - Ok(Query { - key, - parameters, - qid, - target, - consolidation, - body, - }) - } -} diff --git a/commons/zenoh-codec/src/zenoh/routing.rs b/commons/zenoh-codec/src/zenoh/routing.rs deleted file mode 100644 index ffce0749c7..0000000000 --- a/commons/zenoh-codec/src/zenoh/routing.rs +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header}; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, -}; -use zenoh_protocol::{ - common::imsg, - zenoh::{zmsg, RoutingContext}, -}; - -impl WCodec<&RoutingContext, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &RoutingContext) -> Self::Output { - // Header - let header = zmsg::id::ROUTING_CONTEXT; - self.write(&mut *writer, header)?; - - // Body - self.write(&mut *writer, x.tree_id)?; - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let header: u8 = self.read(&mut *reader)?; - let codec = Zenoh080Header::new(header); - - codec.read(reader) - } -} - -impl RCodec for Zenoh080Header -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::id::ROUTING_CONTEXT { - return Err(DidntRead); - } - - let tree_id: u64 = self.codec.read(&mut *reader)?; - Ok(RoutingContext { tree_id }) - } -} diff --git a/commons/zenoh-codec/src/zenoh/unit.rs b/commons/zenoh-codec/src/zenoh/unit.rs deleted file mode 100644 index 489fb72783..0000000000 --- a/commons/zenoh-codec/src/zenoh/unit.rs +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080HeaderReplyContext}; -use zenoh_buffers::{ - reader::{DidntRead, Reader}, - writer::{DidntWrite, Writer}, -}; -use zenoh_protocol::{ - common::imsg, - core::CongestionControl, - zenoh::{zmsg, Unit}, -}; - -impl WCodec<&Unit, &mut W> for Zenoh080 -where - W: Writer, -{ - type Output = Result<(), DidntWrite>; - - fn write(self, writer: &mut W, x: &Unit) -> Self::Output { - if let Some(reply_context) = x.reply_context.as_ref() { - self.write(&mut *writer, reply_context)?; - } - - // Header - let mut header = zmsg::id::UNIT; - if x.congestion_control == CongestionControl::Drop { - header |= zmsg::flag::D; - } - self.write(&mut *writer, header)?; - - // Body - Ok(()) - } -} - -impl RCodec for Zenoh080 -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, reader: &mut R) -> Result { - let mut codec = Zenoh080HeaderReplyContext { - header: self.read(&mut *reader)?, - reply_context: None, - codec: Zenoh080::new(), - }; - if imsg::mid(codec.header) == zmsg::id::REPLY_CONTEXT { - let hodec = Zenoh080Header::new(codec.header); - codec.reply_context = Some(hodec.read(&mut *reader)?); - codec.header = self.read(&mut *reader)?; - } - codec.read(reader) - } -} - -impl RCodec for Zenoh080HeaderReplyContext -where - R: Reader, -{ - type Error = DidntRead; - - fn read(self, _reader: &mut R) -> Result { - if imsg::mid(self.header) != zmsg::id::UNIT { - return Err(DidntRead); - } - - let congestion_control = if imsg::has_flag(self.header, zmsg::flag::D) { - CongestionControl::Drop - } else { - CongestionControl::Block - }; - Ok(Unit { - congestion_control, - reply_context: self.reply_context, - }) - } -} diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index ef5f7291cf..588df01f1e 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -28,7 +28,7 @@ use zenoh_protocol::{ network::{self, *}, scouting::*, transport::{self, *}, - zenoh, zenoh_new, zextunit, zextz64, zextzbuf, + zenoh_new, zextunit, zextz64, zextzbuf, }; const NUM_ITER: usize = 100; @@ -591,123 +591,3 @@ fn codec_ack() { fn codec_pull() { run!(zenoh_new::Pull, zenoh_new::Pull::rand()); } - -// Zenoh -#[test] -fn codec_routing_context_old() { - run!(zenoh::RoutingContext, zenoh::RoutingContext::rand()); -} - -#[test] -fn codec_reply_context_old() { - run!(zenoh::ReplyContext, zenoh::ReplyContext::rand()); -} - -#[test] -fn codec_data_info_old() { - run!(zenoh::DataInfo, zenoh::DataInfo::rand()); -} - -#[test] -fn codec_data_old() { - run!(zenoh::Data, zenoh::Data::rand()); -} - -#[test] -fn codec_unit_old() { - run!(zenoh::Unit, zenoh::Unit::rand()); -} - -#[test] -fn codec_pull_old() { - run!(zenoh::Pull, zenoh::Pull::rand()); -} - -#[test] -fn codec_query_old() { - run!(zenoh::Query, zenoh::Query::rand()); -} - -#[test] -fn codec_declaration_resource_old() { - run!(zenoh::Resource, zenoh::Resource::rand()); -} - -#[test] -fn codec_declaration_undeclare_resource_old() { - run!(zenoh::ForgetResource, zenoh::ForgetResource::rand()); -} - -#[test] -fn codec_declaration_publisher_old() { - run!(zenoh::Publisher, zenoh::Publisher::rand()); -} - -#[test] -fn codec_declaration_undeclare_publisher_old() { - run!(zenoh::ForgetPublisher, zenoh::ForgetPublisher::rand()); -} - -#[test] -fn codec_declaration_subscriber_old() { - run!(zenoh::Subscriber, zenoh::Subscriber::rand()); -} - -#[test] -fn codec_declaration_undeclare_subscriber_old() { - run!(zenoh::ForgetSubscriber, zenoh::ForgetSubscriber::rand()); -} - -#[test] -fn codec_declaration_queryable_old() { - run!(zenoh::Queryable, zenoh::Queryable::rand()); -} - -#[test] -fn codec_declaration_undeclare_queryable_old() { - run!(UndeclareQueryable, UndeclareQueryable::rand()); -} - -#[test] -fn codec_declaration_old() { - run!(zenoh::Declaration, zenoh::Declaration::rand()); -} - -#[test] -fn codec_declare_old() { - run!(zenoh::Declare, zenoh::Declare::rand()); -} - -#[test] -fn codec_link_state_old() { - run!(zenoh::LinkState, zenoh::LinkState::rand()); -} - -#[test] -fn codec_link_state_list_old() { - run!(zenoh::LinkStateList, zenoh::LinkStateList::rand()); -} - -#[test] -fn codec_zenoh_old() { - run!( - zenoh::ZenohMessage, - { - let mut x = zenoh::ZenohMessage::rand(); - x.channel.reliability = Reliability::Reliable; - x - }, - { Zenoh080::new() }, - { Zenoh080Reliability::new(Reliability::Reliable) } - ); - run!( - zenoh::ZenohMessage, - { - let mut x = zenoh::ZenohMessage::rand(); - x.channel.reliability = Reliability::BestEffort; - x - }, - { Zenoh080::new() }, - { Zenoh080Reliability::new(Reliability::BestEffort) } - ); -} diff --git a/commons/zenoh-protocol/src/core/resolution.rs b/commons/zenoh-protocol/src/core/resolution.rs index ebd65a5824..a174ecdc9d 100644 --- a/commons/zenoh-protocol/src/core/resolution.rs +++ b/commons/zenoh-protocol/src/core/resolution.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{transport::TransportSn, zenoh::QueryId}; +use crate::{network::RequestId, transport::TransportSn}; use alloc::string::String; use core::{fmt, str::FromStr}; use zenoh_result::{bail, ZError}; @@ -150,7 +150,7 @@ impl Resolution { impl Default for Resolution { fn default() -> Self { let frame_sn = Bits::from(TransportSn::MAX) as u8; - let request_id = (Bits::from(QueryId::MAX) as u8) << 2; + let request_id = (Bits::from(RequestId::MAX) as u8) << 2; Self(frame_sn | request_id) } } diff --git a/commons/zenoh-protocol/src/lib.rs b/commons/zenoh-protocol/src/lib.rs index 931b90135d..30530335ec 100644 --- a/commons/zenoh-protocol/src/lib.rs +++ b/commons/zenoh-protocol/src/lib.rs @@ -25,7 +25,6 @@ pub mod core; pub mod network; pub mod scouting; pub mod transport; -pub mod zenoh; pub mod zenoh_new; // Zenoh version diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index 6bf878e8a3..5e005d585e 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -66,6 +66,7 @@ pub struct Request { pub mod ext { use crate::{ common::{ZExtZ64, ZExtZBuf}, + core::QueryTarget, zextz64, zextzbuf, }; use core::{num::NonZeroU32, time::Duration}; @@ -87,15 +88,7 @@ pub mod ext { /// +---------------+ /// /// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. - #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] - pub enum TargetType { - #[default] - BestMatching, - All, - AllComplete, - #[cfg(feature = "complete_n")] - Complete(u64), - } + pub type TargetType = QueryTarget; impl TargetType { #[cfg(feature = "test")] diff --git a/commons/zenoh-protocol/src/zenoh/data.rs b/commons/zenoh-protocol/src/zenoh/data.rs deleted file mode 100644 index 2c770ee5fc..0000000000 --- a/commons/zenoh-protocol/src/zenoh/data.rs +++ /dev/null @@ -1,249 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{ - core::{CongestionControl, Encoding, Timestamp, WireExpr, ZenohId}, - zenoh::QueryId, -}; -use core::{convert::TryFrom, fmt}; -use zenoh_buffers::ZBuf; - -/// The kind of a `Sample`. -#[repr(u8)] -#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] -pub enum SampleKind { - /// if the `Sample` was issued by a `put` operation. - #[default] - Put = 0, - /// if the `Sample` was issued by a `delete` operation. - Delete = 1, -} - -impl fmt::Display for SampleKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - SampleKind::Put => write!(f, "PUT"), - SampleKind::Delete => write!(f, "DELETE"), - } - } -} - -impl TryFrom for SampleKind { - type Error = u8; - fn try_from(kind: u8) -> Result { - match kind { - 0 => Ok(SampleKind::Put), - 1 => Ok(SampleKind::Delete), - _ => Err(kind), - } - } -} - -/// # ReplyContext decorator -/// -/// ```text -/// The **ReplyContext** is a message decorator for either: -/// - the **Data** messages that result from a query -/// - or a **Unit** message in case the message is a -/// SOURCE_FINAL or REPLY_FINAL. -/// The **replier-id** (queryable id) is represented as a byte-array. -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |X|X|F| R_CTX | -/// +-+-+-+---------+ -/// ~ qid ~ -/// +---------------+ -/// ~ replier_id ~ if F==0 -/// +---------------+ -/// -/// - if F==1 then the message is a REPLY_FINAL -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ReplierInfo { - pub id: ZenohId, -} -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ReplyContext { - pub qid: QueryId, - pub replier: Option, -} - -impl ReplyContext { - // Note: id replier_id=None flag F is set, meaning it's a REPLY_FINAL - pub fn new(qid: QueryId, replier: Option) -> Self { - Self { qid, replier } - } - - pub fn is_final(&self) -> bool { - self.replier.is_none() - } -} - -impl ReplyContext { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let qid: QueryId = rng.gen(); - let replier = if rng.gen_bool(0.5) { - Some(ReplierInfo { - id: ZenohId::default(), - }) - } else { - None - }; - - Self { qid, replier } - } -} - -/// # DataInfo -/// -/// DataInfo data structure is optionally included in Data messages -/// -/// ```text -/// -/// Options bits -/// - 0: Payload is sliced -/// - 1: Payload kind -/// - 2: Payload encoding -/// - 3: Payload timestamp -/// - 4: Reserved -/// - 5: Reserved -/// - 6: Reserved -/// - 7: Payload source_id -/// - 8: Payload source_sn -/// - 9-63: Reserved -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+---------+ -/// ~ options ~ -/// +---------------+ -/// ~ kind ~ if options & (1 << 1) -/// +---------------+ -/// ~ encoding ~ if options & (1 << 2) -/// +---------------+ -/// ~ timestamp ~ if options & (1 << 3) -/// +---------------+ -/// ~ source_id ~ if options & (1 << 7) -/// +---------------+ -/// ~ source_sn ~ if options & (1 << 8) -/// +---------------+ -/// -/// - if options & (1 << 0) then the payload is sliced -/// -/// ``` -pub type SourceSn = u64; - -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct DataInfo { - pub kind: SampleKind, - pub encoding: Option, - pub timestamp: Option, - pub source_id: Option, - pub source_sn: Option, -} - -impl DataInfo { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let kind = SampleKind::try_from(rng.gen_range(0..=1)).unwrap(); - let encoding = rng.gen_bool(0.5).then(Encoding::rand); - let timestamp = rng.gen_bool(0.5).then(|| { - let time = uhlc::NTP64(rng.gen()); - let id = uhlc::ID::try_from(ZenohId::rand().to_le_bytes()).unwrap(); - Timestamp::new(time, id) - }); - let source_id = rng.gen_bool(0.5).then(ZenohId::rand); - let source_sn = rng.gen_bool(0.5).then(|| rng.gen()); - - Self { - kind, - encoding, - timestamp, - source_id, - source_sn, - } - } -} - -/// # Data message -/// -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|I|D| DATA | -/// +-+-+-+---------+ -/// ~ KeyExpr ~ if K==1 -- Only numerical id -/// +---------------+ -/// ~ DataInfo ~ if I==1 -/// +---------------+ -/// ~ Payload ~ -/// +---------------+ -/// -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Data { - pub key: WireExpr<'static>, - pub data_info: Option, - pub payload: ZBuf, - pub congestion_control: CongestionControl, - pub reply_context: Option, -} - -impl Data { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - const MIN: usize = 2; - const MAX: usize = 16; - - let mut rng = rand::thread_rng(); - - let key = WireExpr::rand(); - let data_info = if rng.gen_bool(0.5) { - Some(DataInfo::rand()) - } else { - None - }; - - let payload = ZBuf::rand(rng.gen_range(MIN..MAX)); - - let congestion_control = if rng.gen_bool(0.5) { - CongestionControl::Block - } else { - CongestionControl::Drop - }; - let reply_context = if rng.gen_bool(0.5) { - Some(ReplyContext::rand()) - } else { - None - }; - - Self { - key, - data_info, - payload, - congestion_control, - reply_context, - } - } -} diff --git a/commons/zenoh-protocol/src/zenoh/declare.rs b/commons/zenoh-protocol/src/zenoh/declare.rs deleted file mode 100644 index bbe5fe9a92..0000000000 --- a/commons/zenoh-protocol/src/zenoh/declare.rs +++ /dev/null @@ -1,314 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{ - core::{ExprId, WireExpr}, - zenoh::Reliability, -}; -use alloc::vec::Vec; - -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |X|X|X| DECLARE | -/// +-+-+-+---------+ -/// ~ Num of Decl ~ -/// +---------------+ -/// ~ [Declaration] ~ -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Declare { - pub declarations: Vec, -} - -impl Declare { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let n: usize = rng.gen_range(1..16); - let declarations = (0..n) - .map(|_| Declaration::rand()) - .collect::>(); - - Self { declarations } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum Declaration { - Resource(Resource), - ForgetResource(ForgetResource), - Publisher(Publisher), - ForgetPublisher(ForgetPublisher), - Subscriber(Subscriber), - ForgetSubscriber(ForgetSubscriber), - Queryable(Queryable), - ForgetQueryable(ForgetQueryable), -} - -impl Declaration { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - match rng.gen_range(0..8) { - 0 => Declaration::Resource(Resource::rand()), - 1 => Declaration::ForgetResource(ForgetResource::rand()), - 2 => Declaration::Publisher(Publisher::rand()), - 3 => Declaration::ForgetPublisher(ForgetPublisher::rand()), - 4 => Declaration::Subscriber(Subscriber::rand()), - 5 => Declaration::ForgetSubscriber(ForgetSubscriber::rand()), - 6 => Declaration::Queryable(Queryable::rand()), - 7 => Declaration::ForgetQueryable(ForgetQueryable::rand()), - _ => unreachable!(), - } - } -} - -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|X|X| RESOURCE| -/// +---------------+ -/// ~ RID ~ -/// +---------------+ -/// ~ KeyExpr ~ if K==1 then key_expr has suffix -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Resource { - pub expr_id: ExprId, - pub key: WireExpr<'static>, -} - -impl Resource { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let expr_id: ExprId = rng.gen(); - let key = WireExpr::rand(); - - Self { expr_id, key } - } -} - -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |X|X|X| F_RES | -/// +---------------+ -/// ~ RID ~ -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetResource { - pub expr_id: ExprId, -} - -impl ForgetResource { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let expr_id: ExprId = rng.gen(); - - Self { expr_id } - } -} - -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|X|X| PUB | -/// +---------------+ -/// ~ KeyExpr ~ if K==1 then key_expr has suffix -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Publisher { - pub key: WireExpr<'static>, -} - -impl Publisher { - #[cfg(feature = "test")] - pub fn rand() -> Self { - let key = WireExpr::rand(); - - Self { key } - } -} - -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|X|X| F_PUB | -/// +---------------+ -/// ~ KeyExpr ~ if K==1 then key_expr has suffix -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetPublisher { - pub key: WireExpr<'static>, -} - -impl ForgetPublisher { - #[cfg(feature = "test")] - pub fn rand() -> Self { - let key = WireExpr::rand(); - - Self { key } - } -} - -/// The subscription mode. -#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] -#[repr(u8)] -pub enum SubMode { - #[default] - Push, - Pull, -} -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct SubInfo { - pub reliability: Reliability, - pub mode: SubMode, -} - -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|S|R| SUB | R for Reliable -/// +---------------+ -/// ~ KeyExpr ~ if K==1 then key_expr has suffix -/// +---------------+ -/// | SubMode | if S==1. Otherwise: SubMode=Push -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Subscriber { - pub key: WireExpr<'static>, - pub info: SubInfo, -} - -impl Subscriber { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let key = WireExpr::rand(); - let reliability = Reliability::rand(); - let mode = if rng.gen_bool(0.5) { - SubMode::Push - } else { - SubMode::Pull - }; - let info = SubInfo { reliability, mode }; - - Self { key, info } - } -} - -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|X|X| F_SUB | -/// +---------------+ -/// ~ KeyExpr ~ if K==1 then key_expr has suffix -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetSubscriber { - pub key: WireExpr<'static>, -} - -impl ForgetSubscriber { - #[cfg(feature = "test")] - pub fn rand() -> Self { - let key = WireExpr::rand(); - - Self { key } - } -} - -#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] -pub struct QueryableInfo { - pub complete: u64, // Default 0: incomplete - pub distance: u64, // Default 0: no distance -} - -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|Q|X| QABLE | -/// +---------------+ -/// ~ KeyExpr ~ if K==1 then key_expr has suffix -/// +---------------+ -/// ~ QablInfo ~ if Q==1 -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Queryable { - pub key: WireExpr<'static>, - pub info: QueryableInfo, -} - -impl Queryable { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let key = WireExpr::rand(); - let complete: u64 = rng.gen(); - let distance: u64 = rng.gen(); - let info = QueryableInfo { complete, distance }; - - Self { key, info } - } -} - -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|X|X| F_QABLE | -/// +---------------+ -/// ~ KeyExpr ~ if K==1 then key_expr has suffix -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ForgetQueryable { - pub key: WireExpr<'static>, -} - -impl ForgetQueryable { - #[cfg(feature = "test")] - pub fn rand() -> Self { - let key = WireExpr::rand(); - - Self { key } - } -} diff --git a/commons/zenoh-protocol/src/zenoh/linkstate.rs b/commons/zenoh-protocol/src/zenoh/linkstate.rs deleted file mode 100644 index d739361c64..0000000000 --- a/commons/zenoh-protocol/src/zenoh/linkstate.rs +++ /dev/null @@ -1,114 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::core::{Locator, WhatAmI, ZenohId}; -use alloc::vec::Vec; - -// 7 6 5 4 3 2 1 0 -// +-+-+-+-+-+-+-+-+ -// ~X|X|X|X|X|L|W|P~ -// +-+-+-+-+-+-+-+-+ -// ~ psid ~ -// +---------------+ -// ~ sn ~ -// +---------------+ -// ~ zid ~ if P == 1 -// +---------------+ -// ~ whatami ~ if W == 1 -// +---------------+ -// ~ [locators] ~ if L == 1 -// +---------------+ -// ~ [links] ~ -// +---------------+ -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct LinkState { - pub psid: u64, - pub sn: u64, - pub zid: Option, - pub whatami: Option, - pub locators: Option>, - pub links: Vec, -} - -impl LinkState { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - const MIN: usize = 1; - const MAX: usize = 16; - - let mut rng = rand::thread_rng(); - - let psid: u64 = rng.gen(); - let sn: u64 = rng.gen(); - let zid = if rng.gen_bool(0.5) { - Some(ZenohId::default()) - } else { - None - }; - let whatami = if rng.gen_bool(0.5) { - Some(WhatAmI::rand()) - } else { - None - }; - let locators = if rng.gen_bool(0.5) { - let n = rng.gen_range(MIN..=MAX); - let locators = (0..n).map(|_| Locator::rand()).collect::>(); - Some(locators) - } else { - None - }; - let n = rng.gen_range(MIN..=MAX); - let links = (0..n).map(|_| rng.gen()).collect::>(); - - Self { - psid, - sn, - zid, - whatami, - locators, - links, - } - } -} - -// 7 6 5 4 3 2 1 0 -// +-+-+-+-+-+-+-+-+ -// |X|X|X|LK_ST_LS | -// +-+-+-+---------+ -// ~ [link_states] ~ -// +---------------+ -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct LinkStateList { - pub link_states: Vec, -} - -impl LinkStateList { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - const MIN: usize = 1; - const MAX: usize = 16; - - let mut rng = rand::thread_rng(); - - let n = rng.gen_range(MIN..=MAX); - let link_states = (0..n) - .map(|_| LinkState::rand()) - .collect::>(); - - Self { link_states } - } -} diff --git a/commons/zenoh-protocol/src/zenoh/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs deleted file mode 100644 index 18fdad9692..0000000000 --- a/commons/zenoh-protocol/src/zenoh/mod.rs +++ /dev/null @@ -1,411 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -mod data; -mod declare; -mod linkstate; -mod pull; -mod query; -mod routing; -mod unit; - -use crate::core::{Channel, CongestionControl, Reliability, WireExpr}; -use alloc::{string::String, vec::Vec}; -use core::fmt; -pub use data::*; -pub use declare::*; -pub use linkstate::*; -pub use pull::*; -pub use query::*; -pub use routing::*; -pub use unit::*; -use zenoh_buffers::ZBuf; - -pub mod zmsg { - use crate::{ - common::imsg, - core::{Channel, CongestionControl, Priority, Reliability}, - }; - - // Zenoh message IDs -- Re-export of some of the Inner Message IDs - pub mod id { - use super::imsg; - - // Messages - pub const DECLARE: u8 = imsg::id::DECLARE; - pub const DATA: u8 = imsg::id::DATA; - pub const QUERY: u8 = imsg::id::QUERY; - pub const PULL: u8 = imsg::id::PULL; - pub const UNIT: u8 = imsg::id::UNIT; - pub const LINK_STATE_LIST: u8 = imsg::id::LINK_STATE_LIST; - - // Message decorators - pub const PRIORITY: u8 = imsg::id::PRIORITY; - pub const REPLY_CONTEXT: u8 = imsg::id::REPLY_CONTEXT; - pub const ROUTING_CONTEXT: u8 = imsg::id::ROUTING_CONTEXT; - } - - // Zenoh message flags - pub mod flag { - pub const B: u8 = 1 << 6; // 0x40 QueryBody if B==1 then QueryBody is present - pub const D: u8 = 1 << 5; // 0x20 Drop if D==1 then the message can be dropped - pub const F: u8 = 1 << 5; // 0x20 Final if F==1 then this is the final message (e.g., ReplyContext, Pull) - pub const I: u8 = 1 << 6; // 0x40 DataInfo if I==1 then DataInfo is present - pub const K: u8 = 1 << 7; // 0x80 KeySuffix if K==1 then key_expr has suffix - pub const N: u8 = 1 << 6; // 0x40 MaxSamples if N==1 then the MaxSamples is indicated - pub const P: u8 = 1 << 0; // 0x01 Zid if P==1 then the zid is present - pub const Q: u8 = 1 << 6; // 0x40 QueryableInfo if Q==1 then the queryable info is present - pub const R: u8 = 1 << 5; // 0x20 Reliable if R==1 then it concerns the reliable channel, best-effort otherwise - pub const S: u8 = 1 << 6; // 0x40 SubMode if S==1 then the declaration SubMode is indicated - pub const T: u8 = 1 << 5; // 0x20 QueryTAK if T==1 then the query target is present - - pub const X: u8 = 0; // Unused flags are set to zero - } - - // Options used for DataInfo - pub mod data { - pub mod info { - #[cfg(feature = "shared-memory")] - pub const SLICED: u8 = 1 << 0; // 0x01 - pub const KIND: u8 = 1 << 1; // 0x02 - pub const ENCODING: u8 = 1 << 2; // 0x04 - pub const TIMESTAMP: u8 = 1 << 3; // 0x08 - pub const SRCID: u8 = 1 << 4; // 0x10 - pub const SRCSN: u8 = 1 << 5; // 0x20 - } - } - - pub mod declaration { - pub mod id { - // Declarations - pub const RESOURCE: u8 = 0x01; - pub const PUBLISHER: u8 = 0x02; - pub const SUBSCRIBER: u8 = 0x03; - pub const QUERYABLE: u8 = 0x04; - - pub const FORGET_RESOURCE: u8 = 0x11; - pub const FORGET_PUBLISHER: u8 = 0x12; - pub const FORGET_SUBSCRIBER: u8 = 0x13; - pub const FORGET_QUERYABLE: u8 = 0x14; - - // SubModes - pub const MODE_PUSH: u8 = 0x00; - pub const MODE_PULL: u8 = 0x01; - } - - pub mod flag { - pub const PERIOD: u8 = 0x80; - } - } - - // Options used for LinkState - pub mod link_state { - pub const PID: u64 = 1; // 0x01 - pub const WAI: u64 = 1 << 1; // 0x02 - pub const LOC: u64 = 1 << 2; // 0x04 - } - - pub mod priority { - use super::{imsg, Priority}; - - pub const CONTROL: u8 = (Priority::Control as u8) << imsg::HEADER_BITS; - pub const REAL_TIME: u8 = (Priority::RealTime as u8) << imsg::HEADER_BITS; - pub const INTERACTIVE_HIGH: u8 = (Priority::InteractiveHigh as u8) << imsg::HEADER_BITS; - pub const INTERACTIVE_LOW: u8 = (Priority::InteractiveLow as u8) << imsg::HEADER_BITS; - pub const DATA_HIGH: u8 = (Priority::DataHigh as u8) << imsg::HEADER_BITS; - pub const DATA: u8 = (Priority::Data as u8) << imsg::HEADER_BITS; - pub const DATA_LOW: u8 = (Priority::DataLow as u8) << imsg::HEADER_BITS; - pub const BACKGROUND: u8 = (Priority::Background as u8) << imsg::HEADER_BITS; - } - - // Default reliability for each Zenoh Message - pub mod default_channel { - use super::{Channel, Priority, Reliability}; - - pub const DECLARE: Channel = Channel { - priority: Priority::RealTime, - reliability: Reliability::Reliable, - }; - pub const DATA: Channel = Channel { - priority: Priority::Data, - reliability: Reliability::BestEffort, - }; - pub const QUERY: Channel = Channel { - priority: Priority::Data, - reliability: Reliability::Reliable, - }; - pub const PULL: Channel = Channel { - priority: Priority::Data, - reliability: Reliability::Reliable, - }; - pub const REPLY: Channel = Channel { - priority: Priority::Data, - reliability: Reliability::Reliable, - }; - pub const UNIT: Channel = Channel { - priority: Priority::Data, - reliability: Reliability::BestEffort, - }; - pub const LINK_STATE_LIST: Channel = Channel { - priority: Priority::Control, - reliability: Reliability::Reliable, - }; - } - - // Default congestion control for each Zenoh Message - pub mod default_congestion_control { - use super::CongestionControl; - - pub const DECLARE: CongestionControl = CongestionControl::Block; - pub const DATA: CongestionControl = CongestionControl::Drop; - pub const QUERY: CongestionControl = CongestionControl::Block; - pub const PULL: CongestionControl = CongestionControl::Block; - pub const REPLY: CongestionControl = CongestionControl::Block; - pub const UNIT: CongestionControl = CongestionControl::Block; - pub const LINK_STATE_LIST: CongestionControl = CongestionControl::Block; - } -} - -// Zenoh messages at zenoh level -#[allow(clippy::large_enum_variant)] -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ZenohBody { - Data(Data), - Unit(Unit), - Pull(Pull), - Query(Query), - Declare(Declare), - LinkStateList(LinkStateList), -} - -#[derive(Clone, PartialEq, Eq)] -pub struct ZenohMessage { - pub body: ZenohBody, - pub channel: Channel, - pub routing_context: Option, - #[cfg(feature = "stats")] - pub size: Option, -} - -impl ZenohMessage { - #[inline] - pub fn new(body: ZenohBody, channel: Channel, routing_context: Option) -> Self { - Self { - body, - channel, - routing_context, - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_declare( - declarations: Vec, - routing_context: Option, - ) -> ZenohMessage { - ZenohMessage { - body: ZenohBody::Declare(Declare { declarations }), - channel: zmsg::default_channel::DECLARE, - routing_context, - #[cfg(feature = "stats")] - size: None, - } - } - - #[allow(clippy::too_many_arguments)] - #[inline(always)] - pub fn make_data( - key: WireExpr<'static>, - payload: ZBuf, - channel: Channel, - congestion_control: CongestionControl, - data_info: Option, - routing_context: Option, - reply_context: Option, - ) -> ZenohMessage { - ZenohMessage { - body: ZenohBody::Data(Data { - key, - data_info, - payload, - congestion_control, - reply_context, - }), - channel, - routing_context, - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_unit( - channel: Channel, - congestion_control: CongestionControl, - reply_context: Option, - ) -> ZenohMessage { - ZenohMessage { - body: ZenohBody::Unit(Unit { - congestion_control, - reply_context, - }), - channel, - routing_context: None, - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_pull( - is_final: bool, - key: WireExpr<'static>, - pull_id: PullId, - max_samples: Option, - ) -> ZenohMessage { - ZenohMessage { - body: ZenohBody::Pull(Pull { - key, - pull_id, - max_samples, - is_final, - }), - channel: zmsg::default_channel::PULL, - routing_context: None, - #[cfg(feature = "stats")] - size: None, - } - } - - #[allow(clippy::too_many_arguments)] - #[inline(always)] - pub fn make_query( - key: WireExpr<'static>, - parameters: String, - qid: QueryId, - target: Option, - consolidation: ConsolidationMode, - body: Option, - routing_context: Option, - ) -> ZenohMessage { - ZenohMessage { - body: ZenohBody::Query(Query { - key, - parameters, - qid, - target, - consolidation, - body, - }), - channel: zmsg::default_channel::QUERY, - routing_context, - #[cfg(feature = "stats")] - size: None, - } - } - - pub fn make_link_state_list(link_states: Vec) -> ZenohMessage { - ZenohMessage { - body: ZenohBody::LinkStateList(LinkStateList { link_states }), - channel: zmsg::default_channel::LINK_STATE_LIST, - routing_context: None, - - #[cfg(feature = "stats")] - size: None, - } - } - - // -- Message Predicates - #[inline] - pub fn is_reliable(&self) -> bool { - self.channel.reliability == Reliability::Reliable - } - - #[inline] - pub fn is_droppable(&self) -> bool { - if !self.is_reliable() { - return true; - } - - let cc = match &self.body { - ZenohBody::Data(data) => data.congestion_control, - ZenohBody::Unit(unit) => unit.congestion_control, - ZenohBody::Declare(_) => zmsg::default_congestion_control::DECLARE, - ZenohBody::Pull(_) => zmsg::default_congestion_control::PULL, - ZenohBody::Query(_) => zmsg::default_congestion_control::QUERY, - ZenohBody::LinkStateList(_) => zmsg::default_congestion_control::LINK_STATE_LIST, - }; - - cc == CongestionControl::Drop - } -} - -impl fmt::Debug for ZenohMessage { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "{:?} {:?} {:?}", - self.body, self.channel, self.routing_context - )?; - #[cfg(feature = "stats")] - write!(f, " {:?}", self.size)?; - Ok(()) - } -} - -impl fmt::Display for ZenohMessage { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(self, f) - } -} - -impl ZenohMessage { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use crate::core::Priority; - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let routing_context = if rng.gen_bool(0.5) { - Some(RoutingContext::rand()) - } else { - None - }; - - let priority: Priority = rng - .gen_range(Priority::MAX as u8..=Priority::MIN as u8) - .try_into() - .unwrap(); - let reliability = Reliability::rand(); - let channel = Channel { - priority, - reliability, - }; - let body = match rng.gen_range(0..6) { - 0 => ZenohBody::Data(Data::rand()), - 1 => ZenohBody::Unit(Unit::rand()), - 2 => ZenohBody::Pull(Pull::rand()), - 3 => ZenohBody::Query(Query::rand()), - 4 => ZenohBody::Declare(Declare::rand()), - 5 => ZenohBody::LinkStateList(LinkStateList::rand()), - _ => unreachable!(), - }; - - Self { - body, - #[cfg(feature = "stats")] - size: None, - channel, - routing_context, - } - } -} diff --git a/commons/zenoh-protocol/src/zenoh/pull.rs b/commons/zenoh-protocol/src/zenoh/pull.rs deleted file mode 100644 index 837a809a25..0000000000 --- a/commons/zenoh-protocol/src/zenoh/pull.rs +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::core::WireExpr; - -/// The resolution of a PullId -pub type PullId = u32; - -/// # Pull message -/// -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|N|F| PULL | -/// +-+-+-+---------+ -/// ~ KeyExpr ~ if K==1 then key_expr has suffix -/// +---------------+ -/// ~ pullid ~ -/// +---------------+ -/// ~ max_samples ~ if N==1 -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Pull { - pub key: WireExpr<'static>, - pub pull_id: PullId, - pub max_samples: Option, - pub is_final: bool, -} - -impl Pull { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let key = WireExpr::rand(); - let pull_id: PullId = rng.gen(); - let max_samples = if rng.gen_bool(0.5) { - Some(rng.gen()) - } else { - None - }; - let is_final = rng.gen_bool(0.5); - - Self { - key, - pull_id, - max_samples, - is_final, - } - } -} diff --git a/commons/zenoh-protocol/src/zenoh/query.rs b/commons/zenoh-protocol/src/zenoh/query.rs deleted file mode 100644 index a173195605..0000000000 --- a/commons/zenoh-protocol/src/zenoh/query.rs +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use crate::{ - core::WireExpr, network::request::ext::TargetType, zenoh::DataInfo, - zenoh_new::query::ext::ConsolidationType, -}; -use alloc::string::String; -use core::sync::atomic::AtomicU32; -use zenoh_buffers::ZBuf; - -/// The resolution of a QueryId -pub type QueryId = u32; -pub type AtomicQueryId = AtomicU32; - -/// The kind of consolidation. -#[derive(Debug, Clone, PartialEq, Eq, Copy)] -pub enum ConsolidationMode { - /// No consolidation applied: multiple samples may be received for the same key-timestamp. - None, - /// Monotonic consolidation immediately forwards samples, except if one with an equal or more recent timestamp - /// has already been sent with the same key. - /// - /// This optimizes latency while potentially reducing bandwidth. - /// - /// Note that this doesn't cause re-ordering, but drops the samples for which a more recent timestamp has already - /// been observed with the same key. - Monotonic, - /// Holds back samples to only send the set of samples that had the highest timestamp for their key. - Latest, -} - -impl From for ConsolidationType { - fn from(val: ConsolidationMode) -> Self { - match val { - ConsolidationMode::None => ConsolidationType::None, - ConsolidationMode::Monotonic => ConsolidationType::Monotonic, - ConsolidationMode::Latest => ConsolidationType::Latest, - } - } -} - -/// The `zenoh::queryable::Queryable`s that should be target of a `zenoh::Session::get()`. -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] -pub enum QueryTarget { - #[default] - BestMatching, - All, - AllComplete, - #[cfg(feature = "complete_n")] - Complete(u64), -} - -impl From for TargetType { - fn from(val: QueryTarget) -> Self { - match val { - QueryTarget::BestMatching => TargetType::BestMatching, - QueryTarget::All => TargetType::All, - QueryTarget::AllComplete => TargetType::AllComplete, - #[cfg(feature = "complete_n")] - QueryTarget::Complete(n) => TargetType::Complete(n), - } - } -} - -/// # QueryBody -/// -/// QueryBody data structure is optionally included in Query messages -/// -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+---------+ -/// ~ DataInfo ~ -/// +---------------+ -/// ~ Payload ~ -/// +---------------+ -/// ``` -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct QueryBody { - pub data_info: DataInfo, - pub payload: ZBuf, -} - -impl QueryBody { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - const MIN: usize = 2; - const MAX: usize = 16; - - let mut rng = rand::thread_rng(); - - let data_info = DataInfo::rand(); - let payload = ZBuf::rand(rng.gen_range(MIN..MAX)); - - Self { data_info, payload } - } -} - -/// # Query message -/// -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |K|B|T| QUERY | -/// +-+-+-+---------+ -/// ~ KeyExpr ~ if K==1 then key_expr has suffix -/// +---------------+ -/// ~selector_params~ -/// +---------------+ -/// ~ qid ~ -/// +---------------+ -/// ~ target ~ if T==1 -/// +---------------+ -/// ~ consolidation ~ -/// +---------------+ -/// ~ QueryBody ~ if B==1 -/// +---------------+ -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Query { - pub key: WireExpr<'static>, - pub parameters: String, - pub qid: QueryId, - pub target: Option, - pub consolidation: ConsolidationMode, - pub body: Option, -} - -impl Query { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::{ - distributions::{Alphanumeric, DistString}, - seq::SliceRandom, - Rng, - }; - - const MIN: usize = 2; - const MAX: usize = 16; - - let mut rng = rand::thread_rng(); - - let key = WireExpr::rand(); - - let parameters = if rng.gen_bool(0.5) { - let len = rng.gen_range(MIN..MAX); - Alphanumeric.sample_string(&mut rng, len) - } else { - String::new() - }; - - let qid: QueryId = rng.gen(); - - let target = if rng.gen_bool(0.5) { - let t = [ - QueryTarget::All, - QueryTarget::AllComplete, - QueryTarget::BestMatching, - #[cfg(feature = "complete_n")] - QueryTarget::Complete(rng.gen()), - ]; - let t = t.choose(&mut rng).unwrap(); - Some(*t) - } else { - None - }; - let consolidation = *[ - ConsolidationMode::Latest, - ConsolidationMode::Monotonic, - ConsolidationMode::None, - ] - .choose(&mut rng) - .unwrap(); - - let body = if rng.gen_bool(0.5) { - Some(QueryBody::rand()) - } else { - None - }; - - Self { - key, - parameters, - qid, - target, - consolidation, - body, - } - } -} diff --git a/commons/zenoh-protocol/src/zenoh/routing.rs b/commons/zenoh-protocol/src/zenoh/routing.rs deleted file mode 100644 index ab0258b57f..0000000000 --- a/commons/zenoh-protocol/src/zenoh/routing.rs +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// - -/// -- RoutingContext decorator -/// -/// ```text -/// The **RoutingContext** is a message decorator containing -/// informations for routing the concerned message. -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |X|X|X| RT_CTX | -/// +-+-+-+---------+ -/// ~ tid ~ -/// +---------------+ -/// ``` -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct RoutingContext { - pub tree_id: u64, -} - -impl RoutingContext { - pub fn new(tree_id: u64) -> RoutingContext { - RoutingContext { tree_id } - } -} - -impl RoutingContext { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - Self { tree_id: rng.gen() } - } -} diff --git a/commons/zenoh-protocol/src/zenoh/unit.rs b/commons/zenoh-protocol/src/zenoh/unit.rs deleted file mode 100644 index 3f23baa2e6..0000000000 --- a/commons/zenoh-protocol/src/zenoh/unit.rs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use super::ReplyContext; -use crate::core::CongestionControl; - -/// # Unit message -/// -/// ```text -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |X|X|D| UNIT | -/// +-+-+-+---------+ -/// -/// ``` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Unit { - pub congestion_control: CongestionControl, - pub reply_context: Option, -} - -impl Unit { - #[cfg(feature = "test")] - pub fn rand() -> Self { - use rand::Rng; - - let mut rng = rand::thread_rng(); - - let congestion_control = if rng.gen_bool(0.5) { - CongestionControl::Block - } else { - CongestionControl::Drop - }; - let reply_context = if rng.gen_bool(0.5) { - Some(ReplyContext::rand()) - } else { - None - }; - Self { - congestion_control, - reply_context, - } - } -} diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh_new/query.rs index d50649ff41..4ffca9e73f 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh_new/query.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::common::ZExtUnknown; +use crate::{common::ZExtUnknown, core::ConsolidationMode}; use alloc::{string::String, vec::Vec}; /// The kind of consolidation. @@ -55,6 +55,16 @@ impl Consolidation { } } +impl From for Consolidation { + fn from(val: ConsolidationMode) -> Self { + match val { + ConsolidationMode::None => Consolidation::None, + ConsolidationMode::Monotonic => Consolidation::Monotonic, + ConsolidationMode::Latest => Consolidation::Latest, + } + } +} + /// # Query message /// /// ```text diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 0a16c61331..96f19c2a0f 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -24,7 +24,6 @@ use zenoh_protocol::{ transport::{ fragment::FragmentHeader, frame::FrameHeader, BatchSize, TransportMessage, TransportSn, }, - zenoh::ZenohMessage, }; const LENGTH_BYTES: [u8; 2] = u16::MIN.to_be_bytes(); @@ -294,80 +293,6 @@ impl Encode<(&NetworkMessage, FrameHeader)> for &mut WBatch { } } -impl Encode<&ZenohMessage> for &mut WBatch { - type Output = Result<(), WError>; - - /// Try to serialize a [`ZenohMessage`][ZenohMessage] on the [`SerializationBatch`][SerializationBatch]. - /// - /// # Arguments - /// * `message` - The [`ZenohMessage`][ZenohMessage] to serialize. - /// - fn encode(self, message: &ZenohMessage) -> Self::Output { - // Eventually update the current frame and sn based on the current status - if let (CurrentFrame::Reliable, false) - | (CurrentFrame::BestEffort, true) - | (CurrentFrame::None, _) = (self.current_frame, message.is_reliable()) - { - // We are not serializing on the right frame. - return Err(WError::NewFrame); - }; - - // Mark the write operation - let mut writer = self.buffer.writer(); - let mark = writer.mark(); - - let codec = Zenoh080::new(); - codec.write(&mut writer, message).map_err(|_| { - // Revert the write operation - writer.rewind(mark); - WError::DidntWrite - }) - } -} - -impl Encode<(&ZenohMessage, FrameHeader)> for &mut WBatch { - type Output = Result<(), DidntWrite>; - - /// Try to serialize a [`ZenohMessage`][ZenohMessage] on the [`SerializationBatch`][SerializationBatch]. - /// - /// # Arguments - /// * `message` - The [`ZenohMessage`][ZenohMessage] to serialize. - /// - fn encode(self, message: (&ZenohMessage, FrameHeader)) -> Self::Output { - let (message, frame) = message; - - // Mark the write operation - let mut writer = self.buffer.writer(); - let mark = writer.mark(); - - let codec = Zenoh080::new(); - // Write the frame header - codec.write(&mut writer, &frame).map_err(|e| { - // Revert the write operation - writer.rewind(mark); - e - })?; - // Write the zenoh message - codec.write(&mut writer, message).map_err(|e| { - // Revert the write operation - writer.rewind(mark); - e - })?; - // Update the frame - self.current_frame = match frame.reliability { - Reliability::Reliable => { - self.latest_sn.reliable = Some(frame.sn); - CurrentFrame::Reliable - } - Reliability::BestEffort => { - self.latest_sn.best_effort = Some(frame.sn); - CurrentFrame::BestEffort - } - }; - Ok(()) - } -} - impl Encode<(&mut ZBufReader<'_>, FragmentHeader)> for &mut WBatch { type Output = Result; @@ -420,12 +345,13 @@ mod tests { use super::*; use zenoh_buffers::ZBuf; use zenoh_protocol::{ - core::{Channel, CongestionControl, Priority, Reliability, WireExpr}, + core::{CongestionControl, Encoding, Priority, Reliability, WireExpr}, + network::{ext, Push}, transport::{ frame::{self, FrameHeader}, KeepAlive, TransportMessage, }, - zenoh::ZenohMessage, + zenoh_new::{PushBody, Put}, }; #[test] @@ -433,60 +359,59 @@ mod tests { let mut batch = WBatch::new(u16::MAX, true); let tmsg: TransportMessage = KeepAlive.into(); - let mut zmsg = ZenohMessage::make_data( - WireExpr::empty(), - ZBuf::from(vec![0u8; 8]), - Channel { - priority: Priority::default(), - reliability: Reliability::Reliable, - }, - CongestionControl::Block, - None, - None, - None, - ); + let nmsg: NetworkMessage = Push { + wire_expr: WireExpr::empty(), + ext_qos: ext::QoSType::new(Priority::default(), CongestionControl::Block, false), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + payload: PushBody::Put(Put { + timestamp: None, + encoding: Encoding::default(), + ext_sinfo: None, + #[cfg(feature = "shared-memory")] + ext_shm: None, + ext_unknown: vec![], + payload: ZBuf::from(vec![0u8; 8]), + }), + } + .into(); let mut tmsgs_in = vec![]; - let mut zmsgs_in = vec![]; + let mut nmsgs_in = vec![]; // Serialize assuming there is already a frame batch.clear(); - assert!(batch.encode(&zmsg).is_err()); + assert!(batch.encode(&nmsg).is_err()); assert_eq!(batch.len(), 0); let mut frame = FrameHeader { - reliability: zmsg.channel.reliability, + reliability: Reliability::Reliable, sn: 0, ext_qos: frame::ext::QoSType::default(), }; // Serialize with a frame - batch.encode((&zmsg, frame)).unwrap(); - assert_ne!(batch.len(), 0); - zmsgs_in.push(zmsg.clone()); - - // Change reliability - zmsg.channel.reliability = Reliability::BestEffort; - assert!(batch.encode(&zmsg).is_err()); + batch.encode((&nmsg, frame)).unwrap(); assert_ne!(batch.len(), 0); + nmsgs_in.push(nmsg.clone()); - frame.reliability = zmsg.channel.reliability; - batch.encode((&zmsg, frame)).unwrap(); + frame.reliability = Reliability::BestEffort; + batch.encode((&nmsg, frame)).unwrap(); assert_ne!(batch.len(), 0); - zmsgs_in.push(zmsg.clone()); + nmsgs_in.push(nmsg.clone()); // Transport batch.encode(&tmsg).unwrap(); tmsgs_in.push(tmsg.clone()); // Serialize assuming there is already a frame - assert!(batch.encode(&zmsg).is_err()); + assert!(batch.encode(&nmsg).is_err()); assert_ne!(batch.len(), 0); // Serialize with a frame frame.sn = 1; - batch.encode((&zmsg, frame)).unwrap(); + batch.encode((&nmsg, frame)).unwrap(); assert_ne!(batch.len(), 0); - zmsgs_in.push(zmsg.clone()); + nmsgs_in.push(nmsg.clone()); } } diff --git a/io/zenoh-transport/src/primitives/mux.rs b/io/zenoh-transport/src/primitives/mux.rs index 6bc5048a23..8783b8ff40 100644 --- a/io/zenoh-transport/src/primitives/mux.rs +++ b/io/zenoh-transport/src/primitives/mux.rs @@ -127,192 +127,4 @@ impl Primitives for McastMux { fn send_close(&self) { // self.handler.closing().await; } - - // fn decl_resource(&self, expr_id: ZInt, key_expr: &WireExpr) { - // let d = Declaration::Resource(Resource { - // expr_id, - // key: key_expr.to_owned(), - // }); - // let decls = vec![d]; - // let _ = self - // .handler - // .handle_message(ZenohMessage::make_declare(decls, None, None)); - // } - - // fn forget_resource(&self, expr_id: ZInt) { - // let d = Declaration::ForgetResource(ForgetResource { expr_id }); - // let decls = vec![d]; - // let _ = self - // .handler - // .handle_message(ZenohMessage::make_declare(decls, None, None)); - // } - - // fn decl_subscriber( - // &self, - // key_expr: &WireExpr, - // sub_info: &SubInfo, - // routing_context: Option, - // ) { - // let d = Declaration::Subscriber(Subscriber { - // key: key_expr.to_owned(), - // info: sub_info.clone(), - // }); - // let decls = vec![d]; - // let _ = - // self.handler - // .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); - // } - - // fn forget_subscriber(&self, key_expr: &WireExpr, routing_context: Option) { - // let d = Declaration::ForgetSubscriber(ForgetSubscriber { - // key: key_expr.to_owned(), - // }); - // let decls = vec![d]; - // let _ = - // self.handler - // .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); - // } - - // fn decl_publisher(&self, key_expr: &WireExpr, routing_context: Option) { - // let d = Declaration::Publisher(Publisher { - // key: key_expr.to_owned(), - // }); - // let decls = vec![d]; - // let _ = - // self.handler - // .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); - // } - - // fn forget_publisher(&self, key_expr: &WireExpr, routing_context: Option) { - // let d = Declaration::ForgetPublisher(ForgetPublisher { - // key: key_expr.to_owned(), - // }); - // let decls = vec![d]; - // let _ = - // self.handler - // .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); - // } - - // fn decl_queryable( - // &self, - // key_expr: &WireExpr, - // qabl_info: &QueryableInfo, - // routing_context: Option, - // ) { - // let d = Declaration::Queryable(Queryable { - // key: key_expr.to_owned(), - // info: qabl_info.clone(), - // }); - // let decls = vec![d]; - // let _ = - // self.handler - // .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); - // } - - // fn forget_queryable(&self, key_expr: &WireExpr, routing_context: Option) { - // let d = Declaration::ForgetQueryable(ForgetQueryable { - // key: key_expr.to_owned(), - // }); - // let decls = vec![d]; - // let _ = - // self.handler - // .handle_message(ZenohMessage::make_declare(decls, routing_context, None)); - // } - - // fn send_data( - // &self, - // key_expr: &WireExpr, - // payload: ZBuf, - // channel: Channel, - // cogestion_control: CongestionControl, - // data_info: Option, - // routing_context: Option, - // ) { - // let _ = self.handler.handle_message(ZenohMessage::make_data( - // key_expr.to_owned(), - // payload, - // channel, - // cogestion_control, - // data_info, - // routing_context, - // None, - // None, - // )); - // } - - // fn send_query( - // &self, - // key_expr: &WireExpr, - // parameters: &str, - // qid: ZInt, - // target: QueryTarget, - // consolidation: ConsolidationMode, - // body: Option, - // routing_context: Option, - // ) { - // let target_opt = if target == QueryTarget::default() { - // None - // } else { - // Some(target) - // }; - // let _ = self.handler.handle_message(ZenohMessage::make_query( - // key_expr.to_owned(), - // parameters.to_owned(), - // qid, - // target_opt, - // consolidation, - // body, - // routing_context, - // None, - // )); - // } - - // fn send_reply_data( - // &self, - // qid: ZInt, - // replier_id: ZenohId, - // key_expr: WireExpr, - // data_info: Option, - // payload: ZBuf, - // ) { - // let _ = self.handler.handle_message(ZenohMessage::make_data( - // key_expr.to_owned(), - // payload, - // zmsg::default_channel::REPLY, - // zmsg::default_congestion_control::REPLY, - // data_info, - // None, - // Some(ReplyContext::new(qid, Some(ReplierInfo { id: replier_id }))), - // None, - // )); - // } - - // fn send_reply_final(&self, qid: ZInt) { - // let _ = self.handler.handle_message(ZenohMessage::make_unit( - // zmsg::default_channel::REPLY, - // zmsg::default_congestion_control::REPLY, - // Some(ReplyContext::new(qid, None)), - // None, - // )); - // } - - // fn send_pull( - // &self, - // is_final: bool, - // key_expr: &WireExpr, - // pull_id: ZInt, - // max_samples: &Option, - // ) { - // let _ = self.handler.handle_message(ZenohMessage::make_pull( - // is_final, - // key_expr.to_owned(), - // pull_id, - // *max_samples, - // None, - // )); - // } - - // fn send_close(&self) { - // // self.handler.closing().await; - // } } diff --git a/plugins/zenoh-plugin-storage-manager/src/replica/storage.rs b/plugins/zenoh-plugin-storage-manager/src/replica/storage.rs index bd43b131f0..f486f25f3c 100644 --- a/plugins/zenoh-plugin-storage-manager/src/replica/storage.rs +++ b/plugins/zenoh-plugin-storage-manager/src/replica/storage.rs @@ -23,6 +23,7 @@ use std::str::{self, FromStr}; use std::time::{SystemTime, UNIX_EPOCH}; use zenoh::buffers::ZBuf; use zenoh::prelude::r#async::*; +use zenoh::query::ConsolidationMode; use zenoh::time::{Timestamp, NTP64}; use zenoh::{Result as ZResult, Session}; use zenoh_backend_traits::config::{GarbageCollectionConfig, StorageConfig}; diff --git a/zenoh/src/admin.rs b/zenoh/src/admin.rs index a39cc79f45..56772797ce 100644 --- a/zenoh/src/admin.rs +++ b/zenoh/src/admin.rs @@ -13,8 +13,9 @@ // use crate::{ keyexpr, - prelude::sync::{KeyExpr, Locality}, + prelude::sync::{KeyExpr, Locality, SampleKind}, queryable::Query, + sample::DataInfo, Sample, Session, ZResult, }; use async_std::task; @@ -27,7 +28,6 @@ use zenoh_core::SyncResolve; use zenoh_protocol::{ core::{Encoding, KnownEncoding, WireExpr}, network::NetworkMessage, - zenoh::{DataInfo, SampleKind}, }; use zenoh_transport::{ TransportEventHandler, TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index 456f348a94..bb6aaabdb4 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -13,7 +13,9 @@ // use super::face::FaceState; use super::network::Network; -use super::resource::{DataRoutes, Direction, PullCaches, Resource, Route, SessionContext}; +use super::resource::{ + DataRoutes, Direction, PullCaches, Resource, Route, RoutingContext, SessionContext, +}; use super::router::{RoutingExpr, Tables, TablesLock}; use petgraph::graph::NodeIndex; use std::borrow::Cow; @@ -34,7 +36,6 @@ use zenoh_protocol::{ }, Push, }, - zenoh::RoutingContext, zenoh_new::PushBody, }; use zenoh_sync::get_mut_unchecked; @@ -62,7 +63,7 @@ fn send_sourced_subscription_to_net_childs( ext_qos: ext::QoSType::default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { - node_id: routing_context.map(|c| c.tree_id).unwrap_or(0) as u16, + node_id: routing_context.unwrap_or(0), }, body: DeclareBody::DeclareSubscriber(DeclareSubscriber { id: 0, // TODO @@ -168,7 +169,7 @@ fn propagate_sourced_subscription( res, src_face, sub_info, - Some(RoutingContext::new(tree_sid.index() as u64)), + Some(tree_sid.index() as u16), ); } else { log::trace!( @@ -568,7 +569,7 @@ fn send_forget_sourced_subscription_to_net_childs( ext_qos: ext::QoSType::default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { - node_id: routing_context.map(|c| c.tree_id).unwrap_or(0) as u16, + node_id: routing_context.unwrap_or(0), }, body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { id: 0, // TODO @@ -656,7 +657,7 @@ fn propagate_forget_sourced_subscription( &net.trees[tree_sid.index()].childs, res, src_face, - Some(RoutingContext::new(tree_sid.index() as u64)), + Some(tree_sid.index() as u16), ); } else { log::trace!( @@ -1109,7 +1110,7 @@ pub(crate) fn pubsub_tree_change( res, None, &sub_info, - Some(RoutingContext::new(tree_sid as u64)), + Some(tree_sid as u16), ); } } @@ -1223,7 +1224,7 @@ fn insert_faces_for_subs( face.clone(), key_expr.to_owned(), if source != 0 { - Some(RoutingContext::new(source as u64)) + Some(source as u16) } else { None }, @@ -1792,7 +1793,7 @@ pub fn full_reentrant_route_data( ext_qos, ext_tstamp: None, ext_nodeid: ext::NodeIdType { - node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, + node_id: context.unwrap_or(0), }, payload, }) @@ -1827,7 +1828,7 @@ pub fn full_reentrant_route_data( ext_qos: ext::QoSType::default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { - node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, + node_id: context.unwrap_or(0), }, payload: payload.clone(), }) @@ -1856,7 +1857,7 @@ pub fn full_reentrant_route_data( ext_qos: ext::QoSType::default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { - node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, + node_id: context.unwrap_or(0), }, payload: payload.clone(), }) diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index ddf813bd82..d968364a60 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -14,7 +14,8 @@ use super::face::FaceState; use super::network::Network; use super::resource::{ - QueryRoute, QueryRoutes, QueryTargetQabl, QueryTargetQablSet, Resource, SessionContext, + QueryRoute, QueryRoutes, QueryTargetQabl, QueryTargetQablSet, Resource, RoutingContext, + SessionContext, }; use super::router::{RoutingExpr, Tables, TablesLock}; use async_trait::async_trait; @@ -41,7 +42,6 @@ use zenoh_protocol::{ request::{ext::TargetType, Request, RequestId}, response::{self, ext::ResponderIdType, Response, ResponseFinal}, }, - zenoh::{QueryId, RoutingContext}, zenoh_new::{reply::ext::ConsolidationType, Reply, RequestBody, ResponseBody}, }; use zenoh_sync::get_mut_unchecked; @@ -49,7 +49,7 @@ use zenoh_util::Timed; pub(crate) struct Query { src_face: Arc, - src_qid: QueryId, + src_qid: RequestId, } #[cfg(feature = "complete_n")] @@ -222,7 +222,7 @@ fn send_sourced_queryable_to_net_childs( ext_qos: ext::QoSType::default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { - node_id: routing_context.map(|c| c.tree_id).unwrap_or(0) as u16, + node_id: routing_context.unwrap_or(0), }, body: DeclareBody::DeclareQueryable(DeclareQueryable { id: 0, // TODO @@ -318,7 +318,7 @@ fn propagate_sourced_queryable( res, qabl_info, src_face, - Some(RoutingContext::new(tree_sid.index() as u64)), + Some(tree_sid.index() as u16), ); } else { log::trace!( @@ -700,7 +700,7 @@ fn send_forget_sourced_queryable_to_net_childs( ext_qos: ext::QoSType::default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { - node_id: routing_context.map(|c| c.tree_id).unwrap_or(0) as u16, + node_id: routing_context.unwrap_or(0), }, body: DeclareBody::UndeclareQueryable(UndeclareQueryable { id: 0, // TODO @@ -789,7 +789,7 @@ fn propagate_forget_sourced_queryable( &net.trees[tree_sid.index()].childs, res, src_face, - Some(RoutingContext::new(tree_sid.index() as u64)), + Some(tree_sid.index() as u16), ); } else { log::trace!( @@ -1321,7 +1321,7 @@ pub(crate) fn queries_tree_change( res, qabl_info, None, - Some(RoutingContext::new(tree_sid as u64)), + Some(tree_sid as u16), ); } } @@ -1359,7 +1359,7 @@ fn insert_target_for_qabls( face.clone(), key_expr.to_owned(), if source != 0 { - Some(RoutingContext::new(source as u64)) + Some(source as u16) } else { None }, @@ -2211,7 +2211,7 @@ pub fn route_query( ext_qos: ext::QoSType::default(), // TODO ext_tstamp: None, ext_nodeid: ext::NodeIdType { - node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, + node_id: context.unwrap_or(0), }, ext_target: target, ext_budget: None, @@ -2250,7 +2250,7 @@ pub fn route_query( pub(crate) fn route_send_response( tables_ref: &Arc, face: &mut Arc, - qid: QueryId, + qid: RequestId, ext_respid: Option, key_expr: WireExpr, body: ResponseBody, @@ -2297,7 +2297,7 @@ pub(crate) fn route_send_response( pub(crate) fn route_send_response_final( tables_ref: &Arc, face: &mut Arc, - qid: QueryId, + qid: RequestId, ) { let queries_lock = zwrite!(tables_ref.queries_lock); match get_mut_unchecked(face).pending_queries.remove(&qid) { diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index 38898a35b5..76d52908c8 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -19,6 +19,7 @@ use std::hash::{Hash, Hasher}; use std::sync::{Arc, Weak}; #[cfg(feature = "complete_n")] use zenoh_protocol::network::request::ext::TargetType; +use zenoh_protocol::network::RequestId; use zenoh_protocol::zenoh_new::PushBody; use zenoh_protocol::{ core::{key_expr::keyexpr, ExprId, WireExpr, ZenohId}, @@ -29,16 +30,17 @@ use zenoh_protocol::{ }, Mapping, }, - zenoh::{QueryId, RoutingContext}, }; use zenoh_sync::get_mut_unchecked; +pub(super) type RoutingContext = u16; + pub(super) type Direction = (Arc, WireExpr<'static>, Option); pub(super) type Route = HashMap; #[cfg(feature = "complete_n")] -pub(super) type QueryRoute = HashMap; +pub(super) type QueryRoute = HashMap; #[cfg(not(feature = "complete_n"))] -pub(super) type QueryRoute = HashMap; +pub(super) type QueryRoute = HashMap; pub(super) struct QueryTargetQabl { pub(super) direction: Direction, pub(super) complete: u64, diff --git a/zenoh/src/prelude.rs b/zenoh/src/prelude.rs index 68d9523ace..380098900a 100644 --- a/zenoh/src/prelude.rs +++ b/zenoh/src/prelude.rs @@ -47,7 +47,7 @@ pub(crate) mod common { pub(crate) use crate::sample::Locality; pub use crate::sample::Sample; - pub use zenoh_protocol::zenoh::{ConsolidationMode, SampleKind}; + pub use zenoh_protocol::core::SampleKind; pub use crate::publication::Priority; pub use zenoh_protocol::core::{CongestionControl, Reliability, WhatAmI}; diff --git a/zenoh/src/publication.rs b/zenoh/src/publication.rs index 226528d50c..bfc1287ee1 100644 --- a/zenoh/src/publication.rs +++ b/zenoh/src/publication.rs @@ -16,6 +16,7 @@ use crate::net::transport::Primitives; use crate::prelude::*; +use crate::sample::DataInfo; use crate::Encoding; use crate::SessionRef; use crate::Undeclarable; @@ -24,7 +25,6 @@ use zenoh_core::{zread, AsyncResolve, Resolvable, Resolve, SyncResolve}; use zenoh_protocol::network::push::ext; use zenoh_protocol::network::Mapping; use zenoh_protocol::network::Push; -use zenoh_protocol::zenoh::DataInfo; use zenoh_protocol::zenoh_new::Del; use zenoh_protocol::zenoh_new::PushBody; use zenoh_protocol::zenoh_new::Put; diff --git a/zenoh/src/query.rs b/zenoh/src/query.rs index 309fad1795..c55822bac6 100644 --- a/zenoh/src/query.rs +++ b/zenoh/src/query.rs @@ -24,10 +24,10 @@ use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; use zenoh_result::ZResult; /// The [`Queryable`](crate::queryable::Queryable)s that should be target of a [`get`](Session::get). -pub use zenoh_protocol::zenoh::QueryTarget; +pub use zenoh_protocol::core::QueryTarget; /// The kind of consolidation. -pub use zenoh_protocol::zenoh::ConsolidationMode; +pub use zenoh_protocol::core::ConsolidationMode; /// The operation: either manual or automatic. #[derive(Clone, Copy, Debug, PartialEq, Eq)] diff --git a/zenoh/src/queryable.rs b/zenoh/src/queryable.rs index 06e52e6e4a..8b80803b42 100644 --- a/zenoh/src/queryable.rs +++ b/zenoh/src/queryable.rs @@ -26,10 +26,10 @@ use std::future::Ready; use std::ops::Deref; use std::sync::Arc; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; -use zenoh_protocol::network::{response, Mapping, Response, ResponseFinal}; +use zenoh_protocol::core::WireExpr; +use zenoh_protocol::network::{response, Mapping, RequestId, Response, ResponseFinal}; use zenoh_protocol::zenoh_new::reply::ext::ConsolidationType; use zenoh_protocol::zenoh_new::{self, ResponseBody}; -use zenoh_protocol::{core::WireExpr, zenoh::QueryId}; use zenoh_result::ZResult; use zenoh_transport::Primitives; @@ -41,7 +41,7 @@ pub(crate) struct QueryInner { /// This Query's body. pub(crate) value: Option, - pub(crate) qid: QueryId, + pub(crate) qid: RequestId, pub(crate) zid: ZenohId, pub(crate) primitives: Arc, } diff --git a/zenoh/src/sample.rs b/zenoh/src/sample.rs index a0c84f646a..6d12d5a819 100644 --- a/zenoh/src/sample.rs +++ b/zenoh/src/sample.rs @@ -22,7 +22,9 @@ use crate::time::{new_reception_timestamp, Timestamp}; #[zenoh_macros::unstable] use serde::Serialize; use std::convert::{TryFrom, TryInto}; -use zenoh_protocol::zenoh::{DataInfo, SourceSn}; +use zenoh_protocol::core::Encoding; + +pub type SourceSn = u64; /// The locality of samples to be received by subscribers or targeted by publishers. #[zenoh_macros::unstable] @@ -42,6 +44,15 @@ pub(crate) enum Locality { Any, } +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub(crate) struct DataInfo { + pub kind: SampleKind, + pub encoding: Option, + pub timestamp: Option, + pub source_id: Option, + pub source_sn: Option, +} + /// Informations on the source of a zenoh [`Sample`]. #[zenoh_macros::unstable] #[derive(Debug, Clone)] diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 6986f51316..c3b0ef9af4 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -28,6 +28,7 @@ use crate::prelude::{KeyExpr, Parameters}; use crate::publication::*; use crate::query::*; use crate::queryable::*; +use crate::sample::DataInfo; use crate::selector::TIME_RANGE_KEY; use crate::subscriber::*; use crate::Id; @@ -52,6 +53,8 @@ use zenoh_buffers::ZBuf; use zenoh_collections::SingleOrVec; use zenoh_config::unwrap_or_default; use zenoh_core::{zconfigurable, zread, Resolve, ResolveClosure, ResolveFuture, SyncResolve}; +use zenoh_protocol::network::AtomicRequestId; +use zenoh_protocol::network::RequestId; use zenoh_protocol::{ core::{ key_expr::{keyexpr, OwnedKeyExpr}, @@ -67,7 +70,6 @@ use zenoh_protocol::{ request::{self, ext::TargetType, Request}, Mapping, Push, Response, ResponseFinal, }, - zenoh::{AtomicQueryId, DataInfo, QueryId, QueryTarget}, zenoh_new::{ query::{ self, @@ -90,7 +92,7 @@ zconfigurable! { pub(crate) struct SessionState { pub(crate) primitives: Option>, // @TODO replace with MaybeUninit ?? pub(crate) expr_id_counter: AtomicExprId, // @TODO: manage rollover and uniqueness - pub(crate) qid_counter: AtomicQueryId, + pub(crate) qid_counter: AtomicRequestId, pub(crate) decl_id_counter: AtomicUsize, pub(crate) local_resources: HashMap, pub(crate) remote_resources: HashMap, @@ -99,7 +101,7 @@ pub(crate) struct SessionState { pub(crate) queryables: HashMap>, #[cfg(feature = "unstable")] pub(crate) tokens: HashMap>, - pub(crate) queries: HashMap, + pub(crate) queries: HashMap, pub(crate) aggregated_subscribers: Vec, //pub(crate) aggregated_publishers: Vec, } @@ -112,7 +114,7 @@ impl SessionState { SessionState { primitives: None, expr_id_counter: AtomicExprId::new(1), // Note: start at 1 because 0 is reserved for NO_RESOURCE - qid_counter: AtomicQueryId::new(0), + qid_counter: AtomicRequestId::new(0), decl_id_counter: AtomicUsize::new(0), local_resources: HashMap::new(), remote_resources: HashMap::new(), @@ -1640,7 +1642,7 @@ impl Session { ext_qos: request::ext::QoSType::default(), ext_tstamp: None, ext_nodeid: request::ext::NodeIdType::default(), - ext_target: target.into(), + ext_target: target, ext_budget: None, ext_timeout: Some(timeout), payload: RequestBody::Query(zenoh_protocol::zenoh_new::Query { @@ -1663,7 +1665,7 @@ impl Session { &wexpr, selector.parameters(), qid, - target.into(), + target, consolidation.into(), value.as_ref().map(|v| query::ext::QueryBodyType { #[cfg(feature = "shared-memory")] @@ -1682,7 +1684,7 @@ impl Session { local: bool, key_expr: &WireExpr, parameters: &str, - qid: QueryId, + qid: RequestId, _target: TargetType, _consolidation: ConsolidationType, body: Option, diff --git a/zenoh/src/subscriber.rs b/zenoh/src/subscriber.rs index 20c872488d..a8a7914f82 100644 --- a/zenoh/src/subscriber.rs +++ b/zenoh/src/subscriber.rs @@ -26,7 +26,7 @@ use zenoh_core::{AsyncResolve, Resolvable, Resolve, SyncResolve}; use zenoh_protocol::network::declare::{subscriber::ext::SubscriberInfo, Mode}; /// The subscription mode. -pub use zenoh_protocol::zenoh::SubMode; +pub use zenoh_protocol::core::SubMode; /// The kind of reliability. pub use zenoh_protocol::core::Reliability; From 6d37e6cde06182b6d2b2ae6648e33ac002f357ab Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Thu, 7 Sep 2023 17:37:54 +0200 Subject: [PATCH 198/203] Rename zenoh_new to zenoh --- commons/zenoh-codec/benches/codec.rs | 2 +- commons/zenoh-codec/src/lib.rs | 2 +- commons/zenoh-codec/src/network/push.rs | 2 +- commons/zenoh-codec/src/network/request.rs | 2 +- commons/zenoh-codec/src/network/response.rs | 2 +- .../zenoh-codec/src/{zenoh_new => zenoh}/ack.rs | 2 +- .../zenoh-codec/src/{zenoh_new => zenoh}/del.rs | 2 +- .../zenoh-codec/src/{zenoh_new => zenoh}/err.rs | 2 +- .../zenoh-codec/src/{zenoh_new => zenoh}/mod.rs | 2 +- .../zenoh-codec/src/{zenoh_new => zenoh}/pull.rs | 2 +- .../zenoh-codec/src/{zenoh_new => zenoh}/put.rs | 2 +- .../src/{zenoh_new => zenoh}/query.rs | 2 +- .../src/{zenoh_new => zenoh}/reply.rs | 2 +- commons/zenoh-codec/tests/codec.rs | 16 ++++++++-------- commons/zenoh-protocol/src/lib.rs | 2 +- commons/zenoh-protocol/src/network/push.rs | 2 +- commons/zenoh-protocol/src/network/request.rs | 2 +- commons/zenoh-protocol/src/network/response.rs | 2 +- .../src/{zenoh_new => zenoh}/ack.rs | 2 +- .../src/{zenoh_new => zenoh}/del.rs | 2 +- .../src/{zenoh_new => zenoh}/err.rs | 4 ++-- .../src/{zenoh_new => zenoh}/mod.rs | 0 .../src/{zenoh_new => zenoh}/pull.rs | 0 .../src/{zenoh_new => zenoh}/put.rs | 4 ++-- .../src/{zenoh_new => zenoh}/query.rs | 7 +++---- .../src/{zenoh_new => zenoh}/reply.rs | 8 ++++---- io/zenoh-transport/src/common/batch.rs | 2 +- io/zenoh-transport/src/common/pipeline.rs | 2 +- io/zenoh-transport/src/shm.rs | 2 +- io/zenoh-transport/tests/multicast_transport.rs | 2 +- io/zenoh-transport/tests/unicast_concurrent.rs | 2 +- .../tests/unicast_defragmentation.rs | 2 +- io/zenoh-transport/tests/unicast_intermittent.rs | 2 +- io/zenoh-transport/tests/unicast_priorities.rs | 2 +- io/zenoh-transport/tests/unicast_shm.rs | 2 +- io/zenoh-transport/tests/unicast_simultaneous.rs | 2 +- io/zenoh-transport/tests/unicast_transport.rs | 2 +- zenoh/src/net/routing/face.rs | 2 +- zenoh/src/net/routing/pubsub.rs | 2 +- zenoh/src/net/routing/queries.rs | 2 +- zenoh/src/net/routing/resource.rs | 2 +- zenoh/src/net/runtime/adminspace.rs | 2 +- zenoh/src/net/tests/tables.rs | 2 +- zenoh/src/publication.rs | 6 +++--- zenoh/src/queryable.rs | 8 ++++---- zenoh/src/session.rs | 4 ++-- 46 files changed, 64 insertions(+), 65 deletions(-) rename commons/zenoh-codec/src/{zenoh_new => zenoh}/ack.rs (99%) rename commons/zenoh-codec/src/{zenoh_new => zenoh}/del.rs (99%) rename commons/zenoh-codec/src/{zenoh_new => zenoh}/err.rs (99%) rename commons/zenoh-codec/src/{zenoh_new => zenoh}/mod.rs (99%) rename commons/zenoh-codec/src/{zenoh_new => zenoh}/pull.rs (99%) rename commons/zenoh-codec/src/{zenoh_new => zenoh}/put.rs (99%) rename commons/zenoh-codec/src/{zenoh_new => zenoh}/query.rs (99%) rename commons/zenoh-codec/src/{zenoh_new => zenoh}/reply.rs (99%) rename commons/zenoh-protocol/src/{zenoh_new => zenoh}/ack.rs (96%) rename commons/zenoh-protocol/src/{zenoh_new => zenoh}/del.rs (96%) rename commons/zenoh-protocol/src/{zenoh_new => zenoh}/err.rs (94%) rename commons/zenoh-protocol/src/{zenoh_new => zenoh}/mod.rs (100%) rename commons/zenoh-protocol/src/{zenoh_new => zenoh}/pull.rs (100%) rename commons/zenoh-protocol/src/{zenoh_new => zenoh}/put.rs (95%) rename commons/zenoh-protocol/src/{zenoh_new => zenoh}/query.rs (94%) rename commons/zenoh-protocol/src/{zenoh_new => zenoh}/reply.rs (92%) diff --git a/commons/zenoh-codec/benches/codec.rs b/commons/zenoh-codec/benches/codec.rs index 7db9449f42..2c786a41db 100644 --- a/commons/zenoh-codec/benches/codec.rs +++ b/commons/zenoh-codec/benches/codec.rs @@ -27,7 +27,7 @@ use zenoh_protocol::{ core::{Encoding, Reliability, WireExpr}, network::{ext, Push}, transport::{BatchSize, Frame, FrameHeader, TransportSn}, - zenoh_new::{PushBody, Put}, + zenoh::{PushBody, Put}, }; fn criterion_benchmark(c: &mut Criterion) { diff --git a/commons/zenoh-codec/src/lib.rs b/commons/zenoh-codec/src/lib.rs index d604acaaf0..14b41f6b0b 100644 --- a/commons/zenoh-codec/src/lib.rs +++ b/commons/zenoh-codec/src/lib.rs @@ -25,7 +25,7 @@ pub mod core; pub mod network; pub mod scouting; pub mod transport; -pub mod zenoh_new; +pub mod zenoh; use ::core::marker::PhantomData; use zenoh_protocol::core::Reliability; diff --git a/commons/zenoh-codec/src/network/push.rs b/commons/zenoh-codec/src/network/push.rs index 821be49899..f6d4ee7f0c 100644 --- a/commons/zenoh-codec/src/network/push.rs +++ b/commons/zenoh-codec/src/network/push.rs @@ -24,7 +24,7 @@ use zenoh_protocol::{ push::{ext, flag}, Mapping, Push, }, - zenoh_new::PushBody, + zenoh::PushBody, }; impl WCodec<&Push, &mut W> for Zenoh080 diff --git a/commons/zenoh-codec/src/network/request.rs b/commons/zenoh-codec/src/network/request.rs index 841ca1bbd6..088c9e79f8 100644 --- a/commons/zenoh-codec/src/network/request.rs +++ b/commons/zenoh-codec/src/network/request.rs @@ -26,7 +26,7 @@ use zenoh_protocol::{ request::{ext, flag}, Mapping, Request, RequestId, }, - zenoh_new::RequestBody, + zenoh::RequestBody, }; // Target diff --git a/commons/zenoh-codec/src/network/response.rs b/commons/zenoh-codec/src/network/response.rs index 5959294aac..59d97fefda 100644 --- a/commons/zenoh-codec/src/network/response.rs +++ b/commons/zenoh-codec/src/network/response.rs @@ -26,7 +26,7 @@ use zenoh_protocol::{ response::{ext, flag}, Mapping, RequestId, Response, ResponseFinal, }, - zenoh_new::ResponseBody, + zenoh::ResponseBody, }; // Response diff --git a/commons/zenoh-codec/src/zenoh_new/ack.rs b/commons/zenoh-codec/src/zenoh/ack.rs similarity index 99% rename from commons/zenoh-codec/src/zenoh_new/ack.rs rename to commons/zenoh-codec/src/zenoh/ack.rs index 03f57fef2c..0b940eb877 100644 --- a/commons/zenoh-codec/src/zenoh_new/ack.rs +++ b/commons/zenoh-codec/src/zenoh/ack.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{iext, imsg}, - zenoh_new::{ + zenoh::{ ack::{ext, flag, Ack}, id, }, diff --git a/commons/zenoh-codec/src/zenoh_new/del.rs b/commons/zenoh-codec/src/zenoh/del.rs similarity index 99% rename from commons/zenoh-codec/src/zenoh_new/del.rs rename to commons/zenoh-codec/src/zenoh/del.rs index f1746a31e8..cdd5c332d8 100644 --- a/commons/zenoh-codec/src/zenoh_new/del.rs +++ b/commons/zenoh-codec/src/zenoh/del.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{iext, imsg}, - zenoh_new::{ + zenoh::{ del::{ext, flag, Del}, id, }, diff --git a/commons/zenoh-codec/src/zenoh_new/err.rs b/commons/zenoh-codec/src/zenoh/err.rs similarity index 99% rename from commons/zenoh-codec/src/zenoh_new/err.rs rename to commons/zenoh-codec/src/zenoh/err.rs index fefb055654..425044402c 100644 --- a/commons/zenoh-codec/src/zenoh_new/err.rs +++ b/commons/zenoh-codec/src/zenoh/err.rs @@ -19,7 +19,7 @@ use zenoh_buffers::{ }; use zenoh_protocol::{ common::{iext, imsg}, - zenoh_new::{ + zenoh::{ err::{ext, flag, Err}, id, }, diff --git a/commons/zenoh-codec/src/zenoh_new/mod.rs b/commons/zenoh-codec/src/zenoh/mod.rs similarity index 99% rename from commons/zenoh-codec/src/zenoh_new/mod.rs rename to commons/zenoh-codec/src/zenoh/mod.rs index a5878a2425..dea0b7c495 100644 --- a/commons/zenoh-codec/src/zenoh_new/mod.rs +++ b/commons/zenoh-codec/src/zenoh/mod.rs @@ -34,7 +34,7 @@ use zenoh_protocol::common::{iext, ZExtUnit}; use zenoh_protocol::{ common::{imsg, ZExtZBufHeader}, core::{Encoding, ZenohId}, - zenoh_new::{ext, id, PushBody, RequestBody, ResponseBody}, + zenoh::{ext, id, PushBody, RequestBody, ResponseBody}, }; // Push diff --git a/commons/zenoh-codec/src/zenoh_new/pull.rs b/commons/zenoh-codec/src/zenoh/pull.rs similarity index 99% rename from commons/zenoh-codec/src/zenoh_new/pull.rs rename to commons/zenoh-codec/src/zenoh/pull.rs index 49e91039eb..2b2a3a61e0 100644 --- a/commons/zenoh-codec/src/zenoh_new/pull.rs +++ b/commons/zenoh-codec/src/zenoh/pull.rs @@ -20,7 +20,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::imsg, - zenoh_new::{ + zenoh::{ id, pull::{flag, Pull}, }, diff --git a/commons/zenoh-codec/src/zenoh_new/put.rs b/commons/zenoh-codec/src/zenoh/put.rs similarity index 99% rename from commons/zenoh-codec/src/zenoh_new/put.rs rename to commons/zenoh-codec/src/zenoh/put.rs index d9fcf2d352..6358a533a1 100644 --- a/commons/zenoh-codec/src/zenoh_new/put.rs +++ b/commons/zenoh-codec/src/zenoh/put.rs @@ -25,7 +25,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::{iext, imsg}, core::Encoding, - zenoh_new::{ + zenoh::{ id, put::{ext, flag, Put}, }, diff --git a/commons/zenoh-codec/src/zenoh_new/query.rs b/commons/zenoh-codec/src/zenoh/query.rs similarity index 99% rename from commons/zenoh-codec/src/zenoh_new/query.rs rename to commons/zenoh-codec/src/zenoh/query.rs index dbff4d3e1a..0844e16df4 100644 --- a/commons/zenoh-codec/src/zenoh_new/query.rs +++ b/commons/zenoh-codec/src/zenoh/query.rs @@ -20,7 +20,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::{iext, imsg}, - zenoh_new::{ + zenoh::{ id, query::{ext, flag, Query}, }, diff --git a/commons/zenoh-codec/src/zenoh_new/reply.rs b/commons/zenoh-codec/src/zenoh/reply.rs similarity index 99% rename from commons/zenoh-codec/src/zenoh_new/reply.rs rename to commons/zenoh-codec/src/zenoh/reply.rs index 62de9d7343..1aef954220 100644 --- a/commons/zenoh-codec/src/zenoh_new/reply.rs +++ b/commons/zenoh-codec/src/zenoh/reply.rs @@ -25,7 +25,7 @@ use zenoh_buffers::{ use zenoh_protocol::{ common::{iext, imsg}, core::Encoding, - zenoh_new::{ + zenoh::{ id, reply::{ext, flag, Reply}, }, diff --git a/commons/zenoh-codec/tests/codec.rs b/commons/zenoh-codec/tests/codec.rs index 588df01f1e..3fdb95e1b5 100644 --- a/commons/zenoh-codec/tests/codec.rs +++ b/commons/zenoh-codec/tests/codec.rs @@ -28,7 +28,7 @@ use zenoh_protocol::{ network::{self, *}, scouting::*, transport::{self, *}, - zenoh_new, zextunit, zextz64, zextzbuf, + zenoh, zextunit, zextz64, zextzbuf, }; const NUM_ITER: usize = 100; @@ -559,35 +559,35 @@ fn codec_network() { // Zenoh new #[test] fn codec_put() { - run!(zenoh_new::Put, zenoh_new::Put::rand()); + run!(zenoh::Put, zenoh::Put::rand()); } #[test] fn codec_del() { - run!(zenoh_new::Del, zenoh_new::Del::rand()); + run!(zenoh::Del, zenoh::Del::rand()); } #[test] fn codec_query() { - run!(zenoh_new::Query, zenoh_new::Query::rand()); + run!(zenoh::Query, zenoh::Query::rand()); } #[test] fn codec_reply() { - run!(zenoh_new::Reply, zenoh_new::Reply::rand()); + run!(zenoh::Reply, zenoh::Reply::rand()); } #[test] fn codec_err() { - run!(zenoh_new::Err, zenoh_new::Err::rand()); + run!(zenoh::Err, zenoh::Err::rand()); } #[test] fn codec_ack() { - run!(zenoh_new::Ack, zenoh_new::Ack::rand()); + run!(zenoh::Ack, zenoh::Ack::rand()); } #[test] fn codec_pull() { - run!(zenoh_new::Pull, zenoh_new::Pull::rand()); + run!(zenoh::Pull, zenoh::Pull::rand()); } diff --git a/commons/zenoh-protocol/src/lib.rs b/commons/zenoh-protocol/src/lib.rs index 30530335ec..a18aeb766f 100644 --- a/commons/zenoh-protocol/src/lib.rs +++ b/commons/zenoh-protocol/src/lib.rs @@ -25,7 +25,7 @@ pub mod core; pub mod network; pub mod scouting; pub mod transport; -pub mod zenoh_new; +pub mod zenoh; // Zenoh version pub const VERSION: u8 = 0x08; diff --git a/commons/zenoh-protocol/src/network/push.rs b/commons/zenoh-protocol/src/network/push.rs index 19f790f7d5..98a773b147 100644 --- a/commons/zenoh-protocol/src/network/push.rs +++ b/commons/zenoh-protocol/src/network/push.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, zenoh_new::PushBody}; +use crate::{core::WireExpr, zenoh::PushBody}; pub mod flag { pub const N: u8 = 1 << 5; // 0x20 Named if N==1 then the key expr has name/suffix diff --git a/commons/zenoh-protocol/src/network/request.rs b/commons/zenoh-protocol/src/network/request.rs index 5e005d585e..17bab1905d 100644 --- a/commons/zenoh-protocol/src/network/request.rs +++ b/commons/zenoh-protocol/src/network/request.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, zenoh_new::RequestBody}; +use crate::{core::WireExpr, zenoh::RequestBody}; use core::sync::atomic::AtomicU32; /// The resolution of a RequestId diff --git a/commons/zenoh-protocol/src/network/response.rs b/commons/zenoh-protocol/src/network/response.rs index 9032971ddc..9ef2c26a10 100644 --- a/commons/zenoh-protocol/src/network/response.rs +++ b/commons/zenoh-protocol/src/network/response.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::{core::WireExpr, network::RequestId, zenoh_new::ResponseBody}; +use crate::{core::WireExpr, network::RequestId, zenoh::ResponseBody}; /// # Response message /// diff --git a/commons/zenoh-protocol/src/zenoh_new/ack.rs b/commons/zenoh-protocol/src/zenoh/ack.rs similarity index 96% rename from commons/zenoh-protocol/src/zenoh_new/ack.rs rename to commons/zenoh-protocol/src/zenoh/ack.rs index 393e35a349..d40bf58791 100644 --- a/commons/zenoh-protocol/src/zenoh_new/ack.rs +++ b/commons/zenoh-protocol/src/zenoh/ack.rs @@ -51,7 +51,7 @@ pub mod ext { /// # SourceInfo extension /// Used to carry additional information about the source of data pub type SourceInfo = zextzbuf!(0x1, false); - pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; + pub type SourceInfoType = crate::zenoh::ext::SourceInfoType<{ SourceInfo::ID }>; } impl Ack { diff --git a/commons/zenoh-protocol/src/zenoh_new/del.rs b/commons/zenoh-protocol/src/zenoh/del.rs similarity index 96% rename from commons/zenoh-protocol/src/zenoh_new/del.rs rename to commons/zenoh-protocol/src/zenoh/del.rs index 6c67129516..0de867ce51 100644 --- a/commons/zenoh-protocol/src/zenoh_new/del.rs +++ b/commons/zenoh-protocol/src/zenoh/del.rs @@ -51,7 +51,7 @@ pub mod ext { /// # SourceInfo extension /// Used to carry additional information about the source of data pub type SourceInfo = zextzbuf!(0x1, false); - pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; + pub type SourceInfoType = crate::zenoh::ext::SourceInfoType<{ SourceInfo::ID }>; } impl Del { diff --git a/commons/zenoh-protocol/src/zenoh_new/err.rs b/commons/zenoh-protocol/src/zenoh/err.rs similarity index 94% rename from commons/zenoh-protocol/src/zenoh_new/err.rs rename to commons/zenoh-protocol/src/zenoh/err.rs index 721d6a6830..648efff441 100644 --- a/commons/zenoh-protocol/src/zenoh_new/err.rs +++ b/commons/zenoh-protocol/src/zenoh/err.rs @@ -56,13 +56,13 @@ pub mod ext { /// # SourceInfo extension /// Used to carry additional information about the source of data pub type SourceInfo = zextzbuf!(0x1, false); - pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; + pub type SourceInfoType = crate::zenoh::ext::SourceInfoType<{ SourceInfo::ID }>; /// # ErrBody extension /// Used to carry a body attached to the query /// Shared Memory extension is automatically defined by ValueType extension if /// #[cfg(feature = "shared-memory")] is defined. - pub type ErrBodyType = crate::zenoh_new::ext::ValueType<{ ZExtZBuf::<0x02>::id(false) }, 0x03>; + pub type ErrBodyType = crate::zenoh::ext::ValueType<{ ZExtZBuf::<0x02>::id(false) }, 0x03>; } impl Err { diff --git a/commons/zenoh-protocol/src/zenoh_new/mod.rs b/commons/zenoh-protocol/src/zenoh/mod.rs similarity index 100% rename from commons/zenoh-protocol/src/zenoh_new/mod.rs rename to commons/zenoh-protocol/src/zenoh/mod.rs diff --git a/commons/zenoh-protocol/src/zenoh_new/pull.rs b/commons/zenoh-protocol/src/zenoh/pull.rs similarity index 100% rename from commons/zenoh-protocol/src/zenoh_new/pull.rs rename to commons/zenoh-protocol/src/zenoh/pull.rs diff --git a/commons/zenoh-protocol/src/zenoh_new/put.rs b/commons/zenoh-protocol/src/zenoh/put.rs similarity index 95% rename from commons/zenoh-protocol/src/zenoh_new/put.rs rename to commons/zenoh-protocol/src/zenoh/put.rs index 83b5920461..30b8ef837a 100644 --- a/commons/zenoh-protocol/src/zenoh_new/put.rs +++ b/commons/zenoh-protocol/src/zenoh/put.rs @@ -62,14 +62,14 @@ pub mod ext { /// # SourceInfo extension /// Used to carry additional information about the source of data pub type SourceInfo = zextzbuf!(0x1, false); - pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; + pub type SourceInfoType = crate::zenoh::ext::SourceInfoType<{ SourceInfo::ID }>; /// # Shared Memory extension /// Used to carry additional information about the shared-memory layour of data #[cfg(feature = "shared-memory")] pub type Shm = zextunit!(0x2, true); #[cfg(feature = "shared-memory")] - pub type ShmType = crate::zenoh_new::ext::ShmType<{ Shm::ID }>; + pub type ShmType = crate::zenoh::ext::ShmType<{ Shm::ID }>; } impl Put { diff --git a/commons/zenoh-protocol/src/zenoh_new/query.rs b/commons/zenoh-protocol/src/zenoh/query.rs similarity index 94% rename from commons/zenoh-protocol/src/zenoh_new/query.rs rename to commons/zenoh-protocol/src/zenoh/query.rs index 4ffca9e73f..17a2aa1d59 100644 --- a/commons/zenoh-protocol/src/zenoh_new/query.rs +++ b/commons/zenoh-protocol/src/zenoh/query.rs @@ -106,18 +106,17 @@ pub mod ext { /// # SourceInfo extension /// Used to carry additional information about the source of data pub type SourceInfo = zextzbuf!(0x1, false); - pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; + pub type SourceInfoType = crate::zenoh::ext::SourceInfoType<{ SourceInfo::ID }>; /// # Consolidation extension pub type Consolidation = zextz64!(0x2, true); - pub type ConsolidationType = crate::zenoh_new::query::Consolidation; + pub type ConsolidationType = crate::zenoh::query::Consolidation; /// # QueryBody extension /// Used to carry a body attached to the query /// Shared Memory extension is automatically defined by ValueType extension if /// #[cfg(feature = "shared-memory")] is defined. - pub type QueryBodyType = - crate::zenoh_new::ext::ValueType<{ ZExtZBuf::<0x03>::id(false) }, 0x04>; + pub type QueryBodyType = crate::zenoh::ext::ValueType<{ ZExtZBuf::<0x03>::id(false) }, 0x04>; } impl Query { diff --git a/commons/zenoh-protocol/src/zenoh_new/reply.rs b/commons/zenoh-protocol/src/zenoh/reply.rs similarity index 92% rename from commons/zenoh-protocol/src/zenoh_new/reply.rs rename to commons/zenoh-protocol/src/zenoh/reply.rs index 58322432ef..d6b65f88c0 100644 --- a/commons/zenoh-protocol/src/zenoh_new/reply.rs +++ b/commons/zenoh-protocol/src/zenoh/reply.rs @@ -66,24 +66,24 @@ pub mod ext { /// # SourceInfo extension /// Used to carry additional information about the source of data pub type SourceInfo = zextzbuf!(0x1, false); - pub type SourceInfoType = crate::zenoh_new::ext::SourceInfoType<{ SourceInfo::ID }>; + pub type SourceInfoType = crate::zenoh::ext::SourceInfoType<{ SourceInfo::ID }>; /// # Consolidation extension pub type Consolidation = zextz64!(0x2, true); - pub type ConsolidationType = crate::zenoh_new::query::ext::ConsolidationType; + pub type ConsolidationType = crate::zenoh::query::ext::ConsolidationType; /// # Shared Memory extension /// Used to carry additional information about the shared-memory layour of data #[cfg(feature = "shared-memory")] pub type Shm = zextunit!(0x3, true); #[cfg(feature = "shared-memory")] - pub type ShmType = crate::zenoh_new::ext::ShmType<{ Shm::ID }>; + pub type ShmType = crate::zenoh::ext::ShmType<{ Shm::ID }>; } impl Reply { #[cfg(feature = "test")] pub fn rand() -> Self { - use crate::{common::iext, core::ZenohId, zenoh_new::Consolidation}; + use crate::{common::iext, core::ZenohId, zenoh::Consolidation}; use rand::Rng; let mut rng = rand::thread_rng(); diff --git a/io/zenoh-transport/src/common/batch.rs b/io/zenoh-transport/src/common/batch.rs index 96f19c2a0f..6fc2051242 100644 --- a/io/zenoh-transport/src/common/batch.rs +++ b/io/zenoh-transport/src/common/batch.rs @@ -351,7 +351,7 @@ mod tests { frame::{self, FrameHeader}, KeepAlive, TransportMessage, }, - zenoh_new::{PushBody, Put}, + zenoh::{PushBody, Put}, }; #[test] diff --git a/io/zenoh-transport/src/common/pipeline.rs b/io/zenoh-transport/src/common/pipeline.rs index 9d5cba3832..47c5ef4a4d 100644 --- a/io/zenoh-transport/src/common/pipeline.rs +++ b/io/zenoh-transport/src/common/pipeline.rs @@ -722,7 +722,7 @@ mod tests { core::{Bits, CongestionControl, Encoding, Priority}, network::{ext, Push}, transport::{BatchSize, Fragment, Frame, TransportBody, TransportSn}, - zenoh_new::{PushBody, Put}, + zenoh::{PushBody, Put}, }; const SLEEP: Duration = Duration::from_millis(100); diff --git a/io/zenoh-transport/src/shm.rs b/io/zenoh-transport/src/shm.rs index ce01fd7d43..04a8f502c4 100644 --- a/io/zenoh-transport/src/shm.rs +++ b/io/zenoh-transport/src/shm.rs @@ -17,7 +17,7 @@ use zenoh_codec::{RCodec, WCodec, Zenoh080}; use zenoh_core::{zasyncread, zasyncwrite, zerror}; use zenoh_protocol::{ network::{NetworkBody, NetworkMessage, Push, Request, Response}, - zenoh_new::{ + zenoh::{ err::{ext::ErrBodyType, Err}, ext::ShmType, query::{ext::QueryBodyType, Query}, diff --git a/io/zenoh-transport/tests/multicast_transport.rs b/io/zenoh-transport/tests/multicast_transport.rs index e930238d81..e9b986040f 100644 --- a/io/zenoh-transport/tests/multicast_transport.rs +++ b/io/zenoh-transport/tests/multicast_transport.rs @@ -38,7 +38,7 @@ mod tests { }, NetworkMessage, }, - zenoh_new::Put, + zenoh::Put, }; use zenoh_result::ZResult; use zenoh_transport::{ diff --git a/io/zenoh-transport/tests/unicast_concurrent.rs b/io/zenoh-transport/tests/unicast_concurrent.rs index 4bda1aa6a1..77cc7eadf2 100644 --- a/io/zenoh-transport/tests/unicast_concurrent.rs +++ b/io/zenoh-transport/tests/unicast_concurrent.rs @@ -29,7 +29,7 @@ use zenoh_protocol::{ }, NetworkMessage, }, - zenoh_new::Put, + zenoh::Put, }; use zenoh_result::ZResult; use zenoh_transport::{ diff --git a/io/zenoh-transport/tests/unicast_defragmentation.rs b/io/zenoh-transport/tests/unicast_defragmentation.rs index c4e8e07a13..d85a0c021e 100644 --- a/io/zenoh-transport/tests/unicast_defragmentation.rs +++ b/io/zenoh-transport/tests/unicast_defragmentation.rs @@ -25,7 +25,7 @@ use zenoh_protocol::{ }, NetworkMessage, }, - zenoh_new::Put, + zenoh::Put, }; use zenoh_transport::{DummyTransportEventHandler, TransportManager}; diff --git a/io/zenoh-transport/tests/unicast_intermittent.rs b/io/zenoh-transport/tests/unicast_intermittent.rs index 41b60caec7..81f7020d29 100644 --- a/io/zenoh-transport/tests/unicast_intermittent.rs +++ b/io/zenoh-transport/tests/unicast_intermittent.rs @@ -30,7 +30,7 @@ use zenoh_protocol::{ }, NetworkMessage, }, - zenoh_new::Put, + zenoh::Put, }; use zenoh_result::ZResult; use zenoh_transport::test_helpers::make_transport_manager_builder; diff --git a/io/zenoh-transport/tests/unicast_priorities.rs b/io/zenoh-transport/tests/unicast_priorities.rs index 13d8c4b55f..589cfe8e04 100644 --- a/io/zenoh-transport/tests/unicast_priorities.rs +++ b/io/zenoh-transport/tests/unicast_priorities.rs @@ -31,7 +31,7 @@ use zenoh_protocol::{ }, NetworkMessage, }, - zenoh_new::Put, + zenoh::Put, }; use zenoh_result::ZResult; use zenoh_transport::{ diff --git a/io/zenoh-transport/tests/unicast_shm.rs b/io/zenoh-transport/tests/unicast_shm.rs index 930a139d85..f0448d5a4d 100644 --- a/io/zenoh-transport/tests/unicast_shm.rs +++ b/io/zenoh-transport/tests/unicast_shm.rs @@ -32,7 +32,7 @@ mod tests { push::ext::{NodeIdType, QoSType}, NetworkBody, NetworkMessage, Push, }, - zenoh_new::{PushBody, Put}, + zenoh::{PushBody, Put}, }; use zenoh_result::ZResult; use zenoh_shm::{SharedMemoryBuf, SharedMemoryManager}; diff --git a/io/zenoh-transport/tests/unicast_simultaneous.rs b/io/zenoh-transport/tests/unicast_simultaneous.rs index 3b0ef3cad8..f3304606e3 100644 --- a/io/zenoh-transport/tests/unicast_simultaneous.rs +++ b/io/zenoh-transport/tests/unicast_simultaneous.rs @@ -28,7 +28,7 @@ mod tests { push::ext::{NodeIdType, QoSType}, NetworkMessage, Push, }, - zenoh_new::Put, + zenoh::Put, }; use zenoh_result::ZResult; use zenoh_transport::{ diff --git a/io/zenoh-transport/tests/unicast_transport.rs b/io/zenoh-transport/tests/unicast_transport.rs index 434309c0c0..25f9e8c530 100644 --- a/io/zenoh-transport/tests/unicast_transport.rs +++ b/io/zenoh-transport/tests/unicast_transport.rs @@ -32,7 +32,7 @@ use zenoh_protocol::{ push::ext::{NodeIdType, QoSType}, NetworkMessage, Push, }, - zenoh_new::Put, + zenoh::Put, }; use zenoh_result::ZResult; use zenoh_transport::test_helpers::make_transport_manager_builder; diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index 8ca0e6f7cc..d84f173d26 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -15,7 +15,7 @@ use super::router::*; use std::collections::{HashMap, HashSet}; use std::fmt; use std::sync::Arc; -use zenoh_protocol::zenoh_new::RequestBody; +use zenoh_protocol::zenoh::RequestBody; use zenoh_protocol::{ core::{ExprId, WhatAmI, ZenohId}, network::{ diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index bb6aaabdb4..ac61022404 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -36,7 +36,7 @@ use zenoh_protocol::{ }, Push, }, - zenoh_new::PushBody, + zenoh::PushBody, }; use zenoh_sync::get_mut_unchecked; diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index d968364a60..9fa922701f 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -42,7 +42,7 @@ use zenoh_protocol::{ request::{ext::TargetType, Request, RequestId}, response::{self, ext::ResponderIdType, Response, ResponseFinal}, }, - zenoh_new::{reply::ext::ConsolidationType, Reply, RequestBody, ResponseBody}, + zenoh::{reply::ext::ConsolidationType, Reply, RequestBody, ResponseBody}, }; use zenoh_sync::get_mut_unchecked; use zenoh_util::Timed; diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index 76d52908c8..557908c9fc 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -20,7 +20,7 @@ use std::sync::{Arc, Weak}; #[cfg(feature = "complete_n")] use zenoh_protocol::network::request::ext::TargetType; use zenoh_protocol::network::RequestId; -use zenoh_protocol::zenoh_new::PushBody; +use zenoh_protocol::zenoh::PushBody; use zenoh_protocol::{ core::{key_expr::keyexpr, ExprId, WireExpr, ZenohId}, network::{ diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 89a8e21150..304afd4491 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -35,7 +35,7 @@ use zenoh_protocol::{ ext, Declare, DeclareBody, DeclareQueryable, DeclareSubscriber, Push, Request, Response, ResponseFinal, }, - zenoh_new::{PushBody, RequestBody}, + zenoh::{PushBody, RequestBody}, }; use zenoh_result::ZResult; use zenoh_transport::{Primitives, TransportUnicast}; diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index 90d3d6f25c..31d862c8bc 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -26,7 +26,7 @@ use zenoh_protocol::core::{ use zenoh_protocol::network::declare::subscriber::ext::SubscriberInfo; use zenoh_protocol::network::declare::Mode; use zenoh_protocol::network::{ext, Declare, DeclareBody, DeclareKeyExpr}; -use zenoh_protocol::zenoh_new::{PushBody, Put}; +use zenoh_protocol::zenoh::{PushBody, Put}; use zenoh_transport::{DummyPrimitives, Primitives}; #[test] diff --git a/zenoh/src/publication.rs b/zenoh/src/publication.rs index bfc1287ee1..85a47bc644 100644 --- a/zenoh/src/publication.rs +++ b/zenoh/src/publication.rs @@ -25,9 +25,9 @@ use zenoh_core::{zread, AsyncResolve, Resolvable, Resolve, SyncResolve}; use zenoh_protocol::network::push::ext; use zenoh_protocol::network::Mapping; use zenoh_protocol::network::Push; -use zenoh_protocol::zenoh_new::Del; -use zenoh_protocol::zenoh_new::PushBody; -use zenoh_protocol::zenoh_new::Put; +use zenoh_protocol::zenoh::Del; +use zenoh_protocol::zenoh::PushBody; +use zenoh_protocol::zenoh::Put; use zenoh_result::ZResult; /// The kind of congestion control. diff --git a/zenoh/src/queryable.rs b/zenoh/src/queryable.rs index 8b80803b42..eacebe35ae 100644 --- a/zenoh/src/queryable.rs +++ b/zenoh/src/queryable.rs @@ -28,8 +28,8 @@ use std::sync::Arc; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; use zenoh_protocol::core::WireExpr; use zenoh_protocol::network::{response, Mapping, RequestId, Response, ResponseFinal}; -use zenoh_protocol::zenoh_new::reply::ext::ConsolidationType; -use zenoh_protocol::zenoh_new::{self, ResponseBody}; +use zenoh_protocol::zenoh::reply::ext::ConsolidationType; +use zenoh_protocol::zenoh::{self, ResponseBody}; use zenoh_result::ZResult; use zenoh_transport::Primitives; @@ -170,12 +170,12 @@ impl SyncResolve for ReplyBuilder<'_> { suffix: std::borrow::Cow::Owned(key_expr.into()), mapping: Mapping::Sender, }, - payload: ResponseBody::Reply(zenoh_new::Reply { + payload: ResponseBody::Reply(zenoh::Reply { timestamp: data_info.timestamp, encoding: data_info.encoding.unwrap_or_default(), ext_sinfo: if data_info.source_id.is_some() || data_info.source_sn.is_some() { - Some(zenoh_new::reply::ext::SourceInfoType { + Some(zenoh::reply::ext::SourceInfoType { zid: data_info.source_id.unwrap_or_default(), eid: 0, // TODO sn: data_info.source_sn.unwrap_or_default() as u32, diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index c3b0ef9af4..5351041d71 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -70,7 +70,7 @@ use zenoh_protocol::{ request::{self, ext::TargetType, Request}, Mapping, Push, Response, ResponseFinal, }, - zenoh_new::{ + zenoh::{ query::{ self, ext::{ConsolidationType, QueryBodyType}, @@ -1645,7 +1645,7 @@ impl Session { ext_target: target, ext_budget: None, ext_timeout: Some(timeout), - payload: RequestBody::Query(zenoh_protocol::zenoh_new::Query { + payload: RequestBody::Query(zenoh_protocol::zenoh::Query { parameters: selector.parameters().to_string(), ext_sinfo: None, ext_consolidation: consolidation.into(), From 3694147bb254d1116eacb52f4aff3a563d6f4173 Mon Sep 17 00:00:00 2001 From: yellowhatter <104833606+yellowhatter@users.noreply.github.com> Date: Fri, 8 Sep 2023 10:42:44 +0300 Subject: [PATCH 199/203] Disable shm tests for macos (#547) --- .github/workflows/ci.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6939de862a..2b845360d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,25 +121,6 @@ jobs: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse ASYNC_STD_THREAD_COUNT: 4 - - name: Run tests with SHM for macOS - if: ${{ matrix.os == 'macOS-latest' }} - uses: actions-rs/cargo@v1 - with: - command: nextest - args: run -F shared-memory -F transport_tcp -p zenoh-transport - env: - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - ASYNC_STD_THREAD_COUNT: 4 - - - name: Run doctests - uses: actions-rs/cargo@v1 - with: - command: test - args: --doc - env: - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - ASYNC_STD_THREAD_COUNT: 4 - nostd: name: Run no_std checks runs-on: ubuntu-latest From 62d0f8e6c18fe383d6e6736a0825be62d0b99337 Mon Sep 17 00:00:00 2001 From: YuanYuYuan Date: Fri, 8 Sep 2023 15:43:44 +0800 Subject: [PATCH 200/203] Correct the default value of shared_memory (#548) --- DEFAULT_CONFIG.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index 1f09d84f58..6728494bb1 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -129,7 +129,7 @@ qos: { enabled: true, }, - link: { + link: { /// An optional whitelist of protocols to be used for accepting and opening sessions. /// If not configured, all the supported protocols are automatically whitelisted. /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] @@ -224,7 +224,7 @@ }, /// Shared memory configuration shared_memory: { - enabled: true, + enabled: false, }, /// Access control configuration auth: { From d0f08e86505fab4d2c21bb5574336b942330ed62 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Fri, 8 Sep 2023 10:16:51 +0200 Subject: [PATCH 201/203] Do not send sub declarations to multicast on windows --- zenoh/src/net/routing/pubsub.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index ac61022404..e31df26b59 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -464,6 +464,9 @@ pub fn declare_client_subscription( ); } else { propagate_simple_subscription(&mut wtables, &res, &propa_sub_info, face); + // This introduced a buffer overflow on windows + // TODO: Let's deactivate this on windows until Fixed + #[cfg(not(windows))] for mcast_group in &wtables.mcast_groups { mcast_group.primitives.send_declare(Declare { ext_qos: ext::QoSType::default(), @@ -480,6 +483,9 @@ pub fn declare_client_subscription( } _ => { propagate_simple_subscription(&mut wtables, &res, &propa_sub_info, face); + // This introduced a buffer overflow on windows + // TODO: Let's deactivate this on windows until Fixed + #[cfg(not(windows))] for mcast_group in &wtables.mcast_groups { mcast_group.primitives.send_declare(Declare { ext_qos: ext::QoSType::default(), From 1829a209ea5b4c363283afe743bcd0e7144324ae Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Fri, 8 Sep 2023 15:40:09 +0200 Subject: [PATCH 202/203] Send Declare, Request, Response, ResponseFinal and Oam messages with CongestionControl::Block --- commons/zenoh-protocol/src/network/mod.rs | 24 ++++++++++++++ zenoh/src/key_expr.rs | 2 +- zenoh/src/net/routing/network.rs | 2 +- zenoh/src/net/routing/pubsub.rs | 32 +++++++++---------- zenoh/src/net/routing/queries.rs | 38 +++++++++++------------ zenoh/src/net/routing/resource.rs | 2 +- zenoh/src/net/runtime/adminspace.rs | 8 ++--- zenoh/src/net/tests/tables.rs | 10 +++--- zenoh/src/publication.rs | 2 +- zenoh/src/queryable.rs | 4 +-- zenoh/src/session.rs | 26 ++++++++-------- 11 files changed, 87 insertions(+), 63 deletions(-) diff --git a/commons/zenoh-protocol/src/network/mod.rs b/commons/zenoh-protocol/src/network/mod.rs index cbda7f578b..44464c4b13 100644 --- a/commons/zenoh-protocol/src/network/mod.rs +++ b/commons/zenoh-protocol/src/network/mod.rs @@ -267,6 +267,30 @@ pub mod ext { let inner: u8 = rng.gen(); Self { inner } } + + pub fn declare_default() -> Self { + Self::new(Priority::default(), CongestionControl::Block, false) + } + + pub fn push_default() -> Self { + Self::new(Priority::default(), CongestionControl::Drop, false) + } + + pub fn request_default() -> Self { + Self::new(Priority::default(), CongestionControl::Block, false) + } + + pub fn response_default() -> Self { + Self::new(Priority::default(), CongestionControl::Block, false) + } + + pub fn response_final_default() -> Self { + Self::new(Priority::default(), CongestionControl::Block, false) + } + + pub fn oam_default() -> Self { + Self::new(Priority::default(), CongestionControl::Block, false) + } } impl Default for QoSType<{ ID }> { diff --git a/zenoh/src/key_expr.rs b/zenoh/src/key_expr.rs index 6ed616fd13..ad41c30457 100644 --- a/zenoh/src/key_expr.rs +++ b/zenoh/src/key_expr.rs @@ -633,7 +633,7 @@ impl SyncResolve for KeyExprUndeclaration<'_> { let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); primitives.send_declare(zenoh_protocol::network::Declare { - ext_qos: declare::ext::QoSType::default(), + ext_qos: declare::ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: declare::ext::NodeIdType::default(), body: DeclareBody::UndeclareKeyExpr(UndeclareKeyExpr { id: expr_id }), diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index 37493831bb..3af1e0a87c 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -275,7 +275,7 @@ impl Network { Ok(NetworkBody::OAM(Oam { id: OAM_LINKSTATE, body: ZExtBody::ZBuf(buf), - ext_qos: oam::ext::QoSType::default(), + ext_qos: oam::ext::QoSType::oam_default(), ext_tstamp: None, }) .into()) diff --git a/zenoh/src/net/routing/pubsub.rs b/zenoh/src/net/routing/pubsub.rs index e31df26b59..f45b8029e3 100644 --- a/zenoh/src/net/routing/pubsub.rs +++ b/zenoh/src/net/routing/pubsub.rs @@ -60,7 +60,7 @@ fn send_sourced_subscription_to_net_childs( log::debug!("Send subscription {} on {}", res.expr(), someface); someface.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { node_id: routing_context.unwrap_or(0), @@ -114,7 +114,7 @@ fn propagate_simple_subscription_to( get_mut_unchecked(dst_face).local_subs.insert(res.clone()); let key_expr = Resource::decl_key(res, dst_face); dst_face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -469,7 +469,7 @@ pub fn declare_client_subscription( #[cfg(not(windows))] for mcast_group in &wtables.mcast_groups { mcast_group.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -488,7 +488,7 @@ pub fn declare_client_subscription( #[cfg(not(windows))] for mcast_group in &wtables.mcast_groups { mcast_group.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -572,7 +572,7 @@ fn send_forget_sourced_subscription_to_net_childs( log::debug!("Send forget subscription {} on {}", res.expr(), someface); someface.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { node_id: routing_context.unwrap_or(0), @@ -595,7 +595,7 @@ fn propagate_forget_simple_subscription(tables: &mut Tables, res: &Arc if face.local_subs.contains(res) { let wire_expr = Resource::get_best_key(res, "", face.id); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { @@ -631,7 +631,7 @@ fn propagate_forget_simple_subscription_to_peers(tables: &mut Tables, res: &Arc< { let wire_expr = Resource::get_best_key(res, "", face.id); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { @@ -870,7 +870,7 @@ pub(crate) fn undeclare_client_subscription( { let wire_expr = Resource::get_best_key(res, "", face.id); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { @@ -930,7 +930,7 @@ pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { get_mut_unchecked(face).local_subs.insert(sub.clone()); let key_expr = Resource::decl_key(sub, face); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -954,7 +954,7 @@ pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { get_mut_unchecked(face).local_subs.insert(sub.clone()); let key_expr = Resource::decl_key(sub, face); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -974,7 +974,7 @@ pub(crate) fn pubsub_new_face(tables: &mut Tables, face: &mut Arc) { get_mut_unchecked(face).local_subs.insert(sub.clone()); let key_expr = Resource::decl_key(sub, face); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -1167,7 +1167,7 @@ pub(crate) fn pubsub_linkstate_change(tables: &mut Tables, zid: &ZenohId, links: if forget { let wire_expr = Resource::get_best_key(res, "", dst_face.id); dst_face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber( @@ -1189,7 +1189,7 @@ pub(crate) fn pubsub_linkstate_change(tables: &mut Tables, zid: &ZenohId, links: mode: Mode::Push, }; dst_face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -1831,7 +1831,7 @@ pub fn full_reentrant_route_data( outface.primitives.send_push(Push { wire_expr: key_expr, - ext_qos: ext::QoSType::default(), + ext_qos, ext_tstamp: None, ext_nodeid: ext::NodeIdType { node_id: context.unwrap_or(0), @@ -1860,7 +1860,7 @@ pub fn full_reentrant_route_data( outface.primitives.send_push(Push { wire_expr: key_expr.into(), - ext_qos: ext::QoSType::default(), + ext_qos, ext_tstamp: None, ext_nodeid: ext::NodeIdType { node_id: context.unwrap_or(0), @@ -1907,7 +1907,7 @@ pub fn pull_data(tables_ref: &RwLock, face: &Arc, expr: WireE for (key_expr, payload) in route { face.primitives.send_push(Push { wire_expr: key_expr, - ext_qos: ext::QoSType::default(), // TODO + ext_qos: ext::QoSType::push_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), payload, diff --git a/zenoh/src/net/routing/queries.rs b/zenoh/src/net/routing/queries.rs index 9fa922701f..e2608a0066 100644 --- a/zenoh/src/net/routing/queries.rs +++ b/zenoh/src/net/routing/queries.rs @@ -219,7 +219,7 @@ fn send_sourced_queryable_to_net_childs( log::debug!("Send queryable {} on {}", res.expr(), someface); someface.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { node_id: routing_context.unwrap_or(0), @@ -286,7 +286,7 @@ fn propagate_simple_queryable( .insert(res.clone(), info); let key_expr = Resource::decl_key(res, &mut dst_face); dst_face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -697,7 +697,7 @@ fn send_forget_sourced_queryable_to_net_childs( log::debug!("Send forget queryable {} on {}", res.expr(), someface); someface.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { node_id: routing_context.unwrap_or(0), @@ -720,7 +720,7 @@ fn propagate_forget_simple_queryable(tables: &mut Tables, res: &mut Arc) { .insert(qabl.clone(), info); let key_expr = Resource::decl_key(qabl, face); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -1092,7 +1092,7 @@ pub(crate) fn queries_new_face(tables: &mut Tables, face: &mut Arc) { .insert(qabl.clone(), info); let key_expr = Resource::decl_key(qabl, face); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -1116,7 +1116,7 @@ pub(crate) fn queries_new_face(tables: &mut Tables, face: &mut Arc) { .insert(qabl.clone(), info); let key_expr = Resource::decl_key(qabl, face); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -1253,7 +1253,7 @@ pub(crate) fn queries_linkstate_change(tables: &mut Tables, zid: &ZenohId, links if forget { let wire_expr = Resource::get_best_key(res, "", dst_face.id); dst_face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareQueryable(UndeclareQueryable { @@ -1272,7 +1272,7 @@ pub(crate) fn queries_linkstate_change(tables: &mut Tables, zid: &ZenohId, links .insert(res.clone(), info); let key_expr = Resource::decl_key(res, dst_face); dst_face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -2128,7 +2128,7 @@ pub fn route_query( rid: qid, wire_expr: expr, payload, - ext_qos: response::ext::QoSType::default(), + ext_qos: response::ext::QoSType::declare_default(), ext_tstamp: None, ext_respid: Some(response::ext::ResponderIdType { zid, @@ -2145,7 +2145,7 @@ pub fn route_query( ); face.primitives.clone().send_response_final(ResponseFinal { rid: qid, - ext_qos: response::ext::QoSType::default(), + ext_qos: response::ext::QoSType::response_final_default(), ext_tstamp: None, }); } else { @@ -2173,7 +2173,7 @@ pub fn route_query( outface.primitives.send_request(Request { id: *qid, wire_expr: key_expr.into(), - ext_qos: ext::QoSType::default(), // TODO + ext_qos: ext::QoSType::request_default(), // TODO ext_tstamp: None, ext_nodeid: ext::NodeIdType { node_id: context.map(|c| c.tree_id).unwrap_or(0) as u16, @@ -2208,7 +2208,7 @@ pub fn route_query( outface.primitives.send_request(Request { id: *qid, wire_expr: key_expr.into(), - ext_qos: ext::QoSType::default(), // TODO + ext_qos: ext::QoSType::request_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType { node_id: context.unwrap_or(0), @@ -2226,7 +2226,7 @@ pub fn route_query( drop(rtables); face.primitives.clone().send_response_final(ResponseFinal { rid: qid, - ext_qos: response::ext::QoSType::default(), + ext_qos: response::ext::QoSType::response_final_default(), ext_tstamp: None, }); } @@ -2239,7 +2239,7 @@ pub fn route_query( drop(rtables); face.primitives.clone().send_response_final(ResponseFinal { rid: qid, - ext_qos: response::ext::QoSType::default(), + ext_qos: response::ext::QoSType::response_final_default(), ext_tstamp: None, }); } @@ -2280,7 +2280,7 @@ pub(crate) fn route_send_response( rid: query.src_qid, wire_expr: key_expr.to_owned(), payload: body, - ext_qos: response::ext::QoSType::default(), + ext_qos: response::ext::QoSType::response_default(), ext_tstamp: None, ext_respid, }); @@ -2337,7 +2337,7 @@ pub(crate) fn finalize_pending_query(query: Arc) { .clone() .send_response_final(ResponseFinal { rid: query.src_qid, - ext_qos: response::ext::QoSType::default(), + ext_qos: response::ext::QoSType::response_final_default(), ext_tstamp: None, }); } diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index 557908c9fc..e26a9217f3 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -516,7 +516,7 @@ impl Resource { .local_mappings .insert(expr_id, nonwild_prefix.clone()); face.primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 304afd4491..23bb47d9b9 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -221,7 +221,7 @@ impl AdminSpace { zlock!(admin.primitives).replace(primitives.clone()); primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -235,7 +235,7 @@ impl AdminSpace { }); primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -342,7 +342,7 @@ impl Primitives for AdminSpace { ); primitives.send_response_final(ResponseFinal { rid: msg.id, - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::response_final_default(), ext_tstamp: None, }); return; @@ -355,7 +355,7 @@ impl Primitives for AdminSpace { log::error!("Unknown KeyExpr: {}", e); primitives.send_response_final(ResponseFinal { rid: msg.id, - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::response_final_default(), ext_tstamp: None, }); return; diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index 31d862c8bc..5dadf8d8a9 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -485,7 +485,7 @@ fn client_test() { &"test/client".into(), ); primitives0.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { @@ -507,7 +507,7 @@ fn client_test() { &WireExpr::from(11).with_suffix("/z1_pub1"), ); primitives0.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { @@ -529,7 +529,7 @@ fn client_test() { &"test/client".into(), ); primitives1.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { @@ -551,7 +551,7 @@ fn client_test() { &WireExpr::from(21).with_suffix("/z2_pub1"), ); primitives1.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { @@ -573,7 +573,7 @@ fn client_test() { &"test/client".into(), ); primitives2.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { diff --git a/zenoh/src/publication.rs b/zenoh/src/publication.rs index 85a47bc644..fa49f22ad8 100644 --- a/zenoh/src/publication.rs +++ b/zenoh/src/publication.rs @@ -431,7 +431,7 @@ impl SyncResolve for Publication<'_> { if publisher.destination != Locality::SessionLocal { primitives.send_push(Push { wire_expr: publisher.key_expr.to_wire(&publisher.session).to_owned(), - ext_qos: ext::QoSType::default(), // TODO + ext_qos: ext::QoSType::push_default(), // TODO // use publisher.priority // use publisher.congestion_control // need to check subscriptions to determine the right reliability value diff --git a/zenoh/src/queryable.rs b/zenoh/src/queryable.rs index eacebe35ae..ed0560d759 100644 --- a/zenoh/src/queryable.rs +++ b/zenoh/src/queryable.rs @@ -50,7 +50,7 @@ impl Drop for QueryInner { fn drop(&mut self) { self.primitives.send_response_final(ResponseFinal { rid: self.qid, - ext_qos: response::ext::QoSType::default(), + ext_qos: response::ext::QoSType::response_final_default(), ext_tstamp: None, }); } @@ -189,7 +189,7 @@ impl SyncResolve for ReplyBuilder<'_> { ext_unknown: vec![], payload, }), - ext_qos: response::ext::QoSType::default(), + ext_qos: response::ext::QoSType::response_default(), ext_tstamp: None, ext_respid: Some(response::ext::ResponderIdType { zid: self.query.inner.zid, diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 5351041d71..744f21965f 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -889,7 +889,7 @@ impl Session { let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); primitives.send_declare(Declare { - ext_qos: declare::ext::QoSType::default(), + ext_qos: declare::ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: declare::ext::NodeIdType::default(), body: DeclareBody::DeclareKeyExpr(DeclareKeyExpr { @@ -1090,7 +1090,7 @@ impl Session { // }; primitives.send_declare(Declare { - ext_qos: declare::ext::QoSType::default(), + ext_qos: declare::ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: declare::ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -1149,7 +1149,7 @@ impl Session { let wire_expr = WireExpr::from(join_sub).to_owned(); drop(state); primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { @@ -1168,7 +1168,7 @@ impl Session { let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { @@ -1218,7 +1218,7 @@ impl Session { distance: 0, }; primitives.send_declare(Declare { - ext_qos: declare::ext::QoSType::default(), + ext_qos: declare::ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: declare::ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -1246,7 +1246,7 @@ impl Session { distance: 0, }; primitives.send_declare(Declare { - ext_qos: declare::ext::QoSType::default(), + ext_qos: declare::ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: declare::ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -1311,7 +1311,7 @@ impl Session { distance: 0, }; primitives.send_declare(Declare { - ext_qos: declare::ext::QoSType::default(), + ext_qos: declare::ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: declare::ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -1330,7 +1330,7 @@ impl Session { distance: 0, }; primitives.send_declare(Declare { - ext_qos: declare::ext::QoSType::default(), + ext_qos: declare::ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: declare::ext::NodeIdType::default(), body: DeclareBody::DeclareQueryable(DeclareQueryable { @@ -1346,7 +1346,7 @@ impl Session { // There are no more Queryables on the same KeyExpr. drop(state); primitives.send_declare(Declare { - ext_qos: declare::ext::QoSType::default(), + ext_qos: declare::ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: declare::ext::NodeIdType::default(), body: DeclareBody::UndeclareQueryable(UndeclareQueryable { @@ -1382,7 +1382,7 @@ impl Session { let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); primitives.send_declare(Declare { - ext_qos: declare::ext::QoSType::default(), + ext_qos: declare::ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: declare::ext::NodeIdType::default(), body: DeclareBody::DeclareSubscriber(DeclareSubscriber { @@ -1406,7 +1406,7 @@ impl Session { let primitives = state.primitives.as_ref().unwrap().clone(); drop(state); primitives.send_declare(Declare { - ext_qos: ext::QoSType::default(), + ext_qos: ext::QoSType::declare_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { @@ -1545,7 +1545,7 @@ impl Session { primitives.send_request(Request { id: 0, // TODO wire_expr: key_expr.to_wire(self).to_owned(), - ext_qos: ext::QoSType::default(), // TODO + ext_qos: ext::QoSType::request_default(), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), ext_target: request::ext::TargetType::default(), @@ -1639,7 +1639,7 @@ impl Session { primitives.send_request(Request { id: qid, wire_expr: wexpr.clone(), - ext_qos: request::ext::QoSType::default(), + ext_qos: request::ext::QoSType::request_default(), ext_tstamp: None, ext_nodeid: request::ext::NodeIdType::default(), ext_target: target, From 960edbc8a06bf9b35d3548fa6a81bbbf1dacb013 Mon Sep 17 00:00:00 2001 From: OlivierHecart Date: Fri, 8 Sep 2023 15:58:39 +0200 Subject: [PATCH 203/203] Publications from a publisher are done with the correct priotity and congestion control --- zenoh/src/publication.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/zenoh/src/publication.rs b/zenoh/src/publication.rs index fa49f22ad8..071eb97da9 100644 --- a/zenoh/src/publication.rs +++ b/zenoh/src/publication.rs @@ -431,10 +431,11 @@ impl SyncResolve for Publication<'_> { if publisher.destination != Locality::SessionLocal { primitives.send_push(Push { wire_expr: publisher.key_expr.to_wire(&publisher.session).to_owned(), - ext_qos: ext::QoSType::push_default(), // TODO - // use publisher.priority - // use publisher.congestion_control - // need to check subscriptions to determine the right reliability value + ext_qos: ext::QoSType::new( + publisher.priority.into(), + publisher.congestion_control, + false, + ), ext_tstamp: None, ext_nodeid: ext::NodeIdType::default(), payload: PushBody::Put(Put {