[PATCH v2 39/42] vpn-provider: Add support for set/get "TransportNameservers"

Jussi Laakkonen <[email protected]> Wed, 13 Aug 2025 18:02:11 +0300
Newsgroups dev.linux.lists.connman
Message-ID <[email protected]>
Set the transport nameservers when property change is received as a
D-Bus signal from connmand. The code to get the nameservers is identical
to plugins/vpn.c:extract_nameservers(). And add a generic getter for
plugins to use.
---
 vpn/vpn-provider.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
 vpn/vpn-provider.h |  2 ++
 2 files changed, 50 insertions(+)

diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index 966866b9..3703c5a2 100644
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -112,6 +112,7 @@ struct vpn_provider {
 	unsigned int signal_watch;
 	unsigned int auth_error_limit;
 	time_t previous_connect_time;
+	char **transport_nameservers;
 };
 
 struct vpn_provider_connect_data {
@@ -1504,6 +1505,7 @@ static void provider_destruct(struct vpn_provider *provider)
 	g_free(provider->config_entry);
 	connman_ipaddress_free(provider->prev_ipv4_addr);
 	connman_ipaddress_free(provider->prev_ipv6_addr);
+	g_strfreev(provider->transport_nameservers);
 	g_free(provider);
 }
 
@@ -2243,6 +2245,41 @@ static gboolean provider_property_changed(DBusConnection *conn,
 		 */
 		vpn_provider_set_boolean(provider, "SplitRouting",
 					split_routing, true);
+	} else if (g_str_equal(key, "TransportNameservers")) {
+		DBusMessageIter entry;
+		char **nameservers = NULL;
+		int i = 0;
+
+		DBG("TransportNameservers");
+
+		dbus_message_iter_recurse(&value, &entry);
+
+		while (dbus_message_iter_get_arg_type(&entry) ==
+							DBUS_TYPE_STRING) {
+			const char *nameserver;
+
+			dbus_message_iter_get_basic(&entry, &nameserver);
+
+			DBG("DNS%d: %s", i, nameserver);
+
+			nameservers = g_try_renew(char *, nameservers, i + 2);
+			if (!nameservers)
+				break;
+
+			nameservers[i] = g_strdup(nameserver);
+			if (!nameservers[i]) {
+				g_strfreev(nameservers);
+				nameservers = NULL;
+				break;
+			}
+
+			nameservers[++i] = NULL;
+
+			dbus_message_iter_next(&entry);
+		}
+
+		g_strfreev(provider->transport_nameservers);
+		provider->transport_nameservers = nameservers;
 	}
 
 out:
@@ -2985,6 +3022,17 @@ const char *vpn_provider_get_string(struct vpn_provider *provider,
 	return setting->value;
 }
 
+char **vpn_provider_get_string_list(struct vpn_provider *provider,
+							const char *key)
+{
+	DBG("provider %p key %s", provider, key);
+
+	if (g_str_equal(key, "TransportNameservers"))
+		return provider->transport_nameservers;
+
+	return NULL;
+}
+
 int vpn_provider_set_boolean(struct vpn_provider *provider, const char *key,
 						bool value, bool force_change)
 {
diff --git a/vpn/vpn-provider.h b/vpn/vpn-provider.h
index a7ec5109..6bd64205 100644
--- a/vpn/vpn-provider.h
+++ b/vpn/vpn-provider.h
@@ -87,6 +87,8 @@ int vpn_provider_set_string_hide_value(struct vpn_provider *provider,
 					const char *key, const char *value);
 const char *vpn_provider_get_string(struct vpn_provider *provider,
 							const char *key);
+char **vpn_provider_get_string_list(struct vpn_provider *provider,
+							const char *key);
 bool vpn_provider_get_string_immutable(struct vpn_provider *provider,
 							const char *key);
 int vpn_provider_set_boolean(struct vpn_provider *provider, const char *key,
-- 
2.39.5