1
#pragma once
2

            
3
#include <functional>
4
#include <string>
5

            
6
#include "envoy/config/typed_config.h"
7
#include "envoy/extensions/filters/common/dependency/v3/dependency.pb.h"
8
#include "envoy/http/filter.h"
9
#include "envoy/init/manager.h"
10
#include "envoy/network/filter.h"
11
#include "envoy/server/drain_manager.h"
12
#include "envoy/server/factory_context.h"
13

            
14
#include "source/common/common/assert.h"
15
#include "source/common/common/macros.h"
16
#include "source/common/protobuf/protobuf.h"
17

            
18
namespace Envoy {
19
namespace Server {
20
namespace Configuration {
21

            
22
/**
23
 * Common interface for listener filters and UDP listener filters
24
 */
25
class ListenerFilterConfigFactoryBase : public Config::TypedFactory {
26
public:
27
82
  ~ListenerFilterConfigFactoryBase() override = default;
28
};
29

            
30
/**
31
 * Implemented by each listener filter and registered via Registry::registerFactory()
32
 * or the convenience class RegisterFactory.
33
 */
34
class NamedListenerFilterConfigFactory : public ListenerFilterConfigFactoryBase {
35
public:
36
25
  ~NamedListenerFilterConfigFactory() override = default;
37

            
38
  /**
39
   * Create a particular listener filter factory implementation. If the implementation is unable to
40
   * produce a factory with the provided parameters, it should throw an EnvoyException in the case
41
   * of general error or a Json::Exception if the json configuration is erroneous. The returned
42
   * callback should always be initialized.
43
   * @param config supplies the general protobuf configuration for the filter.
44
   * @param listener_filter_matcher supplies the matcher to decide when filter is enabled.
45
   * @param context supplies the filter's context.
46
   * @return Network::ListenerFilterFactoryCb the factory creation function.
47
   */
48
  virtual Network::ListenerFilterFactoryCb createListenerFilterFactoryFromProto(
49
      const Protobuf::Message& config,
50
      const Network::ListenerFilterMatcherSharedPtr& listener_filter_matcher,
51
      ListenerFactoryContext& context) PURE;
52

            
53
165
  std::string category() const override { return "envoy.filters.listener"; }
54
};
55

            
56
/**
57
 * Implemented by each UDP listener filter and registered via Registry::registerFactory()
58
 * or the convenience class RegisterFactory.
59
 */
60
class NamedUdpListenerFilterConfigFactory : public ListenerFilterConfigFactoryBase {
61
public:
62
45
  ~NamedUdpListenerFilterConfigFactory() override = default;
63

            
64
  /**
65
   * Create a particular UDP listener filter factory implementation. If the implementation is unable
66
   * to produce a factory with the provided parameters, it should throw an EnvoyException.
67
   * The returned callback should always be initialized.
68
   * @param config supplies the general protobuf configuration for the filter
69
   * @param context supplies the filter's context.
70
   * @return Network::UdpListenerFilterFactoryCb the factory creation function.
71
   */
72
  virtual Network::UdpListenerFilterFactoryCb
73
  createFilterFactoryFromProto(const Protobuf::Message& config,
74
                               ListenerFactoryContext& context) PURE;
75

            
76
105
  std::string category() const override { return "envoy.filters.udp_listener"; }
77
};
78

            
79
/**
80
 * Implemented by each UDP session filter and registered via Registry::registerFactory or the
81
 * convenience class RegisterFactory.
82
 */
83
class NamedUdpSessionFilterConfigFactory : public Envoy::Config::TypedFactory {
84
public:
85
36
  ~NamedUdpSessionFilterConfigFactory() override = default;
86

            
87
  /**
88
   * Create a particular UDP session filter factory implementation. If the implementation is
89
   * unable to produce a factory with the provided parameters, it should throw an EnvoyException
90
   * in the case of general error. The returned callback should always be initialized.
91
   * @param config supplies the configuration for the filter
92
   * @param context supplies the filter's context.
93
   * @return UdpSessionFilterFactoryCb the factory creation function.
94
   */
95
  virtual Network::UdpSessionFilterFactoryCb
96
  createFilterFactoryFromProto(const Protobuf::Message& config,
97
                               Server::Configuration::FactoryContext& context) PURE;
98

            
99
75
  std::string category() const override { return "envoy.filters.udp.session"; }
100
};
101

            
102
/**
103
 * Implemented by each QUIC listener filter and registered via Registry::registerFactory()
104
 * or the convenience class RegisterFactory.
105
 */
106
class NamedQuicListenerFilterConfigFactory : public ListenerFilterConfigFactoryBase {
107
public:
108
12
  ~NamedQuicListenerFilterConfigFactory() override = default;
109

            
110
  /**
111
   * Create a particular listener filter factory implementation. If the implementation is unable to
112
   * produce a factory with the provided parameters, it should throw an EnvoyException in the case
113
   * of general error or a Json::Exception if the json configuration is erroneous. The returned
114
   * callback should always be initialized.
115
   * @param config supplies the general protobuf configuration for the filter.
116
   * @param listener_filter_matcher supplies the matcher to decide when filter is enabled.
117
   * @param context supplies the filter's context.
118
   * @return Network::QuicListenerFilterFactoryCb the factory creation function.
119
   */
120
  virtual Network::QuicListenerFilterFactoryCb createListenerFilterFactoryFromProto(
121
      const Protobuf::Message& config,
122
      const Network::ListenerFilterMatcherSharedPtr& listener_filter_matcher,
123
      ListenerFactoryContext& context) PURE;
124

            
125
46
  std::string category() const override { return "envoy.filters.quic_listener"; }
126
};
127

            
128
/**
129
 * Implemented by filter factories that require more options to process the protocol used by the
130
 * upstream cluster.
131
 */
132
class ProtocolOptionsFactory : public Config::TypedFactory {
133
public:
134
775
  ~ProtocolOptionsFactory() override = default;
135

            
136
  /**
137
   * Create a particular filter's protocol specific options implementation. If the factory
138
   * implementation is unable to produce a factory with the provided parameters, it should throw an
139
   * EnvoyException.
140
   * @param config supplies the protobuf configuration for the filter
141
   * @param validation_visitor message validation visitor instance.
142
   * @return Upstream::ProtocolOptionsConfigConstSharedPtr the protocol options
143
   * or an error message.
144
   */
145
  virtual absl::StatusOr<Upstream::ProtocolOptionsConfigConstSharedPtr>
146
  createProtocolOptionsConfig(const Protobuf::Message& config,
147
                              ProtocolOptionsFactoryContext& factory_context) {
148
    UNREFERENCED_PARAMETER(config);
149
    UNREFERENCED_PARAMETER(factory_context);
150
    return nullptr;
151
  }
152

            
153
  /**
154
   * @return ProtobufTypes::MessagePtr a newly created empty protocol specific options message or
155
   *         nullptr if protocol specific options are not available.
156
   */
157
  virtual ProtobufTypes::MessagePtr createEmptyProtocolOptionsProto() { return nullptr; }
158
};
159

            
160
using FilterDependenciesPtr =
161
    std::unique_ptr<envoy::extensions::filters::common::dependency::v3::FilterDependencies>;
162
using MatchingRequirementsPtr =
163
    std::unique_ptr<envoy::extensions::filters::common::dependency::v3::MatchingRequirements>;
164

            
165
/**
166
 * Implemented by each network filter and registered via Registry::registerFactory()
167
 * or the convenience class RegisterFactory.
168
 */
169
class NamedNetworkFilterConfigFactory : public ProtocolOptionsFactory {
170
public:
171
228
  ~NamedNetworkFilterConfigFactory() override = default;
172

            
173
  /**
174
   * Create a particular network filter factory implementation. If the implementation is unable to
175
   * produce a factory with the provided parameters, it should throw an EnvoyException. The returned
176
   * callback should always be initialized.
177
   * @param config supplies the general json configuration for the filter
178
   * @param filter_chain_factory_context supplies the filter's context.
179
   * @return Network::FilterFactoryCb the factory creation function or an error status.
180
   */
181
  virtual absl::StatusOr<Network::FilterFactoryCb>
182
  createFilterFactoryFromProto(const Protobuf::Message& config,
183
                               FactoryContext& filter_chain_factory_context) PURE;
184

            
185
1303
  std::string category() const override { return "envoy.filters.network"; }
186

            
187
  /**
188
   * @return bool true if this filter must be the last filter in a filter chain, false otherwise.
189
   */
190
59
  virtual bool isTerminalFilterByProto(const Protobuf::Message&, ServerFactoryContext&) {
191
59
    return false;
192
59
  }
193

            
194
  /**
195
   * Match requirements for the filters created by this filter factory. These requirements inform
196
   * the validator what input/outputs are valid for a match tree specified via the
197
   * ExtensionWithMatcher wrapper, allowing us to reject the match tree at configuration time if
198
   * there are any violations.
199
   *
200
   * @return MatchingRequirementsPtr specification of matching requirements
201
   * for a match tree that can be used with this filter factory.
202
   */
203
3
  virtual MatchingRequirementsPtr matchingRequirements() {
204
3
    return std::make_unique<
205
3
        envoy::extensions::filters::common::dependency::v3::MatchingRequirements>();
206
3
  }
207
};
208

            
209
/**
210
 * Implemented by each upstream cluster network filter and registered via
211
 * Registry::registerFactory() or the convenience class RegisterFactory.
212
 */
213
class NamedUpstreamNetworkFilterConfigFactory : public ProtocolOptionsFactory {
214
public:
215
27
  ~NamedUpstreamNetworkFilterConfigFactory() override = default;
216

            
217
  /**
218
   * Create a particular upstream network filter factory implementation. If the implementation is
219
   * unable to produce a factory with the provided parameters, it should throw an EnvoyException in
220
   * the case of general error. The returned callback should always be initialized.
221
   */
222
  virtual Network::FilterFactoryCb
223
  createFilterFactoryFromProto(const Protobuf::Message& config,
224
                               UpstreamFactoryContext& context) PURE;
225

            
226
37
  std::string category() const override { return "envoy.filters.upstream_network"; }
227

            
228
  /**
229
   * @return bool true if this filter must be the last filter in a filter chain, false otherwise.
230
   */
231
36
  virtual bool isTerminalFilterByProto(const Protobuf::Message&, ServerFactoryContext&) {
232
36
    return false;
233
36
  }
234
};
235

            
236
/**
237
 * Implemented by each HTTP filter and registered via Registry::registerFactory or the
238
 * convenience class RegisterFactory.
239
 */
240
class HttpFilterConfigFactoryBase : public ProtocolOptionsFactory {
241
public:
242
520
  ~HttpFilterConfigFactoryBase() override = default;
243

            
244
  /**
245
   * @return ProtobufTypes::MessagePtr create an empty virtual host, route, or weighted
246
   *         cluster-local config proto message for v2. The filter config, which arrives in an
247
   *         opaque message, will be parsed into this empty proto. By default, this method
248
   *         returns the same value as createEmptyConfigProto, and can be optionally overridden
249
   *         in implementations.
250
   */
251
126
  virtual ProtobufTypes::MessagePtr createEmptyRouteConfigProto() {
252
126
    return createEmptyConfigProto();
253
126
  }
254

            
255
  /**
256
   * @return RouteSpecificFilterConfigConstSharedPtr allow the filter to pre-process per route
257
   * config. Returned object will be stored in the loaded route configuration.
258
   */
259
  virtual absl::StatusOr<Router::RouteSpecificFilterConfigConstSharedPtr>
260
  createRouteSpecificFilterConfig(const Protobuf::Message&, ServerFactoryContext&,
261
5
                                  ProtobufMessage::ValidationVisitor&) {
262
5
    return nullptr;
263
5
  }
264

            
265
11845
  std::string category() const override { return "envoy.filters.http"; }
266

            
267
  /**
268
   * @return FilterDependenciesPtr specification of dependencies required or
269
   * provided on the decode and encode paths. This function returns an empty
270
   * filter dependencies specification by default, and can be overridden.
271
   */
272
15653
  virtual FilterDependenciesPtr dependencies() {
273
15653
    return std::make_unique<
274
15653
        envoy::extensions::filters::common::dependency::v3::FilterDependencies>();
275
15653
  }
276

            
277
  /**
278
   * Match requirements for the filters created by this filter factory. These requirements inform
279
   * the validator what input/outputs are valid for a match tree specified via the
280
   * ExtensionWithMatcher wrapper, allowing us to reject the match tree at configuration time if
281
   * there are any violations.
282
   *
283
   * @return MatchingRequirementsPtr specification of matching requirements
284
   * for a match tree that can be used with this filter factory.
285
   */
286
76
  virtual MatchingRequirementsPtr matchingRequirements() {
287
76
    return std::make_unique<
288
76
        envoy::extensions::filters::common::dependency::v3::MatchingRequirements>();
289
76
  }
290

            
291
5215
  std::set<std::string> configTypes() override {
292
5215
    auto config_types = TypedFactory::configTypes();
293

            
294
5215
    if (auto message = createEmptyRouteConfigProto(); message != nullptr) {
295
5215
      config_types.emplace(createReflectableMessage(*message)->GetDescriptor()->full_name());
296
5215
    }
297

            
298
5215
    return config_types;
299
5215
  }
300

            
301
  /**
302
   * @return bool true if this filter must be the last filter in a filter chain, false otherwise.
303
   */
304
  virtual bool isTerminalFilterByProto(const Protobuf::Message&,
305
1295
                                       Server::Configuration::ServerFactoryContext&) {
306
1295
    return false;
307
1295
  }
308
};
309

            
310
class NamedHttpFilterConfigFactory : public virtual HttpFilterConfigFactoryBase {
311
public:
312
  /**
313
   * Create a particular http filter factory implementation. If the implementation is unable to
314
   * produce a factory with the provided parameters, it should throw an EnvoyException. The returned
315
   * callback should always be initialized.
316
   * @param config supplies the general Protobuf message to be marshaled into a filter-specific
317
   * configuration.
318
   * @param stat_prefix prefix for stat logging
319
   * @param context supplies the filter's context.
320
   * @return  absl::StatusOr<Http::FilterFactoryCb> the factory creation function or an error if
321
   * creation fails.
322
   */
323
  virtual absl::StatusOr<Http::FilterFactoryCb>
324
  createFilterFactoryFromProto(const Protobuf::Message& config, const std::string& stat_prefix,
325
                               Server::Configuration::FactoryContext& context) PURE;
326

            
327
  /**
328
   * Create a particular http filter factory implementation. If the implementation is unable to
329
   * produce a factory with the provided parameters or this method is not supported, it should throw
330
   * an EnvoyException. The returned callback should always be initialized.
331
   * @param config supplies the general Protobuf message to be marshaled into a filter-specific
332
   * configuration.
333
   * @param stat_prefix prefix for stat logging
334
   * @param context supplies the filter's ServerFactoryContext.
335
   * @return Http::FilterFactoryCb the factory creation function.
336
   */
337
  virtual Http::FilterFactoryCb
338
  createFilterFactoryFromProtoWithServerContext(const Protobuf::Message&, const std::string&,
339
                                                Server::Configuration::ServerFactoryContext&) {
340
    ExceptionUtil::throwEnvoyException(
341
        "Creating filter factory from server factory context is not supported");
342
    return nullptr;
343
  }
344
};
345

            
346
class UpstreamHttpFilterConfigFactory : public virtual HttpFilterConfigFactoryBase {
347
public:
348
  /**
349
   * Create a particular http filter factory implementation. If the implementation is unable to
350
   * produce a factory with the provided parameters, it should throw an EnvoyException. The returned
351
   * callback should always be initialized.
352
   * @param config supplies the general Protobuf message to be marshaled into a filter-specific
353
   * configuration.
354
   * @param stat_prefix prefix for stat logging
355
   * @param context supplies the filter's context.
356
   * @return Http::FilterFactoryCb the factory creation function.
357
   */
358
  virtual absl::StatusOr<Http::FilterFactoryCb>
359
  createFilterFactoryFromProto(const Protobuf::Message& config, const std::string& stat_prefix,
360
                               Server::Configuration::UpstreamFactoryContext& context) PURE;
361
};
362

            
363
} // namespace Configuration
364
} // namespace Server
365
} // namespace Envoy