mirror of
https://github.com/M66B/NetGuard.git
synced 2024-12-27 02:09:41 +00:00
Use manage thread for native code
This commit is contained in:
parent
0f37f52499
commit
72941a9e88
3 changed files with 86 additions and 88 deletions
|
@ -135,6 +135,7 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
private int last_blocked = -1;
|
||||
private int last_hosts = -1;
|
||||
|
||||
private Thread tunnelThread = null;
|
||||
private ServiceSinkhole.Builder last_builder = null;
|
||||
private ParcelFileDescriptor vpn = null;
|
||||
private boolean temporarilyStopped = false;
|
||||
|
@ -195,9 +196,13 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
private native void jni_init(int sdk);
|
||||
|
||||
private native void jni_start(int tun, boolean fwd53, int rcode, int loglevel);
|
||||
private native void jni_start(int loglevel);
|
||||
|
||||
private native void jni_stop(int tun, boolean clr);
|
||||
private native void jni_run(int tun, boolean fwd53, int rcode);
|
||||
|
||||
private native void jni_stop();
|
||||
|
||||
private native void jni_clear();
|
||||
|
||||
private native int jni_get_mtu();
|
||||
|
||||
|
@ -1369,7 +1374,7 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
return builder;
|
||||
}
|
||||
|
||||
private void startNative(ParcelFileDescriptor vpn, List<Rule> listAllowed, List<Rule> listRule) {
|
||||
private void startNative(final ParcelFileDescriptor vpn, List<Rule> listAllowed, List<Rule> listRule) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ServiceSinkhole.this);
|
||||
boolean log = prefs.getBoolean("log", false);
|
||||
boolean log_app = prefs.getBoolean("log_app", false);
|
||||
|
@ -1403,7 +1408,7 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
if (log || log_app || filter) {
|
||||
int prio = Integer.parseInt(prefs.getString("loglevel", Integer.toString(Log.WARN)));
|
||||
int rcode = Integer.parseInt(prefs.getString("rcode", "3"));
|
||||
final int rcode = Integer.parseInt(prefs.getString("rcode", "3"));
|
||||
if (prefs.getBoolean("socks5_enabled", false))
|
||||
jni_socks5(
|
||||
prefs.getString("socks5_addr", ""),
|
||||
|
@ -1412,18 +1417,48 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
prefs.getString("socks5_password", ""));
|
||||
else
|
||||
jni_socks5("", 0, "", "");
|
||||
jni_start(vpn.getFd(), mapForward.containsKey(53), rcode, prio);
|
||||
|
||||
if (tunnelThread == null) {
|
||||
Log.i(TAG, "Starting tunnel thread");
|
||||
jni_start(prio);
|
||||
|
||||
tunnelThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "Running tunnel");
|
||||
jni_run(vpn.getFd(), mapForward.containsKey(53), rcode);
|
||||
Log.i(TAG, "Tunnel exited");
|
||||
tunnelThread = null;
|
||||
}
|
||||
});
|
||||
tunnelThread.setPriority(Thread.MAX_PRIORITY);
|
||||
tunnelThread.start();
|
||||
|
||||
Log.i(TAG, "Started tunnel thread");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void stopNative(ParcelFileDescriptor vpn, boolean clear) {
|
||||
Log.i(TAG, "Stop native clear=" + clear);
|
||||
try {
|
||||
jni_stop(vpn.getFd(), clear);
|
||||
} catch (Throwable ex) {
|
||||
// File descriptor might be closed
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
jni_stop(-1, clear);
|
||||
|
||||
if (tunnelThread != null) {
|
||||
Log.i(TAG, "Stopping tunnel thread");
|
||||
|
||||
jni_stop();
|
||||
|
||||
while (true)
|
||||
try {
|
||||
tunnelThread.join();
|
||||
break;
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
tunnelThread = null;
|
||||
|
||||
if (clear)
|
||||
jni_clear();
|
||||
|
||||
Log.i(TAG, "Stopped tunnel thread");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,8 @@
|
|||
|
||||
// Global variables
|
||||
|
||||
JavaVM *jvm = NULL;
|
||||
int pipefds[2];
|
||||
pthread_t thread_id = 0;
|
||||
int stopping = 0;
|
||||
pthread_mutex_t lock;
|
||||
char socks5_addr[INET6_ADDRSTRLEN + 1];
|
||||
int socks5_port = 0;
|
||||
|
@ -133,13 +132,21 @@ Java_eu_faircode_netguard_ServiceSinkhole_jni_1init(JNIEnv *env, jobject instanc
|
|||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_eu_faircode_netguard_ServiceSinkhole_jni_1start(
|
||||
JNIEnv *env, jobject instance, jint tun, jboolean fwd53, jint rcode, jint loglevel_) {
|
||||
JNIEnv *env, jobject instance, jint loglevel_) {
|
||||
|
||||
loglevel = loglevel_;
|
||||
max_tun_msg = 0;
|
||||
log_android(ANDROID_LOG_WARN,
|
||||
"Starting tun %d fwd53 %d level %d thread %x",
|
||||
tun, fwd53, loglevel, thread_id);
|
||||
stopping = 0;
|
||||
|
||||
log_android(ANDROID_LOG_WARN, "Starting level %d", loglevel);
|
||||
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_eu_faircode_netguard_ServiceSinkhole_jni_1run(
|
||||
JNIEnv *env, jobject instance, jint tun, jboolean fwd53, jint rcode) {
|
||||
|
||||
log_android(ANDROID_LOG_WARN, "Running tun %d fwd53 %d level %d", tun, fwd53, loglevel);
|
||||
|
||||
// Set blocking
|
||||
int flags = fcntl(tun, F_GETFL, 0);
|
||||
|
@ -147,52 +154,30 @@ Java_eu_faircode_netguard_ServiceSinkhole_jni_1start(
|
|||
log_android(ANDROID_LOG_ERROR, "fcntl tun ~O_NONBLOCK error %d: %s",
|
||||
errno, strerror(errno));
|
||||
|
||||
if (thread_id && pthread_kill(thread_id, 0) == 0)
|
||||
log_android(ANDROID_LOG_ERROR, "Already running thread %x", thread_id);
|
||||
else {
|
||||
jint rs = (*env)->GetJavaVM(env, &jvm);
|
||||
if (rs != JNI_OK)
|
||||
log_android(ANDROID_LOG_ERROR, "GetJavaVM failed");
|
||||
|
||||
// Get arguments
|
||||
struct arguments *args = malloc(sizeof(struct arguments));
|
||||
// args->env = will be set in thread
|
||||
args->instance = (*env)->NewGlobalRef(env, instance);
|
||||
args->tun = tun;
|
||||
args->fwd53 = fwd53;
|
||||
args->rcode = rcode;
|
||||
|
||||
// Start native thread
|
||||
int err = pthread_create(&thread_id, NULL, handle_events, (void *) args);
|
||||
if (err == 0)
|
||||
log_android(ANDROID_LOG_WARN, "Started thread %x", thread_id);
|
||||
else
|
||||
log_android(ANDROID_LOG_ERROR, "pthread_create error %d: %s", err, strerror(err));
|
||||
}
|
||||
// Get arguments
|
||||
struct arguments *args = malloc(sizeof(struct arguments));
|
||||
args->env = env;
|
||||
args->instance = instance;
|
||||
args->tun = tun;
|
||||
args->fwd53 = fwd53;
|
||||
args->rcode = rcode;
|
||||
handle_events(args);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_eu_faircode_netguard_ServiceSinkhole_jni_1stop(
|
||||
JNIEnv *env, jobject instance, jint tun, jboolean clr) {
|
||||
pthread_t t = thread_id;
|
||||
log_android(ANDROID_LOG_WARN, "Stop tun %d thread %x", tun, t);
|
||||
if (t && pthread_kill(t, 0) == 0) {
|
||||
log_android(ANDROID_LOG_WARN, "Write pipe thread %x", t);
|
||||
if (write(pipefds[1], "x", 1) < 0)
|
||||
log_android(ANDROID_LOG_WARN, "Write pipe error %d: %s", errno, strerror(errno));
|
||||
else {
|
||||
log_android(ANDROID_LOG_WARN, "Join thread %x", t);
|
||||
int err = pthread_join(t, NULL);
|
||||
if (err != 0)
|
||||
log_android(ANDROID_LOG_WARN, "pthread_join error %d: %s", err, strerror(err));
|
||||
}
|
||||
JNIEnv *env, jobject instance) {
|
||||
stopping = 1;
|
||||
|
||||
if (clr)
|
||||
clear();
|
||||
log_android(ANDROID_LOG_WARN, "Write pipe wakeup");
|
||||
if (write(pipefds[1], "w", 1) < 0)
|
||||
log_android(ANDROID_LOG_WARN, "Write pipe error %d: %s", errno, strerror(errno));
|
||||
}
|
||||
|
||||
log_android(ANDROID_LOG_WARN, "Stopped thread %x", t);
|
||||
} else
|
||||
log_android(ANDROID_LOG_WARN, "Not running thread %x", t);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_eu_faircode_netguard_ServiceSinkhole_jni_1clear(
|
||||
JNIEnv *env, jobject instance) {
|
||||
clear();
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
|
|
|
@ -19,9 +19,8 @@
|
|||
|
||||
#include "netguard.h"
|
||||
|
||||
extern JavaVM *jvm;
|
||||
extern int pipefds[2];
|
||||
extern pthread_t thread_id;
|
||||
extern int stopping;
|
||||
extern pthread_mutex_t lock;
|
||||
|
||||
struct ng_session *ng_session = NULL;
|
||||
|
@ -47,16 +46,7 @@ void clear() {
|
|||
|
||||
void *handle_events(void *a) {
|
||||
struct arguments *args = (struct arguments *) a;
|
||||
log_android(ANDROID_LOG_WARN, "Start events tun=%d thread %x", args->tun, thread_id);
|
||||
|
||||
// Attach to Java
|
||||
JNIEnv *env;
|
||||
jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
|
||||
if (rs != JNI_OK) {
|
||||
log_android(ANDROID_LOG_ERROR, "AttachCurrentThread failed");
|
||||
return NULL;
|
||||
}
|
||||
args->env = env;
|
||||
log_android(ANDROID_LOG_WARN, "Start events tun=%d", args->tun);
|
||||
|
||||
// Get max number of sessions
|
||||
int maxsessions = SESSION_MAX;
|
||||
|
@ -74,8 +64,6 @@ void *handle_events(void *a) {
|
|||
// Terminate existing sessions not allowed anymore
|
||||
check_allowed(args);
|
||||
|
||||
int stopping = 0;
|
||||
|
||||
// Open epoll file
|
||||
int epoll_fd = epoll_create(1);
|
||||
if (epoll_fd < 0) {
|
||||
|
@ -109,7 +97,7 @@ void *handle_events(void *a) {
|
|||
// Loop
|
||||
long long last_check = 0;
|
||||
while (!stopping) {
|
||||
log_android(ANDROID_LOG_DEBUG, "Loop thread %x", thread_id);
|
||||
log_android(ANDROID_LOG_DEBUG, "Loop");
|
||||
|
||||
int recheck = 0;
|
||||
int timeout = EPOLL_TIMEOUT;
|
||||
|
@ -204,15 +192,14 @@ void *handle_events(void *a) {
|
|||
|
||||
if (ready < 0) {
|
||||
if (errno == EINTR) {
|
||||
log_android(ANDROID_LOG_DEBUG,
|
||||
"epoll interrupted tun %d thread %x", args->tun, thread_id);
|
||||
log_android(ANDROID_LOG_DEBUG, "epoll interrupted tun %d", args->tun);
|
||||
continue;
|
||||
} else {
|
||||
log_android(ANDROID_LOG_ERROR,
|
||||
"epoll tun %d thread %x error %d: %s",
|
||||
args->tun, thread_id, errno, strerror(errno));
|
||||
report_exit(args, "epoll tun %d thread %x error %d: %s",
|
||||
args->tun, thread_id, errno, strerror(errno));
|
||||
"epoll tun %d error %d: %s",
|
||||
args->tun, errno, strerror(errno));
|
||||
report_exit(args, "epoll tun %d error %d: %s",
|
||||
args->tun, errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +216,6 @@ void *handle_events(void *a) {
|
|||
for (int i = 0; i < ready; i++) {
|
||||
if (ev[i].data.ptr == &ev_pipe) {
|
||||
// Check pipe
|
||||
stopping = 1;
|
||||
uint8_t buffer[1];
|
||||
if (read(pipefds[0], buffer, 1) < 0)
|
||||
log_android(ANDROID_LOG_WARN, "Read pipe error %d: %s",
|
||||
|
@ -292,18 +278,10 @@ void *handle_events(void *a) {
|
|||
log_android(ANDROID_LOG_ERROR,
|
||||
"epoll close error %d: %s", errno, strerror(errno));
|
||||
|
||||
(*env)->DeleteGlobalRef(env, args->instance);
|
||||
|
||||
// Detach from Java
|
||||
rs = (*jvm)->DetachCurrentThread(jvm);
|
||||
if (rs != JNI_OK)
|
||||
log_android(ANDROID_LOG_ERROR, "DetachCurrentThread failed");
|
||||
|
||||
// Cleanup
|
||||
free(args);
|
||||
|
||||
log_android(ANDROID_LOG_WARN, "Stopped events tun=%d thread %x", args->tun, thread_id);
|
||||
thread_id = 0;
|
||||
log_android(ANDROID_LOG_WARN, "Stopped events tun=%d", args->tun);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue