netbird/client/internal/peer/worker_relay.go

101 lines
2.5 KiB
Go
Raw Normal View History

package peer
import (
"context"
2024-06-25 15:13:08 +02:00
"errors"
"net"
log "github.com/sirupsen/logrus"
relayClient "github.com/netbirdio/netbird/relay/client"
)
type RelayConnInfo struct {
relayedConn net.Conn
rosenpassPubKey []byte
rosenpassAddr string
}
2024-06-19 11:52:40 +02:00
type WorkerRelayCallbacks struct {
2024-06-25 15:13:08 +02:00
OnConnReady func(RelayConnInfo)
OnDisconnected func()
2024-06-19 11:52:40 +02:00
}
2024-06-18 11:22:40 +02:00
type WorkerRelay struct {
2024-06-19 11:52:40 +02:00
ctx context.Context
log *log.Entry
config ConnConfig
2024-06-21 15:35:15 +02:00
relayManager *relayClient.Manager
2024-06-19 11:52:40 +02:00
conn WorkerRelayCallbacks
}
2024-06-21 15:35:15 +02:00
func NewWorkerRelay(ctx context.Context, log *log.Entry, config ConnConfig, relayManager *relayClient.Manager, callbacks WorkerRelayCallbacks) *WorkerRelay {
2024-06-18 11:22:40 +02:00
return &WorkerRelay{
2024-06-19 11:52:40 +02:00
ctx: ctx,
log: log,
config: config,
2024-06-21 15:35:15 +02:00
relayManager: relayManager,
2024-06-19 11:52:40 +02:00
conn: callbacks,
}
}
2024-06-21 12:35:28 +02:00
func (w *WorkerRelay) OnNewOffer(remoteOfferAnswer *OfferAnswer) {
if !w.isRelaySupported(remoteOfferAnswer) {
w.log.Infof("Relay is not supported by remote peer")
return
}
// the relayManager will return with error in case if the connection has lost with relay server
currentRelayAddress, err := w.relayManager.RelayAddress()
if err != nil {
w.log.Infof("local Relay connection is lost, skipping connection attempt")
return
}
srv := w.preferredRelayServer(currentRelayAddress.String(), remoteOfferAnswer.RelaySrvAddress)
2024-06-25 15:13:08 +02:00
relayedConn, err := w.relayManager.OpenConn(srv, w.config.Key, w.conn.OnDisconnected)
2024-06-21 12:35:28 +02:00
if err != nil {
2024-06-25 15:13:08 +02:00
// todo handle all type errors
if errors.Is(err, relayClient.ErrConnAlreadyExists) {
w.log.Infof("do not need to reopen relay connection")
return
}
2024-06-21 12:35:28 +02:00
w.log.Infof("do not need to reopen relay connection: %s", err)
return
}
2024-06-21 12:35:28 +02:00
2024-06-25 15:13:08 +02:00
w.log.Debugf("Relay connection established with %s", srv)
2024-06-21 12:35:28 +02:00
go w.conn.OnConnReady(RelayConnInfo{
relayedConn: relayedConn,
rosenpassPubKey: remoteOfferAnswer.RosenpassPubKey,
rosenpassAddr: remoteOfferAnswer.RosenpassAddr,
})
}
2024-06-18 11:22:40 +02:00
func (w *WorkerRelay) RelayAddress() (net.Addr, error) {
return w.relayManager.RelayAddress()
}
2024-06-25 15:13:08 +02:00
func (w *WorkerRelay) IsController() bool {
return w.config.LocalKey > w.config.Key
}
func (w *WorkerRelay) RelayIsSupportedLocally() bool {
return w.relayManager.HasRelayAddress()
}
2024-06-18 11:22:40 +02:00
func (w *WorkerRelay) isRelaySupported(answer *OfferAnswer) bool {
2024-06-19 11:52:40 +02:00
if !w.relayManager.HasRelayAddress() {
return false
}
return answer.RelaySrvAddress != ""
}
2024-06-18 11:22:40 +02:00
func (w *WorkerRelay) preferredRelayServer(myRelayAddress, remoteRelayAddress string) string {
2024-06-25 15:13:08 +02:00
if w.IsController() {
return myRelayAddress
}
return remoteRelayAddress
}