From 4cd06c0925ceb3dccd07b5ca1bdcdd6c24cfc77b Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 7 Sep 2019 00:02:07 -0500 Subject: tun: openbsd: check for interface already being up In some cases, we operate on an already-up interface, or the user brings up the interface before we start monitoring. For those situations, we should first check if the interface is already up. This still technically races between the initial check and the start of the route loop, but fixing that is a bit ugly and probably not worth it at the moment. Reported-by: Theo Buehler --- tun/tun_openbsd.go | 54 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/tun/tun_openbsd.go b/tun/tun_openbsd.go index bbc0432..44cedaa 100644 --- a/tun/tun_openbsd.go +++ b/tun/tun_openbsd.go @@ -42,13 +42,41 @@ func (tun *NativeTun) routineRouteListener(tunIfindex int) { defer close(tun.events) + check := func() bool { + iface, err := net.InterfaceByIndex(tunIfindex) + if err != nil { + tun.errors <- err + return true + } + + // Up / Down event + up := (iface.Flags & net.FlagUp) != 0 + if up != statusUp && up { + tun.events <- EventUp + } + if up != statusUp && !up { + tun.events <- EventDown + } + statusUp = up + + // MTU changes + if iface.MTU != statusMTU { + tun.events <- EventMTUUpdate + } + statusMTU = iface.MTU + return false + } + + if check() { + return + } + data := make([]byte, os.Getpagesize()) for { - retry: n, err := unix.Read(tun.routeSocket, data) if err != nil { if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINTR { - goto retry + continue } tun.errors <- err return @@ -65,28 +93,9 @@ func (tun *NativeTun) routineRouteListener(tunIfindex int) { if ifindex != tunIfindex { continue } - - iface, err := net.InterfaceByIndex(ifindex) - if err != nil { - tun.errors <- err + if check() { return } - - // Up / Down event - up := (iface.Flags & net.FlagUp) != 0 - if up != statusUp && up { - tun.events <- EventUp - } - if up != statusUp && !up { - tun.events <- EventDown - } - statusUp = up - - // MTU changes - if iface.MTU != statusMTU { - tun.events <- EventMTUUpdate - } - statusMTU = iface.MTU } } @@ -140,7 +149,6 @@ func CreateTUN(name string, mtu int) (Device, error) { } func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { - tun := &NativeTun{ tunFile: file, events: make(chan Event, 10), -- cgit v1.2.3