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,
"sniff": false,
"sniff_override_destination": false,
"sniff_override_fallback": false,
"sniff_timeout": "300ms",
"domain_strategy": "prefer_ipv6",
"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.
#### 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
Timeout for sniffing.

View File

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

View File

@ -112,6 +112,7 @@ func (h *Inbound) UnmarshalJSON(bytes []byte) error {
type InboundOptions struct {
SniffEnabled bool `json:"sniff,omitempty"`
SniffOverrideDestination bool `json:"sniff_override_destination,omitempty"`
SniffOverrideFallback bool `json:"sniff_override_fallback,omitempty"`
SniffTimeout Duration `json:"sniff_timeout,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.Domain = sniffMetadata.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{
Fqdn: metadata.Domain,
Port: metadata.Destination.Port,
@ -676,11 +679,15 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
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 {
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), " "), "]")
}
}
ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForConnection)
if err != nil {
return err
@ -784,11 +791,15 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
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 {
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), " "), "]")
}
}
ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForPacketConnection)
if err != nil {
return err