bug 1443489 - TRR: require a pref set to allow early AAAA responses r?valentin draft
authorDaniel Stenberg <daniel@haxx.se>
Tue, 06 Mar 2018 16:07:29 +0100
changeset 763705 75a8a3a8bd319e27375c173260622245010a7646
parent 763635 a007dd56b9947a93c276e82275d7065db1949c9e
push id101528
push userbmo:daniel@haxx.se
push dateTue, 06 Mar 2018 15:12:40 +0000
reviewersvalentin
bugs1443489
milestone60.0a1
bug 1443489 - TRR: require a pref set to allow early AAAA responses r?valentin Early AAAA responses might cause issues on hosts without working native IPv6 connectivity, of course especially notable in TRR-only mode. MozReview-Commit-ID: 6ZqE6AKnucH
modules/libpref/init/all.js
netwerk/dns/TRRService.cpp
netwerk/dns/TRRService.h
netwerk/dns/nsHostResolver.cpp
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5486,16 +5486,18 @@ pref("network.trr.useGET", false);
 pref("network.trr.confirmationNS", "example.com");
 // hardcode the resolution of the hostname in network.trr.uri instead of
 // relying on the system resolver to do it for you
 pref("network.trr.bootstrapAddress", "");
 // TRR blacklist entry expire time (in seconds). Default is 72 hours.
 pref("network.trr.blacklist-duration", 259200);
 // Single TRR request timeout, in milliseconds
 pref("network.trr.request-timeout", 3000);
+// Allow AAAA entries to be used "early", before the A results are in
+pref("network.trr.early-AAAA", false);
 
 pref("captivedetect.canonicalURL", "http://detectportal.firefox.com/success.txt");
 pref("captivedetect.canonicalContent", "success\n");
 pref("captivedetect.maxWaitingTime", 5000);
 pref("captivedetect.pollingTime", 3000);
 pref("captivedetect.maxRetryCount", 5);
 
 #ifdef RELEASE_OR_BETA
--- a/netwerk/dns/TRRService.cpp
+++ b/netwerk/dns/TRRService.cpp
@@ -183,16 +183,22 @@ TRRService::ReadPrefs(const char *name)
   }
   if (!name || !strcmp(name, TRR_PREF("request-timeout"))) {
     // number of milliseconds
     uint32_t ms;
     if (NS_SUCCEEDED(Preferences::GetUint(TRR_PREF("request-timeout"), &ms))) {
       mTRRTimeout = ms;
     }
   }
+  if (!name || !strcmp(name, TRR_PREF("early-AAAA"))) {
+    bool tmp;
+    if (NS_SUCCEEDED(Preferences::GetBool(TRR_PREF("early-AAAA"), &tmp))) {
+      mEarlyAAAA = tmp;
+    }
+  }
 
   return NS_OK;
 }
 
 nsresult
 TRRService::GetURI(nsCString &result)
 {
   MutexAutoLock lock(mLock);
--- a/netwerk/dns/TRRService.h
+++ b/netwerk/dns/TRRService.h
@@ -29,16 +29,17 @@ public:
   TRRService();
   nsresult Init();
   nsresult Start();
   bool Enabled();
 
   uint32_t Mode() { return mMode; }
   bool AllowRFC1918() { return mRfc1918; }
   bool UseGET() { return mUseGET; }
+  bool EarlyAAAA() { return mEarlyAAAA; }
   nsresult GetURI(nsCString &result);
   nsresult GetCredentials(nsCString &result);
   uint32_t GetRequestTimeout() { return mTRRTimeout; }
 
   LookupStatus CompleteLookup(nsHostRecord *, nsresult, mozilla::net::AddrInfo *, bool pb) override;
   void TRRBlacklist(const nsACString &host, bool privateBrowsing, bool aParentsToo);
   bool IsTRRBlacklisted(const nsACString &host, bool privateBrowsing, bool fullhost);
 
@@ -60,16 +61,17 @@ private:
   nsCString mPrivateCred; // main thread only
   nsCString mConfirmationNS;
   nsCString mBootstrapAddr;
 
   Atomic<bool, Relaxed> mWaitForCaptive; // wait for the captive portal to say OK before using TRR
   Atomic<bool, Relaxed> mRfc1918; // okay with local IP addresses in DOH responses?
   Atomic<bool, Relaxed> mCaptiveIsPassed; // set when captive portal check is passed
   Atomic<bool, Relaxed> mUseGET; // do DOH using GET requests (instead of POST)
+  Atomic<bool, Relaxed> mEarlyAAAA; // allow use of AAAA results before A is in
 
   // TRR Blacklist storage
   RefPtr<DataStorage> mTRRBLStorage;
   Atomic<bool, Relaxed> mClearTRRBLStorage;
 
   enum ConfirmationState {
     CONFIRM_INIT = 0,
     CONFIRM_TRYING = 1,
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -1522,16 +1522,23 @@ nsHostResolver::CompleteLookup(nsHostRec
             MOZ_ASSERT(!rec->mFirstTRR && newRRSet);
             rec->mFirstTRR = newRRSet; // autoPtr.swap()
             MOZ_ASSERT(rec->mFirstTRR && !newRRSet);
 
             if (rec->mDidCallbacks || rec->mResolverMode == MODE_SHADOW) {
                 return LOOKUP_OK;
             }
 
+            if (rec->mTrrA && (!gTRRService || !gTRRService->EarlyAAAA())) {
+                // This is an early AAAA with a pending A response. Allowed
+                // only by pref.
+                LOG(("CompleteLookup: avoiding early use of TRR AAAA!\n"));
+                return LOOKUP_OK;
+            }
+
             // we can do some callbacks with this partial result which requires
             // a deep copy
             newRRSet = new AddrInfo(rec->mFirstTRR);
             MOZ_ASSERT(rec->mFirstTRR && newRRSet);
 
         } else {
             // no more outstanding TRRs
             // If mFirstTRR is set, merge those addresses into current set!