package masque import ( "sync" "github.com/sagernet/wireguard-go/tun" "github.com/songgao/water" ) type NetstackAdapter struct { dev tun.Device tunnelBufPool sync.Pool tunnelSizesPool sync.Pool } func (n *NetstackAdapter) ReadPacket(buf []byte) (int, error) { packetBufsPtr := n.tunnelBufPool.Get().(*[][]byte) sizesPtr := n.tunnelSizesPool.Get().(*[]int) defer func() { (*packetBufsPtr)[0] = nil n.tunnelBufPool.Put(packetBufsPtr) n.tunnelSizesPool.Put(sizesPtr) }() (*packetBufsPtr)[0] = buf (*sizesPtr)[0] = 0 _, err := n.dev.Read(*packetBufsPtr, *sizesPtr, 0) if err != nil { return 0, err } return (*sizesPtr)[0], nil } func (n *NetstackAdapter) WritePacket(pkt []byte) error { // Write expects a slice of packet buffers. _, err := n.dev.Write([][]byte{pkt}, 0) return err } // NewNetstackAdapter creates a new NetstackAdapter. func NewNetstackAdapter(dev tun.Device) TunnelDevice { return &NetstackAdapter{ dev: dev, tunnelBufPool: sync.Pool{ New: func() interface{} { buf := make([][]byte, 1) return &buf }, }, tunnelSizesPool: sync.Pool{ New: func() interface{} { sizes := make([]int, 1) return &sizes }, }, } } type WaterAdapter struct { iface *water.Interface } func (w *WaterAdapter) ReadPacket(buf []byte) (int, error) { n, err := w.iface.Read(buf) if err != nil { return 0, err } return n, nil } func (w *WaterAdapter) WritePacket(pkt []byte) error { _, err := w.iface.Write(pkt) return err } func NewWaterAdapter(iface *water.Interface) TunnelDevice { return &WaterAdapter{iface: iface} }