Fix reconnect loop

This commit is contained in:
Zoltán Papp 2024-07-19 12:00:19 +02:00
parent 787c900342
commit e10bc658f5

View File

@ -318,29 +318,16 @@ func (conn *Conn) GetKey() string {
} }
func (conn *Conn) reconnectLoopWithRetry() { func (conn *Conn) reconnectLoopWithRetry() {
// give chance to the peer to establish the initial connection // Give chance to the peer to establish the initial connection.
// With it, we can decrease to send necessary offer
select { select {
case <-conn.ctx.Done(): case <-conn.ctx.Done():
case <-time.After(3 * time.Second): case <-time.After(3 * time.Second):
} }
for { ticker := conn.prepareExponentTicker()
bo := backoff.WithContext(&backoff.ExponentialBackOff{
InitialInterval: 800 * time.Millisecond,
RandomizationFactor: 1,
Multiplier: 1.99,
MaxInterval: conn.config.Timeout * time.Second,
MaxElapsedTime: 0,
Stop: backoff.Stop,
Clock: backoff.SystemClock,
}, conn.ctx)
ticker := backoff.NewTicker(bo)
defer ticker.Stop() defer ticker.Stop()
time.Sleep(1 * time.Second)
<-ticker.C // consume the initial tick what is happening right after the ticker has been created
L:
for { for {
select { select {
case t := <-ticker.C: case t := <-ticker.C:
@ -348,13 +335,16 @@ func (conn *Conn) reconnectLoopWithRetry() {
// in case if the ticker has been canceled by context then avoid the temporary loop // in case if the ticker has been canceled by context then avoid the temporary loop
return return
} }
// checks if there is peer connection is established via relay or ice and that it has a wireguard handshake and skip offer // checks if there is peer connection is established via relay or ice and that it has a wireguard handshake and skip offer
// todo check wg handshake // todo check wg handshake
conn.log.Tracef("ticker timedout, relay state: %s, ice state: %s", conn.statusRelay, conn.statusICE) conn.log.Tracef("ticker timedout, relay state: %s, ice state: %s", conn.statusRelay, conn.statusICE)
conn.mu.Lock()
if conn.statusRelay == StatusConnected && conn.statusICE == StatusConnected { if conn.statusRelay == StatusConnected && conn.statusICE == StatusConnected {
conn.mu.Unlock()
continue continue
} }
conn.mu.Unlock()
conn.log.Debugf("ticker timed out, retry to do handshake") conn.log.Debugf("ticker timed out, retry to do handshake")
err := conn.handshaker.sendOffer() err := conn.handshaker.sendOffer()
@ -367,19 +357,35 @@ func (conn *Conn) reconnectLoopWithRetry() {
} }
conn.log.Debugf("Relay state changed, reset reconnect timer") conn.log.Debugf("Relay state changed, reset reconnect timer")
ticker.Stop() ticker.Stop()
break L ticker = conn.prepareExponentTicker()
case changed := <-conn.iCEDisconnected: case changed := <-conn.iCEDisconnected:
if !changed { if !changed {
continue continue
} }
conn.log.Debugf("ICE state changed, reset reconnect timer") conn.log.Debugf("ICE state changed, reset reconnect timer")
ticker.Stop() ticker.Stop()
break L ticker = conn.prepareExponentTicker()
case <-conn.ctx.Done(): case <-conn.ctx.Done():
return return
} }
} }
} }
func (conn *Conn) prepareExponentTicker() *backoff.Ticker {
bo := backoff.WithContext(&backoff.ExponentialBackOff{
InitialInterval: 800 * time.Millisecond,
RandomizationFactor: 1,
Multiplier: 1.99,
MaxInterval: conn.config.Timeout,
MaxElapsedTime: 0,
Stop: backoff.Stop,
Clock: backoff.SystemClock,
}, conn.ctx)
ticker := backoff.NewTicker(bo)
<-ticker.C // consume the initial tick what is happening right after the ticker has been created
return ticker
} }
// reconnectLoopForOnDisconnectedEvent is used when the peer is not a controller and it should reconnect to the peer // reconnectLoopForOnDisconnectedEvent is used when the peer is not a controller and it should reconnect to the peer