mirror of
https://github.com/tim-beatham/smegmesh.git
synced 2025-06-20 19:57:49 +02:00
Incorporated automerge
This commit is contained in:
parent
81e2d16316
commit
47e260e310
@ -64,8 +64,8 @@ func getMesh(client *ipcRpc.Client, meshId string) {
|
||||
|
||||
for _, node := range reply.Nodes {
|
||||
fmt.Println("Public Key: " + node.PublicKey)
|
||||
fmt.Println("WireGuard Endpoint: " + node.HostEndpoint)
|
||||
fmt.Println("Control Endpoint: " + node.WgEndpoint)
|
||||
fmt.Println("WireGuard Endpoint: " + node.WgEndpoint)
|
||||
fmt.Println("Control Endpoint: " + node.HostEndpoint)
|
||||
fmt.Println("Wg IP: " + node.WgHost)
|
||||
fmt.Println("---")
|
||||
}
|
||||
@ -77,7 +77,7 @@ func enableInterface(client *ipcRpc.Client, meshId string) {
|
||||
err := client.Call("RobinIpc.EnableInterface", &meshId, &reply)
|
||||
|
||||
if err != nil {
|
||||
(err.Error())
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,19 @@
|
||||
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
|
||||
type CrdtNodeManager struct {
|
||||
meshId string
|
||||
IfName string
|
||||
Client *wgctrl.Client
|
||||
doc *automerge.Doc
|
||||
}
|
||||
|
||||
@ -13,6 +21,17 @@ func (c *CrdtNodeManager) AddNode(crdt MeshNodeCrdt) {
|
||||
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
|
||||
func (c *CrdtNodeManager) GetCrdt() (*MeshCrdt, error) {
|
||||
return automerge.As[*MeshCrdt](c.doc.Root())
|
||||
@ -27,27 +46,92 @@ func (c *CrdtNodeManager) Load(bytes []byte) error {
|
||||
}
|
||||
|
||||
c.doc = doc
|
||||
c.applyWg()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save: Save an entire mesh network
|
||||
func (c *CrdtNodeManager) Save(doc []byte) []byte {
|
||||
func (c *CrdtNodeManager) Save() []byte {
|
||||
return c.doc.Save()
|
||||
}
|
||||
|
||||
func (c *CrdtNodeManager) LoadChanges(changes []byte) {
|
||||
c.doc.LoadIncremental(changes)
|
||||
func (c *CrdtNodeManager) LoadChanges(changes []byte) error {
|
||||
err := c.doc.LoadIncremental(changes)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.applyWg()
|
||||
}
|
||||
|
||||
func (c *CrdtNodeManager) SaveChanges() []byte {
|
||||
return c.SaveChanges()
|
||||
return c.doc.SaveIncremental()
|
||||
}
|
||||
|
||||
// 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
|
||||
manager.meshId = meshId
|
||||
manager.doc = automerge.New()
|
||||
manager.IfName = devName
|
||||
manager.Client = client
|
||||
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
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ type NewCtrlServerParams struct {
|
||||
func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) {
|
||||
ctrlServer := new(MeshCtrlServer)
|
||||
ctrlServer.Client = params.WgClient
|
||||
ctrlServer.MeshManager = &manager.MeshManger{}
|
||||
ctrlServer.MeshManager = manager.NewMeshManager(*params.WgClient)
|
||||
|
||||
connManagerParams := conn.NewJwtConnectionManagerParams{
|
||||
CertificatePath: params.Conf.CertificatePath,
|
||||
|
@ -25,6 +25,7 @@ message GetMeshReply {
|
||||
|
||||
message JoinMeshRequest {
|
||||
bytes changes = 1;
|
||||
string meshId = 2;
|
||||
}
|
||||
|
||||
message JoinMeshReply {
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"net/rpc"
|
||||
"os"
|
||||
|
||||
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
|
||||
"github.com/tim-beatham/wgmesh/pkg/ctrlserver"
|
||||
)
|
||||
|
||||
@ -16,7 +17,7 @@ type JoinMeshArgs struct {
|
||||
}
|
||||
|
||||
type GetMeshReply struct {
|
||||
Nodes []ctrlserver.MeshNode
|
||||
Nodes []crdt.MeshNodeCrdt
|
||||
}
|
||||
|
||||
type MeshIpc interface {
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
|
||||
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
|
||||
"github.com/tim-beatham/wgmesh/pkg/lib"
|
||||
"github.com/tim-beatham/wgmesh/pkg/wg"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
@ -28,34 +27,31 @@ func (m *MeshManger) CreateMesh(devName string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
nodeManager := crdt.NewCrdtNodeManager(key.String(), devName)
|
||||
nodeManager := crdt.NewCrdtNodeManager(key.String(), devName, m.Client)
|
||||
m.Meshes[key.String()] = nodeManager
|
||||
return key.String(), nil
|
||||
}
|
||||
|
||||
// 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]
|
||||
|
||||
if !ok {
|
||||
return errors.New("mesh does not exist")
|
||||
}
|
||||
|
||||
mesh.LoadChanges(changes)
|
||||
|
||||
crdt, err := mesh.GetCrdt()
|
||||
err := mesh.LoadChanges(changes)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wg.UpdateWgConf(m.Meshes[meshId].IfName, crdt.Nodes, client)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddMesh: Add the mesh to the list of meshes
|
||||
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)
|
||||
|
||||
if err != nil {
|
||||
@ -71,6 +67,11 @@ func (m *MeshManger) AddMeshNode(meshId string, node crdt.MeshNodeCrdt) {
|
||||
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.
|
||||
func (s *MeshManger) EnableInterface(meshId string) error {
|
||||
mesh, contains := s.Meshes[meshId]
|
||||
@ -85,14 +86,19 @@ func (s *MeshManger) EnableInterface(meshId string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
endPoint := lib.GetOutboundIP().String() + ":8080"
|
||||
node, contains := crdt.Nodes[endPoint]
|
||||
dev, err := s.Client.Device(mesh.IfName)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
node, contains := crdt.Nodes[dev.PublicKey.String()]
|
||||
|
||||
if !contains {
|
||||
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
|
||||
@ -111,3 +117,7 @@ func (s *MeshManger) GetPublicKey(meshId string) (*wgtypes.Key, error) {
|
||||
|
||||
return &dev.PublicKey, nil
|
||||
}
|
||||
|
||||
func NewMeshManager(client wgctrl.Client) *MeshManger {
|
||||
return &MeshManger{Meshes: make(map[string]*crdt.CrdtNodeManager), Client: &client}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package robin
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"slices"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@ -15,7 +15,6 @@ import (
|
||||
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
||||
"github.com/tim-beatham/wgmesh/pkg/rpc"
|
||||
"github.com/tim-beatham/wgmesh/pkg/wg"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
type RobinIpc struct {
|
||||
@ -35,12 +34,12 @@ func (n *RobinIpc) CreateMesh(name string, reply *string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
outBoundIp := lib.GetOutboundIP().String()
|
||||
outBoundIp := lib.GetOutboundIP()
|
||||
|
||||
meshNode := crdt.MeshNodeCrdt{
|
||||
HostEndpoint: outBoundIp + ":8080",
|
||||
HostEndpoint: outBoundIp.String() + ":8080",
|
||||
PublicKey: pubKey.String(),
|
||||
WgEndpoint: outBoundIp + ":51820",
|
||||
WgEndpoint: outBoundIp.String() + ":51820",
|
||||
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 {
|
||||
peerConn, err := n.Server.ConnectionManager.GetConnection(endPoint)
|
||||
// peerConn, err := n.Server.ConnectionManager.GetConnection(endPoint)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if err != nil {
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
ctx, cancel := context.WithTimeout(authContext, time.Second)
|
||||
defer cancel()
|
||||
// ctx, cancel := context.WithTimeout(authContext, time.Second)
|
||||
// defer cancel()
|
||||
|
||||
getMeshReq := rpc.GetMeshRequest{
|
||||
MeshId: meshId,
|
||||
}
|
||||
// getMeshReq := rpc.GetMeshRequest{
|
||||
// MeshId: meshId,
|
||||
// }
|
||||
|
||||
r, err := c.GetMesh(ctx, &getMeshReq)
|
||||
// r, err := c.GetMesh(ctx, &getMeshReq)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
key, err := wgtypes.ParseKey(meshId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// key, err := wgtypes.ParseKey(meshId)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
err := n.Server.MeshManager.AddMesh(meshId, "wgmesh", r.Mesh)
|
||||
// err := n.Server.MeshManager.AddMesh(meshId, "wgmesh", r.Mesh)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
// // if err != nil {
|
||||
// // return err
|
||||
// // }
|
||||
|
||||
peerConnection, err := n.Server.ConnectionManager.GetConnection(node.HostEndpoint)
|
||||
// peerConnection, err := n.Server.ConnectionManager.GetConnection(node.HostEndpoint)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
conn, err := peerConnection.GetClient()
|
||||
// conn, err := peerConnection.GetClient()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
c := rpc.NewMeshCtrlServerClient(conn)
|
||||
// c := rpc.NewMeshCtrlServerClient(conn)
|
||||
|
||||
authContext, err := peerConnection.CreateAuthContext(meshId)
|
||||
// authContext, err := peerConnection.CreateAuthContext(meshId)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
ctx, cancel := context.WithTimeout(authContext, time.Second)
|
||||
defer cancel()
|
||||
// ctx, cancel := context.WithTimeout(authContext, time.Second)
|
||||
// defer cancel()
|
||||
|
||||
dev := n.Server.GetDevice()
|
||||
// dev := n.Server.GetDevice()
|
||||
|
||||
joinMeshReq := rpc.JoinMeshRequest{
|
||||
MeshId: meshId,
|
||||
HostPort: 8080,
|
||||
PublicKey: dev.PublicKey.String(),
|
||||
WgPort: int32(dev.ListenPort),
|
||||
WgIp: wgHost,
|
||||
}
|
||||
// joinMeshReq := rpc.JoinMeshRequest{
|
||||
// MeshId: meshId,
|
||||
// HostPort: 8080,
|
||||
// PublicKey: dev.PublicKey.String(),
|
||||
// WgPort: int32(dev.ListenPort),
|
||||
// WgIp: wgHost + "/128",
|
||||
// }
|
||||
|
||||
r, err := c.JoinMesh(ctx, &joinMeshReq)
|
||||
// r, err := c.JoinMesh(ctx, &joinMeshReq)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
if !r.GetSuccess() {
|
||||
return errors.New("Could not join the mesh")
|
||||
}
|
||||
// if !r.GetSuccess() {
|
||||
// return errors.New("Could not join the mesh")
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updatePeers(n *RobinIpc, meshId string, wgHost string, nodesToExclude []string) error {
|
||||
for _, node := range n.Server.Meshes[meshId].Nodes {
|
||||
nodeEndpoint := node.HostEndpoint
|
||||
// for _, node := range n.Server.Meshes[meshId].Nodes {
|
||||
// nodeEndpoint := node.HostEndpoint
|
||||
|
||||
if !slices.Contains(nodesToExclude, nodeEndpoint) {
|
||||
// Best effort service
|
||||
err := updatePeer(n, node, wgHost, meshId)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
// if !slices.Contains(nodesToExclude, nodeEndpoint) {
|
||||
// Best effort service
|
||||
// err := updatePeer(n, node, wgHost, meshId)
|
||||
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -202,6 +200,12 @@ func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = peerConnection.Connect()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := peerConnection.GetClient()
|
||||
|
||||
if err != nil {
|
||||
@ -219,9 +223,25 @@ func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
|
||||
ctx, cancel := context.WithTimeout(authContext, time.Second)
|
||||
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 {
|
||||
return err
|
||||
@ -229,38 +249,53 @@ func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
|
||||
|
||||
logging.InfoLog.Println("WgIP: " + ipAddr.String())
|
||||
|
||||
joinMeshReq := rpc.JoinMeshRequest{
|
||||
MeshId: args.MeshId,
|
||||
HostPort: 8080,
|
||||
PublicKey: dev.PublicKey.String(),
|
||||
WgPort: int32(dev.ListenPort),
|
||||
WgIp: ipAddr.String() + "/128",
|
||||
outBoundIP := lib.GetOutboundIP()
|
||||
|
||||
node := crdt.MeshNodeCrdt{
|
||||
HostEndpoint: outBoundIP.String() + ":8080",
|
||||
WgEndpoint: outBoundIP.String() + ":51820",
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
if r.GetSuccess() {
|
||||
if joinReply.GetSuccess() {
|
||||
updateMesh(n, args.MeshId, args.IpAdress+":8080")
|
||||
}
|
||||
|
||||
err = updatePeers(n, args.MeshId, r.GetMeshIp(), make([]string, 0))
|
||||
|
||||
*reply = strconv.FormatBool(r.GetSuccess())
|
||||
if joinReply.GetSuccess() {
|
||||
err = updatePeers(n, args.MeshId, ipAddr.String(), make([]string, 0))
|
||||
}
|
||||
*reply = strconv.FormatBool(joinReply.GetSuccess())
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
nodes := make([]ctrlserver.MeshNode, len(mesh.Nodes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mesh != nil {
|
||||
nodes := make([]crdt.MeshNodeCrdt, len(meshSnapshot.Nodes))
|
||||
|
||||
i := 0
|
||||
for _, n := range mesh.Nodes {
|
||||
for _, n := range meshSnapshot.Nodes {
|
||||
nodes[i] = n
|
||||
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 {
|
||||
err := n.Server.EnableInterface(meshId)
|
||||
err := n.Server.MeshManager.EnableInterface(meshId)
|
||||
fmt.Println("reached")
|
||||
|
||||
if err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,9 @@ package robin
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/tim-beatham/wgmesh/pkg/ctrlserver"
|
||||
"github.com/tim-beatham/wgmesh/pkg/rpc"
|
||||
"google.golang.org/grpc/peer"
|
||||
)
|
||||
|
||||
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) {
|
||||
mesh, contains := m.Server.Meshes[request.MeshId]
|
||||
mesh := m.Server.MeshManager.GetMesh(request.MeshId)
|
||||
|
||||
if !contains {
|
||||
return nil, errors.New("Element is not in the mesh")
|
||||
if mesh == nil {
|
||||
return nil, errors.New("mesh does not exist")
|
||||
}
|
||||
|
||||
meshBytes := mesh.Save()
|
||||
|
||||
reply := rpc.GetMeshReply{
|
||||
MeshId: request.MeshId,
|
||||
MeshNode: nodesToRpcNodes(mesh.Nodes),
|
||||
Mesh: meshBytes,
|
||||
}
|
||||
|
||||
return &reply, nil
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wgIp := request.WgIp
|
||||
|
||||
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
|
||||
return &rpc.JoinMeshReply{Success: true}, nil
|
||||
}
|
||||
|
@ -191,6 +191,7 @@ type JoinMeshRequest struct {
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
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() {
|
||||
@ -232,6 +233,13 @@ func (x *JoinMeshRequest) GetChanges() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *JoinMeshRequest) GetMeshId() string {
|
||||
if x != nil {
|
||||
return x.MeshId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type JoinMeshReply struct {
|
||||
state protoimpl.MessageState
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75,
|
||||
0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63,
|
||||
0x63, 0x65, 0x73, 0x73, 0x32, 0x91, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x74, 0x72,
|
||||
0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65,
|
||||
0x73, 0x68, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72,
|
||||
0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52,
|
||||
0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x08, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65,
|
||||
0x73, 0x68, 0x12, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4a, 0x6f,
|
||||
0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e,
|
||||
0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 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,
|
||||
0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x73,
|
||||
0x68, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49,
|
||||
0x64, 0x22, 0x29, 0x0a, 0x0d, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70,
|
||||
0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x32, 0x91, 0x01, 0x0a,
|
||||
0x0e, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x74, 0x72, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12,
|
||||
0x3d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x40,
|
||||
0x0a, 0x08, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x12, 0x19, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73,
|
||||
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 (
|
||||
|
61
pkg/wg/wg.go
61
pkg/wg/wg.go
@ -1,11 +1,10 @@
|
||||
package wg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"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/wgtypes"
|
||||
)
|
||||
@ -64,7 +63,7 @@ func EnableInterface(ifName string, ip string) error {
|
||||
cmd := exec.Command("/usr/bin/ip", "link", "set", "up", "dev", ifName)
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Println(err.Error())
|
||||
logging.ErrorLog.Println(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
@ -82,59 +81,3 @@ func EnableInterface(ifName string, ip string) error {
|
||||
|
||||
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user