fix timeout and improve logging on connection close

This commit is contained in:
Arceliar 2019-02-24 14:48:16 -06:00
parent 654407dc6d
commit def4fb3587

View File

@ -4,6 +4,7 @@ import (
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"io"
"net" "net"
"strings" "strings"
"sync" "sync"
@ -223,6 +224,7 @@ func (intf *linkInterface) handler() error {
// Used to enable/disable activity in the switch // Used to enable/disable activity in the switch
signalAlive := make(chan bool, 1) // True = real packet, false = keep-alive signalAlive := make(chan bool, 1) // True = real packet, false = keep-alive
defer close(signalAlive) defer close(signalAlive)
ret := make(chan error, 1) // How we signal the return value when multiple goroutines are involved
go func() { go func() {
var isAlive bool var isAlive bool
var isReady bool var isReady bool
@ -247,6 +249,7 @@ func (intf *linkInterface) handler() error {
return return
} }
util.TimerStop(closeTimer) util.TimerStop(closeTimer)
closeTimer.Reset(closeTime)
util.TimerStop(recvTimer) util.TimerStop(recvTimer)
recvTimerRunning = false recvTimerRunning = false
isAlive = true isAlive = true
@ -278,8 +281,6 @@ func (intf *linkInterface) handler() error {
// Start a timer, if it expires and we haven't gotten any return traffic (including a 0-sized ack), then assume there's a problem // Start a timer, if it expires and we haven't gotten any return traffic (including a 0-sized ack), then assume there's a problem
util.TimerStop(recvTimer) util.TimerStop(recvTimer)
recvTimer.Reset(recvTime) recvTimer.Reset(recvTime)
util.TimerStop(closeTimer)
closeTimer.Reset(closeTime)
recvTimerRunning = true recvTimerRunning = true
} }
case _, ok := <-signalReady: case _, ok := <-signalReady:
@ -306,18 +307,27 @@ func (intf *linkInterface) handler() error {
case <-closeTimer.C: case <-closeTimer.C:
// We haven't received anything in a really long time, so things have died at the switch level and then some... // We haven't received anything in a really long time, so things have died at the switch level and then some...
// Just close the connection at this point... // Just close the connection at this point...
select {
case ret <- errors.New("timeout"):
default:
}
intf.msgIO.close() intf.msgIO.close()
} }
} }
}() }()
// Run reader loop // Run reader loop
for { for {
var msg []byte msg, err := intf.msgIO.readMsg()
msg, err = intf.msgIO.readMsg()
if len(msg) > 0 { if len(msg) > 0 {
intf.peer.handlePacket(msg) intf.peer.handlePacket(msg)
} }
if err != nil { if err != nil {
if err != io.EOF {
select {
case ret <- err:
default:
}
}
break break
} }
select { select {
@ -327,7 +337,14 @@ func (intf *linkInterface) handler() error {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Remember to set `err` to something useful before returning // Remember to set `err` to something useful before returning
intf.link.core.log.Infof("Disconnected %s: %s, source %s, reason: %s", select {
case err = <-ret:
intf.link.core.log.Infof("Disconnected %s: %s, source %s; error: %s",
strings.ToUpper(intf.info.linkType), themString, intf.info.local, err) strings.ToUpper(intf.info.linkType), themString, intf.info.local, err)
default:
err = nil
intf.link.core.log.Infof("Disconnected %s: %s, source %s",
strings.ToUpper(intf.info.linkType), themString, intf.info.local)
}
return err return err
} }