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