5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-23 02:01:36 +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,9 +46,10 @@ func (c *cryptokey) isEnabled() bool {
return c.enabled return c.enabled
} }
func (c *cryptokey) isValidSource(addr address) bool { func (c *cryptokey) isValidSource(addr address, addrlen int) bool {
ip := net.IP(addr[:]) ip := net.IP(addr[:addrlen])
if addrlen == net.IPv6len {
// Does this match our node's address? // Does this match our node's address?
if bytes.Equal(addr[:16], c.core.router.addr[:16]) { if bytes.Equal(addr[:16], c.core.router.addr[:16]) {
return true return true
@ -58,10 +59,23 @@ func (c *cryptokey) isValidSource(addr address) bool {
if bytes.Equal(addr[:8], c.core.router.subnet[:8]) { if bytes.Equal(addr[:8], c.core.router.subnet[:8]) {
return true return true
} }
}
// Does it match a configured CKR source? // Does it match a configured CKR source?
if c.isEnabled() { 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) { if subnet.Contains(ip) {
return true return true
} }

View File

@ -127,14 +127,26 @@ func (r *router) sendPacket(bs []byte) {
var sourceAddr address var sourceAddr address
var dest address var dest address
var snet subnet var snet subnet
copy(sourceAddr[:], bs[8:]) var addrlen int
if !r.cryptokey.isValidSource(sourceAddr) { 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 return
} }
copy(dest[:], bs[24:])
copy(snet[:], bs[24:])
if !dest.isValid() && !snet.isValid() { 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)) addr := *address_addrForNodeID(getNodeID(&key))
copy(dest[:], addr[:]) copy(dest[:], addr[:])
copy(snet[:], addr[:]) copy(snet[:], addr[:])
@ -259,21 +271,33 @@ func (r *router) recvPacket(bs []byte, sinfo *sessionInfo) {
util_putBytes(bs) util_putBytes(bs)
return return
} }
var sourceAddr address
var dest address var dest address
copy(dest[:], bs[24:]) var snet subnet
if !r.cryptokey.isValidSource(dest) { 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) util_putBytes(bs)
return return
} }
var source address
copy(source[:], bs[8:])
var snet subnet
copy(snet[:], bs[8:])
switch { switch {
case source.isValid() && source == sinfo.theirAddr: case sourceAddr.isValid() && sourceAddr == sinfo.theirAddr:
case snet.isValid() && snet == sinfo.theirSubnet: case snet.isValid() && snet == sinfo.theirSubnet:
default: default:
key, err := r.cryptokey.getPublicKeyForAddress(source, 16) key, err := r.cryptokey.getPublicKeyForAddress(sourceAddr, addrlen)
if err != nil || key != sinfo.theirPermPub { if err != nil || key != sinfo.theirPermPub {
util_putBytes(bs) util_putBytes(bs)
return 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 { 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 // Either not an IPv6 packet or not the complete packet for some reason
//panic("Should not happen in testing") //panic("Should not happen in testing")
continue //continue
} }
if buf[o+6] == 58 { if buf[o+6] == 58 {
// Found an ICMPv6 packet // Found an ICMPv6 packet