use super::*;
pub(super) const MAX_UDP_HANDLES: usize = 256;
pub(super) fn udp_registry() -> &'static Mutex<std::collections::HashMap<u64, std::net::UdpSocket>> {
static REGISTRY: OnceLock<Mutex<std::collections::HashMap<u64, std::net::UdpSocket>>> =
OnceLock::new();
REGISTRY.get_or_init(|| Mutex::new(std::collections::HashMap::new()))
}
pub(super) fn next_udp_handle() -> u64 {
static COUNTER: AtomicU64 = AtomicU64::new(1);
COUNTER.fetch_add(1, Ordering::SeqCst)
}
pub(super) fn with_udp<T>(
handle: i64,
op: &str,
f: impl FnOnce(&std::net::UdpSocket) -> Result<T, String>,
) -> Result<T, String> {
let reg = udp_registry().lock().unwrap();
match reg.get(&(handle as u64)) {
Some(sock) => f(sock),
None => Err(format!("{op}: no open socket with handle {handle} (closed, or never opened?)")),
}
}
pub(super) fn udp_datagram_value(data: Vec<u8>, addr: std::net::SocketAddr) -> Value {
let mut rec = indexmap::IndexMap::new();
rec.insert("data".into(), Value::Bytes(data));
rec.insert("host".into(), Value::Str(addr.ip().to_string().into()));
rec.insert("port".into(), Value::Int(i64::from(addr.port())));
Value::record_dynamic(rec)
}
impl DefaultHandler {
pub(super) fn ensure_udp_dest_allowed(&self, host: &str) -> Result<(), String> {
if self.policy.allow_net_host.is_empty() { return Ok(()); }
if self.policy.allow_net_host.iter().any(|h| host == h) {
Ok(())
} else {
Err(format!(
"net.udp_send to `{host}` not in --allow-net-host {:?}",
self.policy.allow_net_host,
))
}
}
}