src/cypherpunks.ru/govpn/tap.go | 15 +++++++++++++-- src/cypherpunks.ru/govpn/tap_android.go | 4 ++++ diff --git a/src/cypherpunks.ru/govpn/tap.go b/src/cypherpunks.ru/govpn/tap.go index efb53a3e591c95dacf1f90057a9d065a63292ac4..dd3c7e9dd678606997c88ec2991430988aff9f1f 100644 --- a/src/cypherpunks.ru/govpn/tap.go +++ b/src/cypherpunks.ru/govpn/tap.go @@ -36,6 +36,7 @@ type TAP struct { Name string Sink chan []byte dev io.ReadWriteCloser + closed bool } var ( @@ -70,6 +71,9 @@ } bufZ = !bufZ n, err = tap.dev.Read(buf) if err != nil { + if tap.closed { + return + } logger.WithError(err).WithFields(logrus.Fields{ "func": logFuncPrefix + "TAP read sink loop", "name": tap.Name, @@ -93,8 +97,15 @@ } // Close close TAP/TUN virtual network interface func (t *TAP) Close() error { - // TODO add chan to stop read loop - return t.dev.Close() + if t.closed { + return nil + } + err := t.dev.Close() + if err != nil { + return errors.Wrap(err, "water.Interface.Close") + } + t.closed = true + return nil } // TAPListen opens an existing TAP (creates if none exists) diff --git a/src/cypherpunks.ru/govpn/tap_android.go b/src/cypherpunks.ru/govpn/tap_android.go index 15c5940f7648819eeffb8e1c6bdaee1123e182b2..1530d2e2cae2047e5f6fa011bfe72b2b0c5f61b4 100644 --- a/src/cypherpunks.ru/govpn/tap_android.go +++ b/src/cypherpunks.ru/govpn/tap_android.go @@ -53,6 +53,10 @@ } bufZ = !bufZ n, err = tap.dev.Read(buf) if err != nil { + if tap.closed { + return + } + e, ok := err.(*os.PathError) if ok && e.Err == syscall.EAGAIN { time.Sleep(time.Millisecond * 20)