Peer configuration management (#69)

* feature: add config properties to the SyncResponse of the management gRpc service

* fix: lint errors

* chore: modify management protocol according to the review notes

* fix: management proto fields sequence

* feature: add proper peer configuration to be synced

* chore: minor changes

* feature: finalize peer config management

* fix: lint errors

* feature: add management server config file

* refactor: extract hosts-config to a separate file

* refactor: review notes applied to correct file_store usage

* refactor: extract management service configuration to a file

* refactor: simplify management config
This commit is contained in:
Mikhail Bragin
2021-07-30 17:46:38 +02:00
committed by GitHub
parent c0c4c4a266
commit 2c2c1e19df
14 changed files with 690 additions and 237 deletions
+119
View File
@@ -0,0 +1,119 @@
package server
import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"net"
"sync"
)
type AccountManager struct {
Store Store
// mutex to synchronise account operations (e.g. generating Peer IP address inside the Network)
mux sync.Mutex
}
// Account represents a unique account of the system
type Account struct {
Id string
SetupKeys map[string]*SetupKey
Network *Network
Peers []*Peer
}
// SetupKey represents a pre-authorized key used to register machines (peers)
// One key might have multiple machines
type SetupKey struct {
Key string
}
// Peer represents a machine connected to the network.
// The Peer is a Wireguard peer identified by a public key
type Peer struct {
// Wireguard public key
Key string
// A setup key this peer was registered with
SetupKey *SetupKey
// IP address of the Peer
IP net.IP
}
// NewManager creates a new AccountManager with a provided Store
func NewManager(store Store) *AccountManager {
return &AccountManager{
Store: store,
mux: sync.Mutex{},
}
}
// GetPeer returns a peer from a Store
func (manager *AccountManager) GetPeer(peerKey string) (*Peer, error) {
manager.mux.Lock()
defer manager.mux.Unlock()
peer, err := manager.Store.GetPeer(peerKey)
if err != nil {
return nil, status.Errorf(codes.NotFound, "provided peer key doesn't exists %s", peerKey)
}
return peer, nil
}
// GetPeersForAPeer returns a list of peers available for a given peer (key)
// Effectively all the peers of the original peer's account except for the peer itself
func (manager *AccountManager) GetPeersForAPeer(peerKey string) ([]*Peer, error) {
manager.mux.Lock()
defer manager.mux.Unlock()
account, err := manager.Store.GetPeerAccount(peerKey)
if err != nil {
return nil, status.Errorf(codes.Internal, "Invalid peer key %s", peerKey)
}
var res []*Peer
for _, peer := range account.Peers {
if peer.Key != peerKey {
res = append(res, peer)
}
}
return res, nil
}
// AddPeer adds a new peer to the Store.
// Each Account has a list of pre-authorised SetupKey and if no Account has a given key err wit ha code codes.Unauthenticated
// will be returned, meaning the key is invalid
// Each new Peer will be assigned a new next net.IP from the Account.Network and Account.Network.LastIP will be updated (IP's are not reused).
func (manager *AccountManager) AddPeer(setupKey string, peerKey string) (*Peer, error) {
manager.mux.Lock()
defer manager.mux.Unlock()
account, err := manager.Store.GetAccountBySetupKey(setupKey)
if err != nil {
//todo
return nil, err
}
var takenIps []net.IP
for _, peer := range account.Peers {
takenIps = append(takenIps, peer.IP)
}
network := account.Network
nextIp, _ := AllocatePeerIP(network.Net, takenIps)
newPeer := &Peer{
Key: peerKey,
SetupKey: &SetupKey{Key: setupKey},
IP: nextIp,
}
account.Peers = append(account.Peers, newPeer)
err = manager.Store.SaveAccount(account)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed adding peer")
}
return newPeer, nil
}
+30
View File
@@ -0,0 +1,30 @@
package server
type Protocol string
const (
UDP Protocol = "udp"
DTLS Protocol = "dtls"
TCP Protocol = "tcp"
HTTP Protocol = "http"
HTTPS Protocol = "https"
)
// Config of the Management service
type Config struct {
Stuns []*Host
Turns []*Host
Signal *Host
Datadir string
LetsEncryptDomain string
}
// Host represents a Wiretrustee host (e.g. STUN, TURN, Signal)
type Host struct {
Proto Protocol
// URI e.g. turns://stun.wiretrustee.com:4430 or signal.wiretrustee.com:10000
URI string
Username string
Password []byte
}
+169
View File
@@ -0,0 +1,169 @@
package server
import (
"os"
"path/filepath"
"strings"
"sync"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/wiretrustee/wiretrustee/util"
)
// storeFileName Store file name. Stored in the datadir
const storeFileName = "store.json"
// FileStore represents an account storage backed by a file persisted to disk
type FileStore struct {
Accounts map[string]*Account
SetupKeyId2AccountId map[string]string `json:"-"`
PeerKeyId2AccountId map[string]string `json:"-"`
// mutex to synchronise Store read/write operations
mux sync.Mutex `json:"-"`
storeFile string `json:"-"`
}
type StoredAccount struct {
}
// NewStore restores a store from the file located in the datadir
func NewStore(dataDir string) (*FileStore, error) {
return restore(filepath.Join(dataDir, storeFileName))
}
// restore restores the state of the store from the file.
// Creates a new empty store file if doesn't exist
func restore(file string) (*FileStore, error) {
if _, err := os.Stat(file); os.IsNotExist(err) {
// create a new FileStore if previously didn't exist (e.g. first run)
s := &FileStore{
Accounts: make(map[string]*Account),
mux: sync.Mutex{},
storeFile: file,
}
err = s.persist(file)
if err != nil {
return nil, err
}
return s, nil
}
read, err := util.ReadJson(file, &FileStore{})
if err != nil {
return nil, err
}
store := read.(*FileStore)
store.storeFile = file
store.SetupKeyId2AccountId = make(map[string]string)
store.PeerKeyId2AccountId = make(map[string]string)
for accountId, account := range store.Accounts {
for setupKeyId := range account.SetupKeys {
store.SetupKeyId2AccountId[strings.ToLower(setupKeyId)] = accountId
}
for _, peer := range account.Peers {
store.PeerKeyId2AccountId[strings.ToLower(peer.Key)] = accountId
}
}
return store, nil
}
// persist persists account data to a file
// It is recommended to call it with locking FileStore.mux
func (s *FileStore) persist(file string) error {
return util.WriteJson(file, s)
}
// GetPeer returns a peer from a Store
func (s *FileStore) GetPeer(peerKey string) (*Peer, error) {
s.mux.Lock()
defer s.mux.Unlock()
accountId, accountIdFound := s.PeerKeyId2AccountId[peerKey]
if !accountIdFound {
return nil, status.Errorf(codes.Internal, "account not found")
}
account, err := s.GetAccount(accountId)
if err != nil {
return nil, err
}
for _, peer := range account.Peers {
if peer.Key == peerKey {
return peer, nil
}
}
return nil, status.Errorf(codes.NotFound, "peer not found")
}
// SaveAccount updates an existing account or adds a new one
func (s *FileStore) SaveAccount(account *Account) error {
s.mux.Lock()
defer s.mux.Unlock()
// todo will override, handle existing keys
s.Accounts[account.Id] = account
// todo check that account.Id and keyId are not exist already
// because if keyId exists for other accounts this can be bad
for keyId := range account.SetupKeys {
s.SetupKeyId2AccountId[strings.ToLower(keyId)] = account.Id
}
for _, peer := range account.Peers {
s.PeerKeyId2AccountId[peer.Key] = account.Id
}
err := s.persist(s.storeFile)
if err != nil {
return err
}
return nil
}
func (s *FileStore) GetAccountBySetupKey(setupKey string) (*Account, error) {
accountId, accountIdFound := s.SetupKeyId2AccountId[strings.ToLower(setupKey)]
if !accountIdFound {
return nil, status.Errorf(codes.NotFound, "provided setup key doesn't exists")
}
account, err := s.GetAccount(accountId)
if err != nil {
return nil, err
}
return account, nil
}
func (s *FileStore) GetAccount(accountId string) (*Account, error) {
account, accountFound := s.Accounts[accountId]
if !accountFound {
return nil, status.Errorf(codes.Internal, "account not found")
}
return account, nil
}
func (s *FileStore) GetPeerAccount(peerKey string) (*Account, error) {
s.mux.Lock()
defer s.mux.Unlock()
accountId, accountIdFound := s.PeerKeyId2AccountId[peerKey]
if !accountIdFound {
return nil, status.Errorf(codes.NotFound, "Provided peer key doesn't exists %s", peerKey)
}
return s.GetAccount(accountId)
}
+114 -13
View File
@@ -2,7 +2,7 @@ package server_test
import (
"context"
server2 "github.com/wiretrustee/wiretrustee/management/server"
server "github.com/wiretrustee/wiretrustee/management/server"
"io/ioutil"
"math/rand"
"net"
@@ -33,7 +33,7 @@ var _ = Describe("Management service", func() {
var (
addr string
server *grpc.Server
s *grpc.Server
dataDir string
client mgmtProto.ManagementServiceClient
serverPubKey wgtypes.Key
@@ -50,11 +50,17 @@ var _ = Describe("Management service", func() {
err = util.CopyFileContents("testdata/store.json", filepath.Join(dataDir, "store.json"))
Expect(err).NotTo(HaveOccurred())
var listener net.Listener
server, listener = startServer(dataDir)
config := &server.Config{}
_, err = util.ReadJson("testdata/management.json", config)
Expect(err).NotTo(HaveOccurred())
config.Datadir = dataDir
s, listener = startServer(config)
addr = listener.Addr().String()
client, conn = createRawClient(addr)
// server public key
// s public key
resp, err := client.GetServerKey(context.TODO(), &mgmtProto.Empty{})
Expect(err).NotTo(HaveOccurred())
serverPubKey, err = wgtypes.ParseKey(resp.Key)
@@ -63,7 +69,7 @@ var _ = Describe("Management service", func() {
})
AfterEach(func() {
server.Stop()
s.Stop()
err := conn.Close()
Expect(err).NotTo(HaveOccurred())
err = os.RemoveAll(dataDir)
@@ -82,6 +88,54 @@ var _ = Describe("Management service", func() {
Context("when calling Sync endpoint", func() {
Context("when there is a new peer registered", func() {
Specify("a proper configuration is returned", func() {
key, _ := wgtypes.GenerateKey()
registerPeerWithValidSetupKey(key, client)
encryptedBytes, err := encryption.EncryptMessage(serverPubKey, key, &mgmtProto.SyncRequest{})
Expect(err).NotTo(HaveOccurred())
sync, err := client.Sync(context.TODO(), &mgmtProto.EncryptedMessage{
WgPubKey: key.PublicKey().String(),
Body: encryptedBytes,
})
Expect(err).NotTo(HaveOccurred())
encryptedResponse := &mgmtProto.EncryptedMessage{}
err = sync.RecvMsg(encryptedResponse)
Expect(err).NotTo(HaveOccurred())
resp := &mgmtProto.SyncResponse{}
err = encryption.DecryptMessage(serverPubKey, key, encryptedResponse.Body, resp)
Expect(err).NotTo(HaveOccurred())
Expect(resp.PeerConfig.Address).To(BeEquivalentTo("100.64.0.1"))
expectedSignalConfig := &mgmtProto.HostConfig{
Uri: "signal.wiretrustee.com:10000",
Protocol: mgmtProto.HostConfig_HTTP,
}
expectedStunsConfig := &mgmtProto.HostConfig{
Uri: "stun:stun.wiretrustee.com:3468",
Protocol: mgmtProto.HostConfig_UDP,
}
expectedTurnsConfig := &mgmtProto.ProtectedHostConfig{
HostConfig: &mgmtProto.HostConfig{
Uri: "turn:stun.wiretrustee.com:3468",
Protocol: mgmtProto.HostConfig_UDP,
},
User: "some_user",
Password: "some_password",
}
Expect(resp.WiretrusteeConfig.Signal).To(BeEquivalentTo(expectedSignalConfig))
Expect(resp.WiretrusteeConfig.Stuns).To(ConsistOf(expectedStunsConfig))
Expect(resp.WiretrusteeConfig.Turns).To(ConsistOf(expectedTurnsConfig))
})
})
Context("when there are 3 peers registered under one account", func() {
Specify("a list containing other 2 peers is returned", func() {
key, _ := wgtypes.GenerateKey()
@@ -112,8 +166,9 @@ var _ = Describe("Management service", func() {
err = pb.Unmarshal(decryptedBytes, resp)
Expect(err).NotTo(HaveOccurred())
Expect(resp.GetPeers()).To(HaveLen(2))
Expect(resp.GetPeers()).To(ContainElements(key1.PublicKey().String(), key2.PublicKey().String()))
Expect(resp.GetRemotePeers()).To(HaveLen(2))
peers := []string{resp.GetRemotePeers()[0].WgPubKey, resp.GetRemotePeers()[1].WgPubKey}
Expect(peers).To(ContainElements(key1.PublicKey().String(), key2.PublicKey().String()))
})
})
@@ -143,7 +198,7 @@ var _ = Describe("Management service", func() {
Expect(err).NotTo(HaveOccurred())
resp := &mgmtProto.SyncResponse{}
err = pb.Unmarshal(decryptedBytes, resp)
Expect(resp.GetPeers()).To(HaveLen(0))
Expect(resp.GetRemotePeers()).To(HaveLen(0))
wg := sync2.WaitGroup{}
wg.Add(1)
@@ -167,8 +222,8 @@ var _ = Describe("Management service", func() {
wg.Wait()
Expect(err).NotTo(HaveOccurred())
Expect(resp.GetPeers()).To(ContainElements(key1.PublicKey().String()))
Expect(resp.GetPeers()).To(HaveLen(1))
Expect(resp.GetRemotePeers()).To(HaveLen(1))
Expect(resp.GetRemotePeers()[0].WgPubKey).To(BeEquivalentTo(key1.PublicKey().String()))
})
})
})
@@ -291,6 +346,52 @@ var _ = Describe("Management service", func() {
})
})
})
Context("when there are peers registered under one account concurrently", func() {
Specify("then there are no duplicate IPs", func() {
initialPeers := 30
ipChannel := make(chan string, 20)
for i := 0; i < initialPeers; i++ {
go func() {
key, _ := wgtypes.GenerateKey()
registerPeerWithValidSetupKey(key, client)
encryptedBytes, err := encryption.EncryptMessage(serverPubKey, key, &mgmtProto.SyncRequest{})
Expect(err).NotTo(HaveOccurred())
// open stream
sync, err := client.Sync(context.TODO(), &mgmtProto.EncryptedMessage{
WgPubKey: key.PublicKey().String(),
Body: encryptedBytes,
})
Expect(err).NotTo(HaveOccurred())
encryptedResponse := &mgmtProto.EncryptedMessage{}
err = sync.RecvMsg(encryptedResponse)
Expect(err).NotTo(HaveOccurred())
resp := &mgmtProto.SyncResponse{}
err = encryption.DecryptMessage(serverPubKey, key, encryptedResponse.Body, resp)
Expect(err).NotTo(HaveOccurred())
ipChannel <- resp.GetPeerConfig().Address
}()
}
ips := make(map[string]struct{})
for ip := range ipChannel {
if _, ok := ips[ip]; ok {
Fail("found duplicate IP: " + ip)
}
ips[ip] = struct{}{}
if len(ips) == initialPeers {
break
}
}
close(ipChannel)
})
})
})
func registerPeerWithValidSetupKey(key wgtypes.Key, client mgmtProto.ManagementServiceClient) *mgmtProto.RegisterPeerResponse {
@@ -320,13 +421,13 @@ func createRawClient(addr string) (mgmtProto.ManagementServiceClient, *grpc.Clie
return mgmtProto.NewManagementServiceClient(conn), conn
}
func startServer(dataDir string) (*grpc.Server, net.Listener) {
func startServer(config *server.Config) (*grpc.Server, net.Listener) {
lis, err := net.Listen("tcp", ":0")
Expect(err).NotTo(HaveOccurred())
s := grpc.NewServer()
server, err := server2.NewServer(dataDir)
mgmtServer, err := server.NewServer(config)
Expect(err).NotTo(HaveOccurred())
mgmtProto.RegisterManagementServiceServer(s, server)
mgmtProto.RegisterManagementServiceServer(s, mgmtServer)
go func() {
if err := s.Serve(lis); err != nil {
Expect(err).NotTo(HaveOccurred())
+69
View File
@@ -0,0 +1,69 @@
package server
import (
"encoding/binary"
"fmt"
"net"
)
var (
upperIPv4 = []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 255, 255, 255, 255}
upperIPv6 = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
)
type Network struct {
Id string
Net net.IPNet
Dns string
}
// AllocatePeerIP pics an available IP from an net.IPNet.
// This method considers already taken IPs and reuses IPs if there are gaps in takenIps
// E.g. if ipNet=100.30.0.0/16 and takenIps=[100.30.0.1, 100.30.0.5] then the result would be 100.30.0.2
func AllocatePeerIP(ipNet net.IPNet, takenIps []net.IP) (net.IP, error) {
takenIpMap := make(map[string]net.IP)
takenIpMap[ipNet.IP.String()] = ipNet.IP
for _, ip := range takenIps {
takenIpMap[ip.String()] = ip
}
for ip := ipNet.IP.Mask(ipNet.Mask); ipNet.Contains(ip); ip = GetNextIP(ip) {
if _, ok := takenIpMap[ip.String()]; !ok {
return ip, nil
}
}
return nil, fmt.Errorf("failed allocating new IP for the ipNet %s and takenIps %s", ipNet.String(), takenIps)
}
// GetNextIP returns the next IP from the given IP address. If the given IP is
// the last IP of a v4 or v6 range, the same IP is returned.
// Credits to Cilium team.
// Copyright 2017-2020 Authors of Cilium
func GetNextIP(ip net.IP) net.IP {
if ip.Equal(upperIPv4) || ip.Equal(upperIPv6) {
return ip
}
nextIP := make(net.IP, len(ip))
switch len(ip) {
case net.IPv4len:
ipU32 := binary.BigEndian.Uint32(ip)
ipU32++
binary.BigEndian.PutUint32(nextIP, ipU32)
return nextIP
case net.IPv6len:
ipU64 := binary.BigEndian.Uint64(ip[net.IPv6len/2:])
ipU64++
binary.BigEndian.PutUint64(nextIP[net.IPv6len/2:], ipU64)
if ipU64 == 0 {
ipU64 = binary.BigEndian.Uint64(ip[:net.IPv6len/2])
ipU64++
binary.BigEndian.PutUint64(nextIP[:net.IPv6len/2], ipU64)
} else {
copy(nextIP[:net.IPv6len/2], ip[:net.IPv6len/2])
}
return nextIP
default:
return ip
}
}
+94 -24
View File
@@ -2,7 +2,7 @@ package server
import (
"context"
"github.com/wiretrustee/wiretrustee/management/store"
"fmt"
"sync"
"time"
@@ -17,33 +17,38 @@ import (
// Server an instance of a Management server
type Server struct {
Store *store.FileStore
wgKey wgtypes.Key
accountManager *AccountManager
wgKey wgtypes.Key
proto.UnimplementedManagementServiceServer
peerChannels map[string]chan *UpdateChannelMessage
channelsMux *sync.Mutex
config *Config
}
// AllowedIPsFormat generates Wireguard AllowedIPs format (e.g. 100.30.30.1/32)
const AllowedIPsFormat = "%s/32"
type UpdateChannelMessage struct {
Update *proto.SyncResponse
}
// NewServer creates a new Management server
func NewServer(dataDir string) (*Server, error) {
func NewServer(config *Config) (*Server, error) {
key, err := wgtypes.GeneratePrivateKey()
if err != nil {
return nil, err
}
store, err := store.NewStore(dataDir)
store, err := NewStore(config.Datadir)
if err != nil {
return nil, err
}
return &Server{
Store: store,
wgKey: key,
// peerKey -> event channel
peerChannels: make(map[string]chan *UpdateChannelMessage),
channelsMux: &sync.Mutex{},
peerChannels: make(map[string]chan *UpdateChannelMessage),
channelsMux: &sync.Mutex{},
accountManager: NewManager(store),
config: config,
}, nil
}
@@ -73,8 +78,8 @@ func (s *Server) Sync(req *proto.EncryptedMessage, srv proto.ManagementService_S
return status.Errorf(codes.InvalidArgument, "provided wgPubKey %s is invalid", peerKey.String())
}
exists := s.Store.PeerExists(peerKey.String())
if !exists {
peer, err := s.accountManager.GetPeer(peerKey.String())
if err != nil {
return status.Errorf(codes.Unauthenticated, "provided peer with the key wgPubKey %s is not registered", peerKey.String())
}
@@ -84,7 +89,7 @@ func (s *Server) Sync(req *proto.EncryptedMessage, srv proto.ManagementService_S
return status.Errorf(codes.InvalidArgument, "invalid request message")
}
err = s.sendInitialSync(peerKey, srv)
err = s.sendInitialSync(peerKey, peer, srv)
if err != nil {
return err
}
@@ -132,28 +137,28 @@ func (s *Server) RegisterPeer(ctx context.Context, req *proto.RegisterPeerReques
s.channelsMux.Lock()
defer s.channelsMux.Unlock()
err := s.Store.AddPeer(req.SetupKey, req.Key)
peer, err := s.accountManager.AddPeer(req.SetupKey, req.Key)
if err != nil {
return &proto.RegisterPeerResponse{}, status.Errorf(codes.NotFound, "provided setup key doesn't exists")
}
peers, err := s.Store.GetPeersForAPeer(req.Key)
peers, err := s.accountManager.GetPeersForAPeer(peer.Key)
if err != nil {
//todo return a proper error
return nil, err
}
// notify other peers of our registration
for _, peer := range peers {
if channel, ok := s.peerChannels[peer]; ok {
for _, remotePeer := range peers {
if channel, ok := s.peerChannels[remotePeer.Key]; ok {
// exclude notified peer and add ourselves
peersToSend := []string{req.Key}
peersToSend := []*Peer{peer}
for _, p := range peers {
if peer != p {
if remotePeer.Key != p.Key {
peersToSend = append(peersToSend, p)
}
}
update := &proto.SyncResponse{Peers: peersToSend}
update := toSyncResponse(s.config, peer, peersToSend)
channel <- &UpdateChannelMessage{Update: update}
}
}
@@ -161,6 +166,73 @@ func (s *Server) RegisterPeer(ctx context.Context, req *proto.RegisterPeerReques
return &proto.RegisterPeerResponse{}, nil
}
func toResponseProto(configProto Protocol) proto.HostConfig_Protocol {
switch configProto {
case UDP:
return proto.HostConfig_UDP
case DTLS:
return proto.HostConfig_DTLS
case HTTP:
return proto.HostConfig_HTTP
case HTTPS:
return proto.HostConfig_HTTPS
case TCP:
return proto.HostConfig_TCP
default:
//mbragin: todo something better?
panic(fmt.Errorf("unexpected config protocol type %v", configProto))
}
}
func toSyncResponse(config *Config, peer *Peer, peers []*Peer) *proto.SyncResponse {
var stuns []*proto.HostConfig
for _, stun := range config.Stuns {
stuns = append(stuns, &proto.HostConfig{
Uri: stun.URI,
Protocol: toResponseProto(stun.Proto),
})
}
var turns []*proto.ProtectedHostConfig
for _, turn := range config.Turns {
turns = append(turns, &proto.ProtectedHostConfig{
HostConfig: &proto.HostConfig{
Uri: turn.URI,
Protocol: toResponseProto(turn.Proto),
},
User: turn.Username,
Password: string(turn.Password),
})
}
wtConfig := &proto.WiretrusteeConfig{
Stuns: stuns,
Turns: turns,
Signal: &proto.HostConfig{
Uri: config.Signal.URI,
Protocol: toResponseProto(config.Signal.Proto),
},
}
pConfig := &proto.PeerConfig{
Address: peer.IP.String(),
}
remotePeers := make([]*proto.RemotePeerConfig, 0, len(peers))
for _, rPeer := range peers {
remotePeers = append(remotePeers, &proto.RemotePeerConfig{
WgPubKey: rPeer.Key,
AllowedIps: []string{fmt.Sprintf(AllowedIPsFormat, rPeer.IP)}, //todo /32
})
}
return &proto.SyncResponse{
WiretrusteeConfig: wtConfig,
PeerConfig: pConfig,
RemotePeers: remotePeers,
}
}
// IsHealthy indicates whether the service is healthy
func (s *Server) IsHealthy(ctx context.Context, req *proto.Empty) (*proto.Empty, error) {
return &proto.Empty{}, nil
@@ -195,16 +267,14 @@ func (s *Server) closeUpdatesChannel(peerKey string) {
}
// sendInitialSync sends initial proto.SyncResponse to the peer requesting synchronization
func (s *Server) sendInitialSync(peerKey wgtypes.Key, srv proto.ManagementService_SyncServer) error {
func (s *Server) sendInitialSync(peerKey wgtypes.Key, peer *Peer, srv proto.ManagementService_SyncServer) error {
peers, err := s.Store.GetPeersForAPeer(peerKey.String())
peers, err := s.accountManager.GetPeersForAPeer(peer.Key)
if err != nil {
log.Warnf("error getting a list of peers for a peer %s", peerKey.String())
log.Warnf("error getting a list of peers for a peer %s", peer.Key)
return err
}
plainResp := &proto.SyncResponse{
Peers: peers,
}
plainResp := toSyncResponse(s.config, peer, peers)
encryptedResp, err := encryption.EncryptMessage(peerKey, s.wgKey, plainResp)
if err != nil {
+9
View File
@@ -0,0 +1,9 @@
package server
type Store interface {
GetPeer(peerId string) (*Peer, error)
GetAccount(accountId string) (*Account, error)
GetPeerAccount(peerId string) (*Account, error)
GetAccountBySetupKey(setupKey string) (*Account, error)
SaveAccount(account *Account) error
}
+25
View File
@@ -0,0 +1,25 @@
{
"Stuns": [
{
"Proto": "udp",
"URI": "stun:stun.wiretrustee.com:3468",
"Username": "",
"Password": null
}
],
"Turns": [
{
"Proto": "udp",
"URI": "turn:stun.wiretrustee.com:3468",
"Username": "some_user",
"Password": "c29tZV9wYXNzd29yZA=="
}
],
"Signal": {
"Proto": "http",
"URI": "signal.wiretrustee.com:10000",
"Username": "",
"Password": null
},
"DataDir": ""
}
+8 -1
View File
@@ -7,7 +7,14 @@
"Key": "a2c8e62b-38f5-4553-b31e-dd66c696cebb"
}
},
"Peers": {}
"Network": {
"Id": "af1c8024-ha40-4ce2-9418-34653101fc3c",
"Net": {
"IP": "100.64.0.0",
"Mask": "/8AAAA=="
},
"Dns": null
}
}
}
}