Files
yggdrasil-go/src/tuntap/iface.go

60 lines
1.3 KiB
Go

package tuntap
import (
"golang.org/x/net/icmp"
"golang.org/x/net/ipv6"
)
const TUN_OFFSET_BYTES = 4
func (tun *TunAdapter) read() {
var buf [TUN_OFFSET_BYTES + 65535]byte
for {
n, err := tun.iface.Read(buf[:], TUN_OFFSET_BYTES)
if n <= TUN_OFFSET_BYTES || err != nil {
tun.log.Errorln("Error reading TUN:", err)
ferr := tun.iface.Flush()
if ferr != nil {
tun.log.Errorln("Unable to flush packets:", ferr)
}
return
}
begin := TUN_OFFSET_BYTES
end := begin + n
bs := buf[begin:end]
if _, err := tun.core.Write(bs); err != nil {
tun.log.Errorln("Unable to send packet:", err)
}
}
}
func (tun *TunAdapter) write() {
var buf [TUN_OFFSET_BYTES + 65535]byte
for {
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 > 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.Write(packet)
}
continue
}
bs = buf[:TUN_OFFSET_BYTES+n]
if _, err = tun.iface.Write(bs, TUN_OFFSET_BYTES); err != nil {
tun.Act(nil, func() {
if !tun.isOpen {
tun.log.Errorln("TUN iface write error:", err)
}
})
}
}
}