Bug 1190502 - RESOLVE_DISABLE_IPV4 returns A records. r=mcmanus, a=ritu
authorValentin Gosu <valentin.gosu@gmail.com>
Mon, 10 Aug 2015 11:22:02 +0200
changeset 288781 d4cbcd9fff58d07dfc454d28cb56f0601ba22031
parent 288780 89bc7fc0d12eb2381a5197f4e67501176b88191b
child 288782 d393cac4e944316a0cb757a4bdac23a971536631
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus, ritu
bugs1190502
milestone42.0a2
Bug 1190502 - RESOLVE_DISABLE_IPV4 returns A records. r=mcmanus, a=ritu nsHostResolver::ThreadFunc should not override addressFamily with PR_AF_UNSPEC for IPv6 since GetAddrInfo.cpp::GetAddrInfo() can handle PR_AF_INET6. _GetAddrInfo_Portable does this before calling PR_GetAddrInfoByName and creates the AddrInfo with a disableIPv4 flag if necessary.
netwerk/dns/nsHostResolver.cpp
netwerk/test/unit/test_dns_disable_ipv4.js
netwerk/test/unit/test_dns_disable_ipv6.js
netwerk/test/unit/xpcshell.ini
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -1398,29 +1398,24 @@ nsHostResolver::ThreadFunc(void *arg)
 
         TimeStamp startTime = TimeStamp::Now();
 #if TTL_AVAILABLE
         bool getTtl = rec->mGetTtl;
 #else
         bool getTtl = false;
 #endif
 
-        // We need to remove IPv4 records manually
-        // because PR_GetAddrInfoByName doesn't support PR_AF_INET6.
-        bool disableIPv4 = rec->af == PR_AF_INET6;
-        uint16_t af = disableIPv4 ? PR_AF_UNSPEC : rec->af;
-        nsresult status = GetAddrInfo(rec->host, af, rec->flags, rec->netInterface,
+        nsresult status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface,
                                       &ai, getTtl);
 #if defined(RES_RETRY_ON_FAILURE)
         if (NS_FAILED(status) && rs.Reset()) {
-            status = GetAddrInfo(rec->host, af, rec->flags, rec->netInterface, &ai,
+            status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface, &ai,
                                  getTtl);
         }
 #endif
-
         TimeDuration elapsed = TimeStamp::Now() - startTime;
         uint32_t millis = static_cast<uint32_t>(elapsed.ToMilliseconds());
 
         if (NS_SUCCEEDED(status)) {
             Telemetry::ID histogramID;
             if (!rec->addr_info_gencnt) {
                 // Time for initial lookup.
                 histogramID = Telemetry::DNS_LOOKUP_TIME;
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit/test_dns_disable_ipv4.js
@@ -0,0 +1,40 @@
+//
+// Tests that calling asyncResolve with the RESOLVE_DISABLE_IPV4 flag doesn't
+// return any IPv4 addresses.
+//
+
+var dns = Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService);
+var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+
+var listener = {
+  onLookupComplete: function(inRequest, inRecord, inStatus) {
+    if (inStatus != Cr.NS_OK) {
+      do_check_eq(inStatus, Cr.NS_ERROR_UNKNOWN_HOST);
+      do_test_finished();
+      return;
+    }
+
+    while (true) {
+      try {
+        var answer = inRecord.getNextAddrAsString();
+        // If there is an answer it should be an IPv6  address
+        dump(answer);
+        do_check_true(answer.indexOf(':') != -1);
+      } catch (e) {
+        break;
+      }
+    }
+    do_test_finished();
+  }
+};
+
+function run_test() {
+  do_test_pending();
+  try {
+    dns.asyncResolve("example.org", Ci.nsIDNSService.RESOLVE_DISABLE_IPV4, listener, null);
+  } catch (e) {
+    dump(e);
+    do_check_true(false);
+    do_test_finished();
+  }
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit/test_dns_disable_ipv6.js
@@ -0,0 +1,41 @@
+//
+// Tests that calling asyncResolve with the RESOLVE_DISABLE_IPV6 flag doesn't
+// return any IPv6 addresses.
+//
+
+var dns = Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService);
+var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+
+var listener = {
+  onLookupComplete: function(inRequest, inRecord, inStatus) {
+    if (inStatus != Cr.NS_OK) {
+      do_check_eq(inStatus, Cr.NS_ERROR_UNKNOWN_HOST);
+      do_test_finished();
+      return;
+    }
+
+    while (true) {
+      try {
+        var answer = inRecord.getNextAddrAsString();
+        // If there is an answer it should be an IPv4  address
+        dump(answer);
+        do_check_true(answer.indexOf(':') == -1);
+        do_check_true(answer.indexOf('.') != -1);
+      } catch (e) {
+        break;
+      }
+    }
+    do_test_finished();
+  }
+};
+
+function run_test() {
+  do_test_pending();
+  try {
+    dns.asyncResolve("example.com", Ci.nsIDNSService.RESOLVE_DISABLE_IPV6, listener, null);
+  } catch (e) {
+    dump(e);
+    do_check_true(false);
+    do_test_finished();
+  }
+}
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -319,8 +319,10 @@ skip-if = os != "win"
 # The local cert service used by this test is not currently shipped on Android
 skip-if = os == "android"
 [test_1073747.js]
 [test_multipart_streamconv_application_package.js]
 [test_safeoutputstream_append.js]
 [test_packaged_app_service.js]
 [test_suspend_channel_before_connect.js]
 [test_inhibit_caching.js]
+[test_dns_disable_ipv4.js]
+[test_dns_disable_ipv6.js]