aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Liu <maliu@mozilla.com>2019-11-19 10:44:53 +0800
committerMax Liu <maliu@mozilla.com>2019-11-27 11:12:59 +0800
commit4ae7e17b9461d9a91ea1e223a459231f05b9058e (patch)
treee92caeec90b08872e4a9617a1d6fd6e78ff1c6ed
parentExtract modules (diff)
downloadwireguard-android-ml/libwg.tar.xz
wireguard-android-ml/libwg.zip
Add simplified TunnelManagerml/libwg
Signed-off-by: Max Liu <maliu@mozilla.com>
-rw-r--r--libwg/build.gradle5
-rw-r--r--libwg/src/main/java/com/wireguard/android/backend/Tunnel.kt40
-rw-r--r--libwg/src/main/java/com/wireguard/android/backend/TunnelManager.kt121
-rw-r--r--libwg/src/main/java/com/wireguard/android/backend/VpnServiceBackend.kt43
4 files changed, 209 insertions, 0 deletions
diff --git a/libwg/build.gradle b/libwg/build.gradle
index 843a0d6..bf4e6f7 100644
--- a/libwg/build.gradle
+++ b/libwg/build.gradle
@@ -31,6 +31,11 @@ android {
}
dependencies {
+ implementation project(":config")
+
+ implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "androidx.annotation:annotation:$annotationsVersion"
implementation "androidx.appcompat:appcompat:$appcompatVersion"
+
+ implementation "net.sourceforge.streamsupport:android-retrofuture:$streamsupportVersion"
}
diff --git a/libwg/src/main/java/com/wireguard/android/backend/Tunnel.kt b/libwg/src/main/java/com/wireguard/android/backend/Tunnel.kt
new file mode 100644
index 0000000..b0893be
--- /dev/null
+++ b/libwg/src/main/java/com/wireguard/android/backend/Tunnel.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2019 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.android.backend
+
+import android.os.ParcelFileDescriptor
+import com.wireguard.config.Config
+
+public class Tunnel {
+
+ public val name: String
+
+ var tunFd: ParcelFileDescriptor? = null
+ var tunnelHandle: Int? = null
+
+ val state: State
+ get() {
+ return if (tunnelHandle == null) {
+ State.Down
+ } else {
+ State.Up
+ }
+ }
+
+
+ val config: Config
+
+ constructor(name: String, config: Config) {
+ this.name = name
+ this.config = config
+ }
+
+ sealed class State {
+ object Up: State()
+ object Down: State()
+ }
+
+} \ No newline at end of file
diff --git a/libwg/src/main/java/com/wireguard/android/backend/TunnelManager.kt b/libwg/src/main/java/com/wireguard/android/backend/TunnelManager.kt
new file mode 100644
index 0000000..54fdc8c
--- /dev/null
+++ b/libwg/src/main/java/com/wireguard/android/backend/TunnelManager.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright © 2019 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.android.backend
+
+import android.content.Context
+import android.content.Intent
+import android.net.VpnService
+import android.net.VpnService.prepare
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.Observer
+import androidx.lifecycle.ProcessLifecycleOwner
+import com.wireguard.config.Config
+
+class TunnelManager {
+
+ val backend: VpnServiceBackend
+ val builderProvider: VpnBuilderProvider
+ val context: Context
+ var currentTunnel: Tunnel? = null
+
+ companion object {
+ private val vpnService = MutableLiveData<VpnService>()
+ }
+
+ interface VpnBuilderProvider {
+ fun patchBuilder(builder: android.net.VpnService.Builder): android.net.VpnService.Builder
+ }
+
+ init {
+
+ }
+
+ constructor(context: Context, builderProvider: VpnBuilderProvider) {
+ this.backend = VpnServiceBackend(object: VpnServiceBackend.VpnServiceDelegate{
+ override fun protect(socket: Int): Boolean {
+ return vpnService.value?.protect(socket) ?: false
+ }
+ })
+ this.context = context.applicationContext
+ this.builderProvider = builderProvider
+ }
+
+ fun tunnelDown() {
+ vpnService.value = null
+ }
+
+ fun tunnelUp(tunnel: Tunnel) {
+ currentTunnel = tunnel
+ val config = tunnel.config
+
+ vpnService.observe(ProcessLifecycleOwner.get(), object: Observer<VpnService>{
+ override fun onChanged(service: VpnService?) {
+ if(service == null){
+ vpnService.removeObserver(this)
+ currentTunnel?.apply { backend.tunnelDown(this) }
+ return
+ }
+
+ val builder = service.Builder()
+ builderProvider.patchBuilder(builder)
+ builder.applyConfig(config)
+ val tun = builder.establish() ?: return
+
+ backend.tunnelUp(tunnel, tun, config.toWgUserspaceString())
+ }
+ })
+ context.startService(Intent(context, VpnService::class.java))
+ }
+
+ fun isGranted(): Boolean {
+ return prepare(context) == null
+ }
+
+ fun isConnected(): Boolean {
+ return currentTunnel?.state == Tunnel.State.Up
+ }
+
+ public class VpnService : android.net.VpnService() {
+ val builder: Builder
+ get() {
+ return Builder()
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ vpnService.value = this
+ }
+
+ override fun onDestroy() {
+ vpnService.value = null
+ super.onDestroy()
+ }
+
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ return super.onStartCommand(intent, flags, startId)
+ }
+ }
+}
+
+fun VpnService.Builder.applyConfig(config: Config){
+ for (excludedApplication in config.getInterface().excludedApplications)
+ addDisallowedApplication(excludedApplication)
+
+ for (addr in config.getInterface().addresses)
+ addAddress(addr.address, addr.mask)
+
+ for (addr in config.getInterface().dnsServers)
+ addDnsServer(addr.hostAddress)
+
+ for (peer in config.peers) {
+ for (addr in peer.allowedIps)
+ addRoute(addr.address, addr.mask)
+ }
+
+ setMtu(config.getInterface().mtu.orElse(1280))
+
+ setBlocking(true)
+} \ No newline at end of file
diff --git a/libwg/src/main/java/com/wireguard/android/backend/VpnServiceBackend.kt b/libwg/src/main/java/com/wireguard/android/backend/VpnServiceBackend.kt
new file mode 100644
index 0000000..6e03a9d
--- /dev/null
+++ b/libwg/src/main/java/com/wireguard/android/backend/VpnServiceBackend.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2019 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.android.backend
+
+import android.os.ParcelFileDescriptor
+
+class VpnServiceBackend : BackendNative {
+
+ private val delegate: VpnServiceDelegate
+
+ constructor(delegate: VpnServiceDelegate) {
+ this.delegate = delegate
+ }
+
+ fun tunnelUp(tunnel: Tunnel, tunFd: ParcelFileDescriptor, config: String) {
+
+ val handle = wgTurnOn(tunnel.name, tunFd.detachFd(), config)
+
+ val socketV4 = wgGetSocketV4(handle)
+ val socketV6 = wgGetSocketV6(handle)
+
+ delegate.protect(socketV4)
+ delegate.protect(socketV6)
+
+ tunnel.tunnelHandle = handle
+ }
+
+ fun tunnelDown(tunnel: Tunnel) {
+ val socket = tunnel.tunnelHandle ?: return
+ wgTurnOff(socket)
+ }
+
+ fun getVersion(): String {
+ return wgVersion()
+ }
+
+ interface VpnServiceDelegate {
+ fun protect(socket: Int): Boolean
+ }
+} \ No newline at end of file