#include <grpc/support/port_platform.h>
#include "src/core/ext/transport/chttp2/transport/frame_window_update.h"
-#include "src/core/ext/transport/chttp2/transport/internal.h"
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
+
+#include "src/core/ext/transport/chttp2/transport/internal.h"
grpc_slice grpc_chttp2_window_update_create(
- uint32_t id, uint32_t window_update, grpc_transport_one_way_stats* stats) {
+ uint32_t id, uint32_t window_delta, grpc_transport_one_way_stats* stats) {
static const size_t frame_size = 13;
grpc_slice slice = GRPC_SLICE_MALLOC(frame_size);
stats->header_bytes += frame_size;
uint8_t* p = GRPC_SLICE_START_PTR(slice);
- GPR_ASSERT(window_update);
+ GPR_ASSERT(window_delta);
*p++ = 0;
*p++ = 0;
*p++ = static_cast<uint8_t>(id >> 16);
*p++ = static_cast<uint8_t>(id >> 8);
*p++ = static_cast<uint8_t>(id);
- *p++ = static_cast<uint8_t>(window_update >> 24);
- *p++ = static_cast<uint8_t>(window_update >> 16);
- *p++ = static_cast<uint8_t>(window_update >> 8);
- *p++ = static_cast<uint8_t>(window_update);
+ *p++ = static_cast<uint8_t>(window_delta >> 24);
+ *p++ = static_cast<uint8_t>(window_delta >> 16);
+ *p++ = static_cast<uint8_t>(window_delta >> 8);
+ *p++ = static_cast<uint8_t>(window_delta);
return slice;
}
-grpc_error* grpc_chttp2_window_update_parser_begin_frame(
+grpc_error_handle grpc_chttp2_window_update_parser_begin_frame(
grpc_chttp2_window_update_parser* parser, uint32_t length, uint8_t flags) {
if (flags || length != 4) {
- char* msg;
- gpr_asprintf(&msg, "invalid window update: length=%d, flags=%02x", length,
- flags);
- grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
- gpr_free(msg);
- return err;
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrFormat(
+ "invalid window update: length=%d, flags=%02x", length, flags));
}
parser->byte = 0;
parser->amount = 0;
return GRPC_ERROR_NONE;
}
-grpc_error* grpc_chttp2_window_update_parser_parse(void* parser,
- grpc_chttp2_transport* t,
- grpc_chttp2_stream* s,
- grpc_slice slice,
- int is_last) {
- uint8_t* const beg = GRPC_SLICE_START_PTR(slice);
- uint8_t* const end = GRPC_SLICE_END_PTR(slice);
- uint8_t* cur = beg;
+grpc_error_handle grpc_chttp2_window_update_parser_parse(
+ void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s,
+ const grpc_slice& slice, int is_last) {
+ const uint8_t* const beg = GRPC_SLICE_START_PTR(slice);
+ const uint8_t* const end = GRPC_SLICE_END_PTR(slice);
+ const uint8_t* cur = beg;
grpc_chttp2_window_update_parser* p =
static_cast<grpc_chttp2_window_update_parser*>(parser);
}
if (p->byte == 4) {
- uint32_t received_update = p->amount;
- if (received_update == 0 || (received_update & 0x80000000u)) {
- char* msg;
- gpr_asprintf(&msg, "invalid window update bytes: %d", p->amount);
- grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
- gpr_free(msg);
- return err;
+ // top bit is reserved and must be ignored.
+ uint32_t received_update = p->amount & 0x7fffffffu;
+ if (received_update == 0) {
+ return GRPC_ERROR_CREATE_FROM_CPP_STRING(
+ absl::StrCat("invalid window update bytes: ", p->amount));
}
GPR_ASSERT(is_last);
if (t->incoming_stream_id != 0) {
if (s != nullptr) {
s->flow_control->RecvUpdate(received_update);
+ if (grpc_core::chttp2::
+ g_test_only_transport_flow_control_window_check &&
+ s->flow_control->remote_window_delta() >
+ grpc_core::chttp2::kMaxWindowDelta) {
+ GPR_ASSERT(false);
+ }
if (grpc_chttp2_list_remove_stalled_by_stream(t, s)) {
grpc_chttp2_mark_stream_writable(t, s);
grpc_chttp2_initiate_write(