mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2024-11-16 11:42:43 +08:00
fix: sing listener panic
This commit is contained in:
parent
1cf9a55e3e
commit
270a080b55
|
@ -4,12 +4,11 @@ import (
|
|||
"net"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/context"
|
||||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
)
|
||||
|
||||
// NewHTTP receive normal http request and return HTTPContext
|
||||
func NewHTTP(target socks5.Addr, source net.Addr, conn net.Conn, additions ...Addition) *context.ConnContext {
|
||||
func NewHTTP(target socks5.Addr, source net.Addr, conn net.Conn, additions ...Addition) (net.Conn, *C.Metadata) {
|
||||
metadata := parseSocksAddr(target)
|
||||
metadata.NetWork = C.TCP
|
||||
metadata.Type = C.HTTP
|
||||
|
@ -17,5 +16,5 @@ func NewHTTP(target socks5.Addr, source net.Addr, conn net.Conn, additions ...Ad
|
|||
for _, addition := range additions {
|
||||
addition.Apply(metadata)
|
||||
}
|
||||
return context.NewConnContext(conn, metadata)
|
||||
return conn, metadata
|
||||
}
|
||||
|
|
|
@ -5,16 +5,15 @@ import (
|
|||
"net/http"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/context"
|
||||
)
|
||||
|
||||
// NewHTTPS receive CONNECT request and return ConnContext
|
||||
func NewHTTPS(request *http.Request, conn net.Conn, additions ...Addition) *context.ConnContext {
|
||||
func NewHTTPS(request *http.Request, conn net.Conn, additions ...Addition) (net.Conn, *C.Metadata) {
|
||||
metadata := parseHTTPAddr(request)
|
||||
metadata.Type = C.HTTPS
|
||||
additions = append(additions, WithSrcAddr(conn.RemoteAddr()), WithInAddr(conn.LocalAddr()))
|
||||
for _, addition := range additions {
|
||||
addition.Apply(metadata)
|
||||
}
|
||||
return context.NewConnContext(conn, metadata)
|
||||
return conn, metadata
|
||||
}
|
||||
|
|
|
@ -5,19 +5,8 @@ import (
|
|||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
)
|
||||
|
||||
// PacketAdapter is a UDP Packet adapter for socks/redir/tun
|
||||
type PacketAdapter struct {
|
||||
C.UDPPacket
|
||||
metadata *C.Metadata
|
||||
}
|
||||
|
||||
// Metadata returns destination metadata
|
||||
func (s *PacketAdapter) Metadata() *C.Metadata {
|
||||
return s.metadata
|
||||
}
|
||||
|
||||
// NewPacket is PacketAdapter generator
|
||||
func NewPacket(target socks5.Addr, packet C.UDPPacket, source C.Type, additions ...Addition) C.PacketAdapter {
|
||||
func NewPacket(target socks5.Addr, packet C.UDPPacket, source C.Type, additions ...Addition) (C.UDPPacket, *C.Metadata) {
|
||||
metadata := parseSocksAddr(target)
|
||||
metadata.NetWork = C.UDP
|
||||
metadata.Type = source
|
||||
|
@ -29,8 +18,5 @@ func NewPacket(target socks5.Addr, packet C.UDPPacket, source C.Type, additions
|
|||
addition.Apply(metadata)
|
||||
}
|
||||
|
||||
return &PacketAdapter{
|
||||
packet,
|
||||
metadata,
|
||||
}
|
||||
return packet, metadata
|
||||
}
|
||||
|
|
|
@ -6,12 +6,11 @@ import (
|
|||
"strconv"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/context"
|
||||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
)
|
||||
|
||||
// NewSocket receive TCP inbound and return ConnContext
|
||||
func NewSocket(target socks5.Addr, conn net.Conn, source C.Type, additions ...Addition) *context.ConnContext {
|
||||
func NewSocket(target socks5.Addr, conn net.Conn, source C.Type, additions ...Addition) (net.Conn, *C.Metadata) {
|
||||
metadata := parseSocksAddr(target)
|
||||
metadata.NetWork = C.TCP
|
||||
metadata.Type = source
|
||||
|
@ -20,10 +19,10 @@ func NewSocket(target socks5.Addr, conn net.Conn, source C.Type, additions ...Ad
|
|||
addition.Apply(metadata)
|
||||
}
|
||||
|
||||
return context.NewConnContext(conn, metadata)
|
||||
return conn, metadata
|
||||
}
|
||||
|
||||
func NewInner(conn net.Conn, address string) *context.ConnContext {
|
||||
func NewInner(conn net.Conn, address string) (net.Conn, *C.Metadata) {
|
||||
metadata := &C.Metadata{}
|
||||
metadata.NetWork = C.TCP
|
||||
metadata.Type = C.INNER
|
||||
|
@ -40,5 +39,5 @@ func NewInner(conn net.Conn, address string) *context.ConnContext {
|
|||
}
|
||||
}
|
||||
|
||||
return context.NewConnContext(conn, metadata)
|
||||
return conn, metadata
|
||||
}
|
||||
|
|
|
@ -252,6 +252,23 @@ type PacketAdapter interface {
|
|||
Metadata() *Metadata
|
||||
}
|
||||
|
||||
type packetAdapter struct {
|
||||
UDPPacket
|
||||
metadata *Metadata
|
||||
}
|
||||
|
||||
// Metadata returns destination metadata
|
||||
func (s *packetAdapter) Metadata() *Metadata {
|
||||
return s.metadata
|
||||
}
|
||||
|
||||
func NewPacketAdapter(packet UDPPacket, metadata *Metadata) PacketAdapter {
|
||||
return &packetAdapter{
|
||||
packet,
|
||||
metadata,
|
||||
}
|
||||
}
|
||||
|
||||
type WriteBack interface {
|
||||
WriteBack(b []byte, addr net.Addr) (n int, err error)
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package constant
|
||||
|
||||
import "net"
|
||||
|
||||
type Tunnel interface {
|
||||
// HandleTCPConn will handle a tcp connection blocking
|
||||
HandleTCPConn(connCtx ConnContext)
|
||||
HandleTCPConn(conn net.Conn, metadata *Metadata)
|
||||
// HandleUDPPacket will handle a udp packet nonblocking
|
||||
HandleUDPPacket(packet PacketAdapter)
|
||||
HandleUDPPacket(packet UDPPacket, metadata *Metadata)
|
||||
// NatTable return nat table
|
||||
NatTable() NatTable
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -53,13 +53,15 @@ type tunnel struct{}
|
|||
|
||||
var Tunnel C.Tunnel = tunnel{}
|
||||
|
||||
func (t tunnel) HandleTCPConn(connCtx C.ConnContext) {
|
||||
func (t tunnel) HandleTCPConn(conn net.Conn, metadata *C.Metadata) {
|
||||
connCtx := icontext.NewConnContext(conn, metadata)
|
||||
handleTCPConn(connCtx)
|
||||
}
|
||||
|
||||
func (t tunnel) HandleUDPPacket(packet C.PacketAdapter) {
|
||||
func (t tunnel) HandleUDPPacket(packet C.UDPPacket, metadata *C.Metadata) {
|
||||
packetAdapter := C.NewPacketAdapter(packet, metadata)
|
||||
select {
|
||||
case udpQueue <- packet:
|
||||
case udpQueue <- packetAdapter:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +276,7 @@ func preHandleMetadata(metadata *C.Metadata) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func resolveMetadata(ctx C.PlainContext, metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err error) {
|
||||
func resolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err error) {
|
||||
if metadata.SpecialProxy != "" {
|
||||
var exist bool
|
||||
proxy, exist = proxies[metadata.SpecialProxy]
|
||||
|
@ -369,7 +371,7 @@ func handleUDPConn(packet C.PacketAdapter) {
|
|||
}()
|
||||
|
||||
pCtx := icontext.NewPacketConnContext(metadata)
|
||||
proxy, rule, err := resolveMetadata(pCtx, metadata)
|
||||
proxy, rule, err := resolveMetadata(metadata)
|
||||
if err != nil {
|
||||
log.Warnln("[UDP] Parse metadata failed: %s", err.Error())
|
||||
return
|
||||
|
@ -477,7 +479,7 @@ func handleTCPConn(connCtx C.ConnContext) {
|
|||
}()
|
||||
}
|
||||
|
||||
proxy, rule, err := resolveMetadata(connCtx, metadata)
|
||||
proxy, rule, err := resolveMetadata(metadata)
|
||||
if err != nil {
|
||||
log.Warnln("[Metadata] parse failed: %s", err.Error())
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue
Block a user