1
0
世界 3 жил өмнө
parent
commit
7f816a2ebc

+ 9 - 11
adapter/inbound.go

@@ -6,7 +6,7 @@ import (
 	"net/netip"
 
 	"github.com/sagernet/sing-box/common/process"
-	"github.com/sagernet/sing-dns"
+	"github.com/sagernet/sing-box/option"
 	M "github.com/sagernet/sing/common/metadata"
 	N "github.com/sagernet/sing/common/network"
 )
@@ -38,16 +38,14 @@ type InboundContext struct {
 
 	// cache
 
-	InboundDetour            string
-	LastInbound              string
-	OriginDestination        M.Socksaddr
-	DomainStrategy           dns.DomainStrategy
-	SniffEnabled             bool
-	SniffOverrideDestination bool
-	DestinationAddresses     []netip.Addr
-	SourceGeoIPCode          string
-	GeoIPCode                string
-	ProcessInfo              *process.Info
+	InboundDetour        string
+	LastInbound          string
+	OriginDestination    M.Socksaddr
+	InboundOptions       option.InboundOptions
+	DestinationAddresses []netip.Addr
+	SourceGeoIPCode      string
+	GeoIPCode            string
+	ProcessInfo          *process.Info
 }
 
 type inboundContextKey struct{}

+ 5 - 2
common/sniff/sniff.go

@@ -19,8 +19,11 @@ type (
 	PacketSniffer = func(ctx context.Context, packet []byte) (*adapter.InboundContext, error)
 )
 
