wintun: Simplify Read method()

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2019-02-08 14:31:05 +01:00
parent 713477cfb1
commit f05f52637f

View File

@ -203,64 +203,64 @@ func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
select { select {
case err := <-tun.errors: case err := <-tun.errors:
return 0, err return 0, err
default: default:
for { }
if tun.rdNextPacket < tun.rdBuff.numPackets {
// Get packet from the queue.
tunPacket := &tun.rdBuff.packets[tun.rdNextPacket]
tun.rdNextPacket++
if packetSizeMax < tunPacket.size { for {
// Invalid packet size. if tun.rdNextPacket < tun.rdBuff.numPackets {
continue // Get packet from the queue.
} tunPacket := &tun.rdBuff.packets[tun.rdNextPacket]
tun.rdNextPacket++
// Copy data. if packetSizeMax < tunPacket.size {
copy(buff[offset:], tunPacket.data[:tunPacket.size]) // Invalid packet size.
return int(tunPacket.size), nil continue
} }
if tun.signals[signalDataAvail] == 0 { // Copy data.
// Data pipe and interface data available event are not open (yet). copy(buff[offset:], tunPacket.data[:tunPacket.size])
err := tun.openTUN() return int(tunPacket.size), nil
if err != nil { }
return 0, err
}
}
// Wait for user close or interface data. if tun.signals[signalDataAvail] == 0 {
r, err := windows.WaitForMultipleObjects(tun.signals[:], false, windows.INFINITE) // Data pipe and interface data available event are not open (yet).
err := tun.openTUN()
if err != nil { if err != nil {
return 0, errors.New("Waiting for data failed: " + err.Error()) return 0, err
}
switch r {
case windows.WAIT_OBJECT_0 + signalClose, windows.WAIT_ABANDONED + signalClose:
return 0, errors.New("TUN closed")
case windows.WAIT_OBJECT_0 + signalDataAvail:
// Data is available.
case windows.WAIT_ABANDONED + signalDataAvail:
// TUN stopped. Reopen it.
tun.closeTUN()
continue
case windows.WAIT_TIMEOUT:
// Congratulations, we reached infinity. Let's do it again! :)
continue
default:
return 0, errors.New("unexpected result from WaitForMultipleObjects")
} }
}
// Fill queue. // Wait for user close or interface data.
data := (*[exchangeBufferSize]byte)(unsafe.Pointer(&tun.rdBuff)) r, err := windows.WaitForMultipleObjects(tun.signals[:], false, windows.INFINITE)
n, err := tun.tunFile.Read(data[:]) if err != nil {
tun.rdNextPacket = 0 return 0, errors.New("Waiting for data failed: " + err.Error())
if n != exchangeBufferSize || err != nil { }
// TUN interface stopped, returned incomplete data, etc. switch r {
// Retry. case windows.WAIT_OBJECT_0 + signalClose, windows.WAIT_ABANDONED + signalClose:
tun.rdBuff.numPackets = 0 return 0, errors.New("TUN closed")
tun.closeTUN() case windows.WAIT_OBJECT_0 + signalDataAvail:
continue // Data is available.
} case windows.WAIT_ABANDONED + signalDataAvail:
// TUN stopped. Reopen it.
tun.closeTUN()
continue
case windows.WAIT_TIMEOUT:
// Congratulations, we reached infinity. Let's do it again! :)
continue
default:
return 0, errors.New("unexpected result from WaitForMultipleObjects")
}
// Fill queue.
data := (*[exchangeBufferSize]byte)(unsafe.Pointer(&tun.rdBuff))
n, err := tun.tunFile.Read(data[:])
tun.rdNextPacket = 0
if n != exchangeBufferSize || err != nil {
// TUN interface stopped, returned incomplete data, etc.
// Retry.
tun.rdBuff.numPackets = 0
tun.closeTUN()
continue
} }
} }
} }