diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-05-21 12:07:17 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-05-21 15:49:25 +0200 |
commit | 1a624ff45a4dcab2167491ad3ecc2e6f3f2e22c8 (patch) | |
tree | 48b28d59f1320c27d0fa9a8bf1a6805e469e5103 /src/libcharon/sa/ikev1/phase1.c | |
parent | 17949695bfd986c1cf32eee0460f02528026bbb9 (diff) | |
download | strongswan-1a624ff45a4dcab2167491ad3ecc2e6f3f2e22c8.tar.bz2 strongswan-1a624ff45a4dcab2167491ad3ecc2e6f3f2e22c8.tar.xz |
Switch to alternative peer config in IKEv1 Main and Aggressive Mode.
Diffstat (limited to 'src/libcharon/sa/ikev1/phase1.c')
-rw-r--r-- | src/libcharon/sa/ikev1/phase1.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c index ec55d533d..709bc6cbc 100644 --- a/src/libcharon/sa/ikev1/phase1.c +++ b/src/libcharon/sa/ikev1/phase1.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2012 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2012 Martin Willi * Copyright (C) 2012 revosec AG * @@ -19,6 +22,7 @@ #include <sa/ikev1/keymat_v1.h> #include <encoding/payloads/ke_payload.h> #include <encoding/payloads/nonce_payload.h> +#include <utils/linked_list.h> typedef struct private_phase1_t private_phase1_t; @@ -38,6 +42,16 @@ struct private_phase1_t { ike_sa_t *ike_sa; /** + * Currently selected peer config + */ + peer_cfg_t *peer_cfg; + + /** + * Other possible peer config candidates + */ + linked_list_t *candidates; + + /** * Acting as initiator */ bool initiator; @@ -513,9 +527,22 @@ METHOD(phase1_t, select_config, peer_cfg_t*, identification_t *id) { enumerator_t *enumerator; - peer_cfg_t *current, *found = NULL; + peer_cfg_t *current; host_t *me, *other; + if (this->peer_cfg) + { /* try to find an alternative config */ + if (this->candidates->remove_first(this->candidates, + (void**)¤t) != SUCCESS) + { + DBG1(DBG_CFG, "no alternative config found"); + return NULL; + } + DBG1(DBG_CFG, "switching to peer config '%s'", + current->get_name(current)); + return current; + } + me = this->ike_sa->get_my_host(this->ike_sa); other = this->ike_sa->get_other_host(this->ike_sa); DBG1(DBG_CFG, "looking for %N peer configs matching %H...%H[%Y]", @@ -527,17 +554,27 @@ METHOD(phase1_t, select_config, peer_cfg_t*, if (check_auth_method(this, current, method) && current->use_aggressive(current) == aggressive) { - found = current->get_ref(current); - break; + current->get_ref(current); + if (!this->peer_cfg) + { + this->peer_cfg = current; + } + else + { + this->candidates->insert_last(this->candidates, current); + } } } enumerator->destroy(enumerator); - if (found) + if (this->peer_cfg) { - DBG2(DBG_CFG, "selected peer config \"%s\"", found->get_name(found)); + DBG1(DBG_CFG, "selected peer config \"%s\"", + this->peer_cfg->get_name(this->peer_cfg)); + return this->peer_cfg->get_ref(this->peer_cfg); } - return found; + DBG1(DBG_IKE, "no peer config found"); + return NULL; } METHOD(phase1_t, get_id, identification_t*, @@ -661,6 +698,9 @@ METHOD(phase1_t, get_nonce_ke, bool, METHOD(phase1_t, destroy, void, private_phase1_t *this) { + DESTROY_IF(this->peer_cfg); + this->candidates->destroy_offset(this->candidates, + offsetof(peer_cfg_t, destroy)); chunk_free(&this->sa_payload); DESTROY_IF(this->dh); free(this->dh_value.ptr); @@ -691,6 +731,7 @@ phase1_t *phase1_create(ike_sa_t *ike_sa, bool initiator) .get_nonce_ke = _get_nonce_ke, .destroy = _destroy, }, + .candidates = linked_list_create(), .ike_sa = ike_sa, .initiator = initiator, .keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa), |