Skip to content

Commit

Permalink
Implement vsock link support
Browse files Browse the repository at this point in the history
  • Loading branch information
sashacmc committed Mar 14, 2024
1 parent c15d925 commit 2a18834
Show file tree
Hide file tree
Showing 11 changed files with 530 additions and 2 deletions.
46 changes: 44 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ members = [
"io/zenoh-links/zenoh-link-unixsock_stream/",
"io/zenoh-links/zenoh-link-ws/",
"io/zenoh-links/zenoh-link-unixpipe/",
"io/zenoh-links/zenoh-link-vsock/",
"io/zenoh-transport",
"plugins/zenoh-backend-example",
"plugins/zenoh-plugin-example",
Expand Down Expand Up @@ -151,6 +152,7 @@ tokio = { version = "1.35.1", default-features = false } # Default features are
tokio-util = "0.7.10"
tokio-tungstenite = "0.21"
tokio-rustls = "0.25.0"
tokio-vsock = "0.5.0"
console-subscriber = "0.2"
typenum = "1.16.0"
uhlc = { version = "0.6.0", default-features = false } # Default features are disabled due to usage in no_std crates
Expand Down Expand Up @@ -190,6 +192,7 @@ zenoh-link-udp = { version = "0.11.0-dev", path = "io/zenoh-links/zenoh-link-udp
zenoh-link-ws = { version = "0.11.0-dev", path = "io/zenoh-links/zenoh-link-ws" }
zenoh-link-unixpipe = { version = "0.11.0-dev", path = "io/zenoh-links/zenoh-link-unixpipe" }
zenoh-link-serial = { version = "0.11.0-dev", path = "io/zenoh-links/zenoh-link-serial" }
zenoh-link-vsock = { version = "0.11.0-dev", path = "io/zenoh-links/zenoh-link-vsock" }
zenoh-link = { version = "0.11.0-dev", path = "io/zenoh-link" }
zenoh-link-commons = { version = "0.11.0-dev", path = "io/zenoh-link-commons" }
zenoh = { version = "0.11.0-dev", path = "zenoh", default-features = false }
Expand Down
2 changes: 2 additions & 0 deletions io/zenoh-link/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ transport_unixsock-stream = ["zenoh-link-unixsock_stream"]
transport_ws = ["zenoh-link-ws"]
transport_serial = ["zenoh-link-serial"]
transport_unixpipe = ["zenoh-link-unixpipe", "zenoh-link-unixpipe/transport_unixpipe"]
transport_vsock = ["zenoh-link-vsock"]

[dependencies]
async-trait = { workspace = true }
Expand All @@ -47,5 +48,6 @@ zenoh-link-udp = { workspace = true, optional = true }
zenoh-link-unixsock_stream = { workspace = true, optional = true }
zenoh-link-ws = { workspace = true, optional = true }
zenoh-link-unixpipe = { workspace = true, optional = true }
zenoh-link-vsock = { workspace = true, optional = true }
zenoh-protocol = { workspace = true }
zenoh-result = { workspace = true }
13 changes: 13 additions & 0 deletions io/zenoh-link/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ use zenoh_link_unixpipe::{
LinkManagerUnicastPipe, UnixPipeConfigurator, UnixPipeLocatorInspector, UNIXPIPE_LOCATOR_PREFIX,
};

#[cfg(feature = "transport_vsock")]
pub use zenoh_link_vsock as vsock;
#[cfg(feature = "transport_vsock")]
use zenoh_link_vsock::{LinkManagerUnicastVsock, VsockLocatorInspector, VSOCK_LOCATOR_PREFIX};

pub use zenoh_link_commons::*;
pub use zenoh_protocol::core::{EndPoint, Locator};

Expand All @@ -92,6 +97,8 @@ pub const PROTOCOLS: &[&str] = &[
serial::SERIAL_LOCATOR_PREFIX,
#[cfg(feature = "transport_unixpipe")]
unixpipe::UNIXPIPE_LOCATOR_PREFIX,
#[cfg(feature = "transport_vsock")]
vsock::VSOCK_LOCATOR_PREFIX,
];

#[derive(Default, Clone)]
Expand All @@ -112,6 +119,8 @@ pub struct LocatorInspector {
serial_inspector: SerialLocatorInspector,
#[cfg(feature = "transport_unixpipe")]
unixpipe_inspector: UnixPipeLocatorInspector,
#[cfg(feature = "transport_vsock")]
vsock_inspector: VsockLocatorInspector,
}
impl LocatorInspector {
pub async fn is_multicast(&self, locator: &Locator) -> ZResult<bool> {
Expand All @@ -137,6 +146,8 @@ impl LocatorInspector {
SERIAL_LOCATOR_PREFIX => self.serial_inspector.is_multicast(locator).await,
#[cfg(feature = "transport_unixpipe")]
UNIXPIPE_LOCATOR_PREFIX => self.unixpipe_inspector.is_multicast(locator).await,
#[cfg(feature = "transport_vsock")]
VSOCK_LOCATOR_PREFIX => self.vsock_inspector.is_multicast(locator).await,
_ => bail!("Unsupported protocol: {}.", protocol),
}
}
Expand Down Expand Up @@ -226,6 +237,8 @@ impl LinkManagerBuilderUnicast {
UNIXPIPE_LOCATOR_PREFIX => {
Ok(std::sync::Arc::new(LinkManagerUnicastPipe::new(_manager)))
}
#[cfg(feature = "transport_vsock")]
VSOCK_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastVsock::new(_manager))),
_ => bail!("Unicast not supported for {} protocol", protocol),
}
}
Expand Down
40 changes: 40 additions & 0 deletions io/zenoh-links/zenoh-link-vsock/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#
# Copyright (c) 2024 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, <[email protected]>
#
[package]
rust-version = { workspace = true }
name = "zenoh-link-vsock"
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

