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.
This commit is contained in:
@@ -970,30 +970,36 @@ merge_global_dns_config (NMResolvConfData *rc, NMGlobalDnsConfig *global_conf)
|
|||||||
const char *const *searches;
|
const char *const *searches;
|
||||||
const char *const *options;
|
const char *const *options;
|
||||||
const char *const *servers;
|
const char *const *servers;
|
||||||
gint i;
|
guint i;
|
||||||
|
|
||||||
if (!global_conf)
|
if (!global_conf)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
searches = nm_global_dns_config_get_searches (global_conf);
|
searches = nm_global_dns_config_get_searches (global_conf);
|
||||||
options = nm_global_dns_config_get_options (global_conf);
|
if (searches) {
|
||||||
|
for (i = 0; searches[i]; i++) {
|
||||||
for (i = 0; searches && searches[i]; i++) {
|
|
||||||
if (domain_is_routing (searches[i]))
|
if (domain_is_routing (searches[i]))
|
||||||
continue;
|
continue;
|
||||||
if (!domain_is_valid (searches[i], FALSE))
|
if (!domain_is_valid (searches[i], FALSE))
|
||||||
continue;
|
continue;
|
||||||
add_string_item (rc->searches, searches[i], TRUE);
|
add_string_item (rc->searches, searches[i], TRUE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; options && options[i]; i++)
|
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);
|
add_string_item (rc->options, options[i], TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
default_domain = nm_global_dns_config_lookup_domain (global_conf, "*");
|
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);
|
servers = nm_global_dns_domain_get_servers (default_domain);
|
||||||
for (i = 0; servers && servers[i]; i++)
|
if (servers) {
|
||||||
|
for (i = 0; servers[i]; i++)
|
||||||
add_string_item (rc->nameservers, servers[i], TRUE);
|
add_string_item (rc->nameservers, servers[i], TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@@ -54,7 +54,7 @@ struct _NMGlobalDnsConfig {
|
|||||||
char **searches;
|
char **searches;
|
||||||
char **options;
|
char **options;
|
||||||
GHashTable *domains;
|
GHashTable *domains;
|
||||||
char **domain_list;
|
const char **domain_list;
|
||||||
gboolean internal;
|
gboolean internal;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -725,9 +725,8 @@ guint
|
|||||||
nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns_config)
|
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, 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 *
|
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, NULL);
|
||||||
g_return_val_if_fail (dns_config->domains, 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_hash_table_size (dns_config->domains), NULL);
|
||||||
g_return_val_if_fail (i < g_strv_length (dns_config->domain_list), 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]);
|
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;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns_config, const char *name)
|
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, NULL);
|
||||||
g_return_val_if_fail (dns_config->domains, NULL);
|
|
||||||
g_return_val_if_fail (name, 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 *
|
const char *
|
||||||
@@ -775,6 +774,7 @@ const char *const *
|
|||||||
nm_global_dns_domain_get_options (const NMGlobalDnsDomain *domain)
|
nm_global_dns_domain_get_options (const NMGlobalDnsDomain *domain)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (domain, NULL);
|
g_return_val_if_fail (domain, NULL);
|
||||||
|
|
||||||
return (const char *const *) domain->options;
|
return (const char *const *) domain->options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,42 +788,59 @@ gboolean
|
|||||||
nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns_config)
|
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, TRUE);
|
||||||
g_return_val_if_fail (dns_config->domains, TRUE);
|
|
||||||
|
|
||||||
return (!dns_config->searches || g_strv_length (dns_config->searches) == 0)
|
return !dns_config->searches
|
||||||
&& (!dns_config->options || g_strv_length (dns_config->options) == 0)
|
&& !dns_config->options
|
||||||
&& g_hash_table_size (dns_config->domains) == 0;
|
&& !dns_config->domain_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_global_dns_config_update_checksum (const NMGlobalDnsConfig *dns_config, GChecksum *sum)
|
nm_global_dns_config_update_checksum (const NMGlobalDnsConfig *dns_config, GChecksum *sum)
|
||||||
{
|
{
|
||||||
NMGlobalDnsDomain *domain;
|
NMGlobalDnsDomain *domain;
|
||||||
GList *keys, *key;
|
|
||||||
guint i;
|
guint i;
|
||||||
|
guint8 v8;
|
||||||
|
|
||||||
g_return_if_fail (dns_config);
|
g_return_if_fail (dns_config);
|
||||||
g_return_if_fail (dns_config->domains);
|
|
||||||
g_return_if_fail (sum);
|
g_return_if_fail (sum);
|
||||||
|
|
||||||
for (i = 0; dns_config->searches && dns_config->searches[i]; i++)
|
v8 = NM_HASH_COMBINE_BOOLS (guint8,
|
||||||
g_checksum_update (sum, (guchar *) dns_config->searches[i], strlen (dns_config->searches[i]));
|
!dns_config->searches,
|
||||||
for (i = 0; dns_config->options && dns_config->options[i]; i++)
|
!dns_config->options,
|
||||||
g_checksum_update (sum, (guchar *) dns_config->options[i], strlen (dns_config->options[i]));
|
!dns_config->domain_list);
|
||||||
|
g_checksum_update (sum, (guchar *) &v8, 1);
|
||||||
|
|
||||||
keys = g_list_sort (g_hash_table_get_keys (dns_config->domains), (GCompareFunc) strcmp);
|
if (dns_config->searches) {
|
||||||
for (key = keys; key; key = g_list_next (key)) {
|
for (i = 0; dns_config->searches[i]; i++)
|
||||||
|
g_checksum_update (sum, (guchar *) dns_config->searches[i], strlen (dns_config->searches[i]) + 1);
|
||||||
domain = g_hash_table_lookup (dns_config->domains, key->data);
|
}
|
||||||
g_assert (domain != NULL);
|
if (dns_config->options) {
|
||||||
g_checksum_update (sum, (guchar *) domain->name, strlen (domain->name));
|
for (i = 0; dns_config->options[i]; i++)
|
||||||
|
g_checksum_update (sum, (guchar *) dns_config->options[i], strlen (dns_config->options[i]) + 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++)
|
if (dns_config->domain_list) {
|
||||||
g_checksum_update (sum, (guchar *) domain->options[i], strlen (domain->options[i]));
|
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);
|
||||||
|
|
||||||
|
v8 = NM_HASH_COMBINE_BOOLS (guint8,
|
||||||
|
!domain->servers,
|
||||||
|
!domain->options);
|
||||||
|
g_checksum_update (sum, (guchar *) &v8, 1);
|
||||||
|
|
||||||
|
g_checksum_update (sum, (guchar *) domain->name, strlen (domain->name) + 1);
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
@@ -844,6 +861,7 @@ nm_global_dns_config_free (NMGlobalDnsConfig *dns_config)
|
|||||||
g_strfreev (dns_config->searches);
|
g_strfreev (dns_config->searches);
|
||||||
g_strfreev (dns_config->options);
|
g_strfreev (dns_config->options);
|
||||||
g_free (dns_config->domain_list);
|
g_free (dns_config->domain_list);
|
||||||
|
if (dns_config->domains)
|
||||||
g_hash_table_unref (dns_config->domains);
|
g_hash_table_unref (dns_config->domains);
|
||||||
g_free (dns_config);
|
g_free (dns_config);
|
||||||
}
|
}
|
||||||
@@ -858,12 +876,16 @@ nm_config_data_get_global_dns_config (const NMConfigData *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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);
|
if (g_hash_table_size (dns_config->domains) == 0)
|
||||||
dns_config->domain_list = (char **) g_hash_table_get_keys_as_array (dns_config->domains, &length);
|
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 *
|
static NMGlobalDnsConfig *
|
||||||
@@ -892,8 +914,13 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
|
|||||||
g_free, (GDestroyNotify) global_dns_domain_free);
|
g_free, (GDestroyNotify) global_dns_domain_free);
|
||||||
|
|
||||||
strv = g_key_file_get_string_list (keyfile, group, "searches", NULL, NULL);
|
strv = g_key_file_get_string_list (keyfile, group, "searches", NULL, NULL);
|
||||||
if (strv)
|
if (strv) {
|
||||||
dns_config->searches = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
|
_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);
|
strv = g_key_file_get_string_list (keyfile, group, "options", NULL, NULL);
|
||||||
if (strv) {
|
if (strv) {
|
||||||
@@ -904,9 +931,13 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
|
|||||||
else
|
else
|
||||||
g_free (strv[i]);
|
g_free (strv[i]);
|
||||||
}
|
}
|
||||||
|
if (j == 0)
|
||||||
|
g_free (strv);
|
||||||
|
else {
|
||||||
strv[j] = NULL;
|
strv[j] = NULL;
|
||||||
dns_config->options = strv;
|
dns_config->options = strv;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
groups = g_key_file_get_groups (keyfile, NULL);
|
groups = g_key_file_get_groups (keyfile, NULL);
|
||||||
for (g = 0; groups[g]; g++) {
|
for (g = 0; groups[g]; g++) {
|
||||||
@@ -928,20 +959,23 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
|
|||||||
else
|
else
|
||||||
g_free (strv[i]);
|
g_free (strv[i]);
|
||||||
}
|
}
|
||||||
if (j) {
|
if (j == 0)
|
||||||
|
g_free (strv);
|
||||||
|
else {
|
||||||
strv[j] = NULL;
|
strv[j] = NULL;
|
||||||
servers = strv;
|
servers = strv;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
g_free (strv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!servers)
|
if (!servers)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strv = g_key_file_get_string_list (keyfile, groups[g], "options", NULL, NULL);
|
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);
|
options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
|
||||||
|
if (!options[0])
|
||||||
|
nm_clear_g_free (&options);
|
||||||
|
}
|
||||||
|
|
||||||
name = strdup (&groups[g][domain_prefix_len]);
|
name = strdup (&groups[g][domain_prefix_len]);
|
||||||
domain = g_malloc0 (sizeof (NMGlobalDnsDomain));
|
domain = g_malloc0 (sizeof (NMGlobalDnsDomain));
|
||||||
@@ -963,7 +997,7 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dns_config->internal = internal;
|
dns_config->internal = internal;
|
||||||
global_dns_config_update_domain_list (dns_config);
|
global_dns_config_seal_domains (dns_config);
|
||||||
return dns_config;
|
return dns_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -972,8 +1006,7 @@ void
|
|||||||
nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns_config, GValue *value)
|
nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns_config, GValue *value)
|
||||||
{
|
{
|
||||||
GVariantBuilder conf_builder, domains_builder, domain_builder;
|
GVariantBuilder conf_builder, domains_builder, domain_builder;
|
||||||
NMGlobalDnsDomain *domain;
|
guint i;
|
||||||
GHashTableIter iter;
|
|
||||||
|
|
||||||
g_variant_builder_init (&conf_builder, G_VARIANT_TYPE ("a{sv}"));
|
g_variant_builder_init (&conf_builder, G_VARIANT_TYPE ("a{sv}"));
|
||||||
if (!dns_config)
|
if (!dns_config)
|
||||||
@@ -990,9 +1023,11 @@ nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns_config, GValue *value
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_variant_builder_init (&domains_builder, G_VARIANT_TYPE ("a{sv}"));
|
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);
|
domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]);
|
||||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &domain)) {
|
|
||||||
|
|
||||||
g_variant_builder_init (&domain_builder, G_VARIANT_TYPE ("a{sv}"));
|
g_variant_builder_init (&domain_builder, G_VARIANT_TYPE ("a{sv}"));
|
||||||
|
|
||||||
@@ -1008,9 +1043,10 @@ nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns_config, GValue *value
|
|||||||
g_variant_builder_add (&domains_builder, "{sv}", domain->name,
|
g_variant_builder_add (&domains_builder, "{sv}", domain->name,
|
||||||
g_variant_builder_end (&domain_builder));
|
g_variant_builder_end (&domain_builder));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
g_variant_builder_add (&conf_builder, "{sv}", "domains",
|
g_variant_builder_add (&conf_builder, "{sv}", "domains",
|
||||||
g_variant_builder_end (&domains_builder));
|
g_variant_builder_end (&domains_builder));
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_value_take_variant (value, g_variant_builder_end (&conf_builder));
|
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
|
else
|
||||||
g_free (strv[i]);
|
g_free (strv[i]);
|
||||||
}
|
}
|
||||||
if (j) {
|
if (j == 0)
|
||||||
strv[j] = NULL;
|
|
||||||
domain->servers = strv;
|
|
||||||
} else
|
|
||||||
g_free (strv);
|
g_free (strv);
|
||||||
|
else {
|
||||||
|
strv[j] = NULL;
|
||||||
|
g_strfreev (domain->servers);
|
||||||
|
domain->servers = strv;
|
||||||
|
}
|
||||||
} else if ( !g_strcmp0 (key, "options")
|
} else if ( !g_strcmp0 (key, "options")
|
||||||
&& g_variant_is_of_type (val, G_VARIANT_TYPE ("as"))) {
|
&& g_variant_is_of_type (val, G_VARIANT_TYPE ("as"))) {
|
||||||
strv = g_variant_dup_strv (val, NULL);
|
strv = g_variant_dup_strv (val, NULL);
|
||||||
|
g_strfreev (domain->options);
|
||||||
domain->options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
|
domain->options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
|
||||||
|
if (!domain->options[0])
|
||||||
|
nm_clear_g_free (&domain->options);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_variant_unref (val);
|
g_variant_unref (val);
|
||||||
@@ -1111,11 +1152,12 @@ nm_global_dns_config_from_dbus (const GValue *value, GError **error)
|
|||||||
else
|
else
|
||||||
g_free (strv[i]);
|
g_free (strv[i]);
|
||||||
}
|
}
|
||||||
|
if (j == 0)
|
||||||
if (strv)
|
g_free (strv);
|
||||||
|
else {
|
||||||
strv[j] = NULL;
|
strv[j] = NULL;
|
||||||
|
|
||||||
dns_config->options = strv;
|
dns_config->options = strv;
|
||||||
|
}
|
||||||
} else if ( !g_strcmp0 (key, "domains")
|
} else if ( !g_strcmp0 (key, "domains")
|
||||||
&& g_variant_is_of_type (val, G_VARIANT_TYPE ("a{sv}"))) {
|
&& g_variant_is_of_type (val, G_VARIANT_TYPE ("a{sv}"))) {
|
||||||
NMGlobalDnsDomain *domain;
|
NMGlobalDnsDomain *domain;
|
||||||
@@ -1145,7 +1187,7 @@ nm_global_dns_config_from_dbus (const GValue *value, GError **error)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
global_dns_config_update_domain_list (dns_config);
|
global_dns_config_seal_domains (dns_config);
|
||||||
return dns_config;
|
return dns_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user