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/formatter/substitution_formatter.h"
16
#include "source/common/http/header_utility.h"
17
#include "source/common/http/matching/data_impl.h"
18
#include "source/common/matcher/matcher.h"
19
#include "source/common/network/cidr_range.h"
20
#include "source/common/protobuf/utility.h"
21
#include "source/common/router/config_utility.h"
22

            
23
#include "absl/types/optional.h"
24

            
25
namespace Envoy {
26
namespace Router {
27

            
28
/**
29
 * Populate rate limit override from dynamic metadata.
30
 */
31
class DynamicMetadataRateLimitOverride : public RateLimitOverrideAction {
32
public:
33
  DynamicMetadataRateLimitOverride(
34
      const envoy::config::route::v3::RateLimit::Override::DynamicMetadata& config)
35
4
      : metadata_key_(config.metadata_key()) {}
36

            
37
  // Router::RateLimitOverrideAction
38
  bool populateOverride(RateLimit::Descriptor& descriptor,
39
                        const envoy::config::core::v3::Metadata* metadata) const override;
40

            
41
private:
42
  const Envoy::Config::MetadataKey metadata_key_;
43
};
44

            
45
/**
46
 * Action for source cluster rate limiting.
47
 */
48
class SourceClusterAction : public RateLimit::DescriptorProducer {
49
public:
50
  // Ratelimit::DescriptorProducer
51
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
52
                          const std::string& local_service_cluster,
53
                          const Http::RequestHeaderMap& headers,
54
                          const StreamInfo::StreamInfo& info) const override;
55
};
56

            
57
/**
58
 * Action for destination cluster rate limiting.
59
 */
60
class DestinationClusterAction : public RateLimit::DescriptorProducer {
61
public:
62
  // Ratelimit::DescriptorProducer
63
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
64
                          const std::string& local_service_cluster,
65
                          const Http::RequestHeaderMap& headers,
66
                          const StreamInfo::StreamInfo& info) const override;
67
};
68

            
69
/**
70
 * Action for request headers rate limiting.
71
 */
72
class RequestHeadersAction : public RateLimit::DescriptorProducer {
73
public:
74
  RequestHeadersAction(const envoy::config::route::v3::RateLimit::Action::RequestHeaders& action)
75
37
      : header_name_(action.header_name()), descriptor_key_(action.descriptor_key()),
76
37
        skip_if_absent_(action.skip_if_absent()) {}
77

            
78
  // Ratelimit::DescriptorProducer
79
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
80
                          const std::string& local_service_cluster,
81
                          const Http::RequestHeaderMap& headers,
82
                          const StreamInfo::StreamInfo& info) const override;
83

            
84
private:
85
  const Http::LowerCaseString header_name_;
86
  const std::string descriptor_key_;
87
  const bool skip_if_absent_;
88
};
89

            
90
/**
91
 * Action for remote address rate limiting.
92
 */
93
class RemoteAddressAction : public RateLimit::DescriptorProducer {
94
public:
95
  // Ratelimit::DescriptorProducer
96
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
97
                          const std::string& local_service_cluster,
98
                          const Http::RequestHeaderMap& headers,
99
                          const StreamInfo::StreamInfo& info) const override;
100
};
101

            
102
/**
103
 * Action for masked remote address rate limiting.
104
 */
105
class MaskedRemoteAddressAction : public RateLimit::DescriptorProducer {
106
public:
107
  MaskedRemoteAddressAction(
108
      const envoy::config::route::v3::RateLimit::Action::MaskedRemoteAddress& action)
109
8
      : v4_prefix_mask_len_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(action, v4_prefix_mask_len, 32)),
110
8
        v6_prefix_mask_len_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(action, v6_prefix_mask_len, 128)) {}
111

            
112
  // Ratelimit::DescriptorProducer
113
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
114
                          const std::string& local_service_cluster,
115
                          const Http::RequestHeaderMap& headers,
116
                          const StreamInfo::StreamInfo& info) const override;
117

            
118
private:
119
  const uint32_t v4_prefix_mask_len_;
120
  const uint32_t v6_prefix_mask_len_;
121
};
122

            
123
/**
124
 * Action for generic key rate limiting.
125
 */
126
class GenericKeyAction : public RateLimit::DescriptorProducer {
127
public:
128
  GenericKeyAction(const envoy::config::route::v3::RateLimit::Action::GenericKey& action,
129
                   std::unique_ptr<Formatter::FormatterImpl> formatter = nullptr);
130

            
131
  // Ratelimit::DescriptorProducer
132
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
133
                          const std::string& local_service_cluster,
134
                          const Http::RequestHeaderMap& headers,
135
                          const StreamInfo::StreamInfo& info) const override;
136

            
137
private:
138
  const std::string descriptor_value_;
139
  const std::string descriptor_key_;
140
  const std::string default_value_;
