fix(route): empty site list now means a full tunnel, not all-direct — DIRECT_ALL no longer leaves the proxy carrying nothing
This commit is contained in:
parent
f2b234341d
commit
55dada7772
2 changed files with 19 additions and 0 deletions
|
|
@ -101,6 +101,11 @@ enum class RouteDecision { PROXY, DIRECT }
|
|||
* - [RoutingMode.PROXY_ALL]: everything proxied; matched sites go DIRECT.
|
||||
* - [RoutingMode.DIRECT_ALL]: everything direct; matched sites go through the PROXY.
|
||||
*
|
||||
* With **no rules at all** the split is inert and everything is proxied (a full tunnel) —
|
||||
* this deliberately overrides DIRECT_ALL, whose literal "everything direct" would otherwise
|
||||
* leave a connected proxy carrying nothing while the user still sees a green "proxy confirmed".
|
||||
* The split only takes effect once there is at least one site to match against.
|
||||
*
|
||||
* Only domain destinations can match — IP-literal / IPv6 / non-DNS flows have no domain
|
||||
* to test, so they always take the global default (the documented coverage gap).
|
||||
*/
|
||||
|
|
@ -109,6 +114,8 @@ class SiteRouter(
|
|||
private val matcher: SiteMatcher,
|
||||
) {
|
||||
fun decide(host: String, isDomain: Boolean): RouteDecision {
|
||||
// No rules ⇒ full tunnel, never the degenerate all-direct of an empty DIRECT_ALL.
|
||||
if (matcher.isEmpty) return RouteDecision.PROXY
|
||||
val matched = isDomain && matcher.matches(host)
|
||||
return when (mode) {
|
||||
RoutingMode.PROXY_ALL -> if (matched) RouteDecision.DIRECT else RouteDecision.PROXY
|
||||
|
|
|
|||
|
|
@ -107,6 +107,18 @@ class SiteRoutingTest {
|
|||
assertEquals(RouteDecision.DIRECT, r.decide("93.184.216.34", isDomain = false))
|
||||
}
|
||||
|
||||
@Test fun directAll_emptyList_fallsBackToFullTunnel() {
|
||||
// The footgun guard: DIRECT_ALL with no rules must NOT send everything direct (a
|
||||
// connected proxy carrying nothing). With no rules the split is inert = full tunnel.
|
||||
val r = SiteRouter(RoutingMode.DIRECT_ALL, SiteMatcher.EMPTY)
|
||||
assertFalse(r.hasRules)
|
||||
assertEquals(RouteDecision.PROXY, r.decide("anything.com", isDomain = true))
|
||||
assertEquals(RouteDecision.PROXY, r.decide("93.184.216.34", isDomain = false))
|
||||
// Same via build() with no entries.
|
||||
val b = SiteRouter.build(RoutingMode.DIRECT_ALL, emptySet(), GeositeSource.EMPTY)
|
||||
assertEquals(RouteDecision.PROXY, b.decide("anything.com", isDomain = true))
|
||||
}
|
||||
|
||||
// --- SiteRouter.build (entries -> rules) ---
|
||||
|
||||
@Test fun build_mixesPlainAndGeositeEntries() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue