aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2014-04-29 16:04:43 +0200
committerTobias Brunner <tobias@strongswan.org>2014-05-15 11:28:09 +0200
commit8b43c9ba349d7370eb82e8340f48a7045d9c5c5e (patch)
treeeea176620dc0eca21843024830ee897f5c7bcc51
parent5ac20cbb8713cea802aa2764704201ae84a0d2d8 (diff)
downloadstrongswan-8b43c9ba349d7370eb82e8340f48a7045d9c5c5e.tar.bz2
strongswan-8b43c9ba349d7370eb82e8340f48a7045d9c5c5e.tar.xz
settings: Adopt the new order of sections and settings when replacing configs
-rw-r--r--src/libstrongswan/settings/settings_types.c42
-rw-r--r--src/libstrongswan/tests/suites/test_settings.c84
2 files changed, 119 insertions, 7 deletions
diff --git a/src/libstrongswan/settings/settings_types.c b/src/libstrongswan/settings/settings_types.c
index 253d06808..125676237 100644
--- a/src/libstrongswan/settings/settings_types.c
+++ b/src/libstrongswan/settings/settings_types.c
@@ -199,10 +199,13 @@ void settings_section_extend(section_t *base, section_t *extension,
enumerator_t *enumerator;
section_t *section;
kv_t *kv;
+ array_t *sections = NULL, *kvs = NULL;
int idx;
if (purge)
- { /* remove sections and settings in base not found in extension */
+ { /* remove sections and settings in base not found in extension, the
+ * others are removed too (from the _order list) so they can be inserted
+ * in the order found in extension */
enumerator = array_create_enumerator(base->sections_order);
while (enumerator->enumerate(enumerator, (void**)&section))
{
@@ -212,32 +215,49 @@ void settings_section_extend(section_t *base, section_t *extension,
idx = array_bsearch(base->sections, section->name,
settings_section_find, NULL);
if (section_purge(section, contents))
- {
+ { /* only remove them if we can purge them */
array_remove(base->sections, idx, NULL);
array_remove_at(base->sections_order, enumerator);
settings_section_destroy(section, contents);
}
}
+ else
+ {
+ array_remove_at(base->sections_order, enumerator);
+ array_insert_create(&sections, ARRAY_TAIL, section);
+ array_sort(sections, settings_section_sort, NULL);
+ }
}
enumerator->destroy(enumerator);
- enumerator = array_create_enumerator(base->kv_order);
- while (enumerator->enumerate(enumerator, (void**)&kv))
+ while (array_remove(base->kv_order, 0, &kv))
{
if (array_bsearch(extension->kv, kv->key, settings_kv_find,
NULL) == -1)
{
idx = array_bsearch(base->kv, kv->key, settings_kv_find, NULL);
array_remove(base->kv, idx, NULL);
- array_remove_at(base->kv_order, enumerator);
settings_kv_destroy(kv, contents);
}
+ else
+ {
+ array_insert_create(&kvs, ARRAY_TAIL, kv);
+ array_sort(kvs, settings_kv_sort, NULL);
+ }
}
- enumerator->destroy(enumerator);
}
while (array_remove(extension->sections_order, 0, &section))
{
+ idx = array_bsearch(sections, section->name,
+ settings_section_find, NULL);
+ if (idx != -1)
+ {
+ section_t *existing;
+
+ array_remove(sections, idx, &existing);
+ array_insert(base->sections_order, ARRAY_TAIL, existing);
+ }
idx = array_bsearch(extension->sections, section->name,
settings_section_find, NULL);
array_remove(extension->sections, idx, NULL);
@@ -246,10 +266,20 @@ void settings_section_extend(section_t *base, section_t *extension,
while (array_remove(extension->kv_order, 0, &kv))
{
+ idx = array_bsearch(kvs, kv->key, settings_kv_find, NULL);
+ if (idx != -1)
+ {
+ kv_t *existing;
+
+ array_remove(kvs, idx, &existing);
+ array_insert(base->kv_order, ARRAY_TAIL, existing);
+ }
idx = array_bsearch(extension->kv, kv->key, settings_kv_find, NULL);
array_remove(extension->kv, idx, NULL);
settings_kv_add(base, kv, contents);
}
+ array_destroy(sections);
+ array_destroy(kvs);
}
/*
diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c
index 77fef12ad..e504b95a1 100644
--- a/src/libstrongswan/tests/suites/test_settings.c
+++ b/src/libstrongswan/tests/suites/test_settings.c
@@ -694,6 +694,87 @@ START_TEST(test_load_files_section)
}
END_TEST
+START_TEST(test_order_kv)
+{
+ chunk_t base = chunk_from_str(
+ "main {\n"
+ " key1 = val1\n"
+ " key2 = val2\n"
+ " key3 = val3\n"
+ "}");
+ chunk_t include = chunk_from_str(
+ "main {\n"
+ " key0 = val0\n"
+ " key3 = val3\n"
+ " key1 = val1\n"
+ "}");
+ linked_list_t *keys, *values;
+
+ create_settings(base);
+ ck_assert(chunk_write(include, include1, 0022, TRUE));
+
+ keys = linked_list_create_with_items("key1", "key2", "key3", NULL);
+ values = linked_list_create_with_items("val1", "val2", "val3", NULL);
+ verify_key_values(keys, values, "main");
+
+ /* the original order is maintained if the settings are merged */
+ ck_assert(settings->load_files(settings, include1, TRUE));
+ keys = linked_list_create_with_items("key1", "key2", "key3", "key0", NULL);
+ values = linked_list_create_with_items("val1", "val2", "val3", "val0", NULL);
+ verify_key_values(keys, values, "main");
+
+ /* but the new order is adopted if the settings are replaced */
+ ck_assert(settings->load_files(settings, include1, FALSE));
+ keys = linked_list_create_with_items("key0", "key3", "key1", NULL);
+ values = linked_list_create_with_items("val0", "val3", "val1", NULL);
+ verify_key_values(keys, values, "main");
+
+ unlink(include1);
+}
+END_TEST
+
+START_TEST(test_order_section)
+{
+ chunk_t base = chunk_from_str(
+ "main {\n"
+ " sub1 {\n"
+ " }\n"
+ " sub2 {\n"
+ " }\n"
+ " sub3 {\n"
+ " }\n"
+ "}");
+ chunk_t include = chunk_from_str(
+ "main {\n"
+ " sub0 {\n"
+ " }\n"
+ " sub3 {\n"
+ " }\n"
+ " sub1 {\n"
+ " }\n"
+ "}");
+ linked_list_t *sections;
+
+ create_settings(base);
+ ck_assert(chunk_write(include, include1, 0022, TRUE));
+
+ sections = linked_list_create_with_items("sub1", "sub2", "sub3", NULL);
+ verify_sections(sections, "main");
+
+ /* the original order is maintained if the settings are merged */
+ ck_assert(settings->load_files(settings, include1, TRUE));
+ sections = linked_list_create_with_items("sub1", "sub2", "sub3", "sub0", NULL);
+ verify_sections(sections, "main");
+
+ /* but the new order is adopted if the settings are replaced */
+ ck_assert(settings->load_files(settings, include1, FALSE));
+ sections = linked_list_create_with_items("sub0", "sub3", "sub1", NULL);
+ verify_sections(sections, "main");
+
+ unlink(include1);
+}
+END_TEST
+
START_SETUP(setup_fallback_config)
{
create_settings(chunk_from_str(
@@ -811,7 +892,6 @@ START_TEST(test_add_fallback_printf)
}
END_TEST
-
START_SETUP(setup_string_config)
{
create_settings(chunk_from_str(
@@ -967,6 +1047,8 @@ Suite *settings_suite_create()
tcase_add_test(tc, test_include);
tcase_add_test(tc, test_load_files);
tcase_add_test(tc, test_load_files_section);
+ tcase_add_test(tc, test_order_kv);
+ tcase_add_test(tc, test_order_section);
suite_add_tcase(s, tc);
tc = tcase_create("fallback");