diff options
author | Thomas Haller <thaller@redhat.com> | 2018-03-26 08:18:51 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-03-27 09:58:00 +0200 |
commit | cd48bc74b69794a1f60c2f08cc503f8ca43322ae (patch) | |
tree | d5dffb30340a3e8689369190b2b8ef4f3d53ae13 | |
parent | 0f1dc3bca3ed3cc2a9e7dacc34cbb2654965770d (diff) | |
download | NetworkManager-cd48bc74b69794a1f60c2f08cc503f8ca43322ae.tar.gz |
config: cleanup fields in NMGlobalDnsConfig
- consistently set options, searches, domains fields to %NULL,
if there are no values.
- in nm_global_dns_config_update_checksum(), ensure that we uniquely
hash values. E.g. a config with "searches[a], options=[b]" should
hash differently from "searches=[ab], options=[]".
- in nm_global_dns_config_to_dbus(), reuse the sorted domain list.
We already have it, and it guarantees a consistent ordering of
fields.
- in global_dns_domain_from_dbus(), fix memleaks if D-Bus strdict
contains duplicate entries.
-rw-r--r-- | src/dns/nm-dns-manager.c | 34 | ||||
-rw-r--r-- | src/nm-config-data.c | 180 | ||||
-rw-r--r-- | src/tests/config/test-config.c | 2 |
3 files changed, 132 insertions, 84 deletions
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index 56be5aab35..ea8ce2d805 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -970,30 +970,36 @@ merge_global_dns_config (NMResolvConfData *rc, NMGlobalDnsConfig *global_conf) const char *const *searches; const char *const *options; const char *const *servers; - gint i; + guint i; if (!global_conf) return FALSE; searches = nm_global_dns_config_get_searches (global_conf); - options = nm_global_dns_config_get_options (global_conf); - - for (i = 0; searches && searches[i]; i++) { - if (domain_is_routing (searches[i])) - continue; - if (!domain_is_valid (searches[i], FALSE)) - continue; - add_string_item (rc->searches, searches[i], TRUE); + if (searches) { + for (i = 0; searches[i]; i++) { + if (domain_is_routing (searches[i])) + continue; + if (!domain_is_valid (searches[i], FALSE)) + continue; + add_string_item (rc->searches, searches[i], TRUE); + } } - for (i = 0; options && options[i]; i++) - add_string_item (rc->options, options[i], TRUE); + options = nm_global_dns_config_get_options (global_conf); + if (options) { + for (i = 0; options[i]; i++) + add_string_item (rc->options, options[i], TRUE); + } default_domain = nm_global_dns_config_lookup_domain (global_conf, "*"); - g_assert (default_domain); + nm_assert (default_domain); + servers = nm_global_dns_domain_get_servers (default_domain); - for (i = 0; servers && servers[i]; i++) - add_string_item (rc->nameservers, servers[i], TRUE); + if (servers) { + for (i = 0; servers[i]; i++) + add_string_item (rc->nameservers, servers[i], TRUE); + } return TRUE; } diff --git a/src/nm-config-data.c b/src/nm-config-data.c index 13d6acc2f8..638d5f3cbd 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -54,7 +54,7 @@ struct _NMGlobalDnsConfig { char **searches; char **options; GHashTable *domains; - char **domain_list; + const char **domain_list; gboolean internal; }; @@ -705,12 +705,12 @@ nm_config_data_log (const NMConfigData *self, /*****************************************************************************/ -const char *const * +const char *const* nm_global_dns_config_get_searches (const NMGlobalDnsConfig *dns_config) { g_return_val_if_fail (dns_config, NULL); - return (const char *const *) dns_config->searches; + return (const char *const*) dns_config->searches; } const char *const * @@ -718,16 +718,15 @@ nm_global_dns_config_get_options (const NMGlobalDnsConfig *dns_config) { g_return_val_if_fail (dns_config, NULL); - return (const char *const *) dns_config->options; + return (const char *const*) dns_config->options; } guint nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns_config) { g_return_val_if_fail (dns_config, 0); - g_return_val_if_fail (dns_config->domains, 0); - return g_hash_table_size (dns_config->domains); + return dns_config->domains ? g_hash_table_size (dns_config->domains) : 0; } NMGlobalDnsDomain * @@ -737,22 +736,22 @@ nm_global_dns_config_get_domain (const NMGlobalDnsConfig *dns_config, guint i) g_return_val_if_fail (dns_config, NULL); g_return_val_if_fail (dns_config->domains, NULL); - g_return_val_if_fail (dns_config->domain_list, NULL); - g_return_val_if_fail (i < g_strv_length (dns_config->domain_list), NULL); + g_return_val_if_fail (i < g_hash_table_size (dns_config->domains), NULL); + + nm_assert (NM_PTRARRAY_LEN (dns_config->domain_list) == g_hash_table_size (dns_config->domains)); domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]); - g_return_val_if_fail (domain, NULL); + nm_assert (domain); return domain; } NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns_config, const char *name) { g_return_val_if_fail (dns_config, NULL); - g_return_val_if_fail (dns_config->domains, NULL); g_return_val_if_fail (name, NULL); - return g_hash_table_lookup (dns_config->domains, name); + return dns_config->domains ? g_hash_table_lookup (dns_config->domains, name) : NULL; } const char * @@ -775,6 +774,7 @@ const char *const * nm_global_dns_domain_get_options (const NMGlobalDnsDomain *domain) { g_return_val_if_fail (domain, NULL); + return (const char *const *) domain->options; } @@ -788,42 +788,59 @@ gboolean nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns_config) { g_return_val_if_fail (dns_config, TRUE); - g_return_val_if_fail (dns_config->domains, TRUE); - return (!dns_config->searches || g_strv_length (dns_config->searches) == 0) - && (!dns_config->options || g_strv_length (dns_config->options) == 0) - && g_hash_table_size (dns_config->domains) == 0; + return !dns_config->searches + && !dns_config->options + && !dns_config->domain_list; } void nm_global_dns_config_update_checksum (const NMGlobalDnsConfig *dns_config, GChecksum *sum) { NMGlobalDnsDomain *domain; - GList *keys, *key; guint i; + guint8 v8; g_return_if_fail (dns_config); - g_return_if_fail (dns_config->domains); g_return_if_fail (sum); - for (i = 0; dns_config->searches && dns_config->searches[i]; i++) - g_checksum_update (sum, (guchar *) dns_config->searches[i], strlen (dns_config->searches[i])); - for (i = 0; dns_config->options && dns_config->options[i]; i++) - g_checksum_update (sum, (guchar *) dns_config->options[i], strlen (dns_config->options[i])); + v8 = NM_HASH_COMBINE_BOOLS (guint8, + !dns_config->searches, + !dns_config->options, + !dns_config->domain_list); + g_checksum_update (sum, (guchar *) &v8, 1); + + if (dns_config->searches) { + for (i = 0; dns_config->searches[i]; i++) + g_checksum_update (sum, (guchar *) dns_config->searches[i], strlen (dns_config->searches[i]) + 1); + } + if (dns_config->options) { + for (i = 0; dns_config->options[i]; i++) + g_checksum_update (sum, (guchar *) dns_config->options[i], strlen (dns_config->options[i]) + 1); + } + + if (dns_config->domain_list) { + for (i = 0; dns_config->domain_list[i]; i++) { + domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]); + nm_assert (domain); - keys = g_list_sort (g_hash_table_get_keys (dns_config->domains), (GCompareFunc) strcmp); - for (key = keys; key; key = g_list_next (key)) { + v8 = NM_HASH_COMBINE_BOOLS (guint8, + !domain->servers, + !domain->options); + g_checksum_update (sum, (guchar *) &v8, 1); - domain = g_hash_table_lookup (dns_config->domains, key->data); - g_assert (domain != NULL); - g_checksum_update (sum, (guchar *) domain->name, strlen (domain->name)); + g_checksum_update (sum, (guchar *) domain->name, strlen (domain->name) + 1); - for (i = 0; domain->servers && domain->servers[i]; i++) - g_checksum_update (sum, (guchar *) domain->servers[i], strlen (domain->servers[i])); - for (i = 0; domain->options && domain->options[i]; i++) - g_checksum_update (sum, (guchar *) domain->options[i], strlen (domain->options[i])); + if (domain->servers) { + for (i = 0; domain->servers && domain->servers[i]; i++) + g_checksum_update (sum, (guchar *) domain->servers[i], strlen (domain->servers[i]) + 1); + } + if (domain->options) { + for (i = 0; domain->options[i]; i++) + g_checksum_update (sum, (guchar *) domain->options[i], strlen (domain->options[i]) + 1); + } + } } - g_list_free (keys); } static void @@ -844,7 +861,8 @@ nm_global_dns_config_free (NMGlobalDnsConfig *dns_config) g_strfreev (dns_config->searches); g_strfreev (dns_config->options); g_free (dns_config->domain_list); - g_hash_table_unref (dns_config->domains); + if (dns_config->domains) + g_hash_table_unref (dns_config->domains); g_free (dns_config); } } @@ -858,12 +876,16 @@ nm_config_data_get_global_dns_config (const NMConfigData *self) } static void -global_dns_config_update_domain_list (NMGlobalDnsConfig *dns_config) +global_dns_config_seal_domains (NMGlobalDnsConfig *dns_config) { - guint length; + nm_assert (dns_config); + nm_assert (dns_config->domains); + nm_assert (!dns_config->domain_list); - g_free (dns_config->domain_list); - dns_config->domain_list = (char **) g_hash_table_get_keys_as_array (dns_config->domains, &length); + if (g_hash_table_size (dns_config->domains) == 0) + nm_clear_pointer (&dns_config->domains, g_hash_table_unref); + else + dns_config->domain_list = nm_utils_strdict_get_keys (dns_config->domains, TRUE, NULL); } static NMGlobalDnsConfig * @@ -892,8 +914,13 @@ load_global_dns (GKeyFile *keyfile, gboolean internal) g_free, (GDestroyNotify) global_dns_domain_free); strv = g_key_file_get_string_list (keyfile, group, "searches", NULL, NULL); - if (strv) - dns_config->searches = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE); + if (strv) { + _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE); + if (!strv[0]) + g_free (strv); + else + dns_config->searches = strv; + } strv = g_key_file_get_string_list (keyfile, group, "options", NULL, NULL); if (strv) { @@ -904,8 +931,12 @@ load_global_dns (GKeyFile *keyfile, gboolean internal) else g_free (strv[i]); } - strv[j] = NULL; - dns_config->options = strv; + if (j == 0) + g_free (strv); + else { + strv[j] = NULL; + dns_config->options = strv; + } } groups = g_key_file_get_groups (keyfile, NULL); @@ -928,20 +959,23 @@ load_global_dns (GKeyFile *keyfile, gboolean internal) else g_free (strv[i]); } - if (j) { + if (j == 0) + g_free (strv); + else { strv[j] = NULL; servers = strv; } - else - g_free (strv); } if (!servers) continue; strv = g_key_file_get_string_list (keyfile, groups[g], "options", NULL, NULL); - if (strv) + if (strv) { options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE); + if (!options[0]) + nm_clear_g_free (&options); + } name = strdup (&groups[g][domain_prefix_len]); domain = g_malloc0 (sizeof (NMGlobalDnsDomain)); @@ -963,7 +997,7 @@ load_global_dns (GKeyFile *keyfile, gboolean internal) } dns_config->internal = internal; - global_dns_config_update_domain_list (dns_config); + global_dns_config_seal_domains (dns_config); return dns_config; } @@ -972,8 +1006,7 @@ void nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns_config, GValue *value) { GVariantBuilder conf_builder, domains_builder, domain_builder; - NMGlobalDnsDomain *domain; - GHashTableIter iter; + guint i; g_variant_builder_init (&conf_builder, G_VARIANT_TYPE ("a{sv}")); if (!dns_config) @@ -990,27 +1023,30 @@ nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns_config, GValue *value } g_variant_builder_init (&domains_builder, G_VARIANT_TYPE ("a{sv}")); + if (dns_config->domain_list) { + for (i = 0; dns_config->domain_list[i]; i++) { + NMGlobalDnsDomain *domain; - g_hash_table_iter_init (&iter, dns_config->domains); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &domain)) { + domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]); - g_variant_builder_init (&domain_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_init (&domain_builder, G_VARIANT_TYPE ("a{sv}")); - if (domain->servers) { - g_variant_builder_add (&domain_builder, "{sv}", "servers", - g_variant_new_strv ((const char *const *) domain->servers, -1)); - } - if (domain->options) { - g_variant_builder_add (&domain_builder, "{sv}", "options", - g_variant_new_strv ((const char *const *) domain->options, -1)); - } + if (domain->servers) { + g_variant_builder_add (&domain_builder, "{sv}", "servers", + g_variant_new_strv ((const char *const *) domain->servers, -1)); + } + if (domain->options) { + g_variant_builder_add (&domain_builder, "{sv}", "options", + g_variant_new_strv ((const char *const *) domain->options, -1)); + } - g_variant_builder_add (&domains_builder, "{sv}", domain->name, - g_variant_builder_end (&domain_builder)); + g_variant_builder_add (&domains_builder, "{sv}", domain->name, + g_variant_builder_end (&domain_builder)); + } } - g_variant_builder_add (&conf_builder, "{sv}", "domains", g_variant_builder_end (&domains_builder)); + out: g_value_take_variant (value, g_variant_builder_end (&conf_builder)); } @@ -1044,15 +1080,20 @@ global_dns_domain_from_dbus (char *name, GVariant *variant) else g_free (strv[i]); } - if (j) { + if (j == 0) + g_free (strv); + else { strv[j] = NULL; + g_strfreev (domain->servers); domain->servers = strv; - } else - g_free (strv); + } } else if ( !g_strcmp0 (key, "options") && g_variant_is_of_type (val, G_VARIANT_TYPE ("as"))) { strv = g_variant_dup_strv (val, NULL); + g_strfreev (domain->options); domain->options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE); + if (!domain->options[0]) + nm_clear_g_free (&domain->options); } g_variant_unref (val); @@ -1111,11 +1152,12 @@ nm_global_dns_config_from_dbus (const GValue *value, GError **error) else g_free (strv[i]); } - - if (strv) + if (j == 0) + g_free (strv); + else { strv[j] = NULL; - - dns_config->options = strv; + dns_config->options = strv; + } } else if ( !g_strcmp0 (key, "domains") && g_variant_is_of_type (val, G_VARIANT_TYPE ("a{sv}"))) { NMGlobalDnsDomain *domain; @@ -1145,7 +1187,7 @@ nm_global_dns_config_from_dbus (const GValue *value, GError **error) return NULL; } - global_dns_config_update_domain_list (dns_config); + global_dns_config_seal_domains (dns_config); return dns_config; } diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c index 8398841d39..a6b886ce43 100644 --- a/src/tests/config/test-config.c +++ b/src/tests/config/test-config.c @@ -254,7 +254,7 @@ test_config_global_dns (void) NMConfig *config; const NMGlobalDnsConfig *dns; NMGlobalDnsDomain *domain; - const char *const *strv; + const char *const*strv; config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, "/no/such/dir", "", NULL); |