mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2024-12-25 01:07:49 +00:00
Merge pull request #461 from yggdrasil-network/connreader
Try to fix TUN/TAP conn reader leakage
This commit is contained in:
commit
2532cd77e4
@ -11,6 +11,8 @@ import (
|
|||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const tunConnTimeout = 2 * time.Minute
|
||||||
|
|
||||||
type tunConn struct {
|
type tunConn struct {
|
||||||
tun *TunAdapter
|
tun *TunAdapter
|
||||||
conn *yggdrasil.Conn
|
conn *yggdrasil.Conn
|
||||||
@ -49,24 +51,37 @@ func (s *tunConn) reader() error {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
s.tun.log.Debugln("Starting conn reader for", s)
|
||||||
var n int
|
var n int
|
||||||
var err error
|
var err error
|
||||||
read := make(chan bool)
|
read := make(chan bool)
|
||||||
b := make([]byte, 65535)
|
b := make([]byte, 65535)
|
||||||
for {
|
|
||||||
go func() {
|
go func() {
|
||||||
// TODO don't start a new goroutine for every packet read, this is probably a big part of the slowdowns we saw when refactoring
|
s.tun.log.Debugln("Starting conn reader helper for", s)
|
||||||
|
for {
|
||||||
|
s.conn.SetReadDeadline(time.Now().Add(tunConnTimeout))
|
||||||
if n, err = s.conn.Read(b); err != nil {
|
if n, err = s.conn.Read(b); err != nil {
|
||||||
s.tun.log.Errorln(s.conn.String(), "TUN/TAP conn read error:", err)
|
s.tun.log.Errorln(s.conn.String(), "TUN/TAP conn read error:", err)
|
||||||
if e, eok := err.(yggdrasil.ConnError); eok && !e.Temporary() {
|
if e, eok := err.(yggdrasil.ConnError); eok {
|
||||||
close(s.stop)
|
switch {
|
||||||
} else {
|
case e.Temporary():
|
||||||
read <- false
|
read <- false
|
||||||
}
|
continue
|
||||||
|
case e.Timeout():
|
||||||
|
s.tun.log.Debugln("Conn reader for helper", s, "timed out")
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
s.tun.log.Debugln("Stopping conn reader helper for", s)
|
||||||
|
s.close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
read <- false
|
||||||
|
}
|
||||||
read <- true
|
read <- true
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
for {
|
||||||
select {
|
select {
|
||||||
case r := <-read:
|
case r := <-read:
|
||||||
if r && n > 0 {
|
if r && n > 0 {
|
||||||
@ -93,6 +108,7 @@ func (s *tunConn) writer() error {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
s.tun.log.Debugln("Starting conn writer for", s)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-s.stop:
|
case <-s.stop:
|
||||||
@ -134,8 +150,7 @@ func (s *tunConn) stillAlive() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *tunConn) checkForTimeouts() error {
|
func (s *tunConn) checkForTimeouts() error {
|
||||||
const timeout = 2 * time.Minute
|
timer := time.NewTimer(tunConnTimeout)
|
||||||
timer := time.NewTimer(timeout)
|
|
||||||
defer util.TimerStop(timer)
|
defer util.TimerStop(timer)
|
||||||
defer s.close()
|
defer s.close()
|
||||||
for {
|
for {
|
||||||
@ -145,7 +160,7 @@ func (s *tunConn) checkForTimeouts() error {
|
|||||||
return errors.New("connection closed")
|
return errors.New("connection closed")
|
||||||
}
|
}
|
||||||
util.TimerStop(timer)
|
util.TimerStop(timer)
|
||||||
timer.Reset(timeout)
|
timer.Reset(tunConnTimeout)
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
return errors.New("timed out")
|
return errors.New("timed out")
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user