mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 08:31:30 +00:00
Add sniff_timeout
This commit is contained in:
parent
39c141651a
commit
7f816a2ebc
|
@ -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{}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue