feat: sniff_override_fallback

This commit is contained in:
zakuwaki 2023-07-26 22:38:31 +08:00
parent 8d629ef323
commit 8915050469
4 changed files with 32 additions and 6 deletions

View File

@ -8,6 +8,7 @@
"udp_fragment": false, "udp_fragment": false,
"sniff": false, "sniff": false,
"sniff_override_destination": false, "sniff_override_destination": false,
"sniff_override_fallback": false,
"sniff_timeout": "300ms", "sniff_timeout": "300ms",
"domain_strategy": "prefer_ipv6", "domain_strategy": "prefer_ipv6",
"udp_timeout": 300, "udp_timeout": 300,
@ -58,6 +59,12 @@ Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work. If the domain name is invalid (like tor), this will not work.
#### sniff_override_fallback
If the sniffed domain fails to be resolved when `sniff_override_destination` is enabled, use the original destination address as fallback.
Helpful when using customized domain.
#### sniff_timeout #### sniff_timeout
Timeout for sniffing. Timeout for sniffing.

View File

@ -8,6 +8,7 @@
"udp_fragment": false, "udp_fragment": false,
"sniff": false, "sniff": false,
"sniff_override_destination": false, "sniff_override_destination": false,
"sniff_override_fallback": false,
"sniff_timeout": "300ms", "sniff_timeout": "300ms",
"domain_strategy": "prefer_ipv6", "domain_strategy": "prefer_ipv6",
"udp_timeout": 300, "udp_timeout": 300,
@ -59,6 +60,12 @@
如果域名无效(如 Tor将不生效。 如果域名无效(如 Tor将不生效。
#### sniff_override_fallback
`sniff_override_destination` 开启且探测出的域名解析失败时,回退使用原连接目标地址。
当使用自定义域名时有帮助。
#### sniff_timeout #### sniff_timeout
探测超时时间。 探测超时时间。

View File

@ -112,6 +112,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"`
SniffOverrideFallback bool `json:"sniff_override_fallback,omitempty"`
SniffTimeout Duration `json:"sniff_timeout,omitempty"` SniffTimeout Duration `json:"sniff_timeout,omitempty"`
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"` DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
} }

View File

@ -645,6 +645,9 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
metadata.Protocol = sniffMetadata.Protocol metadata.Protocol = sniffMetadata.Protocol
metadata.Domain = sniffMetadata.Domain metadata.Domain = sniffMetadata.Domain
if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) { if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) {
if metadata.InboundOptions.SniffOverrideFallback && metadata.Destination.Addr.IsValid() {
metadata.DestinationAddresses = []netip.Addr{metadata.Destination.Addr}
}
metadata.Destination = M.Socksaddr{ metadata.Destination = M.Socksaddr{
Fqdn: metadata.Domain, Fqdn: metadata.Domain,
Port: metadata.Destination.Port, Port: metadata.Destination.Port,
@ -676,10 +679,14 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.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, dns.DomainStrategy(metadata.InboundOptions.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 if len(metadata.DestinationAddresses) == 0 {
return err
}
r.logger.WarnContext(ctx, "using original destination [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]")
} else {
metadata.DestinationAddresses = addresses
r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]")
} }
metadata.DestinationAddresses = addresses
r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]")
} }
ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForConnection) ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForConnection)
if err != nil { if err != nil {
@ -784,10 +791,14 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.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, dns.DomainStrategy(metadata.InboundOptions.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 if len(metadata.DestinationAddresses) == 0 {
return err
}
r.logger.WarnContext(ctx, "using original destination [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]")
} else {
metadata.DestinationAddresses = addresses
r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]")
} }
metadata.DestinationAddresses = addresses
r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]")
} }
ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForPacketConnection) ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForPacketConnection)
if err != nil { if err != nil {