summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-05-20 18:26:01 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2021-05-20 18:26:01 +0200
commit99e8b4ba605538b64c693c4056904f34810c3938 (patch)
tree87bc010144d676f7d74d838e3f475876ffa808fa
parentbd83f0ac993bc5bee0b0f96c74d24cab142ba385 (diff)
tun: linux: account for interface removal from outside
On Linux we can run `ip link del wg0`, in which case the fd becomes stale, and we should exit. Since this is an intentional action, don't treat it as an error. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--device/send.go6
-rw-r--r--tun/tun_linux.go53
2 files changed, 33 insertions, 26 deletions
diff --git a/device/send.go b/device/send.go
index e07df1b..a4f07e4 100644
--- a/device/send.go
+++ b/device/send.go
@@ -8,7 +8,9 @@ package device
import (
"bytes"
"encoding/binary"
+ "errors"
"net"
+ "os"
"sync"
"sync/atomic"
"time"
@@ -227,7 +229,9 @@ func (device *Device) RoutineReadFromTUN() {
if err != nil {
if !device.isClosed() {
- device.log.Errorf("Failed to read packet from TUN device: %v", err)
+ if !errors.Is(err, os.ErrClosed) {
+ device.log.Errorf("Failed to read packet from TUN device: %v", err)
+ }
go device.Close()
}
device.PutMessageBuffer(elem.buffer)
diff --git a/tun/tun_linux.go b/tun/tun_linux.go
index 46eb171..466a805 100644
--- a/tun/tun_linux.go
+++ b/tun/tun_linux.go
@@ -10,6 +10,7 @@ package tun
import (
"bytes"
+ "errors"
"fmt"
"os"
"sync"
@@ -329,32 +330,30 @@ func (tun *NativeTun) nameSlow() (string, error) {
return string(name), nil
}
-func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
-
+func (tun *NativeTun) Write(buf []byte, offset int) (int, error) {
if tun.nopi {
- buff = buff[offset:]
+ buf = buf[offset:]
} else {
// reserve space for header
-
- buff = buff[offset-4:]
+ buf = buf[offset-4:]
// add packet information header
-
- buff[0] = 0x00
- buff[1] = 0x00
-
- if buff[4]>>4 == ipv6.Version {
- buff[2] = 0x86
- buff[3] = 0xdd
+ buf[0] = 0x00
+ buf[1] = 0x00
+ if buf[4]>>4 == ipv6.Version {
+ buf[2] = 0x86
+ buf[3] = 0xdd
} else {
- buff[2] = 0x08
- buff[3] = 0x00
+ buf[2] = 0x08
+ buf[3] = 0x00
}
}
- // write
-
- return tun.tunFile.Write(buff)
+ n, err := tun.tunFile.Write(buf)
+ if errors.Is(err, syscall.EBADFD) {
+ err = os.ErrClosed
+ }
+ return n, err
}
func (tun *NativeTun) Flush() error {
@@ -362,22 +361,26 @@ func (tun *NativeTun) Flush() error {
return nil
}
-func (tun *NativeTun) Read(buff []byte, offset int) (int, error) {
+func (tun *NativeTun) Read(buf []byte, offset int) (n int, err error) {
select {
- case err := <-tun.errors:
- return 0, err
+ case err = <-tun.errors:
default:
if tun.nopi {
- return tun.tunFile.Read(buff[offset:])
+ n, err = tun.tunFile.Read(buf[offset:])
} else {
- buff := buff[offset-4:]
- n, err := tun.tunFile.Read(buff[:])
+ buff := buf[offset-4:]
+ n, err = tun.tunFile.Read(buff[:])
+ if errors.Is(err, syscall.EBADFD) {
+ err = os.ErrClosed
+ }
if n < 4 {
- return 0, err
+ n = 0
+ } else {
+ n -= 4
}
- return n - 4, err
}
}
+ return
}
func (tun *NativeTun) Events() chan Event {