mirror of
https://github.com/netbirdio/netbird.git
synced 2025-04-23 02:48:50 +02:00
Exchange proxy mode via signal (#727)
Before defining if we will use direct or proxy connection we will exchange a message with the other peer if the modes match we keep the decision from the shouldUseProxy function otherwise we skip using direct connection. Added a feature support message to the signal protocol
This commit is contained in:
parent
6143b819c5
commit
731d3ae464
@ -353,6 +353,10 @@ func signalCandidate(candidate ice.Candidate, myKey wgtypes.Key, remoteKey wgtyp
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendSignal(message *sProto.Message, s signal.Client) error {
|
||||||
|
return s.Send(message)
|
||||||
|
}
|
||||||
|
|
||||||
// SignalOfferAnswer signals either an offer or an answer to remote peer
|
// SignalOfferAnswer signals either an offer or an answer to remote peer
|
||||||
func SignalOfferAnswer(offerAnswer peer.OfferAnswer, myKey wgtypes.Key, remoteKey wgtypes.Key, s signal.Client, isAnswer bool) error {
|
func SignalOfferAnswer(offerAnswer peer.OfferAnswer, myKey wgtypes.Key, remoteKey wgtypes.Key, s signal.Client, isAnswer bool) error {
|
||||||
var t sProto.Body_Type
|
var t sProto.Body_Type
|
||||||
@ -369,6 +373,10 @@ func SignalOfferAnswer(offerAnswer peer.OfferAnswer, myKey wgtypes.Key, remoteKe
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// indicates message support in gRPC
|
||||||
|
msg.Body.FeaturesSupported = []uint32{signal.DirectCheck}
|
||||||
|
|
||||||
err = s.Send(msg)
|
err = s.Send(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -827,6 +835,9 @@ func (e Engine) createPeerConn(pubKey string, allowedIPs string) (*peer.Conn, er
|
|||||||
peerConn.SetSignalCandidate(signalCandidate)
|
peerConn.SetSignalCandidate(signalCandidate)
|
||||||
peerConn.SetSignalOffer(signalOffer)
|
peerConn.SetSignalOffer(signalOffer)
|
||||||
peerConn.SetSignalAnswer(signalAnswer)
|
peerConn.SetSignalAnswer(signalAnswer)
|
||||||
|
peerConn.SetSendSignalMessage(func(message *sProto.Message) error {
|
||||||
|
return sendSignal(message, e.signal)
|
||||||
|
})
|
||||||
|
|
||||||
return peerConn, nil
|
return peerConn, nil
|
||||||
}
|
}
|
||||||
@ -850,6 +861,9 @@ func (e *Engine) receiveSignalEvents() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn.RegisterProtoSupportMeta(msg.Body.GetFeaturesSupported())
|
||||||
|
|
||||||
conn.OnRemoteOffer(peer.OfferAnswer{
|
conn.OnRemoteOffer(peer.OfferAnswer{
|
||||||
IceCredentials: peer.IceCredentials{
|
IceCredentials: peer.IceCredentials{
|
||||||
UFrag: remoteCred.UFrag,
|
UFrag: remoteCred.UFrag,
|
||||||
@ -863,6 +877,9 @@ func (e *Engine) receiveSignalEvents() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn.RegisterProtoSupportMeta(msg.Body.GetFeaturesSupported())
|
||||||
|
|
||||||
conn.OnRemoteAnswer(peer.OfferAnswer{
|
conn.OnRemoteAnswer(peer.OfferAnswer{
|
||||||
IceCredentials: peer.IceCredentials{
|
IceCredentials: peer.IceCredentials{
|
||||||
UFrag: remoteCred.UFrag,
|
UFrag: remoteCred.UFrag,
|
||||||
@ -878,6 +895,19 @@ func (e *Engine) receiveSignalEvents() {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
conn.OnRemoteCandidate(candidate)
|
conn.OnRemoteCandidate(candidate)
|
||||||
|
case sProto.Body_MODE:
|
||||||
|
protoMode := msg.GetBody().GetMode()
|
||||||
|
if protoMode == nil {
|
||||||
|
return fmt.Errorf("received an empty mode message")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := conn.OnModeMessage(peer.ModeMessage{
|
||||||
|
Direct: protoMode.GetDirect(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed processing a mode message -> %s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -2,6 +2,7 @@ package peer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -14,6 +15,8 @@ import (
|
|||||||
"github.com/netbirdio/netbird/client/internal/proxy"
|
"github.com/netbirdio/netbird/client/internal/proxy"
|
||||||
"github.com/netbirdio/netbird/iface"
|
"github.com/netbirdio/netbird/iface"
|
||||||
"github.com/netbirdio/netbird/version"
|
"github.com/netbirdio/netbird/version"
|
||||||
|
signal "github.com/netbirdio/netbird/signal/client"
|
||||||
|
sProto "github.com/netbirdio/netbird/signal/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConnConfig is a peer Connection configuration
|
// ConnConfig is a peer Connection configuration
|
||||||
@ -71,6 +74,7 @@ type Conn struct {
|
|||||||
// signalOffer is a handler function to signal remote peer our connection offer (credentials)
|
// signalOffer is a handler function to signal remote peer our connection offer (credentials)
|
||||||
signalOffer func(OfferAnswer) error
|
signalOffer func(OfferAnswer) error
|
||||||
signalAnswer func(OfferAnswer) error
|
signalAnswer func(OfferAnswer) error
|
||||||
|
sendSignalMessage func(message *sProto.Message) error
|
||||||
|
|
||||||
// remoteOffersCh is a channel used to wait for remote credentials to proceed with the connection
|
// remoteOffersCh is a channel used to wait for remote credentials to proceed with the connection
|
||||||
remoteOffersCh chan OfferAnswer
|
remoteOffersCh chan OfferAnswer
|
||||||
@ -86,6 +90,19 @@ type Conn struct {
|
|||||||
statusRecorder *Status
|
statusRecorder *Status
|
||||||
|
|
||||||
proxy proxy.Proxy
|
proxy proxy.Proxy
|
||||||
|
remoteModeCh chan ModeMessage
|
||||||
|
meta meta
|
||||||
|
}
|
||||||
|
|
||||||
|
// meta holds meta information about a connection
|
||||||
|
type meta struct {
|
||||||
|
protoSupport signal.FeaturesSupport
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModeMessage represents a connection mode chosen by the peer
|
||||||
|
type ModeMessage struct {
|
||||||
|
// Direct indicates that it decided to use a direct connection
|
||||||
|
Direct bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConf returns the connection config
|
// GetConf returns the connection config
|
||||||
@ -109,6 +126,7 @@ func NewConn(config ConnConfig, statusRecorder *Status) (*Conn, error) {
|
|||||||
remoteOffersCh: make(chan OfferAnswer),
|
remoteOffersCh: make(chan OfferAnswer),
|
||||||
remoteAnswerCh: make(chan OfferAnswer),
|
remoteAnswerCh: make(chan OfferAnswer),
|
||||||
statusRecorder: statusRecorder,
|
statusRecorder: statusRecorder,
|
||||||
|
remoteModeCh: make(chan ModeMessage, 1),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,15 +384,7 @@ func (conn *Conn) startProxy(remoteConn net.Conn, remoteWgPort int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
peerState := State{PubKey: conn.config.Key}
|
peerState := State{PubKey: conn.config.Key}
|
||||||
useProxy := shouldUseProxy(pair)
|
p := conn.getProxyWithMessageExchange(pair, remoteWgPort)
|
||||||
var p proxy.Proxy
|
|
||||||
if useProxy {
|
|
||||||
p = proxy.NewWireguardProxy(conn.config.ProxyConfig)
|
|
||||||
peerState.Direct = false
|
|
||||||
} else {
|
|
||||||
p = proxy.NewNoProxy(conn.config.ProxyConfig, remoteWgPort)
|
|
||||||
peerState.Direct = true
|
|
||||||
}
|
|
||||||
conn.proxy = p
|
conn.proxy = p
|
||||||
err = p.Start(remoteConn)
|
err = p.Start(remoteConn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -390,6 +400,7 @@ func (conn *Conn) startProxy(remoteConn net.Conn, remoteWgPort int) error {
|
|||||||
if pair.Local.Type() == ice.CandidateTypeRelay || pair.Remote.Type() == ice.CandidateTypeRelay {
|
if pair.Local.Type() == ice.CandidateTypeRelay || pair.Remote.Type() == ice.CandidateTypeRelay {
|
||||||
peerState.Relayed = true
|
peerState.Relayed = true
|
||||||
}
|
}
|
||||||
|
peerState.Direct = p.Type() == proxy.TypeNoProxy
|
||||||
|
|
||||||
err = conn.statusRecorder.UpdatePeerState(peerState)
|
err = conn.statusRecorder.UpdatePeerState(peerState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -399,6 +410,63 @@ func (conn *Conn) startProxy(remoteConn net.Conn, remoteWgPort int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (conn *Conn) getProxyWithMessageExchange(pair *ice.CandidatePair, remoteWgPort int) proxy.Proxy {
|
||||||
|
|
||||||
|
useProxy := shouldUseProxy(pair)
|
||||||
|
localDirectMode := !useProxy
|
||||||
|
remoteDirectMode := localDirectMode
|
||||||
|
|
||||||
|
if conn.meta.protoSupport.DirectCheck {
|
||||||
|
go conn.sendLocalDirectMode(localDirectMode)
|
||||||
|
// will block until message received or timeout
|
||||||
|
remoteDirectMode = conn.receiveRemoteDirectMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
if localDirectMode && remoteDirectMode {
|
||||||
|
log.Debugf("using WireGuard direct mode with peer %s", conn.config.Key)
|
||||||
|
return proxy.NewNoProxy(conn.config.ProxyConfig, remoteWgPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("falling back to local proxy mode with peer %s", conn.config.Key)
|
||||||
|
return proxy.NewWireguardProxy(conn.config.ProxyConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conn *Conn) sendLocalDirectMode(localMode bool) {
|
||||||
|
// todo what happens when we couldn't deliver this message?
|
||||||
|
// we could retry, etc but there is no guarantee
|
||||||
|
|
||||||
|
err := conn.sendSignalMessage(&sProto.Message{
|
||||||
|
Key: conn.config.LocalKey,
|
||||||
|
RemoteKey: conn.config.Key,
|
||||||
|
Body: &sProto.Body{
|
||||||
|
Type: sProto.Body_MODE,
|
||||||
|
Mode: &sProto.Mode{
|
||||||
|
Direct: &localMode,
|
||||||
|
},
|
||||||
|
NetBirdVersion: version.NetbirdVersion(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to send local proxy mode to remote peer %s, error: %s", conn.config.Key, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conn *Conn) receiveRemoteDirectMode() bool {
|
||||||
|
timeout := time.Second
|
||||||
|
timer := time.NewTimer(timeout)
|
||||||
|
defer timer.Stop()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case receivedMSG := <-conn.remoteModeCh:
|
||||||
|
return receivedMSG.Direct
|
||||||
|
case <-timer.C:
|
||||||
|
// we didn't receive a message from remote so we assume that it supports the direct mode to keep the old behaviour
|
||||||
|
log.Debugf("timeout after %s while waiting for remote direct mode message from remote peer %s",
|
||||||
|
timeout, conn.config.Key)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cleanup closes all open resources and sets status to StatusDisconnected
|
// cleanup closes all open resources and sets status to StatusDisconnected
|
||||||
func (conn *Conn) cleanup() error {
|
func (conn *Conn) cleanup() error {
|
||||||
log.Debugf("trying to cleanup %s", conn.config.Key)
|
log.Debugf("trying to cleanup %s", conn.config.Key)
|
||||||
@ -459,6 +527,11 @@ func (conn *Conn) SetSignalCandidate(handler func(candidate ice.Candidate) error
|
|||||||
conn.signalCandidate = handler
|
conn.signalCandidate = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSendSignalMessage sets a handler function to be triggered by Conn when there is new message to send via signal
|
||||||
|
func (conn *Conn) SetSendSignalMessage(handler func(message *sProto.Message) error) {
|
||||||
|
conn.sendSignalMessage = handler
|
||||||
|
}
|
||||||
|
|
||||||
// onICECandidate is a callback attached to an ICE Agent to receive new local connection candidates
|
// onICECandidate is a callback attached to an ICE Agent to receive new local connection candidates
|
||||||
// and then signals them to the remote peer
|
// and then signals them to the remote peer
|
||||||
func (conn *Conn) onICECandidate(candidate ice.Candidate) {
|
func (conn *Conn) onICECandidate(candidate ice.Candidate) {
|
||||||
@ -613,3 +686,19 @@ func (conn *Conn) OnRemoteCandidate(candidate ice.Candidate) {
|
|||||||
func (conn *Conn) GetKey() string {
|
func (conn *Conn) GetKey() string {
|
||||||
return conn.config.Key
|
return conn.config.Key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnModeMessage unmarshall the payload message and send it to the mode message channel
|
||||||
|
func (conn *Conn) OnModeMessage(message ModeMessage) error {
|
||||||
|
select {
|
||||||
|
case conn.remoteModeCh <- message:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unable to process mode message: channel busy")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterProtoSupportMeta register supported proto message in the connection metadata
|
||||||
|
func (conn *Conn) RegisterProtoSupportMeta(support []uint32) {
|
||||||
|
protoSupport := signal.ParseFeaturesSupported(support)
|
||||||
|
conn.meta.protoSupport = protoSupport
|
||||||
|
}
|
||||||
|
@ -7,9 +7,11 @@ import (
|
|||||||
|
|
||||||
"github.com/magiconair/properties/assert"
|
"github.com/magiconair/properties/assert"
|
||||||
"github.com/pion/ice/v2"
|
"github.com/pion/ice/v2"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/internal/proxy"
|
"github.com/netbirdio/netbird/client/internal/proxy"
|
||||||
"github.com/netbirdio/netbird/iface"
|
"github.com/netbirdio/netbird/iface"
|
||||||
|
sproto "github.com/netbirdio/netbird/signal/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var connConf = ConnConfig{
|
var connConf = ConnConfig{
|
||||||
@ -329,3 +331,110 @@ func TestConn_ShouldUseProxy(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetProxyWithMessageExchange(t *testing.T) {
|
||||||
|
publicHostCandidate := &mockICECandidate{
|
||||||
|
AddressFunc: func() string {
|
||||||
|
return "8.8.8.8"
|
||||||
|
},
|
||||||
|
TypeFunc: func() ice.CandidateType {
|
||||||
|
return ice.CandidateTypeHost
|
||||||
|
},
|
||||||
|
}
|
||||||
|
relayCandidate := &mockICECandidate{
|
||||||
|
AddressFunc: func() string {
|
||||||
|
return "1.1.1.1"
|
||||||
|
},
|
||||||
|
TypeFunc: func() ice.CandidateType {
|
||||||
|
return ice.CandidateTypeRelay
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
candatePair *ice.CandidatePair
|
||||||
|
inputDirectModeSupport bool
|
||||||
|
inputRemoteModeMessage bool
|
||||||
|
expected proxy.Type
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Should Result In Using Wireguard Proxy When Local Eval Is Use Proxy",
|
||||||
|
candatePair: &ice.CandidatePair{
|
||||||
|
Local: relayCandidate,
|
||||||
|
Remote: publicHostCandidate,
|
||||||
|
},
|
||||||
|
inputDirectModeSupport: true,
|
||||||
|
inputRemoteModeMessage: true,
|
||||||
|
expected: proxy.TypeWireguard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Should Result In Using Wireguard Proxy When Remote Eval Is Use Proxy",
|
||||||
|
candatePair: &ice.CandidatePair{
|
||||||
|
Local: publicHostCandidate,
|
||||||
|
Remote: publicHostCandidate,
|
||||||
|
},
|
||||||
|
inputDirectModeSupport: true,
|
||||||
|
inputRemoteModeMessage: false,
|
||||||
|
expected: proxy.TypeWireguard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Should Result In Using Wireguard Proxy When Remote Direct Mode Support Is False And Local Eval Is Use Proxy",
|
||||||
|
candatePair: &ice.CandidatePair{
|
||||||
|
Local: relayCandidate,
|
||||||
|
Remote: publicHostCandidate,
|
||||||
|
},
|
||||||
|
inputDirectModeSupport: false,
|
||||||
|
inputRemoteModeMessage: false,
|
||||||
|
expected: proxy.TypeWireguard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Should Result In Using Direct When Remote Direct Mode Support Is False And Local Eval Is No Use Proxy",
|
||||||
|
candatePair: &ice.CandidatePair{
|
||||||
|
Local: publicHostCandidate,
|
||||||
|
Remote: publicHostCandidate,
|
||||||
|
},
|
||||||
|
inputDirectModeSupport: false,
|
||||||
|
inputRemoteModeMessage: false,
|
||||||
|
expected: proxy.TypeNoProxy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Should Result In Using Direct When Local And Remote Eval Is No Proxy",
|
||||||
|
candatePair: &ice.CandidatePair{
|
||||||
|
Local: publicHostCandidate,
|
||||||
|
Remote: publicHostCandidate,
|
||||||
|
},
|
||||||
|
inputDirectModeSupport: true,
|
||||||
|
inputRemoteModeMessage: true,
|
||||||
|
expected: proxy.TypeNoProxy,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
g := errgroup.Group{}
|
||||||
|
conn, err := NewConn(connConf, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
conn.meta.protoSupport.DirectCheck = testCase.inputDirectModeSupport
|
||||||
|
conn.SetSendSignalMessage(func(message *sproto.Message) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
g.Go(func() error {
|
||||||
|
return conn.OnModeMessage(ModeMessage{
|
||||||
|
Direct: testCase.inputRemoteModeMessage,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
resultProxy := conn.getProxyWithMessageExchange(testCase.candatePair, 1000)
|
||||||
|
|
||||||
|
err = g.Wait()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if resultProxy.Type() != testCase.expected {
|
||||||
|
t.Errorf("result didn't match expected value: Expected: %s, Got: %s", testCase.expected, resultProxy.Type())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -55,6 +55,7 @@ require (
|
|||||||
go.opentelemetry.io/otel/metric v0.33.0
|
go.opentelemetry.io/otel/metric v0.33.0
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.33.0
|
go.opentelemetry.io/otel/sdk/metric v0.33.0
|
||||||
golang.org/x/net v0.8.0
|
golang.org/x/net v0.8.0
|
||||||
|
golang.org/x/sync v0.1.0
|
||||||
golang.org/x/term v0.6.0
|
golang.org/x/term v0.6.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
@ -128,7 +129,6 @@ require (
|
|||||||
golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf // indirect
|
golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf // indirect
|
||||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
|
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
|
||||||
golang.org/x/mod v0.8.0 // indirect
|
golang.org/x/mod v0.8.0 // indirect
|
||||||
golang.org/x/sync v0.1.0 // indirect
|
|
||||||
golang.org/x/text v0.8.0 // indirect
|
golang.org/x/text v0.8.0 // indirect
|
||||||
golang.org/x/tools v0.6.0 // indirect
|
golang.org/x/tools v0.6.0 // indirect
|
||||||
golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d // indirect
|
golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d // indirect
|
||||||
|
@ -19,6 +19,16 @@ type Status string
|
|||||||
const StreamConnected Status = "Connected"
|
const StreamConnected Status = "Connected"
|
||||||
const StreamDisconnected Status = "Disconnected"
|
const StreamDisconnected Status = "Disconnected"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DirectCheck indicates support to direct mode checks
|
||||||
|
DirectCheck uint32 = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// FeaturesSupport register protocol supported features
|
||||||
|
type FeaturesSupport struct {
|
||||||
|
DirectCheck bool
|
||||||
|
}
|
||||||
|
|
||||||
type Client interface {
|
type Client interface {
|
||||||
io.Closer
|
io.Closer
|
||||||
StreamConnected() bool
|
StreamConnected() bool
|
||||||
@ -62,3 +72,15 @@ type Credential struct {
|
|||||||
UFrag string
|
UFrag string
|
||||||
Pwd string
|
Pwd string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseFeaturesSupported parses a slice of supported features into FeaturesSupport
|
||||||
|
func ParseFeaturesSupported(featuresMessage []uint32) FeaturesSupport {
|
||||||
|
var protoSupport FeaturesSupport
|
||||||
|
for _, feature := range featuresMessage {
|
||||||
|
if feature == DirectCheck {
|
||||||
|
protoSupport.DirectCheck = true
|
||||||
|
return protoSupport
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return protoSupport
|
||||||
|
}
|
||||||
|
@ -2,8 +2,11 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
sigProto "github.com/netbirdio/netbird/signal/proto"
|
"net"
|
||||||
"github.com/netbirdio/netbird/signal/server"
|
"sync"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@ -12,9 +15,9 @@ import (
|
|||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
"google.golang.org/grpc/keepalive"
|
"google.golang.org/grpc/keepalive"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"net"
|
|
||||||
"sync"
|
sigProto "github.com/netbirdio/netbird/signal/proto"
|
||||||
"time"
|
"github.com/netbirdio/netbird/signal/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("GrpcClient", func() {
|
var _ = Describe("GrpcClient", func() {
|
||||||
@ -43,15 +46,18 @@ var _ = Describe("GrpcClient", func() {
|
|||||||
var msgReceived sync.WaitGroup
|
var msgReceived sync.WaitGroup
|
||||||
msgReceived.Add(2)
|
msgReceived.Add(2)
|
||||||
|
|
||||||
var receivedOnA string
|
var payloadReceivedOnA string
|
||||||
var receivedOnB string
|
var payloadReceivedOnB string
|
||||||
|
var featuresSupportedReceivedOnA []uint32
|
||||||
|
var featuresSupportedReceivedOnB []uint32
|
||||||
|
|
||||||
// connect PeerA to Signal
|
// connect PeerA to Signal
|
||||||
keyA, _ := wgtypes.GenerateKey()
|
keyA, _ := wgtypes.GenerateKey()
|
||||||
clientA := createSignalClient(addr, keyA)
|
clientA := createSignalClient(addr, keyA)
|
||||||
go func() {
|
go func() {
|
||||||
err := clientA.Receive(func(msg *sigProto.Message) error {
|
err := clientA.Receive(func(msg *sigProto.Message) error {
|
||||||
receivedOnA = msg.GetBody().GetPayload()
|
payloadReceivedOnA = msg.GetBody().GetPayload()
|
||||||
|
featuresSupportedReceivedOnA = msg.GetBody().GetFeaturesSupported()
|
||||||
msgReceived.Done()
|
msgReceived.Done()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -67,7 +73,8 @@ var _ = Describe("GrpcClient", func() {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
err := clientB.Receive(func(msg *sigProto.Message) error {
|
err := clientB.Receive(func(msg *sigProto.Message) error {
|
||||||
receivedOnB = msg.GetBody().GetPayload()
|
payloadReceivedOnB = msg.GetBody().GetPayload()
|
||||||
|
featuresSupportedReceivedOnB = msg.GetBody().GetFeaturesSupported()
|
||||||
err := clientB.Send(&sigProto.Message{
|
err := clientB.Send(&sigProto.Message{
|
||||||
Key: keyB.PublicKey().String(),
|
Key: keyB.PublicKey().String(),
|
||||||
RemoteKey: keyA.PublicKey().String(),
|
RemoteKey: keyA.PublicKey().String(),
|
||||||
@ -90,7 +97,7 @@ var _ = Describe("GrpcClient", func() {
|
|||||||
err := clientA.Send(&sigProto.Message{
|
err := clientA.Send(&sigProto.Message{
|
||||||
Key: keyA.PublicKey().String(),
|
Key: keyA.PublicKey().String(),
|
||||||
RemoteKey: keyB.PublicKey().String(),
|
RemoteKey: keyB.PublicKey().String(),
|
||||||
Body: &sigProto.Body{Payload: "ping"},
|
Body: &sigProto.Body{Payload: "ping", FeaturesSupported: []uint32{DirectCheck}},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail("failed sending a message to PeerB")
|
Fail("failed sending a message to PeerB")
|
||||||
@ -100,9 +107,10 @@ var _ = Describe("GrpcClient", func() {
|
|||||||
Fail("test timed out on waiting for peers to exchange messages")
|
Fail("test timed out on waiting for peers to exchange messages")
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect(receivedOnA).To(BeEquivalentTo("pong"))
|
Expect(payloadReceivedOnA).To(BeEquivalentTo("pong"))
|
||||||
Expect(receivedOnB).To(BeEquivalentTo("ping"))
|
Expect(payloadReceivedOnB).To(BeEquivalentTo("ping"))
|
||||||
|
Expect(featuresSupportedReceivedOnA).To(BeNil())
|
||||||
|
Expect(featuresSupportedReceivedOnB).To(ContainElements([]uint32{DirectCheck}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -160,6 +168,41 @@ var _ = Describe("GrpcClient", func() {
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
func TestParseFeaturesSupported(t *testing.T) {
|
||||||
|
expectedOnEmptyOrUnsupported := FeaturesSupport{DirectCheck: false}
|
||||||
|
expectedWithDirectCheck := FeaturesSupport{DirectCheck: true}
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
input []uint32
|
||||||
|
expected FeaturesSupport
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Should Return DirectCheck Supported",
|
||||||
|
input: []uint32{DirectCheck},
|
||||||
|
expected: expectedWithDirectCheck,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Should Return DirectCheck Unsupported When Nil",
|
||||||
|
input: nil,
|
||||||
|
expected: expectedOnEmptyOrUnsupported,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Should Return DirectCheck Unsupported When Not Known Feature",
|
||||||
|
input: []uint32{9999},
|
||||||
|
expected: expectedOnEmptyOrUnsupported,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
result := ParseFeaturesSupported(testCase.input)
|
||||||
|
if result.DirectCheck != testCase.expected.DirectCheck {
|
||||||
|
t.Errorf("Direct check feature should match: Expected: %t, Got: %t", testCase.expected.DirectCheck, result.DirectCheck)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func createSignalClient(addr string, key wgtypes.Key) *GrpcClient {
|
func createSignalClient(addr string, key wgtypes.Key) *GrpcClient {
|
||||||
var sigTLSEnabled = false
|
var sigTLSEnabled = false
|
||||||
client, err := NewClient(context.Background(), addr, key, sigTLSEnabled)
|
client, err := NewClient(context.Background(), addr, key, sigTLSEnabled)
|
||||||
|
@ -1,4 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if ! which realpath > /dev/null 2>&1
|
||||||
|
then
|
||||||
|
echo realpath is not installed
|
||||||
|
echo run: brew install coreutils
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
old_pwd=$(pwd)
|
||||||
|
script_path=$(dirname $(realpath "$0"))
|
||||||
|
cd "$script_path"
|
||||||
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
|
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
|
||||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
|
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
|
||||||
protoc -I proto/ proto/signalexchange.proto --go_out=. --go-grpc_out=.
|
protoc -I ./ ./signalexchange.proto --go_out=../ --go-grpc_out=../
|
||||||
|
cd "$old_pwd"
|
@ -1,15 +1,15 @@
|
|||||||
// 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.12.4
|
// protoc v3.21.9
|
||||||
// source: signalexchange.proto
|
// source: signalexchange.proto
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "github.com/golang/protobuf/protoc-gen-go/descriptor"
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
_ "google.golang.org/protobuf/types/descriptorpb"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
sync "sync"
|
sync "sync"
|
||||||
)
|
)
|
||||||
@ -28,6 +28,7 @@ const (
|
|||||||
Body_OFFER Body_Type = 0
|
Body_OFFER Body_Type = 0
|
||||||
Body_ANSWER Body_Type = 1
|
Body_ANSWER Body_Type = 1
|
||||||
Body_CANDIDATE Body_Type = 2
|
Body_CANDIDATE Body_Type = 2
|
||||||
|
Body_MODE Body_Type = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
// Enum value maps for Body_Type.
|
// Enum value maps for Body_Type.
|
||||||
@ -36,11 +37,13 @@ var (
|
|||||||
0: "OFFER",
|
0: "OFFER",
|
||||||
1: "ANSWER",
|
1: "ANSWER",
|
||||||
2: "CANDIDATE",
|
2: "CANDIDATE",
|
||||||
|
4: "MODE",
|
||||||
}
|
}
|
||||||
Body_Type_value = map[string]int32{
|
Body_Type_value = map[string]int32{
|
||||||
"OFFER": 0,
|
"OFFER": 0,
|
||||||
"ANSWER": 1,
|
"ANSWER": 1,
|
||||||
"CANDIDATE": 2,
|
"CANDIDATE": 2,
|
||||||
|
"MODE": 4,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -217,6 +220,9 @@ type Body struct {
|
|||||||
// wgListenPort is an actual WireGuard listen port
|
// wgListenPort is an actual WireGuard listen port
|
||||||
WgListenPort uint32 `protobuf:"varint,3,opt,name=wgListenPort,proto3" json:"wgListenPort,omitempty"`
|
WgListenPort uint32 `protobuf:"varint,3,opt,name=wgListenPort,proto3" json:"wgListenPort,omitempty"`
|
||||||
NetBirdVersion string `protobuf:"bytes,4,opt,name=netBirdVersion,proto3" json:"netBirdVersion,omitempty"`
|
NetBirdVersion string `protobuf:"bytes,4,opt,name=netBirdVersion,proto3" json:"netBirdVersion,omitempty"`
|
||||||
|
Mode *Mode `protobuf:"bytes,5,opt,name=mode,proto3" json:"mode,omitempty"`
|
||||||
|
// featuresSupported list of supported features by the client of this protocol
|
||||||
|
FeaturesSupported []uint32 `protobuf:"varint,6,rep,packed,name=featuresSupported,proto3" json:"featuresSupported,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Body) Reset() {
|
func (x *Body) Reset() {
|
||||||
@ -279,6 +285,68 @@ func (x *Body) GetNetBirdVersion() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Body) GetMode() *Mode {
|
||||||
|
if x != nil {
|
||||||
|
return x.Mode
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Body) GetFeaturesSupported() []uint32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.FeaturesSupported
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mode indicates a connection mode
|
||||||
|
type Mode struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Direct *bool `protobuf:"varint,1,opt,name=direct,proto3,oneof" json:"direct,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Mode) Reset() {
|
||||||
|
*x = Mode{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_signalexchange_proto_msgTypes[3]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Mode) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Mode) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *Mode) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_signalexchange_proto_msgTypes[3]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Mode.ProtoReflect.Descriptor instead.
|
||||||
|
func (*Mode) Descriptor() ([]byte, []int) {
|
||||||
|
return file_signalexchange_proto_rawDescGZIP(), []int{3}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Mode) GetDirect() bool {
|
||||||
|
if x != nil && x.Direct != nil {
|
||||||
|
return *x.Direct
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
var File_signalexchange_proto protoreflect.FileDescriptor
|
var File_signalexchange_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_signalexchange_proto_rawDesc = []byte{
|
var file_signalexchange_proto_rawDesc = []byte{
|
||||||
@ -298,7 +366,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, 0xc9, 0x01, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x2d,
|
0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0xab, 0x02, 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,
|
||||||
@ -308,22 +376,32 @@ var file_signalexchange_proto_rawDesc = []byte{
|
|||||||
0x67, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x6e,
|
0x67, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x6e,
|
||||||
0x65, 0x74, 0x42, 0x69, 0x72, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20,
|
0x65, 0x74, 0x42, 0x69, 0x72, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20,
|
||||||
0x01, 0x28, 0x09, 0x52, 0x0e, 0x6e, 0x65, 0x74, 0x42, 0x69, 0x72, 0x64, 0x56, 0x65, 0x72, 0x73,
|
0x01, 0x28, 0x09, 0x52, 0x0e, 0x6e, 0x65, 0x74, 0x42, 0x69, 0x72, 0x64, 0x56, 0x65, 0x72, 0x73,
|
||||||
0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x4f,
|
0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||||
0x46, 0x46, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x4e, 0x53, 0x57, 0x45, 0x52,
|
0x0b, 0x32, 0x14, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e,
|
||||||
0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x44, 0x49, 0x44, 0x41, 0x54, 0x45, 0x10,
|
0x67, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x2c, 0x0a,
|
||||||
0x02, 0x32, 0xb9, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x45, 0x78, 0x63, 0x68,
|
0x11, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74,
|
||||||
0x61, 0x6e, 0x67, 0x65, 0x12, 0x4c, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x73,
|
0x65, 0x64, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x11, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72,
|
||||||
0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e,
|
0x65, 0x73, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x22, 0x36, 0x0a, 0x04, 0x54,
|
||||||
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20,
|
0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x46, 0x46, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0a,
|
||||||
|
0x0a, 0x06, 0x41, 0x4e, 0x53, 0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41,
|
||||||
|
0x4e, 0x44, 0x49, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x44,
|
||||||
|
0x45, 0x10, 0x04, 0x22, 0x2e, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x64,
|
||||||
|
0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x64,
|
||||||
|
0x69, 0x72, 0x65, 0x63, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x64, 0x69, 0x72,
|
||||||
|
0x65, 0x63, 0x74, 0x32, 0xb9, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x45, 0x78,
|
||||||
|
0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x4c, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x20,
|
||||||
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e,
|
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,
|
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||||
0x22, 0x00, 0x12, 0x59, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x53, 0x74, 0x72,
|
0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67,
|
||||||
0x65, 0x61, 0x6d, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68,
|
0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||||
0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65,
|
0x67, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x53,
|
||||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78,
|
0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x20, 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,
|
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,
|
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c,
|
||||||
0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
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 (
|
||||||
@ -339,25 +417,27 @@ func file_signalexchange_proto_rawDescGZIP() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var file_signalexchange_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
var file_signalexchange_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||||
var file_signalexchange_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
var file_signalexchange_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||||
var file_signalexchange_proto_goTypes = []interface{}{
|
var file_signalexchange_proto_goTypes = []interface{}{
|
||||||
(Body_Type)(0), // 0: signalexchange.Body.Type
|
(Body_Type)(0), // 0: signalexchange.Body.Type
|
||||||
(*EncryptedMessage)(nil), // 1: signalexchange.EncryptedMessage
|
(*EncryptedMessage)(nil), // 1: signalexchange.EncryptedMessage
|
||||||
(*Message)(nil), // 2: signalexchange.Message
|
(*Message)(nil), // 2: signalexchange.Message
|
||||||
(*Body)(nil), // 3: signalexchange.Body
|
(*Body)(nil), // 3: signalexchange.Body
|
||||||
|
(*Mode)(nil), // 4: signalexchange.Mode
|
||||||
}
|
}
|
||||||
var file_signalexchange_proto_depIdxs = []int32{
|
var file_signalexchange_proto_depIdxs = []int32{
|
||||||
3, // 0: signalexchange.Message.body:type_name -> signalexchange.Body
|
3, // 0: signalexchange.Message.body:type_name -> signalexchange.Body
|
||||||
0, // 1: signalexchange.Body.type:type_name -> signalexchange.Body.Type
|
0, // 1: signalexchange.Body.type:type_name -> signalexchange.Body.Type
|
||||||
1, // 2: signalexchange.SignalExchange.Send:input_type -> signalexchange.EncryptedMessage
|
4, // 2: signalexchange.Body.mode:type_name -> signalexchange.Mode
|
||||||
1, // 3: signalexchange.SignalExchange.ConnectStream:input_type -> signalexchange.EncryptedMessage
|
1, // 3: signalexchange.SignalExchange.Send:input_type -> signalexchange.EncryptedMessage
|
||||||
1, // 4: signalexchange.SignalExchange.Send:output_type -> signalexchange.EncryptedMessage
|
1, // 4: signalexchange.SignalExchange.ConnectStream:input_type -> signalexchange.EncryptedMessage
|
||||||
1, // 5: signalexchange.SignalExchange.ConnectStream:output_type -> signalexchange.EncryptedMessage
|
1, // 5: signalexchange.SignalExchange.Send:output_type -> signalexchange.EncryptedMessage
|
||||||
4, // [4:6] is the sub-list for method output_type
|
1, // 6: signalexchange.SignalExchange.ConnectStream:output_type -> signalexchange.EncryptedMessage
|
||||||
2, // [2:4] is the sub-list for method input_type
|
5, // [5:7] is the sub-list for method output_type
|
||||||
2, // [2:2] is the sub-list for extension type_name
|
3, // [3:5] is the sub-list for method input_type
|
||||||
2, // [2:2] is the sub-list for extension extendee
|
3, // [3:3] is the sub-list for extension type_name
|
||||||
0, // [0:2] is the sub-list for field type_name
|
3, // [3:3] is the sub-list for extension extendee
|
||||||
|
0, // [0:3] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_signalexchange_proto_init() }
|
func init() { file_signalexchange_proto_init() }
|
||||||
@ -402,14 +482,27 @@ func file_signalexchange_proto_init() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
file_signalexchange_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*Mode); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_signalexchange_proto_msgTypes[3].OneofWrappers = []interface{}{}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_signalexchange_proto_rawDesc,
|
RawDescriptor: file_signalexchange_proto_rawDesc,
|
||||||
NumEnums: 1,
|
NumEnums: 1,
|
||||||
NumMessages: 3,
|
NumMessages: 4,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
@ -46,10 +46,20 @@ message Body {
|
|||||||
OFFER = 0;
|
OFFER = 0;
|
||||||
ANSWER = 1;
|
ANSWER = 1;
|
||||||
CANDIDATE = 2;
|
CANDIDATE = 2;
|
||||||
|
MODE = 4;
|
||||||
}
|
}
|
||||||
Type type = 1;
|
Type type = 1;
|
||||||
string payload = 2;
|
string payload = 2;
|
||||||
// wgListenPort is an actual WireGuard listen port
|
// wgListenPort is an actual WireGuard listen port
|
||||||
uint32 wgListenPort = 3;
|
uint32 wgListenPort = 3;
|
||||||
string netBirdVersion = 4;
|
string netBirdVersion = 4;
|
||||||
|
Mode mode = 5;
|
||||||
|
|
||||||
|
// featuresSupported list of supported features by the client of this protocol
|
||||||
|
repeated uint32 featuresSupported = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mode indicates a connection mode
|
||||||
|
message Mode {
|
||||||
|
optional bool direct = 1;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user