Line data Source code
1 : #include "source/common/network/hash_policy.h" 2 : 3 : #include "envoy/common/exception.h" 4 : #include "envoy/common/hashable.h" 5 : #include "envoy/type/v3/hash_policy.pb.h" 6 : 7 : #include "source/common/common/assert.h" 8 : 9 : namespace Envoy { 10 : namespace Network { 11 : 12 : class SourceIpHashMethod : public HashPolicyImpl::HashMethod { 13 : public: 14 0 : absl::optional<uint64_t> evaluate(const Network::Connection& connection) const override { 15 0 : const auto* downstream_addr = connection.connectionInfoProvider().remoteAddress().get(); 16 0 : if (downstream_addr && downstream_addr->ip()) { 17 0 : ASSERT(!downstream_addr->ip()->addressAsString().empty()); 18 0 : return HashUtil::xxHash64(downstream_addr->ip()->addressAsString()); 19 0 : } 20 : 21 0 : return absl::nullopt; 22 0 : } 23 : }; 24 : 25 : class FilterStateHashMethod : public HashPolicyImpl::HashMethod { 26 : public: 27 0 : FilterStateHashMethod(absl::string_view key) : key_(key) {} 28 : 29 0 : absl::optional<uint64_t> evaluate(const Network::Connection& connection) const override { 30 0 : const auto& filter_state = connection.streamInfo().filterState(); 31 0 : if (auto typed_state = filter_state.getDataReadOnly<Hashable>(key_); typed_state != nullptr) { 32 0 : return typed_state->hash(); 33 0 : } 34 0 : return absl::nullopt; 35 0 : } 36 : 37 : private: 38 : const std::string key_; 39 : }; 40 : 41 : HashPolicyImpl::HashPolicyImpl( 42 0 : const absl::Span<const envoy::type::v3::HashPolicy* const>& hash_policies) { 43 0 : ASSERT(hash_policies.size() == 1); 44 0 : switch (hash_policies[0]->policy_specifier_case()) { 45 0 : case envoy::type::v3::HashPolicy::PolicySpecifierCase::kSourceIp: 46 0 : hash_impl_ = std::make_unique<SourceIpHashMethod>(); 47 0 : break; 48 0 : case envoy::type::v3::HashPolicy::PolicySpecifierCase::kFilterState: 49 0 : hash_impl_ = std::make_unique<FilterStateHashMethod>(hash_policies[0]->filter_state().key()); 50 0 : break; 51 0 : case envoy::type::v3::HashPolicy::PolicySpecifierCase::POLICY_SPECIFIER_NOT_SET: 52 0 : PANIC_DUE_TO_PROTO_UNSET; 53 0 : } 54 0 : } 55 : 56 0 : absl::optional<uint64_t> HashPolicyImpl::generateHash(const Network::Connection& connection) const { 57 0 : return hash_impl_->evaluate(connection); 58 0 : } 59 : 60 : } // namespace Network 61 : } // namespace Envoy