1
0
forked from extern/smegmesh

Automerge changes

This commit is contained in:
Tim Beatham 2023-10-05 17:48:54 +01:00
parent f191c4ff44
commit 923ca716ec
16 changed files with 355 additions and 310 deletions

View File

@ -5,6 +5,7 @@ import (
"github.com/tim-beatham/wgmesh/pkg/conf" "github.com/tim-beatham/wgmesh/pkg/conf"
ctrlserver "github.com/tim-beatham/wgmesh/pkg/ctrlserver" ctrlserver "github.com/tim-beatham/wgmesh/pkg/ctrlserver"
"github.com/tim-beatham/wgmesh/pkg/ip"
"github.com/tim-beatham/wgmesh/pkg/ipc" "github.com/tim-beatham/wgmesh/pkg/ipc"
logging "github.com/tim-beatham/wgmesh/pkg/log" logging "github.com/tim-beatham/wgmesh/pkg/log"
"github.com/tim-beatham/wgmesh/pkg/middleware" "github.com/tim-beatham/wgmesh/pkg/middleware"
@ -33,8 +34,14 @@ func main() {
ctrlServer, err := ctrlserver.NewCtrlServer(&ctrlServerParams) ctrlServer, err := ctrlserver.NewCtrlServer(&ctrlServerParams)
authProvider.Manager = ctrlServer.ConnectionServer.JwtManager authProvider.Manager = ctrlServer.ConnectionServer.JwtManager
robinIpcParams := robin.RobinIpcParams{
CtrlServer: ctrlServer,
Allocator: &ip.ULABuilder{},
}
robinRpc.Server = ctrlServer robinRpc.Server = ctrlServer
robinIpc.Server = ctrlServer robinIpc = robin.NewRobinIpc(robinIpcParams)
if err != nil { if err != nil {
logging.ErrorLog.Fatalln(err.Error()) logging.ErrorLog.Fatalln(err.Error())

View File

@ -0,0 +1,53 @@
package crdt
import "github.com/automerge/automerge-go"
// CrdtNodeManager manages nodes in the crdt mesh
type CrdtNodeManager struct {
meshId string
IfName string
doc *automerge.Doc
}
func (c *CrdtNodeManager) AddNode(crdt MeshNodeCrdt) {
c.doc.Path("nodes").Map().Set(crdt.PublicKey, crdt)
}
// GetCrdt(): Converts the document into a struct
func (c *CrdtNodeManager) GetCrdt() (*MeshCrdt, error) {
return automerge.As[*MeshCrdt](c.doc.Root())
}
// Load: Load an entire mesh network
func (c *CrdtNodeManager) Load(bytes []byte) error {
doc, err := automerge.Load(bytes)
if err != nil {
return err
}
c.doc = doc
return nil
}
// Save: Save an entire mesh network
func (c *CrdtNodeManager) Save(doc []byte) []byte {
return c.doc.Save()
}
func (c *CrdtNodeManager) LoadChanges(changes []byte) {
c.doc.LoadIncremental(changes)
}
func (c *CrdtNodeManager) SaveChanges() []byte {
return c.SaveChanges()
}
// NewCrdtNodeManager: Create a new crdt node manager
func NewCrdtNodeManager(meshId, devName string) *CrdtNodeManager {
var manager CrdtNodeManager
manager.meshId = meshId
manager.doc = automerge.New()
manager.IfName = devName
return &manager
}

12
pkg/automerge/types.go Normal file
View File

@ -0,0 +1,12 @@
package crdt
type MeshNodeCrdt struct {
HostEndpoint string `automerge:"hostEndpoint"`
WgEndpoint string `automerge:"wgEndpoint"`
PublicKey string `automerge:"publicKey"`
WgHost string `automerge:"wgHost"`
}
type MeshCrdt struct {
Nodes map[string]MeshNodeCrdt `automerge:"nodes"`
}

View File

@ -13,7 +13,6 @@ import (
"github.com/tim-beatham/wgmesh/pkg/rpc" "github.com/tim-beatham/wgmesh/pkg/rpc"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
) )
@ -35,12 +34,6 @@ type WgCtrlConnection struct {
tokens map[string]string tokens map[string]string
} }
var keepAliveParams = keepalive.ClientParameters{
Time: 5 * time.Minute,
Timeout: time.Second,
PermitWithoutStream: true,
}
func NewWgCtrlConnection(clientConfig *tls.Config, server string) (*WgCtrlConnection, error) { func NewWgCtrlConnection(clientConfig *tls.Config, server string) (*WgCtrlConnection, error) {
var conn WgCtrlConnection var conn WgCtrlConnection
conn.tokens = make(map[string]string) conn.tokens = make(map[string]string)
@ -82,7 +75,6 @@ func (c *WgCtrlConnection) Authenticate(meshId string) error {
// ConnectWithToken: Connects to a new gRPC peer given the address of the other server. // ConnectWithToken: Connects to a new gRPC peer given the address of the other server.
func (c *WgCtrlConnection) Connect() error { func (c *WgCtrlConnection) Connect() error {
conn, err := grpc.Dial(c.endpoint, conn, err := grpc.Dial(c.endpoint,
grpc.WithKeepaliveParams(keepAliveParams),
grpc.WithTransportCredentials(credentials.NewTLS(c.clientConfig)), grpc.WithTransportCredentials(credentials.NewTLS(c.clientConfig)),
) )

View File

@ -7,22 +7,27 @@ import (
logging "github.com/tim-beatham/wgmesh/pkg/log" logging "github.com/tim-beatham/wgmesh/pkg/log"
) )
type ConnectionManager interface {
AddConnection(endPoint string) (PeerConnection, error)
GetConnection(endPoint string) (PeerConnection, error)
}
// ConnectionManager manages connections between other peers // ConnectionManager manages connections between other peers
// in the control plane. // in the control plane.
type ConnectionManager struct { type JwtConnectionManager struct {
// clientConnections maps an endpoint to a connection // clientConnections maps an endpoint to a connection
clientConnections map[string]PeerConnection clientConnections map[string]PeerConnection
serverConfig *tls.Config serverConfig *tls.Config
clientConfig *tls.Config clientConfig *tls.Config
} }
type NewConnectionManagerParams struct { type NewJwtConnectionManagerParams struct {
CertificatePath string CertificatePath string
PrivateKey string PrivateKey string
SkipCertVerification bool SkipCertVerification bool
} }
func NewConnectionManager(params *NewConnectionManagerParams) (*ConnectionManager, error) { func NewJwtConnectionManager(params *NewJwtConnectionManagerParams) (ConnectionManager, error) {
cert, err := tls.LoadX509KeyPair(params.CertificatePath, params.PrivateKey) cert, err := tls.LoadX509KeyPair(params.CertificatePath, params.PrivateKey)
if err != nil { if err != nil {
@ -49,11 +54,11 @@ func NewConnectionManager(params *NewConnectionManagerParams) (*ConnectionManage
} }
connections := make(map[string]PeerConnection) connections := make(map[string]PeerConnection)
connMgr := ConnectionManager{connections, serverConfig, clientConfig} connMgr := JwtConnectionManager{connections, serverConfig, clientConfig}
return &connMgr, nil return &connMgr, nil
} }
func (m *ConnectionManager) GetConnection(endpoint string) (PeerConnection, error) { func (m *JwtConnectionManager) GetConnection(endpoint string) (PeerConnection, error) {
conn, exists := m.clientConnections[endpoint] conn, exists := m.clientConnections[endpoint]
if !exists { if !exists {
@ -63,12 +68,8 @@ func (m *ConnectionManager) GetConnection(endpoint string) (PeerConnection, erro
return conn, nil return conn, nil
} }
type AddConnectionParams struct {
TokenId string
}
// AddToken: Adds a connection to the list of connections to manage // AddToken: Adds a connection to the list of connections to manage
func (m *ConnectionManager) AddConnection(endPoint string) (PeerConnection, error) { func (m *JwtConnectionManager) AddConnection(endPoint string) (PeerConnection, error) {
_, exists := m.clientConnections[endPoint] _, exists := m.clientConnections[endPoint]
if exists { if exists {

View File

@ -6,16 +6,11 @@
package ctrlserver package ctrlserver
import ( import (
"errors"
"net"
"github.com/tim-beatham/wgmesh/pkg/conf" "github.com/tim-beatham/wgmesh/pkg/conf"
"github.com/tim-beatham/wgmesh/pkg/conn" "github.com/tim-beatham/wgmesh/pkg/conn"
"github.com/tim-beatham/wgmesh/pkg/lib" "github.com/tim-beatham/wgmesh/pkg/manager"
"github.com/tim-beatham/wgmesh/pkg/rpc" "github.com/tim-beatham/wgmesh/pkg/rpc"
"github.com/tim-beatham/wgmesh/pkg/wg"
"golang.zx2c4.com/wireguard/wgctrl" "golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
type NewCtrlServerParams struct { type NewCtrlServerParams struct {
@ -33,17 +28,16 @@ type NewCtrlServerParams struct {
*/ */
func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) { func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) {
ctrlServer := new(MeshCtrlServer) ctrlServer := new(MeshCtrlServer)
ctrlServer.Meshes = make(map[string]Mesh)
ctrlServer.Client = params.WgClient ctrlServer.Client = params.WgClient
ctrlServer.IfName = params.Conf.IfName ctrlServer.MeshManager = &manager.MeshManger{}
connManagerParams := conn.NewConnectionManagerParams{ connManagerParams := conn.NewJwtConnectionManagerParams{
CertificatePath: params.Conf.CertificatePath, CertificatePath: params.Conf.CertificatePath,
PrivateKey: params.Conf.PrivateKeyPath, PrivateKey: params.Conf.PrivateKeyPath,
SkipCertVerification: params.Conf.SkipCertVerification, SkipCertVerification: params.Conf.SkipCertVerification,
} }
connMgr, err := conn.NewConnectionManager(&connManagerParams) connMgr, err := conn.NewJwtConnectionManager(&connManagerParams)
if err != nil { if err != nil {
return nil, err return nil, err
@ -68,162 +62,3 @@ func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) {
ctrlServer.ConnectionServer = connServer ctrlServer.ConnectionServer = connServer
return ctrlServer, nil return ctrlServer, nil
} }
/*
* MeshExists returns true if the client is part of the mesh
* false otherwise.
*/
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()
if err != nil {
return nil, err
}
var mesh Mesh = Mesh{
SharedKey: &key,
Nodes: make(map[string]MeshNode),
}
server.Meshes[key.String()] = mesh
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
// 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]
if !contains {
return errors.New("The mesh: " + args.MeshId + " does not exist")
}
_, contains = nodes.Nodes[args.HostEndpoint]
if contains {
return errors.New("The node already has an endpoint in the mesh network")
}
node := MeshNode{
HostEndpoint: args.HostEndpoint,
WgEndpoint: args.WgEndpoint,
PublicKey: args.PublicKey,
WgHost: args.WgIp,
}
err := server.AddWgPeer(node)
if err == nil {
nodes.Nodes[args.HostEndpoint] = node
}
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)
if err != nil {
return nil
}
return dev
}
/*
* 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)
if err != nil {
return err
}
peerEndpoint, err := net.ResolveUDPAddr("udp", node.WgEndpoint)
if err != nil {
return err
}
allowedIps := make([]net.IPNet, 1)
_, ipnet, err := net.ParseCIDR(node.WgHost)
if err != nil {
return err
}
allowedIps[0] = *ipnet
peer[0] = wgtypes.PeerConfig{
PublicKey: peerPublic,
Endpoint: peerEndpoint,
AllowedIPs: allowedIps,
}
cfg := wgtypes.Config{
Peers: peer,
}
server.Client.ConfigureDevice(server.IfName, cfg)
if err != nil {
return err
}
return nil
}
/*
* EnableInterface: Enables the given WireGuard interface.
*/
func (s *MeshCtrlServer) EnableInterface(meshId string) error {
mesh, contains := s.Meshes[meshId]
if !contains {
return errors.New("Mesh does not exist")
}
endPoint := lib.GetOutboundIP().String() + ":8080"
node, contains := mesh.Nodes[endPoint]
if !contains {
return errors.New("Node does not exist in the mesh")
}
return wg.EnableInterface(s.IfName, node.WgHost)
}

View File

@ -2,6 +2,7 @@ package ctrlserver
import ( import (
"github.com/tim-beatham/wgmesh/pkg/conn" "github.com/tim-beatham/wgmesh/pkg/conn"
"github.com/tim-beatham/wgmesh/pkg/manager"
"golang.zx2c4.com/wireguard/wgctrl" "golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
@ -27,8 +28,7 @@ type Mesh struct {
*/ */
type MeshCtrlServer struct { type MeshCtrlServer struct {
Client *wgctrl.Client Client *wgctrl.Client
Meshes map[string]Mesh MeshManager *manager.MeshManger
IfName string ConnectionManager conn.ConnectionManager
ConnectionManager *conn.ConnectionManager
ConnectionServer *conn.ConnectionServer ConnectionServer *conn.ConnectionServer
} }

View File

@ -0,0 +1,28 @@
package gossip
import (
"github.com/tim-beatham/wgmesh/pkg/ctrlserver"
"github.com/tim-beatham/wgmesh/pkg/ip"
"github.com/tim-beatham/wgmesh/pkg/ipc"
)
type GossipRequester struct {
Server *ctrlserver.MeshCtrlServer
ipAlloactor ip.IPAllocator
}
func (r *GossipRequester) CreateMesh(name string, reply *string) error {
return nil
}
func (r *GossipRequester) ListMeshes(name string, reply string) error {
return nil
}
func (r *GossipRequester) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
return nil
}
func (r *GossipRequester) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
return nil
}

View File

@ -0,0 +1 @@
package gossip

View File

@ -1,4 +1,4 @@
package cga package ip
/* /*
* Use a WireGuard public key to generate a unique interface ID * Use a WireGuard public key to generate a unique interface ID
@ -106,7 +106,7 @@ func (c *CgaParameters) generateInterface() []byte {
return interfaceId return interfaceId
} }
func (c *CgaParameters) GetIpv6() net.IP { func (c *CgaParameters) GetIP() net.IP {
if c.flag == 1 { if c.flag == 1 {
return c.interfaceId[:] return c.interfaceId[:]
} }

11
pkg/ip/types.go Normal file
View File

@ -0,0 +1,11 @@
package ip
import (
"net"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
type IPAllocator interface {
GetIP(key wgtypes.Key, meshId string) (net.IP, error)
}

View File

@ -1,15 +1,13 @@
package slaac package ip
import ( import (
"crypto/sha1" "crypto/sha1"
"net"
"github.com/tim-beatham/wgmesh/pkg/cga"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
type ULA struct { type ULABuilder struct{}
CGA cga.CgaParameters
}
func getULAPrefix(meshId string) [8]byte { func getULAPrefix(meshId string) [8]byte {
var ulaPrefix [8]byte var ulaPrefix [8]byte
@ -26,14 +24,13 @@ func getULAPrefix(meshId string) [8]byte {
return ulaPrefix return ulaPrefix
} }
func NewULA(key wgtypes.Key, meshId string) (*ULA, error) { func (u *ULABuilder) GetIP(key wgtypes.Key, meshId string) (net.IP, error) {
ulaPrefix := getULAPrefix(meshId) ulaPrefix := getULAPrefix(meshId)
c, err := cga.NewCga(key, ulaPrefix) c, err := NewCga(key, ulaPrefix)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return c.GetIP(), nil
return &ULA{CGA: *c}, nil
} }

View File

@ -0,0 +1,95 @@
package manager
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"
)
type MeshManger struct {
Meshes map[string]*crdt.CrdtNodeManager
Client *wgctrl.Client
}
func (m *MeshManger) MeshExists(meshId string) bool {
_, inMesh := m.Meshes[meshId]
return inMesh
}
// CreateMesh: Creates a new mesh, stores it and returns the mesh id
func (m *MeshManger) CreateMesh(meshId, devName string) (string, error) {
key, err := wgtypes.GenerateKey()
if err != nil {
return "", err
}
nodeManager := crdt.NewCrdtNodeManager(key.String(), devName)
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 {
mesh, ok := m.Meshes[meshId]
if !ok {
return errors.New("mesh does not exist")
}
mesh.LoadChanges(changes)
crdt, err := mesh.GetCrdt()
if err != nil {
return err
}
wg.UpdateWgConf(m.Meshes[meshId].IfName, crdt.Nodes, client)
return nil
}
// EnableInterface: Enables the given WireGuard interface.
func (s *MeshManger) EnableInterface(meshId string) error {
mesh, contains := s.Meshes[meshId]
if !contains {
return errors.New("Mesh does not exist")
}
crdt, err := mesh.GetCrdt()
if err != nil {
return err
}
endPoint := lib.GetOutboundIP().String() + ":8080"
node, contains := crdt.Nodes[endPoint]
if !contains {
return errors.New("Node does not exist in the mesh")
}
return wg.EnableInterface(mesh.IfName, node.WgEndpoint)
}
// GetPublicKey: Gets the public key of the WireGuard mesh
func (s *MeshManger) GetPublicKey(meshId string) (*wgtypes.Key, error) {
mesh, ok := s.Meshes[meshId]
if !ok {
return nil, errors.New("mesh does not exist")
}
dev, err := s.Client.Device(mesh.IfName)
if err != nil {
return nil, err
}
return &dev.PublicKey, nil
}

View File

@ -8,24 +8,30 @@ import (
"time" "time"
"github.com/tim-beatham/wgmesh/pkg/ctrlserver" "github.com/tim-beatham/wgmesh/pkg/ctrlserver"
"github.com/tim-beatham/wgmesh/pkg/ip"
"github.com/tim-beatham/wgmesh/pkg/ipc" "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/rpc"
"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"
) )
type RobinIpc struct { type RobinIpc struct {
Server *ctrlserver.MeshCtrlServer Server *ctrlserver.MeshCtrlServer
ipAllocator ip.IPAllocator
} }
func (n *RobinIpc) CreateMesh(name string, reply *string) error { func (n *RobinIpc) CreateMesh(name string, reply *string) error {
wg.CreateInterface(n.Server.IfName) wg.CreateInterface(n.Server.IfName)
mesh, err := n.Server.CreateMesh() mesh, err := n.Server.CreateMesh()
ula, _ := slaac.NewULA(n.Server.GetDevice().PublicKey, "0")
nodeIP, err := n.ipAllocator.GetIP(n.Server.GetPublicKey(), mesh.SharedKey.String())
if err != nil {
return err
}
outBoundIp := lib.GetOutboundIP().String() outBoundIp := lib.GetOutboundIP().String()
@ -33,7 +39,7 @@ func (n *RobinIpc) CreateMesh(name string, reply *string) error {
HostEndpoint: outBoundIp + ":8080", HostEndpoint: outBoundIp + ":8080",
PublicKey: n.Server.GetDevice().PublicKey.String(), PublicKey: n.Server.GetDevice().PublicKey.String(),
WgEndpoint: outBoundIp + ":51820", WgEndpoint: outBoundIp + ":51820",
WgIp: ula.CGA.GetIpv6().String() + "/128", WgIp: nodeIP.String() + "/128",
MeshId: mesh.SharedKey.String(), MeshId: mesh.SharedKey.String(),
} }
@ -190,7 +196,6 @@ func (n *RobinIpc) Authenticate(meshId, endpoint string) error {
return err return err
} }
err = peerConnection.Connect()
return err return err
} }
@ -225,16 +230,21 @@ func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
defer cancel() defer cancel()
dev := n.Server.GetDevice() dev := n.Server.GetDevice()
ula, _ := slaac.NewULA(dev.PublicKey, "0")
logging.InfoLog.Println("WgIP: " + ula.CGA.GetIpv6().String()) ipAddr, err := n.ipAllocator.GetIP(n.Server.GetPublicKey(), args.MeshId)
if err != nil {
return err
}
logging.InfoLog.Println("WgIP: " + ipAddr.String())
joinMeshReq := rpc.JoinMeshRequest{ joinMeshReq := rpc.JoinMeshRequest{
MeshId: args.MeshId, MeshId: args.MeshId,
HostPort: 8080, HostPort: 8080,
PublicKey: dev.PublicKey.String(), PublicKey: dev.PublicKey.String(),
WgPort: int32(dev.ListenPort), WgPort: int32(dev.ListenPort),
WgIp: ula.CGA.GetIpv6().String() + "/128", WgIp: ipAddr.String() + "/128",
} }
r, err := c.JoinMesh(ctx, &joinMeshReq) r, err := c.JoinMesh(ctx, &joinMeshReq)
@ -283,6 +293,14 @@ func (n *RobinIpc) EnableInterface(meshId string, reply *string) error {
return nil return nil
} }
func NewRobinIpc(ctrlServer *ctrlserver.MeshCtrlServer) *RobinIpc { type RobinIpcParams struct {
return &RobinIpc{Server: ctrlServer} CtrlServer *ctrlserver.MeshCtrlServer
Allocator ip.IPAllocator
}
func NewRobinIpc(ipcParams RobinIpcParams) RobinIpc {
return RobinIpc{
Server: ipcParams.CtrlServer,
ipAllocator: ipcParams.Allocator,
}
} }

View File

@ -143,8 +143,7 @@ type GetMeshReply struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
MeshId string `protobuf:"bytes,1,opt,name=meshId,proto3" json:"meshId,omitempty"` Mesh []byte `protobuf:"bytes,2,opt,name=mesh,proto3" json:"mesh,omitempty"`
MeshNode []*MeshNode `protobuf:"bytes,2,rep,name=meshNode,proto3" json:"meshNode,omitempty"`
} }
func (x *GetMeshReply) Reset() { func (x *GetMeshReply) Reset() {
@ -179,16 +178,9 @@ func (*GetMeshReply) Descriptor() ([]byte, []int) {
return file_pkg_grpc_ctrlserver_ctrlserver_proto_rawDescGZIP(), []int{2} return file_pkg_grpc_ctrlserver_ctrlserver_proto_rawDescGZIP(), []int{2}
} }
func (x *GetMeshReply) GetMeshId() string { func (x *GetMeshReply) GetMesh() []byte {
if x != nil { if x != nil {
return x.MeshId return x.Mesh
}
return ""
}
func (x *GetMeshReply) GetMeshNode() []*MeshNode {
if x != nil {
return x.MeshNode
} }
return nil return nil
} }
@ -198,11 +190,7 @@ type JoinMeshRequest struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
MeshId string `protobuf:"bytes,1,opt,name=meshId,proto3" json:"meshId,omitempty"` Changes []byte `protobuf:"bytes,1,opt,name=changes,proto3" json:"changes,omitempty"`
HostPort int32 `protobuf:"varint,2,opt,name=hostPort,proto3" json:"hostPort,omitempty"`
PublicKey string `protobuf:"bytes,3,opt,name=publicKey,proto3" json:"publicKey,omitempty"`
WgPort int32 `protobuf:"varint,4,opt,name=wgPort,proto3" json:"wgPort,omitempty"`
WgIp string `protobuf:"bytes,5,opt,name=wgIp,proto3" json:"wgIp,omitempty"`
} }
func (x *JoinMeshRequest) Reset() { func (x *JoinMeshRequest) Reset() {
@ -237,39 +225,11 @@ func (*JoinMeshRequest) Descriptor() ([]byte, []int) {
return file_pkg_grpc_ctrlserver_ctrlserver_proto_rawDescGZIP(), []int{3} return file_pkg_grpc_ctrlserver_ctrlserver_proto_rawDescGZIP(), []int{3}
} }
func (x *JoinMeshRequest) GetMeshId() string { func (x *JoinMeshRequest) GetChanges() []byte {
if x != nil { if x != nil {
return x.MeshId return x.Changes
} }
return "" return nil
}
func (x *JoinMeshRequest) GetHostPort() int32 {
if x != nil {
return x.HostPort
}
return 0
}
func (x *JoinMeshRequest) GetPublicKey() string {
if x != nil {
return x.PublicKey
}
return ""
}
func (x *JoinMeshRequest) GetWgPort() int32 {
if x != nil {
return x.WgPort
}
return 0
}
func (x *JoinMeshRequest) GetWgIp() string {
if x != nil {
return x.WgIp
}
return ""
} }
type JoinMeshReply struct { type JoinMeshReply struct {
@ -278,7 +238,6 @@ type JoinMeshReply struct {
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
MeshIp *string `protobuf:"bytes,2,opt,name=meshIp,proto3,oneof" json:"meshIp,omitempty"`
} }
func (x *JoinMeshReply) Reset() { func (x *JoinMeshReply) Reset() {
@ -320,13 +279,6 @@ func (x *JoinMeshReply) GetSuccess() bool {
return false return false
} }
func (x *JoinMeshReply) GetMeshIp() string {
if x != nil && x.MeshIp != nil {
return *x.MeshIp
}
return ""
}
var File_pkg_grpc_ctrlserver_ctrlserver_proto protoreflect.FileDescriptor var File_pkg_grpc_ctrlserver_ctrlserver_proto protoreflect.FileDescriptor
var file_pkg_grpc_ctrlserver_ctrlserver_proto_rawDesc = []byte{ var file_pkg_grpc_ctrlserver_ctrlserver_proto_rawDesc = []byte{
@ -343,37 +295,25 @@ var file_pkg_grpc_ctrlserver_ctrlserver_proto_rawDesc = []byte{
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x77, 0x67, 0x48, 0x6f, 0x73, 0x74, 0x22, 0x28, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x77, 0x67, 0x48, 0x6f, 0x73, 0x74, 0x22, 0x28,
0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 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, 0x56, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4d, 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, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x73, 0x68,
0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6d, 0x65, 0x73, 0x68, 0x22, 0x2b, 0x0a, 0x0f,
0x12, 0x2e, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x03, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x65, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x73, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x29, 0x0a, 0x0d, 0x4a, 0x6f, 0x69,
0x22, 0x8f, 0x01, 0x0a, 0x0f, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75,
0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x64, 0x18, 0x01, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x65, 0x73, 0x73, 0x32, 0x91, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x74, 0x72,
0x68, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65,
0x68, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x73, 0x68, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x47, 0x65,
0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72,
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x67, 0x50, 0x6f, 0x72, 0x74, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x68, 0x52,
0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x67, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x08, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65,
0x0a, 0x04, 0x77, 0x67, 0x49, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x77, 0x67, 0x73, 0x68, 0x12, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4a, 0x6f,
0x49, 0x70, 0x22, 0x51, 0x0a, 0x0d, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x69, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e,
0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x72, 0x70, 0x63, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x73,
0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, 0x70, 0x6b, 0x67, 0x2f,
0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x06, 0x6d, 0x65, 0x73, 0x68, 0x49, 0x70, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6d,
0x65, 0x73, 0x68, 0x49, 0x70, 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 ( var (
@ -397,16 +337,15 @@ var file_pkg_grpc_ctrlserver_ctrlserver_proto_goTypes = []interface{}{
(*JoinMeshReply)(nil), // 4: rpctypes.JoinMeshReply (*JoinMeshReply)(nil), // 4: rpctypes.JoinMeshReply
} }
var file_pkg_grpc_ctrlserver_ctrlserver_proto_depIdxs = []int32{ var file_pkg_grpc_ctrlserver_ctrlserver_proto_depIdxs = []int32{
0, // 0: rpctypes.GetMeshReply.meshNode:type_name -> rpctypes.MeshNode 1, // 0: rpctypes.MeshCtrlServer.GetMesh:input_type -> rpctypes.GetMeshRequest
1, // 1: rpctypes.MeshCtrlServer.GetMesh:input_type -> rpctypes.GetMeshRequest 3, // 1: rpctypes.MeshCtrlServer.JoinMesh:input_type -> rpctypes.JoinMeshRequest
3, // 2: rpctypes.MeshCtrlServer.JoinMesh:input_type -> rpctypes.JoinMeshRequest 2, // 2: rpctypes.MeshCtrlServer.GetMesh:output_type -> rpctypes.GetMeshReply
2, // 3: rpctypes.MeshCtrlServer.GetMesh:output_type -> rpctypes.GetMeshReply 4, // 3: rpctypes.MeshCtrlServer.JoinMesh:output_type -> rpctypes.JoinMeshReply
4, // 4: rpctypes.MeshCtrlServer.JoinMesh:output_type -> rpctypes.JoinMeshReply 2, // [2:4] is the sub-list for method output_type
3, // [3:5] is the sub-list for method output_type 0, // [0:2] is the sub-list for method input_type
1, // [1:3] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee
1, // [1:1] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name
0, // [0:1] is the sub-list for field type_name
} }
func init() { file_pkg_grpc_ctrlserver_ctrlserver_proto_init() } func init() { file_pkg_grpc_ctrlserver_ctrlserver_proto_init() }
@ -476,7 +415,6 @@ func file_pkg_grpc_ctrlserver_ctrlserver_proto_init() {
} }
} }
} }
file_pkg_grpc_ctrlserver_ctrlserver_proto_msgTypes[4].OneofWrappers = []interface{}{}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -5,6 +5,7 @@ import (
"net" "net"
"os/exec" "os/exec"
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
"golang.zx2c4.com/wireguard/wgctrl" "golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
@ -81,3 +82,59 @@ func EnableInterface(ifName string, ip string) error {
return nil 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
}