aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2008-12-01 18:38:40 +0000
committerMartin Willi <martin@revosec.ch>2010-04-07 13:55:12 +0200
commit9ffcbea6f1b1725d2ba79249ade7e9b83881f293 (patch)
treed9d5409c6c7b7df020dac6a11a312ffca16af090 /src/charon
parentc81f4fa29dd86076c860a4748c3ac40ebaad6db6 (diff)
downloadstrongswan-9ffcbea6f1b1725d2ba79249ade7e9b83881f293.tar.bz2
strongswan-9ffcbea6f1b1725d2ba79249ade7e9b83881f293.tar.xz
added HA resync option to (re-)integrate nodes to a cluster
Diffstat (limited to 'src/charon')
-rw-r--r--src/charon/plugins/ha_sync/ha_sync_ctl.c3
-rw-r--r--src/charon/plugins/ha_sync/ha_sync_segments.c89
-rw-r--r--src/charon/plugins/ha_sync/ha_sync_segments.h20
3 files changed, 104 insertions, 8 deletions
diff --git a/src/charon/plugins/ha_sync/ha_sync_ctl.c b/src/charon/plugins/ha_sync/ha_sync_ctl.c
index 30c9261e6..b83789b5e 100644
--- a/src/charon/plugins/ha_sync/ha_sync_ctl.c
+++ b/src/charon/plugins/ha_sync/ha_sync_ctl.c
@@ -85,6 +85,9 @@ static job_requeue_t dispatch_fifo(private_ha_sync_ctl_t *this)
case '-':
this->segments->deactivate(this->segments, segment);
break;
+ case '*':
+ this->segments->resync(this->segments, segment);
+ break;
default:
break;
}
diff --git a/src/charon/plugins/ha_sync/ha_sync_segments.c b/src/charon/plugins/ha_sync/ha_sync_segments.c
index 6f9985bc1..18d6847c9 100644
--- a/src/charon/plugins/ha_sync/ha_sync_segments.c
+++ b/src/charon/plugins/ha_sync/ha_sync_segments.c
@@ -101,7 +101,7 @@ static void log_segments(private_ha_sync_segments_t *this, bool activated,
pos += snprintf(pos, buf + sizeof(buf) - pos, "%d", i+1);
}
}
- DBG1(DBG_CFG, "HA sync segments %d %sactivated, now active: %s",
+ DBG1(DBG_CFG, "HA sync segment %d %sactivated, now active: %s",
segment, activated ? "" : "de", buf);
}
@@ -114,8 +114,6 @@ static void activate(private_ha_sync_segments_t *this, u_int segment)
enumerator_t *enumerator;
u_int16_t mask = 0x01 << (segment - 1);
- DBG1(DBG_CFG, "activating segment %d", segment);
-
if (segment > 0 && segment <= this->segment_count && !(this->active & mask))
{
this->active |= mask;
@@ -164,6 +162,88 @@ static void deactivate(private_ha_sync_segments_t *this, u_int segment)
}
/**
+ * Rekey all children of an IKE_SA
+ */
+static status_t rekey_children(ike_sa_t *ike_sa)
+{
+ iterator_t *iterator;
+ child_sa_t *child_sa;
+ status_t status = SUCCESS;
+
+ iterator = ike_sa->create_child_sa_iterator(ike_sa);
+ while (iterator->iterate(iterator, (void**)&child_sa))
+ {
+ DBG1(DBG_CFG, "resyncing CHILD_SA");
+ status = ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
+ child_sa->get_spi(child_sa, TRUE));
+ if (status == DESTROY_ME)
+ {
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+ return status;
+}
+
+/**
+ * Implementation of ha_sync_segments_t.resync
+ */
+static void resync(private_ha_sync_segments_t *this, u_int segment)
+{
+ ike_sa_t *ike_sa;
+ enumerator_t *enumerator;
+ linked_list_t *list;
+ ike_sa_id_t *id;
+ u_int16_t mask = 0x01 << (segment - 1);
+
+
+ if (segment > 0 && segment <= this->segment_count && (this->active & mask))
+ {
+ this->active &= ~mask;
+ list = linked_list_create();
+
+ DBG1(DBG_CFG, "resyncing HA sync segment %d", segment);
+
+ /* we do the actual rekeying in a seperate loop to avoid rekeying
+ * an SA twice. */
+ 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 &&
+ in_segment(this, ike_sa->get_other_host(ike_sa), segment))
+ {
+ id = ike_sa->get_id(ike_sa);
+ list->insert_last(list, id->clone(id));
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ while (list->remove_last(list, (void**)&id) == SUCCESS)
+ {
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id);
+ id->destroy(id);
+ if (ike_sa)
+ {
+ DBG1(DBG_CFG, "resyncing IKE_SA");
+ if (ike_sa->rekey(ike_sa) != DESTROY_ME)
+ {
+ if (rekey_children(ike_sa) != DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin(
+ charon->ike_sa_manager, ike_sa);
+ continue;
+ }
+ }
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
+ }
+ }
+ list->destroy(list);
+ }
+}
+
+/**
* Implementation of ha_sync_segments_t.destroy.
*/
static void destroy(private_ha_sync_segments_t *this)
@@ -183,6 +263,7 @@ ha_sync_segments_t *ha_sync_segments_create()
this->public.activate = (void(*)(ha_sync_segments_t*, u_int segment))activate;
this->public.deactivate = (void(*)(ha_sync_segments_t*, u_int segment))deactivate;
+ this->public.resync = (void(*)(ha_sync_segments_t*, u_int segment))resync;
this->public.destroy = (void(*)(ha_sync_segments_t*))destroy;
this->initval = 0;
@@ -196,7 +277,7 @@ ha_sync_segments_t *ha_sync_segments_create()
while (enumerator->enumerate(enumerator, &str))
{
segment = atoi(str);
- if (segment && segment < MAX_SEGMENTS)
+ if (segment > 0 && segment < MAX_SEGMENTS)
{
this->active |= 0x01 << (segment - 1);
}
diff --git a/src/charon/plugins/ha_sync/ha_sync_segments.h b/src/charon/plugins/ha_sync/ha_sync_segments.h
index 62908cf55..7aeda005d 100644
--- a/src/charon/plugins/ha_sync/ha_sync_segments.h
+++ b/src/charon/plugins/ha_sync/ha_sync_segments.h
@@ -39,16 +39,28 @@ struct ha_sync_segments_t {
* This involves moving all SAs to the daemons IKE_SA manager and handle
* them actively now.
*
- * @param segments numerical segments to takeover
+ * @param segment numerical segments to takeover
*/
- void (*activate)(ha_sync_segments_t *this, u_int segments);
+ void (*activate)(ha_sync_segments_t *this, u_int segment);
/**
* Deactivate a set of IKE_SAs identified by a segments.
*
- * @param segments numerical segments to takeover
+ * @param segment numerical segments to takeover
*/
- void (*deactivate)(ha_sync_segments_t *this, u_int segments);
+ void (*deactivate)(ha_sync_segments_t *this, u_int segment);
+
+ /**
+ * Resync an active segment.
+ *
+ * To reintegrade a node into the cluster, resynchronization is reqired.
+ * IKE_SAs and CHILD_SAs are synced automatically during rekeying. A call
+ * to this method enforces a rekeying immediately sync all state of a
+ * segment.
+ *
+ * @param segment segment to resync
+ */
+ void (*resync)(ha_sync_segments_t *this, u_int segment);
/**
* Destroy a ha_sync_segments_t.