From ee21c56e432dca0e439f3675ac58eda50ca4538e Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 15 Oct 2022 15:42:52 +0100 Subject: [PATCH] Fix setting nodeinfo (closes #954) --- cmd/yggdrasil/main.go | 5 +++- src/core/nodeinfo.go | 64 ++++++++++++++++--------------------------- 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index abce0cea..11bda9f2 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -290,7 +290,10 @@ func run(args yggArgs, ctx context.Context, done chan struct{}) { if err != nil { panic(err) } - options := []core.SetupOption{} + options := []core.SetupOption{ + core.NodeInfo(cfg.NodeInfo), + core.NodeInfoPrivacy(cfg.NodeInfoPrivacy), + } for _, addr := range cfg.Listen { options = append(options, core.ListenAddress(addr)) } diff --git a/src/core/nodeinfo.go b/src/core/nodeinfo.go index bac0935b..6f1f4be8 100644 --- a/src/core/nodeinfo.go +++ b/src/core/nodeinfo.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "runtime" - "strings" "time" iwt "github.com/Arceliar/ironwood/types" @@ -14,18 +13,15 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/version" ) -// NodeInfoPayload represents a RequestNodeInfo response, in bytes. -type NodeInfoPayload []byte - type nodeinfo struct { phony.Inbox proto *protoHandler - myNodeInfo NodeInfoPayload + myNodeInfo json.RawMessage callbacks map[keyArray]nodeinfoCallback } type nodeinfoCallback struct { - call func(nodeinfo NodeInfoPayload) + call func(nodeinfo json.RawMessage) created time.Time } @@ -54,7 +50,7 @@ func (m *nodeinfo) _cleanup() { }) } -func (m *nodeinfo) _addCallback(sender keyArray, call func(nodeinfo NodeInfoPayload)) { +func (m *nodeinfo) _addCallback(sender keyArray, call func(nodeinfo json.RawMessage)) { m.callbacks[sender] = nodeinfoCallback{ created: time.Now(), call: call, @@ -62,67 +58,55 @@ func (m *nodeinfo) _addCallback(sender keyArray, call func(nodeinfo NodeInfoPayl } // Handles the callback, if there is one -func (m *nodeinfo) _callback(sender keyArray, nodeinfo NodeInfoPayload) { +func (m *nodeinfo) _callback(sender keyArray, nodeinfo json.RawMessage) { if callback, ok := m.callbacks[sender]; ok { callback.call(nodeinfo) delete(m.callbacks, sender) } } -func (m *nodeinfo) _getNodeInfo() NodeInfoPayload { +func (m *nodeinfo) _getNodeInfo() json.RawMessage { return m.myNodeInfo } // Set the current node's nodeinfo -func (m *nodeinfo) setNodeInfo(given interface{}, privacy bool) (err error) { +func (m *nodeinfo) setNodeInfo(given map[string]interface{}, privacy bool) (err error) { phony.Block(m, func() { err = m._setNodeInfo(given, privacy) }) return } -func (m *nodeinfo) _setNodeInfo(given interface{}, privacy bool) error { - defaults := map[string]interface{}{ - "buildname": version.BuildName(), - "buildversion": version.BuildVersion(), - "buildplatform": runtime.GOOS, - "buildarch": runtime.GOARCH, +func (m *nodeinfo) _setNodeInfo(given map[string]interface{}, privacy bool) error { + newnodeinfo := make(map[string]interface{}, len(given)) + for k, v := range given { + newnodeinfo[k] = v } - newnodeinfo := make(map[string]interface{}) if !privacy { - for k, v := range defaults { - newnodeinfo[k] = v - } - } - if nodeinfomap, ok := given.(map[string]interface{}); ok { - for key, value := range nodeinfomap { - if _, ok := defaults[key]; ok { - if strvalue, strok := value.(string); strok && strings.EqualFold(strvalue, "null") || value == nil { - delete(newnodeinfo, key) - } - continue - } - newnodeinfo[key] = value - } + newnodeinfo["buildname"] = version.BuildName() + newnodeinfo["buildversion"] = version.BuildVersion() + newnodeinfo["buildplatform"] = runtime.GOOS + newnodeinfo["buildarch"] = runtime.GOARCH } newjson, err := json.Marshal(newnodeinfo) - if err == nil { - if len(newjson) > 16384 { - return errors.New("NodeInfo exceeds max length of 16384 bytes") - } + switch { + case err != nil: + return fmt.Errorf("NodeInfo marshalling failed: %w", err) + case len(newjson) > 16384: + return fmt.Errorf("NodeInfo exceeds max length of 16384 bytes") + default: m.myNodeInfo = newjson return nil } - return err } -func (m *nodeinfo) sendReq(from phony.Actor, key keyArray, callback func(nodeinfo NodeInfoPayload)) { +func (m *nodeinfo) sendReq(from phony.Actor, key keyArray, callback func(nodeinfo json.RawMessage)) { m.Act(from, func() { m._sendReq(key, callback) }) } -func (m *nodeinfo) _sendReq(key keyArray, callback func(nodeinfo NodeInfoPayload)) { +func (m *nodeinfo) _sendReq(key keyArray, callback func(nodeinfo json.RawMessage)) { if callback != nil { m._addCallback(key, callback) } @@ -135,7 +119,7 @@ func (m *nodeinfo) handleReq(from phony.Actor, key keyArray) { }) } -func (m *nodeinfo) handleRes(from phony.Actor, key keyArray, info NodeInfoPayload) { +func (m *nodeinfo) handleRes(from phony.Actor, key keyArray, info json.RawMessage) { m.Act(from, func() { m._callback(key, info) }) @@ -169,7 +153,7 @@ func (m *nodeinfo) nodeInfoAdminHandler(in json.RawMessage) (interface{}, error) } copy(key[:], kbs) ch := make(chan []byte, 1) - m.sendReq(nil, key, func(info NodeInfoPayload) { + m.sendReq(nil, key, func(info json.RawMessage) { ch <- info }) timer := time.NewTimer(6 * time.Second)