123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /*
- * Copyright (C) 2012-2014 Tobias Brunner
- * Copyright (C) 2012 Giuliano Grassi
- * Copyright (C) 2012 Ralf Sager
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
- #include "vpnservice_builder.h"
- #include "android_jni.h"
- #include <utils/debug.h>
- #include <library.h>
- typedef struct private_vpnservice_builder_t private_vpnservice_builder_t;
- /**
- * private data of vpnservice_builder
- */
- struct private_vpnservice_builder_t {
- /**
- * public interface
- */
- vpnservice_builder_t public;
- /**
- * Java object
- */
- jobject builder;
- };
- METHOD(vpnservice_builder_t, add_address, bool,
- private_vpnservice_builder_t *this, host_t *addr)
- {
- JNIEnv *env;
- jmethodID method_id;
- jstring str;
- char buf[INET6_ADDRSTRLEN];
- int prefix;
- androidjni_attach_thread(&env);
- DBG2(DBG_LIB, "builder: adding interface address %H", addr);
- prefix = addr->get_family(addr) == AF_INET ? 32 : 128;
- if (snprintf(buf, sizeof(buf), "%H", addr) >= sizeof(buf))
- {
- goto failed;
- }
- method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
- "addAddress", "(Ljava/lang/String;I)Z");
- if (!method_id)
- {
- goto failed;
- }
- str = (*env)->NewStringUTF(env, buf);
- if (!str)
- {
- goto failed;
- }
- if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str, prefix))
- {
- goto failed;
- }
- androidjni_detach_thread();
- return TRUE;
- failed:
- DBG1(DBG_LIB, "builder: failed to add address");
- androidjni_exception_occurred(env);
- androidjni_detach_thread();
- return FALSE;
- }
- METHOD(vpnservice_builder_t, set_mtu, bool,
- private_vpnservice_builder_t *this, int mtu)
- {
- JNIEnv *env;
- jmethodID method_id;
- androidjni_attach_thread(&env);
- DBG2(DBG_LIB, "builder: setting MTU to %d", mtu);
- method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
- "setMtu", "(I)Z");
- if (!method_id)
- {
- goto failed;
- }
- if (!(*env)->CallBooleanMethod(env, this->builder, method_id, mtu))
- {
- goto failed;
- }
- androidjni_detach_thread();
- return TRUE;
- failed:
- DBG1(DBG_LIB, "builder: failed to set MTU");
- androidjni_exception_occurred(env);
- androidjni_detach_thread();
- return FALSE;
- }
- METHOD(vpnservice_builder_t, add_route, bool,
- private_vpnservice_builder_t *this, host_t *net, int prefix)
- {
- JNIEnv *env;
- jmethodID method_id;
- jstring str;
- char buf[INET6_ADDRSTRLEN];
- androidjni_attach_thread(&env);
- DBG2(DBG_LIB, "builder: adding route %+H/%d", net, prefix);
- if (snprintf(buf, sizeof(buf), "%+H", net) >= sizeof(buf))
- {
- goto failed;
- }
- method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
- "addRoute", "(Ljava/lang/String;I)Z");
- if (!method_id)
- {
- goto failed;
- }
- str = (*env)->NewStringUTF(env, buf);
- if (!str)
- {
- goto failed;
- }
- if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str, prefix))
- {
- goto failed;
- }
- androidjni_detach_thread();
- return TRUE;
- failed:
- DBG1(DBG_LIB, "builder: failed to add route");
- androidjni_exception_occurred(env);
- androidjni_detach_thread();
- return FALSE;
- }
- METHOD(vpnservice_builder_t, add_dns, bool,
- private_vpnservice_builder_t *this, host_t *dns)
- {
- JNIEnv *env;
- jmethodID method_id;
- jstring str;
- char buf[INET6_ADDRSTRLEN];
- androidjni_attach_thread(&env);
- DBG2(DBG_LIB, "builder: adding DNS server %H", dns);
- if (snprintf(buf, sizeof(buf), "%H", dns) >= sizeof(buf))
- {
- goto failed;
- }
- method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
- "addDnsServer", "(Ljava/lang/String;)Z");
- if (!method_id)
- {
- goto failed;
- }
- str = (*env)->NewStringUTF(env, buf);
- if (!str)
- {
- goto failed;
- }
- if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str))
- {
- goto failed;
- }
- androidjni_detach_thread();
- return TRUE;
- failed:
- DBG1(DBG_LIB, "builder: failed to add DNS server");
- androidjni_exception_occurred(env);
- androidjni_detach_thread();
- return FALSE;
- }
- /**
- * Establish or reestablish the TUN device
- */
- static int establish_internal(private_vpnservice_builder_t *this, char *method)
- {
- JNIEnv *env;
- jmethodID method_id;
- int fd;
- androidjni_attach_thread(&env);
- DBG2(DBG_LIB, "builder: building TUN device");
- method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
- method, "()I");
- if (!method_id)
- {
- goto failed;
- }
- fd = (*env)->CallIntMethod(env, this->builder, method_id);
- if (fd == -1)
- {
- goto failed;
- }
- androidjni_detach_thread();
- return fd;
- failed:
- DBG1(DBG_LIB, "builder: failed to build TUN device");
- androidjni_exception_occurred(env);
- androidjni_detach_thread();
- return -1;
- }
- METHOD(vpnservice_builder_t, establish, int,
- private_vpnservice_builder_t *this)
- {
- return establish_internal(this, "establish");
- }
- METHOD(vpnservice_builder_t, establish_no_dns, int,
- private_vpnservice_builder_t *this)
- {
- return establish_internal(this, "establishNoDns");
- }
- METHOD(vpnservice_builder_t, destroy, void,
- private_vpnservice_builder_t *this)
- {
- JNIEnv *env;
- androidjni_attach_thread(&env);
- (*env)->DeleteGlobalRef(env, this->builder);
- androidjni_detach_thread();
- free(this);
- }
- vpnservice_builder_t *vpnservice_builder_create(jobject builder)
- {
- JNIEnv *env;
- private_vpnservice_builder_t *this;
- INIT(this,
- .public = {
- .add_address = _add_address,
- .add_route = _add_route,
- .add_dns = _add_dns,
- .set_mtu = _set_mtu,
- .establish = _establish,
- .establish_no_dns = _establish_no_dns,
- .destroy = _destroy,
- },
- );
- androidjni_attach_thread(&env);
- this->builder = (*env)->NewGlobalRef(env, builder);
- androidjni_detach_thread();
- return &this->public;
- }
|