move ckr checks into the tunConn code

This commit is contained in:
Arceliar 2019-08-20 18:10:08 -05:00
parent b79829c43b
commit 4156aa3003
3 changed files with 123 additions and 118 deletions

View file

@ -2,7 +2,6 @@ package tuntap
import (
"bytes"
"errors"
"net"
"time"
@ -21,62 +20,6 @@ func (tun *TunAdapter) writer() error {
if n == 0 {
continue
}
var srcAddr address.Address
var dstAddr address.Address
var addrlen int
// Check whether the packet is IPv4, IPv6 or neither
if b[0]&0xf0 == 0x60 {
// IPv6 packet found
if len(b) < 40 {
// Packet was too short
util.PutBytes(b)
continue
}
// Extract the IPv6 addresses
copy(srcAddr[:16], b[8:24])
copy(dstAddr[:16], b[24:40])
addrlen = 16
} else if b[0]&0xf0 == 0x40 {
// IPv4 packet found
if len(b) < 20 {
// Packet was too short
util.PutBytes(b)
continue
}
// Extract the IPv4 addresses
copy(srcAddr[:4], b[12:16])
copy(dstAddr[:4], b[16:20])
addrlen = 4
} else {
// Neither IPv4 nor IPv6
return errors.New("Invalid address family")
}
// Check the crypto-key routing rules next
if tun.ckr.isEnabled() {
if !tun.ckr.isValidLocalAddress(dstAddr, addrlen) {
util.PutBytes(b)
continue
}
if srcAddr[0] != 0x02 && srcAddr[0] != 0x03 {
// TODO: is this check useful? this doesn't actually guarantee that the
// packet came from the configured public key for that remote, just that
// it came from *a* configured remote. at this stage we have no ability
// to know which Conn or public key was involved
if _, err := tun.ckr.getPublicKeyForAddress(srcAddr, addrlen); err != nil {
util.PutBytes(b)
continue
}
}
} else {
if addrlen != 16 {
util.PutBytes(b)
continue
}
if !bytes.Equal(tun.addr[:16], dstAddr[:16]) && !bytes.Equal(tun.subnet[:8], dstAddr[:8]) {
util.PutBytes(b)
continue
}
}
if tun.iface.IsTAP() {
sendndp := func(dstAddr address.Address) {
neigh, known := tun.icmpv6.getNeighbor(dstAddr)
@ -86,6 +29,7 @@ func (tun *TunAdapter) writer() error {
}
}
peermac := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
var dstAddr address.Address
var peerknown bool
if b[0]&0xf0 == 0x40 {
dstAddr = tun.addr
@ -183,10 +127,7 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
// From the IP header, work out what our source and destination addresses
// and node IDs are. We will need these in order to work out where to send
// the packet
var srcAddr address.Address
var dstAddr address.Address
var dstNodeID *crypto.NodeID
var dstNodeIDMask *crypto.NodeID
var dstSnet address.Subnet
var addrlen int
n := len(bs)
@ -203,7 +144,6 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
}
// IPv6 address
addrlen = 16
copy(srcAddr[:addrlen], bs[8:])
copy(dstAddr[:addrlen], bs[24:])
copy(dstSnet[:addrlen/2], bs[24:])
} else if bs[0]&0xf0 == 0x40 {
@ -217,7 +157,6 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
}
// IPv4 address
addrlen = 4
copy(srcAddr[:addrlen], bs[12:])
copy(dstAddr[:addrlen], bs[16:])
} else {
// Unknown address length or protocol, so drop the packet and ignore it
@ -225,36 +164,22 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
continue
}
if tun.ckr.isEnabled() {
if !tun.ckr.isValidLocalAddress(srcAddr, addrlen) {
continue
}
if !dstAddr.IsValid() && !dstSnet.IsValid() {
if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) {
if key, err := tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil {
// A public key was found, get the node ID for the search
dstNodeID = crypto.GetNodeID(&key)
// 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(dstNodeID)
copy(dstAddr[:], addr[:])
copy(dstSnet[:], addr[:])
// Are we certain we looked up a valid node?
if !dstAddr.IsValid() && !dstSnet.IsValid() {
continue
}
} else {
// No public key was found in the CKR table so we've exhausted our options
continue
dstNodeID := crypto.GetNodeID(&key)
dstAddr = *address.AddrForNodeID(dstNodeID)
dstSnet = *address.SubnetForNodeID(dstNodeID)
addrlen = 16
}
}
} else {
if addrlen != 16 {
continue
}
if !dstAddr.IsValid() && !dstSnet.IsValid() {
continue
}
}
if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) {
// Couldn't find this node's ygg IP
continue
}
// Do we have an active connection for this node address?
var dstNodeID, dstNodeIDMask *crypto.NodeID
tun.mutex.RLock()
session, isIn := tun.addrToConn[dstAddr]
if !isIn || session == nil {