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