Support multiple addresses/pools in left/rightsourceip

This commit is contained in:
Martin Willi
2012-08-30 16:43:42 +02:00
parent 497ce2cf51
commit 96c2b3cf89
9 changed files with 189 additions and 156 deletions
+122 -53
View File
@@ -52,6 +52,11 @@ struct private_stroke_config_t {
* credentials
*/
stroke_cred_t *cred;
/**
* Virtual IP pool / DNS backend
*/
stroke_attribute_t *attributes;
};
METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
@@ -649,7 +654,6 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
{
identification_t *peer_id = NULL;
peer_cfg_t *mediated_by = NULL;
host_t *vip = NULL;
unique_policy_t unique;
u_int32_t rekey = 0, reauth = 0, over, jitter;
peer_cfg_t *peer_cfg;
@@ -708,49 +712,6 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
{
rekey = msg->add_conn.rekey.ike_lifetime - over;
}
if (msg->add_conn.me.sourceip_mask)
{
if (msg->add_conn.me.sourceip)
{
vip = host_create_from_string(msg->add_conn.me.sourceip, 0);
}
if (!vip)
{ /* if it is set to something like %poolname, request an address */
if (msg->add_conn.me.subnets)
{ /* use the same family as in local subnet, if any */
if (strchr(msg->add_conn.me.subnets, '.'))
{
vip = host_create_any(AF_INET);
}
else
{
vip = host_create_any(AF_INET6);
}
}
else if (msg->add_conn.other.subnets)
{ /* use the same family as in remote subnet, if any */
if (strchr(msg->add_conn.other.subnets, '.'))
{
vip = host_create_any(AF_INET);
}
else
{
vip = host_create_any(AF_INET6);
}
}
else
{
if (strchr(ike_cfg->get_my_addr(ike_cfg, NULL), ':'))
{
vip = host_create_any(AF_INET6);
}
else
{
vip = host_create_any(AF_INET);
}
}
}
}
switch (msg->add_conn.unique)
{
case 1: /* yes */
@@ -779,17 +740,123 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
msg->add_conn.mobike, msg->add_conn.aggressive,
msg->add_conn.dpd.delay, msg->add_conn.dpd.timeout,
msg->add_conn.ikeme.mediation, mediated_by, peer_id);
if (vip)
if (msg->add_conn.other.sourceip)
{
peer_cfg->add_virtual_ip(peer_cfg, vip);
enumerator_t *enumerator;
char *token;
enumerator = enumerator_create_token(msg->add_conn.other.sourceip,
",", " ");
while (enumerator->enumerate(enumerator, &token))
{
if (streq(token, "%modeconfig") || streq(token, "%modecfg") ||
streq(token, "%config") || streq(token, "%cfg") ||
streq(token, "%config4") || streq(token, "%config6"))
{
/* empty pool, uses connection name */
this->attributes->add_pool(this->attributes,
mem_pool_create(msg->add_conn.name, NULL, 0));
peer_cfg->add_pool(peer_cfg, msg->add_conn.name);
}
else if (*token == '%')
{
/* external named pool */
peer_cfg->add_pool(peer_cfg, token + 1);
}
else
{
/* in-memory pool, named using CIDR notation */
host_t *base;
int bits;
base = host_create_from_subnet(token, &bits);
if (base)
{
this->attributes->add_pool(this->attributes,
mem_pool_create(token, base, bits));
peer_cfg->add_pool(peer_cfg, token);
base->destroy(base);
}
else
{
DBG1(DBG_CFG, "IP pool %s invalid, ignored", token);
}
}
}
enumerator->destroy(enumerator);
}
if (msg->add_conn.other.sourceip_mask)
if (msg->add_conn.me.sourceip)
{
peer_cfg->add_pool(peer_cfg, msg->add_conn.name);
}
else if (msg->add_conn.other.sourceip)
{
peer_cfg->add_pool(peer_cfg, msg->add_conn.other.sourceip);
enumerator_t *enumerator;
char *token;
enumerator = enumerator_create_token(msg->add_conn.me.sourceip, ",", " ");
while (enumerator->enumerate(enumerator, &token))
{
host_t *vip = NULL;
if (streq(token, "%modeconfig") || streq(token, "%modecfg") ||
streq(token, "%config") || streq(token, "%cfg"))
{ /* try to deduce an address family */
if (msg->add_conn.me.subnets)
{ /* use the same family as in local subnet, if any */
if (strchr(msg->add_conn.me.subnets, '.'))
{
vip = host_create_any(AF_INET);
}
else
{
vip = host_create_any(AF_INET6);
}
}
else if (msg->add_conn.other.subnets)
{ /* use the same family as in remote subnet, if any */
if (strchr(msg->add_conn.other.subnets, '.'))
{
vip = host_create_any(AF_INET);
}
else
{
vip = host_create_any(AF_INET6);
}
}
else
{
if (strchr(ike_cfg->get_my_addr(ike_cfg, NULL), ':'))
{
vip = host_create_any(AF_INET6);
}
else
{
vip = host_create_any(AF_INET);
}
}
}
else if (streq(token, "%config4"))
{
vip = host_create_any(AF_INET);
}
else if (streq(token, "%config6"))
{
vip = host_create_any(AF_INET6);
}
else
{
vip = host_create_from_string(token, 0);
if (vip)
{
DBG1(DBG_CFG, "ignored invalid subnet token: %s", token);
}
}
if (vip)
{
peer_cfg->add_virtual_ip(peer_cfg, vip);
}
}
enumerator->destroy(enumerator);
}
/* build leftauth= */
@@ -1250,7 +1317,8 @@ METHOD(stroke_config_t, destroy, void,
/*
* see header file
*/
stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred)
stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred,
stroke_attribute_t *attributes)
{
private_stroke_config_t *this;
@@ -1270,6 +1338,7 @@ stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred)
.mutex = mutex_create(MUTEX_TYPE_RECURSIVE),
.ca = ca,
.cred = cred,
.attributes = attributes,
);
return &this->public;