github.com/MerlinKodo/sing-tun@v0.1.15/stack_gvisor_filter.go (about) 1 //go:build with_gvisor 2 3 package tun 4 5 import ( 6 "github.com/MerlinKodo/gvisor/pkg/tcpip" 7 "github.com/MerlinKodo/gvisor/pkg/tcpip/header" 8 "github.com/MerlinKodo/gvisor/pkg/tcpip/stack" 9 "github.com/sagernet/sing/common/bufio" 10 N "github.com/sagernet/sing/common/network" 11 ) 12 13 var _ stack.LinkEndpoint = (*LinkEndpointFilter)(nil) 14 15 type LinkEndpointFilter struct { 16 stack.LinkEndpoint 17 Writer N.VectorisedWriter 18 } 19 20 func (w *LinkEndpointFilter) Attach(dispatcher stack.NetworkDispatcher) { 21 w.LinkEndpoint.Attach(&networkDispatcherFilter{dispatcher, w.Writer}) 22 } 23 24 var _ stack.NetworkDispatcher = (*networkDispatcherFilter)(nil) 25 26 type networkDispatcherFilter struct { 27 stack.NetworkDispatcher 28 writer N.VectorisedWriter 29 } 30 31 func (w *networkDispatcherFilter) DeliverNetworkPacket(protocol tcpip.NetworkProtocolNumber, pkt stack.PacketBufferPtr) { 32 var network header.Network 33 if protocol == header.IPv4ProtocolNumber { 34 if headerPackets, loaded := pkt.Data().PullUp(header.IPv4MinimumSize); loaded { 35 network = header.IPv4(headerPackets) 36 } 37 } else { 38 if headerPackets, loaded := pkt.Data().PullUp(header.IPv6MinimumSize); loaded { 39 network = header.IPv6(headerPackets) 40 } 41 } 42 if network == nil { 43 w.NetworkDispatcher.DeliverNetworkPacket(protocol, pkt) 44 return 45 } 46 destination := AddrFromAddress(network.DestinationAddress()) 47 if destination.IsGlobalUnicast() { 48 w.NetworkDispatcher.DeliverNetworkPacket(protocol, pkt) 49 return 50 } 51 _, _ = bufio.WriteVectorised(w.writer, pkt.AsSlices()) 52 }