diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/dns/TRR.h | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/netwerk/dns/TRR.h b/netwerk/dns/TRR.h new file mode 100644 index 0000000000..489cca08b8 --- /dev/null +++ b/netwerk/dns/TRR.h @@ -0,0 +1,161 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_net_TRR_h +#define mozilla_net_TRR_h + +#include "mozilla/net/DNSByTypeRecord.h" +#include "mozilla/Assertions.h" +#include "nsClassHashtable.h" +#include "nsIChannel.h" +#include "nsIHttpPushListener.h" +#include "nsIInterfaceRequestor.h" +#include "nsIStreamListener.h" +#include "nsHostResolver.h" +#include "nsThreadUtils.h" +#include "nsXULAppAPI.h" +#include "DNSPacket.h" + +namespace mozilla { +namespace net { + +class TRRService; +class TRRServiceChannel; +extern TRRService* gTRRService; + +class TRR : public Runnable, + public nsITimerCallback, + public nsIHttpPushListener, + public nsIInterfaceRequestor, + public nsIStreamListener { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIHTTPPUSHLISTENER + NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSITIMERCALLBACK + + // Number of "steps" we follow CNAME chains + static const unsigned int kCnameChaseMax = 64; + + // when firing off a normal A or AAAA query + explicit TRR(AHostResolver* aResolver, nsHostRecord* aRec, enum TrrType aType) + : mozilla::Runnable("TRR"), + mRec(aRec), + mHostResolver(aResolver), + mType(aType), + mOriginSuffix(aRec->originSuffix) { + mHost = aRec->host; + mPB = aRec->pb; + MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(), + "TRR must be in parent or socket process"); + } + + // when following CNAMEs + explicit TRR(AHostResolver* aResolver, nsHostRecord* aRec, nsCString& aHost, + enum TrrType& aType, unsigned int aLoopCount, bool aPB) + : mozilla::Runnable("TRR"), + mHost(aHost), + mRec(aRec), + mHostResolver(aResolver), + mType(aType), + mPB(aPB), + mCnameLoop(aLoopCount), + mOriginSuffix(aRec ? aRec->originSuffix : ""_ns) { + MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(), + "TRR must be in parent or socket process"); + } + + // used on push + explicit TRR(AHostResolver* aResolver, bool aPB) + : mozilla::Runnable("TRR"), + mHostResolver(aResolver), + mType(TRRTYPE_A), + mPB(aPB) { + MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(), + "TRR must be in parent or socket process"); + } + + // to verify a domain + explicit TRR(AHostResolver* aResolver, nsACString& aHost, enum TrrType aType, + const nsACString& aOriginSuffix, bool aPB) + : mozilla::Runnable("TRR"), + mHost(aHost), + mRec(nullptr), + mHostResolver(aResolver), + mType(aType), + mPB(aPB), + mOriginSuffix(aOriginSuffix) { + MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess(), + "TRR must be in parent or socket process"); + } + + NS_IMETHOD Run() override; + void Cancel(); + enum TrrType Type() { return mType; } + nsCString mHost; + RefPtr<nsHostRecord> mRec; + RefPtr<AHostResolver> mHostResolver; + + private: + ~TRR() = default; + nsresult SendHTTPRequest(); + nsresult ReturnData(nsIChannel* aChannel); + + // FailData() must be called to signal that the asynch TRR resolve is + // completed. For failed name resolves ("no such host"), the 'error' it + // passses on in its argument must be NS_ERROR_UNKNOWN_HOST. Other errors + // (if host was blacklisted, there as a bad content-type received, etc) + // other error codes must be used. This distinction is important for the + // subsequent logic to separate the error reasons. + nsresult FailData(nsresult error); + static nsresult DohDecodeQuery(const nsCString& query, nsCString& host, + enum TrrType& type); + nsresult ReceivePush(nsIHttpChannel* pushed, nsHostRecord* pushedRec); + nsresult On200Response(nsIChannel* aChannel); + nsresult FollowCname(nsIChannel* aChannel); + + bool UseDefaultServer(); + void SaveAdditionalRecords( + const nsClassHashtable<nsCStringHashKey, DOHresp>& aRecords); + + nsresult CreateChannelHelper(nsIURI* aUri, nsIChannel** aResult); + + friend class TRRServiceChannel; + static nsresult SetupTRRServiceChannelInternal(nsIHttpChannel* aChannel, + bool aUseGet); + + void StoreIPHintAsDNSRecord(const struct SVCB& aSVCBRecord); + + nsCOMPtr<nsIChannel> mChannel; + enum TrrType mType; + DNSPacket mPacket; + bool mFailed = false; + bool mPB; + DOHresp mDNS; + nsCOMPtr<nsITimer> mTimeout; + nsCString mCname; + uint32_t mCnameLoop = kCnameChaseMax; // loop detection counter + + uint32_t mTTL = UINT32_MAX; + TypeRecordResultType mResult = mozilla::AsVariant(Nothing()); + + nsHostRecord::TRRSkippedReason mTRRSkippedReason = nsHostRecord::TRR_UNSET; + void RecordReason(nsHostRecord::TRRSkippedReason reason) { + if (mTRRSkippedReason == nsHostRecord::TRR_UNSET) { + mTRRSkippedReason = reason; + } + } + + // keep a copy of the originSuffix for the cases where mRec == nullptr */ + const nsCString mOriginSuffix; +}; + +} // namespace net +} // namespace mozilla + +#endif // include guard |