aboutsummaryrefslogtreecommitdiffstats
path: root/src/frontends
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-09-05 11:36:59 +0200
committerTobias Brunner <tobias@strongswan.org>2012-09-06 11:27:07 +0200
commitd7d2a5ec3852d17a137504f16a5d70b04164ec9c (patch)
tree220e7ac5dcd29345c7e1acc5ffe34371e8e0f0e4 /src/frontends
parent0326ceda64ba585094b8c4107d777484b5ca205d (diff)
downloadstrongswan-d7d2a5ec3852d17a137504f16a5d70b04164ec9c.tar.bz2
strongswan-d7d2a5ec3852d17a137504f16a5d70b04164ec9c.tar.xz
android: Properly handle reauthentication initiated by the client
Diffstat (limited to 'src/frontends')
-rw-r--r--src/frontends/android/jni/libandroidbridge/backend/android_service.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/jni/libandroidbridge/backend/android_service.c
index f62aea0e8..ba4717359 100644
--- a/src/frontends/android/jni/libandroidbridge/backend/android_service.c
+++ b/src/frontends/android/jni/libandroidbridge/backend/android_service.c
@@ -149,6 +149,10 @@ static job_requeue_t handle_plain(private_android_service_t *this)
ssize_t len;
int tunfd;
bool old;
+ timeval_t tv = {
+ /* check every second if tunfd is still valid */
+ .tv_sec = 1,
+ };
FD_ZERO(&set);
@@ -163,7 +167,7 @@ static job_requeue_t handle_plain(private_android_service_t *this)
this->lock->unlock(this->lock);
old = thread_cancelability(TRUE);
- len = select(tunfd + 1, &set, NULL, NULL, NULL);
+ len = select(tunfd + 1, &set, NULL, NULL, &tv);
thread_cancelability(old);
if (len < 0)
@@ -171,6 +175,10 @@ static job_requeue_t handle_plain(private_android_service_t *this)
DBG1(DBG_DMN, "select on TUN device failed: %s", strerror(errno));
return JOB_REQUEUE_NONE;
}
+ else if (len == 0)
+ { /* timeout, check again right away */
+ return JOB_REQUEUE_DIRECT;
+ }
raw = chunk_alloc(TUN_DEFAULT_MTU);
len = read(tunfd, raw.ptr, raw.len);
@@ -251,7 +259,7 @@ static bool setup_tun_device(private_android_service_t *this,
{
vpnservice_builder_t *builder;
enumerator_t *enumerator;
- bool vip_found = FALSE;
+ bool vip_found = FALSE, already_registered = FALSE;
host_t *vip;
int tunfd;
@@ -292,21 +300,29 @@ static bool setup_tun_device(private_android_service_t *this,
}
this->lock->write_lock(this->lock);
+ if (this->tunfd > 0)
+ { /* close previously opened TUN device */
+ close(this->tunfd);
+ already_registered = true;
+ }
this->tunfd = tunfd;
this->lock->unlock(this->lock);
DBG1(DBG_DMN, "successfully created TUN device");
- charon->receiver->add_esp_cb(charon->receiver,
+ if (!already_registered)
+ {
+ charon->receiver->add_esp_cb(charon->receiver,
(receiver_esp_cb_t)receiver_esp_cb, NULL);
- ipsec->processor->register_inbound(ipsec->processor,
+ ipsec->processor->register_inbound(ipsec->processor,
(ipsec_inbound_cb_t)deliver_plain, this);
- ipsec->processor->register_outbound(ipsec->processor,
+ ipsec->processor->register_outbound(ipsec->processor,
(ipsec_outbound_cb_t)send_esp, NULL);
- lib->processor->queue_job(lib->processor,
- (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this,
+ lib->processor->queue_job(lib->processor,
+ (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this,
NULL, (callback_job_cancel_t)return_false));
+ }
return TRUE;
}
@@ -360,6 +376,10 @@ METHOD(listener_t, child_updown, bool,
}
else
{
+ if (ike_sa->has_condition(ike_sa, COND_REAUTHENTICATING))
+ { /* we ignore this during reauthentication */
+ return TRUE;
+ }
close_tun_device(this);
charonservice->update_status(charonservice,
CHARONSERVICE_CHILD_STATE_DOWN);
@@ -429,6 +449,20 @@ METHOD(listener_t, ike_rekey, bool,
return TRUE;
}
+METHOD(listener_t, ike_reestablish, bool,
+ private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
+{
+ if (this->ike_sa == old)
+ {
+ this->ike_sa = new;
+ /* re-register hooks to detect initiation failures */
+ this->public.listener.ike_updown = _ike_updown;
+ this->public.listener.ike_state_change = _ike_state_change;
+ /* the TUN device will be closed when the new CHILD_SA is established */
+ }
+ return TRUE;
+}
+
static job_requeue_t initiate(private_android_service_t *this)
{
identification_t *gateway, *user;
@@ -577,6 +611,7 @@ android_service_t *android_service_create(android_creds_t *creds, char *type,
.public = {
.listener = {
.ike_rekey = _ike_rekey,
+ .ike_reestablish = _ike_reestablish,
.ike_updown = _ike_updown,
.ike_state_change = _ike_state_change,
.child_updown = _child_updown,