aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2017-12-04 21:39:06 +0100
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2017-12-04 21:39:06 +0100
commit996c7c4d8aa11a73718e49b520d16bbf0630a3df (patch)
tree458d8349b53eb9b6a9f9d0fdd364a43ac10b96c5
parent9fef0ca2fb26bfc15a5b25fdc4a03768fd6207b8 (diff)
downloadwireguard-go-996c7c4d8aa11a73718e49b520d16bbf0630a3df.tar.gz
wireguard-go-996c7c4d8aa11a73718e49b520d16bbf0630a3df.zip
Removed IFF_NO_PI from TUN linux
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.
-rw-r--r--src/receive.go21
-rw-r--r--src/send.go7
-rw-r--r--src/tun.go14
-rw-r--r--src/tun_linux.go36
4 files changed, 60 insertions, 18 deletions
diff --git a/src/receive.go b/src/receive.go
index f650cc9..dbd2813 100644
--- a/src/receive.go
+++ b/src/receive.go
@@ -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)
diff --git a/src/send.go b/src/send.go
index 2919f2e..9537f5e 100644
--- a/src/send.go
+++ b/src/send.go
@@ -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
diff --git a/src/tun.go b/src/tun.go
index 215022c..54253b4 100644
--- a/src/tun.go
+++ b/src/tun.go
@@ -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() {
diff --git a/src/tun_linux.go b/src/tun_linux.go
index 8a5d53b..daa2462 100644
--- a/src/tun_linux.go
+++ b/src/tun_linux.go
@@ -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")