diff options
author | Martin Willi <martin@revosec.ch> | 2012-06-08 10:18:52 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-06-08 10:22:03 +0200 |
commit | 2d4c347af9ffe408ba252b1fa3b6c16583a4715c (patch) | |
tree | 60524c5a7be9e1e66ec0f7bd99af43f7328214bb | |
parent | 106b938b6bc665b01973f0977743be15db77b80d (diff) | |
download | strongswan-2d4c347af9ffe408ba252b1fa3b6c16583a4715c.tar.bz2 strongswan-2d4c347af9ffe408ba252b1fa3b6c16583a4715c.tar.xz |
While checking for redundant quick modes, compare traffic selectors
If a configuration is instanced more than once using narrowing,
we should keep all unique quick modes up during rekeying.
-rw-r--r-- | src/libcharon/sa/ikev1/task_manager_v1.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index 244aa13b0..007707ed2 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -1367,6 +1367,26 @@ METHOD(task_manager_t, queue_child, void, } /** + * Check if two CHILD_SAs have the same traffic selector + */ +static bool have_equal_ts(child_sa_t *a, child_sa_t *b, bool local) +{ + linked_list_t *list; + traffic_selector_t *ts_a, *ts_b; + + list = a->get_traffic_selectors(a, local); + if (list->get_first(list, (void**)&ts_a) == SUCCESS) + { + list = b->get_traffic_selectors(b, local); + if (list->get_first(list, (void**)&ts_b) == SUCCESS) + { + return ts_a->equals(ts_a, ts_b); + } + } + return FALSE; +} + +/** * Check if a CHILD_SA is redundant and we should delete instead of rekey */ static bool is_redundant(private_task_manager_t *this, child_sa_t *child_sa) @@ -1380,6 +1400,8 @@ static bool is_redundant(private_task_manager_t *this, child_sa_t *child_sa) { if (current->get_state(current) == CHILD_INSTALLED && streq(current->get_name(current), child_sa->get_name(child_sa)) && + have_equal_ts(current, child_sa, TRUE) && + have_equal_ts(current, child_sa, FALSE) && current->get_lifetime(current, FALSE) > child_sa->get_lifetime(child_sa, FALSE)) { |