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>
This commit is contained in:
parent
bd83f0ac99
commit
99e8b4ba60
|
@ -8,7 +8,9 @@ package device
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
@ -227,7 +229,9 @@ func (device *Device) RoutineReadFromTUN() {
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !device.isClosed() {
|
if !device.isClosed() {
|
||||||
|
if !errors.Is(err, os.ErrClosed) {
|
||||||
device.log.Errorf("Failed to read packet from TUN device: %v", err)
|
device.log.Errorf("Failed to read packet from TUN device: %v", err)
|
||||||
|
}
|
||||||
go device.Close()
|
go device.Close()
|
||||||
}
|
}
|
||||||
device.PutMessageBuffer(elem.buffer)
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
|
|
@ -10,6 +10,7 @@ package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -329,32 +330,30 @@ func (tun *NativeTun) nameSlow() (string, error) {
|
||||||
return string(name), nil
|
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 {
|
if tun.nopi {
|
||||||
buff = buff[offset:]
|
buf = buf[offset:]
|
||||||
} else {
|
} else {
|
||||||
// reserve space for header
|
// reserve space for header
|
||||||
|
buf = buf[offset-4:]
|
||||||
buff = buff[offset-4:]
|
|
||||||
|
|
||||||
// add packet information header
|
// add packet information header
|
||||||
|
buf[0] = 0x00
|
||||||
buff[0] = 0x00
|
buf[1] = 0x00
|
||||||
buff[1] = 0x00
|
if buf[4]>>4 == ipv6.Version {
|
||||||
|
buf[2] = 0x86
|
||||||
if buff[4]>>4 == ipv6.Version {
|
buf[3] = 0xdd
|
||||||
buff[2] = 0x86
|
|
||||||
buff[3] = 0xdd
|
|
||||||
} else {
|
} else {
|
||||||
buff[2] = 0x08
|
buf[2] = 0x08
|
||||||
buff[3] = 0x00
|
buf[3] = 0x00
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write
|
n, err := tun.tunFile.Write(buf)
|
||||||
|
if errors.Is(err, syscall.EBADFD) {
|
||||||
return tun.tunFile.Write(buff)
|
err = os.ErrClosed
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Flush() error {
|
func (tun *NativeTun) Flush() error {
|
||||||
|
@ -362,23 +361,27 @@ func (tun *NativeTun) Flush() error {
|
||||||
return nil
|
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 {
|
select {
|
||||||
case err := <-tun.errors:
|
case err = <-tun.errors:
|
||||||
return 0, err
|
|
||||||
default:
|
default:
|
||||||
if tun.nopi {
|
if tun.nopi {
|
||||||
return tun.tunFile.Read(buff[offset:])
|
n, err = tun.tunFile.Read(buf[offset:])
|
||||||
} else {
|
} else {
|
||||||
buff := buff[offset-4:]
|
buff := buf[offset-4:]
|
||||||
n, err := tun.tunFile.Read(buff[:])
|
n, err = tun.tunFile.Read(buff[:])
|
||||||
|
if errors.Is(err, syscall.EBADFD) {
|
||||||
|
err = os.ErrClosed
|
||||||
|
}
|
||||||
if n < 4 {
|
if n < 4 {
|
||||||
return 0, err
|
n = 0
|
||||||
}
|
} else {
|
||||||
return n - 4, err
|
n -= 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Events() chan Event {
|
func (tun *NativeTun) Events() chan Event {
|
||||||
return tun.events
|
return tun.events
|
||||||
|
|
Loading…
Reference in a new issue