5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-25 23:01:38 +00:00

don't panic if we write to a closed tun device because tun.close() was called

This commit is contained in:
Arceliar 2018-12-16 17:01:59 -06:00
parent 1a1e0553aa
commit d9f212dd39

View File

@ -5,6 +5,7 @@ package yggdrasil
import (
"bytes"
"errors"
"sync"
"time"
"github.com/songgao/packets/ethernet"
@ -24,6 +25,8 @@ type tunAdapter struct {
icmpv6 icmpv6
mtu int
iface *water.Interface
mutex sync.RWMutex // Protects the below
isOpen bool
}
// Gets the maximum supported MTU for the platform based on the defaults in
@ -50,6 +53,9 @@ func (tun *tunAdapter) start(ifname string, iftapmode bool, addr string, mtu int
if err := tun.setup(ifname, iftapmode, addr, mtu); err != nil {
return err
}
tun.mutex.Lock()
tun.isOpen = true
tun.mutex.Unlock()
go func() { panic(tun.read()) }()
go func() { panic(tun.write()) }()
if iftapmode {
@ -148,14 +154,28 @@ func (tun *tunAdapter) write() error {
len(data)) // Payload length
copy(frame[tun_ETHER_HEADER_LENGTH:], data[:])
if _, err := tun.iface.Write(frame); err != nil {
tun.mutex.RLock()
open := tun.isOpen
tun.mutex.RUnlock()
if !open {
return nil
} else {
panic(err)
}
}
}
} else {
if _, err := tun.iface.Write(data); err != nil {
tun.mutex.RLock()
open := tun.isOpen
tun.mutex.RUnlock()
if !open {
return nil
} else {
panic(err)
}
}
}
util.PutBytes(data)
}
}
@ -173,9 +193,16 @@ func (tun *tunAdapter) read() error {
for {
n, err := tun.iface.Read(buf)
if err != nil {
tun.mutex.RLock()
open := tun.isOpen
tun.mutex.RUnlock()
if !open {
return nil
} else {
// panic(err)
return err
}
}
o := 0
if tun.iface.IsTAP() {
o = tun_ETHER_HEADER_LENGTH
@ -202,6 +229,9 @@ func (tun *tunAdapter) read() error {
// process stops. Typically this operation will happen quickly, but on macOS
// it can block until a read operation is completed.
func (tun *tunAdapter) close() error {
tun.mutex.Lock()
tun.isOpen = false
tun.mutex.Unlock()
if tun.iface == nil {
return nil
}