1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #ifndef HTTPSSVC_h__
6 #define HTTPSSVC_h__
7
8 #include "nsIDNSByTypeRecord.h"
9 #include "mozilla/net/DNS.h"
10 #include "mozilla/Variant.h"
11 #include "mozilla/Maybe.h"
12 #include "nsHttp.h"
13
14 namespace mozilla {
15 namespace net {
16
17 class DNSHTTPSSVCRecordBase;
18
19 enum SvcParamKey : uint16_t {
20 SvcParamKeyMandatory = 0,
21 SvcParamKeyAlpn = 1,
22 SvcParamKeyNoDefaultAlpn = 2,
23 SvcParamKeyPort = 3,
24 SvcParamKeyIpv4Hint = 4,
25 SvcParamKeyEchConfig = 5,
26 SvcParamKeyIpv6Hint = 6,
27 SvcParamKeyODoHConfig = 32769,
28 };
29
IsValidSvcParamKey(uint16_t aKey)30 inline bool IsValidSvcParamKey(uint16_t aKey) {
31 return aKey <= SvcParamKeyIpv6Hint || aKey == SvcParamKeyODoHConfig;
32 }
33
34 struct SvcParamAlpn {
35 bool operator==(const SvcParamAlpn& aOther) const {
36 return mValue == aOther.mValue;
37 }
38 CopyableTArray<nsCString> mValue;
39 };
40
41 struct SvcParamNoDefaultAlpn {
42 bool operator==(const SvcParamNoDefaultAlpn& aOther) const { return true; }
43 };
44
45 struct SvcParamPort {
46 bool operator==(const SvcParamPort& aOther) const {
47 return mValue == aOther.mValue;
48 }
49 uint16_t mValue;
50 };
51
52 struct SvcParamIpv4Hint {
53 bool operator==(const SvcParamIpv4Hint& aOther) const {
54 return mValue == aOther.mValue;
55 }
56 CopyableTArray<mozilla::net::NetAddr> mValue;
57 };
58
59 struct SvcParamEchConfig {
60 bool operator==(const SvcParamEchConfig& aOther) const {
61 return mValue == aOther.mValue;
62 }
63 nsCString mValue;
64 };
65
66 struct SvcParamIpv6Hint {
67 bool operator==(const SvcParamIpv6Hint& aOther) const {
68 return mValue == aOther.mValue;
69 }
70 CopyableTArray<mozilla::net::NetAddr> mValue;
71 };
72
73 struct SvcParamODoHConfig {
74 bool operator==(const SvcParamODoHConfig& aOther) const {
75 return mValue == aOther.mValue;
76 }
77 nsCString mValue;
78 };
79
80 using SvcParamType =
81 mozilla::Variant<Nothing, SvcParamAlpn, SvcParamNoDefaultAlpn, SvcParamPort,
82 SvcParamIpv4Hint, SvcParamEchConfig, SvcParamIpv6Hint,
83 SvcParamODoHConfig>;
84
85 struct SvcFieldValue {
86 bool operator==(const SvcFieldValue& aOther) const {
87 return mValue == aOther.mValue;
88 }
SvcFieldValueSvcFieldValue89 SvcFieldValue() : mValue(AsVariant(Nothing{})) {}
90 SvcParamType mValue;
91 };
92
93 struct SVCB {
94 bool operator==(const SVCB& aOther) const {
95 return mSvcFieldPriority == aOther.mSvcFieldPriority &&
96 mSvcDomainName == aOther.mSvcDomainName &&
97 mSvcFieldValue == aOther.mSvcFieldValue;
98 }
99 bool operator<(const SVCB& aOther) const;
100 Maybe<uint16_t> GetPort() const;
101 bool NoDefaultAlpn() const;
102 void GetIPHints(CopyableTArray<mozilla::net::NetAddr>& aAddresses) const;
103 nsTArray<Tuple<nsCString, SupportedAlpnRank>> GetAllAlpn() const;
104 uint16_t mSvcFieldPriority = 0;
105 nsCString mSvcDomainName;
106 nsCString mEchConfig;
107 nsCString mODoHConfig;
108 bool mHasIPHints = false;
109 bool mHasEchConfig = false;
110 CopyableTArray<SvcFieldValue> mSvcFieldValue;
111 };
112
113 struct SVCBWrapper {
SVCBWrapperSVCBWrapper114 explicit SVCBWrapper(const SVCB& aRecord) : mRecord(aRecord) {}
115 Maybe<Tuple<nsCString, SupportedAlpnRank>> mAlpn;
116 const SVCB& mRecord;
117 };
118
119 class SVCBRecord : public nsISVCBRecord {
120 NS_DECL_THREADSAFE_ISUPPORTS
121 NS_DECL_NSISVCBRECORD
122 public:
SVCBRecord(const SVCB & data)123 explicit SVCBRecord(const SVCB& data)
124 : mData(data), mPort(Nothing()), mAlpn(Nothing()) {}
125 explicit SVCBRecord(const SVCB& data,
126 Maybe<Tuple<nsCString, SupportedAlpnRank>> aAlpn);
127
128 private:
129 friend class DNSHTTPSSVCRecordBase;
130
131 virtual ~SVCBRecord() = default;
132
133 SVCB mData;
134 Maybe<uint16_t> mPort;
135 Maybe<Tuple<nsCString, SupportedAlpnRank>> mAlpn;
136 };
137
138 class DNSHTTPSSVCRecordBase {
139 public:
DNSHTTPSSVCRecordBase(const nsACString & aHost)140 explicit DNSHTTPSSVCRecordBase(const nsACString& aHost) : mHost(aHost) {}
141
142 protected:
143 virtual ~DNSHTTPSSVCRecordBase() = default;
144
145 already_AddRefed<nsISVCBRecord> GetServiceModeRecordInternal(
146 bool aNoHttp2, bool aNoHttp3, const nsTArray<SVCB>& aRecords,
147 bool& aRecordsAllExcluded, bool aCheckHttp3ExcludedList = true);
148
149 bool HasIPAddressesInternal(const nsTArray<SVCB>& aRecords);
150
151 void GetAllRecordsWithEchConfigInternal(
152 bool aNoHttp2, bool aNoHttp3, const nsTArray<SVCB>& aRecords,
153 bool* aAllRecordsHaveEchConfig, bool* aAllRecordsInH3ExcludedList,
154 nsTArray<RefPtr<nsISVCBRecord>>& aResult,
155 bool aCheckHttp3ExcludedList = true);
156
157 // The owner name of this HTTPS RR.
158 nsCString mHost;
159 };
160
161 } // namespace net
162 } // namespace mozilla
163
164 #endif // HTTPSSVC_h__
165