Coverage Report

Created: 2023-11-12 09:30

/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
858
      : 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.29k
        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
8.26k
        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
9.13k
                                                         : "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
19.1k
  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