Description: Add support for IPv6 DNS servers and domains

This detects IPv6 addresses in th DNS field, parse them and sets the DNS
property for the IPv6 connection.

If IPv6 DNS servers are provided, the DNS domains are also passed for
the IPv6 connection.

Origin: vendor
Author: Stéphane Graber <stgraber@ubuntu.com>

Index: network-manager-openvpn-0.9.8.2/src/nm-openvpn-service-openvpn-helper.c
===================================================================
--- network-manager-openvpn-0.9.8.2.orig/src/nm-openvpn-service-openvpn-helper.c	2014-03-06 12:47:41.000000000 -0500
+++ network-manager-openvpn-0.9.8.2/src/nm-openvpn-service-openvpn-helper.c	2014-03-06 14:36:20.277425406 -0500
@@ -263,6 +263,46 @@
 	return val;
 }
 
+static GValue *
+parse_addr6_list (GValue *value_array, const char *str)
+{
+	char **split;
+	int i;
+	struct in6_addr temp_addr;
+	GPtrArray *array;
+	GByteArray *ba;
+
+	/* Empty */
+	if (!str || strlen (str) < 1)
+		return value_array;
+
+	if (value_array)
+		array = (GPtrArray *) g_value_get_boxed (value_array);
+	else
+		array = g_ptr_array_new();
+
+	split = g_strsplit (str, " ", -1);
+	for (i = 0; split[i]; i++) {
+		if (inet_pton (AF_INET6, split[i], &temp_addr) > 0) {
+			ba = g_byte_array_new ();
+			g_byte_array_append (ba, (guint8 *) &temp_addr, sizeof (temp_addr));
+			g_ptr_array_add (array, ba);
+		}
+	}
+
+	g_strfreev (split);
+
+	if (!value_array && array->len > 0) {
+		value_array = g_slice_new0 (GValue);
+		g_value_init (value_array, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT);
+		g_value_set_boxed (value_array, array);
+	}
+	if (!value_array)
+		g_ptr_array_free (array, TRUE);
+
+	return value_array;
+}
+
 static inline gboolean
 is_domain_valid (const char *str)
 {
@@ -530,6 +570,7 @@
 	int i;
 	GError *err = NULL;
 	GValue *dns_list = NULL;
+	GValue *dns6_list = NULL;
 	GValue *nbns_list = NULL;
 	GPtrArray *dns_domains = NULL;
 	struct in_addr temp_addr;
@@ -699,8 +740,12 @@
 
 		tmp += 12; /* strlen ("dhcp-option ") */
 
-		if (g_str_has_prefix (tmp, "DNS "))
-			dns_list = parse_addr4_list (dns_list, tmp + 4);
+		if (g_str_has_prefix (tmp, "DNS ")) {
+			if (strstr(tmp + 4, ":"))
+				dns6_list = parse_addr6_list (dns6_list, tmp + 4);
+			else
+				dns_list = parse_addr4_list (dns_list, tmp + 4);
+		}
 		else if (g_str_has_prefix (tmp, "WINS "))
 			nbns_list = parse_addr4_list (nbns_list, tmp + 5);
 		else if (g_str_has_prefix (tmp, "DOMAIN ") && is_domain_valid (tmp + 7))
@@ -709,13 +754,18 @@
 
 	if (dns_list)
 		g_hash_table_insert (ip4config, NM_VPN_PLUGIN_IP4_CONFIG_DNS, dns_list);
+	if (dns6_list)
+		g_hash_table_insert (ip6config, NM_VPN_PLUGIN_IP6_CONFIG_DNS, dns6_list);
 	if (nbns_list)
 		g_hash_table_insert (ip4config, NM_VPN_PLUGIN_IP4_CONFIG_NBNS, nbns_list);
 	if (dns_domains->len) {
 		val = g_slice_new0 (GValue);
 		g_value_init (val, DBUS_TYPE_G_PTR_ARRAY_OF_STRING);
 		g_value_take_boxed (val, dns_domains);
-		g_hash_table_insert (ip4config, NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS, val);
+		if (dns_list)
+			g_hash_table_insert (ip4config, NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS, val);
+		if (dns6_list)
+			g_hash_table_insert (ip6config, NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS, val);
 	} else
 		g_ptr_array_free (dns_domains, TRUE);
 
