forked from extern/smegmesh
Implemented the forwarding of packets between meshes
This commit is contained in:
parent
180f5e226c
commit
c205be6748
@ -5,6 +5,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
ipcRpc "net/rpc"
|
ipcRpc "net/rpc"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/akamensky/argparse"
|
"github.com/akamensky/argparse"
|
||||||
@ -80,6 +81,10 @@ func getMesh(client *ipcRpc.Client, meshId string) {
|
|||||||
fmt.Println("WireGuard Endpoint: " + node.WgEndpoint)
|
fmt.Println("WireGuard Endpoint: " + node.WgEndpoint)
|
||||||
fmt.Println("Wg IP: " + node.WgHost)
|
fmt.Println("Wg IP: " + node.WgHost)
|
||||||
fmt.Println(fmt.Sprintf("Timestamp: %s", time.Unix(node.Timestamp, 0).String()))
|
fmt.Println(fmt.Sprintf("Timestamp: %s", time.Unix(node.Timestamp, 0).String()))
|
||||||
|
|
||||||
|
advertiseRoutes := strings.Join(node.Routes, ",")
|
||||||
|
fmt.Printf("Routes: %s\n", advertiseRoutes)
|
||||||
|
|
||||||
fmt.Println("---")
|
fmt.Println("---")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
certificatePath: "../../cert/cert.pem"
|
certificatePath: "../../cert/cert.pem"
|
||||||
privateKeyPath: "../../cert/key.pem"
|
privateKeyPath: "../../cert/key.pem"
|
||||||
skipCertVerification: true
|
skipCertVerification: true
|
||||||
ifName: "wgmesh"
|
|
||||||
wgPort: 51820
|
|
||||||
gRPCPort: "8080"
|
gRPCPort: "8080"
|
||||||
secret: "abc123"
|
advertiseRoutes: true
|
@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/automerge/automerge-go"
|
"github.com/automerge/automerge-go"
|
||||||
|
"github.com/tim-beatham/wgmesh/pkg/conf"
|
||||||
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/wg"
|
"github.com/tim-beatham/wgmesh/pkg/wg"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl"
|
"golang.zx2c4.com/wireguard/wgctrl"
|
||||||
@ -22,6 +23,7 @@ type CrdtNodeManager struct {
|
|||||||
Client *wgctrl.Client
|
Client *wgctrl.Client
|
||||||
doc *automerge.Doc
|
doc *automerge.Doc
|
||||||
LastHash automerge.ChangeHash
|
LastHash automerge.ChangeHash
|
||||||
|
conf *conf.WgMeshConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxFails = 5
|
const maxFails = 5
|
||||||
@ -30,6 +32,8 @@ func (c *CrdtNodeManager) AddNode(crdt MeshNodeCrdt) {
|
|||||||
crdt.FailedMap = automerge.NewMap()
|
crdt.FailedMap = automerge.NewMap()
|
||||||
crdt.Timestamp = time.Now().Unix()
|
crdt.Timestamp = time.Now().Unix()
|
||||||
c.doc.Path("nodes").Map().Set(crdt.HostEndpoint, crdt)
|
c.doc.Path("nodes").Map().Set(crdt.HostEndpoint, crdt)
|
||||||
|
nodeVal, _ := c.doc.Path("nodes").Map().Get(crdt.HostEndpoint)
|
||||||
|
nodeVal.Map().Set("routes", automerge.NewMap())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CrdtNodeManager) ApplyWg() error {
|
func (c *CrdtNodeManager) ApplyWg() error {
|
||||||
@ -66,13 +70,14 @@ func (c *CrdtNodeManager) Save() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCrdtNodeManager: Create a new crdt node manager
|
// NewCrdtNodeManager: Create a new crdt node manager
|
||||||
func NewCrdtNodeManager(meshId, hostId, devName string, port int, client *wgctrl.Client) (*CrdtNodeManager, error) {
|
func NewCrdtNodeManager(meshId, hostId, devName string, port int, conf conf.WgMeshConfiguration, client *wgctrl.Client) (*CrdtNodeManager, error) {
|
||||||
var manager CrdtNodeManager
|
var manager CrdtNodeManager
|
||||||
manager.MeshId = meshId
|
manager.MeshId = meshId
|
||||||
manager.doc = automerge.New()
|
manager.doc = automerge.New()
|
||||||
manager.IfName = devName
|
manager.IfName = devName
|
||||||
manager.Client = client
|
manager.Client = client
|
||||||
manager.NodeId = hostId
|
manager.NodeId = hostId
|
||||||
|
manager.conf = &conf
|
||||||
|
|
||||||
err := wg.CreateWgInterface(client, devName, port)
|
err := wg.CreateWgInterface(client, devName, port)
|
||||||
|
|
||||||
@ -105,6 +110,11 @@ func (m *CrdtNodeManager) convertMeshNode(node MeshNodeCrdt) (*wgtypes.PeerConfi
|
|||||||
|
|
||||||
allowedIps[0] = *ipnet
|
allowedIps[0] = *ipnet
|
||||||
|
|
||||||
|
for route, _ := range node.Routes {
|
||||||
|
_, ipnet, _ := net.ParseCIDR(route)
|
||||||
|
allowedIps = append(allowedIps, *ipnet)
|
||||||
|
}
|
||||||
|
|
||||||
peerConfig := wgtypes.PeerConfig{
|
peerConfig := wgtypes.PeerConfig{
|
||||||
PublicKey: peerPublic,
|
PublicKey: peerPublic,
|
||||||
Remove: m.HasFailed(node.HostEndpoint),
|
Remove: m.HasFailed(node.HostEndpoint),
|
||||||
@ -290,6 +300,31 @@ func (m *CrdtNodeManager) updateWgConf(devName string, nodes map[string]MeshNode
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddRoutes: adds routes to the specific nodeId
|
||||||
|
func (m *CrdtNodeManager) AddRoutes(routes ...string) error {
|
||||||
|
nodeVal, err := m.doc.Path("nodes").Map().Get(m.NodeId)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
routeMap, err := nodeVal.Map().Get("routes")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, route := range routes {
|
||||||
|
err = routeMap.Map().Set(route, struct{}{})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *CrdtNodeManager) GetSyncer() *AutomergeSync {
|
func (m *CrdtNodeManager) GetSyncer() *AutomergeSync {
|
||||||
return NewAutomergeSync(m)
|
return NewAutomergeSync(m)
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,18 @@ package crdt
|
|||||||
|
|
||||||
import "github.com/automerge/automerge-go"
|
import "github.com/automerge/automerge-go"
|
||||||
|
|
||||||
|
// MeshNodeCrdt: Represents a CRDT for a mesh nodes
|
||||||
type MeshNodeCrdt struct {
|
type MeshNodeCrdt struct {
|
||||||
HostEndpoint string `automerge:"hostEndpoint"`
|
HostEndpoint string `automerge:"hostEndpoint"`
|
||||||
WgEndpoint string `automerge:"wgEndpoint"`
|
WgEndpoint string `automerge:"wgEndpoint"`
|
||||||
PublicKey string `automerge:"publicKey"`
|
PublicKey string `automerge:"publicKey"`
|
||||||
WgHost string `automerge:"wgHost"`
|
WgHost string `automerge:"wgHost"`
|
||||||
Timestamp int64 `automerge:"timestamp"`
|
Timestamp int64 `automerge:"timestamp"`
|
||||||
FailedMap *automerge.Map `automerge:"failedMap"`
|
FailedMap *automerge.Map `automerge:"failedMap"`
|
||||||
|
Routes map[string]interface{} `automerge:"routes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MeshCrdt: Represents the mesh network as a whole
|
||||||
type MeshCrdt struct {
|
type MeshCrdt struct {
|
||||||
Nodes map[string]MeshNodeCrdt `automerge:"nodes"`
|
Nodes map[string]MeshNodeCrdt `automerge:"nodes"`
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,8 @@ type WgMeshConfiguration struct {
|
|||||||
CertificatePath string `yaml:"certificatePath"`
|
CertificatePath string `yaml:"certificatePath"`
|
||||||
PrivateKeyPath string `yaml:"privateKeyPath"`
|
PrivateKeyPath string `yaml:"privateKeyPath"`
|
||||||
SkipCertVerification bool `yaml:"skipCertVerification"`
|
SkipCertVerification bool `yaml:"skipCertVerification"`
|
||||||
IfName string `yaml:"ifName"`
|
|
||||||
WgPort int `yaml:"wgPort"`
|
|
||||||
GrpcPort string `yaml:"gRPCPort"`
|
GrpcPort string `yaml:"gRPCPort"`
|
||||||
Secret string `yaml:"secret"`
|
AdvertiseRoutes bool `yaml:"advertiseRoutes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseConfiguration(filePath string) (*WgMeshConfiguration, error) {
|
func ParseConfiguration(filePath string) (*WgMeshConfiguration, error) {
|
||||||
|
@ -18,6 +18,7 @@ type MeshNode struct {
|
|||||||
WgHost string
|
WgHost string
|
||||||
Failed bool
|
Failed bool
|
||||||
Timestamp int64
|
Timestamp int64
|
||||||
|
Routes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mesh struct {
|
type Mesh struct {
|
||||||
|
@ -13,14 +13,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ModifierLength = 16
|
ModifierLength = 16
|
||||||
ZeroLength = 9
|
ZeroLength = 9
|
||||||
hash2Length = 57
|
hash2Length = 57
|
||||||
hash1Length = 58
|
hash1Length = 58
|
||||||
Hash2Prefix = 14
|
Hash2Prefix = 14
|
||||||
Hash1Prefix = 8
|
Hash1Prefix = 8
|
||||||
InterfaceIdLen = 8
|
InterfaceIdLen = 8
|
||||||
SubnetPrefixLen = 8
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -28,14 +27,14 @@ const (
|
|||||||
*/
|
*/
|
||||||
type CgaParameters struct {
|
type CgaParameters struct {
|
||||||
Modifier [ModifierLength]byte
|
Modifier [ModifierLength]byte
|
||||||
SubnetPrefix [SubnetPrefixLen]byte
|
SubnetPrefix [2 * InterfaceIdLen]byte
|
||||||
CollisionCount uint8
|
CollisionCount uint8
|
||||||
PublicKey wgtypes.Key
|
PublicKey wgtypes.Key
|
||||||
interfaceId [2 * InterfaceIdLen]byte
|
interfaceId [2 * InterfaceIdLen]byte
|
||||||
flag byte
|
flag byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCga(key wgtypes.Key, subnetPrefix [SubnetPrefixLen]byte) (*CgaParameters, error) {
|
func NewCga(key wgtypes.Key, subnetPrefix [2 * InterfaceIdLen]byte) (*CgaParameters, error) {
|
||||||
var params CgaParameters
|
var params CgaParameters
|
||||||
|
|
||||||
_, err := rand.Read(params.Modifier[:])
|
_, err := rand.Read(params.Modifier[:])
|
||||||
|
@ -2,6 +2,7 @@ package ip
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
@ -9,8 +10,8 @@ import (
|
|||||||
|
|
||||||
type ULABuilder struct{}
|
type ULABuilder struct{}
|
||||||
|
|
||||||
func getULAPrefix(meshId string) [8]byte {
|
func getMeshPrefix(meshId string) [16]byte {
|
||||||
var ulaPrefix [8]byte
|
var ulaPrefix [16]byte
|
||||||
|
|
||||||
ulaPrefix[0] = 0xfd
|
ulaPrefix[0] = 0xfd
|
||||||
|
|
||||||
@ -24,8 +25,22 @@ func getULAPrefix(meshId string) [8]byte {
|
|||||||
return ulaPrefix
|
return ulaPrefix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ULABuilder) GetIPNet(meshId string) (*net.IPNet, error) {
|
||||||
|
meshBytes := getMeshPrefix(meshId)
|
||||||
|
var meshIP net.IP = meshBytes[:]
|
||||||
|
|
||||||
|
ip := fmt.Sprintf("%s/%d", meshIP.String(), 64)
|
||||||
|
_, net, err := net.ParseCIDR(ip)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return net, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *ULABuilder) GetIP(key wgtypes.Key, meshId string) (net.IP, error) {
|
func (u *ULABuilder) GetIP(key wgtypes.Key, meshId string) (net.IP, error) {
|
||||||
ulaPrefix := getULAPrefix(meshId)
|
ulaPrefix := getMeshPrefix(meshId)
|
||||||
|
|
||||||
c, err := NewCga(key, ulaPrefix)
|
c, err := NewCga(key, ulaPrefix)
|
||||||
|
|
||||||
|
@ -25,3 +25,15 @@ func MapValuesWithExclude[K comparable, V any](m map[K]V, exclude map[K]struct{}
|
|||||||
|
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MapKeys[K comparable, V any](m map[K]V) []K {
|
||||||
|
values := make([]K, len(m))
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for k, _ := range m {
|
||||||
|
values[i] = k
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
@ -44,7 +44,7 @@ func (c *MeshDOTConverter) Generate(meshId string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, node2 := range nodes[i+1:] {
|
for _, node2 := range nodes[i+1:] {
|
||||||
if node1 == node2 || mesh.HasFailed(node2.HostEndpoint) {
|
if node1.WgEndpoint == node2.WgEndpoint || mesh.HasFailed(node2.HostEndpoint) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
|
|
||||||
type MeshManger struct {
|
type MeshManger struct {
|
||||||
Meshes map[string]*crdt.CrdtNodeManager
|
Meshes map[string]*crdt.CrdtNodeManager
|
||||||
|
RouteManager RouteManager
|
||||||
Client *wgctrl.Client
|
Client *wgctrl.Client
|
||||||
HostEndpoint string
|
HostEndpoint string
|
||||||
conf *conf.WgMeshConfiguration
|
conf *conf.WgMeshConfiguration
|
||||||
@ -32,19 +33,20 @@ func (m *MeshManger) CreateMesh(devName string, port int) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeManager, err := crdt.NewCrdtNodeManager(key.String(), m.HostEndpoint, devName, port, m.Client)
|
nodeManager, err := crdt.NewCrdtNodeManager(key.String(), m.HostEndpoint, devName, port, *m.conf, m.Client)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Meshes[key.String()] = nodeManager
|
m.Meshes[key.String()] = nodeManager
|
||||||
return key.String(), nil
|
|
||||||
|
return key.String(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddMesh: Add the mesh to the list of meshes
|
// AddMesh: Add the mesh to the list of meshes
|
||||||
func (m *MeshManger) AddMesh(meshId string, devName string, port int, meshBytes []byte) error {
|
func (m *MeshManger) AddMesh(meshId string, devName string, port int, meshBytes []byte) error {
|
||||||
mesh, err := crdt.NewCrdtNodeManager(meshId, m.HostEndpoint, devName, port, m.Client)
|
mesh, err := crdt.NewCrdtNodeManager(meshId, m.HostEndpoint, devName, port, *m.conf, m.Client)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -63,6 +65,10 @@ func (m *MeshManger) AddMesh(meshId string, devName string, port int, meshBytes
|
|||||||
// AddMeshNode: Add a mesh node
|
// AddMeshNode: Add a mesh node
|
||||||
func (m *MeshManger) AddMeshNode(meshId string, node crdt.MeshNodeCrdt) {
|
func (m *MeshManger) AddMeshNode(meshId string, node crdt.MeshNodeCrdt) {
|
||||||
m.Meshes[meshId].AddNode(node)
|
m.Meshes[meshId].AddNode(node)
|
||||||
|
|
||||||
|
if m.conf.AdvertiseRoutes {
|
||||||
|
m.RouteManager.UpdateRoutes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MeshManger) HasChanges(meshId string) bool {
|
func (m *MeshManger) HasChanges(meshId string) bool {
|
||||||
@ -100,7 +106,13 @@ func (s *MeshManger) EnableInterface(meshId string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return wg.EnableInterface(mesh.IfName, node.WgHost)
|
err = wg.EnableInterface(mesh.IfName, node.WgHost)
|
||||||
|
|
||||||
|
if s.conf.AdvertiseRoutes {
|
||||||
|
s.RouteManager.ApplyWg(mesh)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPublicKey: Gets the public key of the WireGuard mesh
|
// GetPublicKey: Gets the public key of the WireGuard mesh
|
||||||
@ -135,11 +147,13 @@ func (s *MeshManger) UpdateTimeStamp() error {
|
|||||||
|
|
||||||
func NewMeshManager(conf conf.WgMeshConfiguration, client *wgctrl.Client) *MeshManger {
|
func NewMeshManager(conf conf.WgMeshConfiguration, client *wgctrl.Client) *MeshManger {
|
||||||
ip := lib.GetOutboundIP()
|
ip := lib.GetOutboundIP()
|
||||||
|
m := &MeshManger{
|
||||||
return &MeshManger{
|
|
||||||
Meshes: make(map[string]*crdt.CrdtNodeManager),
|
Meshes: make(map[string]*crdt.CrdtNodeManager),
|
||||||
HostEndpoint: fmt.Sprintf("%s:%s", ip.String(), conf.GrpcPort),
|
HostEndpoint: fmt.Sprintf("%s:%s", ip.String(), conf.GrpcPort),
|
||||||
Client: client,
|
Client: client,
|
||||||
conf: &conf,
|
conf: &conf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.RouteManager = NewRouteManager(m)
|
||||||
|
return m
|
||||||
}
|
}
|
||||||
|
78
pkg/mesh/route_manager.go
Normal file
78
pkg/mesh/route_manager.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package mesh
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
|
||||||
|
"github.com/tim-beatham/wgmesh/pkg/ip"
|
||||||
|
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
||||||
|
"github.com/tim-beatham/wgmesh/pkg/route"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RouteManager interface {
|
||||||
|
UpdateRoutes() error
|
||||||
|
ApplyWg(mesh *crdt.CrdtNodeManager) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type RouteManagerImpl struct {
|
||||||
|
meshManager *MeshManger
|
||||||
|
routeInstaller route.RouteInstaller
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RouteManagerImpl) UpdateRoutes() error {
|
||||||
|
meshes := r.meshManager.Meshes
|
||||||
|
ulaBuilder := new(ip.ULABuilder)
|
||||||
|
|
||||||
|
for _, mesh1 := range meshes {
|
||||||
|
for _, mesh2 := range meshes {
|
||||||
|
if mesh1 == mesh2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ipNet, err := ulaBuilder.GetIPNet(mesh2.MeshId)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logging.Log.WriteErrorf(err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh1.AddRoutes(ipNet.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RouteManagerImpl) ApplyWg(mesh *crdt.CrdtNodeManager) error {
|
||||||
|
snapshot, err := mesh.GetCrdt()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, node := range snapshot.Nodes {
|
||||||
|
if node.HostEndpoint == r.meshManager.HostEndpoint {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for route, _ := range node.Routes {
|
||||||
|
_, netIP, err := net.ParseCIDR(route)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.routeInstaller.InstallRoutes(mesh.IfName, netIP)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRouteManager(m *MeshManger) RouteManager {
|
||||||
|
return &RouteManagerImpl{meshManager: m, routeInstaller: route.NewRouteInstaller()}
|
||||||
|
}
|
@ -51,6 +51,7 @@ func (n *RobinIpc) CreateMesh(args *ipc.NewMeshArgs, reply *string) error {
|
|||||||
PublicKey: pubKey.String(),
|
PublicKey: pubKey.String(),
|
||||||
WgEndpoint: fmt.Sprintf("%s:%d", outBoundIp.String(), args.WgPort),
|
WgEndpoint: fmt.Sprintf("%s:%d", outBoundIp.String(), args.WgPort),
|
||||||
WgHost: nodeIP.String() + "/128",
|
WgHost: nodeIP.String() + "/128",
|
||||||
|
Routes: map[string]interface{}{},
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Server.MeshManager.AddMeshNode(meshId, meshNode)
|
n.Server.MeshManager.AddMeshNode(meshId, meshNode)
|
||||||
@ -127,6 +128,7 @@ func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
|
|||||||
WgEndpoint: fmt.Sprintf("%s:%d", outBoundIP.String(), args.Port),
|
WgEndpoint: fmt.Sprintf("%s:%d", outBoundIP.String(), args.Port),
|
||||||
PublicKey: pubKey.String(),
|
PublicKey: pubKey.String(),
|
||||||
WgHost: ipAddr.String() + "/128",
|
WgHost: ipAddr.String() + "/128",
|
||||||
|
Routes: make(map[string]interface{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Server.MeshManager.AddMeshNode(args.MeshId, node)
|
n.Server.MeshManager.AddMeshNode(args.MeshId, node)
|
||||||
@ -154,6 +156,7 @@ func (n *RobinIpc) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
|
|||||||
WgHost: node.WgHost,
|
WgHost: node.WgHost,
|
||||||
Failed: mesh.HasFailed(node.HostEndpoint),
|
Failed: mesh.HasFailed(node.HostEndpoint),
|
||||||
Timestamp: node.Timestamp,
|
Timestamp: node.Timestamp,
|
||||||
|
Routes: lib.MapKeys(node.Routes),
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes[i] = node
|
nodes[i] = node
|
||||||
|
47
pkg/route/route.go
Normal file
47
pkg/route/route.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package route
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
|
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RouteInstaller interface {
|
||||||
|
InstallRoutes(devName string, routes ...*net.IPNet) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type RouteInstallerImpl struct{}
|
||||||
|
|
||||||
|
// InstallRoutes: installs a route into the routing table
|
||||||
|
func (r *RouteInstallerImpl) InstallRoutes(devName string, routes ...*net.IPNet) error {
|
||||||
|
for _, route := range routes {
|
||||||
|
err := r.installRoute(devName, route)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// installRoute: installs a route into the linux table
|
||||||
|
func (r *RouteInstallerImpl) installRoute(devName string, route *net.IPNet) error {
|
||||||
|
// TODO: Find a library that automates this
|
||||||
|
cmd := exec.Command("/usr/bin/ip", "-6", "route", "add", route.String(), "dev", devName)
|
||||||
|
|
||||||
|
logging.Log.WriteInfof("%s %s", route.String(), devName)
|
||||||
|
|
||||||
|
if msg, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
logging.Log.WriteErrorf(err.Error())
|
||||||
|
logging.Log.WriteErrorf(string(msg))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRouteInstaller() RouteInstaller {
|
||||||
|
return &RouteInstallerImpl{}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user