mirror of
https://github.com/dovecoteescapee/ByeDPIAndroid.git
synced 2024-12-21 22:06:22 +00:00
Checkout byedpi to main branch
This commit is contained in:
parent
9a46a16cc0
commit
81d080863f
@ -1 +1 @@
|
||||
Subproject commit 12adfe285f603bfa38c19e9057d897b2b4e40941
|
||||
Subproject commit 6b484d598817cffd61344a812721fb00089f5095
|
@ -5,7 +5,6 @@
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
@ -17,24 +16,15 @@ const enum demode DESYNC_METHODS[] = {
|
||||
DESYNC_FAKE
|
||||
};
|
||||
|
||||
extern int NOT_EXIT;
|
||||
extern struct packet fake_tls, fake_http;
|
||||
extern int get_default_ttl();
|
||||
extern int get_addr(const char *str, struct sockaddr_ina *addr);
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniEventFd(JNIEnv *env, jobject thiz) {
|
||||
int fd = eventfd(0, EFD_NONBLOCK);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniStartProxy(
|
||||
Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jint event_fd,
|
||||
jstring ip,
|
||||
jint port,
|
||||
jint max_connections,
|
||||
@ -87,22 +77,33 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniStartProxy(
|
||||
}
|
||||
}
|
||||
|
||||
int res = listener(event_fd, s);
|
||||
|
||||
if (close(event_fd) < 0) {
|
||||
uniperror("close");
|
||||
int fd = listen_socket(&s);
|
||||
if (fd < 0) {
|
||||
uniperror("listen_socket");
|
||||
return get_e();
|
||||
}
|
||||
|
||||
return res < 0 ? get_e() : 0;
|
||||
LOG(LOG_S, "listen_socket, fd: %d", fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniStartProxy(JNIEnv *env, jobject thiz,
|
||||
jint fd) {
|
||||
LOG(LOG_S, "start_proxy, fd: %d", fd);
|
||||
NOT_EXIT = 1;
|
||||
if (event_loop(fd) < 0) {
|
||||
return get_e();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniStopProxy(JNIEnv *env, jobject thiz,
|
||||
jint event_fd) {
|
||||
if (eventfd_write(event_fd, 1) < 0) {
|
||||
uniperror("eventfd_write");
|
||||
LOG(LOG_S, "event_fd: %d", event_fd);
|
||||
jint fd) {
|
||||
LOG(LOG_S, "stop_proxy, fd: %d", fd);
|
||||
if (shutdown(fd, SHUT_RDWR) < 0) {
|
||||
return get_e();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package io.github.dovecoteescapee.byedpi.core
|
||||
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import java.io.IOException
|
||||
|
||||
class ByeDpiProxy {
|
||||
@ -9,42 +11,61 @@ class ByeDpiProxy {
|
||||
}
|
||||
}
|
||||
|
||||
private val fd = jniEventFd()
|
||||
private val mutex = Mutex()
|
||||
private var fd = -1
|
||||
|
||||
init {
|
||||
if (fd < 0) {
|
||||
throw IOException("Failed to create eventfd")
|
||||
suspend fun startProxy(preferences: ByeDpiProxyPreferences): Int =
|
||||
jniStartProxy(createSocket(preferences))
|
||||
|
||||
suspend fun stopProxy(): Int {
|
||||
mutex.withLock {
|
||||
if (fd < 0) {
|
||||
throw IllegalStateException("Proxy is not running")
|
||||
}
|
||||
|
||||
val result = jniStopProxy(fd)
|
||||
if (result == 0) {
|
||||
fd = -1
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun startProxy(preferences: ByeDpiProxyPreferences): Int =
|
||||
jniStartProxy(
|
||||
eventFd = fd,
|
||||
ip = preferences.ip,
|
||||
port = preferences.port,
|
||||
maxConnections = preferences.maxConnections,
|
||||
bufferSize = preferences.bufferSize,
|
||||
defaultTtl = preferences.defaultTtl,
|
||||
noDomain = preferences.noDomain,
|
||||
desyncKnown = preferences.desyncKnown,
|
||||
desyncMethod = preferences.desyncMethod.ordinal,
|
||||
splitPosition = preferences.splitPosition,
|
||||
splitAtHost = preferences.splitAtHost,
|
||||
fakeTtl = preferences.fakeTtl,
|
||||
hostMixedCase = preferences.hostMixedCase,
|
||||
domainMixedCase = preferences.domainMixedCase,
|
||||
hostRemoveSpaces = preferences.hostRemoveSpaces,
|
||||
tlsRecordSplit = preferences.tlsRecordSplit,
|
||||
tlsRecordSplitPosition = preferences.tlsRecordSplitPosition,
|
||||
tlsRecordSplitAtSni = preferences.tlsRecordSplitAtSni,
|
||||
)
|
||||
private suspend fun createSocket(preferences: ByeDpiProxyPreferences): Int =
|
||||
mutex.withLock {
|
||||
if (fd >= 0) {
|
||||
throw IllegalStateException("Proxy is already running")
|
||||
}
|
||||
|
||||
fun stopProxy(): Int = jniStopProxy(fd)
|
||||
val fd = jniCreateSocket(
|
||||
ip = preferences.ip,
|
||||
port = preferences.port,
|
||||
maxConnections = preferences.maxConnections,
|
||||
bufferSize = preferences.bufferSize,
|
||||
defaultTtl = preferences.defaultTtl,
|
||||
noDomain = preferences.noDomain,
|
||||
desyncKnown = preferences.desyncKnown,
|
||||
desyncMethod = preferences.desyncMethod.ordinal,
|
||||
splitPosition = preferences.splitPosition,
|
||||
splitAtHost = preferences.splitAtHost,
|
||||
fakeTtl = preferences.fakeTtl,
|
||||
hostMixedCase = preferences.hostMixedCase,
|
||||
domainMixedCase = preferences.domainMixedCase,
|
||||
hostRemoveSpaces = preferences.hostRemoveSpaces,
|
||||
tlsRecordSplit = preferences.tlsRecordSplit,
|
||||
tlsRecordSplitPosition = preferences.tlsRecordSplitPosition,
|
||||
tlsRecordSplitAtSni = preferences.tlsRecordSplitAtSni,
|
||||
)
|
||||
|
||||
private external fun jniEventFd(): Int
|
||||
if (fd < 0) {
|
||||
throw IOException("Failed to create socket")
|
||||
}
|
||||
|
||||
private external fun jniStartProxy(
|
||||
eventFd: Int,
|
||||
this.fd = fd
|
||||
fd
|
||||
}
|
||||
|
||||
private external fun jniCreateSocket(
|
||||
ip: String,
|
||||
port: Int,
|
||||
maxConnections: Int,
|
||||
@ -64,5 +85,7 @@ class ByeDpiProxy {
|
||||
tlsRecordSplitAtSni: Boolean,
|
||||
): Int
|
||||
|
||||
private external fun jniStopProxy(eventFd: Int): Int
|
||||
private external fun jniStartProxy(fd: Int): Int
|
||||
|
||||
private external fun jniStopProxy(fd: Int): Int
|
||||
}
|
@ -41,25 +41,23 @@ class ByeDpiProxyPreferences(
|
||||
|
||||
constructor(preferences: SharedPreferences) : this(
|
||||
ip = preferences.getString("byedpi_proxy_ip", null),
|
||||
port = preferences.getString("byedpi_proxy_port", null)?.toInt(),
|
||||
maxConnections = preferences.getString("byedpi_max_connections", null)?.toInt(),
|
||||
bufferSize = preferences.getString("byedpi_buffer_size", null)?.toInt(),
|
||||
defaultTtl = preferences.getString("byedpi_default_ttl", null)?.toInt(),
|
||||
port = preferences.getString("byedpi_proxy_port", null)?.toIntOrNull(),
|
||||
maxConnections = preferences.getString("byedpi_max_connections", null)?.toIntOrNull(),
|
||||
bufferSize = preferences.getString("byedpi_buffer_size", null)?.toIntOrNull(),
|
||||
defaultTtl = preferences.getString("byedpi_default_ttl", null)?.toIntOrNull(),
|
||||
noDomain = preferences.getBoolean("byedpi_no_domain", false),
|
||||
desyncKnown = preferences.getBoolean("byedpi_desync_known", false),
|
||||
desyncMethod = preferences.getString("byedpi_desync_method", null)
|
||||
?.let { DesyncMethod.fromName(it) },
|
||||
splitPosition = preferences.getString("byedpi_split_position", null)?.toInt(),
|
||||
splitPosition = preferences.getString("byedpi_split_position", null)?.toIntOrNull(),
|
||||
splitAtHost = preferences.getBoolean("byedpi_split_at_host", false),
|
||||
fakeTtl = preferences.getString("byedpi_fake_ttl", null)?.toInt(),
|
||||
fakeTtl = preferences.getString("byedpi_fake_ttl", null)?.toIntOrNull(),
|
||||
hostMixedCase = preferences.getBoolean("byedpi_host_mixed_case", false),
|
||||
domainMixedCase = preferences.getBoolean("byedpi_domain_mixed_case", false),
|
||||
hostRemoveSpaces = preferences.getBoolean("byedpi_host_remove_spaces", false),
|
||||
tlsRecordSplit = preferences.getBoolean("byedpi_tlsrec_enabled", false),
|
||||
tlsRecordSplitPosition = preferences.getString("byedpi_tlsrec_position", null)?.toInt(),
|
||||
tlsRecordSplitPosition = preferences.getString("byedpi_tlsrec_position", null)?.toIntOrNull(),
|
||||
tlsRecordSplitAtSni = preferences.getBoolean("byedpi_tlsrec_at_sni", false),
|
||||
|
||||
|
||||
)
|
||||
|
||||
enum class DesyncMethod {
|
||||
|
@ -24,11 +24,14 @@ import io.github.dovecoteescapee.byedpi.utility.registerNotificationChannel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ByeDpiProxyService : LifecycleService() {
|
||||
private var proxy: ByeDpiProxy? = null
|
||||
private var proxy = ByeDpiProxy()
|
||||
private var proxyJob: Job? = null
|
||||
private val mutex = Mutex()
|
||||
|
||||
companion object {
|
||||
private val TAG: String = ByeDpiProxyService::class.java.simpleName
|
||||
@ -77,7 +80,9 @@ class ByeDpiProxyService : LifecycleService() {
|
||||
}
|
||||
|
||||
try {
|
||||
startProxy()
|
||||
mutex.withLock {
|
||||
startProxy()
|
||||
}
|
||||
updateStatus(ServiceStatus.CONNECTED)
|
||||
startForeground()
|
||||
} catch (e: Exception) {
|
||||
@ -103,7 +108,9 @@ class ByeDpiProxyService : LifecycleService() {
|
||||
private suspend fun stop() {
|
||||
Log.i(TAG, "Stopping VPN")
|
||||
|
||||
stopProxy()
|
||||
mutex.withLock {
|
||||
stopProxy()
|
||||
}
|
||||
updateStatus(ServiceStatus.DISCONNECTED)
|
||||
stopSelf()
|
||||
}
|
||||
@ -111,7 +118,7 @@ class ByeDpiProxyService : LifecycleService() {
|
||||
private suspend fun startProxy() {
|
||||
Log.i(TAG, "Starting proxy")
|
||||
|
||||
if (proxy != null || proxyJob != null) {
|
||||
if (proxyJob != null) {
|
||||
Log.w(TAG, "Proxy fields not null")
|
||||
throw IllegalStateException("Proxy fields not null")
|
||||
}
|
||||
@ -120,7 +127,7 @@ class ByeDpiProxyService : LifecycleService() {
|
||||
val preferences = getByeDpiPreferences()
|
||||
|
||||
proxyJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||
val code = proxy?.startProxy(preferences)
|
||||
val code = proxy.startProxy(preferences)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (code != 0) {
|
||||
@ -141,13 +148,12 @@ class ByeDpiProxyService : LifecycleService() {
|
||||
if (status == ServiceStatus.DISCONNECTED) {
|
||||
Log.w(TAG, "Proxy already disconnected")
|
||||
return
|
||||
} else {
|
||||
proxy?.stopProxy()
|
||||
proxyJob?.join()
|
||||
proxy = null
|
||||
proxyJob = null
|
||||
}
|
||||
|
||||
proxy.stopProxy()
|
||||
proxyJob?.join()
|
||||
proxyJob = null
|
||||
|
||||
Log.i(TAG, "Proxy stopped")
|
||||
}
|
||||
|
||||
|
@ -29,17 +29,15 @@ import io.github.dovecoteescapee.byedpi.utility.registerNotificationChannel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ByeDpiVpnService : LifecycleVpnService() {
|
||||
private var proxy: ByeDpiProxy? = null
|
||||
private val proxy = ByeDpiProxy()
|
||||
private var proxyJob: Job? = null
|
||||
private var vpn: ParcelFileDescriptor? = null
|
||||
private val semaphore = Semaphore(1)
|
||||
|
||||
@Volatile
|
||||
private val mutex = Mutex()
|
||||
private var stopping: Boolean = false
|
||||
|
||||
companion object {
|
||||
@ -94,7 +92,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
}
|
||||
|
||||
try {
|
||||
semaphore.withPermit {
|
||||
mutex.withLock {
|
||||
startProxy()
|
||||
startTun2Socks()
|
||||
}
|
||||
@ -123,8 +121,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
private suspend fun stop() {
|
||||
Log.i(TAG, "Stopping")
|
||||
|
||||
// Wait end of starting
|
||||
semaphore.withPermit {
|
||||
mutex.withLock {
|
||||
stopping = true
|
||||
try {
|
||||
stopTun2Socks()
|
||||
@ -143,16 +140,15 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
private suspend fun startProxy() {
|
||||
Log.i(TAG, "Starting proxy")
|
||||
|
||||
if (proxy != null || proxyJob != null) {
|
||||
if (proxyJob != null) {
|
||||
Log.w(TAG, "Proxy fields not null")
|
||||
throw IllegalStateException("Proxy fields not null")
|
||||
}
|
||||
|
||||
proxy = ByeDpiProxy()
|
||||
val preferences = getByeDpiPreferences()
|
||||
|
||||
proxyJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||
val code = proxy?.startProxy(preferences)
|
||||
val code = proxy.startProxy(preferences)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (code != 0) {
|
||||
@ -176,13 +172,12 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
if (status == ServiceStatus.DISCONNECTED) {
|
||||
Log.w(TAG, "Proxy already disconnected")
|
||||
return
|
||||
} else {
|
||||
proxy?.stopProxy() ?: throw IllegalStateException("Proxy field null")
|
||||
proxyJob?.join() ?: throw IllegalStateException("ProxyJob field null")
|
||||
proxy = null
|
||||
proxyJob = null
|
||||
}
|
||||
|
||||
proxy.stopProxy()
|
||||
proxyJob?.join() ?: throw IllegalStateException("ProxyJob field null")
|
||||
proxyJob = null
|
||||
|
||||
Log.i(TAG, "Proxy stopped")
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user