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