mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Wrap the metadata with a mutex to guarantee thread safety across core/router/sessions
This commit is contained in:
		
							parent
							
								
									97464feba9
								
							
						
					
					
						commit
						042a3400fe
					
				
					 4 changed files with 40 additions and 14 deletions
				
			
		| 
						 | 
					@ -80,11 +80,6 @@ func GetBuildVersion() string {
 | 
				
			||||||
	return buildVersion
 | 
						return buildVersion
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gets the friendly name of this node, as specified in the NodeConfig.
 | 
					 | 
				
			||||||
func (c *Core) GetMeta() 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
 | 
				
			||||||
// through the provided log.Logger. The started stack will include TCP and UDP
 | 
					// through the provided log.Logger. The started stack will include TCP and UDP
 | 
				
			||||||
// sockets, a multicast discovery socket, an admin socket, router, switch and
 | 
					// sockets, a multicast discovery socket, an admin socket, router, switch and
 | 
				
			||||||
| 
						 | 
					@ -245,6 +240,16 @@ func (c *Core) GetSubnet() *net.IPNet {
 | 
				
			||||||
	return &net.IPNet{IP: subnet, Mask: net.CIDRMask(64, 128)}
 | 
						return &net.IPNet{IP: subnet, Mask: net.CIDRMask(64, 128)}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Gets the node metadata.
 | 
				
			||||||
 | 
					func (c *Core) GetMetadata() metadata {
 | 
				
			||||||
 | 
						return c.sessions.getMetadata()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sets the node metadata.
 | 
				
			||||||
 | 
					func (c *Core) SetMetadata(meta metadata) {
 | 
				
			||||||
 | 
						c.sessions.setMetadata(meta)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Sets the output logger of the Yggdrasil node after startup. This may be
 | 
					// Sets the output logger of the Yggdrasil node after startup. This may be
 | 
				
			||||||
// useful if you want to redirect the output later.
 | 
					// useful if you want to redirect the output later.
 | 
				
			||||||
func (c *Core) SetLogger(log *log.Logger) {
 | 
					func (c *Core) SetLogger(log *log.Logger) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,9 @@ 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...
 | 
				
			||||||
 | 
						r.core.sessions.myMetadataMutex.RLock()
 | 
				
			||||||
	p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub, &boxSharedKey{}, "(self)", r.core.sessions.myMetadata)
 | 
						p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub, &boxSharedKey{}, "(self)", r.core.sessions.myMetadata)
 | 
				
			||||||
 | 
						r.core.sessions.myMetadataMutex.RUnlock()
 | 
				
			||||||
	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 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ package yggdrasil
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"encoding/hex"
 | 
						"encoding/hex"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -128,7 +129,8 @@ type sessions struct {
 | 
				
			||||||
	sessionFirewallWhitelist            []string
 | 
						sessionFirewallWhitelist            []string
 | 
				
			||||||
	sessionFirewallBlacklist            []string
 | 
						sessionFirewallBlacklist            []string
 | 
				
			||||||
	// Metadata for this node
 | 
						// Metadata for this node
 | 
				
			||||||
	myMetadata metadata
 | 
						myMetadata      metadata
 | 
				
			||||||
 | 
						myMetadataMutex sync.RWMutex
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Initializes the session struct.
 | 
					// Initializes the session struct.
 | 
				
			||||||
| 
						 | 
					@ -143,8 +145,17 @@ func (ss *sessions) init(core *Core) {
 | 
				
			||||||
	ss.lastCleanup = time.Now()
 | 
						ss.lastCleanup = time.Now()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Enable or disable the session firewall
 | 
					// Get the metadata
 | 
				
			||||||
 | 
					func (ss *sessions) getMetadata() metadata {
 | 
				
			||||||
 | 
						ss.myMetadataMutex.RLock()
 | 
				
			||||||
 | 
						defer ss.myMetadataMutex.RUnlock()
 | 
				
			||||||
 | 
						return ss.myMetadata
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Set the metadata
 | 
				
			||||||
func (ss *sessions) setMetadata(meta metadata) {
 | 
					func (ss *sessions) setMetadata(meta metadata) {
 | 
				
			||||||
 | 
						ss.myMetadataMutex.Lock()
 | 
				
			||||||
 | 
						defer ss.myMetadataMutex.Unlock()
 | 
				
			||||||
	ss.myMetadata = meta
 | 
						ss.myMetadata = meta
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -485,18 +496,23 @@ func (ss *sessions) handlePing(ping *sessionPing) {
 | 
				
			||||||
		bs, sinfo.packet = sinfo.packet, nil
 | 
							bs, sinfo.packet = sinfo.packet, nil
 | 
				
			||||||
		ss.core.router.sendPacket(bs)
 | 
							ss.core.router.sendPacket(bs)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if time.Since(sinfo.metaResTime).Minutes() > 15 {
 | 
						// This requests metadata from the remote side fairly quickly after
 | 
				
			||||||
		if time.Since(sinfo.metaReqTime).Minutes() > 1 {
 | 
						// establishing the session, and if other time constraints apply (no more
 | 
				
			||||||
			ss.sendMeta(sinfo, false)
 | 
						// often than 15 minutes since receiving the last metadata)
 | 
				
			||||||
		}
 | 
						//if time.Since(sinfo.metaResTime).Minutes() > 15 {
 | 
				
			||||||
	}
 | 
						//	if time.Since(sinfo.metaReqTime).Minutes() > 1 {
 | 
				
			||||||
 | 
						//		ss.sendMeta(sinfo, false)
 | 
				
			||||||
 | 
						//	}
 | 
				
			||||||
 | 
						//}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ss *sessions) sendMeta(sinfo *sessionInfo, isResponse bool) {
 | 
					func (ss *sessions) sendMeta(sinfo *sessionInfo, isResponse bool) {
 | 
				
			||||||
 | 
						ss.myMetadataMutex.RLock()
 | 
				
			||||||
	meta := sessionMeta{
 | 
						meta := sessionMeta{
 | 
				
			||||||
		IsResponse: isResponse,
 | 
							IsResponse: isResponse,
 | 
				
			||||||
		Metadata:   ss.myMetadata,
 | 
							Metadata:   ss.myMetadata,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ss.myMetadataMutex.RUnlock()
 | 
				
			||||||
	bs := meta.encode()
 | 
						bs := meta.encode()
 | 
				
			||||||
	shared := ss.getSharedKey(&ss.core.boxPriv, &sinfo.theirPermPub)
 | 
						shared := ss.getSharedKey(&ss.core.boxPriv, &sinfo.theirPermPub)
 | 
				
			||||||
	payload, nonce := boxSeal(shared, bs, nil)
 | 
						payload, nonce := boxSeal(shared, bs, nil)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -355,7 +355,7 @@ func (p *sessionPing) decode(bs []byte) bool {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Encodes a sessionPing into its wire format.
 | 
					// Encodes a sessionMeta into its wire format.
 | 
				
			||||||
func (p *sessionMeta) encode() []byte {
 | 
					func (p *sessionMeta) encode() []byte {
 | 
				
			||||||
	var pTypeVal uint64
 | 
						var pTypeVal uint64
 | 
				
			||||||
	if p.IsResponse {
 | 
						if p.IsResponse {
 | 
				
			||||||
| 
						 | 
					@ -370,7 +370,7 @@ func (p *sessionMeta) encode() []byte {
 | 
				
			||||||
	return bs
 | 
						return bs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Decodes an encoded sessionPing into the struct, returning true if successful.
 | 
					// Decodes an encoded sessionMeta into the struct, returning true if successful.
 | 
				
			||||||
func (p *sessionMeta) decode(bs []byte) bool {
 | 
					func (p *sessionMeta) decode(bs []byte) bool {
 | 
				
			||||||
	var pType uint64
 | 
						var pType uint64
 | 
				
			||||||
	switch {
 | 
						switch {
 | 
				
			||||||
| 
						 | 
					@ -380,6 +380,9 @@ func (p *sessionMeta) decode(bs []byte) bool {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if p.IsResponse = pType == wire_SessionMetaResponse; p.IsResponse {
 | 
						if p.IsResponse = pType == wire_SessionMetaResponse; p.IsResponse {
 | 
				
			||||||
 | 
							if len(bs) == 0 {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		p.Metadata = make(metadata, len(bs))
 | 
							p.Metadata = make(metadata, len(bs))
 | 
				
			||||||
		if !wire_chop_slice(p.Metadata[:], &bs) {
 | 
							if !wire_chop_slice(p.Metadata[:], &bs) {
 | 
				
			||||||
			return false
 | 
								return false
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue