receive: implement flush semantics
This commit is contained in:
parent
49ea0c9b1a
commit
6440f010ee
|
@ -482,6 +482,33 @@ func (device *Device) RoutineHandshake() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (peer *Peer) elementStopOrFlush(shouldFlush *bool) (stop bool, elemOk bool, elem *QueueInboundElement) {
|
||||||
|
if !*shouldFlush {
|
||||||
|
select {
|
||||||
|
case <-peer.routines.stop:
|
||||||
|
stop = true
|
||||||
|
return
|
||||||
|
case elem, elemOk = <-peer.queue.inbound:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
select {
|
||||||
|
case <-peer.routines.stop:
|
||||||
|
stop = true
|
||||||
|
return
|
||||||
|
case elem, elemOk = <-peer.queue.inbound:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
*shouldFlush = false
|
||||||
|
err := peer.device.tun.device.Flush()
|
||||||
|
if err != nil {
|
||||||
|
peer.device.log.Error.Printf("Unable to flush packets: %v", err)
|
||||||
|
}
|
||||||
|
return peer.elementStopOrFlush(shouldFlush)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (peer *Peer) RoutineSequentialReceiver() {
|
func (peer *Peer) RoutineSequentialReceiver() {
|
||||||
|
|
||||||
device := peer.device
|
device := peer.device
|
||||||
|
@ -491,6 +518,9 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||||
|
|
||||||
var elem *QueueInboundElement
|
var elem *QueueInboundElement
|
||||||
var ok bool
|
var ok bool
|
||||||
|
var stop bool
|
||||||
|
|
||||||
|
shouldFlush := false
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
logDebug.Println(peer, "- Routine: sequential receiver - stopped")
|
logDebug.Println(peer, "- Routine: sequential receiver - stopped")
|
||||||
|
@ -516,14 +546,8 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||||
elem = nil
|
elem = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
stop, ok, elem = peer.elementStopOrFlush(&shouldFlush)
|
||||||
|
if stop || !ok {
|
||||||
case <-peer.routines.stop:
|
|
||||||
return
|
|
||||||
|
|
||||||
case elem, ok = <-peer.queue.inbound:
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,9 +657,11 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||||
offset := MessageTransportOffsetContent
|
offset := MessageTransportOffsetContent
|
||||||
atomic.AddUint64(&peer.stats.rxBytes, uint64(len(elem.packet)))
|
atomic.AddUint64(&peer.stats.rxBytes, uint64(len(elem.packet)))
|
||||||
_, err := device.tun.device.Write(elem.buffer[:offset+len(elem.packet)], offset)
|
_, err := device.tun.device.Write(elem.buffer[:offset+len(elem.packet)], offset)
|
||||||
|
if err == nil {
|
||||||
|
shouldFlush = true
|
||||||
|
}
|
||||||
if err != nil && !device.isClosed.Get() {
|
if err != nil && !device.isClosed.Get() {
|
||||||
logError.Println("Failed to write packet to TUN device:", err)
|
logError.Println("Failed to write packet to TUN device:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ type TUNDevice interface {
|
||||||
File() *os.File // returns the file descriptor of the device
|
File() *os.File // returns the file descriptor of the device
|
||||||
Read([]byte, int) (int, error) // read a packet from the device (without any additional headers)
|
Read([]byte, int) (int, error) // read a packet from the device (without any additional headers)
|
||||||
Write([]byte, int) (int, error) // writes a packet to the device (without any additional headers)
|
Write([]byte, int) (int, error) // writes a packet to the device (without any additional headers)
|
||||||
|
Flush() error // flush all previous writes to the device
|
||||||
MTU() (int, error) // returns the MTU of the device
|
MTU() (int, error) // returns the MTU of the device
|
||||||
Name() (string, error) // fetches and returns the current name
|
Name() (string, error) // fetches and returns the current name
|
||||||
Events() chan TUNEvent // returns a constant channel of events related to the device
|
Events() chan TUNEvent // returns a constant channel of events related to the device
|
||||||
|
|
|
@ -281,6 +281,11 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
return tun.tunFile.Write(buff)
|
return tun.tunFile.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tun *NativeTun) Flush() error {
|
||||||
|
//TODO: can flushing be implemented by buffering and using sendmmsg?
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Close() error {
|
func (tun *NativeTun) Close() error {
|
||||||
var err2 error
|
var err2 error
|
||||||
err1 := tun.tunFile.Close()
|
err1 := tun.tunFile.Close()
|
||||||
|
|
|
@ -406,6 +406,11 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
return tun.tunFile.Write(buff)
|
return tun.tunFile.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tun *NativeTun) Flush() error {
|
||||||
|
//TODO: can flushing be implemented by buffering and using sendmmsg?
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Close() error {
|
func (tun *NativeTun) Close() error {
|
||||||
var err3 error
|
var err3 error
|
||||||
err1 := tun.tunFile.Close()
|
err1 := tun.tunFile.Close()
|
||||||
|
|
|
@ -318,6 +318,11 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
return tun.tunFile.Write(buff)
|
return tun.tunFile.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tun *NativeTun) Flush() error {
|
||||||
|
//TODO: can flushing be implemented by buffering and using sendmmsg?
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Read(buff []byte, offset int) (int, error) {
|
func (tun *NativeTun) Read(buff []byte, offset int) (int, error) {
|
||||||
select {
|
select {
|
||||||
case err := <-tun.errors:
|
case err := <-tun.errors:
|
||||||
|
|
|
@ -237,6 +237,11 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
return tun.tunFile.Write(buff)
|
return tun.tunFile.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tun *NativeTun) Flush() error {
|
||||||
|
//TODO: can flushing be implemented by buffering and using sendmmsg?
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tun *NativeTun) Close() error {
|
func (tun *NativeTun) Close() error {
|
||||||
var err2 error
|
var err2 error
|
||||||
err1 := tun.tunFile.Close()
|
err1 := tun.tunFile.Close()
|
||||||
|
|
|
@ -281,7 +281,11 @@ func (tun *NativeTun) Read(buff []byte, offset int) (int, error) {
|
||||||
|
|
||||||
// Note: flush() and putTunPacket() assume the caller comes only from a single thread; there's no locking.
|
// Note: flush() and putTunPacket() assume the caller comes only from a single thread; there's no locking.
|
||||||
|
|
||||||
func (tun *NativeTun) flush() error {
|
func (tun *NativeTun) Flush() error {
|
||||||
|
if tun.wrBuff.offset == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Get TUN data pipe.
|
// Get TUN data pipe.
|
||||||
file, err := tun.getTUN()
|
file, err := tun.getTUN()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -322,7 +326,7 @@ func (tun *NativeTun) putTunPacket(buff []byte) error {
|
||||||
|
|
||||||
if tun.wrBuff.packetNum >= packetExchangeMax || tun.wrBuff.offset+pSize >= packetExchangeSize {
|
if tun.wrBuff.packetNum >= packetExchangeMax || tun.wrBuff.offset+pSize >= packetExchangeSize {
|
||||||
// Exchange buffer is full -> flush first.
|
// Exchange buffer is full -> flush first.
|
||||||
err := tun.flush()
|
err := tun.Flush()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -345,9 +349,7 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
return len(buff) - offset, nil
|
||||||
// Flush write buffer.
|
|
||||||
return len(buff) - offset, tun.flush()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue