summaryrefslogtreecommitdiff
path: root/src/libcharon/config/backend_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/config/backend_manager.c')
-rw-r--r--src/libcharon/config/backend_manager.c109
1 files changed, 69 insertions, 40 deletions
diff --git a/src/libcharon/config/backend_manager.c b/src/libcharon/config/backend_manager.c
index a93457ea4..09e123e67 100644
--- a/src/libcharon/config/backend_manager.c
+++ b/src/libcharon/config/backend_manager.c
@@ -78,12 +78,14 @@ static enumerator_t *ike_enum_create(backend_t *backend, ike_data_t *data)
static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other)
{
host_t *me_cand, *other_cand;
+ char *my_addr, *other_addr;
+ bool my_allow_any, other_allow_any;
ike_cfg_match_t match = MATCH_NONE;
if (me)
{
- me_cand = host_create_from_dns(cand->get_my_addr(cand),
- me->get_family(me), 0);
+ my_addr = cand->get_my_addr(cand, &my_allow_any);
+ me_cand = host_create_from_dns(my_addr, me->get_family(me), 0);
if (!me_cand)
{
return MATCH_NONE;
@@ -92,7 +94,7 @@ static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other)
{
match += MATCH_ME;
}
- else if (me_cand->is_anyaddr(me_cand))
+ else if (my_allow_any || me_cand->is_anyaddr(me_cand))
{
match += MATCH_ANY;
}
@@ -110,8 +112,8 @@ static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other)
if (other)
{
- other_cand = host_create_from_dns(cand->get_other_addr(cand),
- other->get_family(other), 0);
+ other_addr = cand->get_other_addr(cand, &other_allow_any);
+ other_cand = host_create_from_dns(other_addr, other->get_family(other), 0);
if (!other_cand)
{
return MATCH_NONE;
@@ -120,7 +122,7 @@ static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other)
{
match += MATCH_OTHER;
}
- else if (other_cand->is_anyaddr(other_cand))
+ else if (other_allow_any || other_cand->is_anyaddr(other_cand))
{
match += MATCH_ANY;
}
@@ -142,14 +144,17 @@ METHOD(backend_manager_t, get_ike_cfg, ike_cfg_t*,
private_backend_manager_t *this, host_t *me, host_t *other)
{
ike_cfg_t *current, *found = NULL;
+ char *my_addr, *other_addr;
+ bool my_allow_any, other_allow_any;
enumerator_t *enumerator;
ike_cfg_match_t match, best = MATCH_ANY;
ike_data_t *data;
- data = malloc_thing(ike_data_t);
- data->this = this;
- data->me = me;
- data->other = other;
+ INIT(data,
+ .this = this,
+ .me = me,
+ .other = other,
+ );
DBG2(DBG_CFG, "looking for an ike config for %H...%H", me, other);
@@ -160,12 +165,14 @@ METHOD(backend_manager_t, get_ike_cfg, ike_cfg_t*,
while (enumerator->enumerate(enumerator, (void**)&current))
{
match = get_ike_match(current, me, other);
-
+ DBG3(DBG_CFG, "ike config match: %d (%H %H)", match, me, other);
if (match)
{
- DBG2(DBG_CFG, " candidate: %s...%s, prio %d",
- current->get_my_addr(current),
- current->get_other_addr(current), match);
+ my_addr = current->get_my_addr(current, &my_allow_any);
+ other_addr = current->get_other_addr(current, &other_allow_any);
+ DBG2(DBG_CFG, " candidate: %s%s...%s%s, prio %d",
+ my_allow_any ? "%":"", my_addr,
+ other_allow_any ? "%":"", other_addr, match);
if (match > best)
{
DESTROY_IF(found);
@@ -179,8 +186,11 @@ METHOD(backend_manager_t, get_ike_cfg, ike_cfg_t*,
this->lock->unlock(this->lock);
if (found)
{
- DBG2(DBG_CFG, "found matching ike config: %s...%s with prio %d",
- found->get_my_addr(found), found->get_other_addr(found), best);
+ my_addr = found->get_my_addr(found, &my_allow_any);
+ other_addr = found->get_other_addr(found, &other_allow_any);
+ DBG2(DBG_CFG, "found matching ike config: %s%s...%s%s with prio %d",
+ my_allow_any ? "%":"", my_addr,
+ other_allow_any ? "%":"", other_addr, best);
}
return found;
}
@@ -195,9 +205,13 @@ static id_match_t get_peer_match(identification_t *id,
auth_cfg_t *auth;
identification_t *candidate;
id_match_t match = ID_MATCH_NONE;
+ char *where = local ? "local" : "remote";
+ chunk_t data;
if (!id)
{
+ DBG3(DBG_CFG, "peer config match %s: %d (%N)",
+ where, ID_MATCH_ANY, id_type_names, ID_ANY);
return ID_MATCH_ANY;
}
@@ -221,10 +235,30 @@ static id_match_t get_peer_match(identification_t *id,
}
}
enumerator->destroy(enumerator);
+
+ data = id->get_encoding(id);
+ DBG3(DBG_CFG, "peer config match %s: %d (%N -> %#B)",
+ where, match, id_type_names, id->get_type(id), &data);
return match;
}
/**
+ * Get match quality of IKE version
+ */
+static int get_version_match(ike_version_t cfg, ike_version_t req)
+{
+ if (req == IKE_ANY || cfg == IKE_ANY)
+ {
+ return 1;
+ }
+ if (req == cfg)
+ {
+ return 2;
+ }
+ return 0;
+}
+
+/**
* data to pass nested peer enumerator
*/
typedef struct {
@@ -317,17 +351,18 @@ static void insert_sorted(match_entry_t *entry, linked_list_t *list,
METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
private_backend_manager_t *this, host_t *me, host_t *other,
- identification_t *my_id, identification_t *other_id)
+ identification_t *my_id, identification_t *other_id, ike_version_t version)
{
enumerator_t *enumerator;
peer_data_t *data;
peer_cfg_t *cfg;
linked_list_t *configs, *helper;
- data = malloc_thing(peer_data_t);
- data->lock = this->lock;
- data->me = my_id;
- data->other = other_id;
+ INIT(data,
+ .lock = this->lock,
+ .me = my_id,
+ .other = other_id,
+ );
/* create a sorted list with all matches */
this->lock->read_lock(this->lock);
@@ -340,9 +375,6 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
return enumerator;
}
- DBG1(DBG_CFG, "looking for peer configs matching %H[%Y]...%H[%Y]",
- me, my_id, other, other_id);
-
configs = linked_list_create();
/* only once allocated helper list for sorting */
helper = linked_list_create();
@@ -350,29 +382,26 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
{
id_match_t match_peer_me, match_peer_other;
ike_cfg_match_t match_ike;
+ int match_version;
match_entry_t *entry;
- chunk_t data;
match_peer_me = get_peer_match(my_id, cfg, TRUE);
- data = my_id->get_encoding(my_id);
- DBG3(DBG_CFG, "match_peer_me: %d (%N -> %#B)", match_peer_me,
- id_type_names, my_id->get_type(my_id), &data);
match_peer_other = get_peer_match(other_id, cfg, FALSE);
- data = other_id->get_encoding(other_id);
- DBG3(DBG_CFG, "match_peer_other: %d (%N -> %#B)", match_peer_other,
- id_type_names, other_id->get_type(other_id), &data);
match_ike = get_ike_match(cfg->get_ike_cfg(cfg), me, other);
- DBG3(DBG_CFG, "match_ike: %d (%H %H)", match_ike, me, other);
+ match_version = get_version_match(cfg->get_ike_version(cfg), version);
+ DBG3(DBG_CFG, "ike config match: %d (%H %H)", match_ike, me, other);
- if (match_peer_me && match_peer_other && match_ike)
+ if (match_peer_me && match_peer_other && match_ike && match_version)
{
- DBG2(DBG_CFG, " candidate \"%s\", match: %d/%d/%d (me/other/ike)",
- cfg->get_name(cfg), match_peer_me, match_peer_other, match_ike);
-
- entry = malloc_thing(match_entry_t);
- entry->match_peer = match_peer_me + match_peer_other;
- entry->match_ike = match_ike;
- entry->cfg = cfg->get_ref(cfg);
+ DBG2(DBG_CFG, " candidate \"%s\", match: %d/%d/%d/%d "
+ "(me/other/ike/version)", cfg->get_name(cfg),
+ match_peer_me, match_peer_other, match_ike, match_version);
+
+ INIT(entry,
+ .match_peer = match_peer_me + match_peer_other,
+ .match_ike = match_ike,
+ .cfg = cfg->get_ref(cfg),
+ );
insert_sorted(entry, configs, helper);
}
}