5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-12-23 12:15:39 +00:00

IPv4 CKR support in router

This commit is contained in:
Neil Alexander 2018-11-06 20:49:19 +00:00
parent 424faa1c51
commit 0240375417
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
3 changed files with 62 additions and 24 deletions

View File

@ -46,22 +46,36 @@ func (c *cryptokey) isEnabled() bool {
return c.enabled
}
func (c *cryptokey) isValidSource(addr address) bool {
ip := net.IP(addr[:])
func (c *cryptokey) isValidSource(addr address, addrlen int) bool {
ip := net.IP(addr[:addrlen])
// Does this match our node's address?
if bytes.Equal(addr[:16], c.core.router.addr[:16]) {
return true
}
if addrlen == net.IPv6len {
// Does this match our node's address?
if bytes.Equal(addr[:16], c.core.router.addr[:16]) {
return true
}
// Does this match our node's subnet?
if bytes.Equal(addr[:8], c.core.router.subnet[:8]) {
return true
// Does this match our node's subnet?
if bytes.Equal(addr[:8], c.core.router.subnet[:8]) {
return true
}
}
// Does it match a configured CKR source?
if c.isEnabled() {
for _, subnet := range c.ipv6sources {
// Build our references to the routing sources
var routingsources *[]net.IPNet
// Check if the prefix is IPv4 or IPv6
if addrlen == net.IPv6len {
routingsources = &c.ipv6sources
} else if addrlen == net.IPv4len {
routingsources = &c.ipv4sources
} else {
return false
}
for _, subnet := range *routingsources {
if subnet.Contains(ip) {
return true
}

View File

@ -127,14 +127,26 @@ func (r *router) sendPacket(bs []byte) {
var sourceAddr address
var dest address
var snet subnet
copy(sourceAddr[:], bs[8:])
if !r.cryptokey.isValidSource(sourceAddr) {
var addrlen int
if bs[0]&0xf0 == 0x60 {
// IPv6 address
addrlen = 16
copy(sourceAddr[:addrlen], bs[8:])
copy(dest[:addrlen], bs[24:])
copy(snet[:addrlen/2], bs[24:])
} else if bs[0]&0xf0 == 0x40 {
// IPv4 address
addrlen = 4
copy(sourceAddr[:addrlen], bs[12:])
copy(dest[:addrlen], bs[16:])
} else {
return
}
if !r.cryptokey.isValidSource(sourceAddr, addrlen) {
return
}
copy(dest[:], bs[24:])
copy(snet[:], bs[24:])
if !dest.isValid() && !snet.isValid() {
if key, err := r.cryptokey.getPublicKeyForAddress(dest, 16); err == nil {
if key, err := r.cryptokey.getPublicKeyForAddress(dest, addrlen); err == nil {
addr := *address_addrForNodeID(getNodeID(&key))
copy(dest[:], addr[:])
copy(snet[:], addr[:])
@ -259,21 +271,33 @@ func (r *router) recvPacket(bs []byte, sinfo *sessionInfo) {
util_putBytes(bs)
return
}
var sourceAddr address
var dest address
copy(dest[:], bs[24:])
if !r.cryptokey.isValidSource(dest) {
var snet subnet
var addrlen int
if bs[0]&0xf0 == 0x60 {
// IPv6 address
addrlen = 16
copy(sourceAddr[:addrlen], bs[8:])
copy(dest[:addrlen], bs[24:])
copy(snet[:addrlen/2], bs[24:])
} else if bs[0]&0xf0 == 0x40 {
// IPv4 address
addrlen = 4
copy(sourceAddr[:addrlen], bs[12:])
copy(dest[:addrlen], bs[16:])
} else {
return
}
if !r.cryptokey.isValidSource(dest, addrlen) {
util_putBytes(bs)
return
}
var source address
copy(source[:], bs[8:])
var snet subnet
copy(snet[:], bs[8:])
switch {
case source.isValid() && source == sinfo.theirAddr:
case sourceAddr.isValid() && sourceAddr == sinfo.theirAddr:
case snet.isValid() && snet == sinfo.theirSubnet:
default:
key, err := r.cryptokey.getPublicKeyForAddress(source, 16)
key, err := r.cryptokey.getPublicKeyForAddress(sourceAddr, addrlen)
if err != nil || key != sinfo.theirPermPub {
util_putBytes(bs)
return

View File

@ -105,7 +105,7 @@ func (tun *tunDevice) read() error {
n != 256*int(buf[o+4])+int(buf[o+5])+tun_IPv6_HEADER_LENGTH+o {
// Either not an IPv6 packet or not the complete packet for some reason
//panic("Should not happen in testing")
continue
//continue
}
if buf[o+6] == 58 {
// Found an ICMPv6 packet