Interfaced problem out

This commit is contained in:
Tim Beatham 2023-09-29 15:00:20 +01:00
parent a0c20e4d11
commit c819bec63d
11 changed files with 162 additions and 95 deletions

View File

@ -13,9 +13,9 @@ import (
const SockAddr = "/tmp/wgmesh_ipc.sock" const SockAddr = "/tmp/wgmesh_ipc.sock"
func createNewMesh(client *ipcRpc.Client) string { func createMesh(client *ipcRpc.Client) string {
var reply string var reply string
err := client.Call("Mesh.CreateNewMesh", "", &reply) err := client.Call("RobinIpc.CreateMesh", "", &reply)
if err != nil { if err != nil {
return err.Error() return err.Error()
@ -27,7 +27,7 @@ func createNewMesh(client *ipcRpc.Client) string {
func listMeshes(client *ipcRpc.Client) { func listMeshes(client *ipcRpc.Client) {
var reply map[string]ctrlserver.Mesh var reply map[string]ctrlserver.Mesh
err := client.Call("Mesh.ListMeshes", "", &reply) err := client.Call("RobinIpc.ListMeshes", "", &reply)
if err != nil { if err != nil {
return return
@ -43,7 +43,7 @@ func joinMesh(client *ipcRpc.Client, meshId string, ipAddress string) string {
args := ipc.JoinMeshArgs{MeshId: meshId, IpAdress: ipAddress} args := ipc.JoinMeshArgs{MeshId: meshId, IpAdress: ipAddress}
err := client.Call("Mesh.JoinMesh", &args, &reply) err := client.Call("RobinIpc.JoinMesh", &args, &reply)
if err != nil { if err != nil {
return err.Error() return err.Error()
@ -55,7 +55,7 @@ func joinMesh(client *ipcRpc.Client, meshId string, ipAddress string) string {
func getMesh(client *ipcRpc.Client, meshId string) { func getMesh(client *ipcRpc.Client, meshId string) {
reply := new(ipc.GetMeshReply) reply := new(ipc.GetMeshReply)
err := client.Call("Mesh.GetMesh", &meshId, &reply) err := client.Call("RobinIpc.GetMesh", &meshId, &reply)
if err != nil { if err != nil {
log.Panic(err.Error()) log.Panic(err.Error())
@ -74,7 +74,7 @@ func getMesh(client *ipcRpc.Client, meshId string) {
func enableInterface(client *ipcRpc.Client, meshId string) { func enableInterface(client *ipcRpc.Client, meshId string) {
var reply string var reply string
err := client.Call("Mesh.EnableInterface", &meshId, &reply) err := client.Call("RobinIpc.EnableInterface", &meshId, &reply)
if err != nil { if err != nil {
(err.Error()) (err.Error())
@ -114,7 +114,7 @@ func main() {
} }
if newMeshCmd.Happened() { if newMeshCmd.Happened() {
fmt.Println(createNewMesh(client)) fmt.Println(createMesh(client))
} }
if listMeshCmd.Happened() { if listMeshCmd.Happened() {

View File

@ -5,8 +5,9 @@ import (
"net" "net"
ctrlserver "github.com/tim-beatham/wgmesh/pkg/ctrlserver" ctrlserver "github.com/tim-beatham/wgmesh/pkg/ctrlserver"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver/ipc" "github.com/tim-beatham/wgmesh/pkg/ipc"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver/rpc" "github.com/tim-beatham/wgmesh/pkg/robin"
"github.com/tim-beatham/wgmesh/pkg/rpc"
wg "github.com/tim-beatham/wgmesh/pkg/wg" wg "github.com/tim-beatham/wgmesh/pkg/wg"
) )
@ -22,9 +23,12 @@ func main() {
ctrlServer := ctrlserver.NewCtrlServer(wgClient, "wgmesh") ctrlServer := ctrlserver.NewCtrlServer(wgClient, "wgmesh")
log.Println("Running IPC Handler") log.Println("Running IPC Handler")
go ipc.RunIpcHandler(ctrlServer)
grpc := rpc.NewRpcServer(ctrlServer) robinIpc := robin.NewRobinIpc(ctrlServer)
robinRpc := robin.NewRobinRpc(ctrlServer)
go ipc.RunIpcHandler(robinIpc)
grpc := rpc.NewRpcServer(*&robinRpc)
lis, err := net.Listen("tcp", ":8080") lis, err := net.Listen("tcp", ":8080")
if err := grpc.Serve(lis); err != nil { if err := grpc.Serve(lis); err != nil {

View File

@ -1,3 +1,8 @@
/*
* ctrlserver controls the WireGuard mesh. Contains an IpcHandler for
* handling commands fired by wgmesh command.
* Contains an RpcHandler for handling commands fired by another server.
*/
package ctrlserver package ctrlserver
import ( import (
@ -11,8 +16,10 @@ import (
) )
/* /*
* Create a new control server instance running * NewCtrlServer creates a new instance of the ctrlserver.
* on the provided port. * It is associated with a WireGuard client and an interface.
* wgClient: Represents the WireGuard control client.
* ifName: WireGuard interface name
*/ */
func NewCtrlServer(wgClient *wgctrl.Client, ifName string) *MeshCtrlServer { func NewCtrlServer(wgClient *wgctrl.Client, ifName string) *MeshCtrlServer {
ctrlServer := new(MeshCtrlServer) ctrlServer := new(MeshCtrlServer)
@ -23,14 +30,18 @@ func NewCtrlServer(wgClient *wgctrl.Client, ifName string) *MeshCtrlServer {
} }
/* /*
* Given the meshid returns true if the node is in the mesh * MeshExists returns true if the client is part of the mesh
* false otherwise. * false otherwise.
*/ */
func (server *MeshCtrlServer) IsInMesh(meshId string) bool { func (server *MeshCtrlServer) MeshExists(meshId string) bool {
_, inMesh := server.Meshes[meshId] _, inMesh := server.Meshes[meshId]
return inMesh return inMesh
} }
/*
* CreateMesh creates a new mesh instance, adds it to the map
* of meshes and returns the newly created mesh.
*/
func (server *MeshCtrlServer) CreateMesh() (*Mesh, error) { func (server *MeshCtrlServer) CreateMesh() (*Mesh, error) {
key, err := wgtypes.GenerateKey() key, err := wgtypes.GenerateKey()
@ -47,14 +58,26 @@ func (server *MeshCtrlServer) CreateMesh() (*Mesh, error) {
return &mesh, nil return &mesh, nil
} }
/*
* AddHostArgs parameters needed to add
* a host to the mesh network
*/
type AddHostArgs struct { type AddHostArgs struct {
// HostEndpoint: Public IP and port of the gRPC server the node is running
HostEndpoint string HostEndpoint string
PublicKey string // PubilcKey: WireGuard public key of the device
MeshId string PublicKey string
WgEndpoint string // MeshId: Mesh ID of the node the the host is joining
WgIp string MeshId string
// WgEndpoint: Public IP and port of the WireGuard server that is running
WgEndpoint string
// WgIp: SLAAC generated WireGuard IP of the node
WgIp string
} }
/*
* AddHost adds a host to the mesh
*/
func (server *MeshCtrlServer) AddHost(args AddHostArgs) error { func (server *MeshCtrlServer) AddHost(args AddHostArgs) error {
nodes, contains := server.Meshes[args.MeshId] nodes, contains := server.Meshes[args.MeshId]
@ -75,7 +98,7 @@ func (server *MeshCtrlServer) AddHost(args AddHostArgs) error {
WgHost: args.WgIp, WgHost: args.WgIp,
} }
err := AddWgPeer(server.IfName, server.Client, node) err := server.AddWgPeer(node)
if err == nil { if err == nil {
nodes.Nodes[args.HostEndpoint] = node nodes.Nodes[args.HostEndpoint] = node
@ -84,6 +107,10 @@ func (server *MeshCtrlServer) AddHost(args AddHostArgs) error {
return err return err
} }
/*
* GetDevice gets the WireGuard client associated with the
* interface name.
*/
func (server *MeshCtrlServer) GetDevice() *wgtypes.Device { func (server *MeshCtrlServer) GetDevice() *wgtypes.Device {
dev, err := server.Client.Device(server.IfName) dev, err := server.Client.Device(server.IfName)
@ -94,7 +121,10 @@ func (server *MeshCtrlServer) GetDevice() *wgtypes.Device {
return dev return dev
} }
func AddWgPeer(ifName string, client *wgctrl.Client, node MeshNode) error { /*
* AddWgPeer Updates the WireGuard configuration to include the peer
*/
func (server *MeshCtrlServer) AddWgPeer(node MeshNode) error {
peer := make([]wgtypes.PeerConfig, 1) peer := make([]wgtypes.PeerConfig, 1)
peerPublic, err := wgtypes.ParseKey(node.PublicKey) peerPublic, err := wgtypes.ParseKey(node.PublicKey)
@ -128,7 +158,7 @@ func AddWgPeer(ifName string, client *wgctrl.Client, node MeshNode) error {
Peers: peer, Peers: peer,
} }
err = client.ConfigureDevice(ifName, cfg) server.Client.ConfigureDevice(server.IfName, cfg)
if err != nil { if err != nil {
return err return err
@ -137,6 +167,9 @@ func AddWgPeer(ifName string, client *wgctrl.Client, node MeshNode) error {
return nil return nil
} }
/*
* EnableInterface: Enables the given WireGuard interface.
*/
func (s *MeshCtrlServer) EnableInterface(meshId string) error { func (s *MeshCtrlServer) EnableInterface(meshId string) error {
mesh, contains := s.Meshes[meshId] mesh, contains := s.Meshes[meshId]

View File

@ -0,0 +1,15 @@
/*
* RPC component of the server
*/
package ctrlserver
import (
"github.com/tim-beatham/wgmesh/pkg/rpc"
"google.golang.org/grpc"
)
func NewRpcServer(server rpc.MeshCtrlServerServer) *grpc.Server {
grpc := grpc.NewServer()
rpc.RegisterMeshCtrlServerServer(grpc, server)
return grpc
}

47
pkg/ipc/ipc.go Normal file
View File

@ -0,0 +1,47 @@
package ipc
import (
"errors"
"net"
"net/http"
"net/rpc"
"os"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver"
)
type JoinMeshArgs struct {
MeshId string
IpAdress string
}
type GetMeshReply struct {
Nodes []ctrlserver.MeshNode
}
type MeshIpc interface {
CreateMesh(name string, reply *string) error
ListMeshes(name string, reply *map[string]ctrlserver.Mesh) error
JoinMesh(args JoinMeshArgs, reply *string) error
GetMesh(meshId string, reply *GetMeshReply) error
EnableInterface(meshId string, reply *string) error
}
const SockAddr = "/tmp/wgmesh_ipc.sock"
func RunIpcHandler(server MeshIpc) error {
if err := os.RemoveAll(SockAddr); err != nil {
return errors.New("Could not find to address")
}
rpc.Register(server)
rpc.HandleHTTP()
l, e := net.Listen("unix", SockAddr)
if e != nil {
return e
}
http.Serve(l, nil)
return nil
}

View File

@ -1,12 +0,0 @@
package ipc
import "github.com/tim-beatham/wgmesh/pkg/ctrlserver"
type JoinMeshArgs struct {
MeshId string
IpAdress string
}
type GetMeshReply struct {
Nodes []ctrlserver.MeshNode
}

View File

@ -1,22 +1,17 @@
package ipc package robin
import ( import (
"context" "context"
"errors" "errors"
"net"
"net/http"
ipcRpc "net/rpc"
"os"
"slices" "slices"
"strconv" "strconv"
"time" "time"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver" "github.com/tim-beatham/wgmesh/pkg/ctrlserver"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver/rpc"
"github.com/tim-beatham/wgmesh/pkg/ipc" "github.com/tim-beatham/wgmesh/pkg/ipc"
ipctypes "github.com/tim-beatham/wgmesh/pkg/ipc"
"github.com/tim-beatham/wgmesh/pkg/lib" "github.com/tim-beatham/wgmesh/pkg/lib"
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/slaac" "github.com/tim-beatham/wgmesh/pkg/slaac"
"github.com/tim-beatham/wgmesh/pkg/wg" "github.com/tim-beatham/wgmesh/pkg/wg"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
@ -24,18 +19,13 @@ import (
"google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/insecure"
) )
const SockAddr = "/tmp/wgmesh_ipc.sock" type RobinIpc struct {
type Mesh struct {
Server *ctrlserver.MeshCtrlServer Server *ctrlserver.MeshCtrlServer
} }
const MeshIfName = "wgmesh" const MeshIfName = "wgmesh"
/* func (n *RobinIpc) CreateMesh(name string, reply *string) error {
* Create a new WireGuard mesh network
*/
func (n Mesh) CreateNewMesh(name *string, reply *string) error {
wg.CreateInterface(MeshIfName) wg.CreateInterface(MeshIfName)
mesh, err := n.Server.CreateMesh() mesh, err := n.Server.CreateMesh()
@ -61,13 +51,12 @@ func (n Mesh) CreateNewMesh(name *string, reply *string) error {
return nil return nil
} }
func (n Mesh) ListMeshes(name *string, reply *map[string]ctrlserver.Mesh) error { func (n *RobinIpc) ListMeshes(name string, reply *map[string]ctrlserver.Mesh) error {
meshes := n.Server.Meshes *reply = n.Server.Meshes
*reply = meshes
return nil return nil
} }
func updateMesh(n *Mesh, meshId string, endPoint string) error { func updateMesh(n *RobinIpc, meshId string, endPoint string) error {
conn, err := grpc.Dial(endPoint, grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := grpc.Dial(endPoint, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil { if err != nil {
@ -109,13 +98,13 @@ func updateMesh(n *Mesh, meshId string, endPoint string) error {
} }
n.Server.Meshes[meshId].Nodes[meshNode.HostEndpoint] = meshNode n.Server.Meshes[meshId].Nodes[meshNode.HostEndpoint] = meshNode
ctrlserver.AddWgPeer(n.Server.IfName, n.Server.Client, meshNode) n.Server.AddWgPeer(meshNode)
} }
return nil return nil
} }
func updatePeer(n *Mesh, node ctrlserver.MeshNode, wgHost string, meshId string) error { func updatePeer(n *RobinIpc, node ctrlserver.MeshNode, wgHost string, meshId string) error {
conn, err := grpc.Dial(node.HostEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := grpc.Dial(node.HostEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil { if err != nil {
@ -152,7 +141,7 @@ func updatePeer(n *Mesh, node ctrlserver.MeshNode, wgHost string, meshId string)
return nil return nil
} }
func updatePeers(n *Mesh, 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
@ -169,7 +158,7 @@ func updatePeers(n *Mesh, meshId string, wgHost string, nodesToExclude []string)
return nil return nil
} }
func (n Mesh) JoinMesh(args *ipctypes.JoinMeshArgs, reply *string) error { func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
conn, err := grpc.Dial(args.IpAdress+":8080", grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := grpc.Dial(args.IpAdress+":8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil { if err != nil {
@ -203,16 +192,16 @@ func (n Mesh) JoinMesh(args *ipctypes.JoinMeshArgs, reply *string) error {
} }
if r.GetSuccess() { if r.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)) err = updatePeers(n, args.MeshId, r.GetMeshIp(), make([]string, 0))
*reply = strconv.FormatBool(r.GetSuccess()) *reply = strconv.FormatBool(r.GetSuccess())
return nil return nil
} }
func (n Mesh) GetMesh(meshId string, reply *ipc.GetMeshReply) error { func (n *RobinIpc) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
mesh, contains := n.Server.Meshes[meshId] mesh, contains := n.Server.Meshes[meshId]
if contains { if contains {
@ -231,7 +220,7 @@ func (n Mesh) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
return nil return nil
} }
func (n Mesh) EnableInterface(meshId string, reply *string) error { func (n *RobinIpc) EnableInterface(meshId string, reply *string) error {
err := n.Server.EnableInterface(meshId) err := n.Server.EnableInterface(meshId)
if err != nil { if err != nil {
@ -242,21 +231,6 @@ func (n Mesh) EnableInterface(meshId string, reply *string) error {
return nil return nil
} }
func RunIpcHandler(server *ctrlserver.MeshCtrlServer) error { func NewRobinIpc(ctrlServer *ctrlserver.MeshCtrlServer) *RobinIpc {
if err := os.RemoveAll(SockAddr); err != nil { return &RobinIpc{Server: ctrlServer}
return errors.New("Could not find to address")
}
newMeshIpc := new(Mesh)
newMeshIpc.Server = server
ipcRpc.Register(newMeshIpc)
ipcRpc.HandleHTTP()
l, e := net.Listen("unix", SockAddr)
if e != nil {
return e
}
http.Serve(l, nil)
return nil
} }

View File

@ -1,23 +1,23 @@
package rpc package robin
import ( import (
context "context" "context"
"errors" "errors"
"net" "net"
"strconv" "strconv"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver" "github.com/tim-beatham/wgmesh/pkg/ctrlserver"
"google.golang.org/grpc" "github.com/tim-beatham/wgmesh/pkg/rpc"
"google.golang.org/grpc/peer" "google.golang.org/grpc/peer"
) )
type meshCtrlServer struct { type RobinRpc struct {
UnimplementedMeshCtrlServerServer rpc.UnimplementedMeshCtrlServerServer
server *ctrlserver.MeshCtrlServer server *ctrlserver.MeshCtrlServer
} }
func nodeToRpcNode(node ctrlserver.MeshNode) *MeshNode { func nodeToRpcNode(node ctrlserver.MeshNode) *rpc.MeshNode {
return &MeshNode{ return &rpc.MeshNode{
PublicKey: node.PublicKey, PublicKey: node.PublicKey,
WgEndpoint: node.WgEndpoint, WgEndpoint: node.WgEndpoint,
WgHost: node.WgHost, WgHost: node.WgHost,
@ -25,9 +25,9 @@ func nodeToRpcNode(node ctrlserver.MeshNode) *MeshNode {
} }
} }
func nodesToRpcNodes(nodes map[string]ctrlserver.MeshNode) []*MeshNode { func nodesToRpcNodes(nodes map[string]ctrlserver.MeshNode) []*rpc.MeshNode {
n := len(nodes) n := len(nodes)
meshNodes := make([]*MeshNode, n) meshNodes := make([]*rpc.MeshNode, n)
var i int = 0 var i int = 0
@ -39,14 +39,14 @@ func nodesToRpcNodes(nodes map[string]ctrlserver.MeshNode) []*MeshNode {
return meshNodes return meshNodes
} }
func (m *meshCtrlServer) GetMesh(ctx context.Context, request *GetMeshRequest) (*GetMeshReply, error) { func (m *RobinRpc) GetMesh(ctx context.Context, request *rpc.GetMeshRequest) (*rpc.GetMeshReply, error) {
mesh, contains := m.server.Meshes[request.MeshId] mesh, contains := m.server.Meshes[request.MeshId]
if !contains { if !contains {
return nil, errors.New("Element is not in the mesh") return nil, errors.New("Element is not in the mesh")
} }
reply := GetMeshReply{ reply := rpc.GetMeshReply{
MeshId: request.MeshId, MeshId: request.MeshId,
MeshNode: nodesToRpcNodes(mesh.Nodes), MeshNode: nodesToRpcNodes(mesh.Nodes),
} }
@ -54,7 +54,7 @@ func (m *meshCtrlServer) GetMesh(ctx context.Context, request *GetMeshRequest) (
return &reply, nil return &reply, nil
} }
func (m *meshCtrlServer) JoinMesh(ctx context.Context, request *JoinMeshRequest) (*JoinMeshReply, error) { func (m *RobinRpc) JoinMesh(ctx context.Context, request *rpc.JoinMeshRequest) (*rpc.JoinMeshReply, error) {
p, _ := peer.FromContext(ctx) p, _ := peer.FromContext(ctx)
hostIp, _, err := net.SplitHostPort(p.Addr.String()) hostIp, _, err := net.SplitHostPort(p.Addr.String())
@ -83,12 +83,9 @@ func (m *meshCtrlServer) JoinMesh(ctx context.Context, request *JoinMeshRequest)
return nil, err return nil, err
} }
return &JoinMeshReply{Success: true, MeshIp: &wgIp}, nil return &rpc.JoinMeshReply{Success: true, MeshIp: &wgIp}, nil
} }
func NewRpcServer(ctlServer *ctrlserver.MeshCtrlServer) *grpc.Server { func NewRobinRpc(ctrlServer *ctrlserver.MeshCtrlServer) *RobinRpc {
server := &meshCtrlServer{server: ctlServer} return &RobinRpc{server: ctrlServer}
grpc := grpc.NewServer()
RegisterMeshCtrlServerServer(grpc, server)
return grpc
} }

9
pkg/rpc/rpc.go Normal file
View File

@ -0,0 +1,9 @@
package rpc
import grpc "google.golang.org/grpc"
func NewRpcServer(server MeshCtrlServerServer) *grpc.Server {
grpc := grpc.NewServer()
RegisterMeshCtrlServerServer(grpc, server)
return grpc
}