diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 5a9db26..2b6d2f0 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -71,6 +71,7 @@ func generateConfig(isAutoconf bool) *nodeConfig { cfg.SessionFirewall.AllowFromDirect = true cfg.SessionFirewall.AllowFromRemote = true cfg.SwitchOptions.MaxTotalQueueSize = yggdrasil.SwitchQueueTotalMinSize + cfg.NodeInfoPrivacy = false return &cfg } diff --git a/src/config/config.go b/src/config/config.go index b5a1f89..192f435 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -19,6 +19,7 @@ type NodeConfig struct { SessionFirewall SessionFirewall `comment:"The session firewall controls who can send/receive network traffic\nto/from. This is useful if you want to protect this node without\nresorting to using a real firewall. This does not affect traffic\nbeing routed via this node to somewhere else. Rules are prioritised as\nfollows: blacklist, whitelist, always allow outgoing, direct, remote."` TunnelRouting TunnelRouting `comment:"Allow tunneling non-Yggdrasil traffic over Yggdrasil. This effectively\nallows you to use Yggdrasil to route to, or to bridge other networks,\nsimilar to a VPN tunnel. Tunnelling works between any two nodes and\ndoes not require them to be directly peered."` SwitchOptions SwitchOptions `comment:"Advanced options for tuning the switch. Normally you will not need\nto edit these options."` + 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."` //Net NetConfig `comment:"Extended options for connecting to peers over other networks."` } diff --git a/src/yggdrasil/core.go b/src/yggdrasil/core.go index 99330e1..e38274f 100644 --- a/src/yggdrasil/core.go +++ b/src/yggdrasil/core.go @@ -125,7 +125,7 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error { c.admin.init(c, nc.AdminListen) c.nodeinfo.init(c) - c.nodeinfo.setNodeInfo(nc.NodeInfo) + c.nodeinfo.setNodeInfo(nc.NodeInfo, nc.NodeInfoPrivacy) if err := c.tcp.init(c, nc.Listen, nc.ReadTimeout); err != nil { c.log.Println("Failed to start TCP interface") @@ -248,8 +248,8 @@ func (c *Core) GetNodeInfo() nodeinfoPayload { } // Sets the nodeinfo. -func (c *Core) SetNodeInfo(nodeinfo interface{}) { - c.nodeinfo.setNodeInfo(nodeinfo) +func (c *Core) SetNodeInfo(nodeinfo interface{}, nodeinfoprivacy bool) { + c.nodeinfo.setNodeInfo(nodeinfo, nodeinfoprivacy) } // Sets the output logger of the Yggdrasil node after startup. This may be diff --git a/src/yggdrasil/nodeinfo.go b/src/yggdrasil/nodeinfo.go index f525bec..b907632 100644 --- a/src/yggdrasil/nodeinfo.go +++ b/src/yggdrasil/nodeinfo.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "runtime" + "strings" "sync" "time" @@ -96,18 +97,27 @@ func (m *nodeinfo) getNodeInfo() nodeinfoPayload { } // Set the current node's nodeinfo -func (m *nodeinfo) setNodeInfo(given interface{}) error { +func (m *nodeinfo) setNodeInfo(given interface{}, privacy bool) error { m.myNodeInfoMutex.Lock() defer m.myNodeInfoMutex.Unlock() - newnodeinfo := map[string]interface{}{ + defaults := map[string]interface{}{ "buildname": GetBuildName(), "buildversion": GetBuildVersion(), "buildplatform": runtime.GOOS, "buildarch": runtime.GOARCH, } + 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 := newnodeinfo[key]; ok { + if _, ok := defaults[key]; ok { + if strvalue, strok := value.(string); strok && strings.EqualFold(strvalue, "null") || value == nil { + delete(newnodeinfo, key) + } continue } newnodeinfo[key] = value