2023-09-29 16:00:20 +02:00
|
|
|
package robin
|
2023-09-18 18:00:43 +02:00
|
|
|
|
|
|
|
import (
|
2023-09-19 19:29:35 +02:00
|
|
|
"context"
|
2023-09-18 18:00:43 +02:00
|
|
|
"errors"
|
2023-10-06 12:52:51 +02:00
|
|
|
"fmt"
|
2023-09-20 00:50:44 +02:00
|
|
|
"strconv"
|
2023-09-19 19:29:35 +02:00
|
|
|
"time"
|
2023-09-18 18:00:43 +02:00
|
|
|
|
2023-10-06 11:12:46 +02:00
|
|
|
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
|
2023-09-19 14:45:49 +02:00
|
|
|
"github.com/tim-beatham/wgmesh/pkg/ctrlserver"
|
2023-10-05 18:48:54 +02:00
|
|
|
"github.com/tim-beatham/wgmesh/pkg/ip"
|
2023-09-20 00:50:44 +02:00
|
|
|
"github.com/tim-beatham/wgmesh/pkg/ipc"
|
2023-09-28 17:55:37 +02:00
|
|
|
"github.com/tim-beatham/wgmesh/pkg/lib"
|
|
|
|
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
2023-09-29 16:00:20 +02:00
|
|
|
"github.com/tim-beatham/wgmesh/pkg/rpc"
|
2023-09-19 14:45:49 +02:00
|
|
|
"github.com/tim-beatham/wgmesh/pkg/wg"
|
2023-09-18 18:00:43 +02:00
|
|
|
)
|
|
|
|
|
2023-09-29 16:00:20 +02:00
|
|
|
type RobinIpc struct {
|
2023-10-05 18:48:54 +02:00
|
|
|
Server *ctrlserver.MeshCtrlServer
|
|
|
|
ipAllocator ip.IPAllocator
|
2023-09-18 18:00:43 +02:00
|
|
|
}
|
|
|
|
|
2023-09-29 16:00:20 +02:00
|
|
|
func (n *RobinIpc) CreateMesh(name string, reply *string) error {
|
2023-10-06 11:12:46 +02:00
|
|
|
wg.CreateInterface("wgmesh")
|
2023-09-19 14:45:49 +02:00
|
|
|
|
2023-10-06 11:12:46 +02:00
|
|
|
meshId, err := n.Server.MeshManager.CreateMesh("wgmesh")
|
2023-10-05 18:48:54 +02:00
|
|
|
|
2023-10-06 11:12:46 +02:00
|
|
|
pubKey, err := n.Server.MeshManager.GetPublicKey(meshId)
|
|
|
|
nodeIP, err := n.ipAllocator.GetIP(*pubKey, meshId)
|
2023-10-05 18:48:54 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-09-28 17:55:37 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
outBoundIp := lib.GetOutboundIP()
|
2023-09-28 17:55:37 +02:00
|
|
|
|
2023-10-06 11:12:46 +02:00
|
|
|
meshNode := crdt.MeshNodeCrdt{
|
2023-10-06 12:52:51 +02:00
|
|
|
HostEndpoint: outBoundIp.String() + ":8080",
|
2023-10-06 11:12:46 +02:00
|
|
|
PublicKey: pubKey.String(),
|
2023-10-06 12:52:51 +02:00
|
|
|
WgEndpoint: outBoundIp.String() + ":51820",
|
2023-10-06 11:12:46 +02:00
|
|
|
WgHost: nodeIP.String() + "/128",
|
2023-09-28 17:55:37 +02:00
|
|
|
}
|
|
|
|
|
2023-10-06 11:12:46 +02:00
|
|
|
n.Server.MeshManager.AddMeshNode(meshId, meshNode)
|
2023-09-18 18:00:43 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-10-06 11:12:46 +02:00
|
|
|
*reply = meshId
|
2023-09-18 18:00:43 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-29 16:00:20 +02:00
|
|
|
func (n *RobinIpc) ListMeshes(name string, reply *map[string]ctrlserver.Mesh) error {
|
2023-10-06 11:12:46 +02:00
|
|
|
// *reply = n.Server.Meshes
|
2023-09-19 19:29:35 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-29 16:00:20 +02:00
|
|
|
func updateMesh(n *RobinIpc, meshId string, endPoint string) error {
|
2023-10-06 12:52:51 +02:00
|
|
|
// peerConn, err := n.Server.ConnectionManager.GetConnection(endPoint)
|
2023-09-20 15:34:34 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
2023-09-20 15:34:34 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// conn, err := peerConn.GetClient()
|
2023-10-02 17:03:41 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// c := rpc.NewMeshCtrlServerClient(conn)
|
2023-09-20 15:34:34 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// authContext, err := peerConn.CreateAuthContext(meshId)
|
2023-10-02 17:03:41 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
2023-10-01 21:14:09 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// ctx, cancel := context.WithTimeout(authContext, time.Second)
|
|
|
|
// defer cancel()
|
2023-09-20 15:34:34 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// getMeshReq := rpc.GetMeshRequest{
|
|
|
|
// MeshId: meshId,
|
|
|
|
// }
|
2023-09-20 15:34:34 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// r, err := c.GetMesh(ctx, &getMeshReq)
|
2023-09-20 15:34:34 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
2023-09-20 15:34:34 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// key, err := wgtypes.ParseKey(meshId)
|
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
2023-09-20 15:34:34 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// err := n.Server.MeshManager.AddMesh(meshId, "wgmesh", r.Mesh)
|
2023-10-06 11:12:46 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
2023-09-20 15:34:34 +02:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-29 16:00:20 +02:00
|
|
|
func updatePeer(n *RobinIpc, node ctrlserver.MeshNode, wgHost string, meshId string) error {
|
2023-10-06 12:52:51 +02:00
|
|
|
// // err := n.Authenticate(meshId, node.HostEndpoint)
|
2023-10-01 21:14:09 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// // if err != nil {
|
|
|
|
// // return err
|
|
|
|
// // }
|
2023-10-01 21:14:09 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// peerConnection, err := n.Server.ConnectionManager.GetConnection(node.HostEndpoint)
|
2023-10-01 21:14:09 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
2023-10-01 21:14:09 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// conn, err := peerConnection.GetClient()
|
2023-09-21 14:50:59 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
2023-09-21 14:50:59 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// c := rpc.NewMeshCtrlServerClient(conn)
|
2023-09-21 14:50:59 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// authContext, err := peerConnection.CreateAuthContext(meshId)
|
2023-10-02 17:03:41 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
2023-10-01 21:14:09 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// ctx, cancel := context.WithTimeout(authContext, time.Second)
|
|
|
|
// defer cancel()
|
2023-09-21 14:50:59 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// dev := n.Server.GetDevice()
|
2023-09-28 17:55:37 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// joinMeshReq := rpc.JoinMeshRequest{
|
|
|
|
// MeshId: meshId,
|
|
|
|
// HostPort: 8080,
|
|
|
|
// PublicKey: dev.PublicKey.String(),
|
|
|
|
// WgPort: int32(dev.ListenPort),
|
|
|
|
// WgIp: wgHost + "/128",
|
|
|
|
// }
|
2023-09-21 14:50:59 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// r, err := c.JoinMesh(ctx, &joinMeshReq)
|
2023-09-21 14:50:59 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
2023-09-21 14:50:59 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
// if !r.GetSuccess() {
|
|
|
|
// return errors.New("Could not join the mesh")
|
|
|
|
// }
|
2023-09-21 14:50:59 +02:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-29 16:00:20 +02:00
|
|
|
func updatePeers(n *RobinIpc, meshId string, wgHost string, nodesToExclude []string) error {
|
2023-10-06 12:52:51 +02:00
|
|
|
// 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
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
2023-09-21 14:50:59 +02:00
|
|
|
return nil
|
|
|
|
}
|
2023-09-20 20:05:29 +02:00
|
|
|
|
2023-10-02 17:03:41 +02:00
|
|
|
func (n *RobinIpc) Authenticate(meshId, endpoint string) error {
|
|
|
|
peerConnection, err := n.Server.ConnectionManager.AddConnection(endpoint)
|
2023-10-01 21:14:09 +02:00
|
|
|
|
|
|
|
if err != nil {
|
2023-10-02 17:03:41 +02:00
|
|
|
return err
|
2023-10-01 21:14:09 +02:00
|
|
|
}
|
|
|
|
|
2023-10-02 17:03:41 +02:00
|
|
|
err = peerConnection.Authenticate(meshId)
|
2023-10-01 21:14:09 +02:00
|
|
|
|
|
|
|
if err != nil {
|
2023-10-02 17:03:41 +02:00
|
|
|
return err
|
2023-10-01 21:14:09 +02:00
|
|
|
}
|
|
|
|
|
2023-10-02 17:03:41 +02:00
|
|
|
return err
|
2023-10-01 21:14:09 +02:00
|
|
|
}
|
|
|
|
|
2023-09-29 16:00:20 +02:00
|
|
|
func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
|
2023-10-02 17:03:41 +02:00
|
|
|
err := n.Authenticate(args.MeshId, args.IpAdress+":8080")
|
2023-10-01 21:14:09 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-10-02 17:03:41 +02:00
|
|
|
peerConnection, err := n.Server.ConnectionManager.GetConnection(args.IpAdress + ":8080")
|
2023-10-01 21:14:09 +02:00
|
|
|
|
2023-10-02 17:03:41 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
err = peerConnection.Connect()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-10-02 17:03:41 +02:00
|
|
|
client, err := peerConnection.GetClient()
|
2023-09-19 19:29:35 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-10-02 17:03:41 +02:00
|
|
|
c := rpc.NewMeshCtrlServerClient(client)
|
2023-09-19 19:29:35 +02:00
|
|
|
|
2023-10-02 17:03:41 +02:00
|
|
|
authContext, err := peerConnection.CreateAuthContext(args.MeshId)
|
2023-09-19 19:29:35 +02:00
|
|
|
|
2023-10-01 21:14:09 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-10-02 17:03:41 +02:00
|
|
|
ctx, cancel := context.WithTimeout(authContext, time.Second)
|
2023-09-19 19:29:35 +02:00
|
|
|
defer cancel()
|
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
meshReply, err := c.GetMesh(ctx, &rpc.GetMeshRequest{MeshId: 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)
|
2023-09-20 00:50:44 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
ipAddr, err := n.ipAllocator.GetIP(*pubKey, args.MeshId)
|
2023-10-05 18:48:54 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
logging.InfoLog.Println("WgIP: " + ipAddr.String())
|
2023-09-21 14:50:59 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
outBoundIP := lib.GetOutboundIP()
|
|
|
|
|
|
|
|
node := crdt.MeshNodeCrdt{
|
|
|
|
HostEndpoint: outBoundIP.String() + ":8080",
|
|
|
|
WgEndpoint: outBoundIP.String() + ":51820",
|
|
|
|
PublicKey: pubKey.String(),
|
|
|
|
WgHost: ipAddr.String() + "/128",
|
|
|
|
}
|
|
|
|
|
|
|
|
n.Server.MeshManager.AddMeshNode(args.MeshId, node)
|
|
|
|
mesh := n.Server.MeshManager.GetMesh(args.MeshId)
|
|
|
|
|
|
|
|
joinMeshRequest := rpc.JoinMeshRequest{
|
|
|
|
MeshId: args.MeshId,
|
|
|
|
Changes: mesh.SaveChanges(),
|
2023-09-20 00:50:44 +02:00
|
|
|
}
|
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
joinReply, err := c.JoinMesh(ctx, &joinMeshRequest)
|
2023-09-19 19:29:35 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
if joinReply.GetSuccess() {
|
2023-09-29 16:00:20 +02:00
|
|
|
updateMesh(n, args.MeshId, args.IpAdress+":8080")
|
2023-09-20 15:34:34 +02:00
|
|
|
}
|
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
if joinReply.GetSuccess() {
|
|
|
|
err = updatePeers(n, args.MeshId, ipAddr.String(), make([]string, 0))
|
|
|
|
}
|
|
|
|
*reply = strconv.FormatBool(joinReply.GetSuccess())
|
2023-09-20 00:50:44 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-29 16:00:20 +02:00
|
|
|
func (n *RobinIpc) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
|
2023-10-06 12:52:51 +02:00
|
|
|
mesh := n.Server.MeshManager.GetMesh(meshId)
|
|
|
|
meshSnapshot, err := mesh.GetCrdt()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-09-20 00:50:44 +02:00
|
|
|
|
2023-10-06 12:52:51 +02:00
|
|
|
if mesh != nil {
|
|
|
|
nodes := make([]crdt.MeshNodeCrdt, len(meshSnapshot.Nodes))
|
2023-09-20 00:50:44 +02:00
|
|
|
|
|
|
|
i := 0
|
2023-10-06 12:52:51 +02:00
|
|
|
for _, n := range meshSnapshot.Nodes {
|
2023-09-20 00:50:44 +02:00
|
|
|
nodes[i] = n
|
|
|
|
i += 1
|
|
|
|
}
|
|
|
|
|
|
|
|
*reply = ipc.GetMeshReply{Nodes: nodes}
|
|
|
|
} else {
|
2023-09-21 14:50:59 +02:00
|
|
|
return errors.New("mesh does not exist")
|
2023-09-20 00:50:44 +02:00
|
|
|
}
|
2023-09-19 19:29:35 +02:00
|
|
|
return nil
|
2023-09-19 14:45:49 +02:00
|
|
|
}
|
|
|
|
|
2023-09-29 16:00:20 +02:00
|
|
|
func (n *RobinIpc) EnableInterface(meshId string, reply *string) error {
|
2023-10-06 12:52:51 +02:00
|
|
|
err := n.Server.MeshManager.EnableInterface(meshId)
|
|
|
|
fmt.Println("reached")
|
2023-09-21 19:43:29 +02:00
|
|
|
|
|
|
|
if err != nil {
|
2023-10-06 12:52:51 +02:00
|
|
|
*reply = err.Error()
|
2023-09-21 19:43:29 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
*reply = "up"
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-10-05 18:48:54 +02:00
|
|
|
type RobinIpcParams struct {
|
|
|
|
CtrlServer *ctrlserver.MeshCtrlServer
|
|
|
|
Allocator ip.IPAllocator
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewRobinIpc(ipcParams RobinIpcParams) RobinIpc {
|
|
|
|
return RobinIpc{
|
|
|
|
Server: ipcParams.CtrlServer,
|
|
|
|
ipAllocator: ipcParams.Allocator,
|
|
|
|
}
|
2023-09-18 18:00:43 +02:00
|
|
|
}
|