Add sniff_timeout

This commit is contained in:
世界 2022-10-07 20:30:27 +08:00
parent 39c141651a
commit 7f816a2ebc
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
9 changed files with 33 additions and 51 deletions

View file

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

View file

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

View file

@ -9,7 +9,6 @@ import (
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata" 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.Inbound = a.tag
metadata.InboundType = a.protocol metadata.InboundType = a.protocol
metadata.InboundDetour = a.listenOptions.Detour metadata.InboundDetour = a.listenOptions.Detour
metadata.SniffEnabled = a.listenOptions.SniffEnabled metadata.InboundOptions = a.listenOptions.InboundOptions
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
if !metadata.Source.IsValid() { if !metadata.Source.IsValid() {
metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap() metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
} }

View file

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

View file

@ -15,7 +15,6 @@ import (
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/hysteria" "github.com/sagernet/sing-box/transport/hysteria"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata" 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 var metadata adapter.InboundContext
metadata.Inbound = h.tag metadata.Inbound = h.tag
metadata.InboundType = C.TypeHysteria metadata.InboundType = C.TypeHysteria
metadata.SniffEnabled = h.listenOptions.SniffEnabled metadata.InboundOptions = h.listenOptions.InboundOptions
metadata.SniffOverrideDestination = h.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(h.listenOptions.DomainStrategy)
metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap() metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap() metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
metadata.Destination = M.ParseSocksaddrHostPort(request.Host, request.Port).Unwrap() metadata.Destination = M.ParseSocksaddrHostPort(request.Host, request.Port).Unwrap()

View file

@ -12,7 +12,6 @@ import (
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing-tun" "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions" 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.InboundType = C.TypeTun
metadata.Source = upstreamMetadata.Source metadata.Source = upstreamMetadata.Source
metadata.Destination = upstreamMetadata.Destination metadata.Destination = upstreamMetadata.Destination
metadata.SniffEnabled = t.inboundOptions.SniffEnabled metadata.InboundOptions = t.inboundOptions
metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source) t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination) t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
err := t.router.RouteConnection(ctx, conn, metadata) 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.InboundType = C.TypeTun
metadata.Source = upstreamMetadata.Source metadata.Source = upstreamMetadata.Source
metadata.Destination = upstreamMetadata.Destination metadata.Destination = upstreamMetadata.Destination
metadata.SniffEnabled = t.inboundOptions.SniffEnabled metadata.InboundOptions = t.inboundOptions
metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source) t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination) t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
err := t.router.RoutePacketConnection(ctx, conn, metadata) err := t.router.RoutePacketConnection(ctx, conn, metadata)

View file

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

View file

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

View file

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