diff --git a/device.go b/device.go index 5f468b2..e116731 100644 --- a/device.go +++ b/device.go @@ -8,6 +8,7 @@ package main import ( "./ratelimiter" + "./tun" "runtime" "sync" "sync/atomic" @@ -80,7 +81,7 @@ type Device struct { } tun struct { - device TUNDevice + device tun.TUNDevice mtu int32 } } @@ -250,7 +251,7 @@ func (device *Device) PutMessageBuffer(msg *[MaxMessageSize]byte) { device.pool.messageBuffers.Put(msg) } -func NewDevice(tun TUNDevice, logger *Logger) *Device { +func NewDevice(tunDevice tun.TUNDevice, logger *Logger) *Device { device := new(Device) device.isUp.Set(false) @@ -258,7 +259,7 @@ func NewDevice(tun TUNDevice, logger *Logger) *Device { device.log = logger - device.tun.device = tun + device.tun.device = tunDevice mtu, err := device.tun.device.MTU() if err != nil { logger.Error.Println("Trouble determining MTU, assuming default:", err) diff --git a/main.go b/main.go index 523a927..a04cd15 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ package main import ( + "./tun" "fmt" "os" "os/signal" @@ -125,10 +126,10 @@ func main() { // open TUN device (or use supplied fd) - tun, err := func() (TUNDevice, error) { + tun, err := func() (tun.TUNDevice, error) { tunFdStr := os.Getenv(ENV_WG_TUN_FD) if tunFdStr == "" { - return CreateTUN(interfaceName) + return tun.CreateTUN(interfaceName, DefaultMTU) } // construct tun device from supplied fd @@ -139,7 +140,7 @@ func main() { } file := os.NewFile(uintptr(fd), "") - return CreateTUNFromFile(file) + return tun.CreateTUNFromFile(file, DefaultMTU) }() if err == nil { diff --git a/misc.go b/misc.go index aeda813..af61718 100644 --- a/misc.go +++ b/misc.go @@ -41,13 +41,6 @@ func (a *AtomicBool) Set(val bool) { atomic.StoreInt32(&a.flag, flag) } -/* Integer manipulation */ - -func toInt32(n uint32) int32 { - mask := uint32(1 << 31) - return int32(-(n & mask) + (n & ^mask)) -} - func min(a, b uint) uint { if a > b { return b diff --git a/tun.go b/tun.go index d2fb708..9752636 100644 --- a/tun.go +++ b/tun.go @@ -7,30 +7,12 @@ package main import ( - "os" + "./tun" "sync/atomic" ) const DefaultMTU = 1420 -type TUNEvent int - -const ( - TUNEventUp = 1 << iota - TUNEventDown - TUNEventMTUUpdate -) - -type TUNDevice interface { - File() *os.File // returns the file descriptor of the device - Read([]byte, int) (int, error) // read a packet from the device (without any additional headers) - Write([]byte, int) (int, error) // writes a packet to the device (without any additional headers) - MTU() (int, error) // returns the MTU of the device - Name() (string, error) // fetches and returns the current name - Events() chan TUNEvent // returns a constant channel of events related to the device - Close() error // stops the device and closes the event channel -} - func (device *Device) RoutineTUNEventReader() { setUp := false logDebug := device.log.Debug @@ -41,7 +23,7 @@ func (device *Device) RoutineTUNEventReader() { device.state.starting.Done() for event := range device.tun.device.Events() { - if event&TUNEventMTUUpdate != 0 { + if event&tun.TUNEventMTUUpdate != 0 { mtu, err := device.tun.device.MTU() old := atomic.LoadInt32(&device.tun.mtu) if err != nil { @@ -56,13 +38,13 @@ func (device *Device) RoutineTUNEventReader() { } } - if event&TUNEventUp != 0 && !setUp { + if event&tun.TUNEventUp != 0 && !setUp { logInfo.Println("Interface set up") setUp = true device.Up() } - if event&TUNEventDown != 0 && setUp { + if event&tun.TUNEventDown != 0 && setUp { logInfo.Println("Interface set down") setUp = false device.Down() diff --git a/tun/tun.go b/tun/tun.go new file mode 100644 index 0000000..a39ced5 --- /dev/null +++ b/tun/tun.go @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2017-2018 Jason A. Donenfeld . All Rights Reserved. + * Copyright (C) 2017-2018 Mathias N. Hall-Andersen . + */ + +package tun + +import "os" + +type TUNEvent int + +const ( + TUNEventUp = 1 << iota + TUNEventDown + TUNEventMTUUpdate +) + +type TUNDevice interface { + File() *os.File // returns the file descriptor of the device + Read([]byte, int) (int, error) // read a packet from the device (without any additional headers) + Write([]byte, int) (int, error) // writes a packet to the device (without any additional headers) + MTU() (int, error) // returns the MTU of the device + Name() (string, error) // fetches and returns the current name + Events() chan TUNEvent // returns a constant channel of events related to the device + Close() error // stops the device and closes the event channel +} diff --git a/tun_darwin.go b/tun/tun_darwin.go similarity index 86% rename from tun_darwin.go rename to tun/tun_darwin.go index e5a01a7..fcbb4f9 100644 --- a/tun_darwin.go +++ b/tun/tun_darwin.go @@ -4,11 +4,10 @@ * Copyright (C) 2017-2018 Mathias N. Hall-Andersen . */ -package main +package tun import ( - "./rwcancel" - "encoding/binary" + "../rwcancel" "errors" "fmt" "golang.org/x/net/ipv6" @@ -34,7 +33,7 @@ type sockaddrCtl struct { scReserved [5]uint32 } -type NativeTun struct { +type nativeTun struct { name string fd *os.File rwcancel *rwcancel.RWCancel @@ -45,7 +44,7 @@ type NativeTun struct { var sockaddrCtlSize uintptr = 32 -func (tun *NativeTun) RoutineRouteListener(tunIfindex int) { +func (tun *nativeTun) routineRouteListener(tunIfindex int) { var ( statusUp bool statusMTU int @@ -97,7 +96,7 @@ func (tun *NativeTun) RoutineRouteListener(tunIfindex int) { } } -func CreateTUN(name string) (TUNDevice, error) { +func CreateTUN(name string, mtu int) (TUNDevice, error) { ifIndex := -1 if name != "utun" { _, err := fmt.Sscanf(name, "utun%d", &ifIndex) @@ -151,21 +150,21 @@ func CreateTUN(name string) (TUNDevice, error) { return nil, fmt.Errorf("SYS_CONNECT: %v", errno) } - tun, err := CreateTUNFromFile(os.NewFile(uintptr(fd), "")) + tun, err := CreateTUNFromFile(os.NewFile(uintptr(fd), ""), mtu) if err == nil && name == "utun" { fname := os.Getenv("WG_TUN_NAME_FILE") if fname != "" { - ioutil.WriteFile(fname, []byte(tun.(*NativeTun).name+"\n"), 0400) + ioutil.WriteFile(fname, []byte(tun.(*nativeTun).name+"\n"), 0400) } } return tun, err } -func CreateTUNFromFile(file *os.File) (TUNDevice, error) { +func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) { - tun := &NativeTun{ + tun := &nativeTun{ fd: file, events: make(chan TUNEvent, 10), errors: make(chan error, 1), @@ -201,10 +200,9 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) { return nil, err } - go tun.RoutineRouteListener(tunIfindex) + go tun.routineRouteListener(tunIfindex) - // set default MTU - err = tun.setMTU(DefaultMTU) + err = tun.setMTU(mtu) if err != nil { tun.Close() return nil, err @@ -213,7 +211,7 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) { return tun, nil } -func (tun *NativeTun) Name() (string, error) { +func (tun *nativeTun) Name() (string, error) { var ifName struct { name [16]byte @@ -236,15 +234,15 @@ func (tun *NativeTun) Name() (string, error) { return tun.name, nil } -func (tun *NativeTun) File() *os.File { +func (tun *nativeTun) File() *os.File { return tun.fd } -func (tun *NativeTun) Events() chan TUNEvent { +func (tun *nativeTun) Events() chan TUNEvent { return tun.events } -func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) { +func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) { select { case err := <-tun.errors: return 0, err @@ -258,7 +256,7 @@ func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) { } } -func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { +func (tun *nativeTun) Read(buff []byte, offset int) (int, error) { for { n, err := tun.doRead(buff, offset) if err == nil || !rwcancel.ErrorIsEAGAIN(err) { @@ -270,7 +268,7 @@ func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { } } -func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { +func (tun *nativeTun) Write(buff []byte, offset int) (int, error) { // reserve space for header @@ -293,7 +291,7 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { return tun.fd.Write(buff) } -func (tun *NativeTun) Close() error { +func (tun *nativeTun) Close() error { var err3 error err1 := tun.rwcancel.Cancel() err2 := tun.fd.Close() @@ -313,7 +311,7 @@ func (tun *NativeTun) Close() error { return err3 } -func (tun *NativeTun) setMTU(n int) error { +func (tun *nativeTun) setMTU(n int) error { // open datagram socket @@ -335,7 +333,7 @@ func (tun *NativeTun) setMTU(n int) error { var ifr [32]byte copy(ifr[:], tun.name) - binary.LittleEndian.PutUint32(ifr[16:20], uint32(n)) + *(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = uint32(n) _, _, errno := unix.Syscall( unix.SYS_IOCTL, uintptr(fd), @@ -350,7 +348,7 @@ func (tun *NativeTun) setMTU(n int) error { return nil } -func (tun *NativeTun) MTU() (int, error) { +func (tun *nativeTun) MTU() (int, error) { // open datagram socket diff --git a/tun_freebsd.go b/tun/tun_freebsd.go similarity index 91% rename from tun_freebsd.go rename to tun/tun_freebsd.go index 5461c45..b4cf57d 100644 --- a/tun_freebsd.go +++ b/tun/tun_freebsd.go @@ -3,10 +3,10 @@ * Copyright (C) 2017-2018 Jason A. Donenfeld . All Rights Reserved. */ -package main +package tun import ( - "./rwcancel" + "../rwcancel" "bytes" "errors" "fmt" @@ -48,7 +48,7 @@ type ifstat struct { Ascii [_IFSTATMAX]byte } -type NativeTun struct { +type nativeTun struct { name string fd *os.File rwcancel *rwcancel.RWCancel @@ -57,7 +57,7 @@ type NativeTun struct { routeSocket int } -func (tun *NativeTun) RoutineRouteListener(tunIfindex int) { +func (tun *nativeTun) routineRouteListener(tunIfindex int) { var ( statusUp bool statusMTU int @@ -221,7 +221,7 @@ func tunDestroy(name string) error { return nil } -func CreateTUN(name string) (TUNDevice, error) { +func CreateTUN(name string, mtu int) (TUNDevice, error) { if len(name) > unix.IFNAMSIZ-1 { return nil, errors.New("interface name too long") } @@ -306,12 +306,12 @@ func CreateTUN(name string) (TUNDevice, error) { return nil, fmt.Errorf("failed to rename %s to %s: %s", assignedName, name, errno.Error()) } - return CreateTUNFromFile(tunfile) + return CreateTUNFromFile(tunfile, mtu) } -func CreateTUNFromFile(file *os.File) (TUNDevice, error) { +func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) { - tun := &NativeTun{ + tun := &nativeTun{ fd: file, events: make(chan TUNEvent, 10), errors: make(chan error, 1), @@ -347,10 +347,9 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) { return nil, err } - go tun.RoutineRouteListener(tunIfindex) + go tun.routineRouteListener(tunIfindex) - // set default MTU - err = tun.setMTU(DefaultMTU) + err = tun.setMTU(mtu) if err != nil { tun.Close() return nil, err @@ -359,7 +358,7 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) { return tun, nil } -func (tun *NativeTun) Name() (string, error) { +func (tun *nativeTun) Name() (string, error) { name, err := tunName(tun.fd.Fd()) if err != nil { return "", err @@ -368,15 +367,15 @@ func (tun *NativeTun) Name() (string, error) { return name, nil } -func (tun *NativeTun) File() *os.File { +func (tun *nativeTun) File() *os.File { return tun.fd } -func (tun *NativeTun) Events() chan TUNEvent { +func (tun *nativeTun) Events() chan TUNEvent { return tun.events } -func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) { +func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) { select { case err := <-tun.errors: return 0, err @@ -390,7 +389,7 @@ func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) { } } -func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { +func (tun *nativeTun) Read(buff []byte, offset int) (int, error) { for { n, err := tun.doRead(buff, offset) if err == nil || !rwcancel.ErrorIsEAGAIN(err) { @@ -402,7 +401,7 @@ func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { } } -func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { +func (tun *nativeTun) Write(buff []byte, offset int) (int, error) { // reserve space for header @@ -425,7 +424,7 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { return tun.fd.Write(buff) } -func (tun *NativeTun) Close() error { +func (tun *nativeTun) Close() error { var err4 error err1 := tun.rwcancel.Cancel() err2 := tun.fd.Close() @@ -449,7 +448,7 @@ func (tun *NativeTun) Close() error { return err4 } -func (tun *NativeTun) setMTU(n int) error { +func (tun *nativeTun) setMTU(n int) error { // open datagram socket var fd int @@ -486,7 +485,7 @@ func (tun *NativeTun) setMTU(n int) error { return nil } -func (tun *NativeTun) MTU() (int, error) { +func (tun *nativeTun) MTU() (int, error) { // open datagram socket fd, err := unix.Socket( diff --git a/tun_linux.go b/tun/tun_linux.go similarity index 86% rename from tun_linux.go rename to tun/tun_linux.go index db9cb51..acfb942 100644 --- a/tun_linux.go +++ b/tun/tun_linux.go @@ -6,15 +6,14 @@ /* Copyright 2018 Jason A. Donenfeld . All Rights Reserved. */ -package main +package tun /* Implementation of the TUN device interface for linux */ import ( - "./rwcancel" + "../rwcancel" "bytes" - "encoding/binary" "errors" "fmt" "golang.org/x/net/ipv6" @@ -32,7 +31,7 @@ const ( ifReqSize = unix.IFNAMSIZ + 64 ) -type NativeTun struct { +type nativeTun struct { fd *os.File fdCancel *rwcancel.RWCancel index int32 // if index @@ -46,11 +45,11 @@ type NativeTun struct { statusListenersShutdown chan struct{} } -func (tun *NativeTun) File() *os.File { +func (tun *nativeTun) File() *os.File { return tun.fd } -func (tun *NativeTun) RoutineHackListener() { +func (tun *nativeTun) routineHackListener() { defer tun.hackListenerClosed.Unlock() /* 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. @@ -90,7 +89,7 @@ func createNetlinkSocket() (int, error) { return sock, nil } -func (tun *NativeTun) RoutineNetlinkListener() { +func (tun *nativeTun) routineNetlinkListener() { defer func() { unix.Close(tun.netlinkSock) tun.hackListenerClosed.Lock() @@ -160,7 +159,7 @@ func (tun *NativeTun) RoutineNetlinkListener() { } } -func (tun *NativeTun) isUp() (bool, error) { +func (tun *nativeTun) isUp() (bool, error) { inter, err := net.InterfaceByName(tun.name) return inter.Flags&net.FlagUp != 0, err } @@ -194,11 +193,10 @@ func getIFIndex(name string) (int32, error) { return 0, errno } - index := binary.LittleEndian.Uint32(ifr[unix.IFNAMSIZ:]) - return toInt32(index), nil + return *(*int32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])), nil } -func (tun *NativeTun) setMTU(n int) error { +func (tun *nativeTun) setMTU(n int) error { // open datagram socket @@ -218,7 +216,7 @@ func (tun *NativeTun) setMTU(n int) error { var ifr [ifReqSize]byte copy(ifr[:], tun.name) - binary.LittleEndian.PutUint32(ifr[16:20], uint32(n)) + *(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = uint32(n) _, _, errno := unix.Syscall( unix.SYS_IOCTL, uintptr(fd), @@ -233,7 +231,7 @@ func (tun *NativeTun) setMTU(n int) error { return nil } -func (tun *NativeTun) MTU() (int, error) { +func (tun *nativeTun) MTU() (int, error) { // open datagram socket @@ -263,10 +261,10 @@ func (tun *NativeTun) MTU() (int, error) { return 0, errors.New("failed to get MTU of TUN device: " + strconv.FormatInt(int64(errno), 10)) } - return int(*(*int32)(unsafe.Pointer(&ifr[16]))), nil + return int(*(*int32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ]))), nil } -func (tun *NativeTun) Name() (string, error) { +func (tun *nativeTun) Name() (string, error) { var ifr [ifReqSize]byte _, _, errno := unix.Syscall( @@ -287,7 +285,7 @@ func (tun *NativeTun) Name() (string, error) { return tun.name, nil } -func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { +func (tun *nativeTun) Write(buff []byte, offset int) (int, error) { if tun.nopi { buff = buff[offset:] @@ -315,7 +313,7 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { return tun.fd.Write(buff) } -func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) { +func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) { select { case err := <-tun.errors: return 0, err @@ -333,7 +331,7 @@ func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) { } } -func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { +func (tun *nativeTun) Read(buff []byte, offset int) (int, error) { for { n, err := tun.doRead(buff, offset) if err == nil || !rwcancel.ErrorIsEAGAIN(err) { @@ -345,11 +343,11 @@ func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { } } -func (tun *NativeTun) Events() chan TUNEvent { +func (tun *nativeTun) Events() chan TUNEvent { return tun.events } -func (tun *NativeTun) Close() error { +func (tun *nativeTun) Close() error { var err1 error if tun.statusListenersShutdown != nil { close(tun.statusListenersShutdown) @@ -371,7 +369,7 @@ func (tun *NativeTun) Close() error { return err3 } -func CreateTUN(name string) (TUNDevice, error) { +func CreateTUN(name string, mtu int) (TUNDevice, error) { // open clone device @@ -401,7 +399,7 @@ func CreateTUN(name string) (TUNDevice, error) { return nil, errors.New("interface name too long") } copy(ifr[:], nameBytes) - binary.LittleEndian.PutUint16(ifr[16:], flags) + *(*uint16)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = flags _, _, errno := unix.Syscall( unix.SYS_IOCTL, @@ -413,12 +411,12 @@ func CreateTUN(name string) (TUNDevice, error) { return nil, errno } - return CreateTUNFromFile(fd) + return CreateTUNFromFile(fd, mtu) } -func CreateTUNFromFile(fd *os.File) (TUNDevice, error) { - tun := &NativeTun{ - fd: fd, +func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) { + tun := &nativeTun{ + fd: file, events: make(chan TUNEvent, 5), errors: make(chan error, 5), statusListenersShutdown: make(chan struct{}), @@ -426,7 +424,7 @@ func CreateTUNFromFile(fd *os.File) (TUNDevice, error) { } var err error - tun.fdCancel, err = rwcancel.NewRWCancel(int(fd.Fd())) + tun.fdCancel, err = rwcancel.NewRWCancel(int(file.Fd())) if err != nil { tun.fd.Close() return nil, err @@ -457,12 +455,10 @@ func CreateTUNFromFile(fd *os.File) (TUNDevice, error) { } tun.hackListenerClosed.Lock() - go tun.RoutineNetlinkListener() - go tun.RoutineHackListener() // cross namespace + go tun.routineNetlinkListener() + go tun.routineHackListener() // cross namespace - // set default MTU - - err = tun.setMTU(DefaultMTU) + err = tun.setMTU(mtu) if err != nil { tun.Close() return nil, err diff --git a/tun_openbsd.go b/tun/tun_openbsd.go similarity index 86% rename from tun_openbsd.go rename to tun/tun_openbsd.go index 932404e..74b25e5 100644 --- a/tun_openbsd.go +++ b/tun/tun_openbsd.go @@ -3,10 +3,10 @@ * Copyright (C) 2017-2018 Jason A. Donenfeld . All Rights Reserved. */ -package main +package tun import ( - "./rwcancel" + "../rwcancel" "errors" "fmt" "golang.org/x/net/ipv6" @@ -27,7 +27,7 @@ type ifreq_mtu struct { const _TUNSIFMODE = 0x8004745d -type NativeTun struct { +type nativeTun struct { name string fd *os.File rwcancel *rwcancel.RWCancel @@ -36,7 +36,7 @@ type NativeTun struct { routeSocket int } -func (tun *NativeTun) RoutineRouteListener(tunIfindex int) { +func (tun *nativeTun) routineRouteListener(tunIfindex int) { var ( statusUp bool statusMTU int @@ -100,7 +100,7 @@ func errorIsEBUSY(err error) bool { return false } -func CreateTUN(name string) (TUNDevice, error) { +func CreateTUN(name string, mtu int) (TUNDevice, error) { ifIndex := -1 if name != "tun" { _, err := fmt.Sscanf(name, "tun%d", &ifIndex) @@ -140,21 +140,21 @@ func CreateTUN(name string) (TUNDevice, error) { return nil, fmt.Errorf("error %s", errno.Error()) } - tun, err := CreateTUNFromFile(tunfile) + tun, err := CreateTUNFromFile(tunfile, mtu) if err == nil && name == "tun" { fname := os.Getenv("WG_TUN_NAME_FILE") if fname != "" { - ioutil.WriteFile(fname, []byte(tun.(*NativeTun).name+"\n"), 0400) + ioutil.WriteFile(fname, []byte(tun.(*nativeTun).name+"\n"), 0400) } } return tun, err } -func CreateTUNFromFile(file *os.File) (TUNDevice, error) { +func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) { - tun := &NativeTun{ + tun := &nativeTun{ fd: file, events: make(chan TUNEvent, 10), errors: make(chan error, 1), @@ -190,10 +190,9 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) { return nil, err } - go tun.RoutineRouteListener(tunIfindex) + go tun.routineRouteListener(tunIfindex) - // set default MTU - err = tun.setMTU(DefaultMTU) + err = tun.setMTU(mtu) if err != nil { tun.Close() return nil, err @@ -202,7 +201,7 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) { return tun, nil } -func (tun *NativeTun) Name() (string, error) { +func (tun *nativeTun) Name() (string, error) { gostat, err := tun.fd.Stat() if err != nil { tun.name = "" @@ -213,15 +212,15 @@ func (tun *NativeTun) Name() (string, error) { return tun.name, nil } -func (tun *NativeTun) File() *os.File { +func (tun *nativeTun) File() *os.File { return tun.fd } -func (tun *NativeTun) Events() chan TUNEvent { +func (tun *nativeTun) Events() chan TUNEvent { return tun.events } -func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) { +func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) { select { case err := <-tun.errors: return 0, err @@ -235,7 +234,7 @@ func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) { } } -func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { +func (tun *nativeTun) Read(buff []byte, offset int) (int, error) { for { n, err := tun.doRead(buff, offset) if err == nil || !rwcancel.ErrorIsEAGAIN(err) { @@ -247,7 +246,7 @@ func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { } } -func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { +func (tun *nativeTun) Write(buff []byte, offset int) (int, error) { // reserve space for header @@ -270,7 +269,7 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { return tun.fd.Write(buff) } -func (tun *NativeTun) Close() error { +func (tun *nativeTun) Close() error { var err3 error err1 := tun.rwcancel.Cancel() err2 := tun.fd.Close() @@ -290,7 +289,7 @@ func (tun *NativeTun) Close() error { return err3 } -func (tun *NativeTun) setMTU(n int) error { +func (tun *nativeTun) setMTU(n int) error { // open datagram socket var fd int @@ -327,7 +326,7 @@ func (tun *NativeTun) setMTU(n int) error { return nil } -func (tun *NativeTun) MTU() (int, error) { +func (tun *nativeTun) MTU() (int, error) { // open datagram socket fd, err := unix.Socket(