Fix logging and error handling

This commit is contained in:
Zoltán Papp
2024-11-28 17:34:09 +01:00
parent b9e3c71f40
commit 5d4899cb78
4 changed files with 46 additions and 24 deletions

View File

@@ -261,7 +261,7 @@ func (c *Client) Close() error {
} }
func (c *Client) connect() error { func (c *Client) connect() error {
conn, err := dialer.RaceDial(c.connectionURL, quic.Dial, ws.Dial) conn, err := dialer.RaceDial(c.log, c.connectionURL, quic.Dialer{}, ws.Dialer{})
if err != nil { if err != nil {
return err return err
} }

View File

@@ -15,7 +15,14 @@ import (
nbnet "github.com/netbirdio/netbird/util/net" nbnet "github.com/netbirdio/netbird/util/net"
) )
func Dial(ctx context.Context, address string) (net.Conn, error) { type Dialer struct {
}
func (d Dialer) Protocol() string {
return "QUIC"
}
func (d Dialer) Dial(ctx context.Context, address string) (net.Conn, error) {
quicURL, err := prepareURL(address) quicURL, err := prepareURL(address)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -41,8 +48,7 @@ func Dial(ctx context.Context, address string) (net.Conn, error) {
session, err := quic.Dial(ctx, udpConn, udpAddr, quictls.ClientQUICTLSConfig(), quicConfig) session, err := quic.Dial(ctx, udpConn, udpAddr, quictls.ClientQUICTLSConfig(), quicConfig)
if err != nil { if err != nil {
if errors.Is(ctx.Err(), context.Canceled) { if errors.Is(err, context.Canceled) {
log.Infof("QUIC connection aborted to: %s", quicURL)
return nil, err return nil, err
} }
log.Errorf("failed to dial to Relay server via QUIC '%s': %s", quicURL, err) log.Errorf("failed to dial to Relay server via QUIC '%s': %s", quicURL, err)

View File

@@ -9,46 +9,56 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
type DialFn func(ctx context.Context, address string) (net.Conn, error) type DialerFn interface {
Dial(ctx context.Context, address string) (net.Conn, error)
type dialResult struct { Protocol() string
Conn net.Conn
Err error
} }
func RaceDial(serverURL string, DialFns ...DialFn) (net.Conn, error) { type dialResult struct {
connChan := make(chan dialResult, len(DialFns)) Conn net.Conn
Protocol string
Err error
}
func RaceDial(log *log.Entry, serverURL string, dialerFns ...DialerFn) (net.Conn, error) {
connChan := make(chan dialResult, len(dialerFns))
winnerConn := make(chan net.Conn, 1) winnerConn := make(chan net.Conn, 1)
abortCtx, abort := context.WithCancel(context.Background()) abortCtx, abort := context.WithCancel(context.Background())
defer abort() defer abort()
for _, dfn := range DialFns { for _, d := range dialerFns {
go func() { go func() {
ctx, cancel := context.WithTimeout(abortCtx, 30*time.Second) ctx, cancel := context.WithTimeout(abortCtx, 30*time.Second)
defer cancel() defer cancel()
conn, err := dfn(ctx, serverURL) log.Infof("dialing Relay server via %s", d.Protocol())
if err != nil { conn, err := d.Dial(ctx, serverURL)
log.Errorf("failed to dial: %s", err) connChan <- dialResult{Conn: conn, Protocol: d.Protocol(), Err: err}
}
connChan <- dialResult{Conn: conn, Err: err}
}() }()
} }
go func() { go func() {
var hasWinner bool var hasWinner bool
for i := 0; i < len(DialFns); i++ { for i := 0; i < len(dialerFns); i++ {
dr := <-connChan dr := <-connChan
if dr.Err != nil { if dr.Err != nil {
if errors.Is(dr.Err, context.Canceled) {
log.Infof("connection attempt aborted via: %s", dr.Protocol)
} else {
log.Errorf("failed to dial via: %s, %s", dr.Protocol, dr.Err)
}
continue continue
} }
if hasWinner { if hasWinner {
_ = dr.Conn.Close() if cerr := dr.Conn.Close(); cerr != nil {
log.Warnf("failed to close connection via: %s, %s", dr.Protocol, cerr)
}
continue continue
} }
log.Infof("successfully dialed via: %s", dr.Protocol)
hasWinner = true hasWinner = true
winnerConn <- dr.Conn winnerConn <- dr.Conn
} }
@@ -57,7 +67,7 @@ func RaceDial(serverURL string, DialFns ...DialFn) (net.Conn, error) {
conn, ok := <-winnerConn conn, ok := <-winnerConn
if !ok { if !ok {
return nil, errors.New("failed to dial to Relay server") return nil, errors.New("failed to dial to Relay server on any protocol")
} }
return conn, nil return conn, nil
} }

View File

@@ -16,7 +16,14 @@ import (
nbnet "github.com/netbirdio/netbird/util/net" nbnet "github.com/netbirdio/netbird/util/net"
) )
func Dial(ctx context.Context, address string) (net.Conn, error) { type Dialer struct {
}
func (d Dialer) Protocol() string {
return "WS"
}
func (d Dialer) Dial(ctx context.Context, address string) (net.Conn, error) {
wsURL, err := prepareURL(address) wsURL, err := prepareURL(address)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -34,8 +41,7 @@ func Dial(ctx context.Context, address string) (net.Conn, error) {
wsConn, resp, err := websocket.Dial(ctx, parsedURL.String(), opts) wsConn, resp, err := websocket.Dial(ctx, parsedURL.String(), opts)
if err != nil { if err != nil {
if errors.Is(ctx.Err(), context.Canceled) { if errors.Is(err, context.Canceled) {
log.Infof("WebSocket connection aborted to: %s", wsURL)
return nil, err return nil, err
} }
log.Errorf("failed to dial to Relay server '%s': %s", wsURL, err) log.Errorf("failed to dial to Relay server '%s': %s", wsURL, err)