mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Working metadata exchange
This commit is contained in:
		
							parent
							
								
									6200136fce
								
							
						
					
					
						commit
						97464feba9
					
				
					 7 changed files with 22 additions and 58 deletions
				
			
		| 
						 | 
				
			
			@ -2,7 +2,6 @@ package config
 | 
			
		|||
 | 
			
		||||
// NodeConfig defines all configuration values needed to run a signle yggdrasil node
 | 
			
		||||
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."`
 | 
			
		||||
	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."`
 | 
			
		||||
| 
						 | 
				
			
			@ -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."`
 | 
			
		||||
	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."`
 | 
			
		||||
	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."`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -52,10 +52,3 @@ type TunnelRouting struct {
 | 
			
		|||
type SwitchOptions struct {
 | 
			
		||||
	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()},
 | 
			
		||||
		{"subnet", a.core.GetSubnet().String()},
 | 
			
		||||
		{"coords", fmt.Sprint(coords)},
 | 
			
		||||
		{"name", a.core.metadata.name},
 | 
			
		||||
		{"location", a.core.metadata.location},
 | 
			
		||||
		{"contact", a.core.metadata.contact},
 | 
			
		||||
	}
 | 
			
		||||
	if name := GetBuildName(); name != "unknown" {
 | 
			
		||||
		self = append(self, admin_pair{"build_name", name})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,6 @@ type Core struct {
 | 
			
		|||
	boxPriv     boxPrivKey
 | 
			
		||||
	sigPub      sigPubKey
 | 
			
		||||
	sigPriv     sigPrivKey
 | 
			
		||||
	metadata    metadata
 | 
			
		||||
	switchTable switchTable
 | 
			
		||||
	peers       peers
 | 
			
		||||
	sessions    sessions
 | 
			
		||||
| 
						 | 
				
			
			@ -41,8 +40,7 @@ type Core struct {
 | 
			
		|||
func (c *Core) init(bpub *boxPubKey,
 | 
			
		||||
	bpriv *boxPrivKey,
 | 
			
		||||
	spub *sigPubKey,
 | 
			
		||||
	spriv *sigPrivKey,
 | 
			
		||||
	metadata metadata) {
 | 
			
		||||
	spriv *sigPrivKey) {
 | 
			
		||||
	// TODO separate init and start functions
 | 
			
		||||
	//  Init sets up structs
 | 
			
		||||
	//  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.sigPub, c.sigPriv = *spub, *spriv
 | 
			
		||||
	c.metadata = metadata
 | 
			
		||||
	c.admin.core = c
 | 
			
		||||
	c.searches.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.
 | 
			
		||||
func (c *Core) GetMeta() metadata {
 | 
			
		||||
	return c.metadata
 | 
			
		||||
	return c.sessions.myMetadata
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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(sigPriv[:], sigPrivHex)
 | 
			
		||||
 | 
			
		||||
	meta := metadata{
 | 
			
		||||
		name:     nc.Metadata.Name,
 | 
			
		||||
		location: nc.Metadata.Location,
 | 
			
		||||
		contact:  nc.Metadata.Contact,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.init(&boxPub, &boxPriv, &sigPub, &sigPriv, meta)
 | 
			
		||||
	c.init(&boxPub, &boxPriv, &sigPub, &sigPriv)
 | 
			
		||||
	c.admin.init(c, nc.AdminListen)
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.sessions.setMetadata(metadata("HIYA, THIS IS METADATA"))
 | 
			
		||||
	c.sessions.setSessionFirewallState(nc.SessionFirewall.Enable)
 | 
			
		||||
	c.sessions.setSessionFirewallDefaults(
 | 
			
		||||
		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.subnet = *address_subnetForNodeID(&r.core.dht.nodeID)
 | 
			
		||||
	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) {
 | 
			
		||||
		// This is to make very sure it never blocks
 | 
			
		||||
		select {
 | 
			
		||||
| 
						 | 
				
			
			@ -483,7 +483,6 @@ func (r *router) handleMeta(bs []byte, fromKey *boxPubKey) {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
	req.SendPermPub = *fromKey
 | 
			
		||||
	r.core.log.Printf("handleMeta: %+v\n", req)
 | 
			
		||||
	r.core.sessions.handleMeta(&req)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,6 +64,8 @@ type sessionMeta struct {
 | 
			
		|||
	Metadata    metadata
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type metadata []byte
 | 
			
		||||
 | 
			
		||||
// 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.
 | 
			
		||||
func (s *sessionInfo) update(p *sessionPing) bool {
 | 
			
		||||
| 
						 | 
				
			
			@ -125,6 +127,8 @@ type sessions struct {
 | 
			
		|||
	sessionFirewallAlwaysAllowsOutbound bool
 | 
			
		||||
	sessionFirewallWhitelist            []string
 | 
			
		||||
	sessionFirewallBlacklist            []string
 | 
			
		||||
	// Metadata for this node
 | 
			
		||||
	myMetadata metadata
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Initializes the session struct.
 | 
			
		||||
| 
						 | 
				
			
			@ -139,6 +143,11 @@ func (ss *sessions) init(core *Core) {
 | 
			
		|||
	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
 | 
			
		||||
func (ss *sessions) setSessionFirewallState(enabled bool) {
 | 
			
		||||
	ss.sessionFirewallEnabled = enabled
 | 
			
		||||
| 
						 | 
				
			
			@ -486,11 +495,7 @@ func (ss *sessions) handlePing(ping *sessionPing) {
 | 
			
		|||
func (ss *sessions) sendMeta(sinfo *sessionInfo, isResponse bool) {
 | 
			
		||||
	meta := sessionMeta{
 | 
			
		||||
		IsResponse: isResponse,
 | 
			
		||||
		Metadata: metadata{
 | 
			
		||||
			name:     "some.name.com", //[]byte(ss.core.friendlyName)[0:len(ss.core.friendlyName):32],
 | 
			
		||||
			location: "Some Place",
 | 
			
		||||
			contact:  "someone@somewhere.com",
 | 
			
		||||
		},
 | 
			
		||||
		Metadata:   ss.myMetadata,
 | 
			
		||||
	}
 | 
			
		||||
	bs := meta.encode()
 | 
			
		||||
	shared := ss.getSharedKey(&ss.core.boxPriv, &sinfo.theirPermPub)
 | 
			
		||||
| 
						 | 
				
			
			@ -504,10 +509,7 @@ func (ss *sessions) sendMeta(sinfo *sessionInfo, isResponse bool) {
 | 
			
		|||
	}
 | 
			
		||||
	packet := p.encode()
 | 
			
		||||
	ss.core.router.out(packet)
 | 
			
		||||
	if isResponse {
 | 
			
		||||
		ss.core.log.Println("Sent meta response to", sinfo.theirAddr)
 | 
			
		||||
	} else {
 | 
			
		||||
		ss.core.log.Println("Sent meta request to", sinfo.theirAddr)
 | 
			
		||||
	if !isResponse {
 | 
			
		||||
		sinfo.metaReqTime = time.Now()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -526,14 +528,9 @@ func (ss *sessions) handleMeta(meta *sessionMeta) {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if meta.IsResponse {
 | 
			
		||||
		ss.core.log.Println("Received meta response", string(meta.Metadata.name), "from", sinfo.theirAddr)
 | 
			
		||||
		sinfo.theirMetadata = meta.Metadata
 | 
			
		||||
		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 {
 | 
			
		||||
		ss.core.log.Println("Received meta request", string(meta.Metadata.name), "from", sinfo.theirAddr)
 | 
			
		||||
		ss.sendMeta(sinfo, true)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -364,10 +364,8 @@ func (p *sessionMeta) encode() []byte {
 | 
			
		|||
		pTypeVal = wire_SessionMetaRequest
 | 
			
		||||
	}
 | 
			
		||||
	bs := wire_encode_uint64(pTypeVal)
 | 
			
		||||
	if p.IsResponse {
 | 
			
		||||
		bs = append(bs, p.Metadata.name...)
 | 
			
		||||
		bs = append(bs, p.Metadata.location...)
 | 
			
		||||
		bs = append(bs, p.Metadata.contact...)
 | 
			
		||||
	if pTypeVal == wire_SessionMetaResponse {
 | 
			
		||||
		bs = append(bs, p.Metadata...)
 | 
			
		||||
	}
 | 
			
		||||
	return bs
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -381,14 +379,9 @@ func (p *sessionMeta) decode(bs []byte) bool {
 | 
			
		|||
	case pType != wire_SessionMetaRequest && pType != wire_SessionMetaResponse:
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	p.IsResponse = pType == wire_SessionMetaResponse
 | 
			
		||||
	if p.IsResponse {
 | 
			
		||||
		switch {
 | 
			
		||||
		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):
 | 
			
		||||
	if p.IsResponse = pType == wire_SessionMetaResponse; p.IsResponse {
 | 
			
		||||
		p.Metadata = make(metadata, len(bs))
 | 
			
		||||
		if !wire_chop_slice(p.Metadata[:], &bs) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue