From 3f3e56f4124fff853d50e30c05c86e08d758a3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20Lensb=C3=B8l?= Date: Mon, 21 Sep 2026 13:56:52 -0400 Subject: [PATCH] wgengine/netstack: avoid returning from sender goroutines on error (#21332) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returning from injectToHost and injectToWireGuard leaves the two goroutines dead and the host without having a way to send traffic. This is especially relevant for android where the tundev is torn down and recreated for every call to updateTUN() from a route table change or roaming between networks. Fixes #21155 Signed-off-by: Claus Lensbøl --- wgengine/netstack/netstack.go | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/wgengine/netstack/netstack.go b/wgengine/netstack/netstack.go index d066d264d..90450db78 100644 --- a/wgengine/netstack/netstack.go +++ b/wgengine/netstack/netstack.go @@ -1055,7 +1055,16 @@ func (ns *Impl) injectToWireGuard() { } if err := ns.tundev.InjectOutboundPacketBuffer(pkt); err != nil { ns.logf("netstack injectToWireGuard err: %v", err) - return + // When failing to inject an outbound packet buffer, log the error, but + // continue serving the ReadContext for sending subsequent packets, as + // nothing manages or restarts a failed injectToWireGuard. An error here + // only applies to the current packet and should not terminate the long-lived + // packet pump. + // The exception to this is if the context has ended, indicating a shutdown. + if ns.ctx.Err() != nil { + return + } + continue } } } @@ -1097,7 +1106,16 @@ func (ns *Impl) injectToHost() { } if err := ns.tundev.InjectInboundPacketBuffer(pkt, inboundSlab, packets, writeBufs); err != nil { ns.logf("netstack injectToHost err: %v", err) - return + // When failing to inject an outbound packet buffer, log the error, but + // continue serving the ReadContext for sending subsequent packets, as + // nothing manages or restarts a failed injectToHost. An error here + // only applies to the current packet and should not terminate the long-lived + // packet pump. + // The exception to this is if the context has ended, indicating a shutdown. + if ns.ctx.Err() != nil { + return + } + continue } } }