Bug 1190502 - RESOLVE_DISABLE_IPV4 returns A records r=mcmanus
authorValentin Gosu <valentin.gosu@gmail.com>
Sat, 08 Aug 2015 07:12:02 +0200
changeset 288611 618c213ed8dbc3af0dd20145b999ae877ba97391
parent 288610 78a61d56adaeb9a8beb4583026463f1dc6945197
child 288612 09634f89158fea816b3d20107dd57deeb97ff2b1
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
bugs1190502
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1190502 - RESOLVE_DISABLE_IPV4 returns A records r=mcmanus 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]