peer-cfg: Add method to atomically replace child configs
This commit is contained in:
parent
8db4f19ad9
commit
622c2b2c33
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Tobias Brunner
|
||||
* Copyright (C) 2007-2015 Tobias Brunner
|
||||
* Copyright (C) 2005-2009 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
|
@ -200,6 +200,117 @@ METHOD(peer_cfg_t, add_child_cfg, void,
|
|||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
enumerator_t public;
|
||||
linked_list_t *removed;
|
||||
linked_list_t *added;
|
||||
enumerator_t *wrapped;
|
||||
bool add;
|
||||
} child_cfgs_replace_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, child_cfgs_replace_enumerate, bool,
|
||||
child_cfgs_replace_enumerator_t *this, child_cfg_t **chd, bool *added)
|
||||
{
|
||||
child_cfg_t *child_cfg;
|
||||
|
||||
if (!this->wrapped)
|
||||
{
|
||||
this->wrapped = this->removed->create_enumerator(this->removed);
|
||||
}
|
||||
while (TRUE)
|
||||
{
|
||||
if (this->wrapped->enumerate(this->wrapped, &child_cfg))
|
||||
{
|
||||
if (chd)
|
||||
{
|
||||
*chd = child_cfg;
|
||||
}
|
||||
if (added)
|
||||
{
|
||||
*added = this->add;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (this->add)
|
||||
{
|
||||
break;
|
||||
}
|
||||
this->wrapped = this->added->create_enumerator(this->added);
|
||||
this->add = TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(enumerator_t, child_cfgs_replace_enumerator_destroy, void,
|
||||
child_cfgs_replace_enumerator_t *this)
|
||||
{
|
||||
DESTROY_IF(this->wrapped);
|
||||
this->removed->destroy_offset(this->removed, offsetof(child_cfg_t, destroy));
|
||||
this->added->destroy_offset(this->added, offsetof(child_cfg_t, destroy));
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*,
|
||||
private_peer_cfg_t *this, peer_cfg_t *other_pub)
|
||||
{
|
||||
private_peer_cfg_t *other = (private_peer_cfg_t*)other_pub;
|
||||
linked_list_t *removed, *added;
|
||||
enumerator_t *mine, *others;
|
||||
child_cfg_t *my_cfg, *other_cfg;
|
||||
child_cfgs_replace_enumerator_t *enumerator;
|
||||
bool found;
|
||||
|
||||
removed = linked_list_create();
|
||||
|
||||
other->mutex->lock(other->mutex);
|
||||
added = linked_list_create_from_enumerator(
|
||||
other->child_cfgs->create_enumerator(other->child_cfgs));
|
||||
added->invoke_offset(added, offsetof(child_cfg_t, get_ref));
|
||||
other->mutex->unlock(other->mutex);
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
others = added->create_enumerator(added);
|
||||
mine = this->child_cfgs->create_enumerator(this->child_cfgs);
|
||||
while (mine->enumerate(mine, &my_cfg))
|
||||
{
|
||||
found = FALSE;
|
||||
while (others->enumerate(others, &other_cfg))
|
||||
{
|
||||
if (my_cfg->equals(my_cfg, other_cfg))
|
||||
{
|
||||
added->remove_at(added, others);
|
||||
other_cfg->destroy(other_cfg);
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
added->reset_enumerator(added, others);
|
||||
if (!found)
|
||||
{
|
||||
this->child_cfgs->remove_at(this->child_cfgs, mine);
|
||||
removed->insert_last(removed, my_cfg);
|
||||
}
|
||||
}
|
||||
while (others->enumerate(others, &other_cfg))
|
||||
{
|
||||
this->child_cfgs->insert_last(this->child_cfgs,
|
||||
other_cfg->get_ref(other_cfg));
|
||||
}
|
||||
others->destroy(others);
|
||||
mine->destroy(mine);
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_child_cfgs_replace_enumerate,
|
||||
.destroy = (void*)_child_cfgs_replace_enumerator_destroy,
|
||||
},
|
||||
.removed = removed,
|
||||
.added = added,
|
||||
);
|
||||
return &enumerator->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* child_cfg enumerator
|
||||
*/
|
||||
|
@ -645,6 +756,7 @@ peer_cfg_t *peer_cfg_create(char *name,
|
|||
.get_ike_cfg = _get_ike_cfg,
|
||||
.add_child_cfg = _add_child_cfg,
|
||||
.remove_child_cfg = (void*)_remove_child_cfg,
|
||||
.replace_child_cfgs = _replace_child_cfgs,
|
||||
.create_child_cfg_enumerator = _create_child_cfg_enumerator,
|
||||
.select_child_cfg = _select_child_cfg,
|
||||
.get_cert_policy = _get_cert_policy,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Tobias Brunner
|
||||
* Copyright (C) 2007-2015 Tobias Brunner
|
||||
* Copyright (C) 2005-2009 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
|
@ -153,6 +153,20 @@ struct peer_cfg_t {
|
|||
*/
|
||||
void (*remove_child_cfg)(peer_cfg_t *this, enumerator_t *enumerator);
|
||||
|
||||
/**
|
||||
* Replace the CHILD configs with those in the given PEER config.
|
||||
*
|
||||
* Configs that are equal are not replaced.
|
||||
*
|
||||
* The enumerator enumerates the removed and added CHILD configs
|
||||
* (child_cfg_t*, bool), where the flag is FALSE for removed configs and
|
||||
* TRUE for added configs.
|
||||
*
|
||||
* @param other other config to get CHILD configs from
|
||||
* @return an enumerator over removed/added CHILD configs
|
||||
*/
|
||||
enumerator_t* (*replace_child_cfgs)(peer_cfg_t *this, peer_cfg_t *other);
|
||||
|
||||
/**
|
||||
* Create an enumerator for all attached CHILD configs.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue