LCOV - code coverage report
Current view: top level - source/common/router - router_ratelimit.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 1 7 14.3 %
Date: 2024-01-05 06:35:25 Functions: 1 7 14.3 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstdint>
       4             : #include <memory>
       5             : #include <string>
       6             : #include <vector>
       7             : 
       8             : #include "envoy/config/core/v3/base.pb.h"
       9             : #include "envoy/config/route/v3/route_components.pb.h"
      10             : #include "envoy/ratelimit/ratelimit.h"
      11             : #include "envoy/router/router.h"
      12             : #include "envoy/router/router_ratelimit.h"
      13             : 
      14             : #include "source/common/config/metadata.h"
      15             : #include "source/common/http/header_utility.h"
      16             : #include "source/common/network/cidr_range.h"
      17             : #include "source/common/protobuf/utility.h"
      18             : #include "source/common/router/config_utility.h"
      19             : 
      20             : #include "absl/types/optional.h"
      21             : 
      22             : namespace Envoy {
      23             : namespace Router {
      24             : 
      25             : /**
      26             :  * Populate rate limit override from dynamic metadata.
      27             :  */
      28             : class DynamicMetadataRateLimitOverride : public RateLimitOverrideAction {
      29             : public:
      30             :   DynamicMetadataRateLimitOverride(
      31             :       const envoy::config::route::v3::RateLimit::Override::DynamicMetadata& config)
      32           0 :       : metadata_key_(config.metadata_key()) {}
      33             : 
      34             :   // Router::RateLimitOverrideAction
      35             :   bool populateOverride(RateLimit::Descriptor& descriptor,
      36             :                         const envoy::config::core::v3::Metadata* metadata) const override;
      37             : 
      38             : private:
      39             :   const Envoy::Config::MetadataKey metadata_key_;
      40             : };
      41             : 
      42             : /**
      43             :  * Action for source cluster rate limiting.
      44             :  */
      45             : class SourceClusterAction : public RateLimit::DescriptorProducer {
      46             : public:
      47             :   // Ratelimit::DescriptorProducer
      48             :   bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
      49             :                           const std::string& local_service_cluster,
      50             :                           const Http::RequestHeaderMap& headers,
      51             :                           const StreamInfo::StreamInfo& info) const override;
      52             : };
      53             : 
      54             : /**
      55             :  * Action for destination cluster rate limiting.
      56             :  */
      57             : class DestinationClusterAction : public RateLimit::DescriptorProducer {
      58             : public:
      59             :   // Ratelimit::DescriptorProducer
      60             :   bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
      61             :                           const std::string& local_service_cluster,
      62             :                           const Http::RequestHeaderMap& headers,
      63             :                           const StreamInfo::StreamInfo& info) const override;
      64             : };
      65             : 
      66             : /**
      67             :  * Action for request headers rate limiting.
      68             :  */
      69             : class RequestHeadersAction : public RateLimit::DescriptorProducer {
      70             : public:
      71             :   RequestHeadersAction(const envoy::config::route::v3::RateLimit::Action::RequestHeaders& action)
      72             :       : header_name_(action.header_name()), descriptor_key_(action.descriptor_key()),
      73           0 :         skip_if_absent_(action.skip_if_absent()) {}
      74             : 
      75             :   // Ratelimit::DescriptorProducer
      76             :   bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
      77             :                           const std::string& local_service_cluster,
      78             :                           const Http::RequestHeaderMap& headers,
      79             :                           const StreamInfo::StreamInfo& info) const override;
      80             : 
      81             : private:
      82             :   const Http::LowerCaseString header_name_;
      83             :   const std::string descriptor_key_;
      84             :   const bool skip_if_absent_;
      85             : };
      86             : 
      87             : /**
      88             :  * Action for remote address rate limiting.
      89             :  */
      90             : class RemoteAddressAction : public RateLimit::DescriptorProducer {
      91             : public:
      92             :   // Ratelimit::DescriptorProducer
      93             :   bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
      94             :                           const std::string& local_service_cluster,
      95             :                           const Http::RequestHeaderMap& headers,
      96             :                           const StreamInfo::StreamInfo& info) const override;
      97             : };
      98             : 
      99             : /**
     100             :  * Action for masked remote address rate limiting.
     101             :  */
     102             : class MaskedRemoteAddressAction : public RateLimit::DescriptorProducer {
     103             : public:
     104             :   MaskedRemoteAddressAction(
     105             :       const envoy::config::route::v3::RateLimit::Action::MaskedRemoteAddress& action)
     106             :       : v4_prefix_mask_len_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(action, v4_prefix_mask_len, 32)),
     107           0 :         v6_prefix_mask_len_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(action, v6_prefix_mask_len, 128)) {}
     108             : 
     109             :   // Ratelimit::DescriptorProducer
     110             :   bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
     111             :                           const std::string& local_service_cluster,
     112             :                           const Http::RequestHeaderMap& headers,
     113             :                           const StreamInfo::StreamInfo& info) const override;
     114             : 
     115             : private:
     116             :   const uint32_t v4_prefix_mask_len_;
     117             :   const uint32_t v6_prefix_mask_len_;
     118             : };
     119             : 
     120             : /**
     121             :  * Action for generic key rate limiting.
     122             :  */
     123             : class GenericKeyAction : public RateLimit::DescriptorProducer {
     124             : public:
     125             :   GenericKeyAction(const envoy::config::route::v3::RateLimit::Action::GenericKey& action)
     126             :       : descriptor_value_(action.descriptor_value()),
     127             :         descriptor_key_(!action.descriptor_key().empty() ? action.descriptor_key()
     128           0 :                                                          : "generic_key") {}
     129             : 
     130             :   // Ratelimit::DescriptorProducer
     131             :   bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
     132             :                           const std::string& local_service_cluster,
     133             :                           const Http::RequestHeaderMap& headers,
     134             :                           const StreamInfo::StreamInfo& info) const override;
     135             : 
     136             : private:
     137             :   const std::string descriptor_value_;
     138             :   const std::string descriptor_key_;
     139             : };
     140             : 
     141             : /**
     142             :  * Action for metadata rate limiting.
     143             :  */
     144             : class MetaDataAction : public RateLimit::DescriptorProducer {
     145             : public:
     146             :   MetaDataAction(const envoy::config::route::v3::RateLimit::Action::MetaData& action);
     147             :   // for maintaining backward compatibility with the deprecated DynamicMetaData action
     148             :   MetaDataAction(const envoy::config::route::v3::RateLimit::Action::DynamicMetaData& action);
     149             :   // Ratelimit::DescriptorProducer
     150             :   bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
     151             :                           const std::string& local_service_cluster,
     152             :                           const Http::RequestHeaderMap& headers,
     153             :                           const StreamInfo::StreamInfo& info) const override;
     154             : 
     155             : private:
     156             :   const Envoy::Config::MetadataKey metadata_key_;
     157             :   const std::string descriptor_key_;
     158             :   const std::string default_value_;
     159             :   const envoy::config::route::v3::RateLimit::Action::MetaData::Source source_;
     160             :   const bool skip_if_absent_;
     161             : };
     162             : 
     163             : /**
     164             :  * Action for header value match rate limiting.
     165             :  */
     166             : class HeaderValueMatchAction : public RateLimit::DescriptorProducer {
     167             : public:
     168             :   HeaderValueMatchAction(
     169             :       const envoy::config::route::v3::RateLimit::Action::HeaderValueMatch& action);
     170             : 
     171             :   // Ratelimit::DescriptorProducer
     172             :   bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
     173             :                           const std::string& local_service_cluster,
     174             :                           const Http::RequestHeaderMap& headers,
     175             :                           const StreamInfo::StreamInfo& info) const override;
     176             : 
     177             : private:
     178             :   const std::string descriptor_value_;
     179             :   const std::string descriptor_key_;
     180             :   const bool expect_match_;
     181             :   const std::vector<Http::HeaderUtility::HeaderDataPtr> action_headers_;
     182             : };
     183             : 
     184             : /**
     185             :  * Action for query parameter value match rate limiting.
     186             :  */
     187             : class QueryParameterValueMatchAction : public RateLimit::DescriptorProducer {
     188             : public:
     189             :   QueryParameterValueMatchAction(
     190             :       const envoy::config::route::v3::RateLimit::Action::QueryParameterValueMatch& action);
     191             : 
     192             :   // Ratelimit::DescriptorProducer
     193             :   bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
     194             :                           const std::string& local_service_cluster,
     195             :                           const Http::RequestHeaderMap& headers,
     196             :                           const StreamInfo::StreamInfo& info) const override;
     197             : 
     198             :   std::vector<ConfigUtility::QueryParameterMatcherPtr> buildQueryParameterMatcherVector(
     199             :       const envoy::config::route::v3::RateLimit::Action::QueryParameterValueMatch& action);
     200             : 
     201             : private:
     202             :   const std::string descriptor_value_;
     203             :   const std::string descriptor_key_;
     204             :   const bool expect_match_;
     205             :   const std::vector<ConfigUtility::QueryParameterMatcherPtr> action_query_parameters_;
     206             : };
     207             : 
     208             : /*
     209             :  * Implementation of RateLimitPolicyEntry that holds the action for the configuration.
     210             :  */
     211             : class RateLimitPolicyEntryImpl : public RateLimitPolicyEntry {
     212             : public:
     213             :   RateLimitPolicyEntryImpl(const envoy::config::route::v3::RateLimit& config,
     214             :                            Server::Configuration::CommonFactoryContext& context);
     215             : 
     216             :   // Router::RateLimitPolicyEntry
     217           4 :   uint64_t stage() const override { return stage_; }
     218           0 :   const std::string& disableKey() const override { return disable_key_; }
     219             :   void populateDescriptors(std::vector<Envoy::RateLimit::Descriptor>& descriptors,
     220             :                            const std::string& local_service_cluster, const Http::RequestHeaderMap&,
     221             :                            const StreamInfo::StreamInfo& info) const override;
     222             :   void populateLocalDescriptors(std::vector<Envoy::RateLimit::LocalDescriptor>& descriptors,
     223             :                                 const std::string& local_service_cluster,
     224             :                                 const Http::RequestHeaderMap&,
     225             :                                 const StreamInfo::StreamInfo& info) const override;
     226             : 
     227             : private:
     228             :   const std::string disable_key_;
     229             :   uint64_t stage_;
     230             :   std::vector<RateLimit::DescriptorProducerPtr> actions_;
     231             :   absl::optional<RateLimitOverrideActionPtr> limit_override_ = absl::nullopt;
     232             : };
     233             : 
     234             : /**
     235             :  * Implementation of RateLimitPolicy that reads from the JSON route config.
     236             :  */
     237             : class RateLimitPolicyImpl : public RateLimitPolicy {
     238             : public:
     239             :   RateLimitPolicyImpl();
     240             :   RateLimitPolicyImpl(
     241             :       const Protobuf::RepeatedPtrField<envoy::config::route::v3::RateLimit>& rate_limits,
     242             :       Server::Configuration::CommonFactoryContext& context);
     243             : 
     244             :   // Router::RateLimitPolicy
     245             :   const std::vector<std::reference_wrapper<const RateLimitPolicyEntry>>&
     246             :   getApplicableRateLimit(uint64_t stage = 0) const override;
     247           0 :   bool empty() const override { return rate_limit_entries_.empty(); }
     248             : 
     249             : private:
     250             :   std::vector<std::unique_ptr<RateLimitPolicyEntry>> rate_limit_entries_;
     251             :   std::vector<std::vector<std::reference_wrapper<const RateLimitPolicyEntry>>>
     252             :       rate_limit_entries_reference_;
     253             :   // The maximum stage number supported. This value should match the maximum stage number in
     254             :   // Json::Schema::HTTP_RATE_LIMITS_CONFIGURATION_SCHEMA and
     255             :   // Json::Schema::RATE_LIMIT_HTTP_FILTER_SCHEMA from common/json/config_schemas.cc.
     256             :   static const uint64_t MAX_STAGE_NUMBER;
     257             : };
     258             : using DefaultRateLimitPolicy = ConstSingleton<RateLimitPolicyImpl>;
     259             : 
     260             : } // namespace Router
     261             : } // namespace Envoy

Generated by: LCOV version 1.15