xref: /aosp_15_r20/external/grpc-grpc/src/core/ext/transport/chttp2/transport/http2_settings.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 // Copyright 2017 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H
18 #define GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H
19 
20 #include <grpc/support/port_platform.h>
21 
22 #include <stdint.h>
23 
24 #include <cstdint>
25 
26 #include "absl/functional/function_ref.h"
27 #include "absl/strings/string_view.h"
28 #include "absl/types/optional.h"
29 
30 #include "src/core/ext/transport/chttp2/transport/frame.h"
31 #include "src/core/lib/gpr/useful.h"
32 #include "src/core/lib/transport/http2_errors.h"
33 
34 namespace grpc_core {
35 
36 class Http2Settings {
37  public:
38   enum : uint16_t {
39     kHeaderTableSizeWireId = 1,
40     kEnablePushWireId = 2,
41     kMaxConcurrentStreamsWireId = 3,
42     kInitialWindowSizeWireId = 4,
43     kMaxFrameSizeWireId = 5,
44     kMaxHeaderListSizeWireId = 6,
45     kGrpcAllowTrueBinaryMetadataWireId = 65027,
46     kGrpcPreferredReceiveCryptoFrameSizeWireId = 65028,
47   };
48 
49   void Diff(bool is_first_send, const Http2Settings& old,
50             absl::FunctionRef<void(uint16_t key, uint32_t value)> cb) const;
51   GRPC_MUST_USE_RESULT grpc_http2_error_code Apply(uint16_t key,
52                                                    uint32_t value);
header_table_size()53   uint32_t header_table_size() const { return header_table_size_; }
max_concurrent_streams()54   uint32_t max_concurrent_streams() const { return max_concurrent_streams_; }
initial_window_size()55   uint32_t initial_window_size() const { return initial_window_size_; }
max_frame_size()56   uint32_t max_frame_size() const { return max_frame_size_; }
max_header_list_size()57   uint32_t max_header_list_size() const { return max_header_list_size_; }
preferred_receive_crypto_message_size()58   uint32_t preferred_receive_crypto_message_size() const {
59     return preferred_receive_crypto_message_size_;
60   }
enable_push()61   bool enable_push() const { return enable_push_; }
allow_true_binary_metadata()62   bool allow_true_binary_metadata() const {
63     return allow_true_binary_metadata_;
64   }
65 
SetHeaderTableSize(uint32_t x)66   void SetHeaderTableSize(uint32_t x) { header_table_size_ = x; }
SetMaxConcurrentStreams(uint32_t x)67   void SetMaxConcurrentStreams(uint32_t x) { max_concurrent_streams_ = x; }
SetInitialWindowSize(uint32_t x)68   void SetInitialWindowSize(uint32_t x) {
69     initial_window_size_ = std::min(x, max_initial_window_size());
70   }
SetEnablePush(bool x)71   void SetEnablePush(bool x) { enable_push_ = x; }
SetMaxHeaderListSize(uint32_t x)72   void SetMaxHeaderListSize(uint32_t x) {
73     max_header_list_size_ = std::min(x, 16777216u);
74   }
SetAllowTrueBinaryMetadata(bool x)75   void SetAllowTrueBinaryMetadata(bool x) { allow_true_binary_metadata_ = x; }
SetMaxFrameSize(uint32_t x)76   void SetMaxFrameSize(uint32_t x) {
77     max_frame_size_ = Clamp(x, min_max_frame_size(), max_max_frame_size());
78   }
SetPreferredReceiveCryptoMessageSize(uint32_t x)79   void SetPreferredReceiveCryptoMessageSize(uint32_t x) {
80     preferred_receive_crypto_message_size_ =
81         Clamp(x, min_preferred_receive_crypto_message_size(),
82               max_preferred_receive_crypto_message_size());
83   }
84 
header_table_size_name()85   static absl::string_view header_table_size_name() {
86     return "HEADER_TABLE_SIZE";
87   }
max_concurrent_streams_name()88   static absl::string_view max_concurrent_streams_name() {
89     return "MAX_CONCURRENT_STREAMS";
90   }
initial_window_size_name()91   static absl::string_view initial_window_size_name() {
92     return "INITIAL_WINDOW_SIZE";
93   }
max_frame_size_name()94   static absl::string_view max_frame_size_name() { return "MAX_FRAME_SIZE"; }
max_header_list_size_name()95   static absl::string_view max_header_list_size_name() {
96     return "MAX_HEADER_LIST_SIZE";
97   }
enable_push_name()98   static absl::string_view enable_push_name() { return "ENABLE_PUSH"; }
allow_true_binary_metadata_name()99   static absl::string_view allow_true_binary_metadata_name() {
100     return "GRPC_ALLOW_TRUE_BINARY_METADATA";
101   }
preferred_receive_crypto_message_size_name()102   static absl::string_view preferred_receive_crypto_message_size_name() {
103     return "GRPC_PREFERRED_RECEIVE_MESSAGE_SIZE";
104   }
105 
max_initial_window_size()106   static uint32_t max_initial_window_size() { return 2147483647u; }
max_max_frame_size()107   static uint32_t max_max_frame_size() { return 16777215u; }
min_max_frame_size()108   static uint32_t min_max_frame_size() { return 16384u; }
min_preferred_receive_crypto_message_size()109   static uint32_t min_preferred_receive_crypto_message_size() { return 16384u; }
max_preferred_receive_crypto_message_size()110   static uint32_t max_preferred_receive_crypto_message_size() {
111     return 2147483647u;
112   }
113 
114   static std::string WireIdToName(uint16_t wire_id);
115 
116   bool operator==(const Http2Settings& rhs) const {
117     return header_table_size_ == rhs.header_table_size_ &&
118            max_concurrent_streams_ == rhs.max_concurrent_streams_ &&
119            initial_window_size_ == rhs.initial_window_size_ &&
120            max_frame_size_ == rhs.max_frame_size_ &&
121            max_header_list_size_ == rhs.max_header_list_size_ &&
122            preferred_receive_crypto_message_size_ ==
123                rhs.preferred_receive_crypto_message_size_ &&
124            enable_push_ == rhs.enable_push_ &&
125            allow_true_binary_metadata_ == rhs.allow_true_binary_metadata_;
126   }
127 
128   bool operator!=(const Http2Settings& rhs) const { return !operator==(rhs); }
129 
130  private:
131   uint32_t header_table_size_ = 4096;
132   uint32_t max_concurrent_streams_ = 4294967295u;
133   uint32_t initial_window_size_ = 65535u;
134   uint32_t max_frame_size_ = 16384u;
135   uint32_t max_header_list_size_ = 16777216u;
136   uint32_t preferred_receive_crypto_message_size_ = 0u;
137   bool enable_push_ = true;
138   bool allow_true_binary_metadata_ = false;
139 };
140 
141 class Http2SettingsManager {
142  public:
mutable_local()143   Http2Settings& mutable_local() { return local_; }
local()144   const Http2Settings& local() const { return local_; }
acked()145   const Http2Settings& acked() const { return acked_; }
mutable_peer()146   Http2Settings& mutable_peer() { return peer_; }
peer()147   const Http2Settings& peer() const { return peer_; }
148 
149   absl::optional<Http2SettingsFrame> MaybeSendUpdate();
150   GRPC_MUST_USE_RESULT bool AckLastSend();
151 
152  private:
153   enum class UpdateState : uint8_t {
154     kFirst,
155     kSending,
156     kIdle,
157   };
158   UpdateState update_state_ = UpdateState::kFirst;
159   Http2Settings local_;
160   Http2Settings sent_;
161   Http2Settings peer_;
162   Http2Settings acked_;
163 };
164 
165 }  // namespace grpc_core
166 
167 #endif  // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H
168