diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2015-03-26 08:57:02 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2015-03-30 13:46:14 +0200 |
commit | feb05fa1cbb18df2fbdb60723d1f72e0fb41d9c7 (patch) | |
tree | 0c7cfa98d06ee46e147c640cf7167465f9dc6cad | |
parent | af060e7c224cc7ce44a18fb23fdedb81f147319e (diff) | |
download | NetworkManager-feb05fa1cbb18df2fbdb60723d1f72e0fb41d9c7.tar.gz |
libnm-core: add dns-options property to NMSettingIPConfig
-rw-r--r-- | libnm-core/nm-setting-ip-config.c | 172 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip-config.h | 12 | ||||
-rw-r--r-- | libnm-core/nm-utils-private.h | 4 | ||||
-rw-r--r-- | libnm-core/nm-utils.c | 127 | ||||
-rw-r--r-- | libnm/libnm.ver | 6 |
5 files changed, 321 insertions, 0 deletions
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index e6f0401a01..c1391690f9 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -1062,6 +1062,7 @@ typedef struct { char *method; GPtrArray *dns; /* array of IP address strings */ GPtrArray *dns_search; /* array of domain name strings */ + GPtrArray *dns_options;/* array of DNS options */ GPtrArray *addresses; /* array of NMIPAddress */ GPtrArray *routes; /* array of NMIPRoute */ gint64 route_metric; @@ -1079,6 +1080,7 @@ enum { PROP_METHOD, PROP_DNS, PROP_DNS_SEARCH, + PROP_DNS_OPTIONS, PROP_ADDRESSES, PROP_GATEWAY, PROP_ROUTES, @@ -1394,6 +1396,155 @@ nm_setting_ip_config_clear_dns_searches (NMSettingIPConfig *setting) } /** + * nm_setting_ip_config_get_num_dns_options: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured DNS options + **/ +guint +nm_setting_ip_config_get_num_dns_options (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns_options->len; +} + +/** + * nm_setting_ip_config_get_dns_options: + * @setting: the #NMSettingIPConfig + * @i: index number of the DNS options + * + * Returns: the DNS option at index @i + **/ +const char * +nm_setting_ip_config_get_dns_option (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_val_if_fail (i < priv->dns_options->len, NULL); + + return priv->dns_options->pdata[i]; +} + +/** + * nm_setting_ip_config_add_dns_option: + * @setting: the #NMSettingIPConfig + * @dns_option: the DNS option to add + * + * Adds a new DNS option to the setting. + * + * Returns: %TRUE if the DNS option was added; %FALSE if the option was + * already known + **/ +gboolean +nm_setting_ip_config_add_dns_option (NMSettingIPConfig *setting, + const char *dns_option) +{ + NMSettingIPConfigPrivate *priv; + gboolean numeric; + char *name; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (dns_option != NULL, FALSE); + g_return_val_if_fail (dns_option[0] != '\0', FALSE); + + /* Check syntax and extract option name */ + if (!_nm_utils_dns_option_parse (dns_option, &name, &numeric)) + return FALSE; + + /* Verify that the option is known */ + if (!_nm_utils_dns_option_validate (name, numeric, + NM_IS_SETTING_IP6_CONFIG (setting))) { + g_free (name); + return FALSE; + } + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + if (!_nm_utils_dns_option_check_duplicate (priv->dns_options, name)) { + g_free (name); + return FALSE; + } + + g_free (name); + g_ptr_array_add (priv->dns_options, g_strdup (dns_option)); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_dns_option: + * @setting: the #NMSettingIPConfig + * @i: index number of the DNS option + * + * Removes the DNS option at index @i. + **/ +void +nm_setting_ip_config_remove_dns_option (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_if_fail (i < priv->dns_options->len); + + g_ptr_array_remove_index (priv->dns_options, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); +} + +/** + * nm_setting_ip_config_remove_dns_option_by_value: + * @setting: the #NMSettingIPConfig + * @dns_option: the DNS option to remove + * + * Removes the DNS option @dns_option. + * + * Returns: %TRUE if the DNS option was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig *setting, + const char *dns_option) +{ + NMSettingIPConfigPrivate *priv; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (dns_option != NULL, FALSE); + g_return_val_if_fail (dns_option[0] != '\0', FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + for (i = 0; i < priv->dns_options->len; i++) { + if (!strcmp (dns_option, priv->dns_options->pdata[i])) { + g_ptr_array_remove_index (priv->dns_options, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_ip_config_clear_dns_options: + * @setting: the #NMSettingIPConfig + * + * Removes all configured DNS options. + **/ +void +nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_ptr_array_set_size (priv->dns_options, 0); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); +} + +/** * nm_setting_ip_config_get_num_addresses: * @setting: the #NMSettingIPConfig * @@ -1959,6 +2110,7 @@ nm_setting_ip_config_init (NMSettingIPConfig *setting) priv->dns = g_ptr_array_new_with_free_func (g_free); priv->dns_search = g_ptr_array_new_with_free_func (g_free); + priv->dns_options = g_ptr_array_new_with_free_func (g_free); priv->addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); priv->routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); } @@ -1975,6 +2127,7 @@ finalize (GObject *object) g_ptr_array_unref (priv->dns); g_ptr_array_unref (priv->dns_search); + g_ptr_array_unref (priv->dns_options); g_ptr_array_unref (priv->addresses); g_ptr_array_unref (priv->routes); @@ -2002,6 +2155,10 @@ set_property (GObject *object, guint prop_id, g_ptr_array_unref (priv->dns_search); priv->dns_search = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value)); break; + case PROP_DNS_OPTIONS: + g_ptr_array_unref (priv->dns_options); + priv->dns_options = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value)); + break; case PROP_ADDRESSES: g_ptr_array_unref (priv->addresses); priv->addresses = _nm_utils_copy_array (g_value_get_boxed (value), @@ -2065,6 +2222,9 @@ get_property (GObject *object, guint prop_id, case PROP_DNS_SEARCH: g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (priv->dns_search)); break; + case PROP_DNS_OPTIONS: + g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (priv->dns_options)); + break; case PROP_ADDRESSES: g_value_take_boxed (value, _nm_utils_copy_array (priv->addresses, (NMUtilsCopyFunc) nm_ip_address_dup, @@ -2185,6 +2345,18 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class) G_PARAM_STATIC_STRINGS)); /** + * NMSettingIPConfig:dns-options: + * + * Array of DNS options. + **/ + g_object_class_install_property + (object_class, PROP_DNS_OPTIONS, + g_param_spec_boxed (NM_SETTING_IP_CONFIG_DNS_OPTIONS, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** * NMSettingIPConfig:addresses: * * Array of IP addresses. diff --git a/libnm-core/nm-setting-ip-config.h b/libnm-core/nm-setting-ip-config.h index 12763fa857..58d1a3baba 100644 --- a/libnm-core/nm-setting-ip-config.h +++ b/libnm-core/nm-setting-ip-config.h @@ -133,6 +133,7 @@ void nm_ip_route_set_attribute (NMIPRoute *route, #define NM_SETTING_IP_CONFIG_METHOD "method" #define NM_SETTING_IP_CONFIG_DNS "dns" #define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search" +#define NM_SETTING_IP_CONFIG_DNS_OPTIONS "dns-options" #define NM_SETTING_IP_CONFIG_ADDRESSES "addresses" #define NM_SETTING_IP_CONFIG_GATEWAY "gateway" #define NM_SETTING_IP_CONFIG_ROUTES "routes" @@ -181,6 +182,17 @@ gboolean nm_setting_ip_config_remove_dns_search_by_value (NMSettingIPConfig const char *dns_search); void nm_setting_ip_config_clear_dns_searches (NMSettingIPConfig *setting); +guint nm_setting_ip_config_get_num_dns_options (NMSettingIPConfig *setting); +const char *nm_setting_ip_config_get_dns_option (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_add_dns_option (NMSettingIPConfig *setting, + const char *dns_option); +void nm_setting_ip_config_remove_dns_option (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig *setting, + const char *dns_option); +void nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting); + guint nm_setting_ip_config_get_num_addresses (NMSettingIPConfig *setting); NMIPAddress *nm_setting_ip_config_get_address (NMSettingIPConfig *setting, int i); diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h index 3854d67951..8b5ae05ffa 100644 --- a/libnm-core/nm-utils-private.h +++ b/libnm-core/nm-utils-private.h @@ -48,4 +48,8 @@ char ** _nm_utils_ptrarray_to_strv (GPtrArray *ptrarray); char * _nm_utils_hwaddr_canonical_or_invalid (const char *mac, gssize length); +gboolean _nm_utils_dns_option_parse (const char *str, char **name, gboolean *numeric); +gboolean _nm_utils_dns_option_validate (const char *name, gboolean numeric, gboolean ipv6); +gboolean _nm_utils_dns_option_check_duplicate (GPtrArray *array, const char *name); + #endif diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index d3557f578a..464177d3f4 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -144,6 +144,29 @@ static const struct IsoLangToEncodings isoLangEntries2[] = static GHashTable * langToEncodings5 = NULL; static GHashTable * langToEncodings2 = NULL; +typedef struct { + const char *name; + gboolean numeric; + gboolean ipv6_only; +} DNSOptionDesc; + +static const DNSOptionDesc dns_option_descs[] = { + { "debug", FALSE, FALSE }, + { "ndots", TRUE, FALSE }, + { "timeout", TRUE, FALSE }, + { "attempts", TRUE, FALSE }, + { "rotate", FALSE, FALSE }, + { "no-check-names", FALSE, FALSE }, + { "inet6", FALSE, TRUE }, + { "ip6-bytestring", FALSE, TRUE }, + { "ip6-dotint", FALSE, TRUE }, + { "no-ip6-dotint", FALSE, TRUE }, + { "edns0", FALSE, FALSE }, + { "single-request", FALSE, FALSE }, + { "single-request-reopen", FALSE, FALSE }, + { NULL, FALSE, FALSE } +}; + static void init_lang_to_encodings_hash (void) { @@ -3406,3 +3429,107 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma return v; } +/** + * _nm_utils_dns_option_parse + * @str: option string + * @name: (out): on return will contain the option name + * @numeric: (out) (allow-none): whether the option has a numeric argument + * + * Parses a DNS option in the form "name" or "name:number" + * + * Returns: %TRUE when the parsing was successfully done, %FALSE otherwise + */ +gboolean _nm_utils_dns_option_parse(const char *str, char **name, + gboolean *numeric) +{ + char **tokens, *ptr; + gboolean ret; + + g_return_val_if_fail (str != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + tokens = g_strsplit (str, ":", 2); + if (numeric) + *numeric = FALSE; + + if (g_strv_length (tokens) == 1) { + *name = g_strdup (tokens[0]); + ret = TRUE; + goto out; + } + + /* Numeric option */ + + if (!tokens[1][0]) { + ret = FALSE; + goto out; + } + + for (ptr = tokens[1]; *ptr; ptr++) { + if (!g_ascii_isdigit (*ptr)) { + ret = FALSE; + goto out; + } + } + + *name = g_strdup (tokens[0]); + if (numeric) + *numeric = TRUE; + ret = TRUE; +out: + g_strfreev (tokens); + return ret; +} + +/** + * _nm_utils_dns_option_validate + * @name: option name + * @numeric: whether the option has a numeric argument + * @ipv6: whether the option refers to a IPv6 connection + * + * Checks if a DNS option is valid + * + * Returns: %TRUE if the option is valid, %FALSE otherwise + */ +gboolean _nm_utils_dns_option_validate(const char *name, gboolean numeric, + gboolean ipv6) +{ + const DNSOptionDesc *desc; + + for (desc = dns_option_descs; desc->name; desc++) { + if (!strcmp (name, desc->name) && + numeric == desc->numeric && + (!desc->ipv6_only || ipv6)) + return TRUE; + } + + return FALSE; +} + +/** + * _nm_utils_dns_option_check_duplicate + * @array: an array of strings + * @name: name of a DNS option + * + * Checks if a DNS option with name @name is already present in the array + * + * Returns: %TRUE if the option is not present, %FALSE otherwise + */ +gboolean _nm_utils_dns_option_check_duplicate(GPtrArray *array, const char *name) +{ + gboolean ret; + char *tmp_name; + int i; + + for (i = 0; i < array->len; i++) { + _nm_utils_dns_option_parse (array->pdata[i], &tmp_name, NULL); + ret = strcmp (tmp_name, name); + g_free (tmp_name); + + if (!ret) + return FALSE; + } + + return TRUE; +} + diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 44b83f6ecb..06640e6d84 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -553,16 +553,19 @@ global: nm_setting_ip_config_add_address; nm_setting_ip_config_add_dns; nm_setting_ip_config_add_dns_search; + nm_setting_ip_config_add_dns_option; nm_setting_ip_config_add_route; nm_setting_ip_config_clear_addresses; nm_setting_ip_config_clear_dns; nm_setting_ip_config_clear_dns_searches; + nm_setting_ip_config_clear_dns_options; nm_setting_ip_config_clear_routes; nm_setting_ip_config_get_address; nm_setting_ip_config_get_dhcp_hostname; nm_setting_ip_config_get_dhcp_send_hostname; nm_setting_ip_config_get_dns; nm_setting_ip_config_get_dns_search; + nm_setting_ip_config_get_dns_option; nm_setting_ip_config_get_gateway; nm_setting_ip_config_get_ignore_auto_dns; nm_setting_ip_config_get_ignore_auto_routes; @@ -572,6 +575,7 @@ global: nm_setting_ip_config_get_num_addresses; nm_setting_ip_config_get_num_dns; nm_setting_ip_config_get_num_dns_searches; + nm_setting_ip_config_get_num_dns_options; nm_setting_ip_config_get_num_routes; nm_setting_ip_config_get_route; nm_setting_ip_config_get_route_metric; @@ -582,6 +586,8 @@ global: nm_setting_ip_config_remove_dns_by_value; nm_setting_ip_config_remove_dns_search; nm_setting_ip_config_remove_dns_search_by_value; + nm_setting_ip_config_remove_dns_option; + nm_setting_ip_config_remove_dns_option_by_value; nm_setting_ip_config_remove_route; nm_setting_ip_config_remove_route_by_value; nm_setting_lookup_type; |