diff options
author | Martin Willi <martin@strongswan.org> | 2009-09-29 16:40:58 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-04-07 13:55:16 +0200 |
commit | ea249cc6f0f53a51cebaed67d8246ee03f669d0b (patch) | |
tree | 1968e4e3cb3ca0d258538914effb9a3ec7d5de50 /src | |
parent | a05e38854008277751047b3582d6ecbfd286fcf7 (diff) | |
download | strongswan-ea249cc6f0f53a51cebaed67d8246ee03f669d0b.tar.bz2 strongswan-ea249cc6f0f53a51cebaed67d8246ee03f669d0b.tar.xz |
Drop overlapping segments only if we have no active SAs on it
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/plugins/ha/ha_segments.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/src/charon/plugins/ha/ha_segments.c b/src/charon/plugins/ha/ha_segments.c index 59091a66a..4a96b24f4 100644 --- a/src/charon/plugins/ha/ha_segments.c +++ b/src/charon/plugins/ha/ha_segments.c @@ -323,24 +323,43 @@ static bool alert_hook(private_ha_segments_t *this, ike_sa_t *ike_sa, } /** + * Get the number of SAs in a segment. + */ +static u_int get_sa_count(private_ha_segments_t *this) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + u_int count = 0; + + enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager); + while (enumerator->enumerate(enumerator, &ike_sa)) + { + if (ike_sa->get_state(ike_sa) != IKE_ESTABLISHED) + { + continue; + } + if (this->tunnel && this->tunnel->is_sa(this->tunnel, ike_sa)) + { + continue; + } + count++; + } + enumerator->destroy(enumerator); + return count; +} + +/** * Implementation of ha_segments_t.handle_status */ static void handle_status(private_ha_segments_t *this, segment_mask_t mask) { segment_mask_t missing, overlap; - int i, active = 0; + int i; this->mutex->lock(this->mutex); missing = ~(this->active | mask); overlap = this->active & mask; - for (i = 1; i <= this->count; i++) - { - if (this->active & SEGMENTS_BIT(i)) - { - active++; - } - } /* Activate any missing segment. The master will disable overlapping * segments if both nodes activate the missing segments simultaneously. */ @@ -359,16 +378,15 @@ static void handle_status(private_ha_segments_t *this, segment_mask_t mask) { if (overlap & SEGMENTS_BIT(i)) { - DBG1(DBG_CFG, "HA segment %d handled twice", i); - if (active > this->count) + if (get_sa_count(this)) { - enable_disable(this, i, FALSE, TRUE); - active--; + DBG1(DBG_CFG, "HA segment %d overlaps, taking over", i); + enable_disable(this, i, TRUE, TRUE); } else { - enable_disable(this, i, TRUE, TRUE); - active++; + DBG1(DBG_CFG, "HA segment %d overlaps, dropping", i); + enable_disable(this, i, FALSE, TRUE); } } } |