From: Sergey Matveev Date: Sun, 15 Mar 2015 16:04:20 +0000 (+0300) Subject: Keep TAP listener state and skip sinkReady step if necessary X-Git-Tag: 2.2^2~1 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=bbcfbd66002c4aa1b2d8fd7e10a71c930b66da49;p=govpn.git Keep TAP listener state and skip sinkReady step if necessary Signed-off-by: Sergey Matveev --- diff --git a/tap.go b/tap.go index 85926d7..4fee83a 100644 --- a/tap.go +++ b/tap.go @@ -26,11 +26,12 @@ import ( ) type TAP struct { - Name string - dev io.ReadWriter - buf []byte - sink chan []byte - ready chan struct{} + Name string + dev io.ReadWriter + buf []byte + sink chan []byte + ready chan struct{} + synced bool } func NewTAP(ifaceName string) (*TAP, error) { @@ -40,11 +41,12 @@ func NewTAP(ifaceName string) (*TAP, error) { return nil, err } tap := TAP{ - Name: ifaceName, - dev: tapRaw, - buf: make([]byte, maxIfacePktSize), - sink: make(chan []byte), - ready: make(chan struct{}), + Name: ifaceName, + dev: tapRaw, + buf: make([]byte, maxIfacePktSize), + sink: make(chan []byte), + ready: make(chan struct{}), + synced: false, } go func() { var n int diff --git a/transport.go b/transport.go index 8c5e8eb..d72fcc1 100644 --- a/transport.go +++ b/transport.go @@ -102,6 +102,7 @@ func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{ sink := make(chan []byte) sinkReady := make(chan struct{}) sinkTerminate := make(chan struct{}) + sinkSkip := make(chan struct{}) go func() { heartbeat := time.Tick(heartbeatPeriodGet()) @@ -114,12 +115,10 @@ func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{ case <-heartbeat: go func() { sink <- make([]byte, 0) }() continue + case <-sinkSkip: case <-sinkReady: - if exists { - exists = false - break - } tap.ready <- struct{}{} + tap.synced = true } HeartbeatCatched: select { @@ -129,12 +128,19 @@ func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{ case <-sinkTerminate: break ListenCycle case pkt = <-tap.sink: + tap.synced = false sink <- pkt } } close(sink) + close(sinkReady) + close(sinkTerminate) }() - sinkReady <- struct{}{} + if exists && tap.synced { + sinkSkip <- struct{}{} + } else { + sinkReady <- struct{}{} + } return tap, sink, sinkReady, sinkTerminate, nil }