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