Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/envoy/api/v2/route/route_components.proto
Original file line number Diff line number Diff line change
Expand Up @@ -675,8 +675,8 @@ message RouteAction {

message FilterState {
// The name of the Object in the per-request filterState, which is an
// Envoy::Http::Hashable object. If there is no data associated with the key,
// or the stored object is not Envoy::Http::Hashable, no hash will be produced.
// Envoy::Hashable object. If there is no data associated with the key,
Comment thread
mergeconflict marked this conversation as resolved.
// or the stored object is not Envoy::Hashable, no hash will be produced.
string key = 1 [(validate.rules).string = {min_bytes: 1}];
}

Expand Down
4 changes: 2 additions & 2 deletions api/envoy/config/route/v3/route_components.proto
Original file line number Diff line number Diff line change
Expand Up @@ -752,8 +752,8 @@ message RouteAction {
"envoy.api.v2.route.RouteAction.HashPolicy.FilterState";

// The name of the Object in the per-request filterState, which is an
// Envoy::Http::Hashable object. If there is no data associated with the key,
// or the stored object is not Envoy::Http::Hashable, no hash will be produced.
// Envoy::Hashable object. If there is no data associated with the key,
// or the stored object is not Envoy::Hashable, no hash will be produced.
string key = 1 [(validate.rules).string = {min_len: 1}];
}

Expand Down
11 changes: 11 additions & 0 deletions api/envoy/type/v3/hash_policy.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,20 @@ message HashPolicy {
option (udpa.annotations.versioning).previous_message_type = "envoy.type.HashPolicy.SourceIp";
}

// An Object in the :ref:`filterState <arch_overview_data_sharing_between_filters>` will be used
// to compute the hash used by hash-based load balancing algorithms.
message FilterState {
// The name of the Object in the filterState, which is an Envoy::Hashable object. If there is no
// data associated with the key, or the stored object is not Envoy::Hashable, no hash will be
// produced.
string key = 1 [(validate.rules).string = {min_len: 1}];
}

oneof policy_specifier {
option (validate.required) = true;

SourceIp source_ip = 1;

FilterState filter_state = 2;
}
}
1 change: 1 addition & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ New Features
* http: added support for :ref:`retriable health check status codes <envoy_v3_api_field_config.core.v3.HealthCheck.HttpHealthCheck.retriable_statuses>`.
* listener: added API for extensions to access :ref:`typed_filter_metadata <envoy_v3_api_field_config.core.v3.Metadata.typed_filter_metadata>` configured in the listener's :ref:`metadata <envoy_v3_api_field_config.listener.v3.Listener.metadata>` field.
* oauth filter: added :ref:`cookie_names <envoy_v3_api_field_extensions.filters.http.oauth2.v3.OAuth2Credentials.cookie_names>` to allow overriding (default) cookie names (``BearerToken``, ``OauthHMAC``, and ``OauthExpires``) set by the filter.
* tcp: added a :ref:`FilterState <envoy_v3_api_msg_type.v3.HashPolicy.FilterState>` :ref:`hash policy <envoy_v3_api_msg_type.v3.HashPolicy>`, used by :ref:`TCP proxy <envoy_v3_api_field_extensions.filters.network.tcp_proxy.v3.TcpProxy.hash_policy>` to allow hashing load balancer algorithms to hash on objects in filter state.
* thrift_proxy: add upstream response zone metrics in the form ``cluster.cluster_name.zone.local_zone.upstream_zone.thrift.upstream_resp_success``.
* thrift_proxy: add upstream metrics to show decoding errors and whether exception is from local or remote, e.g. ``cluster.cluster_name.thrift.upstream_resp_exception_remote``.
* thrift_proxy: add host level success/error metrics where success is a reply of type success and error is any other response to a call.
Expand Down
5 changes: 5 additions & 0 deletions envoy/common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,8 @@ envoy_cc_library(
name = "scope_tracker_interface",
hdrs = ["scope_tracker.h"],
)

envoy_cc_library(
name = "hashable_interface",
hdrs = ["hashable.h"],
)
25 changes: 25 additions & 0 deletions envoy/common/hashable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "envoy/common/pure.h"

#include "absl/types/optional.h"

