Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp
Warning:line 266, column 5
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_netwerk_dns0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/netwerk/dns -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/netwerk/dns -resource-dir /usr/lib/llvm-20/lib/clang/20 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/netwerk/dns -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/base -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/ipc -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-20/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-01-20-090804-167946-1 -x c++ Unified_cpp_netwerk_dns0.cpp
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim:set ts=4 sw=2 sts=2 et cin: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "DNS.h"
8#include "DNSUtils.h"
9#include "nsCharSeparatedTokenizer.h"
10#include "nsContentUtils.h"
11#include "nsHttpHandler.h"
12#include "nsHttpChannel.h"
13#include "nsHostResolver.h"
14#include "nsIHttpChannel.h"
15#include "nsIHttpChannelInternal.h"
16#include "nsIIOService.h"
17#include "nsIInputStream.h"
18#include "nsIObliviousHttp.h"
19#include "nsIOService.h"
20#include "nsISupports.h"
21#include "nsISupportsUtils.h"
22#include "nsITimedChannel.h"
23#include "nsIUploadChannel2.h"
24#include "nsIURIMutator.h"
25#include "nsNetUtil.h"
26#include "nsQueryObject.h"
27#include "nsStringStream.h"
28#include "nsThreadUtils.h"
29#include "nsURLHelper.h"
30#include "ObliviousHttpChannel.h"
31#include "TRR.h"
32#include "TRRService.h"
33#include "TRRServiceChannel.h"
34#include "TRRLoadInfo.h"
35
36#include "mozilla/Base64.h"
37#include "mozilla/DebugOnly.h"
38#include "mozilla/Logging.h"
39#include "mozilla/Maybe.h"
40#include "mozilla/Preferences.h"
41#include "mozilla/StaticPrefs_network.h"
42#include "mozilla/Telemetry.h"
43#include "mozilla/TimeStamp.h"
44#include "mozilla/Tokenizer.h"
45#include "mozilla/UniquePtr.h"
46// Put DNSLogging.h at the end to avoid LOG being overwritten by other headers.
47#include "DNSLogging.h"
48#include "mozilla/glean/GleanMetrics.h"
49
50namespace mozilla {
51namespace net {
52
53NS_IMPL_ISUPPORTS_INHERITED(TRR, Runnable, nsIHttpPushListener,nsresult TRR::QueryInterface(const nsIID& aIID, void** aInstancePtr
) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 55); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE_INHERITED"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<TRR, nsIHttpPushListener>, int32_t( reinterpret_cast
<char*>(static_cast<nsIHttpPushListener*>((TRR*)0x1000
)) - reinterpret_cast<char*>((TRR*)0x1000))}, {&mozilla
::detail::kImplementedIID<TRR, nsIInterfaceRequestor>, int32_t
( reinterpret_cast<char*>(static_cast<nsIInterfaceRequestor
*>((TRR*)0x1000)) - reinterpret_cast<char*>((TRR*)0x1000
))}, {&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
))}, { 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; }
54 nsIInterfaceRequestor, nsIStreamListener,nsresult TRR::QueryInterface(const nsIID& aIID, void** aInstancePtr
) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 55); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE_INHERITED"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<TRR, nsIHttpPushListener>, int32_t( reinterpret_cast
<char*>(static_cast<nsIHttpPushListener*>((TRR*)0x1000
)) - reinterpret_cast<char*>((TRR*)0x1000))}, {&mozilla
::detail::kImplementedIID<TRR, nsIInterfaceRequestor>, int32_t
( reinterpret_cast<char*>(static_cast<nsIInterfaceRequestor
*>((TRR*)0x1000)) - reinterpret_cast<char*>((TRR*)0x1000
))}, {&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
))}, { 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; }
55 nsITimerCallback)nsresult TRR::QueryInterface(const nsIID& aIID, void** aInstancePtr
) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 55); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE_INHERITED"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<TRR, nsIHttpPushListener>, int32_t( reinterpret_cast
<char*>(static_cast<nsIHttpPushListener*>((TRR*)0x1000
)) - reinterpret_cast<char*>((TRR*)0x1000))}, {&mozilla
::detail::kImplementedIID<TRR, nsIInterfaceRequestor>, int32_t
( reinterpret_cast<char*>(static_cast<nsIInterfaceRequestor
*>((TRR*)0x1000)) - reinterpret_cast<char*>((TRR*)0x1000
))}, {&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
))}, { 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; }
56
57// when firing off a normal A or AAAA query
58TRR::TRR(AHostResolver* aResolver, nsHostRecord* aRec, enum TrrType aType)
59 : mozilla::Runnable("TRR"),
60 mRec(aRec),
61 mHostResolver(aResolver),
62 mType(aType),
63 mOriginSuffix(aRec->originSuffix) {
64 mHost = aRec->host;
65 mPB = aRec->pb;
66 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 67); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()"
") (" "TRR must be in parent or socket process" ")"); do { *
((volatile int*)__null) = 67; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
67 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 67); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()"
") (" "TRR must be in parent or socket process" ")"); do { *
((volatile int*)__null) = 67; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
68}
69
70// when following CNAMEs
71TRR::TRR(AHostResolver* aResolver, nsHostRecord* aRec, nsCString& aHost,
72 enum TrrType& aType, unsigned int aLoopCount, bool aPB)
73 : mozilla::Runnable("TRR"),
74 mHost(aHost),
75 mRec(aRec),
76 mHostResolver(aResolver),
77 mType(aType),
78 mPB(aPB),
79 mCnameLoop(aLoopCount),
80 mOriginSuffix(aRec ? aRec->originSuffix : ""_ns) {
81 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 82); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()"
") (" "TRR must be in parent or socket process" ")"); do { *
((volatile int*)__null) = 82; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
82 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 82); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()"
") (" "TRR must be in parent or socket process" ")"); do { *
((volatile int*)__null) = 82; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
83}
84
85// used on push
86TRR::TRR(AHostResolver* aResolver, bool aPB)
87 : mozilla::Runnable("TRR"), mHostResolver(aResolver), mPB(aPB) {
88 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 89); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()"
") (" "TRR must be in parent or socket process" ")"); do { *
((volatile int*)__null) = 89; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
89 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 89); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()"
") (" "TRR must be in parent or socket process" ")"); do { *
((volatile int*)__null) = 89; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
90}
91
92// to verify a domain
93TRR::TRR(AHostResolver* aResolver, nsACString& aHost, enum TrrType aType,
94 const nsACString& aOriginSuffix, bool aPB, bool aUseFreshConnection)
95 : mozilla::Runnable("TRR"),
96 mHost(aHost),
97 mRec(nullptr),
98 mHostResolver(aResolver),
99 mType(aType),
100 mPB(aPB),
101 mOriginSuffix(aOriginSuffix),
102 mUseFreshConnection(aUseFreshConnection) {
103 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 104); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()"
") (" "TRR must be in parent or socket process" ")"); do { *
((volatile int*)__null) = 104; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
104 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 104); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess() || XRE_IsSocketProcess()"
") (" "TRR must be in parent or socket process" ")"); do { *
((volatile int*)__null) = 104; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
105}
106
107void TRR::HandleTimeout() {
108 mTimeout = nullptr;
109 RecordReason(TRRSkippedReason::TRR_TIMEOUT);
110 Cancel(NS_ERROR_NET_TIMEOUT_EXTERNAL);
111}
112
113NS_IMETHODIMPnsresult
114TRR::Notify(nsITimer* aTimer) {
115 if (aTimer == mTimeout) {
116 HandleTimeout();
117 } else {
118 MOZ_CRASH("Unknown timer")do { do { } while (false); MOZ_ReportCrash("" "Unknown timer"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 118); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown timer" ")"
); do { *((volatile int*)__null) = 118; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
119 }
120
121 return NS_OK;
122}
123
124NS_IMETHODIMPnsresult
125TRR::Run() {
126 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 127); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread() || TRRService::Get()->IsOnTRRThread()"
")"); do { *((volatile int*)__null) = 127; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
127 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 127); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread() || TRRService::Get()->IsOnTRRThread()"
")"); do { *((volatile int*)__null) = 127; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
128 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()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 128; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
129
130 if ((TRRService::Get() == nullptr) || NS_FAILED(SendHTTPRequest())((bool)(__builtin_expect(!!(NS_FAILED_impl(SendHTTPRequest())
), 0)))
) {
131 RecordReason(TRRSkippedReason::TRR_SEND_FAILED);
132 FailData(NS_ERROR_FAILURE);
133 // The dtor will now be run
134 }
135 return NS_OK;
136}
137
138DNSPacket* TRR::GetOrCreateDNSPacket() {
139 if (!mPacket) {
140 mPacket = MakeUnique<DNSPacket>();
141 }
142
143 return mPacket.get();
144}
145
146nsresult TRR::CreateQueryURI(nsIURI** aOutURI) {
147 nsAutoCString uri;
148 nsCOMPtr<nsIURI> dnsURI;
149 if (UseDefaultServer()) {
150 TRRService::Get()->GetURI(uri);
151 } else {
152 uri = mRec->mTrrServer;
153 }
154
155 nsresult rv = NS_NewURI(getter_AddRefs(dnsURI), uri);
156 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
157 RecordReason(TRRSkippedReason::TRR_BAD_URL);
158 return rv;
159 }
160
161 dnsURI.forget(aOutURI);
162 return NS_OK;
163}
164
165bool TRR::MaybeBlockRequest() {
166 if (((mType == TRRTYPE_A) || (mType == TRRTYPE_AAAA)) &&
167 mRec->mEffectiveTRRMode != nsIRequest::TRR_ONLY_MODE) {
168 // let NS resolves skip the blocklist check
169 // we also don't check the blocklist for TRR only requests
170 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 170); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRec" ")"); do
{ *((volatile int*)__null) = 170; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
171
172 // If TRRService isn't enabled anymore for the req, don't do TRR.
173 if (!TRRService::Get()->Enabled(mRec->mEffectiveTRRMode)) {
174 RecordReason(TRRSkippedReason::TRR_MODE_NOT_ENABLED);
175 return true;
176 }
177
178 if (!StaticPrefs::network_trr_strict_native_fallback() &&
179 UseDefaultServer() &&
180 TRRService::Get()->IsTemporarilyBlocked(mHost, mOriginSuffix, mPB,
181 true)) {
182 if (mType == TRRTYPE_A) {
183 // count only blocklist for A records to avoid double counts
184 Telemetry::Accumulate(Telemetry::DNS_TRR_BLACKLISTED3,
185 TRRService::ProviderKey(), true);
186 }
187
188 RecordReason(TRRSkippedReason::TRR_HOST_BLOCKED_TEMPORARY);
189 // not really an error but no TRR is issued
190 return true;
191 }
192
193 if (TRRService::Get()->IsExcludedFromTRR(mHost)) {
194 RecordReason(TRRSkippedReason::TRR_EXCLUDED);
195 return true;
196 }
197
198 if (UseDefaultServer() && (mType == TRRTYPE_A)) {
199 Telemetry::Accumulate(Telemetry::DNS_TRR_BLACKLISTED3,
200 TRRService::ProviderKey(), false);
201 }
202 }
203
204 return false;
205}
206
207nsresult TRR::SendHTTPRequest() {
208 // This is essentially the "run" method - created from nsHostResolver
209 if (mCancelled) {
210 return NS_ERROR_FAILURE;
211 }
212
213 if ((mType != TRRTYPE_A) && (mType != TRRTYPE_AAAA) &&
214 (mType != TRRTYPE_NS) && (mType != TRRTYPE_TXT) &&
215 (mType != TRRTYPE_HTTPSSVC)) {
216 // limit the calling interface because nsHostResolver has explicit slots for
217 // these types
218 return NS_ERROR_FAILURE;
219 }
220
221 if (MaybeBlockRequest()) {
222 return NS_ERROR_UNKNOWN_HOST;
223 }
224
225 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)
;
226
227 nsAutoCString body;
228 bool disableECS = StaticPrefs::network_trr_disable_ECS();
229 nsresult rv =
230 GetOrCreateDNSPacket()->EncodeRequest(body, mHost, mType, disableECS);
231 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
232 HandleEncodeError(rv);
233 return rv;
234 }
235
236 bool useGet = StaticPrefs::network_trr_useGET();
237 nsCOMPtr<nsIURI> dnsURI;
238 rv = CreateQueryURI(getter_AddRefs(dnsURI));
239 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
240 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)
;
241 return rv;
242 }
243
244 if (useGet) {
245 /* For GET requests, the outgoing packet needs to be Base64url-encoded and
246 then appended to the end of the URI. */
247 nsAutoCString encoded;
248 rv = Base64URLEncode(body.Length(),
249 reinterpret_cast<const unsigned char*>(body.get()),
250 Base64URLEncodePaddingPolicy::Omit, encoded);
251 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 251); return rv; } } while (false)
;
252
253 nsAutoCString query;
254 rv = dnsURI->GetQuery(query);
255 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
256 return rv;
257 }
258
259 if (query.IsEmpty()) {
260 query.Assign("?dns="_ns);
261 } else {
262 query.Append("&dns="_ns);
263 }
264 query.Append(encoded);
265
266 rv = NS_MutateURI(dnsURI).SetQuery(query).Finalize(dnsURI);
Value stored to 'rv' is never read
267 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)
;
268 }
269
270 nsCOMPtr<nsIChannel> channel;
271 bool useOHTTP = StaticPrefs::network_trr_use_ohttp();
272 if (useOHTTP) {
273 nsCOMPtr<nsIObliviousHttpService> ohttpService(
274 do_GetService("@mozilla.org/network/oblivious-http-service;1"));
275 if (!ohttpService) {
276 return NS_ERROR_FAILURE;
277 }
278 nsCOMPtr<nsIURI> relayURI;
279 nsTArray<uint8_t> encodedConfig;
280 rv = ohttpService->GetTRRSettings(getter_AddRefs(relayURI), encodedConfig);
281 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
282 return rv;
283 }
284 if (!relayURI) {
285 return NS_ERROR_FAILURE;
286 }
287 rv = ohttpService->NewChannel(relayURI, dnsURI, encodedConfig,
288 getter_AddRefs(channel));
289 } else {
290 rv = DNSUtils::CreateChannelHelper(dnsURI, getter_AddRefs(channel));
291 }
292 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !channel) {
293 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)
;
294 return rv;
295 }
296
297 auto loadFlags = nsIRequest::LOAD_ANONYMOUS | nsIRequest::INHIBIT_CACHING |
298 nsIRequest::LOAD_BYPASS_CACHE |
299 nsIChannel::LOAD_BYPASS_URL_CLASSIFIER;
300 if (mUseFreshConnection) {
301 // Causes TRRServiceChannel to tell the connection manager
302 // to clear out any connection with the current conn info.
303 loadFlags |= nsIRequest::LOAD_FRESH_CONNECTION;
304 }
305 channel->SetLoadFlags(loadFlags);
306 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 306); return rv; } } while (false)
;
307
308 rv = channel->SetNotificationCallbacks(this);
309 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 309); return rv; } } while (false)
;
310
311 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
312 if (!httpChannel) {
313 return NS_ERROR_UNEXPECTED;
314 }
315
316 // This connection should not use TRR
317 rv = httpChannel->SetTRRMode(nsIRequest::TRR_DISABLED_MODE);
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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 318); return rv; } } while (false)
;
319
320 nsCString contentType(ContentType());
321 rv = httpChannel->SetRequestHeader("Accept"_ns, contentType, false);
322 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 322); return rv; } } while (false)
;
323
324 nsAutoCString cred;
325 if (UseDefaultServer()) {
326 TRRService::Get()->GetCredentials(cred);
327 }
328 if (!cred.IsEmpty()) {
329 rv = httpChannel->SetRequestHeader("Authorization"_ns, cred, false);
330 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 330); return rv; } } while (false)
;
331 }
332
333 nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(channel);
334 if (!internalChannel) {
335 return NS_ERROR_UNEXPECTED;
336 }
337
338 // setting a small stream window means the h2 stack won't pipeline a window
339 // update with each HEADERS or reply to a DATA with a WINDOW UPDATE
340 rv = internalChannel->SetInitialRwin(127 * 1024);
341 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 341); return rv; } } while (false)
;
342 rv = internalChannel->SetIsTRRServiceChannel(true);
343 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 343); return rv; } } while (false)
;
344
345 if (UseDefaultServer() && StaticPrefs::network_trr_async_connInfo()) {
346 RefPtr<nsHttpConnectionInfo> trrConnInfo =
347 TRRService::Get()->TRRConnectionInfo();
348 if (trrConnInfo) {
349 nsAutoCString host;
350 dnsURI->GetHost(host);
351 if (host.Equals(trrConnInfo->GetOrigin())) {
352 internalChannel->SetConnectionInfo(trrConnInfo);
353 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)
354 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)
;
355 } else {
356 MOZ_DIAGNOSTIC_CRASH("host not equal to trrConnInfo origin")do { do { } while (false); MOZ_ReportCrash("" "host not equal to trrConnInfo origin"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 356); AnnotateMozCrashReason("MOZ_CRASH(" "host not equal to trrConnInfo origin"
")"); do { *((volatile int*)__null) = 356; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
357 }
358 } else {
359 TRRService::Get()->InitTRRConnectionInfo();
360 }
361 }
362
363 if (useGet) {
364 rv = httpChannel->SetRequestMethod("GET"_ns);
365 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 365); return rv; } } while (false)
;
366 } else {
367 nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(httpChannel);
368 if (!uploadChannel) {
369 return NS_ERROR_UNEXPECTED;
370 }
371 uint32_t streamLength = body.Length();
372 nsCOMPtr<nsIInputStream> uploadStream;
373 rv =
374 NS_NewCStringInputStream(getter_AddRefs(uploadStream), std::move(body));
375 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 375); return rv; } } while (false)
;
376
377 rv = uploadChannel->ExplicitSetUploadStream(uploadStream, contentType,
378 streamLength, "POST"_ns, false);
379 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 379); return rv; } } while (false)
;
380 }
381
382 rv = SetupTRRServiceChannelInternal(httpChannel, useGet, contentType);
383 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
384 return rv;
385 }
386
387 rv = httpChannel->AsyncOpen(this);
388 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
389 return rv;
390 }
391
392 // If the asyncOpen succeeded we can say that we actually attempted to
393 // use the TRR connection.
394 if (mRec) {
395 mRec->mResolverType = ResolverType();
396 }
397
398 NS_NewTimerWithCallback(
399 getter_AddRefs(mTimeout), this,
400 mTimeoutMs ? mTimeoutMs : TRRService::Get()->GetRequestTimeout(),
401 nsITimer::TYPE_ONE_SHOT);
402
403 mChannel = channel;
404 return NS_OK;
405}
406
407// static
408nsresult TRR::SetupTRRServiceChannelInternal(nsIHttpChannel* aChannel,
409 bool aUseGet,
410 const nsACString& aContentType) {
411 nsCOMPtr<nsIHttpChannel> httpChannel = aChannel;
412 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 412); AnnotateMozCrashReason("MOZ_ASSERT" "(" "httpChannel"
")"); do { *((volatile int*)__null) = 412; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
413
414 nsresult rv = NS_OK;
415 if (!aUseGet) {
416 rv =
417 httpChannel->SetRequestHeader("Cache-Control"_ns, "no-store"_ns, false);
418 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 418); return rv; } } while (false)
;
419 }
420
421 // Sanitize the request by removing the Accept-Language header so we minimize
422 // the amount of fingerprintable information we send to the server.
423 if (!StaticPrefs::network_trr_send_accept_language_headers()) {
424 rv = httpChannel->SetRequestHeader("Accept-Language"_ns, ""_ns, false);
425 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 425); return rv; } } while (false)
;
426 }
427
428 // Sanitize the request by removing the User-Agent
429 if (!StaticPrefs::network_trr_send_user_agent_headers()) {
430 rv = httpChannel->SetRequestHeader("User-Agent"_ns, ""_ns, false);
431 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 431); return rv; } } while (false)
;
432 }
433
434 if (StaticPrefs::network_trr_send_empty_accept_encoding_headers()) {
435 rv = httpChannel->SetEmptyRequestHeader("Accept-Encoding"_ns);
436 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 436); return rv; } } while (false)
;
437 }
438
439 // set the *default* response content type
440 if (NS_FAILED(httpChannel->SetContentType(aContentType))((bool)(__builtin_expect(!!(NS_FAILED_impl(httpChannel->SetContentType
(aContentType))), 0)))
) {
441 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)
;
442 }
443
444 return NS_OK;
445}
446
447NS_IMETHODIMPnsresult
448TRR::GetInterface(const nsIID& iid, void** result) {
449 if (!iid.Equals(NS_GET_IID(nsIHttpPushListener)(nsIHttpPushListener::COMTypeInfo<nsIHttpPushListener, void
>::kIID)
)) {
450 return NS_ERROR_NO_INTERFACE;
451 }
452
453 nsCOMPtr<nsIHttpPushListener> copy(this);
454 *result = copy.forget().take();
455 return NS_OK;
456}
457
458nsresult TRR::DohDecodeQuery(const nsCString& query, nsCString& host,
459 enum TrrType& type) {
460 FallibleTArray<uint8_t> binary;
461 bool found_dns = false;
462 LOG(("TRR::DohDecodeQuery %s!\n", query.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::DohDecodeQuery %s!\n", query.get()); } } while (0)
;
463
464 // extract "dns=" from the query string
465 nsAutoCString data;
466 for (const nsACString& token :
467 nsCCharSeparatedTokenizer(query, '&').ToRange()) {
468 nsDependentCSubstring dns = Substring(token, 0, 4);
469 nsAutoCString check(dns);
470 if (check.Equals("dns=")) {
471 nsDependentCSubstring q = Substring(token, 4, -1);
472 data = q;
473 found_dns = true;
474 break;
475 }
476 }
477 if (!found_dns) {
478 LOG(("TRR::DohDecodeQuery no dns= in pushed URI query string\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::DohDecodeQuery no dns= in pushed URI query string\n")
; } } while (0)
;
479 return NS_ERROR_ILLEGAL_VALUE;
480 }
481
482 nsresult rv =
483 Base64URLDecode(data, Base64URLDecodePaddingPolicy::Ignore, binary);
484 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 484); return rv; } } while (false)
;
485 uint32_t avail = binary.Length();
486 if (avail < 12) {
487 return NS_ERROR_FAILURE;
488 }
489 // check the query bit and the opcode
490 if ((binary[2] & 0xf8) != 0) {
491 return NS_ERROR_FAILURE;
492 }
493 uint32_t qdcount = (binary[4] << 8) + binary[5];
494 if (!qdcount) {
495 return NS_ERROR_FAILURE;
496 }
497
498 uint32_t index = 12;
499 uint32_t length = 0;
500 host.Truncate();
501 do {
502 if (avail < (index + 1)) {
503 return NS_ERROR_UNEXPECTED;
504 }
505
506 length = binary[index];
507 if (length) {
508 if (host.Length()) {
509 host.Append(".");
510 }
511 if (avail < (index + 1 + length)) {
512 return NS_ERROR_UNEXPECTED;
513 }
514 host.Append((const char*)(&binary[0]) + index + 1, length);
515 }
516 index += 1 + length; // skip length byte + label
517 } while (length);
518
519 LOG(("TRR::DohDecodeQuery host %s\n", host.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::DohDecodeQuery host %s\n", host.get()); } } while (0)
;
520
521 if (avail < (index + 2)) {
522 return NS_ERROR_UNEXPECTED;
523 }
524 uint16_t i16 = 0;
525 i16 += binary[index] << 8;
526 i16 += binary[index + 1];
527 type = (enum TrrType)i16;
528
529 LOG(("TRR::DohDecodeQuery type %d\n", (int)type))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::DohDecodeQuery type %d\n", (int)type); } } while (0)
;
530
531 return NS_OK;
532}
533
534nsresult TRR::ReceivePush(nsIHttpChannel* pushed, nsHostRecord* pushedRec) {
535 if (!mHostResolver) {
536 return NS_ERROR_UNEXPECTED;
537 }
538
539 LOG(("TRR::ReceivePush: PUSH incoming!\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::ReceivePush: PUSH incoming!\n"); } } while (0)
;
540
541 nsCOMPtr<nsIURI> uri;
542 pushed->GetURI(getter_AddRefs(uri));
543 nsAutoCString query;
544 if (uri) {
545 uri->GetQuery(query);
546 }
547
548 if (NS_FAILED(DohDecodeQuery(query, mHost, mType))((bool)(__builtin_expect(!!(NS_FAILED_impl(DohDecodeQuery(query
, mHost, mType))), 0)))
||
549 HostIsIPLiteral(mHost)) { // literal
550 LOG(("TRR::ReceivePush failed to decode %s\n", 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::ReceivePush failed to decode %s\n", mHost.get()); } }
while (0)
;
551 return NS_ERROR_UNEXPECTED;
552 }
553
554 if ((mType != TRRTYPE_A) && (mType != TRRTYPE_AAAA) &&
555 (mType != TRRTYPE_TXT) && (mType != TRRTYPE_HTTPSSVC)) {
556 LOG(("TRR::ReceivePush unknown type %d\n", 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::ReceivePush unknown type %d\n", mType); } } while (0)
;
557 return NS_ERROR_UNEXPECTED;
558 }
559
560 if (TRRService::Get()->IsExcludedFromTRR(mHost)) {
561 return NS_ERROR_FAILURE;
562 }
563
564 uint32_t type = nsIDNSService::RESOLVE_TYPE_DEFAULT;
565 if (mType == TRRTYPE_TXT) {
566 type = nsIDNSService::RESOLVE_TYPE_TXT;
567 } else if (mType == TRRTYPE_HTTPSSVC) {
568 type = nsIDNSService::RESOLVE_TYPE_HTTPSSVC;
569 }
570
571 RefPtr<nsHostRecord> hostRecord;
572 nsresult rv;
573 rv = mHostResolver->GetHostRecord(
574 mHost, ""_ns, type, pushedRec->flags, pushedRec->af, pushedRec->pb,
575 pushedRec->originSuffix, getter_AddRefs(hostRecord));
576 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
577 return rv;
578 }
579
580 // Since we don't ever call nsHostResolver::NameLookup for this record,
581 // we need to copy the trr mode from the previous record
582 if (hostRecord->mEffectiveTRRMode == nsIRequest::TRR_DEFAULT_MODE) {
583 hostRecord->mEffectiveTRRMode =
584 static_cast<nsIRequest::TRRMode>(pushedRec->mEffectiveTRRMode);
585 }
586
587 rv = mHostResolver->TrrLookup_unlocked(hostRecord, this);
588 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
589 return rv;
590 }
591
592 rv = pushed->AsyncOpen(this);
593 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
594 return rv;
595 }
596
597 // OK!
598 mChannel = pushed;
599 mRec.swap(hostRecord);
600
601 return NS_OK;
602}
603
604NS_IMETHODIMPnsresult
605TRR::OnPush(nsIHttpChannel* associated, nsIHttpChannel* pushed) {
606 LOG(("TRR::OnPush entry\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::OnPush entry\n"); } } while (0)
;
607 MOZ_ASSERT(associated == mChannel)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(associated == mChannel)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(associated == mChannel))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("associated == mChannel"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns/TRR.cpp"
, 607); AnnotateMozCrashReason("MOZ_ASSERT" "(" "associated == mChannel"
")"); do { *((volatile int*)__null) = 607; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
608 if (!mRec) {
609 return NS_ERROR_FAILURE;
610 }
611 if (!UseDefaultServer()) {
612 return NS_ERROR_FAILURE;
613 }
614
615 RefPtr<TRR> trr = new TRR(mHostResolver, mPB);
616 trr->SetPurpose(mPurpose);
617 return trr->ReceivePush(pushed, mRec);
618}
619
620NS_IMETHODIMPnsresult
621TRR::OnStartRequest(nsIRequest* aRequest) {
622 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)
;
623
624 nsresult status = NS_OK;
625 aRequest->GetStatus(&status);
626
627 if (NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0)))) {
628 if (gIOService->InSleepMode()) {
629 RecordReason(TRRSkippedReason::TRR_SYSTEM_SLEEP_MODE);
630 } else if (NS_IsOffline()) {
631 RecordReason(TRRSkippedReason::TRR_BROWSER_IS_OFFLINE);
632 }
633
634 switch (status) {
635 case NS_ERROR_UNKNOWN_HOST:
636 RecordReason(TRRSkippedReason::TRR_CHANNEL_DNS_FAIL);
637 break;
638 case NS_ERROR_OFFLINE:
639 RecordReason(TRRSkippedReason::TRR_BROWSER_IS_OFFLINE);
640 break;
641 case NS_ERROR_NET_RESET:
642 RecordReason(TRRSkippedReason::TRR_NET_RESET);
643 break;
644 case NS_ERROR_NET_TIMEOUT:
645 case NS_ERROR_NET_TIMEOUT_EXTERNAL:
646 RecordReason(TRRSkippedReason::TRR_NET_TIMEOUT);
647 break;
648 case NS_ERROR_PROXY_CONNECTION_REFUSED:
649 RecordReason(TRRSkippedReason::TRR_NET_REFUSED);
650 break;
651 case NS_ERROR_NET_INTERRUPT:
652 RecordReason(TRRSkippedReason::TRR_NET_INTERRUPT);
653 break;
654 case NS_ERROR_NET_INADEQUATE_SECURITY:
655 RecordReason(TRRSkippedReason::TRR_NET_INADEQ_SEQURITY);
656 break;
657 default:
658 RecordReason(TRRSkippedReason::TRR_UNKNOWN_CHANNEL_FAILURE);
659 }
660 }
661
662 return NS_OK;
663}
664
665void TRR::SaveAdditionalRecords(
666 const nsClassHashtable<nsCStringHashKey, DOHresp>& aRecords) {
667 if (!mRec) {
668 return;
669 }
670 nsresult rv;
671 for (const auto& recordEntry : aRecords) {
672 if (!recordEntry.GetData() || recordEntry.GetData()->mAddresses.IsEmpty()) {
673 // no point in adding empty records.
674 continue;
675 }
676 // If IPv6 is disabled don't add anything else than IPv4.
677 if (StaticPrefs::network_dns_disableIPv6() &&
678 std::find_if(recordEntry.GetData()->mAddresses.begin(),
679 recordEntry.GetData()->mAddresses.end(),
680 [](const NetAddr& addr) { return !addr.IsIPAddrV4(); }) !=
681 recordEntry.GetData()->mAddresses.end()) {
682 continue;
683 }
684 RefPtr<nsHostRecord> hostRecord;
685 rv = mHostResolver->GetHostRecord(
686 recordEntry.GetKey(), EmptyCString(),
687 nsIDNSService::RESOLVE_TYPE_DEFAULT, mRec->flags, AF_UNSPEC0, mRec->pb,
688 mRec->originSuffix, getter_AddRefs(hostRecord));
689 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
690 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", nsCString
(recordEntry.GetKey()).get()); } } while (0)
691 nsCString(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", nsCString
(recordEntry.GetKey()).get()); } } while (0)
;
692 continue;
693 }
694 RefPtr<AddrInfo> ai(
695 new AddrInfo(recordEntry.GetKey(), ResolverType(), TRRTYPE_A,
696 std::move(recordEntry.GetData()->mAddresses),
697 recordEntry.GetData()->mTtl));
698 mHostResolver->MaybeRenewHostRecord(hostRecord);
699
700 // Since we're not actually calling NameLookup for this record, we need
701 // to set these fields to avoid assertions in CompleteLookup.
702 // This is quite hacky, and should be fixed.
703 hostRecord->Reset();
704 hostRecord->mResolving++;
705 hostRecord->mEffectiveTRRMode =
706 static_cast<nsIRequest::TRRMode>(mRec->mEffectiveTRRMode);
707 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", nsCString(recordEntry
.GetKey()).get()); } } while (0)
708 nsCString(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", nsCString(recordEntry
.GetKey()).get()); } } while (0)
;
709 (void)mHostResolver->CompleteLookup(hostRecord, NS_OK, ai, mPB,
710 mOriginSuffix, TRRSkippedReason::TRR_OK,
711 this);
712 }
713}
714
715void TRR::StoreIPHintAsDNSRecord(const struct SVCB& aSVCBRecord) {
716 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)
717 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)
;
718 CopyableTArray<NetAddr> addresses;
719 aSVCBRecord.GetIPHints(addresses);
720
721 if (StaticPrefs::network_dns_disableIPv6()) {
722 addresses.RemoveElementsBy(
723 [](const NetAddr& addr) { return !addr.IsIPAddrV4(); });
724 }
725
726 if (addresses.IsEmpty()) {
727 return;
728 }
729
730 RefPtr<nsHostRecord> hostRecord;
731 nsresult rv = mHostResolver->GetHostRecord(
732 aSVCBRecord.mSvcDomainName, EmptyCString(),
733 nsIDNSService::RESOLVE_TYPE_DEFAULT,
734 mRec->flags | nsIDNSService::RESOLVE_IP_HINT, AF_UNSPEC0, mRec->pb,
735 mRec->originSuffix, getter_AddRefs(hostRecord));
736 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
737 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)
;
738 return;
739 }
740
741 mHostResolver->MaybeRenewHostRecord(hostRecord);
742
743 RefPtr<AddrInfo> ai(new AddrInfo(aSVCBRecord.mSvcDomainName, ResolverType(),
744 TRRTYPE_A, std::move(addresses), mTTL));
745
746 // Since we're not actually calling NameLookup for this record, we need
747 // to set these fields to avoid assertions in CompleteLookup.
748 // This is quite hacky, and should be fixed.
749 hostRecord->mResolving++;
750 hostRecord->mEffectiveTRRMode =
751 static_cast<nsIRequest::TRRMode>(mRec->mEffectiveTRRMode);
752 (void)mHostResolver->CompleteLookup(hostRecord, NS_OK, ai, mPB, mOriginSuffix,
753 TRRSkippedReason::TRR_OK, this);
754}
755
756nsresult TRR::ReturnData(nsIChannel* aChannel) {
757 Maybe<TimeDuration> trrFetchDuration;
758 Maybe<TimeDuration> trrFetchDurationNetworkOnly;
759 // Set timings.
760 nsCOMPtr<nsITimedChannel> timedChan = do_QueryInterface(aChannel);
761 if (timedChan) {
762 TimeStamp asyncOpen, start, end;
763 if (NS_SUCCEEDED(timedChan->GetAsyncOpen(&asyncOpen))((bool)(__builtin_expect(!!(!NS_FAILED_impl(timedChan->GetAsyncOpen
(&asyncOpen))), 1)))
&&
764 !asyncOpen.IsNull()) {
765 trrFetchDuration = Some(TimeStamp::Now() - asyncOpen);
766 }
767 if (NS_SUCCEEDED(timedChan->GetRequestStart(&start))((bool)(__builtin_expect(!!(!NS_FAILED_impl(timedChan->GetRequestStart
(&start))), 1)))
&&
768 NS_SUCCEEDED(timedChan->GetResponseEnd(&end))((bool)(__builtin_expect(!!(!NS_FAILED_impl(timedChan->GetResponseEnd
(&end))), 1)))
&& !start.IsNull() &&
769 !end.IsNull()) {
770 trrFetchDurationNetworkOnly = Some(end - start);
771 }
772 }
773
774 if (mType != TRRTYPE_TXT && mType != TRRTYPE_HTTPSSVC) {
775 // create and populate an AddrInfo instance to pass on
776 RefPtr<AddrInfo> ai(new AddrInfo(mHost, ResolverType(), mType,
777 nsTArray<NetAddr>(), mDNS.mTtl));
778 auto builder = ai->Build();
779 builder.SetAddresses(std::move(mDNS.mAddresses));
780 builder.SetCanonicalHostname(mCname);
781 if (trrFetchDuration) {
782 builder.SetTrrFetchDuration((*trrFetchDuration).ToMilliseconds());
783 }
784 if (trrFetchDurationNetworkOnly) {
785 builder.SetTrrFetchDurationNetworkOnly(
786 (*trrFetchDurationNetworkOnly).ToMilliseconds());
787 }
788 ai = builder.Finish();
789
790 if (!mHostResolver) {
791 return NS_ERROR_FAILURE;
792 }
793 RecordReason(TRRSkippedReason::TRR_OK);
794 (void)mHostResolver->CompleteLookup(mRec, NS_OK, ai, mPB, mOriginSuffix,
795 mTRRSkippedReason, this);
796 mHostResolver = nullptr;
797 mRec = nullptr;
798 } else {
799 RecordReason(TRRSkippedReason::TRR_OK);
800 (void)mHostResolver->CompleteLookupByType(mRec, NS_OK, mResult,
801 mTRRSkippedReason, mTTL, mPB);
802 }
803
804 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
805 if (httpChannel) {
806 nsAutoCString version;
807 if (NS_SUCCEEDED(httpChannel->GetProtocolVersion(version))((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetProtocolVersion
(version))), 1)))
) {
808 nsAutoCString key("h1"_ns);
809 if (version.Equals("h3"_ns)) {
810 key.Assign("h3"_ns);
811 } else if (version.Equals("h2"_ns)) {
812 key.Assign("h2"_ns);
813 }
814
815 if (trrFetchDuration) {
816 glean::networking::trr_fetch_duration.Get(key).AccumulateRawDuration(
817 *trrFetchDuration);
818 }
819 if (trrFetchDurationNetworkOnly) {
820 key.Append("_network_only"_ns);
821 glean::networking::trr_fetch_duration.Get(key).AccumulateRawDuration(
822 *trrFetchDurationNetworkOnly);
823 }
824 }
825 }
826 return NS_OK;
827}
828
829nsresult TRR::FailData(nsresult error) {
830 if (!mHostResolver) {
831 return NS_ERROR_FAILURE;
832 }
833
834 // If we didn't record a reason until now, record a default one.
835 RecordReason(TRRSkippedReason::TRR_FAILED);
836
837 if (mType == TRRTYPE_TXT || mType == TRRTYPE_HTTPSSVC) {
838 TypeRecordResultType empty(Nothing{});
839 (void)mHostResolver->CompleteLookupByType(mRec, error, empty,
840 mTRRSkippedReason, 0, mPB);
841 } else {
842 // create and populate an TRR AddrInfo instance to pass on to signal that
843 // this comes from TRR
844 nsTArray<NetAddr> noAddresses;
845 RefPtr<AddrInfo> ai =
846 new AddrInfo(mHost, ResolverType(), mType, std::move(noAddresses));
847
848 (void)mHostResolver->CompleteLookup(mRec, error, ai, mPB, mOriginSuffix,
849 mTRRSkippedReason, this);
850 }
851
852 mHostResolver = nullptr;
853 mRec = nullptr;
854 return NS_OK;
855}
856
857void TRR::HandleDecodeError(nsresult aStatusCode) {
858 auto rcode = mPacket->GetRCode();
859 if (rcode.isOk() && rcode.unwrap() != 0) {
860 if (rcode.unwrap() == 0x03) {
861 RecordReason(TRRSkippedReason::TRR_NXDOMAIN);
862 } else {
863 RecordReason(TRRSkippedReason::TRR_RCODE_FAIL);
864 }
865 } else if (aStatusCode == NS_ERROR_UNKNOWN_HOST ||
866 aStatusCode == NS_ERROR_DEFINITIVE_UNKNOWN_HOST) {
867 RecordReason(TRRSkippedReason::TRR_NO_ANSWERS);
868 } else {
869 RecordReason(TRRSkippedReason::TRR_DECODE_FAILED);
870 }
871}
872
873bool TRR::HasUsableResponse() {
874 if (mType == TRRTYPE_A || mType == TRRTYPE_AAAA) {
875 return !mDNS.mAddresses.IsEmpty();
876 }
877 if (mType == TRRTYPE_TXT) {
878 return mResult.is<TypeRecordTxt>();
879 }
880 if (mType == TRRTYPE_HTTPSSVC) {
881 return mResult.is<TypeRecordHTTPSSVC>();
882 }
883 return false;
884}
885
886nsresult TRR::FollowCname(nsIChannel* aChannel) {
887 nsresult rv = NS_OK;
888 nsAutoCString cname;
889 while (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && mDNS.mAddresses.IsEmpty() && !mCname.IsEmpty() &&
890 mCnameLoop > 0) {
891 mCnameLoop--;
892 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)
893 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)
;
894 cname = mCname;
895 mCname.Truncate();
896
897 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)
898 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)
;
899 nsClassHashtable<nsCStringHashKey, DOHresp> additionalRecords;
900 rv = GetOrCreateDNSPacket()->Decode(
901 cname, mType, mCname, StaticPrefs::network_trr_allow_rfc1918(), mDNS,
902 mResult, additionalRecords, mTTL);
903 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
904 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)
;
905 HandleDecodeError(rv);
906 }
907 }
908
909 // restore mCname as DohDecode() change it
910 mCname = cname;
911 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && HasUsableResponse()) {
912 ReturnData(aChannel);
913 return NS_OK;
914 }
915
916 bool ra = mPacket && mPacket->RecursionAvailable().unwrapOr(false);
917 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)
;
918 if (rv == NS_ERROR_UNKNOWN_HOST && ra) {
919 // If recursion is available, but no addresses have been returned,
920 // we can just return a failure here.
921 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)
;
922 FailData(NS_ERROR_UNKNOWN_HOST);
923 return NS_OK;
924 }
925
926 if (!mCnameLoop) {
927 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)
;
928 return NS_ERROR_REDIRECT_LOOP;
929 }
930
931 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)
932 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)
;
933 RefPtr<TRR> trr =
934 new TRR(mHostResolver, mRec, mCname, mType, mCnameLoop, mPB);
935 trr->SetPurpose(mPurpose);
936 if (!TRRService::Get()) {
937 return NS_ERROR_FAILURE;
938 }
939 return TRRService::Get()->DispatchTRRRequest(trr);
940}
941
942nsresult TRR::On200Response(nsIChannel* aChannel) {
943 // decode body and create an AddrInfo struct for the response
944 nsClassHashtable<nsCStringHashKey, DOHresp> additionalRecords;
945 if (RefPtr<TypeHostRecord> typeRec = do_QueryObject(mRec)) {
946 MutexAutoLock lock(typeRec->mResultsLock);
947 if (typeRec->mOriginHost) {
948 GetOrCreateDNSPacket()->SetOriginHost(typeRec->mOriginHost);
949 }
950 }
951 nsresult rv = GetOrCreateDNSPacket()->Decode(
952 mHost, mType, mCname, StaticPrefs::network_trr_allow_rfc1918(), mDNS,
953 mResult, additionalRecords, mTTL);
954 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
955 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
)
;
956 HandleDecodeError(rv);
957 return rv;
958 }
959 if (StaticPrefs::network_trr_add_additional_records()) {
960 SaveAdditionalRecords(additionalRecords);
961 }
962
963 if (mResult.is<TypeRecordHTTPSSVC>()) {
964 auto& results = mResult.as<TypeRecordHTTPSSVC>();
965 for (const auto& rec : results) {
966 StoreIPHintAsDNSRecord(rec);
967 }
968 }
969
970 if (!mDNS.mAddresses.IsEmpty() || mType == TRRTYPE_TXT || mCname.IsEmpty()) {
971 // pass back the response data
972 ReturnData(aChannel);
973 return NS_OK;
974 }
975
976 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)
;
977 return FollowCname(aChannel);
978}
979
980void TRR::RecordProcessingTime(nsIChannel* aChannel) {
981 // This method records the time it took from the last received byte of the
982 // DoH response until we've notified the consumer with a host record.
983 nsCOMPtr<nsITimedChannel> timedChan = do_QueryInterface(aChannel);
984 if (!timedChan) {
985 return;
986 }
987 TimeStamp end;
988 if (NS_FAILED(timedChan->GetResponseEnd(&end))((bool)(__builtin_expect(!!(NS_FAILED_impl(timedChan->GetResponseEnd
(&end))), 0)))
) {
989 return;
990 }
991
992 if (end.IsNull()) {
993 return;
994 }
995
996 Telemetry::AccumulateTimeDelta(Telemetry::DNS_TRR_PROCESSING_TIME, end);
997
998 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)
999 (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)
;
1000}
1001
1002void TRR::ReportStatus(nsresult aStatusCode) {
1003 // If the TRR was cancelled by nsHostResolver, then we don't need to report
1004 // it as failed; otherwise it can cause the confirmation to fail.
1005 if (UseDefaultServer() && aStatusCode != NS_ERROR_ABORT) {
1006 // Bad content is still considered "okay" if the HTTP response is okay
1007 TRRService::Get()->RecordTRRStatus(this);
1008 }
1009}
1010
1011static void RecordHttpVersion(nsIHttpChannel* aHttpChannel) {
1012 nsCOMPtr<nsIHttpChannelInternal> internalChannel =
1013 do_QueryInterface(aHttpChannel);
1014 if (!internalChannel) {
1015 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)
;
1016 return;
1017 }
1018
1019 uint32_t major, minor;
1020 if (NS_FAILED(internalChannel->GetResponseVersion(&major, &minor))((bool)(__builtin_expect(!!(NS_FAILED_impl(internalChannel->
GetResponseVersion(&major, &minor))), 0)))
) {
1021 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)
;
1022 return;
1023 }
1024
1025 auto label = Telemetry::LABELS_DNS_TRR_HTTP_VERSION2::h_1;
1026 if (major == 2) {
1027 label = Telemetry::LABELS_DNS_TRR_HTTP_VERSION2::h_2;
1028 } else if (major == 3) {
1029 label = Telemetry::LABELS_DNS_TRR_HTTP_VERSION2::h_3;
1030 }
1031
1032 Telemetry::AccumulateCategoricalKeyed(TRRService::ProviderKey(), label);
1033
1034 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)
;
1035}
1036
1037NS_IMETHODIMPnsresult
1038TRR::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
1039 // The dtor will be run after the function returns
1040 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)
1041 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)
;
1042 nsCOMPtr<nsIChannel> channel;
1043 channel.swap(mChannel);
1044
1045 mChannelStatus = aStatusCode;
1046 if (NS_SUCCEEDED(aStatusCode)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatusCode)), 1)
))
) {
1047 nsCString label = "regular"_ns;
1048 if (mPB) {
1049 label = "private"_ns;
1050 }
1051 mozilla::glean::networking::trr_request_count.Get(label).Add(1);
1052 }
1053
1054 {
1055 // Cancel the timer since we don't need it anymore.
1056 nsCOMPtr<nsITimer> timer;
1057 mTimeout.swap(timer);
1058 if (timer) {
1059 timer->Cancel();
1060 }
1061 }
1062
1063 auto scopeExit = MakeScopeExit([&] { ReportStatus(aStatusCode); });
1064
1065 nsresult rv = NS_OK;
1066 // if status was "fine", parse the response and pass on the answer
1067 if (!mFailed && NS_SUCCEEDED(aStatusCode)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatusCode)), 1)
))
) {
1068 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
1069 if (!httpChannel) {
1070 return NS_ERROR_UNEXPECTED;
1071 }
1072 nsAutoCString contentType;
1073 httpChannel->GetContentType(contentType);
1074 if (contentType.Length() &&
1075 !contentType.LowerCaseEqualsASCII(ContentType())) {
1076 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)
1077 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)
;
1078 FailData(NS_ERROR_UNEXPECTED);
1079 return NS_OK;
1080 }
1081
1082 uint32_t httpStatus;
1083 rv = httpChannel->GetResponseStatus(&httpStatus);
1084 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && httpStatus == 200) {
1085 rv = On200Response(channel);
1086 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && UseDefaultServer()) {
1087 RecordReason(TRRSkippedReason::TRR_OK);
1088 RecordProcessingTime(channel);
1089 RecordHttpVersion(httpChannel);
1090 return rv;
1091 }
1092 } else {
1093 RecordReason(TRRSkippedReason::TRR_SERVER_RESPONSE_ERR);
1094 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", 1094, this
, (int)rv, httpStatus); } } while (0)
1095 (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", 1094, this
, (int)rv, httpStatus); } } while (0)
;
1096 }
1097 }
1098
1099 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)
1100 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)
;
1101 FailData(NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) ? NS_ERROR_UNKNOWN_HOST : rv);
1102 return NS_OK;
1103}
1104
1105NS_IMETHODIMPnsresult
1106TRR::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
1107 uint64_t aOffset, const uint32_t aCount) {
1108 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)
1109 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)
;
1110 // receive DNS response into the local buffer
1111 if (mFailed) {
1112 return NS_ERROR_FAILURE;
1113 }
1114
1115 nsresult rv = GetOrCreateDNSPacket()->OnDataAvailable(aRequest, aInputStream,
1116 aOffset, aCount);
1117 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1118 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", 1118); } } while (0)
;
1119 mFailed = true;
1120 return rv;
1121 }
1122 return NS_OK;
1123}
1124
1125void TRR::Cancel(nsresult aStatus) {
1126 bool isTRRServiceChannel = false;
1127 nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal(
1128 do_QueryInterface(mChannel));
1129 if (httpChannelInternal) {
1130 nsresult rv =
1131 httpChannelInternal->GetIsTRRServiceChannel(&isTRRServiceChannel);
1132 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1133 isTRRServiceChannel = false;
1134 }
1135 }
1136 // nsHttpChannel can be only canceled on the main thread.
1137 RefPtr<nsHttpChannel> httpChannel = do_QueryObject(mChannel);
1138 if (isTRRServiceChannel && !XRE_IsSocketProcess() && !httpChannel) {
1139 if (TRRService::Get()) {
1140 nsCOMPtr<nsIThread> thread = TRRService::Get()->TRRThread();
1141 if (thread && !thread->IsOnCurrentThread()) {
1142 thread->Dispatch(NS_NewRunnableFunction(
1143 "TRR::Cancel",
1144 [self = RefPtr(this), aStatus]() { self->Cancel(aStatus); }));
1145 return;
1146 }
1147 }
1148 } else {
1149 if (!NS_IsMainThread()) {
1150 NS_DispatchToMainThread(NS_NewRunnableFunction(
1151 "TRR::Cancel",
1152 [self = RefPtr(this), aStatus]() { self->Cancel(aStatus); }));
1153 return;
1154 }
1155 }
1156
1157 if (mCancelled) {
1158 return;
1159 }
1160 mCancelled = true;
1161
1162 if (mChannel) {
1163 RecordReason(TRRSkippedReason::TRR_REQ_CANCELLED);
1164 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)
1165 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)
;
1166 mChannel->Cancel(aStatus);
1167 }
1168}
1169
1170bool TRR::UseDefaultServer() { return !mRec || mRec->mTrrServer.IsEmpty(); }
1171
1172} // namespace net
1173} // namespace mozilla