Skip to content

Commit

Permalink
filter state: register DFP objects
Browse files Browse the repository at this point in the history
Signed-off-by: Kuat Yessenov <[email protected]>
  • Loading branch information
kyessenov committed Sep 5, 2023
1 parent e4741cb commit c189ec3
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 3 deletions.
9 changes: 8 additions & 1 deletion docs/root/configuration/advanced/well_known_filter_state.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@ The following list of filter state objects are consumed by Envoy extensions:
* - **Filter state key**
- **Purpose**
* - ``envoy.tcp_proxy.cluster``
- :ref:`TCP proxy <config_network_filters_tcp_proxy>` dynamic cluster selection on a per-connection basis.
- | :ref:`TCP proxy <config_network_filters_tcp_proxy>` dynamic cluster name selection
| on a per-connection basis.
* - ``envoy.network.transport_socket.original_dst_address``
- | :ref:`Original destination cluster <arch_overview_load_balancing_types_original_destination>` dynamic address selection.
| Fields:
| - *ip*: IP address value;
| - *port*: port value.
* - ``envoy.upstream.dynamic_host``
- | :ref:`Dynamic forward proxy <envoy_v3_api_msg_extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig>``
| upstream host override on a per-connection basis.
* - ``envoy.upstream.dynamic_port``
- | :ref:`Dynamic forward proxy <envoy_v3_api_msg_extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig>``
| upstream port override on a per-connection basis.
3 changes: 3 additions & 0 deletions source/common/stream_info/uint32_accessor_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class UInt32AccessorImpl : public UInt32Accessor {
message->set_value(value_);
return message;
}
absl::optional<std::string> serializeAsString() const override {
return absl::StrCat(value_);
}

// From UInt32Accessor.
void increment() override { value_++; }
Expand Down
2 changes: 2 additions & 0 deletions source/extensions/clusters/dynamic_forward_proxy/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ envoy_cc_extension(
"//source/extensions/common/dynamic_forward_proxy:cluster_store",
"//source/extensions/common/dynamic_forward_proxy:dns_cache_interface",
"//source/extensions/common/dynamic_forward_proxy:dns_cache_manager_impl",
"//source/common/router:string_accessor_lib",
"//source/common/stream_info:uint32_accessor_lib",
"//source/extensions/transport_sockets/tls/cert_validator:cert_validator_lib",
"@envoy_api//envoy/config/cluster/v3:pkg_cc_proto",
"@envoy_api//envoy/config/endpoint/v3:pkg_cc_proto",
Expand Down
36 changes: 34 additions & 2 deletions source/extensions/clusters/dynamic_forward_proxy/cluster.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include "source/common/http/utility.h"
#include "source/common/network/transport_socket_options_impl.h"
#include "source/common/router/string_accessor_impl.h"
#include "source/common/stream_info/uint32_accessor_impl.h"
#include "source/extensions/common/dynamic_forward_proxy/dns_cache_manager_impl.h"
#include "source/extensions/transport_sockets/tls/cert_validator/default_validator.h"
#include "source/extensions/transport_sockets/tls/utility.h"
Expand All @@ -19,6 +21,36 @@ namespace Extensions {
namespace Clusters {
namespace DynamicForwardProxy {

namespace {
constexpr absl::string_view DynamicHostFilterStateKey = "envoy.upstream.dynamic_host";
constexpr absl::string_view DynamicPortFilterStateKey = "envoy.upstream.dynamic_port";

class DynamicHostObjectFactory : public StreamInfo::FilterState::ObjectFactory {
public:
std::string name() const override { return std::string(DynamicHostFilterStateKey); }
std::unique_ptr<StreamInfo::FilterState::Object>
createFromBytes(absl::string_view data) const override {
return std::make_unique<Router::StringAccessorImpl>(data);
}
};
class DynamicPortObjectFactory : public StreamInfo::FilterState::ObjectFactory {
public:
std::string name() const override { return std::string(DynamicPortFilterStateKey); }
std::unique_ptr<StreamInfo::FilterState::Object>
createFromBytes(absl::string_view data) const override {
uint32_t port = 0;
if (absl::SimpleAtoi(data, &port)) {
return std::make_unique<StreamInfo::UInt32AccessorImpl>(port);
}
return nullptr;
}
};

} // namespace

REGISTER_FACTORY(DynamicHostObjectFactory, StreamInfo::FilterState::ObjectFactory);
REGISTER_FACTORY(DynamicPortObjectFactory, StreamInfo::FilterState::ObjectFactory);

Cluster::Cluster(
const envoy::config::cluster::v3::Cluster& cluster,
const envoy::extensions::clusters::dynamic_forward_proxy::v3::ClusterConfig& config,
Expand Down Expand Up @@ -316,7 +348,7 @@ Cluster::LoadBalancer::chooseHost(Upstream::LoadBalancerContext* context) {
context->downstreamConnection()
->streamInfo()
.filterState()
.getDataReadOnly<Router::StringAccessor>("envoy.upstream.dynamic_host");
.getDataReadOnly<Router::StringAccessor>(DynamicHostFilterStateKey);
}

absl::string_view raw_host;
Expand All @@ -343,7 +375,7 @@ Cluster::LoadBalancer::chooseHost(Upstream::LoadBalancerContext* context) {
context->downstreamConnection()
->streamInfo()
.filterState()
.getDataReadOnly<StreamInfo::UInt32Accessor>("envoy.upstream.dynamic_port");
.getDataReadOnly<StreamInfo::UInt32Accessor>(DynamicPortFilterStateKey);
if (dynamic_port_filter_state != nullptr && dynamic_port_filter_state->value() > 0 &&
dynamic_port_filter_state->value() <= 65535) {
port = dynamic_port_filter_state->value();
Expand Down
25 changes: 25 additions & 0 deletions test/extensions/clusters/dynamic_forward_proxy/cluster_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,31 @@ connect_timeout: 0.25s
EXPECT_THROW(createCluster(yaml_config), EnvoyException);
}

TEST(ObjectFactory, DynamicHost) {
const std::string name = "envoy.upstream.dynamic_host";
auto* factory =
Registry::FactoryRegistry<StreamInfo::FilterState::ObjectFactory>::getFactory(name);
ASSERT_NE(nullptr, factory);
EXPECT_EQ(name, factory->name());
const std::string host = "site.com";
auto object = factory->createFromBytes(host);
ASSERT_NE(nullptr, object);
EXPECT_EQ(host, object->serializeAsString());
}

TEST(ObjectFactory, DynamicPort) {
const std::string name = "envoy.upstream.dynamic_port";
auto* factory =
Registry::FactoryRegistry<StreamInfo::FilterState::ObjectFactory>::getFactory(name);
ASSERT_NE(nullptr, factory);
EXPECT_EQ(name, factory->name());
const std::string port = "8080";
auto object = factory->createFromBytes(port);
ASSERT_NE(nullptr, object);
EXPECT_EQ(port, object->serializeAsString());
ASSERT_EQ(nullptr, factory->createFromBytes("blah"));
}

} // namespace DynamicForwardProxy
} // namespace Clusters
} // namespace Extensions
Expand Down

0 comments on commit c189ec3

Please sign in to comment.