namespace Envoy {

/**
* Interface for hashable types used in heterogeneous contexts (see, for example, usage in
* FilterStateHashMethod).
*/
class Hashable {
public:
virtual ~Hashable() = default;

/**
* Request the 64-bit hash for this object.
* @return absl::optional<uint64_t> the hash value, or absl::nullopt if a hash could not be
* produced for this instance.
*/
virtual absl::optional<uint64_t> hash() const PURE;
};

} // namespace Envoy
6 changes: 0 additions & 6 deletions envoy/http/hash_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@
namespace Envoy {
namespace Http {

class Hashable {
public:
virtual absl::optional<uint64_t> hash() const PURE;
virtual ~Hashable() = default;
};

/**
* Request hash policy. I.e., if using a hashing load balancer, how a request should be hashed onto
* an upstream host.
Expand Down
2 changes: 1 addition & 1 deletion envoy/network/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ envoy_cc_library(
hdrs = ["hash_policy.h"],
external_deps = ["abseil_optional"],
deps = [
":address_interface",
":connection_interface",
],
)

Expand Down
14 changes: 7 additions & 7 deletions envoy/network/hash_policy.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "envoy/network/address.h"
#include "envoy/network/connection.h"

#include "absl/types/optional.h"

Expand All @@ -14,14 +14,14 @@ class HashPolicy {
virtual ~HashPolicy() = default;

/**
* @param downstream_address is the address of the connected client.
* @param upstream_address is the address of the connected server.
* @param connection is the raw downstream connection. Different implementations of HashPolicy can
* compute hashes based on different data accessible from the connection (e.g. IP address,
* filter state, etc.).
* @return absl::optional<uint64_t> an optional hash value to route on. A hash value might not be
* returned if for example the downstream address is nullptr.
* returned if the hash policy implementation doesn't find the expected data in the connection
* (e.g. IP address is null, filter state is not populated, etc.).
*/
virtual absl::optional<uint64_t>
generateHash(const Network::Address::Instance* downstream_address,
const Network::Address::Instance* upstream_address) const PURE;
virtual absl::optional<uint64_t> generateHash(const Network::Connection& connection) const PURE;
};
} // namespace Network
} // namespace Envoy
1 change: 1 addition & 0 deletions source/common/http/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ envoy_cc_library(
hdrs = ["hash_policy.h"],
deps = [
":utility_lib",
"//envoy/common:hashable_interface",
"//envoy/http:hash_policy_interface",
"@envoy_api//envoy/config/route/v3:pkg_cc_proto",
],
Expand Down
1 change: 1 addition & 0 deletions source/common/http/hash_policy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <string>

#include "envoy/common/hashable.h"
#include "envoy/config/route/v3/route_components.pb.h"

#include "source/common/common/matchers.h"
Expand Down
3 changes: 1 addition & 2 deletions source/common/http/hash_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ namespace Envoy {
namespace Http {

/**
* Implementation of HashPolicy that reads from the proto route config and only currently supports
* hashing on an HTTP header.
* Implementation of HashPolicy that reads from the proto route config.
*/
class HashPolicyImpl : public HashPolicy {
public:
Expand Down
2 changes: 2 additions & 0 deletions source/common/network/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ envoy_cc_library(
srcs = ["hash_policy.cc"],
hdrs = ["hash_policy.h"],
deps = [
"//envoy/common:hashable_interface",
"//envoy/network:connection_interface",
"//envoy/network:hash_policy_interface",
"//source/common/common:assert_lib",
"//source/common/common:hash_lib",
Expand Down
30 changes: 24 additions & 6 deletions source/common/network/hash_policy.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "source/common/network/hash_policy.h"

#include "envoy/common/exception.h"
#include "envoy/common/hashable.h"
#include "envoy/type/v3/hash_policy.pb.h"

#include "source/common/common/assert.h"
Expand All @@ -10,8 +11,8 @@ namespace Network {

class SourceIpHashMethod : public HashPolicyImpl::HashMethod {
public:
absl::optional<uint64_t> evaluate(const Network::Address::Instance* downstream_addr,
const Network::Address::Instance*) const override {
absl::optional<uint64_t> evaluate(const Network::Connection& connection) const override {
const auto* downstream_addr = connection.connectionInfoProvider().remoteAddress().get();
if (downstream_addr && downstream_addr->ip()) {
ASSERT(!downstream_addr->ip()->addressAsString().empty());
return HashUtil::xxHash64(downstream_addr->ip()->addressAsString());
Expand All @@ -21,22 +22,39 @@ class SourceIpHashMethod : public HashPolicyImpl::HashMethod {
}
};

class FilterStateHashMethod : public HashPolicyImpl::HashMethod {
public:
FilterStateHashMethod(absl::string_view key) : key_(key) {}

absl::optional<uint64_t> evaluate(const Network::Connection& connection) const override {
const auto& filter_state = connection.streamInfo().filterState();
if (filter_state.hasData<Hashable>(key_)) {
return filter_state.getDataReadOnly<Hashable>(key_).hash();
}
return absl::nullopt;
}

private:
const std::string key_;
};

HashPolicyImpl::HashPolicyImpl(
const absl::Span<const envoy::type::v3::HashPolicy* const>& hash_policies) {
ASSERT(hash_policies.size() == 1);
switch (hash_policies[0]->policy_specifier_case()) {
case envoy::type::v3::HashPolicy::PolicySpecifierCase::kSourceIp:
hash_impl_ = std::make_unique<SourceIpHashMethod>();
break;
case envoy::type::v3::HashPolicy::PolicySpecifierCase::kFilterState:
hash_impl_ = std::make_unique<FilterStateHashMethod>(hash_policies[0]->filter_state().key());
break;
default:
NOT_REACHED_GCOVR_EXCL_LINE;
}
}

absl::optional<uint64_t>
HashPolicyImpl::generateHash(const Network::Address::Instance* downstream_addr,
const Network::Address::Instance* upstream_addr) const {
return hash_impl_->evaluate(downstream_addr, upstream_addr);
absl::optional<uint64_t> HashPolicyImpl::generateHash(const Network::Connection& connection) const {
return hash_impl_->evaluate(connection);
}

} // namespace Network
Expand Down
9 changes: 3 additions & 6 deletions source/common/network/hash_policy.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "envoy/network/connection.h"
#include "envoy/network/hash_policy.h"
#include "envoy/type/v3/hash_policy.pb.h"

Expand All @@ -15,16 +16,12 @@ class HashPolicyImpl : public Network::HashPolicy {
explicit HashPolicyImpl(const absl::Span<const envoy::type::v3::HashPolicy* const>& hash_policy);

// Network::HashPolicy
absl::optional<uint64_t>
generateHash(const Network::Address::Instance* downstream_addr,
const Network::Address::Instance* upstream_addr) const override;
absl::optional<uint64_t> generateHash(const Network::Connection& connection) const override;

class HashMethod {
public:
virtual ~HashMethod() = default;
virtual absl::optional<uint64_t>
evaluate(const Network::Address::Instance* downstream_addr,
const Network::Address::Instance* upstream_addr) const PURE;
virtual absl::optional<uint64_t> evaluate(const Network::Connection& connection) const PURE;
};

using HashMethodPtr = std::unique_ptr<HashMethod>;
Expand Down
4 changes: 1 addition & 3 deletions source/common/tcp_proxy/tcp_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,7 @@ class Filter : public Network::ReadFilter,
absl::optional<uint64_t> computeHashKey() override {
auto hash_policy = config_->hashPolicy();
if (hash_policy) {
return hash_policy->generateHash(
downstreamConnection()->connectionInfoProvider().remoteAddress().get(),
downstreamConnection()->connectionInfoProvider().localAddress().get());
return hash_policy->generateHash(*downstreamConnection());
}

return {};
Expand Down
1 change: 1 addition & 0 deletions test/common/router/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ envoy_cc_test_library(
srcs = ["config_impl_test.cc"],
deps = [
":route_fuzz_proto_cc_proto",
"//envoy/common:hashable_interface",
"//source/common/config:metadata_lib",
"//source/common/http:header_map_lib",
"//source/common/http:headers_lib",
Expand Down
3 changes: 2 additions & 1 deletion test/common/router/config_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <string>
#include <vector>

#include "envoy/common/hashable.h"
#include "envoy/config/route/v3/route.pb.h"
#include "envoy/config/route/v3/route.pb.validate.h"
#include "envoy/config/route/v3/route_components.pb.h"
Expand Down Expand Up @@ -2803,7 +2804,7 @@ class RouterMatcherFilterStateHashPolicyTest : public RouterMatcherHashPolicyTes
StreamInfo::FilterState::LifeSpan::FilterChain);
}
class NonHashable : public StreamInfo::FilterState::Object {};
class HashableObj : public StreamInfo::FilterState::Object, public Http::Hashable {
class HashableObj : public StreamInfo::FilterState::Object, public Hashable {
absl::optional<uint64_t> hash() const override { return 12345; };
};

Expand Down
1 change: 1 addition & 0 deletions test/common/tcp_proxy/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ envoy_cc_test(
],
deps = [
":tcp_proxy_test_base",
"//envoy/common:hashable_interface",
],
)

Expand Down
Loading