Skip to content
Merged
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
4cfa9c5
udp: add route proto
zhxie Aug 24, 2021
9891c45
udp: add router
zhxie Aug 25, 2021
367db00
udp: route data to clusters
zhxie Aug 25, 2021
3bd3085
udp: fix format
zhxie Aug 25, 2021
4c1b126
udp: minor type change
zhxie Aug 26, 2021
3f762f7
udp: clean code
zhxie Aug 26, 2021
95e1094
test: add test for routing in UDP proxy
zhxie Aug 26, 2021
b592612
test: add test for route matching of UDP proxy
zhxie Aug 26, 2021
804aedd
test: fix format
zhxie Aug 26, 2021
37def08
udp: deprecate api in favor of router
zhxie Aug 27, 2021
77fb547
test: prioritize router
zhxie Aug 27, 2021
9c71fe4
docs: prioritize router
zhxie Aug 31, 2021
b4cbd8d
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Oct 20, 2021
4a201e7
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Oct 21, 2021
b5086f2
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Oct 25, 2021
42ce9c3
router: add network data inputs
zhxie Oct 26, 2021
0b14da0
udp: migrate to generic matching API
zhxie Oct 26, 2021
744d74b
router: change cidr data input to IP and port
zhxie Oct 27, 2021
cf61bb7
udp: fix no cluster initialized when using generic matching
zhxie Oct 27, 2021
cc24008
example: update UDP proxy example
zhxie Oct 27, 2021
f5fd481
docs: update to generic matching
zhxie Oct 27, 2021
f613a87
docs: fix orphan proto
zhxie Oct 27, 2021
4a2f3f8
test: update to generic matching
zhxie Oct 27, 2021
115b532
test: remove redundant code
zhxie Oct 28, 2021
db04638
udp: fix bug using variable out of scope
zhxie Oct 28, 2021
e9f56d7
router: update network matching data structure
zhxie Oct 28, 2021
786386b
test: add router coverage
zhxie Oct 28, 2021
f615fd5
test: add test for network data inputs
zhxie Oct 28, 2021
854176a
test: fix spelling
zhxie Oct 28, 2021
7cff9bf
test: fix format
zhxie Oct 28, 2021
b0fb7d6
udp: change router method name
zhxie Nov 1, 2021
8cfdf65
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Nov 1, 2021
cfee9b0
udp: remove generated api shadow
zhxie Nov 1, 2021
063cf40
router: remove unused data inputs
zhxie Nov 1, 2021
35b0f5e
udp: fix not throw on invalid data inputs
zhxie Nov 1, 2021
7303e6f
udp: add docs for method
zhxie Nov 1, 2021
8184199
test: mark some tests as deprecated feature test
zhxie Nov 1, 2021
8f3e8e0
udp: revert deprecating cluster syntax
zhxie Nov 2, 2021
ecddff7
test: lower coverage for untested simple method in matching data
zhxie Nov 2, 2021
fae4e72
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Nov 2, 2021
69376a9
docs: add release notes
zhxie Nov 2, 2021
0fc55bf
ci: kick CI
zhxie Nov 2, 2021
e779a36
udp: use full path for include
zhxie Nov 11, 2021
fb2731e
udp: update router abstraction
zhxie Nov 11, 2021
68dc8fb
udp: deprecate cluster API again
zhxie Nov 11, 2021
8de2770
ci: kick CI
zhxie Nov 11, 2021
e9cf799
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Nov 29, 2021
03005e5
udp: fix filter
zhxie Nov 29, 2021
e162cae
tests: prioritize router
zhxie Nov 29, 2021
d62539e
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Dec 1, 2021
e49181a
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Dec 31, 2021
b04a059
api: fix format
zhxie Jan 5, 2022
87d1361
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Jan 10, 2022
bd7b917
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Jan 12, 2022
b00cf9e
nit: add comments and rename methods
zhxie Jan 12, 2022
45165c6
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Feb 14, 2022
5173760
docs: update release notes
zhxie Feb 14, 2022
0e19161
nit: change parameter names
zhxie Feb 14, 2022
8b30f25
docs: update examples
zhxie Feb 14, 2022
d3db96e
examples: update examples
zhxie Feb 14, 2022
b501e34
tests: use single on_no_match
zhxie Feb 14, 2022
bc33bd0
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Feb 25, 2022
2b9fe8d
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Feb 25, 2022
9d1abd2
docs: fix release notes
zhxie Feb 25, 2022
628855d
api: remove duplicate matching data from merging
zhxie Feb 25, 2022
cb3d52c
api: remove duplicate matching data from merging
zhxie Feb 25, 2022
d6911cc
udp: comply with network inputs
zhxie Feb 25, 2022
29e86f8
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Mar 28, 2022
4478d77
udp: replace with network inputs
zhxie Mar 28, 2022
c1dc8b1
test: add UDP router test
zhxie Mar 28, 2022
086ea89
nit: add comment for cluster infos
zhxie Mar 28, 2022
cf77be6
nit: explicitize variable route
zhxie Mar 28, 2022
4830ec7
udp: route with different network inputs
zhxie Mar 28, 2022
5ff8de5
docs: add docs for UDP proxy router
zhxie Mar 28, 2022
43a1b80
docs: fix matcher example
zhxie Mar 28, 2022
2be0b73
docs: fix matcher example
zhxie Mar 28, 2022
03b55aa
udp: remove unused guard
zhxie Mar 29, 2022
549a487
docs: emphasize matcher only
zhxie Mar 29, 2022
a08f1e1
api: clarify deprecation and usage
zhxie Mar 30, 2022
d368ef3
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Mar 30, 2022
9b46d46
mis: post merge conflict
zhxie Mar 30, 2022
79d1748
docs: fix missing label
zhxie Mar 30, 2022
f959f11
docs: add deprecation notes
zhxie Mar 31, 2022
b9ac01e
nit: typo
zhxie Mar 31, 2022
96d1ca1
udp: ensure matching
zhxie Mar 31, 2022
f0eead0
udp: fix cluster removal log
zhxie Mar 31, 2022
a5fc56d
udp: change specifier in route
zhxie Mar 31, 2022
00a84ef
udp: merge path of cluster and matcher
zhxie Mar 31, 2022
eede13d
nit: fix typo
zhxie Apr 1, 2022
0617a91
udp: update signature of route
zhxie Apr 1, 2022
4eeea14
test: fix route
zhxie Apr 1, 2022
dc59d27
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Apr 1, 2022
3f9c62c
Merge remote-tracking branch 'envoyproxy/main' into udp-proxy-router
zhxie Apr 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/envoy/extensions/filters/udp/udp_proxy/v3/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ licenses(["notice"]) # Apache 2

