• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <stdint.h>
22 
23 #include <cstdint>
24 
25 #include "absl/functional/function_ref.h"
26 #include "absl/strings/string_view.h"
27 #include "absl/types/optional.h"
28 #include "src/core/ext/transport/chttp2/transport/frame.h"
29 #include "src/core/lib/transport/http2_errors.h"
30 #include "src/core/util/useful.h"
31 
32 namespace grpc_core {
33 
34 class Http2Settings {
35  public:
36   enum : uint16_t {
37     kHeaderTableSizeWireId = 1,
38     kEnablePushWireId = 2,
39     kMaxConcurrentStreamsWireId = 3,
40     kInitialWindowSizeWireId = 4,
41     kMaxFrameSizeWireId = 5,
42     kMaxHeaderListSizeWireId = 6,
43     kGrpcAllowTrueBinaryMetadataWireId = 65027,
44     kGrpcPreferredReceiveCryptoFrameSizeWireId = 65028,
45     kGrpcAllowSecurityFrameWireId = 65029,
46   };
47 
48   void Diff(bool is_first_send, const Http2Settings& old,
49             absl::FunctionRef<void(uint16_t key, uint32_t value)> cb) const;
50   GRPC_MUST_USE_RESULT grpc_http2_error_code Apply(uint16_t key,
51                                                    uint32_t value);
header_table_size()52   uint32_t header_table_size() const { return header_table_size_; }
max_concurrent_streams()53   uint32_t max_concurrent_streams() const { return max_concurrent_streams_; }
initial_window_size()54   uint32_t initial_window_size() const { return initial_window_size_; }
max_frame_size()55   uint32_t max_frame_size() const { return max_frame_size_; }
max_header_list_size()56   uint32_t max_header_list_size() const { return max_header_list_size_; }
preferred_receive_crypto_message_size()57   uint32_t preferred_receive_crypto_message_size() const {
58     return preferred_receive_crypto_message_size_;
59   }
enable_push()60   bool enable_push() const { return enable_push_; }
allow_true_binary_metadata()61   bool allow_true_binary_metadata() const {
62     return allow_true_binary_metadata_;
63   }
allow_security_frame()64   bool allow_security_frame() const { return allow_security_frame_; }
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   }
SetAllowSecurityFrame(bool x)84   void SetAllowSecurityFrame(bool x) { allow_security_frame_ = x; }
85 
header_table_size_name()86   static absl::string_view header_table_size_name() {
87     return "HEADER_TABLE_SIZE";
88   }
max_concurrent_streams_name()89   static absl::string_view max_concurrent_streams_name() {
90     return "MAX_CONCURRENT_STREAMS";
91   }
initial_window_size_name()92   static absl::string_view initial_window_size_name() {
93     return "INITIAL_WINDOW_SIZE";
94   }
max_frame_size_name()95   static absl::string_view max_frame_size_name() { return "MAX_FRAME_SIZE"; }
max_header_list_size_name()96   static absl::string_view max_header_list_size_name() {
97     return "MAX_HEADER_LIST_SIZE";
98   }
enable_push_name()99   static absl::string_view enable_push_name() { return "ENABLE_PUSH"; }
allow_true_binary_metadata_name()100   static absl::string_view allow_true_binary_metadata_name() {
101     return "GRPC_ALLOW_TRUE_BINARY_METADATA";
102   }
preferred_receive_crypto_message_size_name()103   static absl::string_view preferred_receive_crypto_message_size_name() {
104     return "GRPC_PREFERRED_RECEIVE_MESSAGE_SIZE";
105   }
allow_security_frame_name()106   static absl::string_view allow_security_frame_name() {
107     return "GRPC_ALLOW_SECURITY_FRAME";
108   }
109 
max_initial_window_size()110   static uint32_t max_initial_window_size() { return 2147483647u; }
max_max_frame_size()111   static uint32_t max_max_frame_size() { return 16777215u; }
min_max_frame_size()112   static uint32_t min_max_frame_size() { return 16384u; }
min_preferred_receive_crypto_message_size()113   static uint32_t min_preferred_receive_crypto_message_size() { return 16384u; }
max_preferred_receive_crypto_message_size()114   static uint32_t max_preferred_receive_crypto_message_size() {
115     return 2147483647u;
116   }
117 
118   static std::string WireIdToName(uint16_t wire_id);
119 
120   bool operator==(const Http2Settings& rhs) const {
121     return header_table_size_ == rhs.header_table_size_ &&
122            max_concurrent_streams_ == rhs.max_concurrent_streams_ &&
123            initial_window_size_ == rhs.initial_window_size_ &&
124            max_frame_size_ == rhs.max_frame_size_ &&
125            max_header_list_size_ == rhs.max_header_list_size_ &&
126            preferred_receive_crypto_message_size_ ==
127                rhs.preferred_receive_crypto_message_size_ &&
128            enable_push_ == rhs.enable_push_ &&
129            allow_true_binary_metadata_ == rhs.allow_true_binary_metadata_ &&
130            allow_security_frame_ == rhs.allow_security_frame_;
131   }
132 
133   bool operator!=(const Http2Settings& rhs) const { return !operator==(rhs); }
134 
135  private:
136   uint32_t header_table_size_ = 4096;
137   uint32_t max_concurrent_streams_ = 4294967295u;
138   uint32_t initial_window_size_ = 65535u;
139   uint32_t max_frame_size_ = 16384u;
140   uint32_t max_header_list_size_ = 16777216u;
141   uint32_t preferred_receive_crypto_message_size_ = 0u;
142   bool enable_push_ = true;
143   bool allow_true_binary_metadata_ = false;
144   bool allow_security_frame_ = false;
145 };
146 
147 class Http2SettingsManager {
148  public:
mutable_local()149   Http2Settings& mutable_local() { return local_; }
local()150   const Http2Settings& local() const { return local_; }
acked()151   const Http2Settings& acked() const { return acked_; }
mutable_peer()152   Http2Settings& mutable_peer() { return peer_; }
peer()153   const Http2Settings& peer() const { return peer_; }
154 
155   absl::optional<Http2SettingsFrame> MaybeSendUpdate();
156   GRPC_MUST_USE_RESULT bool AckLastSend();
157 
158  private:
159   enum class UpdateState : uint8_t {
160     kFirst,
161     kSending,
162     kIdle,
163   };
164   UpdateState update_state_ = UpdateState::kFirst;
165   Http2Settings local_;
166   Http2Settings sent_;
167   Http2Settings peer_;
168   Http2Settings acked_;
169 };
170 
171 }  // namespace grpc_core
172 
173 #endif  // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H
174