1
0
forked from extern/smegmesh

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

View File

@ -5,8 +5,9 @@ import (
"net"
ctrlserver "github.com/tim-beatham/wgmesh/pkg/ctrlserver"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver/ipc"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver/rpc"
"github.com/tim-beatham/wgmesh/pkg/ipc"
"github.com/tim-beatham/wgmesh/pkg/robin"
"github.com/tim-beatham/wgmesh/pkg/rpc"
wg "github.com/tim-beatham/wgmesh/pkg/wg"
)
@ -22,9 +23,12 @@ func main() {
ctrlServer := ctrlserver.NewCtrlServer(wgClient, "wgmesh")
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")
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
import (
@ -11,8 +16,10 @@ import (
)
/*
* Create a new control server instance running
* on the provided port.
* NewCtrlServer creates a new instance of the ctrlserver.
* 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 {
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.
*/
func (server *MeshCtrlServer) IsInMesh(meshId string) bool {
func (server *MeshCtrlServer) MeshExists(meshId string) bool {
_, inMesh := server.Meshes[meshId]
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) {
key, err := wgtypes.GenerateKey()
@ -47,14 +58,26 @@ func (server *MeshCtrlServer) CreateMesh() (*Mesh, error) {
return &mesh, nil
}
/*
* AddHostArgs parameters needed to add
* a host to the mesh network
*/
type AddHostArgs struct {
// HostEndpoint: Public IP and port of the gRPC server the node is running
HostEndpoint string
PublicKey string
MeshId string
WgEndpoint string
WgIp string
// PubilcKey: WireGuard public key of the device
PublicKey string
// MeshId: Mesh ID of the node the the host is joining
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 {
nodes, contains := server.Meshes[args.MeshId]
@ -75,7 +98,7 @@ func (server *MeshCtrlServer) AddHost(args AddHostArgs) error {
WgHost: args.WgIp,
}
err := AddWgPeer(server.IfName, server.Client, node)
err := server.AddWgPeer(node)
if err == nil {
nodes.Nodes[args.HostEndpoint] = node
@ -84,6 +107,10 @@ func (server *MeshCtrlServer) AddHost(args AddHostArgs) error {
return err
}
/*
* GetDevice gets the WireGuard client associated with the
* interface name.
*/
func (server *MeshCtrlServer) GetDevice() *wgtypes.Device {
dev, err := server.Client.Device(server.IfName)
@ -94,7 +121,10 @@ func (server *MeshCtrlServer) GetDevice() *wgtypes.Device {
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)
peerPublic, err := wgtypes.ParseKey(node.PublicKey)
@ -128,7 +158,7 @@ func AddWgPeer(ifName string, client *wgctrl.Client, node MeshNode) error {
Peers: peer,
}
err = client.ConfigureDevice(ifName, cfg)
server.Client.ConfigureDevice(server.IfName, cfg)
if err != nil {
return err
@ -137,6 +167,9 @@ func AddWgPeer(ifName string, client *wgctrl.Client, node MeshNode) error {
return nil
}
/*
* EnableInterface: Enables the given WireGuard interface.
*/
func (s *MeshCtrlServer) EnableInterface(meshId string) error {
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 (
"context"
"errors"
"net"
"net/http"
ipcRpc "net/rpc"
"os"
"slices"
"strconv"
"time"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver/rpc"
"github.com/tim-beatham/wgmesh/pkg/ipc"
ipctypes "github.com/tim-beatham/wgmesh/pkg/ipc"
"github.com/tim-beatham/wgmesh/pkg/lib"
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/wg"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
@ -24,18 +19,13 @@ import (
"google.golang.org/grpc/credentials/insecure"
)
const SockAddr = "/tmp/wgmesh_ipc.sock"
type Mesh struct {
type RobinIpc struct {
Server *ctrlserver.MeshCtrlServer
}
const MeshIfName = "wgmesh"
/*
* Create a new WireGuard mesh network
*/
func (n Mesh) CreateNewMesh(name *string, reply *string) error {
func (n *RobinIpc) CreateMesh(name string, reply *string) error {
wg.CreateInterface(MeshIfName)
mesh, err := n.Server.CreateMesh()
@ -61,13 +51,12 @@ func (n Mesh) CreateNewMesh(name *string, reply *string) error {
return nil
}
func (n Mesh) ListMeshes(name *string, reply *map[string]ctrlserver.Mesh) error {
meshes := n.Server.Meshes
*reply = meshes
func (n *RobinIpc) ListMeshes(name string, reply *map[string]ctrlserver.Mesh) error {
*reply = n.Server.Meshes
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()))
if err != nil {
@ -109,13 +98,13 @@ func updateMesh(n *Mesh, meshId string, endPoint string) error {
}
n.Server.Meshes[meshId].Nodes[meshNode.HostEndpoint] = meshNode
ctrlserver.AddWgPeer(n.Server.IfName, n.Server.Client, meshNode)
n.Server.AddWgPeer(meshNode)
}
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()))
if err != nil {
@ -152,7 +141,7 @@ func updatePeer(n *Mesh, node ctrlserver.MeshNode, wgHost string, meshId string)
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 {
nodeEndpoint := node.HostEndpoint
@ -169,7 +158,7 @@ func updatePeers(n *Mesh, meshId string, wgHost string, nodesToExclude []string)
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()))
if err != nil {
@ -203,16 +192,16 @@ func (n Mesh) JoinMesh(args *ipctypes.JoinMeshArgs, reply *string) error {
}
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())
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]
if contains {
@ -231,7 +220,7 @@ func (n Mesh) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
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)
if err != nil {
@ -242,21 +231,6 @@ func (n Mesh) EnableInterface(meshId string, reply *string) error {
return nil
}
func RunIpcHandler(server *ctrlserver.MeshCtrlServer) error {
if err := os.RemoveAll(SockAddr); err != nil {
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
func NewRobinIpc(ctrlServer *ctrlserver.MeshCtrlServer) *RobinIpc {
return &RobinIpc{Server: ctrlServer}
}

View File

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

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
}