Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/source/common/router/router_ratelimit.h
Line
Count
Source (jump to first uncovered line)
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
332
      : 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
2.47k
        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
7.33k
        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
4.71k
                                                         : "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
      Server::Configuration::CommonFactoryContext& context);
171
172
  // Ratelimit::DescriptorProducer
173
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
174
                          const std::string& local_service_cluster,
175
                          const Http::RequestHeaderMap& headers,
176
                          const StreamInfo::StreamInfo& info) const override;
177
178
private:
179
  const std::string descriptor_value_;
180
  const std::string descriptor_key_;
181
  const bool expect_match_;
182
  const std::vector<Http::HeaderUtility::HeaderDataPtr> action_headers_;
183
};
184
185
/**
186
 * Action for query parameter value match rate limiting.
187
 */
188
class QueryParameterValueMatchAction : public RateLimit::DescriptorProducer {
189
public:
190
  QueryParameterValueMatchAction(
191
      const envoy::config::route::v3::RateLimit::Action::QueryParameterValueMatch& action,
192
      Server::Configuration::CommonFactoryContext& context);
193
194
  // Ratelimit::DescriptorProducer
195
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
196
                          const std::string& local_service_cluster,
197
                          const Http::RequestHeaderMap& headers,
198
                          const StreamInfo::StreamInfo& info) const override;
199
200
  std::vector<ConfigUtility::QueryParameterMatcherPtr> buildQueryParameterMatcherVector(
201
      const envoy::config::route::v3::RateLimit::Action::QueryParameterValueMatch& action,
202
      Server::Configuration::CommonFactoryContext& context);
203
204
private:
205
  const std::string descriptor_value_;
206
  const std::string descriptor_key_;
207
  const bool expect_match_;
208
  const std::vector<ConfigUtility::QueryParameterMatcherPtr> action_query_parameters_;
209
};
210
211
/*
212
 * Implementation of RateLimitPolicyEntry that holds the action for the configuration.
213
 */
214
class RateLimitPolicyEntryImpl : public RateLimitPolicyEntry {
215
public:
216
  RateLimitPolicyEntryImpl(const envoy::config::route::v3::RateLimit& config,
217
                           Server::Configuration::CommonFactoryContext& context,
218
                           absl::Status& creation_status);
219
220
  // Router::RateLimitPolicyEntry
221
15.4k
  uint64_t stage() const override { return stage_; }
222
0
  const std::string& disableKey() const override { return disable_key_; }
223
  void populateDescriptors(std::vector<Envoy::RateLimit::Descriptor>& descriptors,
224
                           const std::string& local_service_cluster, const Http::RequestHeaderMap&,
225
                           const StreamInfo::StreamInfo& info) const override;
226
  void populateLocalDescriptors(std::vector<Envoy::RateLimit::LocalDescriptor>& descriptors,
227
                                const std::string& local_service_cluster,
228
                                const Http::RequestHeaderMap&,
229
                                const StreamInfo::StreamInfo& info) const override;
230
231
private:
232
  const std::string disable_key_;
233
  uint64_t stage_;
234
  std::vector<RateLimit::DescriptorProducerPtr> actions_;
235
  absl::optional<RateLimitOverrideActionPtr> limit_override_ = absl::nullopt;
236
};
237
238
/**
239
 * Implementation of RateLimitPolicy that reads from the JSON route config.
240
 */
241
class RateLimitPolicyImpl : public RateLimitPolicy {
242
public:
243
  RateLimitPolicyImpl();
244
  RateLimitPolicyImpl(
245
      const Protobuf::RepeatedPtrField<envoy::config::route::v3::RateLimit>& rate_limits,
246
      Server::Configuration::CommonFactoryContext& context, absl::Status& creation_status);
247
248
  // Router::RateLimitPolicy
249
  const std::vector<std::reference_wrapper<const RateLimitPolicyEntry>>&
250
  getApplicableRateLimit(uint64_t stage = 0) const override;
251
0
  bool empty() const override { return rate_limit_entries_.empty(); }
252
253
private:
254
  std::vector<std::unique_ptr<RateLimitPolicyEntry>> rate_limit_entries_;
255
  std::vector<std::vector<std::reference_wrapper<const RateLimitPolicyEntry>>>
256
      rate_limit_entries_reference_;
257
  // The maximum stage number supported. This value should match the maximum stage number in
258
  // Json::Schema::HTTP_RATE_LIMITS_CONFIGURATION_SCHEMA and
259
  // Json::Schema::RATE_LIMIT_HTTP_FILTER_SCHEMA from common/json/config_schemas.cc.
260
  static const uint64_t MAX_STAGE_NUMBER;
261
};
262
using DefaultRateLimitPolicy = ConstSingleton<RateLimitPolicyImpl>;
263
264
} // namespace Router
265
} // namespace Envoy