| File: | root/firefox-clang/obj-x86_64-pc-linux-gnu/netwerk/dns/./../../../netwerk/dns/TRR.cpp |
| Warning: | line 265, column 5 Value stored to 'rv' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | |
| 5 | #include "TRR.h" |
| 6 | |
| 7 | #include "DNS.h" |
| 8 | #include "DNSUtils.h" |
| 9 | #include "ObliviousHttpChannel.h" |
| 10 | #include "TRRLoadInfo.h" |
| 11 | #include "TRRService.h" |
| 12 | #include "TRRServiceChannel.h" |
| 13 | #include "mozilla/Base64.h" |
| 14 | #include "mozilla/Logging.h" |
| 15 | #include "mozilla/Maybe.h" |
| 16 | #include "mozilla/Preferences.h" |
| 17 | #include "mozilla/StaticPrefs_network.h" |
| 18 | #include "mozilla/TimeStamp.h" |
| 19 | #include "mozilla/Tokenizer.h" |
| 20 | #include "mozilla/UniquePtr.h" |
| 21 | #include "mozilla/glean/NetwerkDnsMetrics.h" |
| 22 | #include "nsCharSeparatedTokenizer.h" |
| 23 | #include "nsContentUtils.h" |
| 24 | #include "nsHostResolver.h" |
| 25 | #include "nsHttpChannel.h" |
| 26 | #include "nsHttpHandler.h" |
| 27 | #include "nsIHttpChannel.h" |
| 28 | #include "nsIHttpChannelInternal.h" |
| 29 | #include "nsIIOService.h" |
| 30 | #include "nsIInputStream.h" |
| 31 | #include "nsIOService.h" |
| 32 | #include "nsIObliviousHttp.h" |
| 33 | #include "nsISupports.h" |
| 34 | #include "nsISupportsUtils.h" |
| 35 | #include "nsITimedChannel.h" |
| 36 | #include "nsIURIMutator.h" |
| 37 | #include "nsIUploadChannel2.h" |
| 38 | #include "nsNetUtil.h" |
| 39 | #include "nsQueryObject.h" |
| 40 | #include "nsStringStream.h" |
| 41 | #include "nsThreadUtils.h" |
| 42 | #include "nsURLHelper.h" |
| 43 | // Put DNSLogging.h at the end to avoid LOG being overwritten by other headers. |
| 44 | #include "DNSLogging.h" |
| 45 | #include "mozilla/glean/NetwerkMetrics.h" |
| 46 | |
| 47 | namespace mozilla { |
| 48 | namespace net { |
| 49 | |
| 50 | NS_IMPL_ISUPPORTS_INHERITED(TRR, Runnable, nsIStreamListener, nsITimerCallback,nsresult TRR::QueryInterface(const nsIID& aIID, void** aInstancePtr ) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION , "QueryInterface requires a non-NULL destination!", "aInstancePtr" , "./../../../netwerk/dns/TRR.cpp", 51); MOZ_PretendNoReturn( ); } } while (0); nsresult rv = NS_ERROR_FAILURE; static_assert (3 > 0, "Need more arguments to NS_INTERFACE_TABLE_INHERITED" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<TRR, nsIStreamListener>, int32_t( reinterpret_cast <char*>(static_cast<nsIStreamListener*>((TRR*)0x1000 )) - reinterpret_cast<char*>((TRR*)0x1000))}, {&mozilla ::detail::kImplementedIID<TRR, nsITimerCallback>, int32_t ( reinterpret_cast<char*>(static_cast<nsITimerCallback *>((TRR*)0x1000)) - reinterpret_cast<char*>((TRR*)0x1000 ))}, {&mozilla::detail::kImplementedIID<TRR, nsIRunnablePriority >, int32_t( reinterpret_cast<char*>(static_cast<nsIRunnablePriority *>((TRR*)0x1000)) - reinterpret_cast<char*>((TRR*)0x1000 ))}, { nullptr, 0 } } ; static_assert(std::size(table) > 1 , "need at least 1 interface"); rv = NS_TableDrivenQI(static_cast <void*>(this), aIID, aInstancePtr, table); if (((bool)( __builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) return rv; return Runnable::QueryInterface(aIID, aInstancePtr); } MozExternalRefCountType TRR::AddRef(void) { static_assert(!std::is_destructible_v< TRR>, "Reference-counted class " "TRR" " should not have a public destructor. " "Make this class's destructor non-public"); nsrefcnt r = Runnable ::AddRef(); if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt <TRR>) { NS_LogAddRef((this), (r), ("TRR"), (uint32_t)( sizeof(*this))); } return r; } MozExternalRefCountType TRR::Release (void) { nsrefcnt r = Runnable::Release(); if constexpr (::mozilla ::detail::ShouldLogInheritedRefcnt<TRR>) { NS_LogRelease ((this), (r), ("TRR")); } return r; } |
| 51 | nsIRunnablePriority)nsresult TRR::QueryInterface(const nsIID& aIID, void** aInstancePtr ) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION , "QueryInterface requires a non-NULL destination!", "aInstancePtr" , "./../../../netwerk/dns/TRR.cpp", 51); MOZ_PretendNoReturn( ); } } while (0); nsresult rv = NS_ERROR_FAILURE; static_assert (3 > 0, "Need more arguments to NS_INTERFACE_TABLE_INHERITED" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<TRR, nsIStreamListener>, int32_t( reinterpret_cast <char*>(static_cast<nsIStreamListener*>((TRR*)0x1000 )) - reinterpret_cast<char*>((TRR*)0x1000))}, {&mozilla ::detail::kImplementedIID<TRR, nsITimerCallback>, int32_t ( reinterpret_cast<char*>(static_cast<nsITimerCallback *>((TRR*)0x1000)) - reinterpret_cast<char*>((TRR*)0x1000 ))}, {&mozilla::detail::kImplementedIID<TRR, nsIRunnablePriority >, int32_t( reinterpret_cast<char*>(static_cast<nsIRunnablePriority *>((TRR*)0x1000)) - reinterpret_cast<char*>((TRR*)0x1000 ))}, { nullptr, 0 } } ; static_assert(std::size(table) > 1 , "need at least 1 interface"); rv = NS_TableDrivenQI(static_cast <void*>(this), aIID, aInstancePtr, table); if (((bool)( __builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) return rv; return Runnable::QueryInterface(aIID, aInstancePtr); } MozExternalRefCountType TRR::AddRef(void) { static_assert(!std::is_destructible_v< TRR>, "Reference-counted class " "TRR" " should not have a public destructor. " "Make this class's destructor non-public"); nsrefcnt r = Runnable ::AddRef(); if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt <TRR>) { NS_LogAddRef((this), (r), ("TRR"), (uint32_t)( sizeof(*this))); } return r; } MozExternalRefCountType TRR::Release (void) { nsrefcnt r = Runnable::Release(); if constexpr (::mozilla ::detail::ShouldLogInheritedRefcnt<TRR>) { NS_LogRelease ((this), (r), ("TRR")); } return r; } |
| 52 | |
| 53 | NS_IMETHODIMPnsresult |
| 54 | TRR::GetPriority(uint32_t* aPriority) { |
| 55 | if (StaticPrefs::network_trr_high_priority_events()) { |
| 56 | *aPriority = nsIRunnablePriority::PRIORITY_MEDIUMHIGH; |
| 57 | } else { |
| 58 | *aPriority = nsIRunnablePriority::PRIORITY_NORMAL; |
| 59 | } |
| 60 | return NS_OK; |
| 61 | } |
| 62 | |
| 63 | // when firing off a normal A or AAAA query |
| 64 | TRR::TRR(AHostResolver* aResolver, nsHostRecord* aRec, enum TrrType aType) |
| 65 | : mozilla::Runnable("TRR"), |
| 66 | mRec(aRec), |
| 67 | mHostResolver(aResolver), |
| 68 | mType(aType), |
| 69 | mOriginSuffix(aRec->originSuffix) { |
| 70 | mHost = aRec->host; |
| 71 | mPB = aRec->pb; |
| 72 | MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(),do { static_assert( mozilla::detail::AssertionConditionType< decltype(XRE_IsParentProcess() || XRE_IsSocketProcess())>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(XRE_IsParentProcess() || XRE_IsSocketProcess()))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess() || XRE_IsSocketProcess()" " (" "TRR must be in parent or socket process" ")", "./../../../netwerk/dns/TRR.cpp" , 73); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()" ") (" "TRR must be in parent or socket process" ")"); do { MOZ_CrashSequence (__null, 73); __attribute__((nomerge)) ::abort(); } while (false ); } } while (false) |
| 73 | "TRR must be in parent or socket process")do { static_assert( mozilla::detail::AssertionConditionType< decltype(XRE_IsParentProcess() || XRE_IsSocketProcess())>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(XRE_IsParentProcess() || XRE_IsSocketProcess()))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess() || XRE_IsSocketProcess()" " (" "TRR must be in parent or socket process" ")", "./../../../netwerk/dns/TRR.cpp" , 73); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()" ") (" "TRR must be in parent or socket process" ")"); do { MOZ_CrashSequence (__null, 73); __attribute__((nomerge)) ::abort(); } while (false ); } } while (false); |
| 74 | } |
| 75 | |
| 76 | // when following CNAMEs |
| 77 | TRR::TRR(AHostResolver* aResolver, nsHostRecord* aRec, nsCString& aHost, |
| 78 | enum TrrType& aType, unsigned int aLoopCount, bool aPB) |
| 79 | : mozilla::Runnable("TRR"), |
| 80 | mHost(aHost), |
| 81 | mRec(aRec), |
| 82 | mHostResolver(aResolver), |
| 83 | mType(aType), |
| 84 | mPB(aPB), |
| 85 | mCnameLoop(aLoopCount), |
| 86 | mOriginSuffix(aRec ? aRec->originSuffix : ""_ns) { |
| 87 | MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(),do { static_assert( mozilla::detail::AssertionConditionType< decltype(XRE_IsParentProcess() || XRE_IsSocketProcess())>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(XRE_IsParentProcess() || XRE_IsSocketProcess()))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess() || XRE_IsSocketProcess()" " (" "TRR must be in parent or socket process" ")", "./../../../netwerk/dns/TRR.cpp" , 88); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()" ") (" "TRR must be in parent or socket process" ")"); do { MOZ_CrashSequence (__null, 88); __attribute__((nomerge)) ::abort(); } while (false ); } } while (false) |
| 88 | "TRR must be in parent or socket process")do { static_assert( mozilla::detail::AssertionConditionType< decltype(XRE_IsParentProcess() || XRE_IsSocketProcess())>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(XRE_IsParentProcess() || XRE_IsSocketProcess()))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess() || XRE_IsSocketProcess()" " (" "TRR must be in parent or socket process" ")", "./../../../netwerk/dns/TRR.cpp" , 88); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()" ") (" "TRR must be in parent or socket process" ")"); do { MOZ_CrashSequence (__null, 88); __attribute__((nomerge)) ::abort(); } while (false ); } } while (false); |
| 89 | } |
| 90 | |
| 91 | // to verify a domain |
| 92 | TRR::TRR(AHostResolver* aResolver, nsACString& aHost, enum TrrType aType, |
| 93 | const nsACString& aOriginSuffix, bool aPB, bool aUseFreshConnection) |
| 94 | : mozilla::Runnable("TRR"), |
| 95 | mHost(aHost), |
| 96 | mRec(nullptr), |
| 97 | mHostResolver(aResolver), |
| 98 | mType(aType), |
| 99 | mPB(aPB), |
| 100 | mOriginSuffix(aOriginSuffix), |
| 101 | mUseFreshConnection(aUseFreshConnection) { |
| 102 | MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(),do { static_assert( mozilla::detail::AssertionConditionType< decltype(XRE_IsParentProcess() || XRE_IsSocketProcess())>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(XRE_IsParentProcess() || XRE_IsSocketProcess()))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess() || XRE_IsSocketProcess()" " (" "TRR must be in parent or socket process" ")", "./../../../netwerk/dns/TRR.cpp" , 103); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()" ") (" "TRR must be in parent or socket process" ")"); do { MOZ_CrashSequence (__null, 103); __attribute__((nomerge)) ::abort(); } while (false ); } } while (false) |
| 103 | "TRR must be in parent or socket process")do { static_assert( mozilla::detail::AssertionConditionType< decltype(XRE_IsParentProcess() || XRE_IsSocketProcess())>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(XRE_IsParentProcess() || XRE_IsSocketProcess()))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess() || XRE_IsSocketProcess()" " (" "TRR must be in parent or socket process" ")", "./../../../netwerk/dns/TRR.cpp" , 103); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()" ") (" "TRR must be in parent or socket process" ")"); do { MOZ_CrashSequence (__null, 103); __attribute__((nomerge)) ::abort(); } while (false ); } } while (false); |
| 104 | } |
| 105 | |
| 106 | void TRR::HandleTimeout() { |
| 107 | mTimeout = nullptr; |
| 108 | RecordReason(TRRSkippedReason::TRR_TIMEOUT); |
| 109 | Cancel(NS_ERROR_NET_TIMEOUT_EXTERNAL); |
| 110 | } |
| 111 | |
| 112 | NS_IMETHODIMPnsresult |
| 113 | TRR::Notify(nsITimer* aTimer) { |
| 114 | if (aTimer == mTimeout) { |
| 115 | HandleTimeout(); |
| 116 | } else { |
| 117 | MOZ_CRASH("Unknown timer")do { do { } while (false); MOZ_ReportCrash("" "Unknown timer" , "./../../../netwerk/dns/TRR.cpp", 117); AnnotateMozCrashReason ("MOZ_CRASH(" "Unknown timer" ")"); do { MOZ_CrashSequence(__null , 117); __attribute__((nomerge)) ::abort(); } while (false); } while (false); |
| 118 | } |
| 119 | |
| 120 | return NS_OK; |
| 121 | } |
| 122 | |
| 123 | NS_IMETHODIMPnsresult |
| 124 | TRR::Run() { |
| 125 | MOZ_ASSERT_IF(XRE_IsParentProcess() && TRRService::Get(),do { if (XRE_IsParentProcess() && TRRService::Get()) { do { static_assert( mozilla::detail::AssertionConditionType< decltype(NS_IsMainThread() || TRRService::Get()->IsOnTRRThread ())>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(NS_IsMainThread() || TRRService::Get()->IsOnTRRThread ()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("NS_IsMainThread() || TRRService::Get()->IsOnTRRThread()" , "./../../../netwerk/dns/TRR.cpp", 126); AnnotateMozCrashReason ("MOZ_ASSERT" "(" "NS_IsMainThread() || TRRService::Get()->IsOnTRRThread()" ")"); do { MOZ_CrashSequence(__null, 126); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false) |
| 126 | NS_IsMainThread() || TRRService::Get()->IsOnTRRThread())do { if (XRE_IsParentProcess() && TRRService::Get()) { do { static_assert( mozilla::detail::AssertionConditionType< decltype(NS_IsMainThread() || TRRService::Get()->IsOnTRRThread ())>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(NS_IsMainThread() || TRRService::Get()->IsOnTRRThread ()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("NS_IsMainThread() || TRRService::Get()->IsOnTRRThread()" , "./../../../netwerk/dns/TRR.cpp", 126); AnnotateMozCrashReason ("MOZ_ASSERT" "(" "NS_IsMainThread() || TRRService::Get()->IsOnTRRThread()" ")"); do { MOZ_CrashSequence(__null, 126); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); |
| 127 | MOZ_ASSERT_IF(XRE_IsSocketProcess(), NS_IsMainThread())do { if (XRE_IsSocketProcess()) { do { static_assert( mozilla ::detail::AssertionConditionType<decltype(NS_IsMainThread( ))>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(NS_IsMainThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("NS_IsMainThread()", "./../../../netwerk/dns/TRR.cpp", 127); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ")" ); do { MOZ_CrashSequence(__null, 127); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); |
| 128 | |
| 129 | if ((TRRService::Get() == nullptr) || NS_FAILED(SendHTTPRequest())((bool)(__builtin_expect(!!(NS_FAILED_impl(SendHTTPRequest()) ), 0)))) { |
| 130 | RecordReason(TRRSkippedReason::TRR_SEND_FAILED); |
| 131 | FailData(NS_ERROR_FAILURE); |
| 132 | // The dtor will now be run |
| 133 | } |
| 134 | return NS_OK; |
| 135 | } |
| 136 | |
| 137 | DNSPacket* TRR::GetOrCreateDNSPacket() { |
| 138 | if (!mPacket) { |
| 139 | mPacket = MakeUnique<DNSPacket>(); |
| 140 | } |
| 141 | |
| 142 | return mPacket.get(); |
| 143 | } |
| 144 | |
| 145 | nsresult TRR::CreateQueryURI(nsIURI** aOutURI) { |
| 146 | nsAutoCString uri; |
| 147 | nsCOMPtr<nsIURI> dnsURI; |
| 148 | if (UseDefaultServer()) { |
| 149 | TRRService::Get()->GetURI(uri); |
| 150 | } else { |
| 151 | uri = mRec->mTrrServer; |
| 152 | } |
| 153 | |
| 154 | nsresult rv = NS_NewURI(getter_AddRefs(dnsURI), uri); |
| 155 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 156 | RecordReason(TRRSkippedReason::TRR_BAD_URL); |
| 157 | return rv; |
| 158 | } |
| 159 | |
| 160 | dnsURI.forget(aOutURI); |
| 161 | return NS_OK; |
| 162 | } |
| 163 | |
| 164 | bool TRR::MaybeBlockRequest() { |
| 165 | if (((mType == TRRTYPE_A) || (mType == TRRTYPE_AAAA)) && |
| 166 | mRec->mEffectiveTRRMode != nsIRequest::TRR_ONLY_MODE) { |
| 167 | // let NS resolves skip the blocklist check |
| 168 | // we also don't check the blocklist for TRR only requests |
| 169 | MOZ_ASSERT(mRec)do { static_assert( mozilla::detail::AssertionConditionType< decltype(mRec)>::isValid, "invalid assertion condition"); if ((__builtin_expect(!!(!(!!(mRec))), 0))) { do { } while (false ); MOZ_ReportAssertionFailure("mRec", "./../../../netwerk/dns/TRR.cpp" , 169); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRec" ")"); do { MOZ_CrashSequence(__null, 169); __attribute__((nomerge)) :: abort(); } while (false); } } while (false); |
| 170 | |
| 171 | // If TRRService isn't enabled anymore for the req, don't do TRR. |
| 172 | if (!TRRService::Get()->Enabled(mRec->mEffectiveTRRMode)) { |
| 173 | RecordReason(TRRSkippedReason::TRR_MODE_NOT_ENABLED); |
| 174 | return true; |
| 175 | } |
| 176 | |
| 177 | if (!StaticPrefs::network_trr_strict_native_fallback() && |
| 178 | UseDefaultServer() && |
| 179 | TRRService::Get()->IsTemporarilyBlocked(mHost, mOriginSuffix, mPB, |
| 180 | true)) { |
| 181 | if (mType == TRRTYPE_A) { |
| 182 | // count only blocklist for A records to avoid double counts |
| 183 | glean::dns::trr_blacklisted.Get(TRRService::ProviderKey(), "true"_ns) |
| 184 | .Add(); |
| 185 | } |
| 186 | |
| 187 | RecordReason(TRRSkippedReason::TRR_HOST_BLOCKED_TEMPORARY); |
| 188 | // not really an error but no TRR is issued |
| 189 | return true; |
| 190 | } |
| 191 | |
| 192 | if (TRRService::Get()->IsExcludedFromTRR(mHost, mRec->mEffectiveTRRMode)) { |
| 193 | RecordReason(TRRSkippedReason::TRR_EXCLUDED); |
| 194 | return true; |
| 195 | } |
| 196 | |
| 197 | if (UseDefaultServer() && (mType == TRRTYPE_A)) { |
| 198 | glean::dns::trr_blacklisted.Get(TRRService::ProviderKey(), "false"_ns) |
| 199 | .Add(); |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | return false; |
| 204 | } |
| 205 | |
| 206 | nsresult TRR::SendHTTPRequest() { |
| 207 | // This is essentially the "run" method - created from nsHostResolver |
| 208 | if (mCancelled) { |
| 209 | return NS_ERROR_FAILURE; |
| 210 | } |
| 211 | |
| 212 | if ((mType != TRRTYPE_A) && (mType != TRRTYPE_AAAA) && |
| 213 | (mType != TRRTYPE_NS) && (mType != TRRTYPE_TXT) && |
| 214 | (mType != TRRTYPE_HTTPSSVC)) { |
| 215 | // limit the calling interface because nsHostResolver has explicit slots for |
| 216 | // these types |
| 217 | return NS_ERROR_FAILURE; |
| 218 | } |
| 219 | |
| 220 | if (MaybeBlockRequest()) { |
| 221 | return NS_ERROR_UNKNOWN_HOST; |
| 222 | } |
| 223 | |
| 224 | LOG(("TRR::SendHTTPRequest resolve %s type %u\n", mHost.get(), mType))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::SendHTTPRequest resolve %s type %u\n", mHost.get(), mType ); } } while (0); |
| 225 | |
| 226 | nsAutoCString body; |
| 227 | bool disableECS = StaticPrefs::network_trr_disable_ECS(); |
| 228 | nsresult rv = |
| 229 | GetOrCreateDNSPacket()->EncodeRequest(body, mHost, mType, disableECS); |
| 230 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 231 | HandleEncodeError(rv); |
| 232 | return rv; |
| 233 | } |
| 234 | |
| 235 | bool useGet = StaticPrefs::network_trr_useGET(); |
| 236 | nsCOMPtr<nsIURI> dnsURI; |
| 237 | rv = CreateQueryURI(getter_AddRefs(dnsURI)); |
| 238 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 239 | LOG(("TRR:SendHTTPRequest: NewURI failed!\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:SendHTTPRequest: NewURI failed!\n"); } } while (0); |
| 240 | return rv; |
| 241 | } |
| 242 | |
| 243 | if (useGet) { |
| 244 | /* For GET requests, the outgoing packet needs to be Base64url-encoded and |
| 245 | then appended to the end of the URI. */ |
| 246 | nsAutoCString encoded; |
| 247 | rv = Base64URLEncode(body.Length(), |
| 248 | reinterpret_cast<const unsigned char*>(body.get()), |
| 249 | Base64URLEncodePaddingPolicy::Omit, encoded); |
| 250 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 250); return rv; } } while (false); |
| 251 | |
| 252 | nsAutoCString query; |
| 253 | rv = dnsURI->GetQuery(query); |
| 254 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 255 | return rv; |
| 256 | } |
| 257 | |
| 258 | if (query.IsEmpty()) { |
| 259 | query.Assign("?dns="_ns); |
| 260 | } else { |
| 261 | query.Append("&dns="_ns); |
| 262 | } |
| 263 | query.Append(encoded); |
| 264 | |
| 265 | rv = NS_MutateURI(dnsURI).SetQuery(query).Finalize(dnsURI); |
Value stored to 'rv' is never read | |
| 266 | LOG(("TRR::SendHTTPRequest GET dns=%s\n", body.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::SendHTTPRequest GET dns=%s\n", body.get()); } } while (0); |
| 267 | } |
| 268 | |
| 269 | nsCOMPtr<nsIChannel> channel; |
| 270 | bool useOHTTP = StaticPrefs::network_trr_use_ohttp(); |
| 271 | if (useOHTTP) { |
| 272 | nsCOMPtr<nsIObliviousHttpService> ohttpService( |
| 273 | do_GetService("@mozilla.org/network/oblivious-http-service;1")); |
| 274 | if (!ohttpService) { |
| 275 | return NS_ERROR_FAILURE; |
| 276 | } |
| 277 | nsCOMPtr<nsIURI> relayURI; |
| 278 | nsTArray<uint8_t> encodedConfig; |
| 279 | rv = ohttpService->GetTRRSettings(getter_AddRefs(relayURI), encodedConfig); |
| 280 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 281 | return rv; |
| 282 | } |
| 283 | if (!relayURI) { |
| 284 | return NS_ERROR_FAILURE; |
| 285 | } |
| 286 | rv = ohttpService->NewChannel(relayURI, dnsURI, encodedConfig, |
| 287 | getter_AddRefs(channel)); |
| 288 | } else { |
| 289 | rv = DNSUtils::CreateChannelHelper(dnsURI, getter_AddRefs(channel)); |
| 290 | } |
| 291 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !channel) { |
| 292 | LOG(("TRR:SendHTTPRequest: NewChannel failed!\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:SendHTTPRequest: NewChannel failed!\n"); } } while (0); |
| 293 | return rv; |
| 294 | } |
| 295 | |
| 296 | auto loadFlags = nsIRequest::LOAD_ANONYMOUS | nsIRequest::INHIBIT_CACHING | |
| 297 | nsIRequest::LOAD_BYPASS_CACHE | |
| 298 | nsIChannel::LOAD_BYPASS_URL_CLASSIFIER; |
| 299 | if (mUseFreshConnection) { |
| 300 | // Causes TRRServiceChannel to tell the connection manager |
| 301 | // to clear out any connection with the current conn info. |
| 302 | loadFlags |= nsIRequest::LOAD_FRESH_CONNECTION; |
| 303 | } |
| 304 | channel->SetLoadFlags(loadFlags); |
| 305 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 305); return rv; } } while (false); |
| 306 | |
| 307 | nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel); |
| 308 | if (!httpChannel) { |
| 309 | return NS_ERROR_UNEXPECTED; |
| 310 | } |
| 311 | |
| 312 | // This connection should not use TRR |
| 313 | rv = httpChannel->SetTRRMode(nsIRequest::TRR_DISABLED_MODE); |
| 314 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 314); return rv; } } while (false); |
| 315 | |
| 316 | nsCString contentType(ContentType()); |
| 317 | rv = httpChannel->SetRequestHeader("Accept"_ns, contentType, false); |
| 318 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 318); return rv; } } while (false); |
| 319 | |
| 320 | nsAutoCString cred; |
| 321 | if (UseDefaultServer()) { |
| 322 | TRRService::Get()->GetCredentials(cred); |
| 323 | } |
| 324 | if (!cred.IsEmpty()) { |
| 325 | rv = httpChannel->SetRequestHeader("Authorization"_ns, cred, false); |
| 326 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 326); return rv; } } while (false); |
| 327 | } |
| 328 | |
| 329 | nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(channel); |
| 330 | if (!internalChannel) { |
| 331 | return NS_ERROR_UNEXPECTED; |
| 332 | } |
| 333 | |
| 334 | // setting a small stream window means the h2 stack won't pipeline a window |
| 335 | // update with each HEADERS or reply to a DATA with a WINDOW UPDATE |
| 336 | rv = internalChannel->SetInitialRwin(127 * 1024); |
| 337 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 337); return rv; } } while (false); |
| 338 | rv = internalChannel->SetIsTRRServiceChannel(true); |
| 339 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 339); return rv; } } while (false); |
| 340 | |
| 341 | // When using OHTTP, the we can't use cached connection info, since we |
| 342 | // need to connect to the relay, not the TRR server. |
| 343 | if (UseDefaultServer() && !useOHTTP && |
| 344 | StaticPrefs::network_trr_async_connInfo()) { |
| 345 | RefPtr<nsHttpConnectionInfo> trrConnInfo = |
| 346 | TRRService::Get()->TRRConnectionInfo(); |
| 347 | if (trrConnInfo) { |
| 348 | nsAutoCString host; |
| 349 | dnsURI->GetHost(host); |
| 350 | if (host.Equals(trrConnInfo->GetOrigin())) { |
| 351 | internalChannel->SetConnectionInfo(trrConnInfo); |
| 352 | LOG(("TRR::SendHTTPRequest use conn info:%s\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::SendHTTPRequest use conn info:%s\n", trrConnInfo-> HashKey().get()); } } while (0) |
| 353 | trrConnInfo->HashKey().get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::SendHTTPRequest use conn info:%s\n", trrConnInfo-> HashKey().get()); } } while (0); |
| 354 | } else { |
| 355 | // The connection info is inconsistent. Avoid using it and generate a |
| 356 | // new one. |
| 357 | TRRService::Get()->SetDefaultTRRConnectionInfo(nullptr); |
| 358 | TRRService::Get()->InitTRRConnectionInfo(true); |
| 359 | } |
| 360 | } else { |
| 361 | TRRService::Get()->InitTRRConnectionInfo(); |
| 362 | } |
| 363 | } |
| 364 | |
| 365 | if (useGet) { |
| 366 | rv = httpChannel->SetRequestMethod("GET"_ns); |
| 367 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 367); return rv; } } while (false); |
| 368 | } else { |
| 369 | nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(httpChannel); |
| 370 | if (!uploadChannel) { |
| 371 | return NS_ERROR_UNEXPECTED; |
| 372 | } |
| 373 | uint32_t streamLength = body.Length(); |
| 374 | nsCOMPtr<nsIInputStream> uploadStream; |
| 375 | rv = |
| 376 | NS_NewCStringInputStream(getter_AddRefs(uploadStream), std::move(body)); |
| 377 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 377); return rv; } } while (false); |
| 378 | |
| 379 | rv = uploadChannel->ExplicitSetUploadStream(uploadStream, contentType, |
| 380 | streamLength, "POST"_ns); |
| 381 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 381); return rv; } } while (false); |
| 382 | } |
| 383 | |
| 384 | rv = SetupTRRServiceChannelInternal(httpChannel, useGet, contentType); |
| 385 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 386 | return rv; |
| 387 | } |
| 388 | |
| 389 | rv = httpChannel->AsyncOpen(this); |
| 390 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 391 | return rv; |
| 392 | } |
| 393 | |
| 394 | // If the asyncOpen succeeded we can say that we actually attempted to |
| 395 | // use the TRR connection. |
| 396 | if (mRec) { |
| 397 | mRec->mResolverType = ResolverType(); |
| 398 | } |
| 399 | |
| 400 | NS_NewTimerWithCallback( |
| 401 | getter_AddRefs(mTimeout), this, |
| 402 | mTimeoutMs ? mTimeoutMs : TRRService::Get()->GetRequestTimeout(), |
| 403 | nsITimer::TYPE_ONE_SHOT); |
| 404 | |
| 405 | mChannel = std::move(channel); |
| 406 | return NS_OK; |
| 407 | } |
| 408 | |
| 409 | // static |
| 410 | nsresult TRR::SetupTRRServiceChannelInternal(nsIHttpChannel* aChannel, |
| 411 | bool aUseGet, |
| 412 | const nsACString& aContentType) { |
| 413 | nsCOMPtr<nsIHttpChannel> httpChannel = aChannel; |
| 414 | MOZ_ASSERT(httpChannel)do { static_assert( mozilla::detail::AssertionConditionType< decltype(httpChannel)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(httpChannel))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("httpChannel", "./../../../netwerk/dns/TRR.cpp" , 414); AnnotateMozCrashReason("MOZ_ASSERT" "(" "httpChannel" ")"); do { MOZ_CrashSequence(__null, 414); __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
| 415 | |
| 416 | nsresult rv = NS_OK; |
| 417 | if (!aUseGet) { |
| 418 | rv = |
| 419 | httpChannel->SetRequestHeader("Cache-Control"_ns, "no-store"_ns, false); |
| 420 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 420); return rv; } } while (false); |
| 421 | } |
| 422 | |
| 423 | // Sanitize the request by removing the Accept-Language header so we minimize |
| 424 | // the amount of fingerprintable information we send to the server. |
| 425 | if (!StaticPrefs::network_trr_send_accept_language_headers()) { |
| 426 | rv = httpChannel->SetRequestHeader("Accept-Language"_ns, ""_ns, false); |
| 427 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 427); return rv; } } while (false); |
| 428 | } |
| 429 | |
| 430 | // Sanitize the request by removing the User-Agent |
| 431 | if (!StaticPrefs::network_trr_send_user_agent_headers()) { |
| 432 | rv = httpChannel->SetRequestHeader("User-Agent"_ns, ""_ns, false); |
| 433 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 433); return rv; } } while (false); |
| 434 | } |
| 435 | |
| 436 | if (StaticPrefs::network_trr_send_empty_accept_encoding_headers()) { |
| 437 | rv = httpChannel->SetEmptyRequestHeader("Accept-Encoding"_ns); |
| 438 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../netwerk/dns/TRR.cpp" , 438); return rv; } } while (false); |
| 439 | } |
| 440 | |
| 441 | // set the *default* response content type |
| 442 | if (NS_FAILED(httpChannel->SetContentType(aContentType))((bool)(__builtin_expect(!!(NS_FAILED_impl(httpChannel->SetContentType (aContentType))), 0)))) { |
| 443 | LOG(("TRR::SetupTRRServiceChannelInternal: couldn't set content-type!\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::SetupTRRServiceChannelInternal: couldn't set content-type!\n" ); } } while (0); |
| 444 | } |
| 445 | |
| 446 | return NS_OK; |
| 447 | } |
| 448 | |
| 449 | NS_IMETHODIMPnsresult |
| 450 | TRR::OnStartRequest(nsIRequest* aRequest) { |
| 451 | LOG(("TRR::OnStartRequest %p %s %d\n", this, mHost.get(), mType))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::OnStartRequest %p %s %d\n", this, mHost.get(), mType) ; } } while (0); |
| 452 | |
| 453 | nsresult status = NS_OK; |
| 454 | aRequest->GetStatus(&status); |
| 455 | |
| 456 | if (NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0)))) { |
| 457 | if (gIOService->InSleepMode()) { |
| 458 | RecordReason(TRRSkippedReason::TRR_SYSTEM_SLEEP_MODE); |
| 459 | } else if (NS_IsOffline()) { |
| 460 | RecordReason(TRRSkippedReason::TRR_BROWSER_IS_OFFLINE); |
| 461 | } |
| 462 | |
| 463 | switch (status) { |
| 464 | case NS_ERROR_UNKNOWN_HOST: |
| 465 | RecordReason(TRRSkippedReason::TRR_CHANNEL_DNS_FAIL); |
| 466 | break; |
| 467 | case NS_ERROR_OFFLINE: |
| 468 | RecordReason(TRRSkippedReason::TRR_BROWSER_IS_OFFLINE); |
| 469 | break; |
| 470 | case NS_ERROR_NET_RESET: |
| 471 | RecordReason(TRRSkippedReason::TRR_NET_RESET); |
| 472 | break; |
| 473 | case NS_ERROR_NET_TIMEOUT: |
| 474 | case NS_ERROR_NET_TIMEOUT_EXTERNAL: |
| 475 | RecordReason(TRRSkippedReason::TRR_NET_TIMEOUT); |
| 476 | break; |
| 477 | case NS_ERROR_PROXY_CONNECTION_REFUSED: |
| 478 | RecordReason(TRRSkippedReason::TRR_NET_REFUSED); |
| 479 | break; |
| 480 | case NS_ERROR_NET_INTERRUPT: |
| 481 | RecordReason(TRRSkippedReason::TRR_NET_INTERRUPT); |
| 482 | break; |
| 483 | case NS_ERROR_NET_INADEQUATE_SECURITY: |
| 484 | RecordReason(TRRSkippedReason::TRR_NET_INADEQ_SEQURITY); |
| 485 | break; |
| 486 | default: |
| 487 | RecordReason(TRRSkippedReason::TRR_UNKNOWN_CHANNEL_FAILURE); |
| 488 | } |
| 489 | } |
| 490 | |
| 491 | return NS_OK; |
| 492 | } |
| 493 | |
| 494 | void TRR::SaveAdditionalRecords( |
| 495 | const nsClassHashtable<nsCStringHashKey, DOHresp>& aRecords) { |
| 496 | if (!mRec) { |
| 497 | return; |
| 498 | } |
| 499 | nsresult rv; |
| 500 | for (const auto& recordEntry : aRecords) { |
| 501 | if (!recordEntry.GetData() || recordEntry.GetData()->mAddresses.IsEmpty()) { |
| 502 | // no point in adding empty records. |
| 503 | continue; |
| 504 | } |
| 505 | // If IPv6 is disabled don't add anything else than IPv4. |
| 506 | if (StaticPrefs::network_dns_disableIPv6() && |
| 507 | std::find_if(recordEntry.GetData()->mAddresses.begin(), |
| 508 | recordEntry.GetData()->mAddresses.end(), |
| 509 | [](const NetAddr& addr) { return !addr.IsIPAddrV4(); }) != |
| 510 | recordEntry.GetData()->mAddresses.end()) { |
| 511 | continue; |
| 512 | } |
| 513 | RefPtr<nsHostRecord> hostRecord; |
| 514 | rv = mHostResolver->GetHostRecord( |
| 515 | recordEntry.GetKey(), EmptyCString(), |
| 516 | nsIDNSService::RESOLVE_TYPE_DEFAULT, mRec->flags, AF_UNSPEC0, mRec->pb, |
| 517 | mRec->originSuffix, getter_AddRefs(hostRecord)); |
| 518 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 519 | LOG(("Failed to get host record for additional record %s",do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "Failed to get host record for additional record %s", TPromiseFlatString <char>(recordEntry.GetKey()).get()); } } while (0) |
| 520 | PromiseFlatCString(recordEntry.GetKey()).get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "Failed to get host record for additional record %s", TPromiseFlatString <char>(recordEntry.GetKey()).get()); } } while (0); |
| 521 | continue; |
| 522 | } |
| 523 | RefPtr<AddrInfo> ai( |
| 524 | new AddrInfo(recordEntry.GetKey(), ResolverType(), TRRTYPE_A, |
| 525 | std::move(recordEntry.GetData()->mAddresses), |
| 526 | recordEntry.GetData()->mTtl)); |
| 527 | mHostResolver->MaybeRenewHostRecord(hostRecord); |
| 528 | |
| 529 | // Since we're not actually calling NameLookup for this record, we need |
| 530 | // to set these fields to avoid assertions in CompleteLookup. |
| 531 | // This is quite hacky, and should be fixed. |
| 532 | hostRecord->Reset(); |
| 533 | hostRecord->mResolving++; |
| 534 | hostRecord->mEffectiveTRRMode = |
| 535 | static_cast<nsIRequest::TRRMode>(mRec->mEffectiveTRRMode); |
| 536 | LOG(("Completing lookup for additional: %s",do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "Completing lookup for additional: %s", TPromiseFlatString< char>(recordEntry.GetKey()).get()); } } while (0) |
| 537 | PromiseFlatCString(recordEntry.GetKey()).get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "Completing lookup for additional: %s", TPromiseFlatString< char>(recordEntry.GetKey()).get()); } } while (0); |
| 538 | (void)mHostResolver->CompleteLookup(hostRecord, NS_OK, ai, mPB, |
| 539 | mOriginSuffix, TRRSkippedReason::TRR_OK, |
| 540 | this); |
| 541 | } |
| 542 | } |
| 543 | |
| 544 | void TRR::StoreIPHintAsDNSRecord(const struct SVCB& aSVCBRecord) { |
| 545 | LOG(("TRR::StoreIPHintAsDNSRecord [%p] [%s]", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::StoreIPHintAsDNSRecord [%p] [%s]", this, aSVCBRecord. mSvcDomainName.get()); } } while (0) |
| 546 | aSVCBRecord.mSvcDomainName.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::StoreIPHintAsDNSRecord [%p] [%s]", this, aSVCBRecord. mSvcDomainName.get()); } } while (0); |
| 547 | CopyableTArray<NetAddr> addresses; |
| 548 | aSVCBRecord.GetIPHints(addresses); |
| 549 | |
| 550 | if (StaticPrefs::network_dns_disableIPv6()) { |
| 551 | addresses.RemoveElementsBy( |
| 552 | [](const NetAddr& addr) { return !addr.IsIPAddrV4(); }); |
| 553 | } |
| 554 | |
| 555 | if (addresses.IsEmpty()) { |
| 556 | return; |
| 557 | } |
| 558 | |
| 559 | RefPtr<nsHostRecord> hostRecord; |
| 560 | nsresult rv = mHostResolver->GetHostRecord( |
| 561 | aSVCBRecord.mSvcDomainName, EmptyCString(), |
| 562 | nsIDNSService::RESOLVE_TYPE_DEFAULT, |
| 563 | mRec->flags | nsIDNSService::RESOLVE_IP_HINT, AF_UNSPEC0, mRec->pb, |
| 564 | mRec->originSuffix, getter_AddRefs(hostRecord)); |
| 565 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 566 | LOG(("Failed to get host record"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "Failed to get host record"); } } while (0); |
| 567 | return; |
| 568 | } |
| 569 | |
| 570 | mHostResolver->MaybeRenewHostRecord(hostRecord); |
| 571 | |
| 572 | RefPtr<AddrInfo> ai(new AddrInfo(aSVCBRecord.mSvcDomainName, ResolverType(), |
| 573 | TRRTYPE_A, std::move(addresses), mTTL)); |
| 574 | |
| 575 | // Since we're not actually calling NameLookup for this record, we need |
| 576 | // to set these fields to avoid assertions in CompleteLookup. |
| 577 | // This is quite hacky, and should be fixed. |
| 578 | hostRecord->mResolving++; |
| 579 | hostRecord->mEffectiveTRRMode = |
| 580 | static_cast<nsIRequest::TRRMode>(mRec->mEffectiveTRRMode); |
| 581 | (void)mHostResolver->CompleteLookup(hostRecord, NS_OK, ai, mPB, mOriginSuffix, |
| 582 | TRRSkippedReason::TRR_OK, this); |
| 583 | } |
| 584 | |
| 585 | nsresult TRR::ReturnData(nsIChannel* aChannel) { |
| 586 | Maybe<TimeDuration> trrFetchDuration; |
| 587 | Maybe<TimeDuration> trrFetchDurationNetworkOnly; |
| 588 | // Set timings. |
| 589 | nsCOMPtr<nsITimedChannel> timedChan = do_QueryInterface(aChannel); |
| 590 | if (timedChan) { |
| 591 | TimeStamp asyncOpen, start, end; |
| 592 | if (NS_SUCCEEDED(timedChan->GetAsyncOpen(&asyncOpen))((bool)(__builtin_expect(!!(!NS_FAILED_impl(timedChan->GetAsyncOpen (&asyncOpen))), 1))) && |
| 593 | !asyncOpen.IsNull()) { |
| 594 | trrFetchDuration = Some(TimeStamp::Now() - asyncOpen); |
| 595 | } |
| 596 | if (NS_SUCCEEDED(timedChan->GetRequestStart(&start))((bool)(__builtin_expect(!!(!NS_FAILED_impl(timedChan->GetRequestStart (&start))), 1))) && |
| 597 | NS_SUCCEEDED(timedChan->GetResponseEnd(&end))((bool)(__builtin_expect(!!(!NS_FAILED_impl(timedChan->GetResponseEnd (&end))), 1))) && !start.IsNull() && |
| 598 | !end.IsNull()) { |
| 599 | trrFetchDurationNetworkOnly = Some(end - start); |
| 600 | } |
| 601 | } |
| 602 | |
| 603 | if (mType != TRRTYPE_TXT && mType != TRRTYPE_HTTPSSVC) { |
| 604 | // create and populate an AddrInfo instance to pass on |
| 605 | RefPtr<AddrInfo> ai(new AddrInfo(mHost, ResolverType(), mType, |
| 606 | nsTArray<NetAddr>(), mDNS.mTtl)); |
| 607 | auto builder = ai->Build(); |
| 608 | builder.SetAddresses(std::move(mDNS.mAddresses)); |
| 609 | builder.SetCanonicalHostname(mCname); |
| 610 | if (trrFetchDuration) { |
| 611 | builder.SetTrrFetchDuration((*trrFetchDuration).ToMilliseconds()); |
| 612 | } |
| 613 | if (trrFetchDurationNetworkOnly) { |
| 614 | builder.SetTrrFetchDurationNetworkOnly( |
| 615 | (*trrFetchDurationNetworkOnly).ToMilliseconds()); |
| 616 | } |
| 617 | ai = builder.Finish(); |
| 618 | |
| 619 | if (!mHostResolver) { |
| 620 | return NS_ERROR_FAILURE; |
| 621 | } |
| 622 | RecordReason(TRRSkippedReason::TRR_OK); |
| 623 | (void)mHostResolver->CompleteLookup(mRec, NS_OK, ai, mPB, mOriginSuffix, |
| 624 | mTRRSkippedReason, this); |
| 625 | mHostResolver = nullptr; |
| 626 | mRec = nullptr; |
| 627 | } else { |
| 628 | RecordReason(TRRSkippedReason::TRR_OK); |
| 629 | (void)mHostResolver->CompleteLookupByType(mRec, NS_OK, mResult, |
| 630 | mTRRSkippedReason, mTTL, mPB); |
| 631 | } |
| 632 | |
| 633 | return NS_OK; |
| 634 | } |
| 635 | |
| 636 | nsresult TRR::FailData(nsresult error) { |
| 637 | if (!mHostResolver) { |
| 638 | return NS_ERROR_FAILURE; |
| 639 | } |
| 640 | |
| 641 | // If we didn't record a reason until now, record a default one. |
| 642 | RecordReason(TRRSkippedReason::TRR_FAILED); |
| 643 | |
| 644 | if (mType == TRRTYPE_TXT || mType == TRRTYPE_HTTPSSVC) { |
| 645 | TypeRecordResultType empty(Nothing{}); |
| 646 | (void)mHostResolver->CompleteLookupByType(mRec, error, empty, |
| 647 | mTRRSkippedReason, 0, mPB); |
| 648 | } else { |
| 649 | // create and populate an TRR AddrInfo instance to pass on to signal that |
| 650 | // this comes from TRR |
| 651 | nsTArray<NetAddr> noAddresses; |
| 652 | RefPtr<AddrInfo> ai = |
| 653 | new AddrInfo(mHost, ResolverType(), mType, std::move(noAddresses)); |
| 654 | |
| 655 | (void)mHostResolver->CompleteLookup(mRec, error, ai, mPB, mOriginSuffix, |
| 656 | mTRRSkippedReason, this); |
| 657 | } |
| 658 | |
| 659 | mHostResolver = nullptr; |
| 660 | mRec = nullptr; |
| 661 | return NS_OK; |
| 662 | } |
| 663 | |
| 664 | void TRR::HandleDecodeError(nsresult aStatusCode) { |
| 665 | auto rcode = mPacket->GetRCode(); |
| 666 | if (rcode.isOk() && rcode.unwrap() != 0) { |
| 667 | if (rcode.unwrap() == 0x03) { |
| 668 | RecordReason(TRRSkippedReason::TRR_NXDOMAIN); |
| 669 | } else { |
| 670 | RecordReason(TRRSkippedReason::TRR_RCODE_FAIL); |
| 671 | } |
| 672 | } else if (aStatusCode == NS_ERROR_UNKNOWN_HOST || |
| 673 | aStatusCode == NS_ERROR_DEFINITIVE_UNKNOWN_HOST) { |
| 674 | RecordReason(TRRSkippedReason::TRR_NO_ANSWERS); |
| 675 | } else { |
| 676 | RecordReason(TRRSkippedReason::TRR_DECODE_FAILED); |
| 677 | } |
| 678 | } |
| 679 | |
| 680 | bool TRR::HasUsableResponse() { |
| 681 | if (mType == TRRTYPE_A || mType == TRRTYPE_AAAA) { |
| 682 | return !mDNS.mAddresses.IsEmpty(); |
| 683 | } |
| 684 | if (mType == TRRTYPE_TXT) { |
| 685 | return mResult.is<TypeRecordTxt>(); |
| 686 | } |
| 687 | if (mType == TRRTYPE_HTTPSSVC) { |
| 688 | return mResult.is<TypeRecordHTTPSSVC>(); |
| 689 | } |
| 690 | return false; |
| 691 | } |
| 692 | |
| 693 | nsresult TRR::FollowCname(nsIChannel* aChannel) { |
| 694 | nsresult rv = NS_OK; |
| 695 | nsAutoCString cname; |
| 696 | // True when at least one link of the chain we are following is an HTTPS |
| 697 | // AliasMode TargetName rather than a plain CNAME. Only then does RFC 9460 |
| 698 | // require us to chase the target ourselves. |
| 699 | bool aliasFollow = |
| 700 | mHTTPSAliasFollow || GetOrCreateDNSPacket()->CnameIsHTTPSAlias(); |
| 701 | while (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && mDNS.mAddresses.IsEmpty() && !mCname.IsEmpty() && |
| 702 | mCnameLoop > 0) { |
| 703 | mCnameLoop--; |
| 704 | LOG(("TRR::On200Response CNAME %s => %s (%u)\n", mHost.get(), mCname.get(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::On200Response CNAME %s => %s (%u)\n", mHost.get(), mCname.get(), mCnameLoop); } } while (0) |
| 705 | mCnameLoop))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::On200Response CNAME %s => %s (%u)\n", mHost.get(), mCname.get(), mCnameLoop); } } while (0); |
| 706 | cname = mCname; |
| 707 | mCname.Truncate(); |
| 708 | |
| 709 | LOG(("TRR: check for CNAME record for %s within previous response\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR: check for CNAME record for %s within previous response\n" , cname.get()); } } while (0) |
| 710 | cname.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR: check for CNAME record for %s within previous response\n" , cname.get()); } } while (0); |
| 711 | nsClassHashtable<nsCStringHashKey, DOHresp> additionalRecords; |
| 712 | rv = GetOrCreateDNSPacket()->Decode( |
| 713 | cname, mType, mCname, StaticPrefs::network_trr_allow_rfc1918(), mDNS, |
| 714 | mResult, additionalRecords, mTTL); |
| 715 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 716 | LOG(("TRR::FollowCname DohDecode %x\n", (int)rv))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::FollowCname DohDecode %x\n", (int)rv); } } while (0); |
| 717 | HandleDecodeError(rv); |
| 718 | } |
| 719 | aliasFollow = aliasFollow || (!mCname.IsEmpty() && |
| 720 | GetOrCreateDNSPacket()->CnameIsHTTPSAlias()); |
| 721 | } |
| 722 | |
| 723 | // restore mCname as DohDecode() change it |
| 724 | mCname = std::move(cname); |
| 725 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && HasUsableResponse()) { |
| 726 | ReturnData(aChannel); |
| 727 | return NS_OK; |
| 728 | } |
| 729 | |
| 730 | bool ra = mPacket && mPacket->RecursionAvailable().unwrapOr(false); |
| 731 | LOG(("ra = %d", ra))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "ra = %d", ra); } } while (0); |
| 732 | if (rv == NS_ERROR_UNKNOWN_HOST && ra && !aliasFollow) { |
| 733 | // If recursion is available, but no addresses have been returned, |
| 734 | // we can just return a failure here. |
| 735 | // This optimization is only valid for CNAME chains: a recursive |
| 736 | // resolver that follows a CNAME already inlines the target's addresses. |
| 737 | // It does not hold for HTTPS AliasMode, since recursive resolvers do not |
| 738 | // chase the SVCB/HTTPS alias, so we must query the TargetName ourselves. |
| 739 | LOG(("TRR::FollowCname not sending another request as RA flag is set."))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::FollowCname not sending another request as RA flag is set." ); } } while (0); |
| 740 | FailData(NS_ERROR_UNKNOWN_HOST); |
| 741 | return NS_OK; |
| 742 | } |
| 743 | |
| 744 | if (!mCnameLoop) { |
| 745 | LOG(("TRR::On200Response CNAME loop, eject!\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::On200Response CNAME loop, eject!\n"); } } while (0); |
| 746 | return NS_ERROR_REDIRECT_LOOP; |
| 747 | } |
| 748 | |
| 749 | LOG(("TRR::On200Response CNAME %s => %s (%u)\n", mHost.get(), mCname.get(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::On200Response CNAME %s => %s (%u)\n", mHost.get(), mCname.get(), mCnameLoop); } } while (0) |
| 750 | mCnameLoop))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::On200Response CNAME %s => %s (%u)\n", mHost.get(), mCname.get(), mCnameLoop); } } while (0); |
| 751 | RefPtr<TRR> trr = |
| 752 | new TRR(mHostResolver, mRec, mCname, mType, mCnameLoop, mPB); |
| 753 | trr->SetPurpose(mPurpose); |
| 754 | // Recursive resolvers do not chase HTTPS AliasMode targets, so following the |
| 755 | // TargetName is an HTTPS alias follow. Remember this so that a target with no |
| 756 | // HTTPS record still yields an AliasMode record instead of failing. A plain |
| 757 | // CNAME is not an alias follow: a target without an HTTPS record simply has |
| 758 | // no HTTPS RR. |
| 759 | trr->mHTTPSAliasFollow = aliasFollow; |
| 760 | if (!TRRService::Get()) { |
| 761 | return NS_ERROR_FAILURE; |
| 762 | } |
| 763 | return TRRService::Get()->DispatchTRRRequest(trr); |
| 764 | } |
| 765 | |
| 766 | nsresult TRR::On200Response(nsIChannel* aChannel) { |
| 767 | // decode body and create an AddrInfo struct for the response |
| 768 | nsClassHashtable<nsCStringHashKey, DOHresp> additionalRecords; |
| 769 | if (RefPtr<TypeHostRecord> typeRec = do_QueryObject(mRec)) { |
| 770 | MutexAutoLock lock(typeRec->mResultsLock); |
| 771 | if (typeRec->mOriginHost) { |
| 772 | GetOrCreateDNSPacket()->SetOriginHost(typeRec->mOriginHost); |
| 773 | } |
| 774 | } |
| 775 | nsresult rv = GetOrCreateDNSPacket()->Decode( |
| 776 | mHost, mType, mCname, StaticPrefs::network_trr_allow_rfc1918(), mDNS, |
| 777 | mResult, additionalRecords, mTTL); |
| 778 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 779 | // We followed an HTTPS AliasMode record to this TargetName. If the target |
| 780 | // resolved successfully (NOERROR) but simply has no HTTPS record of its |
| 781 | // own, RFC 9460 still requires connecting to the TargetName, so synthesize |
| 782 | // an AliasMode record carrying it. The connection layer then routes to the |
| 783 | // target and Happy Eyeballs issues A/AAAA/HTTPS queries for it. A SERVFAIL |
| 784 | // or NXDOMAIN is a genuine failure and is left to propagate. |
| 785 | if (mType == TRRTYPE_HTTPSSVC && mHTTPSAliasFollow && |
| 786 | rv == NS_ERROR_UNKNOWN_HOST) { |
| 787 | auto rcode = mPacket->GetRCode(); |
| 788 | if (rcode.isOk() && rcode.unwrap() == 0) { |
| 789 | LOG(("TRR::On200Response synthesizing AliasMode record for %s\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::On200Response synthesizing AliasMode record for %s\n" , mHost.get()); } } while (0) |
| 790 | mHost.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::On200Response synthesizing AliasMode record for %s\n" , mHost.get()); } } while (0); |
| 791 | SVCB alias; |
| 792 | alias.mSvcFieldPriority = 0; |
| 793 | alias.mSvcDomainName = mHost; |
| 794 | CopyableTArray<SVCB> records; |
| 795 | records.AppendElement(std::move(alias)); |
| 796 | mResult = AsVariant(std::move(records)); |
| 797 | if (mTTL == UINT32_MAX(4294967295U)) { |
| 798 | mTTL = 60; |
| 799 | } |
| 800 | ReturnData(aChannel); |
| 801 | return NS_OK; |
| 802 | } |
| 803 | } |
| 804 | LOG(("TRR::On200Response DohDecode %x\n", (int)rv))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::On200Response DohDecode %x\n", (int)rv); } } while (0 ); |
| 805 | HandleDecodeError(rv); |
| 806 | return rv; |
| 807 | } |
| 808 | if (StaticPrefs::network_trr_add_additional_records()) { |
| 809 | SaveAdditionalRecords(additionalRecords); |
| 810 | } |
| 811 | |
| 812 | if (mResult.is<TypeRecordHTTPSSVC>()) { |
| 813 | auto& results = mResult.as<TypeRecordHTTPSSVC>(); |
| 814 | for (const auto& rec : results) { |
| 815 | StoreIPHintAsDNSRecord(rec); |
| 816 | } |
| 817 | } |
| 818 | |
| 819 | if (!mDNS.mAddresses.IsEmpty() || mType == TRRTYPE_TXT || mCname.IsEmpty()) { |
| 820 | // pass back the response data |
| 821 | ReturnData(aChannel); |
| 822 | return NS_OK; |
| 823 | } |
| 824 | |
| 825 | LOG(("TRR::On200Response trying CNAME %s", mCname.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::On200Response trying CNAME %s", mCname.get()); } } while (0); |
| 826 | return FollowCname(aChannel); |
| 827 | } |
| 828 | |
| 829 | void TRR::RecordProcessingTime(nsIChannel* aChannel) { |
| 830 | // This method records the time it took from the last received byte of the |
| 831 | // DoH response until we've notified the consumer with a host record. |
| 832 | nsCOMPtr<nsITimedChannel> timedChan = do_QueryInterface(aChannel); |
| 833 | if (!timedChan) { |
| 834 | return; |
| 835 | } |
| 836 | TimeStamp end; |
| 837 | if (NS_FAILED(timedChan->GetResponseEnd(&end))((bool)(__builtin_expect(!!(NS_FAILED_impl(timedChan->GetResponseEnd (&end))), 0)))) { |
| 838 | return; |
| 839 | } |
| 840 | |
| 841 | if (end.IsNull()) { |
| 842 | return; |
| 843 | } |
| 844 | |
| 845 | glean::dns::trr_processing_time.AccumulateRawDuration(TimeStamp::Now() - end); |
| 846 | |
| 847 | LOG(("Processing DoH response took %f ms",do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "Processing DoH response took %f ms", (TimeStamp::Now() - end ).ToMilliseconds()); } } while (0) |
| 848 | (TimeStamp::Now() - end).ToMilliseconds()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "Processing DoH response took %f ms", (TimeStamp::Now() - end ).ToMilliseconds()); } } while (0); |
| 849 | } |
| 850 | |
| 851 | void TRR::ReportStatus(nsresult aStatusCode) { |
| 852 | // If the TRR was cancelled by nsHostResolver, then we don't need to report |
| 853 | // it as failed; otherwise it can cause the confirmation to fail. |
| 854 | if (UseDefaultServer() && aStatusCode != NS_ERROR_ABORT) { |
| 855 | // Bad content is still considered "okay" if the HTTP response is okay |
| 856 | TRRService::Get()->RecordTRRStatus(this); |
| 857 | } |
| 858 | } |
| 859 | |
| 860 | static void RecordHttpVersion(nsIHttpChannel* aHttpChannel) { |
| 861 | nsCOMPtr<nsIHttpChannelInternal> internalChannel = |
| 862 | do_QueryInterface(aHttpChannel); |
| 863 | if (!internalChannel) { |
| 864 | LOG(("RecordHttpVersion: Failed to QI nsIHttpChannelInternal"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "RecordHttpVersion: Failed to QI nsIHttpChannelInternal"); } } while (0); |
| 865 | return; |
| 866 | } |
| 867 | |
| 868 | uint32_t major, minor; |
| 869 | if (NS_FAILED(internalChannel->GetResponseVersion(&major, &minor))((bool)(__builtin_expect(!!(NS_FAILED_impl(internalChannel-> GetResponseVersion(&major, &minor))), 0)))) { |
| 870 | LOG(("RecordHttpVersion: Failed to get protocol version"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "RecordHttpVersion: Failed to get protocol version"); } } while (0); |
| 871 | return; |
| 872 | } |
| 873 | |
| 874 | if (major == 2) { |
| 875 | glean::dns::trr_http_version.Get(TRRService::ProviderKey(), "h_2"_ns).Add(); |
| 876 | } else if (major == 3) { |
| 877 | glean::dns::trr_http_version.Get(TRRService::ProviderKey(), "h_3"_ns).Add(); |
| 878 | } else { |
| 879 | glean::dns::trr_http_version.Get(TRRService::ProviderKey(), "h_1"_ns).Add(); |
| 880 | } |
| 881 | |
| 882 | LOG(("RecordHttpVersion: Provider responded using HTTP version: %d", major))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "RecordHttpVersion: Provider responded using HTTP version: %d" , major); } } while (0); |
| 883 | } |
| 884 | |
| 885 | NS_IMETHODIMPnsresult |
| 886 | TRR::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) { |
| 887 | // The dtor will be run after the function returns |
| 888 | LOG(("TRR:OnStopRequest %p %s %d failed=%d code=%X\n", this, mHost.get(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnStopRequest %p %s %d failed=%d code=%X\n", this, mHost .get(), mType, mFailed, (unsigned int)aStatusCode); } } while (0) |
| 889 | mType, mFailed, (unsigned int)aStatusCode))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnStopRequest %p %s %d failed=%d code=%X\n", this, mHost .get(), mType, mFailed, (unsigned int)aStatusCode); } } while (0); |
| 890 | nsCOMPtr<nsIChannel> channel; |
| 891 | channel.swap(mChannel); |
| 892 | |
| 893 | mChannelStatus = aStatusCode; |
| 894 | if (NS_SUCCEEDED(aStatusCode)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatusCode)), 1) ))) { |
| 895 | nsCString label = "regular"_ns; |
| 896 | if (mPB) { |
| 897 | label = "private"_ns; |
| 898 | } |
| 899 | mozilla::glean::networking::trr_request_count.Get(label).Add(1); |
| 900 | } |
| 901 | |
| 902 | { |
| 903 | // Cancel the timer since we don't need it anymore. |
| 904 | nsCOMPtr<nsITimer> timer; |
| 905 | mTimeout.swap(timer); |
| 906 | if (timer) { |
| 907 | timer->Cancel(); |
| 908 | } |
| 909 | } |
| 910 | |
| 911 | auto scopeExit = MakeScopeExit([&] { ReportStatus(aStatusCode); }); |
| 912 | |
| 913 | nsresult rv = NS_OK; |
| 914 | // if status was "fine", parse the response and pass on the answer |
| 915 | if (!mFailed && NS_SUCCEEDED(aStatusCode)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatusCode)), 1) ))) { |
| 916 | nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest); |
| 917 | if (!httpChannel) { |
| 918 | return NS_ERROR_UNEXPECTED; |
| 919 | } |
| 920 | nsAutoCString contentType; |
| 921 | httpChannel->GetContentType(contentType); |
| 922 | if (contentType.Length() && |
| 923 | !contentType.LowerCaseEqualsASCII(ContentType())) { |
| 924 | LOG(("TRR:OnStopRequest %p %s %d wrong content type %s\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnStopRequest %p %s %d wrong content type %s\n", this, mHost.get(), mType, contentType.get()); } } while (0) |
| 925 | mHost.get(), mType, contentType.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnStopRequest %p %s %d wrong content type %s\n", this, mHost.get(), mType, contentType.get()); } } while (0); |
| 926 | FailData(NS_ERROR_UNEXPECTED); |
| 927 | return NS_OK; |
| 928 | } |
| 929 | |
| 930 | uint32_t httpStatus; |
| 931 | rv = httpChannel->GetResponseStatus(&httpStatus); |
| 932 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && httpStatus == 200) { |
| 933 | rv = On200Response(channel); |
| 934 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && UseDefaultServer()) { |
| 935 | RecordReason(TRRSkippedReason::TRR_OK); |
| 936 | RecordProcessingTime(channel); |
| 937 | RecordHttpVersion(httpChannel); |
| 938 | return rv; |
| 939 | } |
| 940 | } else { |
| 941 | RecordReason(TRRSkippedReason::TRR_SERVER_RESPONSE_ERR); |
| 942 | LOG(("TRR:OnStopRequest:%d %p rv %x httpStatus %d\n", __LINE__, this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnStopRequest:%d %p rv %x httpStatus %d\n", 942, this, (int)rv, httpStatus); } } while (0) |
| 943 | (int)rv, httpStatus))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnStopRequest:%d %p rv %x httpStatus %d\n", 942, this, (int)rv, httpStatus); } } while (0); |
| 944 | } |
| 945 | } |
| 946 | |
| 947 | LOG(("TRR:OnStopRequest %p status %x mFailed %d\n", this, (int)aStatusCode,do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnStopRequest %p status %x mFailed %d\n", this, (int)aStatusCode , mFailed); } } while (0) |
| 948 | mFailed))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnStopRequest %p status %x mFailed %d\n", this, (int)aStatusCode , mFailed); } } while (0); |
| 949 | FailData(NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) ? NS_ERROR_UNKNOWN_HOST : rv); |
| 950 | return NS_OK; |
| 951 | } |
| 952 | |
| 953 | NS_IMETHODIMPnsresult |
| 954 | TRR::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream, |
| 955 | uint64_t aOffset, const uint32_t aCount) { |
| 956 | LOG(("TRR:OnDataAvailable %p %s %d failed=%d aCount=%u\n", this, mHost.get(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnDataAvailable %p %s %d failed=%d aCount=%u\n", this, mHost.get(), mType, mFailed, (unsigned int)aCount); } } while (0) |
| 957 | mType, mFailed, (unsigned int)aCount))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR:OnDataAvailable %p %s %d failed=%d aCount=%u\n", this, mHost.get(), mType, mFailed, (unsigned int)aCount); } } while (0); |
| 958 | // receive DNS response into the local buffer |
| 959 | if (mFailed) { |
| 960 | return NS_ERROR_FAILURE; |
| 961 | } |
| 962 | |
| 963 | nsresult rv = GetOrCreateDNSPacket()->OnDataAvailable(aRequest, aInputStream, |
| 964 | aOffset, aCount); |
| 965 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 966 | LOG(("TRR::OnDataAvailable:%d fail\n", __LINE__))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR::OnDataAvailable:%d fail\n", 966); } } while (0); |
| 967 | mFailed = true; |
| 968 | return rv; |
| 969 | } |
| 970 | return NS_OK; |
| 971 | } |
| 972 | |
| 973 | void TRR::Cancel(nsresult aStatus) { |
| 974 | bool isTRRServiceChannel = false; |
| 975 | nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal( |
| 976 | do_QueryInterface(mChannel)); |
| 977 | if (httpChannelInternal) { |
| 978 | nsresult rv = |
| 979 | httpChannelInternal->GetIsTRRServiceChannel(&isTRRServiceChannel); |
| 980 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
| 981 | isTRRServiceChannel = false; |
| 982 | } |
| 983 | } |
| 984 | // nsHttpChannel can be only canceled on the main thread. |
| 985 | RefPtr<nsHttpChannel> httpChannel = do_QueryObject(mChannel); |
| 986 | if (isTRRServiceChannel && !XRE_IsSocketProcess() && !httpChannel) { |
| 987 | if (TRRService::Get()) { |
| 988 | nsCOMPtr<nsIThread> thread = TRRService::Get()->TRRThread(); |
| 989 | if (thread && !thread->IsOnCurrentThread()) { |
| 990 | thread->Dispatch(NS_NewRunnableFunction( |
| 991 | "TRR::Cancel", |
| 992 | [self = RefPtr(this), aStatus]() { self->Cancel(aStatus); })); |
| 993 | return; |
| 994 | } |
| 995 | } |
| 996 | } else { |
| 997 | if (!NS_IsMainThread()) { |
| 998 | NS_DispatchToMainThread(NS_NewRunnableFunction( |
| 999 | "TRR::Cancel", |
| 1000 | [self = RefPtr(this), aStatus]() { self->Cancel(aStatus); })); |
| 1001 | return; |
| 1002 | } |
| 1003 | } |
| 1004 | |
| 1005 | if (mCancelled) { |
| 1006 | return; |
| 1007 | } |
| 1008 | mCancelled = true; |
| 1009 | |
| 1010 | if (mChannel) { |
| 1011 | RecordReason(TRRSkippedReason::TRR_REQ_CANCELLED); |
| 1012 | LOG(("TRR: %p canceling Channel %p %s %d status=%" PRIx32 "\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR: %p canceling Channel %p %s %d status=%" "x" "\n", this , mChannel.get(), mHost.get(), mType, static_cast<uint32_t >(aStatus)); } } while (0) |
| 1013 | mChannel.get(), mHost.get(), mType, static_cast<uint32_t>(aStatus)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net ::gHostResolverLog; if ((__builtin_expect(!!(mozilla::detail:: log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla ::detail::log_print(moz_real_module, mozilla::LogLevel::Debug , "TRR: %p canceling Channel %p %s %d status=%" "x" "\n", this , mChannel.get(), mHost.get(), mType, static_cast<uint32_t >(aStatus)); } } while (0); |
| 1014 | mChannel->Cancel(aStatus); |
| 1015 | } |
| 1016 | } |
| 1017 | |
| 1018 | bool TRR::UseDefaultServer() { return !mRec || mRec->mTrrServer.IsEmpty(); } |
| 1019 | |
| 1020 | } // namespace net |
| 1021 | } // namespace mozilla |