Skip to main content

alpine_protocol_sdk/
network_health.rs

1use std::net::SocketAddr;
2
3use socket2::{Domain, Protocol, Socket, Type};
4
5#[derive(Debug, Clone)]
6pub struct NetworkHealthReport {
7    pub udp_bind_ok: bool,
8    pub broadcast_ok: bool,
9    pub multicast_ok: bool,
10    pub notes: Vec<String>,
11}
12
13impl NetworkHealthReport {
14    pub fn probe() -> Self {
15        let mut notes = Vec::new();
16        let mut udp_bind_ok = false;
17        let mut broadcast_ok = false;
18        let mut multicast_ok = false;
19
20        let udp = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP));
21        match udp {
22            Ok(sock) => {
23                if sock
24                    .bind(&SocketAddr::from(([0, 0, 0, 0], 0)).into())
25                    .is_ok()
26                {
27                    udp_bind_ok = true;
28                } else {
29                    notes.push("udp bind failed".to_string());
30                }
31
32                if sock.set_broadcast(true).is_ok() {
33                    broadcast_ok = true;
34                } else {
35                    notes.push("udp broadcast disabled or blocked".to_string());
36                }
37
38                if sock.set_multicast_ttl_v4(4).is_ok() {
39                    multicast_ok = true;
40                } else {
41                    notes.push("udp multicast disabled or blocked".to_string());
42                }
43            }
44            Err(err) => {
45                notes.push(format!("udp socket creation failed: {}", err));
46            }
47        }
48
49        Self {
50            udp_bind_ok,
51            broadcast_ok,
52            multicast_ok,
53            notes,
54        }
55    }
56
57    pub fn ok(&self) -> bool {
58        self.udp_bind_ok && (self.broadcast_ok || self.multicast_ok)
59    }
60}