Tear down connections on prolonged loss of UDP heartbeat

This commit is contained in:
Adam Harrison committed 2015-02-23 15:29:11 +00:00
1 parent e485e68946
commit 0a0ed7a871
2 files changed
+43 -23

No files matched your search

+23 -5
View File
@@ -45,6 +45,7 @@ type LocalConnection struct {
effectivePMTU int
SessionKey *[32]byte
establishedTimeout *time.Timer
heartbeatTimeout *time.Timer
heartbeatFrame *ForwardedFrame
heartbeat *time.Ticker
fragTest *time.Ticker
@@ -301,10 +302,12 @@ func (conn *LocalConnection) queryLoop(queryChan <-chan *ConnectionInteraction)
case CSendProtocolMsg:
err = conn.handleSendProtocolMsg(query.payload.(ProtocolMsg))
}
case <-conn.establishedTimeout.C:
case <-timerChan(conn.establishedTimeout):
if !conn.established {
err = fmt.Errorf("failed to establish UDP connectivity")
}
case <-timerChan(conn.heartbeatTimeout):
err = fmt.Errorf("timed out waiting for UDP heartbeat")
case <-tickerChan(conn.heartbeat):
conn.Forward(true, conn.heartbeatFrame, nil)
case <-tickerChan(conn.fragTest):
@@ -329,6 +332,9 @@ func (conn *LocalConnection) handleReceivedHeartbeat(remoteUDPAddr *net.UDPAddr)
conn.remoteUDPAddr = remoteUDPAddr
conn.receivedHeartbeat = true
conn.Unlock()
if conn.established {
conn.heartbeatTimeout.Reset(HeartbeatTimeout)
}
if !old {
if err := conn.handleSendSimpleProtocolMsg(ProtocolConnectionEstablished); err != nil {
return err
@@ -362,6 +368,7 @@ func (conn *LocalConnection) handleSetEstablished() error {
dstPeer: conn.remote,
frame: PMTUDiscovery},
nil)
conn.heartbeatTimeout = time.NewTimer(HeartbeatTimeout)
conn.heartbeat = time.NewTicker(SlowHeartbeat)
conn.fragTest = time.NewTicker(FragTestInterval)
// avoid initial waits for timers to fire
@@ -391,10 +398,8 @@ func (conn *LocalConnection) handleShutdown() {
conn.Router.Ourself.DeleteConnection(conn)
}
if conn.establishedTimeout != nil {
conn.establishedTimeout.Stop()
}
stopTimer(conn.establishedTimeout)
stopTimer(conn.heartbeatTimeout)
stopTicker(conn.heartbeat)
stopTicker(conn.fragTest)
@@ -498,3 +503,16 @@ func stopTicker(ticker *time.Ticker) {
ticker.Stop()
}
}
func timerChan(timer *time.Timer) <-chan time.Time {
if timer != nil {
return timer.C
}
return nil
}
func stopTimer(timer *time.Timer) {
if timer != nil {
timer.Stop()
}
}
+20 -18
View File
@@ -6,24 +6,26 @@ import (
)
const (
EthernetOverhead = 14
UDPOverhead = 28 // 20 bytes for IPv4, 8 bytes for UDP
Port = 6783
HttpPort = Port + 1
DefaultPMTU = 65535
MaxUDPPacketSize = 65536
ChannelSize = 16
UDPNonceSendAt = 8192
FragTestSize = 60001
PMTUDiscoverySize = 60000
FastHeartbeat = 500 * time.Millisecond
SlowHeartbeat = 10 * time.Second
FragTestInterval = 5 * time.Minute
EstablishedTimeout = 30 * time.Second
ReadTimeout = 1 * time.Minute
PMTUVerifyAttempts = 8
PMTUVerifyTimeout = 10 * time.Millisecond // gets doubled with every attempt
MaxDuration = time.Duration(math.MaxInt64)
EthernetOverhead = 14
UDPOverhead = 28 // 20 bytes for IPv4, 8 bytes for UDP
Port = 6783
HttpPort = Port + 1
DefaultPMTU = 65535
MaxUDPPacketSize = 65536
ChannelSize = 16
UDPNonceSendAt = 8192
FragTestSize = 60001
PMTUDiscoverySize = 60000
FastHeartbeat = 500 * time.Millisecond
SlowHeartbeat = 10 * time.Second
FragTestInterval = 5 * time.Minute
EstablishedTimeout = 30 * time.Second
ReadTimeout = 1 * time.Minute
PMTUVerifyAttempts = 8
PMTUVerifyTimeout = 10 * time.Millisecond // gets doubled with every attempt
MaxDuration = time.Duration(math.MaxInt64)
MaxMissedHeartbeats = 3
HeartbeatTimeout = MaxMissedHeartbeats * SlowHeartbeat
)
var (