mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-15 21:00:27 +00:00
refactor: New tun udpnat
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-tun"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/wireguard-go/device"
|
||||
@@ -22,17 +23,22 @@ type Device interface {
|
||||
}
|
||||
|
||||
type DeviceOptions struct {
|
||||
Context context.Context
|
||||
Logger logger.ContextLogger
|
||||
System bool
|
||||
Handler tun.Handler
|
||||
UDPTimeout time.Duration
|
||||
ICMPTimeout time.Duration
|
||||
CreateDialer func(interfaceName string) N.Dialer
|
||||
Name string
|
||||
MTU uint32
|
||||
Address []netip.Prefix
|
||||
AllowedAddress []netip.Prefix
|
||||
Context context.Context
|
||||
Logger logger.ContextLogger
|
||||
System bool
|
||||
Handler tun.Handler
|
||||
UDPTimeout time.Duration
|
||||
ICMPTimeout time.Duration
|
||||
UDPMapping tun.NATMapping
|
||||
UDPFiltering tun.NATFiltering
|
||||
UDPNATMax uint32
|
||||
NetworkMonitor tun.NetworkUpdateMonitor
|
||||
InterfaceFinder control.InterfaceFinder
|
||||
CreateDialer func(interfaceName string) N.Dialer
|
||||
Name string
|
||||
MTU uint32
|
||||
Address []netip.Prefix
|
||||
AllowedAddress []netip.Prefix
|
||||
}
|
||||
|
||||
func NewDevice(options DeviceOptions) (Device, error) {
|
||||
|
||||
@@ -42,6 +42,7 @@ type stackDevice struct {
|
||||
inet4Address netip.Addr
|
||||
inet6Address netip.Addr
|
||||
icmpForwarder *tun.ICMPForwarder
|
||||
udpForwarder *tun.UDPForwarder
|
||||
}
|
||||
|
||||
func newStackDevice(options DeviceOptions) (*stackDevice, error) {
|
||||
@@ -79,7 +80,16 @@ func newStackDevice(options DeviceOptions) (*stackDevice, error) {
|
||||
tunDevice.stack = ipStack
|
||||
if options.Handler != nil {
|
||||
ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, tun.NewTCPForwarder(options.Context, ipStack, options.Handler).HandlePacket)
|
||||
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, tun.NewUDPForwarder(options.Context, ipStack, options.Handler, options.UDPTimeout).HandlePacket)
|
||||
udpForwarder := tun.NewUDPForwarder(options.Context, ipStack, options.Handler, tun.UDPNatOptions{
|
||||
Timeout: options.UDPTimeout,
|
||||
Shared: true,
|
||||
Mapping: options.UDPMapping,
|
||||
Filtering: options.UDPFiltering,
|
||||
MaxSize: options.UDPNATMax,
|
||||
InterfaceFinder: options.InterfaceFinder,
|
||||
})
|
||||
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket)
|
||||
tunDevice.udpForwarder = udpForwarder
|
||||
icmpForwarder := tun.NewICMPForwarder(ipStack, options.Handler, options.Logger)
|
||||
ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber4, icmpForwarder.HandlePacket)
|
||||
ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber6, icmpForwarder.HandlePacket)
|
||||
@@ -166,6 +176,12 @@ func (w *stackDevice) SetDevice(device *device.Device) {
|
||||
}
|
||||
|
||||
func (w *stackDevice) Start() error {
|
||||
if w.udpForwarder != nil {
|
||||
err := w.udpForwarder.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.events <- wgTun.EventUp
|
||||
return nil
|
||||
}
|
||||
@@ -245,6 +261,9 @@ func (w *stackDevice) Close() error {
|
||||
if w.icmpForwarder != nil {
|
||||
w.icmpForwarder.Close()
|
||||
}
|
||||
if w.udpForwarder != nil {
|
||||
_ = w.udpForwarder.Close()
|
||||
}
|
||||
w.stack.Close()
|
||||
for _, endpoint := range w.stack.CleanupEndpoints() {
|
||||
endpoint.Abort()
|
||||
|
||||
@@ -27,6 +27,7 @@ type systemStackDevice struct {
|
||||
stack *stack.Stack
|
||||
endpoint *deviceEndpoint
|
||||
icmpForwarder *tun.ICMPForwarder
|
||||
udpForwarder *tun.UDPForwarder
|
||||
writeBufs [][]byte
|
||||
closeOnce sync.Once
|
||||
}
|
||||
@@ -69,7 +70,17 @@ func newSystemStackDevice(options DeviceOptions) (*systemStackDevice, error) {
|
||||
}
|
||||
if options.Handler != nil {
|
||||
ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, tun.NewTCPForwarder(options.Context, ipStack, options.Handler).HandlePacket)
|
||||
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, tun.NewUDPForwarder(options.Context, ipStack, options.Handler, options.UDPTimeout).HandlePacket)
|
||||
udpForwarder := tun.NewUDPForwarder(options.Context, ipStack, options.Handler, tun.UDPNatOptions{
|
||||
Timeout: options.UDPTimeout,
|
||||
Shared: true,
|
||||
Mapping: options.UDPMapping,
|
||||
Filtering: options.UDPFiltering,
|
||||
MaxSize: options.UDPNATMax,
|
||||
InterfaceFinder: options.InterfaceFinder,
|
||||
ExcludeInterface: []string{options.Name},
|
||||
})
|
||||
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket)
|
||||
stackDevice.udpForwarder = udpForwarder
|
||||
icmpForwarder := tun.NewICMPForwarder(ipStack, options.Handler, options.Logger)
|
||||
ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber4, icmpForwarder.HandlePacket)
|
||||
ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber6, icmpForwarder.HandlePacket)
|
||||
@@ -82,6 +93,20 @@ func (w *systemStackDevice) SetDevice(device *device.Device) {
|
||||
w.endpoint.device = device
|
||||
}
|
||||
|
||||
func (w *systemStackDevice) Start() error {
|
||||
if w.udpForwarder != nil {
|
||||
err := w.udpForwarder.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err := w.systemDevice.Start()
|
||||
if err != nil && w.udpForwarder != nil {
|
||||
_ = w.udpForwarder.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *systemStackDevice) Write(bufs [][]byte, offset int) (count int, err error) {
|
||||
if w.batchDevice != nil {
|
||||
w.writeBufs = w.writeBufs[:0]
|
||||
@@ -118,6 +143,9 @@ func (w *systemStackDevice) Close() error {
|
||||
if w.icmpForwarder != nil {
|
||||
w.icmpForwarder.Close()
|
||||
}
|
||||
if w.udpForwarder != nil {
|
||||
_ = w.udpForwarder.Close()
|
||||
}
|
||||
w.stack.Close()
|
||||
for _, endpoint := range w.stack.CleanupEndpoints() {
|
||||
endpoint.Abort()
|
||||
|
||||
@@ -101,17 +101,21 @@ func NewEndpoint(options EndpointOptions) (*Endpoint, error) {
|
||||
options.MTU = 1408
|
||||
}
|
||||
deviceOptions := DeviceOptions{
|
||||
Context: options.Context,
|
||||
Logger: options.Logger,
|
||||
System: options.System,
|
||||
Handler: options.Handler,
|
||||
UDPTimeout: options.UDPTimeout,
|
||||
ICMPTimeout: options.ICMPTimeout,
|
||||
CreateDialer: options.CreateDialer,
|
||||
Name: options.Name,
|
||||
MTU: options.MTU,
|
||||
Address: options.Address,
|
||||
AllowedAddress: allowedAddresses,
|
||||
Context: options.Context,
|
||||
Logger: options.Logger,
|
||||
System: options.System,
|
||||
Handler: options.Handler,
|
||||
UDPTimeout: options.UDPTimeout,
|
||||
ICMPTimeout: options.ICMPTimeout,
|
||||
UDPMapping: options.UDPMapping,
|
||||
UDPFiltering: options.UDPFiltering,
|
||||
UDPNATMax: options.UDPNATMax,
|
||||
InterfaceFinder: options.InterfaceFinder,
|
||||
CreateDialer: options.CreateDialer,
|
||||
Name: options.Name,
|
||||
MTU: options.MTU,
|
||||
Address: options.Address,
|
||||
AllowedAddress: allowedAddresses,
|
||||
}
|
||||
tunDevice, err := NewDevice(deviceOptions)
|
||||
if err != nil {
|
||||
@@ -231,8 +235,9 @@ func (e *Endpoint) Close() error {
|
||||
e.device.Down()
|
||||
e.device.Close()
|
||||
e.device = nil
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
return e.tunDevice.Close()
|
||||
}
|
||||
|
||||
func (e *Endpoint) Lookup(address netip.Addr) *device.Peer {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-tun"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
@@ -18,16 +19,21 @@ type EndpointOptions struct {
|
||||
Handler tun.Handler
|
||||
UDPTimeout time.Duration
|
||||
ICMPTimeout time.Duration
|
||||
Dialer N.Dialer
|
||||
CreateDialer func(interfaceName string) N.Dialer
|
||||
Name string
|
||||
MTU uint32
|
||||
Address []netip.Prefix
|
||||
PrivateKey string
|
||||
ListenPort uint16
|
||||
ResolvePeer func(domain string) (netip.Addr, error)
|
||||
Peers []PeerOptions
|
||||
Workers int
|
||||
UDPMapping tun.NATMapping
|
||||
UDPFiltering tun.NATFiltering
|
||||
UDPNATMax uint32
|
||||
|
||||
InterfaceFinder control.InterfaceFinder
|
||||
Dialer N.Dialer
|
||||
CreateDialer func(interfaceName string) N.Dialer
|
||||
Name string
|
||||
MTU uint32
|
||||
Address []netip.Prefix
|
||||
PrivateKey string
|
||||
ListenPort uint16
|
||||
ResolvePeer func(domain string) (netip.Addr, error)
|
||||
Peers []PeerOptions
|
||||
Workers int
|
||||
}
|
||||
|
||||
type PeerOptions struct {
|
||||
|
||||
Reference in New Issue
Block a user