xref: /aosp_15_r20/external/cronet/net/cert/coalescing_cert_verifier.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2019 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_CERT_COALESCING_CERT_VERIFIER_H_
6 #define NET_CERT_COALESCING_CERT_VERIFIER_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <memory>
12 #include <vector>
13 
14 #include "net/base/net_export.h"
15 #include "net/cert/cert_verifier.h"
16 
17 namespace net {
18 
19 // CoalescingCertVerifier is a CertVerifier that keeps track of in-flight
20 // CertVerifier Verify() requests. If a new call to Verify() is started that
21 // matches the same parameters as an in-progress verification, the new
22 // Verify() call will be joined to the existing, in-progress verification,
23 // completing when it does. If no in-flight requests match, a new request to
24 // the underlying verifier will be started.
25 //
26 // If the underlying configuration changes, existing requests are allowed to
27 // complete, but any new requests will not be seen as matching, even if they
28 // share the same parameters. This ensures configuration changes propagate
29 // "immediately" for all new requests.
30 class NET_EXPORT CoalescingCertVerifier : public CertVerifier,
31                                           public CertVerifier::Observer {
32  public:
33   // Create a new verifier that will forward calls to |verifier|, coalescing
34   // any in-flight, not-yet-completed calls to Verify().
35   explicit CoalescingCertVerifier(std::unique_ptr<CertVerifier> verifier);
36 
37   CoalescingCertVerifier(const CoalescingCertVerifier&) = delete;
38   CoalescingCertVerifier& operator=(const CoalescingCertVerifier&) = delete;
39 
40   ~CoalescingCertVerifier() override;
41 
42   // CertVerifier implementation:
43   int Verify(const RequestParams& params,
44              CertVerifyResult* verify_result,
45              CompletionOnceCallback callback,
46              std::unique_ptr<CertVerifier::Request>* out_req,
47              const NetLogWithSource& net_log) override;
48   void SetConfig(const CertVerifier::Config& config) override;
49   void AddObserver(CertVerifier::Observer* observer) override;
50   void RemoveObserver(CertVerifier::Observer* observer) override;
51 
requests_for_testing()52   uint64_t requests_for_testing() const { return requests_; }
inflight_joins_for_testing()53   uint64_t inflight_joins_for_testing() const { return inflight_joins_; }
54 
55  private:
56   class Job;
57   class Request;
58 
59   // If there is a pending request that matches |params|, and which can be
60   // joined (it shares the same config), returns that Job.
61   // Otherwise, returns nullptr, meaning a new Job should be started.
62   Job* FindJob(const RequestParams& params);
63   void RemoveJob(Job* job);
64   void IncrementGenerationAndMakeCurrentJobsUnjoinable();
65 
66   // CertVerifier::Observer methods:
67   void OnCertVerifierChanged() override;
68 
69   // Contains the set of Jobs for which an active verification is taking
70   // place and which can be used for new requests (e.g. the config is the
71   // same).
72   std::map<CertVerifier::RequestParams, std::unique_ptr<Job>> joinable_jobs_;
73 
74   // Contains all pending Jobs that are in-flight, but cannot be joined, due
75   // to the configuration having changed since they were started.
76   std::vector<std::unique_ptr<Job>> inflight_jobs_;
77 
78   std::unique_ptr<CertVerifier> verifier_;
79 
80   uint64_t requests_ = 0;
81   uint64_t inflight_joins_ = 0;
82 };
83 
84 }  // namespace net
85 
86 #endif  // NET_CERT_COALESCING_CERT_VERIFIER_H_
87