Skip to content

Commit

Permalink
feat: Add IPv6 Route
Browse files Browse the repository at this point in the history
  • Loading branch information
arkxfly committed Oct 26, 2023
1 parent c78945a commit 5421407
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ class NetworkSettingsDesign(

category(R.string.vpn_service_options)

switch(
value = srvStore::ipv6Route,
title = R.string.ipv6_route,
summary = R.string.ipv6_route_summary,
configure = vpnDependencies::add,
)

switch(
value = srvStore::bypassPrivateNetwork,
title = R.string.bypass_private_network,
Expand Down
2 changes: 2 additions & 0 deletions design/src/main/res/values-ja-rJP/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
<string name="vpn_service_options">VPNサービスのオプション</string>
<string name="bypass_private_network">プライベートネットワークをバイパスする</string>
<string name="bypass_private_network_summary">プライベートネットワークアドレスをバイパスする</string>
<string name="ipv6_route">IPv6ルート</string>
<string name="ipv6_route_summary">IPv6ルーティングを有効にする</string>
<string name="dns_hijacking">DNSハイジャック</string>
<string name="dns_hijacking_summary">すべてのDNSパケットの処理</string>
<string name="block_loopback">ループバックをブロックする</string>
Expand Down
2 changes: 2 additions & 0 deletions design/src/main/res/values-ko-rKR/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
<string name="vpn_service_options">VPN 서비스 옵션</string>
<string name="bypass_private_network">사설 네트워크 제외</string>
<string name="bypass_private_network_summary">사설 네트워크 주소를 제외합니다.</string>
<string name="ipv6_route">IPv6 경로</string>
<string name="ipv6_route_summary">IPv6 경로 활성화</string>
<string name="dns_hijacking">DNS 하이재킹</string>
<string name="dns_hijacking_summary">모든 DNS 패킷을 포함합니다.</string>
<string name="block_loopback">로컬 루프백 차단</string>
Expand Down
2 changes: 2 additions & 0 deletions design/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
<string name="vpn_service_options">Настройки VPN</string>
<string name="bypass_private_network">Игнорировать частные сети</string>
<string name="bypass_private_network_summary">Игнорировать адреса частных сетей</string>
<string name="ipv6_route">IPv6-маршрутизация</string>
<string name="ipv6_route_summary">Включить маршрутизацию IPv6</string>
<string name="dns_hijacking">Перехват DNS</string>
<string name="dns_hijacking_summary">Обрабатывать все DNS запросы</string>
<string name="block_loopback">Заблокировать loopback</string>
Expand Down
2 changes: 2 additions & 0 deletions design/src/main/res/values-zh-rHK/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<string name="behavior">行為</string>
<string name="bypass_private_network">繞過私有網絡</string>
<string name="bypass_private_network_summary">繞過私有網絡地址</string>
<string name="ipv6_route">IPv6 路由</string>
<string name="ipv6_route_summary">啟用 IPv6 路由</string>
<string name="cancel">取消</string>
<string name="clash_logcat">Clash 日誌捕捉工具</string>
<string name="create_profile">創建配置</string>
Expand Down
2 changes: 2 additions & 0 deletions design/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<string name="behavior">行為</string>
<string name="bypass_private_network">略過私有網路</string>
<string name="bypass_private_network_summary">略過私有網路位址</string>
<string name="ipv6_route">IPv6 路由</string>
<string name="ipv6_route_summary">啟用 IPv6 路由</string>
<string name="cancel">取消</string>
<string name="clash_logcat">Clash Logcat</string>
<string name="create_profile">建立設定檔</string>
Expand Down
2 changes: 2 additions & 0 deletions design/src/main/res/values-zh/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<string name="behavior">行为</string>
<string name="bypass_private_network">绕过私有网络</string>
<string name="bypass_private_network_summary">绕过私有网络地址</string>
<string name="ipv6_route">IPv6 路由</string>
<string name="ipv6_route_summary">启用 IPv6 路由</string>
<string name="cancel">取消</string>
<string name="clash_logcat">Clash 日志捕捉工具</string>
<string name="create_profile">创建配置</string>
Expand Down
2 changes: 2 additions & 0 deletions design/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
<string name="vpn_service_options">VpnService Options</string>
<string name="bypass_private_network">Bypass Private Network</string>
<string name="bypass_private_network_summary">Bypass private network addresses</string>
<string name="ipv6_route">IPv6 Route</string>
<string name="ipv6_route_summary">Enable IPv6 route</string>
<string name="dns_hijacking">DNS Hijacking</string>
<string name="dns_hijacking_summary">Handle all dns packet</string>
<string name="block_loopback">Block Loopback</string>
Expand Down
48 changes: 36 additions & 12 deletions service/src/main/java/com/github/kr328/clash/service/TunService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De

val device = with(Builder()) {
// Interface address
addAddress(TUN_GATEWAY, TUN_SUBNET_PREFIX)
addAddress(TUN_VLAN4_CLIENT, TUN_VLAN4_SUBNET_PREFIX) // CLIENT

if (store.ipv6Route) {
addAddress(TUN_VLAN6_CLIENT, TUN_VLAN6_SUBNET_PREFIX)
}

// Route
if (store.bypassPrivateNetwork) {
Expand All @@ -140,9 +144,17 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
}

// Route of virtual DNS
addRoute(TUN_DNS, 32)
addRoute(TUN_VLAN4_GATEWAY, 32)

if (store.ipv6Route) {
addRoute("2000::", 3)
addRoute(TUN_VLAN6_GATEWAY, 128)
}
} else {
addRoute(NET_ANY, 0)
addRoute(TUN_VLAN4_ROUTE_DEFAULT, 0)
if (store.ipv6Route) {
addRoute(TUN_VLAN6_ROUTE_DEFAULT, 0)
}
}

// Access Control
Expand Down Expand Up @@ -170,7 +182,11 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
setSession("Clash")

// Virtual Dns Server
addDnsServer(TUN_DNS)
addDnsServer(TUN_VLAN4_DNS)

if (store.ipv6Route) {
addDnsServer(TUN_VLAN6_DNS)
}

// Open MainActivity
setConfigureIntent(
Expand Down Expand Up @@ -207,9 +223,11 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
TunModule.TunDevice(
fd = establish()?.detachFd()
?: throw NullPointerException("Establish VPN rejected by system"),
gateway = "$TUN_GATEWAY/$TUN_SUBNET_PREFIX",
portal = TUN_PORTAL,
dns = if (store.dnsHijacking) NET_ANY else TUN_DNS,
gateway = "$TUN_VLAN4_CLIENT/$TUN_VLAN4_SUBNET_PREFIX",
portal = TUN_VLAN4_GATEWAY,
dns = if (store.dnsHijacking) TUN_VLAN4_ROUTE_DEFAULT else TUN_VLAN4_DNS,
gateway6 = if (store.ipv6Route) TUN_VLAN6_GATEWAY else null,
dns6 = if (store.dnsHijacking) TUN_VLAN6_ROUTE_DEFAULT else (if (store.ipv6Route) TUN_VLAN6_DNS else null),
)
}

Expand All @@ -218,11 +236,17 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De

companion object {
private const val TUN_MTU = 9000
private const val TUN_SUBNET_PREFIX = 30
private const val TUN_GATEWAY = "172.19.0.1"
private const val TUN_PORTAL = "172.19.0.2"
private const val TUN_DNS = TUN_PORTAL
private const val NET_ANY = "0.0.0.0"
private const val TUN_VLAN4_CLIENT = "172.19.0.1"
private const val TUN_VLAN4_GATEWAY = "172.19.0.2"
private const val TUN_VLAN4_DNS = TUN_VLAN4_GATEWAY
private const val TUN_VLAN4_SUBNET_PREFIX = 30
private const val TUN_VLAN4_ROUTE_DEFAULT = "0.0.0.0"

private const val TUN_VLAN6_CLIENT = "fdfe:dcba:9876::1"
private const val TUN_VLAN6_GATEWAY = "fdfe:dcba:9876::2"
private const val TUN_VLAN6_DNS = TUN_VLAN6_GATEWAY
private const val TUN_VLAN6_SUBNET_PREFIX = 126
private const val TUN_VLAN6_ROUTE_DEFAULT = "::"

private val HTTP_PROXY_LOCAL_LIST: List<String> = listOf(
"localhost",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
val gateway: String,
val portal: String,
val dns: String,
val gateway6: String?,
val dns6: String?
)

private val connectivity = service.getSystemService<ConnectivityManager>()!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ class ServiceStore(context: Context) {
defaultValue = true
)

var ipv6Route: Boolean by store.boolean(
key = "ipv6_route",
defaultValue = true
)

var accessControlMode: AccessControlMode by store.enum(
key = "access_control_mode",
defaultValue = AccessControlMode.AcceptAll,
Expand Down

0 comments on commit 5421407

Please sign in to comment.