Use subset matching instead of is_contained_in() to select a child_cfg
authorMartin Willi <martin@revosec.ch>
Thu, 13 Jun 2013 11:34:12 +0000 (13:34 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 13 Jun 2013 11:37:50 +0000 (13:37 +0200)
If one selector has a wider IP range than the other, but the other has a
wider port/protocol selector than the first one, none is completely contained
in the other. The check for a match using is_contained_in() therefore would
fail. Using get_subset() can handle such cases, fixing configuration selection.

src/libcharon/config/peer_cfg.c

index 8de7d12..eb98319 100644 (file)
@@ -249,7 +249,7 @@ static int get_ts_match(child_cfg_t *cfg, bool local,
 {
        linked_list_t *cfg_list;
        enumerator_t *sup_enum, *cfg_enum;
-       traffic_selector_t *sup_ts, *cfg_ts;
+       traffic_selector_t *sup_ts, *cfg_ts, *subset;
        int match = 0, round;
 
        /* fetch configured TS list, narrowing dynamic TS */
@@ -268,10 +268,14 @@ static int get_ts_match(child_cfg_t *cfg, bool local,
                        {       /* equality is honored better than matches */
                                match += round * 5;
                        }
-                       else if (cfg_ts->is_contained_in(cfg_ts, sup_ts) ||
-                                        sup_ts->is_contained_in(sup_ts, cfg_ts))
+                       else
                        {
-                               match += round * 1;
+                               subset = cfg_ts->get_subset(cfg_ts, sup_ts);
+                               if (subset)
+                               {
+                                       subset->destroy(subset);
+                                       match += round * 1;
+                               }
                        }
                }
                cfg_enum->destroy(cfg_enum);