diff options
Diffstat (limited to 'src/charon/sa/tasks/ike_reauth.c')
-rw-r--r-- | src/charon/sa/tasks/ike_reauth.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/src/charon/sa/tasks/ike_reauth.c b/src/charon/sa/tasks/ike_reauth.c index 7b69a938f..47d5c2822 100644 --- a/src/charon/sa/tasks/ike_reauth.c +++ b/src/charon/sa/tasks/ike_reauth.c @@ -61,13 +61,21 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message) host_t *host; iterator_t *iterator; child_sa_t *child_sa; + peer_cfg_t *peer_cfg; /* process delete response first */ this->ike_delete->task.process(&this->ike_delete->task, message); + peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); + /* reestablish only if we have children */ iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa); - if (iterator->get_count(iterator) == 0) + if (iterator->get_count(iterator) == 0 +#ifdef ME + /* we allow a peer to reauth a mediation connection (without CHILD_SA) */ + && !peer_cfg->is_mediation(peer_cfg) +#endif /* ME */ + ) { DBG1(DBG_IKE, "unable to reestablish IKE_SA, no CHILD_SA to recreate"); iterator->destroy(iterator); @@ -76,7 +84,7 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message) new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, TRUE); - new->set_peer_cfg(new, this->ike_sa->get_peer_cfg(this->ike_sa)); + new->set_peer_cfg(new, peer_cfg); host = this->ike_sa->get_other_host(this->ike_sa); new->set_other_host(new, host->clone(host)); host = this->ike_sa->get_my_host(this->ike_sa); @@ -88,6 +96,20 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message) new->set_virtual_ip(new, TRUE, host); } +#ifdef ME + /* we initiate the new IKE_SA of the mediation connection without CHILD_SA */ + if (peer_cfg->is_mediation(peer_cfg)) + { + if (new->initiate(new, NULL) == DESTROY_ME) + { + charon->ike_sa_manager->checkin_and_destroy( + charon->ike_sa_manager, new); + DBG1(DBG_IKE, "reestablishing IKE_SA failed"); + return FAILED; + } + } +#endif /* ME */ + while (iterator->iterate(iterator, (void**)&child_sa)) { switch (child_sa->get_state(child_sa)) |