mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	Merge pull request #432 from neilalexander/gatekeeper
Implement session gatekeeper functions
This commit is contained in:
		
						commit
						2fd3ac6837
					
				
					 3 changed files with 113 additions and 86 deletions
				
			
		| 
						 | 
					@ -2,6 +2,7 @@ package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/hex"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"flag"
 | 
						"flag"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
| 
						 | 
					@ -20,22 +21,21 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/admin"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/admin"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/config"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/config"
 | 
				
			||||||
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/tuntap"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/tuntap"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type nodeConfig = config.NodeConfig
 | 
					 | 
				
			||||||
type Core = yggdrasil.Core
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type node struct {
 | 
					type node struct {
 | 
				
			||||||
	core      Core
 | 
						core      yggdrasil.Core
 | 
				
			||||||
 | 
						state     *config.NodeState
 | 
				
			||||||
	tuntap    tuntap.TunAdapter
 | 
						tuntap    tuntap.TunAdapter
 | 
				
			||||||
	multicast multicast.Multicast
 | 
						multicast multicast.Multicast
 | 
				
			||||||
	admin     admin.AdminSocket
 | 
						admin     admin.AdminSocket
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func readConfig(useconf *bool, useconffile *string, normaliseconf *bool) *nodeConfig {
 | 
					func readConfig(useconf *bool, useconffile *string, normaliseconf *bool) *config.NodeConfig {
 | 
				
			||||||
	// Use a configuration file. If -useconf, the configuration will be read
 | 
						// Use a configuration file. If -useconf, the configuration will be read
 | 
				
			||||||
	// from stdin. If -useconffile, the configuration will be read from the
 | 
						// from stdin. If -useconffile, the configuration will be read from the
 | 
				
			||||||
	// filesystem.
 | 
						// filesystem.
 | 
				
			||||||
| 
						 | 
					@ -116,7 +116,7 @@ func main() {
 | 
				
			||||||
	logging := flag.String("logging", "info,warn,error", "comma-separated list of logging levels to enable")
 | 
						logging := flag.String("logging", "info,warn,error", "comma-separated list of logging levels to enable")
 | 
				
			||||||
	flag.Parse()
 | 
						flag.Parse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var cfg *nodeConfig
 | 
						var cfg *config.NodeConfig
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	switch {
 | 
						switch {
 | 
				
			||||||
	case *version:
 | 
						case *version:
 | 
				
			||||||
| 
						 | 
					@ -181,18 +181,20 @@ func main() {
 | 
				
			||||||
	n := node{}
 | 
						n := node{}
 | 
				
			||||||
	// Now start Yggdrasil - this starts the DHT, router, switch and other core
 | 
						// Now start Yggdrasil - this starts the DHT, router, switch and other core
 | 
				
			||||||
	// components needed for Yggdrasil to operate
 | 
						// components needed for Yggdrasil to operate
 | 
				
			||||||
	state, err := n.core.Start(cfg, logger)
 | 
						n.state, err = n.core.Start(cfg, logger)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logger.Errorln("An error occurred during startup")
 | 
							logger.Errorln("An error occurred during startup")
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// Register the session firewall gatekeeper function
 | 
				
			||||||
 | 
						n.core.SetSessionGatekeeper(n.sessionFirewall)
 | 
				
			||||||
	// Start the admin socket
 | 
						// Start the admin socket
 | 
				
			||||||
	n.admin.Init(&n.core, state, logger, nil)
 | 
						n.admin.Init(&n.core, n.state, logger, nil)
 | 
				
			||||||
	if err := n.admin.Start(); err != nil {
 | 
						if err := n.admin.Start(); err != nil {
 | 
				
			||||||
		logger.Errorln("An error occurred starting admin socket:", err)
 | 
							logger.Errorln("An error occurred starting admin socket:", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Start the multicast interface
 | 
						// Start the multicast interface
 | 
				
			||||||
	n.multicast.Init(&n.core, state, logger, nil)
 | 
						n.multicast.Init(&n.core, n.state, logger, nil)
 | 
				
			||||||
	if err := n.multicast.Start(); err != nil {
 | 
						if err := n.multicast.Start(); err != nil {
 | 
				
			||||||
		logger.Errorln("An error occurred starting multicast:", err)
 | 
							logger.Errorln("An error occurred starting multicast:", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -200,7 +202,7 @@ func main() {
 | 
				
			||||||
	// Start the TUN/TAP interface
 | 
						// Start the TUN/TAP interface
 | 
				
			||||||
	if listener, err := n.core.ConnListen(); err == nil {
 | 
						if listener, err := n.core.ConnListen(); err == nil {
 | 
				
			||||||
		if dialer, err := n.core.ConnDialer(); err == nil {
 | 
							if dialer, err := n.core.ConnDialer(); err == nil {
 | 
				
			||||||
			n.tuntap.Init(state, logger, listener, dialer)
 | 
								n.tuntap.Init(n.state, logger, listener, dialer)
 | 
				
			||||||
			if err := n.tuntap.Start(); err != nil {
 | 
								if err := n.tuntap.Start(); err != nil {
 | 
				
			||||||
				logger.Errorln("An error occurred starting TUN/TAP:", err)
 | 
									logger.Errorln("An error occurred starting TUN/TAP:", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -251,3 +253,66 @@ func main() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
exit:
 | 
					exit:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
 | 
				
			||||||
 | 
						n.state.Mutex.RLock()
 | 
				
			||||||
 | 
						defer n.state.Mutex.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Allow by default if the session firewall is disabled
 | 
				
			||||||
 | 
						if !n.state.Current.SessionFirewall.Enable {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Prepare for checking whitelist/blacklist
 | 
				
			||||||
 | 
						var box crypto.BoxPubKey
 | 
				
			||||||
 | 
						// Reject blacklisted nodes
 | 
				
			||||||
 | 
						for _, b := range n.state.Current.SessionFirewall.BlacklistEncryptionPublicKeys {
 | 
				
			||||||
 | 
							key, err := hex.DecodeString(b)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								copy(box[:crypto.BoxPubKeyLen], key)
 | 
				
			||||||
 | 
								if box == *pubkey {
 | 
				
			||||||
 | 
									return false
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Allow whitelisted nodes
 | 
				
			||||||
 | 
						for _, b := range n.state.Current.SessionFirewall.WhitelistEncryptionPublicKeys {
 | 
				
			||||||
 | 
							key, err := hex.DecodeString(b)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								copy(box[:crypto.BoxPubKeyLen], key)
 | 
				
			||||||
 | 
								if box == *pubkey {
 | 
				
			||||||
 | 
									return true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Allow outbound sessions if appropriate
 | 
				
			||||||
 | 
						if n.state.Current.SessionFirewall.AlwaysAllowOutbound {
 | 
				
			||||||
 | 
							if initiator {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Look and see if the pubkey is that of a direct peer
 | 
				
			||||||
 | 
						var isDirectPeer bool
 | 
				
			||||||
 | 
						for _, peer := range n.core.GetPeers() {
 | 
				
			||||||
 | 
							if peer.PublicKey == *pubkey {
 | 
				
			||||||
 | 
								isDirectPeer = true
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Allow direct peers if appropriate
 | 
				
			||||||
 | 
						if n.state.Current.SessionFirewall.AllowFromDirect && isDirectPeer {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Allow remote nodes if appropriate
 | 
				
			||||||
 | 
						if n.state.Current.SessionFirewall.AllowFromRemote && !isDirectPeer {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Finally, default-deny if not matching any of the above rules
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -395,6 +395,19 @@ func (c *Core) GetNodeInfo(keyString, coordString string, nocache bool) (NodeInf
 | 
				
			||||||
	return NodeInfoPayload{}, errors.New(fmt.Sprintf("getNodeInfo timeout: %s", keyString))
 | 
						return NodeInfoPayload{}, errors.New(fmt.Sprintf("getNodeInfo timeout: %s", keyString))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetSessionGatekeeper allows you to configure a handler function for deciding
 | 
				
			||||||
 | 
					// whether a session should be allowed or not. The default session firewall is
 | 
				
			||||||
 | 
					// implemented in this way. The function receives the public key of the remote
 | 
				
			||||||
 | 
					// side and a boolean which is true if we initiated the session or false if we
 | 
				
			||||||
 | 
					// received an incoming session request. The function should return true to
 | 
				
			||||||
 | 
					// allow the session or false to reject it.
 | 
				
			||||||
 | 
					func (c *Core) SetSessionGatekeeper(f func(pubkey *crypto.BoxPubKey, initiator bool) bool) {
 | 
				
			||||||
 | 
						c.sessions.isAllowedMutex.Lock()
 | 
				
			||||||
 | 
						defer c.sessions.isAllowedMutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c.sessions.isAllowedHandler = f
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetLogger sets the output logger of the Yggdrasil node after startup. This
 | 
					// SetLogger sets the output logger of the Yggdrasil node after startup. This
 | 
				
			||||||
// may be useful if you want to redirect the output later.
 | 
					// may be useful if you want to redirect the output later.
 | 
				
			||||||
func (c *Core) SetLogger(log *log.Logger) {
 | 
					func (c *Core) SetLogger(log *log.Logger) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,6 @@ package yggdrasil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"encoding/hex"
 | 
					 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,18 +110,20 @@ func (s *sessionInfo) update(p *sessionPing) bool {
 | 
				
			||||||
// Sessions are indexed by handle.
 | 
					// Sessions are indexed by handle.
 | 
				
			||||||
// Additionally, stores maps of address/subnet onto keys, and keys onto handles.
 | 
					// Additionally, stores maps of address/subnet onto keys, and keys onto handles.
 | 
				
			||||||
type sessions struct {
 | 
					type sessions struct {
 | 
				
			||||||
	core          *Core
 | 
						core             *Core
 | 
				
			||||||
	listener      *Listener
 | 
						listener         *Listener
 | 
				
			||||||
	listenerMutex sync.Mutex
 | 
						listenerMutex    sync.Mutex
 | 
				
			||||||
	reconfigure   chan chan error
 | 
						reconfigure      chan chan error
 | 
				
			||||||
	lastCleanup   time.Time
 | 
						lastCleanup      time.Time
 | 
				
			||||||
	permShared    map[crypto.BoxPubKey]*crypto.BoxSharedKey // Maps known permanent keys to their shared key, used by DHT a lot
 | 
						isAllowedHandler func(pubkey *crypto.BoxPubKey, initiator bool) bool // Returns true or false if session setup is allowed
 | 
				
			||||||
	sinfos        map[crypto.Handle]*sessionInfo            // Maps (secret) handle onto session info
 | 
						isAllowedMutex   sync.RWMutex                                        // Protects the above
 | 
				
			||||||
	conns         map[crypto.Handle]*Conn                   // Maps (secret) handle onto connections
 | 
						permShared       map[crypto.BoxPubKey]*crypto.BoxSharedKey           // Maps known permanent keys to their shared key, used by DHT a lot
 | 
				
			||||||
	byMySes       map[crypto.BoxPubKey]*crypto.Handle       // Maps mySesPub onto handle
 | 
						sinfos           map[crypto.Handle]*sessionInfo                      // Maps (secret) handle onto session info
 | 
				
			||||||
	byTheirPerm   map[crypto.BoxPubKey]*crypto.Handle       // Maps theirPermPub onto handle
 | 
						conns            map[crypto.Handle]*Conn                             // Maps (secret) handle onto connections
 | 
				
			||||||
	addrToPerm    map[address.Address]*crypto.BoxPubKey
 | 
						byMySes          map[crypto.BoxPubKey]*crypto.Handle                 // Maps mySesPub onto handle
 | 
				
			||||||
	subnetToPerm  map[address.Subnet]*crypto.BoxPubKey
 | 
						byTheirPerm      map[crypto.BoxPubKey]*crypto.Handle                 // Maps theirPermPub onto handle
 | 
				
			||||||
 | 
						addrToPerm       map[address.Address]*crypto.BoxPubKey
 | 
				
			||||||
 | 
						subnetToPerm     map[address.Subnet]*crypto.BoxPubKey
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Initializes the session struct.
 | 
					// Initializes the session struct.
 | 
				
			||||||
| 
						 | 
					@ -155,70 +156,17 @@ func (ss *sessions) init(core *Core) {
 | 
				
			||||||
	ss.lastCleanup = time.Now()
 | 
						ss.lastCleanup = time.Now()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Determines whether the session firewall is enabled.
 | 
					 | 
				
			||||||
func (ss *sessions) isSessionFirewallEnabled() bool {
 | 
					 | 
				
			||||||
	ss.core.config.Mutex.RLock()
 | 
					 | 
				
			||||||
	defer ss.core.config.Mutex.RUnlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ss.core.config.Current.SessionFirewall.Enable
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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.core.config.Mutex.RLock()
 | 
						ss.isAllowedMutex.RLock()
 | 
				
			||||||
	defer ss.core.config.Mutex.RUnlock()
 | 
						defer ss.isAllowedMutex.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allow by default if the session firewall is disabled
 | 
						if ss.isAllowedHandler == nil {
 | 
				
			||||||
	if !ss.isSessionFirewallEnabled() {
 | 
					 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Prepare for checking whitelist/blacklist
 | 
					
 | 
				
			||||||
	var box crypto.BoxPubKey
 | 
						return ss.isAllowedHandler(pubkey, initiator)
 | 
				
			||||||
	// Reject blacklisted nodes
 | 
					 | 
				
			||||||
	for _, b := range ss.core.config.Current.SessionFirewall.BlacklistEncryptionPublicKeys {
 | 
					 | 
				
			||||||
		key, err := hex.DecodeString(b)
 | 
					 | 
				
			||||||
		if err == nil {
 | 
					 | 
				
			||||||
			copy(box[:crypto.BoxPubKeyLen], key)
 | 
					 | 
				
			||||||
			if box == *pubkey {
 | 
					 | 
				
			||||||
				return false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Allow whitelisted nodes
 | 
					 | 
				
			||||||
	for _, b := range ss.core.config.Current.SessionFirewall.WhitelistEncryptionPublicKeys {
 | 
					 | 
				
			||||||
		key, err := hex.DecodeString(b)
 | 
					 | 
				
			||||||
		if err == nil {
 | 
					 | 
				
			||||||
			copy(box[:crypto.BoxPubKeyLen], key)
 | 
					 | 
				
			||||||
			if box == *pubkey {
 | 
					 | 
				
			||||||
				return true
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Allow outbound sessions if appropriate
 | 
					 | 
				
			||||||
	if ss.core.config.Current.SessionFirewall.AlwaysAllowOutbound {
 | 
					 | 
				
			||||||
		if initiator {
 | 
					 | 
				
			||||||
			return true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Look and see if the pubkey is that of a direct peer
 | 
					 | 
				
			||||||
	var isDirectPeer bool
 | 
					 | 
				
			||||||
	for _, peer := range ss.core.peers.ports.Load().(map[switchPort]*peer) {
 | 
					 | 
				
			||||||
		if peer.box == *pubkey {
 | 
					 | 
				
			||||||
			isDirectPeer = true
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Allow direct peers if appropriate
 | 
					 | 
				
			||||||
	if ss.core.config.Current.SessionFirewall.AllowFromDirect && isDirectPeer {
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Allow remote nodes if appropriate
 | 
					 | 
				
			||||||
	if ss.core.config.Current.SessionFirewall.AllowFromRemote && !isDirectPeer {
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Finally, default-deny if not matching any of the above rules
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gets the session corresponding to a given handle.
 | 
					// Gets the session corresponding to a given handle.
 | 
				
			||||||
| 
						 | 
					@ -271,6 +219,7 @@ func (ss *sessions) getByTheirSubnet(snet *address.Subnet) (*sessionInfo, bool)
 | 
				
			||||||
// includse initializing session info to sane defaults (e.g. lowest supported
 | 
					// includse initializing session info to sane defaults (e.g. lowest supported
 | 
				
			||||||
// MTU).
 | 
					// MTU).
 | 
				
			||||||
func (ss *sessions) createSession(theirPermKey *crypto.BoxPubKey) *sessionInfo {
 | 
					func (ss *sessions) createSession(theirPermKey *crypto.BoxPubKey) *sessionInfo {
 | 
				
			||||||
 | 
						// TODO: this check definitely needs to be moved
 | 
				
			||||||
	if !ss.isSessionAllowed(theirPermKey, true) {
 | 
						if !ss.isSessionAllowed(theirPermKey, true) {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -444,12 +393,12 @@ func (ss *sessions) sendPingPong(sinfo *sessionInfo, isPong bool) {
 | 
				
			||||||
func (ss *sessions) handlePing(ping *sessionPing) {
 | 
					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 if the session is allowed
 | 
				
			||||||
	if !isIn && ss.isSessionFirewallEnabled() {
 | 
						// TODO: this check may need to be moved
 | 
				
			||||||
		if !ss.isSessionAllowed(&ping.SendPermPub, false) {
 | 
						if !isIn && !ss.isSessionAllowed(&ping.SendPermPub, false) {
 | 
				
			||||||
			return
 | 
							return
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// Create the session if it doesn't already exist
 | 
				
			||||||
	if !isIn {
 | 
						if !isIn {
 | 
				
			||||||
		ss.createSession(&ping.SendPermPub)
 | 
							ss.createSession(&ping.SendPermPub)
 | 
				
			||||||
		sinfo, isIn = ss.getByTheirPerm(&ping.SendPermPub)
 | 
							sinfo, isIn = ss.getByTheirPerm(&ping.SendPermPub)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue