xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/load_balancer/load_balancer_server_id.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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