diff options
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_attribute.c | 81 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_attribute.h | 23 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_config.c | 175 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_config.h | 4 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_socket.c | 6 | ||||
-rw-r--r-- | src/starter/confread.c | 53 | ||||
-rw-r--r-- | src/starter/confread.h | 1 | ||||
-rw-r--r-- | src/starter/starterstroke.c | 1 | ||||
-rw-r--r-- | src/stroke/stroke_msg.h | 1 |
9 files changed, 189 insertions, 156 deletions
diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index aa3b1d20c..ebae6fcf1 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -17,7 +17,6 @@ #include "stroke_attribute.h" #include <daemon.h> -#include <attributes/mem_pool.h> #include <utils/linked_list.h> #include <threading/rwlock.h> @@ -96,6 +95,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*, { mem_pool_t *pool; host_t *addr = NULL; + this->lock->read_lock(this->lock); pool = find_pool(this, name); if (pool) @@ -112,6 +112,7 @@ METHOD(attribute_provider_t, release_address, bool, { mem_pool_t *pool; bool found = FALSE; + this->lock->read_lock(this->lock); pool = find_pool(this, name); if (pool) @@ -179,36 +180,48 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, } METHOD(stroke_attribute_t, add_pool, void, - private_stroke_attribute_t *this, stroke_msg_t *msg) + private_stroke_attribute_t *this, mem_pool_t *pool) { - if (msg->add_conn.other.sourceip_mask) - { - mem_pool_t *pool; - host_t *base = NULL; - u_int32_t bits = 0; + enumerator_t *enumerator; + mem_pool_t *current; + host_t *base; + int size; - /* if %config, add an empty pool, otherwise */ - if (msg->add_conn.other.sourceip) + base = pool->get_base(pool); + size = pool->get_size(pool); + + this->lock->write_lock(this->lock); + + enumerator = this->pools->create_enumerator(this->pools); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (base && current->get_base(current) && + base->ip_equals(base, current->get_base(current)) && + size == current->get_size(current)) { - DBG1(DBG_CFG, "adding virtual IP address pool '%s': %s/%d", - msg->add_conn.name, msg->add_conn.other.sourceip, - msg->add_conn.other.sourceip_mask); - base = host_create_from_string(msg->add_conn.other.sourceip, 0); - if (!base) - { - DBG1(DBG_CFG, "virtual IP address invalid, discarded"); - return; - } - bits = msg->add_conn.other.sourceip_mask; + pool->destroy(pool); + pool = NULL; + DBG1(DBG_CFG, "reusing virtual IP address pool %H/%d", base, size); + break; } - pool = mem_pool_create(msg->add_conn.name, base, bits); - DESTROY_IF(base); + } + enumerator->destroy(enumerator); - this->lock->write_lock(this->lock); + if (pool) + { + if (base) + { + DBG1(DBG_CFG, "adding virtual IP address pool %H/%d", base, size); + } this->pools->insert_last(this->pools, pool); - this->lock->unlock(this->lock); } + this->lock->unlock(this->lock); +} + +METHOD(stroke_attribute_t, add_dns, void, + private_stroke_attribute_t *this, stroke_msg_t *msg) +{ if (msg->add_conn.other.dns) { enumerator_t *enumerator; @@ -246,25 +259,13 @@ METHOD(stroke_attribute_t, add_pool, void, } } -METHOD(stroke_attribute_t, del_pool, void, +METHOD(stroke_attribute_t, del_dns, void, private_stroke_attribute_t *this, stroke_msg_t *msg) { enumerator_t *enumerator; attributes_t *attr; - mem_pool_t *pool; this->lock->write_lock(this->lock); - enumerator = this->pools->create_enumerator(this->pools); - while (enumerator->enumerate(enumerator, &pool)) - { - if (streq(msg->del_conn.name, pool->get_name(pool))) - { - this->pools->remove_at(this->pools, enumerator); - pool->destroy(pool); - break; - } - } - enumerator->destroy(enumerator); enumerator = this->attrs->create_enumerator(this->attrs); while (enumerator->enumerate(enumerator, &attr)) @@ -289,6 +290,11 @@ static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name, void *d3, u_int *offline) { mem_pool_t *pool = *poolp; + + if (pool->get_size(pool) == 0) + { + return FALSE; + } *name = pool->get_name(pool); *size = pool->get_size(pool); *online = pool->get_online(pool); @@ -344,7 +350,8 @@ stroke_attribute_t *stroke_attribute_create() .create_attribute_enumerator = _create_attribute_enumerator, }, .add_pool = _add_pool, - .del_pool = _del_pool, + .add_dns = _add_dns, + .del_dns = _del_dns, .create_pool_enumerator = _create_pool_enumerator, .create_lease_enumerator = _create_lease_enumerator, .destroy = _destroy, diff --git a/src/libcharon/plugins/stroke/stroke_attribute.h b/src/libcharon/plugins/stroke/stroke_attribute.h index 249a9899b..f1b9d135b 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.h +++ b/src/libcharon/plugins/stroke/stroke_attribute.h @@ -23,6 +23,7 @@ #include <stroke_msg.h> #include <attributes/attribute_provider.h> +#include <attributes/mem_pool.h> typedef struct stroke_attribute_t stroke_attribute_t; @@ -37,18 +38,28 @@ struct stroke_attribute_t { attribute_provider_t provider; /** - * Add a virtual IP address pool. + * Add a memory pool to this virtual IP backend. * - * @param msg stroke message + * The pool gets owned by the provider, or destroyed if such a pool + * is already registered. + * + * @param pool virtual IP pool to add + */ + void (*add_pool)(stroke_attribute_t *this, mem_pool_t *pool); + + /** + * Add connection specific DNS servers. + * + * @param msg stroke add message */ - void (*add_pool)(stroke_attribute_t *this, stroke_msg_t *msg); + void (*add_dns)(stroke_attribute_t *this, stroke_msg_t *msg); /** - * Remove a virtual IP address pool. + * Remove connection specific DNS servers. * - * @param msg stroke message + * @param msg stroke del message */ - void (*del_pool)(stroke_attribute_t *this, stroke_msg_t *msg); + void (*del_dns)(stroke_attribute_t *this, stroke_msg_t *msg); /** * Create an enumerator over installed pools. diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 5f32072ce..fe8baf1bd 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -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) - { - peer_cfg->add_virtual_ip(peer_cfg, vip); - } - if (msg->add_conn.other.sourceip_mask) + + if (msg->add_conn.other.sourceip) { - peer_cfg->add_pool(peer_cfg, msg->add_conn.name); + 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); } - else if (msg->add_conn.other.sourceip) + + if (msg->add_conn.me.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; diff --git a/src/libcharon/plugins/stroke/stroke_config.h b/src/libcharon/plugins/stroke/stroke_config.h index 450d517f3..894e03ce4 100644 --- a/src/libcharon/plugins/stroke/stroke_config.h +++ b/src/libcharon/plugins/stroke/stroke_config.h @@ -26,6 +26,7 @@ #include <stroke_msg.h> #include "stroke_ca.h" #include "stroke_cred.h" +#include "stroke_attribute.h" typedef struct stroke_config_t stroke_config_t; @@ -71,6 +72,7 @@ struct stroke_config_t { /** * Create a stroke_config instance. */ -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); #endif /** STROKE_CONFIG_H_ @}*/ diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index df43e168d..241f0fbf6 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -243,7 +243,7 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg) DBG2(DBG_CFG, " keyexchange=ikev%u", msg->add_conn.version); this->config->add(this->config, msg); - this->attribute->add_pool(this->attribute, msg); + this->attribute->add_dns(this->attribute, msg); this->handler->add_attributes(this->handler, msg); } @@ -256,7 +256,7 @@ static void stroke_del_conn(private_stroke_socket_t *this, stroke_msg_t *msg) DBG1(DBG_CFG, "received stroke: delete connection '%s'", msg->del_conn.name); this->config->del(this->config, msg); - this->attribute->del_pool(this->attribute, msg); + this->attribute->del_dns(this->attribute, msg); this->handler->del_attributes(this->handler, msg); } @@ -831,7 +831,7 @@ stroke_socket_t *stroke_socket_create() this->attribute = stroke_attribute_create(); this->handler = stroke_handler_create(); this->ca = stroke_ca_create(this->cred); - this->config = stroke_config_create(this->ca, this->cred); + this->config = stroke_config_create(this->ca, this->cred, this->attribute); this->control = stroke_control_create(); this->list = stroke_list_create(this->attribute); diff --git a/src/starter/confread.c b/src/starter/confread.c index 9199fce18..f30f2188c 100644 --- a/src/starter/confread.c +++ b/src/starter/confread.c @@ -231,59 +231,6 @@ static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token, end->host = strdupnull(value); break; case KW_SOURCEIP: - if (value[0] == '%') - { - if (streq(value, "%modeconfig") || streq(value, "%modecfg") || - streq(value, "%config") || streq(value, "%cfg")) - { - /* request ip via config payload */ - free(end->sourceip); - end->sourceip = NULL; - end->sourceip_mask = 1; - } - else - { /* %poolname, strip %, serve ip requests */ - free(end->sourceip); - end->sourceip = strdupnull(value+1); - end->sourceip_mask = 0; - } - end->modecfg = TRUE; - } - else - { - host_t *host; - char *sep; - - sep = strchr(value, '/'); - if (sep) - { /* CIDR notation, address pool */ - *sep = '\0'; - host = host_create_from_string(value, 0); - if (!host) - { - DBG1(DBG_APP, "# bad subnet: %s=%s", name, value); - goto err; - } - host->destroy(host); - free(end->sourceip); - end->sourceip = strdupnull(value); - end->sourceip_mask = atoi(sep + 1); - /* restore the original text in case also= is used */ - *sep = '/'; - } - else - { /* fixed srcip */ - host = host_create_from_string(value, 0); - if (!host) - { - DBG1(DBG_APP, "# bad addr: %s=%s", name, value); - goto err; - } - end->sourceip_mask = (host->get_family(host) == AF_INET) ? - 32 : 128; - host->destroy(host); - } - } conn->mode = MODE_TUNNEL; conn->proxy_mode = FALSE; break; diff --git a/src/starter/confread.h b/src/starter/confread.h index d01d9c110..3f2079883 100644 --- a/src/starter/confread.h +++ b/src/starter/confread.h @@ -111,7 +111,6 @@ struct starter_end { u_int16_t port; u_int8_t protocol; char *sourceip; - int sourceip_mask; char *dns; }; diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c index 79bb0ba31..d6ad3eb89 100644 --- a/src/starter/starterstroke.c +++ b/src/starter/starterstroke.c @@ -140,7 +140,6 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta msg_end->ikeport = conn_end->ikeport; msg_end->subnets = push_string(msg, conn_end->subnet); msg_end->sourceip = push_string(msg, conn_end->sourceip); - msg_end->sourceip_mask = conn_end->sourceip_mask; msg_end->dns = push_string(msg, conn_end->dns); msg_end->sendcert = conn_end->sendcert; msg_end->hostaccess = conn_end->hostaccess; diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h index c941aaf4c..662feed69 100644 --- a/src/stroke/stroke_msg.h +++ b/src/stroke/stroke_msg.h @@ -158,7 +158,6 @@ struct stroke_end_t { char *address; u_int16_t ikeport; char *sourceip; - int sourceip_mask; char *dns; char *subnets; int sendcert; |