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.
This commit is contained in:
parent
9fef0ca2fb
commit
996c7c4d8a
|
@ -243,13 +243,24 @@ func (device *Device) RoutineDecryption() {
|
||||||
counter := elem.packet[MessageTransportOffsetCounter:MessageTransportOffsetContent]
|
counter := elem.packet[MessageTransportOffsetCounter:MessageTransportOffsetContent]
|
||||||
content := elem.packet[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
|
// decrypt and release to consumer
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
copy(nonce[4:], counter)
|
|
||||||
elem.counter = binary.LittleEndian.Uint64(counter)
|
elem.counter = binary.LittleEndian.Uint64(counter)
|
||||||
elem.packet, err = elem.keyPair.receive.Open(
|
elem.packet, err = elem.keyPair.receive.Open(
|
||||||
elem.buffer[:0],
|
content[:0],
|
||||||
nonce[:],
|
nonce[:],
|
||||||
content,
|
content,
|
||||||
nil,
|
nil,
|
||||||
|
@ -495,6 +506,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||||
// wait for decryption
|
// wait for decryption
|
||||||
|
|
||||||
elem.mutex.Lock()
|
elem.mutex.Lock()
|
||||||
|
|
||||||
if elem.IsDropped() {
|
if elem.IsDropped() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -603,8 +615,11 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||||
|
|
||||||
// write to tun device
|
// write to tun device
|
||||||
|
|
||||||
|
offset := MessageTransportOffsetContent
|
||||||
atomic.AddUint64(&peer.stats.rxBytes, uint64(len(elem.packet)))
|
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)
|
device.PutMessageBuffer(elem.buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logError.Println("Failed to write packet to TUN device:", err)
|
logError.Println("Failed to write packet to TUN device:", err)
|
||||||
|
|
|
@ -127,8 +127,9 @@ func (device *Device) RoutineReadFromTUN() {
|
||||||
|
|
||||||
// read packet
|
// read packet
|
||||||
|
|
||||||
elem.packet = elem.buffer[MessageTransportHeaderSize:]
|
offset := MessageTransportHeaderSize
|
||||||
size, err := device.tun.device.Read(elem.packet)
|
size, err := device.tun.device.Read(elem.buffer[:], offset)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logError.Println("Failed to read packet from TUN device:", err)
|
logError.Println("Failed to read packet from TUN device:", err)
|
||||||
device.Close()
|
device.Close()
|
||||||
|
@ -139,7 +140,7 @@ func (device *Device) RoutineReadFromTUN() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
elem.packet = elem.packet[:size]
|
elem.packet = elem.buffer[offset : offset+size]
|
||||||
|
|
||||||
// lookup peer
|
// lookup peer
|
||||||
|
|
||||||
|
|
14
src/tun.go
14
src/tun.go
|
@ -16,13 +16,13 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type TUNDevice interface {
|
type TUNDevice interface {
|
||||||
File() *os.File // returns the file descriptor of the device
|
File() *os.File // returns the file descriptor of the device
|
||||||
Read([]byte) (int, error) // read a packet from the device (without any additional headers)
|
Read([]byte, int) (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)
|
Write([]byte, int) (int, error) // writes a packet to the device (without any additional headers)
|
||||||
MTU() (int, error) // returns the MTU of the device
|
MTU() (int, error) // returns the MTU of the device
|
||||||
Name() string // returns the current name
|
Name() string // returns the current name
|
||||||
Events() chan TUNEvent // returns a constant channel of events related to the device
|
Events() chan TUNEvent // returns a constant channel of events related to the device
|
||||||
Close() error // stops the device and closes the event channel
|
Close() error // stops the device and closes the event channel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (device *Device) RoutineTUNEventReader() {
|
func (device *Device) RoutineTUNEventReader() {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/net/ipv6"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
@ -249,16 +250,41 @@ func (tun *NativeTun) MTU() (int, error) {
|
||||||
return int(val), nil
|
return int(val), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Write(d []byte) (int, error) {
|
func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
return tun.fd.Write(d)
|
|
||||||
|
// 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 {
|
select {
|
||||||
case err := <-tun.errors:
|
case err := <-tun.errors:
|
||||||
return 0, err
|
return 0, err
|
||||||
default:
|
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
|
// create new device
|
||||||
|
|
||||||
var ifr [IFReqSize]byte
|
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)
|
nameBytes := []byte(name)
|
||||||
if len(nameBytes) >= unix.IFNAMSIZ {
|
if len(nameBytes) >= unix.IFNAMSIZ {
|
||||||
return nil, errors.New("Interface name too long")
|
return nil, errors.New("Interface name too long")
|
||||||
|
|
Loading…
Reference in a new issue