Move tun to subpackage
This commit is contained in:
parent
65a74f3175
commit
0a63188afa
|
@ -8,6 +8,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"./ratelimiter"
|
"./ratelimiter"
|
||||||
|
"./tun"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -80,7 +81,7 @@ type Device struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
tun struct {
|
tun struct {
|
||||||
device TUNDevice
|
device tun.TUNDevice
|
||||||
mtu int32
|
mtu int32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +251,7 @@ func (device *Device) PutMessageBuffer(msg *[MaxMessageSize]byte) {
|
||||||
device.pool.messageBuffers.Put(msg)
|
device.pool.messageBuffers.Put(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDevice(tun TUNDevice, logger *Logger) *Device {
|
func NewDevice(tunDevice tun.TUNDevice, logger *Logger) *Device {
|
||||||
device := new(Device)
|
device := new(Device)
|
||||||
|
|
||||||
device.isUp.Set(false)
|
device.isUp.Set(false)
|
||||||
|
@ -258,7 +259,7 @@ func NewDevice(tun TUNDevice, logger *Logger) *Device {
|
||||||
|
|
||||||
device.log = logger
|
device.log = logger
|
||||||
|
|
||||||
device.tun.device = tun
|
device.tun.device = tunDevice
|
||||||
mtu, err := device.tun.device.MTU()
|
mtu, err := device.tun.device.MTU()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Println("Trouble determining MTU, assuming default:", err)
|
logger.Error.Println("Trouble determining MTU, assuming default:", err)
|
||||||
|
|
7
main.go
7
main.go
|
@ -7,6 +7,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"./tun"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
@ -125,10 +126,10 @@ func main() {
|
||||||
|
|
||||||
// open TUN device (or use supplied fd)
|
// 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)
|
tunFdStr := os.Getenv(ENV_WG_TUN_FD)
|
||||||
if tunFdStr == "" {
|
if tunFdStr == "" {
|
||||||
return CreateTUN(interfaceName)
|
return tun.CreateTUN(interfaceName, DefaultMTU)
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct tun device from supplied fd
|
// construct tun device from supplied fd
|
||||||
|
@ -139,7 +140,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
file := os.NewFile(uintptr(fd), "")
|
file := os.NewFile(uintptr(fd), "")
|
||||||
return CreateTUNFromFile(file)
|
return tun.CreateTUNFromFile(file, DefaultMTU)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
7
misc.go
7
misc.go
|
@ -41,13 +41,6 @@ func (a *AtomicBool) Set(val bool) {
|
||||||
atomic.StoreInt32(&a.flag, flag)
|
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 {
|
func min(a, b uint) uint {
|
||||||
if a > b {
|
if a > b {
|
||||||
return b
|
return b
|
||||||
|
|
26
tun.go
26
tun.go
|
@ -7,30 +7,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"./tun"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
const DefaultMTU = 1420
|
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() {
|
func (device *Device) RoutineTUNEventReader() {
|
||||||
setUp := false
|
setUp := false
|
||||||
logDebug := device.log.Debug
|
logDebug := device.log.Debug
|
||||||
|
@ -41,7 +23,7 @@ func (device *Device) RoutineTUNEventReader() {
|
||||||
device.state.starting.Done()
|
device.state.starting.Done()
|
||||||
|
|
||||||
for event := range device.tun.device.Events() {
|
for event := range device.tun.device.Events() {
|
||||||
if event&TUNEventMTUUpdate != 0 {
|
if event&tun.TUNEventMTUUpdate != 0 {
|
||||||
mtu, err := device.tun.device.MTU()
|
mtu, err := device.tun.device.MTU()
|
||||||
old := atomic.LoadInt32(&device.tun.mtu)
|
old := atomic.LoadInt32(&device.tun.mtu)
|
||||||
if err != nil {
|
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")
|
logInfo.Println("Interface set up")
|
||||||
setUp = true
|
setUp = true
|
||||||
device.Up()
|
device.Up()
|
||||||
}
|
}
|
||||||
|
|
||||||
if event&TUNEventDown != 0 && setUp {
|
if event&tun.TUNEventDown != 0 && setUp {
|
||||||
logInfo.Println("Interface set down")
|
logInfo.Println("Interface set down")
|
||||||
setUp = false
|
setUp = false
|
||||||
device.Down()
|
device.Down()
|
||||||
|
|
27
tun/tun.go
Normal file
27
tun/tun.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
|
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
|
@ -4,11 +4,10 @@
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"./rwcancel"
|
"../rwcancel"
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
|
@ -34,7 +33,7 @@ type sockaddrCtl struct {
|
||||||
scReserved [5]uint32
|
scReserved [5]uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type NativeTun struct {
|
type nativeTun struct {
|
||||||
name string
|
name string
|
||||||
fd *os.File
|
fd *os.File
|
||||||
rwcancel *rwcancel.RWCancel
|
rwcancel *rwcancel.RWCancel
|
||||||
|
@ -45,7 +44,7 @@ type NativeTun struct {
|
||||||
|
|
||||||
var sockaddrCtlSize uintptr = 32
|
var sockaddrCtlSize uintptr = 32
|
||||||
|
|
||||||
func (tun *NativeTun) RoutineRouteListener(tunIfindex int) {
|
func (tun *nativeTun) routineRouteListener(tunIfindex int) {
|
||||||
var (
|
var (
|
||||||
statusUp bool
|
statusUp bool
|
||||||
statusMTU int
|
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
|
ifIndex := -1
|
||||||
if name != "utun" {
|
if name != "utun" {
|
||||||
_, err := fmt.Sscanf(name, "utun%d", &ifIndex)
|
_, 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)
|
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" {
|
if err == nil && name == "utun" {
|
||||||
fname := os.Getenv("WG_TUN_NAME_FILE")
|
fname := os.Getenv("WG_TUN_NAME_FILE")
|
||||||
if fname != "" {
|
if fname != "" {
|
||||||
ioutil.WriteFile(fname, []byte(tun.(*NativeTun).name+"\n"), 0400)
|
ioutil.WriteFile(fname, []byte(tun.(*nativeTun).name+"\n"), 0400)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tun, err
|
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,
|
fd: file,
|
||||||
events: make(chan TUNEvent, 10),
|
events: make(chan TUNEvent, 10),
|
||||||
errors: make(chan error, 1),
|
errors: make(chan error, 1),
|
||||||
|
@ -201,10 +200,9 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
go tun.RoutineRouteListener(tunIfindex)
|
go tun.routineRouteListener(tunIfindex)
|
||||||
|
|
||||||
// set default MTU
|
err = tun.setMTU(mtu)
|
||||||
err = tun.setMTU(DefaultMTU)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.Close()
|
tun.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -213,7 +211,7 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) {
|
||||||
return tun, nil
|
return tun, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Name() (string, error) {
|
func (tun *nativeTun) Name() (string, error) {
|
||||||
|
|
||||||
var ifName struct {
|
var ifName struct {
|
||||||
name [16]byte
|
name [16]byte
|
||||||
|
@ -236,15 +234,15 @@ func (tun *NativeTun) Name() (string, error) {
|
||||||
return tun.name, nil
|
return tun.name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) File() *os.File {
|
func (tun *nativeTun) File() *os.File {
|
||||||
return tun.fd
|
return tun.fd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Events() chan TUNEvent {
|
func (tun *nativeTun) Events() chan TUNEvent {
|
||||||
return tun.events
|
return tun.events
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) {
|
func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
||||||
select {
|
select {
|
||||||
case err := <-tun.errors:
|
case err := <-tun.errors:
|
||||||
return 0, err
|
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 {
|
for {
|
||||||
n, err := tun.doRead(buff, offset)
|
n, err := tun.doRead(buff, offset)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
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
|
// reserve space for header
|
||||||
|
|
||||||
|
@ -293,7 +291,7 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
return tun.fd.Write(buff)
|
return tun.fd.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Close() error {
|
func (tun *nativeTun) Close() error {
|
||||||
var err3 error
|
var err3 error
|
||||||
err1 := tun.rwcancel.Cancel()
|
err1 := tun.rwcancel.Cancel()
|
||||||
err2 := tun.fd.Close()
|
err2 := tun.fd.Close()
|
||||||
|
@ -313,7 +311,7 @@ func (tun *NativeTun) Close() error {
|
||||||
return err3
|
return err3
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) setMTU(n int) error {
|
func (tun *nativeTun) setMTU(n int) error {
|
||||||
|
|
||||||
// open datagram socket
|
// open datagram socket
|
||||||
|
|
||||||
|
@ -335,7 +333,7 @@ func (tun *NativeTun) setMTU(n int) error {
|
||||||
|
|
||||||
var ifr [32]byte
|
var ifr [32]byte
|
||||||
copy(ifr[:], tun.name)
|
copy(ifr[:], tun.name)
|
||||||
binary.LittleEndian.PutUint32(ifr[16:20], uint32(n))
|
*(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = uint32(n)
|
||||||
_, _, errno := unix.Syscall(
|
_, _, errno := unix.Syscall(
|
||||||
unix.SYS_IOCTL,
|
unix.SYS_IOCTL,
|
||||||
uintptr(fd),
|
uintptr(fd),
|
||||||
|
@ -350,7 +348,7 @@ func (tun *NativeTun) setMTU(n int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) MTU() (int, error) {
|
func (tun *nativeTun) MTU() (int, error) {
|
||||||
|
|
||||||
// open datagram socket
|
// open datagram socket
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"./rwcancel"
|
"../rwcancel"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -48,7 +48,7 @@ type ifstat struct {
|
||||||
Ascii [_IFSTATMAX]byte
|
Ascii [_IFSTATMAX]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type NativeTun struct {
|
type nativeTun struct {
|
||||||
name string
|
name string
|
||||||
fd *os.File
|
fd *os.File
|
||||||
rwcancel *rwcancel.RWCancel
|
rwcancel *rwcancel.RWCancel
|
||||||
|
@ -57,7 +57,7 @@ type NativeTun struct {
|
||||||
routeSocket int
|
routeSocket int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) RoutineRouteListener(tunIfindex int) {
|
func (tun *nativeTun) routineRouteListener(tunIfindex int) {
|
||||||
var (
|
var (
|
||||||
statusUp bool
|
statusUp bool
|
||||||
statusMTU int
|
statusMTU int
|
||||||
|
@ -221,7 +221,7 @@ func tunDestroy(name string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateTUN(name string) (TUNDevice, error) {
|
func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
||||||
if len(name) > unix.IFNAMSIZ-1 {
|
if len(name) > unix.IFNAMSIZ-1 {
|
||||||
return nil, errors.New("interface name too long")
|
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 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,
|
fd: file,
|
||||||
events: make(chan TUNEvent, 10),
|
events: make(chan TUNEvent, 10),
|
||||||
errors: make(chan error, 1),
|
errors: make(chan error, 1),
|
||||||
|
@ -347,10 +347,9 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
go tun.RoutineRouteListener(tunIfindex)
|
go tun.routineRouteListener(tunIfindex)
|
||||||
|
|
||||||
// set default MTU
|
err = tun.setMTU(mtu)
|
||||||
err = tun.setMTU(DefaultMTU)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.Close()
|
tun.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -359,7 +358,7 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) {
|
||||||
return tun, nil
|
return tun, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Name() (string, error) {
|
func (tun *nativeTun) Name() (string, error) {
|
||||||
name, err := tunName(tun.fd.Fd())
|
name, err := tunName(tun.fd.Fd())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -368,15 +367,15 @@ func (tun *NativeTun) Name() (string, error) {
|
||||||
return name, nil
|
return name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) File() *os.File {
|
func (tun *nativeTun) File() *os.File {
|
||||||
return tun.fd
|
return tun.fd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Events() chan TUNEvent {
|
func (tun *nativeTun) Events() chan TUNEvent {
|
||||||
return tun.events
|
return tun.events
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) {
|
func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
||||||
select {
|
select {
|
||||||
case err := <-tun.errors:
|
case err := <-tun.errors:
|
||||||
return 0, err
|
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 {
|
for {
|
||||||
n, err := tun.doRead(buff, offset)
|
n, err := tun.doRead(buff, offset)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
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
|
// reserve space for header
|
||||||
|
|
||||||
|
@ -425,7 +424,7 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
return tun.fd.Write(buff)
|
return tun.fd.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Close() error {
|
func (tun *nativeTun) Close() error {
|
||||||
var err4 error
|
var err4 error
|
||||||
err1 := tun.rwcancel.Cancel()
|
err1 := tun.rwcancel.Cancel()
|
||||||
err2 := tun.fd.Close()
|
err2 := tun.fd.Close()
|
||||||
|
@ -449,7 +448,7 @@ func (tun *NativeTun) Close() error {
|
||||||
return err4
|
return err4
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) setMTU(n int) error {
|
func (tun *nativeTun) setMTU(n int) error {
|
||||||
// open datagram socket
|
// open datagram socket
|
||||||
|
|
||||||
var fd int
|
var fd int
|
||||||
|
@ -486,7 +485,7 @@ func (tun *NativeTun) setMTU(n int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) MTU() (int, error) {
|
func (tun *nativeTun) MTU() (int, error) {
|
||||||
// open datagram socket
|
// open datagram socket
|
||||||
|
|
||||||
fd, err := unix.Socket(
|
fd, err := unix.Socket(
|
|
@ -6,15 +6,14 @@
|
||||||
|
|
||||||
/* Copyright 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
|
/* Copyright 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
|
||||||
|
|
||||||
package main
|
package tun
|
||||||
|
|
||||||
/* Implementation of the TUN device interface for linux
|
/* Implementation of the TUN device interface for linux
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"./rwcancel"
|
"../rwcancel"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
|
@ -32,7 +31,7 @@ const (
|
||||||
ifReqSize = unix.IFNAMSIZ + 64
|
ifReqSize = unix.IFNAMSIZ + 64
|
||||||
)
|
)
|
||||||
|
|
||||||
type NativeTun struct {
|
type nativeTun struct {
|
||||||
fd *os.File
|
fd *os.File
|
||||||
fdCancel *rwcancel.RWCancel
|
fdCancel *rwcancel.RWCancel
|
||||||
index int32 // if index
|
index int32 // if index
|
||||||
|
@ -46,11 +45,11 @@ type NativeTun struct {
|
||||||
statusListenersShutdown chan struct{}
|
statusListenersShutdown chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) File() *os.File {
|
func (tun *nativeTun) File() *os.File {
|
||||||
return tun.fd
|
return tun.fd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) RoutineHackListener() {
|
func (tun *nativeTun) routineHackListener() {
|
||||||
defer tun.hackListenerClosed.Unlock()
|
defer tun.hackListenerClosed.Unlock()
|
||||||
/* This is needed for the detection to work across network namespaces
|
/* 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.
|
* 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
|
return sock, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) RoutineNetlinkListener() {
|
func (tun *nativeTun) routineNetlinkListener() {
|
||||||
defer func() {
|
defer func() {
|
||||||
unix.Close(tun.netlinkSock)
|
unix.Close(tun.netlinkSock)
|
||||||
tun.hackListenerClosed.Lock()
|
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)
|
inter, err := net.InterfaceByName(tun.name)
|
||||||
return inter.Flags&net.FlagUp != 0, err
|
return inter.Flags&net.FlagUp != 0, err
|
||||||
}
|
}
|
||||||
|
@ -194,11 +193,10 @@ func getIFIndex(name string) (int32, error) {
|
||||||
return 0, errno
|
return 0, errno
|
||||||
}
|
}
|
||||||
|
|
||||||
index := binary.LittleEndian.Uint32(ifr[unix.IFNAMSIZ:])
|
return *(*int32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])), nil
|
||||||
return toInt32(index), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) setMTU(n int) error {
|
func (tun *nativeTun) setMTU(n int) error {
|
||||||
|
|
||||||
// open datagram socket
|
// open datagram socket
|
||||||
|
|
||||||
|
@ -218,7 +216,7 @@ func (tun *NativeTun) setMTU(n int) error {
|
||||||
|
|
||||||
var ifr [ifReqSize]byte
|
var ifr [ifReqSize]byte
|
||||||
copy(ifr[:], tun.name)
|
copy(ifr[:], tun.name)
|
||||||
binary.LittleEndian.PutUint32(ifr[16:20], uint32(n))
|
*(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = uint32(n)
|
||||||
_, _, errno := unix.Syscall(
|
_, _, errno := unix.Syscall(
|
||||||
unix.SYS_IOCTL,
|
unix.SYS_IOCTL,
|
||||||
uintptr(fd),
|
uintptr(fd),
|
||||||
|
@ -233,7 +231,7 @@ func (tun *NativeTun) setMTU(n int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) MTU() (int, error) {
|
func (tun *nativeTun) MTU() (int, error) {
|
||||||
|
|
||||||
// open datagram socket
|
// 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 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
|
var ifr [ifReqSize]byte
|
||||||
_, _, errno := unix.Syscall(
|
_, _, errno := unix.Syscall(
|
||||||
|
@ -287,7 +285,7 @@ func (tun *NativeTun) Name() (string, error) {
|
||||||
return tun.name, nil
|
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 {
|
if tun.nopi {
|
||||||
buff = buff[offset:]
|
buff = buff[offset:]
|
||||||
|
@ -315,7 +313,7 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
return tun.fd.Write(buff)
|
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 {
|
select {
|
||||||
case err := <-tun.errors:
|
case err := <-tun.errors:
|
||||||
return 0, err
|
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 {
|
for {
|
||||||
n, err := tun.doRead(buff, offset)
|
n, err := tun.doRead(buff, offset)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
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
|
return tun.events
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Close() error {
|
func (tun *nativeTun) Close() error {
|
||||||
var err1 error
|
var err1 error
|
||||||
if tun.statusListenersShutdown != nil {
|
if tun.statusListenersShutdown != nil {
|
||||||
close(tun.statusListenersShutdown)
|
close(tun.statusListenersShutdown)
|
||||||
|
@ -371,7 +369,7 @@ func (tun *NativeTun) Close() error {
|
||||||
return err3
|
return err3
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateTUN(name string) (TUNDevice, error) {
|
func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
||||||
|
|
||||||
// open clone device
|
// open clone device
|
||||||
|
|
||||||
|
@ -401,7 +399,7 @@ func CreateTUN(name string) (TUNDevice, error) {
|
||||||
return nil, errors.New("interface name too long")
|
return nil, errors.New("interface name too long")
|
||||||
}
|
}
|
||||||
copy(ifr[:], nameBytes)
|
copy(ifr[:], nameBytes)
|
||||||
binary.LittleEndian.PutUint16(ifr[16:], flags)
|
*(*uint16)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = flags
|
||||||
|
|
||||||
_, _, errno := unix.Syscall(
|
_, _, errno := unix.Syscall(
|
||||||
unix.SYS_IOCTL,
|
unix.SYS_IOCTL,
|
||||||
|
@ -413,12 +411,12 @@ func CreateTUN(name string) (TUNDevice, error) {
|
||||||
return nil, errno
|
return nil, errno
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreateTUNFromFile(fd)
|
return CreateTUNFromFile(fd, mtu)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateTUNFromFile(fd *os.File) (TUNDevice, error) {
|
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
||||||
tun := &NativeTun{
|
tun := &nativeTun{
|
||||||
fd: fd,
|
fd: file,
|
||||||
events: make(chan TUNEvent, 5),
|
events: make(chan TUNEvent, 5),
|
||||||
errors: make(chan error, 5),
|
errors: make(chan error, 5),
|
||||||
statusListenersShutdown: make(chan struct{}),
|
statusListenersShutdown: make(chan struct{}),
|
||||||
|
@ -426,7 +424,7 @@ func CreateTUNFromFile(fd *os.File) (TUNDevice, error) {
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
tun.fdCancel, err = rwcancel.NewRWCancel(int(fd.Fd()))
|
tun.fdCancel, err = rwcancel.NewRWCancel(int(file.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.fd.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -457,12 +455,10 @@ func CreateTUNFromFile(fd *os.File) (TUNDevice, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tun.hackListenerClosed.Lock()
|
tun.hackListenerClosed.Lock()
|
||||||
go tun.RoutineNetlinkListener()
|
go tun.routineNetlinkListener()
|
||||||
go tun.RoutineHackListener() // cross namespace
|
go tun.routineHackListener() // cross namespace
|
||||||
|
|
||||||
// set default MTU
|
err = tun.setMTU(mtu)
|
||||||
|
|
||||||
err = tun.setMTU(DefaultMTU)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.Close()
|
tun.Close()
|
||||||
return nil, err
|
return nil, err
|
|
@ -3,10 +3,10 @@
|
||||||
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"./rwcancel"
|
"../rwcancel"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
|
@ -27,7 +27,7 @@ type ifreq_mtu struct {
|
||||||
|
|
||||||
const _TUNSIFMODE = 0x8004745d
|
const _TUNSIFMODE = 0x8004745d
|
||||||
|
|
||||||
type NativeTun struct {
|
type nativeTun struct {
|
||||||
name string
|
name string
|
||||||
fd *os.File
|
fd *os.File
|
||||||
rwcancel *rwcancel.RWCancel
|
rwcancel *rwcancel.RWCancel
|
||||||
|
@ -36,7 +36,7 @@ type NativeTun struct {
|
||||||
routeSocket int
|
routeSocket int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) RoutineRouteListener(tunIfindex int) {
|
func (tun *nativeTun) routineRouteListener(tunIfindex int) {
|
||||||
var (
|
var (
|
||||||
statusUp bool
|
statusUp bool
|
||||||
statusMTU int
|
statusMTU int
|
||||||
|
@ -100,7 +100,7 @@ func errorIsEBUSY(err error) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateTUN(name string) (TUNDevice, error) {
|
func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
||||||
ifIndex := -1
|
ifIndex := -1
|
||||||
if name != "tun" {
|
if name != "tun" {
|
||||||
_, err := fmt.Sscanf(name, "tun%d", &ifIndex)
|
_, 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())
|
return nil, fmt.Errorf("error %s", errno.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
tun, err := CreateTUNFromFile(tunfile)
|
tun, err := CreateTUNFromFile(tunfile, mtu)
|
||||||
|
|
||||||
if err == nil && name == "tun" {
|
if err == nil && name == "tun" {
|
||||||
fname := os.Getenv("WG_TUN_NAME_FILE")
|
fname := os.Getenv("WG_TUN_NAME_FILE")
|
||||||
if fname != "" {
|
if fname != "" {
|
||||||
ioutil.WriteFile(fname, []byte(tun.(*NativeTun).name+"\n"), 0400)
|
ioutil.WriteFile(fname, []byte(tun.(*nativeTun).name+"\n"), 0400)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tun, err
|
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,
|
fd: file,
|
||||||
events: make(chan TUNEvent, 10),
|
events: make(chan TUNEvent, 10),
|
||||||
errors: make(chan error, 1),
|
errors: make(chan error, 1),
|
||||||
|
@ -190,10 +190,9 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
go tun.RoutineRouteListener(tunIfindex)
|
go tun.routineRouteListener(tunIfindex)
|
||||||
|
|
||||||
// set default MTU
|
err = tun.setMTU(mtu)
|
||||||
err = tun.setMTU(DefaultMTU)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.Close()
|
tun.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -202,7 +201,7 @@ func CreateTUNFromFile(file *os.File) (TUNDevice, error) {
|
||||||
return tun, nil
|
return tun, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Name() (string, error) {
|
func (tun *nativeTun) Name() (string, error) {
|
||||||
gostat, err := tun.fd.Stat()
|
gostat, err := tun.fd.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.name = ""
|
tun.name = ""
|
||||||
|
@ -213,15 +212,15 @@ func (tun *NativeTun) Name() (string, error) {
|
||||||
return tun.name, nil
|
return tun.name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) File() *os.File {
|
func (tun *nativeTun) File() *os.File {
|
||||||
return tun.fd
|
return tun.fd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Events() chan TUNEvent {
|
func (tun *nativeTun) Events() chan TUNEvent {
|
||||||
return tun.events
|
return tun.events
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) doRead(buff []byte, offset int) (int, error) {
|
func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
||||||
select {
|
select {
|
||||||
case err := <-tun.errors:
|
case err := <-tun.errors:
|
||||||
return 0, err
|
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 {
|
for {
|
||||||
n, err := tun.doRead(buff, offset)
|
n, err := tun.doRead(buff, offset)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
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
|
// reserve space for header
|
||||||
|
|
||||||
|
@ -270,7 +269,7 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
return tun.fd.Write(buff)
|
return tun.fd.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Close() error {
|
func (tun *nativeTun) Close() error {
|
||||||
var err3 error
|
var err3 error
|
||||||
err1 := tun.rwcancel.Cancel()
|
err1 := tun.rwcancel.Cancel()
|
||||||
err2 := tun.fd.Close()
|
err2 := tun.fd.Close()
|
||||||
|
@ -290,7 +289,7 @@ func (tun *NativeTun) Close() error {
|
||||||
return err3
|
return err3
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) setMTU(n int) error {
|
func (tun *nativeTun) setMTU(n int) error {
|
||||||
// open datagram socket
|
// open datagram socket
|
||||||
|
|
||||||
var fd int
|
var fd int
|
||||||
|
@ -327,7 +326,7 @@ func (tun *NativeTun) setMTU(n int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) MTU() (int, error) {
|
func (tun *nativeTun) MTU() (int, error) {
|
||||||
// open datagram socket
|
// open datagram socket
|
||||||
|
|
||||||
fd, err := unix.Socket(
|
fd, err := unix.Socket(
|
Loading…
Reference in a new issue