mirror of
https://github.com/netbirdio/netbird.git
synced 2024-12-12 18:00:49 +01:00
Initial code
This commit is contained in:
parent
76702c8a09
commit
d67f766b2e
@ -138,6 +138,7 @@ type Engine struct {
|
|||||||
signalProbe *Probe
|
signalProbe *Probe
|
||||||
relayProbe *Probe
|
relayProbe *Probe
|
||||||
wgProbe *Probe
|
wgProbe *Probe
|
||||||
|
turnRelay *relay.PermanentTurn
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peer is an instance of the Connection Peer
|
// Peer is an instance of the Connection Peer
|
||||||
@ -452,10 +453,19 @@ func SignalOfferAnswer(offerAnswer peer.OfferAnswer, myKey wgtypes.Key, remoteKe
|
|||||||
t = sProto.Body_OFFER
|
t = sProto.Body_OFFER
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, err := signal.MarshalCredential(myKey, offerAnswer.WgListenPort, remoteKey, &signal.Credential{
|
msg, err := signal.MarshalCredential(
|
||||||
UFrag: offerAnswer.IceCredentials.UFrag,
|
myKey,
|
||||||
Pwd: offerAnswer.IceCredentials.Pwd,
|
offerAnswer.WgListenPort,
|
||||||
}, t, offerAnswer.RosenpassPubKey, offerAnswer.RosenpassAddr)
|
remoteKey, &signal.Credential{
|
||||||
|
UFrag: offerAnswer.IceCredentials.UFrag,
|
||||||
|
Pwd: offerAnswer.IceCredentials.Pwd,
|
||||||
|
},
|
||||||
|
t,
|
||||||
|
offerAnswer.RosenpassPubKey,
|
||||||
|
offerAnswer.RosenpassAddr,
|
||||||
|
offerAnswer.RelayedAddr.String(),
|
||||||
|
offerAnswer.RemoteAddr.String(),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -483,6 +493,13 @@ func (e *Engine) handleSync(update *mgmProto.SyncResponse) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
turnRelay := relay.NewPermanentTurn(e.STUNs[0], e.TURNs[0])
|
||||||
|
err = turnRelay.Open()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("faile to open turn relay: %w", err)
|
||||||
|
}
|
||||||
|
e.turnRelay = turnRelay
|
||||||
|
|
||||||
// todo update signal
|
// todo update signal
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,6 +620,7 @@ func (e *Engine) updateSTUNs(stuns []*mgmProto.HostConfig) error {
|
|||||||
var newSTUNs []*stun.URI
|
var newSTUNs []*stun.URI
|
||||||
log.Debugf("got STUNs update from Management Service, updating")
|
log.Debugf("got STUNs update from Management Service, updating")
|
||||||
for _, s := range stuns {
|
for _, s := range stuns {
|
||||||
|
log.Debugf("-----updated TURN: %s", s.Uri)
|
||||||
url, err := stun.ParseURI(s.Uri)
|
url, err := stun.ParseURI(s.Uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -621,6 +639,7 @@ func (e *Engine) updateTURNs(turns []*mgmProto.ProtectedHostConfig) error {
|
|||||||
var newTURNs []*stun.URI
|
var newTURNs []*stun.URI
|
||||||
log.Debugf("got TURNs update from Management Service, updating")
|
log.Debugf("got TURNs update from Management Service, updating")
|
||||||
for _, turn := range turns {
|
for _, turn := range turns {
|
||||||
|
log.Debugf("-----updated Turn %v, %s, %s", turn.HostConfig.Uri, turn.User, turn.Password)
|
||||||
url, err := stun.ParseURI(turn.HostConfig.Uri)
|
url, err := stun.ParseURI(turn.HostConfig.Uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -630,7 +649,6 @@ func (e *Engine) updateTURNs(turns []*mgmProto.ProtectedHostConfig) error {
|
|||||||
newTURNs = append(newTURNs, url)
|
newTURNs = append(newTURNs, url)
|
||||||
}
|
}
|
||||||
e.TURNs = newTURNs
|
e.TURNs = newTURNs
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -934,7 +952,7 @@ func (e *Engine) createPeerConn(pubKey string, allowedIPs string) (*peer.Conn, e
|
|||||||
RosenpassAddr: e.getRosenpassAddr(),
|
RosenpassAddr: e.getRosenpassAddr(),
|
||||||
}
|
}
|
||||||
|
|
||||||
peerConn, err := peer.NewConn(config, e.statusRecorder, e.wgProxyFactory, e.mobileDep.TunAdapter, e.mobileDep.IFaceDiscover)
|
peerConn, err := peer.NewConn(config, e.statusRecorder, e.wgProxyFactory, e.mobileDep.TunAdapter, e.mobileDep.IFaceDiscover, e.turnRelay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1000,6 +1018,17 @@ func (e *Engine) receiveSignalEvents() {
|
|||||||
rosenpassPubKey = msg.GetBody().GetRosenpassConfig().GetRosenpassPubKey()
|
rosenpassPubKey = msg.GetBody().GetRosenpassConfig().GetRosenpassPubKey()
|
||||||
rosenpassAddr = msg.GetBody().GetRosenpassConfig().GetRosenpassServerAddr()
|
rosenpassAddr = msg.GetBody().GetRosenpassConfig().GetRosenpassServerAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
relayedAddr, err := net.ResolveUDPAddr("udp", msg.GetBody().GetRelay().GetRelayedAddress())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteAddr, err := net.ResolveUDPAddr("udp", msg.GetBody().GetRelay().GetSrvRefAddress())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
conn.OnRemoteOffer(peer.OfferAnswer{
|
conn.OnRemoteOffer(peer.OfferAnswer{
|
||||||
IceCredentials: peer.IceCredentials{
|
IceCredentials: peer.IceCredentials{
|
||||||
UFrag: remoteCred.UFrag,
|
UFrag: remoteCred.UFrag,
|
||||||
@ -1009,6 +1038,8 @@ func (e *Engine) receiveSignalEvents() {
|
|||||||
Version: msg.GetBody().GetNetBirdVersion(),
|
Version: msg.GetBody().GetNetBirdVersion(),
|
||||||
RosenpassPubKey: rosenpassPubKey,
|
RosenpassPubKey: rosenpassPubKey,
|
||||||
RosenpassAddr: rosenpassAddr,
|
RosenpassAddr: rosenpassAddr,
|
||||||
|
RelayedAddr: relayedAddr,
|
||||||
|
RemoteAddr: remoteAddr,
|
||||||
})
|
})
|
||||||
case sProto.Body_ANSWER:
|
case sProto.Body_ANSWER:
|
||||||
remoteCred, err := signal.UnMarshalCredential(msg)
|
remoteCred, err := signal.UnMarshalCredential(msg)
|
||||||
@ -1024,6 +1055,17 @@ func (e *Engine) receiveSignalEvents() {
|
|||||||
rosenpassPubKey = msg.GetBody().GetRosenpassConfig().GetRosenpassPubKey()
|
rosenpassPubKey = msg.GetBody().GetRosenpassConfig().GetRosenpassPubKey()
|
||||||
rosenpassAddr = msg.GetBody().GetRosenpassConfig().GetRosenpassServerAddr()
|
rosenpassAddr = msg.GetBody().GetRosenpassConfig().GetRosenpassServerAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
relayedAddr, err := net.ResolveUDPAddr("udp", msg.GetBody().GetRelay().GetRelayedAddress())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteAddr, err := net.ResolveUDPAddr("udp", msg.GetBody().GetRelay().GetSrvRefAddress())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
conn.OnRemoteAnswer(peer.OfferAnswer{
|
conn.OnRemoteAnswer(peer.OfferAnswer{
|
||||||
IceCredentials: peer.IceCredentials{
|
IceCredentials: peer.IceCredentials{
|
||||||
UFrag: remoteCred.UFrag,
|
UFrag: remoteCred.UFrag,
|
||||||
@ -1033,6 +1075,8 @@ func (e *Engine) receiveSignalEvents() {
|
|||||||
Version: msg.GetBody().GetNetBirdVersion(),
|
Version: msg.GetBody().GetNetBirdVersion(),
|
||||||
RosenpassPubKey: rosenpassPubKey,
|
RosenpassPubKey: rosenpassPubKey,
|
||||||
RosenpassAddr: rosenpassAddr,
|
RosenpassAddr: rosenpassAddr,
|
||||||
|
RelayedAddr: relayedAddr,
|
||||||
|
RemoteAddr: remoteAddr,
|
||||||
})
|
})
|
||||||
case sProto.Body_CANDIDATE:
|
case sProto.Body_CANDIDATE:
|
||||||
candidate, err := ice.UnmarshalCandidate(msg.GetBody().Payload)
|
candidate, err := ice.UnmarshalCandidate(msg.GetBody().Payload)
|
||||||
@ -1043,7 +1087,6 @@ func (e *Engine) receiveSignalEvents() {
|
|||||||
conn.OnRemoteCandidate(candidate)
|
conn.OnRemoteCandidate(candidate)
|
||||||
case sProto.Body_MODE:
|
case sProto.Body_MODE:
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -14,6 +13,7 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/client/internal/relay"
|
||||||
"github.com/netbirdio/netbird/client/internal/stdnet"
|
"github.com/netbirdio/netbird/client/internal/stdnet"
|
||||||
"github.com/netbirdio/netbird/client/internal/wgproxy"
|
"github.com/netbirdio/netbird/client/internal/wgproxy"
|
||||||
"github.com/netbirdio/netbird/iface"
|
"github.com/netbirdio/netbird/iface"
|
||||||
@ -93,6 +93,10 @@ type OfferAnswer struct {
|
|||||||
// RosenpassAddr is the Rosenpass server address (IP:port) of the remote peer when receiving this message
|
// RosenpassAddr is the Rosenpass server address (IP:port) of the remote peer when receiving this message
|
||||||
// This value is the local Rosenpass server address when sending the message
|
// This value is the local Rosenpass server address when sending the message
|
||||||
RosenpassAddr string
|
RosenpassAddr string
|
||||||
|
|
||||||
|
// Turn Relay
|
||||||
|
RelayedAddr net.Addr
|
||||||
|
RemoteAddr net.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// IceCredentials ICE protocol credentials struct
|
// IceCredentials ICE protocol credentials struct
|
||||||
@ -141,11 +145,11 @@ type Conn struct {
|
|||||||
sentExtraSrflx bool
|
sentExtraSrflx bool
|
||||||
|
|
||||||
remoteEndpoint *net.UDPAddr
|
remoteEndpoint *net.UDPAddr
|
||||||
remoteConn *ice.Conn
|
|
||||||
|
|
||||||
connID nbnet.ConnectionID
|
connID nbnet.ConnectionID
|
||||||
beforeAddPeerHooks []BeforeAddPeerHookFunc
|
beforeAddPeerHooks []BeforeAddPeerHookFunc
|
||||||
afterRemovePeerHooks []AfterRemovePeerHookFunc
|
afterRemovePeerHooks []AfterRemovePeerHookFunc
|
||||||
|
turnRelay *relay.PermanentTurn
|
||||||
}
|
}
|
||||||
|
|
||||||
// meta holds meta information about a connection
|
// meta holds meta information about a connection
|
||||||
@ -176,7 +180,7 @@ func (conn *Conn) UpdateStunTurn(turnStun []*stun.URI) {
|
|||||||
|
|
||||||
// NewConn creates a new not opened Conn to the remote peer.
|
// NewConn creates a new not opened Conn to the remote peer.
|
||||||
// To establish a connection run Conn.Open
|
// To establish a connection run Conn.Open
|
||||||
func NewConn(config ConnConfig, statusRecorder *Status, wgProxyFactory *wgproxy.Factory, adapter iface.TunAdapter, iFaceDiscover stdnet.ExternalIFaceDiscover) (*Conn, error) {
|
func NewConn(config ConnConfig, statusRecorder *Status, wgProxyFactory *wgproxy.Factory, adapter iface.TunAdapter, iFaceDiscover stdnet.ExternalIFaceDiscover, turnRelay *relay.PermanentTurn) (*Conn, error) {
|
||||||
return &Conn{
|
return &Conn{
|
||||||
config: config,
|
config: config,
|
||||||
mu: sync.Mutex{},
|
mu: sync.Mutex{},
|
||||||
@ -189,6 +193,7 @@ func NewConn(config ConnConfig, statusRecorder *Status, wgProxyFactory *wgproxy.
|
|||||||
wgProxyFactory: wgProxyFactory,
|
wgProxyFactory: wgProxyFactory,
|
||||||
adapter: adapter,
|
adapter: adapter,
|
||||||
iFaceDiscover: iFaceDiscover,
|
iFaceDiscover: iFaceDiscover,
|
||||||
|
turnRelay: turnRelay,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +217,7 @@ func (conn *Conn) reCreateAgent() error {
|
|||||||
MulticastDNSMode: ice.MulticastDNSModeDisabled,
|
MulticastDNSMode: ice.MulticastDNSModeDisabled,
|
||||||
NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4, ice.NetworkTypeUDP6},
|
NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4, ice.NetworkTypeUDP6},
|
||||||
Urls: conn.config.StunTurn,
|
Urls: conn.config.StunTurn,
|
||||||
CandidateTypes: conn.candidateTypes(),
|
CandidateTypes: []ice.CandidateType{},
|
||||||
FailedTimeout: &failedTimeout,
|
FailedTimeout: &failedTimeout,
|
||||||
InterfaceFilter: stdnet.InterfaceFilter(conn.config.InterfaceBlackList),
|
InterfaceFilter: stdnet.InterfaceFilter(conn.config.InterfaceBlackList),
|
||||||
UDPMux: conn.config.UDPMux,
|
UDPMux: conn.config.UDPMux,
|
||||||
@ -262,17 +267,6 @@ func (conn *Conn) reCreateAgent() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (conn *Conn) candidateTypes() []ice.CandidateType {
|
|
||||||
if hasICEForceRelayConn() {
|
|
||||||
return []ice.CandidateType{ice.CandidateTypeRelay}
|
|
||||||
}
|
|
||||||
// TODO: remove this once we have refactored userspace proxy into the bind package
|
|
||||||
if runtime.GOOS == "ios" {
|
|
||||||
return []ice.CandidateType{ice.CandidateTypeHost, ice.CandidateTypeServerReflexive}
|
|
||||||
}
|
|
||||||
return []ice.CandidateType{ice.CandidateTypeHost, ice.CandidateTypeServerReflexive, ice.CandidateTypeRelay}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open opens connection to the remote peer starting ICE candidate gathering process.
|
// Open opens connection to the remote peer starting ICE candidate gathering process.
|
||||||
// Blocks until connection has been closed or connection timeout.
|
// Blocks until connection has been closed or connection timeout.
|
||||||
// ConnStatus will be set accordingly
|
// ConnStatus will be set accordingly
|
||||||
@ -351,23 +345,12 @@ func (conn *Conn) Open() error {
|
|||||||
log.Warnf("error while updating the state of peer %s,err: %v", conn.config.Key, err)
|
log.Warnf("error while updating the state of peer %s,err: %v", conn.config.Key, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = conn.agent.GatherCandidates()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// will block until connection succeeded
|
|
||||||
// but it won't release if ICE Agent went into Disconnected or Failed state,
|
|
||||||
// so we have to cancel it with the provided context once agent detected a broken connection
|
|
||||||
isControlling := conn.config.LocalKey > conn.config.Key
|
isControlling := conn.config.LocalKey > conn.config.Key
|
||||||
var remoteConn *ice.Conn
|
|
||||||
if isControlling {
|
if isControlling {
|
||||||
remoteConn, err = conn.agent.Dial(conn.ctx, remoteOfferAnswer.IceCredentials.UFrag, remoteOfferAnswer.IceCredentials.Pwd)
|
err = conn.turnRelay.PunchHole(remoteOfferAnswer.RemoteAddr)
|
||||||
} else {
|
if err != nil {
|
||||||
remoteConn, err = conn.agent.Accept(conn.ctx, remoteOfferAnswer.IceCredentials.UFrag, remoteOfferAnswer.IceCredentials.Pwd)
|
log.Errorf("failed to punch hole: %v", err)
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dynamically set remote WireGuard port is other side specified a different one from the default one
|
// dynamically set remote WireGuard port is other side specified a different one from the default one
|
||||||
@ -376,7 +359,11 @@ func (conn *Conn) Open() error {
|
|||||||
remoteWgPort = remoteOfferAnswer.WgListenPort
|
remoteWgPort = remoteOfferAnswer.WgListenPort
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.remoteConn = remoteConn
|
// todo configure the wg with proper address
|
||||||
|
remoteConn, err := net.Dial("udp", remoteOfferAnswer.RemoteAddr.String())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to dial remote peer %s: %v", conn.config.Key, err)
|
||||||
|
}
|
||||||
|
|
||||||
// the ice connection has been established successfully so we are ready to start the proxy
|
// the ice connection has been established successfully so we are ready to start the proxy
|
||||||
remoteAddr, err := conn.configureConnection(remoteConn, remoteWgPort, remoteOfferAnswer.RosenpassPubKey,
|
remoteAddr, err := conn.configureConnection(remoteConn, remoteWgPort, remoteOfferAnswer.RosenpassPubKey,
|
||||||
@ -415,25 +402,14 @@ func (conn *Conn) configureConnection(remoteConn net.Conn, remoteWgPort int, rem
|
|||||||
conn.mu.Lock()
|
conn.mu.Lock()
|
||||||
defer conn.mu.Unlock()
|
defer conn.mu.Unlock()
|
||||||
|
|
||||||
pair, err := conn.agent.GetSelectedCandidatePair()
|
var endpoint net.Addr
|
||||||
|
log.Debugf("setup relay connection")
|
||||||
|
conn.wgProxy = conn.wgProxyFactory.GetProxy()
|
||||||
|
endpoint, err := conn.wgProxy.AddTurnConn(remoteConn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var endpoint net.Addr
|
|
||||||
if isRelayCandidate(pair.Local) {
|
|
||||||
log.Debugf("setup relay connection")
|
|
||||||
conn.wgProxy = conn.wgProxyFactory.GetProxy()
|
|
||||||
endpoint, err = conn.wgProxy.AddTurnConn(remoteConn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// To support old version's with direct mode we attempt to punch an additional role with the remote WireGuard port
|
|
||||||
go conn.punchRemoteWGPort(pair, remoteWgPort)
|
|
||||||
endpoint = remoteConn.RemoteAddr()
|
|
||||||
}
|
|
||||||
|
|
||||||
endpointUdpAddr, _ := net.ResolveUDPAddr(endpoint.Network(), endpoint.String())
|
endpointUdpAddr, _ := net.ResolveUDPAddr(endpoint.Network(), endpoint.String())
|
||||||
conn.remoteEndpoint = endpointUdpAddr
|
conn.remoteEndpoint = endpointUdpAddr
|
||||||
log.Debugf("Conn resolved IP for %s: %s", endpoint, endpointUdpAddr.IP)
|
log.Debugf("Conn resolved IP for %s: %s", endpoint, endpointUdpAddr.IP)
|
||||||
@ -454,31 +430,33 @@ func (conn *Conn) configureConnection(remoteConn net.Conn, remoteWgPort int, rem
|
|||||||
}
|
}
|
||||||
|
|
||||||
conn.status = StatusConnected
|
conn.status = StatusConnected
|
||||||
rosenpassEnabled := false
|
/*
|
||||||
if remoteRosenpassPubKey != nil {
|
rosenpassEnabled := false
|
||||||
rosenpassEnabled = true
|
if remoteRosenpassPubKey != nil {
|
||||||
}
|
rosenpassEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
peerState := State{
|
peerState := State{
|
||||||
PubKey: conn.config.Key,
|
PubKey: conn.config.Key,
|
||||||
ConnStatus: conn.status,
|
ConnStatus: conn.status,
|
||||||
ConnStatusUpdate: time.Now(),
|
ConnStatusUpdate: time.Now(),
|
||||||
LocalIceCandidateType: pair.Local.Type().String(),
|
LocalIceCandidateType: pair.Local.Type().String(),
|
||||||
RemoteIceCandidateType: pair.Remote.Type().String(),
|
RemoteIceCandidateType: pair.Remote.Type().String(),
|
||||||
LocalIceCandidateEndpoint: fmt.Sprintf("%s:%d", pair.Local.Address(), pair.Local.Port()),
|
LocalIceCandidateEndpoint: fmt.Sprintf("%s:%d", pair.Local.Address(), pair.Local.Port()),
|
||||||
RemoteIceCandidateEndpoint: fmt.Sprintf("%s:%d", pair.Remote.Address(), pair.Local.Port()),
|
RemoteIceCandidateEndpoint: fmt.Sprintf("%s:%d", pair.Remote.Address(), pair.Local.Port()),
|
||||||
Direct: !isRelayCandidate(pair.Local),
|
Direct: !isRelayCandidate(pair.Local),
|
||||||
RosenpassEnabled: rosenpassEnabled,
|
RosenpassEnabled: rosenpassEnabled,
|
||||||
Mux: new(sync.RWMutex),
|
Mux: new(sync.RWMutex),
|
||||||
}
|
}
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
err = conn.statusRecorder.UpdatePeerState(peerState)
|
err = conn.statusRecorder.UpdatePeerState(peerState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("unable to save peer's state, got error: %v", err)
|
log.Warnf("unable to save peer's state, got error: %v", err)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
_, ipNet, err := net.ParseCIDR(conn.config.WgConfig.AllowedIps)
|
_, ipNet, err := net.ParseCIDR(conn.config.WgConfig.AllowedIps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -680,6 +658,8 @@ func (conn *Conn) sendAnswer() error {
|
|||||||
Version: version.NetbirdVersion(),
|
Version: version.NetbirdVersion(),
|
||||||
RosenpassPubKey: conn.config.RosenpassPubKey,
|
RosenpassPubKey: conn.config.RosenpassPubKey,
|
||||||
RosenpassAddr: conn.config.RosenpassAddr,
|
RosenpassAddr: conn.config.RosenpassAddr,
|
||||||
|
RelayedAddr: conn.turnRelay.RelayedAddress(),
|
||||||
|
RemoteAddr: conn.turnRelay.SrvRefAddr(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -703,6 +683,8 @@ func (conn *Conn) sendOffer() error {
|
|||||||
Version: version.NetbirdVersion(),
|
Version: version.NetbirdVersion(),
|
||||||
RosenpassPubKey: conn.config.RosenpassPubKey,
|
RosenpassPubKey: conn.config.RosenpassPubKey,
|
||||||
RosenpassAddr: conn.config.RosenpassAddr,
|
RosenpassAddr: conn.config.RosenpassAddr,
|
||||||
|
RelayedAddr: conn.turnRelay.RelayedAddress(),
|
||||||
|
RemoteAddr: conn.turnRelay.SrvRefAddr(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -742,6 +724,10 @@ func (conn *Conn) Status() ConnStatus {
|
|||||||
return conn.status
|
return conn.status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (conn *Conn) OnRemoteRelayRequest(relayedAddr string, remoteIP string) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// OnRemoteOffer handles an offer from the remote peer and returns true if the message was accepted, false otherwise
|
// OnRemoteOffer handles an offer from the remote peer and returns true if the message was accepted, false otherwise
|
||||||
// doesn't block, discards the message if connection wasn't ready
|
// doesn't block, discards the message if connection wasn't ready
|
||||||
func (conn *Conn) OnRemoteOffer(offer OfferAnswer) bool {
|
func (conn *Conn) OnRemoteOffer(offer OfferAnswer) bool {
|
||||||
|
129
client/internal/relay/turn.go
Normal file
129
client/internal/relay/turn.go
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package relay
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/pion/logging"
|
||||||
|
"github.com/pion/stun/v2"
|
||||||
|
"github.com/pion/turn/v3"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PermanentTurn struct {
|
||||||
|
stunURI *stun.URI
|
||||||
|
turnURI *stun.URI
|
||||||
|
|
||||||
|
stunConn net.PacketConn
|
||||||
|
turnClient *turn.Client
|
||||||
|
turnClientListenLock sync.Mutex
|
||||||
|
relayConn net.PacketConn // represents the remote socket.
|
||||||
|
srvReflexiveAddress *net.UDPAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPermanentTurn(stunURL, turnURL *stun.URI) *PermanentTurn {
|
||||||
|
return &PermanentTurn{
|
||||||
|
stunURI: stunURL,
|
||||||
|
turnURI: turnURL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PermanentTurn) Open() error {
|
||||||
|
stunConn, err := net.ListenPacket("udp4", "0.0.0.0:0")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.stunConn = stunConn
|
||||||
|
|
||||||
|
cfg := &turn.ClientConfig{
|
||||||
|
STUNServerAddr: toURL(r.stunURI),
|
||||||
|
TURNServerAddr: toURL(r.turnURI),
|
||||||
|
Conn: stunConn,
|
||||||
|
Username: r.turnURI.Username,
|
||||||
|
Password: r.turnURI.Password,
|
||||||
|
LoggerFactory: logging.NewDefaultLoggerFactory(),
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := turn.NewClient(cfg)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to create turn client: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.turnClient = client
|
||||||
|
r.listen()
|
||||||
|
|
||||||
|
relayConn, err := client.Allocate()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to allocate relay connection: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.relayConn = relayConn
|
||||||
|
|
||||||
|
srvReflexiveAddress, err := r.discoverPublicIP()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to discover public IP: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.srvReflexiveAddress = srvReflexiveAddress
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PermanentTurn) RelayedAddress() net.Addr {
|
||||||
|
return r.relayConn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PermanentTurn) SrvRefAddr() net.Addr {
|
||||||
|
return r.srvReflexiveAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PermanentTurn) discoverPublicIP() (*net.UDPAddr, error) {
|
||||||
|
addr, err := r.turnClient.SendBindingRequest()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to send binding request: %v", err)
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
udpAddr, ok := addr.(*net.UDPAddr)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("failed to cast addr to udp addr")
|
||||||
|
}
|
||||||
|
|
||||||
|
return udpAddr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PermanentTurn) listen() {
|
||||||
|
if !r.turnClientListenLock.TryLock() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer r.turnClientListenLock.Unlock()
|
||||||
|
|
||||||
|
buf := make([]byte, math.MaxUint16)
|
||||||
|
for {
|
||||||
|
n, from, err := r.stunConn.ReadFrom(buf)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to read from stun conn. Exiting loop %v", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = r.turnClient.HandleInbound(buf[:n], from)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to handle inbound turn message: %s. Exiting loop", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PermanentTurn) PunchHole(mappedAddr net.Addr) error {
|
||||||
|
_, err := r.relayConn.WriteTo([]byte("Hello"), mappedAddr)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func toURL(uri *stun.URI) string {
|
||||||
|
return fmt.Sprintf("%s:%d", uri.Host, uri.Port)
|
||||||
|
}
|
36
client/internal/relay/turn_test.go
Normal file
36
client/internal/relay/turn_test.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package relay
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pion/stun/v2"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
_ = util.InitLog("trace", "console")
|
||||||
|
code := m.Run()
|
||||||
|
os.Exit(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewPermanentTurn(t *testing.T) {
|
||||||
|
turnURI, err := stun.ParseURI("turns:turn.netbird.io:443?transport=tcp")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to parse stun url: %v", err)
|
||||||
|
}
|
||||||
|
turnURI.Username = "1713006060"
|
||||||
|
turnURI.Password = "pO5Pfx15luZ92mW+FHPa6/LtJ7Y="
|
||||||
|
|
||||||
|
stunURI, err := stun.ParseURI("stun:stun.netbird.io:5555")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to parse stun url: %v", err)
|
||||||
|
}
|
||||||
|
turnRelay := NewPermanentTurn(stunURI, turnURI)
|
||||||
|
err = turnRelay.Open()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to open turn relay: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -56,7 +56,7 @@ 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, myPort int, remoteKey wgtypes.Key, credential *Credential, t proto.Body_Type,
|
func MarshalCredential(myKey wgtypes.Key, myPort int, remoteKey wgtypes.Key, credential *Credential, t proto.Body_Type,
|
||||||
rosenpassPubKey []byte, rosenpassAddr string) (*proto.Message, error) {
|
rosenpassPubKey []byte, rosenpassAddr, relayedAddress, serverRefIP string) (*proto.Message, error) {
|
||||||
return &proto.Message{
|
return &proto.Message{
|
||||||
Key: myKey.PublicKey().String(),
|
Key: myKey.PublicKey().String(),
|
||||||
RemoteKey: remoteKey.String(),
|
RemoteKey: remoteKey.String(),
|
||||||
@ -69,6 +69,10 @@ func MarshalCredential(myKey wgtypes.Key, myPort int, remoteKey wgtypes.Key, cre
|
|||||||
RosenpassPubKey: rosenpassPubKey,
|
RosenpassPubKey: rosenpassPubKey,
|
||||||
RosenpassServerAddr: rosenpassAddr,
|
RosenpassServerAddr: rosenpassAddr,
|
||||||
},
|
},
|
||||||
|
Relay: &proto.Relay{
|
||||||
|
RelayedAddress: relayedAddress,
|
||||||
|
SrvRefAddress: serverRefIP,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -215,16 +215,21 @@ type Body struct {
|
|||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Type Body_Type `protobuf:"varint,1,opt,name=type,proto3,enum=signalexchange.Body_Type" json:"type,omitempty"`
|
Type Body_Type `protobuf:"varint,1,opt,name=type,proto3,enum=signalexchange.Body_Type" json:"type,omitempty"`
|
||||||
Payload string `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"`
|
// these will be set in OFFER, ANSWER, CANDIDATE only
|
||||||
|
Payload string `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||||
// 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"`
|
// these will be set in OFFER, ANSWER, CANDIDATE only
|
||||||
|
WgListenPort uint32 `protobuf:"varint,3,opt,name=wgListenPort,proto3" json:"wgListenPort,omitempty"`
|
||||||
|
// these will be set in OFFER, ANSWER, CANDIDATE only
|
||||||
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"`
|
Mode *Mode `protobuf:"bytes,5,opt,name=mode,proto3" json:"mode,omitempty"`
|
||||||
// featuresSupported list of supported features by the client of this protocol
|
// featuresSupported list of supported features by the client of this protocol
|
||||||
FeaturesSupported []uint32 `protobuf:"varint,6,rep,packed,name=featuresSupported,proto3" json:"featuresSupported,omitempty"`
|
FeaturesSupported []uint32 `protobuf:"varint,6,rep,packed,name=featuresSupported,proto3" json:"featuresSupported,omitempty"`
|
||||||
// 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
|
||||||
|
// is this optional or mandatory?
|
||||||
RosenpassConfig *RosenpassConfig `protobuf:"bytes,7,opt,name=rosenpassConfig,proto3" json:"rosenpassConfig,omitempty"`
|
RosenpassConfig *RosenpassConfig `protobuf:"bytes,7,opt,name=rosenpassConfig,proto3" json:"rosenpassConfig,omitempty"`
|
||||||
|
Relay *Relay `protobuf:"bytes,8,opt,name=relay,proto3" json:"relay,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Body) Reset() {
|
func (x *Body) Reset() {
|
||||||
@ -308,13 +313,18 @@ func (x *Body) GetRosenpassConfig() *RosenpassConfig {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Body) GetRelay() *Relay {
|
||||||
|
if x != nil {
|
||||||
|
return x.Relay
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Mode indicates a connection mode
|
// Mode indicates a connection mode
|
||||||
type Mode struct {
|
type Mode struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Direct *bool `protobuf:"varint,1,opt,name=direct,proto3,oneof" json:"direct,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Mode) Reset() {
|
func (x *Mode) Reset() {
|
||||||
@ -349,11 +359,59 @@ func (*Mode) Descriptor() ([]byte, []int) {
|
|||||||
return file_signalexchange_proto_rawDescGZIP(), []int{3}
|
return file_signalexchange_proto_rawDescGZIP(), []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Mode) GetDirect() bool {
|
type Relay struct {
|
||||||
if x != nil && x.Direct != nil {
|
state protoimpl.MessageState
|
||||||
return *x.Direct
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
RelayedAddress string `protobuf:"bytes,1,opt,name=relayedAddress,proto3" json:"relayedAddress,omitempty"`
|
||||||
|
SrvRefAddress string `protobuf:"bytes,2,opt,name=srvRefAddress,proto3" json:"srvRefAddress,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Relay) Reset() {
|
||||||
|
*x = Relay{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_signalexchange_proto_msgTypes[4]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
return false
|
}
|
||||||
|
|
||||||
|
func (x *Relay) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Relay) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *Relay) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_signalexchange_proto_msgTypes[4]
|
||||||
|
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 Relay.ProtoReflect.Descriptor instead.
|
||||||
|
func (*Relay) Descriptor() ([]byte, []int) {
|
||||||
|
return file_signalexchange_proto_rawDescGZIP(), []int{4}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Relay) GetRelayedAddress() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.RelayedAddress
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Relay) GetSrvRefAddress() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.SrvRefAddress
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
type RosenpassConfig struct {
|
type RosenpassConfig struct {
|
||||||
@ -369,7 +427,7 @@ type RosenpassConfig struct {
|
|||||||
func (x *RosenpassConfig) Reset() {
|
func (x *RosenpassConfig) Reset() {
|
||||||
*x = RosenpassConfig{}
|
*x = RosenpassConfig{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_signalexchange_proto_msgTypes[4]
|
mi := &file_signalexchange_proto_msgTypes[5]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -382,7 +440,7 @@ func (x *RosenpassConfig) String() string {
|
|||||||
func (*RosenpassConfig) ProtoMessage() {}
|
func (*RosenpassConfig) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *RosenpassConfig) ProtoReflect() protoreflect.Message {
|
func (x *RosenpassConfig) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_signalexchange_proto_msgTypes[4]
|
mi := &file_signalexchange_proto_msgTypes[5]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -395,7 +453,7 @@ func (x *RosenpassConfig) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use RosenpassConfig.ProtoReflect.Descriptor instead.
|
// Deprecated: Use RosenpassConfig.ProtoReflect.Descriptor instead.
|
||||||
func (*RosenpassConfig) Descriptor() ([]byte, []int) {
|
func (*RosenpassConfig) Descriptor() ([]byte, []int) {
|
||||||
return file_signalexchange_proto_rawDescGZIP(), []int{4}
|
return file_signalexchange_proto_rawDescGZIP(), []int{5}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RosenpassConfig) GetRosenpassPubKey() []byte {
|
func (x *RosenpassConfig) GetRosenpassPubKey() []byte {
|
||||||
@ -431,7 +489,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, 0xf6, 0x02, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x2d,
|
0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0xa3, 0x03, 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,
|
||||||
@ -451,33 +509,39 @@ 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, 0x22, 0x36, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09,
|
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x0a, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18,
|
||||||
0x0a, 0x05, 0x4f, 0x46, 0x46, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x4e, 0x53,
|
0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78,
|
||||||
0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x44, 0x49, 0x44, 0x41,
|
0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x05, 0x72, 0x65,
|
||||||
0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x04, 0x22, 0x2e,
|
0x6c, 0x61, 0x79, 0x22, 0x36, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x4f,
|
||||||
0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
|
0x46, 0x46, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x4e, 0x53, 0x57, 0x45, 0x52,
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
|
0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x44, 0x49, 0x44, 0x41, 0x54, 0x45, 0x10,
|
||||||
0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0x6d,
|
0x02, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x04, 0x22, 0x06, 0x0a, 0x04, 0x4d,
|
||||||
0x0a, 0x0f, 0x52, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
0x6f, 0x64, 0x65, 0x22, 0x55, 0x0a, 0x05, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x26, 0x0a, 0x0e,
|
||||||
0x67, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x50, 0x75,
|
0x72, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01,
|
||||||
0x62, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x72, 0x6f, 0x73, 0x65,
|
0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x41, 0x64, 0x64,
|
||||||
0x6e, 0x70, 0x61, 0x73, 0x73, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x72,
|
0x72, 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x52, 0x65, 0x66, 0x41, 0x64,
|
||||||
0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64,
|
0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x72, 0x76,
|
||||||
0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70,
|
0x52, 0x65, 0x66, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x6d, 0x0a, 0x0f, 0x52, 0x6f,
|
||||||
0x61, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x32, 0xb9, 0x01,
|
0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a,
|
||||||
0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65,
|
0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79,
|
||||||
0x12, 0x4c, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61,
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73,
|
||||||
0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70,
|
0x73, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x72, 0x6f, 0x73, 0x65, 0x6e,
|
||||||
0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67,
|
0x70, 0x61, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x18, 0x02,
|
||||||
0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72,
|
0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x53,
|
||||||
0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x59,
|
0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x32, 0xb9, 0x01, 0x0a, 0x0e, 0x53, 0x69,
|
||||||
0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12,
|
0x67, 0x6e, 0x61, 0x6c, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x4c, 0x0a, 0x04,
|
||||||
0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65,
|
0x53, 0x65, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63,
|
||||||
0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d,
|
||||||
0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e,
|
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65,
|
||||||
0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73,
|
0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65,
|
||||||
0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72,
|
0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0d, 0x43, 0x6f,
|
||||||
0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x53, 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, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 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, 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 (
|
||||||
@ -493,29 +557,31 @@ 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, 5)
|
var file_signalexchange_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||||
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
|
(*Mode)(nil), // 4: signalexchange.Mode
|
||||||
(*RosenpassConfig)(nil), // 5: signalexchange.RosenpassConfig
|
(*Relay)(nil), // 5: signalexchange.Relay
|
||||||
|
(*RosenpassConfig)(nil), // 6: signalexchange.RosenpassConfig
|
||||||
}
|
}
|
||||||
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
|
||||||
4, // 2: signalexchange.Body.mode:type_name -> signalexchange.Mode
|
4, // 2: signalexchange.Body.mode:type_name -> signalexchange.Mode
|
||||||
5, // 3: signalexchange.Body.rosenpassConfig:type_name -> signalexchange.RosenpassConfig
|
6, // 3: signalexchange.Body.rosenpassConfig:type_name -> signalexchange.RosenpassConfig
|
||||||
1, // 4: signalexchange.SignalExchange.Send:input_type -> signalexchange.EncryptedMessage
|
5, // 4: signalexchange.Body.relay:type_name -> signalexchange.Relay
|
||||||
1, // 5: signalexchange.SignalExchange.ConnectStream:input_type -> signalexchange.EncryptedMessage
|
1, // 5: signalexchange.SignalExchange.Send:input_type -> signalexchange.EncryptedMessage
|
||||||
1, // 6: signalexchange.SignalExchange.Send:output_type -> signalexchange.EncryptedMessage
|
1, // 6: signalexchange.SignalExchange.ConnectStream:input_type -> signalexchange.EncryptedMessage
|
||||||
1, // 7: signalexchange.SignalExchange.ConnectStream:output_type -> signalexchange.EncryptedMessage
|
1, // 7: signalexchange.SignalExchange.Send:output_type -> signalexchange.EncryptedMessage
|
||||||
6, // [6:8] is the sub-list for method output_type
|
1, // 8: signalexchange.SignalExchange.ConnectStream:output_type -> signalexchange.EncryptedMessage
|
||||||
4, // [4:6] is the sub-list for method input_type
|
7, // [7:9] is the sub-list for method output_type
|
||||||
4, // [4:4] is the sub-list for extension type_name
|
5, // [5:7] is the sub-list for method input_type
|
||||||
4, // [4:4] is the sub-list for extension extendee
|
5, // [5:5] is the sub-list for extension type_name
|
||||||
0, // [0:4] is the sub-list for field type_name
|
5, // [5:5] is the sub-list for extension extendee
|
||||||
|
0, // [0:5] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_signalexchange_proto_init() }
|
func init() { file_signalexchange_proto_init() }
|
||||||
@ -573,6 +639,18 @@ func file_signalexchange_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_signalexchange_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
file_signalexchange_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*Relay); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_signalexchange_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*RosenpassConfig); i {
|
switch v := v.(*RosenpassConfig); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
@ -585,14 +663,13 @@ func file_signalexchange_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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: 5,
|
NumMessages: 6,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
@ -49,22 +49,33 @@ message Body {
|
|||||||
MODE = 4;
|
MODE = 4;
|
||||||
}
|
}
|
||||||
Type type = 1;
|
Type type = 1;
|
||||||
|
// these will be set in OFFER, ANSWER, CANDIDATE only
|
||||||
string payload = 2;
|
string payload = 2;
|
||||||
// wgListenPort is an actual WireGuard listen port
|
// wgListenPort is an actual WireGuard listen port
|
||||||
|
// these will be set in OFFER, ANSWER, CANDIDATE only
|
||||||
uint32 wgListenPort = 3;
|
uint32 wgListenPort = 3;
|
||||||
|
// these will be set in OFFER, ANSWER, CANDIDATE only
|
||||||
string netBirdVersion = 4;
|
string netBirdVersion = 4;
|
||||||
|
|
||||||
Mode mode = 5;
|
Mode mode = 5;
|
||||||
|
|
||||||
// featuresSupported list of supported features by the client of this protocol
|
// featuresSupported list of supported features by the client of this protocol
|
||||||
repeated uint32 featuresSupported = 6;
|
repeated uint32 featuresSupported = 6;
|
||||||
|
|
||||||
// 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
|
||||||
|
// is this optional or mandatory?
|
||||||
RosenpassConfig rosenpassConfig = 7;
|
RosenpassConfig rosenpassConfig = 7;
|
||||||
|
|
||||||
|
Relay relay = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mode indicates a connection mode
|
// Mode indicates a connection mode
|
||||||
message Mode {
|
message Mode {
|
||||||
optional bool direct = 1;
|
}
|
||||||
|
|
||||||
|
message Relay {
|
||||||
|
string relayedAddress = 1;
|
||||||
|
string srvRefAddress = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RosenpassConfig {
|
message RosenpassConfig {
|
||||||
|
Loading…
Reference in New Issue
Block a user