mirror of
https://github.com/tim-beatham/smegmesh.git
synced 2025-08-13 15:07:12 +02:00
Compare commits
8 Commits
21-phoneti
...
25-modify-
Author | SHA1 | Date | |
---|---|---|---|
4c54022f63 | |||
bf0724f6e5 | |||
624bd6e921 | |||
7b939e0468 | |||
6e201ebaf5 | |||
06542da03c | |||
0d63cd6624 | |||
f13319cfc1 |
257
cmd/api/words.txt
Normal file
257
cmd/api/words.txt
Normal file
@ -0,0 +1,257 @@
|
||||
be
|
||||
to
|
||||
of
|
||||
it
|
||||
in
|
||||
we
|
||||
do
|
||||
he
|
||||
on
|
||||
go
|
||||
at
|
||||
if
|
||||
or
|
||||
up
|
||||
by
|
||||
hi
|
||||
the
|
||||
and
|
||||
you
|
||||
not
|
||||
for
|
||||
but
|
||||
say
|
||||
get
|
||||
she
|
||||
one
|
||||
all
|
||||
can
|
||||
out
|
||||
who
|
||||
now
|
||||
see
|
||||
way
|
||||
how
|
||||
lot
|
||||
yes
|
||||
use
|
||||
any
|
||||
day
|
||||
try
|
||||
put
|
||||
let
|
||||
why
|
||||
new
|
||||
off
|
||||
big
|
||||
too
|
||||
ask
|
||||
man
|
||||
bit
|
||||
end
|
||||
may
|
||||
own
|
||||
run
|
||||
pay
|
||||
job
|
||||
old
|
||||
kid
|
||||
bad
|
||||
few
|
||||
ago
|
||||
far
|
||||
buy
|
||||
set
|
||||
guy
|
||||
car
|
||||
sit
|
||||
war
|
||||
win
|
||||
yet
|
||||
top
|
||||
law
|
||||
cut
|
||||
low
|
||||
die
|
||||
eat
|
||||
age
|
||||
hit
|
||||
air
|
||||
add
|
||||
boy
|
||||
act
|
||||
tax
|
||||
oil
|
||||
eye
|
||||
son
|
||||
key
|
||||
fun
|
||||
dad
|
||||
dog
|
||||
arm
|
||||
fly
|
||||
box
|
||||
gas
|
||||
lie
|
||||
hot
|
||||
gun
|
||||
per
|
||||
art
|
||||
red
|
||||
fit
|
||||
bed
|
||||
fan
|
||||
mix
|
||||
mom
|
||||
sex
|
||||
bus
|
||||
fix
|
||||
bar
|
||||
lay
|
||||
ice
|
||||
bet
|
||||
bag
|
||||
due
|
||||
aid
|
||||
tie
|
||||
leg
|
||||
ban
|
||||
odd
|
||||
cup
|
||||
dry
|
||||
cry
|
||||
rid
|
||||
pop
|
||||
sir
|
||||
cat
|
||||
map
|
||||
sad
|
||||
sea
|
||||
aim
|
||||
sun
|
||||
fat
|
||||
row
|
||||
egg
|
||||
tea
|
||||
god
|
||||
wed
|
||||
tip
|
||||
ear
|
||||
hat
|
||||
net
|
||||
ill
|
||||
dig
|
||||
fee
|
||||
mad
|
||||
gap
|
||||
nor
|
||||
bid
|
||||
era
|
||||
toy
|
||||
sky
|
||||
bin
|
||||
owe
|
||||
wet
|
||||
tap
|
||||
pro
|
||||
ski
|
||||
cow
|
||||
pen
|
||||
van
|
||||
web
|
||||
pot
|
||||
sum
|
||||
cap
|
||||
log
|
||||
pub
|
||||
pig
|
||||
joy
|
||||
raw
|
||||
rat
|
||||
via
|
||||
lip
|
||||
two
|
||||
six
|
||||
ten
|
||||
lab
|
||||
ton
|
||||
mid
|
||||
bat
|
||||
hip
|
||||
gut
|
||||
sin
|
||||
non
|
||||
rub
|
||||
sub
|
||||
par
|
||||
pre
|
||||
ray
|
||||
cue
|
||||
dye
|
||||
fin
|
||||
ion
|
||||
neo
|
||||
hey
|
||||
wow
|
||||
mum
|
||||
bye
|
||||
aye
|
||||
jet
|
||||
sue
|
||||
pet
|
||||
flu
|
||||
cop
|
||||
ooh
|
||||
rip
|
||||
spy
|
||||
pie
|
||||
bug
|
||||
gum
|
||||
wan
|
||||
rap
|
||||
nut
|
||||
beg
|
||||
pin
|
||||
pit
|
||||
jam
|
||||
tag
|
||||
fax
|
||||
vet
|
||||
fry
|
||||
pad
|
||||
lad
|
||||
mud
|
||||
bay
|
||||
con
|
||||
pan
|
||||
gee
|
||||
toe
|
||||
dip
|
||||
shy
|
||||
gym
|
||||
zoo
|
||||
fox
|
||||
bow
|
||||
tin
|
||||
hop
|
||||
wee
|
||||
kit
|
||||
opt
|
||||
vow
|
||||
sew
|
||||
cab
|
||||
bee
|
||||
rob
|
||||
rig
|
||||
yep
|
||||
ego
|
||||
rib
|
||||
nod
|
||||
hug
|
||||
lap
|
||||
ash
|
||||
hum
|
||||
dam
|
||||
bum
|
||||
yen
|
||||
jar
|
@ -237,7 +237,6 @@ func main() {
|
||||
newMeshCmd := parser.NewCommand("new-mesh", "Create a new mesh")
|
||||
listMeshCmd := parser.NewCommand("list-meshes", "List meshes the node is connected to")
|
||||
joinMeshCmd := parser.NewCommand("join-mesh", "Join a mesh network")
|
||||
// getMeshCmd := parser.NewCommand("get-mesh", "Get a mesh network")
|
||||
enableInterfaceCmd := parser.NewCommand("enable-interface", "Enable A Specific Mesh Interface")
|
||||
getGraphCmd := parser.NewCommand("get-graph", "Convert a mesh into DOT format")
|
||||
leaveMeshCmd := parser.NewCommand("leave-mesh", "Leave a mesh network")
|
||||
|
@ -42,8 +42,29 @@ func (c *CrdtMeshManager) AddNode(node mesh.MeshNode) {
|
||||
c.doc.Path("nodes").Map().Set(crdt.HostEndpoint, crdt)
|
||||
}
|
||||
|
||||
func (c *CrdtMeshManager) GetNodeIds() []string {
|
||||
func (c *CrdtMeshManager) isPeer(nodeId string) bool {
|
||||
node, err := c.doc.Path("nodes").Map().Get(nodeId)
|
||||
|
||||
if err != nil || node.Kind() != automerge.KindMap {
|
||||
return false
|
||||
}
|
||||
|
||||
nodeType, err := node.Map().Get("type")
|
||||
|
||||
if err != nil || nodeType.Kind() != automerge.KindStr {
|
||||
return false
|
||||
}
|
||||
|
||||
return nodeType.Str() == string(conf.PEER_ROLE)
|
||||
}
|
||||
|
||||
func (c *CrdtMeshManager) GetPeers() []string {
|
||||
keys, _ := c.doc.Path("nodes").Map().Keys()
|
||||
|
||||
keys = lib.Filter(keys, func(s string) bool {
|
||||
return c.isPeer(s)
|
||||
})
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
@ -55,7 +76,7 @@ func (c *CrdtMeshManager) GetMesh() (mesh.MeshSnapshot, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.cache == nil || len(changes) > 3 {
|
||||
if c.cache == nil || len(changes) > 0 {
|
||||
c.lastCacheHash = c.LastHash
|
||||
cache, err := automerge.As[*MeshCrdt](c.doc.Root())
|
||||
|
||||
@ -113,7 +134,7 @@ func NewCrdtNodeManager(params *NewCrdtNodeMangerParams) (*CrdtMeshManager, erro
|
||||
// NodeExists: returns true if the node exists. Returns false
|
||||
func (m *CrdtMeshManager) NodeExists(key string) bool {
|
||||
node, err := m.doc.Path("nodes").Map().Get(key)
|
||||
return node.Kind() == automerge.KindMap && err != nil
|
||||
return node.Kind() == automerge.KindMap && err == nil
|
||||
}
|
||||
|
||||
func (m *CrdtMeshManager) GetNode(endpoint string) (mesh.MeshNode, error) {
|
||||
@ -450,6 +471,12 @@ func (m *MeshNodeCrdt) GetServices() map[string]string {
|
||||
return services
|
||||
}
|
||||
|
||||
// GetType refers to the type of the node. Peer means that the node is globally accessible
|
||||
// Client means the node is only accessible through another peer
|
||||
func (n *MeshNodeCrdt) GetType() conf.NodeType {
|
||||
return conf.NodeType(n.Type)
|
||||
}
|
||||
|
||||
func (m *MeshCrdt) GetNodes() map[string]mesh.MeshNode {
|
||||
nodes := make(map[string]mesh.MeshNode)
|
||||
|
||||
@ -464,6 +491,7 @@ func (m *MeshCrdt) GetNodes() map[string]mesh.MeshNode {
|
||||
Description: node.Description,
|
||||
Alias: node.Alias,
|
||||
Services: node.GetServices(),
|
||||
Type: node.Type,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ func (f *MeshNodeFactory) Build(params *mesh.MeshNodeFactoryParams) mesh.MeshNod
|
||||
Routes: map[string]interface{}{},
|
||||
Description: "",
|
||||
Alias: "",
|
||||
Type: string(params.Role),
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +51,13 @@ func (f *MeshNodeFactory) getAddress(params *mesh.MeshNodeFactoryParams) string
|
||||
} else if len(f.Config.Endpoint) != 0 {
|
||||
hostName = f.Config.Endpoint
|
||||
} else {
|
||||
hostName = lib.GetOutboundIP().String()
|
||||
ip, err := lib.GetPublicIP()
|
||||
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
hostName = ip.String()
|
||||
}
|
||||
|
||||
return hostName
|
||||
|
@ -11,6 +11,7 @@ type MeshNodeCrdt struct {
|
||||
Alias string `automerge:"alias"`
|
||||
Description string `automerge:"description"`
|
||||
Services map[string]string `automerge:"services"`
|
||||
Type string `automerge:"type"`
|
||||
}
|
||||
|
||||
// MeshCrdt: Represents the mesh network as a whole
|
||||
|
@ -16,6 +16,13 @@ func (m *WgMeshConfigurationError) Error() string {
|
||||
return m.msg
|
||||
}
|
||||
|
||||
type NodeType string
|
||||
|
||||
const (
|
||||
PEER_ROLE NodeType = "peer"
|
||||
CLIENT_ROLE NodeType = "client"
|
||||
)
|
||||
|
||||
type WgMeshConfiguration struct {
|
||||
// CertificatePath is the path to the certificate to use in mTLS
|
||||
CertificatePath string `yaml:"certificatePath"`
|
||||
@ -53,8 +60,12 @@ type WgMeshConfiguration struct {
|
||||
Profile bool `yaml:"profile"`
|
||||
// StubWg whether or not to stub the WireGuard types
|
||||
StubWg bool `yaml:"stubWg"`
|
||||
// What8Words file path for the what 8 words word list.
|
||||
What8Words string `yaml:"what8Words"`
|
||||
// Role specifies whether or not the user is globally accessible.
|
||||
// If the user is globaly accessible they specify themselves as a client.
|
||||
Role NodeType `yaml:"role"`
|
||||
// KeepAliveWg configures the implementation so that we send keep alive packets to peers.
|
||||
// KeepAlive can only be set if role is type client
|
||||
KeepAliveWg int `yaml:"keepAliveWg"`
|
||||
}
|
||||
|
||||
func ValidateConfiguration(c *WgMeshConfiguration) error {
|
||||
@ -136,6 +147,10 @@ func ValidateConfiguration(c *WgMeshConfiguration) error {
|
||||
}
|
||||
}
|
||||
|
||||
if c.Role == "" {
|
||||
c.Role = PEER_ROLE
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) {
|
||||
ipAllocator := &ip.ULABuilder{}
|
||||
interfaceManipulator := wg.NewWgInterfaceManipulator(params.Client)
|
||||
|
||||
configApplyer := mesh.NewWgMeshConfigApplyer()
|
||||
configApplyer := mesh.NewWgMeshConfigApplyer(params.Conf)
|
||||
|
||||
meshManagerParams := &mesh.NewMeshManagerParams{
|
||||
Conf: *params.Conf,
|
||||
|
@ -28,6 +28,9 @@ type JoinMeshArgs struct {
|
||||
// Endpoint is the routable address of this machine. If not provided
|
||||
// defaults to the default address
|
||||
Endpoint string
|
||||
// Client specifies whether we should join as a client of the peer
|
||||
// we are connecting to
|
||||
Client bool
|
||||
}
|
||||
|
||||
type PutServiceArgs struct {
|
||||
|
46
pkg/lib/hashing.go
Normal file
46
pkg/lib/hashing.go
Normal file
@ -0,0 +1,46 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"hash/fnv"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type consistentHashRecord[V any] struct {
|
||||
record V
|
||||
value int
|
||||
}
|
||||
|
||||
func HashString(value string) int {
|
||||
f := fnv.New32a()
|
||||
f.Write([]byte(value))
|
||||
return int(f.Sum32())
|
||||
}
|
||||
|
||||
// ConsistentHash implementation. Traverse the values until we find a key
|
||||
// less than ours.
|
||||
func ConsistentHash[V any](values []V, client V, keyFunc func(V) int) V {
|
||||
if len(values) == 0 {
|
||||
panic("values is empty")
|
||||
}
|
||||
|
||||
vs := Map(values, func(v V) consistentHashRecord[V] {
|
||||
return consistentHashRecord[V]{
|
||||
v,
|
||||
keyFunc(v),
|
||||
}
|
||||
})
|
||||
|
||||
sort.SliceStable(vs, func(i, j int) bool {
|
||||
return vs[i].value < vs[j].value
|
||||
})
|
||||
|
||||
ourKey := keyFunc(client)
|
||||
|
||||
for _, record := range vs {
|
||||
if ourKey < record.value {
|
||||
return record.record
|
||||
}
|
||||
}
|
||||
|
||||
return vs[0].record
|
||||
}
|
@ -1,8 +1,11 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GetOutboundIP: gets the oubound IP of this packet
|
||||
@ -15,3 +18,44 @@ func GetOutboundIP() net.IP {
|
||||
localAddr := conn.LocalAddr().(*net.UDPAddr)
|
||||
return localAddr.IP
|
||||
}
|
||||
|
||||
const IP_SERVICE = "https://api.ipify.org?format=json"
|
||||
|
||||
type IpResponse struct {
|
||||
Ip string `json:"ip"`
|
||||
}
|
||||
|
||||
func (i *IpResponse) GetIP() net.IP {
|
||||
return net.ParseIP(i.Ip)
|
||||
}
|
||||
|
||||
// GetPublicIP: get the nodes public IP address. For when a node is behind NAT
|
||||
func GetPublicIP() (net.IP, error) {
|
||||
req, err := http.NewRequest(http.MethodGet, IP_SERVICE, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resBody, err := io.ReadAll(res.Body)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var jsonResponse IpResponse
|
||||
|
||||
err = json.Unmarshal([]byte(resBody), &jsonResponse)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return jsonResponse.GetIP(), nil
|
||||
}
|
||||
|
@ -3,7 +3,11 @@ package mesh
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/tim-beatham/wgmesh/pkg/conf"
|
||||
"github.com/tim-beatham/wgmesh/pkg/lib"
|
||||
"github.com/tim-beatham/wgmesh/pkg/route"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
@ -16,10 +20,12 @@ type MeshConfigApplyer interface {
|
||||
|
||||
// WgMeshConfigApplyer applies WireGuard configuration
|
||||
type WgMeshConfigApplyer struct {
|
||||
meshManager MeshManager
|
||||
meshManager MeshManager
|
||||
config *conf.WgMeshConfiguration
|
||||
routeInstaller route.RouteInstaller
|
||||
}
|
||||
|
||||
func convertMeshNode(node MeshNode) (*wgtypes.PeerConfig, error) {
|
||||
func (m *WgMeshConfigApplyer) convertMeshNode(node MeshNode, peerToClients map[string][]net.IPNet) (*wgtypes.PeerConfig, error) {
|
||||
endpoint, err := net.ResolveUDPAddr("udp", node.GetWgEndpoint())
|
||||
|
||||
if err != nil {
|
||||
@ -40,10 +46,19 @@ func convertMeshNode(node MeshNode) (*wgtypes.PeerConfig, error) {
|
||||
allowedips = append(allowedips, *ipnet)
|
||||
}
|
||||
|
||||
clients, ok := peerToClients[node.GetWgHost().String()]
|
||||
|
||||
if ok {
|
||||
allowedips = append(allowedips, clients...)
|
||||
}
|
||||
|
||||
keepAlive := time.Duration(m.config.KeepAliveWg) * time.Second
|
||||
|
||||
peerConfig := wgtypes.PeerConfig{
|
||||
PublicKey: pubKey,
|
||||
Endpoint: endpoint,
|
||||
AllowedIPs: allowedips,
|
||||
PublicKey: pubKey,
|
||||
Endpoint: endpoint,
|
||||
AllowedIPs: allowedips,
|
||||
PersistentKeepaliveInterval: &keepAlive,
|
||||
}
|
||||
|
||||
return &peerConfig, nil
|
||||
@ -56,13 +71,66 @@ func (m *WgMeshConfigApplyer) updateWgConf(mesh MeshProvider) error {
|
||||
return err
|
||||
}
|
||||
|
||||
nodes := snap.GetNodes()
|
||||
nodes := lib.MapValues(snap.GetNodes())
|
||||
peerConfigs := make([]wgtypes.PeerConfig, len(nodes))
|
||||
|
||||
peers := lib.Filter(nodes, func(mn MeshNode) bool {
|
||||
return mn.GetType() == conf.PEER_ROLE
|
||||
})
|
||||
|
||||
var count int = 0
|
||||
|
||||
self, err := m.meshManager.GetSelf(mesh.GetMeshId())
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rtnl, err := lib.NewRtNetlinkConfig()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
peerToClients := make(map[string][]net.IPNet)
|
||||
|
||||
for _, n := range nodes {
|
||||
peer, err := convertMeshNode(n)
|
||||
if NodeEquals(n, self) {
|
||||
continue
|
||||
}
|
||||
|
||||
if n.GetType() == conf.CLIENT_ROLE && len(peers) > 0 && self.GetType() == conf.CLIENT_ROLE {
|
||||
peer := lib.ConsistentHash(peers, n, func(mn MeshNode) int {
|
||||
return lib.HashString(mn.GetWgHost().String())
|
||||
})
|
||||
|
||||
dev, err := mesh.GetDevice()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rtnl.AddRoute(dev.Name, lib.Route{
|
||||
Gateway: peer.GetWgHost().IP,
|
||||
Destination: *n.GetWgHost(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clients, ok := peerToClients[peer.GetWgHost().String()]
|
||||
|
||||
if !ok {
|
||||
clients = make([]net.IPNet, 0)
|
||||
peerToClients[peer.GetWgHost().String()] = clients
|
||||
}
|
||||
|
||||
peerToClients[peer.GetWgHost().String()] = append(clients, *n.GetWgHost())
|
||||
continue
|
||||
}
|
||||
|
||||
peer, err := m.convertMeshNode(n, peerToClients)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@ -122,6 +190,9 @@ func (m *WgMeshConfigApplyer) SetMeshManager(manager MeshManager) {
|
||||
m.meshManager = manager
|
||||
}
|
||||
|
||||
func NewWgMeshConfigApplyer() MeshConfigApplyer {
|
||||
return &WgMeshConfigApplyer{}
|
||||
func NewWgMeshConfigApplyer(config *conf.WgMeshConfiguration) MeshConfigApplyer {
|
||||
return &WgMeshConfigApplyer{
|
||||
config: config,
|
||||
routeInstaller: route.NewRouteInstaller(),
|
||||
}
|
||||
}
|
||||
|
@ -256,6 +256,16 @@ func (s *MeshManagerImpl) AddSelf(params *AddSelfParams) error {
|
||||
return fmt.Errorf("addself: mesh %s does not exist", params.MeshId)
|
||||
}
|
||||
|
||||
if params.WgPort == 0 && !s.conf.StubWg {
|
||||
device, err := mesh.GetDevice()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
params.WgPort = device.ListenPort
|
||||
}
|
||||
|
||||
pubKey, err := s.GetPublicKey(params.MeshId)
|
||||
|
||||
if err != nil {
|
||||
@ -273,6 +283,7 @@ func (s *MeshManagerImpl) AddSelf(params *AddSelfParams) error {
|
||||
NodeIP: nodeIP,
|
||||
WgPort: params.WgPort,
|
||||
Endpoint: params.Endpoint,
|
||||
Role: s.conf.Role,
|
||||
})
|
||||
|
||||
if !s.conf.StubWg {
|
||||
@ -328,6 +339,7 @@ func (s *MeshManagerImpl) GetSelf(meshId string) (MeshNode, error) {
|
||||
return nil, fmt.Errorf("mesh %s does not exist", meshId)
|
||||
}
|
||||
|
||||
logging.Log.WriteInfof(s.HostParameters.HostEndpoint)
|
||||
node, err := meshInstance.GetNode(s.HostParameters.HostEndpoint)
|
||||
|
||||
if err != nil {
|
||||
@ -338,6 +350,10 @@ func (s *MeshManagerImpl) GetSelf(meshId string) (MeshNode, error) {
|
||||
}
|
||||
|
||||
func (s *MeshManagerImpl) ApplyConfig() error {
|
||||
if s.conf.StubWg {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := s.configApplyer.ApplyConfig()
|
||||
|
||||
if err != nil {
|
||||
@ -440,7 +456,8 @@ func NewMeshManager(params *NewMeshManagerParams) MeshManager {
|
||||
|
||||
switch params.Conf.Endpoint {
|
||||
case "":
|
||||
hostParams.HostEndpoint = fmt.Sprintf("%s:%s", lib.GetOutboundIP().String(), params.Conf.GrpcPort)
|
||||
ip, _ := lib.GetPublicIP()
|
||||
hostParams.HostEndpoint = fmt.Sprintf("%s:%s", ip.String(), params.Conf.GrpcPort)
|
||||
default:
|
||||
hostParams.HostEndpoint = fmt.Sprintf("%s:%s", params.Conf.Endpoint, params.Conf.GrpcPort)
|
||||
}
|
||||
|
@ -201,8 +201,8 @@ func TestSetDescription(t *testing.T) {
|
||||
manager := getMeshManager()
|
||||
description := "wooooo"
|
||||
|
||||
meshId1, _ := manager.CreateMesh("wg0", 5000)
|
||||
meshId2, _ := manager.CreateMesh("wg0", 5001)
|
||||
meshId1, _ := manager.CreateMesh(5000)
|
||||
meshId2, _ := manager.CreateMesh(5001)
|
||||
|
||||
manager.AddSelf(&AddSelfParams{
|
||||
MeshId: meshId1,
|
||||
@ -225,8 +225,8 @@ func TestSetDescription(t *testing.T) {
|
||||
func TestUpdateTimeStampUpdatesAllMeshes(t *testing.T) {
|
||||
manager := getMeshManager()
|
||||
|
||||
meshId1, _ := manager.CreateMesh("wg0", 5000)
|
||||
meshId2, _ := manager.CreateMesh("wg0", 5001)
|
||||
meshId1, _ := manager.CreateMesh(5000)
|
||||
meshId2, _ := manager.CreateMesh(5001)
|
||||
|
||||
manager.AddSelf(&AddSelfParams{
|
||||
MeshId: meshId1,
|
||||
|
@ -21,6 +21,11 @@ type MeshNodeStub struct {
|
||||
description string
|
||||
}
|
||||
|
||||
// GetType implements MeshNode.
|
||||
func (*MeshNodeStub) GetType() conf.NodeType {
|
||||
return PEER
|
||||
}
|
||||
|
||||
// GetServices implements MeshNode.
|
||||
func (*MeshNodeStub) GetServices() map[string]string {
|
||||
return make(map[string]string)
|
||||
@ -77,28 +82,28 @@ type MeshProviderStub struct {
|
||||
}
|
||||
|
||||
// GetNodeIds implements MeshProvider.
|
||||
func (*MeshProviderStub) GetNodeIds() []string {
|
||||
panic("unimplemented")
|
||||
func (*MeshProviderStub) GetPeers() []string {
|
||||
return make([]string, 0)
|
||||
}
|
||||
|
||||
// GetNode implements MeshProvider.
|
||||
func (*MeshProviderStub) GetNode(string) (MeshNode, error) {
|
||||
panic("unimplemented")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NodeExists implements MeshProvider.
|
||||
func (*MeshProviderStub) NodeExists(string) bool {
|
||||
panic("unimplemented")
|
||||
return false
|
||||
}
|
||||
|
||||
// AddService implements MeshProvider.
|
||||
func (*MeshProviderStub) AddService(nodeId string, key string, value string) error {
|
||||
panic("unimplemented")
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveService implements MeshProvider.
|
||||
func (*MeshProviderStub) RemoveService(nodeId string, key string) error {
|
||||
panic("unimplemented")
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetAlias implements MeshProvider.
|
||||
@ -108,7 +113,7 @@ func (*MeshProviderStub) SetAlias(nodeId string, alias string) error {
|
||||
|
||||
// RemoveRoutes implements MeshProvider.
|
||||
func (*MeshProviderStub) RemoveRoutes(nodeId string, route ...string) error {
|
||||
panic("unimplemented")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Prune implements MeshProvider.
|
||||
|
@ -4,13 +4,19 @@ package mesh
|
||||
|
||||
import (
|
||||
"net"
|
||||
"slices"
|
||||
|
||||
"github.com/tim-beatham/wgmesh/pkg/conf"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
const (
|
||||
// Data Exchanged Between Peers
|
||||
PEER conf.NodeType = "peer"
|
||||
// Data Exchanged Between Clients
|
||||
CLIENT conf.NodeType = "client"
|
||||
)
|
||||
|
||||
// MeshNode represents an implementation of a node in a mesh
|
||||
type MeshNode interface {
|
||||
// GetHostEndpoint: gets the gRPC endpoint of the node
|
||||
@ -34,46 +40,12 @@ type MeshNode interface {
|
||||
GetAlias() string
|
||||
// GetServices: returns a list of services offered by the node
|
||||
GetServices() map[string]string
|
||||
GetType() conf.NodeType
|
||||
}
|
||||
|
||||
// NodeEquals: determines if two mesh nodes are equivalent to one another
|
||||
func NodeEquals(node1, node2 MeshNode) bool {
|
||||
if node1.GetHostEndpoint() != node2.GetHostEndpoint() {
|
||||
return false
|
||||
}
|
||||
|
||||
node1Pub, _ := node1.GetPublicKey()
|
||||
node2Pub, _ := node2.GetPublicKey()
|
||||
|
||||
if node1Pub != node2Pub {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetWgEndpoint() != node2.GetWgEndpoint() {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetWgHost() != node2.GetWgHost() {
|
||||
return false
|
||||
}
|
||||
|
||||
if !slices.Equal(node1.GetRoutes(), node2.GetRoutes()) {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetIdentifier() != node2.GetIdentifier() {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetDescription() != node2.GetDescription() {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetAlias() != node2.GetAlias() {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return node1.GetHostEndpoint() == node2.GetHostEndpoint()
|
||||
}
|
||||
|
||||
type MeshSnapshot interface {
|
||||
@ -129,7 +101,7 @@ type MeshProvider interface {
|
||||
// Prune: prunes all nodes that have not updated their timestamp in
|
||||
// pruneAmount seconds
|
||||
Prune(pruneAmount int) error
|
||||
GetNodeIds() []string
|
||||
GetPeers() []string
|
||||
}
|
||||
|
||||
// HostParameters contains the IDs of a node
|
||||
@ -158,6 +130,7 @@ type MeshNodeFactoryParams struct {
|
||||
NodeIP net.IP
|
||||
WgPort int
|
||||
Endpoint string
|
||||
Role conf.NodeType
|
||||
}
|
||||
|
||||
// MeshBuilder build the hosts mesh node for it to be added to the mesh
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jmespath/go-jmespath"
|
||||
"github.com/tim-beatham/wgmesh/pkg/conf"
|
||||
"github.com/tim-beatham/wgmesh/pkg/lib"
|
||||
"github.com/tim-beatham/wgmesh/pkg/mesh"
|
||||
)
|
||||
@ -28,11 +29,12 @@ type QueryNode struct {
|
||||
PublicKey string `json:"publicKey"`
|
||||
WgEndpoint string `json:"wgEndpoint"`
|
||||
WgHost string `json:"wgHost"`
|
||||
Timestamp int64 `json:"timestmap"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Description string `json:"description"`
|
||||
Routes []string `json:"routes"`
|
||||
Alias string `json:"alias"`
|
||||
Services map[string]string `json:"services"`
|
||||
Type conf.NodeType `json:"type"`
|
||||
}
|
||||
|
||||
func (m *QueryError) Error() string {
|
||||
@ -80,6 +82,7 @@ func MeshNodeToQueryNode(node mesh.MeshNode) *QueryNode {
|
||||
queryNode.Description = node.GetDescription()
|
||||
queryNode.Alias = node.GetAlias()
|
||||
queryNode.Services = node.GetServices()
|
||||
queryNode.Type = node.GetType()
|
||||
|
||||
return queryNode
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ func (s *SyncerImpl) Sync(meshId string) error {
|
||||
}
|
||||
}
|
||||
|
||||
nodeNames := s.manager.GetMesh(meshId).GetNodeIds()
|
||||
nodeNames := s.manager.GetMesh(meshId).GetPeers()
|
||||
|
||||
self, err := s.manager.GetSelf(meshId)
|
||||
|
||||
|
@ -5,20 +5,6 @@ import (
|
||||
"github.com/tim-beatham/wgmesh/pkg/lib"
|
||||
)
|
||||
|
||||
// SyncScheduler: Loops through all nodes in the mesh and runs a schedule to
|
||||
// sync each event
|
||||
type SyncScheduler interface {
|
||||
Run() error
|
||||
Stop() error
|
||||
}
|
||||
|
||||
// SyncSchedulerImpl scheduler for sync scheduling
|
||||
type SyncSchedulerImpl struct {
|
||||
quit chan struct{}
|
||||
server *ctrlserver.MeshCtrlServer
|
||||
syncer Syncer
|
||||
}
|
||||
|
||||
// Run implements SyncScheduler.
|
||||
func syncFunction(syncer Syncer) lib.TimerFunc {
|
||||
return func() error {
|
||||
|
@ -64,11 +64,11 @@ func (s *SyncServiceImpl) SyncMesh(stream rpc.SyncService_SyncMeshServer) error
|
||||
|
||||
syncer = mesh.GetSyncer()
|
||||
} else if meshId != in.MeshId {
|
||||
return errors.New("Differing MeshIDs")
|
||||
return errors.New("differing meshids")
|
||||
}
|
||||
|
||||
if syncer == nil {
|
||||
return errors.New("Syncer should not be nil")
|
||||
return errors.New("syncer should not be nil")
|
||||
}
|
||||
|
||||
msg, moreMessages := syncer.GenerateMessage()
|
||||
|
@ -2,8 +2,8 @@ package wg
|
||||
|
||||
type WgInterfaceManipulatorStub struct{}
|
||||
|
||||
func (i *WgInterfaceManipulatorStub) CreateInterface(port int) error {
|
||||
return nil
|
||||
func (i *WgInterfaceManipulatorStub) CreateInterface(port int) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (i *WgInterfaceManipulatorStub) AddAddress(ifName string, addr string) error {
|
||||
|
Reference in New Issue
Block a user