forked from extern/smegmesh
Automerge changes
This commit is contained in:
parent
f191c4ff44
commit
923ca716ec
@ -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())
|
||||||
|
53
pkg/automerge/automerge.go
Normal file
53
pkg/automerge/automerge.go
Normal 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
12
pkg/automerge/types.go
Normal 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"`
|
||||||
|
}
|
@ -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)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
28
pkg/gossip/gossip_requester.go
Normal file
28
pkg/gossip/gossip_requester.go
Normal 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
|
||||||
|
}
|
1
pkg/gossip/gossip_responser.go
Normal file
1
pkg/gossip/gossip_responser.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package gossip
|
@ -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
11
pkg/ip/types.go
Normal 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)
|
||||||
|
}
|
@ -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
|
|
||||||
}
|
}
|
95
pkg/manager/mesh_manager.go
Normal file
95
pkg/manager/mesh_manager.go
Normal 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
|
||||||
|
}
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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{
|
||||||
|
57
pkg/wg/wg.go
57
pkg/wg/wg.go
@ -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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user