From: Tobias Brunner Date: Wed, 16 Jul 2014 10:38:44 +0000 (+0200) Subject: bus: Add ike_reestablish_pre hook, called before DNS resolution X-Git-Tag: 5.2.1dr1~115^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=614359a7d5bedb5d750bac33fdd4b335dde451e5;p=thirdparty%2Fstrongswan.git bus: Add ike_reestablish_pre hook, called before DNS resolution The old hook is renamed to ike_reestablish_post and is now also called when the initiation of the new IKE_SA failed. --- diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/jni/libandroidbridge/backend/android_service.c index d73dc45825..a6a24dba97 100644 --- a/src/frontends/android/jni/libandroidbridge/backend/android_service.c +++ b/src/frontends/android/jni/libandroidbridge/backend/android_service.c @@ -445,10 +445,11 @@ 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) +METHOD(listener_t, ike_reestablish_post, bool, + private_android_service_t *this, ike_sa_t *old, ike_sa_t *new, + bool initiated) { - if (this->ike_sa == old) + if (this->ike_sa == old && initiated) { this->ike_sa = new; /* re-register hook to detect initiation failures */ @@ -655,7 +656,7 @@ android_service_t *android_service_create(android_creds_t *creds, char *type, .public = { .listener = { .ike_rekey = _ike_rekey, - .ike_reestablish = _ike_reestablish, + .ike_reestablish_post = _ike_reestablish_post, .ike_updown = _ike_updown, .child_updown = _child_updown, .alert = _alert, diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index d1c138cd19..cb59f976bd 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -755,7 +755,7 @@ METHOD(bus_t, ike_rekey, void, this->mutex->unlock(this->mutex); } -METHOD(bus_t, ike_reestablish, void, +METHOD(bus_t, ike_reestablish_pre, void, private_bus_t *this, ike_sa_t *old, ike_sa_t *new) { enumerator_t *enumerator; @@ -766,12 +766,40 @@ METHOD(bus_t, ike_reestablish, void, enumerator = this->listeners->create_enumerator(this->listeners); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->calling || !entry->listener->ike_reestablish) + if (entry->calling || !entry->listener->ike_reestablish_pre) { continue; } entry->calling++; - keep = entry->listener->ike_reestablish(entry->listener, old, new); + keep = entry->listener->ike_reestablish_pre(entry->listener, old, new); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +METHOD(bus_t, ike_reestablish_post, void, + private_bus_t *this, ike_sa_t *old, ike_sa_t *new, bool initiated) +{ + enumerator_t *enumerator; + entry_t *entry; + bool keep; + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->ike_reestablish_post) + { + continue; + } + entry->calling++; + keep = entry->listener->ike_reestablish_post(entry->listener, old, new, + initiated); entry->calling--; if (!keep) { @@ -978,7 +1006,8 @@ bus_t *bus_create() .child_keys = _child_keys, .ike_updown = _ike_updown, .ike_rekey = _ike_rekey, - .ike_reestablish = _ike_reestablish, + .ike_reestablish_pre = _ike_reestablish_pre, + .ike_reestablish_post = _ike_reestablish_post, .child_updown = _child_updown, .child_rekey = _child_rekey, .authorize = _authorize, diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h index 1d708c5a51..1a6711a411 100644 --- a/src/libcharon/bus/bus.h +++ b/src/libcharon/bus/bus.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2014 Tobias Brunner * Copyright (C) 2006-2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -380,12 +380,23 @@ struct bus_t { void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new); /** - * IKE_SA reestablishing hook. + * IKE_SA reestablishing hook (before resolving hosts). * * @param old reestablished and obsolete IKE_SA * @param new new IKE_SA replacing old */ - void (*ike_reestablish)(bus_t *this, ike_sa_t *old, ike_sa_t *new); + void (*ike_reestablish_pre)(bus_t *this, ike_sa_t *old, ike_sa_t *new); + + /** + * IKE_SA reestablishing hook (after configuring and initiating the new + * IKE_SA). + * + * @param old reestablished and obsolete IKE_SA + * @param new new IKE_SA replacing old + * @param initiated TRUE if initiated successfully, FALSE otherwise + */ + void (*ike_reestablish_post)(bus_t *this, ike_sa_t *old, ike_sa_t *new, + bool initiated); /** * CHILD_SA up/down hook. diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h index abcc765e59..0910cb3617 100644 --- a/src/libcharon/bus/listeners/listener.h +++ b/src/libcharon/bus/listeners/listener.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2011-2014 Tobias Brunner * Copyright (C) 2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -126,6 +127,19 @@ struct listener_t { */ bool (*ike_rekey)(listener_t *this, ike_sa_t *old, ike_sa_t *new); + /** + * Hook called when an initiator reestablishes an IKE_SA. + * + * This is invoked right after creating the new IKE_SA and setting the + * peer_cfg (and the old hosts), but before resolving the hosts anew. + * It is not invoked on the responder. + * + * @param old IKE_SA getting reestablished (is destroyed) + * @param new new IKE_SA replacing old (gets established) + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*ike_reestablish_pre)(listener_t *this, ike_sa_t *old, ike_sa_t *new); + /** * Hook called when an initiator reestablishes an IKE_SA. * @@ -134,9 +148,11 @@ struct listener_t { * * @param old IKE_SA getting reestablished (is destroyed) * @param new new IKE_SA replacing old (gets established) + * @param initiated TRUE if initiation was successful, FALSE otherwise * @return TRUE to stay registered, FALSE to unregister */ - bool (*ike_reestablish)(listener_t *this, ike_sa_t *old, ike_sa_t *new); + bool (*ike_reestablish_post)(listener_t *this, ike_sa_t *old, + ike_sa_t *new, bool initiated); /** * Hook called when a CHILD_SA gets up or down. diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index c338cdaefa..fddd83c63b 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1650,6 +1650,7 @@ METHOD(ike_sa_t, reestablish, status_t, new->set_other_host(new, host->clone(host)); host = this->my_host; new->set_my_host(new, host->clone(host)); + charon->bus->ike_reestablish_pre(charon->bus, &this->public, new); /* resolve hosts but use the old addresses above as fallback */ resolve_hosts((private_ike_sa_t*)new); /* if we already have a virtual IP, we reuse it */ @@ -1734,12 +1735,15 @@ METHOD(ike_sa_t, reestablish, status_t, if (status == DESTROY_ME) { + charon->bus->ike_reestablish_post(charon->bus, &this->public, new, + FALSE); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new); status = FAILED; } else { - charon->bus->ike_reestablish(charon->bus, &this->public, new); + charon->bus->ike_reestablish_post(charon->bus, &this->public, new, + TRUE); charon->ike_sa_manager->checkin(charon->ike_sa_manager, new); status = SUCCESS; }