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);
}
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);
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)
{
child_sa->get_protocol(child_sa),
child_sa->get_spi(child_sa, TRUE));
}
+
}
enumerator->destroy(enumerator);
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*,
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,
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;
#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))
{
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;
/* 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 */
* 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))
enumerator_t *enumerator;
child_sa_t *child_sa;
linked_list_t *vips;
+ status_t status;
host_t *host;
vips = linked_list_create();
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);