Add race dialer

This commit is contained in:
Zoltán Papp 2024-11-28 11:53:35 +01:00
parent ceb8a01573
commit 9196104859
2 changed files with 66 additions and 1 deletions

View File

@ -10,7 +10,9 @@ import (
log "github.com/sirupsen/logrus"
auth "github.com/netbirdio/netbird/relay/auth/hmac"
"github.com/netbirdio/netbird/relay/client/dialer"
"github.com/netbirdio/netbird/relay/client/dialer/quic"
"github.com/netbirdio/netbird/relay/client/dialer/ws"
"github.com/netbirdio/netbird/relay/healthcheck"
"github.com/netbirdio/netbird/relay/messages"
)
@ -259,7 +261,7 @@ func (c *Client) Close() error {
}
func (c *Client) connect() error {
conn, err := quic.Dial(c.connectionURL)
conn, err := dialer.RaceDial(c.connectionURL, quic.Dial, ws.Dial)
if err != nil {
return err
}

View File

@ -0,0 +1,63 @@
package dialer
import (
"context"
"errors"
"net"
"time"
log "github.com/sirupsen/logrus"
)
type DialFn func(ctx context.Context, address string) (net.Conn, error)
type dialResult struct {
Conn net.Conn
Err error
}
func RaceDial(serverURL string, DialFns ...DialFn) (net.Conn, error) {
connChan := make(chan dialResult, len(DialFns))
winnerConn := make(chan net.Conn, 1)
abortCtx, abort := context.WithCancel(context.Background())
defer abort()
for _, dfn := range DialFns {
go func() {
ctx, cancel := context.WithTimeout(abortCtx, 30*time.Second)
defer cancel()
conn, err := dfn(ctx, serverURL)
if err != nil {
log.Errorf("failed to dial: %s", err)
}
connChan <- dialResult{Conn: conn, Err: err}
}()
}
go func() {
var hasWinner bool
for i := 0; i < len(DialFns); i++ {
dr := <-connChan
if dr.Err != nil {
continue
}
if hasWinner {
_ = dr.Conn.Close()
continue
}
hasWinner = true
winnerConn <- dr.Conn
}
close(winnerConn)
}()
conn, ok := <-winnerConn
if !ok {
return nil, errors.New("failed to dial to Relay server")
}
return conn, nil
}