mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-12-23 12:15:39 +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
|
||||
ipv4routes []cryptokey_route
|
||||
ipv6routes []cryptokey_route
|
||||
ipv4cache map[address]cryptokey_route
|
||||
ipv6cache map[address]cryptokey_route
|
||||
}
|
||||
|
||||
type cryptokey_route struct {
|
||||
@ -27,6 +29,8 @@ func (c *cryptokey) init(core *Core) {
|
||||
c.core = core
|
||||
c.ipv4routes = 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 {
|
||||
@ -68,12 +72,20 @@ func (c *cryptokey) addRoute(cidr string, dest string) error {
|
||||
subnet: *ipnet,
|
||||
destination: boxPubKey,
|
||||
})
|
||||
|
||||
// Sort so most specific routes are first
|
||||
sort.Slice(c.ipv6routes, func(i, j int) bool {
|
||||
im, _ := c.ipv6routes[i].subnet.Mask.Size()
|
||||
jm, _ := c.ipv6routes[j].subnet.Mask.Size()
|
||||
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
|
||||
}
|
||||
} else if prefixsize == net.IPv4len*8 {
|
||||
@ -83,28 +95,39 @@ func (c *cryptokey) addRoute(cidr string, dest string) error {
|
||||
return errors.New("Unspecified error")
|
||||
}
|
||||
|
||||
func (c *cryptokey) getPublicKeyForAddress(addr string) (boxPubKey, error) {
|
||||
ipaddr := net.ParseIP(addr)
|
||||
func (c *cryptokey) getPublicKeyForAddress(addr address) (boxPubKey, error) {
|
||||
// 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 {
|
||||
// IPv6
|
||||
// No cache was found - start by converting the address into a net.IP
|
||||
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 {
|
||||
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
|
||||
copy(box[:boxPubKeyLen], route.destination)
|
||||
return box, nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// IPv4
|
||||
// IPv4 isn't supported yet
|
||||
return boxPubKey{}, errors.New("IPv4 not supported at this time")
|
||||
/*
|
||||
for _, route := range c.ipv4routes {
|
||||
if route.subnet.Contains(ipaddr) {
|
||||
return route.destination, nil
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
return boxPubKey{}, errors.New(fmt.Sprintf("No route to %s", addr))
|
||||
|
||||
// No route was found if we got to this point
|
||||
return boxPubKey{}, errors.New(fmt.Sprintf("No route to %s", ip.String()))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user