chore(connlib): assert that we don't emit WouldBlock errors (#7696)

When file descriptors like sockets or the TUN device are opened in
non-blocking mode, performing operations that would block emit the
`WouldBlock` IO error. These errors _should_ be translated into
`Poll::Pending` and have a waker registered that gets called whenever
the operation should be attempted again. Therefore, we should _never_
see these IO errors.

Previously, the implementation of the tunnel's event-loop did not yet
properly handle this backpressure and instead sometimes dropped packets
when it should have suspended. This has since been fixed but the then
introduced branch of just ignored the `io::ErrorKind::WouldBlock` errors
had remained.

Changing this to a debug-assert will alert us whenever we accidentally
break this without altering the behaviour of the release binary.
This commit is contained in:
Thomas Eizinger
2025-01-08 15:11:01 +01:00
committed by GitHub
parent 5ec9973b1f
commit 3a8c6c7182
2 changed files with 11 additions and 6 deletions

View File

@@ -89,9 +89,6 @@ where
self.handle_tunnel_event(event);
continue;
}
Poll::Ready(Err(e)) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Poll::Ready(Err(e))
if e.kind() == io::ErrorKind::NetworkUnreachable
|| e.kind() == io::ErrorKind::HostUnreachable =>
@@ -100,6 +97,11 @@ where
continue;
}
Poll::Ready(Err(e)) => {
debug_assert_ne!(
e.kind(),
io::ErrorKind::WouldBlock,
"Tunnel should never emit WouldBlock errors but suspend instead"
);
telemetry_event!("Tunnel error: {}", err_with_src(&e));
continue;
}

View File

@@ -77,9 +77,6 @@ impl Eventloop {
self.handle_tunnel_event(event);
continue;
}
Poll::Ready(Err(e)) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Poll::Ready(Err(e))
if e.kind() == io::ErrorKind::NetworkUnreachable
|| e.kind() == io::ErrorKind::HostUnreachable =>
@@ -88,6 +85,12 @@ impl Eventloop {
continue;
}
Poll::Ready(Err(e)) => {
debug_assert_ne!(
e.kind(),
io::ErrorKind::WouldBlock,
"Tunnel should never emit WouldBlock errors but suspend instead"
);
let e = anyhow::Error::from(e);
if e.root_cause().is::<ip_packet::ImpossibleTranslation>() {