zenoh_link_ws/
lib.rs

1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14
15//! ⚠️ WARNING ⚠️
16//!
17//! This crate is intended for Zenoh's internal use.
18//!
19//! [Click here for Zenoh's documentation](https://docs.rs/zenoh/latest/zenoh)
20use std::{net::SocketAddr, str::FromStr};
21
22use async_trait::async_trait;
23use url::Url;
24use zenoh_core::zconfigurable;
25use zenoh_link_commons::LocatorInspector;
26use zenoh_protocol::{
27    core::{endpoint::Address, Locator, Metadata, Reliability},
28    transport::BatchSize,
29};
30use zenoh_result::{bail, ZResult};
31mod unicast;
32pub use unicast::*;
33
34// Default MTU (WSS PDU) in bytes.
35// NOTE: Since TCP is a byte-stream oriented transport, theoretically it has
36//       no limit regarding the MTU. However, given the batching strategy
37//       adopted in Zenoh and the usage of 16 bits in Zenoh to encode the
38//       payload length in byte-streamed, the TCP MTU is constrained to
39//       2^16 - 1 bytes (i.e., 65535).
40const WS_MAX_MTU: BatchSize = BatchSize::MAX;
41
42pub const WS_LOCATOR_PREFIX: &str = "ws";
43
44const IS_RELIABLE: bool = true;
45
46#[derive(Default, Clone, Copy)]
47pub struct WsLocatorInspector;
48#[async_trait]
49impl LocatorInspector for WsLocatorInspector {
50    fn protocol(&self) -> &str {
51        WS_LOCATOR_PREFIX
52    }
53    async fn is_multicast(&self, _locator: &Locator) -> ZResult<bool> {
54        Ok(false)
55    }
56
57    fn is_reliable(&self, locator: &Locator) -> ZResult<bool> {
58        if let Some(reliability) = locator
59            .metadata()
60            .get(Metadata::RELIABILITY)
61            .map(Reliability::from_str)
62            .transpose()?
63        {
64            Ok(reliability == Reliability::Reliable)
65        } else {
66            Ok(IS_RELIABLE)
67        }
68    }
69}
70
71zconfigurable! {
72    // Default MTU (TCP PDU) in bytes.
73    static ref WS_DEFAULT_MTU: BatchSize = WS_MAX_MTU;
74    // Amount of time in microseconds to throttle the accept loop upon an error.
75    // Default set to 100 ms.
76    static ref TCP_ACCEPT_THROTTLE_TIME: u64 = 100_000;
77}
78
79pub async fn get_ws_addr(address: Address<'_>) -> ZResult<SocketAddr> {
80    match tokio::net::lookup_host(address.as_str()).await?.next() {
81        Some(addr) => Ok(addr),
82        None => bail!("Couldn't resolve WebSocket locator address: {}", address),
83    }
84}
85
86pub async fn get_ws_url(address: Address<'_>) -> ZResult<Url> {
87    match Url::parse(&format!(
88        "{}://{}",
89        WS_LOCATOR_PREFIX,
90        get_ws_addr(address).await?
91    )) {
92        Ok(url) => Ok(url),
93        Err(e) => bail!(
94            "Couldn't resolve WebSocket locator address: {}: {}",
95            address,
96            e
97        ),
98    }
99}