diff --git a/router/connection.go b/router/connection.go index 696c2b79..111830b3 100644 --- a/router/connection.go +++ b/router/connection.go @@ -37,27 +37,27 @@ type RemoteConnection struct { type LocalConnection struct { sync.RWMutex RemoteConnection - TCPConn *net.TCPConn - tcpSender TCPSender - remoteUDPAddr *net.UDPAddr - receivedHeartbeat bool - stackFrag bool - effectivePMTU int - SessionKey *[32]byte - establishedTimeout *time.Timer - heartbeatFrame *ForwardedFrame - heartbeat *time.Ticker - fragTest *time.Ticker - forwardChan chan<- *ForwardedFrame - forwardChanDF chan<- *ForwardedFrame - stopForward chan<- interface{} - stopForwardDF chan<- interface{} - verifyPMTU chan<- int - Decryptor Decryptor - Router *Router - uid uint64 - queryChan chan<- *ConnectionInteraction - finished <-chan struct{} // closed to signal that queryLoop has finished + TCPConn *net.TCPConn + tcpSender TCPSender + remoteUDPAddr *net.UDPAddr + receivedHeartbeat bool + stackFrag bool + effectivePMTU int + SessionKey *[32]byte + heartbeatTimeout *time.Timer + heartbeatFrame *ForwardedFrame + heartbeat *time.Ticker + fragTest *time.Ticker + forwardChan chan<- *ForwardedFrame + forwardChanDF chan<- *ForwardedFrame + stopForward chan<- interface{} + stopForwardDF chan<- interface{} + verifyPMTU chan<- int + Decryptor Decryptor + Router *Router + uid uint64 + queryChan chan<- *ConnectionInteraction + finished <-chan struct{} // closed to signal that queryLoop has finished } type ConnectionInteraction struct { @@ -270,7 +270,7 @@ func (conn *LocalConnection) run(queryChan <-chan *ConnectionInteraction, finish } } - conn.establishedTimeout = time.NewTimer(EstablishedTimeout) + conn.heartbeatTimeout = time.NewTimer(HeartbeatTimeout) if err := conn.queryLoop(queryChan); err != nil { conn.log("connection shutting down due to error:", err) @@ -305,15 +305,12 @@ func (conn *LocalConnection) queryLoop(queryChan <-chan *ConnectionInteraction) case CReceivedHeartbeat: err = conn.handleReceivedHeartbeat(query.payload.(*net.UDPAddr)) case CSetEstablished: - conn.establishedTimeout.Stop() err = conn.handleSetEstablished() case CSendProtocolMsg: err = conn.handleSendProtocolMsg(query.payload.(ProtocolMsg)) } - case <-conn.establishedTimeout.C: - if !conn.established { - err = fmt.Errorf("failed to establish UDP connectivity") - } + case <-conn.heartbeatTimeout.C: + err = fmt.Errorf("timed out waiting for UDP heartbeat") case <-tickerChan(conn.heartbeat): conn.Forward(true, conn.heartbeatFrame, nil) case <-tickerChan(conn.fragTest): @@ -338,6 +335,7 @@ func (conn *LocalConnection) handleReceivedHeartbeat(remoteUDPAddr *net.UDPAddr) conn.remoteUDPAddr = remoteUDPAddr conn.receivedHeartbeat = true conn.Unlock() + conn.heartbeatTimeout.Reset(HeartbeatTimeout) if !old { if err := conn.handleSendSimpleProtocolMsg(ProtocolConnectionEstablished); err != nil { return err @@ -400,8 +398,8 @@ func (conn *LocalConnection) handleShutdown() { conn.Router.Ourself.DeleteConnection(conn) } - if conn.establishedTimeout != nil { - conn.establishedTimeout.Stop() + if conn.heartbeatTimeout != nil { + conn.heartbeatTimeout.Stop() } stopTicker(conn.heartbeat) diff --git a/router/consts.go b/router/consts.go index 11075638..b2709d22 100644 --- a/router/consts.go +++ b/router/consts.go @@ -6,24 +6,25 @@ 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 + 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 (