X-Git-Url: https://code.octet-stream.net/netwatcher/blobdiff_plain/7cbddf0b21f7cf98b46c66a430eb8221f3622d55..4abfa61b20e567fdd69ac3ca47a9c218971a30ff:/src/watch_linux.rs?ds=sidebyside diff --git a/src/watch_linux.rs b/src/watch_linux.rs index 4e4049b..efc3842 100644 --- a/src/watch_linux.rs +++ b/src/watch_linux.rs @@ -1,7 +1,6 @@ use std::os::fd::AsRawFd; use std::os::fd::OwnedFd; -use nix::libc::nlmsghdr; use nix::libc::RTMGRP_IPV4_IFADDR; use nix::libc::RTMGRP_IPV6_IFADDR; use nix::libc::RTMGRP_LINK; @@ -16,21 +15,23 @@ use nix::sys::socket::SockProtocol; use nix::sys::socket::SockType; use crate::Error; +use crate::List; use crate::Update; pub(crate) struct WatchHandle { // PROBLEM: close() doesn't cancel recv() for a netlink socket + // SOLUTION: open a pipe() and use poll() inside the thread to watch for cancellation too sockfd: OwnedFd, } -pub(crate) fn watch_interfaces( +pub(crate) fn watch_interfaces( callback: F, ) -> Result { let sockfd = start_watcher_thread(callback)?; Ok(WatchHandle { sockfd }) } -fn start_watcher_thread(callback: F) -> Result { +fn start_watcher_thread(mut callback: F) -> Result { let sockfd = socket(AddressFamily::Netlink, SockType::Raw, SockFlag::empty(), Some(SockProtocol::NetlinkRoute)) .map_err(|_| Error::Internal)?; // TODO: proper errors let sa_nl = NetlinkAddr::new(0, (RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR) as u32); @@ -40,15 +41,30 @@ fn start_watcher_thread(callback: F) -> Result