smegmesh/pkg/robin/robin_requester.go

289 lines
5.5 KiB
Go
Raw Normal View History

2023-09-29 16:00:20 +02:00
package robin
2023-09-18 18:00:43 +02:00
import (
"context"
2023-09-18 18:00:43 +02:00
"errors"
2023-09-20 00:50:44 +02:00
"strconv"
"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"
"github.com/tim-beatham/wgmesh/pkg/mesh"
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-10 21:14:40 +02:00
wg.CreateInterface(n.Server.Conf.IfName)
2023-09-19 14:45:49 +02:00
meshId, err := n.Server.MeshManager.CreateMesh(n.Server.Conf.IfName)
if err != nil {
return err
}
2023-10-05 18:48:54 +02:00
2023-10-06 11:12:46 +02:00
pubKey, err := n.Server.MeshManager.GetPublicKey(meshId)
if err != nil {
return err
}
2023-10-06 11:12:46 +02:00
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-10-06 19:25:38 +02:00
func (n *RobinIpc) ListMeshes(_ string, reply *ipc.ListMeshReply) error {
meshNames := make([]string, len(n.Server.MeshManager.Meshes))
i := 0
for _, mesh := range n.Server.MeshManager.Meshes {
meshNames[i] = mesh.MeshId
i++
}
2023-09-20 15:34:34 +02:00
2023-10-06 19:25:38 +02:00
*reply = ipc.ListMeshReply{Meshes: meshNames}
2023-09-20 15:34:34 +02:00
return nil
}
2023-10-06 19:25:38 +02:00
func (n *RobinIpc) Authenticate(meshId, endpoint string) error {
peerConnection, err := n.Server.ConnectionManager.AddConnection(endpoint)
2023-10-06 19:25:38 +02:00
if err != nil {
return err
}
2023-10-06 19:25:38 +02:00
err = peerConnection.Authenticate(meshId)
2023-10-06 19:25:38 +02:00
if err != nil {
return err
}
2023-10-06 19:25:38 +02:00
return err
}
func (n *RobinIpc) authenticatePeers(meshId string) error {
2023-10-06 19:25:38 +02:00
theMesh := n.Server.MeshManager.GetMesh(meshId)
2023-10-06 12:52:51 +02:00
2023-10-06 19:25:38 +02:00
if theMesh == nil {
return errors.New("the mesh does not exist")
}
2023-10-06 19:25:38 +02:00
snapshot, _ := theMesh.GetCrdt()
publicKey, err := n.Server.MeshManager.GetPublicKey(meshId)
2023-10-01 21:14:09 +02:00
if err != nil {
return err
2023-10-01 21:14:09 +02:00
}
2023-10-06 19:25:38 +02:00
for nodeKey, node := range snapshot.Nodes {
logging.InfoLog.Println(nodeKey)
if nodeKey == publicKey.String() {
continue
}
2023-10-01 21:14:09 +02:00
err := n.Authenticate(meshId, node.HostEndpoint)
2023-10-06 19:25:38 +02:00
if err != nil {
return err
}
2023-10-01 21:14:09 +02:00
}
2023-10-06 19:25:38 +02:00
return nil
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-06 19:25:38 +02:00
err := n.Authenticate(args.MeshId, args.IpAdress)
2023-10-01 21:14:09 +02:00
if err != nil {
return err
}
2023-10-06 19:25:38 +02:00
peerConnection, err := n.Server.ConnectionManager.GetConnection(args.IpAdress)
2023-10-01 21:14:09 +02:00
if err != nil {
return err
}
2023-10-06 12:52:51 +02:00
err = peerConnection.Connect()
if err != nil {
return err
}
client, err := peerConnection.GetClient()
if err != nil {
return err
}
c := rpc.NewMeshCtrlServerClient(client)
authContext, err := peerConnection.CreateAuthContext(args.MeshId)
2023-10-01 21:14:09 +02:00
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(authContext, time.Second)
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
}
2023-10-10 21:14:40 +02:00
err = n.Server.MeshManager.AddMesh(args.MeshId, n.Server.Conf.IfName, meshReply.Mesh)
2023-10-06 12:52:51 +02:00
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-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)
if err != nil {
return err
}
2023-10-06 12:52:51 +02:00
if joinReply.GetSuccess() {
err = n.authenticatePeers(args.MeshId)
}
if err != nil {
return err
2023-09-20 15:34:34 +02:00
}
2023-10-06 12:52:51 +02:00
*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([]ctrlserver.MeshNode, len(meshSnapshot.Nodes))
2023-09-20 00:50:44 +02:00
i := 0
for _, node := range meshSnapshot.Nodes {
node := ctrlserver.MeshNode{
HostEndpoint: node.HostEndpoint,
WgEndpoint: node.WgEndpoint,
PublicKey: node.PublicKey,
WgHost: node.WgHost,
Failed: mesh.HasFailed(node.HostEndpoint),
}
nodes[i] = node
2023-09-20 00:50:44 +02:00
i += 1
}
*reply = ipc.GetMeshReply{Nodes: nodes}
} else {
return errors.New("mesh does not exist")
2023-09-20 00:50:44 +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)
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
}
func (n *RobinIpc) GetDOT(meshId string, reply *string) error {
g := mesh.NewMeshDotConverter(n.Server.MeshManager)
result, err := g.Generate(meshId)
if err != nil {
return err
}
*reply = result
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
}