diff options
Diffstat (limited to 'tunnel/tools/libwg-go/jni.c')
-rw-r--r-- | tunnel/tools/libwg-go/jni.c | 101 |
1 files changed, 96 insertions, 5 deletions
diff --git a/tunnel/tools/libwg-go/jni.c b/tunnel/tools/libwg-go/jni.c index 121729a7..5dd20ed2 100644 --- a/tunnel/tools/libwg-go/jni.c +++ b/tunnel/tools/libwg-go/jni.c @@ -3,40 +3,105 @@ * Copyright © 2017-2021 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */ +#include <assert.h> #include <jni.h> #include <stdlib.h> #include <string.h> +#include <android/log.h> + +#define TAG "WireGuard/GoBackend" struct go_string { const char *str; long n; }; -extern int wgTurnOn(struct go_string ifname, int tun_fd, struct go_string settings); -extern void wgTurnOff(int handle); +extern int wgTurnOn(struct go_string ifname, int tun_fd, struct go_string settings, void *eventHandler); +extern int wgTurnOnDhcp(struct go_string ifname, struct go_string settings, void *eventHandler); +extern void wgSetFd(int handle, int tun_fd); +extern void *wgTurnOff(int handle); extern int wgGetSocketV4(int handle); extern int wgGetSocketV6(int handle); extern char *wgGetConfig(int handle); extern char *wgVersion(); extern int wgStartGrpc(); +extern void wgOnEvent(void *eventHandler, const char *event); + +static JavaVM *gVm; +static jclass gEventHandlerClass; +static jmethodID gOnEventMethod; -JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOn(JNIEnv *env, jclass c, jstring ifname, jint tun_fd, jstring settings) +JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) +{ + JNIEnv* env; + char buf[128]; + + __android_log_write(ANDROID_LOG_ERROR, TAG, "JNI_OnLoad"); + + gVm = vm; + if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) { + __android_log_write(ANDROID_LOG_ERROR, TAG, "GetEnv error"); + return JNI_ERR; + } + + sprintf(buf, "GetEnv FindClass %p", (*env)->FindClass); + __android_log_write(ANDROID_LOG_ERROR, TAG, buf); + gEventHandlerClass = (*env)->FindClass(env, "com/wireguard/android/backend/EventHandler"); + sprintf(buf, "gEventHandlerClass %p", gEventHandlerClass); + __android_log_write(ANDROID_LOG_ERROR, TAG, buf); + + gOnEventMethod = (*env)->GetMethodID(env, gEventHandlerClass, "onEvent", "(Ljava/lang/String;)V"); + sprintf(buf, "gOnEventMethod %p", gOnEventMethod); + __android_log_write(ANDROID_LOG_ERROR, TAG, buf); + //assert(gOnEventMethod); + + return JNI_VERSION_1_6; +} + +JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOn(JNIEnv *env, jclass c, jstring ifname, jint tun_fd, jstring settings, jobject eventHandler) { const char *ifname_str = (*env)->GetStringUTFChars(env, ifname, 0); size_t ifname_len = (*env)->GetStringUTFLength(env, ifname); const char *settings_str = (*env)->GetStringUTFChars(env, settings, 0); size_t settings_len = (*env)->GetStringUTFLength(env, settings); + jobject event_handler = (*env)->NewGlobalRef(env, eventHandler); int ret = wgTurnOn((struct go_string){ .str = ifname_str, .n = ifname_len }, tun_fd, (struct go_string){ .str = settings_str, .n = settings_len - }); + }, event_handler); (*env)->ReleaseStringUTFChars(env, ifname, ifname_str); (*env)->ReleaseStringUTFChars(env, settings, settings_str); return ret; } +JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOnDhcp(JNIEnv *env, jclass c, jstring ifname, jstring settings, jobject eventHandler) +{ + const char *ifname_str = (*env)->GetStringUTFChars(env, ifname, 0); + size_t ifname_len = (*env)->GetStringUTFLength(env, ifname); + const char *settings_str = (*env)->GetStringUTFChars(env, settings, 0); + size_t settings_len = (*env)->GetStringUTFLength(env, settings); + jobject event_handler = (*env)->NewGlobalRef(env, eventHandler); + int ret = wgTurnOnDhcp((struct go_string){ + .str = ifname_str, + .n = ifname_len + }, (struct go_string){ + .str = settings_str, + .n = settings_len + }, event_handler); + (*env)->ReleaseStringUTFChars(env, ifname, ifname_str); + (*env)->ReleaseStringUTFChars(env, settings, settings_str); + return ret; +} + +JNIEXPORT void JNICALL Java_com_wireguard_android_backend_GoBackend_wgSetFd(JNIEnv *env, jclass c, jint handle, jint tun_fd) +{ + wgSetFd(handle, tun_fd); +} + JNIEXPORT void JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOff(JNIEnv *env, jclass c, jint handle) { - wgTurnOff(handle); + jobject event_handler = wgTurnOff(handle); + if (event_handler) + (*env)->DeleteGlobalRef(env, event_handler); } JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgGetSocketV4(JNIEnv *env, jclass c, jint handle) @@ -82,3 +147,29 @@ JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgStartGrpc( (*env)->ReleaseStringUTFChars(env, sockname, sockname_str); return res; } + +void wgOnEvent(void *eventHandler, const char *event) +{ + JavaVMAttachArgs attachArgs = { JNI_VERSION_1_6, NULL, NULL }; + jobject jEventHandler = eventHandler; + JNIEnv *env; + char buf[128]; + + __android_log_write(ANDROID_LOG_ERROR, TAG, "wgOnEvent enter 2"); + jint rs = (*gVm)->AttachCurrentThread(gVm, &env, &attachArgs); + + sprintf(buf, "AttachCurrentThread %i %p", rs, env); + __android_log_write(ANDROID_LOG_ERROR, TAG, buf); + assert (rs == JNI_OK); + jstring jevent = (*env)->NewStringUTF(env, event); + sprintf(buf, "NewStringUTF %p", jevent); + __android_log_write(ANDROID_LOG_ERROR, TAG, buf); + //free(event); + sprintf(buf, "CallVoidMethod %p %p %p %p", env, jEventHandler, gOnEventMethod, jevent); + __android_log_write(ANDROID_LOG_ERROR, TAG, buf); + (*env)->CallVoidMethod(env, jEventHandler, gOnEventMethod, jevent); + /* sprintf(buf, "CallVoidMethod"); */ + /* __android_log_write(ANDROID_LOG_ERROR, TAG, buf); */ + // TODO free jevent? + __android_log_write(ANDROID_LOG_ERROR, TAG, "wgOnEvent end"); +} |