aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/config/policies/local_policy_store.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/config/policies/local_policy_store.c')
-rw-r--r--src/charon/config/policies/local_policy_store.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/src/charon/config/policies/local_policy_store.c b/src/charon/config/policies/local_policy_store.c
index 2054b9df5..0c3e0ee04 100644
--- a/src/charon/config/policies/local_policy_store.c
+++ b/src/charon/config/policies/local_policy_store.c
@@ -67,9 +67,42 @@ static void add_policy(private_local_policy_store_t *this, policy_t *policy)
}
/**
- * Implementation of policy_store_t.get_policy_by_ids.
+ * Check if a policy contains traffic selectors
*/
-static policy_t *get_policy_by_ids(private_local_policy_store_t *this, identification_t *my_id, identification_t *other_id)
+static bool contains_traffic_selectors(policy_t *policy, bool mine,
+ linked_list_t *ts, host_t *host)
+{
+ linked_list_t *selected;
+ bool contains = FALSE;
+ traffic_selector_t *to;
+
+ if (mine)
+ {
+ selected = policy->select_my_traffic_selectors(policy, ts, host);
+ }
+ else
+ {
+ selected = policy->select_other_traffic_selectors(policy, ts, host);
+ }
+ if (selected->get_count(selected))
+ {
+ contains = TRUE;
+ }
+ while (selected->remove_last(selected, (void**)&to) == SUCCESS)
+ {
+ to->destroy(to);
+ }
+ selected->destroy(selected);
+ return contains;
+}
+
+/**
+ * Implementation of policy_store_t.get_policy.
+ */
+static policy_t *get_policy(private_local_policy_store_t *this,
+ identification_t *my_id, identification_t *other_id,
+ linked_list_t *my_ts, linked_list_t *other_ts,
+ host_t *my_host, host_t *other_host)
{
typedef enum {
PRIO_UNDEFINED = 0x00,
@@ -111,9 +144,22 @@ static policy_t *get_policy_by_ids(private_local_policy_store_t *this, identific
{
prio = PRIO_ID_MATCH - wildcards;
}
+
+ /* only accept if traffic selectors match */
+ if (!contains_traffic_selectors(candidate, TRUE, my_ts, my_host) ||
+ !contains_traffic_selectors(candidate, FALSE, other_ts, other_host))
+ {
+ this->logger->log(this->logger, CONTROL|LEVEL2,
+ "candidate '%s' inacceptable due traffic selector mismatch",
+ candidate->get_name(candidate),
+ candidate_my_id->get_string(candidate_my_id),
+ candidate_other_id->get_string(candidate_other_id),
+ prio);
+ continue;
+ }
this->logger->log(this->logger, CONTROL|LEVEL2,
- "candidate policy \"%s\": %s...%s (prio=%d)",
+ "candidate policy '%s': %s...%s (prio=%d)",
candidate->get_name(candidate),
candidate_my_id->get_string(candidate_my_id),
candidate_other_id->get_string(candidate_other_id),
@@ -134,18 +180,13 @@ static policy_t *get_policy_by_ids(private_local_policy_store_t *this, identific
identification_t *found_other_id = found->get_other_id(found);
this->logger->log(this->logger, CONTROL|LEVEL1,
- "found matching policy \"%s\": %s...%s (prio=%d)",
+ "found matching policy '%s': %s...%s (prio=%d)",
found->get_name(found),
found_my_id->get_string(found_my_id),
found_other_id->get_string(found_other_id),
best_prio);
-
- found = found->clone(found);
- if (best_prio != PRIO_ID_MATCH)
- {
- /* replace %any/wildcards by the peer's address */
- found->update_other_id(found, other_id->clone(other_id));
- }
+ /* give out a new reference to it */
+ found->get_ref(found);
}
pthread_mutex_unlock(&(this->mutex));
return found;
@@ -168,12 +209,14 @@ static policy_t *get_policy_by_name(private_local_policy_store_t *this, char *na
iterator->current(iterator, (void **)&current);
if (strcmp(current->get_name(current), name) == 0)
{
- found = current->clone(current);
+ found = current;
}
}
iterator->destroy(iterator);
pthread_mutex_unlock(&(this->mutex));
+ /* give out a new reference */
+ found->get_ref(found);
return found;
}
@@ -234,7 +277,7 @@ local_policy_store_t *local_policy_store_create(void)
private_local_policy_store_t *this = malloc_thing(private_local_policy_store_t);
this->public.policy_store.add_policy = (void(*)(policy_store_t*,policy_t*))add_policy;
- this->public.policy_store.get_policy_by_ids = (policy_t*(*)(policy_store_t*,identification_t*,identification_t*))get_policy_by_ids;
+ this->public.policy_store.get_policy = (policy_t*(*)(policy_store_t*,identification_t*,identification_t*,linked_list_t*,linked_list_t*,host_t*,host_t*))get_policy;
this->public.policy_store.get_policy_by_name = (policy_t*(*)(policy_store_t*,char*))get_policy_by_name;
this->public.policy_store.delete_policy = (status_t(*)(policy_store_t*,char*))delete_policy;
this->public.policy_store.destroy = (void(*)(policy_store_t*))destroy;