mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Add source addresses option and more intelligent source checking
This commit is contained in:
		
							parent
							
								
									cfdbc481a5
								
							
						
					
					
						commit
						8c2327a2bf
					
				
					 3 changed files with 64 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -12,12 +12,14 @@ import (
 | 
			
		|||
// allow traffic for non-Yggdrasil ranges to be routed over Yggdrasil.
 | 
			
		||||
 | 
			
		||||
type cryptokey struct {
 | 
			
		||||
	core       *Core
 | 
			
		||||
	enabled    bool
 | 
			
		||||
	ipv4routes []cryptokey_route
 | 
			
		||||
	ipv6routes []cryptokey_route
 | 
			
		||||
	ipv4cache  map[address]cryptokey_route
 | 
			
		||||
	ipv6cache  map[address]cryptokey_route
 | 
			
		||||
	core        *Core
 | 
			
		||||
	enabled     bool
 | 
			
		||||
	ipv4routes  []cryptokey_route
 | 
			
		||||
	ipv6routes  []cryptokey_route
 | 
			
		||||
	ipv4cache   map[address]cryptokey_route
 | 
			
		||||
	ipv6cache   map[address]cryptokey_route
 | 
			
		||||
	ipv4sources []net.IPNet
 | 
			
		||||
	ipv6sources []net.IPNet
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type cryptokey_route struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -31,12 +33,60 @@ func (c *cryptokey) init(core *Core) {
 | 
			
		|||
	c.ipv6routes = make([]cryptokey_route, 0)
 | 
			
		||||
	c.ipv4cache = make(map[address]cryptokey_route, 0)
 | 
			
		||||
	c.ipv6cache = make(map[address]cryptokey_route, 0)
 | 
			
		||||
	c.ipv4sources = make([]net.IPNet, 0)
 | 
			
		||||
	c.ipv6sources = make([]net.IPNet, 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *cryptokey) isEnabled() bool {
 | 
			
		||||
	return c.enabled
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *cryptokey) isValidSource(addr address) bool {
 | 
			
		||||
	ip := net.IP(addr[:])
 | 
			
		||||
 | 
			
		||||
	// Does this match our node's address?
 | 
			
		||||
	if addr == c.core.router.addr {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Does this match our node's subnet?
 | 
			
		||||
	var subnet net.IPNet
 | 
			
		||||
	copy(subnet.IP, c.core.router.subnet[:])
 | 
			
		||||
	copy(subnet.Mask, net.CIDRMask(64, 128))
 | 
			
		||||
	if subnet.Contains(ip) {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Does it match a configured CKR source?
 | 
			
		||||
	for _, subnet := range c.ipv6sources {
 | 
			
		||||
		if subnet.Contains(ip) {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Doesn't match any of the above
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *cryptokey) addSourceSubnet(cidr string) error {
 | 
			
		||||
	// Is the CIDR we've been given valid?
 | 
			
		||||
	_, ipnet, err := net.ParseCIDR(cidr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check if we already have this CIDR
 | 
			
		||||
	for _, subnet := range c.ipv6sources {
 | 
			
		||||
		if subnet.String() == ipnet.String() {
 | 
			
		||||
			return errors.New("Source subnet already configured")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add the source subnet
 | 
			
		||||
	c.ipv6sources = append(c.ipv6sources, *ipnet)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *cryptokey) addRoute(cidr string, dest string) error {
 | 
			
		||||
	// Is the CIDR we've been given valid?
 | 
			
		||||
	ipaddr, ipnet, err := net.ParseCIDR(cidr)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,7 @@ type SessionFirewall struct {
 | 
			
		|||
 | 
			
		||||
// TunnelRouting contains the crypto-key routing tables for tunneling
 | 
			
		||||
type TunnelRouting struct {
 | 
			
		||||
	Enable     bool              `comment:"Enable or disable tunneling."`
 | 
			
		||||
	IPv6Routes map[string]string `comment:"IPv6 subnets, mapped to the public keys to which they should be routed."`
 | 
			
		||||
	Enable      bool              `comment:"Enable or disable tunneling."`
 | 
			
		||||
	IPv6Routes  map[string]string `comment:"IPv6 subnets, mapped to the public keys to which they should be routed."`
 | 
			
		||||
	IPv6Sources []string          `comment:"Allow source addresses in these subnets."`
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@ import (
 | 
			
		|||
type router struct {
 | 
			
		||||
	core      *Core
 | 
			
		||||
	addr      address
 | 
			
		||||
	subnet    subnet
 | 
			
		||||
	in        <-chan []byte // packets we received from the network, link to peer's "out"
 | 
			
		||||
	out       func([]byte)  // packets we're sending to the network, link to peer's "in"
 | 
			
		||||
	recv      chan<- []byte // place where the tun pulls received packets from
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +48,7 @@ type router struct {
 | 
			
		|||
func (r *router) init(core *Core) {
 | 
			
		||||
	r.core = core
 | 
			
		||||
	r.addr = *address_addrForNodeID(&r.core.dht.nodeID)
 | 
			
		||||
	r.subnet = *address_subnetForNodeID(&r.core.dht.nodeID)
 | 
			
		||||
	in := make(chan []byte, 32) // TODO something better than this...
 | 
			
		||||
	p := r.core.peers.newPeer(&r.core.boxPub, &r.core.sigPub, &boxSharedKey{}, "(self)")
 | 
			
		||||
	p.out = func(packet []byte) {
 | 
			
		||||
| 
						 | 
				
			
			@ -128,6 +130,9 @@ func (r *router) sendPacket(bs []byte) {
 | 
			
		|||
	var snet subnet
 | 
			
		||||
	copy(sourceAddr[:], bs[8:])
 | 
			
		||||
	copy(sourceSubnet[:], bs[8:])
 | 
			
		||||
	if !r.cryptokey.isValidSource(sourceAddr) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	copy(dest[:], bs[24:])
 | 
			
		||||
	copy(snet[:], bs[24:])
 | 
			
		||||
	if !dest.isValid() && !snet.isValid() {
 | 
			
		||||
| 
						 | 
				
			
			@ -141,10 +146,6 @@ func (r *router) sendPacket(bs []byte) {
 | 
			
		|||
		} else {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if !sourceAddr.isValid() && !sourceSubnet.isValid() {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	doSearch := func(packet []byte) {
 | 
			
		||||
		var nodeID, mask *NodeID
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue