aboutsummaryrefslogtreecommitdiff
path: root/src/core/ext/transport/chttp2/transport/frame_settings.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ext/transport/chttp2/transport/frame_settings.cc')
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_settings.cc112
1 files changed, 33 insertions, 79 deletions
diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.cc b/src/core/ext/transport/chttp2/transport/frame_settings.cc
index e4bf9d4fdb..c0e24c336e 100644
--- a/src/core/ext/transport/chttp2/transport/frame_settings.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_settings.cc
@@ -33,6 +33,7 @@
#include "src/core/ext/transport/chttp2/transport/flow_control.h"
#include "src/core/ext/transport/chttp2/transport/frame_goaway.h"
+#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
#include "src/core/ext/transport/chttp2/transport/http_trace.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include "src/core/ext/transport/chttp2/transport/legacy_frame.h"
@@ -55,38 +56,6 @@ static uint8_t* fill_header(uint8_t* out, uint32_t length, uint8_t flags) {
return out;
}
-grpc_slice grpc_chttp2_settings_create(uint32_t* old_settings,
- const uint32_t* new_settings,
- uint32_t force_mask, size_t count) {
- size_t i;
- uint32_t n = 0;
- grpc_slice output;
- uint8_t* p;
-
- for (i = 0; i < count; i++) {
- n += (new_settings[i] != old_settings[i] || (force_mask & (1u << i)) != 0);
- }
-
- output = GRPC_SLICE_MALLOC(9 + 6 * n);
- p = fill_header(GRPC_SLICE_START_PTR(output), 6 * n, 0);
-
- for (i = 0; i < count; i++) {
- if (new_settings[i] != old_settings[i] || (force_mask & (1u << i)) != 0) {
- *p++ = static_cast<uint8_t>(grpc_setting_id_to_wire_id[i] >> 8);
- *p++ = static_cast<uint8_t>(grpc_setting_id_to_wire_id[i]);
- *p++ = static_cast<uint8_t>(new_settings[i] >> 24);
- *p++ = static_cast<uint8_t>(new_settings[i] >> 16);
- *p++ = static_cast<uint8_t>(new_settings[i] >> 8);
- *p++ = static_cast<uint8_t>(new_settings[i]);
- old_settings[i] = new_settings[i];
- }
- }
-
- GPR_ASSERT(p == GRPC_SLICE_END_PTR(output));
-
- return output;
-}
-
grpc_slice grpc_chttp2_settings_ack_create(void) {
grpc_slice output = GRPC_SLICE_MALLOC(9);
fill_header(GRPC_SLICE_START_PTR(output), 0, GRPC_CHTTP2_FLAG_ACK);
@@ -95,10 +64,9 @@ grpc_slice grpc_chttp2_settings_ack_create(void) {
grpc_error_handle grpc_chttp2_settings_parser_begin_frame(
grpc_chttp2_settings_parser* parser, uint32_t length, uint8_t flags,
- uint32_t* settings) {
- parser->target_settings = settings;
- memcpy(parser->incoming_settings, settings,
- GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t));
+ grpc_core::Http2Settings& settings) {
+ parser->target_settings = &settings;
+ parser->incoming_settings.Init(settings);
parser->is_ack = 0;
parser->state = GRPC_CHTTP2_SPS_ID0;
if (flags == GRPC_CHTTP2_FLAG_ACK) {
@@ -125,7 +93,6 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p,
static_cast<grpc_chttp2_settings_parser*>(p);
const uint8_t* cur = GRPC_SLICE_START_PTR(slice);
const uint8_t* end = GRPC_SLICE_END_PTR(slice);
- grpc_chttp2_setting_id id;
if (parser->is_ack) {
return absl::OkStatus();
@@ -137,8 +104,7 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p,
if (cur == end) {
parser->state = GRPC_CHTTP2_SPS_ID0;
if (is_last) {
- memcpy(parser->target_settings, parser->incoming_settings,
- GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t));
+ *parser->target_settings = *parser->incoming_settings;
t->num_pending_induced_frames++;
grpc_slice_buffer_add(&t->qbuf, grpc_chttp2_settings_ack_create());
grpc_chttp2_initiate_write(t,
@@ -187,7 +153,7 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p,
parser->value |= (static_cast<uint32_t>(*cur)) << 8;
cur++;
ABSL_FALLTHROUGH_INTENDED;
- case GRPC_CHTTP2_SPS_VAL3:
+ case GRPC_CHTTP2_SPS_VAL3: {
if (cur == end) {
parser->state = GRPC_CHTTP2_SPS_VAL3;
return absl::OkStatus();
@@ -197,47 +163,35 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p,
parser->value |= *cur;
cur++;
- if (grpc_wire_id_to_setting_id(parser->id, &id)) {
- const grpc_chttp2_setting_parameters* sp =
- &grpc_chttp2_settings_parameters[id];
- if (parser->value < sp->min_value || parser->value > sp->max_value) {
- switch (sp->invalid_value_behavior) {
- case GRPC_CHTTP2_CLAMP_INVALID_VALUE:
- parser->value = grpc_core::Clamp(parser->value, sp->min_value,
- sp->max_value);
- break;
- case GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE:
- grpc_chttp2_goaway_append(
- t->last_new_stream_id, sp->error_value,
- grpc_slice_from_static_string("HTTP2 settings error"),
- &t->qbuf);
- return GRPC_ERROR_CREATE(absl::StrFormat(
- "invalid value %u passed for %s", parser->value, sp->name));
- }
- }
- if (id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE &&
- parser->incoming_settings[id] != parser->value) {
- t->initial_window_update += static_cast<int64_t>(parser->value) -
- parser->incoming_settings[id];
- if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) ||
- GRPC_TRACE_FLAG_ENABLED(grpc_flowctl_trace)) {
- gpr_log(GPR_INFO, "%p[%s] adding %d for initial_window change", t,
- t->is_client ? "cli" : "svr",
- static_cast<int>(t->initial_window_update));
- }
- }
- parser->incoming_settings[id] = parser->value;
- if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
- gpr_log(GPR_INFO, "CHTTP2:%s:%s: got setting %s = %d",
- t->is_client ? "CLI" : "SVR",
- std::string(t->peer_string.as_string_view()).c_str(),
- sp->name, parser->value);
+ if (parser->id == grpc_core::Http2Settings::kInitialWindowSizeWireId) {
+ t->initial_window_update +=
+ static_cast<int64_t>(parser->value) -
+ parser->incoming_settings->initial_window_size();
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) ||
+ GRPC_TRACE_FLAG_ENABLED(grpc_flowctl_trace)) {
+ gpr_log(GPR_INFO, "%p[%s] adding %d for initial_window change", t,
+ t->is_client ? "cli" : "svr",
+ static_cast<int>(t->initial_window_update));
}
- } else if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
- gpr_log(GPR_DEBUG, "CHTTP2: Ignoring unknown setting %d (value %d)",
- parser->id, parser->value);
}
- break;
+ auto error =
+ parser->incoming_settings->Apply(parser->id, parser->value);
+ if (error != GRPC_HTTP2_NO_ERROR) {
+ grpc_chttp2_goaway_append(
+ t->last_new_stream_id, error,
+ grpc_slice_from_static_string("HTTP2 settings error"), &t->qbuf);
+ return GRPC_ERROR_CREATE(absl::StrFormat(
+ "invalid value %u passed for %s", parser->value,
+ grpc_core::Http2Settings::WireIdToName(parser->id).c_str()));
+ }
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
+ gpr_log(GPR_INFO, "CHTTP2:%s:%s: got setting %s = %d",
+ t->is_client ? "CLI" : "SVR",
+ std::string(t->peer_string.as_string_view()).c_str(),
+ grpc_core::Http2Settings::WireIdToName(parser->id).c_str(),
+ parser->value);
+ }
+ } break;
}
}
}