From: Martin Willi Date: Tue, 29 Sep 2009 14:40:58 +0000 (+0200) Subject: Drop overlapping segments only if we have no active SAs on it X-Git-Tag: 4.4.0~67 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ea249cc6f0f53a51cebaed67d8246ee03f669d0b;p=thirdparty%2Fstrongswan.git Drop overlapping segments only if we have no active SAs on it --- diff --git a/src/charon/plugins/ha/ha_segments.c b/src/charon/plugins/ha/ha_segments.c index 59091a66ac..4a96b24f48 100644 --- a/src/charon/plugins/ha/ha_segments.c +++ b/src/charon/plugins/ha/ha_segments.c @@ -322,25 +322,44 @@ static bool alert_hook(private_ha_segments_t *this, ike_sa_t *ike_sa, return TRUE; } +/** + * 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); } } }