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 //
18 // Automatically generated by tools/codegen/core/gen_settings_ids.py
19 //
20
21 #include <grpc/support/port_platform.h>
22
23 #include "src/core/ext/transport/chttp2/transport/http2_settings.h"
24
25 #include "absl/strings/str_cat.h"
26
27 #include "src/core/ext/transport/chttp2/transport/frame.h"
28 #include "src/core/lib/gpr/useful.h"
29 #include "src/core/lib/transport/http2_errors.h"
30
31 namespace grpc_core {
32
Diff(bool is_first_send,const Http2Settings & old,absl::FunctionRef<void (uint16_t key,uint32_t value)> cb) const33 void Http2Settings::Diff(
34 bool is_first_send, const Http2Settings& old,
35 absl::FunctionRef<void(uint16_t key, uint32_t value)> cb) const {
36 if (header_table_size_ != old.header_table_size_) {
37 cb(kHeaderTableSizeWireId, header_table_size_);
38 }
39 if (enable_push_ != old.enable_push_) {
40 cb(kEnablePushWireId, enable_push_);
41 }
42 if (max_concurrent_streams_ != old.max_concurrent_streams_) {
43 cb(kMaxConcurrentStreamsWireId, max_concurrent_streams_);
44 }
45 if (is_first_send || initial_window_size_ != old.initial_window_size_) {
46 cb(kInitialWindowSizeWireId, initial_window_size_);
47 }
48 if (max_frame_size_ != old.max_frame_size_) {
49 cb(kMaxFrameSizeWireId, max_frame_size_);
50 }
51 if (max_header_list_size_ != old.max_header_list_size_) {
52 cb(kMaxHeaderListSizeWireId, max_header_list_size_);
53 }
54 if (allow_true_binary_metadata_ != old.allow_true_binary_metadata_) {
55 cb(kGrpcAllowTrueBinaryMetadataWireId, allow_true_binary_metadata_);
56 }
57 if (preferred_receive_crypto_message_size_ !=
58 old.preferred_receive_crypto_message_size_) {
59 cb(kGrpcPreferredReceiveCryptoFrameSizeWireId,
60 preferred_receive_crypto_message_size_);
61 }
62 }
63
WireIdToName(uint16_t wire_id)64 std::string Http2Settings::WireIdToName(uint16_t wire_id) {
65 switch (wire_id) {
66 case kHeaderTableSizeWireId:
67 return std::string(header_table_size_name());
68 case kEnablePushWireId:
69 return std::string(enable_push_name());
70 case kMaxConcurrentStreamsWireId:
71 return std::string(max_concurrent_streams_name());
72 case kInitialWindowSizeWireId:
73 return std::string(initial_window_size_name());
74 case kMaxFrameSizeWireId:
75 return std::string(max_frame_size_name());
76 case kMaxHeaderListSizeWireId:
77 return std::string(max_header_list_size_name());
78 case kGrpcAllowTrueBinaryMetadataWireId:
79 return std::string(allow_true_binary_metadata_name());
80 case kGrpcPreferredReceiveCryptoFrameSizeWireId:
81 return std::string(preferred_receive_crypto_message_size_name());
82 default:
83 return absl::StrCat("UNKNOWN (", wire_id, ")");
84 }
85 }
86
Apply(uint16_t key,uint32_t value)87 grpc_http2_error_code Http2Settings::Apply(uint16_t key, uint32_t value) {
88 switch (key) {
89 case kHeaderTableSizeWireId:
90 header_table_size_ = value;
91 break;
92 case kEnablePushWireId:
93 if (value > 1) return GRPC_HTTP2_PROTOCOL_ERROR;
94 enable_push_ = value != 0;
95 break;
96 case kMaxConcurrentStreamsWireId:
97 max_concurrent_streams_ = value;
98 break;
99 case kInitialWindowSizeWireId:
100 if (value > max_initial_window_size()) {
101 return GRPC_HTTP2_FLOW_CONTROL_ERROR;
102 }
103 initial_window_size_ = value;
104 break;
105 case kMaxFrameSizeWireId:
106 if (value < min_max_frame_size() || value > max_max_frame_size()) {
107 return GRPC_HTTP2_PROTOCOL_ERROR;
108 }
109 max_frame_size_ = value;
110 break;
111 case kMaxHeaderListSizeWireId:
112 max_header_list_size_ = std::min(value, 16777216u);
113 break;
114 case kGrpcAllowTrueBinaryMetadataWireId:
115 if (value > 1) return GRPC_HTTP2_PROTOCOL_ERROR;
116 allow_true_binary_metadata_ = value != 0;
117 break;
118 case kGrpcPreferredReceiveCryptoFrameSizeWireId:
119 preferred_receive_crypto_message_size_ =
120 Clamp(value, min_preferred_receive_crypto_message_size(),
121 max_preferred_receive_crypto_message_size());
122 break;
123 }
124 return GRPC_HTTP2_NO_ERROR;
125 }
126
MaybeSendUpdate()127 absl::optional<Http2SettingsFrame> Http2SettingsManager::MaybeSendUpdate() {
128 switch (update_state_) {
129 case UpdateState::kSending:
130 return absl::nullopt;
131 case UpdateState::kIdle:
132 if (local_ == sent_) return absl::nullopt;
133 break;
134 case UpdateState::kFirst:
135 break;
136 }
137 Http2SettingsFrame frame;
138 local_.Diff(update_state_ == UpdateState::kFirst, sent_,
139 [&frame](uint16_t key, uint32_t value) {
140 frame.settings.emplace_back(key, value);
141 });
142 sent_ = local_;
143 update_state_ = UpdateState::kSending;
144 return frame;
145 }
146
AckLastSend()147 bool Http2SettingsManager::AckLastSend() {
148 if (update_state_ != UpdateState::kSending) return false;
149 update_state_ = UpdateState::kIdle;
150 acked_ = sent_;
151 return true;
152 }
153
154 } // namespace grpc_core
155