[BCL,Android] Get DNS server addresses from Android
authorMarek Habersack <grendel@twistedcode.net>
Wed, 11 Jan 2017 10:34:47 +0000 (11:34 +0100)
committerMarek Habersack <grendel@twistedcode.net>
Thu, 12 Jan 2017 11:45:36 +0000 (12:45 +0100)
This change implements retrieving a list of DNS server addresses from Android
instead of attempting to parse `/etc/resolv.conf` which doesn't exist on
Android.
The list is retrieved by calling native function in Xamarin.Android that gets
the data from the system.

Part 2 of fix for https://bugzilla.xamarin.com/show_bug.cgi?id=48016

mcs/class/System/System.Net.NetworkInformation/IPInterfaceProperties.cs

index af9fbec33bef62230039b5cefe5983203eb9ca64..94d4292a4740128a18f5a46658cc88226b685c3e 100644 (file)
@@ -54,7 +54,33 @@ namespace System.Net.NetworkInformation {
                {
                        throw new NotImplementedException ();
                }
+#if MONODROID
+               [DllImport ("__Internal")]
+               static extern int _monodroid_get_dns_servers (out IntPtr dns_servers_array);
 
+               void GetDNSServersFromOS ()
+               {
+                       IntPtr dsa;
+                       int len = _monodroid_get_dns_servers (out dsa);
+                       if (len <= 0)
+                               return;
+
+                       var servers = new IntPtr [len];
+                       Marshal.Copy (dsa, servers, 0, len);
+
+                       dns_servers = new IPAddressCollection ();
+                       foreach (IntPtr s in servers) {
+                               string server_ip = Marshal.PtrToStringAnsi (s);
+                               Marshal.FreeHGlobal (s);
+
+                               IPAddress addr;
+                               if (!IPAddress.TryParse (server_ip, out addr))
+                                       continue;
+                               dns_servers.InternalAdd (addr);
+                       }
+                       Marshal.FreeHGlobal (dsa);
+               }
+#else
                static Regex ns = new Regex (@"\s*nameserver\s+(?<address>.*)");
                static Regex search = new Regex (@"\s*search\s+(?<domain>.*)");
                void ParseResolvConf ()
@@ -95,7 +121,7 @@ namespace System.Net.NetworkInformation {
                        } catch {
                        }
                }
-
+#endif
                public override IPAddressInformationCollection AnycastAddresses {
                        get {
                                var c = new IPAddressInformationCollection ();
@@ -119,15 +145,23 @@ namespace System.Net.NetworkInformation {
 
                public override IPAddressCollection DnsAddresses {
                        get {
+#if MONODROID
+                               GetDNSServersFromOS ();
+#else
                                ParseResolvConf ();
+#endif
                                return dns_servers;
                        }
                }
 
                public override string DnsSuffix {
                        get {
+#if MONODROID
+                               return String.Empty;
+#else
                                ParseResolvConf ();
                                return dns_suffix;
+#endif
                        }
                }