@@ -120,6 +120,8 @@ impl SocketCollector { |
| 120 | let mut socket = Socket::new(NETLINK_SOCK_DIAG)?; | 120 | let mut socket = Socket::new(NETLINK_SOCK_DIAG)?; |
| 121 | socket.bind_auto()?; | 121 | socket.bind_auto()?; |
| 122 | socket.connect(&SocketAddr::new(0, 0))?; | 122 | socket.connect(&SocketAddr::new(0, 0))?; |
| | 123 | + // Set non-blocking to prevent hanging on recv |
| | 124 | + socket.set_non_blocking(true)?; |
| 123 | self.nl_socket = Some(socket); | 125 | self.nl_socket = Some(socket); |
| 124 | } | 126 | } |
| 125 | Ok(()) | 127 | Ok(()) |
@@ -284,10 +286,19 @@ impl SocketCollector { |
| 284 | socket.send(&send_buf, 0)?; | 286 | socket.send(&send_buf, 0)?; |
| 285 | | 287 | |
| 286 | let mut recv_buf = vec![0u8; 65536]; | 288 | let mut recv_buf = vec![0u8; 65536]; |
| 287 | - loop { | 289 | + let mut done = false; |
| | 290 | + let mut retries = 0; |
| | 291 | + const MAX_RETRIES: u32 = 100; // 100ms max wait |
| | 292 | + |
| | 293 | + while !done && retries < MAX_RETRIES { |
| 288 | let n = match socket.recv(&mut recv_buf, 0) { | 294 | let n = match socket.recv(&mut recv_buf, 0) { |
| 289 | Ok(n) => n, | 295 | Ok(n) => n, |
| 290 | - Err(e) if e.kind() == io::ErrorKind::WouldBlock => break, | 296 | + Err(e) if e.kind() == io::ErrorKind::WouldBlock => { |
| | 297 | + // Wait a bit for data to arrive |
| | 298 | + retries += 1; |
| | 299 | + std::thread::sleep(std::time::Duration::from_millis(1)); |
| | 300 | + continue; |
| | 301 | + } |
| 291 | Err(e) => return Err(e), | 302 | Err(e) => return Err(e), |
| 292 | }; | 303 | }; |
| 293 | | 304 | |
@@ -305,7 +316,10 @@ impl SocketCollector { |
| 305 | offset += msg.header.length as usize; | 316 | offset += msg.header.length as usize; |
| 306 | | 317 | |
| 307 | match msg.payload { | 318 | match msg.payload { |
| 308 | - NetlinkPayload::Done(_) => break, | 319 | + NetlinkPayload::Done(_) => { |
| | 320 | + done = true; |
| | 321 | + break; |
| | 322 | + } |
| 309 | NetlinkPayload::Error(e) => { | 323 | NetlinkPayload::Error(e) => { |
| 310 | if e.code.is_some() { | 324 | if e.code.is_some() { |
| 311 | return Err(io::Error::new(io::ErrorKind::Other, "netlink error")); | 325 | return Err(io::Error::new(io::ErrorKind::Other, "netlink error")); |