*/
android_service_t *service;
+ /**
+ * VpnService builder (accessed via JNI)
+ */
+ vpnservice_builder_t *builder;
+
/**
* CharonVpnService reference
*/
return NULL;
}
+METHOD(charonservice_t, get_vpnservice_builder, vpnservice_builder_t*,
+ private_charonservice_t *this)
+{
+ return this->builder;
+}
+
/**
* Initiate a new connection
*
/**
* Initialize the charonservice object
*/
-static void charonservice_init(JNIEnv *env, jobject service)
+static void charonservice_init(JNIEnv *env, jobject service, jobject builder)
{
private_charonservice_t *this;
static plugin_feature_t features[] = {
.update_status = _update_status,
.bypass_socket = _bypass_socket,
.get_trusted_certificates = _get_trusted_certificates,
+ .get_vpnservice_builder = _get_vpnservice_builder,
},
.creds = android_creds_create(),
+ .builder = vpnservice_builder_create(builder),
.vpn_service = (*env)->NewGlobalRef(env, service),
);
charonservice = &this->public;
{
private_charonservice_t *this = (private_charonservice_t*)charonservice;
+ this->builder->destroy(this->builder);
this->creds->destroy(this->creds);
(*env)->DeleteGlobalRef(env, this->vpn_service);
free(this);
/**
* Initialize charon and the libraries via JNI
*/
-JNI_METHOD(CharonVpnService, initializeCharon, void)
+JNI_METHOD(CharonVpnService, initializeCharon, void,
+ jobject builder)
{
struct sigaction action;
return;
}
- charonservice_init(env, this);
+ charonservice_init(env, this, builder);
if (!libcharon_init("charon") ||
!charon->initialize(charon, PLUGINS))
--- /dev/null
+/*
+ * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012 Giuliano Grassi
+ * Copyright (C) 2012 Ralf Sager
+ * 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 <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[INET_ADDRSTRLEN];
+
+ androidjni_attach_thread(&env);
+
+ DBG2(DBG_LIB, "builder: adding interface address %H", addr);
+
+ if (addr->get_family(addr) != AF_INET)
+ {
+ goto failed;
+ }
+ 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, 32))
+ {
+ 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[INET_ADDRSTRLEN];
+
+ androidjni_attach_thread(&env);
+
+ DBG2(DBG_LIB, "builder: adding route %+H/%d", net, prefix);
+
+ if (net->get_family(net) != AF_INET)
+ {
+ goto failed;
+ }
+ 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[INET_ADDRSTRLEN];
+
+ androidjni_attach_thread(&env);
+
+ DBG2(DBG_LIB, "builder: adding DNS server %H", dns);
+
+ if (dns->get_family(dns) != AF_INET)
+ {
+ goto failed;
+ }
+ 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;
+}
+
+METHOD(vpnservice_builder_t, establish, int,
+ private_vpnservice_builder_t *this)
+{
+ 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,
+ "establish", "()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, 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,
+ .destroy = _destroy,
+ },
+ );
+
+ androidjni_attach_thread(&env);
+ this->builder = (*env)->NewGlobalRef(env, builder);
+ androidjni_detach_thread();
+
+ return &this->public;
+}
--- /dev/null
+/*
+ * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012 Giuliano Grassi
+ * Copyright (C) 2012 Ralf Sager
+ * 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.
+ */
+
+/**
+ * @defgroup vpnservice_builder vpnservice_builder
+ * @{ @ingroup libandroidbridge
+ */
+
+#ifndef VPNSERVICE_BUILDER_H_
+#define VPNSERVICE_BUILDER_H_
+
+#include <jni.h>
+
+#include <library.h>
+#include <utils/host.h>
+
+typedef struct vpnservice_builder_t vpnservice_builder_t;
+
+/**
+ * VpnService.Builder, used to build a TUN device.
+ *
+ * Communicates with CharonVpnService.BuilderAdapter via JNI
+ */
+struct vpnservice_builder_t {
+
+ /**
+ * Add an interface address
+ *
+ * @param addr the desired interface address
+ * @return TRUE on success
+ */
+ bool (*add_address)(vpnservice_builder_t *this, host_t *addr);
+
+ /**
+ * Add a route
+ *
+ * @param net the network address
+ * @param prefix_length the prefix length
+ * @return TRUE on success
+ */
+ bool (*add_route)(vpnservice_builder_t *this, host_t *net, int prefix);
+
+ /**
+ * Add a DNS server
+ *
+ * @param dns the address of the DNS server
+ * @return TRUE on success
+ */
+ bool (*add_dns)(vpnservice_builder_t *this, host_t *dns);
+
+ /**
+ * Set the MTU for the TUN device
+ *
+ * @param mtu the MTU to set
+ * @return TRUE on success
+ */
+ bool (*set_mtu)(vpnservice_builder_t *this, int mtu);
+
+ /**
+ * Build the TUN device
+ *
+ * @return the TUN file descriptor, -1 if failed
+ */
+ int (*establish)(vpnservice_builder_t *this);
+
+ /**
+ * Destroy a vpnservice_builder
+ */
+ void (*destroy)(vpnservice_builder_t *this);
+
+};
+
+/**
+ * Create a vpnservice_builder instance
+ *
+ * @param builder CharonVpnService.BuilderAdapter object
+ * @return vpnservice_builder_t instance
+ */
+vpnservice_builder_t *vpnservice_builder_create(jobject builder);
+
+#endif /** VPNSERVICE_BUILDER_H_ @}*/