fix: sing listener panic

This commit is contained in:
wwqgtxx
2023-10-11 10:55:12 +08:00
parent 1cf9a55e3e
commit 270a080b55
14 changed files with 91 additions and 67 deletions

View File

@ -20,7 +20,6 @@ func HandleTcp(address string) (conn net.Conn, err error) {
}
// executor Parsed
conn1, conn2 := net.Pipe()
context := inbound.NewInner(conn2, address)
go tunnel.HandleTCPConn(context)
go tunnel.HandleTCPConn(inbound.NewInner(conn2, address))
return conn1, nil
}

View File

@ -67,7 +67,7 @@ func handleSocksUDP(pc net.PacketConn, tunnel C.Tunnel, buf []byte, put func(),
}
return
}
target := socks5.ParseAddr(tgtAddr.String())
target := tgtAddr
payload := buf[len(tgtAddr):]
packet := &packet{

View File

@ -26,7 +26,7 @@ func getAdditions(ctx context.Context) []inbound.Addition {
return nil
}
func combineAdditions(ctx context.Context, additions []inbound.Addition) []inbound.Addition {
func combineAdditions(ctx context.Context, additions []inbound.Addition, extraAdditions ...inbound.Addition) []inbound.Addition {
additionsCloned := false
if ctxAdditions := getAdditions(ctx); len(ctxAdditions) > 0 {
additions = slices.Clone(additions)
@ -40,5 +40,12 @@ func combineAdditions(ctx context.Context, additions []inbound.Addition) []inbou
}
additions = append(additions, inbound.WithInUser(user))
}
if len(extraAdditions) > 0 {
if !additionsCloned {
additions = slices.Clone(additions)
additionsCloned = true
}
additions = append(additions, extraAdditions...)
}
return additions
}

View File

@ -12,7 +12,6 @@ import (
N "github.com/Dreamacro/clash/common/net"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
"github.com/Dreamacro/clash/transport/socks5"
vmess "github.com/metacubex/sing-vmess"
mux "github.com/sagernet/sing-mux"
@ -85,15 +84,26 @@ func (h *ListenerHandler) NewConnection(ctx context.Context, conn net.Conn, meta
if h.IsSpecialFqdn(metadata.Destination.Fqdn) {
return h.ParseSpecialFqdn(ctx, conn, metadata)
}
target := socks5.ParseAddr(metadata.Destination.String())
if deadline.NeedAdditionalReadDeadline(conn) {
conn = N.NewDeadlineConn(conn) // conn from sing should check NeedAdditionalReadDeadline
}
connCtx := inbound.NewSocket(target, conn, h.Type, combineAdditions(ctx, h.Additions)...)
inbound.WithSrcAddr(metadata.Source.TCPAddr()).Apply(connCtx.Metadata()) // set srcAddr from sing's metadata
h.Tunnel.HandleTCPConn(connCtx) // this goroutine must exit after conn unused
cMetadata := &C.Metadata{
NetWork: C.TCP,
Type: h.Type,
Host: metadata.Destination.Fqdn,
DstIP: metadata.Destination.Addr,
DstPort: metadata.Destination.Port,
SrcIP: metadata.Source.Addr,
SrcPort: metadata.Source.Port,
}
additions := combineAdditions(ctx, h.Additions, inbound.WithInAddr(conn.LocalAddr()))
for _, addition := range additions {
addition.Apply(cMetadata)
}
h.Tunnel.HandleTCPConn(conn, cMetadata) // this goroutine must exit after conn unused
return nil
}
@ -138,8 +148,7 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
}
return err
}
target := socks5.ParseAddr(dest.String())
packet := &packet{
cPacket := &packet{
conn: &conn2,
mutex: &mutex,
rAddr: metadata.Source.UDPAddr(),
@ -147,7 +156,21 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
buff: buff,
}
h.Tunnel.HandleUDPPacket(inbound.NewPacket(target, packet, h.Type, combineAdditions(ctx, h.Additions)...))
cMetadata := &C.Metadata{
NetWork: C.UDP,
Type: h.Type,
Host: dest.Fqdn,
DstIP: dest.Addr,
DstPort: dest.Port,
SrcIP: metadata.Source.Addr,
SrcPort: metadata.Source.Port,
}
additions := combineAdditions(ctx, h.Additions, inbound.WithInAddr(conn.LocalAddr()))
for _, addition := range additions {
addition.Apply(cMetadata)
}
h.Tunnel.HandleUDPPacket(cPacket, cMetadata)
}
return nil
}
@ -215,11 +238,3 @@ func (c *packet) Drop() {
func (c *packet) InAddr() net.Addr {
return c.lAddr
}
func (c *packet) SetNatTable(natTable C.NatTable) {
// no need
}
func (c *packet) SetUdpInChan(in chan<- C.PacketAdapter) {
// no need
}

View File

@ -94,19 +94,18 @@ func New(config LC.TuicServer, tunnel C.Tunnel, additions ...inbound.Addition) (
newAdditions = slices.Clone(additions)
newAdditions = append(newAdditions, _additions...)
}
connCtx := inbound.NewSocket(addr, conn, C.TUIC, newAdditions...)
metadata := sing.ConvertMetadata(connCtx.Metadata())
if h.IsSpecialFqdn(metadata.Destination.Fqdn) {
conn, metadata := inbound.NewSocket(addr, conn, C.TUIC, newAdditions...)
if h.IsSpecialFqdn(metadata.Host) {
go func() { // ParseSpecialFqdn will block, so open a new goroutine
_ = h.ParseSpecialFqdn(
sing.WithAdditions(context.Background(), newAdditions...),
conn,
metadata,
sing.ConvertMetadata(metadata),
)
}()
return nil
}
go tunnel.HandleTCPConn(connCtx)
go tunnel.HandleTCPConn(conn, metadata)
return nil
}
handleUdpFn := func(addr socks5.Addr, packet C.UDPPacket, _additions ...inbound.Addition) error {

View File

@ -36,9 +36,9 @@ func (l *Listener) Close() error {
func (l *Listener) handleTCP(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) {
N.TCPKeepAlive(conn)
ctx := inbound.NewSocket(l.target, conn, C.TUNNEL, additions...)
ctx.Metadata().SpecialProxy = l.proxy
tunnel.HandleTCPConn(ctx)
conn, metadata := inbound.NewSocket(l.target, conn, C.TUNNEL, additions...)
metadata.SpecialProxy = l.proxy
tunnel.HandleTCPConn(conn, metadata)
}
func New(addr, target, proxy string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) {

View File

@ -70,13 +70,13 @@ func NewUDP(addr, target, proxy string, tunnel C.Tunnel, additions ...inbound.Ad
}
func (l *PacketConn) handleUDP(pc net.PacketConn, tunnel C.Tunnel, buf []byte, addr net.Addr, additions ...inbound.Addition) {
packet := &packet{
cPacket := &packet{
pc: pc,
rAddr: addr,
payload: buf,
}
ctx := inbound.NewPacket(l.target, packet, C.TUNNEL, additions...)
ctx.Metadata().SpecialProxy = l.proxy
tunnel.HandleUDPPacket(ctx)
packet, metadata := inbound.NewPacket(l.target, cPacket, C.TUNNEL, additions...)
metadata.SpecialProxy = l.proxy
tunnel.HandleUDPPacket(packet, metadata)
}