mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-29 21:56:40 +00:00
Address review on relay server IP signaling
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.
This commit is contained in:
@@ -42,7 +42,7 @@ type OfferAnswer struct {
|
|||||||
// relay server address
|
// relay server address
|
||||||
RelaySrvAddress string
|
RelaySrvAddress string
|
||||||
// RelaySrvIP is the IP the remote peer is connected to on its
|
// RelaySrvIP is the IP the remote peer is connected to on its
|
||||||
// relay server. Used as a fallback dial target if DNS for RelaySrvAddress
|
// relay server. Used as a dial target if DNS for RelaySrvAddress
|
||||||
// fails. Zero value if the peer did not advertise an IP.
|
// fails. Zero value if the peer did not advertise an IP.
|
||||||
RelaySrvIP netip.Addr
|
RelaySrvIP netip.Addr
|
||||||
// SessionID is the unique identifier of the session, used to discard old messages
|
// SessionID is the unique identifier of the session, used to discard old messages
|
||||||
@@ -222,9 +222,9 @@ func (h *Handshaker) buildOfferAnswer() OfferAnswer {
|
|||||||
answer.SessionID = &sid
|
answer.SessionID = &sid
|
||||||
}
|
}
|
||||||
|
|
||||||
if addr, err := h.relay.RelayInstanceAddress(); err == nil {
|
if addr, ip, err := h.relay.RelayInstanceAddress(); err == nil {
|
||||||
answer.RelaySrvAddress = addr
|
answer.RelaySrvAddress = addr
|
||||||
answer.RelaySrvIP = h.relay.RelayInstanceIP()
|
answer.RelaySrvIP = ip
|
||||||
}
|
}
|
||||||
|
|
||||||
return answer
|
return answer
|
||||||
|
|||||||
@@ -919,7 +919,7 @@ func (d *Status) GetRelayStates() []relay.ProbeResult {
|
|||||||
|
|
||||||
// if the server connection is not established then we will use the general address
|
// if the server connection is not established then we will use the general address
|
||||||
// in case of connection we will use the instance specific address
|
// in case of connection we will use the instance specific address
|
||||||
instanceAddr, err := d.relayMgr.RelayInstanceAddress()
|
instanceAddr, _, err := d.relayMgr.RelayInstanceAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO add their status
|
// TODO add their status
|
||||||
for _, r := range d.relayMgr.ServerURLs() {
|
for _, r := range d.relayMgr.ServerURLs() {
|
||||||
|
|||||||
@@ -54,19 +54,19 @@ func (w *WorkerRelay) OnNewOffer(remoteOfferAnswer *OfferAnswer) {
|
|||||||
w.relaySupportedOnRemotePeer.Store(true)
|
w.relaySupportedOnRemotePeer.Store(true)
|
||||||
|
|
||||||
// the relayManager will return with error in case if the connection has lost with relay server
|
// the relayManager will return with error in case if the connection has lost with relay server
|
||||||
currentRelayAddress, err := w.relayManager.RelayInstanceAddress()
|
currentRelayAddress, _, err := w.relayManager.RelayInstanceAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.log.Errorf("failed to handle new offer: %s", err)
|
w.log.Errorf("failed to handle new offer: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
srv := w.preferredRelayServer(currentRelayAddress, remoteOfferAnswer.RelaySrvAddress)
|
srv := w.preferredRelayServer(currentRelayAddress, remoteOfferAnswer.RelaySrvAddress)
|
||||||
var fallbackIP netip.Addr
|
var serverIP netip.Addr
|
||||||
if srv == remoteOfferAnswer.RelaySrvAddress {
|
if srv == remoteOfferAnswer.RelaySrvAddress {
|
||||||
fallbackIP = remoteOfferAnswer.RelaySrvIP
|
serverIP = remoteOfferAnswer.RelaySrvIP
|
||||||
}
|
}
|
||||||
|
|
||||||
relayedConn, err := w.relayManager.OpenConn(w.peerCtx, srv, w.config.Key, fallbackIP)
|
relayedConn, err := w.relayManager.OpenConn(w.peerCtx, srv, w.config.Key, serverIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, relayClient.ErrConnAlreadyExists) {
|
if errors.Is(err, relayClient.ErrConnAlreadyExists) {
|
||||||
w.log.Debugf("handled offer by reusing existing relay connection")
|
w.log.Debugf("handled offer by reusing existing relay connection")
|
||||||
@@ -95,14 +95,10 @@ func (w *WorkerRelay) OnNewOffer(remoteOfferAnswer *OfferAnswer) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerRelay) RelayInstanceAddress() (string, error) {
|
func (w *WorkerRelay) RelayInstanceAddress() (string, netip.Addr, error) {
|
||||||
return w.relayManager.RelayInstanceAddress()
|
return w.relayManager.RelayInstanceAddress()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkerRelay) RelayInstanceIP() netip.Addr {
|
|
||||||
return w.relayManager.RelayInstanceIP()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorkerRelay) IsRelayConnectionSupportedWithPeer() bool {
|
func (w *WorkerRelay) IsRelayConnectionSupportedWithPeer() bool {
|
||||||
return w.relaySupportedOnRemotePeer.Load() && w.RelayIsSupportedLocally()
|
return w.relaySupportedOnRemotePeer.Load() && w.RelayIsSupportedLocally()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ func transfer(t *testing.T, testData []byte, peerPairs int) {
|
|||||||
|
|
||||||
clientsSender := make([]*client.Client, peerPairs)
|
clientsSender := make([]*client.Client, peerPairs)
|
||||||
for i := 0; i < cap(clientsSender); i++ {
|
for i := 0; i < cap(clientsSender); i++ {
|
||||||
c := client.NewClient(serverConnURL, netip.Addr{}, hmacTokenStore, "sender-"+fmt.Sprint(i), iface.DefaultMTU)
|
c := client.NewClient(serverConnURL, hmacTokenStore, "sender-"+fmt.Sprint(i), iface.DefaultMTU)
|
||||||
err := c.Connect(ctx)
|
err := c.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
@@ -112,7 +112,7 @@ func transfer(t *testing.T, testData []byte, peerPairs int) {
|
|||||||
|
|
||||||
clientsReceiver := make([]*client.Client, peerPairs)
|
clientsReceiver := make([]*client.Client, peerPairs)
|
||||||
for i := 0; i < cap(clientsReceiver); i++ {
|
for i := 0; i < cap(clientsReceiver); i++ {
|
||||||
c := client.NewClient(serverConnURL, netip.Addr{}, hmacTokenStore, "receiver-"+fmt.Sprint(i), iface.DefaultMTU)
|
c := client.NewClient(serverConnURL, hmacTokenStore, "receiver-"+fmt.Sprint(i), iface.DefaultMTU)
|
||||||
err := c.Connect(ctx)
|
err := c.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -72,7 +71,7 @@ func prepareConnsSender(serverConnURL string, peerPairs int) []net.Conn {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
clientsSender := make([]*client.Client, peerPairs)
|
clientsSender := make([]*client.Client, peerPairs)
|
||||||
for i := 0; i < cap(clientsSender); i++ {
|
for i := 0; i < cap(clientsSender); i++ {
|
||||||
c := client.NewClient(serverConnURL, netip.Addr{}, hmacTokenStore, "sender-"+fmt.Sprint(i), iface.DefaultMTU)
|
c := client.NewClient(serverConnURL, hmacTokenStore, "sender-"+fmt.Sprint(i), iface.DefaultMTU)
|
||||||
if err := c.Connect(ctx); err != nil {
|
if err := c.Connect(ctx); err != nil {
|
||||||
log.Fatalf("failed to connect to server: %s", err)
|
log.Fatalf("failed to connect to server: %s", err)
|
||||||
}
|
}
|
||||||
@@ -158,7 +157,7 @@ func runReader(conn net.Conn) time.Duration {
|
|||||||
func prepareConnsReceiver(serverConnURL string, peerPairs int) []net.Conn {
|
func prepareConnsReceiver(serverConnURL string, peerPairs int) []net.Conn {
|
||||||
clientsReceiver := make([]*client.Client, peerPairs)
|
clientsReceiver := make([]*client.Client, peerPairs)
|
||||||
for i := 0; i < cap(clientsReceiver); i++ {
|
for i := 0; i < cap(clientsReceiver); i++ {
|
||||||
c := client.NewClient(serverConnURL, netip.Addr{}, hmacTokenStore, "receiver-"+fmt.Sprint(i), iface.DefaultMTU)
|
c := client.NewClient(serverConnURL, hmacTokenStore, "receiver-"+fmt.Sprint(i), iface.DefaultMTU)
|
||||||
err := c.Connect(context.Background())
|
err := c.Connect(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to connect to server: %s", err)
|
log.Fatalf("failed to connect to server: %s", err)
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ func (cc *connContainer) close() {
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
log *log.Entry
|
log *log.Entry
|
||||||
connectionURL string
|
connectionURL string
|
||||||
fallbackIP netip.Addr
|
serverIP netip.Addr
|
||||||
authTokenStore *auth.TokenStore
|
authTokenStore *auth.TokenStore
|
||||||
hashedID messages.PeerID
|
hashedID messages.PeerID
|
||||||
|
|
||||||
@@ -175,16 +175,21 @@ type Client struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a new client for the relay server. The client is not connected to the server until the Connect
|
// NewClient creates a new client for the relay server. The client is not connected to the server until the Connect
|
||||||
// is called. fallbackIP, when valid, is used as a dial-time fallback if the FQDN-based dial fails. TLS
|
// is called.
|
||||||
// verification still uses the FQDN from serverURL via SNI.
|
func NewClient(serverURL string, authTokenStore *auth.TokenStore, peerID string, mtu uint16) *Client {
|
||||||
func NewClient(serverURL string, fallbackIP netip.Addr, authTokenStore *auth.TokenStore, peerID string, mtu uint16) *Client {
|
return NewClientWithServerIP(serverURL, netip.Addr{}, authTokenStore, peerID, mtu)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClientWithServerIP creates a new client for the relay server with a known server IP. serverIP, when valid, is
|
||||||
|
// used as a dial target if the FQDN-based dial fails. TLS verification still uses the FQDN from serverURL via SNI.
|
||||||
|
func NewClientWithServerIP(serverURL string, serverIP netip.Addr, authTokenStore *auth.TokenStore, peerID string, mtu uint16) *Client {
|
||||||
hashedID := messages.HashID(peerID)
|
hashedID := messages.HashID(peerID)
|
||||||
relayLog := log.WithFields(log.Fields{"relay": serverURL})
|
relayLog := log.WithFields(log.Fields{"relay": serverURL})
|
||||||
|
|
||||||
c := &Client{
|
c := &Client{
|
||||||
log: relayLog,
|
log: relayLog,
|
||||||
connectionURL: serverURL,
|
connectionURL: serverURL,
|
||||||
fallbackIP: fallbackIP,
|
serverIP: serverIP,
|
||||||
authTokenStore: authTokenStore,
|
authTokenStore: authTokenStore,
|
||||||
hashedID: hashedID,
|
hashedID: hashedID,
|
||||||
mtu: mtu,
|
mtu: mtu,
|
||||||
@@ -378,11 +383,11 @@ func (c *Client) connect(ctx context.Context) (*RelayAddr, error) {
|
|||||||
rd := dialer.NewRaceDial(c.log, dialer.DefaultConnectionTimeout, c.connectionURL, dialers...)
|
rd := dialer.NewRaceDial(c.log, dialer.DefaultConnectionTimeout, c.connectionURL, dialers...)
|
||||||
conn, err := rd.Dial(ctx)
|
conn, err := rd.Dial(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fallbackConn, fbErr := c.dialFallback(ctx, dialers)
|
directConn, dErr := c.dialDirect(ctx, dialers)
|
||||||
if fbErr != nil {
|
if dErr != nil {
|
||||||
return nil, fmt.Errorf("primary dial: %w; fallback dial: %w", err, fbErr)
|
return nil, fmt.Errorf("dial via FQDN: %w; dial via server IP: %w", err, dErr)
|
||||||
}
|
}
|
||||||
conn = fallbackConn
|
conn = directConn
|
||||||
}
|
}
|
||||||
c.relayConn = conn
|
c.relayConn = conn
|
||||||
|
|
||||||
@@ -398,22 +403,21 @@ func (c *Client) connect(ctx context.Context) (*RelayAddr, error) {
|
|||||||
return instanceURL, nil
|
return instanceURL, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// dialFallback retries the dial against c.fallbackIP, preserving the
|
// dialDirect retries the dial against c.serverIP, preserving the original FQDN as the TLS ServerName for SNI.
|
||||||
// original FQDN as the TLS ServerName for SNI. Returns an error if no
|
// Returns an error if no usable server IP is configured or if the substituted URL is malformed.
|
||||||
// fallback IP is configured or if the substituted URL is malformed.
|
func (c *Client) dialDirect(ctx context.Context, dialers []dialer.DialeFn) (net.Conn, error) {
|
||||||
func (c *Client) dialFallback(ctx context.Context, dialers []dialer.DialeFn) (net.Conn, error) {
|
if !c.serverIP.IsValid() || c.serverIP.IsUnspecified() {
|
||||||
if !c.fallbackIP.IsValid() || c.fallbackIP.IsUnspecified() {
|
return nil, errors.New("no usable server IP configured")
|
||||||
return nil, errors.New("no usable fallback IP configured")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fallbackURL, serverName, err := substituteHost(c.connectionURL, c.fallbackIP)
|
directURL, serverName, err := substituteHost(c.connectionURL, c.serverIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("substitute host: %w", err)
|
return nil, fmt.Errorf("substitute host: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Infof("primary dial failed, retrying via fallback IP %s (SNI=%s)", c.fallbackIP, serverName)
|
c.log.Infof("FQDN dial failed, retrying via server IP %s (SNI=%s)", c.serverIP, serverName)
|
||||||
|
|
||||||
rd := dialer.NewRaceDial(c.log, dialer.DefaultConnectionTimeout, fallbackURL, dialers...).
|
rd := dialer.NewRaceDial(c.log, dialer.DefaultConnectionTimeout, directURL, dialers...).
|
||||||
WithServerName(serverName)
|
WithServerName(serverName)
|
||||||
return rd.Dial(ctx)
|
return rd.Dial(ctx)
|
||||||
}
|
}
|
||||||
@@ -431,7 +435,7 @@ func substituteHost(serverURL string, ip netip.Addr) (string, string, error) {
|
|||||||
return "", "", fmt.Errorf("invalid relay URL %q", serverURL)
|
return "", "", fmt.Errorf("invalid relay URL %q", serverURL)
|
||||||
}
|
}
|
||||||
if !ip.IsValid() {
|
if !ip.IsValid() {
|
||||||
return "", "", errors.New("invalid fallback IP")
|
return "", "", errors.New("invalid server IP")
|
||||||
}
|
}
|
||||||
origHost := u.Hostname()
|
origHost := u.Hostname()
|
||||||
if _, err := netip.ParseAddr(origHost); err == nil {
|
if _, err := netip.ParseAddr(origHost); err == nil {
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ import (
|
|||||||
"github.com/netbirdio/netbird/shared/relay/auth/allow"
|
"github.com/netbirdio/netbird/shared/relay/auth/allow"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestClient_FallbackIPRecoversFromUnresolvableFQDN verifies that when the
|
// TestClient_ServerIPRecoversFromUnresolvableFQDN verifies that when the
|
||||||
// primary FQDN-based dial fails (unresolvable .invalid host), Connect
|
// primary FQDN-based dial fails (unresolvable .invalid host), Connect
|
||||||
// recovers via the fallback IP and SNI still uses the FQDN.
|
// recovers via the server IP and SNI still uses the FQDN.
|
||||||
func TestClient_FallbackIPRecoversFromUnresolvableFQDN(t *testing.T) {
|
func TestClient_ServerIPRecoversFromUnresolvableFQDN(t *testing.T) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -49,19 +49,19 @@ func TestClient_FallbackIPRecoversFromUnresolvableFQDN(t *testing.T) {
|
|||||||
t.Fatalf("server failed to start: %s", err)
|
t.Fatalf("server failed to start: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("no fallback IP, primary fails", func(t *testing.T) {
|
t.Run("no server IP, primary fails", func(t *testing.T) {
|
||||||
c := NewClient(srvCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "alice-nofallback", iface.DefaultMTU)
|
c := NewClient(srvCfg.ExposedAddress, hmacTokenStore, "alice-noip", iface.DefaultMTU)
|
||||||
err := c.Connect(ctx)
|
err := c.Connect(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
_ = c.Close()
|
_ = c.Close()
|
||||||
t.Fatalf("expected connect to fail without fallback IP, got nil")
|
t.Fatalf("expected connect to fail without server IP, got nil")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("fallback IP recovers", func(t *testing.T) {
|
t.Run("server IP recovers", func(t *testing.T) {
|
||||||
c := NewClient(srvCfg.ExposedAddress, netip.MustParseAddr("127.0.0.1"), hmacTokenStore, "alice-fallback", iface.DefaultMTU)
|
c := NewClientWithServerIP(srvCfg.ExposedAddress, netip.MustParseAddr("127.0.0.1"), hmacTokenStore, "alice-with-ip", iface.DefaultMTU)
|
||||||
if err := c.Connect(ctx); err != nil {
|
if err := c.Connect(ctx); err != nil {
|
||||||
t.Fatalf("connect with fallback IP: %s", err)
|
t.Fatalf("connect with server IP: %s", err)
|
||||||
}
|
}
|
||||||
t.Cleanup(func() { _ = c.Close() })
|
t.Cleanup(func() { _ = c.Close() })
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ func TestClient_FallbackIPRecoversFromUnresolvableFQDN(t *testing.T) {
|
|||||||
// TestClient_ConnectedIPAfterFQDNDial verifies ConnectedIP returns the
|
// TestClient_ConnectedIPAfterFQDNDial verifies ConnectedIP returns the
|
||||||
// resolved IP after a successful FQDN-based dial. The underlying socket's
|
// resolved IP after a successful FQDN-based dial. The underlying socket's
|
||||||
// RemoteAddr must be exposed through the dialer wrappers; if it returns
|
// RemoteAddr must be exposed through the dialer wrappers; if it returns
|
||||||
// the dial-time URL instead, ConnectedIP returns empty and the fallback
|
// the dial-time URL instead, ConnectedIP returns empty and the dial
|
||||||
// IP we advertise to peers is empty too.
|
// IP we advertise to peers is empty too.
|
||||||
func TestClient_ConnectedIPAfterFQDNDial(t *testing.T) {
|
func TestClient_ConnectedIPAfterFQDNDial(t *testing.T) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
@@ -105,7 +105,7 @@ func TestClient_ConnectedIPAfterFQDNDial(t *testing.T) {
|
|||||||
t.Fatalf("server failed to start: %s", err)
|
t.Fatalf("server failed to start: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := NewClient(srvCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "alice-fqdn", iface.DefaultMTU)
|
c := NewClient(srvCfg.ExposedAddress, hmacTokenStore, "alice-fqdn", iface.DefaultMTU)
|
||||||
if err := c.Connect(ctx); err != nil {
|
if err := c.Connect(ctx); err != nil {
|
||||||
t.Fatalf("connect: %s", err)
|
t.Fatalf("connect: %s", err)
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ func TestSubstituteHost(t *testing.T) {
|
|||||||
wantServerName: "relay.example.com",
|
wantServerName: "relay.example.com",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ipv6 fallback bracketed",
|
name: "ipv6 server IP bracketed",
|
||||||
serverURL: "rels://relay.example.com:443",
|
serverURL: "rels://relay.example.com:443",
|
||||||
ip: "2001:db8::1",
|
ip: "2001:db8::1",
|
||||||
wantURL: "rels://[2001:db8::1]:443",
|
wantURL: "rels://[2001:db8::1]:443",
|
||||||
@@ -169,7 +169,7 @@ func TestSubstituteHost(t *testing.T) {
|
|||||||
wantServerName: "",
|
wantServerName: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ipv6 fallback no port",
|
name: "ipv6 server IP no port",
|
||||||
serverURL: "rels://relay.example.com",
|
serverURL: "rels://relay.example.com",
|
||||||
ip: "2001:db8::1",
|
ip: "2001:db8::1",
|
||||||
wantURL: "rels://[2001:db8::1]",
|
wantURL: "rels://[2001:db8::1]",
|
||||||
@@ -215,7 +215,7 @@ func TestSubstituteHost(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_ConnectedIPEmptyWhenNotConnected(t *testing.T) {
|
func TestClient_ConnectedIPEmptyWhenNotConnected(t *testing.T) {
|
||||||
c := NewClient("rel://example.invalid:80", netip.Addr{}, hmacTokenStore, "x", iface.DefaultMTU)
|
c := NewClient("rel://example.invalid:80", hmacTokenStore, "x", iface.DefaultMTU)
|
||||||
if got := c.ConnectedIP(); got.IsValid() {
|
if got := c.ConnectedIP(); got.IsValid() {
|
||||||
t.Fatalf("ConnectedIP on disconnected client = %q, want zero", got)
|
t.Fatalf("ConnectedIP on disconnected client = %q, want zero", got)
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,6 @@ package client
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -69,7 +68,7 @@ func TestClient(t *testing.T) {
|
|||||||
t.Fatalf("failed to start server: %s", err)
|
t.Fatalf("failed to start server: %s", err)
|
||||||
}
|
}
|
||||||
t.Log("alice connecting to server")
|
t.Log("alice connecting to server")
|
||||||
clientAlice := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "alice", iface.DefaultMTU)
|
clientAlice := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "alice", iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
@@ -77,7 +76,7 @@ func TestClient(t *testing.T) {
|
|||||||
defer clientAlice.Close()
|
defer clientAlice.Close()
|
||||||
|
|
||||||
t.Log("placeholder connecting to server")
|
t.Log("placeholder connecting to server")
|
||||||
clientPlaceHolder := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "clientPlaceHolder", iface.DefaultMTU)
|
clientPlaceHolder := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "clientPlaceHolder", iface.DefaultMTU)
|
||||||
err = clientPlaceHolder.Connect(ctx)
|
err = clientPlaceHolder.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
@@ -85,7 +84,7 @@ func TestClient(t *testing.T) {
|
|||||||
defer clientPlaceHolder.Close()
|
defer clientPlaceHolder.Close()
|
||||||
|
|
||||||
t.Log("Bob connecting to server")
|
t.Log("Bob connecting to server")
|
||||||
clientBob := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "bob", iface.DefaultMTU)
|
clientBob := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "bob", iface.DefaultMTU)
|
||||||
err = clientBob.Connect(ctx)
|
err = clientBob.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
@@ -145,7 +144,7 @@ func TestRegistration(t *testing.T) {
|
|||||||
t.Fatalf("failed to start server: %s", err)
|
t.Fatalf("failed to start server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAlice := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "alice", iface.DefaultMTU)
|
clientAlice := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "alice", iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = srv.Shutdown(ctx)
|
_ = srv.Shutdown(ctx)
|
||||||
@@ -185,7 +184,7 @@ func TestRegistrationTimeout(t *testing.T) {
|
|||||||
_ = fakeTCPListener.Close()
|
_ = fakeTCPListener.Close()
|
||||||
}(fakeTCPListener)
|
}(fakeTCPListener)
|
||||||
|
|
||||||
clientAlice := NewClient("127.0.0.1:50201", netip.Addr{}, hmacTokenStore, "alice", iface.DefaultMTU)
|
clientAlice := NewClient("127.0.0.1:50201", hmacTokenStore, "alice", iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("failed to connect to server: %s", err)
|
t.Errorf("failed to connect to server: %s", err)
|
||||||
@@ -228,7 +227,7 @@ func TestEcho(t *testing.T) {
|
|||||||
t.Fatalf("failed to start server: %s", err)
|
t.Fatalf("failed to start server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAlice := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, idAlice, iface.DefaultMTU)
|
clientAlice := NewClient(serverCfg.ExposedAddress, hmacTokenStore, idAlice, iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
@@ -240,7 +239,7 @@ func TestEcho(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
clientBob := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, idBob, iface.DefaultMTU)
|
clientBob := NewClient(serverCfg.ExposedAddress, hmacTokenStore, idBob, iface.DefaultMTU)
|
||||||
err = clientBob.Connect(ctx)
|
err = clientBob.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
@@ -320,7 +319,7 @@ func TestBindToUnavailabePeer(t *testing.T) {
|
|||||||
t.Fatalf("failed to start server: %s", err)
|
t.Fatalf("failed to start server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAlice := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "alice", iface.DefaultMTU)
|
clientAlice := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "alice", iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to connect to server: %s", err)
|
t.Errorf("failed to connect to server: %s", err)
|
||||||
@@ -368,13 +367,13 @@ func TestBindReconnect(t *testing.T) {
|
|||||||
t.Fatalf("failed to start server: %s", err)
|
t.Fatalf("failed to start server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAlice := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "alice", iface.DefaultMTU)
|
clientAlice := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "alice", iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientBob := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "bob", iface.DefaultMTU)
|
clientBob := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "bob", iface.DefaultMTU)
|
||||||
err = clientBob.Connect(ctx)
|
err = clientBob.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to connect to server: %s", err)
|
t.Errorf("failed to connect to server: %s", err)
|
||||||
@@ -396,7 +395,7 @@ func TestBindReconnect(t *testing.T) {
|
|||||||
t.Errorf("failed to close client: %s", err)
|
t.Errorf("failed to close client: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAlice = NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "alice", iface.DefaultMTU)
|
clientAlice = NewClient(serverCfg.ExposedAddress, hmacTokenStore, "alice", iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to connect to server: %s", err)
|
t.Errorf("failed to connect to server: %s", err)
|
||||||
@@ -471,13 +470,13 @@ func TestCloseConn(t *testing.T) {
|
|||||||
t.Fatalf("failed to start server: %s", err)
|
t.Fatalf("failed to start server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bob := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "bob", iface.DefaultMTU)
|
bob := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "bob", iface.DefaultMTU)
|
||||||
err = bob.Connect(ctx)
|
err = bob.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to connect to server: %s", err)
|
t.Errorf("failed to connect to server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAlice := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "alice", iface.DefaultMTU)
|
clientAlice := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "alice", iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to connect to server: %s", err)
|
t.Errorf("failed to connect to server: %s", err)
|
||||||
@@ -535,13 +534,13 @@ func TestCloseRelayConn(t *testing.T) {
|
|||||||
t.Fatalf("failed to start server: %s", err)
|
t.Fatalf("failed to start server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bob := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "bob", iface.DefaultMTU)
|
bob := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "bob", iface.DefaultMTU)
|
||||||
err = bob.Connect(ctx)
|
err = bob.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAlice := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, "alice", iface.DefaultMTU)
|
clientAlice := NewClient(serverCfg.ExposedAddress, hmacTokenStore, "alice", iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
@@ -591,7 +590,7 @@ func TestCloseByServer(t *testing.T) {
|
|||||||
|
|
||||||
idAlice := "alice"
|
idAlice := "alice"
|
||||||
log.Debugf("connect by alice")
|
log.Debugf("connect by alice")
|
||||||
relayClient := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, idAlice, iface.DefaultMTU)
|
relayClient := NewClient(serverCfg.ExposedAddress, hmacTokenStore, idAlice, iface.DefaultMTU)
|
||||||
if err = relayClient.Connect(ctx); err != nil {
|
if err = relayClient.Connect(ctx); err != nil {
|
||||||
log.Fatalf("failed to connect to server: %s", err)
|
log.Fatalf("failed to connect to server: %s", err)
|
||||||
}
|
}
|
||||||
@@ -649,7 +648,7 @@ func TestCloseByClient(t *testing.T) {
|
|||||||
|
|
||||||
idAlice := "alice"
|
idAlice := "alice"
|
||||||
log.Debugf("connect by alice")
|
log.Debugf("connect by alice")
|
||||||
relayClient := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, idAlice, iface.DefaultMTU)
|
relayClient := NewClient(serverCfg.ExposedAddress, hmacTokenStore, idAlice, iface.DefaultMTU)
|
||||||
err = relayClient.Connect(ctx)
|
err = relayClient.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to connect to server: %s", err)
|
log.Fatalf("failed to connect to server: %s", err)
|
||||||
@@ -702,7 +701,7 @@ func TestCloseNotDrainedChannel(t *testing.T) {
|
|||||||
t.Fatalf("failed to start server: %s", err)
|
t.Fatalf("failed to start server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAlice := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, idAlice, iface.DefaultMTU)
|
clientAlice := NewClient(serverCfg.ExposedAddress, hmacTokenStore, idAlice, iface.DefaultMTU)
|
||||||
err = clientAlice.Connect(ctx)
|
err = clientAlice.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
@@ -714,7 +713,7 @@ func TestCloseNotDrainedChannel(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
clientBob := NewClient(serverCfg.ExposedAddress, netip.Addr{}, hmacTokenStore, idBob, iface.DefaultMTU)
|
clientBob := NewClient(serverCfg.ExposedAddress, hmacTokenStore, idBob, iface.DefaultMTU)
|
||||||
err = clientBob.Connect(ctx)
|
err = clientBob.Connect(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to connect to server: %s", err)
|
t.Fatalf("failed to connect to server: %s", err)
|
||||||
|
|||||||
@@ -132,9 +132,9 @@ func (m *Manager) Serve() error {
|
|||||||
// established via the relay server. If the peer is on a different relay server, the manager will establish a new
|
// established via the relay server. If the peer is on a different relay server, the manager will establish a new
|
||||||
// connection to the relay server. It returns back with a net.Conn what represent the remote peer connection.
|
// connection to the relay server. It returns back with a net.Conn what represent the remote peer connection.
|
||||||
//
|
//
|
||||||
// fallbackIP, when valid and serverAddress is foreign, is used as a dial-time fallback if the FQDN-based
|
// serverIP, when valid and serverAddress is foreign, is used as a dial target if the FQDN-based dial fails.
|
||||||
// dial fails. Ignored for the local home-server path. TLS verification still uses the FQDN via SNI.
|
// Ignored for the local home-server path. TLS verification still uses the FQDN via SNI.
|
||||||
func (m *Manager) OpenConn(ctx context.Context, serverAddress, peerKey string, fallbackIP netip.Addr) (net.Conn, error) {
|
func (m *Manager) OpenConn(ctx context.Context, serverAddress, peerKey string, serverIP netip.Addr) (net.Conn, error) {
|
||||||
m.relayClientMu.RLock()
|
m.relayClientMu.RLock()
|
||||||
defer m.relayClientMu.RUnlock()
|
defer m.relayClientMu.RUnlock()
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ func (m *Manager) OpenConn(ctx context.Context, serverAddress, peerKey string, f
|
|||||||
netConn, err = m.relayClient.OpenConn(ctx, peerKey)
|
netConn, err = m.relayClient.OpenConn(ctx, peerKey)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("open peer connection via foreign server: %s", serverAddress)
|
log.Debugf("open peer connection via foreign server: %s", serverAddress)
|
||||||
netConn, err = m.openConnVia(ctx, serverAddress, peerKey, fallbackIP)
|
netConn, err = m.openConnVia(ctx, serverAddress, peerKey, serverIP)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -207,29 +207,22 @@ func (m *Manager) AddCloseListener(serverAddress string, onClosedListener OnServ
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RelayInstanceAddress returns the address of the permanent relay server. It could change if the network connection is
|
// RelayInstanceAddress returns the address and resolved IP of the permanent relay server. It could change if the
|
||||||
// lost. This address will be sent to the target peer to choose the common relay server for the communication.
|
// network connection is lost. The address is sent to the target peer to choose the common relay server for the
|
||||||
func (m *Manager) RelayInstanceAddress() (string, error) {
|
// communication; the IP is sent alongside so remote peers can dial directly without their own DNS lookup. Both
|
||||||
|
// values are read under the same lock so they cannot diverge across a reconnection.
|
||||||
|
func (m *Manager) RelayInstanceAddress() (string, netip.Addr, error) {
|
||||||
m.relayClientMu.RLock()
|
m.relayClientMu.RLock()
|
||||||
defer m.relayClientMu.RUnlock()
|
defer m.relayClientMu.RUnlock()
|
||||||
|
|
||||||
if m.relayClient == nil {
|
if m.relayClient == nil {
|
||||||
return "", ErrRelayClientNotConnected
|
return "", netip.Addr{}, ErrRelayClientNotConnected
|
||||||
}
|
}
|
||||||
return m.relayClient.ServerInstanceURL()
|
addr, err := m.relayClient.ServerInstanceURL()
|
||||||
}
|
if err != nil {
|
||||||
|
return "", netip.Addr{}, err
|
||||||
// RelayInstanceIP returns the IP address of the live home relay connection.
|
|
||||||
// Zero value if not connected. Sent alongside RelayInstanceAddress so remote
|
|
||||||
// peers can dial directly without their own DNS lookup.
|
|
||||||
func (m *Manager) RelayInstanceIP() netip.Addr {
|
|
||||||
m.relayClientMu.RLock()
|
|
||||||
defer m.relayClientMu.RUnlock()
|
|
||||||
|
|
||||||
if m.relayClient == nil {
|
|
||||||
return netip.Addr{}
|
|
||||||
}
|
}
|
||||||
return m.relayClient.ConnectedIP()
|
return addr, m.relayClient.ConnectedIP(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerURLs returns the addresses of the relay servers.
|
// ServerURLs returns the addresses of the relay servers.
|
||||||
@@ -253,7 +246,7 @@ func (m *Manager) UpdateToken(token *relayAuth.Token) error {
|
|||||||
return m.tokenStore.UpdateToken(token)
|
return m.tokenStore.UpdateToken(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) openConnVia(ctx context.Context, serverAddress, peerKey string, fallbackIP netip.Addr) (net.Conn, error) {
|
func (m *Manager) openConnVia(ctx context.Context, serverAddress, peerKey string, serverIP netip.Addr) (net.Conn, error) {
|
||||||
// check if already has a connection to the desired relay server
|
// check if already has a connection to the desired relay server
|
||||||
m.relayClientsMutex.RLock()
|
m.relayClientsMutex.RLock()
|
||||||
rt, ok := m.relayClients[serverAddress]
|
rt, ok := m.relayClients[serverAddress]
|
||||||
@@ -288,7 +281,7 @@ func (m *Manager) openConnVia(ctx context.Context, serverAddress, peerKey string
|
|||||||
m.relayClients[serverAddress] = rt
|
m.relayClients[serverAddress] = rt
|
||||||
m.relayClientsMutex.Unlock()
|
m.relayClientsMutex.Unlock()
|
||||||
|
|
||||||
relayClient := NewClient(serverAddress, fallbackIP, m.tokenStore, m.peerID, m.mtu)
|
relayClient := NewClientWithServerIP(serverAddress, serverIP, m.tokenStore, m.peerID, m.mtu)
|
||||||
err := relayClient.Connect(m.ctx)
|
err := relayClient.Connect(m.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rt.err = err
|
rt.err = err
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import (
|
|||||||
"github.com/netbirdio/netbird/relay/server"
|
"github.com/netbirdio/netbird/relay/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestManager_ForeignRelayFallbackIP exercises the foreign-relay path
|
// TestManager_ForeignRelayServerIP exercises the foreign-relay path
|
||||||
// end-to-end through Manager.OpenConn. Alice and Bob register on different
|
// end-to-end through Manager.OpenConn. Alice and Bob register on different
|
||||||
// relay servers; Alice dials Bob's foreign relay using an unresolvable
|
// relay servers; Alice dials Bob's foreign relay using an unresolvable
|
||||||
// FQDN. Without a fallback IP the dial fails; with Bob's advertised IP it
|
// FQDN. Without a server IP the dial fails; with Bob's advertised IP it
|
||||||
// recovers and a payload round-trips between the peers.
|
// recovers and a payload round-trips between the peers.
|
||||||
func TestManager_ForeignRelayFallbackIP(t *testing.T) {
|
func TestManager_ForeignRelayServerIP(t *testing.T) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -66,14 +66,11 @@ func TestManager_ForeignRelayFallbackIP(t *testing.T) {
|
|||||||
t.Fatalf("bob manager serve: %s", err)
|
t.Fatalf("bob manager serve: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bob's real relay URL (what mgrBob.RelayInstanceAddress returns).
|
// Bob's real relay URL and the IP that would ride along in signal as relayServerIP.
|
||||||
bobRealAddr, err := mgrBob.RelayInstanceAddress()
|
bobRealAddr, bobAdvertisedIP, err := mgrBob.RelayInstanceAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("bob relay address: %s", err)
|
t.Fatalf("bob relay address: %s", err)
|
||||||
}
|
}
|
||||||
// What Bob's RelayInstanceIP() reports — this is the field that
|
|
||||||
// would ride along in signal as relayServerIP.
|
|
||||||
bobAdvertisedIP := mgrBob.RelayInstanceIP()
|
|
||||||
if !bobAdvertisedIP.IsValid() {
|
if !bobAdvertisedIP.IsValid() {
|
||||||
t.Fatalf("expected valid RelayInstanceIP for bob, got zero")
|
t.Fatalf("expected valid RelayInstanceIP for bob, got zero")
|
||||||
}
|
}
|
||||||
@@ -84,16 +81,16 @@ func TestManager_ForeignRelayFallbackIP(t *testing.T) {
|
|||||||
t.Fatalf("broken FQDN must differ from bob's real address (%s)", bobRealAddr)
|
t.Fatalf("broken FQDN must differ from bob's real address (%s)", bobRealAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("no fallback IP, dial fails", func(t *testing.T) {
|
t.Run("no server IP, dial fails", func(t *testing.T) {
|
||||||
dialCtx, dialCancel := context.WithTimeout(ctx, 5*time.Second)
|
dialCtx, dialCancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
defer dialCancel()
|
defer dialCancel()
|
||||||
_, err := mgrAlice.OpenConn(dialCtx, brokenFQDN, "bob", netip.Addr{})
|
_, err := mgrAlice.OpenConn(dialCtx, brokenFQDN, "bob", netip.Addr{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected OpenConn to fail without fallback IP, got success")
|
t.Fatalf("expected OpenConn to fail without server IP, got success")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("fallback IP recovers", func(t *testing.T) {
|
t.Run("server IP recovers", func(t *testing.T) {
|
||||||
// Bob waits for Alice's incoming peer connection on his side.
|
// Bob waits for Alice's incoming peer connection on his side.
|
||||||
bobSideCh := make(chan error, 1)
|
bobSideCh := make(chan error, 1)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -117,7 +114,7 @@ func TestManager_ForeignRelayFallbackIP(t *testing.T) {
|
|||||||
|
|
||||||
aliceConn, err := mgrAlice.OpenConn(ctx, brokenFQDN, "bob", bobAdvertisedIP)
|
aliceConn, err := mgrAlice.OpenConn(ctx, brokenFQDN, "bob", bobAdvertisedIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("alice OpenConn with fallback IP: %s", err)
|
t.Fatalf("alice OpenConn with server IP: %s", err)
|
||||||
}
|
}
|
||||||
t.Cleanup(func() { _ = aliceConn.Close() })
|
t.Cleanup(func() { _ = aliceConn.Close() })
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/netip"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ func TestForeignConn(t *testing.T) {
|
|||||||
if err := clientBob.Serve(); err != nil {
|
if err := clientBob.Serve(); err != nil {
|
||||||
t.Fatalf("failed to serve manager: %s", err)
|
t.Fatalf("failed to serve manager: %s", err)
|
||||||
}
|
}
|
||||||
bobsSrvAddr, err := clientBob.RelayInstanceAddress()
|
bobsSrvAddr, _, err := clientBob.RelayInstanceAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get relay address: %s", err)
|
t.Fatalf("failed to get relay address: %s", err)
|
||||||
}
|
}
|
||||||
@@ -368,7 +368,7 @@ func TestAutoReconnect(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to serve manager: %s", err)
|
t.Fatalf("failed to serve manager: %s", err)
|
||||||
}
|
}
|
||||||
ra, err := clientAlice.RelayInstanceAddress()
|
ra, _, err := clientAlice.RelayInstanceAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to get relay address: %s", err)
|
t.Errorf("failed to get relay address: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/netip"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -70,7 +69,7 @@ func (sp *ServerPicker) PickServer(parentCtx context.Context) (*Client, error) {
|
|||||||
|
|
||||||
func (sp *ServerPicker) startConnection(ctx context.Context, resultChan chan connResult, url string) {
|
func (sp *ServerPicker) startConnection(ctx context.Context, resultChan chan connResult, url string) {
|
||||||
log.Infof("try to connecting to relay server: %s", url)
|
log.Infof("try to connecting to relay server: %s", url)
|
||||||
relayClient := NewClient(url, netip.Addr{}, sp.TokenStore, sp.PeerID, sp.MTU)
|
relayClient := NewClient(url, sp.TokenStore, sp.PeerID, sp.MTU)
|
||||||
err := relayClient.Connect(ctx)
|
err := relayClient.Connect(ctx)
|
||||||
resultChan <- connResult{
|
resultChan <- connResult{
|
||||||
RelayClient: relayClient,
|
RelayClient: relayClient,
|
||||||
|
|||||||
@@ -72,25 +72,26 @@ func UnMarshalCredential(msg *proto.Message) (*Credential, error) {
|
|||||||
|
|
||||||
// MarshalCredential marshal a Credential instance and returns a Message object
|
// MarshalCredential marshal a Credential instance and returns a Message object
|
||||||
func MarshalCredential(myKey wgtypes.Key, remoteKey string, p CredentialPayload) (*proto.Message, error) {
|
func MarshalCredential(myKey wgtypes.Key, remoteKey string, p CredentialPayload) (*proto.Message, error) {
|
||||||
var relayIPBytes []byte
|
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() {
|
if p.RelaySrvIP.IsValid() {
|
||||||
relayIPBytes = p.RelaySrvIP.Unmap().AsSlice()
|
body.RelayServerIP = p.RelaySrvIP.Unmap().AsSlice()
|
||||||
}
|
}
|
||||||
return &proto.Message{
|
return &proto.Message{
|
||||||
Key: myKey.PublicKey().String(),
|
Key: myKey.PublicKey().String(),
|
||||||
RemoteKey: remoteKey,
|
RemoteKey: remoteKey,
|
||||||
Body: &proto.Body{
|
Body: 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,
|
|
||||||
},
|
|
||||||
RelayServerAddress: p.RelaySrvAddress,
|
|
||||||
RelayServerIP: relayIPBytes,
|
|
||||||
SessionId: p.SessionID,
|
|
||||||
},
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.26.0
|
// protoc-gen-go v1.26.0
|
||||||
// protoc v3.21.12
|
// protoc v7.34.1
|
||||||
// source: signalexchange.proto
|
// source: signalexchange.proto
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
@@ -229,13 +229,13 @@ type Body struct {
|
|||||||
// RosenpassConfig is a Rosenpass config of the remote peer our peer tries to connect to
|
// RosenpassConfig is a Rosenpass config of the remote peer our peer tries to connect to
|
||||||
RosenpassConfig *RosenpassConfig `protobuf:"bytes,7,opt,name=rosenpassConfig,proto3" json:"rosenpassConfig,omitempty"`
|
RosenpassConfig *RosenpassConfig `protobuf:"bytes,7,opt,name=rosenpassConfig,proto3" json:"rosenpassConfig,omitempty"`
|
||||||
// relayServerAddress is url of the relay server
|
// relayServerAddress is url of the relay server
|
||||||
RelayServerAddress string `protobuf:"bytes,8,opt,name=relayServerAddress,proto3" json:"relayServerAddress,omitempty"`
|
RelayServerAddress *string `protobuf:"bytes,8,opt,name=relayServerAddress,proto3,oneof" json:"relayServerAddress,omitempty"`
|
||||||
SessionId []byte `protobuf:"bytes,10,opt,name=sessionId,proto3,oneof" json:"sessionId,omitempty"`
|
SessionId []byte `protobuf:"bytes,10,opt,name=sessionId,proto3,oneof" json:"sessionId,omitempty"`
|
||||||
// relayServerIP is the IP the sender is connected to on its relay server,
|
// relayServerIP is the IP the sender is connected to on its relay server,
|
||||||
// encoded as 4 bytes (IPv4) or 16 bytes (IPv6). Receivers may use it as a
|
// encoded as 4 bytes (IPv4) or 16 bytes (IPv6). Receivers may use it as a
|
||||||
// fallback dial target when DNS resolution of relayServerAddress fails.
|
// fallback dial target when DNS resolution of relayServerAddress fails.
|
||||||
// SNI/TLS verification still uses relayServerAddress.
|
// SNI/TLS verification still uses relayServerAddress.
|
||||||
RelayServerIP []byte `protobuf:"bytes,11,opt,name=relayServerIP,proto3" json:"relayServerIP,omitempty"`
|
RelayServerIP []byte `protobuf:"bytes,11,opt,name=relayServerIP,proto3,oneof" json:"relayServerIP,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Body) Reset() {
|
func (x *Body) Reset() {
|
||||||
@@ -320,8 +320,8 @@ func (x *Body) GetRosenpassConfig() *RosenpassConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (x *Body) GetRelayServerAddress() string {
|
func (x *Body) GetRelayServerAddress() string {
|
||||||
if x != nil {
|
if x != nil && x.RelayServerAddress != nil {
|
||||||
return x.RelayServerAddress
|
return *x.RelayServerAddress
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -463,7 +463,7 @@ var file_signalexchange_proto_rawDesc = []byte{
|
|||||||
0x52, 0x09, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x04, 0x62,
|
0x52, 0x09, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x04, 0x62,
|
||||||
0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x69, 0x67, 0x6e,
|
0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x69, 0x67, 0x6e,
|
||||||
0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52,
|
0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52,
|
||||||
0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x90, 0x04, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x2d,
|
0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0xc3, 0x04, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x2d,
|
||||||
0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73,
|
0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73,
|
||||||
0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x42, 0x6f,
|
0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x42, 0x6f,
|
||||||
0x64, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a,
|
0x64, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a,
|
||||||
@@ -483,43 +483,46 @@ var file_signalexchange_proto_rawDesc = []byte{
|
|||||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63,
|
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63,
|
||||||
0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x52, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x43,
|
0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x52, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x43,
|
||||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73,
|
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73,
|
||||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53,
|
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x33, 0x0a, 0x12, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53,
|
||||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x08, 0x20, 0x01,
|
0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x08, 0x20, 0x01,
|
||||||
0x28, 0x09, 0x52, 0x12, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41,
|
0x28, 0x09, 0x48, 0x00, 0x52, 0x12, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65,
|
||||||
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
|
0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, 0x73,
|
||||||
0x6e, 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x09, 0x73, 0x65, 0x73,
|
0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x01,
|
||||||
0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x65, 0x6c,
|
0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x29,
|
||||||
0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x50, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c,
|
0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x50, 0x18,
|
||||||
0x52, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x50, 0x22,
|
0x0b, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x02, 0x52, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65,
|
||||||
0x43, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x46, 0x46, 0x45, 0x52,
|
0x72, 0x76, 0x65, 0x72, 0x49, 0x50, 0x88, 0x01, 0x01, 0x22, 0x43, 0x0a, 0x04, 0x54, 0x79, 0x70,
|
||||||
0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x4e, 0x53, 0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0d,
|
0x65, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x46, 0x46, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06,
|
||||||
0x0a, 0x09, 0x43, 0x41, 0x4e, 0x44, 0x49, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a,
|
0x41, 0x4e, 0x53, 0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x44,
|
||||||
0x04, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x4f, 0x5f, 0x49, 0x44,
|
0x49, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x44, 0x45, 0x10,
|
||||||
0x4c, 0x45, 0x10, 0x05, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
0x04, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x4f, 0x5f, 0x49, 0x44, 0x4c, 0x45, 0x10, 0x05, 0x42, 0x15,
|
||||||
0x49, 0x64, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x2e, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65,
|
0x0a, 0x13, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64,
|
||||||
0x12, 0x1b, 0x0a, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
|
0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
|
||||||
0x48, 0x00, 0x52, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a,
|
0x6e, 0x49, 0x64, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x72,
|
||||||
0x07, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0x6d, 0x0a, 0x0f, 0x52, 0x6f, 0x73, 0x65,
|
0x76, 0x65, 0x72, 0x49, 0x50, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x2e, 0x0a, 0x04, 0x4d,
|
||||||
0x6e, 0x70, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x72,
|
0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20,
|
||||||
0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x01,
|
0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x88, 0x01, 0x01,
|
||||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x50,
|
0x42, 0x09, 0x0a, 0x07, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0x6d, 0x0a, 0x0f, 0x52,
|
||||||
0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61,
|
0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28,
|
||||||
0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01,
|
0x0a, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x50, 0x75, 0x62, 0x4b, 0x65,
|
||||||
0x28, 0x09, 0x52, 0x13, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x53, 0x65, 0x72,
|
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61,
|
||||||
0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x32, 0xb9, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e,
|
0x73, 0x73, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x72, 0x6f, 0x73, 0x65,
|
||||||
0x61, 0x6c, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x4c, 0x0a, 0x04, 0x53, 0x65,
|
0x6e, 0x70, 0x61, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x18,
|
||||||
0x6e, 0x64, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61,
|
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73,
|
||||||
0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73,
|
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x32, 0xb9, 0x01, 0x0a, 0x0e, 0x53,
|
||||||
0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63,
|
0x69, 0x67, 0x6e, 0x61, 0x6c, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x4c, 0x0a,
|
||||||
0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d,
|
0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78,
|
||||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x6e,
|
0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
|
||||||
0x65, 0x63, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e,
|
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c,
|
||||||
0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79,
|
0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
|
||||||
0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69,
|
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0d, 0x43,
|
||||||
0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63,
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x20, 0x2e, 0x73,
|
||||||
0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28,
|
0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e,
|
||||||
0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70,
|
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20,
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e,
|
||||||
|
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||||
|
0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
|
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ message Body {
|
|||||||
RosenpassConfig rosenpassConfig = 7;
|
RosenpassConfig rosenpassConfig = 7;
|
||||||
|
|
||||||
// relayServerAddress is url of the relay server
|
// relayServerAddress is url of the relay server
|
||||||
string relayServerAddress = 8;
|
optional string relayServerAddress = 8;
|
||||||
|
|
||||||
reserved 9;
|
reserved 9;
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ message Body {
|
|||||||
// encoded as 4 bytes (IPv4) or 16 bytes (IPv6). Receivers may use it as a
|
// encoded as 4 bytes (IPv4) or 16 bytes (IPv6). Receivers may use it as a
|
||||||
// fallback dial target when DNS resolution of relayServerAddress fails.
|
// fallback dial target when DNS resolution of relayServerAddress fails.
|
||||||
// SNI/TLS verification still uses relayServerAddress.
|
// SNI/TLS verification still uses relayServerAddress.
|
||||||
bytes relayServerIP = 11;
|
optional bytes relayServerIP = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mode indicates a connection mode
|
// Mode indicates a connection mode
|
||||||
|
|||||||
Reference in New Issue
Block a user