summaryrefslogtreecommitdiffhomepage
path: root/tun
diff options
context:
space:
mode:
authorSimon Rozman <simon@rozman.si>2019-02-20 11:41:37 +0100
committerSimon Rozman <simon@rozman.si>2019-02-20 11:41:37 +0100
commit6581cfb8850ee98dc9ee7aceb76e51b0de904db1 (patch)
treed9a3b87f19d71127c4a94cce522b5fe762e343c9 /tun
parent486308912077a665006afa93c76b9fa377446d12 (diff)
wintun: Move exchange buffer in separate struct on heap
This allows buffer alignment and keeps it together with its meta-data. Furthermore, the write buffer has been reduced - as long as we flush after _every_ write, we don't need a 1MiB write buffer. Signed-off-by: Simon Rozman <simon@rozman.si>
Diffstat (limited to 'tun')
-rw-r--r--tun/tun_windows.go77
1 files changed, 44 insertions, 33 deletions
diff --git a/tun/tun_windows.go b/tun/tun_windows.go
index 3c990c4..d2bcd01 100644
--- a/tun/tun_windows.go
+++ b/tun/tun_windows.go
@@ -18,7 +18,8 @@ const (
packetSizeMax uint32 = 0xeffc // Maximum packet size: 4 + packetSizeMax == 0xf000
packetExchangeMax uint32 = 256 // Number of packets that may be written at a time
packetExchangeAlignment uint32 = 16 // Number of bytes packets are aligned to in exchange buffers
- packetExchangeSize uint32 = 0x100000 // Exchange buffer size (defaults to 1MiB)
+ packetExchangeSizeRead uint32 = 0x100000 // Read exchange buffer size (defaults to 1MiB)
+ packetExchangeSizeWrite uint32 = 0x10000 // Write exchange buffer size (defaults to 64kiB)
)
const (
@@ -28,20 +29,28 @@ const (
signalMax
)
+type exchgBufRead struct {
+ data [packetExchangeSizeRead]byte
+ offset uint32
+ avail uint32
+}
+
+type exchgBufWrite struct {
+ data [packetExchangeSizeWrite]byte
+ offset uint32
+ packetNum uint32
+}
+
type nativeTun struct {
- wt *wintun.Wintun
- tunName string
- signalName *uint16
- tunFile *os.File
- wrBuff [packetExchangeSize]byte
- rdBuff [packetExchangeSize]byte
- signals [signalMax]windows.Handle
- wrOffset uint32
- wrPacketNum uint32
- rdOffset uint32
- rdAvailabe uint32
- events chan TUNEvent
- errors chan error
+ wt *wintun.Wintun
+ tunName string
+ signalName *uint16
+ tunFile *os.File
+ rdBuff *exchgBufRead
+ wrBuff *exchgBufWrite
+ signals [signalMax]windows.Handle
+ events chan TUNEvent
+ errors chan error
}
func packetAlign(size uint32) uint32 {
@@ -88,6 +97,8 @@ func CreateTUN(ifname string) (TUNDevice, error) {
wt: wt,
tunName: wt.DataFileName(),
signalName: signalNameUTF16,
+ rdBuff: &exchgBufRead{},
+ wrBuff: &exchgBufWrite{},
events: make(chan TUNEvent, 10),
errors: make(chan error, 1),
}
@@ -203,19 +214,19 @@ func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
}
for {
- if tun.rdOffset+4 <= tun.rdAvailabe {
- // Get packet from the queue.
- size := *(*uint32)(unsafe.Pointer(&tun.rdBuff[tun.rdOffset]))
+ if tun.rdBuff.offset+4 <= tun.rdBuff.avail {
+ // Get packet from the exchange buffer.
+ size := *(*uint32)(unsafe.Pointer(&tun.rdBuff.data[tun.rdBuff.offset]))
pSize := packetAlign(4 + size)
- if packetSizeMax < size || tun.rdAvailabe < tun.rdOffset+pSize {
+ if packetSizeMax < size || tun.rdBuff.avail < tun.rdBuff.offset+pSize {
// Invalid packet size.
- tun.rdAvailabe = 0
+ tun.rdBuff.avail = 0
continue
}
// Copy data.
- copy(buff[offset:], (*(*[packetSizeMax]byte)(unsafe.Pointer(&tun.rdBuff[tun.rdOffset+4])))[:size])
- tun.rdOffset += pSize
+ copy(buff[offset:], (*(*[packetSizeMax]byte)(unsafe.Pointer(&tun.rdBuff.data[tun.rdBuff.offset+4])))[:size])
+ tun.rdBuff.offset += pSize
return int(size), nil
}
@@ -249,16 +260,16 @@ func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
}
// Fill queue.
- n, err := tun.tunFile.Read(tun.rdBuff[:])
+ n, err := tun.tunFile.Read(tun.rdBuff.data[:])
if err != nil {
// TUN interface stopped, returned incomplete data, etc.
// Retry.
- tun.rdAvailabe = 0
+ tun.rdBuff.avail = 0
tun.closeTUN()
continue
}
- tun.rdOffset = 0
- tun.rdAvailabe = uint32(n)
+ tun.rdBuff.offset = 0
+ tun.rdBuff.avail = uint32(n)
}
}
@@ -266,9 +277,9 @@ func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
func (tun *nativeTun) flush() error {
// Flush write buffer.
- _, err := tun.tunFile.Write(tun.wrBuff[:tun.wrOffset])
- tun.wrPacketNum = 0
- tun.wrOffset = 0
+ _, err := tun.tunFile.Write(tun.wrBuff.data[:tun.wrBuff.offset])
+ tun.wrBuff.packetNum = 0
+ tun.wrBuff.offset = 0
if err != nil {
return err
}
@@ -286,7 +297,7 @@ func (tun *nativeTun) putTunPacket(buff []byte) error {
}
pSize := packetAlign(4 + size)
- if tun.wrPacketNum >= packetExchangeMax || tun.wrOffset+pSize >= packetExchangeSize {
+ if tun.wrBuff.packetNum >= packetExchangeMax || tun.wrBuff.offset+pSize >= packetExchangeSizeWrite {
// Exchange buffer is full -> flush first.
err := tun.flush()
if err != nil {
@@ -295,11 +306,11 @@ func (tun *nativeTun) putTunPacket(buff []byte) error {
}
// Write packet to the exchange buffer.
- *(*uint32)(unsafe.Pointer(&tun.wrBuff[tun.wrOffset])) = size
- copy((*(*[packetSizeMax]byte)(unsafe.Pointer(&tun.wrBuff[tun.wrOffset+4])))[:size], buff)
+ *(*uint32)(unsafe.Pointer(&tun.wrBuff.data[tun.wrBuff.offset])) = size
+ copy((*(*[packetSizeMax]byte)(unsafe.Pointer(&tun.wrBuff.data[tun.wrBuff.offset+4])))[:size], buff)
- tun.wrPacketNum++
- tun.wrOffset += pSize
+ tun.wrBuff.packetNum++
+ tun.wrBuff.offset += pSize
return nil
}