| // Copyright (c) 2022 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_H_ |
| #define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_H_ |
| |
| #include <array> |
| #include <cstdint> |
| #include <string> |
| |
| #include "absl/strings/string_view.h" |
| #include "absl/types/span.h" |
| #include "quiche/quic/platform/api/quic_export.h" |
| |
| namespace quic { |
| |
| // The maximum number of bytes in a LoadBalancerServerId. |
| inline constexpr uint8_t kLoadBalancerMaxServerIdLen = 15; |
| // Regardless of key length, the AES block size is always 16 Bytes. |
| inline constexpr uint8_t kLoadBalancerBlockSize = 16; |
| static_assert(kLoadBalancerMaxServerIdLen <= kLoadBalancerBlockSize, |
| "LoadBalancerServerId array not large enough to hold Server ID"); |
| |
| // LoadBalancerServerId is the globally understood identifier for a given pool |
| // member. It is unique to any given QUIC-LB configuration. See |
| // draft-ietf-quic-load-balancers. |
| // Note: this has nothing to do with QuicServerID. It's an unfortunate collision |
| // between an internal term for the destination identifiers for a particular |
| // deployment (QuicServerID) and the object of a load balancing decision |
| // (LoadBalancerServerId). |
| class QUIC_EXPORT_PRIVATE LoadBalancerServerId { |
| public: |
| // Creates an empty/invalid server id. |
| LoadBalancerServerId() : length_(0) {} |
| |
| // Copies all the bytes from |data| into a new LoadBalancerServerId. |
| explicit LoadBalancerServerId(absl::Span<const uint8_t> data); |
| explicit LoadBalancerServerId(absl::string_view data); |
| |
| // Server IDs are opaque bytes, but defining these operators allows us to sort |
| // them into a tree and define ranges. |
| bool operator<(const LoadBalancerServerId& other) const { |
| return data() < other.data(); |
| } |
| bool operator==(const LoadBalancerServerId& other) const { |
| return data() == other.data(); |
| } |
| |
| // Hash function to allow use as a key in unordered maps. |
| template <typename H> |
| friend H AbslHashValue(H h, const LoadBalancerServerId& server_id) { |
| return H::combine_contiguous(std::move(h), server_id.data().data(), |
| server_id.length()); |
| } |
| |
| absl::Span<const uint8_t> data() const { |
| return absl::MakeConstSpan(data_.data(), length_); |
| } |
| uint8_t* mutable_data() { return data_.data(); } |
| |
| uint8_t length() const { return length_; } |
| void set_length(uint8_t length); |
| |
| // Returns the server ID in hex format. |
| std::string ToString() const; |
| |
| // Returns true if this is a valid server id. |
| bool IsValid() { return length_ != 0; } |
| |
| private: |
| // Make the array large enough to hold an entire decrypt result, to save a |
| // copy from the decrypt result into LoadBalancerServerId. |
| std::array<uint8_t, kLoadBalancerBlockSize> data_; |
| uint8_t length_; |
| }; |
| |
| } // namespace quic |
| |
| #endif // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_H_ |