From d17ac397898391129c834f9966464a6072513249 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 28 Oct 2023 05:26:43 -0500 Subject: [PATCH] update ironwood dependency, add a debug API call for lookups --- cmd/yggdrasil/main.go | 3 +++ contrib/mobile/mobile.go | 8 +++--- go.mod | 2 +- go.sum | 4 +-- src/admin/options.go | 54 ++++++++++++++++++++++++++++++++++++++++ src/config/config.go | 1 + 6 files changed, 65 insertions(+), 7 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 64cc6ae..7f820db 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -216,6 +216,9 @@ func main() { options := []admin.SetupOption{ admin.ListenAddress(cfg.AdminListen), } + if cfg.LogLookups { + options = append(options, admin.LogLookups{}) + } if n.admin, err = admin.New(n.core, logger, options...); err != nil { panic(err) } diff --git a/contrib/mobile/mobile.go b/contrib/mobile/mobile.go index 0b52ffa..cf026a7 100644 --- a/contrib/mobile/mobile.go +++ b/contrib/mobile/mobile.go @@ -164,10 +164,10 @@ func (m *Yggdrasil) Stop() error { logger.EnableLevel("info") logger.Infof("Stopping the mobile Yggdrasil instance %s", "") if m.multicast != nil { - logger.Infof("Stopping multicast %s", "") - if err := m.multicast.Stop(); err != nil { - return err - } + logger.Infof("Stopping multicast %s", "") + if err := m.multicast.Stop(); err != nil { + return err + } } logger.Infof("Stopping TUN device %s", "") if m.tun != nil { diff --git a/go.mod b/go.mod index 3f2f6b7..faa0e0d 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.20 require ( - github.com/Arceliar/ironwood v0.0.0-20230805085300-86206813435f + github.com/Arceliar/ironwood v0.0.0-20231028101932-ceac99571f43 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 diff --git a/go.sum b/go.sum index e8bbf5f..901eaba 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20230805085300-86206813435f h1:Fz0zG7ZyQQqk+ROnmHuGrIZO250Lx/YHmp9o48XE+Vw= -github.com/Arceliar/ironwood v0.0.0-20230805085300-86206813435f/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= +github.com/Arceliar/ironwood v0.0.0-20231028101932-ceac99571f43 h1:M4NczBPk7Fy0Uy2YvNoXwSkk3dGoGTOYtUjyqpOC5ko= +github.com/Arceliar/ironwood v0.0.0-20231028101932-ceac99571f43/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= diff --git a/src/admin/options.go b/src/admin/options.go index 4607384..b2e273b 100644 --- a/src/admin/options.go +++ b/src/admin/options.go @@ -1,9 +1,20 @@ package admin +import ( + "encoding/hex" + "encoding/json" + "sync" + "time" + + "github.com/Arceliar/ironwood/network" +) + func (c *AdminSocket) _applyOption(opt SetupOption) { switch v := opt.(type) { case ListenAddress: c.config.listenaddr = v + case LogLookups: + c.logLookups() } } @@ -14,3 +25,46 @@ type SetupOption interface { type ListenAddress string func (a ListenAddress) isSetupOption() {} + +type LogLookups struct{} + +func (l LogLookups) isSetupOption() {} + +func (a *AdminSocket) logLookups() { + type resi struct { + Key string `json:"key"` + Path []uint64 `json:"path"` + Time int64 `json:"time"` + } + type res struct { + Infos []resi `json:"infos"` + } + type info struct { + path []uint64 + time time.Time + } + infos := make(map[string]info) + var m sync.Mutex + a.core.PacketConn.PacketConn.Debug.SetDebugLookupLogger(func(l network.DebugLookupInfo) { + key := hex.EncodeToString(l.Key[:]) + m.Lock() + infos[key] = info{path: l.Path, time: time.Now()} + m.Unlock() + }) + _ = a.AddHandler( + "lookups", "Dump a record of lookups received in the past hour", []string{}, + func(in json.RawMessage) (interface{}, error) { + m.Lock() + rs := make([]resi, 0, len(infos)) + for k, v := range infos { + if time.Since(v.time) > 24*time.Hour { + // TODO? automatic cleanup, so we don't need to call lookups periodically to prevent leaks + delete(infos, k) + } + rs = append(rs, resi{Key: k, Path: v.path, Time: v.time.Unix()}) + } + m.Unlock() + return &res{Infos: rs}, nil + }, + ) +} diff --git a/src/config/config.go b/src/config/config.go index bb94b67..289b6f9 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -53,6 +53,7 @@ type NodeConfig struct { IfMTU uint64 `comment:"Maximum Transmission Unit (MTU) size for your local TUN interface.\nDefault is the largest supported size for your platform. The lowest\npossible value is 1280."` NodeInfoPrivacy bool `comment:"By default, nodeinfo contains some defaults including the platform,\narchitecture and Yggdrasil version. These can help when surveying\nthe network and diagnosing network routing problems. Enabling\nnodeinfo privacy prevents this, so that only items specified in\n\"NodeInfo\" are sent back if specified."` NodeInfo map[string]interface{} `comment:"Optional node info. This must be a { \"key\": \"value\", ... } map\nor set as null. This is entirely optional but, if set, is visible\nto the whole network on request."` + LogLookups bool `json:",omitempty"` } type MulticastInterfaceConfig struct {