mostly finish migration of IP stuff to core, tuntap is still responsible for ICMP PacketTooBig

This commit is contained in:
Arceliar 2021-06-13 04:54:06 -05:00
parent 1147ee1934
commit 816356ea65
7 changed files with 114 additions and 185 deletions

View file

@ -1,20 +1,8 @@
package tuntap
import (
"crypto/ed25519"
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv6"
//"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
//"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
//"golang.org/x/net/icmp"
//"golang.org/x/net/ipv6"
iwt "github.com/Arceliar/ironwood/types"
//"github.com/Arceliar/phony"
)
const TUN_OFFSET_BYTES = 4
@ -34,28 +22,8 @@ func (tun *TunAdapter) read() {
begin := TUN_OFFSET_BYTES
end := begin + n
bs := buf[begin:end]
if bs[0]&0xf0 != 0x60 {
continue // not IPv6
}
if len(bs) < 40 {
tun.log.Traceln("TUN iface read undersized ipv6 packet, length:", len(bs))
continue
}
var srcAddr, dstAddr address.Address
var srcSubnet, dstSubnet address.Subnet
copy(srcAddr[:], bs[8:])
copy(dstAddr[:], bs[24:])
copy(srcSubnet[:], bs[8:])
copy(dstSubnet[:], bs[24:])
if srcAddr != tun.addr && srcSubnet != tun.subnet {
continue // Wrong source address
}
bs = buf[begin-1 : end]
bs[0] = typeSessionTraffic
if dstAddr.IsValid() {
tun.store.sendToAddress(dstAddr, bs)
} else if dstSubnet.IsValid() {
tun.store.sendToSubnet(dstSubnet, bs)
if _, err := tun.core.Write(bs); err != nil {
tun.log.Errorln("Unable to send packet:", err)
}
}
}
@ -63,63 +31,23 @@ func (tun *TunAdapter) read() {
func (tun *TunAdapter) write() {
var buf [TUN_OFFSET_BYTES + 65535]byte
for {
bs := buf[TUN_OFFSET_BYTES-1:]
n, from, err := tun.core.ReadFrom(bs)
bs := buf[TUN_OFFSET_BYTES:]
n, err := tun.core.Read(bs)
if err != nil {
tun.log.Errorln("Exiting tun writer due to core read error:", err)
return
}
if n == 0 {
continue
}
switch bs[0] {
case typeSessionTraffic:
// This is what we want to handle here
if !tun.isEnabled {
continue // Drop traffic if the tun is disabled
}
case typeSessionProto:
var key keyArray
copy(key[:], from.(iwt.Addr))
data := append([]byte(nil), bs[1:n]...)
tun.proto.handleProto(nil, key, data)
continue
default:
continue
}
bs = bs[1:n]
if len(bs) == 0 {
continue
}
if bs[0]&0xf0 != 0x60 {
continue // not IPv6
}
if len(bs) < 40 {
continue
}
if len(bs) > int(tun.MTU()) {
if n > int(tun.MTU()) {
ptb := &icmp.PacketTooBig{
MTU: int(tun.mtu),
Data: bs[:40],
}
if packet, err := CreateICMPv6(bs[8:24], bs[24:40], ipv6.ICMPTypePacketTooBig, 0, ptb); err == nil {
_, _ = tun.core.WriteTo(packet, from)
_, _ = tun.core.Write(packet)
}
continue
}
var srcAddr, dstAddr address.Address
var srcSubnet, dstSubnet address.Subnet
copy(srcAddr[:], bs[8:])
copy(dstAddr[:], bs[24:])
copy(srcSubnet[:], bs[8:])
copy(dstSubnet[:], bs[24:])
if dstAddr != tun.addr && dstSubnet != tun.subnet {
continue // bad local address/subnet
}
info := tun.store.update(ed25519.PublicKey(from.(iwt.Addr)))
if srcAddr != info.address && srcSubnet != info.subnet {
continue // bad remote address/subnet
}
bs = buf[:TUN_OFFSET_BYTES+len(bs)]
bs = buf[:TUN_OFFSET_BYTES+n]
if _, err = tun.iface.Write(bs, TUN_OFFSET_BYTES); err != nil {
tun.Act(nil, func() {
if !tun.isOpen {