mirror of
https://github.com/dovecoteescapee/ByeDPIAndroid.git
synced 2024-12-22 06:15:44 +00:00
Replace tun2socks with hev-socks5-tunnel
This commit is contained in:
parent
6580068112
commit
b4dcb46723
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
/app/src/main/jniLibs
|
||||
|
@ -2,7 +2,16 @@
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/libs/tun2socks" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/byedpi" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/hev-socks5-tunnel" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/hev-socks5-tunnel/src/core" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/hev-socks5-tunnel/third-part/hev-task-system" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/hev-socks5-tunnel/third-part/lwip" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/hev-socks5-tunnel/third-part/yaml" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/jni/hev-socks5-tunnel" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/jni/hev-socks5-tunnel/src/core" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/jni/hev-socks5-tunnel/third-part/hev-task-system" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/jni/hev-socks5-tunnel/third-part/lwip" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/jni/hev-socks5-tunnel/third-part/yaml" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -1,5 +1,3 @@
|
||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
@ -13,10 +11,17 @@ android {
|
||||
applicationId = "io.github.dovecoteescapee.byedpi"
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
versionCode = 7
|
||||
versionName = "1.0.2"
|
||||
versionCode = 8
|
||||
versionName = "1.1.0-beta"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
ndk {
|
||||
abiFilters.add("armeabi-v7a")
|
||||
abiFilters.add("arm64-v8a")
|
||||
abiFilters.add("x86")
|
||||
abiFilters.add("x86_64")
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
@ -61,8 +66,6 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(files("libs/tun2socks.aar"))
|
||||
|
||||
implementation("androidx.fragment:fragment-ktx:1.8.2")
|
||||
implementation("androidx.core:core-ktx:1.13.1")
|
||||
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||
@ -77,75 +80,25 @@ dependencies {
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
||||
}
|
||||
|
||||
abstract class BaseTun2SocksTask : DefaultTask() {
|
||||
@get:InputDirectory
|
||||
val tun2socksDir: File
|
||||
get() = project.file("libs/tun2socks")
|
||||
|
||||
@get:OutputFile
|
||||
val tun2socksOutput: File
|
||||
get() = project.file("libs/tun2socks.aar")
|
||||
|
||||
@Internal
|
||||
protected fun isUpToDate(): Boolean {
|
||||
if (tun2socksOutput.exists()) {
|
||||
val lastModified = tun2socksOutput.lastModified()
|
||||
return !tun2socksDir.walkTopDown().any {
|
||||
it.isFile && it.lastModified() > lastModified
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
abstract class GetGomobileBind : BaseTun2SocksTask() {
|
||||
@TaskAction
|
||||
fun getBind() {
|
||||
if (isUpToDate()) {
|
||||
logger.lifecycle("No changes detected, skipping getBind.")
|
||||
return
|
||||
}
|
||||
|
||||
project.exec {
|
||||
workingDir = tun2socksDir
|
||||
|
||||
commandLine("go", "get", "golang.org/x/mobile/bind")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BuildTun2Socks : BaseTun2SocksTask() {
|
||||
@TaskAction
|
||||
fun buildTun2Socks() {
|
||||
if (isUpToDate()) {
|
||||
logger.lifecycle("No changes detected, skipping buildTun2Socks.")
|
||||
return
|
||||
}
|
||||
|
||||
project.exec {
|
||||
workingDir = tun2socksDir
|
||||
|
||||
commandLine(
|
||||
"gomobile", "bind",
|
||||
"-target", "android",
|
||||
"-androidapi", "21",
|
||||
"-o", tun2socksOutput,
|
||||
"-trimpath",
|
||||
"./engine"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val getGomobileBind = tasks.register<GetGomobileBind>("getGomobileBind") {
|
||||
tasks.register<Exec>("runNdkBuild") {
|
||||
group = "build"
|
||||
description = "Get gomobile bind for compiling tun2socks"
|
||||
|
||||
val ndkDir = android.ndkDirectory
|
||||
executable = if (System.getProperty("os.name").startsWith("Windows", ignoreCase = true)) {
|
||||
"$ndkDir\\ndk-build.cmd"
|
||||
} else {
|
||||
"$ndkDir/ndk-build"
|
||||
}
|
||||
setArgs(listOf(
|
||||
"NDK_PROJECT_PATH=build/intermediates/ndkBuild",
|
||||
"NDK_LIBS_OUT=src/main/jniLibs",
|
||||
"APP_BUILD_SCRIPT=src/main/jni/Android.mk",
|
||||
"NDK_APPLICATION_MK=src/main/jni/Application.mk"
|
||||
))
|
||||
|
||||
println("Command: $commandLine")
|
||||
}
|
||||
|
||||
val buildTun2Socks = tasks.register<BuildTun2Socks>("buildTun2Socks") {
|
||||
group = "build"
|
||||
description = "Build tun2socks for Android"
|
||||
dependsOn(getGomobileBind)
|
||||
}
|
||||
|
||||
tasks.preBuild.dependsOn(buildTun2Socks)
|
||||
tasks.preBuild {
|
||||
dependsOn("runNdkBuild")
|
||||
}
|
@ -1 +0,0 @@
|
||||
Subproject commit e083dafcf534d85e7fce86b3d48ee5c7a63c604e
|
@ -1,53 +1,14 @@
|
||||
# For more information about using CMake with Android Studio, read the
|
||||
# documentation: https://d.android.com/studio/projects/add-native-code.html.
|
||||
# For more examples on how to use CMake, see https://github.com/android/ndk-samples.
|
||||
|
||||
# Sets the minimum CMake version required for this project.
|
||||
cmake_minimum_required(VERSION 3.22.1)
|
||||
|
||||
# Declares the project name. The project name can be accessed via ${ PROJECT_NAME},
|
||||
# Since this is the top level CMakeLists.txt, the project name is also accessible
|
||||
# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level
|
||||
# build script scope).
|
||||
project("byedpi")
|
||||
project(byedpi_native)
|
||||
|
||||
# Creates and names a library, sets it as either STATIC
|
||||
# or SHARED, and provides the relative paths to its source code.
|
||||
# You can define multiple libraries, and CMake builds them for you.
|
||||
# Gradle automatically packages shared libraries with your APK.
|
||||
#
|
||||
# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define
|
||||
# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME}
|
||||
# is preferred for the same purpose.
|
||||
#
|
||||
# In order to load a library into your app from Java/Kotlin, you must call
|
||||
# System.loadLibrary() and pass the name of the library defined here;
|
||||
# for GameActivity/NativeActivity derived applications, the same library name must be
|
||||
# used in the AndroidManifest.xml file.
|
||||
add_library(${CMAKE_PROJECT_NAME} SHARED
|
||||
# List C/C++ source files with relative paths to this CMakeLists.txt.
|
||||
byedpi/conev.c
|
||||
byedpi/desync.c
|
||||
byedpi/extend.c
|
||||
byedpi/packets.c
|
||||
byedpi/proxy.c
|
||||
byedpi/main.c
|
||||
byedpi/mpool.c
|
||||
native-lib.c
|
||||
utils.c
|
||||
)
|
||||
file(GLOB BYE_DPI_SRC byedpi/*.c)
|
||||
list(REMOVE_ITEM BYE_DPI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/byedpi/win_service.c)
|
||||
|
||||
include_directories("byedpi")
|
||||
add_library(byedpi SHARED ${BYE_DPI_SRC} native-lib.c utils.c)
|
||||
target_include_directories(byedpi PRIVATE byedpi)
|
||||
|
||||
set(CMAKE_C_FLAGS "-std=c99 -O2 -D_XOPEN_SOURCE=500")
|
||||
target_compile_options(byedpi PRIVATE -std=c99 -O2 -D_XOPEN_SOURCE=500)
|
||||
target_compile_definitions(byedpi PRIVATE ANDROID_APP)
|
||||
|
||||
add_compile_definitions(ANDROID_APP)
|
||||
|
||||
# Specifies libraries CMake should link to your target library. You
|
||||
# can link libraries from various origins, such as libraries defined in this
|
||||
# build script, prebuilt third-party libraries, or Android system libraries.
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
# List libraries link to the target library
|
||||
android
|
||||
log
|
||||
)
|
||||
target_link_libraries(byedpi PRIVATE android log)
|
||||
|
@ -8,9 +8,6 @@ import android.os.Build
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import engine.Engine
|
||||
import engine.Key
|
||||
import io.github.dovecoteescapee.byedpi.BuildConfig
|
||||
import io.github.dovecoteescapee.byedpi.R
|
||||
import io.github.dovecoteescapee.byedpi.activities.MainActivity
|
||||
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxy
|
||||
@ -23,11 +20,12 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
||||
class ByeDpiVpnService : LifecycleVpnService() {
|
||||
private val proxy = ByeDpiProxy()
|
||||
private val byeDpiProxy = ByeDpiProxy()
|
||||
private var proxyJob: Job? = null
|
||||
private var vpn: ParcelFileDescriptor? = null
|
||||
private var tunFd: ParcelFileDescriptor? = null
|
||||
private val mutex = Mutex()
|
||||
private var stopping: Boolean = false
|
||||
|
||||
@ -138,7 +136,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
val preferences = getByeDpiPreferences()
|
||||
|
||||
proxyJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||
val code = proxy.startProxy(preferences)
|
||||
val code = byeDpiProxy.startProxy(preferences)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (code != 0) {
|
||||
@ -164,7 +162,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
return
|
||||
}
|
||||
|
||||
proxy.stopProxy()
|
||||
byeDpiProxy.stopProxy()
|
||||
proxyJob?.join() ?: throw IllegalStateException("ProxyJob field null")
|
||||
proxyJob = null
|
||||
|
||||
@ -174,7 +172,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
private fun startTun2Socks() {
|
||||
Log.i(TAG, "Starting tun2socks")
|
||||
|
||||
if (vpn != null) {
|
||||
if (tunFd != null) {
|
||||
throw IllegalStateException("VPN field not null")
|
||||
}
|
||||
|
||||
@ -182,22 +180,49 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
val port = sharedPreferences.getString("byedpi_proxy_port", null)?.toInt() ?: 1080
|
||||
val dns = sharedPreferences.getStringNotNull("dns_ip", "1.1.1.1")
|
||||
|
||||
val tun2socksConfig = """
|
||||
| misc:
|
||||
| task-stack-size: 81920
|
||||
| socks5:
|
||||
| mtu: 8500
|
||||
| address: 127.0.0.1
|
||||
| port: $port
|
||||
| udp: udp
|
||||
""".trimMargin("| ")
|
||||
|
||||
val configPath = try {
|
||||
File.createTempFile("config", "tmp", cacheDir).apply {
|
||||
writeText(tun2socksConfig)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to create config file", e)
|
||||
throw e
|
||||
}
|
||||
|
||||
val vpn = createBuilder(dns).establish()
|
||||
?: throw IllegalStateException("VPN connection failed")
|
||||
|
||||
this.vpn = vpn
|
||||
// val fd = vpn.detachFd()
|
||||
Engine.insert(createKey(vpn.fd, port))
|
||||
Engine.start()
|
||||
this.tunFd = vpn
|
||||
|
||||
Log.d(TAG, "Native tun2socks start")
|
||||
TProxyService.TProxyStartService(configPath.absolutePath, vpn.fd)
|
||||
|
||||
Log.i(TAG, "Tun2Socks started")
|
||||
}
|
||||
|
||||
private fun stopTun2Socks() {
|
||||
Log.i(TAG, "Stopping tun2socks")
|
||||
// Engine.stop() // sometimes crashes with fdsan
|
||||
vpn?.close() ?: Log.w(TAG, "VPN not running") // Is engine close sockets?
|
||||
vpn = null
|
||||
|
||||
TProxyService.TProxyStopService()
|
||||
Log.d(TAG, "Native tun2socks stopped done")
|
||||
|
||||
tunFd?.close() ?: Log.w(TAG, "VPN not running")
|
||||
tunFd = null
|
||||
try {
|
||||
File(cacheDir, "config.tmp").delete()
|
||||
} catch (e: SecurityException) {
|
||||
Log.e(TAG, "Failed to delete config file", e)
|
||||
}
|
||||
Log.i(TAG, "Tun2socks stopped")
|
||||
}
|
||||
|
||||
@ -212,6 +237,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
setStatus(
|
||||
when (newStatus) {
|
||||
ServiceStatus.Connected -> AppStatus.Running
|
||||
|
||||
ServiceStatus.Disconnected,
|
||||
ServiceStatus.Failed -> {
|
||||
proxyJob = null
|
||||
@ -261,23 +287,8 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
builder.setMetered(false)
|
||||
}
|
||||
|
||||
builder.addDisallowedApplication("io.github.dovecoteescapee.byedpi")
|
||||
builder.addDisallowedApplication(applicationContext.packageName)
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
private fun createKey(fd: Int, port: Int): Key = Key().apply {
|
||||
mark = 0
|
||||
mtu = 0
|
||||
device = "fd://${fd}"
|
||||
|
||||
setInterface("")
|
||||
logLevel = if (BuildConfig.DEBUG) "debug" else "info"
|
||||
proxy = "socks5://127.0.0.1:$port"
|
||||
|
||||
restAPI = ""
|
||||
tcpSendBufferSize = ""
|
||||
tcpReceiveBufferSize = ""
|
||||
tcpModerateReceiveBuffer = false
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.ServiceLifecycleDispatcher
|
||||
|
||||
/**
|
||||
* Based on @link [androidx.lifecycle.LifecycleService]
|
||||
* Based on [androidx.lifecycle.LifecycleService]
|
||||
*/
|
||||
open class LifecycleVpnService : VpnService(), LifecycleOwner {
|
||||
@Suppress("LeakingThis")
|
||||
@ -28,10 +28,10 @@ open class LifecycleVpnService : VpnService(), LifecycleOwner {
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
@Suppress("DEPRECATION")
|
||||
@CallSuper
|
||||
override fun onStart(intent: Intent?, startId: Int) {
|
||||
dispatcher.onServicePreSuperOnStart()
|
||||
@Suppress("DEPRECATION")
|
||||
super.onStart(intent, startId)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
package io.github.dovecoteescapee.byedpi.services
|
||||
|
||||
object TProxyService {
|
||||
init {
|
||||
System.loadLibrary("hev-socks5-tunnel")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
external fun TProxyStartService(configPath: String, fd: Int)
|
||||
|
||||
@JvmStatic
|
||||
external fun TProxyStopService()
|
||||
|
||||
@JvmStatic
|
||||
@Suppress("unused")
|
||||
external fun TProxyGetStats(): LongArray
|
||||
}
|
16
app/src/main/jni/Android.mk
Normal file
16
app/src/main/jni/Android.mk
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2023 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
include $(call all-subdir-makefiles)
|
21
app/src/main/jni/Application.mk
Normal file
21
app/src/main/jni/Application.mk
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (C) 2023 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
APP_OPTIM := release
|
||||
APP_PLATFORM := android-21
|
||||
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
|
||||
APP_CFLAGS := -O3 -DPKGNAME=io/github/dovecoteescapee/byedpi/services
|
||||
APP_CPPFLAGS := -O3 -std=c++11
|
||||
NDK_TOOLCHAIN_VERSION := clang
|
Loading…
Reference in New Issue
Block a user