api_proto_package(
deps = [
"//envoy/annotations:pkg",
"//envoy/config/core/v3:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",
"@com_github_cncf_udpa//xds/annotations/v3:pkg",
"@com_github_cncf_udpa//xds/type/matcher/v3:pkg",
],
)
20 changes: 20 additions & 0 deletions api/envoy/extensions/filters/udp/udp_proxy/v3/route.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
syntax = "proto3";

package envoy.extensions.filters.udp.udp_proxy.v3;

import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.filters.udp.udp_proxy.v3";
option java_outer_classname = "RouteProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/udp/udp_proxy/v3;udp_proxyv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: UDP proxy route configuration]
// UDP proxy :ref:`configuration overview <config_udp_listener_filters_udp_proxy>`.

message Route {
// Indicates the upstream cluster to which the request should be routed.
string cluster = 1 [(validate.rules).string = {min_len: 1}];
}
16 changes: 14 additions & 2 deletions api/envoy/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import "envoy/config/core/v3/udp_socket_config.proto";

import "google/protobuf/duration.proto";

import "xds/annotations/v3/status.proto";
import "xds/type/matcher/v3/matcher.proto";

import "envoy/annotations/deprecation.proto";
import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
import "validate/validate.proto";
Expand All @@ -21,7 +25,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#extension: envoy.filters.udp_listener.udp_proxy]

