bug 1441391 - TRR: restart failed NS confirms in TRR-only mode r?valentin
MozReview-Commit-ID: FHw3Zx07iFG
--- a/netwerk/dns/TRR.cpp
+++ b/netwerk/dns/TRR.cpp
@@ -41,17 +41,16 @@ extern mozilla::LazyLogModule gHostResol
NS_IMPL_ISUPPORTS(TRR, nsIHttpPushListener, nsIInterfaceRequestor, nsIStreamListener, nsIRunnable)
const uint8_t kDNS_CLASS_IN = 1;
NS_IMETHODIMP
TRR::Notify(nsITimer *aTimer)
{
if (aTimer == mTimeout) {
- LOG(("TRR request for %s timed out\n", mHost.get()));
mTimeout = nullptr;
Cancel();
} else {
MOZ_CRASH("Unknown timer");
}
return NS_OK;
}
--- a/netwerk/dns/TRRService.cpp
+++ b/netwerk/dns/TRRService.cpp
@@ -39,16 +39,17 @@ TRRService::TRRService()
, mLock("trrservice")
, mConfirmationNS(NS_LITERAL_CSTRING("example.com"))
, mWaitForCaptive(true)
, mRfc1918(false)
, mCaptiveIsPassed(false)
, mUseGET(false)
, mClearTRRBLStorage(false)
, mConfirmationState(CONFIRM_INIT)
+ , mRetryConfirmInterval(1000)
{
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
}
nsresult
TRRService::Init()
{
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
@@ -78,23 +79,29 @@ TRRService::Init()
LOG(("Initialized TRRService\n"));
return NS_OK;
}
bool
TRRService::Enabled()
{
if (mConfirmationState == CONFIRM_INIT && !mWaitForCaptive) {
+ LOG(("TRRService::Enabled => CONFIRM_TRYING\n"));
mConfirmationState = CONFIRM_TRYING;
}
if (mConfirmationState == CONFIRM_TRYING) {
+ LOG(("TRRService::Enabled MaybeConfirm()\n"));
MaybeConfirm();
}
+ if (mConfirmationState != CONFIRM_OK) {
+ LOG(("TRRService::Enabled mConfirmationState=%d\n", (int)mConfirmationState));
+ }
+
return (mConfirmationState == CONFIRM_OK);
}
void
TRRService::GetPrefBranch(nsIPrefBranch **result)
{
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
*result = nullptr;
@@ -285,16 +292,18 @@ TRRService::Observe(nsISupports *aSubjec
return NS_OK;
}
void
TRRService::MaybeConfirm()
{
if ((mMode == MODE_NATIVEONLY) || mConfirmer ||
mConfirmationState != CONFIRM_TRYING) {
+ LOG(("TRRService:MaybeConfirm mode=%d, mConfirmer=%p mConfirmationState=%d\n",
+ (int)mMode, (void *)mConfirmer, (int)mConfirmationState));
return;
}
nsAutoCString host;
{
MutexAutoLock lock(mLock);
host = mConfirmationNS;
}
if (host.Equals("skip")) {
@@ -473,16 +482,34 @@ TRRService::TRRBlacklist(const nsACStrin
// check if there's an NS entry for this name
RefPtr<TRR> trr = new TRR(this, check, TRRTYPE_NS, privateBrowsing);
NS_DispatchToMainThread(trr);
}
}
}
+NS_IMETHODIMP
+TRRService::Notify(nsITimer *aTimer)
+{
+ if (aTimer == mRetryConfirmTimer) {
+ mRetryConfirmTimer = nullptr;
+ if (mConfirmationState == CONFIRM_FAILED) {
+ LOG(("TRRService retry NS of %s\n", mConfirmationNS.get()));
+ mConfirmationState = CONFIRM_TRYING;
+ MaybeConfirm();
+ }
+ } else {
+ MOZ_CRASH("Unknown timer");
+ }
+
+ return NS_OK;
+}
+
+
AHostResolver::LookupStatus
TRRService::CompleteLookup(nsHostRecord *rec, nsresult status, AddrInfo *aNewRRSet, bool pb)
{
// this is an NS check for the TRR blacklist or confirmationNS check
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!rec);
@@ -491,16 +518,28 @@ TRRService::CompleteLookup(nsHostRecord
MOZ_ASSERT(!mConfirmer || (mConfirmationState == CONFIRM_TRYING));
if (mConfirmationState == CONFIRM_TRYING) {
MOZ_ASSERT(mConfirmer);
mConfirmationState = NS_SUCCEEDED(status) ? CONFIRM_OK : CONFIRM_FAILED;
LOG(("TRRService finishing confirmation test %s %d %X\n",
mPrivateURI.get(), (int)mConfirmationState, (unsigned int)status));
mConfirmer = nullptr;
+ if ((mConfirmationState == CONFIRM_FAILED) && (mMode == MODE_TRRONLY)) {
+ // in TRR-only mode; retry failed confirmations
+ NS_NewTimerWithCallback(getter_AddRefs(mRetryConfirmTimer),
+ this, mRetryConfirmInterval,
+ nsITimer::TYPE_ONE_SHOT);
+ if (mRetryConfirmInterval < 64000) {
+ // double the interval up to this point
+ mRetryConfirmInterval *= 2;
+ }
+ } else {
+ mRetryConfirmInterval = 1000;
+ }
return LOOKUP_OK;
}
// when called without a host record, this is a domain name check response.
if (NS_SUCCEEDED(status)) {
LOG(("TRR verified %s to be fine!\n", newRRSet->mHostName));
} else {
LOG(("TRR says %s doesn't resove as NS!\n", newRRSet->mHostName));
--- a/netwerk/dns/TRRService.h
+++ b/netwerk/dns/TRRService.h
@@ -14,22 +14,24 @@
class nsIPrefBranch;
namespace mozilla {
namespace net {
class TRRService
: public nsIObserver
+ , public nsITimerCallback
, public nsSupportsWeakReference
, public AHostResolver
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
+ NS_DECL_NSITIMERCALLBACK
TRRService();
nsresult Init();
nsresult Start();
bool Enabled();
uint32_t Mode() { return mMode; }
bool AllowRFC1918() { return mRfc1918; }
@@ -74,17 +76,19 @@ private:
enum ConfirmationState {
CONFIRM_INIT = 0,
CONFIRM_TRYING = 1,
CONFIRM_OK = 2,
CONFIRM_FAILED = 3
};
Atomic<ConfirmationState, Relaxed> mConfirmationState;
- RefPtr<TRR> mConfirmer;
+ RefPtr<TRR> mConfirmer;
+ nsCOMPtr<nsITimer> mRetryConfirmTimer;
+ uint32_t mRetryConfirmInterval; // milliseconds until retry
};
extern TRRService *gTRRService;
} // namespace net
} // namespace mozilla
#endif // TRRService_h_