xref: /aosp_15_r20/external/cronet/net/network_error_logging/network_error_logging_service.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_NETWORK_ERROR_LOGGING_NETWORK_ERROR_LOGGING_SERVICE_H_
6 #define NET_NETWORK_ERROR_LOGGING_NETWORK_ERROR_LOGGING_SERVICE_H_
7 
8 #include <map>
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <vector>
13 
14 #include "base/feature_list.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/time/clock.h"
17 #include "base/time/time.h"
18 #include "net/base/ip_address.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/net_export.h"
21 #include "net/base/network_anonymization_key.h"
22 #include "url/gurl.h"
23 #include "url/origin.h"
24 
25 namespace base {
26 class Value;
27 }  // namespace base
28 
29 namespace net {
30 class ReportingService;
31 }  // namespace net
32 
33 namespace url {
34 class Origin;
35 }  // namespace url
36 
37 namespace features {
38 extern const base::Feature NET_EXPORT kNetworkErrorLogging;
39 }  // namespace features
40 
41 namespace net {
42 
43 class NET_EXPORT NetworkErrorLoggingService {
44  public:
45   class PersistentNelStore;
46 
47   // Every (NAK, origin) pair can have at most one policy.
48   struct NET_EXPORT NelPolicyKey {
49     NelPolicyKey();
50     NelPolicyKey(const NetworkAnonymizationKey& network_anonymization_key,
51                  const url::Origin& origin);
52     NelPolicyKey(const NelPolicyKey& other);
53     ~NelPolicyKey();
54 
55     bool operator<(const NelPolicyKey& other) const;
56     bool operator==(const NelPolicyKey& other) const;
57     bool operator!=(const NelPolicyKey& other) const;
58 
59     // The NAK of the request this policy was received from. This will be used
60     // for any requests uploading reports according to this policy. (Not
61     // included in the report itself.)
62     NetworkAnonymizationKey network_anonymization_key;
63 
64     url::Origin origin;
65   };
66 
67   // Used for wildcard policies that are applicable to |domain| and its
68   // subdomains.
69   struct WildcardNelPolicyKey {
70     WildcardNelPolicyKey();
71     WildcardNelPolicyKey(
72         const NetworkAnonymizationKey& network_anonymization_key,
73         const std::string& domain);
74     explicit WildcardNelPolicyKey(const NelPolicyKey& origin_key);
75     WildcardNelPolicyKey(const WildcardNelPolicyKey& other);
76     ~WildcardNelPolicyKey();
77 
78     bool operator<(const WildcardNelPolicyKey& other) const;
79 
80     // The NAK of the request this policy was received from. This will be used
81     // for any requests uploading reports according to this policy. (Not
82     // included in the report itself.)
83     NetworkAnonymizationKey network_anonymization_key;
84 
85     std::string domain;
86   };
87 
88   // NEL policy set by an origin.
89   struct NET_EXPORT NelPolicy {
90     NelPolicy();
91     NelPolicy(const NelPolicy& other);
92     ~NelPolicy();
93 
94     NelPolicyKey key;
95 
96     IPAddress received_ip_address = IPAddress();
97 
98     // Reporting API endpoint group to which reports should be sent.
99     std::string report_to;
100 
101     base::Time expires;
102 
103     double success_fraction = 0.0;
104     double failure_fraction = 1.0;
105     bool include_subdomains = false;
106 
107     // Last time the policy was accessed to create a report, even if no report
108     // ends up being queued. Also updated when the policy is first set.
109     mutable base::Time last_used;
110   };
111 
112   // The details of a network error that are included in an NEL report.
113   //
114   // See http://wicg.github.io/network-error-logging/#dfn-network-error-object
115   // for details on the semantics of each field.
116   struct NET_EXPORT RequestDetails {
117     RequestDetails();
118     RequestDetails(const RequestDetails& other);
119     ~RequestDetails();
120 
121     // NetworkAnonymizationKey of the request triggering the error. Not included
122     // in the uploaded report.
123     NetworkAnonymizationKey network_anonymization_key;
124 
125     GURL uri;
126     GURL referrer;
127     std::string user_agent;
128     IPAddress server_ip;
129     std::string protocol;
130     std::string method;
131     int status_code;
132     base::TimeDelta elapsed_time;
133     Error type;
134 
135     // Upload nesting depth of this request.
136     //
137     // If the request is not a Reporting upload, the depth is 0.
138     //
139     // If the request is a Reporting upload, the depth is the max of the depth
140     // of the requests reported within it plus 1. (Non-NEL reports are
141     // considered to have depth 0.)
142     int reporting_upload_depth;
143   };
144 
145   // The details of a signed exchange report.
146   struct NET_EXPORT SignedExchangeReportDetails {
147     SignedExchangeReportDetails();
148     SignedExchangeReportDetails(const SignedExchangeReportDetails& other);
149     ~SignedExchangeReportDetails();
150 
151     // NetworkAnonymizationKey of the request triggering the error. Not included
152     // in the uploaded report.
153     NetworkAnonymizationKey network_anonymization_key;
154 
155     bool success;
156     std::string type;
157     GURL outer_url;
158     GURL inner_url;
159     GURL cert_url;
160     std::string referrer;
161     IPAddress server_ip_address;
162     std::string protocol;
163     std::string method;
164     int32_t status_code;
165     base::TimeDelta elapsed_time;
166     std::string user_agent;
167   };
168 
169   static const char kHeaderName[];
170 
171   static const char kReportType[];
172 
173   static const int kMaxNestedReportDepth;
174 
175   // Keys for data included in report bodies. Exposed for tests.
176 
177   static const char kReferrerKey[];
178   static const char kSamplingFractionKey[];
179   static const char kServerIpKey[];
180   static const char kProtocolKey[];
181   static const char kMethodKey[];
182   static const char kStatusCodeKey[];
183   static const char kElapsedTimeKey[];
184   static const char kPhaseKey[];
185   static const char kTypeKey[];
186 
187   static const char kSignedExchangePhaseValue[];
188   static const char kSignedExchangeBodyKey[];
189   static const char kOuterUrlKey[];
190   static const char kInnerUrlKey[];
191   static const char kCertUrlKey[];
192 
193   // Maximum number of NEL policies to store before evicting.
194   static const size_t kMaxPolicies;
195 
196   static const char kSignedExchangeRequestOutcomeHistogram[];
197 
198   // Used for histogramming Signed Exchange request outcomes only. Previously,
199   // the outcome of all requests would be histogrammed, but this was removed in
200   // crbug.com/1007122 because the histogram was very large and not very useful.
201   enum class RequestOutcome {
202     kDiscardedNoNetworkErrorLoggingService = 0,
203 
204     kDiscardedNoReportingService = 1,
205     kDiscardedInsecureOrigin = 2,
206     kDiscardedNoOriginPolicy = 3,
207     kDiscardedUnmappedError = 4,
208     kDiscardedReportingUpload = 5,
209     kDiscardedUnsampledSuccess = 6,
210     kDiscardedUnsampledFailure = 7,
211     kQueued = 8,
212     kDiscardedNonDNSSubdomainReport = 9,
213     kDiscardedIPAddressMismatch = 10,
214 
215     kMaxValue = kDiscardedIPAddressMismatch
216   };
217 
218   // NEL policies are persisted to disk if |store| is not null.
219   // The store, if given, should outlive |*this|.
220   static std::unique_ptr<NetworkErrorLoggingService> Create(
221       PersistentNelStore* store);
222 
223   NetworkErrorLoggingService(const NetworkErrorLoggingService&) = delete;
224   NetworkErrorLoggingService& operator=(const NetworkErrorLoggingService&) =
225       delete;
226 
227   virtual ~NetworkErrorLoggingService();
228 
229   // Ingests a "NEL:" header received for |network_anonymization_key| and
230   // |origin| from |received_ip_address| with normalized value |value|. May or
231   // may not actually set a policy for that origin.
232   virtual void OnHeader(
233       const NetworkAnonymizationKey& network_anonymization_key,
234       const url::Origin& origin,
235       const IPAddress& received_ip_address,
236       const std::string& value) = 0;
237 
238   // Considers queueing a network error report for the request described in
239   // |details|.  The contents of |details| might be changed, depending on the
240   // NEL policy associated with the request's origin.  Note that |details| is
241   // passed by value, so that it doesn't need to be copied in this function if
242   // it needs to be changed.  Consider using std::move to pass this parameter if
243   // the caller doesn't need to access it after this method call.
244   //
245   // Note that Network Error Logging can report a fraction of successful
246   // requests as well (to calculate error rates), so this should be called on
247   // *all* secure requests. NEL is only available to secure origins, so this is
248   // not called on any insecure requests.
249   virtual void OnRequest(RequestDetails details) = 0;
250 
251   // Queues a Signed Exchange report.
252   virtual void QueueSignedExchangeReport(
253       SignedExchangeReportDetails details) = 0;
254 
255   // Removes browsing data (origin policies) associated with any origin for
256   // which |origin_filter| returns true.
257   virtual void RemoveBrowsingData(
258       const base::RepeatingCallback<bool(const url::Origin&)>&
259           origin_filter) = 0;
260 
261   // Removes browsing data (origin policies) for all origins. Allows slight
262   // optimization over passing an always-true filter to RemoveBrowsingData.
263   virtual void RemoveAllBrowsingData() = 0;
264 
265   // Sets the ReportingService that will be used to queue network error reports.
266   // If |nullptr| is passed, reports will be queued locally or discarded.
267   // |reporting_service| must outlive the NetworkErrorLoggingService.
268   // Should not be called again if previously called with a non-null pointer.
269   void SetReportingService(ReportingService* reporting_service);
270 
271   // Shuts down the NEL service, so that no more requests or headers can be
272   // processed, no more reports are queued, and browsing data can no longer be
273   // cleared.
274   void OnShutdown();
275 
276   // Sets a base::Clock (used to track policy expiration) for tests.
277   // |clock| must outlive the NetworkErrorLoggingService, and cannot be
278   // nullptr.
279   void SetClockForTesting(const base::Clock* clock);
280 
281   // Dumps info about all the currently stored policies, including expired ones.
282   // Used to display information about NEL policies on the NetLog Reporting tab.
283   virtual base::Value StatusAsValue() const;
284 
285   // Gets the (NAK, origin) keys of all currently stored policies, including
286   // expired ones.
287   virtual std::set<NelPolicyKey> GetPolicyKeysForTesting();
288 
289   virtual PersistentNelStore* GetPersistentNelStoreForTesting();
290   virtual ReportingService* GetReportingServiceForTesting();
291 
292  protected:
293   NetworkErrorLoggingService();
294 
295   // Unowned:
296   raw_ptr<const base::Clock> clock_;
297   raw_ptr<ReportingService, DanglingUntriaged> reporting_service_ = nullptr;
298   bool shut_down_ = false;
299 };
300 
301 // Persistent storage for NEL policies.
302 class NET_EXPORT NetworkErrorLoggingService::PersistentNelStore {
303  public:
304   using NelPoliciesLoadedCallback =
305       base::OnceCallback<void(std::vector<NelPolicy>)>;
306 
307   PersistentNelStore() = default;
308 
309   PersistentNelStore(const PersistentNelStore&) = delete;
310   PersistentNelStore& operator=(const PersistentNelStore&) = delete;
311 
312   virtual ~PersistentNelStore() = default;
313 
314   // Initializes the store and retrieves stored NEL policies. This will be
315   // called only once at startup.
316   virtual void LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback) = 0;
317 
318   // Adds a NEL policy to the store.
319   virtual void AddNelPolicy(const NelPolicy& policy) = 0;
320 
321   // Updates the access time of the NEL policy in the store.
322   virtual void UpdateNelPolicyAccessTime(const NelPolicy& policy) = 0;
323 
324   // Deletes a NEL policy from the store.
325   virtual void DeleteNelPolicy(const NelPolicy& policy) = 0;
326 
327   // Flushes the store.
328   virtual void Flush() = 0;
329 };
330 
331 }  // namespace net
332 
333 #endif  // NET_NETWORK_ERROR_LOGGING_NETWORK_ERROR_LOGGING_SERVICE_H_
334