Incorporated automerge

This commit is contained in:
Tim Beatham 2023-10-06 11:52:51 +01:00
parent 81e2d16316
commit 47e260e310
10 changed files with 290 additions and 222 deletions

View File

@ -64,8 +64,8 @@ func getMesh(client *ipcRpc.Client, meshId string) {
for _, node := range reply.Nodes { for _, node := range reply.Nodes {
fmt.Println("Public Key: " + node.PublicKey) fmt.Println("Public Key: " + node.PublicKey)
fmt.Println("WireGuard Endpoint: " + node.HostEndpoint) fmt.Println("WireGuard Endpoint: " + node.WgEndpoint)
fmt.Println("Control Endpoint: " + node.WgEndpoint) fmt.Println("Control Endpoint: " + node.HostEndpoint)
fmt.Println("Wg IP: " + node.WgHost) fmt.Println("Wg IP: " + node.WgHost)
fmt.Println("---") fmt.Println("---")
} }
@ -77,7 +77,7 @@ func enableInterface(client *ipcRpc.Client, meshId string) {
err := client.Call("RobinIpc.EnableInterface", &meshId, &reply) err := client.Call("RobinIpc.EnableInterface", &meshId, &reply)
if err != nil { if err != nil {
(err.Error()) fmt.Println(err.Error())
return return
} }

View File

@ -1,11 +1,19 @@
package crdt package crdt
import "github.com/automerge/automerge-go" import (
"net"
"github.com/automerge/automerge-go"
logging "github.com/tim-beatham/wgmesh/pkg/log"
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
// CrdtNodeManager manages nodes in the crdt mesh // CrdtNodeManager manages nodes in the crdt mesh
type CrdtNodeManager struct { type CrdtNodeManager struct {
meshId string meshId string
IfName string IfName string
Client *wgctrl.Client
doc *automerge.Doc doc *automerge.Doc
} }
@ -13,6 +21,17 @@ func (c *CrdtNodeManager) AddNode(crdt MeshNodeCrdt) {
c.doc.Path("nodes").Map().Set(crdt.PublicKey, crdt) c.doc.Path("nodes").Map().Set(crdt.PublicKey, crdt)
} }
func (c *CrdtNodeManager) applyWg() error {
snapshot, err := c.GetCrdt()
if err != nil {
return err
}
updateWgConf(c.IfName, snapshot.Nodes, *c.Client)
return nil
}
// GetCrdt(): Converts the document into a struct // GetCrdt(): Converts the document into a struct
func (c *CrdtNodeManager) GetCrdt() (*MeshCrdt, error) { func (c *CrdtNodeManager) GetCrdt() (*MeshCrdt, error) {
return automerge.As[*MeshCrdt](c.doc.Root()) return automerge.As[*MeshCrdt](c.doc.Root())
@ -27,27 +46,92 @@ func (c *CrdtNodeManager) Load(bytes []byte) error {
} }
c.doc = doc c.doc = doc
c.applyWg()
return nil return nil
} }
// Save: Save an entire mesh network // Save: Save an entire mesh network
func (c *CrdtNodeManager) Save(doc []byte) []byte { func (c *CrdtNodeManager) Save() []byte {
return c.doc.Save() return c.doc.Save()
} }
func (c *CrdtNodeManager) LoadChanges(changes []byte) { func (c *CrdtNodeManager) LoadChanges(changes []byte) error {
c.doc.LoadIncremental(changes) err := c.doc.LoadIncremental(changes)
if err != nil {
return err
}
return c.applyWg()
} }
func (c *CrdtNodeManager) SaveChanges() []byte { func (c *CrdtNodeManager) SaveChanges() []byte {
return c.SaveChanges() return c.doc.SaveIncremental()
} }
// NewCrdtNodeManager: Create a new crdt node manager // NewCrdtNodeManager: Create a new crdt node manager
func NewCrdtNodeManager(meshId, devName string) *CrdtNodeManager { func NewCrdtNodeManager(meshId, devName string, client *wgctrl.Client) *CrdtNodeManager {
var manager CrdtNodeManager var manager CrdtNodeManager
manager.meshId = meshId manager.meshId = meshId
manager.doc = automerge.New() manager.doc = automerge.New()
manager.IfName = devName manager.IfName = devName
manager.Client = client
return &manager return &manager
} }
func convertMeshNode(node MeshNodeCrdt) (*wgtypes.PeerConfig, error) {
peerEndpoint, err := net.ResolveUDPAddr("udp", node.WgEndpoint)
if err != nil {
return nil, err
}
peerPublic, err := wgtypes.ParseKey(node.PublicKey)
if err != nil {
return nil, err
}
allowedIps := make([]net.IPNet, 1)
_, ipnet, err := net.ParseCIDR(node.WgHost)
if err != nil {
return nil, err
}
allowedIps[0] = *ipnet
peerConfig := wgtypes.PeerConfig{
PublicKey: peerPublic,
Endpoint: peerEndpoint,
AllowedIPs: allowedIps,
}
return &peerConfig, nil
}
func updateWgConf(devName string, nodes map[string]MeshNodeCrdt, client wgctrl.Client) error {
peerConfigs := make([]wgtypes.PeerConfig, len(nodes))
var count int = 0
for _, n := range nodes {
peer, err := convertMeshNode(n)
logging.InfoLog.Println(n.HostEndpoint)
if err != nil {
return err
}
peerConfigs[count] = *peer
count++
}
cfg := wgtypes.Config{
Peers: peerConfigs,
ReplacePeers: true,
}
client.ConfigureDevice(devName, cfg)
return nil
}

View File

@ -29,7 +29,7 @@ type NewCtrlServerParams struct {
func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) { func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) {
ctrlServer := new(MeshCtrlServer) ctrlServer := new(MeshCtrlServer)
ctrlServer.Client = params.WgClient ctrlServer.Client = params.WgClient
ctrlServer.MeshManager = &manager.MeshManger{} ctrlServer.MeshManager = manager.NewMeshManager(*params.WgClient)
connManagerParams := conn.NewJwtConnectionManagerParams{ connManagerParams := conn.NewJwtConnectionManagerParams{
CertificatePath: params.Conf.CertificatePath, CertificatePath: params.Conf.CertificatePath,

View File

@ -25,6 +25,7 @@ message GetMeshReply {
message JoinMeshRequest { message JoinMeshRequest {
bytes changes = 1; bytes changes = 1;
string meshId = 2;
} }
message JoinMeshReply { message JoinMeshReply {

View File

@ -7,6 +7,7 @@ import (
"net/rpc" "net/rpc"
"os" "os"
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver" "github.com/tim-beatham/wgmesh/pkg/ctrlserver"
) )
@ -16,7 +17,7 @@ type JoinMeshArgs struct {
} }
type GetMeshReply struct { type GetMeshReply struct {
Nodes []ctrlserver.MeshNode Nodes []crdt.MeshNodeCrdt
} }
type MeshIpc interface { type MeshIpc interface {

View File

@ -4,7 +4,6 @@ import (
"errors" "errors"
crdt "github.com/tim-beatham/wgmesh/pkg/automerge" crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
"github.com/tim-beatham/wgmesh/pkg/lib"
"github.com/tim-beatham/wgmesh/pkg/wg" "github.com/tim-beatham/wgmesh/pkg/wg"
"golang.zx2c4.com/wireguard/wgctrl" "golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
@ -28,34 +27,31 @@ func (m *MeshManger) CreateMesh(devName string) (string, error) {
return "", err return "", err
} }
nodeManager := crdt.NewCrdtNodeManager(key.String(), devName) nodeManager := crdt.NewCrdtNodeManager(key.String(), devName, m.Client)
m.Meshes[key.String()] = nodeManager m.Meshes[key.String()] = nodeManager
return key.String(), nil return key.String(), nil
} }
// UpdateMesh: merge the changes and save it to the device // UpdateMesh: merge the changes and save it to the device
func (m *MeshManger) UpdateMesh(meshId string, changes []byte, client wgctrl.Client) error { func (m *MeshManger) UpdateMesh(meshId string, changes []byte) error {
mesh, ok := m.Meshes[meshId] mesh, ok := m.Meshes[meshId]
if !ok { if !ok {
return errors.New("mesh does not exist") return errors.New("mesh does not exist")
} }
mesh.LoadChanges(changes) err := mesh.LoadChanges(changes)
crdt, err := mesh.GetCrdt()
if err != nil { if err != nil {
return err return err
} }
wg.UpdateWgConf(m.Meshes[meshId].IfName, crdt.Nodes, client)
return nil return nil
} }
// AddMesh: Add the mesh to the list of meshes // AddMesh: Add the mesh to the list of meshes
func (m *MeshManger) AddMesh(meshId string, devName string, meshBytes []byte) error { func (m *MeshManger) AddMesh(meshId string, devName string, meshBytes []byte) error {
mesh := crdt.NewCrdtNodeManager(meshId, devName) mesh := crdt.NewCrdtNodeManager(meshId, devName, m.Client)
err := mesh.Load(meshBytes) err := mesh.Load(meshBytes)
if err != nil { if err != nil {
@ -71,6 +67,11 @@ func (m *MeshManger) AddMeshNode(meshId string, node crdt.MeshNodeCrdt) {
m.Meshes[meshId].AddNode(node) m.Meshes[meshId].AddNode(node)
} }
func (m *MeshManger) GetMesh(meshId string) *crdt.CrdtNodeManager {
theMesh, _ := m.Meshes[meshId]
return theMesh
}
// EnableInterface: Enables the given WireGuard interface. // EnableInterface: Enables the given WireGuard interface.
func (s *MeshManger) EnableInterface(meshId string) error { func (s *MeshManger) EnableInterface(meshId string) error {
mesh, contains := s.Meshes[meshId] mesh, contains := s.Meshes[meshId]
@ -85,14 +86,19 @@ func (s *MeshManger) EnableInterface(meshId string) error {
return err return err
} }
endPoint := lib.GetOutboundIP().String() + ":8080" dev, err := s.Client.Device(mesh.IfName)
node, contains := crdt.Nodes[endPoint]
if err != nil {
return err
}
node, contains := crdt.Nodes[dev.PublicKey.String()]
if !contains { if !contains {
return errors.New("Node does not exist in the mesh") return errors.New("Node does not exist in the mesh")
} }
return wg.EnableInterface(mesh.IfName, node.WgEndpoint) return wg.EnableInterface(mesh.IfName, node.WgHost)
} }
// GetPublicKey: Gets the public key of the WireGuard mesh // GetPublicKey: Gets the public key of the WireGuard mesh
@ -111,3 +117,7 @@ func (s *MeshManger) GetPublicKey(meshId string) (*wgtypes.Key, error) {
return &dev.PublicKey, nil return &dev.PublicKey, nil
} }
func NewMeshManager(client wgctrl.Client) *MeshManger {
return &MeshManger{Meshes: make(map[string]*crdt.CrdtNodeManager), Client: &client}
}

View File

@ -3,7 +3,7 @@ package robin
import ( import (
"context" "context"
"errors" "errors"
"slices" "fmt"
"strconv" "strconv"
"time" "time"
@ -15,7 +15,6 @@ import (
logging "github.com/tim-beatham/wgmesh/pkg/log" logging "github.com/tim-beatham/wgmesh/pkg/log"
"github.com/tim-beatham/wgmesh/pkg/rpc" "github.com/tim-beatham/wgmesh/pkg/rpc"
"github.com/tim-beatham/wgmesh/pkg/wg" "github.com/tim-beatham/wgmesh/pkg/wg"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
type RobinIpc struct { type RobinIpc struct {
@ -35,12 +34,12 @@ func (n *RobinIpc) CreateMesh(name string, reply *string) error {
return err return err
} }
outBoundIp := lib.GetOutboundIP().String() outBoundIp := lib.GetOutboundIP()
meshNode := crdt.MeshNodeCrdt{ meshNode := crdt.MeshNodeCrdt{
HostEndpoint: outBoundIp + ":8080", HostEndpoint: outBoundIp.String() + ":8080",
PublicKey: pubKey.String(), PublicKey: pubKey.String(),
WgEndpoint: outBoundIp + ":51820", WgEndpoint: outBoundIp.String() + ":51820",
WgHost: nodeIP.String() + "/128", WgHost: nodeIP.String() + "/128",
} }
@ -60,116 +59,115 @@ func (n *RobinIpc) ListMeshes(name string, reply *map[string]ctrlserver.Mesh) er
} }
func updateMesh(n *RobinIpc, meshId string, endPoint string) error { func updateMesh(n *RobinIpc, meshId string, endPoint string) error {
peerConn, err := n.Server.ConnectionManager.GetConnection(endPoint) // peerConn, err := n.Server.ConnectionManager.GetConnection(endPoint)
if err != nil { // if err != nil {
return err // return err
} // }
conn, err := peerConn.GetClient() // conn, err := peerConn.GetClient()
c := rpc.NewMeshCtrlServerClient(conn) // c := rpc.NewMeshCtrlServerClient(conn)
authContext, err := peerConn.CreateAuthContext(meshId) // authContext, err := peerConn.CreateAuthContext(meshId)
if err != nil { // if err != nil {
return err // return err
} // }
ctx, cancel := context.WithTimeout(authContext, time.Second) // ctx, cancel := context.WithTimeout(authContext, time.Second)
defer cancel() // defer cancel()
getMeshReq := rpc.GetMeshRequest{ // getMeshReq := rpc.GetMeshRequest{
MeshId: meshId, // MeshId: meshId,
} // }
r, err := c.GetMesh(ctx, &getMeshReq) // r, err := c.GetMesh(ctx, &getMeshReq)
if err != nil { // if err != nil {
return err // return err
} // }
key, err := wgtypes.ParseKey(meshId) // key, err := wgtypes.ParseKey(meshId)
if err != nil { // if err != nil {
return err // return err
} // }
err := n.Server.MeshManager.AddMesh(meshId, "wgmesh", r.Mesh) // err := n.Server.MeshManager.AddMesh(meshId, "wgmesh", r.Mesh)
if err != nil { // if err != nil {
return err // return err
} // }
return nil return nil
} }
func updatePeer(n *RobinIpc, node ctrlserver.MeshNode, wgHost string, meshId string) error { func updatePeer(n *RobinIpc, node ctrlserver.MeshNode, wgHost string, meshId string) error {
err := n.Authenticate(meshId, node.HostEndpoint) // // err := n.Authenticate(meshId, node.HostEndpoint)
if err != nil { // // if err != nil {
return err // // return err
} // // }
peerConnection, err := n.Server.ConnectionManager.GetConnection(node.HostEndpoint) // peerConnection, err := n.Server.ConnectionManager.GetConnection(node.HostEndpoint)
if err != nil { // if err != nil {
return err // return err
} // }
conn, err := peerConnection.GetClient() // conn, err := peerConnection.GetClient()
if err != nil { // if err != nil {
return err // return err
} // }
c := rpc.NewMeshCtrlServerClient(conn) // c := rpc.NewMeshCtrlServerClient(conn)
authContext, err := peerConnection.CreateAuthContext(meshId) // authContext, err := peerConnection.CreateAuthContext(meshId)
if err != nil { // if err != nil {
return err // return err
} // }
ctx, cancel := context.WithTimeout(authContext, time.Second) // ctx, cancel := context.WithTimeout(authContext, time.Second)
defer cancel() // defer cancel()
dev := n.Server.GetDevice() // dev := n.Server.GetDevice()
joinMeshReq := rpc.JoinMeshRequest{ // joinMeshReq := rpc.JoinMeshRequest{
MeshId: meshId, // MeshId: meshId,
HostPort: 8080, // HostPort: 8080,
PublicKey: dev.PublicKey.String(), // PublicKey: dev.PublicKey.String(),
WgPort: int32(dev.ListenPort), // WgPort: int32(dev.ListenPort),
WgIp: wgHost, // WgIp: wgHost + "/128",
} // }
r, err := c.JoinMesh(ctx, &joinMeshReq) // r, err := c.JoinMesh(ctx, &joinMeshReq)
if err != nil { // if err != nil {
return err // return err
} // }
if !r.GetSuccess() { // if !r.GetSuccess() {
return errors.New("Could not join the mesh") // return errors.New("Could not join the mesh")
} // }
return nil return nil
} }
func updatePeers(n *RobinIpc, meshId string, wgHost string, nodesToExclude []string) error { func updatePeers(n *RobinIpc, meshId string, wgHost string, nodesToExclude []string) error {
for _, node := range n.Server.Meshes[meshId].Nodes { // for _, node := range n.Server.Meshes[meshId].Nodes {
nodeEndpoint := node.HostEndpoint // nodeEndpoint := node.HostEndpoint
if !slices.Contains(nodesToExclude, nodeEndpoint) { // if !slices.Contains(nodesToExclude, nodeEndpoint) {
// Best effort service // Best effort service
err := updatePeer(n, node, wgHost, meshId) // err := updatePeer(n, node, wgHost, meshId)
if err != nil {
return err
}
}
}
// if err != nil {
// return err
// }
// }
// }
return nil return nil
} }
@ -202,6 +200,12 @@ func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
return err return err
} }
err = peerConnection.Connect()
if err != nil {
return err
}
client, err := peerConnection.GetClient() client, err := peerConnection.GetClient()
if err != nil { if err != nil {
@ -219,9 +223,25 @@ func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
ctx, cancel := context.WithTimeout(authContext, time.Second) ctx, cancel := context.WithTimeout(authContext, time.Second)
defer cancel() defer cancel()
dev := n.Server.GetDevice() meshReply, err := c.GetMesh(ctx, &rpc.GetMeshRequest{MeshId: args.MeshId})
ipAddr, err := n.ipAllocator.GetIP(n.Server.GetPublicKey(), args.MeshId) if err != nil {
return err
}
err = n.Server.MeshManager.AddMesh(args.MeshId, "wgmesh", meshReply.Mesh)
if err != nil {
return err
}
pubKey, err := n.Server.MeshManager.GetPublicKey(args.MeshId)
if err != nil {
return err
}
ipAddr, err := n.ipAllocator.GetIP(*pubKey, args.MeshId)
if err != nil { if err != nil {
return err return err
@ -229,38 +249,53 @@ func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
logging.InfoLog.Println("WgIP: " + ipAddr.String()) logging.InfoLog.Println("WgIP: " + ipAddr.String())
joinMeshReq := rpc.JoinMeshRequest{ outBoundIP := lib.GetOutboundIP()
MeshId: args.MeshId,
HostPort: 8080, node := crdt.MeshNodeCrdt{
PublicKey: dev.PublicKey.String(), HostEndpoint: outBoundIP.String() + ":8080",
WgPort: int32(dev.ListenPort), WgEndpoint: outBoundIP.String() + ":51820",
WgIp: ipAddr.String() + "/128", PublicKey: pubKey.String(),
WgHost: ipAddr.String() + "/128",
} }
r, err := c.JoinMesh(ctx, &joinMeshReq) n.Server.MeshManager.AddMeshNode(args.MeshId, node)
mesh := n.Server.MeshManager.GetMesh(args.MeshId)
joinMeshRequest := rpc.JoinMeshRequest{
MeshId: args.MeshId,
Changes: mesh.SaveChanges(),
}
joinReply, err := c.JoinMesh(ctx, &joinMeshRequest)
if err != nil { if err != nil {
return err return err
} }
if r.GetSuccess() { if joinReply.GetSuccess() {
updateMesh(n, args.MeshId, args.IpAdress+":8080") updateMesh(n, args.MeshId, args.IpAdress+":8080")
} }
err = updatePeers(n, args.MeshId, r.GetMeshIp(), make([]string, 0)) if joinReply.GetSuccess() {
err = updatePeers(n, args.MeshId, ipAddr.String(), make([]string, 0))
*reply = strconv.FormatBool(r.GetSuccess()) }
*reply = strconv.FormatBool(joinReply.GetSuccess())
return nil return nil
} }
func (n *RobinIpc) GetMesh(meshId string, reply *ipc.GetMeshReply) error { func (n *RobinIpc) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
mesh, contains := n.Server.Meshes[meshId] mesh := n.Server.MeshManager.GetMesh(meshId)
meshSnapshot, err := mesh.GetCrdt()
if contains { if err != nil {
nodes := make([]ctrlserver.MeshNode, len(mesh.Nodes)) return err
}
if mesh != nil {
nodes := make([]crdt.MeshNodeCrdt, len(meshSnapshot.Nodes))
i := 0 i := 0
for _, n := range mesh.Nodes { for _, n := range meshSnapshot.Nodes {
nodes[i] = n nodes[i] = n
i += 1 i += 1
} }
@ -273,9 +308,11 @@ func (n *RobinIpc) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
} }
func (n *RobinIpc) EnableInterface(meshId string, reply *string) error { func (n *RobinIpc) EnableInterface(meshId string, reply *string) error {
err := n.Server.EnableInterface(meshId) err := n.Server.MeshManager.EnableInterface(meshId)
fmt.Println("reached")
if err != nil { if err != nil {
*reply = err.Error()
return err return err
} }

View File

@ -3,12 +3,9 @@ package robin
import ( import (
"context" "context"
"errors" "errors"
"net"
"strconv"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver" "github.com/tim-beatham/wgmesh/pkg/ctrlserver"
"github.com/tim-beatham/wgmesh/pkg/rpc" "github.com/tim-beatham/wgmesh/pkg/rpc"
"google.golang.org/grpc/peer"
) )
type RobinRpc struct { type RobinRpc struct {
@ -40,48 +37,33 @@ func nodesToRpcNodes(nodes map[string]ctrlserver.MeshNode) []*rpc.MeshNode {
} }
func (m *RobinRpc) GetMesh(ctx context.Context, request *rpc.GetMeshRequest) (*rpc.GetMeshReply, error) { func (m *RobinRpc) GetMesh(ctx context.Context, request *rpc.GetMeshRequest) (*rpc.GetMeshReply, error) {
mesh, contains := m.Server.Meshes[request.MeshId] mesh := m.Server.MeshManager.GetMesh(request.MeshId)
if !contains { if mesh == nil {
return nil, errors.New("Element is not in the mesh") return nil, errors.New("mesh does not exist")
} }
meshBytes := mesh.Save()
reply := rpc.GetMeshReply{ reply := rpc.GetMeshReply{
MeshId: request.MeshId, Mesh: meshBytes,
MeshNode: nodesToRpcNodes(mesh.Nodes),
} }
return &reply, nil return &reply, nil
} }
func (m *RobinRpc) JoinMesh(ctx context.Context, request *rpc.JoinMeshRequest) (*rpc.JoinMeshReply, error) { func (m *RobinRpc) JoinMesh(ctx context.Context, request *rpc.JoinMeshRequest) (*rpc.JoinMeshReply, error) {
p, _ := peer.FromContext(ctx) mesh := m.Server.MeshManager.GetMesh(request.MeshId)
hostIp, _, err := net.SplitHostPort(p.Addr.String()) if mesh == nil {
return nil, errors.New("mesh does not exist")
}
err := m.Server.MeshManager.UpdateMesh(request.MeshId, request.Changes)
if err != nil { if err != nil {
return nil, err return nil, err
} }
wgIp := request.WgIp return &rpc.JoinMeshReply{Success: true}, nil
if wgIp == "" {
return nil, errors.New("Haven't provided a valid IP address")
}
addHostArgs := ctrlserver.AddHostArgs{
HostEndpoint: hostIp + ":" + strconv.Itoa(int(request.HostPort)),
PublicKey: request.PublicKey,
MeshId: request.MeshId,
WgEndpoint: hostIp + ":" + strconv.Itoa(int(request.WgPort)),
WgIp: wgIp,
}
err = m.Server.AddHost(addHostArgs)
if err != nil {
return nil, err
}
return &rpc.JoinMeshReply{Success: true, MeshIp: &wgIp}, nil
} }

View File

@ -191,6 +191,7 @@ type JoinMeshRequest struct {
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Changes []byte `protobuf:"bytes,1,opt,name=changes,proto3" json:"changes,omitempty"` Changes []byte `protobuf:"bytes,1,opt,name=changes,proto3" json:"changes,omitempty"`
MeshId string `protobuf:"bytes,2,opt,name=meshId,proto3" json:"meshId,omitempty"`
} }
func (x *JoinMeshRequest) Reset() { func (x *JoinMeshRequest) Reset() {
@ -232,6 +233,13 @@ func (x *JoinMeshRequest) GetChanges() []byte {
return nil return nil
} }
func (x *JoinMeshRequest) GetMeshId() string {
if x != nil {
return x.MeshId
}
return ""
}
type JoinMeshReply struct { type JoinMeshReply struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -297,23 +305,25 @@ var file_pkg_grpc_ctrlserver_ctrlserver_proto_rawDesc = []byte{
0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x64, 0x22, 0x22, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4d, 0x52, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x64, 0x22, 0x22, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4d,
0x65, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x73, 0x68,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x22, 0x2b, 0x0a, 0x0f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x22, 0x43, 0x0a, 0x0f,
0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x29, 0x0a, 0x0d, 0x4a, 0x6f, 0x69, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x73,
0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x68, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49,
0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x64, 0x22, 0x29, 0x0a, 0x0d, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70,
0x63, 0x65, 0x73, 0x73, 0x32, 0x91, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x74, 0x72, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x32, 0x91, 0x01, 0x0a,
0x73, 0x68, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x0e, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x74, 0x72, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12,
0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x3d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63,
0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71,
0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x08, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
0x73, 0x68, 0x12, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4a, 0x6f, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x40,
0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x0a, 0x08, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x12, 0x19, 0x2e, 0x72, 0x70, 0x63,
0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65,
0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, 0x70, 0x6b, 0x67, 0x2f, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73,
0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00,
0x42, 0x09, 0x5a, 0x07, 0x70, 0x6b, 0x67, 0x2f, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
} }
var ( var (

View File

@ -1,11 +1,10 @@
package wg package wg
import ( import (
"fmt"
"net" "net"
"os/exec" "os/exec"
crdt "github.com/tim-beatham/wgmesh/pkg/automerge" logging "github.com/tim-beatham/wgmesh/pkg/log"
"golang.zx2c4.com/wireguard/wgctrl" "golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
@ -64,7 +63,7 @@ func EnableInterface(ifName string, ip string) error {
cmd := exec.Command("/usr/bin/ip", "link", "set", "up", "dev", ifName) cmd := exec.Command("/usr/bin/ip", "link", "set", "up", "dev", ifName)
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
fmt.Println(err.Error()) logging.ErrorLog.Println(err.Error())
return err return err
} }
@ -82,59 +81,3 @@ func EnableInterface(ifName string, ip string) error {
return nil return nil
} }
func convertMeshNode(node crdt.MeshNodeCrdt) (*wgtypes.PeerConfig, error) {
peerEndpoint, err := net.ResolveUDPAddr("udp", node.WgEndpoint)
if err != nil {
return nil, err
}
peerPublic, err := wgtypes.ParseKey(node.PublicKey)
if err != nil {
return nil, err
}
allowedIps := make([]net.IPNet, 1)
_, ipnet, err := net.ParseCIDR(node.WgHost)
if err != nil {
return nil, err
}
allowedIps[0] = *ipnet
peerConfig := wgtypes.PeerConfig{
PublicKey: peerPublic,
Endpoint: peerEndpoint,
AllowedIPs: allowedIps,
}
return &peerConfig, nil
}
func UpdateWgConf(devName string, nodes map[string]crdt.MeshNodeCrdt, client wgctrl.Client) error {
peerConfigs := make([]wgtypes.PeerConfig, len(nodes))
var count int = 0
for _, n := range nodes {
peer, err := convertMeshNode(n)
if err != nil {
return err
}
peerConfigs[count] = *peer
count++
}
cfg := wgtypes.Config{
Peers: peerConfigs,
ReplacePeers: true,
}
client.ConfigureDevice(devName, cfg)
return nil
}