Update network handler usages

This commit is contained in:
世界 2024-10-20 13:42:53 +08:00
parent a8ae222eeb
commit 99eea00432
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
12 changed files with 51 additions and 78 deletions

View file

@ -4,7 +4,6 @@ import (
"sync"
"github.com/sagernet/sing-tun/internal/winipcfg"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
"github.com/sagernet/sing/common/x/list"
@ -14,7 +13,6 @@ import (
type networkUpdateMonitor struct {
routeListener *winipcfg.RouteChangeCallback
interfaceListener *winipcfg.InterfaceChangeCallback
errorHandler E.Handler
access sync.Mutex
callbacks list.List[NetworkUpdateCallback]

View file

@ -5,6 +5,7 @@ import (
"github.com/sagernet/sing/common/control"
"github.com/sagernet/sing/common/logger"
N "github.com/sagernet/sing/common/network"
"go4.org/netipx"
)
@ -23,7 +24,7 @@ type AutoRedirect interface {
type AutoRedirectOptions struct {
TunOptions *Options
Context context.Context
Handler Handler
Handler N.TCPConnectionHandlerEx
Logger logger.Logger
NetworkMonitor NetworkUpdateMonitor
InterfaceFinder control.InterfaceFinder

View file

@ -13,6 +13,7 @@ import (
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/x/list"
"go4.org/netipx"
@ -21,7 +22,7 @@ import (
type autoRedirect struct {
tunOptions *Options
ctx context.Context
handler Handler
handler N.TCPConnectionHandlerEx
logger logger.Logger
tableName string
networkMonitor NetworkUpdateMonitor

View file

@ -14,20 +14,19 @@ import (
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
const ProtocolRedirect = "redirect"
type redirectServer struct {
ctx context.Context
handler Handler
handler N.TCPConnectionHandlerEx
logger logger.Logger
listenAddr netip.Addr
listener *net.TCPListener
inShutdown atomic.Bool
}
func newRedirectServer(ctx context.Context, handler Handler, logger logger.Logger, listenAddr netip.Addr) *redirectServer {
func newRedirectServer(ctx context.Context, handler N.TCPConnectionHandlerEx, logger logger.Logger, listenAddr netip.Addr) *redirectServer {
return &redirectServer{
ctx: ctx,
handler: handler,
@ -59,7 +58,6 @@ func (s *redirectServer) loopIn() {
conn, err := s.listener.AcceptTCP()
if err != nil {
var netError net.Error
//goland:noinspection GoDeprecation
//nolint:staticcheck
if errors.As(err, &netError) && netError.Temporary() {
s.logger.Error(err)
@ -72,17 +70,14 @@ func (s *redirectServer) loopIn() {
s.logger.Error("serve error: ", err)
continue
}
var metadata M.Metadata
metadata.Protocol = ProtocolRedirect
metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
source := M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
destination, err := control.GetOriginalDestination(conn)
if err != nil {
_ = conn.SetLinger(0)
_ = conn.Close()
s.logger.Error("process connection from ", metadata.Source, ": invalid connection: ", err)
s.logger.Error("process redirect connection from ", source, ": invalid connection: ", err)
continue
}
metadata.Destination = M.SocksaddrFromNetIP(destination).Unwrap()
go s.handler.NewConnection(s.ctx, conn, metadata)
go s.handler.NewConnectionEx(s.ctx, conn, source, M.SocksaddrFromNetIP(destination).Unwrap(), nil)
}
}

View file

@ -11,6 +11,8 @@ import (
"github.com/sagernet/sing/common/logger"
)
var ErrDrop = E.New("drop connections by rule")
type Stack interface {
Start() error
Close() error

View file

@ -76,17 +76,16 @@ func (t *GVisor) Start() error {
return err
}
tcpForwarder := tcp.NewForwarder(ipStack, 0, 1024, func(r *tcp.ForwarderRequest) {
var metadata M.Metadata
metadata.Source = M.SocksaddrFrom(AddrFromAddress(r.ID().RemoteAddress), r.ID().RemotePort)
metadata.Destination = M.SocksaddrFrom(AddrFromAddress(r.ID().LocalAddress), r.ID().LocalPort)
source := M.SocksaddrFrom(AddrFromAddress(r.ID().RemoteAddress), r.ID().RemotePort)
destination := M.SocksaddrFrom(AddrFromAddress(r.ID().LocalAddress), r.ID().LocalPort)
conn := &gLazyConn{
parentCtx: t.ctx,
stack: t.stack,
request: r,
localAddr: metadata.Source.TCPAddr(),
remoteAddr: metadata.Destination.TCPAddr(),
localAddr: source.TCPAddr(),
remoteAddr: destination.TCPAddr(),
}
_ = t.handler.NewConnection(t.ctx, conn, metadata)
go t.handler.NewConnectionEx(t.ctx, conn, source, destination, nil)
})
ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)
if !t.endpointIndependentNat {
@ -104,14 +103,10 @@ func (t *GVisor) Start() error {
return
}
go func() {
var metadata M.Metadata
metadata.Source = M.SocksaddrFromNet(lAddr)
metadata.Destination = M.SocksaddrFromNet(rAddr)
ctx, conn := canceler.NewPacketConn(t.ctx, bufio.NewUnbindPacketConnWithAddr(udpConn, metadata.Destination), time.Duration(t.udpTimeout)*time.Second)
hErr := t.handler.NewPacketConnection(ctx, conn, metadata)
if hErr != nil {
endpoint.Abort()
}
source := M.SocksaddrFromNet(lAddr)
destination := M.SocksaddrFromNet(rAddr)
ctx, conn := canceler.NewPacketConn(t.ctx, bufio.NewUnbindPacketConnWithAddr(udpConn, destination), time.Duration(t.udpTimeout)*time.Second)
t.handler.NewPacketConnectionEx(ctx, conn, source, destination, nil)
}()
})
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket)

View file

@ -71,8 +71,7 @@ func (c *gLazyConn) HandshakeFailure(err error) error {
if c.handshakeDone {
return nil
}
wErr := gWriteUnreachable(c.stack, c.request.Packet(), err)
c.request.Complete(wErr == os.ErrInvalid)
c.request.Complete(gWriteUnreachable(c.stack, c.request.Packet(), err) == os.ErrInvalid)
c.handshakeDone = true
c.handshakeErr = err
return nil
@ -196,9 +195,11 @@ func (c *gLazyConn) Upstream() any {
}
func gWriteUnreachable(gStack *stack.Stack, packet *stack.PacketBuffer, err error) error {
if errors.Is(err, syscall.ENETUNREACH) {
if errors.Is(err, ErrDrop) {
return nil
} else if errors.Is(err, syscall.ENETUNREACH) {
if packet.NetworkProtocolNumber == header.IPv4ProtocolNumber {
return gWriteUnreachable4(gStack, packet, stack.RejectIPv4WithICMPPortUnreachable)
return gWriteUnreachable4(gStack, packet, stack.RejectIPv4WithICMPNetProhibited)
} else {
return gWriteUnreachable6(gStack, packet, stack.RejectIPv6WithICMPNoRoute)
}

View file

@ -36,15 +36,14 @@ func NewUDPForwarder(ctx context.Context, stack *stack.Stack, handler Handler, u
return &UDPForwarder{
ctx: ctx,
stack: stack,
udpNat: udpnat.New[netip.AddrPort](udpTimeout, handler),
udpNat: udpnat.NewEx[netip.AddrPort](udpTimeout, handler),
}
}
func (f *UDPForwarder) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
var upstreamMetadata M.Metadata
upstreamMetadata.Source = M.SocksaddrFrom(AddrFromAddress(id.RemoteAddress), id.RemotePort)
upstreamMetadata.Destination = M.SocksaddrFrom(AddrFromAddress(id.LocalAddress), id.LocalPort)
if upstreamMetadata.Source.IsIPv4() {
source := M.SocksaddrFrom(AddrFromAddress(id.RemoteAddress), id.RemotePort)
destination := M.SocksaddrFrom(AddrFromAddress(id.LocalAddress), id.LocalPort)
if source.IsIPv4() {
f.cacheProto = header.IPv4ProtocolNumber
} else {
f.cacheProto = header.IPv6ProtocolNumber
@ -55,11 +54,12 @@ func (f *UDPForwarder) HandlePacket(id stack.TransportEndpointID, pkt *stack.Pac
sBuffer.Write(view.AsSlice())
})
f.cacheID = id
f.udpNat.NewPacket(
f.udpNat.NewPacketEx(
f.ctx,
upstreamMetadata.Source.AddrPort(),
source.AddrPort(),
sBuffer,
upstreamMetadata,
source,
destination,
f.newUDPConn,
)
return true

View file

@ -64,14 +64,10 @@ func (m *Mixed) Start() error {
return
}
go func() {
var metadata M.Metadata
metadata.Source = M.SocksaddrFromNet(lAddr)
metadata.Destination = M.SocksaddrFromNet(rAddr)
ctx, conn := canceler.NewPacketConn(m.ctx, bufio.NewUnbindPacketConnWithAddr(udpConn, metadata.Destination), time.Duration(m.udpTimeout)*time.Second)
hErr := m.handler.NewPacketConnection(ctx, conn, metadata)
if hErr != nil {
endpoint.Abort()
}
source := M.SocksaddrFromNet(lAddr)
destination := M.SocksaddrFromNet(rAddr)
ctx, conn := canceler.NewPacketConn(m.ctx, bufio.NewUnbindPacketConnWithAddr(udpConn, destination), time.Duration(m.udpTimeout)*time.Second)
m.handler.NewPacketConnectionEx(ctx, conn, source, destination, nil)
}()
})
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket)

View file

@ -152,7 +152,7 @@ func (s *System) start() error {
go s.acceptLoop(tcpListener)
}
s.tcpNat = NewNat(s.ctx, time.Second*time.Duration(s.udpTimeout))
s.udpNat = udpnat.New[netip.AddrPort](s.udpTimeout, s.handler)
s.udpNat = udpnat.NewEx[netip.AddrPort](s.udpTimeout, s.handler)
return nil
}
@ -300,16 +300,7 @@ func (s *System) acceptLoop(listener net.Listener) {
}
}
}
go func() {
_ = s.handler.NewConnection(s.ctx, conn, M.Metadata{
Source: M.SocksaddrFromNetIP(session.Source),
Destination: destination,
})
if tcpConn, isTCPConn := conn.(*net.TCPConn); isTCPConn {
_ = tcpConn.SetLinger(0)
}
_ = conn.Close()
}()
go s.handler.NewConnectionEx(s.ctx, conn, M.SocksaddrFromNet(conn.RemoteAddr()), destination, nil)
}
}
@ -427,11 +418,7 @@ func (s *System) processIPv4UDP(packet clashtcpip.IPv4Packet, header clashtcpip.
if data.Len() == 0 {
return nil
}
metadata := M.Metadata{
Source: M.SocksaddrFromNetIP(source),
Destination: M.SocksaddrFromNetIP(destination),
}
s.udpNat.NewPacket(s.ctx, source, data.ToOwned(), metadata, func(natConn N.PacketConn) N.PacketWriter {
s.udpNat.NewPacketEx(s.ctx, source, data.ToOwned(), M.SocksaddrFromNetIP(source), M.SocksaddrFromNetIP(destination), func(natConn N.PacketConn) N.PacketWriter {
headerLen := packet.HeaderLen() + clashtcpip.UDPHeaderSize
headerCopy := make([]byte, headerLen)
copy(headerCopy, packet[:headerLen])
@ -459,11 +446,7 @@ func (s *System) processIPv6UDP(packet clashtcpip.IPv6Packet, header clashtcpip.
if data.Len() == 0 {
return nil
}
metadata := M.Metadata{
Source: M.SocksaddrFromNetIP(source),
Destination: M.SocksaddrFromNetIP(destination),
}
s.udpNat.NewPacket(s.ctx, source, data.ToOwned(), metadata, func(natConn N.PacketConn) N.PacketWriter {
s.udpNat.NewPacketEx(s.ctx, source, data.ToOwned(), M.SocksaddrFromNetIP(source), M.SocksaddrFromNetIP(destination), func(natConn N.PacketConn) N.PacketWriter {
headerLen := len(packet) - int(header.Length()) + clashtcpip.UDPHeaderSize
headerCopy := make([]byte, headerLen)
copy(headerCopy, packet[:headerLen])

6
tun.go
View file

@ -8,7 +8,6 @@ import (
"strconv"
"strings"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/logger"
N "github.com/sagernet/sing/common/network"
@ -16,9 +15,8 @@ import (
)
type Handler interface {
N.TCPConnectionHandler
N.UDPConnectionHandler
E.Handler
N.TCPConnectionHandlerEx
N.UDPConnectionHandlerEx
}
type Tun interface {

View file

@ -1,7 +1,6 @@
package tun
import (
"context"
"net/netip"
"os"
"runtime"
@ -20,7 +19,7 @@ const (
userEnd uint32 = 0xFFFFFFFF - 1
)
func (o *Options) BuildAndroidRules(packageManager PackageManager, errorHandler E.Handler) {
func (o *Options) BuildAndroidRules(packageManager PackageManager) {
var includeUser []uint32
if len(o.IncludeAndroidUser) > 0 {
o.IncludeAndroidUser = common.Uniq(o.IncludeAndroidUser)
@ -64,7 +63,9 @@ func (o *Options) BuildAndroidRules(packageManager PackageManager, errorHandler
}
continue
}
errorHandler.NewError(context.Background(), E.New("package to include not found: ", packageName))
if o.Logger != nil {
o.Logger.Debug("package to include not found: ", packageName)
}
}
}
if len(o.ExcludePackage) > 0 {
@ -81,7 +82,9 @@ func (o *Options) BuildAndroidRules(packageManager PackageManager, errorHandler
}
continue
}
errorHandler.NewError(context.Background(), E.New("package to exclude not found: ", packageName))
if o.Logger != nil {
o.Logger.Debug("package to exclude not found: ", packageName)
}
}
}
}