diff options
Diffstat (limited to 'src/libcharon/config/backend_manager.c')
-rw-r--r-- | src/libcharon/config/backend_manager.c | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/src/libcharon/config/backend_manager.c b/src/libcharon/config/backend_manager.c index 09e123e67..f47d5715a 100644 --- a/src/libcharon/config/backend_manager.c +++ b/src/libcharon/config/backend_manager.c @@ -18,7 +18,7 @@ #include <sys/types.h> #include <daemon.h> -#include <utils/linked_list.h> +#include <collections/linked_list.h> #include <threading/rwlock.h> @@ -49,10 +49,16 @@ struct private_backend_manager_t { * match of an ike_cfg */ typedef enum ike_cfg_match_t { - MATCH_NONE = 0x00, - MATCH_ANY = 0x01, - MATCH_ME = 0x04, - MATCH_OTHER = 0x08, + /* doesn't match at all */ + MATCH_NONE = 0x00, + /* match for a %any host. For both hosts, hence skip 0x02 */ + MATCH_ANY = 0x01, + /* IKE version matches exactly (config is not for any version) */ + MATCH_VERSION = 0x04, + /* local identity matches */ + MATCH_ME = 0x08, + /* remote identity matches */ + MATCH_OTHER = 0x10, } ike_cfg_match_t; /** @@ -75,13 +81,20 @@ static enumerator_t *ike_enum_create(backend_t *backend, ike_data_t *data) /** * get a match of a candidate ike_cfg for two hosts */ -static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other) +static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other, + ike_version_t version) { 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 (cand->get_version(cand) != IKE_ANY && + version != cand->get_version(cand)) + { + return MATCH_NONE; + } + if (me) { my_addr = cand->get_my_addr(cand, &my_allow_any); @@ -137,11 +150,18 @@ static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other) { match += MATCH_ANY; } + + if (match != MATCH_NONE && + cand->get_version(cand) != IKE_ANY) + { /* if we have a match, improve it if candidate version specified */ + match += MATCH_VERSION; + } return match; } METHOD(backend_manager_t, get_ike_cfg, ike_cfg_t*, - private_backend_manager_t *this, host_t *me, host_t *other) + private_backend_manager_t *this, host_t *me, host_t *other, + ike_version_t version) { ike_cfg_t *current, *found = NULL; char *my_addr, *other_addr; @@ -164,8 +184,9 @@ METHOD(backend_manager_t, get_ike_cfg, ike_cfg_t*, (void*)ike_enum_create, data, (void*)free); 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); + match = get_ike_match(current, me, other, version); + DBG3(DBG_CFG, "ike config match: %d (%H %H %N)", + match, me, other, ike_version_names, version); if (match) { my_addr = current->get_my_addr(current, &my_allow_any); @@ -243,22 +264,6 @@ static id_match_t get_peer_match(identification_t *id, } /** - * 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 { @@ -382,20 +387,18 @@ 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; match_peer_me = get_peer_match(my_id, cfg, TRUE); match_peer_other = get_peer_match(other_id, cfg, FALSE); - match_ike = get_ike_match(cfg->get_ike_cfg(cfg), 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); + match_ike = get_ike_match(cfg->get_ike_cfg(cfg), me, other, version); + DBG3(DBG_CFG, "ike config match: %d (%H %H %N)", + match_ike, me, other, ike_version_names, version); - if (match_peer_me && match_peer_other && match_ike && match_version) + if (match_peer_me && match_peer_other && match_ike) { - 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); + DBG2(DBG_CFG, " candidate \"%s\", match: %d/%d/%d (me/other/ike)", + cfg->get_name(cfg), match_peer_me, match_peer_other, match_ike); INIT(entry, .match_peer = match_peer_me + match_peer_other, |