[dependencies]
async-trait = { workspace = true }
tokio = { workspace = true, features = ["net", "io-util", "rt", "time"] }
tokio-util = { workspace = true, features = ["rt"] }
tokio-vsock = { workspace = true }
log = { workspace = true }
libc = { workspace = true }
zenoh-core = { workspace = true }
zenoh-link-commons = { workspace = true }
zenoh-protocol = { workspace = true }
zenoh-result = { workspace = true }
zenoh-sync = { workspace = true }
zenoh-util = { workspace = true }
zenoh-runtime = { workspace = true }
98 changes: 98 additions & 0 deletions io/zenoh-links/zenoh-link-vsock/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//
// Copyright (c) 2024 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, <[email protected]>
//

//! ⚠️ WARNING ⚠️
//!
//! This crate is intended for Zenoh's internal use.
//!
//! [Click here for Zenoh's documentation](../zenoh/index.html)
use async_trait::async_trait;
use libc::VMADDR_PORT_ANY;
use tokio_vsock::{
VsockAddr, VMADDR_CID_ANY, VMADDR_CID_HOST, VMADDR_CID_HYPERVISOR, VMADDR_CID_LOCAL,
};
use zenoh_core::zconfigurable;
use zenoh_link_commons::LocatorInspector;
use zenoh_protocol::core::{endpoint::Address, Locator};
use zenoh_result::{bail, ZResult};

mod unicast;
pub use unicast::*;

pub const VSOCK_LOCATOR_PREFIX: &str = "vsock";

pub const VSOCK_VMADDR_CID_ANY: &str = "VMADDR_CID_ANY";
pub const VSOCK_VMADDR_CID_HYPERVISOR: &str = "VMADDR_CID_HYPERVISOR";
pub const VSOCK_VMADDR_CID_LOCAL: &str = "VMADDR_CID_LOCAL";
pub const VSOCK_VMADDR_CID_HOST: &str = "VMADDR_CID_HOST";

pub const VSOCK_VMADDR_PORT_ANY: &str = "VMADDR_PORT_ANY";

#[derive(Default, Clone, Copy)]
pub struct VsockLocatorInspector;
#[async_trait]
impl LocatorInspector for VsockLocatorInspector {
fn protocol(&self) -> &str {
VSOCK_LOCATOR_PREFIX
}

async fn is_multicast(&self, _locator: &Locator) -> ZResult<bool> {
Ok(false)
}
}

zconfigurable! {
// Default MTU in bytes.
static ref VSOCK_DEFAULT_MTU: u16 = u16::MAX;
// Amount of time in microseconds to throttle the accept loop upon an error.
// Default set to 100 ms.
static ref VSOCK_ACCEPT_THROTTLE_TIME: u64 = 100_000;
}

pub fn get_vsock_addr(address: Address<'_>) -> ZResult<VsockAddr> {
let parts: Vec<&str> = address.as_str().split(':').collect();

if parts.len() != 2 {
bail!("Incorrect vsock address: {:?}", address);
}

let cid = match parts[0].to_uppercase().as_str() {
VSOCK_VMADDR_CID_HYPERVISOR => VMADDR_CID_HYPERVISOR,
VSOCK_VMADDR_CID_HOST => VMADDR_CID_HOST,
VSOCK_VMADDR_CID_LOCAL => VMADDR_CID_LOCAL,
VSOCK_VMADDR_CID_ANY => VMADDR_CID_ANY,
"-1" => VMADDR_CID_ANY,
_ => {
if let Ok(cid) = parts[0].parse::<u32>() {
cid
} else {
bail!("Incorrect vsock cid: {:?}", parts[0]);
}
}
};

let port = match parts[1].to_uppercase().as_str() {
VSOCK_VMADDR_PORT_ANY => VMADDR_PORT_ANY,
"-1" => VMADDR_PORT_ANY,
_ => {
if let Ok(cid) = parts[1].parse::<u32>() {
cid
} else {
bail!("Incorrect vsock port: {:?}", parts[1]);
}
}
};

Ok(VsockAddr::new(cid, port))
}
Loading

0 comments on commit 2a18834

Please sign in to comment.