mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-14 18:22:04 +00:00
net/tstun: split TUN events channel into up/down and MTU
We had a long-standing bug in which our TUN events channel was being received from simultaneously in two places. The first is wireguard-go. At wgengine/userspace.go:366, we pass e.tundev to wireguard-go, which starts a goroutine (RoutineTUNEventReader) that receives from that channel and uses events to adjust the MTU and bring the device up/down. At wgengine/userspace.go:374, we launch a goroutine that receives from e.tundev, logs MTU changes, and triggers state updates when up/down changes occur. Events were getting delivered haphazardly between the two of them. We don't really want wireguard-go to receive the up/down events; we control the state of the device explicitly by calling device.Up. And the userspace.go loop MTU logging duplicates logging that wireguard-go does when it received MTU updates. So this change splits the single TUN events channel into up/down and other (aka MTU), and sends them to the parties that ought to receive them. I'm actually a bit surprised that this hasn't caused more visible trouble. If a down event went to wireguard-go but the subsequent up event went to userspace.go, we could end up with the wireguard-go device disappearing. I believe that this may also (somewhat accidentally) be a fix for #1790. Signed-off-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
@@ -373,11 +373,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
||||
|
||||
go func() {
|
||||
up := false
|
||||
for event := range e.tundev.Events() {
|
||||
if event&tun.EventMTUUpdate != 0 {
|
||||
mtu, err := e.tundev.MTU()
|
||||
e.logf("external route MTU: %d (%v)", mtu, err)
|
||||
}
|
||||
for event := range e.tundev.EventsUpDown() {
|
||||
if event&tun.EventUp != 0 && !up {
|
||||
e.logf("external route: up")
|
||||
e.RequestStatus()
|
||||
|
Reference in New Issue
Block a user