]> Cypherpunks.ru repositories - govpn.git/commitdiff
Keep TAP listener state and skip sinkReady step if necessary
authorSergey Matveev <stargrave@stargrave.org>
Sun, 15 Mar 2015 16:04:20 +0000 (19:04 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 15 Mar 2015 16:04:20 +0000 (19:04 +0300)
Signed-off-by: Sergey Matveev <stargrave@stargrave.org>
tap.go
transport.go

diff --git a/tap.go b/tap.go
index 85926d7df9d1c4d290f85c77408251de0e50f417..4fee83a28c3ea920cb619da22a1a9ddc984d71e7 100644 (file)
--- 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
index 8c5e8eb249eb65473c38cda1da4892cd0ad182c3..d72fcc15ea140c74584514dd380fbc3fe6dea607 100644 (file)
@@ -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
 }