Native poll

This commit is contained in:
M66B 2016-01-12 17:19:27 +01:00
parent fa5b8c974a
commit 1542e29ccd
2 changed files with 42 additions and 24 deletions

View File

@ -85,6 +85,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
private Object subscriptionsChangedListener = null; private Object subscriptionsChangedListener = null;
private ParcelFileDescriptor vpn = null; private ParcelFileDescriptor vpn = null;
private Thread receiveThread = null; private Thread receiveThread = null;
private Thread pollThread = null;
private volatile Looper mServiceLooper; private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler; private volatile ServiceHandler mServiceHandler;
@ -120,7 +121,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
private native void jni_decode(byte[] buffer, int length); private native void jni_decode(byte[] buffer, int length);
private native void jni_receive(int fd); private native void jni_poll();
static { static {
System.loadLibrary("netguard"); System.loadLibrary("netguard");
@ -728,8 +729,22 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
} }
} }
} }
}, getString(R.string.app_name) + " debug"); }, getString(R.string.app_name) + " receive");
receiveThread.start(); receiveThread.start();
pollThread = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted())
try {
Thread.sleep(5000);
jni_poll();
} catch (InterruptedException ignore) {
break;
}
}
}, getString(R.string.app_name) + " poll");
pollThread.start();
} }
// Called from native code // Called from native code
@ -748,6 +763,8 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
private void stopReceiving() { private void stopReceiving() {
if (receiveThread != null) if (receiveThread != null)
receiveThread.interrupt(); receiveThread.interrupt();
if (pollThread != null)
pollThread.interrupt();
} }
private BroadcastReceiver interactiveStateReceiver = new BroadcastReceiver() { private BroadcastReceiver interactiveStateReceiver = new BroadcastReceiver() {

View File

@ -8,6 +8,7 @@
#include <netinet/ip6.h> #include <netinet/ip6.h>
#include <netinet/udp.h> #include <netinet/udp.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <pthread.h>
// This should go into a header file later // This should go into a header file later
@ -47,12 +48,18 @@ char *hex(jbyte *, int);
int tun; int tun;
struct connection *connection = NULL; struct connection *connection = NULL;
pthread_mutex_t poll_lock;
// JNI interface // JNI interface
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_eu_faircode_netguard_SinkholeService_jni_1init(JNIEnv *env, jobject instance) { Java_eu_faircode_netguard_SinkholeService_jni_1init(JNIEnv *env, jobject instance) {
__android_log_print(ANDROID_LOG_INFO, TAG, "Init"); __android_log_print(ANDROID_LOG_INFO, TAG, "Init");
if (pthread_mutex_init(&poll_lock, NULL) != 0)
__android_log_print(ANDROID_LOG_ERROR, TAG, "Mutex init error %d: %s",
errno, strerror(errno));
// TODO pthread_mutex_destroy
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
@ -70,26 +77,17 @@ Java_eu_faircode_netguard_SinkholeService_jni_1decode(JNIEnv *env, jobject insta
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_eu_faircode_netguard_SinkholeService_jni_1receive(JNIEnv *env, jobject instance, jint fd) { Java_eu_faircode_netguard_SinkholeService_jni_1poll(JNIEnv *env, jobject instance) {
int len; __android_log_print(ANDROID_LOG_DEBUG, TAG, "Poll");
jbyte buffer[MAXPKT]; poll();
while (1) {
len = read(fd, buffer, sizeof(buffer));
if (len < 0) {
__android_log_print(ANDROID_LOG_WARN, TAG, "Receive error=%d", len);
return;
} else if (len > 0)
decode(env, instance, buffer, len);
else
__android_log_print(ANDROID_LOG_WARN, TAG, "Nothing received");
}
} }
// Private functions // Private functions
void poll() { void poll() {
if (pthread_mutex_lock(&poll_lock) != 0)
__android_log_print(ANDROID_LOG_ERROR, TAG, "Mutex lock error %d: %s",
errno, strerror(errno));
time_t now = time(NULL); time_t now = time(NULL);
struct connection *last = NULL; struct connection *last = NULL;
@ -207,9 +205,8 @@ void poll() {
// Send packet // Send packet
__android_log_print(ANDROID_LOG_DEBUG, TAG, __android_log_print(ANDROID_LOG_DEBUG, TAG,
"Sending SYN+ACK to tun %s/%u ack %u len %d %s", "Sending SYN+ACK to tun %s/%u ack %u",
to, ntohs(tcp->dest), ntohl(tcp->ack_seq), len, to, ntohs(tcp->dest), ntohl(tcp->ack_seq));
hex(buffer, len));
if (write(tun, buffer, len) < 0) { if (write(tun, buffer, len) < 0) {
// TODO // TODO
__android_log_print(ANDROID_LOG_ERROR, TAG, "write error %d: %s", __android_log_print(ANDROID_LOG_ERROR, TAG, "write error %d: %s",
@ -228,6 +225,10 @@ void poll() {
cur = cur->next; cur = cur->next;
} }
if (pthread_mutex_unlock(&poll_lock) != 0)
__android_log_print(ANDROID_LOG_ERROR, TAG, "Mutex unlock error %d: %s",
errno, strerror(errno));
} }
void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) { void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
@ -237,7 +238,7 @@ void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
return; return;
// Copy buffer // Copy buffer
jbyte *copy = malloc(len); // TODO free jbyte *copy = malloc(len); // TODO check/free
memcpy(copy, buffer, len); memcpy(copy, buffer, len);
// Get headers // Get headers
@ -263,7 +264,7 @@ void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
ntohs(tcphdr->dest), ntohl(tcphdr->seq)); ntohs(tcphdr->dest), ntohl(tcphdr->seq));
// Register connection // Register connection
struct connection *syn = malloc(sizeof(struct connection)); struct connection *syn = malloc(sizeof(struct connection)); // TODO check/free
syn->time = time(NULL); syn->time = time(NULL);
syn->remote_seq = ntohl(tcphdr->seq); syn->remote_seq = ntohl(tcphdr->seq);
syn->local_seq = 123; // TODO randomize syn->local_seq = 123; // TODO randomize