5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-26 14:11:37 +00:00

Remove mutexes from CKR and use router goroutine/doAdmin for update config

This commit is contained in:
Neil Alexander 2019-01-14 18:34:15 +00:00
parent 51026d762e
commit 9e186bdd67
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
3 changed files with 17 additions and 56 deletions

View File

@ -7,7 +7,6 @@ import (
"fmt" "fmt"
"net" "net"
"sort" "sort"
"sync"
"github.com/yggdrasil-network/yggdrasil-go/src/address" "github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/crypto" "github.com/yggdrasil-network/yggdrasil-go/src/crypto"
@ -17,19 +16,15 @@ import (
// allow traffic for non-Yggdrasil ranges to be routed over Yggdrasil. // allow traffic for non-Yggdrasil ranges to be routed over Yggdrasil.
type cryptokey struct { type cryptokey struct {
core *Core core *Core
enabled bool enabled bool
reconfigure chan chan error reconfigure chan chan error
ipv4routes []cryptokey_route ipv4routes []cryptokey_route
ipv6routes []cryptokey_route ipv6routes []cryptokey_route
ipv4cache map[address.Address]cryptokey_route ipv4cache map[address.Address]cryptokey_route
ipv6cache map[address.Address]cryptokey_route ipv6cache map[address.Address]cryptokey_route
ipv4sources []net.IPNet ipv4sources []net.IPNet
ipv6sources []net.IPNet ipv6sources []net.IPNet
mutexenabled sync.RWMutex // protects enabled
mutexroutes sync.RWMutex // protects ipv4routes, ipv6routes
mutexcache sync.RWMutex // protects ipv4cache, ipv6cache
mutexsources sync.RWMutex // protects ipv4sources, ipv6sources
} }
type cryptokey_route struct { type cryptokey_route struct {
@ -45,7 +40,11 @@ func (c *cryptokey) init(core *Core) {
for { for {
select { select {
case e := <-c.reconfigure: case e := <-c.reconfigure:
e <- c.configure() var err error
c.core.router.doAdmin(func() {
err = c.core.router.cryptokey.configure()
})
e <- err
} }
} }
}() }()
@ -55,7 +54,8 @@ func (c *cryptokey) init(core *Core) {
} }
} }
// Configure the CKR routes // Configure the CKR routes - this must only ever be called from the router
// goroutine, e.g. through router.doAdmin
func (c *cryptokey) configure() error { func (c *cryptokey) configure() error {
c.core.configMutex.RLock() c.core.configMutex.RLock()
defer c.core.configMutex.RUnlock() defer c.core.configMutex.RUnlock()
@ -64,10 +64,8 @@ func (c *cryptokey) configure() error {
c.setEnabled(c.core.config.TunnelRouting.Enable) c.setEnabled(c.core.config.TunnelRouting.Enable)
// Clear out existing routes // Clear out existing routes
c.mutexroutes.Lock()
c.ipv6routes = make([]cryptokey_route, 0) c.ipv6routes = make([]cryptokey_route, 0)
c.ipv4routes = make([]cryptokey_route, 0) c.ipv4routes = make([]cryptokey_route, 0)
c.mutexroutes.Unlock()
// Add IPv6 routes // Add IPv6 routes
for ipv6, pubkey := range c.core.config.TunnelRouting.IPv6Destinations { for ipv6, pubkey := range c.core.config.TunnelRouting.IPv6Destinations {
@ -84,10 +82,8 @@ func (c *cryptokey) configure() error {
} }
// Clear out existing sources // Clear out existing sources
c.mutexsources.Lock()
c.ipv6sources = make([]net.IPNet, 0) c.ipv6sources = make([]net.IPNet, 0)
c.ipv4sources = make([]net.IPNet, 0) c.ipv4sources = make([]net.IPNet, 0)
c.mutexsources.Unlock()
// Add IPv6 sources // Add IPv6 sources
c.ipv6sources = make([]net.IPNet, 0) c.ipv6sources = make([]net.IPNet, 0)
@ -106,25 +102,19 @@ func (c *cryptokey) configure() error {
} }
// Wipe the caches // Wipe the caches
c.mutexcache.Lock()
c.ipv4cache = make(map[address.Address]cryptokey_route, 0) c.ipv4cache = make(map[address.Address]cryptokey_route, 0)
c.ipv6cache = make(map[address.Address]cryptokey_route, 0) c.ipv6cache = make(map[address.Address]cryptokey_route, 0)
c.mutexcache.Unlock()
return nil return nil
} }
// Enable or disable crypto-key routing. // Enable or disable crypto-key routing.
func (c *cryptokey) setEnabled(enabled bool) { func (c *cryptokey) setEnabled(enabled bool) {
c.mutexenabled.Lock()
defer c.mutexenabled.Unlock()
c.enabled = enabled c.enabled = enabled
} }
// Check if crypto-key routing is enabled. // Check if crypto-key routing is enabled.
func (c *cryptokey) isEnabled() bool { func (c *cryptokey) isEnabled() bool {
c.mutexenabled.RLock()
defer c.mutexenabled.RUnlock()
return c.enabled return c.enabled
} }
@ -148,9 +138,6 @@ func (c *cryptokey) isValidSource(addr address.Address, addrlen int) bool {
// Does it match a configured CKR source? // Does it match a configured CKR source?
if c.isEnabled() { if c.isEnabled() {
c.mutexsources.RLock()
defer c.mutexsources.RUnlock()
// Build our references to the routing sources // Build our references to the routing sources
var routingsources *[]net.IPNet var routingsources *[]net.IPNet
@ -177,9 +164,6 @@ func (c *cryptokey) isValidSource(addr address.Address, addrlen int) bool {
// Adds a source subnet, which allows traffic with these source addresses to // Adds a source subnet, which allows traffic with these source addresses to
// be tunnelled using crypto-key routing. // be tunnelled using crypto-key routing.
func (c *cryptokey) addSourceSubnet(cidr string) error { func (c *cryptokey) addSourceSubnet(cidr string) error {
c.mutexsources.Lock()
defer c.mutexsources.Unlock()
// Is the CIDR we've been given valid? // Is the CIDR we've been given valid?
_, ipnet, err := net.ParseCIDR(cidr) _, ipnet, err := net.ParseCIDR(cidr)
if err != nil { if err != nil {
@ -217,9 +201,6 @@ func (c *cryptokey) addSourceSubnet(cidr string) error {
// Adds a destination route for the given CIDR to be tunnelled to the node // Adds a destination route for the given CIDR to be tunnelled to the node
// with the given BoxPubKey. // with the given BoxPubKey.
func (c *cryptokey) addRoute(cidr string, dest string) error { func (c *cryptokey) addRoute(cidr string, dest string) error {
c.mutexroutes.Lock()
defer c.mutexroutes.Unlock()
// Is the CIDR we've been given valid? // Is the CIDR we've been given valid?
ipaddr, ipnet, err := net.ParseCIDR(cidr) ipaddr, ipnet, err := net.ParseCIDR(cidr)
if err != nil { if err != nil {
@ -294,11 +275,6 @@ func (c *cryptokey) addRoute(cidr string, dest string) error {
// length specified in bytes) from the crypto-key routing table. An error is // length specified in bytes) from the crypto-key routing table. An error is
// returned if the address is not suitable or no route was found. // returned if the address is not suitable or no route was found.
func (c *cryptokey) getPublicKeyForAddress(addr address.Address, addrlen int) (crypto.BoxPubKey, error) { func (c *cryptokey) getPublicKeyForAddress(addr address.Address, addrlen int) (crypto.BoxPubKey, error) {
c.mutexroutes.RLock()
c.mutexcache.RLock()
defer c.mutexroutes.RUnlock()
defer c.mutexcache.RUnlock()
// Check if the address is a valid Yggdrasil address - if so it // Check if the address is a valid Yggdrasil address - if so it
// is exempt from all CKR checking // is exempt from all CKR checking
if addr.IsValid() { if addr.IsValid() {
@ -359,9 +335,6 @@ func (c *cryptokey) getPublicKeyForAddress(addr address.Address, addrlen int) (c
// Removes a source subnet, which allows traffic with these source addresses to // Removes a source subnet, which allows traffic with these source addresses to
// be tunnelled using crypto-key routing. // be tunnelled using crypto-key routing.
func (c *cryptokey) removeSourceSubnet(cidr string) error { func (c *cryptokey) removeSourceSubnet(cidr string) error {
c.mutexsources.Lock()
defer c.mutexsources.Unlock()
// Is the CIDR we've been given valid? // Is the CIDR we've been given valid?
_, ipnet, err := net.ParseCIDR(cidr) _, ipnet, err := net.ParseCIDR(cidr)
if err != nil { if err != nil {
@ -397,11 +370,6 @@ func (c *cryptokey) removeSourceSubnet(cidr string) error {
// Removes a destination route for the given CIDR to be tunnelled to the node // Removes a destination route for the given CIDR to be tunnelled to the node
// with the given BoxPubKey. // with the given BoxPubKey.
func (c *cryptokey) removeRoute(cidr string, dest string) error { func (c *cryptokey) removeRoute(cidr string, dest string) error {
c.mutexroutes.Lock()
c.mutexcache.Lock()
defer c.mutexroutes.Unlock()
defer c.mutexcache.Unlock()
// Is the CIDR we've been given valid? // Is the CIDR we've been given valid?
_, ipnet, err := net.ParseCIDR(cidr) _, ipnet, err := net.ParseCIDR(cidr)
if err != nil { if err != nil {

View File

@ -141,6 +141,7 @@ func (c *Core) UpdateConfig(config *config.NodeConfig) {
c.peers.reconfigure, c.peers.reconfigure,
c.router.reconfigure, c.router.reconfigure,
c.router.tun.reconfigure, c.router.tun.reconfigure,
c.router.cryptokey.reconfigure,
c.switchTable.reconfigure, c.switchTable.reconfigure,
c.tcp.reconfigure, c.tcp.reconfigure,
c.multicast.reconfigure, c.multicast.reconfigure,

View File

@ -127,14 +127,6 @@ func (r *router) mainLoop() {
case f := <-r.admin: case f := <-r.admin:
f() f()
case e := <-r.reconfigure: case e := <-r.reconfigure:
// Send reconfigure notification to cryptokey
response := make(chan error)
r.cryptokey.reconfigure <- response
if err := <-response; err != nil {
e <- err
}
// Anything else to do?
e <- nil e <- nil
} }
} }