aboutsummaryrefslogtreecommitdiffstats
path: root/src/frontends/android/jni/libandroidbridge/backend/android_service.c
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-08-08 14:43:39 +0200
committerTobias Brunner <tobias@strongswan.org>2012-08-13 11:09:34 +0200
commita2993d72435970805f271231bf169e9c5a092508 (patch)
tree9ebfd4359f4caf9330d1e91118b5cb7674550bc7 /src/frontends/android/jni/libandroidbridge/backend/android_service.c
parent3a05756b423411a8dfba6c68adc4c85cbf1ec353 (diff)
downloadstrongswan-a2993d72435970805f271231bf169e9c5a092508.tar.bz2
strongswan-a2993d72435970805f271231bf169e9c5a092508.tar.xz
Create a TUN device via VpnService.Builder once the CHILD_SA is established
Diffstat (limited to 'src/frontends/android/jni/libandroidbridge/backend/android_service.c')
-rw-r--r--src/frontends/android/jni/libandroidbridge/backend/android_service.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/jni/libandroidbridge/backend/android_service.c
index 5c18924be..691d5fc6d 100644
--- a/src/frontends/android/jni/libandroidbridge/backend/android_service.c
+++ b/src/frontends/android/jni/libandroidbridge/backend/android_service.c
@@ -17,13 +17,17 @@
#include "android_service.h"
#include "../charonservice.h"
+#include "../vpnservice_builder.h"
#include <daemon.h>
#include <library.h>
#include <processing/jobs/callback_job.h>
+#include <threading/rwlock.h>
typedef struct private_android_service_t private_android_service_t;
+#define TUN_DEFAULT_MTU 1400
+
/**
* private data of Android service
*/
@@ -54,8 +58,72 @@ struct private_android_service_t {
*/
char *username;
+ /**
+ * lock to safely access the TUN device fd
+ */
+ rwlock_t *lock;
+
+ /**
+ * TUN device file descriptor
+ */
+ int tunfd;
+
};
+/**
+ * Setup a new TUN device for the supplied SAs.
+ * Additional information such as DNS servers are gathered in appropriate
+ * listeners asynchronously. To be sure every required bit of information is
+ * available this should be called after the CHILD_SA has been established.
+ */
+static bool setup_tun_device(private_android_service_t *this,
+ ike_sa_t *ike_sa, child_sa_t *child_sa)
+{
+ vpnservice_builder_t *builder;
+ int tunfd;
+
+ DBG1(DBG_DMN, "setting up TUN device for CHILD_SA %s{%u}",
+ child_sa->get_name(child_sa), child_sa->get_reqid(child_sa));
+
+ builder = charonservice->get_vpnservice_builder(charonservice);
+ if (!builder->set_mtu(builder, TUN_DEFAULT_MTU))
+ {
+ return FALSE;
+ }
+
+ tunfd = builder->establish(builder);
+ if (tunfd == -1)
+ {
+ return FALSE;
+ }
+
+ this->lock->write_lock(this->lock);
+ this->tunfd = tunfd;
+ this->lock->unlock(this->lock);
+
+ DBG1(DBG_DMN, "successfully created TUN device");
+ return TRUE;
+}
+
+/**
+ * Close the current tun device
+ */
+static void close_tun_device(private_android_service_t *this)
+{
+ int tunfd;
+
+ this->lock->write_lock(this->lock);
+ if (this->tunfd < 0)
+ { /* already closed (or never created) */
+ this->lock->unlock(this->lock);
+ return;
+ }
+ tunfd = this->tunfd;
+ this->tunfd = -1;
+ this->lock->unlock(this->lock);
+ close(tunfd);
+}
+
METHOD(listener_t, child_updown, bool,
private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
bool up)
@@ -67,11 +135,20 @@ METHOD(listener_t, child_updown, bool,
/* disable the hooks registered to catch initiation failures */
this->public.listener.ike_updown = NULL;
this->public.listener.ike_state_change = NULL;
+ if (!setup_tun_device(this, ike_sa, child_sa))
+ {
+ DBG1(DBG_DMN, "failed to setup TUN device");
+ charonservice->update_status(charonservice,
+ CHARONSERVICE_GENERIC_ERROR);
+ return FALSE;
+
+ }
charonservice->update_status(charonservice,
CHARONSERVICE_CHILD_STATE_UP);
}
else
{
+ close_tun_device(this);
charonservice->update_status(charonservice,
CHARONSERVICE_CHILD_STATE_DOWN);
return FALSE;
@@ -230,6 +307,9 @@ METHOD(android_service_t, destroy, void,
private_android_service_t *this)
{
charon->bus->remove_listener(charon->bus, &this->public.listener);
+ /* make sure the tun device is actually closed */
+ close_tun_device(this);
+ this->lock->destroy(this->lock);
free(this->local_address);
free(this->username);
free(this->gateway);
@@ -255,9 +335,11 @@ android_service_t *android_service_create(char *local_address, char *gateway,
},
.destroy = _destroy,
},
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
.local_address = local_address,
.username = username,
.gateway = gateway,
+ .tunfd = -1,
);
charon->bus->add_listener(charon->bus, &this->public.listener);