Skip to content

Commit 3cc77c7

Browse files
committed
support set tun stack
1 parent bb2c528 commit 3cc77c7

File tree

10 files changed

+46
-8
lines changed

10 files changed

+46
-8
lines changed

core/src/main/cpp/main.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,18 +111,20 @@ Java_com_github_kr328_clash_core_bridge_Bridge_nativeNotifyInstalledAppChanged(J
111111
JNIEXPORT void JNICALL
112112
Java_com_github_kr328_clash_core_bridge_Bridge_nativeStartTun(JNIEnv *env, jobject thiz,
113113
jint fd,
114+
jstring stack,
114115
jstring gateway,
115116
jstring portal,
116117
jstring dns,
117118
jobject cb) {
118119
TRACE_METHOD();
119120

121+
scoped_string _stack = get_string(stack);
120122
scoped_string _gateway = get_string(gateway);
121123
scoped_string _portal = get_string(portal);
122124
scoped_string _dns = get_string(dns);
123125
jobject _interface = new_global(cb);
124126

125-
startTun(fd, _gateway, _portal, _dns, _interface);
127+
startTun(fd, _stack, _gateway, _portal, _dns, _interface);
126128
}
127129

128130
JNIEXPORT void JNICALL

core/src/main/golang/native/tun.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (t *remoteTun) close() {
6464
}
6565

6666
//export startTun
67-
func startTun(fd C.int, gateway, portal, dns C.c_string, callback unsafe.Pointer) C.int {
67+
func startTun(fd C.int, stack, gateway, portal, dns C.c_string, callback unsafe.Pointer) C.int {
6868
rTunLock.Lock()
6969
defer rTunLock.Unlock()
7070

@@ -74,6 +74,7 @@ func startTun(fd C.int, gateway, portal, dns C.c_string, callback unsafe.Pointer
7474
}
7575

7676
f := int(fd)
77+
s := C.GoString(stack)
7778
g := C.GoString(gateway)
7879
p := C.GoString(portal)
7980
d := C.GoString(dns)
@@ -82,7 +83,7 @@ func startTun(fd C.int, gateway, portal, dns C.c_string, callback unsafe.Pointer
8283

8384
app.ApplyTunContext(remote.markSocket, remote.querySocketUid)
8485

85-
closer, err := tun.Start(f, g, p, d)
86+
closer, err := tun.Start(f, s, g, p, d)
8687
if err != nil {
8788
remote.close()
8889

core/src/main/golang/native/tun/tun.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@ import (
1414
"github.com/metacubex/mihomo/tunnel"
1515
)
1616

17-
func Start(fd int, gateway, portal, dns string) (io.Closer, error) {
18-
log.Debugln("TUN: fd = %d, gateway = %s, portal = %s, dns = %s", fd, gateway, portal, dns)
17+
func Start(fd int, stack, gateway, portal, dns string) (io.Closer, error) {
18+
log.Debugln("TUN: fd = %d, stack = %s, gateway = %s, portal = %s, dns = %s", fd, stack, gateway, portal, dns)
19+
20+
tunStack, ok := C.StackTypeMapping[strings.ToLower(stack)]
21+
if !ok {
22+
tunStack = C.TunSystem
23+
}
1924

2025
var prefix4 []netip.Prefix
2126
var prefix6 []netip.Prefix
@@ -49,7 +54,7 @@ func Start(fd int, gateway, portal, dns string) (io.Closer, error) {
4954
options := LC.Tun{
5055
Enable: true,
5156
Device: sing_tun.InterfaceName,
52-
Stack: C.TunSystem,
57+
Stack: tunStack,
5358
DNSHijack: dnsHijack,
5459
Inet4Address: prefix4,
5560
Inet6Address: prefix6,

core/src/main/java/com/github/kr328/clash/core/Clash.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,14 @@ object Clash {
6464

6565
fun startTun(
6666
fd: Int,
67+
stack: String,
6768
gateway: String,
6869
portal: String,
6970
dns: String,
7071
markSocket: (Int) -> Boolean,
7172
querySocketUid: (protocol: Int, source: InetSocketAddress, target: InetSocketAddress) -> Int
7273
) {
73-
Bridge.nativeStartTun(fd, gateway, portal, dns, object : TunInterface {
74+
Bridge.nativeStartTun(fd, stack, gateway, portal, dns, object : TunInterface {
7475
override fun markSocket(fd: Int) {
7576
markSocket(fd)
7677
}

core/src/main/java/com/github/kr328/clash/core/bridge/Bridge.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object Bridge {
1919
external fun nativeNotifyDnsChanged(dnsList: String)
2020
external fun nativeNotifyTimeZoneChanged(name: String, offset: Int)
2121
external fun nativeNotifyInstalledAppChanged(uidList: String)
22-
external fun nativeStartTun(fd: Int, gateway: String, portal: String, dns: String, cb: TunInterface)
22+
external fun nativeStartTun(fd: Int, stack: String, gateway: String, portal: String, dns: String, cb: TunInterface)
2323
external fun nativeStopTun()
2424
external fun nativeStartHttp(listenAt: String): String?
2525
external fun nativeStopHttp()

design/src/main/java/com/github/kr328/clash/design/NetworkSettingsDesign.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,22 @@ class NetworkSettingsDesign(
9393
)
9494
}
9595

96+
selectableList(
97+
value = srvStore::tunStackMode,
98+
values = arrayOf(
99+
"system",
100+
"gvisor",
101+
"mixed"
102+
),
103+
valuesText = arrayOf(
104+
R.string.tun_stack_system,
105+
R.string.tun_stack_gvisor,
106+
R.string.tun_stack_mixed
107+
),
108+
title = R.string.tun_stack_mode,
109+
configure = vpnDependencies::add,
110+
)
111+
96112
selectableList(
97113
value = srvStore::accessControlMode,
98114
values = AccessControlMode.values(),

design/src/main/res/values/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@
232232
<string name="always_dark">Always Dark</string>
233233
<string name="always_light">Always Light</string>
234234

235+
<string name="tun_stack_mode">Stack Mode</string>
236+
<string name="tun_stack_system">System Stack</string>
237+
<string name="tun_stack_gvisor">Gvisor Stack</string>
238+
<string name="tun_stack_mixed">Mixed Stack</string>
239+
235240
<string name="allow_all_apps">Allow all apps</string>
236241
<string name="allow_selected_apps">Allow selected apps</string>
237242
<string name="deny_selected_apps">Deny selected apps</string>

service/src/main/java/com/github/kr328/clash/service/TunService.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
218218
TunModule.TunDevice(
219219
fd = establish()?.detachFd()
220220
?: throw NullPointerException("Establish VPN rejected by system"),
221+
stack = store.tunStackMode,
221222
gateway = "$TUN_GATEWAY/$TUN_SUBNET_PREFIX" + if (store.allowIpv6) ",$TUN_GATEWAY6/$TUN_SUBNET_PREFIX6" else "",
222223
portal = TUN_PORTAL + if (store.allowIpv6) ",$TUN_PORTAL6" else "",
223224
dns = if (store.dnsHijacking) NET_ANY else (TUN_DNS + if (store.allowIpv6) ",$TUN_DNS6" else ""),

service/src/main/java/com/github/kr328/clash/service/clash/module/TunModule.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import java.security.SecureRandom
1515
class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
1616
data class TunDevice(
1717
val fd: Int,
18+
var stack: String,
1819
val gateway: String,
1920
val portal: String,
2021
val dns: String,
@@ -56,6 +57,7 @@ class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
5657
fun attach(device: TunDevice) {
5758
Clash.startTun(
5859
fd = device.fd,
60+
stack = device.stack,
5961
gateway = device.gateway,
6062
portal = device.portal,
6163
dns = device.dns,

service/src/main/java/com/github/kr328/clash/service/store/ServiceStore.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ class ServiceStore(context: Context) {
5656
defaultValue = false
5757
)
5858

59+
var tunStackMode by store.string(
60+
key = "tun_stack_mode",
61+
defaultValue = "system"
62+
)
63+
5964
var dynamicNotification by store.boolean(
6065
key = "dynamic_notification",
6166
defaultValue = true

0 commit comments

Comments
 (0)