xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/load_balancer/load_balancer_decoder.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_DECODER_H_
6 #define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_DECODER_H_
7 
8 #include <cstdint>
9 #include <optional>
10 
11 #include "absl/base/attributes.h"
12 #include "quiche/quic/core/quic_connection_id.h"
13 #include "quiche/quic/load_balancer/load_balancer_config.h"
14 #include "quiche/quic/load_balancer/load_balancer_server_id.h"
15 #include "quiche/quic/platform/api/quic_export.h"
16 
17 namespace quic {
18 
19 // Manages QUIC-LB configurations to extract a server ID from a properly
20 // encoded connection ID, usually on behalf of a load balancer.
21 //
22 // IMPORTANT: The decoder data path is likely the most performance-sensitive
23 // part of the load balancer design, and this code has been carefully
24 // optimized for performance. Please do not make changes without running the
25 // benchmark tests to ensure there is no regression.
26 class QUIC_EXPORT_PRIVATE LoadBalancerDecoder {
27  public:
28   // Returns false if the config_id codepoint is already occupied.
29   bool AddConfig(const LoadBalancerConfig& config);
30 
31   // Remove support for a config. Does nothing if there is no config for
32   // |config_id|. Does nothing and creates a bug if |config_id| is greater than
33   // 2.
34   void DeleteConfig(uint8_t config_id);
35 
36   // Return the config for |config_id|, or nullptr if not found.
GetConfig(const uint8_t config_id)37   const LoadBalancerConfig* GetConfig(const uint8_t config_id) const {
38     if (config_id >= kNumLoadBalancerConfigs ||
39         !config_[config_id].has_value()) {
40       return nullptr;
41     }
42 
43     return &*config_[config_id];
44   }
45 
46   // Extract a server ID from |connection_id| and write it into |server_id|. If
47   // there is no config for the codepoint, |connection_id| is too short, or
48   // there's a decrypt error, returns false. Will accept |connection_id| that is
49   // longer than necessary without error. If GetServerId() returns false, there
50   // are no guarantees about the properties of |server_id|.
51   ABSL_MUST_USE_RESULT bool GetServerId(const QuicConnectionId& connection_id,
52                                         LoadBalancerServerId& server_id) const;
53 
54   // Returns the config ID stored in the first two bits of |connection_id|, or
55   // empty if |connection_id| is empty, or the first two bits of the first byte
56   // of |connection_id| are 0b11.
57   static std::optional<uint8_t> GetConfigId(
58       const QuicConnectionId& connection_id);
59 
60   // Returns the config ID stored in the first two bits of
61   // |connection_id_first_byte|, or empty if the first two bits are 0b11.
62   static std::optional<uint8_t> GetConfigId(uint8_t connection_id_first_byte);
63 
64  private:
65   // Decoders can support up to 3 configs at once.
66   std::optional<LoadBalancerConfig> config_[kNumLoadBalancerConfigs];
67 };
68 
69 }  // namespace quic
70 
71 #endif  // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_DECODER_H_
72