From 75e649422164e9f73e58fe58b60fbf7ac893fcbf Mon Sep 17 00:00:00 2001 From: gargnupur Date: Thu, 25 Jul 2019 17:01:01 -0700 Subject: [PATCH 01/12] WIP:Alpn Proxy Filter Work left: test is not passing completely yet.. make it pass Add an integration/e2e test Move writing of metadata to the callback when TLS handshake is complete. onNewConnection gets called when connection is established but before handshake is complete. Thus couldnt do metadata write here. Updating based on feedback Fix formatting and use MessageDifferencer Updating based on feedback Fix lint error Updating based on feedback Updating based on feedback Added upstream filter Add e2e test for tcp metadata exchange Added TODO's Remove tmp file added by mistake Using client and server metadata variables Fix asan and build errors Fix lint errors Fix construction of initial header Updated based on feedback Updated based on feedback Updated based on feedback Updated code with comments Fix after refactor Fix build errors --- src/envoy/BUILD | 1 + src/envoy/tcp/alpn_proxy/BUILD | 87 ++++++ src/envoy/tcp/alpn_proxy/alpn_proxy.cc | 262 ++++++++++++++++++ src/envoy/tcp/alpn_proxy/alpn_proxy.h | 175 ++++++++++++ .../alpn_proxy/alpn_proxy_initial_header.cc | 26 ++ .../alpn_proxy/alpn_proxy_initial_header.h | 35 +++ src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc | 149 ++++++++++ src/envoy/tcp/alpn_proxy/config.cc | 108 ++++++++ src/envoy/tcp/alpn_proxy/config.h | 76 +++++ src/envoy/tcp/alpn_proxy/config/BUILD | 27 ++ .../tcp/alpn_proxy/config/alpn_proxy.proto | 35 +++ .../basic_tcp_flow/basic_tcp_flow_test.go | 8 +- test/envoye2e/env/ports.go | 2 + test/envoye2e/env/setup.go | 44 ++- test/envoye2e/env/tcp_envoy_conf.go | 79 ++---- test/envoye2e/env/tcp_server.go | 83 +++++- .../stackdriver_plugin_test.go | 1 + .../tcp_metadata_exchange/cert-chain.pem | 60 ++++ test/envoye2e/tcp_metadata_exchange/doc.go | 16 ++ test/envoye2e/tcp_metadata_exchange/key.pem | 51 ++++ .../tcp_metadata_exchange/root-cert.pem | 30 ++ .../tcp_metadata_exchange_test.go | 181 ++++++++++++ 22 files changed, 1459 insertions(+), 77 deletions(-) create mode 100644 src/envoy/tcp/alpn_proxy/BUILD create mode 100644 src/envoy/tcp/alpn_proxy/alpn_proxy.cc create mode 100644 src/envoy/tcp/alpn_proxy/alpn_proxy.h create mode 100644 src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.cc create mode 100644 src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h create mode 100644 src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc create mode 100644 src/envoy/tcp/alpn_proxy/config.cc create mode 100644 src/envoy/tcp/alpn_proxy/config.h create mode 100644 src/envoy/tcp/alpn_proxy/config/BUILD create mode 100644 src/envoy/tcp/alpn_proxy/config/alpn_proxy.proto create mode 100644 test/envoye2e/tcp_metadata_exchange/cert-chain.pem create mode 100644 test/envoye2e/tcp_metadata_exchange/doc.go create mode 100644 test/envoye2e/tcp_metadata_exchange/key.pem create mode 100644 test/envoye2e/tcp_metadata_exchange/root-cert.pem create mode 100644 test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go diff --git a/src/envoy/BUILD b/src/envoy/BUILD index 96743a7a96f..9047eb69567 100644 --- a/src/envoy/BUILD +++ b/src/envoy/BUILD @@ -31,6 +31,7 @@ envoy_cc_binary( "//src/envoy/http/authn:filter_lib", "//src/envoy/http/jwt_auth:http_filter_factory", "//src/envoy/http/mixer:filter_lib", + "//src/envoy/tcp/alpn_proxy:config_lib", "//src/envoy/tcp/forward_downstream_sni:config_lib", "//src/envoy/tcp/mixer:filter_lib", "//src/envoy/tcp/sni_verifier:config_lib", diff --git a/src/envoy/tcp/alpn_proxy/BUILD b/src/envoy/tcp/alpn_proxy/BUILD new file mode 100644 index 00000000000..010f3f9c873 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/BUILD @@ -0,0 +1,87 @@ +# Copyright 2019 Istio Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ +# + +# Alpn Proxy filter + +load( + "@envoy//bazel:envoy_build_system.bzl", + "envoy_cc_library", + "envoy_cc_test", + "envoy_package", +) + +envoy_package() + +envoy_cc_library( + name = "alpn_proxy", + srcs = [ + "alpn_proxy.cc", + "alpn_proxy_initial_header.cc", + ], + hdrs = [ + "alpn_proxy.h", + "alpn_proxy_initial_header.h", + ], + repository = "@envoy", + deps = [ + "//src/envoy/tcp/alpn_proxy/config:alpn_proxy_cc_proto", + "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/base:endian", + "@com_google_absl//absl/strings", + "@envoy//include/envoy/local_info:local_info_interface", + "@envoy//include/envoy/network:connection_interface", + "@envoy//include/envoy/network:filter_interface", + "@envoy//include/envoy/runtime:runtime_interface", + "@envoy//include/envoy/stats:stats_macros", + "@envoy//source/common/http:utility_lib", + "@envoy//source/common/network:utility_lib", + "@envoy//source/common/protobuf", + "@envoy//source/common/protobuf:utility_lib", + "@envoy//source/extensions/filters/network:well_known_names", + ], +) + +envoy_cc_library( + name = "config_lib", + srcs = ["config.cc"], + hdrs = ["config.h"], + repository = "@envoy", + visibility = ["//visibility:public"], + deps = [ + ":alpn_proxy", + "//src/envoy/tcp/alpn_proxy/config:alpn_proxy_cc_proto", + "//src/envoy/utils:utils_lib", + "@envoy//include/envoy/registry", + "@envoy//source/extensions/filters/network/common:factory_base_lib", + ], +) + +envoy_cc_test( + name = "alpnproxy_test", + srcs = [ + "alpn_proxy_test.cc", + ], + repository = "@envoy", + deps = [ + ":alpn_proxy", + ":config_lib", + "@envoy//source/common/protobuf", + "@envoy//test/mocks/local_info:local_info_mocks", + "@envoy//test/mocks/network:network_mocks", + "@envoy//test/mocks/protobuf:protobuf_mocks", + ], +) diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy.cc b/src/envoy/tcp/alpn_proxy/alpn_proxy.cc new file mode 100644 index 00000000000..68ad439ed79 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy.cc @@ -0,0 +1,262 @@ +/* Copyright 2019 Istio Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "absl/base/internal/endian.h" +#include "absl/strings/string_view.h" +#include "common/buffer/buffer_impl.h" +#include "common/protobuf/message_validator_impl.h" +#include "common/protobuf/utility.h" +#include "envoy/network/connection.h" +#include "envoy/stats/scope.h" +#include "src/envoy/tcp/alpn_proxy/alpn_proxy.h" +#include "src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h" + +namespace Envoy { +namespace Tcp { +namespace AlpnProxy { +namespace { + +std::unique_ptr<::Envoy::Buffer::OwnedImpl> constructProxyHeaderData( + const Envoy::ProtobufWkt::Any& proxy_data) { + AlpnProxyInitialHeader initial_header; + std::string proxy_data_str = proxy_data.SerializeAsString(); + // Converting from host to network byte order so that most significant byte is + // placed first. + initial_header.magic = absl::ghtonl(AlpnProxyInitialHeader::magic_number); + initial_header.data_size = absl::ghtonl(proxy_data_str.length()); + + ::Envoy::Buffer::OwnedImpl initial_header_buffer{ + absl::string_view(reinterpret_cast(&initial_header), + sizeof(AlpnProxyInitialHeader))}; + auto proxy_data_buffer = + std::make_unique<::Envoy::Buffer::OwnedImpl>(proxy_data_str); + proxy_data_buffer->prepend(initial_header_buffer); + return proxy_data_buffer; +} + +} // namespace + +AlpnProxyConfig::AlpnProxyConfig(const std::string& stat_prefix, + const std::string& protocol, + const std::string& node_metadata_id, + const FilterDirection filter_direction, + Stats::Scope& scope) + : scope_(scope), + stat_prefix_(stat_prefix), + protocol_(protocol), + node_metadata_id_(node_metadata_id), + filter_direction_(filter_direction), + stats_(generateStats(stat_prefix, scope)) {} + +Network::FilterStatus AlpnProxyFilter::onData(Buffer::Instance& data, bool) { + switch (conn_state_) { + case Invalid: + case Done: + // No work needed if connection state is Done or Invalid. + return Network::FilterStatus::Continue; + case ConnProtocolNotRead: { + if (read_callbacks_->connection().nextProtocol() != config_->protocol_) { + conn_state_ = Invalid; + config_->stats().alpn_protocol_not_found_.inc(); + return Network::FilterStatus::Continue; + } else { + conn_state_ = WriteMetadata; + config_->stats().alpn_protocol_found_.inc(); + } + } + case WriteMetadata: { + // TODO(gargnupur): Try to move this just after alpn protocol is + // determined and first onData is called in Downstream filter. + if (config_->filter_direction_ == FilterDirection::Downstream) { + writeNodeMetadata(); + } + } + case ReadingInitialHeader: + case NeedMoreDataInitialHeader: { + tryReadInitialProxyHeader(data); + if (conn_state_ == NeedMoreDataInitialHeader) { + return Network::FilterStatus::StopIteration; + } + if (conn_state_ == Invalid) { + return Network::FilterStatus::Continue; + } + } + case ReadingProxyHeader: + case NeedMoreDataProxyHeader: { + tryReadProxyData(data); + if (conn_state_ == NeedMoreDataProxyHeader) { + return Network::FilterStatus::StopIteration; + } + if (conn_state_ == Invalid) { + return Network::FilterStatus::Continue; + } + } + default: + conn_state_ = Done; + return Network::FilterStatus::Continue; + } + + return Network::FilterStatus::Continue; +} + +Network::FilterStatus AlpnProxyFilter::onNewConnection() { + return Network::FilterStatus::Continue; +} + +Network::FilterStatus AlpnProxyFilter::onWrite(Buffer::Instance&, bool) { + switch (conn_state_) { + case Invalid: + case Done: + // No work needed if connection state is Done or Invalid. + return Network::FilterStatus::Continue; + case ConnProtocolNotRead: { + if (read_callbacks_->connection().nextProtocol() != config_->protocol_) { + conn_state_ = Invalid; + config_->stats().alpn_protocol_not_found_.inc(); + return Network::FilterStatus::Continue; + } else { + conn_state_ = WriteMetadata; + config_->stats().alpn_protocol_found_.inc(); + } + } + case WriteMetadata: { + // TODO(gargnupur): Try to move this just after alpn protocol is + // determined and first onWrite is called in Upstream filter. + if (config_->filter_direction_ == FilterDirection::Upstream) { + writeNodeMetadata(); + } + } + case ReadingInitialHeader: + case ReadingProxyHeader: + case NeedMoreDataInitialHeader: + case NeedMoreDataProxyHeader: + // These are to be handled in Reading Pipeline. + return Network::FilterStatus::Continue; + } + + return Network::FilterStatus::Continue; +} + +void AlpnProxyFilter::writeNodeMetadata() { + if (conn_state_ != WriteMetadata) { + return; + } + + std::unique_ptr metadata = + readMetadata(config_->node_metadata_id_); + if (metadata != nullptr) { + Envoy::ProtobufWkt::Any metadata_any_value; + *metadata_any_value.mutable_type_url() = StructTypeUrl; + *metadata_any_value.mutable_value() = metadata->SerializeAsString(); + std::unique_ptr<::Envoy::Buffer::OwnedImpl> buf = + constructProxyHeaderData(metadata_any_value); + write_callbacks_->injectWriteDataToFilterChain(*buf, false); + + if (config_->filter_direction_ == FilterDirection::Downstream) { + writeMetadata(DownstreamDynamicDataKey, *metadata); + } else { + writeMetadata(UpstreamDynamicDataKey, *metadata); + } + config_->stats().metadata_added_.inc(); + } + + conn_state_ = ReadingInitialHeader; +} + +void AlpnProxyFilter::tryReadInitialProxyHeader(Buffer::Instance& data) { + if (conn_state_ != ReadingInitialHeader && + conn_state_ != NeedMoreDataInitialHeader) { + return; + } + const uint32_t initial_header_length = sizeof(AlpnProxyInitialHeader); + if (data.length() < initial_header_length) { + config_->stats().initial_header_not_found_.inc(); + // Not enough data to read. Wait for it to come. + conn_state_ = NeedMoreDataInitialHeader; + return; + } + std::string initial_header_buf = std::string( + static_cast(data.linearize(initial_header_length)), + initial_header_length); + const AlpnProxyInitialHeader* initial_header = + reinterpret_cast( + initial_header_buf.c_str()); + if (absl::gntohl(initial_header->magic) != + AlpnProxyInitialHeader::magic_number) { + config_->stats().initial_header_not_found_.inc(); + conn_state_ = Invalid; + return; + } + proxy_data_length_ = absl::gntohl(initial_header->data_size); + // Drain the initial header length bytes read. + data.drain(initial_header_length); + conn_state_ = ReadingProxyHeader; +} + +void AlpnProxyFilter::tryReadProxyData(Buffer::Instance& data) { + if (conn_state_ != ReadingProxyHeader && + conn_state_ != NeedMoreDataProxyHeader) { + return; + } + if (data.length() < proxy_data_length_) { + // Not enough data to read. Wait for it to come. + conn_state_ = NeedMoreDataProxyHeader; + return; + } + std::string proxy_data_buf = + std::string(static_cast(data.linearize(proxy_data_length_)), + proxy_data_length_); + Envoy::ProtobufWkt::Any proxy_data; + if (!proxy_data.ParseFromString(proxy_data_buf)) { + config_->stats().header_not_found_.inc(); + conn_state_ = Invalid; + return; + } + data.drain(proxy_data_length_); + + Envoy::ProtobufWkt::Struct struct_metadata = + Envoy::MessageUtil::anyConvert( + proxy_data, validation_visitor_); + if (config_->filter_direction_ == FilterDirection::Downstream) { + writeMetadata(UpstreamDynamicDataKey, struct_metadata); + } else { + writeMetadata(DownstreamDynamicDataKey, struct_metadata); + } +} + +void AlpnProxyFilter::writeMetadata(const std::string key, + const ProtobufWkt::Struct& value) { + read_callbacks_->connection().streamInfo().setDynamicMetadata(key, value); +} + +std::unique_ptr AlpnProxyFilter::readMetadata( + const std::string& key) { + if (local_info_.node().has_metadata()) { + auto metadata_fields = local_info_.node().metadata().fields(); + auto node_metadata = metadata_fields.find(key); + if (node_metadata != metadata_fields.end()) { + return std::make_unique( + node_metadata->second.struct_value()); + } + } + return nullptr; +} + +} // namespace AlpnProxy +} // namespace Tcp +} // namespace Envoy \ No newline at end of file diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy.h b/src/envoy/tcp/alpn_proxy/alpn_proxy.h new file mode 100644 index 00000000000..a2db88a42e5 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy.h @@ -0,0 +1,175 @@ +/* Copyright 2019 Istio Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "common/protobuf/message_validator_impl.h" +#include "common/protobuf/protobuf.h" +#include "envoy/local_info/local_info.h" +#include "envoy/network/filter.h" +#include "envoy/runtime/runtime.h" +#include "envoy/stats/scope.h" +#include "envoy/stats/stats_macros.h" +#include "src/envoy/tcp/alpn_proxy/config/alpn_proxy.pb.h" + +namespace Envoy { +namespace Tcp { +namespace AlpnProxy { + +/** + * All AlpnProxy filter stats. @see stats_macros.h + */ +#define ALL_ALPN_STATS(COUNTER) \ + COUNTER(alpn_protocol_not_found) \ + COUNTER(alpn_protocol_found) \ + COUNTER(initial_header_not_found) \ + COUNTER(header_not_found) \ + COUNTER(metadata_added) + +/** + * Struct definition for all AlpnProxy stats. @see stats_macros.h + */ +struct AlpnProxyStats { + ALL_ALPN_STATS(GENERATE_COUNTER_STRUCT) +}; + +/** + * Direction of the flow of traffic in which this this AlpnProxy filter + * is placed. + */ +enum FilterDirection { Downstream, Upstream }; + +/** + * Configuration for the AlpnProxy filter. + */ +class AlpnProxyConfig { + public: + AlpnProxyConfig(const std::string& stat_prefix, const std::string& protocol, + const std::string& node_metadata_id, + const FilterDirection filter_direction, Stats::Scope& scope); + + const AlpnProxyStats& stats() { return stats_; } + + // Scope for the stats. + Stats::Scope& scope_; + // Stat prefix. + const std::string stat_prefix_; + // Expected Alpn Protocol. + const std::string protocol_; + // Node metadata id to read. + const std::string node_metadata_id_; + // Direction of filter. + const FilterDirection filter_direction_; + // Stats for Alpn Proxy Filter. + AlpnProxyStats stats_; + + private: + AlpnProxyStats generateStats(const std::string& prefix, Stats::Scope& scope) { + return AlpnProxyStats{ALL_ALPN_STATS(POOL_COUNTER_PREFIX(scope, prefix))}; + } +}; + +using AlpnProxyConfigSharedPtr = std::shared_ptr; + +/** + * A AlpnProxy filter instance. One per connection. + */ +class AlpnProxyFilter : public Network::Filter { + public: + AlpnProxyFilter(AlpnProxyConfigSharedPtr config, + const LocalInfo::LocalInfo& local_info, + ProtobufMessage::ValidationVisitor& validation_visitor) + : config_(config), + local_info_(local_info), + validation_visitor_(validation_visitor), + conn_state_(ConnProtocolNotRead) {} + + // Network::ReadFilter + Network::FilterStatus onData(Buffer::Instance& data, + bool end_stream) override; + Network::FilterStatus onNewConnection() override; + Network::FilterStatus onWrite(Buffer::Instance& data, + bool end_stream) override; + void initializeReadFilterCallbacks( + Network::ReadFilterCallbacks& callbacks) override { + read_callbacks_ = &callbacks; + // read_callbacks_->connection().addConnectionCallbacks(*this); + } + void initializeWriteFilterCallbacks( + Network::WriteFilterCallbacks& callbacks) override { + write_callbacks_ = &callbacks; + } + + private: + // Writes node metadata in write pipeline of the filter chain. + // Also, sets node metadata in Dynamic Metadata to be available for subsequent + // filters. + void writeNodeMetadata(); + + // Tries to read inital proxy header in the data bytes. + void tryReadInitialProxyHeader(Buffer::Instance& data); + + // Tries to read data after initial proxy header. This is currently in the + // form of google::protobuf::any which encapsulates google::protobuf::struct. + void tryReadProxyData(Buffer::Instance& data); + + // Helper function to write Dynamic metadata. + void writeMetadata(const std::string key, const ProtobufWkt::Struct& value); + + // Helper function to read Dynamic metadata. + std::unique_ptr readMetadata( + const std::string& key); + + // Config for AlpnProxy filter. + AlpnProxyConfigSharedPtr config_; + // LocalInfo instance. + const LocalInfo::LocalInfo& local_info_; + // Read callback instance. + Network::ReadFilterCallbacks* read_callbacks_{}; + // Write callback instance. + Network::WriteFilterCallbacks* write_callbacks_{}; + // Stores the length of proxy data that contains node metadata. + uint64_t proxy_data_length_{0}; + // Validation Visitor instance. + ProtobufMessage::ValidationVisitor& validation_visitor_; + + // Key Identifier for dynamic metadata in upstream filter. + const std::string UpstreamDynamicDataKey = + "filters.network.alpn_proxy.upstream"; + // Key Identifier for dynamic metadata in downstream filter. + const std::string DownstreamDynamicDataKey = + "filters.network.alpn_proxy.downstream"; + // Type url of google::protobug::struct. + const std::string StructTypeUrl = + "type.googleapis.com/google.protobuf.Struct"; + + // Captures the state machine of what is going on in the filter. + enum { + ConnProtocolNotRead, // Connection Protocol has not been read yet + WriteMetadata, // Write node metadata + ReadingInitialHeader, // AlpnProxyInitialHeader is being read + ReadingProxyHeader, // Proxy Header is being read + NeedMoreDataInitialHeader, // Need more data to be read + NeedMoreDataProxyHeader, // Need more data to be read + Done, // Alpn Protocol Found and all the read is done + Invalid, // Invalid state, all operations fail + } conn_state_; +}; + +} // namespace AlpnProxy +} // namespace Tcp +} // namespace Envoy diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.cc b/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.cc new file mode 100644 index 00000000000..0b7d4272249 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.cc @@ -0,0 +1,26 @@ +/* Copyright 2019 Istio Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h" + +namespace Envoy { +namespace Tcp { +namespace AlpnProxy { + +const uint32_t AlpnProxyInitialHeader::magic_number; + +} // namespace AlpnProxy +} // namespace Tcp +} // namespace Envoy \ No newline at end of file diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h b/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h new file mode 100644 index 00000000000..0cbcfac01c6 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h @@ -0,0 +1,35 @@ +/* Copyright 2019 Istio Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace Envoy { +namespace Tcp { +namespace AlpnProxy { + +// Used with AlpnProxyHeaderProto to be extensible. +struct AlpnProxyInitialHeader { + uint32_t magic; // Magic number in network byte order. Most significant byte + // is placed first. + static const uint32_t magic_number = 0x23071961; // decimal 587667809 + uint32_t data_size; // Size of the data blob in network byte order. Most + // significant byte is placed first. +} __attribute__((packed)); + +} // namespace AlpnProxy +} // namespace Tcp +} // namespace Envoy \ No newline at end of file diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc b/src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc new file mode 100644 index 00000000000..5b9fb4a0692 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc @@ -0,0 +1,149 @@ +/* Copyright 2019 Istio Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "src/envoy/tcp/alpn_proxy/alpn_proxy.h" +#include "common/buffer/buffer_impl.h" +#include "common/protobuf/protobuf.h" +#include "gmock/gmock.h" +#include "google/protobuf/util/message_differencer.h" +#include "gtest/gtest.h" +#include "src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h" +#include "test/mocks/local_info/mocks.h" +#include "test/mocks/network/mocks.h" +#include "test/mocks/protobuf/mocks.h" + +using ::google::protobuf::util::MessageDifferencer; +using testing::NiceMock; +using testing::Return; +using testing::ReturnRef; + +namespace Envoy { +namespace Tcp { +namespace AlpnProxy { +namespace { + +MATCHER_P(MapEq, rhs, "") { return MessageDifferencer::Equals(arg, rhs); } + +void ConstructProxyHeaderData(::Envoy::Buffer::OwnedImpl& serialized_header, + Envoy::ProtobufWkt::Any& proxy_header, + AlpnProxyInitialHeader* initial_header) { + std::string serialized_proxy_header = proxy_header.SerializeAsString(); + memset(initial_header, 0, sizeof(AlpnProxyInitialHeader)); + initial_header->magic = absl::ghtonl(AlpnProxyInitialHeader::magic_number); + initial_header->data_size = absl::ghtonl(serialized_proxy_header.length()); + serialized_header.add(::Envoy::Buffer::OwnedImpl{ + absl::string_view(reinterpret_cast(initial_header), + sizeof(AlpnProxyInitialHeader))}); + serialized_header.add(::Envoy::Buffer::OwnedImpl{serialized_proxy_header}); +} + +} // namespace + +class AlpnProxyFilterTest : public testing::Test { + public: + AlpnProxyFilterTest() { ENVOY_LOG_MISC(info, "test"); } + + void initialize() { + config_ = std::make_shared( + stat_prefix_, "istio2", "istio/metadata", FilterDirection::Downstream, + scope_); + filter_ = std::make_unique(config_, local_info_, + validation_visitor_); + filter_->initializeReadFilterCallbacks(read_filter_callbacks_); + filter_->initializeWriteFilterCallbacks(write_filter_callbacks_); + metadata_node_.set_id("test"); + EXPECT_CALL(read_filter_callbacks_.connection_, streamInfo()) + .WillRepeatedly(ReturnRef(stream_info_)); + EXPECT_CALL(local_info_, node()).WillRepeatedly(ReturnRef(metadata_node_)); + } + + void initializeStructValues() { + (*details_value_.mutable_fields())["namespace"].set_string_value("default"); + (*details_value_.mutable_fields())["labels"].set_string_value( + "{app, details}"); + + (*productpage_value_.mutable_fields())["namespace"].set_string_value( + "default"); + (*productpage_value_.mutable_fields())["labels"].set_string_value( + "{app, productpage}"); + } + + Envoy::ProtobufWkt::Struct details_value_; + Envoy::ProtobufWkt::Struct productpage_value_; + AlpnProxyConfigSharedPtr config_; + std::unique_ptr filter_; + Stats::IsolatedStoreImpl scope_; + std::string stat_prefix_{"test.alpnmetadata"}; + NiceMock read_filter_callbacks_; + NiceMock write_filter_callbacks_; + Network::MockConnection connection_; + NiceMock local_info_; + NiceMock validation_visitor_; + NiceMock stream_info_; + envoy::api::v2::core::Node metadata_node_; +}; + +TEST_F(AlpnProxyFilterTest, AlpnProxyFound) { + initialize(); + initializeStructValues(); + + auto node_metadata_map = metadata_node_.mutable_metadata()->mutable_fields(); + google::protobuf::Value& value = (*node_metadata_map)["istio/metadata"]; + (*value.mutable_struct_value()).CopyFrom(details_value_); + + EXPECT_CALL(read_filter_callbacks_.connection_, nextProtocol()) + .WillRepeatedly(Return("istio2")); + EXPECT_CALL(stream_info_, + setDynamicMetadata("filters.network.alpn_proxy.downstream", + MapEq(details_value_))); + EXPECT_CALL(stream_info_, + setDynamicMetadata("filters.network.alpn_proxy.upstream", + MapEq(productpage_value_))); + + ::Envoy::Buffer::OwnedImpl data; + AlpnProxyInitialHeader initial_header; + Envoy::ProtobufWkt::Any productpage_any_value; + *productpage_any_value.mutable_type_url() = + "type.googleapis.com/google.protobuf.Struct"; + *productpage_any_value.mutable_value() = + productpage_value_.SerializeAsString(); + ConstructProxyHeaderData(data, productpage_any_value, &initial_header); + ::Envoy::Buffer::OwnedImpl world{"world"}; + data.add(world); + + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onData(data, false)); + EXPECT_EQ(data.toString(), "world"); + + EXPECT_EQ(0UL, config_->stats().initial_header_not_found_.value()); + EXPECT_EQ(0UL, config_->stats().header_not_found_.value()); + EXPECT_EQ(1UL, config_->stats().alpn_protocol_found_.value()); +} + +TEST_F(AlpnProxyFilterTest, AlpnProxyNotFound) { + initialize(); + + EXPECT_CALL(read_filter_callbacks_.connection_, nextProtocol()) + .WillRepeatedly(Return("istio")); + + ::Envoy::Buffer::OwnedImpl data{}; + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onData(data, false)); + EXPECT_EQ(1UL, config_->stats().alpn_protocol_not_found_.value()); +} + +} // namespace AlpnProxy +} // namespace Tcp +} // namespace Envoy diff --git a/src/envoy/tcp/alpn_proxy/config.cc b/src/envoy/tcp/alpn_proxy/config.cc new file mode 100644 index 00000000000..03325e99ec0 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/config.cc @@ -0,0 +1,108 @@ +/* Copyright 2019 Istio Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "src/envoy/tcp/alpn_proxy/config.h" +#include "envoy/network/connection.h" +#include "envoy/registry/registry.h" +#include "src/envoy/tcp/alpn_proxy/alpn_proxy.h" +#include "src/envoy/utils/config.h" + +namespace Envoy { +namespace Tcp { +namespace AlpnProxy { +namespace { + +static constexpr char StatPrefix[] = "alpn_proxy."; + +Network::FilterFactoryCb createFilterFactoryHelper( + const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, + Server::Configuration::CommonFactoryContext& context, + FilterDirection filter_direction) { + ASSERT(!proto_config.protocol().empty()); + + AlpnProxyConfigSharedPtr filter_config(std::make_shared( + StatPrefix, proto_config.protocol(), proto_config.node_metadata_id(), + filter_direction, context.scope())); + return [filter_config, + &context](Network::FilterManager& filter_manager) -> void { + filter_manager.addFilter( + std::make_shared(filter_config, context.localInfo(), + context.messageValidationVisitor())); + }; +} +} // namespace + +Network::FilterFactoryCb AlpnProxyConfigFactory::createFilterFactoryFromProto( + const Protobuf::Message& config, + Server::Configuration::FactoryContext& context) { + return createFilterFactory( + dynamic_cast(config), + context); +} + +ProtobufTypes::MessagePtr AlpnProxyConfigFactory::createEmptyConfigProto() { + return ProtobufTypes::MessagePtr{ + new envoy::tcp::alpnproxy::config::AlpnProxy}; +} + +Network::FilterFactoryCb AlpnProxyConfigFactory::createFilterFactory( + const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, + Server::Configuration::FactoryContext& context) { + return createFilterFactoryHelper(proto_config, context, + FilterDirection::Downstream); +} + +Network::FilterFactoryCb +AlpnProxyUpstreamConfigFactory::createFilterFactoryFromProto( + const Protobuf::Message& config, + Server::Configuration::CommonFactoryContext& context) { + return createFilterFactory( + dynamic_cast(config), + context); +} + +ProtobufTypes::MessagePtr +AlpnProxyUpstreamConfigFactory::createEmptyConfigProto() { + return ProtobufTypes::MessagePtr{ + new envoy::tcp::alpnproxy::config::AlpnProxy}; +} + +Network::FilterFactoryCb AlpnProxyUpstreamConfigFactory::createFilterFactory( + const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, + Server::Configuration::CommonFactoryContext& context) { + return createFilterFactoryHelper(proto_config, context, + FilterDirection::Upstream); +} + +/** + * Static registration for the Alpn Proxy Downstream filter. @see + * RegisterFactory. + */ +static Registry::RegisterFactory< + AlpnProxyConfigFactory, + Server::Configuration::NamedNetworkFilterConfigFactory> + registered_; + +/** + * Static registration for the Alpn Proxy Upstream filter. @see RegisterFactory. + */ +static Registry::RegisterFactory< + AlpnProxyUpstreamConfigFactory, + Server::Configuration::NamedUpstreamNetworkFilterConfigFactory> + registered_upstream_; + +} // namespace AlpnProxy +} // namespace Tcp +} // namespace Envoy diff --git a/src/envoy/tcp/alpn_proxy/config.h b/src/envoy/tcp/alpn_proxy/config.h new file mode 100644 index 00000000000..611aee32333 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/config.h @@ -0,0 +1,76 @@ +/* Copyright 2019 Istio Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "extensions/filters/network/common/factory_base.h" +#include "src/envoy/tcp/alpn_proxy/config/alpn_proxy.pb.h" + +namespace Envoy { +namespace Tcp { +namespace AlpnProxy { + +/** + * Config registration for the Alpn Proxy filter. @see + * NamedNetworkFilterConfigFactory. + */ +class AlpnProxyConfigFactory + : public Server::Configuration::NamedNetworkFilterConfigFactory { + public: + Network::FilterFactoryCb createFilterFactory( + const Json::Object&, Server::Configuration::FactoryContext&) override { + NOT_IMPLEMENTED_GCOVR_EXCL_LINE; + } + + Network::FilterFactoryCb createFilterFactoryFromProto( + const Protobuf::Message&, + Server::Configuration::FactoryContext&) override; + + ProtobufTypes::MessagePtr createEmptyConfigProto() override; + + std::string name() override { return "envoy.filters.network.alpn_proxy"; } + + private: + Network::FilterFactoryCb createFilterFactory( + const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, + Server::Configuration::FactoryContext& context); +}; + +/** + * Config registration for the Alpn Proxy Upstream filter. @see + * NamedUpstreamNetworkFilterConfigFactory. + */ +class AlpnProxyUpstreamConfigFactory + : public Server::Configuration::NamedUpstreamNetworkFilterConfigFactory { + public: + Network::FilterFactoryCb createFilterFactoryFromProto( + const Protobuf::Message&, + Server::Configuration::CommonFactoryContext&) override; + + ProtobufTypes::MessagePtr createEmptyConfigProto() override; + + std::string name() override { + return "envoy.filters.network.upstream.alpn_proxy"; + } + + private: + Network::FilterFactoryCb createFilterFactory( + const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, + Server::Configuration::CommonFactoryContext& context); +}; + +} // namespace AlpnProxy +} // namespace Tcp +} // namespace Envoy diff --git a/src/envoy/tcp/alpn_proxy/config/BUILD b/src/envoy/tcp/alpn_proxy/config/BUILD new file mode 100644 index 00000000000..deef73aa6a7 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/config/BUILD @@ -0,0 +1,27 @@ +# Copyright 2019 Istio Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ +# + +proto_library( + name = "alpn_proxy_proto", + srcs = ["alpn_proxy.proto"], +) + +cc_proto_library( + name = "alpn_proxy_cc_proto", + visibility = ["//visibility:public"], + deps = ["alpn_proxy_proto"], +) diff --git a/src/envoy/tcp/alpn_proxy/config/alpn_proxy.proto b/src/envoy/tcp/alpn_proxy/config/alpn_proxy.proto new file mode 100644 index 00000000000..a494d40b487 --- /dev/null +++ b/src/envoy/tcp/alpn_proxy/config/alpn_proxy.proto @@ -0,0 +1,35 @@ +/* Copyright 2019 Istio Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto3"; + +package envoy.tcp.alpnproxy.config; + +option java_outer_classname = "AlpnProxyProto"; +option java_multiple_files = true; +option java_package = "io.envoyproxy.envoy.tcp.alpnproxy.config"; +option go_package = "AlpnProxy"; + +// [#protodoc-title: AlpnProxy protocol match and data transfer] +// AlpnProxy protocol match and data transfer +message AlpnProxy { + // Protocol that Alpn should support on the server. + // [#comment:TODO(GargNupur): Make it a list.] + string protocol = 1; + + // The node metadata id whose data will be written to connection data. + // [#comment: TODO(GargNupur): Remove this and use bootstrap node.id] + string node_metadata_id = 2; +} diff --git a/test/envoye2e/basic_tcp_flow/basic_tcp_flow_test.go b/test/envoye2e/basic_tcp_flow/basic_tcp_flow_test.go index e54fff7d9bb..da14f5c180b 100644 --- a/test/envoye2e/basic_tcp_flow/basic_tcp_flow_test.go +++ b/test/envoye2e/basic_tcp_flow/basic_tcp_flow_test.go @@ -27,15 +27,13 @@ import ( // Stats in Client Envoy proxy. var expectedClientStats = map[string]int{ - // http listener stats - "tcp.inbound_tcp.downstream_cx_total": 1, - "tcp.outbound_tcp.downstream_cx_total": 1, + // tcp listener stats + "tcp.inbound_tcp.downstream_cx_total": 1, } // Stats in Server Envoy proxy. var expectedServerStats = map[string]int{ - // http listener stats - "tcp.inbound_tcp.downstream_cx_total": 1, + // tcp listener stats "tcp.outbound_tcp.downstream_cx_total": 1, } diff --git a/test/envoye2e/env/ports.go b/test/envoye2e/env/ports.go index 2eef6d29d98..ea8c731a74c 100644 --- a/test/envoye2e/env/ports.go +++ b/test/envoye2e/env/ports.go @@ -30,6 +30,8 @@ const ( StackdriverPluginTest uint16 = iota + TcpMetadataExchangeTest uint16 = iota + // The number of total tests. has to be the last one. maxTestNum ) diff --git a/test/envoye2e/env/setup.go b/test/envoye2e/env/setup.go index 0dc06494d40..f1c9bcaf7b7 100644 --- a/test/envoye2e/env/setup.go +++ b/test/envoye2e/env/setup.go @@ -96,6 +96,21 @@ type TestSetup struct { // Client side Envoy node metadata. ClientNodeMetadata string + + // Whether Tls is Enabled or not. + EnableTls bool + + // Format for accesslog + AccesslogFormat string + + // TlsContext to be used. + TlsContext string + + // ClusterTlsContext to be used. + ClusterTlsContext string + + // UpstreamFilters chain in client. + UpstreamFiltersInClient string } func NewClientServerEnvoyTestSetup(name uint16, t *testing.T) *TestSetup { @@ -149,6 +164,21 @@ func (s *TestSetup) SetFiltersBeforeEnvoyRouterInAppToClient(filters string) { s.FiltersBeforeEnvoyRouterInAppToClient = filters } +// SetEnableTls sets EnableTls. +func (s *TestSetup) SetEnableTls(enableTls bool) { + s.EnableTls = enableTls +} + +// SetTlsContext sets TLS COntext. +func (s *TestSetup) SetTlsContext(tlsContext string) { + s.TlsContext = tlsContext +} + +// SetTlsContext sets TLS COntext. +func (s *TestSetup) SetClusterTlsContext(clusterTlsContext string) { + s.ClusterTlsContext = clusterTlsContext +} + // SetFiltersBeforeEnvoyRouterInClientToProxy sets the configurations of the filters that come before envoy.router http // filter in ClientToProxy listener. func (s *TestSetup) SetFiltersBeforeEnvoyRouterInClientToProxy(filters string) { @@ -177,6 +207,16 @@ func (s *TestSetup) SetClientNodeMetadata(metadata string) { s.ClientNodeMetadata = metadata } +// SetAccessLogFormat sets the accesslogformat. +func (s *TestSetup) SetAccessLogFormat(accesslogformat string) { + s.AccesslogFormat = accesslogformat +} + +// SetUpstreamFiltersInClient sets upstream filters chain in client envoy.. +func (s *TestSetup) SetUpstreamFiltersInClient(upstreamFiltersInClient string) { + s.UpstreamFiltersInClient = upstreamFiltersInClient +} + func (s *TestSetup) SetUpClientServerEnvoy() error { var err error @@ -218,7 +258,7 @@ func (s *TestSetup) SetUpClientServerEnvoy() error { } } if s.startTcpBackend { - s.tcpBackend, err = NewTCPServer(s.ports.BackendPort, "hello") + s.tcpBackend, err = NewTCPServer(s.ports.BackendPort, "hello", s.EnableTls) if err != nil { log.Printf("unable to create TCP server %v", err) } else { @@ -250,7 +290,7 @@ func (s *TestSetup) TearDownClientServerEnvoy() { s.backend.Stop() } if s.tcpBackend != nil { - s.tcpBackend.Start() + s.tcpBackend.Stop() } } diff --git a/test/envoye2e/env/tcp_envoy_conf.go b/test/envoye2e/env/tcp_envoy_conf.go index e25e8f6c40e..fe841965fda 100644 --- a/test/envoye2e/env/tcp_envoy_conf.go +++ b/test/envoye2e/env/tcp_envoy_conf.go @@ -15,6 +15,11 @@ package env const tcpEnvoyClientConfTemplYAML = ` +node: + id: test + metadata: { +{{.ClientNodeMetadata | indent 4 }} + } admin: access_log_path: {{.ClientAccessLogPath}} address: @@ -35,26 +40,20 @@ static_resources: socket_address: address: 127.0.0.1 port_value: {{.Ports.ClientToServerProxyPort}} - - name: server - connect_timeout: 5s - type: STATIC - load_assignment: - cluster_name: server - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: 127.0.0.1 - port_value: {{.Ports.ProxyToServerProxyPort}} +{{.UpstreamFiltersInClient | indent 4 }} +{{.ClusterTlsContext | indent 4 }} listeners: - name: app-to-client address: socket_address: address: 127.0.0.1 port_value: {{.Ports.AppToClientProxyPort}} + listener_filters: + - name: "envoy.listener.tls_inspector" + typed_config: {} filter_chains: - filters: +{{.FiltersBeforeEnvoyRouterInAppToClient | indent 6 }} - name: envoy.tcp_proxy config: stat_prefix: inbound_tcp @@ -63,24 +62,16 @@ static_resources: - name: envoy.file_access_log config: path: {{.ClientAccessLogPath}} - - name: client-to-proxy - address: - socket_address: - address: 127.0.0.1 - port_value: {{.Ports.ClientToServerProxyPort}} - filter_chains: - - filters: - - name: envoy.tcp_proxy - config: - stat_prefix: outbound_tcp - cluster: server - access_log: - - name: envoy.file_access_log - config: - path: {{.ClientAccessLogPath}} +{{.AccesslogFormat | indent 14 }} +{{.TlsContext | indent 6 }} ` const tcpEnvoyServerConfTemplYAML = ` +node: + id: test + metadata: { +{{.ServerNodeMetadata | indent 4 }} + } admin: access_log_path: {{.ServerAccessLogPath}} address: @@ -101,41 +92,16 @@ static_resources: socket_address: address: 127.0.0.1 port_value: {{.Ports.BackendPort}} - - name: server - connect_timeout: 5s - type: STATIC - load_assignment: - cluster_name: server - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: 127.0.0.1 - port_value: {{.Ports.ClientToAppProxyPort}} +{{.ClusterTlsContext | indent 4 }} listeners: - - name: proxy-to-server - address: - socket_address: - address: 127.0.0.1 - port_value: {{.Ports.ProxyToServerProxyPort}} - filter_chains: - - filters: - - name: envoy.tcp_proxy - config: - stat_prefix: inbound_tcp - cluster: server - access_log: - - name: envoy.file_access_log - config: - path: {{.ServerAccessLogPath}} - - name: client-to-app + - name: server address: socket_address: address: 127.0.0.1 - port_value: {{.Ports.ClientToAppProxyPort}} + port_value: {{.Ports.ClientToServerProxyPort}} filter_chains: - filters: +{{.FiltersBeforeEnvoyRouterInClientToApp | indent 6 }} - name: envoy.tcp_proxy config: stat_prefix: outbound_tcp @@ -144,6 +110,7 @@ static_resources: - name: envoy.file_access_log config: path: {{.ServerAccessLogPath}} +{{.TlsContext | indent 6 }} ` func GetTcpClientEnvoyConfTmp() string { diff --git a/test/envoye2e/env/tcp_server.go b/test/envoye2e/env/tcp_server.go index 53ba2a0b545..217c0accf06 100644 --- a/test/envoye2e/env/tcp_server.go +++ b/test/envoye2e/env/tcp_server.go @@ -16,8 +16,11 @@ package env import ( "bufio" + "crypto/tls" + "crypto/x509" "fmt" "io" + "io/ioutil" "log" "net" "time" @@ -25,23 +28,54 @@ import ( // TCPServer stores data for a TCP server. type TCPServer struct { - port uint16 - lis net.Listener - prefix string + port uint16 + lis net.Listener + prefix string + enableTLS bool } // NewTCPServer creates a new TCP server. -func NewTCPServer(port uint16, prefix string) (*TCPServer, error) { +func NewTCPServer(port uint16, prefix string, enableTLS bool) (*TCPServer, error) { log.Printf("Tcp server listening on port %v\n", port) - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) - if err != nil { - log.Fatal(err) - return nil, err + var lis net.Listener + if enableTLS { + certificate, err := tls.LoadX509KeyPair("cert-chain.pem", "key.pem") + if err != nil { + return nil, err + } + caCert, err := ioutil.ReadFile("root-cert.pem") + if err != nil { + return nil, err + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + config := &tls.Config{ + Certificates: []tls.Certificate{certificate}, + NextProtos: []string{"istio2"}, + ClientAuth: tls.RequestClientCert, + ClientCAs: caCertPool, + ServerName: "localhost", + } + lis, err = tls.Listen("tcp", fmt.Sprintf(":%d", port), config) + if err != nil { + log.Fatal(err) + return nil, err + } + } else { + var err error + lis, err = net.Listen("tcp", fmt.Sprintf(":%d", port)) + if err != nil { + log.Fatal(err) + return nil, err + } } + return &TCPServer{ - port: port, - lis: lis, - prefix: prefix, + port: port, + lis: lis, + prefix: prefix, + enableTLS: enableTLS, }, nil } @@ -68,9 +102,29 @@ func handleConnection(conn net.Conn, prefix string) { } // WaitForTCPServer waits for a TCP server -func WaitForTCPServer(port uint16) error { +func WaitForTCPServer(port uint16, enableTLS bool) error { + var config *tls.Config + + if enableTLS { + certPool := x509.NewCertPool() + bs, err := ioutil.ReadFile("cert-chain.pem") + if err != nil { + return fmt.Errorf("failed to read client ca cert: %s", err) + } + ok := certPool.AppendCertsFromPEM(bs) + if !ok { + return fmt.Errorf("failed to append client certs") + } + config = &tls.Config{RootCAs: certPool, NextProtos: []string{"istio2"}, ServerName: "localhost"} + } for i := 0; i < maxAttempts; i++ { - conn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", port)) + var conn net.Conn + var err error + if enableTLS { + conn, err = tls.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", port), config) + } else { + conn, err = net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", port)) + } if err != nil { log.Println("Will wait 200ms and try again.") time.Sleep(200 * time.Millisecond) @@ -91,6 +145,7 @@ func WaitForTCPServer(port uint16) error { return fmt.Errorf("timeout waiting for server startup") } +// Serve tcp requests func Serve(l net.Listener, prefix string) error { for { conn, err := l.Accept() @@ -110,7 +165,7 @@ func (s *TCPServer) Start() <-chan error { errCh <- Serve(s.lis, s.prefix) }() go func() { - errCh <- WaitForTCPServer(s.port) + errCh <- WaitForTCPServer(s.port, s.enableTLS) }() return errCh diff --git a/test/envoye2e/stackdriver_plugin/stackdriver_plugin_test.go b/test/envoye2e/stackdriver_plugin/stackdriver_plugin_test.go index 67b25134106..f52f5d401c5 100644 --- a/test/envoye2e/stackdriver_plugin/stackdriver_plugin_test.go +++ b/test/envoye2e/stackdriver_plugin/stackdriver_plugin_test.go @@ -20,6 +20,7 @@ import ( "time" "github.com/golang/protobuf/jsonpb" + "istio.io/proxy/test/envoye2e/env" fs "istio.io/proxy/test/envoye2e/stackdriver_plugin/fake_stackdriver" diff --git a/test/envoye2e/tcp_metadata_exchange/cert-chain.pem b/test/envoye2e/tcp_metadata_exchange/cert-chain.pem new file mode 100644 index 00000000000..cb825644a3f --- /dev/null +++ b/test/envoye2e/tcp_metadata_exchange/cert-chain.pem @@ -0,0 +1,60 @@ +-----BEGIN CERTIFICATE----- +MIIFMTCCAxmgAwIBAgIDAxaCMA0GCSqGSIb3DQEBCwUAMCIxDjAMBgNVBAoMBUlz +dGlvMRAwDgYDVQQDDAdSb290IENBMB4XDTE5MDcyMjIxMzAzMloXDTIxMDcyMTIx +MzAzMlowNzEOMAwGA1UECgwFSXN0aW8xGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBD +QTELMAkGA1UEBwwCY2EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4 +rEngnty6lVXmyFqC5DsLpoDXWPaOXr4bmKYHL4PeL5vX/OOn+kbHhm4JjYOxKTmO +YtdLttsQZT7jUd+3WercyVIesWULIO33VbEtNvqKE408J0+5W266+Y+dSmVbrbOf +a6nKP6gpVf1r7Rf0NeS4S3XnUQ0igWo/Pbqn3S2C+ewkR66sCAB5vopKLzdABIN1 +7oLXil2mY4cotk4QPDRgk+AHh+uw1w6JC2c3FcNi3MLh7DIVsLyX//3BWX2bs4jR +FKva6w1KX2nohECj5FqCd7JuFdqtQO+XW5Ihhag3Hzq9VrqDgR2h0XACLqRNJQG4 +0yzP0b0SvOdpOj6JE33IxOBcLGTvrteBadA0sMzWoCfqYeFLOBhFUGSDamHqd0Or +qIAza/dE3Pb3VX0OZzW601PqnWXr4YDIKIdb3tgc97j/zbYvcjp40MQfgik6S/lZ +v8E5ZHHc1Je0zGojL8mAjoklCET1HyP/aRSMIRekdYuCjPqjVyrGeeS3R/Fatigm +gicVYvFDT7iGauyHPA7894CavHVaA40q20Y78bDJSVgsiznNGN7n2oenBZ7P8kbk +Y2pbNnqhn67v5Na1uSHVGMjB+kbVn0WZbbSawKp0W30TCtnuaBdfI1QjOWYdkIEs +pvtdI31V3cLJO9vzegwhcdYS7YG95m6VrdMQbaBE3wIDAQABo1swWTAdBgNVHQ4E +FgQUuTgg1nLlC0d35VPxZh1T6NqkDg8wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNV +HQ8BAf8EBAMCAuQwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUA +A4ICAQBV0mZPDPDOna692/cRVP2qHoHzEsYLttTioRCmQT8ideW8tpW7IwWozpKr +BlcaCXUc1K8hoMFSgYCcuh+VMH8qNCQHDEcWoPHPBFrr83ALRVdh4cYeMa7ZcIRS +l08Fa5TbVQXDkkj+t0KFr6VIBzXvVw8W/r8bgy4LSu/33WGQg4fRecp9mm0j/P8Y +DaWalN1m8TeRZtN1k7ltHmkeOPH+3NlgZ4YvlZ+ltPMrXowdP+/nCZgeR1BzFmer +0EVZ0Hq35EvXrmrrN5X4cc3b9OmaQpPQxqSlA/8hwyd0ItLZCYv1v4CB+0AI6CvY +P2RtxJ87UCz9wlthIlV2a8/d0NItV08HATfK5nXjuY8Ndm3V+jgEGGivizEaSeso +grBKJ/TbyoUpsfji5Fc2ogzrGkon1EFgR/WJ8FVlty2YVnjTfjVxD8OJ8Znjm1MH +YbisHAdTqTND0Fa2F7GFxtltD0DxQ2zsH3D8W98dxeRRigYCifixqFtk72iE702o +4K3CfPhi7MN4dxbQNFXtjrjnIQn9lN+ih+E1RK0Z4LTrd4WwsJF1MHBm6MRIFu4t +xaJb3fB5Artwn6DJ1vhfLoONDfwbrRL9/QDt0fFKtnCMbHcApsGJmrXskGim8Kma +Cw3FWjtdhpzmgK5L0SVell2IK3gEF3rphETn37YFDCttOUzpCg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFFDCCAvygAwIBAgIUZqU0Sviq/wULK6UV7PoAZ7B+nqAwDQYJKoZIhvcNAQEL +BQAwIjEOMAwGA1UECgwFSXN0aW8xEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTkwNzIy +MjEzMDA0WhcNMjkwNzE5MjEzMDA0WjAiMQ4wDAYDVQQKDAVJc3RpbzEQMA4GA1UE +AwwHUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNl5/pH +/ktdqEsb83cqHrYJCyzbvWce6k/iud4Czu6FClFX8b+n/Rv9GrZFxJwKAFlUx3iA +BGlSn/1XYpnhudQhgVGvyuWNO5kX4BfrAJwfWt+7Mn6NcWvunDqwqUPxI07sgCJW +AYBAwkZH/Nhn6tj571XWNPziUtCwlPNkFMiRu/2nI/tq12IgwimFjVgiCuprNfyX +tQz/DMVTWpCRQLK5ptlYMfk0P25UKyJdKHnr1MPQBJmPXMfSSqpGjksikV4QnYc7 +CXB3ucq7ty0IWA8QXH+86WqMTh22mosWVXHe0OGbzYtuyVnXc1G7YRv4D87G3Ves +G4n/8e+RaDTacvwOsYEkuQGk+s8pggPkIqydGy02JNZ4cSRpXJRTzME2BgBZxT8S +Ew1Omr5+iuLNRAKEYRM/eWI7qrs5fxpD6K9JELHS41hWHGdW94PP0wKz70trx5pM +fLpcVm7BQ5ppgf+t4vgKnrNiACQpfyZbInCBU0doaZaqVMnKH0vgyM7xrC43fsOP +y5URy3tEH8Uk7Dbvsmj7AXR7IPKlYtgcqcJXmeWa+kLOpx3G55hgJL1ySrxXg/qz +AobgmV0IycH2ntn5lXvjbwe0cfXAnZgGoALZjJVuEazyBmmVzjBjG2Qcq35nHfp8 +Rm6WnCZIaGsZqgoDuSJD280ZLWW7R0PMcnypAgMBAAGjQjBAMB0GA1UdDgQWBBQZ +h3/ckcK23ZYKO+JsZowd3dIobDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIC5DANBgkqhkiG9w0BAQsFAAOCAgEAjh4CdrwnLsqwVxyVSgxd7TfSHtKE/J2Y +2IZ4fJYXGkq3McPk2e9u0zjCH0buvfDwyAItLIacD+YwIP+OC2WxLe+YMZ5KkXl3 +LuhQ2TOoRlrbp5tYLQITZIIl9+vNkgnn1DkdxkLm9cDDag19LSxa9Rjrnb3wwFAT +IzEhy+d18FpQtdMMhmonU/L8Oy5LqjT5BR3T8VrXYUsaAkcUs/yHNTFAY3iJFBWL +Z8dFa5v0A1Ryi8quSNo7lK/hSEZvvV9k4XfFAolXSUqe8BCuXe0rbAq3Jq9HgDww +oImGM0uz4Zf89uhTk1O7UOUfQoSTmA0yZICtQkCiOC0J4AlAOTmiEXUC9gicV3R8 +dvVOqNBOcBELglZ+NIMm6FQQqPh1nZ6A3Bh+JRTPerAF12725RZZE6XMxq2MSr3G +k5yH10QPMH7/DJRQUhRHAhbge+jk2csa7EGSxABcbsPLSV+cEzXRO4cJeItoZQLh +saFhIn9lGukXG6lgiperOqZl6DFVcUG6/nogK7KOTAnV9zjR/7vNwvYzPI9iOR3V +6dbG38KnipcfL885VLJVTnfhvYHlxFklCKTEnOHnmKsM0qjQuky3DBzmDA6iqeOM +SHRje5LKxi7mllJfu/X0MxYJWiu6i4gMCWZsC3UtAJQ09x7iwcNr/1bl9ApGszOy +Uff0OxD2hzk= +-----END CERTIFICATE----- diff --git a/test/envoye2e/tcp_metadata_exchange/doc.go b/test/envoye2e/tcp_metadata_exchange/doc.go new file mode 100644 index 00000000000..35e5077484d --- /dev/null +++ b/test/envoye2e/tcp_metadata_exchange/doc.go @@ -0,0 +1,16 @@ +// Copyright 2019 Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package tcp_metadata_exchange contains an integration test for metadata exchange in envoy proxy. +package tcp_metadata_exchange diff --git a/test/envoye2e/tcp_metadata_exchange/key.pem b/test/envoye2e/tcp_metadata_exchange/key.pem new file mode 100644 index 00000000000..21e580d3565 --- /dev/null +++ b/test/envoye2e/tcp_metadata_exchange/key.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/test/envoye2e/tcp_metadata_exchange/root-cert.pem b/test/envoye2e/tcp_metadata_exchange/root-cert.pem new file mode 100644 index 00000000000..261912d6eac --- /dev/null +++ b/test/envoye2e/tcp_metadata_exchange/root-cert.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFFDCCAvygAwIBAgIUZqU0Sviq/wULK6UV7PoAZ7B+nqAwDQYJKoZIhvcNAQEL +BQAwIjEOMAwGA1UECgwFSXN0aW8xEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTkwNzIy +MjEzMDA0WhcNMjkwNzE5MjEzMDA0WjAiMQ4wDAYDVQQKDAVJc3RpbzEQMA4GA1UE +AwwHUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNl5/pH +/ktdqEsb83cqHrYJCyzbvWce6k/iud4Czu6FClFX8b+n/Rv9GrZFxJwKAFlUx3iA +BGlSn/1XYpnhudQhgVGvyuWNO5kX4BfrAJwfWt+7Mn6NcWvunDqwqUPxI07sgCJW +AYBAwkZH/Nhn6tj571XWNPziUtCwlPNkFMiRu/2nI/tq12IgwimFjVgiCuprNfyX +tQz/DMVTWpCRQLK5ptlYMfk0P25UKyJdKHnr1MPQBJmPXMfSSqpGjksikV4QnYc7 +CXB3ucq7ty0IWA8QXH+86WqMTh22mosWVXHe0OGbzYtuyVnXc1G7YRv4D87G3Ves +G4n/8e+RaDTacvwOsYEkuQGk+s8pggPkIqydGy02JNZ4cSRpXJRTzME2BgBZxT8S +Ew1Omr5+iuLNRAKEYRM/eWI7qrs5fxpD6K9JELHS41hWHGdW94PP0wKz70trx5pM +fLpcVm7BQ5ppgf+t4vgKnrNiACQpfyZbInCBU0doaZaqVMnKH0vgyM7xrC43fsOP +y5URy3tEH8Uk7Dbvsmj7AXR7IPKlYtgcqcJXmeWa+kLOpx3G55hgJL1ySrxXg/qz +AobgmV0IycH2ntn5lXvjbwe0cfXAnZgGoALZjJVuEazyBmmVzjBjG2Qcq35nHfp8 +Rm6WnCZIaGsZqgoDuSJD280ZLWW7R0PMcnypAgMBAAGjQjBAMB0GA1UdDgQWBBQZ +h3/ckcK23ZYKO+JsZowd3dIobDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIC5DANBgkqhkiG9w0BAQsFAAOCAgEAjh4CdrwnLsqwVxyVSgxd7TfSHtKE/J2Y +2IZ4fJYXGkq3McPk2e9u0zjCH0buvfDwyAItLIacD+YwIP+OC2WxLe+YMZ5KkXl3 +LuhQ2TOoRlrbp5tYLQITZIIl9+vNkgnn1DkdxkLm9cDDag19LSxa9Rjrnb3wwFAT +IzEhy+d18FpQtdMMhmonU/L8Oy5LqjT5BR3T8VrXYUsaAkcUs/yHNTFAY3iJFBWL +Z8dFa5v0A1Ryi8quSNo7lK/hSEZvvV9k4XfFAolXSUqe8BCuXe0rbAq3Jq9HgDww +oImGM0uz4Zf89uhTk1O7UOUfQoSTmA0yZICtQkCiOC0J4AlAOTmiEXUC9gicV3R8 +dvVOqNBOcBELglZ+NIMm6FQQqPh1nZ6A3Bh+JRTPerAF12725RZZE6XMxq2MSr3G +k5yH10QPMH7/DJRQUhRHAhbge+jk2csa7EGSxABcbsPLSV+cEzXRO4cJeItoZQLh +saFhIn9lGukXG6lgiperOqZl6DFVcUG6/nogK7KOTAnV9zjR/7vNwvYzPI9iOR3V +6dbG38KnipcfL885VLJVTnfhvYHlxFklCKTEnOHnmKsM0qjQuky3DBzmDA6iqeOM +SHRje5LKxi7mllJfu/X0MxYJWiu6i4gMCWZsC3UtAJQ09x7iwcNr/1bl9ApGszOy +Uff0OxD2hzk= +-----END CERTIFICATE----- diff --git a/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go b/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go new file mode 100644 index 00000000000..38ec95a1287 --- /dev/null +++ b/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go @@ -0,0 +1,181 @@ +// Copyright 2019 Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp_metadata_exchange_test + +import ( + "bytes" + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" + + "testing" + "text/template" + + "istio.io/proxy/test/envoye2e/env" +) + +const alpnIstioConfigFilter = ` +- name: envoy.filters.network.alpn_proxy + config: + protocol: istio2 + node_metadata_id: istio.io/metadata +` + +const alpnIstioUpstreamConfigFilterChain = ` +filters: +- name: envoy.filters.network.upstream.alpn_proxy + typed_config: + "@type": type.googleapis.com/envoy.tcp.alpnproxy.config.AlpnProxy + protocol: istio2 + node_metadata_id: istio.io/metadata +` + +const tlsContext = ` +tls_context: + common_tls_context: + alpn_protocols: + - istio2 + tls_certificates: + - certificate_chain: + inline_string: "-----BEGIN CERTIFICATE-----\nMIIFMTCCAxmgAwIBAgIDAxaCMA0GCSqGSIb3DQEBCwUAMCIxDjAMBgNVBAoMBUlz\ndGlvMRAwDgYDVQQDDAdSb290IENBMB4XDTE5MDcyMjIxMzAzMloXDTIxMDcyMTIx\nMzAzMlowNzEOMAwGA1UECgwFSXN0aW8xGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBD\nQTELMAkGA1UEBwwCY2EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4\nrEngnty6lVXmyFqC5DsLpoDXWPaOXr4bmKYHL4PeL5vX/OOn+kbHhm4JjYOxKTmO\nYtdLttsQZT7jUd+3WercyVIesWULIO33VbEtNvqKE408J0+5W266+Y+dSmVbrbOf\na6nKP6gpVf1r7Rf0NeS4S3XnUQ0igWo/Pbqn3S2C+ewkR66sCAB5vopKLzdABIN1\n7oLXil2mY4cotk4QPDRgk+AHh+uw1w6JC2c3FcNi3MLh7DIVsLyX//3BWX2bs4jR\nFKva6w1KX2nohECj5FqCd7JuFdqtQO+XW5Ihhag3Hzq9VrqDgR2h0XACLqRNJQG4\n0yzP0b0SvOdpOj6JE33IxOBcLGTvrteBadA0sMzWoCfqYeFLOBhFUGSDamHqd0Or\nqIAza/dE3Pb3VX0OZzW601PqnWXr4YDIKIdb3tgc97j/zbYvcjp40MQfgik6S/lZ\nv8E5ZHHc1Je0zGojL8mAjoklCET1HyP/aRSMIRekdYuCjPqjVyrGeeS3R/Fatigm\ngicVYvFDT7iGauyHPA7894CavHVaA40q20Y78bDJSVgsiznNGN7n2oenBZ7P8kbk\nY2pbNnqhn67v5Na1uSHVGMjB+kbVn0WZbbSawKp0W30TCtnuaBdfI1QjOWYdkIEs\npvtdI31V3cLJO9vzegwhcdYS7YG95m6VrdMQbaBE3wIDAQABo1swWTAdBgNVHQ4E\nFgQUuTgg1nLlC0d35VPxZh1T6NqkDg8wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNV\nHQ8BAf8EBAMCAuQwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUA\nA4ICAQBV0mZPDPDOna692/cRVP2qHoHzEsYLttTioRCmQT8ideW8tpW7IwWozpKr\nBlcaCXUc1K8hoMFSgYCcuh+VMH8qNCQHDEcWoPHPBFrr83ALRVdh4cYeMa7ZcIRS\nl08Fa5TbVQXDkkj+t0KFr6VIBzXvVw8W/r8bgy4LSu/33WGQg4fRecp9mm0j/P8Y\nDaWalN1m8TeRZtN1k7ltHmkeOPH+3NlgZ4YvlZ+ltPMrXowdP+/nCZgeR1BzFmer\n0EVZ0Hq35EvXrmrrN5X4cc3b9OmaQpPQxqSlA/8hwyd0ItLZCYv1v4CB+0AI6CvY\nP2RtxJ87UCz9wlthIlV2a8/d0NItV08HATfK5nXjuY8Ndm3V+jgEGGivizEaSeso\ngrBKJ/TbyoUpsfji5Fc2ogzrGkon1EFgR/WJ8FVlty2YVnjTfjVxD8OJ8Znjm1MH\nYbisHAdTqTND0Fa2F7GFxtltD0DxQ2zsH3D8W98dxeRRigYCifixqFtk72iE702o\n4K3CfPhi7MN4dxbQNFXtjrjnIQn9lN+ih+E1RK0Z4LTrd4WwsJF1MHBm6MRIFu4t\nxaJb3fB5Artwn6DJ1vhfLoONDfwbrRL9/QDt0fFKtnCMbHcApsGJmrXskGim8Kma\nCw3FWjtdhpzmgK5L0SVell2IK3gEF3rphETn37YFDCttOUzpCg==\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIFFDCCAvygAwIBAgIUZqU0Sviq/wULK6UV7PoAZ7B+nqAwDQYJKoZIhvcNAQEL\nBQAwIjEOMAwGA1UECgwFSXN0aW8xEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTkwNzIy\nMjEzMDA0WhcNMjkwNzE5MjEzMDA0WjAiMQ4wDAYDVQQKDAVJc3RpbzEQMA4GA1UE\nAwwHUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNl5/pH\n/ktdqEsb83cqHrYJCyzbvWce6k/iud4Czu6FClFX8b+n/Rv9GrZFxJwKAFlUx3iA\nBGlSn/1XYpnhudQhgVGvyuWNO5kX4BfrAJwfWt+7Mn6NcWvunDqwqUPxI07sgCJW\nAYBAwkZH/Nhn6tj571XWNPziUtCwlPNkFMiRu/2nI/tq12IgwimFjVgiCuprNfyX\ntQz/DMVTWpCRQLK5ptlYMfk0P25UKyJdKHnr1MPQBJmPXMfSSqpGjksikV4QnYc7\nCXB3ucq7ty0IWA8QXH+86WqMTh22mosWVXHe0OGbzYtuyVnXc1G7YRv4D87G3Ves\nG4n/8e+RaDTacvwOsYEkuQGk+s8pggPkIqydGy02JNZ4cSRpXJRTzME2BgBZxT8S\nEw1Omr5+iuLNRAKEYRM/eWI7qrs5fxpD6K9JELHS41hWHGdW94PP0wKz70trx5pM\nfLpcVm7BQ5ppgf+t4vgKnrNiACQpfyZbInCBU0doaZaqVMnKH0vgyM7xrC43fsOP\ny5URy3tEH8Uk7Dbvsmj7AXR7IPKlYtgcqcJXmeWa+kLOpx3G55hgJL1ySrxXg/qz\nAobgmV0IycH2ntn5lXvjbwe0cfXAnZgGoALZjJVuEazyBmmVzjBjG2Qcq35nHfp8\nRm6WnCZIaGsZqgoDuSJD280ZLWW7R0PMcnypAgMBAAGjQjBAMB0GA1UdDgQWBBQZ\nh3/ckcK23ZYKO+JsZowd3dIobDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE\nAwIC5DANBgkqhkiG9w0BAQsFAAOCAgEAjh4CdrwnLsqwVxyVSgxd7TfSHtKE/J2Y\n2IZ4fJYXGkq3McPk2e9u0zjCH0buvfDwyAItLIacD+YwIP+OC2WxLe+YMZ5KkXl3\nLuhQ2TOoRlrbp5tYLQITZIIl9+vNkgnn1DkdxkLm9cDDag19LSxa9Rjrnb3wwFAT\nIzEhy+d18FpQtdMMhmonU/L8Oy5LqjT5BR3T8VrXYUsaAkcUs/yHNTFAY3iJFBWL\nZ8dFa5v0A1Ryi8quSNo7lK/hSEZvvV9k4XfFAolXSUqe8BCuXe0rbAq3Jq9HgDww\noImGM0uz4Zf89uhTk1O7UOUfQoSTmA0yZICtQkCiOC0J4AlAOTmiEXUC9gicV3R8\ndvVOqNBOcBELglZ+NIMm6FQQqPh1nZ6A3Bh+JRTPerAF12725RZZE6XMxq2MSr3G\nk5yH10QPMH7/DJRQUhRHAhbge+jk2csa7EGSxABcbsPLSV+cEzXRO4cJeItoZQLh\nsaFhIn9lGukXG6lgiperOqZl6DFVcUG6/nogK7KOTAnV9zjR/7vNwvYzPI9iOR3V\n6dbG38KnipcfL885VLJVTnfhvYHlxFklCKTEnOHnmKsM0qjQuky3DBzmDA6iqeOM\nSHRje5LKxi7mllJfu/X0MxYJWiu6i4gMCWZsC3UtAJQ09x7iwcNr/1bl9ApGszOy\nUff0OxD2hzk=\n-----END CERTIFICATE-----\n" + private_key: + inline_string: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----\n" + validation_context: + trusted_ca: + inline_string: "-----BEGIN CERTIFICATE-----\nMIIFFDCCAvygAwIBAgIUZqU0Sviq/wULK6UV7PoAZ7B+nqAwDQYJKoZIhvcNAQEL\nBQAwIjEOMAwGA1UECgwFSXN0aW8xEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTkwNzIy\nMjEzMDA0WhcNMjkwNzE5MjEzMDA0WjAiMQ4wDAYDVQQKDAVJc3RpbzEQMA4GA1UE\nAwwHUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNl5/pH\n/ktdqEsb83cqHrYJCyzbvWce6k/iud4Czu6FClFX8b+n/Rv9GrZFxJwKAFlUx3iA\nBGlSn/1XYpnhudQhgVGvyuWNO5kX4BfrAJwfWt+7Mn6NcWvunDqwqUPxI07sgCJW\nAYBAwkZH/Nhn6tj571XWNPziUtCwlPNkFMiRu/2nI/tq12IgwimFjVgiCuprNfyX\ntQz/DMVTWpCRQLK5ptlYMfk0P25UKyJdKHnr1MPQBJmPXMfSSqpGjksikV4QnYc7\nCXB3ucq7ty0IWA8QXH+86WqMTh22mosWVXHe0OGbzYtuyVnXc1G7YRv4D87G3Ves\nG4n/8e+RaDTacvwOsYEkuQGk+s8pggPkIqydGy02JNZ4cSRpXJRTzME2BgBZxT8S\nEw1Omr5+iuLNRAKEYRM/eWI7qrs5fxpD6K9JELHS41hWHGdW94PP0wKz70trx5pM\nfLpcVm7BQ5ppgf+t4vgKnrNiACQpfyZbInCBU0doaZaqVMnKH0vgyM7xrC43fsOP\ny5URy3tEH8Uk7Dbvsmj7AXR7IPKlYtgcqcJXmeWa+kLOpx3G55hgJL1ySrxXg/qz\nAobgmV0IycH2ntn5lXvjbwe0cfXAnZgGoALZjJVuEazyBmmVzjBjG2Qcq35nHfp8\nRm6WnCZIaGsZqgoDuSJD280ZLWW7R0PMcnypAgMBAAGjQjBAMB0GA1UdDgQWBBQZ\nh3/ckcK23ZYKO+JsZowd3dIobDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE\nAwIC5DANBgkqhkiG9w0BAQsFAAOCAgEAjh4CdrwnLsqwVxyVSgxd7TfSHtKE/J2Y\n2IZ4fJYXGkq3McPk2e9u0zjCH0buvfDwyAItLIacD+YwIP+OC2WxLe+YMZ5KkXl3\nLuhQ2TOoRlrbp5tYLQITZIIl9+vNkgnn1DkdxkLm9cDDag19LSxa9Rjrnb3wwFAT\nIzEhy+d18FpQtdMMhmonU/L8Oy5LqjT5BR3T8VrXYUsaAkcUs/yHNTFAY3iJFBWL\nZ8dFa5v0A1Ryi8quSNo7lK/hSEZvvV9k4XfFAolXSUqe8BCuXe0rbAq3Jq9HgDww\noImGM0uz4Zf89uhTk1O7UOUfQoSTmA0yZICtQkCiOC0J4AlAOTmiEXUC9gicV3R8\ndvVOqNBOcBELglZ+NIMm6FQQqPh1nZ6A3Bh+JRTPerAF12725RZZE6XMxq2MSr3G\nk5yH10QPMH7/DJRQUhRHAhbge+jk2csa7EGSxABcbsPLSV+cEzXRO4cJeItoZQLh\nsaFhIn9lGukXG6lgiperOqZl6DFVcUG6/nogK7KOTAnV9zjR/7vNwvYzPI9iOR3V\n6dbG38KnipcfL885VLJVTnfhvYHlxFklCKTEnOHnmKsM0qjQuky3DBzmDA6iqeOM\nSHRje5LKxi7mllJfu/X0MxYJWiu6i4gMCWZsC3UtAJQ09x7iwcNr/1bl9ApGszOy\nUff0OxD2hzk=\n-----END CERTIFICATE-----\n" + require_client_certificate: true +` + +const clusterTlsContext = ` +tls_context: + common_tls_context: + alpn_protocols: + - istio2 + tls_certificates: + - certificate_chain: + inline_string: "-----BEGIN CERTIFICATE-----\nMIIFMTCCAxmgAwIBAgIDAxaCMA0GCSqGSIb3DQEBCwUAMCIxDjAMBgNVBAoMBUlz\ndGlvMRAwDgYDVQQDDAdSb290IENBMB4XDTE5MDcyMjIxMzAzMloXDTIxMDcyMTIx\nMzAzMlowNzEOMAwGA1UECgwFSXN0aW8xGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBD\nQTELMAkGA1UEBwwCY2EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4\nrEngnty6lVXmyFqC5DsLpoDXWPaOXr4bmKYHL4PeL5vX/OOn+kbHhm4JjYOxKTmO\nYtdLttsQZT7jUd+3WercyVIesWULIO33VbEtNvqKE408J0+5W266+Y+dSmVbrbOf\na6nKP6gpVf1r7Rf0NeS4S3XnUQ0igWo/Pbqn3S2C+ewkR66sCAB5vopKLzdABIN1\n7oLXil2mY4cotk4QPDRgk+AHh+uw1w6JC2c3FcNi3MLh7DIVsLyX//3BWX2bs4jR\nFKva6w1KX2nohECj5FqCd7JuFdqtQO+XW5Ihhag3Hzq9VrqDgR2h0XACLqRNJQG4\n0yzP0b0SvOdpOj6JE33IxOBcLGTvrteBadA0sMzWoCfqYeFLOBhFUGSDamHqd0Or\nqIAza/dE3Pb3VX0OZzW601PqnWXr4YDIKIdb3tgc97j/zbYvcjp40MQfgik6S/lZ\nv8E5ZHHc1Je0zGojL8mAjoklCET1HyP/aRSMIRekdYuCjPqjVyrGeeS3R/Fatigm\ngicVYvFDT7iGauyHPA7894CavHVaA40q20Y78bDJSVgsiznNGN7n2oenBZ7P8kbk\nY2pbNnqhn67v5Na1uSHVGMjB+kbVn0WZbbSawKp0W30TCtnuaBdfI1QjOWYdkIEs\npvtdI31V3cLJO9vzegwhcdYS7YG95m6VrdMQbaBE3wIDAQABo1swWTAdBgNVHQ4E\nFgQUuTgg1nLlC0d35VPxZh1T6NqkDg8wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNV\nHQ8BAf8EBAMCAuQwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUA\nA4ICAQBV0mZPDPDOna692/cRVP2qHoHzEsYLttTioRCmQT8ideW8tpW7IwWozpKr\nBlcaCXUc1K8hoMFSgYCcuh+VMH8qNCQHDEcWoPHPBFrr83ALRVdh4cYeMa7ZcIRS\nl08Fa5TbVQXDkkj+t0KFr6VIBzXvVw8W/r8bgy4LSu/33WGQg4fRecp9mm0j/P8Y\nDaWalN1m8TeRZtN1k7ltHmkeOPH+3NlgZ4YvlZ+ltPMrXowdP+/nCZgeR1BzFmer\n0EVZ0Hq35EvXrmrrN5X4cc3b9OmaQpPQxqSlA/8hwyd0ItLZCYv1v4CB+0AI6CvY\nP2RtxJ87UCz9wlthIlV2a8/d0NItV08HATfK5nXjuY8Ndm3V+jgEGGivizEaSeso\ngrBKJ/TbyoUpsfji5Fc2ogzrGkon1EFgR/WJ8FVlty2YVnjTfjVxD8OJ8Znjm1MH\nYbisHAdTqTND0Fa2F7GFxtltD0DxQ2zsH3D8W98dxeRRigYCifixqFtk72iE702o\n4K3CfPhi7MN4dxbQNFXtjrjnIQn9lN+ih+E1RK0Z4LTrd4WwsJF1MHBm6MRIFu4t\nxaJb3fB5Artwn6DJ1vhfLoONDfwbrRL9/QDt0fFKtnCMbHcApsGJmrXskGim8Kma\nCw3FWjtdhpzmgK5L0SVell2IK3gEF3rphETn37YFDCttOUzpCg==\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIFFDCCAvygAwIBAgIUZqU0Sviq/wULK6UV7PoAZ7B+nqAwDQYJKoZIhvcNAQEL\nBQAwIjEOMAwGA1UECgwFSXN0aW8xEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTkwNzIy\nMjEzMDA0WhcNMjkwNzE5MjEzMDA0WjAiMQ4wDAYDVQQKDAVJc3RpbzEQMA4GA1UE\nAwwHUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNl5/pH\n/ktdqEsb83cqHrYJCyzbvWce6k/iud4Czu6FClFX8b+n/Rv9GrZFxJwKAFlUx3iA\nBGlSn/1XYpnhudQhgVGvyuWNO5kX4BfrAJwfWt+7Mn6NcWvunDqwqUPxI07sgCJW\nAYBAwkZH/Nhn6tj571XWNPziUtCwlPNkFMiRu/2nI/tq12IgwimFjVgiCuprNfyX\ntQz/DMVTWpCRQLK5ptlYMfk0P25UKyJdKHnr1MPQBJmPXMfSSqpGjksikV4QnYc7\nCXB3ucq7ty0IWA8QXH+86WqMTh22mosWVXHe0OGbzYtuyVnXc1G7YRv4D87G3Ves\nG4n/8e+RaDTacvwOsYEkuQGk+s8pggPkIqydGy02JNZ4cSRpXJRTzME2BgBZxT8S\nEw1Omr5+iuLNRAKEYRM/eWI7qrs5fxpD6K9JELHS41hWHGdW94PP0wKz70trx5pM\nfLpcVm7BQ5ppgf+t4vgKnrNiACQpfyZbInCBU0doaZaqVMnKH0vgyM7xrC43fsOP\ny5URy3tEH8Uk7Dbvsmj7AXR7IPKlYtgcqcJXmeWa+kLOpx3G55hgJL1ySrxXg/qz\nAobgmV0IycH2ntn5lXvjbwe0cfXAnZgGoALZjJVuEazyBmmVzjBjG2Qcq35nHfp8\nRm6WnCZIaGsZqgoDuSJD280ZLWW7R0PMcnypAgMBAAGjQjBAMB0GA1UdDgQWBBQZ\nh3/ckcK23ZYKO+JsZowd3dIobDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE\nAwIC5DANBgkqhkiG9w0BAQsFAAOCAgEAjh4CdrwnLsqwVxyVSgxd7TfSHtKE/J2Y\n2IZ4fJYXGkq3McPk2e9u0zjCH0buvfDwyAItLIacD+YwIP+OC2WxLe+YMZ5KkXl3\nLuhQ2TOoRlrbp5tYLQITZIIl9+vNkgnn1DkdxkLm9cDDag19LSxa9Rjrnb3wwFAT\nIzEhy+d18FpQtdMMhmonU/L8Oy5LqjT5BR3T8VrXYUsaAkcUs/yHNTFAY3iJFBWL\nZ8dFa5v0A1Ryi8quSNo7lK/hSEZvvV9k4XfFAolXSUqe8BCuXe0rbAq3Jq9HgDww\noImGM0uz4Zf89uhTk1O7UOUfQoSTmA0yZICtQkCiOC0J4AlAOTmiEXUC9gicV3R8\ndvVOqNBOcBELglZ+NIMm6FQQqPh1nZ6A3Bh+JRTPerAF12725RZZE6XMxq2MSr3G\nk5yH10QPMH7/DJRQUhRHAhbge+jk2csa7EGSxABcbsPLSV+cEzXRO4cJeItoZQLh\nsaFhIn9lGukXG6lgiperOqZl6DFVcUG6/nogK7KOTAnV9zjR/7vNwvYzPI9iOR3V\n6dbG38KnipcfL885VLJVTnfhvYHlxFklCKTEnOHnmKsM0qjQuky3DBzmDA6iqeOM\nSHRje5LKxi7mllJfu/X0MxYJWiu6i4gMCWZsC3UtAJQ09x7iwcNr/1bl9ApGszOy\nUff0OxD2hzk=\n-----END CERTIFICATE-----\n" + private_key: + inline_string: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----\n" + validation_context: + trusted_ca: + inline_string: "-----BEGIN CERTIFICATE-----\nMIIFFDCCAvygAwIBAgIUZqU0Sviq/wULK6UV7PoAZ7B+nqAwDQYJKoZIhvcNAQEL\nBQAwIjEOMAwGA1UECgwFSXN0aW8xEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTkwNzIy\nMjEzMDA0WhcNMjkwNzE5MjEzMDA0WjAiMQ4wDAYDVQQKDAVJc3RpbzEQMA4GA1UE\nAwwHUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNl5/pH\n/ktdqEsb83cqHrYJCyzbvWce6k/iud4Czu6FClFX8b+n/Rv9GrZFxJwKAFlUx3iA\nBGlSn/1XYpnhudQhgVGvyuWNO5kX4BfrAJwfWt+7Mn6NcWvunDqwqUPxI07sgCJW\nAYBAwkZH/Nhn6tj571XWNPziUtCwlPNkFMiRu/2nI/tq12IgwimFjVgiCuprNfyX\ntQz/DMVTWpCRQLK5ptlYMfk0P25UKyJdKHnr1MPQBJmPXMfSSqpGjksikV4QnYc7\nCXB3ucq7ty0IWA8QXH+86WqMTh22mosWVXHe0OGbzYtuyVnXc1G7YRv4D87G3Ves\nG4n/8e+RaDTacvwOsYEkuQGk+s8pggPkIqydGy02JNZ4cSRpXJRTzME2BgBZxT8S\nEw1Omr5+iuLNRAKEYRM/eWI7qrs5fxpD6K9JELHS41hWHGdW94PP0wKz70trx5pM\nfLpcVm7BQ5ppgf+t4vgKnrNiACQpfyZbInCBU0doaZaqVMnKH0vgyM7xrC43fsOP\ny5URy3tEH8Uk7Dbvsmj7AXR7IPKlYtgcqcJXmeWa+kLOpx3G55hgJL1ySrxXg/qz\nAobgmV0IycH2ntn5lXvjbwe0cfXAnZgGoALZjJVuEazyBmmVzjBjG2Qcq35nHfp8\nRm6WnCZIaGsZqgoDuSJD280ZLWW7R0PMcnypAgMBAAGjQjBAMB0GA1UdDgQWBBQZ\nh3/ckcK23ZYKO+JsZowd3dIobDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE\nAwIC5DANBgkqhkiG9w0BAQsFAAOCAgEAjh4CdrwnLsqwVxyVSgxd7TfSHtKE/J2Y\n2IZ4fJYXGkq3McPk2e9u0zjCH0buvfDwyAItLIacD+YwIP+OC2WxLe+YMZ5KkXl3\nLuhQ2TOoRlrbp5tYLQITZIIl9+vNkgnn1DkdxkLm9cDDag19LSxa9Rjrnb3wwFAT\nIzEhy+d18FpQtdMMhmonU/L8Oy5LqjT5BR3T8VrXYUsaAkcUs/yHNTFAY3iJFBWL\nZ8dFa5v0A1Ryi8quSNo7lK/hSEZvvV9k4XfFAolXSUqe8BCuXe0rbAq3Jq9HgDww\noImGM0uz4Zf89uhTk1O7UOUfQoSTmA0yZICtQkCiOC0J4AlAOTmiEXUC9gicV3R8\ndvVOqNBOcBELglZ+NIMm6FQQqPh1nZ6A3Bh+JRTPerAF12725RZZE6XMxq2MSr3G\nk5yH10QPMH7/DJRQUhRHAhbge+jk2csa7EGSxABcbsPLSV+cEzXRO4cJeItoZQLh\nsaFhIn9lGukXG6lgiperOqZl6DFVcUG6/nogK7KOTAnV9zjR/7vNwvYzPI9iOR3V\n6dbG38KnipcfL885VLJVTnfhvYHlxFklCKTEnOHnmKsM0qjQuky3DBzmDA6iqeOM\nSHRje5LKxi7mllJfu/X0MxYJWiu6i4gMCWZsC3UtAJQ09x7iwcNr/1bl9ApGszOy\nUff0OxD2hzk=\n-----END CERTIFICATE-----\n" +` + +const clientNodeMetadata = ` +"istio.io/metadata": { + namespace: default, + labels: { app: productpage }, + } +` + +const serverNodeMetadata = ` +"istio.io/metadata": { + namespace: default, + labels: { app: details }, + } +` + +// Stats in Client Envoy proxy. +var expectedClientStats = map[string]int{ + "cluster.client.alpn_proxy.alpn_protocol_found": 1, + "cluster.client.alpn_proxy.alpn_protocol_not_found": 0, + "cluster.client.alpn_proxy.initial_header_not_found": 0, + "cluster.client.alpn_proxy.header_not_found": 0, + "cluster.client.alpn_proxy.metadata_added": 1, +} + +// Stats in Server Envoy proxy. +var expectedServerStats = map[string]int{ + "alpn_proxy.alpn_protocol_found": 1, + "alpn_proxy.alpn_protocol_not_found": 0, + "alpn_proxy.initial_header_not_found": 0, + "alpn_proxy.header_not_found": 0, + "alpn_proxy.metadata_added": 1, +} + +func TestTcpMetadataExchange(t *testing.T) { + s := env.NewClientServerEnvoyTestSetup(env.TcpMetadataExchangeTest, t) + s.SetNoBackend(true) + s.SetStartTcpBackend(true) + s.SetTlsContext(tlsContext) + s.SetClusterTlsContext(clusterTlsContext) + s.SetFiltersBeforeEnvoyRouterInClientToApp(alpnIstioConfigFilter) + s.SetUpstreamFiltersInClient(alpnIstioUpstreamConfigFilterChain) + s.SetEnableTls(true) + s.SetClientNodeMetadata(clientNodeMetadata) + s.SetServerNodeMetadata(serverNodeMetadata) + s.ClientEnvoyTemplate = env.GetTcpClientEnvoyConfTmp() + s.ServerEnvoyTemplate = env.GetTcpServerEnvoyConfTmp() + if err := s.SetUpClientServerEnvoy(); err != nil { + t.Fatalf("Failed to setup te1 st: %v", err) + } + defer s.TearDownClientServerEnvoy() + + certPool := x509.NewCertPool() + bs, err := ioutil.ReadFile("cert-chain.pem") + if err != nil { + t.Fatalf("failed to read client ca cert: %s", err) + } + ok := certPool.AppendCertsFromPEM(bs) + if !ok { + t.Fatal("failed to append client certs") + } + + certificate, err := tls.LoadX509KeyPair("cert-chain.pem", "key.pem") + if err != nil { + t.Fatal("failed to get certificate") + } + config := &tls.Config{Certificates: []tls.Certificate{certificate}, ServerName: "localhost", NextProtos: []string{"istio2"}, RootCAs: certPool} + + conn, err := tls.Dial("tcp", fmt.Sprintf("localhost:%d", s.Ports().AppToClientProxyPort /*s.Ports().ProxyToServerProxyPort*/), config) + if err != nil { + t.Fatal(err) + } + + conn.Write([]byte("world \n")) + reply := make([]byte, 256) + n, err := conn.Read(reply) + if err != nil { + t.Fatal(err) + } + + if fmt.Sprintf("%s", reply[:n]) != "hello world \n" { + t.Fatalf("Verification Failed. Expected: hello world. Got: %v", fmt.Sprintf("%s", reply[:n])) + } + + _ = conn.Close() + s.VerifyStats(getParsedExpectedStats(expectedClientStats, t, s), s.Ports().ClientAdminPort) + s.VerifyStats(getParsedExpectedStats(expectedServerStats, t, s), s.Ports().ServerAdminPort) +} + +func getParsedExpectedStats(expectedStats map[string]int, t *testing.T, s *env.TestSetup) map[string]int { + parsedExpectedStats := make(map[string]int) + for key, value := range expectedStats { + tmpl, err := template.New("parse_state").Parse(key) + if err != nil { + t.Errorf("failed to parse config template: %v", err) + } + + var tpl bytes.Buffer + err = tmpl.Execute(&tpl, s) + if err != nil { + t.Errorf("failed to execute config template: %v", err) + } + parsedExpectedStats[tpl.String()] = value + } + + return parsedExpectedStats +} From 13100f6c4ded026d82abe6572a6a836c4d7cf9ae Mon Sep 17 00:00:00 2001 From: gargnupur Date: Thu, 26 Sep 2019 11:34:07 -0700 Subject: [PATCH 02/12] Fix build errors --- src/envoy/tcp/alpn_proxy/alpn_proxy.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy.cc b/src/envoy/tcp/alpn_proxy/alpn_proxy.cc index 68ad439ed79..3ddc4f560fb 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy.cc +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy.cc @@ -230,8 +230,8 @@ void AlpnProxyFilter::tryReadProxyData(Buffer::Instance& data) { data.drain(proxy_data_length_); Envoy::ProtobufWkt::Struct struct_metadata = - Envoy::MessageUtil::anyConvert( - proxy_data, validation_visitor_); + Envoy::MessageUtil::anyConvert(proxy_data); + Envoy::MessageUtil::validate(struct_metadata, validation_visitor_); if (config_->filter_direction_ == FilterDirection::Downstream) { writeMetadata(UpstreamDynamicDataKey, struct_metadata); } else { From b6f306f8cace58f8e302faccf698a90832a8d4b2 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Thu, 26 Sep 2019 14:21:51 -0700 Subject: [PATCH 03/12] Fix build errors --- src/envoy/tcp/alpn_proxy/alpn_proxy.cc | 2 -- src/envoy/tcp/alpn_proxy/alpn_proxy.h | 7 +------ src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc | 4 +--- src/envoy/tcp/alpn_proxy/config.cc | 3 +-- 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy.cc b/src/envoy/tcp/alpn_proxy/alpn_proxy.cc index 3ddc4f560fb..4e7f01409cd 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy.cc +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy.cc @@ -19,7 +19,6 @@ #include "absl/base/internal/endian.h" #include "absl/strings/string_view.h" #include "common/buffer/buffer_impl.h" -#include "common/protobuf/message_validator_impl.h" #include "common/protobuf/utility.h" #include "envoy/network/connection.h" #include "envoy/stats/scope.h" @@ -231,7 +230,6 @@ void AlpnProxyFilter::tryReadProxyData(Buffer::Instance& data) { Envoy::ProtobufWkt::Struct struct_metadata = Envoy::MessageUtil::anyConvert(proxy_data); - Envoy::MessageUtil::validate(struct_metadata, validation_visitor_); if (config_->filter_direction_ == FilterDirection::Downstream) { writeMetadata(UpstreamDynamicDataKey, struct_metadata); } else { diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy.h b/src/envoy/tcp/alpn_proxy/alpn_proxy.h index a2db88a42e5..615ea417057 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy.h +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy.h @@ -17,7 +17,6 @@ #include -#include "common/protobuf/message_validator_impl.h" #include "common/protobuf/protobuf.h" #include "envoy/local_info/local_info.h" #include "envoy/network/filter.h" @@ -91,11 +90,9 @@ using AlpnProxyConfigSharedPtr = std::shared_ptr; class AlpnProxyFilter : public Network::Filter { public: AlpnProxyFilter(AlpnProxyConfigSharedPtr config, - const LocalInfo::LocalInfo& local_info, - ProtobufMessage::ValidationVisitor& validation_visitor) + const LocalInfo::LocalInfo& local_info) : config_(config), local_info_(local_info), - validation_visitor_(validation_visitor), conn_state_(ConnProtocolNotRead) {} // Network::ReadFilter @@ -144,8 +141,6 @@ class AlpnProxyFilter : public Network::Filter { Network::WriteFilterCallbacks* write_callbacks_{}; // Stores the length of proxy data that contains node metadata. uint64_t proxy_data_length_{0}; - // Validation Visitor instance. - ProtobufMessage::ValidationVisitor& validation_visitor_; // Key Identifier for dynamic metadata in upstream filter. const std::string UpstreamDynamicDataKey = diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc b/src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc index 5b9fb4a0692..9c8d319a639 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc @@ -59,8 +59,7 @@ class AlpnProxyFilterTest : public testing::Test { config_ = std::make_shared( stat_prefix_, "istio2", "istio/metadata", FilterDirection::Downstream, scope_); - filter_ = std::make_unique(config_, local_info_, - validation_visitor_); + filter_ = std::make_unique(config_, local_info_); filter_->initializeReadFilterCallbacks(read_filter_callbacks_); filter_->initializeWriteFilterCallbacks(write_filter_callbacks_); metadata_node_.set_id("test"); @@ -90,7 +89,6 @@ class AlpnProxyFilterTest : public testing::Test { NiceMock write_filter_callbacks_; Network::MockConnection connection_; NiceMock local_info_; - NiceMock validation_visitor_; NiceMock stream_info_; envoy::api::v2::core::Node metadata_node_; }; diff --git a/src/envoy/tcp/alpn_proxy/config.cc b/src/envoy/tcp/alpn_proxy/config.cc index 03325e99ec0..4fecb65ed8b 100644 --- a/src/envoy/tcp/alpn_proxy/config.cc +++ b/src/envoy/tcp/alpn_proxy/config.cc @@ -38,8 +38,7 @@ Network::FilterFactoryCb createFilterFactoryHelper( return [filter_config, &context](Network::FilterManager& filter_manager) -> void { filter_manager.addFilter( - std::make_shared(filter_config, context.localInfo(), - context.messageValidationVisitor())); + std::make_shared(filter_config, context.localInfo())); }; } } // namespace From a12ca8fc17d649b9ee98d2c62793c9b12e68f1ca Mon Sep 17 00:00:00 2001 From: gargnupur Date: Mon, 30 Sep 2019 11:19:03 -0700 Subject: [PATCH 04/12] Fix build errors --- src/envoy/tcp/alpn_proxy/alpn_proxy.cc | 33 +++++++++++++------------- src/envoy/tcp/alpn_proxy/alpn_proxy.h | 8 +++---- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy.cc b/src/envoy/tcp/alpn_proxy/alpn_proxy.cc index 4e7f01409cd..519da62b9fa 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy.cc +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy.cc @@ -69,21 +69,22 @@ Network::FilterStatus AlpnProxyFilter::onData(Buffer::Instance& data, bool) { // No work needed if connection state is Done or Invalid. return Network::FilterStatus::Continue; case ConnProtocolNotRead: { + // If Alpn protocol is not the expected one, then return. + // Else find and write node metadata. if (read_callbacks_->connection().nextProtocol() != config_->protocol_) { conn_state_ = Invalid; config_->stats().alpn_protocol_not_found_.inc(); return Network::FilterStatus::Continue; - } else { - conn_state_ = WriteMetadata; - config_->stats().alpn_protocol_found_.inc(); } + conn_state_ = WriteMetadata; + config_->stats().alpn_protocol_found_.inc(); } case WriteMetadata: { // TODO(gargnupur): Try to move this just after alpn protocol is // determined and first onData is called in Downstream filter. - if (config_->filter_direction_ == FilterDirection::Downstream) { - writeNodeMetadata(); - } + // If downstream filter, write metadata. + // Otherwise, go ahead and try to read initial header and proxy data. + writeNodeMetadata(); } case ReadingInitialHeader: case NeedMoreDataInitialHeader: { @@ -136,9 +137,7 @@ Network::FilterStatus AlpnProxyFilter::onWrite(Buffer::Instance&, bool) { case WriteMetadata: { // TODO(gargnupur): Try to move this just after alpn protocol is // determined and first onWrite is called in Upstream filter. - if (config_->filter_direction_ == FilterDirection::Upstream) { - writeNodeMetadata(); - } + writeNodeMetadata(); } case ReadingInitialHeader: case ReadingProxyHeader: @@ -157,7 +156,7 @@ void AlpnProxyFilter::writeNodeMetadata() { } std::unique_ptr metadata = - readMetadata(config_->node_metadata_id_); + getMetadata(config_->node_metadata_id_); if (metadata != nullptr) { Envoy::ProtobufWkt::Any metadata_any_value; *metadata_any_value.mutable_type_url() = StructTypeUrl; @@ -167,9 +166,9 @@ void AlpnProxyFilter::writeNodeMetadata() { write_callbacks_->injectWriteDataToFilterChain(*buf, false); if (config_->filter_direction_ == FilterDirection::Downstream) { - writeMetadata(DownstreamDynamicDataKey, *metadata); + setMetadata(DownstreamDynamicDataKey, *metadata); } else { - writeMetadata(UpstreamDynamicDataKey, *metadata); + setMetadata(UpstreamDynamicDataKey, *metadata); } config_->stats().metadata_added_.inc(); } @@ -231,18 +230,18 @@ void AlpnProxyFilter::tryReadProxyData(Buffer::Instance& data) { Envoy::ProtobufWkt::Struct struct_metadata = Envoy::MessageUtil::anyConvert(proxy_data); if (config_->filter_direction_ == FilterDirection::Downstream) { - writeMetadata(UpstreamDynamicDataKey, struct_metadata); + setMetadata(UpstreamDynamicDataKey, struct_metadata); } else { - writeMetadata(DownstreamDynamicDataKey, struct_metadata); + setMetadata(DownstreamDynamicDataKey, struct_metadata); } } -void AlpnProxyFilter::writeMetadata(const std::string key, - const ProtobufWkt::Struct& value) { +void AlpnProxyFilter::setMetadata(const std::string key, + const ProtobufWkt::Struct& value) { read_callbacks_->connection().streamInfo().setDynamicMetadata(key, value); } -std::unique_ptr AlpnProxyFilter::readMetadata( +std::unique_ptr AlpnProxyFilter::getMetadata( const std::string& key) { if (local_info_.node().has_metadata()) { auto metadata_fields = local_info_.node().metadata().fields(); diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy.h b/src/envoy/tcp/alpn_proxy/alpn_proxy.h index 615ea417057..aaac744ae62 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy.h +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy.h @@ -124,11 +124,11 @@ class AlpnProxyFilter : public Network::Filter { // form of google::protobuf::any which encapsulates google::protobuf::struct. void tryReadProxyData(Buffer::Instance& data); - // Helper function to write Dynamic metadata. - void writeMetadata(const std::string key, const ProtobufWkt::Struct& value); + // Helper function to set Dynamic metadata. + void setMetadata(const std::string key, const ProtobufWkt::Struct& value); - // Helper function to read Dynamic metadata. - std::unique_ptr readMetadata( + // Helper function to get Dynamic metadata. + std::unique_ptr getMetadata( const std::string& key); // Config for AlpnProxy filter. From e595d56b118e21a87d9dd82c04731864f736c34b Mon Sep 17 00:00:00 2001 From: gargnupur Date: Tue, 1 Oct 2019 12:13:28 -0700 Subject: [PATCH 05/12] Fixed based on feedback --- src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h b/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h index 0cbcfac01c6..5cf64302768 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h +++ b/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h @@ -17,18 +17,20 @@ #include +#include "envoy/common/platform.h" + namespace Envoy { namespace Tcp { namespace AlpnProxy { // Used with AlpnProxyHeaderProto to be extensible. -struct AlpnProxyInitialHeader { +PACKED_STRUCT(struct AlpnProxyInitialHeader { uint32_t magic; // Magic number in network byte order. Most significant byte // is placed first. static const uint32_t magic_number = 0x23071961; // decimal 587667809 uint32_t data_size; // Size of the data blob in network byte order. Most // significant byte is placed first. -} __attribute__((packed)); +}); } // namespace AlpnProxy } // namespace Tcp From df7a9a794624e8a392e67266e88c7a75a97322ef Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 2 Oct 2019 13:30:45 -0700 Subject: [PATCH 06/12] Renamed AlpnProxy to MetadataExchange --- src/envoy/BUILD | 2 +- .../{alpn_proxy => metadata_exchange}/BUILD | 24 ++++----- .../config.cc | 48 ++++++++--------- .../config.h | 22 ++++---- .../config/BUILD | 8 +-- .../config/metadata_exchange.proto} | 14 ++--- .../metadata_exchange.cc} | 40 +++++++------- .../metadata_exchange.h} | 52 +++++++++---------- .../metadata_exchange_initial_header.cc} | 8 +-- .../metadata_exchange_initial_header.h} | 8 +-- .../metadata_exchange_test.cc} | 40 +++++++------- .../tcp_metadata_exchange_test.go | 34 ++++++------ 12 files changed, 150 insertions(+), 150 deletions(-) rename src/envoy/tcp/{alpn_proxy => metadata_exchange}/BUILD (81%) rename src/envoy/tcp/{alpn_proxy => metadata_exchange}/config.cc (58%) rename src/envoy/tcp/{alpn_proxy => metadata_exchange}/config.h (74%) rename src/envoy/tcp/{alpn_proxy => metadata_exchange}/config/BUILD (82%) rename src/envoy/tcp/{alpn_proxy/config/alpn_proxy.proto => metadata_exchange/config/metadata_exchange.proto} (72%) rename src/envoy/tcp/{alpn_proxy/alpn_proxy.cc => metadata_exchange/metadata_exchange.cc} (85%) rename src/envoy/tcp/{alpn_proxy/alpn_proxy.h => metadata_exchange/metadata_exchange.h} (75%) rename src/envoy/tcp/{alpn_proxy/alpn_proxy_initial_header.cc => metadata_exchange/metadata_exchange_initial_header.cc} (77%) rename src/envoy/tcp/{alpn_proxy/alpn_proxy_initial_header.h => metadata_exchange/metadata_exchange_initial_header.h} (86%) rename src/envoy/tcp/{alpn_proxy/alpn_proxy_test.cc => metadata_exchange/metadata_exchange_test.cc} (79%) diff --git a/src/envoy/BUILD b/src/envoy/BUILD index 9047eb69567..15e99c01936 100644 --- a/src/envoy/BUILD +++ b/src/envoy/BUILD @@ -31,7 +31,7 @@ envoy_cc_binary( "//src/envoy/http/authn:filter_lib", "//src/envoy/http/jwt_auth:http_filter_factory", "//src/envoy/http/mixer:filter_lib", - "//src/envoy/tcp/alpn_proxy:config_lib", + "//src/envoy/tcp/metadata_exchange:config_lib", "//src/envoy/tcp/forward_downstream_sni:config_lib", "//src/envoy/tcp/mixer:filter_lib", "//src/envoy/tcp/sni_verifier:config_lib", diff --git a/src/envoy/tcp/alpn_proxy/BUILD b/src/envoy/tcp/metadata_exchange/BUILD similarity index 81% rename from src/envoy/tcp/alpn_proxy/BUILD rename to src/envoy/tcp/metadata_exchange/BUILD index 010f3f9c873..273551c8896 100644 --- a/src/envoy/tcp/alpn_proxy/BUILD +++ b/src/envoy/tcp/metadata_exchange/BUILD @@ -15,7 +15,7 @@ ################################################################################ # -# Alpn Proxy filter +# Metadata Exchange filter load( "@envoy//bazel:envoy_build_system.bzl", @@ -27,18 +27,18 @@ load( envoy_package() envoy_cc_library( - name = "alpn_proxy", + name = "metadata_exchange", srcs = [ - "alpn_proxy.cc", - "alpn_proxy_initial_header.cc", + "metadata_exchange.cc", + "metadata_exchange_initial_header.cc", ], hdrs = [ - "alpn_proxy.h", - "alpn_proxy_initial_header.h", + "metadata_exchange.h", + "metadata_exchange_initial_header.h", ], repository = "@envoy", deps = [ - "//src/envoy/tcp/alpn_proxy/config:alpn_proxy_cc_proto", + "//src/envoy/tcp/metadata_exchange/config:metadata_exchange_cc_proto", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:endian", "@com_google_absl//absl/strings", @@ -62,8 +62,8 @@ envoy_cc_library( repository = "@envoy", visibility = ["//visibility:public"], deps = [ - ":alpn_proxy", - "//src/envoy/tcp/alpn_proxy/config:alpn_proxy_cc_proto", + ":metadata_exchange", + "//src/envoy/tcp/metadata_exchange/config:metadata_exchange_cc_proto", "//src/envoy/utils:utils_lib", "@envoy//include/envoy/registry", "@envoy//source/extensions/filters/network/common:factory_base_lib", @@ -71,13 +71,13 @@ envoy_cc_library( ) envoy_cc_test( - name = "alpnproxy_test", + name = "metadataexchange_test", srcs = [ - "alpn_proxy_test.cc", + "metadata_exchange_test.cc", ], repository = "@envoy", deps = [ - ":alpn_proxy", + ":metadata_exchange", ":config_lib", "@envoy//source/common/protobuf", "@envoy//test/mocks/local_info:local_info_mocks", diff --git a/src/envoy/tcp/alpn_proxy/config.cc b/src/envoy/tcp/metadata_exchange/config.cc similarity index 58% rename from src/envoy/tcp/alpn_proxy/config.cc rename to src/envoy/tcp/metadata_exchange/config.cc index 4fecb65ed8b..e6ea09f800b 100644 --- a/src/envoy/tcp/alpn_proxy/config.cc +++ b/src/envoy/tcp/metadata_exchange/config.cc @@ -13,95 +13,95 @@ * limitations under the License. */ -#include "src/envoy/tcp/alpn_proxy/config.h" +#include "src/envoy/tcp/metadata_exchange/config.h" #include "envoy/network/connection.h" #include "envoy/registry/registry.h" -#include "src/envoy/tcp/alpn_proxy/alpn_proxy.h" +#include "src/envoy/tcp/metadata_exchange/metadata_exchange.h" #include "src/envoy/utils/config.h" namespace Envoy { namespace Tcp { -namespace AlpnProxy { +namespace MetadataExchange { namespace { -static constexpr char StatPrefix[] = "alpn_proxy."; +static constexpr char StatPrefix[] = "metadata_exchange."; Network::FilterFactoryCb createFilterFactoryHelper( - const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, + const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, Server::Configuration::CommonFactoryContext& context, FilterDirection filter_direction) { ASSERT(!proto_config.protocol().empty()); - AlpnProxyConfigSharedPtr filter_config(std::make_shared( + MetadataExchangeConfigSharedPtr filter_config(std::make_shared( StatPrefix, proto_config.protocol(), proto_config.node_metadata_id(), filter_direction, context.scope())); return [filter_config, &context](Network::FilterManager& filter_manager) -> void { filter_manager.addFilter( - std::make_shared(filter_config, context.localInfo())); + std::make_shared(filter_config, context.localInfo())); }; } } // namespace -Network::FilterFactoryCb AlpnProxyConfigFactory::createFilterFactoryFromProto( +Network::FilterFactoryCb MetadataExchangeConfigFactory::createFilterFactoryFromProto( const Protobuf::Message& config, Server::Configuration::FactoryContext& context) { return createFilterFactory( - dynamic_cast(config), + dynamic_cast(config), context); } -ProtobufTypes::MessagePtr AlpnProxyConfigFactory::createEmptyConfigProto() { +ProtobufTypes::MessagePtr MetadataExchangeConfigFactory::createEmptyConfigProto() { return ProtobufTypes::MessagePtr{ - new envoy::tcp::alpnproxy::config::AlpnProxy}; + new envoy::tcp::metadataexchange::config::MetadataExchange}; } -Network::FilterFactoryCb AlpnProxyConfigFactory::createFilterFactory( - const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, +Network::FilterFactoryCb MetadataExchangeConfigFactory::createFilterFactory( + const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, Server::Configuration::FactoryContext& context) { return createFilterFactoryHelper(proto_config, context, FilterDirection::Downstream); } Network::FilterFactoryCb -AlpnProxyUpstreamConfigFactory::createFilterFactoryFromProto( +MetadataExchangeUpstreamConfigFactory::createFilterFactoryFromProto( const Protobuf::Message& config, Server::Configuration::CommonFactoryContext& context) { return createFilterFactory( - dynamic_cast(config), + dynamic_cast(config), context); } ProtobufTypes::MessagePtr -AlpnProxyUpstreamConfigFactory::createEmptyConfigProto() { +MetadataExchangeUpstreamConfigFactory::createEmptyConfigProto() { return ProtobufTypes::MessagePtr{ - new envoy::tcp::alpnproxy::config::AlpnProxy}; + new envoy::tcp::metadataexchange::config::MetadataExchange}; } -Network::FilterFactoryCb AlpnProxyUpstreamConfigFactory::createFilterFactory( - const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, +Network::FilterFactoryCb MetadataExchangeUpstreamConfigFactory::createFilterFactory( + const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, Server::Configuration::CommonFactoryContext& context) { return createFilterFactoryHelper(proto_config, context, FilterDirection::Upstream); } /** - * Static registration for the Alpn Proxy Downstream filter. @see + * Static registration for the MetadataExchange Downstream filter. @see * RegisterFactory. */ static Registry::RegisterFactory< - AlpnProxyConfigFactory, + MetadataExchangeConfigFactory, Server::Configuration::NamedNetworkFilterConfigFactory> registered_; /** - * Static registration for the Alpn Proxy Upstream filter. @see RegisterFactory. + * Static registration for the MetadataExchange Upstream filter. @see RegisterFactory. */ static Registry::RegisterFactory< - AlpnProxyUpstreamConfigFactory, + MetadataExchangeUpstreamConfigFactory, Server::Configuration::NamedUpstreamNetworkFilterConfigFactory> registered_upstream_; -} // namespace AlpnProxy +} // namespace MetadataExchange } // namespace Tcp } // namespace Envoy diff --git a/src/envoy/tcp/alpn_proxy/config.h b/src/envoy/tcp/metadata_exchange/config.h similarity index 74% rename from src/envoy/tcp/alpn_proxy/config.h rename to src/envoy/tcp/metadata_exchange/config.h index 611aee32333..2b8f3651307 100644 --- a/src/envoy/tcp/alpn_proxy/config.h +++ b/src/envoy/tcp/metadata_exchange/config.h @@ -16,17 +16,17 @@ #pragma once #include "extensions/filters/network/common/factory_base.h" -#include "src/envoy/tcp/alpn_proxy/config/alpn_proxy.pb.h" +#include "src/envoy/tcp/metadata_exchange/config/metadata_exchange.pb.h" namespace Envoy { namespace Tcp { -namespace AlpnProxy { +namespace MetadataExchange { /** - * Config registration for the Alpn Proxy filter. @see + * Config registration for the MetadataExchange filter. @see * NamedNetworkFilterConfigFactory. */ -class AlpnProxyConfigFactory +class MetadataExchangeConfigFactory : public Server::Configuration::NamedNetworkFilterConfigFactory { public: Network::FilterFactoryCb createFilterFactory( @@ -40,19 +40,19 @@ class AlpnProxyConfigFactory ProtobufTypes::MessagePtr createEmptyConfigProto() override; - std::string name() override { return "envoy.filters.network.alpn_proxy"; } + std::string name() override { return "envoy.filters.network.metadata_exchange"; } private: Network::FilterFactoryCb createFilterFactory( - const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, + const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, Server::Configuration::FactoryContext& context); }; /** - * Config registration for the Alpn Proxy Upstream filter. @see + * Config registration for the MetadataExchange Upstream filter. @see * NamedUpstreamNetworkFilterConfigFactory. */ -class AlpnProxyUpstreamConfigFactory +class MetadataExchangeUpstreamConfigFactory : public Server::Configuration::NamedUpstreamNetworkFilterConfigFactory { public: Network::FilterFactoryCb createFilterFactoryFromProto( @@ -62,15 +62,15 @@ class AlpnProxyUpstreamConfigFactory ProtobufTypes::MessagePtr createEmptyConfigProto() override; std::string name() override { - return "envoy.filters.network.upstream.alpn_proxy"; + return "envoy.filters.network.upstream.metadata_exchange"; } private: Network::FilterFactoryCb createFilterFactory( - const envoy::tcp::alpnproxy::config::AlpnProxy& proto_config, + const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, Server::Configuration::CommonFactoryContext& context); }; -} // namespace AlpnProxy +} // namespace MetadataExchange } // namespace Tcp } // namespace Envoy diff --git a/src/envoy/tcp/alpn_proxy/config/BUILD b/src/envoy/tcp/metadata_exchange/config/BUILD similarity index 82% rename from src/envoy/tcp/alpn_proxy/config/BUILD rename to src/envoy/tcp/metadata_exchange/config/BUILD index deef73aa6a7..f9a96022426 100644 --- a/src/envoy/tcp/alpn_proxy/config/BUILD +++ b/src/envoy/tcp/metadata_exchange/config/BUILD @@ -16,12 +16,12 @@ # proto_library( - name = "alpn_proxy_proto", - srcs = ["alpn_proxy.proto"], + name = "metadata_exchange_proto", + srcs = ["metadata_exchange.proto"], ) cc_proto_library( - name = "alpn_proxy_cc_proto", + name = "metadata_exchange_cc_proto", visibility = ["//visibility:public"], - deps = ["alpn_proxy_proto"], + deps = ["metadata_exchange_proto"], ) diff --git a/src/envoy/tcp/alpn_proxy/config/alpn_proxy.proto b/src/envoy/tcp/metadata_exchange/config/metadata_exchange.proto similarity index 72% rename from src/envoy/tcp/alpn_proxy/config/alpn_proxy.proto rename to src/envoy/tcp/metadata_exchange/config/metadata_exchange.proto index a494d40b487..f69c46520e4 100644 --- a/src/envoy/tcp/alpn_proxy/config/alpn_proxy.proto +++ b/src/envoy/tcp/metadata_exchange/config/metadata_exchange.proto @@ -15,16 +15,16 @@ syntax = "proto3"; -package envoy.tcp.alpnproxy.config; +package envoy.tcp.metadataexchange.config; -option java_outer_classname = "AlpnProxyProto"; +option java_outer_classname = "MetadataExchangeProto"; option java_multiple_files = true; -option java_package = "io.envoyproxy.envoy.tcp.alpnproxy.config"; -option go_package = "AlpnProxy"; +option java_package = "io.envoyproxy.envoy.tcp.metadataexchange.config"; +option go_package = "MetadataExchange"; -// [#protodoc-title: AlpnProxy protocol match and data transfer] -// AlpnProxy protocol match and data transfer -message AlpnProxy { +// [#protodoc-title: MetadataExchange protocol match and data transfer] +// MetadataExchange protocol match and data transfer +message MetadataExchange { // Protocol that Alpn should support on the server. // [#comment:TODO(GargNupur): Make it a list.] string protocol = 1; diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy.cc b/src/envoy/tcp/metadata_exchange/metadata_exchange.cc similarity index 85% rename from src/envoy/tcp/alpn_proxy/alpn_proxy.cc rename to src/envoy/tcp/metadata_exchange/metadata_exchange.cc index 519da62b9fa..1b300596b88 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy.cc +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange.cc @@ -22,26 +22,26 @@ #include "common/protobuf/utility.h" #include "envoy/network/connection.h" #include "envoy/stats/scope.h" -#include "src/envoy/tcp/alpn_proxy/alpn_proxy.h" -#include "src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h" +#include "src/envoy/tcp/metadata_exchange/metadata_exchange.h" +#include "src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h" namespace Envoy { namespace Tcp { -namespace AlpnProxy { +namespace MetadataExchange { namespace { std::unique_ptr<::Envoy::Buffer::OwnedImpl> constructProxyHeaderData( const Envoy::ProtobufWkt::Any& proxy_data) { - AlpnProxyInitialHeader initial_header; + MetadataExchangeInitialHeader initial_header; std::string proxy_data_str = proxy_data.SerializeAsString(); // Converting from host to network byte order so that most significant byte is // placed first. - initial_header.magic = absl::ghtonl(AlpnProxyInitialHeader::magic_number); + initial_header.magic = absl::ghtonl(MetadataExchangeInitialHeader::magic_number); initial_header.data_size = absl::ghtonl(proxy_data_str.length()); ::Envoy::Buffer::OwnedImpl initial_header_buffer{ absl::string_view(reinterpret_cast(&initial_header), - sizeof(AlpnProxyInitialHeader))}; + sizeof(MetadataExchangeInitialHeader))}; auto proxy_data_buffer = std::make_unique<::Envoy::Buffer::OwnedImpl>(proxy_data_str); proxy_data_buffer->prepend(initial_header_buffer); @@ -50,7 +50,7 @@ std::unique_ptr<::Envoy::Buffer::OwnedImpl> constructProxyHeaderData( } // namespace -AlpnProxyConfig::AlpnProxyConfig(const std::string& stat_prefix, +MetadataExchangeConfig::MetadataExchangeConfig(const std::string& stat_prefix, const std::string& protocol, const std::string& node_metadata_id, const FilterDirection filter_direction, @@ -62,7 +62,7 @@ AlpnProxyConfig::AlpnProxyConfig(const std::string& stat_prefix, filter_direction_(filter_direction), stats_(generateStats(stat_prefix, scope)) {} -Network::FilterStatus AlpnProxyFilter::onData(Buffer::Instance& data, bool) { +Network::FilterStatus MetadataExchangeFilter::onData(Buffer::Instance& data, bool) { switch (conn_state_) { case Invalid: case Done: @@ -114,11 +114,11 @@ Network::FilterStatus AlpnProxyFilter::onData(Buffer::Instance& data, bool) { return Network::FilterStatus::Continue; } -Network::FilterStatus AlpnProxyFilter::onNewConnection() { +Network::FilterStatus MetadataExchangeFilter::onNewConnection() { return Network::FilterStatus::Continue; } -Network::FilterStatus AlpnProxyFilter::onWrite(Buffer::Instance&, bool) { +Network::FilterStatus MetadataExchangeFilter::onWrite(Buffer::Instance&, bool) { switch (conn_state_) { case Invalid: case Done: @@ -150,7 +150,7 @@ Network::FilterStatus AlpnProxyFilter::onWrite(Buffer::Instance&, bool) { return Network::FilterStatus::Continue; } -void AlpnProxyFilter::writeNodeMetadata() { +void MetadataExchangeFilter::writeNodeMetadata() { if (conn_state_ != WriteMetadata) { return; } @@ -176,12 +176,12 @@ void AlpnProxyFilter::writeNodeMetadata() { conn_state_ = ReadingInitialHeader; } -void AlpnProxyFilter::tryReadInitialProxyHeader(Buffer::Instance& data) { +void MetadataExchangeFilter::tryReadInitialProxyHeader(Buffer::Instance& data) { if (conn_state_ != ReadingInitialHeader && conn_state_ != NeedMoreDataInitialHeader) { return; } - const uint32_t initial_header_length = sizeof(AlpnProxyInitialHeader); + const uint32_t initial_header_length = sizeof(MetadataExchangeInitialHeader); if (data.length() < initial_header_length) { config_->stats().initial_header_not_found_.inc(); // Not enough data to read. Wait for it to come. @@ -191,11 +191,11 @@ void AlpnProxyFilter::tryReadInitialProxyHeader(Buffer::Instance& data) { std::string initial_header_buf = std::string( static_cast(data.linearize(initial_header_length)), initial_header_length); - const AlpnProxyInitialHeader* initial_header = - reinterpret_cast( + const MetadataExchangeInitialHeader* initial_header = + reinterpret_cast( initial_header_buf.c_str()); if (absl::gntohl(initial_header->magic) != - AlpnProxyInitialHeader::magic_number) { + MetadataExchangeInitialHeader::magic_number) { config_->stats().initial_header_not_found_.inc(); conn_state_ = Invalid; return; @@ -206,7 +206,7 @@ void AlpnProxyFilter::tryReadInitialProxyHeader(Buffer::Instance& data) { conn_state_ = ReadingProxyHeader; } -void AlpnProxyFilter::tryReadProxyData(Buffer::Instance& data) { +void MetadataExchangeFilter::tryReadProxyData(Buffer::Instance& data) { if (conn_state_ != ReadingProxyHeader && conn_state_ != NeedMoreDataProxyHeader) { return; @@ -236,12 +236,12 @@ void AlpnProxyFilter::tryReadProxyData(Buffer::Instance& data) { } } -void AlpnProxyFilter::setMetadata(const std::string key, +void MetadataExchangeFilter::setMetadata(const std::string key, const ProtobufWkt::Struct& value) { read_callbacks_->connection().streamInfo().setDynamicMetadata(key, value); } -std::unique_ptr AlpnProxyFilter::getMetadata( +std::unique_ptr MetadataExchangeFilter::getMetadata( const std::string& key) { if (local_info_.node().has_metadata()) { auto metadata_fields = local_info_.node().metadata().fields(); @@ -254,6 +254,6 @@ std::unique_ptr AlpnProxyFilter::getMetadata( return nullptr; } -} // namespace AlpnProxy +} // namespace MetadataExchange } // namespace Tcp } // namespace Envoy \ No newline at end of file diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy.h b/src/envoy/tcp/metadata_exchange/metadata_exchange.h similarity index 75% rename from src/envoy/tcp/alpn_proxy/alpn_proxy.h rename to src/envoy/tcp/metadata_exchange/metadata_exchange.h index aaac744ae62..8790eb946b0 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy.h +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange.h @@ -23,16 +23,16 @@ #include "envoy/runtime/runtime.h" #include "envoy/stats/scope.h" #include "envoy/stats/stats_macros.h" -#include "src/envoy/tcp/alpn_proxy/config/alpn_proxy.pb.h" +#include "src/envoy/tcp/metadata_exchange/config/metadata_exchange.pb.h" namespace Envoy { namespace Tcp { -namespace AlpnProxy { +namespace MetadataExchange { /** - * All AlpnProxy filter stats. @see stats_macros.h + * All MetadataExchange filter stats. @see stats_macros.h */ -#define ALL_ALPN_STATS(COUNTER) \ +#define ALL_METADATA_EXCHANGE_STATS(COUNTER) \ COUNTER(alpn_protocol_not_found) \ COUNTER(alpn_protocol_found) \ COUNTER(initial_header_not_found) \ @@ -40,28 +40,28 @@ namespace AlpnProxy { COUNTER(metadata_added) /** - * Struct definition for all AlpnProxy stats. @see stats_macros.h + * Struct definition for all MetadataExchange stats. @see stats_macros.h */ -struct AlpnProxyStats { - ALL_ALPN_STATS(GENERATE_COUNTER_STRUCT) +struct MetadataExchangeStats { + ALL_METADATA_EXCHANGE_STATS(GENERATE_COUNTER_STRUCT) }; /** - * Direction of the flow of traffic in which this this AlpnProxy filter + * Direction of the flow of traffic in which this this MetadataExchange filter * is placed. */ enum FilterDirection { Downstream, Upstream }; /** - * Configuration for the AlpnProxy filter. + * Configuration for the MetadataExchange filter. */ -class AlpnProxyConfig { +class MetadataExchangeConfig { public: - AlpnProxyConfig(const std::string& stat_prefix, const std::string& protocol, + MetadataExchangeConfig(const std::string& stat_prefix, const std::string& protocol, const std::string& node_metadata_id, const FilterDirection filter_direction, Stats::Scope& scope); - const AlpnProxyStats& stats() { return stats_; } + const MetadataExchangeStats& stats() { return stats_; } // Scope for the stats. Stats::Scope& scope_; @@ -73,23 +73,23 @@ class AlpnProxyConfig { const std::string node_metadata_id_; // Direction of filter. const FilterDirection filter_direction_; - // Stats for Alpn Proxy Filter. - AlpnProxyStats stats_; + // Stats for MetadataExchange Filter. + MetadataExchangeStats stats_; private: - AlpnProxyStats generateStats(const std::string& prefix, Stats::Scope& scope) { - return AlpnProxyStats{ALL_ALPN_STATS(POOL_COUNTER_PREFIX(scope, prefix))}; + MetadataExchangeStats generateStats(const std::string& prefix, Stats::Scope& scope) { + return MetadataExchangeStats{ALL_METADATA_EXCHANGE_STATS(POOL_COUNTER_PREFIX(scope, prefix))}; } }; -using AlpnProxyConfigSharedPtr = std::shared_ptr; +using MetadataExchangeConfigSharedPtr = std::shared_ptr; /** - * A AlpnProxy filter instance. One per connection. + * A MetadataExchange filter instance. One per connection. */ -class AlpnProxyFilter : public Network::Filter { +class MetadataExchangeFilter : public Network::Filter { public: - AlpnProxyFilter(AlpnProxyConfigSharedPtr config, + MetadataExchangeFilter(MetadataExchangeConfigSharedPtr config, const LocalInfo::LocalInfo& local_info) : config_(config), local_info_(local_info), @@ -131,8 +131,8 @@ class AlpnProxyFilter : public Network::Filter { std::unique_ptr getMetadata( const std::string& key); - // Config for AlpnProxy filter. - AlpnProxyConfigSharedPtr config_; + // Config for MetadataExchange filter. + MetadataExchangeConfigSharedPtr config_; // LocalInfo instance. const LocalInfo::LocalInfo& local_info_; // Read callback instance. @@ -144,10 +144,10 @@ class AlpnProxyFilter : public Network::Filter { // Key Identifier for dynamic metadata in upstream filter. const std::string UpstreamDynamicDataKey = - "filters.network.alpn_proxy.upstream"; + "filters.network.metadata_exchange.upstream"; // Key Identifier for dynamic metadata in downstream filter. const std::string DownstreamDynamicDataKey = - "filters.network.alpn_proxy.downstream"; + "filters.network.metadata_exchange.downstream"; // Type url of google::protobug::struct. const std::string StructTypeUrl = "type.googleapis.com/google.protobuf.Struct"; @@ -156,7 +156,7 @@ class AlpnProxyFilter : public Network::Filter { enum { ConnProtocolNotRead, // Connection Protocol has not been read yet WriteMetadata, // Write node metadata - ReadingInitialHeader, // AlpnProxyInitialHeader is being read + ReadingInitialHeader, // MetadataExchangeInitialHeader is being read ReadingProxyHeader, // Proxy Header is being read NeedMoreDataInitialHeader, // Need more data to be read NeedMoreDataProxyHeader, // Need more data to be read @@ -165,6 +165,6 @@ class AlpnProxyFilter : public Network::Filter { } conn_state_; }; -} // namespace AlpnProxy +} // namespace MetadataExchange } // namespace Tcp } // namespace Envoy diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.cc b/src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.cc similarity index 77% rename from src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.cc rename to src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.cc index 0b7d4272249..88fbc785fa6 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.cc +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.cc @@ -13,14 +13,14 @@ * limitations under the License. */ -#include "src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h" +#include "src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h" namespace Envoy { namespace Tcp { -namespace AlpnProxy { +namespace MetadataExchange { -const uint32_t AlpnProxyInitialHeader::magic_number; +const uint32_t MetadataExchangeInitialHeader::magic_number; -} // namespace AlpnProxy +} // namespace MetadataExchange } // namespace Tcp } // namespace Envoy \ No newline at end of file diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h b/src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h similarity index 86% rename from src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h rename to src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h index 5cf64302768..b0b9c3fccbd 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h @@ -21,10 +21,10 @@ namespace Envoy { namespace Tcp { -namespace AlpnProxy { +namespace MetadataExchange { -// Used with AlpnProxyHeaderProto to be extensible. -PACKED_STRUCT(struct AlpnProxyInitialHeader { +// Used with MetadataExchangeHeaderProto to be extensible. +PACKED_STRUCT(struct MetadataExchangeInitialHeader { uint32_t magic; // Magic number in network byte order. Most significant byte // is placed first. static const uint32_t magic_number = 0x23071961; // decimal 587667809 @@ -32,6 +32,6 @@ PACKED_STRUCT(struct AlpnProxyInitialHeader { // significant byte is placed first. }); -} // namespace AlpnProxy +} // namespace MetadataExchange } // namespace Tcp } // namespace Envoy \ No newline at end of file diff --git a/src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc b/src/envoy/tcp/metadata_exchange/metadata_exchange_test.cc similarity index 79% rename from src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc rename to src/envoy/tcp/metadata_exchange/metadata_exchange_test.cc index 9c8d319a639..101a20eb1fb 100644 --- a/src/envoy/tcp/alpn_proxy/alpn_proxy_test.cc +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange_test.cc @@ -13,13 +13,13 @@ * limitations under the License. */ -#include "src/envoy/tcp/alpn_proxy/alpn_proxy.h" +#include "src/envoy/tcp/metadata_exchange/metadata_exchange.h" #include "common/buffer/buffer_impl.h" #include "common/protobuf/protobuf.h" #include "gmock/gmock.h" #include "google/protobuf/util/message_differencer.h" #include "gtest/gtest.h" -#include "src/envoy/tcp/alpn_proxy/alpn_proxy_initial_header.h" +#include "src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h" #include "test/mocks/local_info/mocks.h" #include "test/mocks/network/mocks.h" #include "test/mocks/protobuf/mocks.h" @@ -31,35 +31,35 @@ using testing::ReturnRef; namespace Envoy { namespace Tcp { -namespace AlpnProxy { +namespace MetadataExchange { namespace { MATCHER_P(MapEq, rhs, "") { return MessageDifferencer::Equals(arg, rhs); } void ConstructProxyHeaderData(::Envoy::Buffer::OwnedImpl& serialized_header, Envoy::ProtobufWkt::Any& proxy_header, - AlpnProxyInitialHeader* initial_header) { + MetadataExchangeInitialHeader* initial_header) { std::string serialized_proxy_header = proxy_header.SerializeAsString(); - memset(initial_header, 0, sizeof(AlpnProxyInitialHeader)); - initial_header->magic = absl::ghtonl(AlpnProxyInitialHeader::magic_number); + memset(initial_header, 0, sizeof(MetadataExchangeInitialHeader)); + initial_header->magic = absl::ghtonl(MetadataExchangeInitialHeader::magic_number); initial_header->data_size = absl::ghtonl(serialized_proxy_header.length()); serialized_header.add(::Envoy::Buffer::OwnedImpl{ absl::string_view(reinterpret_cast(initial_header), - sizeof(AlpnProxyInitialHeader))}); + sizeof(MetadataExchangeInitialHeader))}); serialized_header.add(::Envoy::Buffer::OwnedImpl{serialized_proxy_header}); } } // namespace -class AlpnProxyFilterTest : public testing::Test { +class MetadataExchangeFilterTest : public testing::Test { public: - AlpnProxyFilterTest() { ENVOY_LOG_MISC(info, "test"); } + MetadataExchangeFilterTest() { ENVOY_LOG_MISC(info, "test"); } void initialize() { - config_ = std::make_shared( + config_ = std::make_shared( stat_prefix_, "istio2", "istio/metadata", FilterDirection::Downstream, scope_); - filter_ = std::make_unique(config_, local_info_); + filter_ = std::make_unique(config_, local_info_); filter_->initializeReadFilterCallbacks(read_filter_callbacks_); filter_->initializeWriteFilterCallbacks(write_filter_callbacks_); metadata_node_.set_id("test"); @@ -81,10 +81,10 @@ class AlpnProxyFilterTest : public testing::Test { Envoy::ProtobufWkt::Struct details_value_; Envoy::ProtobufWkt::Struct productpage_value_; - AlpnProxyConfigSharedPtr config_; - std::unique_ptr filter_; + MetadataExchangeConfigSharedPtr config_; + std::unique_ptr filter_; Stats::IsolatedStoreImpl scope_; - std::string stat_prefix_{"test.alpnmetadata"}; + std::string stat_prefix_{"test.metadataexchange"}; NiceMock read_filter_callbacks_; NiceMock write_filter_callbacks_; Network::MockConnection connection_; @@ -93,7 +93,7 @@ class AlpnProxyFilterTest : public testing::Test { envoy::api::v2::core::Node metadata_node_; }; -TEST_F(AlpnProxyFilterTest, AlpnProxyFound) { +TEST_F(MetadataExchangeFilterTest, MetadataExchangeFound) { initialize(); initializeStructValues(); @@ -104,14 +104,14 @@ TEST_F(AlpnProxyFilterTest, AlpnProxyFound) { EXPECT_CALL(read_filter_callbacks_.connection_, nextProtocol()) .WillRepeatedly(Return("istio2")); EXPECT_CALL(stream_info_, - setDynamicMetadata("filters.network.alpn_proxy.downstream", + setDynamicMetadata("filters.network.metadata_exchange.downstream", MapEq(details_value_))); EXPECT_CALL(stream_info_, - setDynamicMetadata("filters.network.alpn_proxy.upstream", + setDynamicMetadata("filters.network.metadata_exchange.upstream", MapEq(productpage_value_))); ::Envoy::Buffer::OwnedImpl data; - AlpnProxyInitialHeader initial_header; + MetadataExchangeInitialHeader initial_header; Envoy::ProtobufWkt::Any productpage_any_value; *productpage_any_value.mutable_type_url() = "type.googleapis.com/google.protobuf.Struct"; @@ -130,7 +130,7 @@ TEST_F(AlpnProxyFilterTest, AlpnProxyFound) { EXPECT_EQ(1UL, config_->stats().alpn_protocol_found_.value()); } -TEST_F(AlpnProxyFilterTest, AlpnProxyNotFound) { +TEST_F(MetadataExchangeFilterTest, MetadataExchangeNotFound) { initialize(); EXPECT_CALL(read_filter_callbacks_.connection_, nextProtocol()) @@ -142,6 +142,6 @@ TEST_F(AlpnProxyFilterTest, AlpnProxyNotFound) { EXPECT_EQ(1UL, config_->stats().alpn_protocol_not_found_.value()); } -} // namespace AlpnProxy +} // namespace MetadataExchange } // namespace Tcp } // namespace Envoy diff --git a/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go b/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go index 38ec95a1287..47f57efc227 100644 --- a/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go +++ b/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go @@ -27,18 +27,18 @@ import ( "istio.io/proxy/test/envoye2e/env" ) -const alpnIstioConfigFilter = ` -- name: envoy.filters.network.alpn_proxy +const metadataExchangeIstioConfigFilter = ` +- name: envoy.filters.network.metadata_exchange config: protocol: istio2 node_metadata_id: istio.io/metadata ` -const alpnIstioUpstreamConfigFilterChain = ` +const metadataExchangeIstioUpstreamConfigFilterChain = ` filters: -- name: envoy.filters.network.upstream.alpn_proxy +- name: envoy.filters.network.upstream.metadata_exchange typed_config: - "@type": type.googleapis.com/envoy.tcp.alpnproxy.config.AlpnProxy + "@type": type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange protocol: istio2 node_metadata_id: istio.io/metadata ` @@ -90,20 +90,20 @@ const serverNodeMetadata = ` // Stats in Client Envoy proxy. var expectedClientStats = map[string]int{ - "cluster.client.alpn_proxy.alpn_protocol_found": 1, - "cluster.client.alpn_proxy.alpn_protocol_not_found": 0, - "cluster.client.alpn_proxy.initial_header_not_found": 0, - "cluster.client.alpn_proxy.header_not_found": 0, - "cluster.client.alpn_proxy.metadata_added": 1, + "cluster.client.metadata_exchange.alpn_protocol_found": 1, + "cluster.client.metadata_exchange.alpn_protocol_not_found": 0, + "cluster.client.metadata_exchange.initial_header_not_found": 0, + "cluster.client.metadata_exchange.header_not_found": 0, + "cluster.client.metadata_exchange.metadata_added": 1, } // Stats in Server Envoy proxy. var expectedServerStats = map[string]int{ - "alpn_proxy.alpn_protocol_found": 1, - "alpn_proxy.alpn_protocol_not_found": 0, - "alpn_proxy.initial_header_not_found": 0, - "alpn_proxy.header_not_found": 0, - "alpn_proxy.metadata_added": 1, + "metadata_exchange.alpn_protocol_found": 1, + "metadata_exchange.alpn_protocol_not_found": 0, + "metadata_exchange.initial_header_not_found": 0, + "metadata_exchange.header_not_found": 0, + "metadata_exchange.metadata_added": 1, } func TestTcpMetadataExchange(t *testing.T) { @@ -112,8 +112,8 @@ func TestTcpMetadataExchange(t *testing.T) { s.SetStartTcpBackend(true) s.SetTlsContext(tlsContext) s.SetClusterTlsContext(clusterTlsContext) - s.SetFiltersBeforeEnvoyRouterInClientToApp(alpnIstioConfigFilter) - s.SetUpstreamFiltersInClient(alpnIstioUpstreamConfigFilterChain) + s.SetFiltersBeforeEnvoyRouterInClientToApp(metadataExchangeIstioConfigFilter) + s.SetUpstreamFiltersInClient(metadataExchangeIstioUpstreamConfigFilterChain) s.SetEnableTls(true) s.SetClientNodeMetadata(clientNodeMetadata) s.SetServerNodeMetadata(serverNodeMetadata) From b2e6fdde09360d98740326d6e4872caf7467cc8b Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 2 Oct 2019 13:44:44 -0700 Subject: [PATCH 07/12] Fix linting errors --- src/envoy/BUILD | 2 +- src/envoy/tcp/metadata_exchange/BUILD | 2 +- src/envoy/tcp/metadata_exchange/config.cc | 31 ++++++++++++------- src/envoy/tcp/metadata_exchange/config.h | 10 ++++-- .../metadata_exchange/metadata_exchange.cc | 21 +++++++------ .../tcp/metadata_exchange/metadata_exchange.h | 26 +++++++++------- .../metadata_exchange_test.cc | 3 +- 7 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/envoy/BUILD b/src/envoy/BUILD index 15e99c01936..157daef58b5 100644 --- a/src/envoy/BUILD +++ b/src/envoy/BUILD @@ -31,8 +31,8 @@ envoy_cc_binary( "//src/envoy/http/authn:filter_lib", "//src/envoy/http/jwt_auth:http_filter_factory", "//src/envoy/http/mixer:filter_lib", - "//src/envoy/tcp/metadata_exchange:config_lib", "//src/envoy/tcp/forward_downstream_sni:config_lib", + "//src/envoy/tcp/metadata_exchange:config_lib", "//src/envoy/tcp/mixer:filter_lib", "//src/envoy/tcp/sni_verifier:config_lib", "//src/envoy/tcp/tcp_cluster_rewrite:config_lib", diff --git a/src/envoy/tcp/metadata_exchange/BUILD b/src/envoy/tcp/metadata_exchange/BUILD index 273551c8896..347e61095dc 100644 --- a/src/envoy/tcp/metadata_exchange/BUILD +++ b/src/envoy/tcp/metadata_exchange/BUILD @@ -77,8 +77,8 @@ envoy_cc_test( ], repository = "@envoy", deps = [ - ":metadata_exchange", ":config_lib", + ":metadata_exchange", "@envoy//source/common/protobuf", "@envoy//test/mocks/local_info:local_info_mocks", "@envoy//test/mocks/network:network_mocks", diff --git a/src/envoy/tcp/metadata_exchange/config.cc b/src/envoy/tcp/metadata_exchange/config.cc index e6ea09f800b..de18672f395 100644 --- a/src/envoy/tcp/metadata_exchange/config.cc +++ b/src/envoy/tcp/metadata_exchange/config.cc @@ -32,26 +32,31 @@ Network::FilterFactoryCb createFilterFactoryHelper( FilterDirection filter_direction) { ASSERT(!proto_config.protocol().empty()); - MetadataExchangeConfigSharedPtr filter_config(std::make_shared( - StatPrefix, proto_config.protocol(), proto_config.node_metadata_id(), - filter_direction, context.scope())); + MetadataExchangeConfigSharedPtr filter_config( + std::make_shared( + StatPrefix, proto_config.protocol(), proto_config.node_metadata_id(), + filter_direction, context.scope())); return [filter_config, &context](Network::FilterManager& filter_manager) -> void { - filter_manager.addFilter( - std::make_shared(filter_config, context.localInfo())); + filter_manager.addFilter(std::make_shared( + filter_config, context.localInfo())); }; } } // namespace -Network::FilterFactoryCb MetadataExchangeConfigFactory::createFilterFactoryFromProto( +Network::FilterFactoryCb +MetadataExchangeConfigFactory::createFilterFactoryFromProto( const Protobuf::Message& config, Server::Configuration::FactoryContext& context) { return createFilterFactory( - dynamic_cast(config), + dynamic_cast< + const envoy::tcp::metadataexchange::config::MetadataExchange&>( + config), context); } -ProtobufTypes::MessagePtr MetadataExchangeConfigFactory::createEmptyConfigProto() { +ProtobufTypes::MessagePtr +MetadataExchangeConfigFactory::createEmptyConfigProto() { return ProtobufTypes::MessagePtr{ new envoy::tcp::metadataexchange::config::MetadataExchange}; } @@ -68,7 +73,9 @@ MetadataExchangeUpstreamConfigFactory::createFilterFactoryFromProto( const Protobuf::Message& config, Server::Configuration::CommonFactoryContext& context) { return createFilterFactory( - dynamic_cast(config), + dynamic_cast< + const envoy::tcp::metadataexchange::config::MetadataExchange&>( + config), context); } @@ -78,7 +85,8 @@ MetadataExchangeUpstreamConfigFactory::createEmptyConfigProto() { new envoy::tcp::metadataexchange::config::MetadataExchange}; } -Network::FilterFactoryCb MetadataExchangeUpstreamConfigFactory::createFilterFactory( +Network::FilterFactoryCb +MetadataExchangeUpstreamConfigFactory::createFilterFactory( const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, Server::Configuration::CommonFactoryContext& context) { return createFilterFactoryHelper(proto_config, context, @@ -95,7 +103,8 @@ static Registry::RegisterFactory< registered_; /** - * Static registration for the MetadataExchange Upstream filter. @see RegisterFactory. + * Static registration for the MetadataExchange Upstream filter. @see + * RegisterFactory. */ static Registry::RegisterFactory< MetadataExchangeUpstreamConfigFactory, diff --git a/src/envoy/tcp/metadata_exchange/config.h b/src/envoy/tcp/metadata_exchange/config.h index 2b8f3651307..10871551e12 100644 --- a/src/envoy/tcp/metadata_exchange/config.h +++ b/src/envoy/tcp/metadata_exchange/config.h @@ -40,11 +40,14 @@ class MetadataExchangeConfigFactory ProtobufTypes::MessagePtr createEmptyConfigProto() override; - std::string name() override { return "envoy.filters.network.metadata_exchange"; } + std::string name() override { + return "envoy.filters.network.metadata_exchange"; + } private: Network::FilterFactoryCb createFilterFactory( - const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, + const envoy::tcp::metadataexchange::config::MetadataExchange& + proto_config, Server::Configuration::FactoryContext& context); }; @@ -67,7 +70,8 @@ class MetadataExchangeUpstreamConfigFactory private: Network::FilterFactoryCb createFilterFactory( - const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, + const envoy::tcp::metadataexchange::config::MetadataExchange& + proto_config, Server::Configuration::CommonFactoryContext& context); }; diff --git a/src/envoy/tcp/metadata_exchange/metadata_exchange.cc b/src/envoy/tcp/metadata_exchange/metadata_exchange.cc index 1b300596b88..71414766cf1 100644 --- a/src/envoy/tcp/metadata_exchange/metadata_exchange.cc +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange.cc @@ -36,7 +36,8 @@ std::unique_ptr<::Envoy::Buffer::OwnedImpl> constructProxyHeaderData( std::string proxy_data_str = proxy_data.SerializeAsString(); // Converting from host to network byte order so that most significant byte is // placed first. - initial_header.magic = absl::ghtonl(MetadataExchangeInitialHeader::magic_number); + initial_header.magic = + absl::ghtonl(MetadataExchangeInitialHeader::magic_number); initial_header.data_size = absl::ghtonl(proxy_data_str.length()); ::Envoy::Buffer::OwnedImpl initial_header_buffer{ @@ -50,11 +51,10 @@ std::unique_ptr<::Envoy::Buffer::OwnedImpl> constructProxyHeaderData( } // namespace -MetadataExchangeConfig::MetadataExchangeConfig(const std::string& stat_prefix, - const std::string& protocol, - const std::string& node_metadata_id, - const FilterDirection filter_direction, - Stats::Scope& scope) +MetadataExchangeConfig::MetadataExchangeConfig( + const std::string& stat_prefix, const std::string& protocol, + const std::string& node_metadata_id, const FilterDirection filter_direction, + Stats::Scope& scope) : scope_(scope), stat_prefix_(stat_prefix), protocol_(protocol), @@ -62,7 +62,8 @@ MetadataExchangeConfig::MetadataExchangeConfig(const std::string& stat_prefix, filter_direction_(filter_direction), stats_(generateStats(stat_prefix, scope)) {} -Network::FilterStatus MetadataExchangeFilter::onData(Buffer::Instance& data, bool) { +Network::FilterStatus MetadataExchangeFilter::onData(Buffer::Instance& data, + bool) { switch (conn_state_) { case Invalid: case Done: @@ -237,12 +238,12 @@ void MetadataExchangeFilter::tryReadProxyData(Buffer::Instance& data) { } void MetadataExchangeFilter::setMetadata(const std::string key, - const ProtobufWkt::Struct& value) { + const ProtobufWkt::Struct& value) { read_callbacks_->connection().streamInfo().setDynamicMetadata(key, value); } -std::unique_ptr MetadataExchangeFilter::getMetadata( - const std::string& key) { +std::unique_ptr +MetadataExchangeFilter::getMetadata(const std::string& key) { if (local_info_.node().has_metadata()) { auto metadata_fields = local_info_.node().metadata().fields(); auto node_metadata = metadata_fields.find(key); diff --git a/src/envoy/tcp/metadata_exchange/metadata_exchange.h b/src/envoy/tcp/metadata_exchange/metadata_exchange.h index 8790eb946b0..4c1d87828a9 100644 --- a/src/envoy/tcp/metadata_exchange/metadata_exchange.h +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange.h @@ -32,11 +32,11 @@ namespace MetadataExchange { /** * All MetadataExchange filter stats. @see stats_macros.h */ -#define ALL_METADATA_EXCHANGE_STATS(COUNTER) \ - COUNTER(alpn_protocol_not_found) \ - COUNTER(alpn_protocol_found) \ - COUNTER(initial_header_not_found) \ - COUNTER(header_not_found) \ +#define ALL_METADATA_EXCHANGE_STATS(COUNTER) \ + COUNTER(alpn_protocol_not_found) \ + COUNTER(alpn_protocol_found) \ + COUNTER(initial_header_not_found) \ + COUNTER(header_not_found) \ COUNTER(metadata_added) /** @@ -57,9 +57,11 @@ enum FilterDirection { Downstream, Upstream }; */ class MetadataExchangeConfig { public: - MetadataExchangeConfig(const std::string& stat_prefix, const std::string& protocol, - const std::string& node_metadata_id, - const FilterDirection filter_direction, Stats::Scope& scope); + MetadataExchangeConfig(const std::string& stat_prefix, + const std::string& protocol, + const std::string& node_metadata_id, + const FilterDirection filter_direction, + Stats::Scope& scope); const MetadataExchangeStats& stats() { return stats_; } @@ -77,8 +79,10 @@ class MetadataExchangeConfig { MetadataExchangeStats stats_; private: - MetadataExchangeStats generateStats(const std::string& prefix, Stats::Scope& scope) { - return MetadataExchangeStats{ALL_METADATA_EXCHANGE_STATS(POOL_COUNTER_PREFIX(scope, prefix))}; + MetadataExchangeStats generateStats(const std::string& prefix, + Stats::Scope& scope) { + return MetadataExchangeStats{ + ALL_METADATA_EXCHANGE_STATS(POOL_COUNTER_PREFIX(scope, prefix))}; } }; @@ -90,7 +94,7 @@ using MetadataExchangeConfigSharedPtr = std::shared_ptr; class MetadataExchangeFilter : public Network::Filter { public: MetadataExchangeFilter(MetadataExchangeConfigSharedPtr config, - const LocalInfo::LocalInfo& local_info) + const LocalInfo::LocalInfo& local_info) : config_(config), local_info_(local_info), conn_state_(ConnProtocolNotRead) {} diff --git a/src/envoy/tcp/metadata_exchange/metadata_exchange_test.cc b/src/envoy/tcp/metadata_exchange/metadata_exchange_test.cc index 101a20eb1fb..5d617951805 100644 --- a/src/envoy/tcp/metadata_exchange/metadata_exchange_test.cc +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange_test.cc @@ -41,7 +41,8 @@ void ConstructProxyHeaderData(::Envoy::Buffer::OwnedImpl& serialized_header, MetadataExchangeInitialHeader* initial_header) { std::string serialized_proxy_header = proxy_header.SerializeAsString(); memset(initial_header, 0, sizeof(MetadataExchangeInitialHeader)); - initial_header->magic = absl::ghtonl(MetadataExchangeInitialHeader::magic_number); + initial_header->magic = + absl::ghtonl(MetadataExchangeInitialHeader::magic_number); initial_header->data_size = absl::ghtonl(serialized_proxy_header.length()); serialized_header.add(::Envoy::Buffer::OwnedImpl{ absl::string_view(reinterpret_cast(initial_header), From d9c582ff28ff5e46f059ed2faa996b413eca5e0c Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 2 Oct 2019 16:03:24 -0700 Subject: [PATCH 08/12] Update magic number --- .../tcp/metadata_exchange/metadata_exchange_initial_header.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h b/src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h index b0b9c3fccbd..cdf72cea93a 100644 --- a/src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h @@ -27,7 +27,7 @@ namespace MetadataExchange { PACKED_STRUCT(struct MetadataExchangeInitialHeader { uint32_t magic; // Magic number in network byte order. Most significant byte // is placed first. - static const uint32_t magic_number = 0x23071961; // decimal 587667809 + static const uint32_t magic_number = 0x3D230467; // decimal 1025705063 uint32_t data_size; // Size of the data blob in network byte order. Most // significant byte is placed first. }); From 78db2ae74b34fd16f83a8712cb1644371553f750 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Fri, 4 Oct 2019 14:53:03 -0700 Subject: [PATCH 09/12] Add tls and http inspectors in tcp envoy config This validates that having these inspectors doesnt affect Metadata Exchange filter --- test/envoye2e/env/tcp_envoy_conf.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/envoye2e/env/tcp_envoy_conf.go b/test/envoye2e/env/tcp_envoy_conf.go index fe841965fda..d412fa2f36a 100644 --- a/test/envoye2e/env/tcp_envoy_conf.go +++ b/test/envoye2e/env/tcp_envoy_conf.go @@ -51,6 +51,8 @@ static_resources: listener_filters: - name: "envoy.listener.tls_inspector" typed_config: {} + - name: "envoy.listener.http_inspector" + typed_config: {} filter_chains: - filters: {{.FiltersBeforeEnvoyRouterInAppToClient | indent 6 }} @@ -99,6 +101,11 @@ static_resources: socket_address: address: 127.0.0.1 port_value: {{.Ports.ClientToServerProxyPort}} + listener_filters: + - name: "envoy.listener.tls_inspector" + typed_config: {} + - name: "envoy.listener.http_inspector" + typed_config: {} filter_chains: - filters: {{.FiltersBeforeEnvoyRouterInClientToApp | indent 6 }} From 6bdd5c9aa95e9aec6212a944bc37fc9761ecffd3 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Mon, 7 Oct 2019 14:14:52 -0700 Subject: [PATCH 10/12] Fixed based on feedback --- src/envoy/tcp/metadata_exchange/config.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/envoy/tcp/metadata_exchange/config.cc b/src/envoy/tcp/metadata_exchange/config.cc index de18672f395..39af69b3fd4 100644 --- a/src/envoy/tcp/metadata_exchange/config.cc +++ b/src/envoy/tcp/metadata_exchange/config.cc @@ -56,10 +56,9 @@ MetadataExchangeConfigFactory::createFilterFactoryFromProto( } ProtobufTypes::MessagePtr -MetadataExchangeConfigFactory::createEmptyConfigProto() { - return ProtobufTypes::MessagePtr{ - new envoy::tcp::metadataexchange::config::MetadataExchange}; -} +MetadataExchangeConfigFactory::createEmptyConfigProto(){return std::make_unique< + envoy::tcp::metadataexchange::config::MetadataExchange>()}; +} // namespace MetadataExchange Network::FilterFactoryCb MetadataExchangeConfigFactory::createFilterFactory( const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, @@ -111,6 +110,6 @@ static Registry::RegisterFactory< Server::Configuration::NamedUpstreamNetworkFilterConfigFactory> registered_upstream_; -} // namespace MetadataExchange } // namespace Tcp } // namespace Envoy +} // namespace Envoy From f15cb06a27e197b6ffc5f8dec53ea47b85bcc7d1 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Mon, 7 Oct 2019 14:22:16 -0700 Subject: [PATCH 11/12] Fixed based on feedback --- src/envoy/tcp/metadata_exchange/config.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/envoy/tcp/metadata_exchange/config.cc b/src/envoy/tcp/metadata_exchange/config.cc index 39af69b3fd4..4f7720496a2 100644 --- a/src/envoy/tcp/metadata_exchange/config.cc +++ b/src/envoy/tcp/metadata_exchange/config.cc @@ -56,9 +56,9 @@ MetadataExchangeConfigFactory::createFilterFactoryFromProto( } ProtobufTypes::MessagePtr -MetadataExchangeConfigFactory::createEmptyConfigProto(){return std::make_unique< - envoy::tcp::metadataexchange::config::MetadataExchange>()}; -} // namespace MetadataExchange +MetadataExchangeConfigFactory::createEmptyConfigProto() { + return std::make_unique(); +} Network::FilterFactoryCb MetadataExchangeConfigFactory::createFilterFactory( const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config, @@ -80,8 +80,8 @@ MetadataExchangeUpstreamConfigFactory::createFilterFactoryFromProto( ProtobufTypes::MessagePtr MetadataExchangeUpstreamConfigFactory::createEmptyConfigProto() { - return ProtobufTypes::MessagePtr{ - new envoy::tcp::metadataexchange::config::MetadataExchange}; + return std::make_unique(); + ; } Network::FilterFactoryCb @@ -110,6 +110,6 @@ static Registry::RegisterFactory< Server::Configuration::NamedUpstreamNetworkFilterConfigFactory> registered_upstream_; +} // namespace MetadataExchange } // namespace Tcp } // namespace Envoy -} // namespace Envoy From 053226360e26cbef0947a61ad1072d0ad7781538 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Mon, 7 Oct 2019 15:29:41 -0700 Subject: [PATCH 12/12] Fixed based on feedback --- src/envoy/tcp/metadata_exchange/config.cc | 7 ++++--- src/envoy/tcp/metadata_exchange/metadata_exchange.cc | 12 ++++-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/envoy/tcp/metadata_exchange/config.cc b/src/envoy/tcp/metadata_exchange/config.cc index 4f7720496a2..e3926910fda 100644 --- a/src/envoy/tcp/metadata_exchange/config.cc +++ b/src/envoy/tcp/metadata_exchange/config.cc @@ -57,7 +57,8 @@ MetadataExchangeConfigFactory::createFilterFactoryFromProto( ProtobufTypes::MessagePtr MetadataExchangeConfigFactory::createEmptyConfigProto() { - return std::make_unique(); + return std::make_unique< + envoy::tcp::metadataexchange::config::MetadataExchange>(); } Network::FilterFactoryCb MetadataExchangeConfigFactory::createFilterFactory( @@ -80,8 +81,8 @@ MetadataExchangeUpstreamConfigFactory::createFilterFactoryFromProto( ProtobufTypes::MessagePtr MetadataExchangeUpstreamConfigFactory::createEmptyConfigProto() { - return std::make_unique(); - ; + return std::make_unique< + envoy::tcp::metadataexchange::config::MetadataExchange>(); } Network::FilterFactoryCb diff --git a/src/envoy/tcp/metadata_exchange/metadata_exchange.cc b/src/envoy/tcp/metadata_exchange/metadata_exchange.cc index 71414766cf1..983c8a56a5b 100644 --- a/src/envoy/tcp/metadata_exchange/metadata_exchange.cc +++ b/src/envoy/tcp/metadata_exchange/metadata_exchange.cc @@ -189,19 +189,15 @@ void MetadataExchangeFilter::tryReadInitialProxyHeader(Buffer::Instance& data) { conn_state_ = NeedMoreDataInitialHeader; return; } - std::string initial_header_buf = std::string( - static_cast(data.linearize(initial_header_length)), - initial_header_length); - const MetadataExchangeInitialHeader* initial_header = - reinterpret_cast( - initial_header_buf.c_str()); - if (absl::gntohl(initial_header->magic) != + MetadataExchangeInitialHeader initial_header; + data.copyOut(0, initial_header_length, &initial_header); + if (absl::gntohl(initial_header.magic) != MetadataExchangeInitialHeader::magic_number) { config_->stats().initial_header_not_found_.inc(); conn_state_ = Invalid; return; } - proxy_data_length_ = absl::gntohl(initial_header->data_size); + proxy_data_length_ = absl::gntohl(initial_header.data_size); // Drain the initial header length bytes read. data.drain(initial_header_length); conn_state_ = ReadingProxyHeader;