Skip to main content

sig_net/
net.rs

1use crate::*;
2use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};
3use std::time::Duration;
4
5pub struct UdpMulticastSocket {
6    socket: UdpSocket,
7    port: u16,
8}
9
10impl UdpMulticastSocket {
11    pub fn bind(port: u16) -> Result<Self> {
12        let addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, port);
13        let socket = UdpSocket::bind(addr).map_err(|_| SigNetError::Network)?;
14        socket.set_read_timeout(Some(Duration::from_millis(100))).ok();
15        Ok(UdpMulticastSocket { socket, port })
16    }
17
18    pub fn set_multicast_ttl(&self, ttl: u8) -> Result<()> {
19        self.socket
20            .set_multicast_ttl_v4(ttl as u32)
21            .map_err(|_| SigNetError::Network)
22    }
23
24    pub fn set_multicast_loopback(&self, enabled: bool) -> Result<()> {
25        self.socket
26            .set_multicast_loop_v4(enabled)
27            .map_err(|_| SigNetError::Network)
28    }
29
30    pub fn join_multicast_group(&self, multicast_addr: Ipv4Addr, interface: Option<Ipv4Addr>) -> Result<()> {
31        let iface = interface.unwrap_or(Ipv4Addr::UNSPECIFIED);
32        self.socket
33            .join_multicast_v4(&multicast_addr, &iface)
34            .map_err(|_| SigNetError::Network)
35    }
36
37    pub fn leave_multicast_group(&self, multicast_addr: Ipv4Addr, interface: Option<Ipv4Addr>) -> Result<()> {
38        let iface = interface.unwrap_or(Ipv4Addr::UNSPECIFIED);
39        self.socket
40            .leave_multicast_v4(&multicast_addr, &iface)
41            .map_err(|_| SigNetError::Network)
42    }
43
44    pub fn send_to(&self, data: &[u8], dest: SocketAddrV4) -> Result<usize> {
45        self.socket.send_to(data, dest).map_err(|_| SigNetError::Network)
46    }
47
48    pub fn send_multicast(&self, data: &[u8], universe: u16) -> Result<usize> {
49        let octets = calculate_multicast_address(universe)?;
50        let addr = Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]);
51        let dest = SocketAddrV4::new(addr, self.port);
52        self.send_to(data, dest)
53    }
54
55    pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddrV4)> {
56        self.socket
57            .recv_from(buf)
58            .map_err(|_| SigNetError::Network)
59            .and_then(|(n, addr)| match addr {
60                std::net::SocketAddr::V4(v4) => Ok((n, v4)),
61                _ => Err(SigNetError::Network),
62            })
63    }
64}