manage synced SAs in IKE_SA Manager, tag them with IKE_PASSIVE state

This commit is contained in:
Martin Willi
2010-04-07 13:55:12 +02:00
committed by Martin Willi
parent d4113a42e9
commit 34d240a6e3
16 changed files with 274 additions and 345 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ libstrongswan_ha_sync_la_SOURCES = \
ha_sync_message.h ha_sync_message.c \ ha_sync_message.h ha_sync_message.c \
ha_sync_socket.h ha_sync_socket.c \ ha_sync_socket.h ha_sync_socket.c \
ha_sync_dispatcher.h ha_sync_dispatcher.c \ ha_sync_dispatcher.h ha_sync_dispatcher.c \
ha_sync_cache.h ha_sync_cache.c \ ha_sync_segments.h ha_sync_segments.c \
ha_sync_ctl.h ha_sync_ctl.c \ ha_sync_ctl.h ha_sync_ctl.c \
ha_sync_ike.h ha_sync_ike.c \ ha_sync_ike.h ha_sync_ike.c \
ha_sync_child.h ha_sync_child.c ha_sync_child.h ha_sync_child.c
@@ -1,89 +0,0 @@
/*
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* $Id$
*/
/**
* @defgroup ha_sync_cache ha_sync_cache
* @{ @ingroup ha_sync
*/
#ifndef HA_SYNC_CACHE_H_
#define HA_SYNC_CACHE_H_
#include <daemon.h>
typedef struct ha_sync_cache_t ha_sync_cache_t;
/**
* Locally cached HA state synced from other nodes.
*/
struct ha_sync_cache_t {
/**
* Get a synced and cached IKE_SA entry.
*
* If no cached IKE_SA with such an id exists, it gets created.
*
* @param id IKE_SA identifier of cached SA.
* @return cached IKE_SA
*/
ike_sa_t* (*get_ike_sa)(ha_sync_cache_t *this, ike_sa_id_t *id);
/**
* Check if an IKE_SA is in the cache.
*
* @param id IKE_SA identifier of cached SA.
* @return TRUE if IKE_SA found
*/
bool (*has_ike_sa)(ha_sync_cache_t *this, ike_sa_id_t *id);
/**
* Delete a synced and cached IKE_SA entry.
*
* @param id IKE_SA identifier of cached SA to delete.
*/
void (*delete_ike_sa)(ha_sync_cache_t *this, ike_sa_id_t *id);
/**
* Activate a set of IKE_SAs identified by a segment.
*
* Activating means do a takeover of SAs as the responsible node has failed.
* This involves moving all SAs to the daemons IKE_SA manager and handle
* them actively now.
*
* @param segment numerical segment to takeover
*/
void (*activate)(ha_sync_cache_t *this, u_int segment);
/**
* Deactivate a set of IKE_SAs identified by a segment.
*
* @param segment numerical segment to takeover
*/
void (*deactivate)(ha_sync_cache_t *this, u_int segment);
/**
* Destroy a ha_sync_cache_t.
*/
void (*destroy)(ha_sync_cache_t *this);
};
/**
* Create a ha_sync_cache instance.
*/
ha_sync_cache_t *ha_sync_cache_create();
#endif /* HA_SYNC_CACHE_ @}*/
+3 -15
View File
@@ -33,11 +33,6 @@ struct private_ha_sync_child_t {
* socket we use for syncing * socket we use for syncing
*/ */
ha_sync_socket_t *socket; ha_sync_socket_t *socket;
/**
* synced and cached IKE_SA state
*/
ha_sync_cache_t *cache;
}; };
/** /**
@@ -55,11 +50,6 @@ static bool child_keys(private_ha_sync_child_t *this, ike_sa_t *ike_sa,
enumerator_t *enumerator; enumerator_t *enumerator;
traffic_selector_t *ts; traffic_selector_t *ts;
if (this->cache->has_ike_sa(this->cache, ike_sa->get_id(ike_sa)))
{ /* IKE_SA is cached, do not sync */
return TRUE;
}
m = ha_sync_message_create(HA_SYNC_CHILD_ADD); m = ha_sync_message_create(HA_SYNC_CHILD_ADD);
m->add_attribute(m, HA_SYNC_IKE_ID, ike_sa->get_id(ike_sa)); m->add_attribute(m, HA_SYNC_IKE_ID, ike_sa->get_id(ike_sa));
@@ -119,8 +109,8 @@ static bool child_keys(private_ha_sync_child_t *this, ike_sa_t *ike_sa,
static bool child_state_change(private_ha_sync_child_t *this, ike_sa_t *ike_sa, static bool child_state_change(private_ha_sync_child_t *this, ike_sa_t *ike_sa,
child_sa_t *child_sa, child_sa_state_t state) child_sa_t *child_sa, child_sa_state_t state)
{ {
if (this->cache->has_ike_sa(this->cache, ike_sa->get_id(ike_sa))) if (ike_sa->get_state(ike_sa) == IKE_PASSIVE)
{ /* IKE_SA is cached, do not sync */ { /* only sync active IKE_SAs */
return TRUE; return TRUE;
} }
@@ -150,8 +140,7 @@ static void destroy(private_ha_sync_child_t *this)
/** /**
* See header * See header
*/ */
ha_sync_child_t *ha_sync_child_create(ha_sync_socket_t *socket, ha_sync_child_t *ha_sync_child_create(ha_sync_socket_t *socket)
ha_sync_cache_t *cache)
{ {
private_ha_sync_child_t *this = malloc_thing(private_ha_sync_child_t); private_ha_sync_child_t *this = malloc_thing(private_ha_sync_child_t);
@@ -161,7 +150,6 @@ ha_sync_child_t *ha_sync_child_create(ha_sync_socket_t *socket,
this->public.destroy = (void(*)(ha_sync_child_t*))destroy; this->public.destroy = (void(*)(ha_sync_child_t*))destroy;
this->socket = socket; this->socket = socket;
this->cache = cache;
return &this->public; return &this->public;
} }
+2 -4
View File
@@ -24,7 +24,7 @@
#define HA_SYNC_CHILD_H_ #define HA_SYNC_CHILD_H_
#include "ha_sync_socket.h" #include "ha_sync_socket.h"
#include "ha_sync_cache.h" #include "ha_sync_segments.h"
#include <daemon.h> #include <daemon.h>
@@ -50,10 +50,8 @@ struct ha_sync_child_t {
* Create a ha_sync_child instance. * Create a ha_sync_child instance.
* *
* @param socket socket to use for sending synchronization messages * @param socket socket to use for sending synchronization messages
* @param cache synced and cached SAs
* @return CHILD listener * @return CHILD listener
*/ */
ha_sync_child_t *ha_sync_child_create(ha_sync_socket_t *socket, ha_sync_child_t *ha_sync_child_create(ha_sync_socket_t *socket);
ha_sync_cache_t *cache);
#endif /* HA_SYNC_CHILD_ @}*/ #endif /* HA_SYNC_CHILD_ @}*/
+6 -6
View File
@@ -42,9 +42,9 @@ struct private_ha_sync_ctl_t {
ha_sync_ctl_t public; ha_sync_ctl_t public;
/** /**
* Cache to control * Segments to control
*/ */
ha_sync_cache_t *cache; ha_sync_segments_t *segments;
/** /**
* FIFO reader thread * FIFO reader thread
@@ -80,10 +80,10 @@ static job_requeue_t dispatch_fifo(private_ha_sync_ctl_t *this)
switch (buf[0]) switch (buf[0])
{ {
case '+': case '+':
this->cache->activate(this->cache, segment); this->segments->activate(this->segments, segment);
break; break;
case '-': case '-':
this->cache->deactivate(this->cache, segment); this->segments->deactivate(this->segments, segment);
break; break;
default: default:
break; break;
@@ -107,7 +107,7 @@ static void destroy(private_ha_sync_ctl_t *this)
/** /**
* See header * See header
*/ */
ha_sync_ctl_t *ha_sync_ctl_create(ha_sync_cache_t *cache) ha_sync_ctl_t *ha_sync_ctl_create(ha_sync_segments_t *segments)
{ {
private_ha_sync_ctl_t *this = malloc_thing(private_ha_sync_ctl_t); private_ha_sync_ctl_t *this = malloc_thing(private_ha_sync_ctl_t);
@@ -122,7 +122,7 @@ ha_sync_ctl_t *ha_sync_ctl_create(ha_sync_cache_t *cache)
} }
} }
this->cache = cache; this->segments = segments;
this->job = callback_job_create((callback_job_cb_t)dispatch_fifo, this->job = callback_job_create((callback_job_cb_t)dispatch_fifo,
this, NULL, NULL); this, NULL, NULL);
charon->processor->queue_job(charon->processor, (job_t*)this->job); charon->processor->queue_job(charon->processor, (job_t*)this->job);
+3 -3
View File
@@ -23,7 +23,7 @@
#ifndef HA_SYNC_CTL_H_ #ifndef HA_SYNC_CTL_H_
#define HA_SYNC_CTL_H_ #define HA_SYNC_CTL_H_
#include "ha_sync_cache.h" #include "ha_sync_segments.h"
typedef struct ha_sync_ctl_t ha_sync_ctl_t; typedef struct ha_sync_ctl_t ha_sync_ctl_t;
@@ -41,9 +41,9 @@ struct ha_sync_ctl_t {
/** /**
* Create a ha_sync_ctl instance. * Create a ha_sync_ctl instance.
* *
* @param cache cache to control in this socket * @param segments segments to control
* @return HA sync control interface * @return HA sync control interface
*/ */
ha_sync_ctl_t *ha_sync_ctl_create(ha_sync_cache_t *cache); ha_sync_ctl_t *ha_sync_ctl_create(ha_sync_segments_t *segments);
#endif /* HA_SYNC_CTL_ @}*/ #endif /* HA_SYNC_CTL_ @}*/
+79 -76
View File
@@ -37,11 +37,6 @@ struct private_ha_sync_dispatcher_t {
*/ */
ha_sync_socket_t *socket; ha_sync_socket_t *socket;
/**
* Synced SA state cache
*/
ha_sync_cache_t *cache;
/** /**
* Dispatcher job * Dispatcher job
*/ */
@@ -77,14 +72,11 @@ static void process_ike_add(private_ha_sync_dispatcher_t *this,
switch (attribute) switch (attribute)
{ {
case HA_SYNC_IKE_ID: case HA_SYNC_IKE_ID:
ike_sa = this->cache->get_ike_sa(this->cache, value.ike_sa_id); ike_sa = ike_sa_create(value.ike_sa_id);
DBG2(DBG_IKE, "got HA_SYNC_IKE_ADD: %llx:%llx - %p",
value.ike_sa_id->get_initiator_spi(value.ike_sa_id),
value.ike_sa_id->get_responder_spi(value.ike_sa_id),
ike_sa);
break; break;
case HA_SYNC_IKE_REKEY_ID: case HA_SYNC_IKE_REKEY_ID:
old_sa = this->cache->get_ike_sa(this->cache, value.ike_sa_id); old_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
value.ike_sa_id);
break; break;
case HA_SYNC_NONCE_I: case HA_SYNC_NONCE_I:
nonce_i = value.chunk; nonce_i = value.chunk;
@@ -142,19 +134,30 @@ static void process_ike_add(private_ha_sync_dispatcher_t *this,
proposal->add_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, prf, 0); proposal->add_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, prf, 0);
} }
charon->bus->set_sa(charon->bus, ike_sa); charon->bus->set_sa(charon->bus, ike_sa);
if (!keymat->derive_ike_keys(keymat, proposal, &dh, nonce_i, nonce_r, if (keymat->derive_ike_keys(keymat, proposal, &dh, nonce_i, nonce_r,
ike_sa->get_id(ike_sa), old_prf, old_skd)) ike_sa->get_id(ike_sa), old_prf, old_skd))
{
if (old_sa)
{
ike_sa->inherit(ike_sa, old_sa);
charon->ike_sa_manager->checkin_and_destroy(
charon->ike_sa_manager, old_sa);
old_sa = NULL;
}
ike_sa->set_state(ike_sa, IKE_CONNECTING);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
else
{ {
DBG1(DBG_IKE, "HA sync keymat derivation failed"); DBG1(DBG_IKE, "HA sync keymat derivation failed");
ike_sa->destroy(ike_sa);
} }
charon->bus->set_sa(charon->bus, NULL); charon->bus->set_sa(charon->bus, NULL);
proposal->destroy(proposal); proposal->destroy(proposal);
}
if (old_sa) if (old_sa)
{ {
ike_sa->inherit(ike_sa, old_sa); charon->ike_sa_manager->checkin(charon->ike_sa_manager, old_sa);
this->cache->delete_ike_sa(this->cache, old_sa->get_id(old_sa));
}
} }
} }
@@ -196,17 +199,14 @@ static void process_ike_update(private_ha_sync_dispatcher_t *this,
{ {
if (attribute != HA_SYNC_IKE_ID && ike_sa == NULL) if (attribute != HA_SYNC_IKE_ID && ike_sa == NULL)
{ {
DBG1(DBG_IKE, "HA_SYNC_IKE_ID must be first attribute"); /* must be first attribute */
break; break;
} }
switch (attribute) switch (attribute)
{ {
case HA_SYNC_IKE_ID: case HA_SYNC_IKE_ID:
ike_sa = this->cache->get_ike_sa(this->cache, value.ike_sa_id); ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
DBG2(DBG_IKE, "got HA_SYNC_IKE_UPDATE: %llx:%llx - %p", value.ike_sa_id);
value.ike_sa_id->get_initiator_spi(value.ike_sa_id),
value.ike_sa_id->get_responder_spi(value.ike_sa_id),
ike_sa);
break; break;
case HA_SYNC_LOCAL_ID: case HA_SYNC_LOCAL_ID:
ike_sa->set_my_id(ike_sa, value.id->clone(value.id)); ike_sa->set_my_id(ike_sa, value.id->clone(value.id));
@@ -235,6 +235,15 @@ static void process_ike_update(private_ha_sync_dispatcher_t *this,
case HA_SYNC_CONFIG_NAME: case HA_SYNC_CONFIG_NAME:
peer_cfg = charon->backends->get_peer_cfg_by_name( peer_cfg = charon->backends->get_peer_cfg_by_name(
charon->backends, value.str); charon->backends, value.str);
if (peer_cfg)
{
ike_sa->set_peer_cfg(ike_sa, peer_cfg);
peer_cfg->destroy(peer_cfg);
}
else
{
DBG1(DBG_IKE, "HA sync is missing nodes peer configuration");
}
break; break;
case HA_SYNC_CONDITIONS: case HA_SYNC_CONDITIONS:
set_condition(ike_sa, value.u32, EXT_NATT); set_condition(ike_sa, value.u32, EXT_NATT);
@@ -250,26 +259,26 @@ static void process_ike_update(private_ha_sync_dispatcher_t *this,
set_extension(ike_sa, value.u32, COND_CERTREQ_SEEN); set_extension(ike_sa, value.u32, COND_CERTREQ_SEEN);
set_extension(ike_sa, value.u32, COND_ORIGINAL_INITIATOR); set_extension(ike_sa, value.u32, COND_ORIGINAL_INITIATOR);
break; break;
case HA_SYNC_INITIATE_MID:
ike_sa->set_message_id(ike_sa, TRUE, value.u32);
break;
case HA_SYNC_RESPOND_MID:
ike_sa->set_message_id(ike_sa, FALSE, value.u32);
break;
default: default:
break; break;
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (peer_cfg) if (ike_sa)
{ {
ike_sa->set_peer_cfg(ike_sa, peer_cfg); if (ike_sa->get_state(ike_sa) == IKE_CONNECTING &&
peer_cfg->destroy(peer_cfg); ike_sa->get_peer_cfg(ike_sa))
{
charon->bus->set_sa(charon->bus, ike_sa); ike_sa->set_state(ike_sa, IKE_PASSIVE);
/* we use the CONNECTING state to indicate sync is complete. */ }
/* TODO: add an additional HOT_COPY state? */ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
ike_sa->set_state(ike_sa, IKE_CONNECTING);
charon->bus->set_sa(charon->bus, NULL);
}
else
{
DBG1(DBG_IKE, "HA sync is missing nodes peer configuration");
} }
} }
@@ -282,6 +291,7 @@ static void process_ike_delete(private_ha_sync_dispatcher_t *this,
ha_sync_message_attribute_t attribute; ha_sync_message_attribute_t attribute;
ha_sync_message_value_t value; ha_sync_message_value_t value;
enumerator_t *enumerator; enumerator_t *enumerator;
ike_sa_t *ike_sa;
enumerator = message->create_attribute_enumerator(message); enumerator = message->create_attribute_enumerator(message);
while (enumerator->enumerate(enumerator, &attribute, &value)) while (enumerator->enumerate(enumerator, &attribute, &value))
@@ -289,10 +299,13 @@ static void process_ike_delete(private_ha_sync_dispatcher_t *this,
switch (attribute) switch (attribute)
{ {
case HA_SYNC_IKE_ID: case HA_SYNC_IKE_ID:
DBG2(DBG_IKE, "got HA_SYNC_IKE_DELETE: %llx:%llx", ike_sa = charon->ike_sa_manager->checkout(
value.ike_sa_id->get_initiator_spi(value.ike_sa_id), charon->ike_sa_manager, value.ike_sa_id);
value.ike_sa_id->get_responder_spi(value.ike_sa_id)); if (ike_sa)
this->cache->delete_ike_sa(this->cache, value.ike_sa_id); {
charon->ike_sa_manager->checkin_and_destroy(
charon->ike_sa_manager, ike_sa);
}
break; break;
default: default:
break; break;
@@ -301,17 +314,16 @@ static void process_ike_delete(private_ha_sync_dispatcher_t *this,
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
/** /**
* get the child_cfg with the same name as the peer cfg * Lookup a child cfg from the peer cfg by name
*/ */
static child_cfg_t* find_child_cfg(char *name) static child_cfg_t* find_child_cfg(ike_sa_t *ike_sa, char *name)
{ {
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
child_cfg_t *current, *found = NULL; child_cfg_t *current, *found = NULL;
enumerator_t *enumerator; enumerator_t *enumerator;
peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, name); peer_cfg = ike_sa->get_peer_cfg(ike_sa);
if (peer_cfg) if (peer_cfg)
{ {
enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg); enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
@@ -320,12 +332,10 @@ static child_cfg_t* find_child_cfg(char *name)
if (streq(current->get_name(current), name)) if (streq(current->get_name(current), name))
{ {
found = current; found = current;
found->get_ref(found);
break; break;
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
peer_cfg->destroy(peer_cfg);
} }
return found; return found;
} }
@@ -340,6 +350,7 @@ static void process_child_add(private_ha_sync_dispatcher_t *this,
ha_sync_message_value_t value; ha_sync_message_value_t value;
enumerator_t *enumerator; enumerator_t *enumerator;
ike_sa_t *ike_sa = NULL; ike_sa_t *ike_sa = NULL;
char *config_name;
child_cfg_t *config = NULL; child_cfg_t *config = NULL;
child_sa_t *child_sa; child_sa_t *child_sa;
proposal_t *proposal; proposal_t *proposal;
@@ -362,15 +373,12 @@ static void process_child_add(private_ha_sync_dispatcher_t *this,
switch (attribute) switch (attribute)
{ {
case HA_SYNC_IKE_ID: case HA_SYNC_IKE_ID:
ike_sa = this->cache->get_ike_sa(this->cache, value.ike_sa_id); ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
value.ike_sa_id);
initiator = value.ike_sa_id->is_initiator(value.ike_sa_id); initiator = value.ike_sa_id->is_initiator(value.ike_sa_id);
DBG2(DBG_CHD, "got HA_SYNC_CHILD_ADD: %llx:%llx - %p",
value.ike_sa_id->get_initiator_spi(value.ike_sa_id),
value.ike_sa_id->get_responder_spi(value.ike_sa_id),
ike_sa);
break; break;
case HA_SYNC_CONFIG_NAME: case HA_SYNC_CONFIG_NAME:
config = find_child_cfg(value.str); config_name = value.str;
break; break;
case HA_SYNC_INBOUND_SPI: case HA_SYNC_INBOUND_SPI:
inbound_spi = value.u32; inbound_spi = value.u32;
@@ -414,22 +422,22 @@ static void process_child_add(private_ha_sync_dispatcher_t *this,
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (!config)
{
DBG1(DBG_CHD, "HA sync is missing nodes child configuration");
return;
}
if (!ike_sa) if (!ike_sa)
{ {
config->destroy(config);
DBG1(DBG_CHD, "IKE_SA for HA sync CHILD_SA not found"); DBG1(DBG_CHD, "IKE_SA for HA sync CHILD_SA not found");
return; return;
} }
charon->bus->set_sa(charon->bus, ike_sa); config = find_child_cfg(ike_sa, config_name);
if (!config)
{
DBG1(DBG_CHD, "HA sync is missing nodes child configuration");
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
return;
}
child_sa = child_sa_create(ike_sa->get_my_host(ike_sa), child_sa = child_sa_create(ike_sa->get_my_host(ike_sa),
ike_sa->get_other_host(ike_sa), config, 0, ike_sa->get_other_host(ike_sa), config, 0,
ike_sa->has_condition(ike_sa, COND_NAT_ANY)); ike_sa->has_condition(ike_sa, COND_NAT_ANY));
config->destroy(config);
child_sa->set_mode(child_sa, mode); child_sa->set_mode(child_sa, mode);
child_sa->set_protocol(child_sa, PROTO_ESP); child_sa->set_protocol(child_sa, PROTO_ESP);
child_sa->set_ipcomp(child_sa, ipcomp); child_sa->set_ipcomp(child_sa, ipcomp);
@@ -451,7 +459,7 @@ static void process_child_add(private_ha_sync_dispatcher_t *this,
DBG1(DBG_CHD, "HA sync CHILD_SA key derivation failed"); DBG1(DBG_CHD, "HA sync CHILD_SA key derivation failed");
child_sa->destroy(child_sa); child_sa->destroy(child_sa);
proposal->destroy(proposal); proposal->destroy(proposal);
charon->bus->set_sa(charon->bus, NULL); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
return; return;
} }
child_sa->set_proposal(child_sa, proposal); child_sa->set_proposal(child_sa, proposal);
@@ -487,7 +495,7 @@ static void process_child_add(private_ha_sync_dispatcher_t *this,
{ {
DBG1(DBG_CHD, "HA sync CHILD_SA installation failed"); DBG1(DBG_CHD, "HA sync CHILD_SA installation failed");
child_sa->destroy(child_sa); child_sa->destroy(child_sa);
charon->bus->set_sa(charon->bus, NULL); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
return; return;
} }
@@ -516,7 +524,7 @@ static void process_child_add(private_ha_sync_dispatcher_t *this,
child_sa->set_state(child_sa, CHILD_INSTALLED); child_sa->set_state(child_sa, CHILD_INSTALLED);
ike_sa->add_child_sa(ike_sa, child_sa); ike_sa->add_child_sa(ike_sa, child_sa);
charon->bus->set_sa(charon->bus, NULL); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
} }
/** /**
@@ -536,15 +544,8 @@ static void process_child_delete(private_ha_sync_dispatcher_t *this,
switch (attribute) switch (attribute)
{ {
case HA_SYNC_IKE_ID: case HA_SYNC_IKE_ID:
if (this->cache->has_ike_sa(this->cache, value.ike_sa_id)) ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
{ value.ike_sa_id);
ike_sa = this->cache->get_ike_sa(this->cache, value.ike_sa_id);
DBG2(DBG_CHD, "got HA_SYNC_CHILD_DELETE: %llx:%llx - %p",
value.ike_sa_id->get_initiator_spi(value.ike_sa_id),
value.ike_sa_id->get_responder_spi(value.ike_sa_id),
ike_sa);
continue;
}
break; break;
case HA_SYNC_INBOUND_SPI: case HA_SYNC_INBOUND_SPI:
if (!ike_sa || ike_sa->destroy_child_sa(ike_sa, PROTO_ESP, if (!ike_sa || ike_sa->destroy_child_sa(ike_sa, PROTO_ESP,
@@ -559,6 +560,10 @@ static void process_child_delete(private_ha_sync_dispatcher_t *this,
} }
break; break;
} }
if (ike_sa)
{
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
@@ -609,15 +614,13 @@ static void destroy(private_ha_sync_dispatcher_t *this)
/** /**
* See header * See header
*/ */
ha_sync_dispatcher_t *ha_sync_dispatcher_create(ha_sync_socket_t *socket, ha_sync_dispatcher_t *ha_sync_dispatcher_create(ha_sync_socket_t *socket)
ha_sync_cache_t *cache)
{ {
private_ha_sync_dispatcher_t *this = malloc_thing(private_ha_sync_dispatcher_t); private_ha_sync_dispatcher_t *this = malloc_thing(private_ha_sync_dispatcher_t);
this->public.destroy = (void(*)(ha_sync_dispatcher_t*))destroy; this->public.destroy = (void(*)(ha_sync_dispatcher_t*))destroy;
this->socket = socket; this->socket = socket;
this->cache = cache;
this->job = callback_job_create((callback_job_cb_t)dispatch, this->job = callback_job_create((callback_job_cb_t)dispatch,
this, NULL, NULL); this, NULL, NULL);
charon->processor->queue_job(charon->processor, (job_t*)this->job); charon->processor->queue_job(charon->processor, (job_t*)this->job);
@@ -24,7 +24,6 @@
#define HA_SYNC_DISPATCHER_H_ #define HA_SYNC_DISPATCHER_H_
#include "ha_sync_socket.h" #include "ha_sync_socket.h"
#include "ha_sync_cache.h"
typedef struct ha_sync_dispatcher_t ha_sync_dispatcher_t; typedef struct ha_sync_dispatcher_t ha_sync_dispatcher_t;
@@ -43,10 +42,8 @@ struct ha_sync_dispatcher_t {
* Create a ha_sync_dispatcher instance pulling from socket. * Create a ha_sync_dispatcher instance pulling from socket.
* *
* @param socket socket to pull messages from * @param socket socket to pull messages from
* @param cache cache to push synced SAs to
* @return dispatcher object * @return dispatcher object
*/ */
ha_sync_dispatcher_t *ha_sync_dispatcher_create(ha_sync_socket_t *socket, ha_sync_dispatcher_t *ha_sync_dispatcher_create(ha_sync_socket_t *socket);
ha_sync_cache_t *cache);
#endif /* HA_SYNC_DISPATCHER_ @}*/ #endif /* HA_SYNC_DISPATCHER_ @}*/
+56 -27
View File
@@ -33,11 +33,6 @@ struct private_ha_sync_ike_t {
* socket we use for syncing * socket we use for syncing
*/ */
ha_sync_socket_t *socket; ha_sync_socket_t *socket;
/**
* Synced and cached SAs
*/
ha_sync_cache_t *cache;
}; };
/** /**
@@ -76,11 +71,6 @@ static bool ike_keys(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
proposal_t *proposal; proposal_t *proposal;
u_int16_t alg, len; u_int16_t alg, len;
if (this->cache->has_ike_sa(this->cache, ike_sa->get_id(ike_sa)))
{ /* IKE_SA is cached, do not sync */
return TRUE;
}
if (dh->get_shared_secret(dh, &secret) != SUCCESS) if (dh->get_shared_secret(dh, &secret) != SUCCESS)
{ {
return TRUE; return TRUE;
@@ -136,8 +126,8 @@ static bool ike_state_change(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
{ {
ha_sync_message_t *m; ha_sync_message_t *m;
if (this->cache->has_ike_sa(this->cache, ike_sa->get_id(ike_sa))) if (ike_sa->get_state(ike_sa) == IKE_PASSIVE)
{ /* IKE_SA is cached, do not sync */ { /* only sync active IKE_SAs */
return TRUE; return TRUE;
} }
@@ -148,8 +138,9 @@ static bool ike_state_change(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
iterator_t *iterator; iterator_t *iterator;
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
u_int32_t extension, condition; u_int32_t extension, condition;
host_t *local_vip, *remote_vip, *addr; host_t *addr;
identification_t *eap_id; identification_t *eap_id;
ike_sa_id_t *id;
peer_cfg = ike_sa->get_peer_cfg(ike_sa); peer_cfg = ike_sa->get_peer_cfg(ike_sa);
@@ -165,12 +156,11 @@ static bool ike_state_change(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
| copy_extension(ike_sa, EXT_MOBIKE) | copy_extension(ike_sa, EXT_MOBIKE)
| copy_extension(ike_sa, EXT_HASH_AND_URL); | copy_extension(ike_sa, EXT_HASH_AND_URL);
local_vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
remote_vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
eap_id = ike_sa->get_eap_identity(ike_sa); eap_id = ike_sa->get_eap_identity(ike_sa);
id = ike_sa->get_id(ike_sa);
m = ha_sync_message_create(HA_SYNC_IKE_UPDATE); m = ha_sync_message_create(HA_SYNC_IKE_UPDATE);
m->add_attribute(m, HA_SYNC_IKE_ID, ike_sa->get_id(ike_sa)); m->add_attribute(m, HA_SYNC_IKE_ID, id);
m->add_attribute(m, HA_SYNC_LOCAL_ID, ike_sa->get_my_id(ike_sa)); m->add_attribute(m, HA_SYNC_LOCAL_ID, ike_sa->get_my_id(ike_sa));
m->add_attribute(m, HA_SYNC_REMOTE_ID, ike_sa->get_other_id(ike_sa)); m->add_attribute(m, HA_SYNC_REMOTE_ID, ike_sa->get_other_id(ike_sa));
m->add_attribute(m, HA_SYNC_LOCAL_ADDR, ike_sa->get_my_host(ike_sa)); m->add_attribute(m, HA_SYNC_LOCAL_ADDR, ike_sa->get_my_host(ike_sa));
@@ -178,14 +168,6 @@ static bool ike_state_change(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
m->add_attribute(m, HA_SYNC_CONDITIONS, condition); m->add_attribute(m, HA_SYNC_CONDITIONS, condition);
m->add_attribute(m, HA_SYNC_EXTENSIONS, extension); m->add_attribute(m, HA_SYNC_EXTENSIONS, extension);
m->add_attribute(m, HA_SYNC_CONFIG_NAME, peer_cfg->get_name(peer_cfg)); m->add_attribute(m, HA_SYNC_CONFIG_NAME, peer_cfg->get_name(peer_cfg));
if (local_vip)
{
m->add_attribute(m, HA_SYNC_LOCAL_VIP, local_vip);
}
if (remote_vip)
{
m->add_attribute(m, HA_SYNC_REMOTE_VIP, remote_vip);
}
if (eap_id) if (eap_id)
{ {
m->add_attribute(m, HA_SYNC_EAP_ID, eap_id); m->add_attribute(m, HA_SYNC_EAP_ID, eap_id);
@@ -212,6 +194,54 @@ static bool ike_state_change(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
return TRUE; return TRUE;
} }
/**
* Implementation of listener_t.message
*/
static bool message_hook(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
message_t *message, bool incoming)
{
if (message->get_exchange_type(message) != IKE_SA_INIT &&
message->get_request(message))
{ /* we sync on requests, but skip it on IKE_SA_INIT */
ha_sync_message_t *m;
u_int32_t mid;
m = ha_sync_message_create(HA_SYNC_IKE_UPDATE);
m->add_attribute(m, HA_SYNC_IKE_ID, ike_sa->get_id(ike_sa));
mid = message->get_message_id(message) + 1;
if (incoming)
{
m->add_attribute(m, HA_SYNC_RESPOND_MID, mid);
}
else
{
m->add_attribute(m, HA_SYNC_INITIATE_MID, mid);
}
this->socket->push(this->socket, m);
m->destroy(m);
}
if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED &&
message->get_exchange_type(message) == IKE_AUTH &&
!message->get_request(message))
{ /* After IKE_SA has been established, sync peers virtual IP.
* We cannot sync it in the state_change hook, it is installed later.
* TODO: where to sync local VIP? */
ha_sync_message_t *m;
host_t *vip;
vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
if (vip)
{
m = ha_sync_message_create(HA_SYNC_IKE_UPDATE);
m->add_attribute(m, HA_SYNC_IKE_ID, ike_sa->get_id(ike_sa));
m->add_attribute(m, HA_SYNC_REMOTE_VIP, vip);
this->socket->push(this->socket, m);
m->destroy(m);
}
}
return TRUE;
}
/** /**
* Implementation of ha_sync_ike_t.destroy. * Implementation of ha_sync_ike_t.destroy.
*/ */
@@ -223,18 +253,17 @@ static void destroy(private_ha_sync_ike_t *this)
/** /**
* See header * See header
*/ */
ha_sync_ike_t *ha_sync_ike_create(ha_sync_socket_t *socket, ha_sync_ike_t *ha_sync_ike_create(ha_sync_socket_t *socket)
ha_sync_cache_t *cache)
{ {
private_ha_sync_ike_t *this = malloc_thing(private_ha_sync_ike_t); private_ha_sync_ike_t *this = malloc_thing(private_ha_sync_ike_t);
memset(&this->public.listener, 0, sizeof(listener_t)); memset(&this->public.listener, 0, sizeof(listener_t));
this->public.listener.ike_keys = (bool(*)(listener_t*, ike_sa_t *ike_sa, diffie_hellman_t *dh,chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey))ike_keys; this->public.listener.ike_keys = (bool(*)(listener_t*, ike_sa_t *ike_sa, diffie_hellman_t *dh,chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey))ike_keys;
this->public.listener.ike_state_change = (bool(*)(listener_t*,ike_sa_t *ike_sa, ike_sa_state_t state))ike_state_change; this->public.listener.ike_state_change = (bool(*)(listener_t*,ike_sa_t *ike_sa, ike_sa_state_t state))ike_state_change;
this->public.listener.message = (bool(*)(listener_t*, ike_sa_t *, message_t *,bool))message_hook;
this->public.destroy = (void(*)(ha_sync_ike_t*))destroy; this->public.destroy = (void(*)(ha_sync_ike_t*))destroy;
this->socket = socket; this->socket = socket;
this->cache = cache;
return &this->public; return &this->public;
} }
+2 -4
View File
@@ -24,7 +24,7 @@
#define HA_SYNC_IKE_H_ #define HA_SYNC_IKE_H_
#include "ha_sync_socket.h" #include "ha_sync_socket.h"
#include "ha_sync_cache.h" #include "ha_sync_segments.h"
#include <daemon.h> #include <daemon.h>
@@ -50,10 +50,8 @@ struct ha_sync_ike_t {
* Create a ha_sync_ike instance. * Create a ha_sync_ike instance.
* *
* @param socket socket to use for sending synchronization messages * @param socket socket to use for sending synchronization messages
* @param cache synced and cached SAs
* @return IKE listener * @return IKE listener
*/ */
ha_sync_ike_t *ha_sync_ike_create(ha_sync_socket_t *socket, ha_sync_ike_t *ha_sync_ike_create(ha_sync_socket_t *socket);
ha_sync_cache_t *cache);
#endif /* HA_SYNC_IKE_ @}*/ #endif /* HA_SYNC_IKE_ @}*/
+7 -3
View File
@@ -211,7 +211,7 @@ static void add_attribute(private_ha_sync_message_t *this,
{ {
u_int8_t val; u_int8_t val;
val = (u_int8_t)va_arg(args, u_int32_t); val = va_arg(args, u_int);
check_buf(this, sizeof(val)); check_buf(this, sizeof(val));
this->buf.ptr[this->buf.len] = val; this->buf.ptr[this->buf.len] = val;
this->buf.len += sizeof(val); this->buf.len += sizeof(val);
@@ -228,7 +228,7 @@ static void add_attribute(private_ha_sync_message_t *this,
{ {
u_int16_t val; u_int16_t val;
val = (u_int16_t)va_arg(args, u_int32_t); val = va_arg(args, u_int);
check_buf(this, sizeof(val)); check_buf(this, sizeof(val));
*(u_int16_t*)(this->buf.ptr + this->buf.len) = htons(val); *(u_int16_t*)(this->buf.ptr + this->buf.len) = htons(val);
this->buf.len += sizeof(val); this->buf.len += sizeof(val);
@@ -239,10 +239,12 @@ static void add_attribute(private_ha_sync_message_t *this,
case HA_SYNC_EXTENSIONS: case HA_SYNC_EXTENSIONS:
case HA_SYNC_INBOUND_SPI: case HA_SYNC_INBOUND_SPI:
case HA_SYNC_OUTBOUND_SPI: case HA_SYNC_OUTBOUND_SPI:
case HA_SYNC_INITIATE_MID:
case HA_SYNC_RESPOND_MID:
{ {
u_int32_t val; u_int32_t val;
val = va_arg(args, u_int32_t); val = va_arg(args, u_int);
check_buf(this, sizeof(val)); check_buf(this, sizeof(val));
*(u_int32_t*)(this->buf.ptr + this->buf.len) = htonl(val); *(u_int32_t*)(this->buf.ptr + this->buf.len) = htonl(val);
this->buf.len += sizeof(val); this->buf.len += sizeof(val);
@@ -453,6 +455,8 @@ static bool attribute_enumerate(attribute_enumerator_t *this,
case HA_SYNC_EXTENSIONS: case HA_SYNC_EXTENSIONS:
case HA_SYNC_INBOUND_SPI: case HA_SYNC_INBOUND_SPI:
case HA_SYNC_OUTBOUND_SPI: case HA_SYNC_OUTBOUND_SPI:
case HA_SYNC_INITIATE_MID:
case HA_SYNC_RESPOND_MID:
{ {
if (this->buf.len < sizeof(u_int32_t)) if (this->buf.len < sizeof(u_int32_t))
{ {
@@ -119,6 +119,10 @@ enum ha_sync_message_attribute_t {
HA_SYNC_LOCAL_TS, HA_SYNC_LOCAL_TS,
/** traffic_selector_t*, remote traffic selector */ /** traffic_selector_t*, remote traffic selector */
HA_SYNC_REMOTE_TS, HA_SYNC_REMOTE_TS,
/** u_int32_t, initiating message ID */
HA_SYNC_INITIATE_MID,
/** u_int32_t, responding message ID */
HA_SYNC_RESPOND_MID,
}; };
/** /**
+9 -9
View File
@@ -20,7 +20,7 @@
#include "ha_sync_child.h" #include "ha_sync_child.h"
#include "ha_sync_socket.h" #include "ha_sync_socket.h"
#include "ha_sync_dispatcher.h" #include "ha_sync_dispatcher.h"
#include "ha_sync_cache.h" #include "ha_sync_segments.h"
#include "ha_sync_ctl.h" #include "ha_sync_ctl.h"
#include <daemon.h> #include <daemon.h>
@@ -59,9 +59,9 @@ struct private_ha_sync_plugin_t {
ha_sync_dispatcher_t *dispatcher; ha_sync_dispatcher_t *dispatcher;
/** /**
* Local cache of a nodes synced SAs * Active/Passive segment management
*/ */
ha_sync_cache_t *cache; ha_sync_segments_t *segments;
/** /**
* Segment control interface via FIFO * Segment control interface via FIFO
@@ -80,7 +80,7 @@ static void destroy(private_ha_sync_plugin_t *this)
this->child->destroy(this->child); this->child->destroy(this->child);
this->dispatcher->destroy(this->dispatcher); this->dispatcher->destroy(this->dispatcher);
this->ctl->destroy(this->ctl); this->ctl->destroy(this->ctl);
this->cache->destroy(this->cache); this->segments->destroy(this->segments);
this->socket->destroy(this->socket); this->socket->destroy(this->socket);
free(this); free(this);
} }
@@ -100,11 +100,11 @@ plugin_t *plugin_create()
free(this); free(this);
return NULL; return NULL;
} }
this->cache = ha_sync_cache_create(); this->segments = ha_sync_segments_create();
this->ctl = ha_sync_ctl_create(this->cache); this->ctl = ha_sync_ctl_create(this->segments);
this->dispatcher = ha_sync_dispatcher_create(this->socket, this->cache); this->dispatcher = ha_sync_dispatcher_create(this->socket);
this->ike = ha_sync_ike_create(this->socket, this->cache); this->ike = ha_sync_ike_create(this->socket);
this->child = ha_sync_child_create(this->socket, this->cache); this->child = ha_sync_child_create(this->socket);
charon->bus->add_listener(charon->bus, &this->ike->listener); charon->bus->add_listener(charon->bus, &this->ike->listener);
charon->bus->add_listener(charon->bus, &this->child->listener); charon->bus->add_listener(charon->bus, &this->child->listener);
@@ -15,7 +15,7 @@
* $Id$ * $Id$
*/ */
#include "ha_sync_cache.h" #include "ha_sync_segments.h"
#include <utils/linked_list.h> #include <utils/linked_list.h>
@@ -26,22 +26,17 @@ typedef u_int8_t u8;
#define MAX_SEGMENTS 16 #define MAX_SEGMENTS 16
typedef struct private_ha_sync_cache_t private_ha_sync_cache_t; typedef struct private_ha_sync_segments_t private_ha_sync_segments_t;
/** /**
* Private data of an ha_sync_cache_t object. * Private data of an ha_sync_segments_t object.
*/ */
struct private_ha_sync_cache_t { struct private_ha_sync_segments_t {
/** /**
* Public ha_sync_cache_t interface. * Public ha_sync_segments_t interface.
*/ */
ha_sync_cache_t public; ha_sync_segments_t public;
/**
* Linked list of IKE_SAs, ike_sa_t
*/
linked_list_t *list;
/** /**
* Init value for jhash * Init value for jhash
@@ -59,80 +54,10 @@ struct private_ha_sync_cache_t {
u_int16_t active; u_int16_t active;
}; };
/**
* Implementation of ha_sync_cache_t.get_ike_sa
*/
static ike_sa_t* get_ike_sa(private_ha_sync_cache_t *this, ike_sa_id_t *id)
{
enumerator_t *enumerator;
ike_sa_t *current, *found = NULL;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &current))
{
if (id->equals(id, current->get_id(current)))
{
found = current;
break;
}
}
enumerator->destroy(enumerator);
if (!found)
{
found = ike_sa_create(id);
this->list->insert_first(this->list, found);
}
return found;
}
/**
* Implementation of ha_sync_cache_t.has_ike_sa
*/
static bool has_ike_sa(private_ha_sync_cache_t *this, ike_sa_id_t *id)
{
enumerator_t *enumerator;
ike_sa_t *ike_sa;
bool found = FALSE;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (id->equals(id, ike_sa->get_id(ike_sa)))
{
found = TRUE;
break;
}
}
enumerator->destroy(enumerator);
return found;
}
/**
* Implementation of ha_sync_cache_t.delete_ike_sa
*/
static void delete_ike_sa(private_ha_sync_cache_t *this, ike_sa_id_t *id)
{
enumerator_t *enumerator;
ike_sa_t *ike_sa;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (id->equals(id, ike_sa->get_id(ike_sa)))
{
this->list->remove_at(this->list, enumerator);
ike_sa->destroy(ike_sa);
break;
}
}
enumerator->destroy(enumerator);
}
/** /**
* Check if a host address is in the CLUSTERIP segment * Check if a host address is in the CLUSTERIP segment
*/ */
static bool in_segment(private_ha_sync_cache_t *this, static bool in_segment(private_ha_sync_segments_t *this,
host_t *host, u_int segment) host_t *host, u_int segment)
{ {
if (host->get_family(host) == AF_INET) if (host->get_family(host) == AF_INET)
@@ -154,7 +79,7 @@ static bool in_segment(private_ha_sync_cache_t *this,
/** /**
* Log currently active segments * Log currently active segments
*/ */
static void log_segments(private_ha_sync_cache_t *this, bool activated, static void log_segments(private_ha_sync_segments_t *this, bool activated,
u_int segment) u_int segment)
{ {
char buf[64], *pos = buf; char buf[64], *pos = buf;
@@ -181,9 +106,9 @@ static void log_segments(private_ha_sync_cache_t *this, bool activated,
} }
/** /**
* Implementation of ha_sync_cache_t.activate * Implementation of ha_sync_segments_t.activate
*/ */
static void activate(private_ha_sync_cache_t *this, u_int segment) static void activate(private_ha_sync_segments_t *this, u_int segment)
{ {
ike_sa_t *ike_sa; ike_sa_t *ike_sa;
enumerator_t *enumerator; enumerator_t *enumerator;
@@ -195,63 +120,71 @@ static void activate(private_ha_sync_cache_t *this, u_int segment)
{ {
this->active |= mask; this->active |= mask;
enumerator = this->list->create_enumerator(this->list); enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
while (enumerator->enumerate(enumerator, &ike_sa)) while (enumerator->enumerate(enumerator, &ike_sa))
{ {
if (ike_sa->get_state(ike_sa) == IKE_CONNECTING && if (ike_sa->get_state(ike_sa) == IKE_PASSIVE &&
in_segment(this, ike_sa->get_other_host(ike_sa), segment)) in_segment(this, ike_sa->get_other_host(ike_sa), segment))
{ {
this->list->remove_at(this->list, enumerator);
ike_sa->set_state(ike_sa, IKE_ESTABLISHED); ike_sa->set_state(ike_sa, IKE_ESTABLISHED);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
log_segments(this, TRUE, segment); log_segments(this, TRUE, segment);
} }
} }
/** /**
* Implementation of ha_sync_cache_t.deactivate * Implementation of ha_sync_segments_t.deactivate
*/ */
static void deactivate(private_ha_sync_cache_t *this, u_int segment) static void deactivate(private_ha_sync_segments_t *this, u_int segment)
{ {
ike_sa_t *ike_sa;
enumerator_t *enumerator;
u_int16_t mask = 0x01 << (segment - 1); u_int16_t mask = 0x01 << (segment - 1);
if (segment > 0 && segment <= this->segment_count && (this->active & mask)) if (segment > 0 && segment <= this->segment_count && (this->active & mask))
{ {
this->active &= ~mask; this->active &= ~mask;
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))
{
ike_sa->set_state(ike_sa, IKE_PASSIVE);
}
}
enumerator->destroy(enumerator);
log_segments(this, FALSE, segment); log_segments(this, FALSE, segment);
} }
} }
/** /**
* Implementation of ha_sync_cache_t.destroy. * Implementation of ha_sync_segments_t.destroy.
*/ */
static void destroy(private_ha_sync_cache_t *this) static void destroy(private_ha_sync_segments_t *this)
{ {
this->list->destroy_offset(this->list, offsetof(ike_sa_t, destroy));
free(this); free(this);
} }
/** /**
* See header * See header
*/ */
ha_sync_cache_t *ha_sync_cache_create() ha_sync_segments_t *ha_sync_segments_create()
{ {
private_ha_sync_cache_t *this = malloc_thing(private_ha_sync_cache_t); private_ha_sync_segments_t *this = malloc_thing(private_ha_sync_segments_t);
enumerator_t *enumerator; enumerator_t *enumerator;
u_int segment; u_int segment;
char *str; char *str;
this->public.get_ike_sa = (ike_sa_t*(*)(ha_sync_cache_t*, ike_sa_id_t *id))get_ike_sa; this->public.activate = (void(*)(ha_sync_segments_t*, u_int segment))activate;
this->public.has_ike_sa = (bool(*)(ha_sync_cache_t*, ike_sa_id_t *id))has_ike_sa; this->public.deactivate = (void(*)(ha_sync_segments_t*, u_int segment))deactivate;
this->public.delete_ike_sa = (void(*)(ha_sync_cache_t*, ike_sa_id_t *id))delete_ike_sa; this->public.destroy = (void(*)(ha_sync_segments_t*))destroy;
this->public.activate = (void(*)(ha_sync_cache_t*, u_int segment))activate;
this->public.deactivate = (void(*)(ha_sync_cache_t*, u_int segment))deactivate;
this->public.destroy = (void(*)(ha_sync_cache_t*))destroy;
this->list = linked_list_create();
this->initval = 0; this->initval = 0;
this->active = 0; this->active = 0;
this->segment_count = lib->settings->get_int(lib->settings, this->segment_count = lib->settings->get_int(lib->settings,
@@ -0,0 +1,64 @@
/*
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* $Id$
*/
/**
* @defgroup ha_sync_segments ha_sync_segments
* @{ @ingroup ha_sync
*/
#ifndef HA_SYNC_SEGMENTS_H_
#define HA_SYNC_SEGMENTS_H_
#include <daemon.h>
typedef struct ha_sync_segments_t ha_sync_segments_t;
/**
* Locally segmentsd HA state synced from other nodes.
*/
struct ha_sync_segments_t {
/**
* Activate a set of IKE_SAs identified by a segments.
*
* Activating means do a takeover of SAs as the responsible node has failed.
* This involves moving all SAs to the daemons IKE_SA manager and handle
* them actively now.
*
* @param segments numerical segments to takeover
*/
void (*activate)(ha_sync_segments_t *this, u_int segments);
/**
* Deactivate a set of IKE_SAs identified by a segments.
*
* @param segments numerical segments to takeover
*/
void (*deactivate)(ha_sync_segments_t *this, u_int segments);
/**
* Destroy a ha_sync_segments_t.
*/
void (*destroy)(ha_sync_segments_t *this);
};
/**
* Create a ha_sync_segments instance.
*/
ha_sync_segments_t *ha_sync_segments_create();
#endif /* HA_SYNC_SEGMENTS_ @}*/
+1 -1
View File
@@ -322,7 +322,7 @@ struct child_sa_t {
}; };
/** /**
* Constructor to create a new child_sa_t. * Constructor to create a child SA negotiated with IKE.
* *
* @param me own address * @param me own address
* @param other remote address * @param other remote address