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 
13 namespace mozilla {
14 namespace net {
15 
16 enum SvcParamKey : uint16_t {
17   SvcParamKeyMandatory = 0,
18   SvcParamKeyAlpn = 1,
19   SvcParamKeyNoDefaultAlpn = 2,
20   SvcParamKeyPort = 3,
21   SvcParamKeyIpv4Hint = 4,
22   SvcParamKeyEchConfig = 5,
23   SvcParamKeyIpv6Hint = 6,
24   SvcParamKeyODoHConfig = 32769,
25 };
26 
27 inline bool IsValidSvcParamKey(uint16_t aKey) {
28   return aKey <= SvcParamKeyIpv6Hint || aKey == SvcParamKeyODoHConfig;
29 }
30 
31 struct SvcParamAlpn {
32   bool operator==(const SvcParamAlpn& aOther) const {
33     return mValue == aOther.mValue;
34   }
35   CopyableTArray<nsCString> mValue;
36 };
37 
38 struct SvcParamNoDefaultAlpn {
39   bool operator==(const SvcParamNoDefaultAlpn& aOther) const { return true; }
40 };
41 
42 struct SvcParamPort {
43   bool operator==(const SvcParamPort& aOther) const {
44     return mValue == aOther.mValue;
45   }
46   uint16_t mValue;
47 };
48 
49 struct SvcParamIpv4Hint {
50   bool operator==(const SvcParamIpv4Hint& aOther) const {
51     return mValue == aOther.mValue;
52   }
53   CopyableTArray<mozilla::net::NetAddr> mValue;
54 };
55 
56 struct SvcParamEchConfig {
57   bool operator==(const SvcParamEchConfig& aOther) const {
58     return mValue == aOther.mValue;
59   }
60   nsCString mValue;
61 };
62 
63 struct SvcParamIpv6Hint {
64   bool operator==(const SvcParamIpv6Hint& aOther) const {
65     return mValue == aOther.mValue;
66   }
67   CopyableTArray<mozilla::net::NetAddr> mValue;
68 };
69 
70 struct SvcParamODoHConfig {
71   bool operator==(const SvcParamODoHConfig& aOther) const {
72     return mValue == aOther.mValue;
73   }
74   nsCString mValue;
75 };
76 
77 using SvcParamType =
78     mozilla::Variant<Nothing, SvcParamAlpn, SvcParamNoDefaultAlpn, SvcParamPort,
79                      SvcParamIpv4Hint, SvcParamEchConfig, SvcParamIpv6Hint,
80                      SvcParamODoHConfig>;
81 
82 struct SvcFieldValue {
83   bool operator==(const SvcFieldValue& aOther) const {
84     return mValue == aOther.mValue;
85   }
86   SvcFieldValue() : mValue(AsVariant(Nothing{})) {}
87   SvcParamType mValue;
88 };
89 
90 struct SVCB {
91   bool operator==(const SVCB& aOther) const {
92     return mSvcFieldPriority == aOther.mSvcFieldPriority &&
93            mSvcDomainName == aOther.mSvcDomainName &&
94            mSvcFieldValue == aOther.mSvcFieldValue;
95   }
96   bool operator<(const SVCB& aOther) const;
97   Maybe<uint16_t> GetPort() const;
98   bool NoDefaultAlpn() const;
99   Maybe<Tuple<nsCString, bool>> GetAlpn(bool aNoHttp2, bool aNoHttp3) const;
100   void GetIPHints(CopyableTArray<mozilla::net::NetAddr>& aAddresses) const;
101   uint16_t mSvcFieldPriority = 0;
102   nsCString mSvcDomainName;
103   nsCString mEchConfig;
104   nsCString mODoHConfig;
105   bool mHasIPHints = false;
106   bool mHasEchConfig = false;
107   CopyableTArray<SvcFieldValue> mSvcFieldValue;
108 };
109 
110 class SVCBRecord : public nsISVCBRecord {
111   NS_DECL_THREADSAFE_ISUPPORTS
112   NS_DECL_NSISVCBRECORD
113  public:
114   explicit SVCBRecord(const SVCB& data)
115       : mData(data), mPort(Nothing()), mAlpn(Nothing()) {}
116   explicit SVCBRecord(const SVCB& data, Maybe<uint16_t>&& aPort,
117                       Maybe<Tuple<nsCString, bool>>&& aAlpn)
118       : mData(data), mPort(std::move(aPort)), mAlpn(std::move(aAlpn)) {}
119 
120  private:
121   virtual ~SVCBRecord() = default;
122   SVCB mData;
123   Maybe<uint16_t> mPort;
124   Maybe<Tuple<nsCString, bool>> mAlpn;
125 };
126 
127 class DNSHTTPSSVCRecordBase {
128  public:
129   explicit DNSHTTPSSVCRecordBase(const nsACString& aHost) : mHost(aHost) {}
130 
131  protected:
132   virtual ~DNSHTTPSSVCRecordBase() = default;
133 
134   already_AddRefed<nsISVCBRecord> GetServiceModeRecordInternal(
135       bool aNoHttp2, bool aNoHttp3, const nsTArray<SVCB>& aRecords,
136       bool& aRecordsAllExcluded, bool aCheckHttp3ExcludedList = true);
137 
138   bool HasIPAddressesInternal(const nsTArray<SVCB>& aRecords);
139 
140   void GetAllRecordsWithEchConfigInternal(
141       bool aNoHttp2, bool aNoHttp3, const nsTArray<SVCB>& aRecords,
142       bool* aAllRecordsHaveEchConfig, bool* aAllRecordsInH3ExcludedList,
143       nsTArray<RefPtr<nsISVCBRecord>>& aResult,
144       bool aCheckHttp3ExcludedList = true);
145 
146   // The owner name of this HTTPS RR.
147   nsCString mHost;
148 };
149 
150 }  // namespace net
151 }  // namespace mozilla
152 
153 #endif  // HTTPSSVC_h__
154