-func PeekStream(ctx context.Context, conn net.Conn, buffer *buf.Buffer, sniffers ...StreamSniffer) (*adapter.InboundContext, error) {
-	err := conn.SetReadDeadline(time.Now().Add(C.ReadPayloadTimeout))
+func PeekStream(ctx context.Context, conn net.Conn, buffer *buf.Buffer, timeout time.Duration, sniffers ...StreamSniffer) (*adapter.InboundContext, error) {
+	if timeout == 0 {
+		timeout = C.ReadPayloadTimeout
+	}
+	err := conn.SetReadDeadline(time.Now().Add(timeout))
 	if err != nil {
 		return nil, err
 	}

+ 1 - 4
inbound/default.go

@@ -9,7 +9,6 @@ import (
 	C "github.com/sagernet/sing-box/constant"
 	"github.com/sagernet/sing-box/log"
 	"github.com/sagernet/sing-box/option"
-	"github.com/sagernet/sing-dns"
 	"github.com/sagernet/sing/common"
 	E "github.com/sagernet/sing/common/exceptions"
 	M "github.com/sagernet/sing/common/metadata"
@@ -137,9 +136,7 @@ func (a *myInboundAdapter) createMetadata(conn net.Conn, metadata adapter.Inboun
 	metadata.Inbound = a.tag
 	metadata.InboundType = a.protocol
 	metadata.InboundDetour = a.listenOptions.Detour
-	metadata.SniffEnabled = a.listenOptions.SniffEnabled
-	metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
-	metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
+	metadata.InboundOptions = a.listenOptions.InboundOptions
 	if !metadata.Source.IsValid() {
 		metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
 	}

+ 4 - 13
inbound/default_udp.go

@@ -7,7 +7,6 @@ import (
 	"time"
 
 	"github.com/sagernet/sing-box/adapter"
-	"github.com/sagernet/sing-dns"
 	"github.com/sagernet/sing/common"
 	"github.com/sagernet/sing/common/buf"
 	"github.com/sagernet/sing/common/control"
@@ -51,9 +50,7 @@ func (a *myInboundAdapter) loopUDPIn() {
 		var metadata adapter.InboundContext
 		metadata.Inbound = a.tag
 		metadata.InboundType = a.protocol
-		metadata.SniffEnabled = a.listenOptions.SniffEnabled
-		metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
-		metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
+		metadata.InboundOptions = a.listenOptions.InboundOptions
 		metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap()
 		metadata.OriginDestination = a.udpAddr
 		err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
@@ -83,9 +80,7 @@ func (a *myInboundAdapter) loopUDPOOBIn() {
 		var metadata adapter.InboundContext
 		metadata.Inbound = a.tag
 		metadata.InboundType = a.protocol
-		metadata.SniffEnabled = a.listenOptions.SniffEnabled
-		metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
-		metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
+		metadata.InboundOptions = a.listenOptions.InboundOptions
 		metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap()
 		metadata.OriginDestination = a.udpAddr
 		err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
@@ -109,9 +104,7 @@ func (a *myInboundAdapter) loopUDPInThreadSafe() {
 		var metadata adapter.InboundContext
 		metadata.Inbound = a.tag
 		metadata.InboundType = a.protocol
-		metadata.SniffEnabled = a.listenOptions.SniffEnabled
-		metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
-		metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
+		metadata.InboundOptions = a.listenOptions.InboundOptions
 		metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap()
 		metadata.OriginDestination = a.udpAddr
 		err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
@@ -137,9 +130,7 @@ func (a *myInboundAdapter) loopUDPOOBInThreadSafe() {
 		var metadata adapter.InboundContext
 		metadata.Inbound = a.tag
 		metadata.InboundType = a.protocol
-		metadata.SniffEnabled = a.listenOptions.SniffEnabled
-		metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
-		metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
+		metadata.InboundOptions = a.listenOptions.InboundOptions
 		metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap()
 		metadata.OriginDestination = a.udpAddr
 		err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)

+ 1 - 4
inbound/hysteria.go

@@ -15,7 +15,6 @@ import (
 	"github.com/sagernet/sing-box/log"
 	"github.com/sagernet/sing-box/option"
 	"github.com/sagernet/sing-box/transport/hysteria"
-	"github.com/sagernet/sing-dns"
 	"github.com/sagernet/sing/common"
 	E "github.com/sagernet/sing/common/exceptions"
 	M "github.com/sagernet/sing/common/metadata"
@@ -258,9 +257,7 @@ func (h *Hysteria) acceptStream(ctx context.Context, conn quic.Connection, strea
 	var metadata adapter.InboundContext
 	metadata.Inbound = h.tag
 	metadata.InboundType = C.TypeHysteria
-	metadata.SniffEnabled = h.listenOptions.SniffEnabled
-	metadata.SniffOverrideDestination = h.listenOptions.SniffOverrideDestination
-	metadata.DomainStrategy = dns.DomainStrategy(h.listenOptions.DomainStrategy)
+	metadata.InboundOptions = h.listenOptions.InboundOptions
 	metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
 	metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
 	metadata.Destination = M.ParseSocksaddrHostPort(request.Host, request.Port).Unwrap()

+ 2 - 7
inbound/tun.go

@@ -12,7 +12,6 @@ import (
 	C "github.com/sagernet/sing-box/constant"
 	"github.com/sagernet/sing-box/log"
 	"github.com/sagernet/sing-box/option"
-	"github.com/sagernet/sing-dns"
 	"github.com/sagernet/sing-tun"
 	"github.com/sagernet/sing/common"
 	E "github.com/sagernet/sing/common/exceptions"
@@ -181,9 +180,7 @@ func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata
 	metadata.InboundType = C.TypeTun
 	metadata.Source = upstreamMetadata.Source
 	metadata.Destination = upstreamMetadata.Destination
-	metadata.SniffEnabled = t.inboundOptions.SniffEnabled
-	metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
-	metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
+	metadata.InboundOptions = t.inboundOptions
 	t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
 	t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
 	err := t.router.RouteConnection(ctx, conn, metadata)
@@ -203,9 +200,7 @@ func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstre
 	metadata.InboundType = C.TypeTun
 	metadata.Source = upstreamMetadata.Source
 	metadata.Destination = upstreamMetadata.Destination
-	metadata.SniffEnabled = t.inboundOptions.SniffEnabled
-	metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
-	metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
+	metadata.InboundOptions = t.inboundOptions
 	t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
 	t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
 	err := t.router.RoutePacketConnection(ctx, conn, metadata)

+ 1 - 0
option/inbound.go

@@ -107,6 +107,7 @@ func (h *Inbound) UnmarshalJSON(bytes []byte) error {
 type InboundOptions struct {
 	SniffEnabled             bool           `json:"sniff,omitempty"`
 	SniffOverrideDestination bool           `json:"sniff_override_destination,omitempty"`
+	SniffTimeout             Duration       `json:"sniff_timeout,omitempty"`
 	DomainStrategy           DomainStrategy `json:"domain_strategy,omitempty"`
 }
 

+ 1 - 1
outbound/direct.go

@@ -132,7 +132,7 @@ func (h *Direct) DialParallel(ctx context.Context, network string, destination M
 	if h.domainStrategy != dns.DomainStrategyAsIS {
 		domainStrategy = h.domainStrategy
 	} else {
-		domainStrategy = metadata.DomainStrategy
+		domainStrategy = dns.DomainStrategy(metadata.InboundOptions.DomainStrategy)
 	}
 	conn, err := N.DialParallel(ctx, h.dialer, network, destination, destinationAddresses, domainStrategy == dns.DomainStrategyPreferIPv6, h.fallbackDelay)
 	if err != nil {

+ 9 - 9
route/router.go

@@ -552,14 +552,14 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
 		metadata.Destination = M.Socksaddr{}
 		return r.RoutePacketConnection(ctx, uot.NewClientConn(conn), metadata)
 	}
-	if metadata.SniffEnabled {
+	if metadata.InboundOptions.SniffEnabled {
 		buffer := buf.NewPacket()
 		buffer.FullReset()
-		sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost)
+		sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, time.Duration(metadata.InboundOptions.SniffTimeout), sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost)
 		if err == nil {
 			metadata.Protocol = sniffMetadata.Protocol
 			metadata.Domain = sniffMetadata.Domain
-			if metadata.SniffOverrideDestination && M.IsDomainName(metadata.Domain) {
+			if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) {
 				metadata.Destination = M.Socksaddr{
 					Fqdn: metadata.Domain,
 					Port: metadata.Destination.Port,
@@ -577,8 +577,8 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
 			buffer.Release()
 		}
 	}
-	if metadata.Destination.IsFqdn() && metadata.DomainStrategy != dns.DomainStrategyAsIS {
-		addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, metadata.DomainStrategy)
+	if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS {
+		addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy))
 		if err != nil {
 			return err
 		}
@@ -629,7 +629,7 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
 		return nil
 	}
 	metadata.Network = N.NetworkUDP
-	if metadata.SniffEnabled {
+	if metadata.InboundOptions.SniffEnabled {
 		buffer := buf.NewPacket()
 		buffer.FullReset()
 		destination, err := conn.ReadPacket(buffer)
@@ -641,7 +641,7 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
 		if err == nil {
 			metadata.Protocol = sniffMetadata.Protocol
 			metadata.Domain = sniffMetadata.Domain
-			if metadata.SniffOverrideDestination && M.IsDomainName(metadata.Domain) {
+			if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) {
 				metadata.Destination = M.Socksaddr{
 					Fqdn: metadata.Domain,
 					Port: metadata.Destination.Port,
@@ -655,8 +655,8 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
 		}
 		conn = bufio.NewCachedPacketConn(conn, buffer, destination)
 	}
-	if metadata.Destination.IsFqdn() && metadata.Destination.Fqdn != uot.UOTMagicAddress && metadata.DomainStrategy != dns.DomainStrategyAsIS {
-		addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, metadata.DomainStrategy)
+	if metadata.Destination.IsFqdn() && metadata.Destination.Fqdn != uot.UOTMagicAddress && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS {
+		addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy))
 		if err != nil {
 			return err
 		}