]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
Fixed MTU method for linux TUN interface
authorMathias Hall-Andersen <mathias@hall-andersen.dk>
Tue, 11 Jul 2017 20:48:58 +0000 (22:48 +0200)
committerMathias Hall-Andersen <mathias@hall-andersen.dk>
Tue, 11 Jul 2017 20:48:58 +0000 (22:48 +0200)
Updated the TUN interface
Added the "MTU" method for the linux implementation of the TUN interface

src/constants.go
src/device.go
src/timers.go
src/tun.go
src/tun_linux.go

index 4e8d52133bdc1993cd231ed2d0bf7a47e6fbec4a..03847418e845fd864992be5894c70bbf66dc8cbb 100644 (file)
@@ -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?
 )
index 2a2ad62bb785540c90df728abfd3cd0ff638e59d..a26cc7be12ab6840c8d3f3eb3a0be192ce5d77a9 100644 (file)
@@ -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()
index 70e0766da9fb83427686b0271e8b733f9f7b873b..63939556c8deceb7ed32533c9914dd953cccfd81 100644 (file)
@@ -229,6 +229,7 @@ func (peer *Peer) RoutineHandshakeInitiator() {
 
                run = func() bool {
                        for {
+
                                // clear completed signal
 
                                select {
index 60732c442101c89edd5f39ad994554a5d2aba16a..85735a657ebd1076fe85b1892febf9caf47dc511 100644 (file)
@@ -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
 }
index d16a966c7f8074ff6f51f92ec8d64c3dd6ad01dc..63c38869cd11da3aa96553814271a4dbcb1d56f9 100644 (file)
@@ -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
 }