ike: Maintain per-IKE_SA CHILD_SAs in the global CHILD_SA manager
This commit is contained in:
@@ -82,6 +82,7 @@ METHOD(job_t, execute, job_requeue_t,
|
|||||||
enumerator_t *children, *enumerator;
|
enumerator_t *children, *enumerator;
|
||||||
child_sa_t *child_sa;
|
child_sa_t *child_sa;
|
||||||
host_t *host;
|
host_t *host;
|
||||||
|
status_t status;
|
||||||
linked_list_t *vips;
|
linked_list_t *vips;
|
||||||
|
|
||||||
children = ike_sa->create_child_sa_enumerator(ike_sa);
|
children = ike_sa->create_child_sa_enumerator(ike_sa);
|
||||||
@@ -113,11 +114,21 @@ METHOD(job_t, execute, job_requeue_t,
|
|||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
if (child_sa->update(child_sa, this->local, this->remote, vips,
|
status = child_sa->update(child_sa, this->local, this->remote, vips,
|
||||||
ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
|
ike_sa->has_condition(ike_sa, COND_NAT_ANY));
|
||||||
|
switch (status)
|
||||||
{
|
{
|
||||||
ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
|
case NOT_SUPPORTED:
|
||||||
child_sa->get_spi(child_sa, TRUE));
|
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);
|
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||||
vips->destroy(vips);
|
vips->destroy(vips);
|
||||||
|
|||||||
@@ -964,6 +964,10 @@ METHOD(ike_sa_t, update_hosts, void,
|
|||||||
enumerator = array_create_enumerator(this->child_sas);
|
enumerator = array_create_enumerator(this->child_sas);
|
||||||
while (enumerator->enumerate(enumerator, &child_sa))
|
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,
|
if (child_sa->update(child_sa, this->my_host, this->other_host,
|
||||||
vips, has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
|
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_protocol(child_sa),
|
||||||
child_sa->get_spi(child_sa, TRUE));
|
child_sa->get_spi(child_sa, TRUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
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)
|
private_ike_sa_t *this, child_sa_t *child_sa)
|
||||||
{
|
{
|
||||||
array_insert_create(&this->child_sas, ARRAY_TAIL, 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*,
|
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);
|
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*,
|
METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*,
|
||||||
private_ike_sa_t *this)
|
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,
|
METHOD(ike_sa_t, remove_child_sa, void,
|
||||||
private_ike_sa_t *this, enumerator_t *enumerator)
|
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,
|
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;
|
child_sa_t *child_sa;
|
||||||
status_t status = NOT_FOUND;
|
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))
|
while (enumerator->enumerate(enumerator, (void**)&child_sa))
|
||||||
{
|
{
|
||||||
if (child_sa->get_protocol(child_sa) == protocol &&
|
if (child_sa->get_protocol(child_sa) == protocol &&
|
||||||
child_sa->get_spi(child_sa, TRUE) == spi)
|
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);
|
child_sa->destroy(child_sa);
|
||||||
status = SUCCESS;
|
status = SUCCESS;
|
||||||
break;
|
break;
|
||||||
@@ -1771,7 +1820,7 @@ METHOD(ike_sa_t, reestablish, status_t,
|
|||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
{
|
{
|
||||||
/* handle existing CHILD_SAs */
|
/* handle existing CHILD_SAs */
|
||||||
enumerator = array_create_enumerator(this->child_sas);
|
enumerator = create_child_sa_enumerator(this);
|
||||||
while (enumerator->enumerate(enumerator, (void**)&child_sa))
|
while (enumerator->enumerate(enumerator, (void**)&child_sa))
|
||||||
{
|
{
|
||||||
if (has_condition(this, COND_REAUTHENTICATING))
|
if (has_condition(this, COND_REAUTHENTICATING))
|
||||||
@@ -1780,7 +1829,7 @@ METHOD(ike_sa_t, reestablish, status_t,
|
|||||||
{
|
{
|
||||||
case CHILD_ROUTED:
|
case CHILD_ROUTED:
|
||||||
{ /* move routed child directly */
|
{ /* move routed child directly */
|
||||||
array_remove_at(this->child_sas, enumerator);
|
remove_child_sa(this, enumerator);
|
||||||
new->add_child_sa(new, child_sa);
|
new->add_child_sa(new, child_sa);
|
||||||
action = ACTION_NONE;
|
action = ACTION_NONE;
|
||||||
break;
|
break;
|
||||||
@@ -2251,7 +2300,8 @@ METHOD(ike_sa_t, inherit_post, void,
|
|||||||
/* adopt all children */
|
/* adopt all children */
|
||||||
while (array_remove(other->child_sas, ARRAY_HEAD, &child_sa))
|
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 */
|
/* 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. */
|
* routes that the CHILD_SA tries to uninstall. */
|
||||||
while (array_remove(this->child_sas, ARRAY_TAIL, &child_sa))
|
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);
|
child_sa->destroy(child_sa);
|
||||||
}
|
}
|
||||||
while (array_remove(this->my_vips, ARRAY_TAIL, &vip))
|
while (array_remove(this->my_vips, ARRAY_TAIL, &vip))
|
||||||
|
|||||||
@@ -256,6 +256,7 @@ static void update_children(private_ike_mobike_t *this)
|
|||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
child_sa_t *child_sa;
|
child_sa_t *child_sa;
|
||||||
linked_list_t *vips;
|
linked_list_t *vips;
|
||||||
|
status_t status;
|
||||||
host_t *host;
|
host_t *host;
|
||||||
|
|
||||||
vips = linked_list_create();
|
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);
|
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
|
||||||
while (enumerator->enumerate(enumerator, (void**)&child_sa))
|
while (enumerator->enumerate(enumerator, (void**)&child_sa))
|
||||||
{
|
{
|
||||||
if (child_sa->update(child_sa,
|
status = child_sa->update(child_sa,
|
||||||
this->ike_sa->get_my_host(this->ike_sa),
|
this->ike_sa->get_my_host(this->ike_sa),
|
||||||
this->ike_sa->get_other_host(this->ike_sa), vips,
|
this->ike_sa->get_other_host(this->ike_sa), vips,
|
||||||
this->ike_sa->has_condition(this->ike_sa,
|
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
|
||||||
COND_NAT_ANY)) == NOT_SUPPORTED)
|
switch (status)
|
||||||
{
|
{
|
||||||
this->ike_sa->rekey_child_sa(this->ike_sa,
|
case NOT_SUPPORTED:
|
||||||
child_sa->get_protocol(child_sa),
|
this->ike_sa->rekey_child_sa(this->ike_sa,
|
||||||
child_sa->get_spi(child_sa, TRUE));
|
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);
|
enumerator->destroy(enumerator);
|
||||||
|
|||||||
Reference in New Issue
Block a user