mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-10 06:20:26 +00:00
Make session firewall thread-safe for config updates
This commit is contained in:
parent
bd04124e43
commit
51026d762e
@ -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…
Reference in New Issue
Block a user