Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion core/src/main/cpp/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ Java_com_github_kr328_clash_core_bridge_Bridge_nativeStartTun(JNIEnv *env, jobje
jstring gateway,
jstring portal,
jstring dns,
jboolean disable_icmp_forwarding,
jint icmp_timeout,
jobject cb) {
TRACE_METHOD();

Expand All @@ -125,7 +127,7 @@ Java_com_github_kr328_clash_core_bridge_Bridge_nativeStartTun(JNIEnv *env, jobje
scoped_string _dns = get_string(dns);
jobject _interface = new_global(cb);

startTun(fd, _stack, _gateway, _portal, _dns, _interface);
startTun(fd, _stack, _gateway, _portal, _dns, (int) disable_icmp_forwarding, (int) icmp_timeout, _interface);
}

JNIEXPORT void JNICALL
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/golang/native/tun.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (t *remoteTun) close() {
}

//export startTun
func startTun(fd C.int, stack, gateway, portal, dns C.c_string, callback unsafe.Pointer) C.int {
func startTun(fd C.int, stack, gateway, portal, dns C.c_string, disableICMPForwarding C.int, icmpTimeout C.int, callback unsafe.Pointer) C.int {
rTunLock.Lock()
defer rTunLock.Unlock()

Expand All @@ -83,7 +83,7 @@ func startTun(fd C.int, stack, gateway, portal, dns C.c_string, callback unsafe.

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

closer, err := tun.Start(f, s, g, p, d)
closer, err := tun.Start(f, s, g, p, d, disableICMPForwarding != 0, int64(icmpTimeout))
if err != nil {
remote.close()

Expand Down
24 changes: 13 additions & 11 deletions core/src/main/golang/native/tun/tun.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/metacubex/mihomo/tunnel"
)

func Start(fd int, stack, gateway, portal, dns string) (io.Closer, error) {
func Start(fd int, stack, gateway, portal, dns string, disableICMPForwarding bool, icmpTimeout int64) (io.Closer, error) {
log.Debugln("TUN: fd = %d, stack = %s, gateway = %s, portal = %s, dns = %s", fd, stack, gateway, portal, dns)

tunStack, ok := C.StackTypeMapping[strings.ToLower(stack)]
Expand Down Expand Up @@ -52,16 +52,18 @@ func Start(fd int, stack, gateway, portal, dns string) (io.Closer, error) {
}

options := LC.Tun{
Enable: true,
Device: sing_tun.InterfaceName,
Stack: tunStack,
DNSHijack: dnsHijack,
AutoRoute: false, // had set route in TunService.kt
AutoDetectInterface: false, // implements by VpnService::protect
Inet4Address: prefix4,
Inet6Address: prefix6,
MTU: 9000, // private const val TUN_MTU = 9000 in TunService.kt
FileDescriptor: fd,
Enable: true,
Device: sing_tun.InterfaceName,
Stack: tunStack,
DNSHijack: dnsHijack,
AutoRoute: false, // had set route in TunService.kt
AutoDetectInterface: false, // implements by VpnService::protect
Inet4Address: prefix4,
Inet6Address: prefix6,
MTU: 9000, // private const val TUN_MTU = 9000 in TunService.kt
FileDescriptor: fd,
DisableICMPForwarding: disableICMPForwarding,
ICMPTimeout: icmpTimeout,
}

tunOptions, _ := json.Marshal(options)
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/com/github/kr328/clash/core/Clash.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,12 @@ object Clash {
gateway: String,
portal: String,
dns: String,
disableIcmpForwarding: Boolean,
icmpTimeout: Int,
markSocket: (Int) -> Boolean,
querySocketUid: (protocol: Int, source: InetSocketAddress, target: InetSocketAddress) -> Int
) {
Bridge.nativeStartTun(fd, stack, gateway, portal, dns, object : TunInterface {
Bridge.nativeStartTun(fd, stack, gateway, portal, dns, disableIcmpForwarding, icmpTimeout, object : TunInterface {
override fun markSocket(fd: Int) {
markSocket(fd)
}
Expand Down
11 changes: 10 additions & 1 deletion core/src/main/java/com/github/kr328/clash/core/bridge/Bridge.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@ object Bridge {
external fun nativeNotifyDnsChanged(dnsList: String)
external fun nativeNotifyTimeZoneChanged(name: String, offset: Int)
external fun nativeNotifyInstalledAppChanged(uidList: String)
external fun nativeStartTun(fd: Int, stack: String, gateway: String, portal: String, dns: String, cb: TunInterface)
external fun nativeStartTun(
fd: Int,
stack: String,
gateway: String,
portal: String,
dns: String,
disableIcmpForwarding: Boolean,
icmpTimeout: Int,
cb: TunInterface
)
external fun nativeStopTun()
external fun nativeStartHttp(listenAt: String): String?
external fun nativeStopHttp()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,21 @@ class NetworkSettingsDesign(
configure = vpnDependencies::add,
)

switch(
value = srvStore::disableIcmpForwarding,
title = R.string.disable_icmp_forwarding,
summary = R.string.disable_icmp_forwarding_summary,
configure = vpnDependencies::add,
)

editableText(
value = srvStore::icmpTimeout,
adapter = NullableTextAdapter.Int,
title = R.string.icmp_timeout,
empty = R.string.icmp_timeout_default,
configure = vpnDependencies::add,
)

switch(
value = srvStore::allowBypass,
title = R.string.allow_bypass,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ interface NullableTextAdapter<T> {
}
}

val Int = object : NullableTextAdapter<Int> {
override fun from(value: Int): String? {
return if (value > 0) value.toString() else ""
}

override fun to(text: String?): Int {
return text?.trim()?.toIntOrNull()?.coerceAtLeast(0) ?: 0
}
}

val String = object : NullableTextAdapter<String?> {
override fun from(value: String?): String? {
return value
Expand Down
4 changes: 4 additions & 0 deletions design/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@
<string name="bypass_private_network_summary">Bypass private network addresses</string>
<string name="dns_hijacking">DNS Hijacking</string>
<string name="dns_hijacking_summary">Handle all dns packet</string>
<string name="disable_icmp_forwarding">Disable ICMP Forwarding</string>
<string name="disable_icmp_forwarding_summary">Reply ICMP echo requests locally instead of forwarding them</string>
<string name="icmp_timeout">ICMP Timeout (seconds)</string>
<string name="icmp_timeout_default">Default</string>
<string name="block_loopback">Block Loopback</string>
<string name="block_loopback_summary">Block loopback connections</string>
<string name="allow_bypass">Allow Bypass</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
gateway = "$TUN_GATEWAY/$TUN_SUBNET_PREFIX" + if (store.allowIpv6) ",$TUN_GATEWAY6/$TUN_SUBNET_PREFIX6" else "",
portal = TUN_PORTAL + if (store.allowIpv6) ",$TUN_PORTAL6" else "",
dns = if (store.dnsHijacking) NET_ANY else (TUN_DNS + if (store.allowIpv6) ",$TUN_DNS6" else ""),
disableIcmpForwarding = store.disableIcmpForwarding,
icmpTimeout = store.icmpTimeout,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
val gateway: String,
val portal: String,
val dns: String,
val disableIcmpForwarding: Boolean,
val icmpTimeout: Int,
)

private val connectivity = service.getSystemService<ConnectivityManager>()!!
Expand Down Expand Up @@ -61,6 +63,8 @@ class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
gateway = device.gateway,
portal = device.portal,
dns = device.dns,
disableIcmpForwarding = device.disableIcmpForwarding,
icmpTimeout = device.icmpTimeout,
markSocket = vpn::protect,
querySocketUid = this::queryUid
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ class ServiceStore(context: Context) {
defaultValue = "system"
)

var disableIcmpForwarding by store.boolean(
key = "disable_icmp_forwarding",
defaultValue = true
)

var icmpTimeout by store.int(
key = "icmp_timeout",
defaultValue = 0
)

var dynamicNotification by store.boolean(
key = "dynamic_notification",
defaultValue = true
Expand Down