mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-03 18:55:08 +03:00 
			
		
		
		
	Make session firewall thread-safe for config updates
This commit is contained in:
		
							parent
							
								
									bd04124e43
								
							
						
					
					
						commit
						51026d762e
					
				
					 1 changed files with 18 additions and 4 deletions
				
			
		| 
						 | 
					@ -7,6 +7,7 @@ package yggdrasil
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"encoding/hex"
 | 
						"encoding/hex"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/address"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/address"
 | 
				
			||||||
| 
						 | 
					@ -115,6 +116,7 @@ type sessions struct {
 | 
				
			||||||
	addrToPerm   map[address.Address]*crypto.BoxPubKey
 | 
						addrToPerm   map[address.Address]*crypto.BoxPubKey
 | 
				
			||||||
	subnetToPerm map[address.Subnet]*crypto.BoxPubKey
 | 
						subnetToPerm map[address.Subnet]*crypto.BoxPubKey
 | 
				
			||||||
	// Options from the session firewall
 | 
						// Options from the session firewall
 | 
				
			||||||
 | 
						sessionFirewallMutex                sync.RWMutex
 | 
				
			||||||
	sessionFirewallEnabled              bool
 | 
						sessionFirewallEnabled              bool
 | 
				
			||||||
	sessionFirewallAllowsDirect         bool
 | 
						sessionFirewallAllowsDirect         bool
 | 
				
			||||||
	sessionFirewallAllowsRemote         bool
 | 
						sessionFirewallAllowsRemote         bool
 | 
				
			||||||
| 
						 | 
					@ -157,12 +159,16 @@ func (ss *sessions) init(core *Core) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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.sessionFirewallMutex.Lock()
 | 
				
			||||||
 | 
						defer ss.sessionFirewallMutex.Unlock()
 | 
				
			||||||
	ss.sessionFirewallEnabled = enabled
 | 
						ss.sessionFirewallEnabled = enabled
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set the session firewall defaults (first parameter is whether to allow
 | 
					// Set the session firewall defaults (first parameter is whether to allow
 | 
				
			||||||
// sessions from direct peers, second is whether to allow from remote nodes).
 | 
					// sessions from direct peers, second is whether to allow from remote nodes).
 | 
				
			||||||
func (ss *sessions) setSessionFirewallDefaults(allowsDirect bool, allowsRemote bool, alwaysAllowsOutbound bool) {
 | 
					func (ss *sessions) setSessionFirewallDefaults(allowsDirect bool, allowsRemote bool, alwaysAllowsOutbound bool) {
 | 
				
			||||||
 | 
						ss.sessionFirewallMutex.Lock()
 | 
				
			||||||
 | 
						defer ss.sessionFirewallMutex.Unlock()
 | 
				
			||||||
	ss.sessionFirewallAllowsDirect = allowsDirect
 | 
						ss.sessionFirewallAllowsDirect = allowsDirect
 | 
				
			||||||
	ss.sessionFirewallAllowsRemote = allowsRemote
 | 
						ss.sessionFirewallAllowsRemote = allowsRemote
 | 
				
			||||||
	ss.sessionFirewallAlwaysAllowsOutbound = alwaysAllowsOutbound
 | 
						ss.sessionFirewallAlwaysAllowsOutbound = alwaysAllowsOutbound
 | 
				
			||||||
| 
						 | 
					@ -170,17 +176,24 @@ func (ss *sessions) setSessionFirewallDefaults(allowsDirect bool, allowsRemote b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set the session firewall whitelist - nodes always allowed to open sessions.
 | 
					// Set the session firewall whitelist - nodes always allowed to open sessions.
 | 
				
			||||||
func (ss *sessions) setSessionFirewallWhitelist(whitelist []string) {
 | 
					func (ss *sessions) setSessionFirewallWhitelist(whitelist []string) {
 | 
				
			||||||
 | 
						ss.sessionFirewallMutex.Lock()
 | 
				
			||||||
 | 
						defer ss.sessionFirewallMutex.Unlock()
 | 
				
			||||||
	ss.sessionFirewallWhitelist = whitelist
 | 
						ss.sessionFirewallWhitelist = whitelist
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set the session firewall blacklist - nodes never allowed to open sessions.
 | 
					// Set the session firewall blacklist - nodes never allowed to open sessions.
 | 
				
			||||||
func (ss *sessions) setSessionFirewallBlacklist(blacklist []string) {
 | 
					func (ss *sessions) setSessionFirewallBlacklist(blacklist []string) {
 | 
				
			||||||
 | 
						ss.sessionFirewallMutex.Lock()
 | 
				
			||||||
 | 
						defer ss.sessionFirewallMutex.Unlock()
 | 
				
			||||||
	ss.sessionFirewallBlacklist = blacklist
 | 
						ss.sessionFirewallBlacklist = blacklist
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Determines whether the session with a given publickey is allowed based on
 | 
					// Determines whether the session with a given publickey is allowed based on
 | 
				
			||||||
// session firewall rules.
 | 
					// session firewall rules.
 | 
				
			||||||
func (ss *sessions) isSessionAllowed(pubkey *crypto.BoxPubKey, initiator bool) bool {
 | 
					func (ss *sessions) isSessionAllowed(pubkey *crypto.BoxPubKey, initiator bool) bool {
 | 
				
			||||||
 | 
						ss.sessionFirewallMutex.RLock()
 | 
				
			||||||
 | 
						defer ss.sessionFirewallMutex.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allow by default if the session firewall is disabled
 | 
						// Allow by default if the session firewall is disabled
 | 
				
			||||||
	if !ss.sessionFirewallEnabled {
 | 
						if !ss.sessionFirewallEnabled {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
| 
						 | 
					@ -286,11 +299,9 @@ func (ss *sessions) getByTheirSubnet(snet *address.Subnet) (*sessionInfo, bool)
 | 
				
			||||||
// Creates a new session and lazily cleans up old/timedout existing sessions.
 | 
					// Creates a new session and lazily cleans up old/timedout existing sessions.
 | 
				
			||||||
// This includse initializing session info to sane defaults (e.g. lowest supported MTU).
 | 
					// This includse initializing session info to sane defaults (e.g. lowest supported MTU).
 | 
				
			||||||
func (ss *sessions) createSession(theirPermKey *crypto.BoxPubKey) *sessionInfo {
 | 
					func (ss *sessions) createSession(theirPermKey *crypto.BoxPubKey) *sessionInfo {
 | 
				
			||||||
	if ss.sessionFirewallEnabled {
 | 
					 | 
				
			||||||
	if !ss.isSessionAllowed(theirPermKey, true) {
 | 
						if !ss.isSessionAllowed(theirPermKey, true) {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	sinfo := sessionInfo{}
 | 
						sinfo := sessionInfo{}
 | 
				
			||||||
	sinfo.core = ss.core
 | 
						sinfo.core = ss.core
 | 
				
			||||||
	sinfo.reconfigure = make(chan chan error, 1)
 | 
						sinfo.reconfigure = make(chan chan error, 1)
 | 
				
			||||||
| 
						 | 
					@ -465,11 +476,14 @@ func (ss *sessions) handlePing(ping *sessionPing) {
 | 
				
			||||||
	// Get the corresponding session (or create a new session)
 | 
						// Get the corresponding session (or create a new session)
 | 
				
			||||||
	sinfo, isIn := ss.getByTheirPerm(&ping.SendPermPub)
 | 
						sinfo, isIn := ss.getByTheirPerm(&ping.SendPermPub)
 | 
				
			||||||
	// Check the session firewall
 | 
						// Check the session firewall
 | 
				
			||||||
 | 
						ss.sessionFirewallMutex.RLock()
 | 
				
			||||||
	if !isIn && ss.sessionFirewallEnabled {
 | 
						if !isIn && ss.sessionFirewallEnabled {
 | 
				
			||||||
		if !ss.isSessionAllowed(&ping.SendPermPub, false) {
 | 
							if !ss.isSessionAllowed(&ping.SendPermPub, false) {
 | 
				
			||||||
 | 
								ss.sessionFirewallMutex.RUnlock()
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ss.sessionFirewallMutex.RUnlock()
 | 
				
			||||||
	if !isIn || sinfo.timedout() {
 | 
						if !isIn || sinfo.timedout() {
 | 
				
			||||||
		if isIn {
 | 
							if isIn {
 | 
				
			||||||
			sinfo.close()
 | 
								sinfo.close()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue