]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
Removed IFF_NO_PI from TUN linux
authorMathias Hall-Andersen <mathias@hall-andersen.dk>
Mon, 4 Dec 2017 20:39:06 +0000 (21:39 +0100)
committerMathias Hall-Andersen <mathias@hall-andersen.dk>
Mon, 4 Dec 2017 20:39:06 +0000 (21:39 +0100)
This change was needed for the Linux TUN status hack
to work properly (not increment the error counter).

This commit also updates the TUN interface to allow for
the construction / removal of the TUN info headers in-place.

src/receive.go
src/send.go
src/tun.go
src/tun_linux.go

index f650cc9d73259da3b1ddbcf60d78bf27eba0aed9..dbd2813ea10e88131325eb86225d3ad6c8c07518 100644 (file)
@@ -243,13 +243,24 @@ func (device *Device) RoutineDecryption() {
                        counter := elem.packet[MessageTransportOffsetCounter:MessageTransportOffsetContent]
                        content := elem.packet[MessageTransportOffsetContent:]
 
+                       // expand nonce
+
+                       nonce[0x4] = counter[0x0]
+                       nonce[0x5] = counter[0x1]
+                       nonce[0x6] = counter[0x2]
+                       nonce[0x7] = counter[0x3]
+
+                       nonce[0x8] = counter[0x4]
+                       nonce[0x9] = counter[0x5]
+                       nonce[0xa] = counter[0x6]
+                       nonce[0xb] = counter[0x7]
+
                        // decrypt and release to consumer
 
                        var err error
-                       copy(nonce[4:], counter)
                        elem.counter = binary.LittleEndian.Uint64(counter)
                        elem.packet, err = elem.keyPair.receive.Open(
-                               elem.buffer[:0],
+                               content[:0],
                                nonce[:],
                                content,
                                nil,
@@ -495,6 +506,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
                        // wait for decryption
 
                        elem.mutex.Lock()
+
                        if elem.IsDropped() {
                                continue
                        }
@@ -603,8 +615,11 @@ func (peer *Peer) RoutineSequentialReceiver() {
 
                        // write to tun device
 
+                       offset := MessageTransportOffsetContent
                        atomic.AddUint64(&peer.stats.rxBytes, uint64(len(elem.packet)))
-                       _, err := device.tun.device.Write(elem.packet)
+                       _, err := device.tun.device.Write(
+                               elem.buffer[:offset+len(elem.packet)],
+                               offset)
                        device.PutMessageBuffer(elem.buffer)
                        if err != nil {
                                logError.Println("Failed to write packet to TUN device:", err)
index 2919f2e1caf4475fdd27a9473f35454774a50248..9537f5eb9113216781ff654598021ea611ab6ed2 100644 (file)
@@ -127,8 +127,9 @@ func (device *Device) RoutineReadFromTUN() {
 
                // read packet
 
-               elem.packet = elem.buffer[MessageTransportHeaderSize:]
-               size, err := device.tun.device.Read(elem.packet)
+               offset := MessageTransportHeaderSize
+               size, err := device.tun.device.Read(elem.buffer[:], offset)
+
                if err != nil {
                        logError.Println("Failed to read packet from TUN device:", err)
                        device.Close()
@@ -139,7 +140,7 @@ func (device *Device) RoutineReadFromTUN() {
                        continue
                }
 
-               elem.packet = elem.packet[:size]
+               elem.packet = elem.buffer[offset : offset+size]
 
                // lookup peer
 
index 215022c443689f22a4343406e6a47ac436fcd4d8..54253b4f25dba54080bc770ef4914929940fc0d8 100644 (file)
@@ -16,13 +16,13 @@ const (
 )
 
 type TUNDevice interface {
-       File() *os.File            // returns the file descriptor of the device
-       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
-       Events() chan TUNEvent     // returns a constant channel of events related to the device
-       Close() error              // stops the device and closes the event channel
+       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                   // 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() {
index 8a5d53bc168aa5a02b75e22ac5ba7f44df4effae..daa2462ad7650c27825cf4eec3074d0f57597f25 100644 (file)
@@ -7,6 +7,7 @@ import (
        "encoding/binary"
        "errors"
        "fmt"
+       "golang.org/x/net/ipv6"
        "golang.org/x/sys/unix"
        "net"
        "os"
@@ -249,16 +250,41 @@ func (tun *NativeTun) MTU() (int, error) {
        return int(val), nil
 }
 
-func (tun *NativeTun) Write(d []byte) (int, error) {
-       return tun.fd.Write(d)
+func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
+
+       // reserve space for header
+
+       buff = buff[offset-4:]
+
+       // add packet information header
+
+       buff[0] = 0x00
+       buff[1] = 0x00
+
+       if buff[4] == ipv6.Version<<4 {
+               buff[2] = 0x86
+               buff[3] = 0xdd
+       } else {
+               buff[2] = 0x08
+               buff[3] = 0x00
+       }
+
+       // write
+
+       return tun.fd.Write(buff)
 }
 
-func (tun *NativeTun) Read(d []byte) (int, error) {
+func (tun *NativeTun) Read(buff []byte, offset int) (int, error) {
        select {
        case err := <-tun.errors:
                return 0, err
        default:
-               return tun.fd.Read(d)
+               buff := buff[offset-4:]
+               n, err := tun.fd.Read(buff[:])
+               if n < 4 {
+                       return 0, err
+               }
+               return n - 4, err
        }
 }
 
@@ -306,7 +332,7 @@ func CreateTUN(name string) (TUNDevice, error) {
        // create new device
 
        var ifr [IFReqSize]byte
-       var flags uint16 = unix.IFF_TUN | unix.IFF_NO_PI
+       var flags uint16 = unix.IFF_TUN // | unix.IFF_NO_PI
        nameBytes := []byte(name)
        if len(nameBytes) >= unix.IFNAMSIZ {
                return nil, errors.New("Interface name too long")