mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-15 10:25:40 +00:00
109 lines
3.4 KiB
Kotlin
109 lines
3.4 KiB
Kotlin
package com.plugin.vpnservice
|
|
|
|
import android.content.Intent
|
|
import android.net.VpnService
|
|
import android.os.Build
|
|
import android.os.ParcelFileDescriptor
|
|
import android.os.Bundle
|
|
import java.net.InetAddress
|
|
import java.util.Arrays
|
|
|
|
import app.tauri.plugin.JSObject
|
|
|
|
class TauriVpnService : VpnService() {
|
|
companion object {
|
|
@JvmField var triggerCallback: (String, JSObject) -> Unit = { _, _ -> }
|
|
@JvmField var self: TauriVpnService? = null
|
|
|
|
const val IPV4_ADDR = "IPV4_ADDR"
|
|
const val ROUTES = "ROUTES"
|
|
const val DNS = "DNS"
|
|
const val DISALLOWED_APPLICATIONS = "DISALLOWED_APPLICATIONS"
|
|
const val MTU = "MTU"
|
|
}
|
|
|
|
private lateinit var vpnInterface: ParcelFileDescriptor
|
|
|
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
println("vpn on start command ${intent?.getExtras()} $intent")
|
|
var args = intent?.getExtras()
|
|
|
|
vpnInterface = createVpnInterface(args)
|
|
println("vpn created ${vpnInterface.fd}")
|
|
|
|
var event_data = JSObject()
|
|
event_data.put("fd", vpnInterface.fd)
|
|
triggerCallback("vpn_service_start", event_data)
|
|
|
|
return START_STICKY
|
|
}
|
|
|
|
override fun onCreate() {
|
|
super.onCreate()
|
|
self = this
|
|
println("vpn on create")
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
println("vpn on destroy")
|
|
super.onDestroy()
|
|
disconnect()
|
|
self = null
|
|
}
|
|
|
|
override fun onRevoke() {
|
|
println("vpn on revoke")
|
|
super.onRevoke()
|
|
disconnect()
|
|
self = null
|
|
}
|
|
|
|
private fun disconnect() {
|
|
if (self == this && this::vpnInterface.isInitialized) {
|
|
triggerCallback("vpn_service_stop", JSObject())
|
|
vpnInterface.close()
|
|
}
|
|
}
|
|
|
|
private fun createVpnInterface(args: Bundle?): ParcelFileDescriptor {
|
|
var builder = Builder()
|
|
.setSession("TauriVpnService")
|
|
.setBlocking(false)
|
|
|
|
var mtu = args?.getInt(MTU) ?: 1500
|
|
var ipv4Addr = args?.getString(IPV4_ADDR) ?: "10.126.126.1/24"
|
|
var dns = args?.getString(DNS) ?: "114.114.114.114"
|
|
var routes = args?.getStringArray(ROUTES) ?: emptyArray()
|
|
var disallowedApplications = args?.getStringArray(DISALLOWED_APPLICATIONS) ?: emptyArray()
|
|
|
|
println("vpn create vpn interface. mtu: $mtu, ipv4Addr: $ipv4Addr, dns:" +
|
|
"$dns, routes: ${java.util.Arrays.toString(routes)}," +
|
|
"disallowedApplications: ${java.util.Arrays.toString(disallowedApplications)}")
|
|
|
|
val ipParts = ipv4Addr.split("/")
|
|
if (ipParts.size != 2) throw IllegalArgumentException("Invalid IP addr string")
|
|
builder.addAddress(ipParts[0], ipParts[1].toInt())
|
|
|
|
builder.setMtu(mtu)
|
|
builder.addDnsServer(dns)
|
|
|
|
for (route in routes) {
|
|
val ipParts = route.split("/")
|
|
if (ipParts.size != 2) throw IllegalArgumentException("Invalid route cidr string")
|
|
builder.addRoute(ipParts[0], ipParts[1].toInt())
|
|
}
|
|
|
|
for (app in disallowedApplications) {
|
|
builder.addDisallowedApplication(app)
|
|
}
|
|
|
|
return builder.also {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
it.setMetered(false)
|
|
}
|
|
}
|
|
.establish()
|
|
?: throw IllegalStateException("Failed to init VpnService")
|
|
}
|
|
}
|