added HA resync option to (re-)integrate nodes to a cluster
This commit is contained in:
committed by
Martin Willi
parent
c81f4fa29d
commit
9ffcbea6f1
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -163,6 +161,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.
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user