Refactored segment enabling/disabling

This commit is contained in:
Martin Willi
2010-04-07 13:55:15 +02:00
committed by Martin Willi
parent 5d67259042
commit 874c0bd8b8
+75 -72
View File
@@ -97,28 +97,50 @@ static void log_segments(private_ha_sync_segments_t *this, bool activated,
}
/**
* Enable/Disable an an IKE_SA.
* Enable/Disable a specific segment
*/
static void enable_disable(private_ha_sync_segments_t *this, u_int segment,
ike_sa_state_t old, ike_sa_state_t new, bool enable)
bool enable, bool notify)
{
ike_sa_t *ike_sa;
enumerator_t *enumerator;
u_int i, from, to;
ike_sa_state_t old, new;
ha_sync_message_t *message = NULL;
ha_sync_message_type_t type;
bool changes = FALSE;
this->lock->write_lock(this->lock);
if (segment == 0 || segment <= this->count)
if (segment > this->count)
{
if (segment)
{ /* loop once for single segment ... */
from = to = segment;
return;
}
if (enable)
{
old = IKE_PASSIVE;
new = IKE_ESTABLISHED;
type = HA_SYNC_SEGMENT_TAKE;
if (!(this->active & SEGMENTS_BIT(segment)))
{
this->active |= SEGMENTS_BIT(segment);
this->kernel->activate(this->kernel, segment);
changes = TRUE;
}
else
{ /* or count times for all segments */
from = 1;
to = this->count;
}
else
{
old = IKE_ESTABLISHED;
new = IKE_PASSIVE;
type = HA_SYNC_SEGMENT_DROP;
if (this->active & SEGMENTS_BIT(segment))
{
this->active &= ~SEGMENTS_BIT(segment);
this->kernel->deactivate(this->kernel, segment);
changes = TRUE;
}
}
if (changes)
{
enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
while (enumerator->enumerate(enumerator, &ike_sa))
{
@@ -130,38 +152,44 @@ static void enable_disable(private_ha_sync_segments_t *this, u_int segment,
{
continue;
}
for (i = from; i <= to; i++)
if (this->kernel->in_segment(this->kernel,
ike_sa->get_other_host(ike_sa), segment))
{
if (this->kernel->in_segment(this->kernel,
ike_sa->get_other_host(ike_sa), i))
{
ike_sa->set_state(ike_sa, new);
}
ike_sa->set_state(ike_sa, new);
}
}
enumerator->destroy(enumerator);
for (i = from; i <= to; i++)
{
if (enable)
{
if (!(this->active & SEGMENTS_BIT(i)))
{
this->active |= SEGMENTS_BIT(i);
this->kernel->activate(this->kernel, i);
}
}
else
{
if (this->active & SEGMENTS_BIT(i))
{
this->active &= ~SEGMENTS_BIT(i);
this->kernel->deactivate(this->kernel, i);
}
}
}
log_segments(this, enable, segment);
}
if (notify)
{
message = ha_sync_message_create(type);
message->add_attribute(message, HA_SYNC_SEGMENT, segment);
this->socket->push(this->socket, message);
}
}
/**
* Enable/Disable all or a specific segment, do locking
*/
static void enable_disable_all(private_ha_sync_segments_t *this, u_int segment,
bool enable, bool notify)
{
int i;
this->lock->write_lock(this->lock);
if (segment == 0)
{
for (i = 1; i <= this->count; i++)
{
enable_disable(this, i, enable, notify);
}
}
else
{
enable_disable(this, segment, enable, notify);
}
this->lock->unlock(this->lock);
}
@@ -171,16 +199,7 @@ static void enable_disable(private_ha_sync_segments_t *this, u_int segment,
static void activate(private_ha_sync_segments_t *this, u_int segment,
bool notify)
{
ha_sync_message_t *message;
enable_disable(this, segment, IKE_PASSIVE, IKE_ESTABLISHED, TRUE);
if (notify)
{
message = ha_sync_message_create(HA_SYNC_SEGMENT_TAKE);
message->add_attribute(message, HA_SYNC_SEGMENT, segment);
this->socket->push(this->socket, message);
}
enable_disable_all(this, segment, TRUE, notify);
}
/**
@@ -189,16 +208,7 @@ static void activate(private_ha_sync_segments_t *this, u_int segment,
static void deactivate(private_ha_sync_segments_t *this, u_int segment,
bool notify)
{
ha_sync_message_t *message;
enable_disable(this, segment, IKE_ESTABLISHED, IKE_PASSIVE, FALSE);
if (notify)
{
message = ha_sync_message_create(HA_SYNC_SEGMENT_DROP);
message->add_attribute(message, HA_SYNC_SEGMENT, segment);
this->socket->push(this->socket, message);
}
enable_disable_all(this, segment, FALSE, notify);
}
/**
@@ -294,15 +304,7 @@ static bool alert_hook(private_ha_sync_segments_t *this, ike_sa_t *ike_sa,
{
if (alert == ALERT_SHUTDOWN_SIGNAL)
{
int i;
for (i = 1; i <= this->count; i++)
{
if (this->active & SEGMENTS_BIT(i))
{
deactivate(this, i, TRUE);
}
}
deactivate(this, 0, TRUE);
}
return TRUE;
}
@@ -315,7 +317,8 @@ static void handle_status(private_ha_sync_segments_t *this, segment_mask_t mask)
segment_mask_t missing, overlap;
int i, active = 0;
this->lock->read_lock(this->lock);
this->lock->write_lock(this->lock);
missing = ~(this->active | mask);
overlap = this->active & mask;
for (i = 1; i <= this->count; i++)
@@ -325,7 +328,6 @@ static void handle_status(private_ha_sync_segments_t *this, segment_mask_t mask)
active++;
}
}
this->lock->unlock(this->lock);
/* Activate any missing segment. The master will disable overlapping
* segments if both nodes activate the missing segments simultaneously. */
@@ -334,7 +336,7 @@ static void handle_status(private_ha_sync_segments_t *this, segment_mask_t mask)
if (missing & SEGMENTS_BIT(i))
{
DBG1(DBG_CFG, "HA segment %d was not handled", i);
activate(this, i, TRUE);
enable_disable(this, i, TRUE, TRUE);
}
}
if (this->master && overlap)
@@ -347,17 +349,18 @@ static void handle_status(private_ha_sync_segments_t *this, segment_mask_t mask)
DBG1(DBG_CFG, "HA segment %d handled twice", i);
if (active > this->count)
{
deactivate(this, i, TRUE);
enable_disable(this, i, FALSE, TRUE);
active--;
}
else
{
activate(this, i, TRUE);
enable_disable(this, i, TRUE, TRUE);
active++;
}
}
}
}
this->lock->unlock(this->lock);
}
/**