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/. */
7 #ifndef mozilla_net_TRR_h
8 #define mozilla_net_TRR_h
10 #include "mozilla/net/DNSByTypeRecord.h"
11 #include "mozilla/Assertions.h"
12 #include "nsClassHashtable.h"
13 #include "nsIChannel.h"
14 #include "nsIHttpPushListener.h"
15 #include "nsIInterfaceRequestor.h"
16 #include "nsIStreamListener.h"
17 #include "nsThreadUtils.h"
18 #include "nsXULAppAPI.h"
19 #include "DNSPacket.h"
20 #include "TRRSkippedReason.h"
29 class TRRServiceChannel
;
31 class TRR
: public Runnable
,
32 public nsITimerCallback
,
33 public nsIHttpPushListener
,
34 public nsIInterfaceRequestor
,
35 public nsIStreamListener
{
37 NS_DECL_ISUPPORTS_INHERITED
38 NS_DECL_NSIHTTPPUSHLISTENER
39 NS_DECL_NSIINTERFACEREQUESTOR
40 NS_DECL_NSIREQUESTOBSERVER
41 NS_DECL_NSISTREAMLISTENER
42 NS_DECL_NSITIMERCALLBACK
44 // Number of "steps" we follow CNAME chains
45 static const unsigned int kCnameChaseMax
= 64;
47 // when firing off a normal A or AAAA query
48 explicit TRR(AHostResolver
* aResolver
, nsHostRecord
* aRec
,
50 // when following CNAMEs
51 explicit TRR(AHostResolver
* aResolver
, nsHostRecord
* aRec
, nsCString
& aHost
,
52 enum TrrType
& aType
, unsigned int aLoopCount
, bool aPB
);
54 explicit TRR(AHostResolver
* aResolver
, bool aPB
);
56 explicit TRR(AHostResolver
* aResolver
, nsACString
& aHost
, enum TrrType aType
,
57 const nsACString
& aOriginSuffix
, bool aPB
,
58 bool aUseFreshConnection
);
60 NS_IMETHOD
Run() override
;
61 void Cancel(nsresult aStatus
);
62 enum TrrType
Type() { return mType
; }
64 RefPtr
<nsHostRecord
> mRec
;
65 RefPtr
<AHostResolver
> mHostResolver
;
67 void SetTimeout(uint32_t aTimeoutMs
) { mTimeoutMs
= aTimeoutMs
; }
69 nsresult
ChannelStatus() { return mChannelStatus
; }
77 RequestPurpose
Purpose() { return mPurpose
; }
78 void SetPurpose(RequestPurpose aPurpose
) { mPurpose
= aPurpose
; }
81 virtual ~TRR() = default;
82 virtual DNSPacket
* GetOrCreateDNSPacket();
83 virtual nsresult
CreateQueryURI(nsIURI
** aOutURI
);
84 virtual const char* ContentType() const { return "application/dns-message"; }
85 virtual DNSResolverType
ResolverType() const { return DNSResolverType::TRR
; }
86 virtual bool MaybeBlockRequest();
87 virtual void RecordProcessingTime(nsIChannel
* aChannel
);
88 virtual void ReportStatus(nsresult aStatusCode
);
89 virtual void HandleTimeout();
90 virtual void HandleEncodeError(nsresult aStatusCode
) {}
91 virtual void HandleDecodeError(nsresult aStatusCode
);
92 nsresult
SendHTTPRequest();
93 nsresult
ReturnData(nsIChannel
* aChannel
);
95 // FailData() must be called to signal that the asynch TRR resolve is
96 // completed. For failed name resolves ("no such host"), the 'error' it
97 // passses on in its argument must be NS_ERROR_UNKNOWN_HOST. Other errors
98 // (if host was blocklisted, there as a bad content-type received, etc)
99 // other error codes must be used. This distinction is important for the
100 // subsequent logic to separate the error reasons.
101 nsresult
FailData(nsresult error
);
102 static nsresult
DohDecodeQuery(const nsCString
& query
, nsCString
& host
,
104 nsresult
ReceivePush(nsIHttpChannel
* pushed
, nsHostRecord
* pushedRec
);
105 nsresult
On200Response(nsIChannel
* aChannel
);
106 nsresult
FollowCname(nsIChannel
* aChannel
);
108 bool HasUsableResponse();
110 bool UseDefaultServer();
111 void SaveAdditionalRecords(
112 const nsClassHashtable
<nsCStringHashKey
, DOHresp
>& aRecords
);
114 friend class TRRServiceChannel
;
115 static nsresult
SetupTRRServiceChannelInternal(
116 nsIHttpChannel
* aChannel
, bool aUseGet
, const nsACString
& aContentType
);
118 void StoreIPHintAsDNSRecord(const struct SVCB
& aSVCBRecord
);
120 nsCOMPtr
<nsIChannel
> mChannel
;
121 enum TrrType mType
{ TRRTYPE_A
};
122 UniquePtr
<DNSPacket
> mPacket
;
123 bool mFailed
= false;
126 nsresult mChannelStatus
= NS_OK
;
128 RequestPurpose mPurpose
= Resolve
;
129 Atomic
<bool, Relaxed
> mCancelled
{false};
131 // The request timeout in milliseconds. If 0 we will use the default timeout
132 // we get from the prefs.
133 uint32_t mTimeoutMs
= 0;
134 nsCOMPtr
<nsITimer
> mTimeout
;
136 uint32_t mCnameLoop
= kCnameChaseMax
; // loop detection counter
138 uint32_t mTTL
= UINT32_MAX
;
139 TypeRecordResultType mResult
= mozilla::AsVariant(Nothing());
141 TRRSkippedReason mTRRSkippedReason
= TRRSkippedReason::TRR_UNSET
;
142 void RecordReason(TRRSkippedReason reason
) {
143 if (mTRRSkippedReason
== TRRSkippedReason::TRR_UNSET
) {
144 mTRRSkippedReason
= reason
;
148 // keep a copy of the originSuffix for the cases where mRec == nullptr */
149 const nsCString mOriginSuffix
;
151 // If true, we set LOAD_FRESH_CONNECTION on our channel's load flags.
152 bool mUseFreshConnection
= false;
156 } // namespace mozilla
158 #endif // include guard