Skip to main content

network_inspector/
resolver.rs

1// Best-effort reverse DNS with a short timeout. For CLI/TUI display only.
2
3use std::net::{SocketAddr, ToSocketAddrs};
4use std::sync::mpsc;
5use std::time::Duration;
6
7const RESOLVE_TIMEOUT_MS: u64 = 500;
8
9/// Resolve an address like "192.168.1.1:443" or "fe80::1%eth0:80" to a hostname.
10/// Returns the reverse DNS name if found within the timeout; otherwise returns `None`.
11/// Use only for display (CLI/TUI); does not block core types.
12pub fn resolve(addr: &str) -> Option<String> {
13    let socket_addr: SocketAddr = addr.to_socket_addrs().ok()?.next()?;
14    resolve_socket_addr(&socket_addr)
15}
16
17/// Reverse lookup for a `SocketAddr`. Time-bounded via a background thread.
18pub fn resolve_socket_addr(addr: &SocketAddr) -> Option<String> {
19    let addr = *addr;
20    let (tx, rx) = mpsc::channel();
21    std::thread::spawn(move || {
22        let name = dns_lookup::lookup_addr(&addr.ip()).ok();
23        let _ = tx.send(name);
24    });
25    rx.recv_timeout(Duration::from_millis(RESOLVE_TIMEOUT_MS))
26        .ok()
27        .flatten()
28}
29
30#[cfg(test)]
31mod tests {
32    use super::resolve;
33
34    #[test]
35    fn resolve_handles_invalid_input() {
36        // This should not panic and will likely return None.
37        let res = resolve("not-a-valid-socket-address");
38        assert!(res.is_none());
39    }
40}