5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-26 02:31:37 +00:00

Check IP header lengths correctly per protocol

This commit is contained in:
Neil Alexander 2018-11-07 10:29:08 +00:00
parent 9542bfa902
commit 685b565512
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944

View File

@ -122,9 +122,6 @@ func (r *router) mainLoop() {
// If the session hasn't responded recently, it triggers a ping or search to keep things alive or deal with broken coords *relatively* quickly. // If the session hasn't responded recently, it triggers a ping or search to keep things alive or deal with broken coords *relatively* quickly.
// It also deals with oversized packets if there are MTU issues by calling into icmpv6.go to spoof PacketTooBig traffic, or DestinationUnreachable if the other side has their tun/tap disabled. // It also deals with oversized packets if there are MTU issues by calling into icmpv6.go to spoof PacketTooBig traffic, or DestinationUnreachable if the other side has their tun/tap disabled.
func (r *router) sendPacket(bs []byte) { func (r *router) sendPacket(bs []byte) {
if len(bs) < 40 {
panic("Tried to send a packet shorter than a header...")
}
var sourceAddr address var sourceAddr address
var destAddr address var destAddr address
var destSnet subnet var destSnet subnet
@ -132,12 +129,20 @@ func (r *router) sendPacket(bs []byte) {
var destNodeID *NodeID var destNodeID *NodeID
var addrlen int var addrlen int
if bs[0]&0xf0 == 0x60 { if bs[0]&0xf0 == 0x60 {
// Check if we have a fully-sized header
if len(bs) < 40 {
panic("Tried to send a packet shorter than an IPv6 header...")
}
// IPv6 address // IPv6 address
addrlen = 16 addrlen = 16
copy(sourceAddr[:addrlen], bs[8:]) copy(sourceAddr[:addrlen], bs[8:])
copy(destAddr[:addrlen], bs[24:]) copy(destAddr[:addrlen], bs[24:])
copy(destSnet[:addrlen/2], bs[24:]) copy(destSnet[:addrlen/2], bs[24:])
} else if bs[0]&0xf0 == 0x40 { } else if bs[0]&0xf0 == 0x40 {
// Check if we have a fully-sized header
if len(bs) < 20 {
panic("Tried to send a packet shorter than an IPv4 header...")
}
// IPv4 address // IPv4 address
addrlen = 4 addrlen = 4
copy(sourceAddr[:addrlen], bs[12:]) copy(sourceAddr[:addrlen], bs[12:])
@ -147,12 +152,19 @@ func (r *router) sendPacket(bs []byte) {
return return
} }
if !r.cryptokey.isValidSource(sourceAddr, addrlen) { if !r.cryptokey.isValidSource(sourceAddr, addrlen) {
// The packet had a source address that doesn't belong to us or our
// configured crypto-key routing source subnets
return return
} }
if !destAddr.isValid() && !destSnet.isValid() { if !destAddr.isValid() && !destSnet.isValid() {
// The addresses didn't match valid Yggdrasil node addresses so let's see
// whether it matches a crypto-key routing range instead
if key, err := r.cryptokey.getPublicKeyForAddress(destAddr, addrlen); err == nil { if key, err := r.cryptokey.getPublicKeyForAddress(destAddr, addrlen); err == nil {
// A public key was found, get the node ID for the search
destPubKey = &key destPubKey = &key
destNodeID = getNodeID(destPubKey) destNodeID = getNodeID(destPubKey)
// Do a quick check to ensure that the node ID refers to a vaild Yggdrasil
// address or subnet - this might be superfluous
addr := *address_addrForNodeID(destNodeID) addr := *address_addrForNodeID(destNodeID)
copy(destAddr[:], addr[:]) copy(destAddr[:], addr[:])
copy(destSnet[:], addr[:]) copy(destSnet[:], addr[:])
@ -160,6 +172,7 @@ func (r *router) sendPacket(bs []byte) {
return return
} }
} else { } else {
// No public key was found in the CKR table so we've exhausted our options
return return
} }
} }
@ -320,10 +333,13 @@ func (r *router) recvPacket(bs []byte, sinfo *sessionInfo) {
// Unknown address length // Unknown address length
return return
} }
// Check that the packet is destined for either our Yggdrasil address or
// subnet, or that it matches one of the crypto-key routing source routes
if !r.cryptokey.isValidSource(dest, addrlen) { if !r.cryptokey.isValidSource(dest, addrlen) {
util_putBytes(bs) util_putBytes(bs)
return return
} }
// See whether the packet they sent should have originated from this session
switch { switch {
case sourceAddr.isValid() && sourceAddr == sinfo.theirAddr: case sourceAddr.isValid() && sourceAddr == sinfo.theirAddr:
case snet.isValid() && snet == sinfo.theirSubnet: case snet.isValid() && snet == sinfo.theirSubnet: