diff options
author | Martin Willi <martin@revosec.ch> | 2014-10-23 16:52:25 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2015-02-20 13:34:49 +0100 |
commit | 38227d0e081975c6bed5163af22edddb338c825f (patch) | |
tree | 0b6cb1550d2c4aa791303f5cf20b569b4651ed3b /src | |
parent | e732fb11a915b5e760a8c1fbd1a5f12581912787 (diff) | |
download | strongswan-38227d0e081975c6bed5163af22edddb338c825f.tar.bz2 strongswan-38227d0e081975c6bed5163af22edddb338c825f.tar.xz |
ike: Maintain per-IKE_SA CHILD_SAs in the global CHILD_SA manager
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/processing/jobs/migrate_job.c | 19 | ||||
-rw-r--r-- | src/libcharon/sa/ike_sa.c | 65 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/ike_mobike.c | 27 |
3 files changed, 92 insertions, 19 deletions
diff --git a/src/libcharon/processing/jobs/migrate_job.c b/src/libcharon/processing/jobs/migrate_job.c index 2ebfc6714..311c4abe9 100644 --- a/src/libcharon/processing/jobs/migrate_job.c +++ b/src/libcharon/processing/jobs/migrate_job.c @@ -82,6 +82,7 @@ METHOD(job_t, execute, job_requeue_t, enumerator_t *children, *enumerator; child_sa_t *child_sa; host_t *host; + status_t status; linked_list_t *vips; children = ike_sa->create_child_sa_enumerator(ike_sa); @@ -113,11 +114,21 @@ METHOD(job_t, execute, job_requeue_t, } enumerator->destroy(enumerator); - if (child_sa->update(child_sa, this->local, this->remote, vips, - ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED) + status = child_sa->update(child_sa, this->local, this->remote, vips, + ike_sa->has_condition(ike_sa, COND_NAT_ANY)); + switch (status) { - ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE)); + case NOT_SUPPORTED: + ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa), + child_sa->get_spi(child_sa, TRUE)); + break; + case SUCCESS: + charon->child_sa_manager->remove(charon->child_sa_manager, + child_sa); + charon->child_sa_manager->add(charon->child_sa_manager, + child_sa, ike_sa); + default: + break; } charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); vips->destroy(vips); diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index d92b9df8e..54f22e61e 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -964,6 +964,10 @@ METHOD(ike_sa_t, update_hosts, void, enumerator = array_create_enumerator(this->child_sas); while (enumerator->enumerate(enumerator, &child_sa)) { + charon->child_sa_manager->remove(charon->child_sa_manager, child_sa); + charon->child_sa_manager->add(charon->child_sa_manager, + child_sa, &this->public); + if (child_sa->update(child_sa, this->my_host, this->other_host, vips, has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED) { @@ -971,6 +975,7 @@ METHOD(ike_sa_t, update_hosts, void, child_sa->get_protocol(child_sa), child_sa->get_spi(child_sa, TRUE)); } + } enumerator->destroy(enumerator); @@ -1444,6 +1449,8 @@ METHOD(ike_sa_t, add_child_sa, void, private_ike_sa_t *this, child_sa_t *child_sa) { array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa); + charon->child_sa_manager->add(charon->child_sa_manager, + child_sa, &this->public); } METHOD(ike_sa_t, get_child_sa, child_sa_t*, @@ -1471,16 +1478,58 @@ METHOD(ike_sa_t, get_child_count, int, return array_count(this->child_sas); } +/** + * Private data of a create_child_sa_enumerator() + */ +typedef struct { + /** implements enumerator */ + enumerator_t public; + /** inner array enumerator */ + enumerator_t *inner; + /** current item */ + child_sa_t *current; +} child_enumerator_t; + +METHOD(enumerator_t, child_enumerate, bool, + child_enumerator_t *this, child_sa_t **child_sa) +{ + if (this->inner->enumerate(this->inner, &this->current)) + { + *child_sa = this->current; + return TRUE; + } + return FALSE; +} + +METHOD(enumerator_t, child_enumerator_destroy, void, + child_enumerator_t *this) +{ + this->inner->destroy(this->inner); + free(this); +} + METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*, private_ike_sa_t *this) { - return array_create_enumerator(this->child_sas); + child_enumerator_t *enumerator; + + INIT(enumerator, + .public = { + .enumerate = (void*)_child_enumerate, + .destroy = _child_enumerator_destroy, + }, + .inner = array_create_enumerator(this->child_sas), + ); + return &enumerator->public; } METHOD(ike_sa_t, remove_child_sa, void, private_ike_sa_t *this, enumerator_t *enumerator) { - array_remove_at(this->child_sas, enumerator); + child_enumerator_t *ce = (child_enumerator_t*)enumerator; + + charon->child_sa_manager->remove(charon->child_sa_manager, ce->current); + array_remove_at(this->child_sas, ce->inner); } METHOD(ike_sa_t, rekey_child_sa, status_t, @@ -1513,13 +1562,13 @@ METHOD(ike_sa_t, destroy_child_sa, status_t, child_sa_t *child_sa; status_t status = NOT_FOUND; - enumerator = array_create_enumerator(this->child_sas); + enumerator = create_child_sa_enumerator(this); while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (child_sa->get_protocol(child_sa) == protocol && child_sa->get_spi(child_sa, TRUE) == spi) { - array_remove_at(this->child_sas, enumerator); + remove_child_sa(this, enumerator); child_sa->destroy(child_sa); status = SUCCESS; break; @@ -1771,7 +1820,7 @@ METHOD(ike_sa_t, reestablish, status_t, #endif /* ME */ { /* handle existing CHILD_SAs */ - enumerator = array_create_enumerator(this->child_sas); + enumerator = create_child_sa_enumerator(this); while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (has_condition(this, COND_REAUTHENTICATING)) @@ -1780,7 +1829,7 @@ METHOD(ike_sa_t, reestablish, status_t, { case CHILD_ROUTED: { /* move routed child directly */ - array_remove_at(this->child_sas, enumerator); + remove_child_sa(this, enumerator); new->add_child_sa(new, child_sa); action = ACTION_NONE; break; @@ -2251,7 +2300,8 @@ METHOD(ike_sa_t, inherit_post, void, /* adopt all children */ while (array_remove(other->child_sas, ARRAY_HEAD, &child_sa)) { - array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa); + charon->child_sa_manager->remove(charon->child_sa_manager, child_sa); + add_child_sa(this, child_sa); } /* move pending tasks to the new IKE_SA */ @@ -2305,6 +2355,7 @@ METHOD(ike_sa_t, destroy, void, * routes that the CHILD_SA tries to uninstall. */ while (array_remove(this->child_sas, ARRAY_TAIL, &child_sa)) { + charon->child_sa_manager->remove(charon->child_sa_manager, child_sa); child_sa->destroy(child_sa); } while (array_remove(this->my_vips, ARRAY_TAIL, &vip)) diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index d91fa5862..6295d7960 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -256,6 +256,7 @@ static void update_children(private_ike_mobike_t *this) enumerator_t *enumerator; child_sa_t *child_sa; linked_list_t *vips; + status_t status; host_t *host; vips = linked_list_create(); @@ -270,15 +271,25 @@ static void update_children(private_ike_mobike_t *this) enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa); while (enumerator->enumerate(enumerator, (void**)&child_sa)) { - if (child_sa->update(child_sa, - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), vips, - this->ike_sa->has_condition(this->ike_sa, - COND_NAT_ANY)) == NOT_SUPPORTED) + status = child_sa->update(child_sa, + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), vips, + this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)); + switch (status) { - this->ike_sa->rekey_child_sa(this->ike_sa, - child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE)); + case NOT_SUPPORTED: + this->ike_sa->rekey_child_sa(this->ike_sa, + child_sa->get_protocol(child_sa), + child_sa->get_spi(child_sa, TRUE)); + break; + case SUCCESS: + charon->child_sa_manager->remove(charon->child_sa_manager, + child_sa); + charon->child_sa_manager->add(charon->child_sa_manager, + child_sa, this->ike_sa); + break; + default: + break; } } enumerator->destroy(enumerator); |