2022-01-10 18:43:13 +01:00
|
|
|
package internal
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2022-11-07 15:38:21 +01:00
|
|
|
"github.com/netbirdio/netbird/client/internal/dns"
|
2022-09-05 09:06:35 +02:00
|
|
|
"github.com/netbirdio/netbird/client/internal/routemanager"
|
2022-06-23 17:04:53 +02:00
|
|
|
"github.com/netbirdio/netbird/client/ssh"
|
2022-07-02 12:02:17 +02:00
|
|
|
nbstatus "github.com/netbirdio/netbird/client/status"
|
2022-11-07 15:38:21 +01:00
|
|
|
nbdns "github.com/netbirdio/netbird/dns"
|
2022-06-23 17:04:53 +02:00
|
|
|
"github.com/netbirdio/netbird/iface"
|
2022-09-05 09:06:35 +02:00
|
|
|
"github.com/netbirdio/netbird/route"
|
2022-06-23 17:04:53 +02:00
|
|
|
"github.com/stretchr/testify/assert"
|
2022-02-08 18:03:27 +01:00
|
|
|
"net"
|
2022-09-05 09:06:35 +02:00
|
|
|
"net/netip"
|
2022-02-08 18:03:27 +01:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
2022-06-04 19:41:01 +02:00
|
|
|
"strings"
|
2022-02-08 18:03:27 +01:00
|
|
|
"sync"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2022-03-26 12:08:54 +01:00
|
|
|
"github.com/netbirdio/netbird/client/system"
|
|
|
|
mgmt "github.com/netbirdio/netbird/management/client"
|
|
|
|
mgmtProto "github.com/netbirdio/netbird/management/proto"
|
|
|
|
"github.com/netbirdio/netbird/management/server"
|
|
|
|
signal "github.com/netbirdio/netbird/signal/client"
|
|
|
|
"github.com/netbirdio/netbird/signal/proto"
|
|
|
|
signalServer "github.com/netbirdio/netbird/signal/server"
|
|
|
|
"github.com/netbirdio/netbird/util"
|
2022-01-10 18:43:13 +01:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/keepalive"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
kaep = keepalive.EnforcementPolicy{
|
|
|
|
MinTime: 15 * time.Second,
|
|
|
|
PermitWithoutStream: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
kasp = keepalive.ServerParameters{
|
|
|
|
MaxConnectionIdle: 15 * time.Second,
|
|
|
|
MaxConnectionAgeGrace: 5 * time.Second,
|
|
|
|
Time: 5 * time.Second,
|
|
|
|
Timeout: 2 * time.Second,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2022-06-23 17:04:53 +02:00
|
|
|
func TestEngine_SSH(t *testing.T) {
|
|
|
|
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
t.Skip("skipping TestEngine_SSH on Windows")
|
|
|
|
}
|
|
|
|
|
|
|
|
key, err := wgtypes.GeneratePrivateKey()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
engine := NewEngine(ctx, cancel, &signal.MockClient{}, &mgmt.MockClient{}, &EngineConfig{
|
|
|
|
WgIfaceName: "utun101",
|
|
|
|
WgAddr: "100.64.0.1/24",
|
|
|
|
WgPrivateKey: key,
|
|
|
|
WgPort: 33100,
|
2022-07-02 12:02:17 +02:00
|
|
|
}, nbstatus.NewRecorder())
|
2022-06-23 17:04:53 +02:00
|
|
|
|
2022-11-29 11:49:18 +01:00
|
|
|
engine.dnsServer = &dns.MockServer{
|
|
|
|
UpdateDNSServerFunc: func(serial uint64, update nbdns.Config) error { return nil },
|
|
|
|
}
|
|
|
|
|
2022-06-23 17:04:53 +02:00
|
|
|
var sshKeysAdded []string
|
|
|
|
var sshPeersRemoved []string
|
|
|
|
|
|
|
|
sshCtx, cancel := context.WithCancel(context.Background())
|
|
|
|
|
|
|
|
engine.sshServerFunc = func(hostKeyPEM []byte, addr string) (ssh.Server, error) {
|
|
|
|
return &ssh.MockServer{
|
|
|
|
Ctx: sshCtx,
|
|
|
|
StopFunc: func() error {
|
|
|
|
cancel()
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
StartFunc: func() error {
|
|
|
|
<-ctx.Done()
|
|
|
|
return ctx.Err()
|
|
|
|
},
|
|
|
|
AddAuthorizedKeyFunc: func(peer, newKey string) error {
|
|
|
|
sshKeysAdded = append(sshKeysAdded, newKey)
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
RemoveAuthorizedKeyFunc: func(peer string) {
|
|
|
|
sshPeersRemoved = append(sshPeersRemoved, peer)
|
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
err = engine.Start()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
err := engine.Stop()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
peerWithSSH := &mgmtProto.RemotePeerConfig{
|
|
|
|
WgPubKey: "MNHf3Ma6z6mdLbriAJbqhX7+nM/B71lgw2+91q3LfhU=",
|
|
|
|
AllowedIps: []string{"100.64.0.21/24"},
|
|
|
|
SshConfig: &mgmtProto.SSHConfig{
|
|
|
|
SshPubKey: []byte("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFATYCqaQw/9id1Qkq3n16JYhDhXraI6Pc1fgB8ynEfQ"),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
// SSH server is not enabled so SSH config of a remote peer should be ignored
|
|
|
|
networkMap := &mgmtProto.NetworkMap{
|
|
|
|
Serial: 6,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{peerWithSSH},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = engine.updateNetworkMap(networkMap)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Nil(t, engine.sshServer)
|
|
|
|
|
|
|
|
// SSH server is enabled, therefore SSH config should be applied
|
|
|
|
networkMap = &mgmtProto.NetworkMap{
|
|
|
|
Serial: 7,
|
|
|
|
PeerConfig: &mgmtProto.PeerConfig{Address: "100.64.0.1/24",
|
|
|
|
SshConfig: &mgmtProto.SSHConfig{SshEnabled: true}},
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{peerWithSSH},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = engine.updateNetworkMap(networkMap)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
time.Sleep(250 * time.Millisecond)
|
|
|
|
assert.NotNil(t, engine.sshServer)
|
|
|
|
assert.Contains(t, sshKeysAdded, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFATYCqaQw/9id1Qkq3n16JYhDhXraI6Pc1fgB8ynEfQ")
|
|
|
|
|
|
|
|
// now remove peer
|
|
|
|
networkMap = &mgmtProto.NetworkMap{
|
|
|
|
Serial: 8,
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = engine.updateNetworkMap(networkMap)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
//time.Sleep(250 * time.Millisecond)
|
|
|
|
assert.NotNil(t, engine.sshServer)
|
|
|
|
assert.Contains(t, sshPeersRemoved, "MNHf3Ma6z6mdLbriAJbqhX7+nM/B71lgw2+91q3LfhU=")
|
|
|
|
|
|
|
|
// now disable SSH server
|
|
|
|
networkMap = &mgmtProto.NetworkMap{
|
|
|
|
Serial: 9,
|
|
|
|
PeerConfig: &mgmtProto.PeerConfig{Address: "100.64.0.1/24",
|
|
|
|
SshConfig: &mgmtProto.SSHConfig{SshEnabled: false}},
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{peerWithSSH},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = engine.updateNetworkMap(networkMap)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Nil(t, engine.sshServer)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-01-18 16:44:58 +01:00
|
|
|
func TestEngine_UpdateNetworkMap(t *testing.T) {
|
|
|
|
// test setup
|
|
|
|
key, err := wgtypes.GeneratePrivateKey()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
2022-03-08 14:47:55 +01:00
|
|
|
engine := NewEngine(ctx, cancel, &signal.MockClient{}, &mgmt.MockClient{}, &EngineConfig{
|
2022-06-23 17:04:53 +02:00
|
|
|
WgIfaceName: "utun102",
|
2022-01-18 16:44:58 +01:00
|
|
|
WgAddr: "100.64.0.1/24",
|
|
|
|
WgPrivateKey: key,
|
|
|
|
WgPort: 33100,
|
2022-07-02 12:02:17 +02:00
|
|
|
}, nbstatus.NewRecorder())
|
2022-06-23 17:04:53 +02:00
|
|
|
engine.wgInterface, err = iface.NewWGIFace("utun102", "100.64.0.1/24", iface.DefaultMTU)
|
2022-09-05 09:06:35 +02:00
|
|
|
engine.routeManager = routemanager.NewManager(ctx, key.PublicKey().String(), engine.wgInterface, engine.statusRecorder)
|
2022-11-23 13:39:42 +01:00
|
|
|
engine.dnsServer = &dns.MockServer{
|
|
|
|
UpdateDNSServerFunc: func(serial uint64, update nbdns.Config) error { return nil },
|
|
|
|
}
|
2022-01-18 16:44:58 +01:00
|
|
|
|
|
|
|
type testCase struct {
|
2022-01-18 17:52:55 +01:00
|
|
|
name string
|
|
|
|
networkMap *mgmtProto.NetworkMap
|
|
|
|
|
2022-01-18 16:44:58 +01:00
|
|
|
expectedLen int
|
2022-06-04 19:41:01 +02:00
|
|
|
expectedPeers []*mgmtProto.RemotePeerConfig
|
2022-01-18 16:44:58 +01:00
|
|
|
expectedSerial uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
peer1 := &mgmtProto.RemotePeerConfig{
|
|
|
|
WgPubKey: "RRHf3Ma6z6mdLbriAJbqhX7+nM/B71lgw2+91q3LfhU=",
|
|
|
|
AllowedIps: []string{"100.64.0.10/24"},
|
|
|
|
}
|
|
|
|
|
|
|
|
peer2 := &mgmtProto.RemotePeerConfig{
|
|
|
|
WgPubKey: "LLHf3Ma6z6mdLbriAJbqhX7+nM/B71lgw2+91q3LfhU=",
|
|
|
|
AllowedIps: []string{"100.64.0.11/24"},
|
|
|
|
}
|
|
|
|
|
|
|
|
peer3 := &mgmtProto.RemotePeerConfig{
|
|
|
|
WgPubKey: "GGHf3Ma6z6mdLbriAJbqhX7+nM/B71lgw2+91q3LfhU=",
|
|
|
|
AllowedIps: []string{"100.64.0.12/24"},
|
|
|
|
}
|
|
|
|
|
2022-06-04 19:41:01 +02:00
|
|
|
modifiedPeer3 := &mgmtProto.RemotePeerConfig{
|
|
|
|
WgPubKey: "GGHf3Ma6z6mdLbriAJbqhX7+nM/B71lgw2+91q3LfhU=",
|
|
|
|
AllowedIps: []string{"100.64.0.20/24"},
|
|
|
|
}
|
|
|
|
|
2022-01-18 16:44:58 +01:00
|
|
|
case1 := testCase{
|
2022-01-18 17:52:55 +01:00
|
|
|
name: "input with a new peer to add",
|
2022-01-18 16:44:58 +01:00
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 1,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{
|
|
|
|
peer1,
|
|
|
|
},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
},
|
|
|
|
expectedLen: 1,
|
2022-06-04 19:41:01 +02:00
|
|
|
expectedPeers: []*mgmtProto.RemotePeerConfig{peer1},
|
2022-01-18 16:44:58 +01:00
|
|
|
expectedSerial: 1,
|
|
|
|
}
|
|
|
|
|
2022-03-10 18:18:38 +01:00
|
|
|
// 2nd case - one extra peer added and network map has CurrentSerial grater than local => apply the update
|
2022-01-18 16:44:58 +01:00
|
|
|
case2 := testCase{
|
2022-01-18 17:52:55 +01:00
|
|
|
name: "input with an old peer and a new peer to add",
|
2022-01-18 16:44:58 +01:00
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 2,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{
|
|
|
|
peer1, peer2,
|
|
|
|
},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
},
|
|
|
|
expectedLen: 2,
|
2022-06-04 19:41:01 +02:00
|
|
|
expectedPeers: []*mgmtProto.RemotePeerConfig{peer1, peer2},
|
2022-01-18 16:44:58 +01:00
|
|
|
expectedSerial: 2,
|
|
|
|
}
|
|
|
|
|
|
|
|
case3 := testCase{
|
2022-01-18 17:52:55 +01:00
|
|
|
name: "input with outdated (old) update to ignore",
|
2022-01-18 16:44:58 +01:00
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 0,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{
|
|
|
|
peer1, peer2, peer3,
|
|
|
|
},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
},
|
|
|
|
expectedLen: 2,
|
2022-06-04 19:41:01 +02:00
|
|
|
expectedPeers: []*mgmtProto.RemotePeerConfig{peer1, peer2},
|
2022-01-18 16:44:58 +01:00
|
|
|
expectedSerial: 2,
|
|
|
|
}
|
|
|
|
|
|
|
|
case4 := testCase{
|
2022-01-18 17:52:55 +01:00
|
|
|
name: "input with one peer to remove and one new to add",
|
2022-01-18 16:44:58 +01:00
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 4,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{
|
|
|
|
peer2, peer3,
|
|
|
|
},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
},
|
|
|
|
expectedLen: 2,
|
2022-06-04 19:41:01 +02:00
|
|
|
expectedPeers: []*mgmtProto.RemotePeerConfig{peer2, peer3},
|
2022-01-18 16:44:58 +01:00
|
|
|
expectedSerial: 4,
|
|
|
|
}
|
|
|
|
|
|
|
|
case5 := testCase{
|
2022-06-04 19:41:01 +02:00
|
|
|
name: "input with one peer to modify",
|
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 4,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{
|
|
|
|
modifiedPeer3, peer2,
|
|
|
|
},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
},
|
|
|
|
expectedLen: 2,
|
|
|
|
expectedPeers: []*mgmtProto.RemotePeerConfig{peer2, modifiedPeer3},
|
|
|
|
expectedSerial: 4,
|
|
|
|
}
|
|
|
|
|
|
|
|
case6 := testCase{
|
2022-01-18 17:52:55 +01:00
|
|
|
name: "input with all peers to remove",
|
2022-01-18 16:44:58 +01:00
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 5,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{},
|
|
|
|
RemotePeersIsEmpty: true,
|
|
|
|
},
|
|
|
|
expectedLen: 0,
|
|
|
|
expectedPeers: nil,
|
|
|
|
expectedSerial: 5,
|
|
|
|
}
|
|
|
|
|
2022-06-04 19:41:01 +02:00
|
|
|
for _, c := range []testCase{case1, case2, case3, case4, case5, case6} {
|
2022-01-18 17:52:55 +01:00
|
|
|
t.Run(c.name, func(t *testing.T) {
|
|
|
|
err = engine.updateNetworkMap(c.networkMap)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
2022-01-18 16:44:58 +01:00
|
|
|
}
|
2022-01-18 17:52:55 +01:00
|
|
|
|
|
|
|
if len(engine.peerConns) != c.expectedLen {
|
|
|
|
t.Errorf("expecting Engine.peerConns to be of size %d, got %d", c.expectedLen, len(engine.peerConns))
|
|
|
|
}
|
|
|
|
|
|
|
|
if engine.networkSerial != c.expectedSerial {
|
|
|
|
t.Errorf("expecting Engine.networkSerial to be equal to %d, actual %d", c.expectedSerial, engine.networkSerial)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, p := range c.expectedPeers {
|
2022-06-04 19:41:01 +02:00
|
|
|
conn, ok := engine.peerConns[p.GetWgPubKey()]
|
|
|
|
if !ok {
|
2022-01-18 17:52:55 +01:00
|
|
|
t.Errorf("expecting Engine.peerConns to contain peer %s", p)
|
|
|
|
}
|
2022-06-04 19:41:01 +02:00
|
|
|
expectedAllowedIPs := strings.Join(p.AllowedIps, ",")
|
|
|
|
if conn.GetConf().ProxyConfig.AllowedIps != expectedAllowedIPs {
|
|
|
|
t.Errorf("expecting peer %s to have AllowedIPs= %s, got %s", p.GetWgPubKey(),
|
|
|
|
expectedAllowedIPs, conn.GetConf().ProxyConfig.AllowedIps)
|
|
|
|
}
|
2022-01-18 17:52:55 +01:00
|
|
|
}
|
|
|
|
})
|
2022-01-18 16:44:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestEngine_Sync(t *testing.T) {
|
|
|
|
key, err := wgtypes.GeneratePrivateKey()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
// feed updates to Engine via mocked Management client
|
|
|
|
updates := make(chan *mgmtProto.SyncResponse)
|
|
|
|
defer close(updates)
|
|
|
|
syncFunc := func(msgHandler func(msg *mgmtProto.SyncResponse) error) error {
|
|
|
|
for msg := range updates {
|
|
|
|
err := msgHandler(msg)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-03-08 14:47:55 +01:00
|
|
|
engine := NewEngine(ctx, cancel, &signal.MockClient{}, &mgmt.MockClient{SyncFunc: syncFunc}, &EngineConfig{
|
2022-06-23 17:04:53 +02:00
|
|
|
WgIfaceName: "utun103",
|
2022-01-18 16:44:58 +01:00
|
|
|
WgAddr: "100.64.0.1/24",
|
|
|
|
WgPrivateKey: key,
|
|
|
|
WgPort: 33100,
|
2022-07-02 12:02:17 +02:00
|
|
|
}, nbstatus.NewRecorder())
|
2022-01-18 16:44:58 +01:00
|
|
|
|
2022-11-29 11:49:18 +01:00
|
|
|
engine.dnsServer = &dns.MockServer{
|
|
|
|
UpdateDNSServerFunc: func(serial uint64, update nbdns.Config) error { return nil },
|
|
|
|
}
|
|
|
|
|
2022-01-18 16:44:58 +01:00
|
|
|
defer func() {
|
|
|
|
err := engine.Stop()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
err = engine.Start()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
peer1 := &mgmtProto.RemotePeerConfig{
|
|
|
|
WgPubKey: "RRHf3Ma6z6mdLbriAJbqhX7+nM/B71lgw2+91q3LfhU=",
|
|
|
|
AllowedIps: []string{"100.64.0.10/24"},
|
|
|
|
}
|
|
|
|
peer2 := &mgmtProto.RemotePeerConfig{
|
|
|
|
WgPubKey: "LLHf3Ma6z6mdLbriAJbqhX9+nM/B71lgw2+91q3LlhU=",
|
|
|
|
AllowedIps: []string{"100.64.0.11/24"},
|
|
|
|
}
|
|
|
|
peer3 := &mgmtProto.RemotePeerConfig{
|
|
|
|
WgPubKey: "GGHf3Ma6z6mdLbriAJbqhX9+nM/B71lgw2+91q3LlhU=",
|
|
|
|
AllowedIps: []string{"100.64.0.12/24"},
|
|
|
|
}
|
|
|
|
// 1st update with just 1 peer and serial larger than the current serial of the engine => apply update
|
|
|
|
updates <- &mgmtProto.SyncResponse{
|
|
|
|
NetworkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 10,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeers: []*mgmtProto.RemotePeerConfig{peer1, peer2, peer3},
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
timeout := time.After(time.Second * 2)
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-timeout:
|
|
|
|
t.Fatalf("timeout while waiting for test to finish")
|
2022-02-16 20:00:21 +01:00
|
|
|
return
|
2022-01-18 16:44:58 +01:00
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(engine.GetPeers()) == 3 && engine.networkSerial == 10 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-05 09:06:35 +02:00
|
|
|
func TestEngine_UpdateNetworkMapWithRoutes(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
inputErr error
|
|
|
|
networkMap *mgmtProto.NetworkMap
|
|
|
|
expectedLen int
|
|
|
|
expectedRoutes []*route.Route
|
|
|
|
expectedSerial uint64
|
|
|
|
}{
|
|
|
|
{
|
2022-11-07 15:38:21 +01:00
|
|
|
name: "Routes Config Should Be Passed To Manager",
|
2022-09-05 09:06:35 +02:00
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 1,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
Routes: []*mgmtProto.Route{
|
|
|
|
{
|
|
|
|
ID: "a",
|
|
|
|
Network: "192.168.0.0/24",
|
|
|
|
NetID: "n1",
|
|
|
|
Peer: "p1",
|
|
|
|
NetworkType: 1,
|
|
|
|
Masquerade: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID: "b",
|
|
|
|
Network: "192.168.1.0/24",
|
|
|
|
NetID: "n2",
|
|
|
|
Peer: "p1",
|
|
|
|
NetworkType: 1,
|
|
|
|
Masquerade: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedLen: 2,
|
|
|
|
expectedRoutes: []*route.Route{
|
|
|
|
{
|
|
|
|
ID: "a",
|
|
|
|
Network: netip.MustParsePrefix("192.168.0.0/24"),
|
|
|
|
NetID: "n1",
|
|
|
|
Peer: "p1",
|
|
|
|
NetworkType: 1,
|
|
|
|
Masquerade: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID: "b",
|
|
|
|
Network: netip.MustParsePrefix("192.168.1.0/24"),
|
|
|
|
NetID: "n2",
|
|
|
|
Peer: "p1",
|
|
|
|
NetworkType: 1,
|
|
|
|
Masquerade: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedSerial: 1,
|
|
|
|
},
|
|
|
|
{
|
2022-11-07 15:38:21 +01:00
|
|
|
name: "Empty Routes Config Should Be Passed",
|
2022-09-05 09:06:35 +02:00
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 1,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
Routes: nil,
|
|
|
|
},
|
|
|
|
expectedLen: 0,
|
|
|
|
expectedRoutes: []*route.Route{},
|
|
|
|
expectedSerial: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Error Shouldn't Break Engine",
|
|
|
|
inputErr: fmt.Errorf("mocking error"),
|
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 1,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
Routes: nil,
|
|
|
|
},
|
|
|
|
expectedLen: 0,
|
|
|
|
expectedRoutes: []*route.Route{},
|
|
|
|
expectedSerial: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for n, testCase := range testCases {
|
|
|
|
t.Run(testCase.name, func(t *testing.T) {
|
|
|
|
// test setup
|
|
|
|
key, err := wgtypes.GeneratePrivateKey()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
wgIfaceName := fmt.Sprintf("utun%d", 104+n)
|
|
|
|
wgAddr := fmt.Sprintf("100.66.%d.1/24", n)
|
|
|
|
|
|
|
|
engine := NewEngine(ctx, cancel, &signal.MockClient{}, &mgmt.MockClient{}, &EngineConfig{
|
|
|
|
WgIfaceName: wgIfaceName,
|
|
|
|
WgAddr: wgAddr,
|
|
|
|
WgPrivateKey: key,
|
|
|
|
WgPort: 33100,
|
|
|
|
}, nbstatus.NewRecorder())
|
|
|
|
engine.wgInterface, err = iface.NewWGIFace(wgIfaceName, wgAddr, iface.DefaultMTU)
|
|
|
|
assert.NoError(t, err, "shouldn't return error")
|
|
|
|
input := struct {
|
|
|
|
inputSerial uint64
|
|
|
|
inputRoutes []*route.Route
|
|
|
|
}{}
|
|
|
|
|
|
|
|
mockRouteManager := &routemanager.MockManager{
|
|
|
|
UpdateRoutesFunc: func(updateSerial uint64, newRoutes []*route.Route) error {
|
|
|
|
input.inputSerial = updateSerial
|
|
|
|
input.inputRoutes = newRoutes
|
|
|
|
return testCase.inputErr
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
engine.routeManager = mockRouteManager
|
2022-11-23 13:39:42 +01:00
|
|
|
engine.dnsServer = &dns.MockServer{}
|
2022-09-05 09:06:35 +02:00
|
|
|
|
|
|
|
defer func() {
|
|
|
|
exitErr := engine.Stop()
|
|
|
|
if exitErr != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
err = engine.updateNetworkMap(testCase.networkMap)
|
|
|
|
assert.NoError(t, err, "shouldn't return error")
|
|
|
|
assert.Equal(t, testCase.expectedSerial, input.inputSerial, "serial should match")
|
|
|
|
assert.Len(t, input.inputRoutes, testCase.expectedLen, "routes len should match")
|
|
|
|
assert.Equal(t, testCase.expectedRoutes, input.inputRoutes, "routes should match")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-07 15:38:21 +01:00
|
|
|
func TestEngine_UpdateNetworkMapWithDNSUpdate(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
inputErr error
|
|
|
|
networkMap *mgmtProto.NetworkMap
|
|
|
|
expectedZonesLen int
|
|
|
|
expectedZones []nbdns.CustomZone
|
|
|
|
expectedNSGroupsLen int
|
|
|
|
expectedNSGroups []*nbdns.NameServerGroup
|
|
|
|
expectedSerial uint64
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "DNS Config Should Be Passed To DNS Server",
|
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 1,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
Routes: nil,
|
|
|
|
DNSConfig: &mgmtProto.DNSConfig{
|
|
|
|
ServiceEnable: true,
|
|
|
|
CustomZones: []*mgmtProto.CustomZone{
|
|
|
|
{
|
|
|
|
Domain: "netbird.cloud.",
|
|
|
|
Records: []*mgmtProto.SimpleRecord{
|
|
|
|
{
|
|
|
|
Name: "peer-a.netbird.cloud.",
|
|
|
|
Type: 1,
|
|
|
|
Class: nbdns.DefaultClass,
|
|
|
|
TTL: 300,
|
|
|
|
RData: "100.64.0.1",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
NameServerGroups: []*mgmtProto.NameServerGroup{
|
|
|
|
{
|
|
|
|
Primary: true,
|
|
|
|
NameServers: []*mgmtProto.NameServer{
|
|
|
|
{
|
|
|
|
IP: "8.8.8.8",
|
|
|
|
NSType: 1,
|
|
|
|
Port: 53,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedZonesLen: 1,
|
|
|
|
expectedZones: []nbdns.CustomZone{
|
|
|
|
{
|
|
|
|
Domain: "netbird.cloud.",
|
|
|
|
Records: []nbdns.SimpleRecord{
|
|
|
|
{
|
|
|
|
Name: "peer-a.netbird.cloud.",
|
|
|
|
Type: 1,
|
|
|
|
Class: nbdns.DefaultClass,
|
|
|
|
TTL: 300,
|
|
|
|
RData: "100.64.0.1",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedNSGroupsLen: 1,
|
|
|
|
expectedNSGroups: []*nbdns.NameServerGroup{
|
|
|
|
{
|
|
|
|
Primary: true,
|
|
|
|
NameServers: []nbdns.NameServer{
|
|
|
|
{
|
|
|
|
IP: netip.MustParseAddr("8.8.8.8"),
|
|
|
|
NSType: 1,
|
|
|
|
Port: 53,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expectedSerial: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Empty DNS Config Should Be OK",
|
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 1,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
Routes: nil,
|
|
|
|
DNSConfig: nil,
|
|
|
|
},
|
|
|
|
expectedZonesLen: 0,
|
|
|
|
expectedZones: []nbdns.CustomZone{},
|
|
|
|
expectedNSGroupsLen: 0,
|
|
|
|
expectedNSGroups: []*nbdns.NameServerGroup{},
|
|
|
|
expectedSerial: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Error Shouldn't Break Engine",
|
|
|
|
inputErr: fmt.Errorf("mocking error"),
|
|
|
|
networkMap: &mgmtProto.NetworkMap{
|
|
|
|
Serial: 1,
|
|
|
|
PeerConfig: nil,
|
|
|
|
RemotePeersIsEmpty: false,
|
|
|
|
Routes: nil,
|
|
|
|
},
|
|
|
|
expectedZonesLen: 0,
|
|
|
|
expectedZones: []nbdns.CustomZone{},
|
|
|
|
expectedNSGroupsLen: 0,
|
|
|
|
expectedNSGroups: []*nbdns.NameServerGroup{},
|
|
|
|
expectedSerial: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for n, testCase := range testCases {
|
|
|
|
t.Run(testCase.name, func(t *testing.T) {
|
|
|
|
// test setup
|
|
|
|
key, err := wgtypes.GeneratePrivateKey()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
wgIfaceName := fmt.Sprintf("utun%d", 104+n)
|
|
|
|
wgAddr := fmt.Sprintf("100.66.%d.1/24", n)
|
|
|
|
|
|
|
|
engine := NewEngine(ctx, cancel, &signal.MockClient{}, &mgmt.MockClient{}, &EngineConfig{
|
|
|
|
WgIfaceName: wgIfaceName,
|
|
|
|
WgAddr: wgAddr,
|
|
|
|
WgPrivateKey: key,
|
|
|
|
WgPort: 33100,
|
|
|
|
}, nbstatus.NewRecorder())
|
|
|
|
engine.wgInterface, err = iface.NewWGIFace(wgIfaceName, wgAddr, iface.DefaultMTU)
|
|
|
|
assert.NoError(t, err, "shouldn't return error")
|
|
|
|
|
|
|
|
mockRouteManager := &routemanager.MockManager{
|
|
|
|
UpdateRoutesFunc: func(updateSerial uint64, newRoutes []*route.Route) error {
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
engine.routeManager = mockRouteManager
|
|
|
|
|
|
|
|
input := struct {
|
|
|
|
inputSerial uint64
|
|
|
|
inputNSGroups []*nbdns.NameServerGroup
|
|
|
|
inputZones []nbdns.CustomZone
|
|
|
|
}{}
|
|
|
|
|
|
|
|
mockDNSServer := &dns.MockServer{
|
|
|
|
UpdateDNSServerFunc: func(serial uint64, update nbdns.Config) error {
|
|
|
|
input.inputSerial = serial
|
|
|
|
input.inputZones = update.CustomZones
|
|
|
|
input.inputNSGroups = update.NameServerGroups
|
|
|
|
return testCase.inputErr
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
engine.dnsServer = mockDNSServer
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
exitErr := engine.Stop()
|
|
|
|
if exitErr != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
err = engine.updateNetworkMap(testCase.networkMap)
|
|
|
|
assert.NoError(t, err, "shouldn't return error")
|
|
|
|
assert.Equal(t, testCase.expectedSerial, input.inputSerial, "serial should match")
|
|
|
|
assert.Len(t, input.inputNSGroups, testCase.expectedZonesLen, "zones len should match")
|
|
|
|
assert.Equal(t, testCase.expectedZones, input.inputZones, "custom zones should match")
|
|
|
|
assert.Len(t, input.inputNSGroups, testCase.expectedNSGroupsLen, "ns groups len should match")
|
|
|
|
assert.Equal(t, testCase.expectedNSGroups, input.inputNSGroups, "ns groups should match")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-10 18:43:13 +01:00
|
|
|
func TestEngine_MultiplePeers(t *testing.T) {
|
2022-03-08 14:47:55 +01:00
|
|
|
// log.SetLevel(log.DebugLevel)
|
2022-01-10 18:43:13 +01:00
|
|
|
|
|
|
|
dir := t.TempDir()
|
|
|
|
|
|
|
|
err := util.CopyFileContents("../testdata/store.json", filepath.Join(dir, "store.json"))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer func() {
|
2022-01-17 14:01:58 +01:00
|
|
|
err = os.Remove(filepath.Join(dir, "store.json")) //nolint
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
2022-01-10 18:43:13 +01:00
|
|
|
}()
|
|
|
|
|
2022-03-08 14:47:55 +01:00
|
|
|
ctx, cancel := context.WithCancel(CtxInitState(context.Background()))
|
2022-01-10 18:43:13 +01:00
|
|
|
defer cancel()
|
2022-03-08 14:47:55 +01:00
|
|
|
|
2022-01-17 15:10:18 +01:00
|
|
|
sport := 10010
|
2022-01-18 16:44:58 +01:00
|
|
|
sigServer, err := startSignal(sport)
|
2022-01-10 18:43:13 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
2022-01-18 16:44:58 +01:00
|
|
|
defer sigServer.Stop()
|
2022-01-17 15:10:18 +01:00
|
|
|
mport := 33081
|
2022-01-18 16:44:58 +01:00
|
|
|
mgmtServer, err := startManagement(mport, dir)
|
2022-01-10 18:43:13 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
2022-01-25 09:40:28 +01:00
|
|
|
defer mgmtServer.GracefulStop()
|
2022-01-10 18:43:13 +01:00
|
|
|
|
|
|
|
setupKey := "A2C8E62B-38F5-4553-B31E-DD66C696CEBB"
|
|
|
|
|
|
|
|
mu := sync.Mutex{}
|
|
|
|
engines := []*Engine{}
|
|
|
|
numPeers := 10
|
|
|
|
wg := sync.WaitGroup{}
|
|
|
|
wg.Add(numPeers)
|
|
|
|
// create and start peers
|
|
|
|
for i := 0; i < numPeers; i++ {
|
|
|
|
j := i
|
|
|
|
go func() {
|
2022-01-17 15:10:18 +01:00
|
|
|
engine, err := createEngine(ctx, cancel, setupKey, j, mport, sport)
|
2022-01-10 18:43:13 +01:00
|
|
|
if err != nil {
|
2022-03-16 11:02:06 +01:00
|
|
|
wg.Done()
|
|
|
|
t.Errorf("unable to create the engine for peer %d with error %v", j, err)
|
2022-01-10 18:43:13 +01:00
|
|
|
return
|
|
|
|
}
|
2022-11-23 13:39:42 +01:00
|
|
|
engine.dnsServer = &dns.MockServer{}
|
2022-01-10 18:43:13 +01:00
|
|
|
mu.Lock()
|
|
|
|
defer mu.Unlock()
|
2022-03-16 11:02:06 +01:00
|
|
|
err = engine.Start()
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("unable to start engine for peer %d with error %v", j, err)
|
|
|
|
wg.Done()
|
|
|
|
return
|
|
|
|
}
|
2022-01-10 18:43:13 +01:00
|
|
|
engines = append(engines, engine)
|
|
|
|
wg.Done()
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait until all have been created and started
|
|
|
|
wg.Wait()
|
2022-03-16 11:02:06 +01:00
|
|
|
if len(engines) != numPeers {
|
|
|
|
t.Fatal("not all peers was started")
|
|
|
|
}
|
2022-01-10 18:43:13 +01:00
|
|
|
// check whether all the peer have expected peers connected
|
2022-01-17 14:01:58 +01:00
|
|
|
|
2022-01-10 18:43:13 +01:00
|
|
|
expectedConnected := numPeers * (numPeers - 1)
|
2022-03-16 11:02:06 +01:00
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
// adjust according to timeouts
|
|
|
|
timeout := 50 * time.Second
|
|
|
|
timeoutChan := time.After(timeout)
|
2022-03-16 11:02:06 +01:00
|
|
|
ticker := time.NewTicker(time.Second)
|
|
|
|
defer ticker.Stop()
|
|
|
|
loop:
|
2022-01-10 18:43:13 +01:00
|
|
|
for {
|
2022-01-17 14:01:58 +01:00
|
|
|
select {
|
|
|
|
case <-timeoutChan:
|
|
|
|
t.Fatalf("waiting for expected connections timeout after %s", timeout.String())
|
2022-03-16 11:02:06 +01:00
|
|
|
break loop
|
|
|
|
case <-ticker.C:
|
|
|
|
totalConnected := 0
|
|
|
|
for _, engine := range engines {
|
|
|
|
totalConnected = totalConnected + len(engine.GetConnectedPeers())
|
|
|
|
}
|
|
|
|
if totalConnected == expectedConnected {
|
|
|
|
log.Infof("total connected=%d", totalConnected)
|
|
|
|
break loop
|
|
|
|
}
|
|
|
|
log.Infof("total connected=%d", totalConnected)
|
2022-01-10 18:43:13 +01:00
|
|
|
}
|
|
|
|
}
|
2022-01-17 14:01:58 +01:00
|
|
|
// cleanup test
|
2022-03-16 11:02:06 +01:00
|
|
|
for n, peerEngine := range engines {
|
|
|
|
t.Logf("stopping peer with interface %s from multipeer test, loopIndex %d", peerEngine.wgInterface.Name, n)
|
2022-01-25 11:18:01 +01:00
|
|
|
errStop := peerEngine.mgmClient.Close()
|
|
|
|
if errStop != nil {
|
|
|
|
log.Infoln("got error trying to close management clients from engine: ", errStop)
|
|
|
|
}
|
|
|
|
errStop = peerEngine.Stop()
|
2022-01-17 14:01:58 +01:00
|
|
|
if errStop != nil {
|
|
|
|
log.Infoln("got error trying to close testing peers engine: ", errStop)
|
|
|
|
}
|
|
|
|
}
|
2022-01-10 18:43:13 +01:00
|
|
|
}
|
|
|
|
|
2022-01-17 15:10:18 +01:00
|
|
|
func createEngine(ctx context.Context, cancel context.CancelFunc, setupKey string, i int, mport int, sport int) (*Engine, error) {
|
2022-01-17 14:01:58 +01:00
|
|
|
key, err := wgtypes.GeneratePrivateKey()
|
2022-01-10 18:43:13 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-01-17 15:10:18 +01:00
|
|
|
mgmtClient, err := mgmt.NewClient(ctx, fmt.Sprintf("localhost:%d", mport), key, false)
|
2022-01-10 18:43:13 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-01-17 15:10:18 +01:00
|
|
|
signalClient, err := signal.NewClient(ctx, fmt.Sprintf("localhost:%d", sport), key, false)
|
2022-01-10 18:43:13 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
publicKey, err := mgmtClient.GetServerPublicKey()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-05-25 23:25:02 +02:00
|
|
|
info := system.GetInfo(ctx)
|
2022-06-23 17:04:53 +02:00
|
|
|
resp, err := mgmtClient.Register(*publicKey, setupKey, "", info, nil)
|
2022-01-10 18:43:13 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var ifaceName string
|
|
|
|
if runtime.GOOS == "darwin" {
|
|
|
|
ifaceName = fmt.Sprintf("utun1%d", i)
|
|
|
|
} else {
|
|
|
|
ifaceName = fmt.Sprintf("wt%d", i)
|
|
|
|
}
|
|
|
|
|
2022-02-16 20:00:21 +01:00
|
|
|
wgPort := 33100 + i
|
2022-01-10 18:43:13 +01:00
|
|
|
conf := &EngineConfig{
|
2022-01-17 14:01:58 +01:00
|
|
|
WgIfaceName: ifaceName,
|
2022-01-10 18:43:13 +01:00
|
|
|
WgAddr: resp.PeerConfig.Address,
|
|
|
|
WgPrivateKey: key,
|
2022-02-16 20:00:21 +01:00
|
|
|
WgPort: wgPort,
|
2022-01-10 18:43:13 +01:00
|
|
|
}
|
|
|
|
|
2022-07-02 12:02:17 +02:00
|
|
|
return NewEngine(ctx, cancel, signalClient, mgmtClient, conf, nbstatus.NewRecorder()), nil
|
2022-01-10 18:43:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func startSignal(port int) (*grpc.Server, error) {
|
|
|
|
s := grpc.NewServer(grpc.KeepaliveEnforcementPolicy(kaep), grpc.KeepaliveParams(kasp))
|
|
|
|
|
|
|
|
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to listen: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
proto.RegisterSignalExchangeServer(s, signalServer.NewServer())
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
if err = s.Serve(lis); err != nil {
|
|
|
|
log.Fatalf("failed to serve: %v", err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
return s, nil
|
|
|
|
}
|
|
|
|
|
2022-01-18 16:44:58 +01:00
|
|
|
func startManagement(port int, dataDir string) (*grpc.Server, error) {
|
|
|
|
config := &server.Config{
|
|
|
|
Stuns: []*server.Host{},
|
|
|
|
TURNConfig: &server.TURNConfig{},
|
|
|
|
Signal: &server.Host{
|
|
|
|
Proto: "http",
|
|
|
|
URI: "localhost:10000",
|
|
|
|
},
|
|
|
|
Datadir: dataDir,
|
|
|
|
HttpConfig: nil,
|
|
|
|
}
|
2022-01-10 18:43:13 +01:00
|
|
|
|
|
|
|
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
s := grpc.NewServer(grpc.KeepaliveEnforcementPolicy(kaep), grpc.KeepaliveParams(kasp))
|
2022-11-08 10:46:12 +01:00
|
|
|
store, err := server.NewFileStore(config.Datadir)
|
2022-01-10 18:43:13 +01:00
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed creating a store: %s: %v", config.Datadir, err)
|
|
|
|
}
|
|
|
|
peersUpdateManager := server.NewPeersUpdateManager()
|
2022-11-07 15:38:21 +01:00
|
|
|
accountManager, err := server.BuildManager(store, peersUpdateManager, nil, "", "")
|
2022-05-21 15:21:39 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-01-10 18:43:13 +01:00
|
|
|
turnManager := server.NewTimeBasedAuthSecretsManager(peersUpdateManager, config.TURNConfig)
|
2022-10-22 15:06:54 +02:00
|
|
|
mgmtServer, err := server.NewServer(config, accountManager, peersUpdateManager, turnManager, nil)
|
2022-01-10 18:43:13 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
mgmtProto.RegisterManagementServiceServer(s, mgmtServer)
|
|
|
|
go func() {
|
|
|
|
if err = s.Serve(lis); err != nil {
|
|
|
|
log.Fatalf("failed to serve: %v", err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
return s, nil
|
|
|
|
}
|