METHOD(child_cfg_t, select_proposal, proposal_t*,
private_child_cfg_t*this, linked_list_t *proposals, bool strip_dh,
- bool private)
+ bool private, bool prefer_self)
{
- enumerator_t *stored_enum, *supplied_enum;
- proposal_t *stored, *supplied, *selected = NULL;
+ enumerator_t *prefer_enum, *match_enum;
+ proposal_t *proposal, *match, *selected = NULL;
- stored_enum = this->proposals->create_enumerator(this->proposals);
- supplied_enum = proposals->create_enumerator(proposals);
+ if (prefer_self)
+ {
+ prefer_enum = this->proposals->create_enumerator(this->proposals);
+ match_enum = proposals->create_enumerator(proposals);
+ }
+ else
+ {
+ prefer_enum = proposals->create_enumerator(proposals);
+ match_enum = this->proposals->create_enumerator(this->proposals);
+ }
- /* compare all stored proposals with all supplied. Stored ones are preferred. */
- while (stored_enum->enumerate(stored_enum, &stored))
+ while (prefer_enum->enumerate(prefer_enum, &proposal))
{
- stored = stored->clone(stored);
- while (supplied_enum->enumerate(supplied_enum, &supplied))
+ proposal = proposal->clone(proposal);
+ if (prefer_self)
+ {
+ proposals->reset_enumerator(proposals, match_enum);
+ }
+ else
+ {
+ this->proposals->reset_enumerator(this->proposals, match_enum);
+ }
+ while (match_enum->enumerate(match_enum, &match))
{
if (strip_dh)
{
- stored->strip_dh(stored, MODP_NONE);
+ proposal->strip_dh(proposal, MODP_NONE);
}
- selected = stored->select(stored, supplied, private);
+ selected = proposal->select(proposal, match, private);
if (selected)
{
DBG2(DBG_CFG, "received proposals: %#P", proposals);
break;
}
}
- stored->destroy(stored);
+ proposal->destroy(proposal);
if (selected)
{
break;
}
- supplied_enum->destroy(supplied_enum);
- supplied_enum = proposals->create_enumerator(proposals);
}
- stored_enum->destroy(stored_enum);
- supplied_enum->destroy(supplied_enum);
- if (selected == NULL)
+ prefer_enum->destroy(prefer_enum);
+ match_enum->destroy(match_enum);
+ if (!selected)
{
DBG1(DBG_CFG, "received proposals: %#P", proposals);
DBG1(DBG_CFG, "configured proposals: %#P", this->proposals);
* @param proposals list from which proposals are selected
* @param strip_dh TRUE strip out diffie hellman groups
* @param private accept algorithms from a private range
+ * @param prefer_self whether to prefer configured or supplied proposals
* @return selected proposal, or NULL if nothing matches
*/
proposal_t* (*select_proposal)(child_cfg_t*this, linked_list_t *proposals,
- bool strip_dh, bool private);
+ bool strip_dh, bool private,
+ bool prefer_self);
/**
* Add a traffic selector to the config.
}
private = this->ike_sa->supports_extension(this->ike_sa,
EXT_STRONGSWAN);
- this->proposal = this->config->select_proposal(this->config,
- list, FALSE, private);
+ this->proposal = this->config->select_proposal(this->config, list,
+ FALSE, private, TRUE);
list->destroy_offset(list, offsetof(proposal_t, destroy));
get_lifetimes(this);
}
private = this->ike_sa->supports_extension(this->ike_sa,
EXT_STRONGSWAN);
- this->proposal = this->config->select_proposal(this->config,
- list, FALSE, private);
+ this->proposal = this->config->select_proposal(this->config, list,
+ FALSE, private, TRUE);
list->destroy_offset(list, offsetof(proposal_t, destroy));
if (!this->proposal)
{