diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-09-07 00:02:07 -0500 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-09-07 00:13:23 -0500 |
commit | 4cd06c0925ceb3dccd07b5ca1bdcdd6c24cfc77b (patch) | |
tree | 0332abfbd2b792fcaf2a14e7b0a8235a3f1f2dca | |
parent | d12eb91f9a309a30dd78e89ff71050842d4a4e6e (diff) |
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 <tb@theobuehler.org>
-rw-r--r-- | tun/tun_openbsd.go | 54 |
1 files 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), |