mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-23 04:21:34 +00:00
Cache crypto-key routes (until routing table changes)
This commit is contained in:
parent
ec751e8cc7
commit
295e9c9a10
@ -16,6 +16,8 @@ type cryptokey struct {
|
|||||||
enabled bool
|
enabled bool
|
||||||
ipv4routes []cryptokey_route
|
ipv4routes []cryptokey_route
|
||||||
ipv6routes []cryptokey_route
|
ipv6routes []cryptokey_route
|
||||||
|
ipv4cache map[address]cryptokey_route
|
||||||
|
ipv6cache map[address]cryptokey_route
|
||||||
}
|
}
|
||||||
|
|
||||||
type cryptokey_route struct {
|
type cryptokey_route struct {
|
||||||
@ -27,6 +29,8 @@ func (c *cryptokey) init(core *Core) {
|
|||||||
c.core = core
|
c.core = core
|
||||||
c.ipv4routes = make([]cryptokey_route, 0)
|
c.ipv4routes = make([]cryptokey_route, 0)
|
||||||
c.ipv6routes = make([]cryptokey_route, 0)
|
c.ipv6routes = make([]cryptokey_route, 0)
|
||||||
|
c.ipv4cache = make(map[address]cryptokey_route, 0)
|
||||||
|
c.ipv6cache = make(map[address]cryptokey_route, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cryptokey) isEnabled() bool {
|
func (c *cryptokey) isEnabled() bool {
|
||||||
@ -68,12 +72,20 @@ func (c *cryptokey) addRoute(cidr string, dest string) error {
|
|||||||
subnet: *ipnet,
|
subnet: *ipnet,
|
||||||
destination: boxPubKey,
|
destination: boxPubKey,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Sort so most specific routes are first
|
// Sort so most specific routes are first
|
||||||
sort.Slice(c.ipv6routes, func(i, j int) bool {
|
sort.Slice(c.ipv6routes, func(i, j int) bool {
|
||||||
im, _ := c.ipv6routes[i].subnet.Mask.Size()
|
im, _ := c.ipv6routes[i].subnet.Mask.Size()
|
||||||
jm, _ := c.ipv6routes[j].subnet.Mask.Size()
|
jm, _ := c.ipv6routes[j].subnet.Mask.Size()
|
||||||
return im > jm
|
return im > jm
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Clear the cache as this route might change future routing
|
||||||
|
// Setting an empty slice keeps the memory whereas nil invokes GC
|
||||||
|
for k := range c.ipv6cache {
|
||||||
|
delete(c.ipv6cache, k)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
} else if prefixsize == net.IPv4len*8 {
|
} else if prefixsize == net.IPv4len*8 {
|
||||||
@ -83,28 +95,39 @@ func (c *cryptokey) addRoute(cidr string, dest string) error {
|
|||||||
return errors.New("Unspecified error")
|
return errors.New("Unspecified error")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cryptokey) getPublicKeyForAddress(addr string) (boxPubKey, error) {
|
func (c *cryptokey) getPublicKeyForAddress(addr address) (boxPubKey, error) {
|
||||||
ipaddr := net.ParseIP(addr)
|
// Check if there's a cache entry for this addr
|
||||||
|
if route, ok := c.ipv6cache[addr]; ok {
|
||||||
|
var box boxPubKey
|
||||||
|
copy(box[:boxPubKeyLen], route.destination)
|
||||||
|
return box, nil
|
||||||
|
}
|
||||||
|
|
||||||
if ipaddr.To4() == nil {
|
// No cache was found - start by converting the address into a net.IP
|
||||||
// IPv6
|
ip := make(net.IP, 16)
|
||||||
|
copy(ip[:16], addr[:])
|
||||||
|
|
||||||
|
// Check whether it's an IPv4 or an IPv6 address
|
||||||
|
if ip.To4() == nil {
|
||||||
|
// Check if we have a route. At this point c.ipv6routes should be
|
||||||
|
// pre-sorted so that the most specific routes are first
|
||||||
for _, route := range c.ipv6routes {
|
for _, route := range c.ipv6routes {
|
||||||
if route.subnet.Contains(ipaddr) {
|
// Does this subnet match the given IP?
|
||||||
|
if route.subnet.Contains(ip) {
|
||||||
|
// Cache the entry for future packets to get a faster lookup
|
||||||
|
c.ipv6cache[addr] = route
|
||||||
|
|
||||||
|
// Return the boxPubKey
|
||||||
var box boxPubKey
|
var box boxPubKey
|
||||||
copy(box[:boxPubKeyLen], route.destination)
|
copy(box[:boxPubKeyLen], route.destination)
|
||||||
return box, nil
|
return box, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// IPv4
|
// IPv4 isn't supported yet
|
||||||
return boxPubKey{}, errors.New("IPv4 not supported at this time")
|
return boxPubKey{}, errors.New("IPv4 not supported at this time")
|
||||||
/*
|
|
||||||
for _, route := range c.ipv4routes {
|
|
||||||
if route.subnet.Contains(ipaddr) {
|
|
||||||
return route.destination, nil
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
// No route was found if we got to this point
|
||||||
}
|
return boxPubKey{}, errors.New(fmt.Sprintf("No route to %s", ip.String()))
|
||||||
return boxPubKey{}, errors.New(fmt.Sprintf("No route to %s", addr))
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user