141
  const std::unique_ptr<Formatter::FormatterImpl> descriptor_formatter_;
142
};
143

            
144
/**
145
 * Action for metadata rate limiting.
146
 */
147
class MetaDataAction : public RateLimit::DescriptorProducer {
148
public:
149
  MetaDataAction(const envoy::config::route::v3::RateLimit::Action::MetaData& action);
150
  // for maintaining backward compatibility with the deprecated DynamicMetaData action
151
  MetaDataAction(const envoy::config::route::v3::RateLimit::Action::DynamicMetaData& action);
152

            
153
  // Ratelimit::DescriptorProducer
154
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
155
                          const std::string& local_service_cluster,
156
                          const Http::RequestHeaderMap& headers,
157
                          const StreamInfo::StreamInfo& info) const override;
158

            
159
private:
160
  const Envoy::Config::MetadataKey metadata_key_;
161
  const std::string descriptor_key_;
162
  const std::string default_value_;
163
  const envoy::config::route::v3::RateLimit::Action::MetaData::Source source_;
164
  const bool skip_if_absent_;
165
};
166

            
167
/**
168
 * Action for query parameters rate limiting.
169
 */
170
class QueryParametersAction : public RateLimit::DescriptorProducer {
171
public:
172
  QueryParametersAction(const envoy::config::route::v3::RateLimit::Action::QueryParameters& action);
173

            
174
  // Ratelimit::DescriptorProducer
175
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
176
                          const std::string& local_service_cluster,
177
                          const Http::RequestHeaderMap& headers,
178
                          const StreamInfo::StreamInfo& info) const override;
179

            
180
private:
181
  const std::string query_param_name_;
182
  const std::string descriptor_key_;
183
  const bool skip_if_absent_;
184
};
185

            
186
/**
187
 * Action for header value match rate limiting.
188
 */
189
class HeaderValueMatchAction : public RateLimit::DescriptorProducer {
190
public:
191
  HeaderValueMatchAction(
192
      const envoy::config::route::v3::RateLimit::Action::HeaderValueMatch& action,
193
      Server::Configuration::CommonFactoryContext& context,
194
      std::unique_ptr<Formatter::FormatterImpl> formatter = nullptr);
195

            
196
  // Ratelimit::DescriptorProducer
197
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
198
                          const std::string& local_service_cluster,
199
                          const Http::RequestHeaderMap& headers,
200
                          const StreamInfo::StreamInfo& info) const override;
201

            
202
private:
203
  const std::string descriptor_value_;
204
  const std::string descriptor_key_;
205
  const std::string default_value_;
206
  const bool expect_match_;
207
  const std::vector<Http::HeaderUtility::HeaderDataPtr> action_headers_;
208
  const std::unique_ptr<Formatter::FormatterImpl> descriptor_formatter_;
209
};
210

            
211
/**
212
 * Action for query parameter value match rate limiting.
213
 */
214
class QueryParameterValueMatchAction : public RateLimit::DescriptorProducer {
215
public:
216
  QueryParameterValueMatchAction(
217
      const envoy::config::route::v3::RateLimit::Action::QueryParameterValueMatch& action,
218
      Server::Configuration::CommonFactoryContext& context,
219
      std::unique_ptr<Formatter::FormatterImpl> formatter = nullptr);
220

            
221
  // Ratelimit::DescriptorProducer
222
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
223
                          const std::string& local_service_cluster,
224
                          const Http::RequestHeaderMap& headers,
225
                          const StreamInfo::StreamInfo& info) const override;
226

            
227
  std::vector<ConfigUtility::QueryParameterMatcherPtr> buildQueryParameterMatcherVector(
228
      const Protobuf::RepeatedPtrField<envoy::config::route::v3::QueryParameterMatcher>&
229
          query_parameters,
230
      Server::Configuration::CommonFactoryContext& context);
231

            
232
private:
233
  const std::string descriptor_value_;
234
  const std::string descriptor_key_;
235
  const std::string default_value_;
236
  const bool expect_match_;
237
  const std::vector<ConfigUtility::QueryParameterMatcherPtr> action_query_parameters_;
238
  const std::unique_ptr<Formatter::FormatterImpl> descriptor_formatter_;
239
};
240

            
241
/**
242
 * Action for remote address match rate limiting.
243
 */
244
class RemoteAddressMatchAction : public RateLimit::DescriptorProducer {
245
public:
246
  RemoteAddressMatchAction(
247
      const envoy::config::route::v3::RateLimit::Action::RemoteAddressMatch& action,
248
      Server::Configuration::CommonFactoryContext& context);
249

            
250
  // Ratelimit::DescriptorProducer
251
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry,
252
                          const std::string& local_service_cluster,
253
                          const Http::RequestHeaderMap& headers,
254
                          const StreamInfo::StreamInfo& info) const override;
255

            
256
private:
257
  const std::string descriptor_key_;
258
  const std::string default_value_;
