summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-10-17 21:26:53 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-10-17 21:31:42 +0200
commit2e772194cf7cd7c37d24364a9f9d407dc96a25e8 (patch)
treeaa4c543d4ed445d72e2bc3bc722659087ede01c5
parent85b2378a07126fb64460f0a23e7a150d0e63d909 (diff)
tun: only call .Fd() once
Doing so tends to make the tunnel blocking, so we only retrieve it once before we call SetNonblock, and then cache the result.
-rw-r--r--tun/tun_darwin.go30
-rw-r--r--tun/tun_freebsd.go40
-rw-r--r--tun/tun_linux.go32
-rw-r--r--tun/tun_openbsd.go26
4 files changed, 67 insertions, 61 deletions
diff --git a/tun/tun_darwin.go b/tun/tun_darwin.go
index 24d2319..a4e2e9a 100644
--- a/tun/tun_darwin.go
+++ b/tun/tun_darwin.go
@@ -37,7 +37,8 @@ type sockaddrCtl struct {
type nativeTun struct {
name string
- fd *os.File
+ tunFile *os.File
+ fd uintptr
rwcancel *rwcancel.RWCancel
events chan TUNEvent
errors chan error
@@ -171,14 +172,15 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun := &nativeTun{
- fd: file,
- events: make(chan TUNEvent, 10),
- errors: make(chan error, 1),
+ tunFile: file,
+ fd: file.Fd(),
+ events: make(chan TUNEvent, 10),
+ errors: make(chan error, 1),
}
name, err := tun.Name()
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
@@ -190,19 +192,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
return iface.Index, nil
}()
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
- tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
+ tun.rwcancel, err = rwcancel.NewRWCancel(int(tun.fd))
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
@@ -226,7 +228,7 @@ func (tun *nativeTun) Name() (string, error) {
_, _, errno := unix.Syscall6(
unix.SYS_GETSOCKOPT,
- uintptr(tun.fd.Fd()),
+ uintptr(tun.fd),
2, /* #define SYSPROTO_CONTROL 2 */
2, /* #define UTUN_OPT_IFNAME 2 */
uintptr(unsafe.Pointer(&ifName)),
@@ -241,7 +243,7 @@ func (tun *nativeTun) Name() (string, error) {
}
func (tun *nativeTun) File() *os.File {
- return tun.fd
+ return tun.tunFile
}
func (tun *nativeTun) Events() chan TUNEvent {
@@ -254,7 +256,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
return 0, err
default:
buff := buff[offset-4:]
- n, err := tun.fd.Read(buff[:])
+ n, err := tun.tunFile.Read(buff[:])
if n < 4 {
return 0, err
}
@@ -294,13 +296,13 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
// write
- return tun.fd.Write(buff)
+ return tun.tunFile.Write(buff)
}
func (tun *nativeTun) Close() error {
var err3 error
err1 := tun.rwcancel.Cancel()
- err2 := tun.fd.Close()
+ err2 := tun.tunFile.Close()
if tun.routeSocket != -1 {
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
err3 = unix.Close(tun.routeSocket)
diff --git a/tun/tun_freebsd.go b/tun/tun_freebsd.go
index a0c8b28..c1ae30a 100644
--- a/tun/tun_freebsd.go
+++ b/tun/tun_freebsd.go
@@ -51,7 +51,8 @@ type ifstat struct {
type nativeTun struct {
name string
- fd *os.File
+ tunFile *os.File
+ fd uintptr
rwcancel *rwcancel.RWCancel
events chan TUNEvent
errors chan error
@@ -237,15 +238,15 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
return nil, fmt.Errorf("interface %s already exists", name)
}
- tunfile, err := os.OpenFile("/dev/tun", unix.O_RDWR, 0)
+ tunFile, err := os.OpenFile("/dev/tun", unix.O_RDWR, 0)
if err != nil {
return nil, err
}
- tunfd := tunfile.Fd()
+ tunfd := tunFile.Fd()
assignedName, err := tunName(tunfd)
if err != nil {
- tunfile.Close()
+ tunFile.Close()
return nil, err
}
@@ -293,25 +294,26 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
uintptr(unsafe.Pointer(&ifr)),
)
if errno != 0 {
- tunfile.Close()
+ tunFile.Close()
tunDestroy(name)
return nil, fmt.Errorf("failed to rename %s to %s: %s", assignedName, name, errno.Error())
}
- return CreateTUNFromFile(tunfile, mtu)
+ return CreateTUNFromFile(tunFile, mtu)
}
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun := &nativeTun{
- fd: file,
- events: make(chan TUNEvent, 10),
- errors: make(chan error, 1),
+ tunFile: file,
+ fd: file.Fd(),
+ events: make(chan TUNEvent, 10),
+ errors: make(chan error, 1),
}
name, err := tun.Name()
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
@@ -323,19 +325,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
return iface.Index, nil
}()
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
- tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
+ tun.rwcancel, err = rwcancel.NewRWCancel(int(tun.fd))
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
@@ -351,7 +353,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
}
func (tun *nativeTun) Name() (string, error) {
- name, err := tunName(tun.fd.Fd())
+ name, err := tunName(tun.fd)
if err != nil {
return "", err
}
@@ -360,7 +362,7 @@ func (tun *nativeTun) Name() (string, error) {
}
func (tun *nativeTun) File() *os.File {
- return tun.fd
+ return tun.tunFile
}
func (tun *nativeTun) Events() chan TUNEvent {
@@ -373,7 +375,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
return 0, err
default:
buff := buff[offset-4:]
- n, err := tun.fd.Read(buff[:])
+ n, err := tun.tunFile.Read(buff[:])
if n < 4 {
return 0, err
}
@@ -413,13 +415,13 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
// write
- return tun.fd.Write(buff)
+ return tun.tunFile.Write(buff)
}
func (tun *nativeTun) Close() error {
var err4 error
err1 := tun.rwcancel.Cancel()
- err2 := tun.fd.Close()
+ err2 := tun.tunFile.Close()
err3 := tunDestroy(tun.name)
if tun.routeSocket != -1 {
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
diff --git a/tun/tun_linux.go b/tun/tun_linux.go
index d0af51d..bb6bede 100644
--- a/tun/tun_linux.go
+++ b/tun/tun_linux.go
@@ -29,7 +29,8 @@ const (
)
type nativeTun struct {
- fd *os.File
+ tunFile *os.File
+ fd uintptr
fdCancel *rwcancel.RWCancel
index int32 // if index
name string // name of interface
@@ -43,7 +44,7 @@ type nativeTun struct {
}
func (tun *nativeTun) File() *os.File {
- return tun.fd
+ return tun.tunFile
}
func (tun *nativeTun) routineHackListener() {
@@ -51,7 +52,7 @@ func (tun *nativeTun) routineHackListener() {
/* This is needed for the detection to work across network namespaces
* If you are reading this and know a better method, please get in touch.
*/
- fd := int(tun.fd.Fd())
+ fd := int(tun.fd)
for {
_, err := unix.Write(fd, nil)
switch err {
@@ -266,7 +267,7 @@ func (tun *nativeTun) Name() (string, error) {
var ifr [ifReqSize]byte
_, _, errno := unix.Syscall(
unix.SYS_IOCTL,
- tun.fd.Fd(),
+ tun.fd,
uintptr(unix.TUNGETIFF),
uintptr(unsafe.Pointer(&ifr[0])),
)
@@ -307,7 +308,7 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
// write
- return tun.fd.Write(buff)
+ return tun.tunFile.Write(buff)
}
func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
@@ -316,10 +317,10 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
return 0, err
default:
if tun.nopi {
- return tun.fd.Read(buff[offset:])
+ return tun.tunFile.Read(buff[offset:])
} else {
buff := buff[offset-4:]
- n, err := tun.fd.Read(buff[:])
+ n, err := tun.tunFile.Read(buff[:])
if n < 4 {
return 0, err
}
@@ -354,7 +355,7 @@ func (tun *nativeTun) Close() error {
} else if tun.events != nil {
close(tun.events)
}
- err2 := tun.fd.Close()
+ err2 := tun.tunFile.Close()
err3 := tun.fdCancel.Cancel()
if err1 != nil {
@@ -413,23 +414,24 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun := &nativeTun{
- fd: file,
+ tunFile: file,
+ fd: file.Fd(),
events: make(chan TUNEvent, 5),
errors: make(chan error, 5),
statusListenersShutdown: make(chan struct{}),
- nopi: false,
+ nopi: false,
}
var err error
- tun.fdCancel, err = rwcancel.NewRWCancel(int(file.Fd()))
+ tun.fdCancel, err = rwcancel.NewRWCancel(int(tun.fd))
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
_, err = tun.Name()
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
@@ -442,12 +444,12 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun.netlinkSock, err = createNetlinkSocket()
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
tun.netlinkCancel, err = rwcancel.NewRWCancel(tun.netlinkSock)
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
diff --git a/tun/tun_openbsd.go b/tun/tun_openbsd.go
index 58871b1..b99c9f6 100644
--- a/tun/tun_openbsd.go
+++ b/tun/tun_openbsd.go
@@ -29,7 +29,7 @@ const _TUNSIFMODE = 0x8004745d
type nativeTun struct {
name string
- fd *os.File
+ tunFile *os.File
rwcancel *rwcancel.RWCancel
events chan TUNEvent
errors chan error
@@ -144,14 +144,14 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun := &nativeTun{
- fd: file,
- events: make(chan TUNEvent, 10),
- errors: make(chan error, 1),
+ tunFile: file,
+ events: make(chan TUNEvent, 10),
+ errors: make(chan error, 1),
}
name, err := tun.Name()
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
@@ -163,19 +163,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
return iface.Index, nil
}()
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
if err != nil {
- tun.fd.Close()
+ tun.tunFile.Close()
return nil, err
}
@@ -191,7 +191,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
}
func (tun *nativeTun) Name() (string, error) {
- gostat, err := tun.fd.Stat()
+ gostat, err := tun.tunFile.Stat()
if err != nil {
tun.name = ""
return "", err
@@ -202,7 +202,7 @@ func (tun *nativeTun) Name() (string, error) {
}
func (tun *nativeTun) File() *os.File {
- return tun.fd
+ return tun.tunFile
}
func (tun *nativeTun) Events() chan TUNEvent {
@@ -215,7 +215,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
return 0, err
default:
buff := buff[offset-4:]
- n, err := tun.fd.Read(buff[:])
+ n, err := tun.tunFile.Read(buff[:])
if n < 4 {
return 0, err
}
@@ -255,13 +255,13 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
// write
- return tun.fd.Write(buff)
+ return tun.tunFile.Write(buff)
}
func (tun *nativeTun) Close() error {
var err3 error
err1 := tun.rwcancel.Cancel()
- err2 := tun.fd.Close()
+ err2 := tun.tunFile.Close()
if tun.routeSocket != -1 {
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
err3 = unix.Close(tun.routeSocket)