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) } }) } } }