1mod multicast;
21mod pktinfo;
22mod unicast;
23
24use std::{net::SocketAddr, str::FromStr};
25
26use async_trait::async_trait;
27pub use multicast::*;
28pub use unicast::*;
29use zenoh_core::zconfigurable;
30use zenoh_link_commons::LocatorInspector;
31use zenoh_protocol::{
32 core::{endpoint::Address, Locator, Metadata, Reliability},
33 transport::BatchSize,
34};
35use zenoh_result::{zerror, ZResult};
36
37const UDP_MAX_MTU: BatchSize = u16::MAX - 8 - 40;
55
56pub const UDP_LOCATOR_PREFIX: &str = "udp";
57
58#[cfg(any(target_os = "linux", target_os = "windows"))]
59const UDP_MTU_LIMIT: BatchSize = UDP_MAX_MTU;
61
62#[cfg(target_os = "macos")]
63const UDP_MTU_LIMIT: BatchSize = 9_216;
65
66#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
67const UDP_MTU_LIMIT: BatchSize = 8_192;
68
69const IS_RELIABLE: bool = false;
70
71zconfigurable! {
72 static ref UDP_DEFAULT_MTU: BatchSize = UDP_MTU_LIMIT;
74 static ref UDP_ACCEPT_THROTTLE_TIME: u64 = 100_000;
77}
78
79#[derive(Default, Clone, Copy)]
80pub struct UdpLocatorInspector;
81#[async_trait]
82impl LocatorInspector for UdpLocatorInspector {
83 fn protocol(&self) -> &str {
84 UDP_LOCATOR_PREFIX
85 }
86
87 async fn is_multicast(&self, locator: &Locator) -> ZResult<bool> {
88 let is_multicast = get_udp_addrs(locator.address())
89 .await?
90 .any(|x| x.ip().is_multicast());
91 Ok(is_multicast)
92 }
93
94 fn is_reliable(&self, locator: &Locator) -> ZResult<bool> {
95 if let Some(reliability) = locator
96 .metadata()
97 .get(Metadata::RELIABILITY)
98 .map(Reliability::from_str)
99 .transpose()?
100 {
101 Ok(reliability == Reliability::Reliable)
102 } else {
103 Ok(IS_RELIABLE)
104 }
105 }
106}
107
108pub mod config {
109 pub const UDP_MULTICAST_IFACE: &str = "iface";
110 pub const UDP_MULTICAST_JOIN: &str = "join";
111 pub const UDP_MULTICAST_TTL: &str = "ttl";
112}
113
114pub async fn get_udp_addrs(address: Address<'_>) -> ZResult<impl Iterator<Item = SocketAddr>> {
115 let iter = tokio::net::lookup_host(address.as_str().to_string())
116 .await
117 .map_err(|e| zerror!("{}", e))?;
118 Ok(iter)
119}
120
121pub(crate) fn socket_addr_to_udp_locator(addr: &SocketAddr) -> Locator {
122 Locator::new(UDP_LOCATOR_PREFIX, addr.to_string(), "").unwrap()
123}