From: Bruno Clermont Date: Tue, 7 Mar 2017 03:48:52 +0000 (+0800) Subject: fix close by interrupt read, do not close multiple times X-Git-Url: http://www.git.cypherpunks.ru/?p=govpn.git;a=commitdiff_plain;h=ff2ecfd11acbf58a2e1a5885ef6859f811ff2c77 fix close by interrupt read, do not close multiple times --- diff --git a/src/cypherpunks.ru/govpn/tap.go b/src/cypherpunks.ru/govpn/tap.go index efb53a3..dd3c7e9 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 @@ func NewTAP(ifaceName string, mtu int) (*TAP, error) { 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 @@ func (t *TAP) Write(data []byte) (int, error) { // 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 15c5940..1530d2e 100644 --- a/src/cypherpunks.ru/govpn/tap_android.go +++ b/src/cypherpunks.ru/govpn/tap_android.go @@ -53,6 +53,10 @@ func TapListenFileDescriptor(fd uintptr, ifaceName string, mtu int) *TAP { 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)