// Configuration for the UDP proxy filter.
// [#next-free-field: 8]
// [#next-free-field: 9]
message UdpProxyConfig {
option (udpa.annotations.versioning).previous_message_type =
"envoy.config.filter.udp.udp_proxy.v2alpha.UdpProxyConfig";
Expand Down Expand Up @@ -51,7 +55,15 @@ message UdpProxyConfig {
option (validate.required) = true;

// The upstream cluster to connect to.
Comment thread
mattklein123 marked this conversation as resolved.
string cluster = 2 [(validate.rules).string = {min_len: 1}];
string cluster = 2 [
deprecated = true,
(validate.rules).string = {min_len: 1},
(envoy.annotations.deprecated_at_minor_version) = "3.0"
];
Comment thread
mattklein123 marked this conversation as resolved.

// The match tree to use when resolving route actions for incoming requests.
Comment thread
mattklein123 marked this conversation as resolved.
xds.type.matcher.v3.Matcher matcher = 8
[(xds.annotations.v3.field_status).work_in_progress = true];
}

// The idle timeout for sessions. Idle is defined as no datagrams between received or sent by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ static_resources:
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.UdpProxyConfig
stat_prefix: service
cluster: service_udp
matcher:
Comment thread
mattklein123 marked this conversation as resolved.
on_no_match:
action:
name: route
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route
cluster: service_udp
upstream_socket_config:
max_rx_datagram_size: 9000
clusters:
Expand Down
1 change: 1 addition & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ New Features
useful in support systems such as CI, CD, etc. The
:ref:`schema validator check tool <install_tools_schema_validator_check_tool>` has been added
to the tools image.
* udp_proxy: added :ref:`matcher <envoy_v3_api_field_extensions.filters.udp.udp_proxy.v3.UdpProxyConfig.matcher>` to support matching and routing to different clusters.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a note in deprecated below for the deprecated field.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, added.


Deprecated
----------
Expand Down
8 changes: 7 additions & 1 deletion examples/udp/envoy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ static_resources:
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.UdpProxyConfig
stat_prefix: service
cluster: service_udp
matcher:
on_no_match:
action:
name: route
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route
cluster: service_udp

clusters:
- name: service_udp
Expand Down
2 changes: 2 additions & 0 deletions source/extensions/filters/udp/udp_proxy/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ envoy_cc_library(
"//envoy/network:listener_interface",
"//envoy/upstream:cluster_manager_interface",
"//source/common/api:os_sys_calls_lib",
"//source/common/common:empty_string",
"//source/common/network:socket_lib",
"//source/common/network:socket_option_factory_lib",
"//source/common/network:utility_lib",
"//source/common/upstream:load_balancer_lib",
"//source/extensions/filters/udp/udp_proxy/router:router_lib",
"@envoy_api//envoy/extensions/filters/udp/udp_proxy/v3:pkg_cc_proto",
],
)
Expand Down
1 change: 1 addition & 0 deletions source/extensions/filters/udp/udp_proxy/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class UdpProxyFilterConfigFactory
Server::Configuration::ListenerFactoryContext& context) override {
auto shared_config = std::make_shared<UdpProxyFilterConfig>(
context.clusterManager(), context.timeSource(), context.scope(),
context.getServerFactoryContext(),
MessageUtil::downcastAndValidate<
const envoy::extensions::filters::udp::udp_proxy::v3::UdpProxyConfig&>(
config, context.messageValidationVisitor()));
Expand Down
29 changes: 29 additions & 0 deletions source/extensions/filters/udp/udp_proxy/router/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_extension_package",
)

licenses(["notice"]) # Apache 2

envoy_extension_package()

envoy_cc_library(
name = "router_interface",
hdrs = ["router.h"],
)

envoy_cc_library(
name = "router_lib",
srcs = ["router_impl.cc"],
hdrs = ["router_impl.h"],
deps = [
":router_interface",
"//source/common/common:empty_string",
"//source/common/matcher:matcher_lib",
"//source/common/matcher:validation_visitor_lib",
"//source/common/network/matching:inputs_lib",
"@envoy_api//envoy/extensions/filters/udp/udp_proxy/v3:pkg_cc_proto",
"@envoy_api//envoy/type/matcher/v3:pkg_cc_proto",
],
)
45 changes: 45 additions & 0 deletions source/extensions/filters/udp/udp_proxy/router/router.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include <memory>
#include <string>
#include <vector>

#include "envoy/common/pure.h"
#include "envoy/network/address.h"

