Feat/split tunneling - #244
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
pappz
left a comment
There was a problem hiding this comment.
In pruneUninstalled(), call save() instead of persist() (or call serviceAccessor.applySplitTunneling() after a successful persist), so a prune that changes the effective resolution is applied to the live tunnel.
pappz
left a comment
There was a problem hiding this comment.
Synchronize access to tunCreator (one lock shared by queueTUNRenewal and onDestroy), or create the thread eagerly in onCreate and only post messages afterwards.
User toggles an app in the split-tunneling screen at the same moment the Go engine reports a route change, before any TUN renewal has ever been queued: both threads see tunCreator == null, both create and start a TUNCreatorLooperThread. One is orphaned and never quit, and the tunnel can be rebuilt twice back to back. Or a route change lands while onDestroy is tearing down, the Go thread passes the null check, onDestroy sets the field to null, the Go thread dereferences it and crashes the process.
Adds a split tunnelling screen with three modes: off, exclude the picked apps, or include only them. The two selections are stored apart, since Android's builder takes an allow list or a deny list but never both. A change forces a TUN rebuild, so it applies without reconnecting.
Moves the mode and both app selections out of SharedPreferences and into the profile's preferences on the Go side, so they follow the active profile instead of being shared by every profile on the device. SplitTunnelConfig is unchanged and still owns the VpnService rules: allow list against deny list, the historic exclusions, and the fallback when an include selection is empty. The new SplitTunnelStore only translates between it and the Go settings, and resolves the active profile. Needs the matching submodule change.
The submodule bump also carries the split tunnel store the previous commit needed.
00c7252 to
94a679f
Compare
Let the user choose which apps the tunnel carries
What
Adds a split tunnelling screen under Settings, letting the user decide which
applications the tunnel carries. Three modes:
Until now
IFace.createTunkept four applications out of the tunnel with no wayfor the user to add their own. Those four remain the floor of Exclude, so
turning split tunnelling on never silently pulls them back in.
How
Android's
VpnService.Buildertakes an allow list or a deny list, never both onthe same builder, so the two selections are stored apart and a mode says which
one is live.
SplitTunnelConfigholds that decision — plain Java, no Androidtypes, so the rules are covered by JVM unit tests.
A change to the selection leaves routes and search domains untouched, which the
existing
recreateTUNguard reads as "nothing to do". The renewal request nowcarries a force flag so the rebuild that applies the new filter actually runs,
and the change takes hold without asking the user to reconnect.
Two rules are worth calling out:
carries nothing and reads as broken rather than configured. It falls back to
carrying everything, and the screen says so.
through
protectSocket, but the built-in SSH client has to reach peersthrough it.
The app list resolves the launcher intent rather than asking for
QUERY_ALL_PACKAGES, which Play treats as a sensitive permission. The trade-offis that applications without a launcher entry are not listed.
Tests
SplitTunnelConfigUnitTest— 11 JVM tests covering mode resolution, the emptyallowlist fallback, self-inclusion, and defensive copying of the stored sets.
PreferencesInstrumentedTest— 4 new cases for persistence, including keepingthe inactive selection across a mode change.
Verified by hand on an API 30 emulator with the tunnel up, watching the filter
follow the mode (
disallow 4→disallow 5→allow 2) and the tunnel rebuildon every change without a reconnection.
Screenshots
Note for reviewers
The branch also carries
Implement the ConnectionListener state callback, keptas a separate commit. The netbird bump in
1b7f067addedOnStateChangedto theinterface without the Java side following, which leaves the branch unable to
compile. Drop that commit if it lands upstream first.