summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2017-07-11 22:48:58 +0200
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2017-07-11 22:48:58 +0200
commit86707cbc88fbad58481b400eaf12fa75c78f9855 (patch)
treece3b662db2da9ad78f09ed96cb2a93c2f0e6bfa4
parentc273078376d5aa394e871e7436b8e770b0c3f4a0 (diff)
Fixed MTU method for linux TUN interface
Updated the TUN interface Added the "MTU" method for the linux implementation of the TUN interface
-rw-r--r--src/constants.go12
-rw-r--r--src/device.go2
-rw-r--r--src/timers.go1
-rw-r--r--src/tun.go8
-rw-r--r--src/tun_linux.go76
5 files changed, 69 insertions, 30 deletions
diff --git a/src/constants.go b/src/constants.go
index 4e8d521..0384741 100644
--- a/src/constants.go
+++ b/src/constants.go
@@ -4,15 +4,17 @@ import (
"time"
)
+/* Specification constants */
+
const (
RekeyAfterMessages = (1 << 64) - (1 << 16) - 1
+ RejectAfterMessages = (1 << 64) - (1 << 4) - 1
RekeyAfterTime = time.Second * 120
RekeyAttemptTime = time.Second * 90
- RekeyTimeout = time.Second * 5 // TODO: Exponential backoff
+ RekeyTimeout = time.Second * 5
RejectAfterTime = time.Second * 180
- RejectAfterMessages = (1 << 64) - (1 << 4) - 1
KeepaliveTimeout = time.Second * 10
- CookieRefreshTime = time.Minute * 2
+ CookieRefreshTime = time.Second * 120
MaxHandshakeAttemptTime = time.Second * 90
)
@@ -20,11 +22,13 @@ const (
RekeyAfterTimeReceiving = RekeyAfterTime - KeepaliveTimeout - RekeyTimeout
)
+/* Implementation specific constants */
+
const (
QueueOutboundSize = 1024
QueueInboundSize = 1024
QueueHandshakeSize = 1024
QueueHandshakeBusySize = QueueHandshakeSize / 8
MinMessageSize = MessageTransportSize // keep-alive
- MaxMessageSize = 4096
+ MaxMessageSize = 4096 // TODO: make depend on the MTU?
)
diff --git a/src/device.go b/src/device.go
index 2a2ad62..a26cc7b 100644
--- a/src/device.go
+++ b/src/device.go
@@ -64,7 +64,7 @@ func NewDevice(tun TUNDevice, logLevel int) *Device {
defer device.mutex.Unlock()
device.log = NewLogger(logLevel)
- device.mtu = tun.MTU()
+ // device.mtu = tun.MTU()
device.peers = make(map[NoisePublicKey]*Peer)
device.indices.Init()
device.ratelimiter.Init()
diff --git a/src/timers.go b/src/timers.go
index 70e0766..6393955 100644
--- a/src/timers.go
+++ b/src/timers.go
@@ -229,6 +229,7 @@ func (peer *Peer) RoutineHandshakeInitiator() {
run = func() bool {
for {
+
// clear completed signal
select {
diff --git a/src/tun.go b/src/tun.go
index 60732c4..85735a6 100644
--- a/src/tun.go
+++ b/src/tun.go
@@ -1,8 +1,8 @@
package main
type TUNDevice interface {
- Read([]byte) (int, error)
- Write([]byte) (int, error)
- Name() string
- MTU() int
+ Read([]byte) (int, error) // read a packet from the device (without any additional headers)
+ Write([]byte) (int, error) // writes a packet to the device (without any additional headers)
+ MTU() (int, error) // returns the MTU of the device
+ Name() string // returns the current name
}
diff --git a/src/tun_linux.go b/src/tun_linux.go
index d16a966..63c3886 100644
--- a/src/tun_linux.go
+++ b/src/tun_linux.go
@@ -14,25 +14,52 @@ import (
const CloneDevicePath = "/dev/net/tun"
-const (
- IFF_NO_PI = 0x1000
- IFF_TUN = 0x1
- IFNAMSIZ = 0x10
- TUNSETIFF = 0x400454CA
-)
-
type NativeTun struct {
fd *os.File
name string
- mtu int
}
func (tun *NativeTun) Name() string {
return tun.name
}
-func (tun *NativeTun) MTU() int {
- return tun.mtu
+func (tun *NativeTun) MTU() (int, error) {
+
+ // open datagram socket
+
+ fd, err := syscall.Socket(
+ syscall.AF_INET,
+ syscall.SOCK_DGRAM,
+ 0,
+ )
+
+ if err != nil {
+ return 0, err
+ }
+
+ // do ioctl call
+
+ var ifr [64]byte
+ var flags uint16
+ copy(ifr[:], tun.name)
+ binary.LittleEndian.PutUint16(ifr[16:], flags)
+ _, _, errno := syscall.Syscall(
+ syscall.SYS_IOCTL,
+ uintptr(fd),
+ uintptr(syscall.SIOCGIFMTU),
+ uintptr(unsafe.Pointer(&ifr[0])),
+ )
+ if errno != 0 {
+ return 0, errors.New("Failed to get MTU of TUN device")
+ }
+
+ // convert result to signed 32-bit int
+
+ val := binary.LittleEndian.Uint32(ifr[16:20])
+ if val >= (1 << 31) {
+ return int(val-(1<<31)) - (1 << 31), nil
+ }
+ return int(val), nil
}
func (tun *NativeTun) Write(d []byte) (int, error) {
@@ -44,36 +71,43 @@ func (tun *NativeTun) Read(d []byte) (int, error) {
}
func CreateTUN(name string) (TUNDevice, error) {
- // Open clone device
+
+ // open clone device
+
fd, err := os.OpenFile(CloneDevicePath, os.O_RDWR, 0)
if err != nil {
return nil, err
}
- // Prepare ifreq struct
- var ifr [128]byte
- var flags uint16 = IFF_TUN | IFF_NO_PI
+ // prepare ifreq struct
+
+ var ifr [64]byte
+ var flags uint16 = syscall.IFF_TUN | syscall.IFF_NO_PI
nameBytes := []byte(name)
- if len(nameBytes) >= IFNAMSIZ {
+ if len(nameBytes) >= syscall.IFNAMSIZ {
return nil, errors.New("Name size too long")
}
copy(ifr[:], nameBytes)
binary.LittleEndian.PutUint16(ifr[16:], flags)
- // Create new device
- _, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
- uintptr(fd.Fd()), uintptr(TUNSETIFF),
- uintptr(unsafe.Pointer(&ifr[0])))
+ // create new device
+
+ _, _, errno := syscall.Syscall(
+ syscall.SYS_IOCTL,
+ uintptr(fd.Fd()),
+ uintptr(syscall.TUNSETIFF),
+ uintptr(unsafe.Pointer(&ifr[0])),
+ )
if errno != 0 {
return nil, errors.New("Failed to create tun, ioctl call failed")
}
- // Read name of interface
+ // read (new) name of interface
+
newName := string(ifr[:])
newName = newName[:strings.Index(newName, "\000")]
return &NativeTun{
fd: fd,
name: newName,
- mtu: 0,
}, nil
}