summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-09-07 00:02:07 -0500
committerJason A. Donenfeld <Jason@zx2c4.com>2019-09-07 00:13:23 -0500
commit4cd06c0925ceb3dccd07b5ca1bdcdd6c24cfc77b (patch)
tree0332abfbd2b792fcaf2a14e7b0a8235a3f1f2dca
parentd12eb91f9a309a30dd78e89ff71050842d4a4e6e (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.go54
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),