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-2009 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
@ -200,6 +200,117 @@ METHOD(peer_cfg_t, add_child_cfg, void,
|
||||||
this->mutex->unlock(this->mutex);
|
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
|
* child_cfg enumerator
|
||||||
*/
|
*/
|
||||||
|
@ -645,6 +756,7 @@ peer_cfg_t *peer_cfg_create(char *name,
|
||||||
.get_ike_cfg = _get_ike_cfg,
|
.get_ike_cfg = _get_ike_cfg,
|
||||||
.add_child_cfg = _add_child_cfg,
|
.add_child_cfg = _add_child_cfg,
|
||||||
.remove_child_cfg = (void*)_remove_child_cfg,
|
.remove_child_cfg = (void*)_remove_child_cfg,
|
||||||
|
.replace_child_cfgs = _replace_child_cfgs,
|
||||||
.create_child_cfg_enumerator = _create_child_cfg_enumerator,
|
.create_child_cfg_enumerator = _create_child_cfg_enumerator,
|
||||||
.select_child_cfg = _select_child_cfg,
|
.select_child_cfg = _select_child_cfg,
|
||||||
.get_cert_policy = _get_cert_policy,
|
.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-2009 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
@ -153,6 +153,20 @@ struct peer_cfg_t {
|
||||||
*/
|
*/
|
||||||
void (*remove_child_cfg)(peer_cfg_t *this, enumerator_t *enumerator);
|
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.
|
* Create an enumerator for all attached CHILD configs.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue