Feat: [app/router] Implement resolution strategy
Currently during routing decision, v2ray will use its internal DNS to resolve domain to IPs. But in transparent proxying, if the IP of a domain is guaranteed to be reliable because of a user-provided DNS (e.g. another v2ray instance only serving as DNS server), it would be better to use the original IP from request to resolve the domain, instead of taking the trouble to lookup again.
Based on idea above, a new settings resolveStrategy is proposed for router. It contains following options:
- UseDNS (default): Resolve IP with internal DNS Only.
- UseOrigin: Resolve IP to its original destination, if available.
- PreferOrigin: Resolve IP to its original destination first, and fallback to internal DNS if not available. This option is for those inbound connections from HTTP proxy.
- Disabled: Do not try to resolve IP. This rule effectively disables IP lookup during routing decision.
A problem is that after sniffing the domain, the outbound destination gets overriden to the domain string, and the original IP is lost. This PR records the original destination in session.Context if destOverride occurs to solve the problem.
This PR also reorganizes logic in default dispatcher to render them more readable.
Codecov Report
Base: 38.88% // Head: 38.81% // Decreases project coverage by -0.07% :warning:
Coverage data is based on head (
7171deb) compared to base (2e0ea88). Patch coverage: 32.58% of modified lines in pull request are covered.
:exclamation: Current head 7171deb differs from pull request most recent head 775a64b. Consider uploading reports for the commit 775a64b to get more accurate results
Additional details and impacted files
@@ Coverage Diff @@
## master #1973 +/- ##
==========================================
- Coverage 38.88% 38.81% -0.08%
==========================================
Files 616 609 -7
Lines 36336 36139 -197
==========================================
- Hits 14128 14026 -102
+ Misses 20630 20555 -75
+ Partials 1578 1558 -20
| Impacted Files | Coverage Δ | |
|---|---|---|
| common/session/session.go | 70.58% <ø> (ø) |
|
| features/routing/session/context_origindest.go | 0.00% <0.00%> (ø) |
|
| app/router/config.pb.go | 12.86% <5.26%> (-0.44%) |
:arrow_down: |
| infra/conf/synthetic/router/router.go | 64.64% <37.50%> (-5.24%) |
:arrow_down: |
| app/dispatcher/default.go | 29.71% <39.13%> (+0.30%) |
:arrow_up: |
| app/router/router.go | 28.93% <56.52%> (+1.34%) |
:arrow_up: |
| app/proxyman/outbound/errors.generated.go | 0.00% <0.00%> (-100.00%) |
:arrow_down: |
| transport/internet/domainsocket/config.go | 52.63% <0.00%> (-10.53%) |
:arrow_down: |
| common/task/task.go | 88.88% <0.00%> (-7.41%) |
:arrow_down: |
| testing/servers/tcp/tcp.go | 81.81% <0.00%> (-5.46%) |
:arrow_down: |
| ... and 19 more |
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.
:umbrella: View full report at Codecov.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.
Considering the fakedns case, converting it to draft.
Any chance to incorporate the logic of #1271? In transparent proxy case, that can keep original ip as the destination and prevent overridding the destination with a fake domain (like Tor).
@dyhkwong Thanks for mentioning the issue. Assume that the "destination" is the address sent to remote server for dialing, do you mean that the destination to send should not be replaced by tor's fake domain (I am not familiar with tor), but keep the original IP (so the domain is used for routing only)?
For reference, this PR currently does not alter the behavior of destination overriding, even though the original IP is used for routing, the outbound will still send the overridden domain.
Regards the SkippedDomains option in linked PR https://github.com/Shadowsocks-NET/v2ray-go/pull/19, does the case for dispatching with tor is: if the domain matches certain domain rules, use the original ip as outbound destination?
I decide to extend the router to achieve both goals in this PR (how to derive the target IP) and @dyhkwong desires (controlling the destination to use). Following new settings will be introduced:
ipStrategy
There are three ways to interpret what is "Target IP":
- Origin: By directly using the IP destination in the packet.
- DNS: By resolving the domain if present in context.
- Fake IP: By using the fake IP identified by FakeDNS engine.
Select some of above three ways and combine them in order results in an ipStrategy:
["dns"]: The default. Use DNS to resolve IP if destination is a domain.["origin"]: Same asUseOriginin this PR.["origin", "dns"]: Same asPreferOriginin this PR.["fake"]: Use this in a specific rule will make"ip"field in this rule matching the Fake IP. Suitable when different fake IP range has different meaning (e.g. bound to differnt set of domains).
outboundSettings
We can alter the behavior of chosen outbound through the routing result:
"destination": we can alter the final destination to use."mark": we can alter the socket mark to use for this connection.
Possible values for "destination" option:
["ip"]: Use target IP as the final destination. Suitable for tor. So we could match the tor domains and specify destination to use IP here.["domain"]: Use target domain as the final destination. Suitable for fake IP and scenarios that need resolve the domain again.["ip:<ip>"]: Force override the destination to use the ip address.["domain:<domain>"]: Force override the destination to use the domain.- Not specified: do not alter, use the original destination.
Both ipStrategy and outboundSettings could be set at router and rule scope, to provide global or rule-specific strategy.
It has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days