mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-03 00:00:24 -04:00
child-create: Consider triggering TS when checking for duplicate
This commit is contained in:
parent
6e274271af
commit
6ae29af18b
@ -1292,21 +1292,76 @@ static status_t defer_child_sa(private_child_create_t *this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two CHILD_SA objects for equality
|
||||
* Check if the given TS is contained in any of the ones of the given CHILD_SA.
|
||||
*/
|
||||
static bool child_sa_equals(child_sa_t *a, child_sa_t *b)
|
||||
static bool ts_match_existing(traffic_selector_t *ts, child_sa_t *child_sa,
|
||||
bool local)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
traffic_selector_t *negotiated;
|
||||
|
||||
enumerator = child_sa->create_ts_enumerator(child_sa, local);
|
||||
while (enumerator->enumerate(enumerator, &negotiated))
|
||||
{
|
||||
if (ts->is_contained_in(ts, negotiated))
|
||||
{
|
||||
enumerator->destroy(enumerator);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the reqids and possibly traffic selectors of two CHILD_SAs for
|
||||
* equality.
|
||||
*
|
||||
* The second CHILD_SA is assumed to be the one newly created.
|
||||
*/
|
||||
static bool reqid_and_ts_equals(private_child_create_t *this, child_sa_t *a,
|
||||
child_sa_t *b)
|
||||
{
|
||||
/* reqids are allocated based on the traffic selectors. if all the other
|
||||
* selectors are the same, they can only differ if narrowing occurred.
|
||||
*
|
||||
* if the new SA has no reqid assigned, it was initiated manually or due to
|
||||
* a start action and we assume the peer will do the same narrowing it
|
||||
* possibly did before, so we treat the SAs as equal.
|
||||
*
|
||||
* if the new SA has a reqid, it was either triggered by an acquire or
|
||||
* during a reestablishment. if they are equal, we are done */
|
||||
if (!b->get_reqid(b) || a->get_reqid(a) == b->get_reqid(b))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
/* if the reqids differ, the one of the established SA was changed due to
|
||||
* narrowing. in this case we check if we have triggering TS. if not, we
|
||||
* assume the peer will do the same narrowing and treat the SAs equal.
|
||||
* otherwise, we check whether they match the TS of the existing SA. if
|
||||
* they do, there is no point to negotiate another SA. if not, the peer
|
||||
* will potentially narrow the TS to a different set for the new SA */
|
||||
return !this->packet_tsi || !this->packet_tsr ||
|
||||
(ts_match_existing(this->packet_tsi, a, TRUE) &&
|
||||
ts_match_existing(this->packet_tsr, a, FALSE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two CHILD_SA objects for equality.
|
||||
*
|
||||
* The second CHILD_SA is assumed to be the one newly created.
|
||||
*/
|
||||
static bool child_sa_equals(private_child_create_t *this, child_sa_t *a,
|
||||
child_sa_t *b)
|
||||
{
|
||||
child_cfg_t *cfg = a->get_config(a);
|
||||
return cfg->equals(cfg, b->get_config(b)) &&
|
||||
/* reqids are allocated based on the final TS, so we can only compare
|
||||
* them if they are static (i.e. both have them) */
|
||||
(!a->get_reqid(a) || !b->get_reqid(b) ||
|
||||
a->get_reqid(a) == b->get_reqid(b)) &&
|
||||
a->get_mark(a, TRUE).value == b->get_mark(b, TRUE).value &&
|
||||
a->get_mark(a, FALSE).value == b->get_mark(b, FALSE).value &&
|
||||
a->get_if_id(a, TRUE) == b->get_if_id(b, TRUE) &&
|
||||
a->get_if_id(a, FALSE) == b->get_if_id(b, FALSE) &&
|
||||
sec_labels_equal(a->get_label(a), b->get_label(b));
|
||||
sec_labels_equal(a->get_label(a), b->get_label(b)) &&
|
||||
reqid_and_ts_equals(this, a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1322,7 +1377,7 @@ static bool check_for_duplicate(private_child_create_t *this)
|
||||
while (enumerator->enumerate(enumerator, (void**)&child_sa))
|
||||
{
|
||||
if (child_sa->get_state(child_sa) == CHILD_INSTALLED &&
|
||||
child_sa_equals(child_sa, this->child_sa))
|
||||
child_sa_equals(this, child_sa, this->child_sa))
|
||||
{
|
||||
found = child_sa;
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user