mirror of
https://github.com/SagerNet/sing-tun.git
synced 2025-04-03 20:07:40 +03:00
Add broadcast filter
This commit is contained in:
parent
1a00992d06
commit
da350ecc72
4 changed files with 26 additions and 6 deletions
12
stack.go
12
stack.go
|
@ -2,6 +2,8 @@ package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
"github.com/sagernet/sing/common/control"
|
"github.com/sagernet/sing/common/control"
|
||||||
|
@ -52,3 +54,13 @@ func NewStack(
|
||||||
return nil, E.New("unknown stack: ", stack)
|
return nil, E.New("unknown stack: ", stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BroadcastAddr(inet4Address []netip.Prefix) netip.Addr {
|
||||||
|
if len(inet4Address) == 0 {
|
||||||
|
return netip.Addr{}
|
||||||
|
}
|
||||||
|
prefix := inet4Address[0]
|
||||||
|
var broadcastAddr [4]byte
|
||||||
|
binary.BigEndian.PutUint32(broadcastAddr[:], binary.BigEndian.Uint32(prefix.Masked().Addr().AsSlice())|^binary.BigEndian.Uint32(net.CIDRMask(prefix.Bits(), 32)))
|
||||||
|
return netip.AddrFrom4(broadcastAddr)
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ type GVisor struct {
|
||||||
tunMtu uint32
|
tunMtu uint32
|
||||||
endpointIndependentNat bool
|
endpointIndependentNat bool
|
||||||
udpTimeout int64
|
udpTimeout int64
|
||||||
|
broadcastAddr netip.Addr
|
||||||
handler Handler
|
handler Handler
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
stack *stack.Stack
|
stack *stack.Stack
|
||||||
|
@ -59,6 +60,7 @@ func NewGVisor(
|
||||||
tunMtu: options.MTU,
|
tunMtu: options.MTU,
|
||||||
endpointIndependentNat: options.EndpointIndependentNat,
|
endpointIndependentNat: options.EndpointIndependentNat,
|
||||||
udpTimeout: options.UDPTimeout,
|
udpTimeout: options.UDPTimeout,
|
||||||
|
broadcastAddr: BroadcastAddr(options.Inet4Address),
|
||||||
handler: options.Handler,
|
handler: options.Handler,
|
||||||
logger: options.Logger,
|
logger: options.Logger,
|
||||||
}
|
}
|
||||||
|
@ -70,7 +72,7 @@ func (t *GVisor) Start() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
linkEndpoint = &LinkEndpointFilter{linkEndpoint, t.tun.CreateVectorisedWriter()}
|
linkEndpoint = &LinkEndpointFilter{linkEndpoint, t.broadcastAddr, t.tun.CreateVectorisedWriter()}
|
||||||
ipStack, err := newGVisorStack(linkEndpoint)
|
ipStack, err := newGVisorStack(linkEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
package tun
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip"
|
"github.com/sagernet/gvisor/pkg/tcpip"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/header"
|
"github.com/sagernet/gvisor/pkg/tcpip/header"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
||||||
|
@ -14,18 +16,20 @@ var _ stack.LinkEndpoint = (*LinkEndpointFilter)(nil)
|
||||||
|
|
||||||
type LinkEndpointFilter struct {
|
type LinkEndpointFilter struct {
|
||||||
stack.LinkEndpoint
|
stack.LinkEndpoint
|
||||||
Writer N.VectorisedWriter
|
BroadcastAddress netip.Addr
|
||||||
|
Writer N.VectorisedWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LinkEndpointFilter) Attach(dispatcher stack.NetworkDispatcher) {
|
func (w *LinkEndpointFilter) Attach(dispatcher stack.NetworkDispatcher) {
|
||||||
w.LinkEndpoint.Attach(&networkDispatcherFilter{dispatcher, w.Writer})
|
w.LinkEndpoint.Attach(&networkDispatcherFilter{dispatcher, w.BroadcastAddress, w.Writer})
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ stack.NetworkDispatcher = (*networkDispatcherFilter)(nil)
|
var _ stack.NetworkDispatcher = (*networkDispatcherFilter)(nil)
|
||||||
|
|
||||||
type networkDispatcherFilter struct {
|
type networkDispatcherFilter struct {
|
||||||
stack.NetworkDispatcher
|
stack.NetworkDispatcher
|
||||||
writer N.VectorisedWriter
|
broadcastAddress netip.Addr
|
||||||
|
writer N.VectorisedWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *networkDispatcherFilter) DeliverNetworkPacket(protocol tcpip.NetworkProtocolNumber, pkt stack.PacketBufferPtr) {
|
func (w *networkDispatcherFilter) DeliverNetworkPacket(protocol tcpip.NetworkProtocolNumber, pkt stack.PacketBufferPtr) {
|
||||||
|
@ -44,7 +48,7 @@ func (w *networkDispatcherFilter) DeliverNetworkPacket(protocol tcpip.NetworkPro
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
destination := AddrFromAddress(network.DestinationAddress())
|
destination := AddrFromAddress(network.DestinationAddress())
|
||||||
if destination.IsMulticast() || !destination.IsGlobalUnicast() {
|
if destination == w.broadcastAddress || !destination.IsGlobalUnicast() {
|
||||||
_, _ = bufio.WriteVectorised(w.writer, pkt.AsSlices())
|
_, _ = bufio.WriteVectorised(w.writer, pkt.AsSlices())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ type System struct {
|
||||||
inet4Address netip.Addr
|
inet4Address netip.Addr
|
||||||
inet6ServerAddress netip.Addr
|
inet6ServerAddress netip.Addr
|
||||||
inet6Address netip.Addr
|
inet6Address netip.Addr
|
||||||
|
broadcastAddr netip.Addr
|
||||||
udpTimeout int64
|
udpTimeout int64
|
||||||
tcpListener net.Listener
|
tcpListener net.Listener
|
||||||
tcpListener6 net.Listener
|
tcpListener6 net.Listener
|
||||||
|
@ -60,6 +61,7 @@ func NewSystem(options StackOptions) (Stack, error) {
|
||||||
logger: options.Logger,
|
logger: options.Logger,
|
||||||
inet4Prefixes: options.Inet4Address,
|
inet4Prefixes: options.Inet4Address,
|
||||||
inet6Prefixes: options.Inet6Address,
|
inet6Prefixes: options.Inet6Address,
|
||||||
|
broadcastAddr: BroadcastAddr(options.Inet4Address),
|
||||||
bindInterface: options.ForwarderBindInterface,
|
bindInterface: options.ForwarderBindInterface,
|
||||||
interfaceFinder: options.InterfaceFinder,
|
interfaceFinder: options.InterfaceFinder,
|
||||||
}
|
}
|
||||||
|
@ -234,7 +236,7 @@ func (s *System) acceptLoop(listener net.Listener) {
|
||||||
|
|
||||||
func (s *System) processIPv4(packet clashtcpip.IPv4Packet) error {
|
func (s *System) processIPv4(packet clashtcpip.IPv4Packet) error {
|
||||||
destination := packet.DestinationIP()
|
destination := packet.DestinationIP()
|
||||||
if destination.IsMulticast() || !destination.IsGlobalUnicast() {
|
if destination == s.broadcastAddr || !destination.IsGlobalUnicast() {
|
||||||
return common.Error(s.tun.Write(packet))
|
return common.Error(s.tun.Write(packet))
|
||||||
}
|
}
|
||||||
switch packet.Protocol() {
|
switch packet.Protocol() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue