TRR.h (4910B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set sw=2 ts=8 et tw=80 : */ 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 #ifndef mozilla_net_TRR_h 8 #define mozilla_net_TRR_h 9 10 #include "mozilla/net/DNSByTypeRecord.h" 11 #include "nsClassHashtable.h" 12 #include "nsIChannel.h" 13 #include "nsIInterfaceRequestor.h" 14 #include "nsIStreamListener.h" 15 #include "nsThreadUtils.h" 16 #include "nsXULAppAPI.h" 17 #include "DNSPacket.h" 18 #include "nsITRRSkipReason.h" 19 20 class AHostResolver; 21 class nsHostRecord; 22 23 namespace mozilla { 24 namespace net { 25 26 class TRRService; 27 class TRRServiceChannel; 28 29 class TRR : public Runnable, public nsITimerCallback, public nsIStreamListener { 30 public: 31 NS_DECL_ISUPPORTS_INHERITED 32 NS_DECL_NSIREQUESTOBSERVER 33 NS_DECL_NSISTREAMLISTENER 34 NS_DECL_NSITIMERCALLBACK 35 36 // Number of "steps" we follow CNAME chains 37 static const unsigned int kCnameChaseMax = 64; 38 39 // when firing off a normal A or AAAA query 40 explicit TRR(AHostResolver* aResolver, nsHostRecord* aRec, 41 enum TrrType aType); 42 // when following CNAMEs 43 explicit TRR(AHostResolver* aResolver, nsHostRecord* aRec, nsCString& aHost, 44 enum TrrType& aType, unsigned int aLoopCount, bool aPB); 45 // to verify a domain 46 explicit TRR(AHostResolver* aResolver, nsACString& aHost, enum TrrType aType, 47 const nsACString& aOriginSuffix, bool aPB, 48 bool aUseFreshConnection); 49 50 NS_IMETHOD Run() override; 51 void Cancel(nsresult aStatus); 52 enum TrrType Type() { return mType; } 53 nsCString mHost; 54 RefPtr<nsHostRecord> mRec; 55 RefPtr<AHostResolver> mHostResolver; 56 57 void SetTimeout(uint32_t aTimeoutMs) { mTimeoutMs = aTimeoutMs; } 58 59 nsresult ChannelStatus() { return mChannelStatus; } 60 61 enum RequestPurpose { 62 Resolve, 63 Confirmation, 64 Blocklist, 65 }; 66 67 RequestPurpose Purpose() { return mPurpose; } 68 void SetPurpose(RequestPurpose aPurpose) { mPurpose = aPurpose; } 69 TRRSkippedReason SkipReason() const { return mTRRSkippedReason; } 70 71 protected: 72 virtual ~TRR() = default; 73 virtual DNSPacket* GetOrCreateDNSPacket(); 74 virtual nsresult CreateQueryURI(nsIURI** aOutURI); 75 virtual const char* ContentType() const { return "application/dns-message"; } 76 virtual DNSResolverType ResolverType() const { return DNSResolverType::TRR; } 77 virtual bool MaybeBlockRequest(); 78 virtual void RecordProcessingTime(nsIChannel* aChannel); 79 virtual void ReportStatus(nsresult aStatusCode); 80 virtual void HandleTimeout(); 81 virtual void HandleEncodeError(nsresult aStatusCode) {} 82 virtual void HandleDecodeError(nsresult aStatusCode); 83 nsresult SendHTTPRequest(); 84 nsresult ReturnData(nsIChannel* aChannel); 85 86 // FailData() must be called to signal that the asynch TRR resolve is 87 // completed. For failed name resolves ("no such host"), the 'error' it 88 // passses on in its argument must be NS_ERROR_UNKNOWN_HOST. Other errors 89 // (if host was blocklisted, there as a bad content-type received, etc) 90 // other error codes must be used. This distinction is important for the 91 // subsequent logic to separate the error reasons. 92 nsresult FailData(nsresult error); 93 nsresult On200Response(nsIChannel* aChannel); 94 nsresult FollowCname(nsIChannel* aChannel); 95 96 bool HasUsableResponse(); 97 98 bool UseDefaultServer(); 99 void SaveAdditionalRecords( 100 const nsClassHashtable<nsCStringHashKey, DOHresp>& aRecords); 101 102 friend class TRRServiceChannel; 103 static nsresult SetupTRRServiceChannelInternal( 104 nsIHttpChannel* aChannel, bool aUseGet, const nsACString& aContentType); 105 106 void StoreIPHintAsDNSRecord(const struct SVCB& aSVCBRecord); 107 108 nsCOMPtr<nsIChannel> mChannel; 109 enum TrrType mType { TRRTYPE_A }; 110 UniquePtr<DNSPacket> mPacket; 111 bool mFailed = false; 112 bool mPB = false; 113 DOHresp mDNS; 114 nsresult mChannelStatus = NS_OK; 115 116 RequestPurpose mPurpose = Resolve; 117 Atomic<bool, Relaxed> mCancelled{false}; 118 119 // The request timeout in milliseconds. If 0 we will use the default timeout 120 // we get from the prefs. 121 uint32_t mTimeoutMs = 0; 122 nsCOMPtr<nsITimer> mTimeout; 123 nsCString mCname; 124 uint32_t mCnameLoop = kCnameChaseMax; // loop detection counter 125 126 uint32_t mTTL = UINT32_MAX; 127 TypeRecordResultType mResult = mozilla::AsVariant(Nothing()); 128 129 TRRSkippedReason mTRRSkippedReason = TRRSkippedReason::TRR_UNSET; 130 void RecordReason(TRRSkippedReason reason) { 131 if (mTRRSkippedReason == TRRSkippedReason::TRR_UNSET) { 132 mTRRSkippedReason = reason; 133 } 134 } 135 136 // keep a copy of the originSuffix for the cases where mRec == nullptr */ 137 const nsCString mOriginSuffix; 138 139 // If true, we set LOAD_FRESH_CONNECTION on our channel's load flags. 140 bool mUseFreshConnection = false; 141 }; 142 143 } // namespace net 144 } // namespace mozilla 145 146 #endif // include guard