mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Cache crypto-key routes (until routing table changes)
This commit is contained in:
		
							parent
							
								
									ec751e8cc7
								
							
						
					
					
						commit
						295e9c9a10
					
				
					 1 changed files with 37 additions and 14 deletions
				
			
		| 
						 | 
					@ -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
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
		*/
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue