diff options
-rw-r--r-- | src/constants.go | 12 | ||||
-rw-r--r-- | src/device.go | 2 | ||||
-rw-r--r-- | src/timers.go | 1 | ||||
-rw-r--r-- | src/tun.go | 8 | ||||
-rw-r--r-- | src/tun_linux.go | 76 |
5 files changed, 69 insertions, 30 deletions
diff --git a/src/constants.go b/src/constants.go index 4e8d521..0384741 100644 --- a/src/constants.go +++ b/src/constants.go @@ -4,15 +4,17 @@ import ( "time" ) +/* Specification constants */ + const ( RekeyAfterMessages = (1 << 64) - (1 << 16) - 1 + RejectAfterMessages = (1 << 64) - (1 << 4) - 1 RekeyAfterTime = time.Second * 120 RekeyAttemptTime = time.Second * 90 - RekeyTimeout = time.Second * 5 // TODO: Exponential backoff + RekeyTimeout = time.Second * 5 RejectAfterTime = time.Second * 180 - RejectAfterMessages = (1 << 64) - (1 << 4) - 1 KeepaliveTimeout = time.Second * 10 - CookieRefreshTime = time.Minute * 2 + CookieRefreshTime = time.Second * 120 MaxHandshakeAttemptTime = time.Second * 90 ) @@ -20,11 +22,13 @@ const ( RekeyAfterTimeReceiving = RekeyAfterTime - KeepaliveTimeout - RekeyTimeout ) +/* Implementation specific constants */ + const ( QueueOutboundSize = 1024 QueueInboundSize = 1024 QueueHandshakeSize = 1024 QueueHandshakeBusySize = QueueHandshakeSize / 8 MinMessageSize = MessageTransportSize // keep-alive - MaxMessageSize = 4096 + MaxMessageSize = 4096 // TODO: make depend on the MTU? ) diff --git a/src/device.go b/src/device.go index 2a2ad62..a26cc7b 100644 --- a/src/device.go +++ b/src/device.go @@ -64,7 +64,7 @@ func NewDevice(tun TUNDevice, logLevel int) *Device { defer device.mutex.Unlock() device.log = NewLogger(logLevel) - device.mtu = tun.MTU() + // device.mtu = tun.MTU() device.peers = make(map[NoisePublicKey]*Peer) device.indices.Init() device.ratelimiter.Init() diff --git a/src/timers.go b/src/timers.go index 70e0766..6393955 100644 --- a/src/timers.go +++ b/src/timers.go @@ -229,6 +229,7 @@ func (peer *Peer) RoutineHandshakeInitiator() { run = func() bool { for { + // clear completed signal select { @@ -1,8 +1,8 @@ package main type TUNDevice interface { - Read([]byte) (int, error) - Write([]byte) (int, error) - Name() string - MTU() int + 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 } diff --git a/src/tun_linux.go b/src/tun_linux.go index d16a966..63c3886 100644 --- a/src/tun_linux.go +++ b/src/tun_linux.go @@ -14,25 +14,52 @@ import ( const CloneDevicePath = "/dev/net/tun" -const ( - IFF_NO_PI = 0x1000 - IFF_TUN = 0x1 - IFNAMSIZ = 0x10 - TUNSETIFF = 0x400454CA -) - type NativeTun struct { fd *os.File name string - mtu int } func (tun *NativeTun) Name() string { return tun.name } -func (tun *NativeTun) MTU() int { - return tun.mtu +func (tun *NativeTun) MTU() (int, error) { + + // 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) { @@ -44,36 +71,43 @@ func (tun *NativeTun) Read(d []byte) (int, error) { } func CreateTUN(name string) (TUNDevice, error) { - // Open clone device + + // open clone device + fd, err := os.OpenFile(CloneDevicePath, os.O_RDWR, 0) if err != nil { return nil, err } - // Prepare ifreq struct - var ifr [128]byte - var flags uint16 = IFF_TUN | IFF_NO_PI + // prepare ifreq struct + + var ifr [64]byte + var flags uint16 = syscall.IFF_TUN | syscall.IFF_NO_PI nameBytes := []byte(name) - if len(nameBytes) >= IFNAMSIZ { + if len(nameBytes) >= syscall.IFNAMSIZ { return nil, errors.New("Name size too long") } copy(ifr[:], nameBytes) binary.LittleEndian.PutUint16(ifr[16:], flags) - // Create new device - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, - uintptr(fd.Fd()), uintptr(TUNSETIFF), - uintptr(unsafe.Pointer(&ifr[0]))) + // create new device + + _, _, errno := syscall.Syscall( + syscall.SYS_IOCTL, + uintptr(fd.Fd()), + uintptr(syscall.TUNSETIFF), + uintptr(unsafe.Pointer(&ifr[0])), + ) if errno != 0 { return nil, errors.New("Failed to create tun, ioctl call failed") } - // Read name of interface + // read (new) name of interface + newName := string(ifr[:]) newName = newName[:strings.Index(newName, "\000")] return &NativeTun{ fd: fd, name: newName, - mtu: 0, }, nil } |