grpc 1.82.0 → 1.83.0.pre1
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 +8 -5
- data/etc/roots.pem +10400 -3855
- data/include/grpc/grpc_audit_logging.h +2 -2
- data/include/grpc/grpc_security_constants.h +2 -0
- data/include/grpc/impl/channel_arg_names.h +23 -0
- data/src/core/call/call_filters.h +19 -3
- data/src/core/call/call_spine.h +4 -4
- data/src/core/call/client_call.cc +1 -1
- data/src/core/call/metadata.cc +7 -2
- data/src/core/call/server_call.cc +13 -3
- data/src/core/call/server_call.h +5 -3
- data/src/core/client_channel/backup_poller.cc +2 -17
- data/src/core/client_channel/client_channel.cc +17 -14
- data/src/core/client_channel/client_channel.h +3 -1
- data/src/core/client_channel/client_channel_filter.cc +11 -13
- data/src/core/client_channel/client_channel_service_config.cc +5 -13
- data/src/core/client_channel/direct_channel.cc +5 -1
- data/src/core/client_channel/direct_channel.h +3 -1
- data/src/core/config/experiment_env_var.cc +30 -0
- data/src/core/config/experiment_env_var.h +26 -0
- data/src/core/credentials/call/regional_access_boundary_fetcher.cc +6 -6
- data/src/core/credentials/transport/ssl/ssl_security_connector.cc +14 -2
- data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.cc +172 -0
- data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.h +103 -0
- data/src/core/credentials/transport/tls/load_system_roots_fallback.cc +3 -2
- data/src/core/credentials/transport/tls/load_system_roots_supported.cc +10 -3
- data/src/core/credentials/transport/tls/tls_security_connector.cc +14 -2
- data/src/core/credentials/transport/xds/xds_credentials.cc +4 -12
- data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +2 -1
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +19 -13
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +11 -9
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/flow_control.h +3 -2
- data/src/core/ext/transport/chttp2/transport/frame.cc +58 -1
- data/src/core/ext/transport/chttp2/transport/frame.h +13 -1
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -4
- data/src/core/ext/transport/chttp2/transport/frame_security.cc +10 -1
- data/src/core/ext/transport/chttp2/transport/frame_security.h +2 -1
- data/src/core/ext/transport/chttp2/transport/goaway.cc +11 -1
- data/src/core/ext/transport/chttp2/transport/goaway.h +17 -1
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +9 -0
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +117 -276
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +44 -17
- data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +382 -496
- data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +75 -77
- data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +30 -11
- data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +24 -9
- data/src/core/ext/transport/chttp2/transport/http2_transport.cc +26 -0
- data/src/core/ext/transport/chttp2/transport/http2_transport.h +2 -0
- data/src/core/ext/transport/chttp2/transport/internal.h +4 -0
- data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
- data/src/core/ext/transport/chttp2/transport/ping_promise.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +4 -10
- data/src/core/ext/transport/chttp2/transport/read_context.h +62 -20
- data/src/core/ext/transport/chttp2/transport/security_frame.h +1 -0
- data/src/core/ext/transport/chttp2/transport/stream.h +271 -120
- data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +77 -61
- data/src/core/handshaker/security/secure_endpoint.cc +0 -13
- data/src/core/lib/channel/promise_based_filter.cc +77 -3
- data/src/core/lib/channel/promise_based_filter.h +238 -184
- data/src/core/lib/event_engine/extensions/receive_coalescing_extension.h +0 -4
- data/src/core/lib/event_engine/extensions/tcp_trace.h +1 -1
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +2 -12
- data/src/core/lib/event_engine/shim.cc +2 -16
- data/src/core/lib/event_engine/shim.h +0 -4
- data/src/core/lib/experiments/experiments.cc +51 -102
- data/src/core/lib/experiments/experiments.h +37 -59
- data/src/core/lib/iomgr/error.cc +3 -73
- data/src/core/lib/iomgr/error.h +8 -6
- data/src/core/lib/iomgr/error_cfstream.cc +1 -2
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +2 -6
- data/src/core/lib/iomgr/ev_poll_posix.cc +2 -6
- data/src/core/lib/iomgr/tcp_posix.cc +2 -6
- data/src/core/lib/security/authorization/audit_logging.cc +2 -2
- data/src/core/lib/security/authorization/audit_logging.h +3 -3
- data/src/core/lib/security/authorization/grpc_authorization_engine.cc +11 -13
- data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
- data/src/core/lib/security/authorization/matchers.cc +20 -20
- data/src/core/lib/security/authorization/matchers.h +15 -16
- data/src/core/lib/security/authorization/rbac_policy.h +1 -1
- data/src/core/lib/security/authorization/stdout_logger.cc +3 -3
- data/src/core/lib/security/authorization/stdout_logger.h +6 -5
- data/src/core/lib/surface/call.cc +0 -8
- data/src/core/lib/surface/call.h +2 -0
- data/src/core/lib/surface/channel.cc +21 -2
- data/src/core/lib/surface/channel.h +14 -6
- data/src/core/lib/surface/filter_stack_call.cc +10 -29
- data/src/core/lib/surface/legacy_channel.cc +7 -7
- data/src/core/lib/surface/legacy_channel.h +3 -1
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/bdp_estimator.cc +13 -13
- data/src/core/lib/transport/bdp_estimator.h +9 -5
- data/src/core/lib/transport/error_utils.cc +26 -138
- data/src/core/lib/transport/promise_endpoint.h +2 -4
- data/src/core/load_balancing/grpclb/grpclb.cc +2 -1
- data/src/core/load_balancing/pick_first/pick_first.cc +33 -2
- data/src/core/load_balancing/pick_first/pick_first.h +6 -0
- data/src/core/load_balancing/ring_hash/ring_hash.cc +3 -10
- data/src/core/load_balancing/rls/rls.cc +2 -1
- data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +2 -7
- data/src/core/load_balancing/xds/cds.cc +80 -56
- data/src/core/load_balancing/xds/cds.h +21 -0
- data/src/core/mitigation_engine/mitigation.h +53 -0
- data/src/core/mitigation_engine/mitigation_provider.h +62 -0
- data/src/core/resolver/dns/dns_resolver_plugin.cc +1 -6
- data/src/core/resolver/xds/xds_resolver.cc +14 -11
- data/src/core/server/server.h +1 -4
- data/src/core/server/server_config_selector.h +5 -4
- data/src/core/server/server_config_selector_filter.cc +67 -80
- data/src/core/server/xds_server_config_fetcher.cc +681 -692
- data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -12
- data/src/core/telemetry/call_tracer.cc +49 -2
- data/src/core/telemetry/call_tracer.h +1 -0
- data/src/core/telemetry/tcp_tracer.h +38 -0
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
- data/src/core/tsi/ssl_telemetry_utils.cc +343 -0
- data/src/core/tsi/ssl_telemetry_utils.h +74 -0
- data/src/core/tsi/ssl_transport_security.cc +577 -301
- data/src/core/tsi/ssl_transport_security.h +22 -6
- data/src/core/tsi/ssl_transport_security_utils.cc +2 -0
- data/src/core/tsi/transport_security.h +7 -0
- data/src/core/util/http_client/httpcli.cc +1 -4
- data/src/core/util/http_client/httpcli_security_connector.cc +2 -1
- data/src/core/util/status_helper.cc +71 -192
- data/src/core/util/status_helper.h +16 -21
- data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +2 -11
- data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -7
- data/src/core/xds/grpc/xds_cluster_parser.cc +5 -16
- data/src/core/xds/grpc/xds_common_types.cc +94 -38
- data/src/core/xds/grpc/xds_common_types.h +33 -18
- data/src/core/xds/grpc/xds_common_types_parser.cc +168 -100
- data/src/core/xds/grpc/xds_common_types_parser.h +18 -1
- data/src/core/xds/grpc/xds_endpoint_parser.cc +6 -17
- data/src/core/xds/grpc/xds_http_filter_registry.cc +2 -10
- data/src/core/xds/grpc/xds_http_rbac_filter.cc +3 -12
- data/src/core/xds/grpc/xds_metadata_parser.cc +0 -2
- data/src/core/xds/grpc/xds_route_config_parser.cc +7 -11
- data/src/core/xds/grpc/xds_routing.cc +113 -82
- data/src/core/xds/grpc/xds_routing.h +70 -20
- data/src/core/xds/grpc/xds_server_grpc.cc +22 -13
- data/src/core/xds/grpc/xds_server_grpc.h +16 -2
- data/src/core/xds/grpc/xds_server_grpc_interface.h +10 -0
- data/src/core/xds/grpc/xds_transport_grpc.cc +123 -18
- data/src/core/xds/grpc/xds_transport_grpc.h +28 -4
- data/src/core/xds/xds_client/lrs_client.cc +3 -7
- data/src/core/xds/xds_client/xds_bootstrap.cc +4 -16
- data/src/core/xds/xds_client/xds_client.cc +2 -15
- data/src/core/xds/xds_client/xds_transport.h +3 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +1 -1
- metadata +9 -1
|
@@ -363,29 +363,36 @@ Http2Status Http2ServerTransport::ProcessIncomingFrame(Http2DataFrame&& frame) {
|
|
|
363
363
|
break;
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
+
if (frame.end_stream) {
|
|
367
|
+
HandleStreamStateChange(*stream, stream->OnHalfCloseReceived());
|
|
368
|
+
}
|
|
366
369
|
return Http2Status::Ok();
|
|
367
370
|
}
|
|
368
371
|
|
|
369
372
|
template <typename T>
|
|
370
373
|
Http2Status Http2ServerTransport::ProcessIncomingMetadata(T&& frame) {
|
|
374
|
+
GRPC_HTTP2_SERVER_DLOG
|
|
375
|
+
<< "Http2ServerTransport::ProcessIncomingMetadata { stream_id="
|
|
376
|
+
<< frame.stream_id << ", end_headers=" << frame.end_headers << " }";
|
|
371
377
|
ping_manager_->ReceivedDataFrame();
|
|
372
378
|
|
|
373
379
|
bool is_new_stream = false;
|
|
374
380
|
RefCountedPtr<Stream> stream = nullptr;
|
|
375
381
|
// State update MUST happen before processing the frame.
|
|
376
|
-
read_context_.UpdateState(frame, /*is_existing_stream=*/(stream != nullptr));
|
|
377
382
|
if (!read_context_.IsWaitingForContinuationFrame()) {
|
|
378
383
|
// This is a HEADERS frame.
|
|
379
384
|
stream = LookupStream(frame.stream_id);
|
|
380
385
|
is_new_stream = (stream == nullptr);
|
|
381
386
|
// TODO(tjagtap) : [PH2][P2] : Implement initial stream id checks for new
|
|
382
387
|
// streams.
|
|
388
|
+
last_incoming_stream_id_ = frame.stream_id;
|
|
383
389
|
} else {
|
|
384
390
|
// This is a CONTINUATION frame.
|
|
385
391
|
GRPC_DCHECK(read_context_.GetStreamId() == frame.stream_id);
|
|
386
392
|
GRPC_DCHECK(LookupStream(frame.stream_id) != nullptr);
|
|
387
393
|
is_new_stream = true;
|
|
388
394
|
}
|
|
395
|
+
read_context_.UpdateState(frame, /*is_existing_stream=*/!is_new_stream);
|
|
389
396
|
|
|
390
397
|
if (is_new_stream) {
|
|
391
398
|
// TODO(tjagtap) : [PH2][P3] : Implement this.
|
|
@@ -395,6 +402,13 @@ Http2Status Http2ServerTransport::ProcessIncomingMetadata(T&& frame) {
|
|
|
395
402
|
// frame and streams that are reserved using PUSH_PROMISE. An endpoint that
|
|
396
403
|
// receives an unexpected stream identifier MUST respond with a connection
|
|
397
404
|
// error (Section 5.4.1) of type PROTOCOL_ERROR.
|
|
405
|
+
|
|
406
|
+
if (goaway_manager_.IsFinalGracefulGoawayScheduledOrSent()) {
|
|
407
|
+
return read_context_.ParseAndDiscardHeaders(
|
|
408
|
+
std::move(frame.payload), frame.end_headers, Http2Status::Ok(),
|
|
409
|
+
settings_->acked().max_header_list_size());
|
|
410
|
+
}
|
|
411
|
+
|
|
398
412
|
Http2Status append_result =
|
|
399
413
|
read_context_.header_assembler().AppendFrame(frame);
|
|
400
414
|
if (!append_result.IsOk()) {
|
|
@@ -433,9 +447,8 @@ Http2Status Http2ServerTransport::ProcessIncomingFrame(
|
|
|
433
447
|
Http2HeaderFrame&& frame) {
|
|
434
448
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-headers
|
|
435
449
|
GRPC_HTTP2_SERVER_DLOG
|
|
436
|
-
<< "Http2ServerTransport::ProcessIncomingFrame(HeaderFrame)
|
|
437
|
-
<< frame.
|
|
438
|
-
<< ", end_stream=" << frame.end_stream << " }";
|
|
450
|
+
<< "Http2ServerTransport::ProcessIncomingFrame(HeaderFrame) end_stream="
|
|
451
|
+
<< frame.end_stream;
|
|
439
452
|
return ProcessIncomingMetadata(std::forward<Http2HeaderFrame>(frame));
|
|
440
453
|
}
|
|
441
454
|
|
|
@@ -443,21 +456,24 @@ Http2Status Http2ServerTransport::ProcessIncomingFrame(
|
|
|
443
456
|
Http2RstStreamFrame&& frame) {
|
|
444
457
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-rst_stream
|
|
445
458
|
GRPC_HTTP2_SERVER_DLOG
|
|
446
|
-
<< "Http2ServerTransport::ProcessIncomingFrame(
|
|
459
|
+
<< "Http2ServerTransport::ProcessIncomingFrame(ResetStreamFrame) { "
|
|
447
460
|
"stream_id="
|
|
448
461
|
<< frame.stream_id << ", error_code=" << frame.error_code << " }";
|
|
462
|
+
read_context_.OnResetFrameReceived();
|
|
449
463
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
464
|
+
Http2ErrorCode error_code = FrameErrorCodeToHttp2ErrorCode(frame.error_code);
|
|
465
|
+
absl::Status status = absl::Status(ErrorCodeToAbslStatusCode(error_code),
|
|
466
|
+
"Reset stream frame received.");
|
|
467
|
+
RefCountedPtr<Stream> stream = LookupStream(frame.stream_id);
|
|
468
|
+
if (stream != nullptr) {
|
|
469
|
+
if (status.ok()) {
|
|
470
|
+
status =
|
|
471
|
+
absl::UnavailableError("RST_STREAM frame received with no error.");
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
HandleStreamStateChange(*stream,
|
|
475
|
+
stream->OnResetReceived(std::move(status)));
|
|
476
|
+
}
|
|
461
477
|
|
|
462
478
|
// In case of stream error, we do not want the Read Loop to be broken. Hence
|
|
463
479
|
// returning an ok status.
|
|
@@ -473,6 +489,7 @@ Http2Status Http2ServerTransport::ProcessIncomingFrame(
|
|
|
473
489
|
<< frame.ack << ", settings length=" << frame.settings.size() << "}";
|
|
474
490
|
|
|
475
491
|
if (!frame.ack) {
|
|
492
|
+
read_context_.OnSettingsFrameReceived();
|
|
476
493
|
Http2Status s = settings_->BufferPeerSettings(std::move(frame.settings));
|
|
477
494
|
if (!s.IsOk()) {
|
|
478
495
|
return s;
|
|
@@ -509,17 +526,9 @@ Http2Status Http2ServerTransport::ProcessIncomingFrame(Http2PingFrame&& frame) {
|
|
|
509
526
|
if (frame.ack) {
|
|
510
527
|
return ToHttpOkOrConnError(AckPing(frame.opaque));
|
|
511
528
|
} else {
|
|
529
|
+
read_context_.OnPingFrameReceived();
|
|
512
530
|
if (test_only_ack_pings_) {
|
|
513
|
-
// TODO(akshitpatel) : [PH2][P2] : Have a counter to track number
|
|
514
|
-
// of pending induced frames (Ping/Settings Ack). This is to
|
|
515
|
-
// ensure that if write is taking a long time, we can stop reads
|
|
516
|
-
// and prioritize writes. RFC9113: PING responses SHOULD be given
|
|
517
|
-
// higher priority than any other frame.
|
|
518
531
|
ping_manager_->AddPendingPingAck(frame.opaque);
|
|
519
|
-
// TODO(akshitpatel) : [PH2][P2] : This is done assuming that the
|
|
520
|
-
// other ProcessFrame promises may return stream or connection
|
|
521
|
-
// failures. If this does not turn out to be true, consider
|
|
522
|
-
// returning absl::Status here.
|
|
523
532
|
return ToHttpOkOrConnError(TriggerWriteCycle());
|
|
524
533
|
} else {
|
|
525
534
|
GRPC_HTTP2_SERVER_DLOG
|
|
@@ -664,9 +673,7 @@ Http2Status Http2ServerTransport::ProcessIncomingFrame(
|
|
|
664
673
|
Http2ContinuationFrame&& frame) {
|
|
665
674
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-continuation
|
|
666
675
|
GRPC_HTTP2_SERVER_DLOG
|
|
667
|
-
<< "Http2ServerTransport::ProcessIncomingFrame(ContinuationFrame)
|
|
668
|
-
"stream_id="
|
|
669
|
-
<< frame.stream_id << ", end_headers=" << frame.end_headers << " }";
|
|
676
|
+
<< "Http2ServerTransport::ProcessIncomingFrame(ContinuationFrame)";
|
|
670
677
|
return ProcessIncomingMetadata(std::forward<Http2ContinuationFrame>(frame));
|
|
671
678
|
}
|
|
672
679
|
|
|
@@ -708,13 +715,28 @@ Http2Status Http2ServerTransport::ProcessMetadata() {
|
|
|
708
715
|
settings_->acked().max_header_list_size());
|
|
709
716
|
if (read_result.IsOk()) {
|
|
710
717
|
ServerMetadataHandle metadata = TakeValue(std::move(read_result));
|
|
718
|
+
// TODO(tjagtap): [PH2][P0] : Might be worth differentiating between
|
|
719
|
+
// initial and trailing metadata based on the number of header frames
|
|
720
|
+
// received.
|
|
711
721
|
if (read_context_.HeaderHasEndStream()) {
|
|
712
|
-
// TODO(
|
|
713
|
-
//
|
|
714
|
-
//
|
|
715
|
-
//
|
|
716
|
-
//
|
|
717
|
-
//
|
|
722
|
+
// TODO(akshitpatel) [PH2][P1] : Implement receiving trailing metadata.
|
|
723
|
+
// Details:
|
|
724
|
+
// - Standard gRPC clients do not send trailers (only EOS).
|
|
725
|
+
// - If received (HEADERS with END_STREAM), mark stream as half-closed
|
|
726
|
+
// remote.
|
|
727
|
+
// - Upper layers discard client trailers, so we are fine with not
|
|
728
|
+
// propagating them.
|
|
729
|
+
//
|
|
730
|
+
// With these assumptions, the flow will look like this:
|
|
731
|
+
// - If the client sends trailing metadata with an OK status, we will
|
|
732
|
+
// mark the stream as half-closed remote and do nothing else.
|
|
733
|
+
// - If the client sends trailing metadata with a non-OK status, this
|
|
734
|
+
// case needs to be handled.
|
|
735
|
+
// TODO(akshitpatel) : [PH2][P0] : Verify this.
|
|
736
|
+
RefCountedPtr<Stream> stream =
|
|
737
|
+
LookupStream(read_context_.GetStreamId());
|
|
738
|
+
HandleStreamStateChange(
|
|
739
|
+
*stream, stream->OnTrailingMetadataReceived(std::move(metadata)));
|
|
718
740
|
} else {
|
|
719
741
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::ProcessMetadata "
|
|
720
742
|
"SpawnPushServerInitialMetadata";
|
|
@@ -745,14 +767,15 @@ auto Http2ServerTransport::ReadAndProcessOneFrame() {
|
|
|
745
767
|
/*max_frame_size_setting=*/settings_->acked().max_frame_size(),
|
|
746
768
|
/*current_frame_header=*/header,
|
|
747
769
|
// TODO(tjagtap) : [PH2][P0] : Fix
|
|
748
|
-
/*last_stream_id=*//*GetLastStreamId()*/
|
|
770
|
+
/*last_stream_id=*//*GetLastStreamId()*/
|
|
771
|
+
std::numeric_limits<uint32_t>::max(),
|
|
749
772
|
/*is_first_settings_processed=*/
|
|
750
773
|
settings_->IsFirstPeerSettingsApplied());
|
|
751
774
|
|
|
752
775
|
if (GPR_UNLIKELY(!status.IsOk())) {
|
|
753
776
|
GRPC_DCHECK(status.GetType() ==
|
|
754
777
|
Http2Status::Http2ErrorType::kConnectionError);
|
|
755
|
-
return HandleError(/*
|
|
778
|
+
return HandleError(/*stream=*/nullptr, std::move(status));
|
|
756
779
|
}
|
|
757
780
|
read_context_.SetCurrentFrameHeader(header);
|
|
758
781
|
return absl::OkStatus();
|
|
@@ -776,7 +799,8 @@ auto Http2ServerTransport::ReadAndProcessOneFrame() {
|
|
|
776
799
|
TakeValue(std::move(payload)));
|
|
777
800
|
if (GPR_UNLIKELY(!frame.IsOk())) {
|
|
778
801
|
return HandleError(
|
|
779
|
-
|
|
802
|
+
LookupStream(
|
|
803
|
+
read_context_.GetCurrentFrameHeader().stream_id),
|
|
780
804
|
ValueOrHttp2Status<Http2Frame>::TakeStatus(
|
|
781
805
|
std::move(frame)));
|
|
782
806
|
}
|
|
@@ -784,7 +808,8 @@ auto Http2ServerTransport::ReadAndProcessOneFrame() {
|
|
|
784
808
|
ProcessOneIncomingFrame(TakeValue(std::move(frame)));
|
|
785
809
|
if (GPR_UNLIKELY(!status.IsOk())) {
|
|
786
810
|
return HandleError(
|
|
787
|
-
|
|
811
|
+
LookupStream(
|
|
812
|
+
read_context_.GetCurrentFrameHeader().stream_id),
|
|
788
813
|
std::move(status));
|
|
789
814
|
}
|
|
790
815
|
return absl::OkStatus();
|
|
@@ -830,13 +855,13 @@ absl::Status Http2ServerTransport::PrepareControlFrames() {
|
|
|
830
855
|
// 5. Custom gRPC security frame
|
|
831
856
|
|
|
832
857
|
goaway_manager_.MaybeGetSerializedGoawayFrame(frame_sender);
|
|
833
|
-
|
|
858
|
+
ApplySettingsResult apply_settings_result;
|
|
834
859
|
|
|
835
860
|
const uint32_t old_initial_window_size =
|
|
836
861
|
settings_->peer().initial_window_size();
|
|
837
|
-
http2::Http2ErrorCode apply_status =
|
|
838
|
-
settings_->MaybeReportAndApplyBufferedPeerSettings(
|
|
839
|
-
|
|
862
|
+
const http2::Http2ErrorCode apply_status =
|
|
863
|
+
settings_->MaybeReportAndApplyBufferedPeerSettings(event_engine_.get(),
|
|
864
|
+
apply_settings_result);
|
|
840
865
|
|
|
841
866
|
if (apply_status == http2::Http2ErrorCode::kNoError) {
|
|
842
867
|
const uint32_t new_initial_window_size =
|
|
@@ -855,7 +880,7 @@ absl::Status Http2ServerTransport::PrepareControlFrames() {
|
|
|
855
880
|
}
|
|
856
881
|
}
|
|
857
882
|
|
|
858
|
-
if (should_spawn_security_frame_loop) {
|
|
883
|
+
if (apply_settings_result.should_spawn_security_frame_loop) {
|
|
859
884
|
const SecurityFrameHandler::EndpointExtensionState state =
|
|
860
885
|
security_frame_handler_->Initialize(event_engine_);
|
|
861
886
|
if (state.is_set) {
|
|
@@ -869,14 +894,14 @@ absl::Status Http2ServerTransport::PrepareControlFrames() {
|
|
|
869
894
|
EnforceLatestIncomingSettings();
|
|
870
895
|
settings_->MaybeGetSettingsAndSettingsAckFrames(flow_control_,
|
|
871
896
|
frame_sender);
|
|
872
|
-
|
|
873
|
-
|
|
897
|
+
MaybeSpawnDelayedPing(ping_manager_->MaybeGetSerializedPingFrames(
|
|
898
|
+
frame_sender, NextAllowedPingInterval()));
|
|
874
899
|
MaybeGetWindowUpdateFrames(frame_sender);
|
|
875
900
|
security_frame_handler_->MaybeAppendSecurityFrame(frame_sender);
|
|
876
901
|
}
|
|
877
902
|
|
|
878
903
|
if (apply_status != http2::Http2ErrorCode::kNoError) {
|
|
879
|
-
return HandleError(/*
|
|
904
|
+
return HandleError(/*stream=*/nullptr,
|
|
880
905
|
Http2Status::Http2ConnectionError(
|
|
881
906
|
apply_status, "Failed to apply incoming settings"));
|
|
882
907
|
}
|
|
@@ -905,7 +930,7 @@ void Http2ServerTransport::NotifyFramesWriteDone() {
|
|
|
905
930
|
// All notifications are expected to be synchronous.
|
|
906
931
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::NotifyFramesWriteDone";
|
|
907
932
|
read_context_.ResumeReadLoopIfPaused();
|
|
908
|
-
|
|
933
|
+
MaybeSpawnPingTimeout(ping_manager_->NotifyPingSent());
|
|
909
934
|
goaway_manager_.NotifyGoawaySent();
|
|
910
935
|
MaybeSpawnWaitForSettingsTimeout();
|
|
911
936
|
}
|
|
@@ -946,8 +971,7 @@ absl::Status Http2ServerTransport::DequeueStreamFrames(
|
|
|
946
971
|
"enqueue stream "
|
|
947
972
|
<< stream->GetStreamId() << " with status: " << status;
|
|
948
973
|
// Close transport if we fail to enqueue stream.
|
|
949
|
-
return HandleError(/*
|
|
950
|
-
ToHttpOkOrConnError(status));
|
|
974
|
+
return HandleError(/*stream=*/nullptr, ToHttpOkOrConnError(status));
|
|
951
975
|
}
|
|
952
976
|
}
|
|
953
977
|
|
|
@@ -956,26 +980,24 @@ absl::Status Http2ServerTransport::DequeueStreamFrames(
|
|
|
956
980
|
<< "Http2ServerTransport::DequeueStreamFrames InitialMetadataDequeued "
|
|
957
981
|
"stream_id = "
|
|
958
982
|
<< stream->GetStreamId();
|
|
959
|
-
stream->SentInitialMetadata();
|
|
960
983
|
}
|
|
961
984
|
|
|
962
985
|
if (result.IsTrailingMetadataDequeued()) {
|
|
963
986
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::DequeueStreamFrames "
|
|
964
987
|
"TrailingMetadataDequeued stream_id = "
|
|
965
988
|
<< stream->GetStreamId();
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
// TODO(akshitpatel) : [PH2][P1] : Close stream for reads and send
|
|
969
|
-
// RST_STREAM.
|
|
989
|
+
// Stream is not marked closed here as TrailingMetadata is always followed
|
|
990
|
+
// by RST_STREAM and we close the stream when we dequeue the RST_STREAM.
|
|
970
991
|
}
|
|
992
|
+
|
|
971
993
|
if (result.IsResetStreamDequeued()) {
|
|
972
994
|
GRPC_HTTP2_SERVER_DLOG
|
|
973
995
|
<< "Http2ServerTransport::DequeueStreamFrames ResetStreamDequeued "
|
|
974
996
|
"stream_id = "
|
|
975
997
|
<< stream->GetStreamId();
|
|
976
|
-
|
|
977
|
-
//
|
|
978
|
-
|
|
998
|
+
// As Trailing metadata is already read from CallInitiator, no need to send
|
|
999
|
+
// a status to the application.
|
|
1000
|
+
HandleStreamStateChange(*stream, stream->OnResetSent());
|
|
979
1001
|
}
|
|
980
1002
|
|
|
981
1003
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::DequeueStreamFrames "
|
|
@@ -1078,9 +1100,6 @@ auto Http2ServerTransport::MultiplexerLoop() {
|
|
|
1078
1100
|
}));
|
|
1079
1101
|
}
|
|
1080
1102
|
|
|
1081
|
-
//////////////////////////////////////////////////////////////////////////////
|
|
1082
|
-
// Spawn Helpers and Promise Helpers
|
|
1083
|
-
|
|
1084
1103
|
//////////////////////////////////////////////////////////////////////////////
|
|
1085
1104
|
// Settings
|
|
1086
1105
|
|
|
@@ -1092,10 +1111,9 @@ auto Http2ServerTransport::WaitForSettingsTimeoutOnDone() {
|
|
|
1092
1111
|
return [self = RefAsSubclass<Http2ServerTransport>()](absl::Status status) {
|
|
1093
1112
|
if (!status.ok()) {
|
|
1094
1113
|
GRPC_UNUSED absl::Status result = self->HandleError(
|
|
1095
|
-
/*
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
std::string(RFC9113::kSettingsTimeout)));
|
|
1114
|
+
/*stream=*/nullptr, Http2Status::Http2ConnectionError(
|
|
1115
|
+
Http2ErrorCode::kProtocolError,
|
|
1116
|
+
std::string(RFC9113::kSettingsTimeout)));
|
|
1099
1117
|
}
|
|
1100
1118
|
};
|
|
1101
1119
|
}
|
|
@@ -1253,7 +1271,7 @@ absl::Status Http2ServerTransport::MaybeAddStreamToWritableStreamList(
|
|
|
1253
1271
|
writable_stream_list_.Enqueue(std::move(stream), result.priority);
|
|
1254
1272
|
if (!status.ok()) {
|
|
1255
1273
|
return HandleError(
|
|
1256
|
-
/*
|
|
1274
|
+
/*stream=*/nullptr,
|
|
1257
1275
|
Http2Status::Http2ConnectionError(
|
|
1258
1276
|
Http2ErrorCode::kRefusedStream,
|
|
1259
1277
|
std::string(GrpcErrors::kFailedToEnqueueStream)));
|
|
@@ -1262,53 +1280,13 @@ absl::Status Http2ServerTransport::MaybeAddStreamToWritableStreamList(
|
|
|
1262
1280
|
return absl::OkStatus();
|
|
1263
1281
|
}
|
|
1264
1282
|
|
|
1265
|
-
// absl::StatusOr<uint32_t> Http2ServerTransport::NextStreamId() {
|
|
1266
|
-
// if (next_stream_id_ > GetMaxAllowedStreamId()) {
|
|
1267
|
-
// // TODO(tjagtap) : [PH2][P3] : Handle case if transport runs out of
|
|
1268
|
-
// stream
|
|
1269
|
-
// // ids
|
|
1270
|
-
// // RFC9113 : Stream identifiers cannot be reused. Long-lived connections
|
|
1271
|
-
// // can result in an endpoint exhausting the available range of stream
|
|
1272
|
-
// // identifiers. A client that is unable to establish a new stream
|
|
1273
|
-
// // identifier can establish a new connection for new streams. A server
|
|
1274
|
-
// // that is unable to establish a new stream identifier can send a GOAWAY
|
|
1275
|
-
// // frame so that the client is forced to open a new connection for new
|
|
1276
|
-
// // streams.
|
|
1277
|
-
// return absl::ResourceExhaustedError("No more stream ids available");
|
|
1278
|
-
// }
|
|
1279
|
-
// // TODO(akshitpatel) : [PH2][P3] : There is a channel arg to delay
|
|
1280
|
-
// // starting new streams instead of failing them. This needs to be
|
|
1281
|
-
// // implemented.
|
|
1282
|
-
// {
|
|
1283
|
-
// // TODO(tjagtap) : [PH2][P1] : For a server we will have to do
|
|
1284
|
-
// // this for incoming streams only. If a server receives more
|
|
1285
|
-
// // streams from a client than is allowed by the clients settings,
|
|
1286
|
-
// // whether or not we should fail is debatable.
|
|
1287
|
-
// MutexLock lock(&transport_mutex_);
|
|
1288
|
-
// if (GetActiveStreamCountLocked() >=
|
|
1289
|
-
// settings_->peer().max_concurrent_streams()) {
|
|
1290
|
-
// return absl::ResourceExhaustedError("Reached max concurrent streams");
|
|
1291
|
-
// }
|
|
1292
|
-
// }
|
|
1293
|
-
|
|
1294
|
-
// // RFC9113 : Streams initiated by a client MUST use odd-numbered stream
|
|
1295
|
-
// // identifiers.
|
|
1296
|
-
// uint32_t new_stream_id = std::exchange(next_stream_id_, next_stream_id_ +
|
|
1297
|
-
// 2); if (GPR_UNLIKELY(next_stream_id_ > GetMaxAllowedStreamId())) {
|
|
1298
|
-
// ReportDisconnection(
|
|
1299
|
-
// absl::ResourceExhaustedError("Transport Stream IDs exhausted"),
|
|
1300
|
-
// {}, // TODO(tjagtap) : [PH2][P2] : Report better disconnect info.
|
|
1301
|
-
// "no_more_stream_ids");
|
|
1302
|
-
// }
|
|
1303
|
-
// return new_stream_id;
|
|
1304
|
-
// }
|
|
1305
|
-
|
|
1306
1283
|
//////////////////////////////////////////////////////////////////////////////
|
|
1307
1284
|
// Stream Operations
|
|
1308
1285
|
auto Http2ServerTransport::HandleMetadataAndMessages(
|
|
1309
1286
|
RefCountedPtr<Stream> stream) {
|
|
1310
1287
|
auto send_message = [this, stream](MessageHandle&& message) mutable {
|
|
1311
|
-
return TrySeq(
|
|
1288
|
+
return TrySeq(HandleStreamErrorOnFailure(
|
|
1289
|
+
stream->EnqueueMessage(std::move(message)), stream),
|
|
1312
1290
|
[this, stream](const StreamWritabilityUpdate result) mutable {
|
|
1313
1291
|
GRPC_HTTP2_SERVER_DLOG
|
|
1314
1292
|
<< "Http2ServerTransport::HandleMetadataAndMessages "
|
|
@@ -1324,7 +1302,11 @@ auto Http2ServerTransport::HandleMetadataAndMessages(
|
|
|
1324
1302
|
stream->EnqueueInitialMetadata(
|
|
1325
1303
|
std::forward<ServerMetadataHandle>(metadata));
|
|
1326
1304
|
if (GPR_UNLIKELY(!enqueue_result.ok())) {
|
|
1327
|
-
|
|
1305
|
+
absl::Status status = enqueue_result.status();
|
|
1306
|
+
GRPC_UNUSED absl::Status unused = HandleError(
|
|
1307
|
+
stream, Http2Status::AbslStreamError(status.code(),
|
|
1308
|
+
std::string(status.message())));
|
|
1309
|
+
return status;
|
|
1328
1310
|
}
|
|
1329
1311
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::HandleMetadataAndMessages "
|
|
1330
1312
|
"Enqueued Initial Metadata";
|
|
@@ -1333,14 +1315,14 @@ auto Http2ServerTransport::HandleMetadataAndMessages(
|
|
|
1333
1315
|
};
|
|
1334
1316
|
|
|
1335
1317
|
return TrySeq(
|
|
1336
|
-
stream->GetCallInitiator().PullServerInitialMetadata(),
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1318
|
+
Map(stream->GetCallInitiator().PullServerInitialMetadata(),
|
|
1319
|
+
[send_initial_metadata = std::move(send_initial_metadata)](
|
|
1320
|
+
std::optional<ServerMetadataHandle> initial_metadata) mutable {
|
|
1321
|
+
if (initial_metadata.has_value()) {
|
|
1322
|
+
return send_initial_metadata(std::move(initial_metadata).value());
|
|
1323
|
+
}
|
|
1324
|
+
return absl::OkStatus();
|
|
1325
|
+
}),
|
|
1344
1326
|
ForEach(MessagesFrom(stream->GetCallInitiator()),
|
|
1345
1327
|
std::move(send_message)));
|
|
1346
1328
|
}
|
|
@@ -1354,6 +1336,10 @@ auto Http2ServerTransport::CallOutboundLoop(RefCountedPtr<Stream> stream) {
|
|
|
1354
1336
|
absl::StatusOr<StreamWritabilityUpdate> enqueue_result =
|
|
1355
1337
|
stream->EnqueueTrailingMetadata(std::move(metadata));
|
|
1356
1338
|
if (GPR_UNLIKELY(!enqueue_result.ok())) {
|
|
1339
|
+
GRPC_HTTP2_SERVER_DLOG
|
|
1340
|
+
<< "Http2ServerTransport::CallOutboundLoop Failed to enqueue "
|
|
1341
|
+
"trailing metadata: "
|
|
1342
|
+
<< enqueue_result.status();
|
|
1357
1343
|
return enqueue_result.status();
|
|
1358
1344
|
}
|
|
1359
1345
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::CallOutboundLoop "
|
|
@@ -1366,10 +1352,6 @@ auto Http2ServerTransport::CallOutboundLoop(RefCountedPtr<Stream> stream) {
|
|
|
1366
1352
|
"Ph2CallOutboundLoop",
|
|
1367
1353
|
Seq(Map(HandleMetadataAndMessages(stream),
|
|
1368
1354
|
[stream = stream.get()](absl::Status&& status) {
|
|
1369
|
-
if (GPR_UNLIKELY(!status.ok())) {
|
|
1370
|
-
// TODO(akshitpatel) : [PH2][P1] : Call BeginCloseStream.
|
|
1371
|
-
// BeginCloseStream(stream, error_code, cancelled_metadata);
|
|
1372
|
-
}
|
|
1373
1355
|
GRPC_HTTP2_SERVER_DLOG
|
|
1374
1356
|
<< "Http2ServerTransport::CallOutboundLoop "
|
|
1375
1357
|
"Completed initial metadata and messages with status: "
|
|
@@ -1385,7 +1367,6 @@ auto Http2ServerTransport::CallOutboundLoop(RefCountedPtr<Stream> stream) {
|
|
|
1385
1367
|
GRPC_HTTP2_SERVER_DLOG
|
|
1386
1368
|
<< "Http2ServerTransport::CallOutboundLoop "
|
|
1387
1369
|
"Received Server Trailing Metadata";
|
|
1388
|
-
// TODO(akshitpatel) : [PH2][P1] : Call BeginCloseStream.
|
|
1389
1370
|
return send_trailing_metadata(std::move(metadata));
|
|
1390
1371
|
});
|
|
1391
1372
|
}));
|
|
@@ -1409,14 +1390,13 @@ std::optional<RefCountedPtr<Stream>> Http2ServerTransport::MakeStream(
|
|
|
1409
1390
|
|
|
1410
1391
|
Http2Status Http2ServerTransport::IncomingStream(
|
|
1411
1392
|
ClientMetadataHandle&& metadata, const uint32_t stream_id) {
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
// }
|
|
1393
|
+
{
|
|
1394
|
+
MutexLock lock(&transport_mutex_);
|
|
1395
|
+
if (is_transport_closed_) {
|
|
1396
|
+
return Http2Status::Http2ConnectionError(Http2ErrorCode::kRefusedStream,
|
|
1397
|
+
"Transport is closed.");
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1420
1400
|
|
|
1421
1401
|
GRPC_DCHECK(LookupStream(stream_id) == nullptr);
|
|
1422
1402
|
|
|
@@ -1440,210 +1420,94 @@ Http2Status Http2ServerTransport::IncomingStream(
|
|
|
1440
1420
|
AddToStreamList(stream);
|
|
1441
1421
|
stream->SetInitialMetadataReceived();
|
|
1442
1422
|
|
|
1443
|
-
// TODO(tjagtap) : [PH2][P1] : We could receive a valid Metadata. And
|
|
1444
|
-
// Spawn CallOutboundLoop. But before the CallOutboundLoop starts, if
|
|
1445
|
-
// a BAD frame is received, it might cause either Stream or Transport Error.
|
|
1446
|
-
// Handle those errors.
|
|
1447
1423
|
stream->GetCallInitiator().SpawnGuarded(
|
|
1448
|
-
"CallOutboundLoop",
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1424
|
+
"CallOutboundLoop",
|
|
1425
|
+
[self = RefAsSubclass<Http2ServerTransport>(), stream = std::move(stream),
|
|
1426
|
+
call_handler = std::move(call.handler)]() mutable {
|
|
1427
|
+
self->call_destination_->StartCall(std::move(call_handler));
|
|
1428
|
+
return Map(self->CallOutboundLoop(std::move(stream)),
|
|
1429
|
+
[self](absl::Status status) { return status; });
|
|
1452
1430
|
});
|
|
1453
1431
|
return Http2Status::Ok();
|
|
1454
1432
|
}
|
|
1455
1433
|
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
// half close is discarded. If no RST stream is read, the stream is closed
|
|
1468
|
-
// for reads and writes upon sending the half close frame from the
|
|
1469
|
-
// multiplexer loop.
|
|
1470
|
-
// 3. Hitting error condition in the transport: In this case, RST stream is
|
|
1471
|
-
// enqueued and the stream is closed for reads immediately. This implies we
|
|
1472
|
-
// reduce the number of active streams inline. When multiplexer loop
|
|
1473
|
-
// processes the RST stream frame, the stream ref will dropped. The other
|
|
1474
|
-
// stream ref will be dropped when CallHandler's OnDone is executed causing
|
|
1475
|
-
// the stream to be destroyed. CallHandlers OnDone also tries to enqueue a
|
|
1476
|
-
// RST stream frame. This is a no-op at this point.
|
|
1477
|
-
// 4. Application abort: In this case, CallHandler OnDone will enqueue RST
|
|
1478
|
-
// stream frame to the stream data queue. The multiplexer loop will send the
|
|
1479
|
-
// reset stream frame and close the stream from reads and writes.
|
|
1480
|
-
// 5. Transport close: This takes up the same path as case 3.
|
|
1481
|
-
// In all the above cases, trailing metadata is pushed to the call spine.
|
|
1482
|
-
// Note: The stream ref is held in atmost 3 places:
|
|
1483
|
-
// 1. stream_list_ : This is released when the stream is closed for reads.
|
|
1484
|
-
// 2. CallHandler OnDone : This is released when Trailing Metadata is pushed to
|
|
1485
|
-
// the call spine.
|
|
1486
|
-
// 3. List of writable streams : This is released after the final frame is
|
|
1487
|
-
// dequeued from the StreamDataQueue.
|
|
1488
|
-
// void Http2ServerTransport::BeginCloseStream(
|
|
1489
|
-
// RefCountedPtr<Stream> stream,
|
|
1490
|
-
// std::optional<uint32_t> reset_stream_error_code,
|
|
1491
|
-
// ServerMetadataHandle&& metadata, DebugLocation whence) {
|
|
1492
|
-
// if (stream == nullptr) {
|
|
1493
|
-
// GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::BeginCloseStream stream
|
|
1494
|
-
// "
|
|
1495
|
-
// "is null reset_stream_error_code="
|
|
1496
|
-
// << (reset_stream_error_code.has_value()
|
|
1497
|
-
// ? absl::StrCat(*reset_stream_error_code)
|
|
1498
|
-
// : "nullopt")
|
|
1499
|
-
// << " metadata=" << metadata->DebugString();
|
|
1500
|
-
// return;
|
|
1501
|
-
// }
|
|
1502
|
-
|
|
1503
|
-
// GRPC_HTTP2_SERVER_DLOG
|
|
1504
|
-
// << "Http2ServerTransport::BeginCloseStream for stream id: "
|
|
1505
|
-
// << stream->GetStreamId() << " error_code="
|
|
1506
|
-
// << (reset_stream_error_code.has_value()
|
|
1507
|
-
// ? absl::StrCat(*reset_stream_error_code)
|
|
1508
|
-
// : "nullopt")
|
|
1509
|
-
// << " ServerMetadata=" << metadata->DebugString()
|
|
1510
|
-
// << " location=" << whence.file() << ":" << whence.line();
|
|
1511
|
-
|
|
1512
|
-
// bool close_reads = false;
|
|
1513
|
-
// bool close_writes = false;
|
|
1514
|
-
// if (metadata->get(GrpcCallWasCancelled())) {
|
|
1515
|
-
// if (!reset_stream_error_code) {
|
|
1516
|
-
// // Callers taking this path:
|
|
1517
|
-
// // 1. Reading a RST stream frame (will not send any frame out).
|
|
1518
|
-
// // 2. Closing a stream before initial metadata is sent.
|
|
1519
|
-
// close_reads = true;
|
|
1520
|
-
// close_writes = true;
|
|
1521
|
-
// GRPC_HTTP2_SERVER_DLOG
|
|
1522
|
-
// << "Http2ServerTransport::BeginCloseStream for stream id: "
|
|
1523
|
-
// << stream->GetStreamId() << " close_reads= " << close_reads
|
|
1524
|
-
// << " close_writes= " << close_writes;
|
|
1525
|
-
// } else {
|
|
1526
|
-
// // Callers taking this path:
|
|
1527
|
-
// // 1. Processing Error in transport (will send reset stream from here).
|
|
1528
|
-
// absl::StatusOr<StreamWritabilityUpdate> enqueue_result =
|
|
1529
|
-
// stream->EnqueueResetStream(reset_stream_error_code.value());
|
|
1530
|
-
// GRPC_HTTP2_SERVER_DLOG << "Enqueued ResetStream with error code="
|
|
1531
|
-
// << reset_stream_error_code.value()
|
|
1532
|
-
// << " status=" << enqueue_result.status();
|
|
1533
|
-
// if (enqueue_result.ok()) {
|
|
1534
|
-
// GRPC_UNUSED absl::Status status =
|
|
1535
|
-
// MaybeAddStreamToWritableStreamList(stream,
|
|
1536
|
-
// enqueue_result.value());
|
|
1537
|
-
// }
|
|
1538
|
-
// close_reads = true;
|
|
1539
|
-
// GRPC_HTTP2_SERVER_DLOG
|
|
1540
|
-
// << "Http2ServerTransport::BeginCloseStream for stream id: "
|
|
1541
|
-
// << stream->GetStreamId() << " close_reads= " << close_reads
|
|
1542
|
-
// << " close_writes= " << close_writes;
|
|
1543
|
-
// }
|
|
1544
|
-
// } else {
|
|
1545
|
-
// // Callers taking this path:
|
|
1546
|
-
// // 1. Reading Trailing Metadata (MAY send half close from OnDone).
|
|
1547
|
-
// // If a half close frame has already been sent, we should close the
|
|
1548
|
-
// stream
|
|
1549
|
-
// // for reads and writes.
|
|
1550
|
-
// if (stream->IsHalfClosedLocal() || stream->IsStreamClosed()) {
|
|
1551
|
-
// close_reads = true;
|
|
1552
|
-
// close_writes = true;
|
|
1553
|
-
// GRPC_HTTP2_SERVER_DLOG
|
|
1554
|
-
// << "Http2ServerTransport::BeginCloseStream for stream id: "
|
|
1555
|
-
// << stream->GetStreamId() << " close_reads= " << close_reads
|
|
1556
|
-
// << " close_writes= " << close_writes;
|
|
1557
|
-
// }
|
|
1558
|
-
// }
|
|
1559
|
-
|
|
1560
|
-
// if (close_reads || close_writes) {
|
|
1561
|
-
// CloseStream(*stream, CloseStreamArgs{close_reads, close_writes}, whence);
|
|
1562
|
-
// }
|
|
1563
|
-
|
|
1564
|
-
// // If the call was cancelled, the stream MUST be closed for reads.
|
|
1565
|
-
// GRPC_DCHECK(metadata->get(GrpcCallWasCancelled()) ? close_reads : true);
|
|
1566
|
-
|
|
1567
|
-
// // This maybe called multiple times while closing a stream. In CallV3, the
|
|
1568
|
-
// // flow for pushing server trailing metadata is idempotent. However, there
|
|
1569
|
-
// is
|
|
1570
|
-
// // a subtle difference. When we push server trailing metadata with a
|
|
1571
|
-
// cancelled
|
|
1572
|
-
// // status PushServerTrailingMetadata is spawned inline on the Call party
|
|
1573
|
-
// // whereas for the non-cancelled status, PushServerTrailingMetadata is
|
|
1574
|
-
// // spawned in the server_to_client spawn serializer. Because of this, in
|
|
1575
|
-
// // case when the server pushes trailing metadata (non-cancelled) followed
|
|
1576
|
-
// by a
|
|
1577
|
-
// // RST stream with cancelled status, it is possible that the cancelled
|
|
1578
|
-
// // trailing metadata (for RST stream) is processed before. This would
|
|
1579
|
-
// result
|
|
1580
|
-
// // in losing the actual status/message pushed by the server.
|
|
1581
|
-
// // To address this, we push the server trailing metadata to the stream only
|
|
1582
|
-
// // if it is not pushed already.
|
|
1583
|
-
// stream->MaybePushServerTrailingMetadata(std::move(metadata));
|
|
1584
|
-
// }
|
|
1585
|
-
|
|
1586
|
-
// This function MUST be idempotent. This function MUST be called from the
|
|
1587
|
-
// transport party.
|
|
1588
|
-
// void Http2ServerTransport::CloseStream(Stream& stream, CloseStreamArgs args,
|
|
1589
|
-
// DebugLocation whence) {
|
|
1590
|
-
// std::optional<Http2Status> close_transport_error;
|
|
1591
|
-
|
|
1592
|
-
// {
|
|
1593
|
-
// // TODO(akshitpatel) : [PH2][P3] : Measure the impact of holding mutex
|
|
1594
|
-
// // throughout this function.
|
|
1595
|
-
// MutexLock lock(&transport_mutex_);
|
|
1596
|
-
// GRPC_HTTP2_SERVER_DLOG
|
|
1597
|
-
// << "Http2ServerTransport::CloseStream for stream id: "
|
|
1598
|
-
// << stream.GetStreamId() << " close_reads=" << args.close_reads
|
|
1599
|
-
// << " close_writes=" << args.close_writes
|
|
1600
|
-
// << " read_context_=" << read_context_.DebugString()
|
|
1601
|
-
// << " location=" << whence.file() << ":" << whence.line();
|
|
1602
|
-
|
|
1603
|
-
// if (args.close_writes) {
|
|
1604
|
-
// stream.SetWriteClosed();
|
|
1605
|
-
// }
|
|
1434
|
+
void Http2ServerTransport::BeginCloseStream(
|
|
1435
|
+
RefCountedPtr<Stream> stream, uint32_t reset_stream_error_code,
|
|
1436
|
+
absl::Status trailing_metadata_status, DebugLocation whence) {
|
|
1437
|
+
GRPC_DCHECK(!trailing_metadata_status.ok());
|
|
1438
|
+
if (stream == nullptr) {
|
|
1439
|
+
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::BeginCloseStream stream"
|
|
1440
|
+
"is null reset_stream_error_code="
|
|
1441
|
+
<< reset_stream_error_code
|
|
1442
|
+
<< " status=" << trailing_metadata_status;
|
|
1443
|
+
return;
|
|
1444
|
+
}
|
|
1606
1445
|
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
//
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
//
|
|
1632
|
-
//
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1446
|
+
GRPC_HTTP2_SERVER_DLOG
|
|
1447
|
+
<< "Http2ServerTransport::BeginCloseStream for stream id: "
|
|
1448
|
+
<< stream->GetStreamId() << " error_code=" << reset_stream_error_code
|
|
1449
|
+
<< " Status=" << trailing_metadata_status << " location=" << whence.file()
|
|
1450
|
+
<< ":" << whence.line();
|
|
1451
|
+
|
|
1452
|
+
// Enqueue RST_STREAM.
|
|
1453
|
+
absl::StatusOr<StreamWritabilityUpdate> enqueue_result =
|
|
1454
|
+
stream->EnqueueResetStream(reset_stream_error_code);
|
|
1455
|
+
GRPC_HTTP2_SERVER_DLOG << "Enqueued ResetStream with error code="
|
|
1456
|
+
<< reset_stream_error_code
|
|
1457
|
+
<< " status=" << enqueue_result.status();
|
|
1458
|
+
if (enqueue_result.ok()) {
|
|
1459
|
+
GRPC_UNUSED absl::Status status =
|
|
1460
|
+
MaybeAddStreamToWritableStreamList(stream, enqueue_result.value());
|
|
1461
|
+
}
|
|
1462
|
+
HandleStreamStateChange(
|
|
1463
|
+
*stream, stream->OnInitiateReset(std::move(trailing_metadata_status)));
|
|
1464
|
+
read_context_.OnResetFrameEnqueued(reset_stream_error_code);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
void Http2ServerTransport::HandleStreamStateChange(Stream& stream,
|
|
1468
|
+
StreamStateChange change) {
|
|
1469
|
+
if (change.reads_became_closed) {
|
|
1470
|
+
// If a stream is closing for reads and was actively waiting for a
|
|
1471
|
+
// continuation frame, parse the buffered HEADER/CONTINUATION frames
|
|
1472
|
+
if (read_context_.IsWaitingForContinuationFrame() &&
|
|
1473
|
+
read_context_.GetStreamId() == stream.GetStreamId()) {
|
|
1474
|
+
Http2Status result = read_context_.ParseAndDiscardHeaders(
|
|
1475
|
+
SliceBuffer(), /*is_end_headers=*/false,
|
|
1476
|
+
/*original_status=*/Http2Status::Ok(),
|
|
1477
|
+
settings_->acked().max_header_list_size());
|
|
1478
|
+
if (result.GetType() == Http2Status::Http2ErrorType::kConnectionError) {
|
|
1479
|
+
GRPC_HTTP2_SERVER_DLOG
|
|
1480
|
+
<< "Http2ServerTransport::HandleStreamStateChange (DiscardHeaders) "
|
|
1481
|
+
"for stream id: "
|
|
1482
|
+
<< stream.GetStreamId()
|
|
1483
|
+
<< " failed to partially process header : " << result.DebugString();
|
|
1484
|
+
GRPC_UNUSED absl::Status status =
|
|
1485
|
+
HandleError(/*stream=*/nullptr, std::move(result));
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
if (change.stream_became_closed) {
|
|
1491
|
+
CleanupStream(stream);
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1641
1494
|
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1495
|
+
void Http2ServerTransport::CleanupStream(Stream& stream) {
|
|
1496
|
+
bool should_close = false;
|
|
1497
|
+
{
|
|
1498
|
+
MutexLock lock(&transport_mutex_);
|
|
1499
|
+
stream_list_.erase(stream.GetStreamId());
|
|
1500
|
+
// Close transport if graceful GOAWAY has been sent and there are no more
|
|
1501
|
+
// streams.
|
|
1502
|
+
if (goaway_manager_.IsFinalGracefulGoawaySent() && stream_list_.empty()) {
|
|
1503
|
+
should_close = true;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
if (should_close) {
|
|
1507
|
+
MaybeSpawnCloseTransport(Http2Status::AbslConnectionError(
|
|
1508
|
+
absl::StatusCode::kUnavailable, "Graceful shutdown complete."));
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1647
1511
|
|
|
1648
1512
|
absl::Status Http2ServerTransport::UpdateAllStreamsWritability() {
|
|
1649
1513
|
MutexLock lock(&transport_mutex_);
|
|
@@ -1674,27 +1538,27 @@ absl::Status Http2ServerTransport::UpdateAllStreamsWritability() {
|
|
|
1674
1538
|
//////////////////////////////////////////////////////////////////////////////
|
|
1675
1539
|
// Ping Keepalive and Goaway
|
|
1676
1540
|
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1541
|
+
void Http2ServerTransport::MaybeSpawnPingTimeout(
|
|
1542
|
+
std::optional<uint64_t> opaque_data) {
|
|
1543
|
+
if (opaque_data.has_value()) {
|
|
1544
|
+
SpawnGuardedTransportParty(
|
|
1545
|
+
"PingTimeout", [self = RefAsSubclass<Http2ServerTransport>(),
|
|
1546
|
+
opaque_data = *opaque_data]() {
|
|
1547
|
+
return self->ping_manager_->TimeoutPromise(opaque_data);
|
|
1548
|
+
});
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
void Http2ServerTransport::MaybeSpawnDelayedPing(
|
|
1552
|
+
std::optional<Duration> delayed_ping_wait) {
|
|
1553
|
+
if (delayed_ping_wait.has_value()) {
|
|
1554
|
+
SpawnGuardedTransportParty(
|
|
1555
|
+
"DelayedPing", [self = RefAsSubclass<Http2ServerTransport>(),
|
|
1556
|
+
wait = *delayed_ping_wait]() {
|
|
1557
|
+
GRPC_HTTP2_PING_LOG << "Scheduling delayed ping after wait=" << wait;
|
|
1558
|
+
return self->ping_manager_->DelayedPingPromise(wait);
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1698
1562
|
|
|
1699
1563
|
absl::Status Http2ServerTransport::AckPing(uint64_t opaque_data) {
|
|
1700
1564
|
// It is possible that the PingRatePolicy may decide to not send a ping
|
|
@@ -1715,122 +1579,151 @@ absl::Status Http2ServerTransport::AckPing(uint64_t opaque_data) {
|
|
|
1715
1579
|
return absl::OkStatus();
|
|
1716
1580
|
}
|
|
1717
1581
|
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1582
|
+
void Http2ServerTransport::MaybeSpawnKeepaliveLoop() {
|
|
1583
|
+
if (keepalive_manager_->IsKeepAliveLoopNeeded()) {
|
|
1584
|
+
SpawnGuardedTransportParty(
|
|
1585
|
+
"KeepaliveLoop", [self = RefAsSubclass<Http2ServerTransport>()]() {
|
|
1586
|
+
return self->keepalive_manager_->KeepaliveLoop();
|
|
1587
|
+
});
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
auto Http2ServerTransport::SpawnGracefulGoawayPromise(Slice&& debug_data) {
|
|
1592
|
+
SpawnGuardedTransportParty(
|
|
1593
|
+
"GracefulGoaway",
|
|
1594
|
+
[self = RefAsSubclass<Http2ServerTransport>(),
|
|
1595
|
+
debug_data = std::forward<Slice>(debug_data)]() mutable {
|
|
1596
|
+
GRPC_HTTP2_SERVER_DLOG
|
|
1597
|
+
<< "Http2ServerTransport::SpawnGracefulGoawayPromise: "
|
|
1598
|
+
"Initiated graceful GOAWAY";
|
|
1599
|
+
return self->UntilTransportClosed(Map(
|
|
1600
|
+
self->goaway_manager_.RequestGoaway(
|
|
1601
|
+
Http2ErrorCode::kNoError, std::move(debug_data),
|
|
1602
|
+
self->last_incoming_stream_id_, /*immediate=*/false),
|
|
1603
|
+
[self](absl::Status status) {
|
|
1604
|
+
bool should_close = false;
|
|
1605
|
+
{
|
|
1606
|
+
MutexLock lock(&self->transport_mutex_);
|
|
1607
|
+
if (self->GetActiveStreamCountLocked() == 0) {
|
|
1608
|
+
should_close = true;
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
if (should_close) {
|
|
1612
|
+
self->MaybeSpawnCloseTransport(Http2Status::AbslConnectionError(
|
|
1613
|
+
absl::StatusCode::kUnavailable,
|
|
1614
|
+
"Graceful shutdown complete."));
|
|
1615
|
+
}
|
|
1616
|
+
return status;
|
|
1617
|
+
}));
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1726
1620
|
|
|
1727
1621
|
//////////////////////////////////////////////////////////////////////////////
|
|
1728
1622
|
// Error Path and Close Path
|
|
1729
1623
|
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
// http2_status.GetAbslConnectionError(), {},
|
|
1758
|
-
// absl::StrCat("Transport closed: ",
|
|
1759
|
-
// http2_status.DebugString()).c_str());
|
|
1760
|
-
// lock.Release();
|
|
1761
|
-
|
|
1762
|
-
// SpawnInfallibleTransportParty(
|
|
1763
|
-
// "CloseTransport", [self = RefAsSubclass<Http2ServerTransport>(),
|
|
1764
|
-
// stream_list = std::move(stream_list),
|
|
1765
|
-
// http2_status = std::move(http2_status)]() mutable {
|
|
1766
|
-
// self->security_frame_handler_->OnTransportClosed();
|
|
1767
|
-
// GRPC_HTTP2_SERVER_DLOG
|
|
1768
|
-
// << "Http2ServerTransport::MaybeSpawnCloseTransport "
|
|
1769
|
-
// "Cleaning up call stacks";
|
|
1770
|
-
// // Clean up the call stacks for all active streams.
|
|
1771
|
-
// for (const auto& pair : stream_list) {
|
|
1772
|
-
// // There is no merit in transitioning the stream to
|
|
1773
|
-
// // closed state here as the subsequent lookups would
|
|
1774
|
-
// // fail. Also, as this is running on the transport
|
|
1775
|
-
// // party, there would not be concurrent access to the stream.
|
|
1776
|
-
// RefCountedPtr<Stream> stream = pair.second;
|
|
1777
|
-
// self->BeginCloseStream(std::move(stream),
|
|
1778
|
-
// Http2ErrorCodeToFrameErrorCode(
|
|
1779
|
-
// http2_status.GetConnectionErrorCode()),
|
|
1780
|
-
// CancelledServerMetadataFromStatus(
|
|
1781
|
-
// http2_status.GetAbslConnectionError()));
|
|
1782
|
-
// }
|
|
1783
|
-
|
|
1784
|
-
// // RFC9113 : A GOAWAY frame might not immediately precede closing of
|
|
1785
|
-
// // the connection; a receiver of a GOAWAY that has no more use for
|
|
1786
|
-
// the
|
|
1787
|
-
// // connection SHOULD still send a GOAWAY frame before terminating the
|
|
1788
|
-
// // connection.
|
|
1789
|
-
// return Map(
|
|
1790
|
-
// // TODO(akshitpatel) : [PH2][P4] : This is creating a copy of
|
|
1791
|
-
// // the debug data. Verify if this is causing a performance
|
|
1792
|
-
// // issue.
|
|
1793
|
-
// Race(AssertResultType<absl::Status>(
|
|
1794
|
-
// self->goaway_manager_.RequestGoaway(
|
|
1795
|
-
// http2_status.GetConnectionErrorCode(),
|
|
1796
|
-
// /*debug_data=*/
|
|
1797
|
-
// Slice::FromCopiedString(
|
|
1798
|
-
// http2_status.GetAbslConnectionError().message()),
|
|
1799
|
-
// kLastIncomingStreamIdClient, /*immediate=*/true)),
|
|
1800
|
-
// // Failsafe to close the transport if goaway is not
|
|
1801
|
-
// // sent within kGoawaySendTimeoutSeconds seconds.
|
|
1802
|
-
// Sleep(Duration::Seconds(kGoawaySendTimeoutSeconds))),
|
|
1803
|
-
// [self](auto) mutable {
|
|
1804
|
-
// self->CloseTransport();
|
|
1805
|
-
// return Empty{};
|
|
1806
|
-
// });
|
|
1807
|
-
// ;
|
|
1808
|
-
// });
|
|
1809
|
-
// }
|
|
1624
|
+
absl::Status Http2ServerTransport::HandleError(RefCountedPtr<Stream> stream,
|
|
1625
|
+
Http2Status status,
|
|
1626
|
+
DebugLocation whence) {
|
|
1627
|
+
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::HandleError for stream id="
|
|
1628
|
+
<< (stream != nullptr
|
|
1629
|
+
? absl::StrCat(stream->GetStreamId())
|
|
1630
|
+
: "nullopt")
|
|
1631
|
+
<< " status=" << status.DebugString()
|
|
1632
|
+
<< " location=" << whence.file() << ":"
|
|
1633
|
+
<< whence.line();
|
|
1634
|
+
Http2Status::Http2ErrorType error_type = status.GetType();
|
|
1635
|
+
GRPC_DCHECK(error_type != Http2Status::Http2ErrorType::kOk);
|
|
1636
|
+
|
|
1637
|
+
if (error_type == Http2Status::Http2ErrorType::kConnectionError) {
|
|
1638
|
+
GRPC_DCHECK(stream == nullptr);
|
|
1639
|
+
absl::Status absl_status = status.GetAbslConnectionError();
|
|
1640
|
+
MaybeSpawnCloseTransport(std::move(status), whence);
|
|
1641
|
+
return absl_status;
|
|
1642
|
+
} else if (error_type == Http2Status::Http2ErrorType::kStreamError) {
|
|
1643
|
+
uint32_t reset_stream_error_code =
|
|
1644
|
+
Http2ErrorCodeToFrameErrorCode(status.GetStreamErrorCode());
|
|
1645
|
+
if (stream != nullptr) {
|
|
1646
|
+
BeginCloseStream(std::move(stream), reset_stream_error_code,
|
|
1647
|
+
status.GetAbslStreamError(), whence);
|
|
1648
|
+
}
|
|
1649
|
+
return absl::OkStatus();
|
|
1650
|
+
}
|
|
1810
1651
|
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
// // max allowed stream id, then no more streams can be created and it is
|
|
1814
|
-
// // safe to close the transport.
|
|
1815
|
-
// GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::CanCloseTransportLocked "
|
|
1816
|
-
// "GetActiveStreamCountLocked="
|
|
1817
|
-
// << GetActiveStreamCountLocked()
|
|
1818
|
-
// << " PeekNextStreamId=" << PeekNextStreamId()
|
|
1819
|
-
// << " GetMaxAllowedStreamId="
|
|
1820
|
-
// << GetMaxAllowedStreamId();
|
|
1821
|
-
// return GetActiveStreamCountLocked() == 0 &&
|
|
1822
|
-
// PeekNextStreamId() > GetMaxAllowedStreamId();
|
|
1823
|
-
// }
|
|
1652
|
+
GPR_UNREACHABLE_CODE(return absl::InternalError("Invalid error type"));
|
|
1653
|
+
}
|
|
1824
1654
|
|
|
1825
|
-
|
|
1826
|
-
|
|
1655
|
+
void Http2ServerTransport::MaybeSpawnCloseTransport(Http2Status http2_status,
|
|
1656
|
+
DebugLocation whence) {
|
|
1657
|
+
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::MaybeSpawnCloseTransport "
|
|
1658
|
+
"status="
|
|
1659
|
+
<< http2_status.DebugString()
|
|
1660
|
+
<< " location=" << whence.file() << ":"
|
|
1661
|
+
<< whence.line();
|
|
1827
1662
|
|
|
1828
|
-
|
|
1829
|
-
|
|
1663
|
+
ReleasableMutexLock lock(&transport_mutex_);
|
|
1664
|
+
if (is_transport_closed_) {
|
|
1665
|
+
lock.Release();
|
|
1666
|
+
return;
|
|
1667
|
+
}
|
|
1668
|
+
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::MaybeSpawnCloseTransport "
|
|
1669
|
+
"Initiating transport close";
|
|
1670
|
+
is_transport_closed_ = true;
|
|
1671
|
+
absl::flat_hash_map<uint32_t, RefCountedPtr<Stream>> stream_list =
|
|
1672
|
+
std::move(stream_list_);
|
|
1673
|
+
stream_list_.clear();
|
|
1674
|
+
ReportDisconnectionLocked(
|
|
1675
|
+
GRPC_CHANNEL_SHUTDOWN, http2_status.GetAbslConnectionError(), {},
|
|
1676
|
+
absl::StrCat("Transport closed: ", http2_status.DebugString()).c_str());
|
|
1677
|
+
lock.Release();
|
|
1678
|
+
|
|
1679
|
+
SpawnInfallibleTransportParty(
|
|
1680
|
+
"CloseTransport",
|
|
1681
|
+
[self = RefAsSubclass<Http2ServerTransport>(),
|
|
1682
|
+
stream_list = std::move(stream_list),
|
|
1683
|
+
http2_status = std::move(http2_status), whence]() mutable {
|
|
1684
|
+
self->security_frame_handler_->OnTransportClosed();
|
|
1685
|
+
GRPC_HTTP2_SERVER_DLOG
|
|
1686
|
+
<< "Http2ServerTransport::MaybeSpawnCloseTransport "
|
|
1687
|
+
"Cleaning up call stacks";
|
|
1688
|
+
// Clean up the call stacks for all active streams.
|
|
1689
|
+
for (const auto& pair : stream_list) {
|
|
1690
|
+
RefCountedPtr<Stream> stream = pair.second;
|
|
1691
|
+
self->BeginCloseStream(std::move(stream),
|
|
1692
|
+
Http2ErrorCodeToFrameErrorCode(
|
|
1693
|
+
http2_status.GetConnectionErrorCode()),
|
|
1694
|
+
http2_status.GetAbslConnectionError(), whence);
|
|
1695
|
+
}
|
|
1830
1696
|
|
|
1831
|
-
//
|
|
1832
|
-
//
|
|
1833
|
-
|
|
1697
|
+
// Sleep for kGoawaySendTimeoutSeconds before closing the transport to
|
|
1698
|
+
// let write buffers drain.
|
|
1699
|
+
return Map(
|
|
1700
|
+
Race(AssertResultType<absl::Status>(
|
|
1701
|
+
self->goaway_manager_.RequestGoaway(
|
|
1702
|
+
http2_status.GetConnectionErrorCode(),
|
|
1703
|
+
Slice::FromCopiedString(std::string(
|
|
1704
|
+
http2_status.GetAbslConnectionError().message())),
|
|
1705
|
+
self->last_incoming_stream_id_, /*immediate=*/true)),
|
|
1706
|
+
Sleep(Duration::Seconds(kGoawaySendTimeoutSeconds))),
|
|
1707
|
+
[self](auto) mutable {
|
|
1708
|
+
self->CloseTransport();
|
|
1709
|
+
return Empty{};
|
|
1710
|
+
});
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
void Http2ServerTransport::CloseTransport() {
|
|
1715
|
+
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::CloseTransport";
|
|
1716
|
+
|
|
1717
|
+
transport_closed_latch_.Set();
|
|
1718
|
+
settings_->HandleTransportShutdown(event_engine_.get());
|
|
1719
|
+
|
|
1720
|
+
if (on_close_callback_ != nullptr) {
|
|
1721
|
+
ExecCtx::Run(DEBUG_LOCATION, on_close_callback_, absl::OkStatus());
|
|
1722
|
+
on_close_callback_ = nullptr;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
general_party_.reset();
|
|
1726
|
+
}
|
|
1834
1727
|
|
|
1835
1728
|
//////////////////////////////////////////////////////////////////////////////
|
|
1836
1729
|
// Misc Transport Stuff
|
|
@@ -1923,10 +1816,6 @@ void Http2ServerTransport::ReadChannelArgs(const ChannelArgs& channel_args,
|
|
|
1923
1816
|
keepalive_permit_without_calls_ = args.keepalive_permit_without_calls;
|
|
1924
1817
|
test_only_ack_pings_ = args.test_only_ack_pings;
|
|
1925
1818
|
|
|
1926
|
-
if (args.initial_sequence_number > 0) {
|
|
1927
|
-
next_stream_id_ = args.initial_sequence_number;
|
|
1928
|
-
}
|
|
1929
|
-
|
|
1930
1819
|
settings_->SetSettingsTimeout(args.settings_timeout);
|
|
1931
1820
|
if (args.max_usable_hpack_table_size >= 0) {
|
|
1932
1821
|
encoder_.SetMaxUsableSize(args.max_usable_hpack_table_size);
|
|
@@ -1958,7 +1847,7 @@ Http2ServerTransport::PingSystemInterfaceImpl::PingTimeout() {
|
|
|
1958
1847
|
// kRefusedStream doesn't seem to fit this case. We should revisit this
|
|
1959
1848
|
// and update the error code.
|
|
1960
1849
|
return Immediate(transport_->HandleError(
|
|
1961
|
-
|
|
1850
|
+
nullptr,
|
|
1962
1851
|
Http2Status::Http2ConnectionError(Http2ErrorCode::kRefusedStream,
|
|
1963
1852
|
GRPC_CHTTP2_PING_TIMEOUT_STR)));
|
|
1964
1853
|
}
|
|
@@ -1987,7 +1876,7 @@ Http2ServerTransport::KeepAliveInterfaceImpl::OnKeepAliveTimeout() {
|
|
|
1987
1876
|
// kRefusedStream doesn't seem to fit this case. We should revisit this
|
|
1988
1877
|
// and update the error code.
|
|
1989
1878
|
return Immediate(transport_->HandleError(
|
|
1990
|
-
|
|
1879
|
+
nullptr,
|
|
1991
1880
|
Http2Status::Http2ConnectionError(Http2ErrorCode::kRefusedStream,
|
|
1992
1881
|
GRPC_CHTTP2_KEEPALIVE_TIMEOUT_STR)));
|
|
1993
1882
|
}
|
|
@@ -2009,9 +1898,7 @@ Http2ServerTransport::GoawayInterfaceImpl::Make(
|
|
|
2009
1898
|
}
|
|
2010
1899
|
|
|
2011
1900
|
uint32_t Http2ServerTransport::GoawayInterfaceImpl::GetLastAcceptedStreamId() {
|
|
2012
|
-
|
|
2013
|
-
// Implement this for the server.
|
|
2014
|
-
return 0;
|
|
1901
|
+
return transport_->last_incoming_stream_id_;
|
|
2015
1902
|
}
|
|
2016
1903
|
|
|
2017
1904
|
//////////////////////////////////////////////////////////////////////////////
|
|
@@ -2024,14 +1911,14 @@ Http2ServerTransport::Http2ServerTransport(
|
|
|
2024
1911
|
grpc_closure* on_close_callback)
|
|
2025
1912
|
: channelz::DataSource(http2::CreateChannelzSocketNode(
|
|
2026
1913
|
endpoint.GetEventEngineEndpoint(), channel_args)),
|
|
2027
|
-
outgoing_frames_(10), // TODO(akshitpatel) : [PH2][P0][Write] : Remove
|
|
2028
1914
|
event_engine_(std::move(event_engine)),
|
|
2029
1915
|
endpoint_(std::move(endpoint)),
|
|
2030
1916
|
settings_(MakeRefCounted<SettingsPromiseManager>(
|
|
2031
|
-
std::move(on_receive_settings))),
|
|
1917
|
+
kIsClient, std::move(on_receive_settings))),
|
|
2032
1918
|
on_close_callback_(on_close_callback),
|
|
2033
1919
|
should_reset_ping_clock_(false),
|
|
2034
|
-
read_context_(MaxNewStreamsPerRead(channel_args), endpoint_, kIsClient
|
|
1920
|
+
read_context_(MaxNewStreamsPerRead(channel_args), endpoint_, kIsClient,
|
|
1921
|
+
GetMaxSecurityFrameSize(channel_args)),
|
|
2035
1922
|
transport_write_context_(kIsClient),
|
|
2036
1923
|
ping_manager_(std::nullopt),
|
|
2037
1924
|
keepalive_manager_(std::nullopt),
|
|
@@ -2040,7 +1927,7 @@ Http2ServerTransport::Http2ServerTransport(
|
|
|
2040
1927
|
->memory_quota()
|
|
2041
1928
|
->CreateMemoryOwner()),
|
|
2042
1929
|
flow_control_(
|
|
2043
|
-
|
|
1930
|
+
/*peer_name=*/read_context_.peer_string().as_string_view(),
|
|
2044
1931
|
channel_args.GetBool(GRPC_ARG_HTTP2_BDP_PROBE).value_or(true),
|
|
2045
1932
|
&memory_owner_),
|
|
2046
1933
|
security_frame_handler_(MakeRefCounted<SecurityFrameHandler>()),
|
|
@@ -2099,7 +1986,6 @@ void Http2ServerTransport::SetCallDestination(
|
|
|
2099
1986
|
|
|
2100
1987
|
void Http2ServerTransport::PerformOp(grpc_transport_op* op) {
|
|
2101
1988
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport PerformOp Begin";
|
|
2102
|
-
// TODO(tjagtap) : [PH2][P1] : Implement the needed operations.
|
|
2103
1989
|
bool did_stuff = false;
|
|
2104
1990
|
if (op->start_connectivity_watch != nullptr) {
|
|
2105
1991
|
StartConnectivityWatch(op->start_connectivity_watch_state,
|
|
@@ -2110,8 +1996,20 @@ void Http2ServerTransport::PerformOp(grpc_transport_op* op) {
|
|
|
2110
1996
|
StopConnectivityWatch(op->stop_connectivity_watch);
|
|
2111
1997
|
did_stuff = true;
|
|
2112
1998
|
}
|
|
2113
|
-
|
|
2114
|
-
|
|
1999
|
+
if (!op->disconnect_with_error.ok()) {
|
|
2000
|
+
MaybeSpawnCloseTransport(Http2Status::Http2ConnectionError(
|
|
2001
|
+
AbslStatusCodeToErrorCode(op->disconnect_with_error.code()),
|
|
2002
|
+
std::string(op->disconnect_with_error.message())));
|
|
2003
|
+
did_stuff = true;
|
|
2004
|
+
}
|
|
2005
|
+
// We always consider this case as a graceful shutdown.
|
|
2006
|
+
if (!op->goaway_error.ok()) {
|
|
2007
|
+
GRPC_HTTP2_SERVER_DLOG << "GracefulGoaway triggered with error: "
|
|
2008
|
+
<< op->goaway_error;
|
|
2009
|
+
SpawnGracefulGoawayPromise(
|
|
2010
|
+
Slice::FromCopiedString(op->goaway_error.message()));
|
|
2011
|
+
did_stuff = true;
|
|
2012
|
+
}
|
|
2115
2013
|
GRPC_DCHECK(did_stuff) << "Unimplemented transport perform op ";
|
|
2116
2014
|
|
|
2117
2015
|
ExecCtx::Run(DEBUG_LOCATION, op->on_consumed, absl::OkStatus());
|
|
@@ -2128,27 +2026,15 @@ void Http2ServerTransport::PerformOp(grpc_transport_op* op) {
|
|
|
2128
2026
|
void Http2ServerTransport::Orphan() {
|
|
2129
2027
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::Orphan Begin";
|
|
2130
2028
|
SourceDestructing();
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
// TODO(akshitpatel) : [PH2][P1] : These calls need to be moved to a different
|
|
2135
|
-
// place once shutdown code is added.
|
|
2136
|
-
ReportDisconnection(GRPC_CHANNEL_SHUTDOWN, absl::UnavailableError("Orphan"),
|
|
2137
|
-
StateWatcher::DisconnectInfo(), "Orphan");
|
|
2138
|
-
// TODO(tjagtap) : [PH2][P2] : Implement the needed cleanup. This is not the
|
|
2139
|
-
// right place to clean up the party.
|
|
2140
|
-
general_party_.reset();
|
|
2141
|
-
if (on_close_callback_ != nullptr) {
|
|
2142
|
-
ExecCtx::Run(DEBUG_LOCATION, on_close_callback_, absl::OkStatus());
|
|
2143
|
-
on_close_callback_ = nullptr;
|
|
2144
|
-
}
|
|
2029
|
+
MaybeSpawnCloseTransport(
|
|
2030
|
+
ToHttpOkOrConnError(absl::UnavailableError("Orphaned")));
|
|
2145
2031
|
Unref();
|
|
2146
2032
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::Orphan End";
|
|
2147
2033
|
}
|
|
2148
2034
|
|
|
2149
2035
|
void Http2ServerTransport::SpawnTransportLoops() {
|
|
2150
2036
|
GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::SpawnTransportLoops Begin";
|
|
2151
|
-
|
|
2037
|
+
MaybeSpawnKeepaliveLoop();
|
|
2152
2038
|
|
|
2153
2039
|
// SpawnGuardedTransportParty(
|
|
2154
2040
|
// "FlowControlPeriodicUpdateLoop",
|
|
@@ -2170,16 +2056,16 @@ void Http2ServerTransport::SpawnTransportLoops() {
|
|
|
2170
2056
|
void Http2ServerTransport::InitializeAndSpawnTransportLoops() {
|
|
2171
2057
|
SpawnGuardedTransportParty(
|
|
2172
2058
|
"SpawnTransportLoops", [self = RefAsSubclass<Http2ServerTransport>()] {
|
|
2173
|
-
return Map(
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2059
|
+
return Map(self->EndpointReadSlice(GRPC_CHTTP2_CLIENT_CONNECT_STRLEN),
|
|
2060
|
+
[self](absl::StatusOr<Slice> status) -> absl::Status {
|
|
2061
|
+
Http2Status result =
|
|
2062
|
+
ValidateIncomingConnectionPreface(status);
|
|
2063
|
+
if (!result.IsOk()) {
|
|
2064
|
+
return self->HandleError(nullptr, std::move(result));
|
|
2065
|
+
}
|
|
2066
|
+
self->SpawnTransportLoops();
|
|
2067
|
+
return absl::OkStatus();
|
|
2068
|
+
});
|
|
2183
2069
|
});
|
|
2184
2070
|
}
|
|
2185
2071
|
|