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,
// wait for decryption
elem.mutex.Lock()
+
if elem.IsDropped() {
continue
}
// 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)
// 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()
continue
}
- elem.packet = elem.packet[:size]
+ elem.packet = elem.buffer[offset : offset+size]
// lookup peer
)
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() {
"encoding/binary"
"errors"
"fmt"
+ "golang.org/x/net/ipv6"
"golang.org/x/sys/unix"
"net"
"os"
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
}
}
// 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")