diff options
Diffstat (limited to 'src/libcharon/config/backend_manager.c')
-rw-r--r-- | src/libcharon/config/backend_manager.c | 109 |
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**)¤t)) { 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); } } |