diff options
author | Martin Willi <martin@strongswan.org> | 2009-09-30 10:36:27 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-04-07 13:55:16 +0200 |
commit | 1466af8556495044f3c2bb1174fdd1c91c436ff4 (patch) | |
tree | 8e43bfdba15099b7a37d4d79c332a67975f6d5b7 /src/charon | |
parent | ea249cc6f0f53a51cebaed67d8246ee03f669d0b (diff) | |
download | strongswan-1466af8556495044f3c2bb1174fdd1c91c436ff4.tar.bz2 strongswan-1466af8556495044f3c2bb1174fdd1c91c436ff4.tar.xz |
Do not automatically take over segments, as we need to resync first
Diffstat (limited to 'src/charon')
-rw-r--r-- | src/charon/plugins/ha/ha_dispatcher.c | 2 | ||||
-rw-r--r-- | src/charon/plugins/ha/ha_kernel.c | 10 | ||||
-rw-r--r-- | src/charon/plugins/ha/ha_segments.c | 125 |
3 files changed, 57 insertions, 80 deletions
diff --git a/src/charon/plugins/ha/ha_dispatcher.c b/src/charon/plugins/ha/ha_dispatcher.c index b9d3f6322..f2eabc672 100644 --- a/src/charon/plugins/ha/ha_dispatcher.c +++ b/src/charon/plugins/ha/ha_dispatcher.c @@ -591,10 +591,12 @@ static void process_segment(private_ha_dispatcher_t *this, case HA_SEGMENT: if (take) { + DBG1(DBG_CFG, "remote node takes segment %d", value.u16); this->segments->deactivate(this->segments, value.u16, FALSE); } else { + DBG1(DBG_CFG, "remote node drops segment %d", value.u16); this->segments->activate(this->segments, value.u16, FALSE); } break; diff --git a/src/charon/plugins/ha/ha_kernel.c b/src/charon/plugins/ha/ha_kernel.c index 69e1c9e28..0ad9c22c3 100644 --- a/src/charon/plugins/ha/ha_kernel.c +++ b/src/charon/plugins/ha/ha_kernel.c @@ -175,9 +175,9 @@ static void deactivate(private_ha_kernel_t *this, u_int segment) } /** - * Enable all not-yet enabled segments on all clusterip addresses + * Disable all not-yet disabled segments on all clusterip addresses */ -static void activate_all(private_ha_kernel_t *this) +static void disable_all(private_ha_kernel_t *this) { enumerator_t *enumerator; segment_mask_t active; @@ -190,9 +190,9 @@ static void activate_all(private_ha_kernel_t *this) active = get_active(this, file); for (i = 1; i <= this->count; i++) { - if (!(active & SEGMENTS_BIT(i))) + if (active & SEGMENTS_BIT(i)) { - enable_disable(this, i, file, TRUE); + enable_disable(this, i, file, FALSE); } } } @@ -222,7 +222,7 @@ ha_kernel_t *ha_kernel_create(u_int count) this->initval = 0; this->count = count; - activate_all(this); + disable_all(this); return &this->public; } diff --git a/src/charon/plugins/ha/ha_segments.c b/src/charon/plugins/ha/ha_segments.c index 4a96b24f4..9b7490c94 100644 --- a/src/charon/plugins/ha/ha_segments.c +++ b/src/charon/plugins/ha/ha_segments.c @@ -323,29 +323,39 @@ static bool alert_hook(private_ha_segments_t *this, ike_sa_t *ike_sa, } /** - * Get the number of SAs in a segment. + * Monitor heartbeat activity of remote node */ -static u_int get_sa_count(private_ha_segments_t *this) +static job_requeue_t watchdog(private_ha_segments_t *this) { - enumerator_t *enumerator; - ike_sa_t *ike_sa; - u_int count = 0; + int oldstate; + bool timeout; - enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager); - while (enumerator->enumerate(enumerator, &ike_sa)) + this->mutex->lock(this->mutex); + pthread_cleanup_push((void*)this->mutex->unlock, this->mutex); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); + timeout = this->condvar->timed_wait(this->condvar, this->mutex, + HEARTBEAT_TIMEOUT); + pthread_setcancelstate(oldstate, NULL); + pthread_cleanup_pop(TRUE); + if (timeout) { - if (ike_sa->get_state(ike_sa) != IKE_ESTABLISHED) - { - continue; - } - if (this->tunnel && this->tunnel->is_sa(this->tunnel, ike_sa)) - { - continue; - } - count++; + DBG1(DBG_CFG, "no heartbeat received, taking all segments"); + activate(this, 0, TRUE); + /* disable heartbeat detection util we get one */ + this->job = NULL; + return JOB_REQUEUE_NONE; } - enumerator->destroy(enumerator); - return count; + return JOB_REQUEUE_DIRECT; +} + +/** + * Start the heartbeat detection thread + */ +static void start_watchdog(private_ha_segments_t *this) +{ + this->job = callback_job_create((callback_job_cb_t)watchdog, + this, NULL, NULL); + charon->processor->queue_job(charon->processor, (job_t*)this->job); } /** @@ -353,46 +363,38 @@ static u_int get_sa_count(private_ha_segments_t *this) */ static void handle_status(private_ha_segments_t *this, segment_mask_t mask) { - segment_mask_t missing, overlap; + segment_mask_t missing; int i; this->mutex->lock(this->mutex); missing = ~(this->active | mask); - overlap = this->active & mask; - /* Activate any missing segment. The master will disable overlapping - * segments if both nodes activate the missing segments simultaneously. */ for (i = 1; i <= this->count; i++) { if (missing & SEGMENTS_BIT(i)) { - DBG1(DBG_CFG, "HA segment %d was not handled", i); - enable_disable(this, i, TRUE, TRUE); - } - } - if (this->master && overlap) - { - /* Disable overlapping segment on one node, controlled by master */ - for (i = 1; i <= this->count; i++) - { - if (overlap & SEGMENTS_BIT(i)) + if (this->master != i % 2) { - if (get_sa_count(this)) - { - DBG1(DBG_CFG, "HA segment %d overlaps, taking over", i); - enable_disable(this, i, TRUE, TRUE); - } - else - { - DBG1(DBG_CFG, "HA segment %d overlaps, dropping", i); - enable_disable(this, i, FALSE, TRUE); - } + DBG1(DBG_CFG, "HA segment %d was not handled, taking", i); + enable_disable(this, i, TRUE, TRUE); + } + else + { + DBG1(DBG_CFG, "HA segment %d was not handled, dropping", i); + enable_disable(this, i, FALSE, TRUE); } } } + this->mutex->unlock(this->mutex); this->condvar->signal(this->condvar); + + if (!this->job) + { + DBG1(DBG_CFG, "received heartbeat, reenabling watchdog"); + start_watchdog(this); + } } /** @@ -425,33 +427,14 @@ static job_requeue_t send_status(private_ha_segments_t *this) } /** - * Monitor heartbeat activity of remote node - */ -static job_requeue_t watchdog(private_ha_segments_t *this) -{ - int oldstate; - bool timeout; - - this->mutex->lock(this->mutex); - pthread_cleanup_push((void*)this->mutex->unlock, this->mutex); - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); - timeout = this->condvar->timed_wait(this->condvar, this->mutex, - HEARTBEAT_TIMEOUT); - pthread_setcancelstate(oldstate, NULL); - pthread_cleanup_pop(TRUE); - if (timeout) - { /* didn't get a heartbeat, take all segments */ - activate(this, 0, TRUE); - } - return JOB_REQUEUE_DIRECT; -} - -/** * Implementation of ha_segments_t.destroy. */ static void destroy(private_ha_segments_t *this) { - this->job->cancel(this->job); + if (this->job) + { + this->job->cancel(this->job); + } this->mutex->destroy(this->mutex); this->condvar->destroy(this->condvar); free(this); @@ -464,7 +447,6 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel, ha_tunnel_t *tunnel, char *local, char *remote, u_int count) { private_ha_segments_t *this = malloc_thing(private_ha_segments_t); - int i; memset(&this->public.listener, 0, sizeof(listener_t)); this->public.listener.alert = (bool(*)(listener_t*, ike_sa_t *, alert_t, va_list))alert_hook; @@ -482,19 +464,12 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel, this->count = count; this->master = strcmp(local, remote) > 0; - /* initially all segments are active */ + /* initially all segments are deactivated */ this->active = 0; - for (i = 1; i <= count; i++) - { - this->active |= SEGMENTS_BIT(i); - } send_status(this); - /* start heartbeat detection thread */ - this->job = callback_job_create((callback_job_cb_t)watchdog, - this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + start_watchdog(this); return &this->public; } |