grpc 1.83.0.pre1 → 1.83.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +1 -1
- data/src/core/ext/filters/http/message_compress/compression_filter.cc +25 -32
- data/src/core/ext/filters/http/message_compress/compression_filter.h +0 -1
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +48 -3
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +34 -2
- data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +55 -23
- data/src/core/ext/transport/chttp2/transport/frame_goaway.h +1 -0
- data/src/core/ext/transport/chttp2/transport/internal.h +6 -0
- data/src/core/ext/transport/chttp2/transport/parsing.cc +8 -0
- data/src/core/lib/compression/message_compress.cc +132 -97
- data/src/core/lib/compression/message_compress.h +24 -0
- data/src/core/lib/experiments/experiments.cc +21 -6
- data/src/core/lib/experiments/experiments.h +23 -6
- data/src/core/lib/surface/legacy_channel.cc +3 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b7cad78eb1a239fccff217f8dfda9db31f92a3f0f32b713a55cf26ebc782c5e3
|
|
4
|
+
data.tar.gz: '039647b8a259b5e5c561efd5e23c0831d2caa17184ad92f4da26b8de00fe2594'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a442ff623a15321dc764714d9389c6cf58db45b8d7f5a73d40161d9277f7ff34ea6796a8e07cc9eece2443a1f37f406bea2b6b19804311545c2ebb444fc1c8e2
|
|
7
|
+
data.tar.gz: cc1c384f869bee5ff9336804619580ef647f0f9d3ce643a7b1494d41fa6da73511b8d74b30eabbb39f0a9baaa1ed3f806a51f44c42332395b2a3643d2963b7e6
|
data/Makefile
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
#include <grpc/support/port_platform.h>
|
|
22
22
|
#include <inttypes.h>
|
|
23
23
|
|
|
24
|
+
#include <cstdint>
|
|
24
25
|
#include <functional>
|
|
25
26
|
#include <memory>
|
|
26
27
|
#include <optional>
|
|
@@ -44,6 +45,7 @@
|
|
|
44
45
|
#include "src/core/lib/surface/call.h"
|
|
45
46
|
#include "src/core/lib/transport/transport.h"
|
|
46
47
|
#include "src/core/telemetry/call_tracer.h"
|
|
48
|
+
#include "src/core/transport/message_size_service_config.h"
|
|
47
49
|
#include "src/core/util/grpc_check.h"
|
|
48
50
|
#include "src/core/util/latent_see.h"
|
|
49
51
|
#include "absl/status/status.h"
|
|
@@ -75,8 +77,6 @@ ServerCompressionFilter::Create(const ChannelArgs& args, ChannelFilter::Args) {
|
|
|
75
77
|
|
|
76
78
|
ChannelCompression::ChannelCompression(const ChannelArgs& args)
|
|
77
79
|
: max_recv_size_(GetMaxRecvSizeFromChannelArgs(args)),
|
|
78
|
-
message_size_service_config_parser_index_(
|
|
79
|
-
MessageSizeParser::ParserIndex()),
|
|
80
80
|
default_compression_algorithm_(
|
|
81
81
|
DefaultCompressionAlgorithmFromChannelArgs(args).value_or(
|
|
82
82
|
GRPC_COMPRESS_NONE)),
|
|
@@ -118,26 +118,25 @@ MessageHandle ChannelCompression::CompressMessage(
|
|
|
118
118
|
return message;
|
|
119
119
|
}
|
|
120
120
|
// Try to compress the payload.
|
|
121
|
-
SliceBuffer
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
tmp.c_slice_buffer());
|
|
121
|
+
std::optional<SliceBuffer> compressed =
|
|
122
|
+
MessageCompress(algorithm, *message->payload());
|
|
123
|
+
|
|
125
124
|
// If we achieved compression send it as compressed, otherwise send it as (to
|
|
126
125
|
// avoid spending cycles on the receiver decompressing).
|
|
127
|
-
if (
|
|
126
|
+
if (compressed.has_value()) {
|
|
128
127
|
if (GRPC_TRACE_FLAG_ENABLED(compression)) {
|
|
129
128
|
const char* algo_name;
|
|
130
|
-
|
|
131
|
-
const size_t
|
|
129
|
+
GRPC_CHECK(grpc_compression_algorithm_name(algorithm, &algo_name));
|
|
130
|
+
const size_t before_size = message->payload()->Length();
|
|
131
|
+
const size_t after_size = compressed->Length();
|
|
132
132
|
const float savings_ratio = 1.0f - (static_cast<float>(after_size) /
|
|
133
133
|
static_cast<float>(before_size));
|
|
134
|
-
GRPC_CHECK(grpc_compression_algorithm_name(algorithm, &algo_name));
|
|
135
134
|
LOG(INFO) << absl::StrFormat(
|
|
136
135
|
"Compressed[%s] %" PRIuPTR " bytes vs. %" PRIuPTR
|
|
137
136
|
" bytes (%.2f%% savings)",
|
|
138
137
|
algo_name, before_size, after_size, 100 * savings_ratio);
|
|
139
138
|
}
|
|
140
|
-
|
|
139
|
+
*message->payload() = std::move(*compressed);
|
|
141
140
|
flags |= GRPC_WRITE_INTERNAL_COMPRESS;
|
|
142
141
|
if (call_tracer != nullptr) {
|
|
143
142
|
call_tracer->RecordSendCompressedMessage(*message);
|
|
@@ -148,7 +147,7 @@ MessageHandle ChannelCompression::CompressMessage(
|
|
|
148
147
|
GRPC_CHECK(grpc_compression_algorithm_name(algorithm, &algo_name));
|
|
149
148
|
LOG(INFO) << "Algorithm '" << algo_name
|
|
150
149
|
<< "' enabled but decided not to compress. Input size: "
|
|
151
|
-
<< payload->Length();
|
|
150
|
+
<< message->payload()->Length();
|
|
152
151
|
}
|
|
153
152
|
}
|
|
154
153
|
return message;
|
|
@@ -180,15 +179,17 @@ absl::StatusOr<MessageHandle> ChannelCompression::DecompressMessage(
|
|
|
180
179
|
return std::move(message);
|
|
181
180
|
}
|
|
182
181
|
// Try to decompress the payload.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
std::optional<uint32_t> max_output_size = IsMessageSizeRefactoringEnabled()
|
|
183
|
+
? args.max_recv_message_length
|
|
184
|
+
: std::nullopt;
|
|
185
|
+
absl::StatusOr<SliceBuffer> decompressed_slices =
|
|
186
|
+
MessageDecompress(args.algorithm, *message->payload(), max_output_size);
|
|
187
|
+
if (!decompressed_slices.ok()) {
|
|
188
|
+
return decompressed_slices.status();
|
|
189
189
|
}
|
|
190
|
-
|
|
191
|
-
message
|
|
190
|
+
|
|
191
|
+
// Move the decompressed slices into the message.
|
|
192
|
+
*message->payload() = std::move(*decompressed_slices);
|
|
192
193
|
message->mutable_flags() &= ~GRPC_WRITE_INTERNAL_COMPRESS;
|
|
193
194
|
message->mutable_flags() |= GRPC_WRITE_INTERNAL_TEST_ONLY_WAS_COMPRESSED;
|
|
194
195
|
if (call_tracer != nullptr) {
|
|
@@ -213,18 +214,10 @@ grpc_compression_algorithm ChannelCompression::HandleOutgoingMetadata(
|
|
|
213
214
|
ChannelCompression::DecompressArgs ChannelCompression::HandleIncomingMetadata(
|
|
214
215
|
const grpc_metadata_batch& incoming_metadata) {
|
|
215
216
|
// Configure max receive size.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (limits != nullptr && limits->max_recv_size().has_value() &&
|
|
221
|
-
(!max_recv_message_length.has_value() ||
|
|
222
|
-
*limits->max_recv_size() < *max_recv_message_length)) {
|
|
223
|
-
max_recv_message_length = limits->max_recv_size();
|
|
224
|
-
}
|
|
225
|
-
return DecompressArgs{incoming_metadata.get(GrpcEncodingMetadata())
|
|
226
|
-
.value_or(GRPC_COMPRESS_NONE),
|
|
227
|
-
max_recv_message_length};
|
|
217
|
+
return DecompressArgs{
|
|
218
|
+
incoming_metadata.get(GrpcEncodingMetadata())
|
|
219
|
+
.value_or(GRPC_COMPRESS_NONE),
|
|
220
|
+
GetMaxRecvSizeFromCallContext(GetContext<Arena>(), max_recv_size_)};
|
|
228
221
|
}
|
|
229
222
|
|
|
230
223
|
void ClientCompressionFilter::Call::OnClientInitialMetadata(
|
|
@@ -107,7 +107,6 @@ class ChannelCompression {
|
|
|
107
107
|
private:
|
|
108
108
|
// Max receive message length, if set.
|
|
109
109
|
std::optional<uint32_t> max_recv_size_;
|
|
110
|
-
size_t message_size_service_config_parser_index_;
|
|
111
110
|
// The default, channel-level, compression algorithm.
|
|
112
111
|
grpc_compression_algorithm default_compression_algorithm_;
|
|
113
112
|
// Enabled compression algorithms.
|
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
#include "src/core/telemetry/stats_data.h"
|
|
107
107
|
#include "src/core/telemetry/tcp_tracer.h"
|
|
108
108
|
#include "src/core/transport/auth_context.h"
|
|
109
|
+
#include "src/core/transport/message_size_service_config.h"
|
|
109
110
|
#include "src/core/util/bitset.h"
|
|
110
111
|
#include "src/core/util/crash.h"
|
|
111
112
|
#include "src/core/util/debug_location.h"
|
|
@@ -816,6 +817,7 @@ grpc_chttp2_transport::grpc_chttp2_transport(
|
|
|
816
817
|
Ref(), &init_keepalive_ping_locked),
|
|
817
818
|
absl::OkStatus());
|
|
818
819
|
|
|
820
|
+
// TODO(tjagtap) : [PH2][P0] : Do this for PH2.
|
|
819
821
|
if (flow_control.bdp_probe()) {
|
|
820
822
|
bdp_ping_blocked = true;
|
|
821
823
|
grpc_chttp2_act_on_flowctl_action(flow_control.PeriodicUpdate(), this,
|
|
@@ -859,6 +861,9 @@ grpc_chttp2_transport::grpc_chttp2_transport(
|
|
|
859
861
|
epte->SetSocketNode(channelz_socket);
|
|
860
862
|
}
|
|
861
863
|
}
|
|
864
|
+
|
|
865
|
+
max_recv_message_length =
|
|
866
|
+
grpc_core::GetMaxRecvSizeFromChannelArgs(channel_args);
|
|
862
867
|
}
|
|
863
868
|
|
|
864
869
|
static void destroy_transport_locked(void* tp, grpc_error_handle /*error*/) {
|
|
@@ -879,6 +884,10 @@ static void close_transport_locked(grpc_chttp2_transport* t,
|
|
|
879
884
|
grpc_error_handle error) {
|
|
880
885
|
end_all_the_calls(t, error);
|
|
881
886
|
cancel_pings(t, error);
|
|
887
|
+
if (t->transport_framing_endpoint_extension != nullptr) {
|
|
888
|
+
t->transport_framing_endpoint_extension->SetSendFrameCallback(nullptr);
|
|
889
|
+
t->transport_framing_endpoint_extension = nullptr;
|
|
890
|
+
}
|
|
882
891
|
if (t->closed_with_error.ok()) {
|
|
883
892
|
if (!grpc_error_has_clear_grpc_status(error)) {
|
|
884
893
|
error =
|
|
@@ -1507,7 +1516,8 @@ static grpc_closure* add_closure_barrier(grpc_closure* closure) {
|
|
|
1507
1516
|
return closure;
|
|
1508
1517
|
}
|
|
1509
1518
|
|
|
1510
|
-
static void
|
|
1519
|
+
static void null_then_sched_closure_with_error(grpc_closure** closure,
|
|
1520
|
+
grpc_error_handle error) {
|
|
1511
1521
|
grpc_closure* c = *closure;
|
|
1512
1522
|
*closure = nullptr;
|
|
1513
1523
|
// null_then_schedule_closure might be run during a start_batch which might
|
|
@@ -1516,7 +1526,11 @@ static void null_then_sched_closure(grpc_closure** closure) {
|
|
|
1516
1526
|
// completion, have the application see it, and make a new operation on the
|
|
1517
1527
|
// call which recycles the batch BEFORE the call to start_batch completes,
|
|
1518
1528
|
// forcing a race.
|
|
1519
|
-
grpc_core::ExecCtx::Run(DEBUG_LOCATION, c,
|
|
1529
|
+
grpc_core::ExecCtx::Run(DEBUG_LOCATION, c, error);
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
static void null_then_sched_closure(grpc_closure** closure) {
|
|
1533
|
+
null_then_sched_closure_with_error(closure, absl::OkStatus());
|
|
1520
1534
|
}
|
|
1521
1535
|
|
|
1522
1536
|
void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t,
|
|
@@ -2343,6 +2357,8 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_chttp2_transport* t,
|
|
|
2343
2357
|
t->registered_method_matcher_cb(t->accept_stream_cb_user_data,
|
|
2344
2358
|
s->recv_initial_metadata);
|
|
2345
2359
|
}
|
|
2360
|
+
s->max_recv_message_length =
|
|
2361
|
+
GetMaxRecvSizeFromCallContext(s->arena, t->max_recv_message_length);
|
|
2346
2362
|
null_then_sched_closure(&s->recv_initial_metadata_ready);
|
|
2347
2363
|
}
|
|
2348
2364
|
}
|
|
@@ -2415,7 +2431,36 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t,
|
|
|
2415
2431
|
*s->call_failed_before_recv_message =
|
|
2416
2432
|
(s->published_metadata[1] != GRPC_METADATA_PUBLISHED_AT_CLOSE);
|
|
2417
2433
|
}
|
|
2418
|
-
|
|
2434
|
+
if (s->seen_error && s->message_size_limit_exceeded) {
|
|
2435
|
+
null_then_sched_closure_with_error(&s->recv_message_ready, error);
|
|
2436
|
+
} else {
|
|
2437
|
+
null_then_sched_closure(&s->recv_message_ready);
|
|
2438
|
+
}
|
|
2439
|
+
} else if (s->seen_error && s->message_size_limit_exceeded) {
|
|
2440
|
+
null_then_sched_closure_with_error(&s->recv_message_ready, error);
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
if (grpc_core::IsMessageSizeRefactoringEnabled() && s->seen_error &&
|
|
2444
|
+
s->message_size_limit_exceeded) {
|
|
2445
|
+
s->message_size_limit_exceeded = false;
|
|
2446
|
+
// Explicitly cancel the stream to fail the RPC immediately.
|
|
2447
|
+
// We delay the cancellation until the recv_message_ready closure is
|
|
2448
|
+
// executed to prevent re-entrancy issues. When the HTTP/2 frame deframer
|
|
2449
|
+
// in `grpc_deframe_unprocessed_incoming_frames`
|
|
2450
|
+
// returns a size violation error, invoking `grpc_chttp2_cancel_stream`
|
|
2451
|
+
// immediately triggers `grpc_chttp2_mark_stream_closed`. This in turn
|
|
2452
|
+
// synchronously re-enters `grpc_chttp2_maybe_complete_recv_message` while
|
|
2453
|
+
// the original deframing loop is still active on the call stack.
|
|
2454
|
+
//
|
|
2455
|
+
// Because the re-entrant invocation observes that the incoming frame
|
|
2456
|
+
// storage has been cleared but `s->recv_message_ready` is still non-null,
|
|
2457
|
+
// it preemptively schedules the closure as a standard/non-error stream
|
|
2458
|
+
// termination (i.e., via `null_then_sched_closure(...,
|
|
2459
|
+
// absl::OkStatus())`). By the time control returns to the initial (outer)
|
|
2460
|
+
// deframing loop to execute `null_then_sched_closure_with_error`, the
|
|
2461
|
+
// closure pointer is already null, causing the original error context to
|
|
2462
|
+
// be discarded.
|
|
2463
|
+
grpc_chttp2_cancel_stream(t, s, error, true, nullptr);
|
|
2419
2464
|
}
|
|
2420
2465
|
}();
|
|
2421
2466
|
|
|
@@ -48,6 +48,7 @@ absl::Status grpc_chttp2_data_parser_begin_frame(uint8_t flags,
|
|
|
48
48
|
} else {
|
|
49
49
|
s->received_last_frame = false;
|
|
50
50
|
}
|
|
51
|
+
++s->num_frames;
|
|
51
52
|
|
|
52
53
|
return absl::OkStatus();
|
|
53
54
|
}
|
|
@@ -123,6 +124,24 @@ grpc_core::Poll<grpc_error_handle> grpc_deframe_unprocessed_incoming_frames(
|
|
|
123
124
|
(static_cast<uint32_t>(header[3]) << 8) |
|
|
124
125
|
static_cast<uint32_t>(header[4]);
|
|
125
126
|
|
|
127
|
+
if (grpc_core::IsMessageSizeRefactoringEnabled()) {
|
|
128
|
+
if (s->max_recv_message_length.has_value() &&
|
|
129
|
+
length > *(s->max_recv_message_length)) {
|
|
130
|
+
error = GRPC_ERROR_CREATE(
|
|
131
|
+
absl::StrFormat("%s: Received message larger than max (%d vs. %u)",
|
|
132
|
+
s->t->is_client ? "CLIENT" : "SERVER", length,
|
|
133
|
+
*(s->max_recv_message_length)));
|
|
134
|
+
error = grpc_error_set_int(error, grpc_core::StatusIntProperty::kStreamId,
|
|
135
|
+
static_cast<intptr_t>(s->id));
|
|
136
|
+
// Attach the explicit gRPC status code to fail the RPC correctly.
|
|
137
|
+
error =
|
|
138
|
+
grpc_error_set_int(error, grpc_core::StatusIntProperty::kRpcStatus,
|
|
139
|
+
GRPC_STATUS_RESOURCE_EXHAUSTED);
|
|
140
|
+
s->message_size_limit_exceeded = true;
|
|
141
|
+
return error;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
126
145
|
if (slices->length < length + GRPC_HEADER_SIZE_IN_BYTES) {
|
|
127
146
|
if (min_progress_size != nullptr) {
|
|
128
147
|
*min_progress_size = length + GRPC_HEADER_SIZE_IN_BYTES - slices->length;
|
|
@@ -138,6 +157,7 @@ grpc_core::Poll<grpc_error_handle> grpc_deframe_unprocessed_incoming_frames(
|
|
|
138
157
|
grpc_slice_buffer_move_first_into_buffer(slices, GRPC_HEADER_SIZE_IN_BYTES,
|
|
139
158
|
header);
|
|
140
159
|
grpc_slice_buffer_move_first(slices, length, stream_out->c_slice_buffer());
|
|
160
|
+
s->num_frames = 0;
|
|
141
161
|
}
|
|
142
162
|
|
|
143
163
|
return absl::OkStatus();
|
|
@@ -148,8 +168,20 @@ grpc_error_handle grpc_chttp2_data_parser_parse(void* /*parser*/,
|
|
|
148
168
|
grpc_chttp2_stream* s,
|
|
149
169
|
const grpc_slice& slice,
|
|
150
170
|
int is_last) {
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
const size_t slice_len = GRPC_SLICE_LENGTH(slice);
|
|
172
|
+
bool is_small_frame = 0 < slice_len && slice_len < GRPC_SLICE_INLINED_SIZE;
|
|
173
|
+
bool multiple_small_frames =
|
|
174
|
+
(s->num_frames >= 64) &&
|
|
175
|
+
((s->frame_storage.length / s->num_frames) < GRPC_SLICE_INLINED_SIZE);
|
|
176
|
+
if (GPR_UNLIKELY(multiple_small_frames && is_small_frame &&
|
|
177
|
+
grpc_core::IsHeaderDataFrameEnabled())) {
|
|
178
|
+
uint8_t* append_ptr =
|
|
179
|
+
grpc_slice_buffer_tiny_add(&s->frame_storage, slice_len);
|
|
180
|
+
memcpy(append_ptr, GRPC_SLICE_START_PTR(slice), slice_len);
|
|
181
|
+
} else {
|
|
182
|
+
grpc_core::CSliceRef(slice);
|
|
183
|
+
grpc_slice_buffer_add(&s->frame_storage, slice);
|
|
184
|
+
}
|
|
153
185
|
grpc_chttp2_maybe_complete_recv_message(t, s);
|
|
154
186
|
|
|
155
187
|
if (is_last) {
|
|
@@ -31,11 +31,15 @@
|
|
|
31
31
|
#include "absl/strings/string_view.h"
|
|
32
32
|
|
|
33
33
|
void grpc_chttp2_goaway_parser_init(grpc_chttp2_goaway_parser* p) {
|
|
34
|
-
|
|
34
|
+
if (!grpc_core::IsPh2Perf01Enabled()) {
|
|
35
|
+
p->debug_data = nullptr;
|
|
36
|
+
}
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
void grpc_chttp2_goaway_parser_destroy(grpc_chttp2_goaway_parser* p) {
|
|
38
|
-
|
|
40
|
+
if (!grpc_core::IsPh2Perf01Enabled()) {
|
|
41
|
+
gpr_free(p->debug_data);
|
|
42
|
+
}
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
grpc_error_handle grpc_chttp2_goaway_parser_begin_frame(
|
|
@@ -45,10 +49,14 @@ grpc_error_handle grpc_chttp2_goaway_parser_begin_frame(
|
|
|
45
49
|
absl::StrFormat("goaway frame too short (%d bytes)", length));
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
gpr_free(p->debug_data);
|
|
49
52
|
p->debug_length = length - 8;
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
if (grpc_core::IsPh2Perf01Enabled()) {
|
|
54
|
+
p->debug_slice_buffer.Clear();
|
|
55
|
+
} else {
|
|
56
|
+
gpr_free(p->debug_data);
|
|
57
|
+
p->debug_data = static_cast<char*>(gpr_malloc(p->debug_length));
|
|
58
|
+
p->debug_pos = 0;
|
|
59
|
+
}
|
|
52
60
|
p->state = GRPC_CHTTP2_GOAWAY_LSI0;
|
|
53
61
|
return absl::OkStatus();
|
|
54
62
|
}
|
|
@@ -130,24 +138,48 @@ grpc_error_handle grpc_chttp2_goaway_parser_parse(void* parser,
|
|
|
130
138
|
++cur;
|
|
131
139
|
[[fallthrough]];
|
|
132
140
|
case GRPC_CHTTP2_GOAWAY_DEBUG:
|
|
133
|
-
if (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
141
|
+
if (grpc_core::IsPh2Perf01Enabled()) {
|
|
142
|
+
if (end != cur) {
|
|
143
|
+
p->debug_slice_buffer.AppendIndexed(
|
|
144
|
+
grpc_core::Slice::FromCopiedBuffer(
|
|
145
|
+
cur, static_cast<size_t>(end - cur)));
|
|
146
|
+
}
|
|
147
|
+
GRPC_CHECK(p->debug_slice_buffer.Length() <= p->debug_length);
|
|
148
|
+
p->state = GRPC_CHTTP2_GOAWAY_DEBUG;
|
|
149
|
+
if (is_last) {
|
|
150
|
+
std::string debug_str = p->debug_slice_buffer.JoinIntoString();
|
|
151
|
+
|
|
152
|
+
grpc_chttp2_add_incoming_goaway(t, p->error_code, p->last_stream_id,
|
|
153
|
+
absl::string_view(debug_str));
|
|
154
|
+
|
|
155
|
+
t->http2_ztrace_collector.Append(
|
|
156
|
+
[last_stream_id = p->last_stream_id, error_code = p->error_code,
|
|
157
|
+
debug_str = std::move(debug_str)]() mutable {
|
|
158
|
+
return grpc_core::H2GoAwayTrace<true>{
|
|
159
|
+
last_stream_id, error_code, std::move(debug_str)};
|
|
160
|
+
});
|
|
161
|
+
p->debug_slice_buffer.Clear();
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
if (end != cur) {
|
|
165
|
+
memcpy(p->debug_data + p->debug_pos, cur,
|
|
166
|
+
static_cast<size_t>(end - cur));
|
|
167
|
+
}
|
|
168
|
+
GRPC_CHECK((size_t)(end - cur) < UINT32_MAX - p->debug_pos);
|
|
169
|
+
p->debug_pos += static_cast<uint32_t>(end - cur);
|
|
170
|
+
p->state = GRPC_CHTTP2_GOAWAY_DEBUG;
|
|
171
|
+
if (is_last) {
|
|
172
|
+
t->http2_ztrace_collector.Append([p]() {
|
|
173
|
+
return grpc_core::H2GoAwayTrace<true>{
|
|
174
|
+
p->last_stream_id, p->error_code,
|
|
175
|
+
std::string(absl::string_view(p->debug_data, p->debug_length))};
|
|
176
|
+
});
|
|
177
|
+
grpc_chttp2_add_incoming_goaway(
|
|
178
|
+
t, p->error_code, p->last_stream_id,
|
|
179
|
+
absl::string_view(p->debug_data, p->debug_length));
|
|
180
|
+
gpr_free(p->debug_data);
|
|
181
|
+
p->debug_data = nullptr;
|
|
182
|
+
}
|
|
151
183
|
}
|
|
152
184
|
return absl::OkStatus();
|
|
153
185
|
}
|
|
@@ -629,6 +629,8 @@ struct grpc_chttp2_transport final : public grpc_core::FilterStackTransport,
|
|
|
629
629
|
|
|
630
630
|
GPR_NO_UNIQUE_ADDRESS grpc_core::latent_see::Flow write_flow;
|
|
631
631
|
|
|
632
|
+
std::optional<uint32_t> max_recv_message_length;
|
|
633
|
+
|
|
632
634
|
// Current mitigation engine, retrieved once per connection.
|
|
633
635
|
grpc_core::RefCountedPtr<grpc_core::MitigationEngine> mitigation_engine;
|
|
634
636
|
};
|
|
@@ -718,6 +720,7 @@ struct grpc_chttp2_stream {
|
|
|
718
720
|
grpc_metadata_batch trailing_metadata_buffer;
|
|
719
721
|
|
|
720
722
|
grpc_slice_buffer frame_storage; // protected by t combiner
|
|
723
|
+
size_t num_frames = 0; // protected by t combiner
|
|
721
724
|
|
|
722
725
|
grpc_core::Timestamp deadline = grpc_core::Timestamp::InfFuture();
|
|
723
726
|
|
|
@@ -777,6 +780,9 @@ struct grpc_chttp2_stream {
|
|
|
777
780
|
// The last time a stream window update was received.
|
|
778
781
|
grpc_core::Timestamp last_window_update_time =
|
|
779
782
|
grpc_core::Timestamp::InfPast();
|
|
783
|
+
|
|
784
|
+
bool message_size_limit_exceeded = false;
|
|
785
|
+
std::optional<uint32_t> max_recv_message_length;
|
|
780
786
|
};
|
|
781
787
|
|
|
782
788
|
/// Transport writing call flow:
|
|
@@ -430,6 +430,14 @@ static grpc_error_handle init_frame_parser(grpc_chttp2_transport* t,
|
|
|
430
430
|
t->incoming_frame_type));
|
|
431
431
|
}
|
|
432
432
|
t->is_first_frame = false;
|
|
433
|
+
|
|
434
|
+
if (grpc_core::IsPh2Perf01Enabled() &&
|
|
435
|
+
t->incoming_frame_size > t->settings.acked().max_frame_size()) {
|
|
436
|
+
return GRPC_ERROR_CREATE(absl::StrFormat(
|
|
437
|
+
"Frame size %d is larger than max frame size %d",
|
|
438
|
+
t->incoming_frame_size, t->settings.acked().max_frame_size()));
|
|
439
|
+
}
|
|
440
|
+
|
|
433
441
|
if (t->expect_continuation_stream_id != 0) {
|
|
434
442
|
if (t->incoming_frame_type != GRPC_CHTTP2_FRAME_CONTINUATION) {
|
|
435
443
|
return GRPC_ERROR_CREATE(
|
|
@@ -25,168 +25,203 @@
|
|
|
25
25
|
#include <zconf.h>
|
|
26
26
|
#include <zlib.h>
|
|
27
27
|
|
|
28
|
+
#include <algorithm>
|
|
29
|
+
#include <cstdint>
|
|
30
|
+
#include <optional>
|
|
31
|
+
|
|
28
32
|
#include "src/core/lib/slice/slice.h"
|
|
29
33
|
#include "src/core/util/grpc_check.h"
|
|
34
|
+
#include "src/core/util/status_helper.h"
|
|
30
35
|
#include "absl/log/log.h"
|
|
36
|
+
#include "absl/status/status.h"
|
|
37
|
+
#include "absl/status/statusor.h"
|
|
31
38
|
|
|
32
39
|
#define OUTPUT_BLOCK_SIZE 1024
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
namespace grpc_core {
|
|
42
|
+
namespace {
|
|
43
|
+
|
|
44
|
+
absl::StatusOr<SliceBuffer> ZlibBody(z_stream* zs, const SliceBuffer& input,
|
|
45
|
+
int (*flate)(z_stream* zs, int flush),
|
|
46
|
+
std::optional<uint32_t> max_output_size) {
|
|
37
47
|
int r = Z_STREAM_END; // Do not fail on an empty input.
|
|
38
48
|
int flush;
|
|
39
49
|
size_t i;
|
|
40
|
-
|
|
50
|
+
uint32_t remaining_output_size = max_output_size.value_or(UINT32_MAX);
|
|
51
|
+
SliceBuffer output_sb;
|
|
41
52
|
const uInt uint_max = ~uInt{0};
|
|
53
|
+
auto outbuf = MutableSlice::CreateUninitialized(
|
|
54
|
+
std::min<uint32_t>(remaining_output_size, OUTPUT_BLOCK_SIZE));
|
|
42
55
|
|
|
43
|
-
GRPC_CHECK(
|
|
44
|
-
zs->avail_out = static_cast<uInt>
|
|
45
|
-
zs->next_out =
|
|
56
|
+
GRPC_CHECK(outbuf.length() <= uint_max);
|
|
57
|
+
zs->avail_out = static_cast<uInt>(outbuf.length());
|
|
58
|
+
zs->next_out = const_cast<uint8_t*>(outbuf.begin());
|
|
46
59
|
flush = Z_NO_FLUSH;
|
|
47
|
-
for (i = 0; i < input
|
|
48
|
-
if (i == input
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
60
|
+
for (i = 0; i < input.Count(); i++) {
|
|
61
|
+
if (i == input.Count() - 1) {
|
|
62
|
+
flush = Z_FINISH;
|
|
63
|
+
}
|
|
64
|
+
GRPC_CHECK(input[i].length() <= uint_max);
|
|
65
|
+
zs->avail_in = static_cast<uInt>(input[i].length());
|
|
66
|
+
zs->next_in = const_cast<uint8_t*>(input[i].begin());
|
|
52
67
|
do {
|
|
53
68
|
if (zs->avail_out == 0) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
if (max_output_size.has_value() && remaining_output_size == 0) {
|
|
70
|
+
VLOG(2) << "zlib: max provided output size exceeded";
|
|
71
|
+
return absl::ResourceExhaustedError(
|
|
72
|
+
"Decompressed message larger than max");
|
|
73
|
+
}
|
|
74
|
+
output_sb.AppendIndexed(Slice(std::move(outbuf)));
|
|
75
|
+
outbuf = MutableSlice::CreateUninitialized(
|
|
76
|
+
std::min<uint32_t>(remaining_output_size, OUTPUT_BLOCK_SIZE));
|
|
77
|
+
// Update remaining output size to reflect the size of the slice we just
|
|
78
|
+
// filled with compressed / decompressed data.
|
|
79
|
+
if (max_output_size.has_value()) {
|
|
80
|
+
remaining_output_size -= outbuf.length();
|
|
81
|
+
}
|
|
82
|
+
GRPC_CHECK(outbuf.length() <= uint_max);
|
|
83
|
+
zs->avail_out = static_cast<uInt>(outbuf.length());
|
|
84
|
+
zs->next_out = const_cast<uint8_t*>(outbuf.begin());
|
|
59
85
|
}
|
|
60
86
|
r = flate(zs, flush);
|
|
61
87
|
if (r < 0 && r != Z_BUF_ERROR /* not fatal */) {
|
|
62
88
|
VLOG(2) << "zlib error (" << r << ")";
|
|
63
|
-
|
|
89
|
+
return absl::InternalError("Decompression failed due to zlib error");
|
|
64
90
|
}
|
|
65
91
|
} while (zs->avail_out == 0);
|
|
66
92
|
if (zs->avail_in) {
|
|
67
93
|
VLOG(2) << "zlib: not all input consumed";
|
|
68
|
-
|
|
94
|
+
return absl::InternalError(
|
|
95
|
+
"Decompression failed due to not all input "
|
|
96
|
+
"consumed");
|
|
69
97
|
}
|
|
70
98
|
}
|
|
71
99
|
if (r != Z_STREAM_END) {
|
|
72
100
|
VLOG(2) << "zlib: Data error";
|
|
73
|
-
|
|
101
|
+
return absl::InternalError("Decompression failed due to data error");
|
|
74
102
|
}
|
|
75
103
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
104
|
+
// TODO(vigneshbabu): Add a Truncate() method to the Slice type to avoid using
|
|
105
|
+
// the underlying C type here.
|
|
106
|
+
grpc_slice slice = outbuf.TakeCSlice();
|
|
107
|
+
if (slice.refcount) {
|
|
108
|
+
slice.data.refcounted.length -= zs->avail_out;
|
|
109
|
+
} else {
|
|
110
|
+
slice.data.inlined.length -= zs->avail_out;
|
|
111
|
+
}
|
|
112
|
+
output_sb.AppendIndexed(Slice(slice));
|
|
113
|
+
return output_sb;
|
|
85
114
|
}
|
|
86
115
|
|
|
87
|
-
|
|
88
|
-
unsigned int size) {
|
|
116
|
+
void* ZallocGpr(void* /*opaque*/, unsigned int items, unsigned int size) {
|
|
89
117
|
return gpr_malloc(items * size);
|
|
90
118
|
}
|
|
91
119
|
|
|
92
|
-
|
|
120
|
+
void ZFreeGpr(void* /*opaque*/, void* address) { gpr_free(address); }
|
|
93
121
|
|
|
94
|
-
|
|
95
|
-
int gzip) {
|
|
122
|
+
std::optional<SliceBuffer> ZlibCompress(const SliceBuffer& input, int gzip) {
|
|
96
123
|
z_stream zs;
|
|
97
|
-
|
|
98
|
-
size_t i;
|
|
99
|
-
size_t count_before = output->count;
|
|
100
|
-
size_t length_before = output->length;
|
|
124
|
+
absl::StatusOr<SliceBuffer> compression_result;
|
|
101
125
|
memset(&zs, 0, sizeof(zs));
|
|
102
|
-
zs.zalloc =
|
|
103
|
-
zs.zfree =
|
|
104
|
-
r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
|
|
105
|
-
|
|
126
|
+
zs.zalloc = ZallocGpr;
|
|
127
|
+
zs.zfree = ZFreeGpr;
|
|
128
|
+
bool r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
|
|
129
|
+
15 | (gzip ? 16 : 0), 8, Z_DEFAULT_STRATEGY);
|
|
106
130
|
GRPC_CHECK(r == Z_OK);
|
|
107
|
-
|
|
108
|
-
if (!r) {
|
|
109
|
-
for (i = count_before; i < output->count; i++) {
|
|
110
|
-
grpc_core::CSliceUnref(output->slices[i]);
|
|
111
|
-
}
|
|
112
|
-
output->count = count_before;
|
|
113
|
-
output->length = length_before;
|
|
114
|
-
}
|
|
131
|
+
compression_result = ZlibBody(&zs, input, deflate, input.Length());
|
|
115
132
|
deflateEnd(&zs);
|
|
116
|
-
|
|
133
|
+
if (compression_result.ok() &&
|
|
134
|
+
compression_result->Length() < input.Length()) {
|
|
135
|
+
return std::move(*compression_result);
|
|
136
|
+
}
|
|
137
|
+
return std::nullopt;
|
|
117
138
|
}
|
|
118
139
|
|
|
119
|
-
|
|
120
|
-
|
|
140
|
+
absl::StatusOr<SliceBuffer> ZlibDecompress(
|
|
141
|
+
const SliceBuffer& input, int gzip,
|
|
142
|
+
std::optional<uint32_t> max_output_size) {
|
|
121
143
|
z_stream zs;
|
|
122
|
-
|
|
123
|
-
size_t i;
|
|
124
|
-
size_t count_before = output->count;
|
|
125
|
-
size_t length_before = output->length;
|
|
144
|
+
absl::StatusOr<SliceBuffer> decompression_result;
|
|
126
145
|
memset(&zs, 0, sizeof(zs));
|
|
127
|
-
zs.zalloc =
|
|
128
|
-
zs.zfree =
|
|
129
|
-
r = inflateInit2(&zs, 15 | (gzip ? 16 : 0));
|
|
146
|
+
zs.zalloc = ZallocGpr;
|
|
147
|
+
zs.zfree = ZFreeGpr;
|
|
148
|
+
bool r = inflateInit2(&zs, 15 | (gzip ? 16 : 0));
|
|
130
149
|
GRPC_CHECK(r == Z_OK);
|
|
131
|
-
|
|
132
|
-
if (!r) {
|
|
133
|
-
for (i = count_before; i < output->count; i++) {
|
|
134
|
-
grpc_core::CSliceUnref(output->slices[i]);
|
|
135
|
-
}
|
|
136
|
-
output->count = count_before;
|
|
137
|
-
output->length = length_before;
|
|
138
|
-
}
|
|
150
|
+
decompression_result = ZlibBody(&zs, input, inflate, max_output_size);
|
|
139
151
|
inflateEnd(&zs);
|
|
140
|
-
return
|
|
152
|
+
return decompression_result;
|
|
141
153
|
}
|
|
142
154
|
|
|
143
|
-
|
|
144
|
-
size_t i;
|
|
145
|
-
for (i = 0; i < input->count; i++) {
|
|
146
|
-
grpc_slice_buffer_add(output, grpc_core::CSliceRef(input->slices[i]));
|
|
147
|
-
}
|
|
148
|
-
return 1;
|
|
149
|
-
}
|
|
155
|
+
} // namespace
|
|
150
156
|
|
|
151
|
-
|
|
152
|
-
|
|
157
|
+
std::optional<SliceBuffer> MessageCompress(grpc_compression_algorithm algorithm,
|
|
158
|
+
const SliceBuffer& input) {
|
|
153
159
|
switch (algorithm) {
|
|
154
160
|
case GRPC_COMPRESS_NONE:
|
|
155
161
|
// the fallback path always needs to be send uncompressed: we simply
|
|
156
162
|
// rely on that here
|
|
157
|
-
return
|
|
163
|
+
return std::nullopt;
|
|
158
164
|
case GRPC_COMPRESS_DEFLATE:
|
|
159
|
-
return
|
|
165
|
+
return ZlibCompress(input, 0);
|
|
160
166
|
case GRPC_COMPRESS_GZIP:
|
|
161
|
-
return
|
|
167
|
+
return ZlibCompress(input, 1);
|
|
162
168
|
case GRPC_COMPRESS_ALGORITHMS_COUNT:
|
|
163
169
|
break;
|
|
164
170
|
}
|
|
165
171
|
LOG(ERROR) << "invalid compression algorithm " << algorithm;
|
|
166
|
-
return
|
|
172
|
+
return std::nullopt;
|
|
167
173
|
}
|
|
168
174
|
|
|
175
|
+
absl::StatusOr<SliceBuffer> MessageDecompress(
|
|
176
|
+
grpc_compression_algorithm algorithm, const SliceBuffer& input,
|
|
177
|
+
std::optional<uint32_t> max_output_size) {
|
|
178
|
+
switch (algorithm) {
|
|
179
|
+
case GRPC_COMPRESS_NONE: {
|
|
180
|
+
SliceBuffer output;
|
|
181
|
+
output.Append(input);
|
|
182
|
+
return output;
|
|
183
|
+
}
|
|
184
|
+
case GRPC_COMPRESS_DEFLATE:
|
|
185
|
+
return ZlibDecompress(input, 0, max_output_size);
|
|
186
|
+
case GRPC_COMPRESS_GZIP:
|
|
187
|
+
return ZlibDecompress(input, 1, max_output_size);
|
|
188
|
+
case GRPC_COMPRESS_ALGORITHMS_COUNT:
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
LOG(ERROR) << "invalid compression algorithm " << algorithm;
|
|
192
|
+
return absl::InternalError("Invalid compression algorithm");
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
} // namespace grpc_core
|
|
196
|
+
|
|
169
197
|
int grpc_msg_compress(grpc_compression_algorithm algorithm,
|
|
170
198
|
grpc_slice_buffer* input, grpc_slice_buffer* output) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
199
|
+
int retval = 1;
|
|
200
|
+
grpc_core::SliceBuffer input_sb;
|
|
201
|
+
grpc_slice_buffer_swap(input, input_sb.c_slice_buffer());
|
|
202
|
+
std::optional<grpc_core::SliceBuffer> output_sb =
|
|
203
|
+
grpc_core::MessageCompress(algorithm, input_sb);
|
|
204
|
+
if (!output_sb.has_value()) {
|
|
205
|
+
output_sb.emplace();
|
|
206
|
+
output_sb->Append(input_sb);
|
|
207
|
+
retval = 0;
|
|
174
208
|
}
|
|
175
|
-
|
|
209
|
+
grpc_slice_buffer_swap(input, input_sb.c_slice_buffer());
|
|
210
|
+
grpc_slice_buffer_swap(output, output_sb->c_slice_buffer());
|
|
211
|
+
return retval;
|
|
176
212
|
}
|
|
177
213
|
|
|
178
214
|
int grpc_msg_decompress(grpc_compression_algorithm algorithm,
|
|
179
215
|
grpc_slice_buffer* input, grpc_slice_buffer* output) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
case GRPC_COMPRESS_ALGORITHMS_COUNT:
|
|
188
|
-
break;
|
|
216
|
+
grpc_core::SliceBuffer input_sb;
|
|
217
|
+
grpc_slice_buffer_swap(input, input_sb.c_slice_buffer());
|
|
218
|
+
|
|
219
|
+
absl::StatusOr<grpc_core::SliceBuffer> output_sb =
|
|
220
|
+
grpc_core::MessageDecompress(algorithm, input_sb, std::nullopt);
|
|
221
|
+
if (!output_sb.ok()) {
|
|
222
|
+
return 0;
|
|
189
223
|
}
|
|
190
|
-
|
|
191
|
-
|
|
224
|
+
grpc_slice_buffer_swap(input, input_sb.c_slice_buffer());
|
|
225
|
+
grpc_slice_buffer_swap(output, output_sb->c_slice_buffer());
|
|
226
|
+
return 1;
|
|
192
227
|
}
|
|
@@ -23,6 +23,13 @@
|
|
|
23
23
|
#include <grpc/slice.h>
|
|
24
24
|
#include <grpc/support/port_platform.h>
|
|
25
25
|
|
|
26
|
+
#include <cstdint>
|
|
27
|
+
#include <optional>
|
|
28
|
+
|
|
29
|
+
#include "src/core/lib/slice/slice_buffer.h"
|
|
30
|
+
#include "absl/status/status.h"
|
|
31
|
+
#include "absl/status/statusor.h"
|
|
32
|
+
|
|
26
33
|
// compress 'input' to 'output' using 'algorithm'.
|
|
27
34
|
// On success, appends compressed slices to output and returns 1.
|
|
28
35
|
// On failure, appends uncompressed slices to output and returns 0.
|
|
@@ -35,4 +42,21 @@ int grpc_msg_compress(grpc_compression_algorithm algorithm,
|
|
|
35
42
|
int grpc_msg_decompress(grpc_compression_algorithm algorithm,
|
|
36
43
|
grpc_slice_buffer* input, grpc_slice_buffer* output);
|
|
37
44
|
|
|
45
|
+
namespace grpc_core {
|
|
46
|
+
|
|
47
|
+
// Compresses 'input' using 'algorithm'.
|
|
48
|
+
// On success, returns a SliceBuffer containing the compressed data.
|
|
49
|
+
// On failure, returns nullopt.
|
|
50
|
+
std::optional<SliceBuffer> MessageCompress(grpc_compression_algorithm algorithm,
|
|
51
|
+
const SliceBuffer& input);
|
|
52
|
+
// Decompresses 'input'.
|
|
53
|
+
// On success, returns a SliceBuffer containing the decompressed data.
|
|
54
|
+
// On failure, returns a non-OK status.
|
|
55
|
+
// Fails if the decompressed data would be larger than max_output_size.
|
|
56
|
+
absl::StatusOr<SliceBuffer> MessageDecompress(
|
|
57
|
+
grpc_compression_algorithm algorithm, const SliceBuffer& input,
|
|
58
|
+
std::optional<uint32_t> max_output_size);
|
|
59
|
+
|
|
60
|
+
} // namespace grpc_core
|
|
61
|
+
|
|
38
62
|
#endif // GRPC_SRC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H
|
|
@@ -103,6 +103,9 @@ const char* const description_h2_max_deallocating_streams_headroom =
|
|
|
103
103
|
"Separate allocated max concurrent streams.";
|
|
104
104
|
const char* const additional_constraints_h2_max_deallocating_streams_headroom =
|
|
105
105
|
"{}";
|
|
106
|
+
const char* const description_header_data_frame =
|
|
107
|
+
"Managing header and data memory better";
|
|
108
|
+
const char* const additional_constraints_header_data_frame = "{}";
|
|
106
109
|
const char* const description_inproc_cancel_stream =
|
|
107
110
|
"If set, cancel inproc stream inside the transport mutex.";
|
|
108
111
|
const char* const additional_constraints_inproc_cancel_stream = "{}";
|
|
@@ -336,6 +339,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|
|
336
339
|
description_h2_max_deallocating_streams_headroom,
|
|
337
340
|
additional_constraints_h2_max_deallocating_streams_headroom, nullptr, 0,
|
|
338
341
|
false, true},
|
|
342
|
+
{"header_data_frame", description_header_data_frame,
|
|
343
|
+
additional_constraints_header_data_frame, nullptr, 0, true, true},
|
|
339
344
|
{"inproc_cancel_stream", description_inproc_cancel_stream,
|
|
340
345
|
additional_constraints_inproc_cancel_stream, nullptr, 0, true, true},
|
|
341
346
|
{"keep_alive_ping_timer_batch", description_keep_alive_ping_timer_batch,
|
|
@@ -348,7 +353,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|
|
348
353
|
{"memory_optimization_02", description_memory_optimization_02,
|
|
349
354
|
additional_constraints_memory_optimization_02, nullptr, 0, false, false},
|
|
350
355
|
{"message_size_refactoring", description_message_size_refactoring,
|
|
351
|
-
additional_constraints_message_size_refactoring, nullptr, 0,
|
|
356
|
+
additional_constraints_message_size_refactoring, nullptr, 0, true, true},
|
|
352
357
|
{"metadata_outstanding_token_refactor",
|
|
353
358
|
description_metadata_outstanding_token_refactor,
|
|
354
359
|
additional_constraints_metadata_outstanding_token_refactor, nullptr, 0,
|
|
@@ -380,7 +385,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|
|
380
385
|
{"ph2_client_server", description_ph2_client_server,
|
|
381
386
|
additional_constraints_ph2_client_server, nullptr, 0, false, true},
|
|
382
387
|
{"ph2_perf_01", description_ph2_perf_01, additional_constraints_ph2_perf_01,
|
|
383
|
-
nullptr, 0,
|
|
388
|
+
nullptr, 0, true, true},
|
|
384
389
|
{"ph2_server", description_ph2_server, additional_constraints_ph2_server,
|
|
385
390
|
nullptr, 0, false, true},
|
|
386
391
|
{"pick_first_ignore_empty_updates",
|
|
@@ -554,6 +559,9 @@ const char* const description_h2_max_deallocating_streams_headroom =
|
|
|
554
559
|
"Separate allocated max concurrent streams.";
|
|
555
560
|
const char* const additional_constraints_h2_max_deallocating_streams_headroom =
|
|
556
561
|
"{}";
|
|
562
|
+
const char* const description_header_data_frame =
|
|
563
|
+
"Managing header and data memory better";
|
|
564
|
+
const char* const additional_constraints_header_data_frame = "{}";
|
|
557
565
|
const char* const description_inproc_cancel_stream =
|
|
558
566
|
"If set, cancel inproc stream inside the transport mutex.";
|
|
559
567
|
const char* const additional_constraints_inproc_cancel_stream = "{}";
|
|
@@ -787,6 +795,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|
|
787
795
|
description_h2_max_deallocating_streams_headroom,
|
|
788
796
|
additional_constraints_h2_max_deallocating_streams_headroom, nullptr, 0,
|
|
789
797
|
false, true},
|
|
798
|
+
{"header_data_frame", description_header_data_frame,
|
|
799
|
+
additional_constraints_header_data_frame, nullptr, 0, true, true},
|
|
790
800
|
{"inproc_cancel_stream", description_inproc_cancel_stream,
|
|
791
801
|
additional_constraints_inproc_cancel_stream, nullptr, 0, true, true},
|
|
792
802
|
{"keep_alive_ping_timer_batch", description_keep_alive_ping_timer_batch,
|
|
@@ -799,7 +809,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|
|
799
809
|
{"memory_optimization_02", description_memory_optimization_02,
|
|
800
810
|
additional_constraints_memory_optimization_02, nullptr, 0, false, false},
|
|
801
811
|
{"message_size_refactoring", description_message_size_refactoring,
|
|
802
|
-
additional_constraints_message_size_refactoring, nullptr, 0,
|
|
812
|
+
additional_constraints_message_size_refactoring, nullptr, 0, true, true},
|
|
803
813
|
{"metadata_outstanding_token_refactor",
|
|
804
814
|
description_metadata_outstanding_token_refactor,
|
|
805
815
|
additional_constraints_metadata_outstanding_token_refactor, nullptr, 0,
|
|
@@ -831,7 +841,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|
|
831
841
|
{"ph2_client_server", description_ph2_client_server,
|
|
832
842
|
additional_constraints_ph2_client_server, nullptr, 0, false, true},
|
|
833
843
|
{"ph2_perf_01", description_ph2_perf_01, additional_constraints_ph2_perf_01,
|
|
834
|
-
nullptr, 0,
|
|
844
|
+
nullptr, 0, true, true},
|
|
835
845
|
{"ph2_server", description_ph2_server, additional_constraints_ph2_server,
|
|
836
846
|
nullptr, 0, false, true},
|
|
837
847
|
{"pick_first_ignore_empty_updates",
|
|
@@ -1005,6 +1015,9 @@ const char* const description_h2_max_deallocating_streams_headroom =
|
|
|
1005
1015
|
"Separate allocated max concurrent streams.";
|
|
1006
1016
|
const char* const additional_constraints_h2_max_deallocating_streams_headroom =
|
|
1007
1017
|
"{}";
|
|
1018
|
+
const char* const description_header_data_frame =
|
|
1019
|
+
"Managing header and data memory better";
|
|
1020
|
+
const char* const additional_constraints_header_data_frame = "{}";
|
|
1008
1021
|
const char* const description_inproc_cancel_stream =
|
|
1009
1022
|
"If set, cancel inproc stream inside the transport mutex.";
|
|
1010
1023
|
const char* const additional_constraints_inproc_cancel_stream = "{}";
|
|
@@ -1238,6 +1251,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|
|
1238
1251
|
description_h2_max_deallocating_streams_headroom,
|
|
1239
1252
|
additional_constraints_h2_max_deallocating_streams_headroom, nullptr, 0,
|
|
1240
1253
|
false, true},
|
|
1254
|
+
{"header_data_frame", description_header_data_frame,
|
|
1255
|
+
additional_constraints_header_data_frame, nullptr, 0, true, true},
|
|
1241
1256
|
{"inproc_cancel_stream", description_inproc_cancel_stream,
|
|
1242
1257
|
additional_constraints_inproc_cancel_stream, nullptr, 0, true, true},
|
|
1243
1258
|
{"keep_alive_ping_timer_batch", description_keep_alive_ping_timer_batch,
|
|
@@ -1250,7 +1265,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|
|
1250
1265
|
{"memory_optimization_02", description_memory_optimization_02,
|
|
1251
1266
|
additional_constraints_memory_optimization_02, nullptr, 0, false, false},
|
|
1252
1267
|
{"message_size_refactoring", description_message_size_refactoring,
|
|
1253
|
-
additional_constraints_message_size_refactoring, nullptr, 0,
|
|
1268
|
+
additional_constraints_message_size_refactoring, nullptr, 0, true, true},
|
|
1254
1269
|
{"metadata_outstanding_token_refactor",
|
|
1255
1270
|
description_metadata_outstanding_token_refactor,
|
|
1256
1271
|
additional_constraints_metadata_outstanding_token_refactor, nullptr, 0,
|
|
@@ -1282,7 +1297,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|
|
1282
1297
|
{"ph2_client_server", description_ph2_client_server,
|
|
1283
1298
|
additional_constraints_ph2_client_server, nullptr, 0, false, true},
|
|
1284
1299
|
{"ph2_perf_01", description_ph2_perf_01, additional_constraints_ph2_perf_01,
|
|
1285
|
-
nullptr, 0,
|
|
1300
|
+
nullptr, 0, true, true},
|
|
1286
1301
|
{"ph2_server", description_ph2_server, additional_constraints_ph2_server,
|
|
1287
1302
|
nullptr, 0, false, true},
|
|
1288
1303
|
{"pick_first_ignore_empty_updates",
|
|
@@ -93,13 +93,16 @@ inline bool IsFailRecvMetadataOnDeadlineExceededEnabled() { return false; }
|
|
|
93
93
|
inline bool IsFreeLargeAllocatorEnabled() { return false; }
|
|
94
94
|
inline bool IsFuseFiltersEnabled() { return false; }
|
|
95
95
|
inline bool IsH2MaxDeallocatingStreamsHeadroomEnabled() { return false; }
|
|
96
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_HEADER_DATA_FRAME
|
|
97
|
+
inline bool IsHeaderDataFrameEnabled() { return true; }
|
|
96
98
|
#define GRPC_EXPERIMENT_IS_INCLUDED_INPROC_CANCEL_STREAM
|
|
97
99
|
inline bool IsInprocCancelStreamEnabled() { return true; }
|
|
98
100
|
inline bool IsKeepAlivePingTimerBatchEnabled() { return false; }
|
|
99
101
|
inline bool IsLocalConnectorSecureEnabled() { return false; }
|
|
100
102
|
inline bool IsMemoryOptimization01Enabled() { return false; }
|
|
101
103
|
inline bool IsMemoryOptimization02Enabled() { return false; }
|
|
102
|
-
|
|
104
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_MESSAGE_SIZE_REFACTORING
|
|
105
|
+
inline bool IsMessageSizeRefactoringEnabled() { return true; }
|
|
103
106
|
inline bool IsMetadataOutstandingTokenRefactorEnabled() { return false; }
|
|
104
107
|
inline bool IsMetadataPublishToAppTagEnabled() { return false; }
|
|
105
108
|
#define GRPC_EXPERIMENT_IS_INCLUDED_MONITORING_EXPERIMENT
|
|
@@ -118,7 +121,8 @@ inline bool IsOptimization06Enabled() { return false; }
|
|
|
118
121
|
inline bool IsOtelExportTelemetryDomainsEnabled() { return false; }
|
|
119
122
|
inline bool IsPh2ClientEnabled() { return false; }
|
|
120
123
|
inline bool IsPh2ClientServerEnabled() { return false; }
|
|
121
|
-
|
|
124
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_PH2_PERF_01
|
|
125
|
+
inline bool IsPh2Perf01Enabled() { return true; }
|
|
122
126
|
inline bool IsPh2ServerEnabled() { return false; }
|
|
123
127
|
inline bool IsPickFirstIgnoreEmptyUpdatesEnabled() { return false; }
|
|
124
128
|
inline bool IsPipelinedReadSecureEndpointEnabled() { return false; }
|
|
@@ -185,13 +189,16 @@ inline bool IsFailRecvMetadataOnDeadlineExceededEnabled() { return false; }
|
|
|
185
189
|
inline bool IsFreeLargeAllocatorEnabled() { return false; }
|
|
186
190
|
inline bool IsFuseFiltersEnabled() { return false; }
|
|
187
191
|
inline bool IsH2MaxDeallocatingStreamsHeadroomEnabled() { return false; }
|
|
192
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_HEADER_DATA_FRAME
|
|
193
|
+
inline bool IsHeaderDataFrameEnabled() { return true; }
|
|
188
194
|
#define GRPC_EXPERIMENT_IS_INCLUDED_INPROC_CANCEL_STREAM
|
|
189
195
|
inline bool IsInprocCancelStreamEnabled() { return true; }
|
|
190
196
|
inline bool IsKeepAlivePingTimerBatchEnabled() { return false; }
|
|
191
197
|
inline bool IsLocalConnectorSecureEnabled() { return false; }
|
|
192
198
|
inline bool IsMemoryOptimization01Enabled() { return false; }
|
|
193
199
|
inline bool IsMemoryOptimization02Enabled() { return false; }
|
|
194
|
-
|
|
200
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_MESSAGE_SIZE_REFACTORING
|
|
201
|
+
inline bool IsMessageSizeRefactoringEnabled() { return true; }
|
|
195
202
|
inline bool IsMetadataOutstandingTokenRefactorEnabled() { return false; }
|
|
196
203
|
inline bool IsMetadataPublishToAppTagEnabled() { return false; }
|
|
197
204
|
#define GRPC_EXPERIMENT_IS_INCLUDED_MONITORING_EXPERIMENT
|
|
@@ -210,7 +217,8 @@ inline bool IsOptimization06Enabled() { return false; }
|
|
|
210
217
|
inline bool IsOtelExportTelemetryDomainsEnabled() { return false; }
|
|
211
218
|
inline bool IsPh2ClientEnabled() { return false; }
|
|
212
219
|
inline bool IsPh2ClientServerEnabled() { return false; }
|
|
213
|
-
|
|
220
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_PH2_PERF_01
|
|
221
|
+
inline bool IsPh2Perf01Enabled() { return true; }
|
|
214
222
|
inline bool IsPh2ServerEnabled() { return false; }
|
|
215
223
|
inline bool IsPickFirstIgnoreEmptyUpdatesEnabled() { return false; }
|
|
216
224
|
inline bool IsPipelinedReadSecureEndpointEnabled() { return false; }
|
|
@@ -277,13 +285,16 @@ inline bool IsFailRecvMetadataOnDeadlineExceededEnabled() { return false; }
|
|
|
277
285
|
inline bool IsFreeLargeAllocatorEnabled() { return false; }
|
|
278
286
|
inline bool IsFuseFiltersEnabled() { return false; }
|
|
279
287
|
inline bool IsH2MaxDeallocatingStreamsHeadroomEnabled() { return false; }
|
|
288
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_HEADER_DATA_FRAME
|
|
289
|
+
inline bool IsHeaderDataFrameEnabled() { return true; }
|
|
280
290
|
#define GRPC_EXPERIMENT_IS_INCLUDED_INPROC_CANCEL_STREAM
|
|
281
291
|
inline bool IsInprocCancelStreamEnabled() { return true; }
|
|
282
292
|
inline bool IsKeepAlivePingTimerBatchEnabled() { return false; }
|
|
283
293
|
inline bool IsLocalConnectorSecureEnabled() { return false; }
|
|
284
294
|
inline bool IsMemoryOptimization01Enabled() { return false; }
|
|
285
295
|
inline bool IsMemoryOptimization02Enabled() { return false; }
|
|
286
|
-
|
|
296
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_MESSAGE_SIZE_REFACTORING
|
|
297
|
+
inline bool IsMessageSizeRefactoringEnabled() { return true; }
|
|
287
298
|
inline bool IsMetadataOutstandingTokenRefactorEnabled() { return false; }
|
|
288
299
|
inline bool IsMetadataPublishToAppTagEnabled() { return false; }
|
|
289
300
|
#define GRPC_EXPERIMENT_IS_INCLUDED_MONITORING_EXPERIMENT
|
|
@@ -302,7 +313,8 @@ inline bool IsOptimization06Enabled() { return false; }
|
|
|
302
313
|
inline bool IsOtelExportTelemetryDomainsEnabled() { return false; }
|
|
303
314
|
inline bool IsPh2ClientEnabled() { return false; }
|
|
304
315
|
inline bool IsPh2ClientServerEnabled() { return false; }
|
|
305
|
-
|
|
316
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_PH2_PERF_01
|
|
317
|
+
inline bool IsPh2Perf01Enabled() { return true; }
|
|
306
318
|
inline bool IsPh2ServerEnabled() { return false; }
|
|
307
319
|
inline bool IsPickFirstIgnoreEmptyUpdatesEnabled() { return false; }
|
|
308
320
|
inline bool IsPipelinedReadSecureEndpointEnabled() { return false; }
|
|
@@ -354,6 +366,7 @@ enum ExperimentIds {
|
|
|
354
366
|
kExperimentIdFreeLargeAllocator,
|
|
355
367
|
kExperimentIdFuseFilters,
|
|
356
368
|
kExperimentIdH2MaxDeallocatingStreamsHeadroom,
|
|
369
|
+
kExperimentIdHeaderDataFrame,
|
|
357
370
|
kExperimentIdInprocCancelStream,
|
|
358
371
|
kExperimentIdKeepAlivePingTimerBatch,
|
|
359
372
|
kExperimentIdLocalConnectorSecure,
|
|
@@ -479,6 +492,10 @@ inline bool IsFuseFiltersEnabled() {
|
|
|
479
492
|
inline bool IsH2MaxDeallocatingStreamsHeadroomEnabled() {
|
|
480
493
|
return IsExperimentEnabled<kExperimentIdH2MaxDeallocatingStreamsHeadroom>();
|
|
481
494
|
}
|
|
495
|
+
#define GRPC_EXPERIMENT_IS_INCLUDED_HEADER_DATA_FRAME
|
|
496
|
+
inline bool IsHeaderDataFrameEnabled() {
|
|
497
|
+
return IsExperimentEnabled<kExperimentIdHeaderDataFrame>();
|
|
498
|
+
}
|
|
482
499
|
#define GRPC_EXPERIMENT_IS_INCLUDED_INPROC_CANCEL_STREAM
|
|
483
500
|
inline bool IsInprocCancelStreamEnabled() {
|
|
484
501
|
return IsExperimentEnabled<kExperimentIdInprocCancelStream>();
|
|
@@ -180,7 +180,9 @@ grpc_call* LegacyChannel::CreateCall(
|
|
|
180
180
|
args.authority = std::move(authority);
|
|
181
181
|
args.send_deadline = deadline;
|
|
182
182
|
args.registered_method = registered_method;
|
|
183
|
-
|
|
183
|
+
if (arena_init_function.has_value()) {
|
|
184
|
+
args.arena_init_function.emplace(*arena_init_function);
|
|
185
|
+
}
|
|
184
186
|
grpc_call* call;
|
|
185
187
|
GRPC_LOG_IF_ERROR("call_create", grpc_call_create(&args, &call));
|
|
186
188
|
return call;
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: grpc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.83.
|
|
4
|
+
version: 1.83.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- gRPC Authors
|
|
@@ -3981,7 +3981,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
3981
3981
|
- !ruby/object:Gem::Version
|
|
3982
3982
|
version: '0'
|
|
3983
3983
|
requirements: []
|
|
3984
|
-
rubygems_version: 4.0.
|
|
3984
|
+
rubygems_version: 4.0.19
|
|
3985
3985
|
specification_version: 4
|
|
3986
3986
|
summary: GRPC system in Ruby
|
|
3987
3987
|
test_files:
|