@@ -120,6 +120,8 @@ impl SocketCollector { |
| 120 | 120 | let mut socket = Socket::new(NETLINK_SOCK_DIAG)?; |
| 121 | 121 | socket.bind_auto()?; |
| 122 | 122 | socket.connect(&SocketAddr::new(0, 0))?; |
| 123 | + // Set non-blocking to prevent hanging on recv |
| 124 | + socket.set_non_blocking(true)?; |
| 123 | 125 | self.nl_socket = Some(socket); |
| 124 | 126 | } |
| 125 | 127 | Ok(()) |
@@ -284,10 +286,19 @@ impl SocketCollector { |
| 284 | 286 | socket.send(&send_buf, 0)?; |
| 285 | 287 | |
| 286 | 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 | 294 | let n = match socket.recv(&mut recv_buf, 0) { |
| 289 | 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 | 302 | Err(e) => return Err(e), |
| 292 | 303 | }; |
| 293 | 304 | |
@@ -305,7 +316,10 @@ impl SocketCollector { |
| 305 | 316 | offset += msg.header.length as usize; |
| 306 | 317 | |
| 307 | 318 | match msg.payload { |
| 308 | | - NetlinkPayload::Done(_) => break, |
| 319 | + NetlinkPayload::Done(_) => { |
| 320 | + done = true; |
| 321 | + break; |
| 322 | + } |
| 309 | 323 | NetlinkPayload::Error(e) => { |
| 310 | 324 | if e.code.is_some() { |
| 311 | 325 | return Err(io::Error::new(io::ErrorKind::Other, "netlink error")); |