summaryrefslogtreecommitdiffhomepage
path: root/tun/tun_linux.go
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 /tun/tun_linux.go
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.
Diffstat (limited to 'tun/tun_linux.go')
-rw-r--r--tun/tun_linux.go32
1 files changed, 17 insertions, 15 deletions
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
}