1 // Copyright (c) 2022 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_H_ 6 #define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_H_ 7 8 #include <array> 9 #include <cstdint> 10 #include <string> 11 12 #include "absl/strings/string_view.h" 13 #include "absl/types/span.h" 14 #include "quiche/quic/platform/api/quic_export.h" 15 16 namespace quic { 17 18 // The maximum number of bytes in a LoadBalancerServerId. 19 inline constexpr uint8_t kLoadBalancerMaxServerIdLen = 15; 20 // Regardless of key length, the AES block size is always 16 Bytes. 21 inline constexpr uint8_t kLoadBalancerBlockSize = 16; 22 static_assert(kLoadBalancerMaxServerIdLen <= kLoadBalancerBlockSize, 23 "LoadBalancerServerId array not large enough to hold Server ID"); 24 25 // LoadBalancerServerId is the globally understood identifier for a given pool 26 // member. It is unique to any given QUIC-LB configuration. See 27 // draft-ietf-quic-load-balancers. 28 // Note: this has nothing to do with QuicServerID. It's an unfortunate collision 29 // between an internal term for the destination identifiers for a particular 30 // deployment (QuicServerID) and the object of a load balancing decision 31 // (LoadBalancerServerId). 32 class QUIC_EXPORT_PRIVATE LoadBalancerServerId { 33 public: 34 // Creates an empty/invalid server id. LoadBalancerServerId()35 LoadBalancerServerId() : length_(0) {} 36 37 // Copies all the bytes from |data| into a new LoadBalancerServerId. 38 explicit LoadBalancerServerId(absl::Span<const uint8_t> data); 39 explicit LoadBalancerServerId(absl::string_view data); 40 41 // Server IDs are opaque bytes, but defining these operators allows us to sort 42 // them into a tree and define ranges. 43 bool operator<(const LoadBalancerServerId& other) const { 44 return data() < other.data(); 45 } 46 bool operator==(const LoadBalancerServerId& other) const { 47 return data() == other.data(); 48 } 49 50 // Hash function to allow use as a key in unordered maps. 51 template <typename H> AbslHashValue(H h,const LoadBalancerServerId & server_id)52 friend H AbslHashValue(H h, const LoadBalancerServerId& server_id) { 53 return H::combine_contiguous(std::move(h), server_id.data().data(), 54 server_id.length()); 55 } 56 data()57 absl::Span<const uint8_t> data() const { 58 return absl::MakeConstSpan(data_.data(), length_); 59 } mutable_data()60 uint8_t* mutable_data() { return data_.data(); } 61 length()62 uint8_t length() const { return length_; } 63 void set_length(uint8_t length); 64 65 // Returns the server ID in hex format. 66 std::string ToString() const; 67 68 // Returns true if this is a valid server id. IsValid()69 bool IsValid() { return length_ != 0; } 70 71 private: 72 // Make the array large enough to hold an entire decrypt result, to save a 73 // copy from the decrypt result into LoadBalancerServerId. 74 std::array<uint8_t, kLoadBalancerBlockSize> data_; 75 uint8_t length_; 76 }; 77 78 } // namespace quic 79 80 #endif // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_H_ 81