Fixed MTU method for linux TUN interface
Updated the TUN interface Added the "MTU" method for the linux implementation of the TUN interface
This commit is contained in:
parent
c273078376
commit
86707cbc88
|
@ -4,15 +4,17 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* Specification constants */
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RekeyAfterMessages = (1 << 64) - (1 << 16) - 1
|
RekeyAfterMessages = (1 << 64) - (1 << 16) - 1
|
||||||
|
RejectAfterMessages = (1 << 64) - (1 << 4) - 1
|
||||||
RekeyAfterTime = time.Second * 120
|
RekeyAfterTime = time.Second * 120
|
||||||
RekeyAttemptTime = time.Second * 90
|
RekeyAttemptTime = time.Second * 90
|
||||||
RekeyTimeout = time.Second * 5 // TODO: Exponential backoff
|
RekeyTimeout = time.Second * 5
|
||||||
RejectAfterTime = time.Second * 180
|
RejectAfterTime = time.Second * 180
|
||||||
RejectAfterMessages = (1 << 64) - (1 << 4) - 1
|
|
||||||
KeepaliveTimeout = time.Second * 10
|
KeepaliveTimeout = time.Second * 10
|
||||||
CookieRefreshTime = time.Minute * 2
|
CookieRefreshTime = time.Second * 120
|
||||||
MaxHandshakeAttemptTime = time.Second * 90
|
MaxHandshakeAttemptTime = time.Second * 90
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,11 +22,13 @@ const (
|
||||||
RekeyAfterTimeReceiving = RekeyAfterTime - KeepaliveTimeout - RekeyTimeout
|
RekeyAfterTimeReceiving = RekeyAfterTime - KeepaliveTimeout - RekeyTimeout
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* Implementation specific constants */
|
||||||
|
|
||||||
const (
|
const (
|
||||||
QueueOutboundSize = 1024
|
QueueOutboundSize = 1024
|
||||||
QueueInboundSize = 1024
|
QueueInboundSize = 1024
|
||||||
QueueHandshakeSize = 1024
|
QueueHandshakeSize = 1024
|
||||||
QueueHandshakeBusySize = QueueHandshakeSize / 8
|
QueueHandshakeBusySize = QueueHandshakeSize / 8
|
||||||
MinMessageSize = MessageTransportSize // keep-alive
|
MinMessageSize = MessageTransportSize // keep-alive
|
||||||
MaxMessageSize = 4096
|
MaxMessageSize = 4096 // TODO: make depend on the MTU?
|
||||||
)
|
)
|
||||||
|
|
|
@ -64,7 +64,7 @@ func NewDevice(tun TUNDevice, logLevel int) *Device {
|
||||||
defer device.mutex.Unlock()
|
defer device.mutex.Unlock()
|
||||||
|
|
||||||
device.log = NewLogger(logLevel)
|
device.log = NewLogger(logLevel)
|
||||||
device.mtu = tun.MTU()
|
// device.mtu = tun.MTU()
|
||||||
device.peers = make(map[NoisePublicKey]*Peer)
|
device.peers = make(map[NoisePublicKey]*Peer)
|
||||||
device.indices.Init()
|
device.indices.Init()
|
||||||
device.ratelimiter.Init()
|
device.ratelimiter.Init()
|
||||||
|
|
|
@ -229,6 +229,7 @@ func (peer *Peer) RoutineHandshakeInitiator() {
|
||||||
|
|
||||||
run = func() bool {
|
run = func() bool {
|
||||||
for {
|
for {
|
||||||
|
|
||||||
// clear completed signal
|
// clear completed signal
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type TUNDevice interface {
|
type TUNDevice interface {
|
||||||
Read([]byte) (int, error)
|
Read([]byte) (int, error) // read a packet from the device (without any additional headers)
|
||||||
Write([]byte) (int, error)
|
Write([]byte) (int, error) // writes a packet to the device (without any additional headers)
|
||||||
Name() string
|
MTU() (int, error) // returns the MTU of the device
|
||||||
MTU() int
|
Name() string // returns the current name
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,25 +14,52 @@ import (
|
||||||
|
|
||||||
const CloneDevicePath = "/dev/net/tun"
|
const CloneDevicePath = "/dev/net/tun"
|
||||||
|
|
||||||
const (
|
|
||||||
IFF_NO_PI = 0x1000
|
|
||||||
IFF_TUN = 0x1
|
|
||||||
IFNAMSIZ = 0x10
|
|
||||||
TUNSETIFF = 0x400454CA
|
|
||||||
)
|
|
||||||
|
|
||||||
type NativeTun struct {
|
type NativeTun struct {
|
||||||
fd *os.File
|
fd *os.File
|
||||||
name string
|
name string
|
||||||
mtu int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Name() string {
|
func (tun *NativeTun) Name() string {
|
||||||
return tun.name
|
return tun.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) MTU() int {
|
func (tun *NativeTun) MTU() (int, error) {
|
||||||
return tun.mtu
|
|
||||||
|
// 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) {
|
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) {
|
func CreateTUN(name string) (TUNDevice, error) {
|
||||||
// Open clone device
|
|
||||||
|
// open clone device
|
||||||
|
|
||||||
fd, err := os.OpenFile(CloneDevicePath, os.O_RDWR, 0)
|
fd, err := os.OpenFile(CloneDevicePath, os.O_RDWR, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare ifreq struct
|
// prepare ifreq struct
|
||||||
var ifr [128]byte
|
|
||||||
var flags uint16 = IFF_TUN | IFF_NO_PI
|
var ifr [64]byte
|
||||||
|
var flags uint16 = syscall.IFF_TUN | syscall.IFF_NO_PI
|
||||||
nameBytes := []byte(name)
|
nameBytes := []byte(name)
|
||||||
if len(nameBytes) >= IFNAMSIZ {
|
if len(nameBytes) >= syscall.IFNAMSIZ {
|
||||||
return nil, errors.New("Name size too long")
|
return nil, errors.New("Name size too long")
|
||||||
}
|
}
|
||||||
copy(ifr[:], nameBytes)
|
copy(ifr[:], nameBytes)
|
||||||
binary.LittleEndian.PutUint16(ifr[16:], flags)
|
binary.LittleEndian.PutUint16(ifr[16:], flags)
|
||||||
|
|
||||||
// Create new device
|
// create new device
|
||||||
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
|
|
||||||
uintptr(fd.Fd()), uintptr(TUNSETIFF),
|
_, _, errno := syscall.Syscall(
|
||||||
uintptr(unsafe.Pointer(&ifr[0])))
|
syscall.SYS_IOCTL,
|
||||||
|
uintptr(fd.Fd()),
|
||||||
|
uintptr(syscall.TUNSETIFF),
|
||||||
|
uintptr(unsafe.Pointer(&ifr[0])),
|
||||||
|
)
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
return nil, errors.New("Failed to create tun, ioctl call failed")
|
return nil, errors.New("Failed to create tun, ioctl call failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read name of interface
|
// read (new) name of interface
|
||||||
|
|
||||||
newName := string(ifr[:])
|
newName := string(ifr[:])
|
||||||
newName = newName[:strings.Index(newName, "\000")]
|
newName = newName[:strings.Index(newName, "\000")]
|
||||||
return &NativeTun{
|
return &NativeTun{
|
||||||
fd: fd,
|
fd: fd,
|
||||||
name: newName,
|
name: newName,
|
||||||
mtu: 0,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue