From 7f816a2ebc51478edb11274b92da9a16ae275cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Fri, 7 Oct 2022 20:30:27 +0800 Subject: [PATCH] Add sniff_timeout --- adapter/inbound.go | 20 +++++++++----------- common/sniff/sniff.go | 7 +++++-- inbound/default.go | 5 +---- inbound/default_udp.go | 17 ++++------------- inbound/hysteria.go | 5 +---- inbound/tun.go | 9 ++------- option/inbound.go | 1 + outbound/direct.go | 2 +- route/router.go | 18 +++++++++--------- 9 files changed, 33 insertions(+), 51 deletions(-) diff --git a/adapter/inbound.go b/adapter/inbound.go index 1b4affbb..d07d2810 100644 --- a/adapter/inbound.go +++ b/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{} diff --git a/common/sniff/sniff.go b/common/sniff/sniff.go index f2fdb1e0..5a39d900 100644 --- a/common/sniff/sniff.go +++ b/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 } diff --git a/inbound/default.go b/inbound/default.go index b45b5543..9a827519 100644 --- a/inbound/default.go +++ b/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() } diff --git a/inbound/default_udp.go b/inbound/default_udp.go index 3436311a..55a8462d 100644 --- a/inbound/default_udp.go +++ b/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) diff --git a/inbound/hysteria.go b/inbound/hysteria.go index 55ba8937..5beab69a 100644 --- a/inbound/hysteria.go +++ b/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() diff --git a/inbound/tun.go b/inbound/tun.go index 7cabd960..bf908f3e 100644 --- a/inbound/tun.go +++ b/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) diff --git a/option/inbound.go b/option/inbound.go index 6145bced..e717c7ba 100644 --- a/option/inbound.go +++ b/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"` } diff --git a/outbound/direct.go b/outbound/direct.go index 71989d6f..b252a771 100644 --- a/outbound/direct.go +++ b/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 { diff --git a/route/router.go b/route/router.go index d575f4e6..e51085b3 100644 --- a/route/router.go +++ b/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 }