diff --git a/router/connection.go b/router/connection.go index a42f04ce..a17a6fea 100644 --- a/router/connection.go +++ b/router/connection.go @@ -47,6 +47,7 @@ type LocalConnection struct { stackFrag bool effectivePMTU int SessionKey *[32]byte + heartbeatTCP *time.Ticker heartbeatTimeout *time.Timer heartbeatFrame *ForwardedFrame heartbeat *time.Ticker @@ -339,6 +340,7 @@ func (conn *LocalConnection) run(actionChan <-chan ConnectionAction, finished ch // goroutine, at least not without some synchronisation. func (conn *LocalConnection) initHeartbeats() error { + conn.heartbeatTCP = time.NewTicker(TCPHeartbeat) conn.heartbeatTimeout = time.NewTimer(HeartbeatTimeout) heartbeatFrameBytes := make([]byte, EthernetOverhead+8) binary.BigEndian.PutUint64(heartbeatFrameBytes[EthernetOverhead:], conn.uid) @@ -360,6 +362,8 @@ func (conn *LocalConnection) actorLoop(actionChan <-chan ConnectionAction) (err break } err = action() + case <-conn.heartbeatTCP.C: + err = conn.sendSimpleProtocolMsg(ProtocolHeartbeat) case <-conn.heartbeatTimeout.C: err = fmt.Errorf("timed out waiting for UDP heartbeat") case <-tickerChan(conn.heartbeat): @@ -386,6 +390,7 @@ func (conn *LocalConnection) shutdown() { conn.heartbeatTimeout.Stop() } + stopTicker(conn.heartbeatTCP) stopTicker(conn.heartbeat) stopTicker(conn.fragTest) @@ -439,6 +444,7 @@ func (conn *LocalConnection) receiveTCP(decoder *gob.Decoder) { func (conn *LocalConnection) handleProtocolMsg(tag ProtocolTag, payload []byte) error { switch tag { + case ProtocolHeartbeat: case ProtocolConnectionEstablished: // We sent fast heartbeats to the remote peer, which has now // received at least one of them and told us via this message. @@ -469,7 +475,7 @@ func (conn *LocalConnection) handleProtocolMsg(tag ProtocolTag, payload []byte) } func (conn *LocalConnection) extendReadDeadline() { - conn.TCPConn.SetReadDeadline(time.Now().Add(ReadTimeout)) + conn.TCPConn.SetReadDeadline(time.Now().Add(TCPHeartbeat * 2)) } func (conn *LocalConnection) sendFastHeartbeats() error { diff --git a/router/consts.go b/router/consts.go index 4d8f312a..0aa13fd6 100644 --- a/router/consts.go +++ b/router/consts.go @@ -16,10 +16,10 @@ const ( UDPNonceSendAt = 8192 FragTestSize = 60001 PMTUDiscoverySize = 60000 + TCPHeartbeat = 30 * time.Second FastHeartbeat = 500 * time.Millisecond SlowHeartbeat = 10 * time.Second FragTestInterval = 5 * time.Minute - ReadTimeout = 1 * time.Minute PMTUVerifyAttempts = 8 PMTUVerifyTimeout = 10 * time.Millisecond // gets doubled with every attempt MaxDuration = time.Duration(math.MaxInt64) diff --git a/router/protocol.go b/router/protocol.go index b9bb9f29..0fc548c6 100644 --- a/router/protocol.go +++ b/router/protocol.go @@ -8,7 +8,8 @@ const ( type ProtocolTag byte const ( - ProtocolConnectionEstablished ProtocolTag = iota + ProtocolHeartbeat ProtocolTag = iota + ProtocolConnectionEstablished ProtocolFragmentationReceived ProtocolStartFragmentationTest ProtocolNonce