pushing basic CHILD_SA sync data to backup node
This commit is contained in:
committed by
Martin Willi
parent
765935c8f6
commit
7999be5b0e
@@ -42,6 +42,85 @@ static bool child_keys(private_ha_sync_child_t *this, ike_sa_t *ike_sa,
|
|||||||
child_sa_t *child_sa, diffie_hellman_t *dh,
|
child_sa_t *child_sa, diffie_hellman_t *dh,
|
||||||
chunk_t nonce_i, chunk_t nonce_r)
|
chunk_t nonce_i, chunk_t nonce_r)
|
||||||
{
|
{
|
||||||
|
ha_sync_message_t *m;
|
||||||
|
chunk_t secret;
|
||||||
|
proposal_t *proposal;
|
||||||
|
u_int16_t alg, len;
|
||||||
|
linked_list_t *list;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
|
||||||
|
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_INBOUND_SPI, child_sa->get_spi(child_sa, TRUE));
|
||||||
|
m->add_attribute(m, HA_SYNC_OUTBOUND_SPI, child_sa->get_spi(child_sa, FALSE));
|
||||||
|
m->add_attribute(m, HA_SYNC_INBOUND_CPI, child_sa->get_cpi(child_sa, TRUE));
|
||||||
|
m->add_attribute(m, HA_SYNC_OUTBOUND_CPI, child_sa->get_cpi(child_sa, FALSE));
|
||||||
|
m->add_attribute(m, HA_SYNC_IPSEC_MODE, child_sa->get_mode(child_sa));
|
||||||
|
m->add_attribute(m, HA_SYNC_IPCOMP, child_sa->get_ipcomp(child_sa));
|
||||||
|
m->add_attribute(m, HA_SYNC_CONFIG_NAME, child_sa->get_name(child_sa));
|
||||||
|
|
||||||
|
proposal = child_sa->get_proposal(child_sa);
|
||||||
|
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &len))
|
||||||
|
{
|
||||||
|
m->add_attribute(m, HA_SYNC_ALG_ENCR, alg);
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
m->add_attribute(m, HA_SYNC_ALG_ENCR_LEN, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL))
|
||||||
|
{
|
||||||
|
m->add_attribute(m, HA_SYNC_ALG_INTEG, alg);
|
||||||
|
}
|
||||||
|
m->add_attribute(m, HA_SYNC_NONCE_I, nonce_i);
|
||||||
|
m->add_attribute(m, HA_SYNC_NONCE_R, nonce_r);
|
||||||
|
if (dh && dh->get_shared_secret(dh, &secret) == SUCCESS)
|
||||||
|
{
|
||||||
|
m->add_attribute(m, HA_SYNC_SECRET, secret);
|
||||||
|
chunk_clear(&secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
list = child_sa->get_traffic_selectors(child_sa, TRUE);
|
||||||
|
enumerator = list->create_enumerator(list);
|
||||||
|
while (enumerator->enumerate(enumerator, &ts))
|
||||||
|
{
|
||||||
|
m->add_attribute(m, HA_SYNC_LOCAL_TS, ts);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
list = child_sa->get_traffic_selectors(child_sa, FALSE);
|
||||||
|
enumerator = list->create_enumerator(list);
|
||||||
|
while (enumerator->enumerate(enumerator, &ts))
|
||||||
|
{
|
||||||
|
m->add_attribute(m, HA_SYNC_REMOTE_TS, ts);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
this->socket->push(this->socket, m);
|
||||||
|
m->destroy(m);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of listener_t.child_state_change
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (state == CHILD_DESTROYING)
|
||||||
|
{
|
||||||
|
ha_sync_message_t *m;
|
||||||
|
|
||||||
|
m = ha_sync_message_create(HA_SYNC_CHILD_DELETE);
|
||||||
|
|
||||||
|
m->add_attribute(m, HA_SYNC_IKE_ID, ike_sa->get_id(ike_sa));
|
||||||
|
m->add_attribute(m, HA_SYNC_INBOUND_SPI,
|
||||||
|
child_sa->get_spi(child_sa, TRUE));
|
||||||
|
this->socket->push(this->socket, m);
|
||||||
|
m->destroy(m);
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +141,7 @@ ha_sync_child_t *ha_sync_child_create(ha_sync_socket_t *socket)
|
|||||||
|
|
||||||
memset(&this->public.listener, 0, sizeof(listener_t));
|
memset(&this->public.listener, 0, sizeof(listener_t));
|
||||||
this->public.listener.child_keys = (bool(*)(listener_t*, ike_sa_t *ike_sa, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r))child_keys;
|
this->public.listener.child_keys = (bool(*)(listener_t*, ike_sa_t *ike_sa, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r))child_keys;
|
||||||
|
this->public.listener.child_state_change = (bool(*)(listener_t*,ike_sa_t *ike_sa, child_sa_t *child_sa, child_sa_state_t state))child_state_change;
|
||||||
this->public.destroy = (void(*)(ha_sync_child_t*))destroy;
|
this->public.destroy = (void(*)(ha_sync_child_t*))destroy;
|
||||||
|
|
||||||
this->socket = socket;
|
this->socket = socket;
|
||||||
|
|||||||
@@ -270,6 +270,28 @@ static void process_ike_delete(private_ha_sync_dispatcher_t *this,
|
|||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process messages of type CHILD_ADD
|
||||||
|
*/
|
||||||
|
static void process_child_add(private_ha_sync_dispatcher_t *this,
|
||||||
|
ha_sync_message_t *message)
|
||||||
|
{
|
||||||
|
chunk_t chunk = message->get_encoding(message);
|
||||||
|
|
||||||
|
DBG1(DBG_CHD, "CHILD_ADD: %B", &chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process messages of type CHILD_DELETE
|
||||||
|
*/
|
||||||
|
static void process_child_delete(private_ha_sync_dispatcher_t *this,
|
||||||
|
ha_sync_message_t *message)
|
||||||
|
{
|
||||||
|
chunk_t chunk = message->get_encoding(message);
|
||||||
|
|
||||||
|
DBG1(DBG_CHD, "CHILD_DELETE: %B", &chunk);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatcher job function
|
* Dispatcher job function
|
||||||
*/
|
*/
|
||||||
@@ -292,8 +314,10 @@ static job_requeue_t dispatch(private_ha_sync_dispatcher_t *this)
|
|||||||
case HA_SYNC_IKE_REKEY:
|
case HA_SYNC_IKE_REKEY:
|
||||||
break;
|
break;
|
||||||
case HA_SYNC_CHILD_ADD:
|
case HA_SYNC_CHILD_ADD:
|
||||||
|
process_child_add(this, message);
|
||||||
break;
|
break;
|
||||||
case HA_SYNC_CHILD_DELETE:
|
case HA_SYNC_CHILD_DELETE:
|
||||||
|
process_child_delete(this, message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBG1(DBG_CFG, "received unknown HA sync message type %d",
|
DBG1(DBG_CFG, "received unknown HA sync message type %d",
|
||||||
|
|||||||
@@ -81,6 +81,20 @@ struct host_encoding_t {
|
|||||||
char encoding[];
|
char encoding[];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
typedef struct ts_encoding_t ts_encoding_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encoding of a traffic_selector_t
|
||||||
|
*/
|
||||||
|
struct ts_encoding_t {
|
||||||
|
u_int8_t type;
|
||||||
|
u_int8_t protocol;
|
||||||
|
u_int16_t from_port;
|
||||||
|
u_int16_t to_port;
|
||||||
|
u_int8_t dynamic;
|
||||||
|
char encoding[];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of ha_sync_message_t.get_type
|
* Implementation of ha_sync_message_t.get_type
|
||||||
*/
|
*/
|
||||||
@@ -191,11 +205,25 @@ static void add_attribute(private_ha_sync_message_t *this,
|
|||||||
this->buf.len += len;
|
this->buf.len += len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* u_int8_t */
|
||||||
|
case HA_SYNC_IPSEC_MODE:
|
||||||
|
case HA_SYNC_IPCOMP:
|
||||||
|
{
|
||||||
|
u_int8_t val;
|
||||||
|
|
||||||
|
val = (u_int8_t)va_arg(args, u_int32_t);
|
||||||
|
check_buf(this, sizeof(val));
|
||||||
|
this->buf.ptr[this->buf.len] = val;
|
||||||
|
this->buf.len += sizeof(val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* u_int16_t */
|
/* u_int16_t */
|
||||||
case HA_SYNC_ALG_PRF:
|
case HA_SYNC_ALG_PRF:
|
||||||
case HA_SYNC_ALG_ENCR:
|
case HA_SYNC_ALG_ENCR:
|
||||||
case HA_SYNC_ALG_ENCR_LEN:
|
case HA_SYNC_ALG_ENCR_LEN:
|
||||||
case HA_SYNC_ALG_INTEG:
|
case HA_SYNC_ALG_INTEG:
|
||||||
|
case HA_SYNC_INBOUND_CPI:
|
||||||
|
case HA_SYNC_OUTBOUND_CPI:
|
||||||
{
|
{
|
||||||
u_int16_t val;
|
u_int16_t val;
|
||||||
|
|
||||||
@@ -208,6 +236,8 @@ static void add_attribute(private_ha_sync_message_t *this,
|
|||||||
/** u_int32_t */
|
/** u_int32_t */
|
||||||
case HA_SYNC_CONDITIONS:
|
case HA_SYNC_CONDITIONS:
|
||||||
case HA_SYNC_EXTENSIONS:
|
case HA_SYNC_EXTENSIONS:
|
||||||
|
case HA_SYNC_INBOUND_SPI:
|
||||||
|
case HA_SYNC_OUTBOUND_SPI:
|
||||||
{
|
{
|
||||||
u_int32_t val;
|
u_int32_t val;
|
||||||
|
|
||||||
@@ -232,6 +262,28 @@ static void add_attribute(private_ha_sync_message_t *this,
|
|||||||
this->buf.len += chunk.len + sizeof(u_int16_t);;
|
this->buf.len += chunk.len + sizeof(u_int16_t);;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/** traffic_selector_t */
|
||||||
|
case HA_SYNC_LOCAL_TS:
|
||||||
|
case HA_SYNC_REMOTE_TS:
|
||||||
|
{
|
||||||
|
ts_encoding_t *enc;
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
chunk_t data;
|
||||||
|
|
||||||
|
ts = va_arg(args, traffic_selector_t*);
|
||||||
|
data = chunk_cata("cc", ts->get_from_address(ts),
|
||||||
|
ts->get_to_address(ts));
|
||||||
|
check_buf(this, sizeof(ts_encoding_t) + data.len);
|
||||||
|
enc = (ts_encoding_t*)(this->buf.ptr + this->buf.len);
|
||||||
|
this->buf.len += sizeof(ts_encoding_t) + data.len;
|
||||||
|
enc->type = ts->get_type(ts);
|
||||||
|
enc->protocol = ts->get_protocol(ts);
|
||||||
|
enc->from_port = htons(ts->get_from_port(ts));
|
||||||
|
enc->to_port = htons(ts->get_to_port(ts));
|
||||||
|
enc->dynamic = ts->is_dynamic(ts);
|
||||||
|
memcpy(enc->encoding, data.ptr, data.len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "unable to encode, attribute %d unknown", attribute);
|
DBG1(DBG_CFG, "unable to encode, attribute %d unknown", attribute);
|
||||||
@@ -363,11 +415,26 @@ static bool attribute_enumerate(attribute_enumerator_t *this,
|
|||||||
this->buf = chunk_skip(this->buf, len + 1);
|
this->buf = chunk_skip(this->buf, len + 1);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
/* u_int8_t */
|
||||||
|
case HA_SYNC_IPSEC_MODE:
|
||||||
|
case HA_SYNC_IPCOMP:
|
||||||
|
{
|
||||||
|
if (this->buf.len < sizeof(u_int8_t))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
value->u8 = *(u_int8_t*)this->buf.ptr;
|
||||||
|
*attr_out = attr;
|
||||||
|
this->buf = chunk_skip(this->buf, sizeof(u_int8_t));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
/** u_int16_t */
|
/** u_int16_t */
|
||||||
case HA_SYNC_ALG_PRF:
|
case HA_SYNC_ALG_PRF:
|
||||||
case HA_SYNC_ALG_ENCR:
|
case HA_SYNC_ALG_ENCR:
|
||||||
case HA_SYNC_ALG_ENCR_LEN:
|
case HA_SYNC_ALG_ENCR_LEN:
|
||||||
case HA_SYNC_ALG_INTEG:
|
case HA_SYNC_ALG_INTEG:
|
||||||
|
case HA_SYNC_INBOUND_CPI:
|
||||||
|
case HA_SYNC_OUTBOUND_CPI:
|
||||||
{
|
{
|
||||||
if (this->buf.len < sizeof(u_int16_t))
|
if (this->buf.len < sizeof(u_int16_t))
|
||||||
{
|
{
|
||||||
@@ -381,6 +448,8 @@ static bool attribute_enumerate(attribute_enumerator_t *this,
|
|||||||
/** u_int32_t */
|
/** u_int32_t */
|
||||||
case HA_SYNC_CONDITIONS:
|
case HA_SYNC_CONDITIONS:
|
||||||
case HA_SYNC_EXTENSIONS:
|
case HA_SYNC_EXTENSIONS:
|
||||||
|
case HA_SYNC_INBOUND_SPI:
|
||||||
|
case HA_SYNC_OUTBOUND_SPI:
|
||||||
{
|
{
|
||||||
if (this->buf.len < sizeof(u_int32_t))
|
if (this->buf.len < sizeof(u_int32_t))
|
||||||
{
|
{
|
||||||
@@ -414,6 +483,69 @@ static bool attribute_enumerate(attribute_enumerator_t *this,
|
|||||||
this->buf = chunk_skip(this->buf, len);
|
this->buf = chunk_skip(this->buf, len);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
case HA_SYNC_LOCAL_TS:
|
||||||
|
case HA_SYNC_REMOTE_TS:
|
||||||
|
{
|
||||||
|
ts_encoding_t *enc;
|
||||||
|
host_t *host;
|
||||||
|
int addr_len;
|
||||||
|
|
||||||
|
enc = (ts_encoding_t*)(this->buf.ptr);
|
||||||
|
if (this->buf.len < sizeof(ts_encoding_t))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
switch (enc->type)
|
||||||
|
{
|
||||||
|
case TS_IPV4_ADDR_RANGE:
|
||||||
|
addr_len = 4;
|
||||||
|
if (this->buf.len < sizeof(ts_encoding_t) + 2 * addr_len)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TS_IPV6_ADDR_RANGE:
|
||||||
|
addr_len = 16;
|
||||||
|
if (this->buf.len < sizeof(ts_encoding_t) + 2 * addr_len)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (enc->dynamic)
|
||||||
|
{
|
||||||
|
host = host_create_from_chunk(0,
|
||||||
|
chunk_create(enc->encoding, addr_len), 0);
|
||||||
|
if (!host)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
value->ts = traffic_selector_create_dynamic(enc->protocol,
|
||||||
|
ntohs(enc->from_port), ntohs(enc->to_port));
|
||||||
|
value->ts->set_address(value->ts, host);
|
||||||
|
host->destroy(host);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value->ts = traffic_selector_create_from_bytes(enc->protocol,
|
||||||
|
enc->type, chunk_create(enc->encoding, addr_len),
|
||||||
|
ntohs(enc->from_port),
|
||||||
|
chunk_create(enc->encoding + addr_len, addr_len),
|
||||||
|
ntohs(enc->to_port));
|
||||||
|
if (!value->ts)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*attr_out = attr;
|
||||||
|
this->cleanup = (void*)value->ts->destroy;
|
||||||
|
this->cleanup_data = value->ts;
|
||||||
|
this->buf = chunk_skip(this->buf, sizeof(ts_encoding_t)
|
||||||
|
+ addr_len * 2);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <utils/host.h>
|
#include <utils/host.h>
|
||||||
#include <utils/identification.h>
|
#include <utils/identification.h>
|
||||||
#include <sa/ike_sa_id.h>
|
#include <sa/ike_sa_id.h>
|
||||||
|
#include <config/traffic_selector.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protocol version of this implementation
|
* Protocol version of this implementation
|
||||||
@@ -100,19 +101,37 @@ enum ha_sync_message_attribute_t {
|
|||||||
HA_SYNC_ALG_ENCR_LEN,
|
HA_SYNC_ALG_ENCR_LEN,
|
||||||
/** u_int16_t, integrity protection algorithm */
|
/** u_int16_t, integrity protection algorithm */
|
||||||
HA_SYNC_ALG_INTEG,
|
HA_SYNC_ALG_INTEG,
|
||||||
|
/** u_int8_t, IPsec mode, TUNNEL|TRANSPORT|... */
|
||||||
|
HA_SYNC_IPSEC_MODE,
|
||||||
|
/** u_int8_t, IPComp protocol */
|
||||||
|
HA_SYNC_IPCOMP,
|
||||||
|
/** u_int32_t, inbound security parameter index */
|
||||||
|
HA_SYNC_INBOUND_SPI,
|
||||||
|
/** u_int32_t, outbound security parameter index */
|
||||||
|
HA_SYNC_OUTBOUND_SPI,
|
||||||
|
/** u_int16_t, inbound security parameter index */
|
||||||
|
HA_SYNC_INBOUND_CPI,
|
||||||
|
/** u_int16_t, outbound security parameter index */
|
||||||
|
HA_SYNC_OUTBOUND_CPI,
|
||||||
|
/** traffic_selector_t*, local traffic selector */
|
||||||
|
HA_SYNC_LOCAL_TS,
|
||||||
|
/** traffic_selector_t*, remote traffic selector */
|
||||||
|
HA_SYNC_REMOTE_TS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Union to enumerate typed attributes in a message
|
* Union to enumerate typed attributes in a message
|
||||||
*/
|
*/
|
||||||
union ha_sync_message_value_t {
|
union ha_sync_message_value_t {
|
||||||
u_int32_t u32;
|
u_int8_t u8;
|
||||||
u_int16_t u16;
|
u_int16_t u16;
|
||||||
|
u_int32_t u32;
|
||||||
char *str;
|
char *str;
|
||||||
chunk_t chunk;
|
chunk_t chunk;
|
||||||
ike_sa_id_t *ike_sa_id;
|
ike_sa_id_t *ike_sa_id;
|
||||||
identification_t *id;
|
identification_t *id;
|
||||||
host_t *host;
|
host_t *host;
|
||||||
|
traffic_selector_t *ts;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user