namespace Envoy {
namespace Extensions {
namespace UdpFilters {
namespace UdpProxy {
namespace Router {

/**
* The router which holds all clusters and determines the cluster which UDP data should be routed
* to.
*/
class Router {
public:
virtual ~Router() = default;

/**
* Based on the source address of the incoming UDP data, determine the target route for the data.
* @return the cluster name or empty string if there is not matching route for the data.
*/
virtual const std::string
route(Network::Address::InstanceConstSharedPtr source_address) const PURE;

/**
* Returns all cluster names in the router. The UDP proxy filter requires every cluster names for

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Returns all cluster names in the router. The UDP proxy filter requires every cluster names for
* Returns all cluster names in the router. The UDP proxy filter requires every cluster name for

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, changed.

* initialization which will call this method on construction.
* @return vector of all cluster names.
*/
virtual const std::vector<std::string>& allClusterNames() const PURE;
};

using RouterConstSharedPtr = std::shared_ptr<const Router>;

} // namespace Router
} // namespace UdpProxy
} // namespace UdpFilters
} // namespace Extensions
} // namespace Envoy
93 changes: 93 additions & 0 deletions source/extensions/filters/udp/udp_proxy/router/router_impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include "source/extensions/filters/udp/udp_proxy/router/router_impl.h"

#include "envoy/extensions/filters/udp/udp_proxy/v3/route.pb.h"
#include "envoy/extensions/filters/udp/udp_proxy/v3/route.pb.validate.h"
#include "envoy/type/matcher/v3/network_inputs.pb.h"

#include "source/common/common/empty_string.h"
#include "source/common/network/matching/data_impl.h"
#include "source/common/network/matching/inputs.h"