259
  const std::unique_ptr<Network::Address::IpList> ip_list_;
260
  const bool invert_match_;
261
  const std::unique_ptr<Formatter::FormatterImpl> descriptor_formatter_;
262
};
263

            
264
class RateLimitDescriptorValidationVisitor
265
    : public Matcher::MatchTreeValidationVisitor<Http::HttpMatchingData> {
266
public:
267
  absl::Status performDataInputValidation(const Matcher::DataInputFactory<Http::HttpMatchingData>&,
268
6
                                          absl::string_view) override {
269
6
    return absl::OkStatus();
270
6
  }
271
};
272

            
273
class MatchInputRateLimitDescriptor : public RateLimit::DescriptorProducer {
274
public:
275
  MatchInputRateLimitDescriptor(const std::string& descriptor_key,
276
                                Matcher::DataInputPtr<Http::HttpMatchingData>&& data_input)
277
6
      : descriptor_key_(descriptor_key), data_input_(std::move(data_input)) {}
278

            
279
  // Ratelimit::DescriptorProducer
280
  bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, const std::string&,
281
                          const Http::RequestHeaderMap& headers,
282
                          const StreamInfo::StreamInfo& info) const override;
283

            
284
private:
285
  const std::string descriptor_key_;
286
  Matcher::DataInputPtr<Http::HttpMatchingData> data_input_;
287
};
288

            
289
/*
290
 * Implementation of RateLimitPolicyEntry that holds the action for the configuration.
291
 */
292
class RateLimitPolicyEntryImpl : public RateLimitPolicyEntry {
293
public:
294
  RateLimitPolicyEntryImpl(const envoy::config::route::v3::RateLimit& config,
295
                           Server::Configuration::CommonFactoryContext& context,
296
                           absl::Status& creation_status);
297

            
298
  // Router::RateLimitPolicyEntry
299
49
  uint64_t stage() const override { return stage_; }
300
81
  const std::string& disableKey() const override { return disable_key_; }
301
  void populateDescriptors(std::vector<Envoy::RateLimit::Descriptor>& descriptors,
302
                           const std::string& local_service_cluster, const Http::RequestHeaderMap&,
303
                           const StreamInfo::StreamInfo& info) const override;
304
  void populateLocalDescriptors(std::vector<Envoy::RateLimit::LocalDescriptor>& descriptors,
305
                                const std::string& local_service_cluster,
306
                                const Http::RequestHeaderMap&,
307
                                const StreamInfo::StreamInfo& info) const override;
308
80
  bool applyOnStreamDone() const override { return apply_on_stream_done_; }
309

            
310
private:
311
  const std::string disable_key_;
312
  const uint64_t stage_;
313
  std::vector<RateLimit::DescriptorProducerPtr> actions_;
314
  absl::optional<RateLimitOverrideActionPtr> limit_override_ = absl::nullopt;
315
  const bool apply_on_stream_done_ = false;
316
  const RateLimit::XRateLimitOption x_ratelimit_option_{};
317
};
318

            
319
/**
320
 * Implementation of RateLimitPolicy that reads from the JSON route config.
321
 */
322
class RateLimitPolicyImpl : public RateLimitPolicy {
323
public:
324
  RateLimitPolicyImpl(
325
      const Protobuf::RepeatedPtrField<envoy::config::route::v3::RateLimit>& rate_limits,
326
      Server::Configuration::CommonFactoryContext& context, absl::Status& creation_status);
327

            
328
  // Router::RateLimitPolicy
329
  const std::vector<std::reference_wrapper<const RateLimitPolicyEntry>>&
330
  getApplicableRateLimit(uint64_t stage = 0) const override;
331
81
  bool empty() const override { return rate_limit_entries_.empty(); }
332

            
333
private:
334
  const std::vector<RateLimitPolicyEntryImpl> rate_limit_entries_;
335
  const std::vector<std::vector<std::reference_wrapper<const RateLimitPolicyEntry>>>
336
      rate_limit_entries_reference_;
337
};
338

            
339
/**
340
 * An implementation of a default rate limit policy that is empty.
341
 */
342
class DefaultRateLimitPolicyImpl : public RateLimitPolicy {
343
public:
344
  // Router::RateLimitPolicy
345
  const std::vector<std::reference_wrapper<const RateLimitPolicyEntry>>&
346
2
  getApplicableRateLimit(uint64_t) const override {
347
2
    return empty_vector_;
348
2
  }
349
1
  bool empty() const override { return true; }
350

            
351
private:
352
  // An empty vector that will be returned for any getApplicableRateLimit() invocation.
353
  const std::vector<std::reference_wrapper<const RateLimitPolicyEntry>> empty_vector_;
354
};
355
using DefaultRateLimitPolicy = ConstSingleton<DefaultRateLimitPolicyImpl>;
356

            
357
} // namespace Router
358
} // namespace Envoy