From 71c707058862bb7c46633b425c3746c0325f3cb9 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 28 Apr 2015 14:50:11 +0200 Subject: [PATCH] ike-sa: Add redirect() method to actively redirect an IKE_SA --- src/libcharon/sa/ike_sa.c | 41 +++++++++++++++++++++++++++++++++++++++ src/libcharon/sa/ike_sa.h | 9 +++++++++ 2 files changed, 50 insertions(+) diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index f0c38efa8..6884bf249 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -57,6 +57,7 @@ #include #include #include +#include #ifdef ME #include @@ -2101,6 +2102,45 @@ METHOD(ike_sa_t, handle_redirect, bool, } } +METHOD(ike_sa_t, redirect, status_t, + private_ike_sa_t *this, identification_t *gateway) +{ + switch (this->state) + { + case IKE_CONNECTING: + case IKE_ESTABLISHED: + case IKE_REKEYING: + if (has_condition(this, COND_REDIRECTED)) + { /* IKE_SA already got redirected */ + return SUCCESS; + } + if (has_condition(this, COND_ORIGINAL_INITIATOR)) + { + DBG1(DBG_IKE, "unable to redirect IKE_SA as initiator"); + return FAILED; + } + if (this->version == IKEV1) + { + DBG1(DBG_IKE, "unable to redirect IKEv1 SA"); + return FAILED; + } + if (!supports_extension(this, EXT_IKE_REDIRECTION)) + { + DBG1(DBG_IKE, "client does not support IKE redirection"); + return FAILED; + } +#ifdef USE_IKEV2 + this->task_manager->queue_task(this->task_manager, + (task_t*)ike_redirect_create(&this->public, gateway)); +#endif + return this->task_manager->initiate(this->task_manager); + default: + DBG1(DBG_IKE, "unable to redirect IKE_SA in state %N", + ike_sa_state_names, this->state); + return INVALID_STATE; + } +} + METHOD(ike_sa_t, retransmit, status_t, private_ike_sa_t *this, u_int32_t message_id) { @@ -2694,6 +2734,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, .destroy = _destroy, .send_dpd = _send_dpd, .send_keepalive = _send_keepalive, + .redirect = _redirect, .handle_redirect = _handle_redirect, .get_redirected_from = _get_redirected_from, .get_keymat = _get_keymat, diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 32e9d65d5..08c19971f 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -852,6 +852,15 @@ struct ike_sa_t { */ void (*send_keepalive) (ike_sa_t *this, bool scheduled); + /** + * Redirect an active IKE_SA. + * + * @param gateway gateway ID (IP or FQDN) of the target + * @return state, including DESTROY_ME, if this IKE_SA MUST be + * destroyed + */ + status_t (*redirect)(ike_sa_t *this, identification_t *gateway); + /** * Handle a redirect request. *