namespace Envoy {
namespace Extensions {
namespace UdpFilters {
namespace UdpProxy {
namespace Router {

Matcher::ActionFactoryCb RouteMatchActionFactory::createActionFactoryCb(
const Protobuf::Message& config, RouteActionContext& context,
ProtobufMessage::ValidationVisitor& validation_visitor) {
const auto& route_config = MessageUtil::downcastAndValidate<
const envoy::extensions::filters::udp::udp_proxy::v3::Route&>(config, validation_visitor);
const auto& cluster = route_config.cluster();

// Emplace cluster names to context to get all cluster names
context.cluster_name_.emplace(cluster);

return [cluster]() { return std::make_unique<RouteMatchAction>(cluster); };
}

REGISTER_FACTORY(RouteMatchActionFactory, Matcher::ActionFactory<RouteActionContext>);

absl::Status RouteActionValidationVisitor::performDataInputValidation(
const Matcher::DataInputFactory<Network::MatchingData>&, absl::string_view type_url) {
static std::string source_ip_input_name = TypeUtil::descriptorFullNameToTypeUrl(
envoy::type::matcher::v3::SourceIpMatchInput::descriptor()->full_name());
if (type_url == source_ip_input_name) {
return absl::OkStatus();
}

return absl::InvalidArgumentError(
fmt::format("Route table can only match on source IP, saw {}", type_url));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the source IP input is the only thing registered for this match tree I don't think we need this additional validation, just means more work whenever a new input is added

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently we only support sip input, but I think I have registered sip, dip, sport, dport in the match tree for future use.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I think I have registered sip, dip, sport, dport in the match tree for future use.

Can we just remove them for now and add them later? I would rather only add the code that is actually used. It will also make this PR smaller.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will remove these data inputs, but I still think the validation is necessary since a HTTP data input is also syntax valid for the UDP router and the validator will keep the gate.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way the factory registrations work is that registrations are unique per data input type, so since you're using the NetworkDataInput it won't share registrations with HttpDataInput registrations

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TEST_F(RouterImplTest, InvalidDataInput) {

Yes, I also think matcher is expected to work that way, but the test shows Envoy will not stop until the validation visitor returns the error. I guess the registration of HttpDataInput is shared with NetworkDataInput, do I miss something?

}

RouterImpl::RouterImpl(const envoy::extensions::filters::udp::udp_proxy::v3::UdpProxyConfig& config,
Server::Configuration::ServerFactoryContext& factory_context) {
if (config.has_cluster()) {
cluster_ = config.cluster();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be a bit cleaner to just synthesize matcher config for this case. Then you can use unified code for the rest of it? (Basically it makes the deprecated path cheaper to maintain and understand as the only special case is here.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry but I cannot catch your idea here. Do you mention we can move cluster_ out of Router?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I catch your thought finally, I will submit the commit soon.

cluster_names_.push_back(config.cluster());
} else {
RouteActionContext context{};
RouteActionValidationVisitor validation_visitor;
Matcher::MatchTreeFactory<Network::MatchingData, RouteActionContext> factory(
context, factory_context, validation_visitor);
matcher_ = factory.create(config.matcher())();

if (!validation_visitor.errors().empty()) {
// TODO(snowp): Output all violations.
throw EnvoyException(fmt::format("requirement violation while creating route match tree: {}",
validation_visitor.errors()[0]));
}

// Copy all clusters names
cluster_names_.insert(cluster_names_.end(), context.cluster_name_.begin(),
context.cluster_name_.end());
}
}

const std::string RouterImpl::route(Network::Address::InstanceConstSharedPtr source_address) const {
if (cluster_.has_value()) {
return cluster_.value();
}

if (source_address->ip()) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically isn't it possible to send UDP/datagrams over a pipe? Or do we block this in config? Either way it seems like this should be handled elsewhere as a config load issue vs. on every route request?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is redundant. I will remove it, thanks.

Network::Matching::MatchingDataImpl data(source_address->ip());

auto result = matcher_->match(data);
if (result.match_state_ == Matcher::MatchState::MatchComplete) {
if (result.on_match_.has_value()) {
return result.on_match_.value().action_cb_()->getTyped<RouteMatchAction>().cluster();
}
}
}

return EMPTY_STRING;
}

const std::vector<std::string>& RouterImpl::allClusterNames() const { return cluster_names_; }

} // namespace Router
} // namespace UdpProxy
} // namespace UdpFilters
} // namespace Extensions
} // namespace Envoy
71 changes: 71 additions & 0 deletions source/extensions/filters/udp/udp_proxy/router/router_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once

#include "envoy/extensions/filters/udp/udp_proxy/v3/route.pb.h"
#include "envoy/extensions/filters/udp/udp_proxy/v3/udp_proxy.pb.h"
#include "envoy/network/filter.h"
#include "envoy/server/factory_context.h"

#include "source/common/matcher/matcher.h"
#include "source/common/matcher/validation_visitor.h"
#include "source/extensions/filters/udp/udp_proxy/router/router.h"

namespace Envoy {
namespace Extensions {
namespace UdpFilters {
namespace UdpProxy {
namespace Router {

struct RouteActionContext {
absl::flat_hash_set<std::string> cluster_name_;
};

class RouteMatchAction
: public Matcher::ActionBase<envoy::extensions::filters::udp::udp_proxy::v3::Route> {
public:
explicit RouteMatchAction(const std::string& cluster) : cluster_(cluster) {}

const std::string& cluster() const { return cluster_; }

private:
const std::string cluster_;
};

class RouteMatchActionFactory : public Matcher::ActionFactory<RouteActionContext> {
public:
Matcher::ActionFactoryCb
createActionFactoryCb(const Protobuf::Message& config, RouteActionContext& context,
ProtobufMessage::ValidationVisitor& validation_visitor) override;
std::string name() const override { return "route"; }
ProtobufTypes::MessagePtr createEmptyConfigProto() override {
return std::make_unique<envoy::extensions::filters::udp::udp_proxy::v3::Route>();
}
};

class RouteActionValidationVisitor
: public Matcher::MatchTreeValidationVisitor<Network::MatchingData> {
public:
absl::Status
performDataInputValidation(const Matcher::DataInputFactory<Network::MatchingData>& data_input,
absl::string_view type_url) override;
};

class RouterImpl : public Router {
public:
RouterImpl(const envoy::extensions::filters::udp::udp_proxy::v3::UdpProxyConfig& config,
Server::Configuration::ServerFactoryContext& context);

// Router::Router
const std::string route(Network::Address::InstanceConstSharedPtr source_address) const override;
const std::vector<std::string>& allClusterNames() const override;

private:
absl::optional<std::string> cluster_;
Matcher::MatchTreeSharedPtr<Network::MatchingData> matcher_;
std::vector<std::string> cluster_names_;
};

} // namespace Router
} // namespace UdpProxy
} // namespace UdpFilters
} // namespace Extensions
} // namespace Envoy
Loading