Skip to content

Commit

Permalink
filter state: add more well-known 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 22, 2023
1 parent 94a69e5 commit cae3e7c
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 0 deletions.
14 changes: 14 additions & 0 deletions docs/root/configuration/advanced/well_known_filter_state.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ The following list of filter state objects are consumed by Envoy extensions:

* - **Filter state key**
- **Purpose**
* - ``envoy.network.upstream_server_name``
- | Sets the transport socket option to override the
| `SNI <https://en.wikipedia.org/wiki/Server_Name_Indication>`
| in the upstream connections.
| Accepts a host name as a constructor, e.g. "lyft.com".
* - ``envoy.network.application_protocols``
- | Sets the transport socket option to override the
| `ALPN <https://en.wikipedia.org/wiki/Application-Layer Protocol Negotiation>` list
| in the upstream connections. This setting takes precedence over the upstream cluster
| configuration.
| Accepts a comma-separated list of protocols as a constructor, e.g. "h2,http/1.1".
* - ``envoy.network.upstream_subject_alt_names``
| Enables additional verification of the upstream peer certificate SAN names.
| Accepts a comma-separated list of SAN names as a constructor.
* - ``envoy.tcp_proxy.cluster``
- | :ref:`TCP proxy <config_network_filters_tcp_proxy>` dynamic cluster name selection
| on a per-connection basis.
Expand Down
3 changes: 3 additions & 0 deletions source/common/network/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ envoy_cc_library(
srcs = ["application_protocol.cc"],
hdrs = ["application_protocol.h"],
deps = [
"//envoy/registry",
"//envoy/stream_info:filter_state_interface",
"//source/common/common:macros",
],
Expand Down Expand Up @@ -520,6 +521,7 @@ envoy_cc_library(
srcs = ["upstream_server_name.cc"],
hdrs = ["upstream_server_name.h"],
deps = [
"//envoy/registry",
"//envoy/stream_info:filter_state_interface",
"//source/common/common:macros",
],
Expand All @@ -530,6 +532,7 @@ envoy_cc_library(
srcs = ["upstream_subject_alt_names.cc"],
hdrs = ["upstream_subject_alt_names.h"],
deps = [
"//envoy/registry",
"//envoy/stream_info:filter_state_interface",
"//source/common/common:macros",
],
Expand Down
15 changes: 15 additions & 0 deletions source/common/network/application_protocol.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "source/common/network/application_protocol.h"

#include "envoy/registry/registry.h"
#include "envoy/stream_info/filter_state.h"

#include "source/common/common/macros.h"

namespace Envoy {
Expand All @@ -8,5 +11,17 @@ namespace Network {
const std::string& ApplicationProtocols::key() {
CONSTRUCT_ON_FIRST_USE(std::string, "envoy.network.application_protocols");
}

class ApplicationProtocolsObjectFactory : public StreamInfo::FilterState::ObjectFactory {
public:
std::string name() const override { return ApplicationProtocols::key(); }
std::unique_ptr<StreamInfo::FilterState::Object>
createFromBytes(absl::string_view data) const override {
const std::vector<std::string> parts = absl::StrSplit(data, ',');
return std::make_unique<ApplicationProtocols>(parts);
}
};

REGISTER_FACTORY(ApplicationProtocolsObjectFactory, StreamInfo::FilterState::ObjectFactory);
} // namespace Network
} // namespace Envoy
15 changes: 15 additions & 0 deletions source/common/network/upstream_server_name.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "source/common/network/upstream_server_name.h"

#include "envoy/registry/registry.h"
#include "envoy/stream_info/filter_state.h"

#include "source/common/common/macros.h"

namespace Envoy {
Expand All @@ -8,5 +11,17 @@ namespace Network {
const std::string& UpstreamServerName::key() {
CONSTRUCT_ON_FIRST_USE(std::string, "envoy.network.upstream_server_name");
}

class UpstreamServerNameObjectFactory : public StreamInfo::FilterState::ObjectFactory {
public:
std::string name() const override { return UpstreamServerName::key(); }
std::unique_ptr<StreamInfo::FilterState::Object>
createFromBytes(absl::string_view data) const override {
return std::make_unique<UpstreamServerName>(data);
}
};

REGISTER_FACTORY(UpstreamServerNameObjectFactory, StreamInfo::FilterState::ObjectFactory);

} // namespace Network
} // namespace Envoy
15 changes: 15 additions & 0 deletions source/common/network/upstream_subject_alt_names.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "source/common/network/upstream_subject_alt_names.h"

#include "envoy/registry/registry.h"
#include "envoy/stream_info/filter_state.h"

#include "source/common/common/macros.h"

namespace Envoy {
Expand All @@ -8,5 +11,17 @@ namespace Network {
const std::string& UpstreamSubjectAltNames::key() {
CONSTRUCT_ON_FIRST_USE(std::string, "envoy.network.upstream_subject_alt_names");
}

class UpstreamSubjectAltNamesObjectFactory : public StreamInfo::FilterState::ObjectFactory {
public:
std::string name() const override { return UpstreamSubjectAltNames::key(); }
std::unique_ptr<StreamInfo::FilterState::Object>
createFromBytes(absl::string_view data) const override {
const std::vector<std::string> parts = absl::StrSplit(data, ',');
return std::make_unique<UpstreamSubjectAltNames>(parts);
}
};

REGISTER_FACTORY(UpstreamSubjectAltNamesObjectFactory, StreamInfo::FilterState::ObjectFactory);
} // namespace Network
} // namespace Envoy
24 changes: 24 additions & 0 deletions test/common/network/transport_socket_options_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "source/common/network/proxy_protocol_filter_state.h"
#include "source/common/network/transport_socket_options_impl.h"
#include "source/common/network/upstream_server_name.h"
#include "source/common/network/upstream_subject_alt_names.h"
#include "source/common/stream_info/filter_state_impl.h"

#include "gtest/gtest.h"
Expand All @@ -18,6 +19,16 @@ class TransportSocketOptionsImplTest : public testing::Test {
public:
TransportSocketOptionsImplTest()
: filter_state_(StreamInfo::FilterState::LifeSpan::FilterChain) {}
void setFilterStateObject(const std::string& key, const std::string& value) {
auto* factory =
Registry::FactoryRegistry<StreamInfo::FilterState::ObjectFactory>::getFactory(key);
ASSERT_NE(nullptr, factory);
EXPECT_EQ(key, factory->name());
auto object = factory->createFromBytes(value);
ASSERT_NE(nullptr, object);
filter_state_.setData(key, std::move(object), StreamInfo::FilterState::StateType::ReadOnly,
StreamInfo::FilterState::LifeSpan::FilterChain);
}

protected:
StreamInfo::FilterStateImpl filter_state_;
Expand Down Expand Up @@ -128,6 +139,19 @@ TEST_F(TransportSocketOptionsImplTest, FilterStateNonHashable) {
EXPECT_EQ(keys.size(), 0);
}

TEST_F(TransportSocketOptionsImplTest, DynamicObjects) {
setFilterStateObject(UpstreamServerName::key(), "www.example.com");
setFilterStateObject(ApplicationProtocols::key(), "h2,http/1.1");
setFilterStateObject(UpstreamSubjectAltNames::key(), "www.example.com,example.com");
auto transport_socket_options = TransportSocketOptionsUtility::fromFilterState(filter_state_);
EXPECT_EQ(absl::make_optional<std::string>("www.example.com"),
transport_socket_options->serverNameOverride());
std::vector<std::string> http_alpns{"h2", "http/1.1"};
EXPECT_EQ(http_alpns, transport_socket_options->applicationProtocolListOverride());
std::vector<std::string> sans{"www.example.com", "example.com"};
EXPECT_EQ(sans, transport_socket_options->verifySubjectAltNameListOverride());
}

} // namespace
} // namespace Network
} // namespace Envoy

0 comments on commit cae3e7c

Please sign in to comment.