shared-tun: preserve member ownership on mobile

Introduce shared NIC source ownership and dispatcher handling so a
single dev_name can be shared by multiple tun-enabled instances while
keeping per-member IP and route claims distinct.

Pass Android VpnService fd registration with per-instance source and
route claims. Keep the VPN address list limited to real member
addresses and allow AF_INET6 without installing hidden fd00::1.

Invalidate dispatcher flow and NAT state when source ownership changes
or a member unregisters. Avoid rewriting non-first IPv4 fragment
payloads, and adjust fragmented TCP/UDP checksums without recomputing
over partial fragment bodies.

Preserve source-owner routing for equal-prefix route conflicts, keep
ICMP echo NAT entries distinct by echo id, and retry stale flow-owner
send failures from the original packet. Only record NAT state after a
translated packet is accepted by its member.

Apply Linux IPv4 route preferred-source hints for shared routes and keep
route repair paths source-aware. Keep Darwin ifcfg access scoped to
cleanup-only paths where netns is not available.
This commit is contained in:
sijie.sun
2026-06-16 02:16:25 +08:00
parent ca17e856a6
commit 800c840bb5
13 changed files with 2423 additions and 175 deletions
+18 -3
View File
@@ -70,8 +70,23 @@ export async function setLoggingLevel(level: string) {
return await invoke('set_logging_level', { level })
}
export async function setTunFd(fd: number) {
return await invoke('set_tun_fd', { fd })
export interface TunFdInstanceSources {
instanceId: string
ipv4Addrs: string[]
ipv6Addrs?: string[]
ipv4Routes?: string[]
ipv6Routes?: string[]
}
export async function setTunFd(fd: number, instanceIds?: string[], instanceSources?: TunFdInstanceSources[]) {
const args: { fd: number, instanceIds?: string[], instanceSources?: TunFdInstanceSources[] } = { fd }
if (instanceIds?.length) {
args.instanceIds = instanceIds
}
if (instanceSources?.length) {
args.instanceSources = instanceSources
}
return await invoke('set_tun_fd', args)
}
export async function getEasytierVersion() {
@@ -110,7 +125,7 @@ export async function sendConfigs(enabledNetworks: string[]) {
config: NetworkTypes.toBackendNetworkConfig(config),
source,
})),
enabledNetworks
enabledNetworks,
})
}