mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-22 22:20:27 +00:00
Working metadata exchange
This commit is contained in:
parent
6200136fce
commit
97464feba9
@ -2,7 +2,6 @@ package config
|
|||||||
|
|
||||||
// NodeConfig defines all configuration values needed to run a signle yggdrasil node
|
// NodeConfig defines all configuration values needed to run a signle yggdrasil node
|
||||||
type NodeConfig struct {
|
type NodeConfig struct {
|
||||||
Metadata Metadata `comment:"Optional node metadata. Entirely optional but visible to all\npeers and nodes with open sessions."`
|
|
||||||
Listen string `comment:"Listen address for peer connections. Default is to listen for all\nTCP connections over IPv4 and IPv6 with a random port."`
|
Listen string `comment:"Listen address for peer connections. Default is to listen for all\nTCP connections over IPv4 and IPv6 with a random port."`
|
||||||
AdminListen string `comment:"Listen address for admin connections. Default is to listen for local\nconnections either on TCP/9001 or a UNIX socket depending on your\nplatform. Use this value for yggdrasilctl -endpoint=X. To disable\nthe admin socket, use the value \"none\" instead."`
|
AdminListen string `comment:"Listen address for admin connections. Default is to listen for local\nconnections either on TCP/9001 or a UNIX socket depending on your\nplatform. Use this value for yggdrasilctl -endpoint=X. To disable\nthe admin socket, use the value \"none\" instead."`
|
||||||
Peers []string `comment:"List of connection strings for static peers in URI format, e.g.\ntcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j."`
|
Peers []string `comment:"List of connection strings for static peers in URI format, e.g.\ntcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j."`
|
||||||
@ -20,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."`
|
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."`
|
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."`
|
SwitchOptions SwitchOptions `comment:"Advanced options for tuning the switch. Normally you will not need\nto edit these options."`
|
||||||
|
Metadata interface{} `comment:"Optional node metadata. Entirely optional but visible to all\npeers and nodes with open sessions."`
|
||||||
//Net NetConfig `comment:"Extended options for connecting to peers over other networks."`
|
//Net NetConfig `comment:"Extended options for connecting to peers over other networks."`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,10 +52,3 @@ type TunnelRouting struct {
|
|||||||
type SwitchOptions struct {
|
type SwitchOptions struct {
|
||||||
MaxTotalQueueSize uint64 `comment:"Maximum size of all switch queues combined (in bytes)."`
|
MaxTotalQueueSize uint64 `comment:"Maximum size of all switch queues combined (in bytes)."`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optional metadata - format subject to change
|
|
||||||
type Metadata struct {
|
|
||||||
Name string
|
|
||||||
Location string
|
|
||||||
Contact string
|
|
||||||
}
|
|
||||||
|
@ -574,9 +574,6 @@ func (a *admin) getData_getSelf() *admin_nodeInfo {
|
|||||||
{"ip", a.core.GetAddress().String()},
|
{"ip", a.core.GetAddress().String()},
|
||||||
{"subnet", a.core.GetSubnet().String()},
|
{"subnet", a.core.GetSubnet().String()},
|
||||||
{"coords", fmt.Sprint(coords)},
|
{"coords", fmt.Sprint(coords)},
|
||||||
{"name", a.core.metadata.name},
|
|
||||||
{"location", a.core.metadata.location},
|
|
||||||
{"contact", a.core.metadata.contact},
|
|
||||||
}
|
}
|
||||||
if name := GetBuildName(); name != "unknown" {
|
if name := GetBuildName(); name != "unknown" {
|
||||||
self = append(self, admin_pair{"build_name", name})
|
self = append(self, admin_pair{"build_name", name})
|
||||||
|
@ -23,7 +23,6 @@ type Core struct {
|
|||||||
boxPriv boxPrivKey
|
boxPriv boxPrivKey
|
||||||
sigPub sigPubKey
|
sigPub sigPubKey
|
||||||
sigPriv sigPrivKey
|
sigPriv sigPrivKey
|
||||||
metadata metadata
|
|
||||||
switchTable switchTable
|
switchTable switchTable
|
||||||
peers peers
|
peers peers
|
||||||
sessions sessions
|
sessions sessions
|
||||||
@ -41,8 +40,7 @@ type Core struct {
|
|||||||
func (c *Core) init(bpub *boxPubKey,
|
func (c *Core) init(bpub *boxPubKey,
|
||||||
bpriv *boxPrivKey,
|
bpriv *boxPrivKey,
|
||||||
spub *sigPubKey,
|
spub *sigPubKey,
|
||||||
spriv *sigPrivKey,
|
spriv *sigPrivKey) {
|
||||||
metadata metadata) {
|
|
||||||
// TODO separate init and start functions
|
// TODO separate init and start functions
|
||||||
// Init sets up structs
|
// Init sets up structs
|
||||||
// Start launches goroutines that depend on structs being set up
|
// Start launches goroutines that depend on structs being set up
|
||||||
@ -53,7 +51,6 @@ func (c *Core) init(bpub *boxPubKey,
|
|||||||
}
|
}
|
||||||
c.boxPub, c.boxPriv = *bpub, *bpriv
|
c.boxPub, c.boxPriv = *bpub, *bpriv
|
||||||
c.sigPub, c.sigPriv = *spub, *spriv
|
c.sigPub, c.sigPriv = *spub, *spriv
|
||||||
c.metadata = metadata
|
|
||||||
c.admin.core = c
|
c.admin.core = c
|
||||||
c.searches.init(c)
|
c.searches.init(c)
|
||||||
c.dht.init(c)
|
c.dht.init(c)
|
||||||
@ -85,7 +82,7 @@ func GetBuildVersion() string {
|
|||||||
|
|
||||||
// Gets the friendly name of this node, as specified in the NodeConfig.
|
// Gets the friendly name of this node, as specified in the NodeConfig.
|
||||||
func (c *Core) GetMeta() metadata {
|
func (c *Core) GetMeta() metadata {
|
||||||
return c.metadata
|
return c.sessions.myMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts up Yggdrasil using the provided NodeConfig, and outputs debug logging
|
// Starts up Yggdrasil using the provided NodeConfig, and outputs debug logging
|
||||||
@ -129,13 +126,7 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error {
|
|||||||
copy(sigPub[:], sigPubHex)
|
copy(sigPub[:], sigPubHex)
|
||||||
copy(sigPriv[:], sigPrivHex)
|
copy(sigPriv[:], sigPrivHex)
|
||||||
|
|
||||||
meta := metadata{
|
c.init(&boxPub, &boxPriv, &sigPub, &sigPriv)
|
||||||
name: nc.Metadata.Name,
|
|
||||||
location: nc.Metadata.Location,
|
|
||||||
contact: nc.Metadata.Contact,
|
|
||||||
}
|
|
||||||
|
|
||||||
c.init(&boxPub, &boxPriv, &sigPub, &sigPriv, meta)
|
|
||||||
c.admin.init(c, nc.AdminListen)
|
c.admin.init(c, nc.AdminListen)
|
||||||
|
|
||||||
if err := c.tcp.init(c, nc.Listen, nc.ReadTimeout); err != nil {
|
if err := c.tcp.init(c, nc.Listen, nc.ReadTimeout); err != nil {
|
||||||
@ -152,6 +143,7 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.sessions.setMetadata(metadata("HIYA, THIS IS METADATA"))
|
||||||
c.sessions.setSessionFirewallState(nc.SessionFirewall.Enable)
|
c.sessions.setSessionFirewallState(nc.SessionFirewall.Enable)
|
||||||
c.sessions.setSessionFirewallDefaults(
|
c.sessions.setSessionFirewallDefaults(
|
||||||
nc.SessionFirewall.AllowFromDirect,
|
nc.SessionFirewall.AllowFromDirect,
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
package yggdrasil
|
|
||||||
|
|
||||||
type metadata struct {
|
|
||||||
name string
|
|
||||||
location string
|
|
||||||
contact string
|
|
||||||
}
|
|
@ -58,7 +58,7 @@ func (r *router) init(core *Core) {
|
|||||||
r.addr = *address_addrForNodeID(&r.core.dht.nodeID)
|
r.addr = *address_addrForNodeID(&r.core.dht.nodeID)
|
||||||
r.subnet = *address_subnetForNodeID(&r.core.dht.nodeID)
|
r.subnet = *address_subnetForNodeID(&r.core.dht.nodeID)
|
||||||
in := make(chan []byte, 32) // TODO something better than this...
|
in := make(chan []byte, 32) // TODO something better than this...
|
||||||
p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub, &boxSharedKey{}, "(self)", r.core.metadata)
|
p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub, &boxSharedKey{}, "(self)", r.core.sessions.myMetadata)
|
||||||
p.out = func(packet []byte) {
|
p.out = func(packet []byte) {
|
||||||
// This is to make very sure it never blocks
|
// This is to make very sure it never blocks
|
||||||
select {
|
select {
|
||||||
@ -483,7 +483,6 @@ func (r *router) handleMeta(bs []byte, fromKey *boxPubKey) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.SendPermPub = *fromKey
|
req.SendPermPub = *fromKey
|
||||||
r.core.log.Printf("handleMeta: %+v\n", req)
|
|
||||||
r.core.sessions.handleMeta(&req)
|
r.core.sessions.handleMeta(&req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,8 @@ type sessionMeta struct {
|
|||||||
Metadata metadata
|
Metadata metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type metadata []byte
|
||||||
|
|
||||||
// Updates session info in response to a ping, after checking that the ping is OK.
|
// Updates session info in response to a ping, after checking that the ping is OK.
|
||||||
// Returns true if the session was updated, or false otherwise.
|
// Returns true if the session was updated, or false otherwise.
|
||||||
func (s *sessionInfo) update(p *sessionPing) bool {
|
func (s *sessionInfo) update(p *sessionPing) bool {
|
||||||
@ -125,6 +127,8 @@ type sessions struct {
|
|||||||
sessionFirewallAlwaysAllowsOutbound bool
|
sessionFirewallAlwaysAllowsOutbound bool
|
||||||
sessionFirewallWhitelist []string
|
sessionFirewallWhitelist []string
|
||||||
sessionFirewallBlacklist []string
|
sessionFirewallBlacklist []string
|
||||||
|
// Metadata for this node
|
||||||
|
myMetadata metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes the session struct.
|
// Initializes the session struct.
|
||||||
@ -139,6 +143,11 @@ func (ss *sessions) init(core *Core) {
|
|||||||
ss.lastCleanup = time.Now()
|
ss.lastCleanup = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable or disable the session firewall
|
||||||
|
func (ss *sessions) setMetadata(meta metadata) {
|
||||||
|
ss.myMetadata = meta
|
||||||
|
}
|
||||||
|
|
||||||
// Enable or disable the session firewall
|
// Enable or disable the session firewall
|
||||||
func (ss *sessions) setSessionFirewallState(enabled bool) {
|
func (ss *sessions) setSessionFirewallState(enabled bool) {
|
||||||
ss.sessionFirewallEnabled = enabled
|
ss.sessionFirewallEnabled = enabled
|
||||||
@ -486,11 +495,7 @@ func (ss *sessions) handlePing(ping *sessionPing) {
|
|||||||
func (ss *sessions) sendMeta(sinfo *sessionInfo, isResponse bool) {
|
func (ss *sessions) sendMeta(sinfo *sessionInfo, isResponse bool) {
|
||||||
meta := sessionMeta{
|
meta := sessionMeta{
|
||||||
IsResponse: isResponse,
|
IsResponse: isResponse,
|
||||||
Metadata: metadata{
|
Metadata: ss.myMetadata,
|
||||||
name: "some.name.com", //[]byte(ss.core.friendlyName)[0:len(ss.core.friendlyName):32],
|
|
||||||
location: "Some Place",
|
|
||||||
contact: "someone@somewhere.com",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
bs := meta.encode()
|
bs := meta.encode()
|
||||||
shared := ss.getSharedKey(&ss.core.boxPriv, &sinfo.theirPermPub)
|
shared := ss.getSharedKey(&ss.core.boxPriv, &sinfo.theirPermPub)
|
||||||
@ -504,10 +509,7 @@ func (ss *sessions) sendMeta(sinfo *sessionInfo, isResponse bool) {
|
|||||||
}
|
}
|
||||||
packet := p.encode()
|
packet := p.encode()
|
||||||
ss.core.router.out(packet)
|
ss.core.router.out(packet)
|
||||||
if isResponse {
|
if !isResponse {
|
||||||
ss.core.log.Println("Sent meta response to", sinfo.theirAddr)
|
|
||||||
} else {
|
|
||||||
ss.core.log.Println("Sent meta request to", sinfo.theirAddr)
|
|
||||||
sinfo.metaReqTime = time.Now()
|
sinfo.metaReqTime = time.Now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,14 +528,9 @@ func (ss *sessions) handleMeta(meta *sessionMeta) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if meta.IsResponse {
|
if meta.IsResponse {
|
||||||
ss.core.log.Println("Received meta response", string(meta.Metadata.name), "from", sinfo.theirAddr)
|
|
||||||
sinfo.theirMetadata = meta.Metadata
|
sinfo.theirMetadata = meta.Metadata
|
||||||
sinfo.metaResTime = time.Now()
|
sinfo.metaResTime = time.Now()
|
||||||
ss.core.log.Println("- name:", meta.Metadata.name)
|
|
||||||
ss.core.log.Println("- contact:", meta.Metadata.contact)
|
|
||||||
ss.core.log.Println("- location:", meta.Metadata.location)
|
|
||||||
} else {
|
} else {
|
||||||
ss.core.log.Println("Received meta request", string(meta.Metadata.name), "from", sinfo.theirAddr)
|
|
||||||
ss.sendMeta(sinfo, true)
|
ss.sendMeta(sinfo, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,10 +364,8 @@ func (p *sessionMeta) encode() []byte {
|
|||||||
pTypeVal = wire_SessionMetaRequest
|
pTypeVal = wire_SessionMetaRequest
|
||||||
}
|
}
|
||||||
bs := wire_encode_uint64(pTypeVal)
|
bs := wire_encode_uint64(pTypeVal)
|
||||||
if p.IsResponse {
|
if pTypeVal == wire_SessionMetaResponse {
|
||||||
bs = append(bs, p.Metadata.name...)
|
bs = append(bs, p.Metadata...)
|
||||||
bs = append(bs, p.Metadata.location...)
|
|
||||||
bs = append(bs, p.Metadata.contact...)
|
|
||||||
}
|
}
|
||||||
return bs
|
return bs
|
||||||
}
|
}
|
||||||
@ -381,14 +379,9 @@ func (p *sessionMeta) decode(bs []byte) bool {
|
|||||||
case pType != wire_SessionMetaRequest && pType != wire_SessionMetaResponse:
|
case pType != wire_SessionMetaRequest && pType != wire_SessionMetaResponse:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
p.IsResponse = pType == wire_SessionMetaResponse
|
if p.IsResponse = pType == wire_SessionMetaResponse; p.IsResponse {
|
||||||
if p.IsResponse {
|
p.Metadata = make(metadata, len(bs))
|
||||||
switch {
|
if !wire_chop_slice(p.Metadata[:], &bs) {
|
||||||
case !wire_chop_slice([]byte(p.Metadata.name), &bs):
|
|
||||||
return false
|
|
||||||
case !wire_chop_slice([]byte(p.Metadata.location), &bs):
|
|
||||||
return false
|
|
||||||
case !wire_chop_slice([]byte(p.Metadata.contact), &bs):
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user