aboutsummaryrefslogtreecommitdiff
path: root/src/core/ext/transport/chttp2/transport/http2_settings.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ext/transport/chttp2/transport/http2_settings.cc')
-rw-r--r--src/core/ext/transport/chttp2/transport/http2_settings.cc154
1 files changed, 122 insertions, 32 deletions
diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.cc b/src/core/ext/transport/chttp2/transport/http2_settings.cc
index d966a7aebe..d9e4341250 100644
--- a/src/core/ext/transport/chttp2/transport/http2_settings.cc
+++ b/src/core/ext/transport/chttp2/transport/http2_settings.cc
@@ -22,43 +22,133 @@
#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
+#include "absl/strings/str_cat.h"
+
+#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/transport/http2_errors.h"
-const uint16_t grpc_setting_id_to_wire_id[] = {1, 2, 3, 4, 5, 6, 65027, 65028};
+namespace grpc_core {
+
+void Http2Settings::Diff(
+ bool is_first_send, const Http2Settings& old,
+ absl::FunctionRef<void(uint16_t key, uint32_t value)> cb) const {
+ if (header_table_size_ != old.header_table_size_) {
+ cb(kHeaderTableSizeWireId, header_table_size_);
+ }
+ if (enable_push_ != old.enable_push_) {
+ cb(kEnablePushWireId, enable_push_);
+ }
+ if (max_concurrent_streams_ != old.max_concurrent_streams_) {
+ cb(kMaxConcurrentStreamsWireId, max_concurrent_streams_);
+ }
+ if (is_first_send || initial_window_size_ != old.initial_window_size_) {
+ cb(kInitialWindowSizeWireId, initial_window_size_);
+ }
+ if (max_frame_size_ != old.max_frame_size_) {
+ cb(kMaxFrameSizeWireId, max_frame_size_);
+ }
+ if (max_header_list_size_ != old.max_header_list_size_) {
+ cb(kMaxHeaderListSizeWireId, max_header_list_size_);
+ }
+ if (allow_true_binary_metadata_ != old.allow_true_binary_metadata_) {
+ cb(kGrpcAllowTrueBinaryMetadataWireId, allow_true_binary_metadata_);
+ }
+ if (preferred_receive_crypto_message_size_ !=
+ old.preferred_receive_crypto_message_size_) {
+ cb(kGrpcPreferredReceiveCryptoFrameSizeWireId,
+ preferred_receive_crypto_message_size_);
+ }
+}
+
+std::string Http2Settings::WireIdToName(uint16_t wire_id) {
+ switch (wire_id) {
+ case kHeaderTableSizeWireId:
+ return std::string(header_table_size_name());
+ case kEnablePushWireId:
+ return std::string(enable_push_name());
+ case kMaxConcurrentStreamsWireId:
+ return std::string(max_concurrent_streams_name());
+ case kInitialWindowSizeWireId:
+ return std::string(initial_window_size_name());
+ case kMaxFrameSizeWireId:
+ return std::string(max_frame_size_name());
+ case kMaxHeaderListSizeWireId:
+ return std::string(max_header_list_size_name());
+ case kGrpcAllowTrueBinaryMetadataWireId:
+ return std::string(allow_true_binary_metadata_name());
+ case kGrpcPreferredReceiveCryptoFrameSizeWireId:
+ return std::string(preferred_receive_crypto_message_size_name());
+ default:
+ return absl::StrCat("UNKNOWN (", wire_id, ")");
+ }
+}
+
+grpc_http2_error_code Http2Settings::Apply(uint16_t key, uint32_t value) {
+ switch (key) {
+ case kHeaderTableSizeWireId:
+ header_table_size_ = value;
+ break;
+ case kEnablePushWireId:
+ if (value > 1) return GRPC_HTTP2_PROTOCOL_ERROR;
+ enable_push_ = value != 0;
+ break;
+ case kMaxConcurrentStreamsWireId:
+ max_concurrent_streams_ = value;
+ break;
+ case kInitialWindowSizeWireId:
+ if (value > max_initial_window_size()) {
+ return GRPC_HTTP2_FLOW_CONTROL_ERROR;
+ }
+ initial_window_size_ = value;
+ break;
+ case kMaxFrameSizeWireId:
+ if (value < min_max_frame_size() || value > max_max_frame_size()) {
+ return GRPC_HTTP2_PROTOCOL_ERROR;
+ }
+ max_frame_size_ = value;
+ break;
+ case kMaxHeaderListSizeWireId:
+ max_header_list_size_ = std::min(value, 16777216u);
+ break;
+ case kGrpcAllowTrueBinaryMetadataWireId:
+ if (value > 1) return GRPC_HTTP2_PROTOCOL_ERROR;
+ allow_true_binary_metadata_ = value != 0;
+ break;
+ case kGrpcPreferredReceiveCryptoFrameSizeWireId:
+ preferred_receive_crypto_message_size_ =
+ Clamp(value, min_preferred_receive_crypto_message_size(),
+ max_preferred_receive_crypto_message_size());
+ break;
+ }
+ return GRPC_HTTP2_NO_ERROR;
+}
-bool grpc_wire_id_to_setting_id(uint32_t wire_id, grpc_chttp2_setting_id* out) {
- uint32_t i = wire_id - 1;
- uint32_t x = i % 256;
- uint32_t y = i / 256;
- uint32_t h = x;
- switch (y) {
- case 254:
- h += 4;
+absl::optional<Http2SettingsFrame> Http2SettingsManager::MaybeSendUpdate() {
+ switch (update_state_) {
+ case UpdateState::kSending:
+ return absl::nullopt;
+ case UpdateState::kIdle:
+ if (local_ == sent_) return absl::nullopt;
+ break;
+ case UpdateState::kFirst:
break;
}
- *out = static_cast<grpc_chttp2_setting_id>(h);
- return h < GPR_ARRAY_SIZE(grpc_setting_id_to_wire_id) &&
- grpc_setting_id_to_wire_id[h] == wire_id;
+ Http2SettingsFrame frame;
+ local_.Diff(update_state_ == UpdateState::kFirst, sent_,
+ [&frame](uint16_t key, uint32_t value) {
+ frame.settings.emplace_back(key, value);
+ });
+ sent_ = local_;
+ update_state_ = UpdateState::kSending;
+ return frame;
+}
+
+bool Http2SettingsManager::AckLastSend() {
+ if (update_state_ != UpdateState::kSending) return false;
+ update_state_ = UpdateState::kIdle;
+ acked_ = sent_;
+ return true;
}
-const grpc_chttp2_setting_parameters
- grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = {
- {"HEADER_TABLE_SIZE", 4096u, 0u, 4294967295u,
- GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
- {"ENABLE_PUSH", 1u, 0u, 1u, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE,
- GRPC_HTTP2_PROTOCOL_ERROR},
- {"MAX_CONCURRENT_STREAMS", 4294967295u, 0u, 4294967295u,
- GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
- {"INITIAL_WINDOW_SIZE", 65535u, 0u, 2147483647u,
- GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE,
- GRPC_HTTP2_FLOW_CONTROL_ERROR},
- {"MAX_FRAME_SIZE", 16384u, 16384u, 16777215u,
- GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
- {"MAX_HEADER_LIST_SIZE", 16777216u, 0u, 16777216u,
- GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
- {"GRPC_ALLOW_TRUE_BINARY_METADATA", 0u, 0u, 1u,
- GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
- {"GRPC_PREFERRED_RECEIVE_CRYPTO_FRAME_SIZE", 0u, 16384u, 2147483647u,
- GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_HTTP2_PROTOCOL_ERROR},
-};
+} // namespace grpc_core