diff --git a/cmd/wg-mesh/main.go b/cmd/wg-mesh/main.go index 70f78b4..8925b7d 100644 --- a/cmd/wg-mesh/main.go +++ b/cmd/wg-mesh/main.go @@ -157,6 +157,20 @@ func queryMesh(client *ipcRpc.Client, meshId, query string) { fmt.Println(reply) } +// putDescription: puts updates the description about the node to the meshes +func putDescription(client *ipcRpc.Client, description string) { + var reply string + + err := client.Call("IpcHandler.PutDescription", &description, &reply) + + if err != nil { + fmt.Println(err.Error()) + return + } + + fmt.Println(reply) +} + func main() { parser := argparse.NewParser("wg-mesh", "wg-mesh Manipulate WireGuard meshes") @@ -164,11 +178,12 @@ func main() { newMeshCmd := parser.NewCommand("new-mesh", "Create a new mesh") listMeshCmd := parser.NewCommand("list-meshes", "List meshes the node is connected to") joinMeshCmd := parser.NewCommand("join-mesh", "Join a mesh network") - getMeshCmd := parser.NewCommand("get-mesh", "Get a mesh network") + // getMeshCmd := parser.NewCommand("get-mesh", "Get a mesh network") enableInterfaceCmd := parser.NewCommand("enable-interface", "Enable A Specific Mesh Interface") getGraphCmd := parser.NewCommand("get-graph", "Convert a mesh into DOT format") leaveMeshCmd := parser.NewCommand("leave-mesh", "Leave a mesh network") queryMeshCmd := parser.NewCommand("query-mesh", "Query a mesh network using JMESPath") + putDescriptionCmd := parser.NewCommand("put-description", "Place a description for the node") var newMeshIfName *string = newMeshCmd.String("f", "ifname", &argparse.Options{Required: true}) var newMeshPort *int = newMeshCmd.Int("p", "wgport", &argparse.Options{Required: true}) @@ -180,8 +195,10 @@ func main() { var joinMeshPort *int = joinMeshCmd.Int("p", "wgport", &argparse.Options{Required: true}) var joinMeshEndpoint *string = joinMeshCmd.String("e", "endpoint", &argparse.Options{}) - var getMeshId *string = getMeshCmd.String("m", "mesh", &argparse.Options{Required: true}) + // var getMeshId *string = getMeshCmd.String("m", "mesh", &argparse.Options{Required: true}) + var enableInterfaceMeshId *string = enableInterfaceCmd.String("m", "mesh", &argparse.Options{Required: true}) + var getGraphMeshId *string = getGraphCmd.String("m", "mesh", &argparse.Options{Required: true}) var leaveMeshMeshId *string = leaveMeshCmd.String("m", "mesh", &argparse.Options{Required: true}) @@ -189,6 +206,8 @@ func main() { var queryMeshMeshId *string = queryMeshCmd.String("m", "mesh", &argparse.Options{Required: true}) var queryMeshQuery *string = queryMeshCmd.String("q", "query", &argparse.Options{Required: true}) + var description *string = putDescriptionCmd.String("d", "description", &argparse.Options{Required: true}) + err := parser.Parse(os.Args) if err != nil { @@ -226,9 +245,9 @@ func main() { })) } - if getMeshCmd.Happened() { - getMesh(client, *getMeshId) - } + // if getMeshCmd.Happened() { + // getMesh(client, *getMeshId) + // } if getGraphCmd.Happened() { getGraph(client, *getGraphMeshId) @@ -245,4 +264,8 @@ func main() { if queryMeshCmd.Happened() { queryMesh(client, *queryMeshMeshId, *queryMeshQuery) } + + if putDescriptionCmd.Happened() { + putDescription(client, *description) + } } diff --git a/cmd/wgmeshd/main.go b/cmd/wgmeshd/main.go index b4c8a16..a345755 100644 --- a/cmd/wgmeshd/main.go +++ b/cmd/wgmeshd/main.go @@ -3,6 +3,7 @@ package main import ( "log" "os" + "os/signal" "github.com/tim-beatham/wgmesh/pkg/conf" ctrlserver "github.com/tim-beatham/wgmesh/pkg/ctrlserver" @@ -71,16 +72,30 @@ func main() { go syncScheduler.Run() go timestampScheduler.Run() + closeResources := func() { + logging.Log.WriteInfof("Closing resources") + syncScheduler.Stop() + timestampScheduler.Stop() + ctrlServer.Close() + client.Close() + } + + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + + go func() { + for range c { + closeResources() + os.Exit(0) + } + }() + err = ctrlServer.ConnectionServer.Listen() if err != nil { logging.Log.WriteErrorf(err.Error()) - return } - defer syncScheduler.Stop() - defer timestampScheduler.Stop() - defer ctrlServer.Close() - defer client.Close() + go closeResources() } diff --git a/go.sum b/go.sum deleted file mode 100644 index 249d9f1..0000000 --- a/go.sum +++ /dev/null @@ -1,62 +0,0 @@ -github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc= -github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA= -github.com/automerge/automerge-go v0.0.0-20230903201930-b80ce8aadbb9 h1:+6JSfuxZgmURoIlGdnYnY/FLRGWGagLyiBjt/VLtwi4= -github.com/automerge/automerge-go v0.0.0-20230903201930-b80ce8aadbb9/go.mod h1:6UxoDE+thWsISXK93pxaOuOfkcAfCvDbg0eAnFmxL5E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= -github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= -github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw= -github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o= -github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= -github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= -github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI= -github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI= -github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws= -github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.zx2c4.com/wireguard v0.0.0-20230704135630-469159ecf7d1 h1:EY138uSo1JYlDq+97u1FtcOUwPpIU6WL1Lkt7WpYjPA= -golang.zx2c4.com/wireguard v0.0.0-20230704135630-469159ecf7d1/go.mod h1:tqur9LnfstdR9ep2LaJT4lFUl0EjlHtge+gAjmsHUG4= -golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE= -golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= -google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= -google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/automerge/automerge.go b/pkg/automerge/automerge.go index 0bba122..a349234 100644 --- a/pkg/automerge/automerge.go +++ b/pkg/automerge/automerge.go @@ -2,6 +2,7 @@ package crdt import ( "errors" + "fmt" "net" "strings" "time" @@ -161,7 +162,27 @@ func (m *CrdtMeshManager) UpdateTimeStamp(nodeId string) error { err = node.Map().Set("timestamp", time.Now().Unix()) if err == nil { - logging.Log.WriteInfof("Timestamp Updated for %s", m.MeshId) + logging.Log.WriteInfof("Timestamp Updated for %s", nodeId) + } + + return err +} + +func (m *CrdtMeshManager) SetDescription(nodeId string, description string) error { + node, err := m.doc.Path("nodes").Map().Get(nodeId) + + if err != nil { + return err + } + + if node.Kind() != automerge.KindMap { + return errors.New(fmt.Sprintf("%s does not exist", nodeId)) + } + + err = node.Map().Set("description", description) + + if err == nil { + logging.Log.WriteInfof("Description Updated for %s", nodeId) } return err @@ -232,6 +253,10 @@ func (m *MeshNodeCrdt) GetRoutes() []string { return lib.MapKeys(m.Routes) } +func (m *MeshNodeCrdt) GetDescription() string { + return m.Description +} + func (m *MeshNodeCrdt) GetIdentifier() string { ipv6 := m.WgHost[:len(m.WgHost)-4] @@ -252,6 +277,7 @@ func (m *MeshCrdt) GetNodes() map[string]mesh.MeshNode { WgHost: node.WgHost, Timestamp: node.Timestamp, Routes: node.Routes, + Description: node.Description, } } diff --git a/pkg/automerge/types.go b/pkg/automerge/types.go index 81b10f4..60315fe 100644 --- a/pkg/automerge/types.go +++ b/pkg/automerge/types.go @@ -8,6 +8,7 @@ type MeshNodeCrdt struct { WgHost string `automerge:"wgHost"` Timestamp int64 `automerge:"timestamp"` Routes map[string]interface{} `automerge:"routes"` + Description string `automerge:"description"` } // MeshCrdt: Represents the mesh network as a whole diff --git a/pkg/ctrlserver/ctrlserver.go b/pkg/ctrlserver/ctrlserver.go index f0bf0db..548a38a 100644 --- a/pkg/ctrlserver/ctrlserver.go +++ b/pkg/ctrlserver/ctrlserver.go @@ -6,6 +6,7 @@ import ( "github.com/tim-beatham/wgmesh/pkg/conn" "github.com/tim-beatham/wgmesh/pkg/ip" "github.com/tim-beatham/wgmesh/pkg/lib" + logging "github.com/tim-beatham/wgmesh/pkg/log" "github.com/tim-beatham/wgmesh/pkg/mesh" "github.com/tim-beatham/wgmesh/pkg/query" "github.com/tim-beatham/wgmesh/pkg/rpc" @@ -84,11 +85,11 @@ func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) { // Close closes the ctrl server tearing down any connections that exist func (s *MeshCtrlServer) Close() error { if err := s.ConnectionManager.Close(); err != nil { - return err + logging.Log.WriteErrorf(err.Error()) } if err := s.ConnectionServer.Close(); err != nil { - return err + logging.Log.WriteErrorf(err.Error()) } return nil diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go index 7cc7dd7..208be4a 100644 --- a/pkg/ipc/ipc.go +++ b/pkg/ipc/ipc.go @@ -56,6 +56,7 @@ type MeshIpc interface { EnableInterface(meshId string, reply *string) error GetDOT(meshId string, reply *string) error Query(query QueryMesh, reply *string) error + PutDescription(description string, reply *string) error } const SockAddr = "/tmp/wgmesh_ipc.sock" diff --git a/pkg/mesh/config.go b/pkg/mesh/config.go index aea7f86..049cf46 100644 --- a/pkg/mesh/config.go +++ b/pkg/mesh/config.go @@ -1,6 +1,8 @@ package mesh import ( + "errors" + "fmt" "net" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" @@ -9,6 +11,7 @@ import ( // MeshConfigApplyer abstracts applying the mesh configuration type MeshConfigApplyer interface { ApplyConfig() error + RemovePeers(meshId string) error } // WgMeshConfigApplyer applies WireGuard configuration @@ -94,6 +97,27 @@ func (m *WgMeshConfigApplyer) ApplyConfig() error { return nil } +func (m *WgMeshConfigApplyer) RemovePeers(meshId string) error { + mesh := m.meshManager.GetMesh(meshId) + + if mesh == nil { + return errors.New(fmt.Sprintf("mesh %s does not exist", meshId)) + } + + dev, err := mesh.GetDevice() + + if err != nil { + return err + } + + m.meshManager.Client.ConfigureDevice(dev.Name, wgtypes.Config{ + ReplacePeers: true, + Peers: make([]wgtypes.PeerConfig, 1), + }) + + return nil +} + func NewWgMeshConfigApplyer(manager *MeshManager) MeshConfigApplyer { return &WgMeshConfigApplyer{meshManager: manager} } diff --git a/pkg/mesh/manager.go b/pkg/mesh/manager.go index 5d76b0b..3bc244b 100644 --- a/pkg/mesh/manager.go +++ b/pkg/mesh/manager.go @@ -49,11 +49,23 @@ func (m *MeshManager) CreateMesh(devName string, port int) (string, error) { return "", err } - m.Meshes[meshId] = nodeManager - return meshId, m.interfaceManipulator.CreateInterface(&wg.CreateInterfaceParams{ + err = m.interfaceManipulator.CreateInterface(&wg.CreateInterfaceParams{ IfName: devName, Port: port, }) + + if err != nil { + return "", nil + } + + m.Meshes[meshId] = nodeManager + err = m.configApplyer.RemovePeers(meshId) + + if err != nil { + logging.Log.WriteErrorf(err.Error()) + } + + return meshId, nil } type AddMeshParams struct { @@ -222,6 +234,18 @@ func (s *MeshManager) ApplyConfig() error { return s.configApplyer.ApplyConfig() } +func (s *MeshManager) SetDescription(description string) error { + for _, mesh := range s.Meshes { + err := mesh.SetDescription(s.HostParameters.HostEndpoint, description) + + if err != nil { + return err + } + } + + return nil +} + // UpdateTimeStamp updates the timestamp of this node in all meshes func (s *MeshManager) UpdateTimeStamp() error { for _, mesh := range s.Meshes { diff --git a/pkg/mesh/types.go b/pkg/mesh/types.go index 138ec0b..fd0b0e2 100644 --- a/pkg/mesh/types.go +++ b/pkg/mesh/types.go @@ -26,6 +26,8 @@ type MeshNode interface { GetRoutes() []string // GetIdentifier: returns the identifier of the node GetIdentifier() string + // GetDescription: returns the description for this node + GetDescription() string } type MeshSnapshot interface { @@ -63,6 +65,7 @@ type MeshProvider interface { // AddRoutes: adds routes to the given node AddRoutes(nodeId string, route ...string) error GetSyncer() MeshSyncer + SetDescription(nodeId string, description string) error } // HostParameters contains the IDs of a node diff --git a/pkg/robin/requester.go b/pkg/robin/requester.go index 41bb4f3..ef9c273 100644 --- a/pkg/robin/requester.go +++ b/pkg/robin/requester.go @@ -187,6 +187,17 @@ func (n *IpcHandler) Query(params ipc.QueryMesh, reply *string) error { return nil } +func (n *IpcHandler) PutDescription(description string, reply *string) error { + err := n.Server.MeshManager.SetDescription(description) + + if err != nil { + return err + } + + *reply = fmt.Sprintf("Set description to %s", description) + return nil +} + type RobinIpcParams struct { CtrlServer *ctrlserver.MeshCtrlServer } diff --git a/pkg/wg/wg.go b/pkg/wg/wg.go index f080563..ceea489 100644 --- a/pkg/wg/wg.go +++ b/pkg/wg/wg.go @@ -17,7 +17,8 @@ func createInterface(ifName string) error { _, err := net.InterfaceByName(ifName) if err == nil { - return &WgError{msg: fmt.Sprintf("Interface %s already exists", ifName)} + err = flushInterface(ifName) + return err } // Check if the interface exists