Added padding

Added plaintext padding and fixed default interface MTU
This commit is contained in:
Mathias Hall-Andersen 2017-07-15 16:27:59 +02:00
parent b21c82e32d
commit dd4da93749
4 changed files with 77 additions and 17 deletions

View file

@ -4,10 +4,12 @@ import (
"net" "net"
"runtime" "runtime"
"sync" "sync"
"sync/atomic"
"time"
) )
type Device struct { type Device struct {
mtu int mtu int32
log *Logger // collection of loggers for levels log *Logger // collection of loggers for levels
idCounter uint // for assigning debug ids to peers idCounter uint // for assigning debug ids to peers
fwMark uint32 fwMark uint32
@ -118,6 +120,7 @@ func NewDevice(tun TUNDevice, logLevel int) *Device {
} }
go device.RoutineBusyMonitor() go device.RoutineBusyMonitor()
go device.RoutineMTUUpdater(tun)
go device.RoutineWriteToTUN(tun) go device.RoutineWriteToTUN(tun)
go device.RoutineReadFromTUN(tun) go device.RoutineReadFromTUN(tun)
go device.RoutineReceiveIncomming() go device.RoutineReceiveIncomming()
@ -126,6 +129,18 @@ func NewDevice(tun TUNDevice, logLevel int) *Device {
return device return device
} }
func (device *Device) RoutineMTUUpdater(tun TUNDevice) {
logError := device.log.Error
for ; ; time.Sleep(time.Second) {
mtu, err := tun.MTU()
if err != nil {
logError.Println("Failed to load updated MTU of device:", err)
continue
}
atomic.StoreInt32(&device.mtu, int32(mtu))
}
}
func (device *Device) LookupPeer(pk NoisePublicKey) *Peer { func (device *Device) LookupPeer(pk NoisePublicKey) *Peer {
device.mutex.RLock() device.mutex.RLock()
defer device.mutex.RUnlock() defer device.mutex.RUnlock()

View file

@ -281,7 +281,6 @@ func (device *Device) RoutineEncryption() {
// populate header fields // populate header fields
func() {
header := work.buffer[:MessageTransportHeaderSize] header := work.buffer[:MessageTransportHeaderSize]
fieldType := header[0:4] fieldType := header[0:4]
@ -291,7 +290,13 @@ func (device *Device) RoutineEncryption() {
binary.LittleEndian.PutUint32(fieldType, MessageTransportType) binary.LittleEndian.PutUint32(fieldType, MessageTransportType)
binary.LittleEndian.PutUint32(fieldReceiver, work.keyPair.remoteIndex) binary.LittleEndian.PutUint32(fieldReceiver, work.keyPair.remoteIndex)
binary.LittleEndian.PutUint64(fieldNonce, work.nonce) binary.LittleEndian.PutUint64(fieldNonce, work.nonce)
}()
// pad content to MTU size
mtu := int(atomic.LoadInt32(&device.mtu))
for i := len(work.packet); i < mtu; i++ {
work.packet = append(work.packet, 0)
}
// encrypt content // encrypt content

View file

@ -1,5 +1,11 @@
package main package main
/*
* The default MTU of the new device must be 1420
*/
const DefaultMTU = 1420
type TUNDevice interface { type TUNDevice interface {
Read([]byte) (int, error) // read a packet from the device (without any additional headers) 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) Write([]byte) (int, error) // writes a packet to the device (without any additional headers)

View file

@ -23,6 +23,39 @@ func (tun *NativeTun) Name() string {
return tun.name return tun.name
} }
func (tun *NativeTun) setMTU(n int) error {
// open datagram socket
fd, err := syscall.Socket(
syscall.AF_INET,
syscall.SOCK_DGRAM,
0,
)
if err != nil {
return err
}
// do ioctl call
var ifr [64]byte
copy(ifr[:], tun.name)
binary.LittleEndian.PutUint32(ifr[16:20], uint32(n))
_, _, errno := syscall.Syscall(
syscall.SYS_IOCTL,
uintptr(fd),
uintptr(syscall.SIOCSIFMTU),
uintptr(unsafe.Pointer(&ifr[0])),
)
if errno != 0 {
return errors.New("Failed to set MTU of TUN device")
}
return nil
}
func (tun *NativeTun) MTU() (int, error) { func (tun *NativeTun) MTU() (int, error) {
// open datagram socket // open datagram socket
@ -40,9 +73,7 @@ func (tun *NativeTun) MTU() (int, error) {
// do ioctl call // do ioctl call
var ifr [64]byte var ifr [64]byte
var flags uint16
copy(ifr[:], tun.name) copy(ifr[:], tun.name)
binary.LittleEndian.PutUint16(ifr[16:], flags)
_, _, errno := syscall.Syscall( _, _, errno := syscall.Syscall(
syscall.SYS_IOCTL, syscall.SYS_IOCTL,
uintptr(fd), uintptr(fd),
@ -79,7 +110,7 @@ func CreateTUN(name string) (TUNDevice, error) {
return nil, err return nil, err
} }
// prepare ifreq struct // create new device
var ifr [64]byte var ifr [64]byte
var flags uint16 = syscall.IFF_TUN | syscall.IFF_NO_PI var flags uint16 = syscall.IFF_TUN | syscall.IFF_NO_PI
@ -90,8 +121,6 @@ func CreateTUN(name string) (TUNDevice, error) {
copy(ifr[:], nameBytes) copy(ifr[:], nameBytes)
binary.LittleEndian.PutUint16(ifr[16:], flags) binary.LittleEndian.PutUint16(ifr[16:], flags)
// create new device
_, _, errno := syscall.Syscall( _, _, errno := syscall.Syscall(
syscall.SYS_IOCTL, syscall.SYS_IOCTL,
uintptr(fd.Fd()), uintptr(fd.Fd()),
@ -106,8 +135,13 @@ func CreateTUN(name string) (TUNDevice, error) {
newName := string(ifr[:]) newName := string(ifr[:])
newName = newName[:strings.Index(newName, "\000")] newName = newName[:strings.Index(newName, "\000")]
return &NativeTun{ device := &NativeTun{
fd: fd, fd: fd,
name: newName, name: newName,
}, nil }
// set default MTU
err = device.setMTU(DefaultMTU)
return device, err
} }