mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-04 16:16:40 +00:00
Mark relayServerAddress and relayServerIP as optional in the signal proto, return the relay instance address and IP atomically from Manager.RelayInstanceAddress to avoid divergence across reconnections, and split the relay client constructor into NewClient and NewClientWithServerIP. Rename fallback terminology to server IP throughout.
98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/netip"
|
|
"strings"
|
|
|
|
"github.com/netbirdio/netbird/shared/signal/proto"
|
|
"github.com/netbirdio/netbird/version"
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
)
|
|
|
|
// A set of tools to exchange connection details (Wireguard endpoints) with the remote peer.
|
|
|
|
const (
|
|
StreamConnected Status = "Connected"
|
|
StreamDisconnected Status = "Disconnected"
|
|
|
|
// DirectCheck indicates support to direct mode checks
|
|
DirectCheck uint32 = 1
|
|
)
|
|
|
|
// Status is the status of the client
|
|
type Status string
|
|
|
|
type Client interface {
|
|
io.Closer
|
|
StreamConnected() bool
|
|
GetStatus() Status
|
|
Receive(ctx context.Context, msgHandler func(msg *proto.Message) error) error
|
|
Ready() bool
|
|
IsHealthy() bool
|
|
WaitStreamConnected()
|
|
SendToStream(msg *proto.EncryptedMessage) error
|
|
Send(msg *proto.Message) error
|
|
SetOnReconnectedListener(func())
|
|
}
|
|
|
|
// Credential is an instance of a GrpcClient's Credential
|
|
type Credential struct {
|
|
UFrag string
|
|
Pwd string
|
|
}
|
|
|
|
// CredentialPayload bundles the fields of a signal Body for MarshalCredential.
|
|
type CredentialPayload struct {
|
|
Type proto.Body_Type
|
|
WgListenPort int
|
|
Credential *Credential
|
|
RosenpassPubKey []byte
|
|
RosenpassAddr string
|
|
RelaySrvAddress string
|
|
RelaySrvIP netip.Addr
|
|
SessionID []byte
|
|
}
|
|
|
|
// UnMarshalCredential parses the credentials from the message and returns a Credential instance
|
|
func UnMarshalCredential(msg *proto.Message) (*Credential, error) {
|
|
|
|
credential := strings.Split(msg.GetBody().GetPayload(), ":")
|
|
if len(credential) != 2 {
|
|
return nil, fmt.Errorf("error parsing message body %s", msg.Body)
|
|
}
|
|
return &Credential{
|
|
UFrag: credential[0],
|
|
Pwd: credential[1],
|
|
}, nil
|
|
}
|
|
|
|
// MarshalCredential marshal a Credential instance and returns a Message object
|
|
func MarshalCredential(myKey wgtypes.Key, remoteKey string, p CredentialPayload) (*proto.Message, error) {
|
|
body := &proto.Body{
|
|
Type: p.Type,
|
|
Payload: fmt.Sprintf("%s:%s", p.Credential.UFrag, p.Credential.Pwd),
|
|
WgListenPort: uint32(p.WgListenPort),
|
|
NetBirdVersion: version.NetbirdVersion(),
|
|
RosenpassConfig: &proto.RosenpassConfig{
|
|
RosenpassPubKey: p.RosenpassPubKey,
|
|
RosenpassServerAddr: p.RosenpassAddr,
|
|
},
|
|
SessionId: p.SessionID,
|
|
}
|
|
if p.RelaySrvAddress != "" {
|
|
body.RelayServerAddress = &p.RelaySrvAddress
|
|
}
|
|
if p.RelaySrvIP.IsValid() {
|
|
body.RelayServerIP = p.RelaySrvIP.Unmap().AsSlice()
|
|
}
|
|
return &proto.Message{
|
|
Key: myKey.PublicKey().String(),
|
|
RemoteKey: remoteKey,
|
|
Body: body,
|
|
}, nil
|
|
}
|