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.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8 -5
  3. data/etc/roots.pem +10400 -3855
  4. data/include/grpc/grpc_audit_logging.h +2 -2
  5. data/include/grpc/grpc_security_constants.h +2 -0
  6. data/include/grpc/impl/channel_arg_names.h +23 -0
  7. data/src/core/call/call_filters.h +19 -3
  8. data/src/core/call/call_spine.h +4 -4
  9. data/src/core/call/client_call.cc +1 -1
  10. data/src/core/call/metadata.cc +7 -2
  11. data/src/core/call/server_call.cc +13 -3
  12. data/src/core/call/server_call.h +5 -3
  13. data/src/core/client_channel/backup_poller.cc +2 -17
  14. data/src/core/client_channel/client_channel.cc +17 -14
  15. data/src/core/client_channel/client_channel.h +3 -1
  16. data/src/core/client_channel/client_channel_filter.cc +11 -13
  17. data/src/core/client_channel/client_channel_service_config.cc +5 -13
  18. data/src/core/client_channel/direct_channel.cc +5 -1
  19. data/src/core/client_channel/direct_channel.h +3 -1
  20. data/src/core/config/experiment_env_var.cc +30 -0
  21. data/src/core/config/experiment_env_var.h +26 -0
  22. data/src/core/credentials/call/regional_access_boundary_fetcher.cc +6 -6
  23. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +14 -2
  24. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.cc +172 -0
  25. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.h +103 -0
  26. data/src/core/credentials/transport/tls/load_system_roots_fallback.cc +3 -2
  27. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +10 -3
  28. data/src/core/credentials/transport/tls/tls_security_connector.cc +14 -2
  29. data/src/core/credentials/transport/xds/xds_credentials.cc +4 -12
  30. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +2 -1
  31. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +19 -13
  32. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +11 -9
  33. data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -2
  34. data/src/core/ext/transport/chttp2/transport/flow_control.h +3 -2
  35. data/src/core/ext/transport/chttp2/transport/frame.cc +58 -1
  36. data/src/core/ext/transport/chttp2/transport/frame.h +13 -1
  37. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -4
  38. data/src/core/ext/transport/chttp2/transport/frame_security.cc +10 -1
  39. data/src/core/ext/transport/chttp2/transport/frame_security.h +2 -1
  40. data/src/core/ext/transport/chttp2/transport/goaway.cc +11 -1
  41. data/src/core/ext/transport/chttp2/transport/goaway.h +17 -1
  42. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +9 -0
  43. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +117 -276
  44. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +44 -17
  45. data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +382 -496
  46. data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +75 -77
  47. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -1
  48. data/src/core/ext/transport/chttp2/transport/http2_settings.h +30 -11
  49. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +24 -9
  50. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +26 -0
  51. data/src/core/ext/transport/chttp2/transport/http2_transport.h +2 -0
  52. data/src/core/ext/transport/chttp2/transport/internal.h +4 -0
  53. data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
  54. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +1 -1
  55. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +4 -10
  56. data/src/core/ext/transport/chttp2/transport/read_context.h +62 -20
  57. data/src/core/ext/transport/chttp2/transport/security_frame.h +1 -0
  58. data/src/core/ext/transport/chttp2/transport/stream.h +271 -120
  59. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +77 -61
  60. data/src/core/handshaker/security/secure_endpoint.cc +0 -13
  61. data/src/core/lib/channel/promise_based_filter.cc +77 -3
  62. data/src/core/lib/channel/promise_based_filter.h +238 -184
  63. data/src/core/lib/event_engine/extensions/receive_coalescing_extension.h +0 -4
  64. data/src/core/lib/event_engine/extensions/tcp_trace.h +1 -1
  65. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +2 -12
  66. data/src/core/lib/event_engine/shim.cc +2 -16
  67. data/src/core/lib/event_engine/shim.h +0 -4
  68. data/src/core/lib/experiments/experiments.cc +51 -102
  69. data/src/core/lib/experiments/experiments.h +37 -59
  70. data/src/core/lib/iomgr/error.cc +3 -73
  71. data/src/core/lib/iomgr/error.h +8 -6
  72. data/src/core/lib/iomgr/error_cfstream.cc +1 -2
  73. data/src/core/lib/iomgr/ev_epoll1_linux.cc +2 -6
  74. data/src/core/lib/iomgr/ev_poll_posix.cc +2 -6
  75. data/src/core/lib/iomgr/tcp_posix.cc +2 -6
  76. data/src/core/lib/security/authorization/audit_logging.cc +2 -2
  77. data/src/core/lib/security/authorization/audit_logging.h +3 -3
  78. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +11 -13
  79. data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
  80. data/src/core/lib/security/authorization/matchers.cc +20 -20
  81. data/src/core/lib/security/authorization/matchers.h +15 -16
  82. data/src/core/lib/security/authorization/rbac_policy.h +1 -1
  83. data/src/core/lib/security/authorization/stdout_logger.cc +3 -3
  84. data/src/core/lib/security/authorization/stdout_logger.h +6 -5
  85. data/src/core/lib/surface/call.cc +0 -8
  86. data/src/core/lib/surface/call.h +2 -0
  87. data/src/core/lib/surface/channel.cc +21 -2
  88. data/src/core/lib/surface/channel.h +14 -6
  89. data/src/core/lib/surface/filter_stack_call.cc +10 -29
  90. data/src/core/lib/surface/legacy_channel.cc +7 -7
  91. data/src/core/lib/surface/legacy_channel.h +3 -1
  92. data/src/core/lib/surface/version.cc +2 -2
  93. data/src/core/lib/transport/bdp_estimator.cc +13 -13
  94. data/src/core/lib/transport/bdp_estimator.h +9 -5
  95. data/src/core/lib/transport/error_utils.cc +26 -138
  96. data/src/core/lib/transport/promise_endpoint.h +2 -4
  97. data/src/core/load_balancing/grpclb/grpclb.cc +2 -1
  98. data/src/core/load_balancing/pick_first/pick_first.cc +33 -2
  99. data/src/core/load_balancing/pick_first/pick_first.h +6 -0
  100. data/src/core/load_balancing/ring_hash/ring_hash.cc +3 -10
  101. data/src/core/load_balancing/rls/rls.cc +2 -1
  102. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +2 -7
  103. data/src/core/load_balancing/xds/cds.cc +80 -56
  104. data/src/core/load_balancing/xds/cds.h +21 -0
  105. data/src/core/mitigation_engine/mitigation.h +53 -0
  106. data/src/core/mitigation_engine/mitigation_provider.h +62 -0
  107. data/src/core/resolver/dns/dns_resolver_plugin.cc +1 -6
  108. data/src/core/resolver/xds/xds_resolver.cc +14 -11
  109. data/src/core/server/server.h +1 -4
  110. data/src/core/server/server_config_selector.h +5 -4
  111. data/src/core/server/server_config_selector_filter.cc +67 -80
  112. data/src/core/server/xds_server_config_fetcher.cc +681 -692
  113. data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -12
  114. data/src/core/telemetry/call_tracer.cc +49 -2
  115. data/src/core/telemetry/call_tracer.h +1 -0
  116. data/src/core/telemetry/tcp_tracer.h +38 -0
  117. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  118. data/src/core/tsi/ssl_telemetry_utils.cc +343 -0
  119. data/src/core/tsi/ssl_telemetry_utils.h +74 -0
  120. data/src/core/tsi/ssl_transport_security.cc +577 -301
  121. data/src/core/tsi/ssl_transport_security.h +22 -6
  122. data/src/core/tsi/ssl_transport_security_utils.cc +2 -0
  123. data/src/core/tsi/transport_security.h +7 -0
  124. data/src/core/util/http_client/httpcli.cc +1 -4
  125. data/src/core/util/http_client/httpcli_security_connector.cc +2 -1
  126. data/src/core/util/status_helper.cc +71 -192
  127. data/src/core/util/status_helper.h +16 -21
  128. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +2 -11
  129. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -7
  130. data/src/core/xds/grpc/xds_cluster_parser.cc +5 -16
  131. data/src/core/xds/grpc/xds_common_types.cc +94 -38
  132. data/src/core/xds/grpc/xds_common_types.h +33 -18
  133. data/src/core/xds/grpc/xds_common_types_parser.cc +168 -100
  134. data/src/core/xds/grpc/xds_common_types_parser.h +18 -1
  135. data/src/core/xds/grpc/xds_endpoint_parser.cc +6 -17
  136. data/src/core/xds/grpc/xds_http_filter_registry.cc +2 -10
  137. data/src/core/xds/grpc/xds_http_rbac_filter.cc +3 -12
  138. data/src/core/xds/grpc/xds_metadata_parser.cc +0 -2
  139. data/src/core/xds/grpc/xds_route_config_parser.cc +7 -11
  140. data/src/core/xds/grpc/xds_routing.cc +113 -82
  141. data/src/core/xds/grpc/xds_routing.h +70 -20
  142. data/src/core/xds/grpc/xds_server_grpc.cc +22 -13
  143. data/src/core/xds/grpc/xds_server_grpc.h +16 -2
  144. data/src/core/xds/grpc/xds_server_grpc_interface.h +10 -0
  145. data/src/core/xds/grpc/xds_transport_grpc.cc +123 -18
  146. data/src/core/xds/grpc/xds_transport_grpc.h +28 -4
  147. data/src/core/xds/xds_client/lrs_client.cc +3 -7
  148. data/src/core/xds/xds_client/xds_bootstrap.cc +4 -16
  149. data/src/core/xds/xds_client/xds_client.cc +2 -15
  150. data/src/core/xds/xds_client/xds_transport.h +3 -0
  151. data/src/ruby/lib/grpc/version.rb +1 -1
  152. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +1 -1
  153. metadata +9 -1
@@ -29,7 +29,6 @@
29
29
  #include <optional>
30
30
  #include <type_traits>
31
31
  #include <utility>
32
- #include <vector>
33
32
 
34
33
  #include "src/core/call/call_destination.h"
35
34
  #include "src/core/call/call_spine.h"
@@ -39,9 +38,6 @@
39
38
  #include "src/core/ext/transport/chttp2/transport/frame.h"
40
39
  #include "src/core/ext/transport/chttp2/transport/goaway.h"
41
40
  #include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
42
- #include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
43
- #include "src/core/ext/transport/chttp2/transport/http2_settings.h"
44
- #include "src/core/ext/transport/chttp2/transport/http2_settings_manager.h"
45
41
  #include "src/core/ext/transport/chttp2/transport/http2_settings_promises.h"
46
42
  #include "src/core/ext/transport/chttp2/transport/http2_status.h"
47
43
  #include "src/core/ext/transport/chttp2/transport/http2_transport.h"
@@ -59,7 +55,6 @@
59
55
  #include "src/core/lib/promise/context.h"
60
56
  #include "src/core/lib/promise/latch.h"
61
57
  #include "src/core/lib/promise/map.h"
62
- #include "src/core/lib/promise/mpsc.h"
63
58
  #include "src/core/lib/promise/party.h"
64
59
  #include "src/core/lib/promise/poll.h"
65
60
  #include "src/core/lib/promise/promise.h"
@@ -70,7 +65,6 @@
70
65
  #include "src/core/lib/transport/promise_endpoint.h"
71
66
  #include "src/core/lib/transport/transport.h"
72
67
  #include "src/core/util/debug_location.h"
73
- #include "src/core/util/grpc_check.h"
74
68
  #include "src/core/util/orphanable.h"
75
69
  #include "src/core/util/ref_counted.h"
76
70
  #include "src/core/util/ref_counted_ptr.h"
@@ -80,7 +74,6 @@
80
74
  #include "absl/container/flat_hash_map.h"
81
75
  #include "absl/functional/any_invocable.h"
82
76
  #include "absl/log/log.h"
83
- #include "absl/meta/type_traits.h"
84
77
  #include "absl/status/status.h"
85
78
  #include "absl/status/statusor.h"
86
79
  #include "absl/strings/string_view.h"
@@ -181,6 +174,10 @@ class Http2ServerTransport final : public ServerTransport,
181
174
  int64_t TestOnlyTransportFlowControlWindow();
182
175
  int64_t TestOnlyGetStreamFlowControlWindow(const uint32_t stream_id);
183
176
 
177
+ uint32_t TestOnlyLastIncomingStreamId() const {
178
+ return last_incoming_stream_id_;
179
+ }
180
+
184
181
  private:
185
182
  //////////////////////////////////////////////////////////////////////////////
186
183
  // Endpoint Helpers
@@ -190,9 +187,9 @@ class Http2ServerTransport final : public ServerTransport,
190
187
  GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION auto EndpointReadSlice(
191
188
  const size_t num_bytes) {
192
189
  return Map(endpoint_.ReadSlice(num_bytes),
193
- [this, num_bytes](absl::StatusOr<Slice> status) {
190
+ [this, num_bytes](absl::StatusOr<Slice>&& status) {
194
191
  OnEndpointRead(status.ok(), num_bytes);
195
- return status;
192
+ return std::move(status);
196
193
  });
197
194
  }
198
195
 
@@ -201,9 +198,9 @@ class Http2ServerTransport final : public ServerTransport,
201
198
  GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION auto EndpointRead(
202
199
  const size_t num_bytes) {
203
200
  return Map(endpoint_.Read(num_bytes),
204
- [this, num_bytes](absl::StatusOr<SliceBuffer> status) {
201
+ [this, num_bytes](absl::StatusOr<SliceBuffer>&& status) {
205
202
  OnEndpointRead(status.ok(), num_bytes);
206
- return status;
203
+ return std::move(status);
207
204
  });
208
205
  }
209
206
 
@@ -313,6 +310,27 @@ class Http2ServerTransport final : public ServerTransport,
313
310
 
314
311
  auto HandleMetadataAndMessages(RefCountedPtr<Stream> stream);
315
312
 
313
+ // Handles failure of a promise by closing the associated stream.
314
+ template <typename Promise>
315
+ auto HandleStreamErrorOnFailure(Promise&& promise,
316
+ RefCountedPtr<Stream> stream) {
317
+ return Map(std::forward<Promise>(promise),
318
+ [this, stream = std::move(stream)](auto&& result) mutable {
319
+ absl::Status status = StatusCast<absl::Status>(result);
320
+ GRPC_HTTP2_SERVER_DLOG
321
+ << "Http2ServerTransport::HandleStreamErrorOnFailure "
322
+ "Received status: "
323
+ << status;
324
+ if (GPR_UNLIKELY(!status.ok())) {
325
+ GRPC_UNUSED absl::Status unused_status = HandleError(
326
+ std::move(stream),
327
+ Http2Status::AbslStreamError(
328
+ status.code(), std::string(status.message())));
329
+ }
330
+ return std::forward<decltype(result)>(result);
331
+ });
332
+ }
333
+
316
334
  // Force triggers a transport write cycle
317
335
  absl::Status TriggerWriteCycle(DebugLocation whence = {}) {
318
336
  GRPC_HTTP2_SERVER_DLOG
@@ -331,7 +349,7 @@ class Http2ServerTransport final : public ServerTransport,
331
349
  "status: "
332
350
  << status << " at " << whence.file() << ":" << whence.line();
333
351
  GRPC_UNUSED absl::Status unused_status = HandleError(
334
- /*stream_id=*/std::nullopt, ToHttpOkOrConnError(status), whence);
352
+ /*stream=*/nullptr, ToHttpOkOrConnError(status), whence);
335
353
  return false;
336
354
  }
337
355
 
@@ -388,7 +406,7 @@ class Http2ServerTransport final : public ServerTransport,
388
406
  [self = RefAsSubclass<Http2ServerTransport>()](absl::Status status) {
389
407
  if (!status.ok()) {
390
408
  GRPC_UNUSED absl::Status error = self->HandleError(
391
- /*stream_id=*/std::nullopt, ToHttpOkOrConnError(status));
409
+ /*stream=*/nullptr, ToHttpOkOrConnError(status));
392
410
  }
393
411
  });
394
412
  }
@@ -443,21 +461,6 @@ class Http2ServerTransport final : public ServerTransport,
443
461
  RefCountedPtr<Stream> stream,
444
462
  StreamDataQueue<ServerMetadataHandle>::StreamWritabilityUpdate result);
445
463
 
446
- // Returns the next stream id. If the next stream id is not available, it
447
- // returns std::nullopt. MUST be called from the transport party.
448
- // absl::StatusOr<uint32_t> NextStreamId();
449
-
450
- // Returns the next stream id without incrementing it. MUST be called from the
451
- // transport party.
452
- // uint32_t PeekNextStreamId() const { return next_stream_id_; }
453
-
454
- // Returns the last stream id sent by the transport. If no streams were sent,
455
- // returns 0. MUST be called from the transport party.
456
- // uint32_t GetLastStreamId() const {
457
- // const uint32_t next_stream_id = PeekNextStreamId();
458
- // return (next_stream_id > 1) ? (next_stream_id - 2) : 0;
459
- // }
460
-
461
464
  // Returns the number of active streams. A stream is removed from the `active`
462
465
  // list once both client and server agree to close the stream. The count of
463
466
  // stream_list_(even though stream list represents streams open for reads)
@@ -499,29 +502,39 @@ class Http2ServerTransport final : public ServerTransport,
499
502
  Http2Status IncomingStream(ClientMetadataHandle&& metadata,
500
503
  uint32_t stream_id);
501
504
 
502
- // void BeginCloseStream(RefCountedPtr<Stream> stream,
503
- // std::optional<uint32_t> reset_stream_error_code,
504
- // ServerMetadataHandle&& metadata,
505
- // DebugLocation whence = {});
506
-
507
- // This function MUST be idempotent.
508
- void CloseStream(uint32_t stream_id, absl::Status status,
509
- DebugLocation whence = {}) {
510
- LOG(INFO) << "Http2ServerTransport::CloseStream for stream id=" << stream_id
511
- << " status=" << status << " location=" << whence.file() << ":"
512
- << whence.line();
513
- // TODO(akshitpatel) : [PH2][P2] : Implement this.
514
- }
515
-
516
- // This function MUST be idempotent.
517
- // void CloseStream(Stream& stream, CloseStreamArgs args,
518
- // DebugLocation whence = {});
505
+ // Call this when a stream needs to be closed and we must notify the client by
506
+ // sending a RST_STREAM frame (e.g., due to local stream error, cancellation).
507
+ // This enqueues the RST_STREAM frame and immediately closes the stream for
508
+ // reads. Writes will be closed by the write loop after the RST_STREAM frame
509
+ // is written to the wire.
510
+ // Prefer calling HandleError over this API.
511
+ // Parameters:
512
+ // stream: The stream to close.
513
+ // reset_stream_error_code: The error code to use for the RST_STREAM frame.
514
+ // trailing_metadata_status: The failure status to propagate to the
515
+ // application.
516
+ // whence: The location of the caller.
517
+ void BeginCloseStream(RefCountedPtr<Stream> stream,
518
+ uint32_t reset_stream_error_code,
519
+ absl::Status trailing_metadata_status,
520
+ DebugLocation whence = {});
521
+
522
+ // Handles stream state changes by discarding pending header parsing if reads
523
+ // became closed, and triggering cleanup if the stream became closed.
524
+ // This function does not hold the transport mutex and is safe to call from
525
+ // the read loop.
526
+ void HandleStreamStateChange(Stream& stream, StreamStateChange change);
527
+
528
+ // Erases the stream from the active stream list. The caller MUST ensure the
529
+ // stream is closed.
530
+ // This function acquires the transport mutex internally.
531
+ void CleanupStream(Stream& stream);
519
532
 
520
533
  //////////////////////////////////////////////////////////////////////////////
521
534
  // Ping Keepalive and Goaway
522
535
 
523
- // void MaybeSpawnPingTimeout(std::optional<uint64_t> opaque_data);
524
- // void MaybeSpawnDelayedPing(std::optional<Duration> delayed_ping_wait);
536
+ void MaybeSpawnPingTimeout(std::optional<uint64_t> opaque_data);
537
+ void MaybeSpawnDelayedPing(std::optional<Duration> delayed_ping_wait);
525
538
 
526
539
  auto SendPing(absl::AnyInvocable<void()> on_initiate, bool important) {
527
540
  return ping_manager_->RequestPing(std::move(on_initiate), important);
@@ -529,17 +542,14 @@ class Http2ServerTransport final : public ServerTransport,
529
542
 
530
543
  auto WaitForPingAck() { return ping_manager_->WaitForPingAck(); }
531
544
 
532
- // Duration NextAllowedPingInterval() {
533
- // MutexLock lock(&transport_mutex_);
534
- // return (!keepalive_permit_without_calls_ &&
535
- // GetActiveStreamCountLocked() == 0)
536
- // ? Duration::Hours(2)
537
- // : Duration::Seconds(1);
538
- // }
545
+ Duration NextAllowedPingInterval() {
546
+ // TODO(akshitpatel) : [PH2][P1] : Add server logic.
547
+ return Duration::Zero();
548
+ }
539
549
 
540
550
  absl::Status AckPing(uint64_t opaque_data);
541
551
 
542
- // void MaybeSpawnKeepaliveLoop();
552
+ void MaybeSpawnKeepaliveLoop();
543
553
 
544
554
  // uint32_t GetMaxAllowedStreamId() const;
545
555
  // void SetMaxAllowedStreamId(uint32_t max_allowed_stream_id);
@@ -547,8 +557,8 @@ class Http2ServerTransport final : public ServerTransport,
547
557
  //////////////////////////////////////////////////////////////////////////////
548
558
  // Error Path and Close Path
549
559
 
550
- // void MaybeSpawnCloseTransport(Http2Status http2_status,
551
- // DebugLocation whence = {});
560
+ void MaybeSpawnCloseTransport(Http2Status http2_status,
561
+ DebugLocation whence = {});
552
562
 
553
563
  // bool CanCloseTransportLocked() const
554
564
  // ABSL_EXCLUSIVE_LOCKS_REQUIRED(transport_mutex_);
@@ -559,22 +569,13 @@ class Http2ServerTransport final : public ServerTransport,
559
569
  // Handles the error status and returns the corresponding absl status. Absl
560
570
  // Status is returned so that the error can be gracefully handled
561
571
  // by promise primitives.
562
- // If the error is a stream error, it closes the stream and returns an ok
572
+ // If the error is a stream error, it initiates stream close and returns an ok
563
573
  // status. Ok status is returned because the calling transport promise loops
564
574
  // should not be cancelled in case of stream errors.
565
575
  // If the error is a connection error, it closes the transport and returns the
566
576
  // corresponding (failed) absl status.
567
- absl::Status HandleError(const std::optional<uint32_t> stream_id,
568
- Http2Status status, DebugLocation whence = {}) {
569
- // TODO(akshitpatel) : [PH2][P0] : Implement this. And remove the log.
570
- GRPC_HTTP2_SERVER_DLOG << "Http2ServerTransport::HandleError for stream id="
571
- << (stream_id.has_value() ? absl::StrCat(*stream_id)
572
- : "nullopt")
573
- << " status=" << status.DebugString()
574
- << " location=" << whence.file() << ":"
575
- << whence.line();
576
- return absl::OkStatus();
577
- }
577
+ absl::Status HandleError(RefCountedPtr<Stream> stream, Http2Status status,
578
+ DebugLocation whence = {});
578
579
 
579
580
  //////////////////////////////////////////////////////////////////////////////
580
581
  // Misc Transport Stuff
@@ -613,6 +614,8 @@ class Http2ServerTransport final : public ServerTransport,
613
614
  }));
614
615
  }
615
616
 
617
+ auto SpawnGracefulGoawayPromise(Slice&& debug_data);
618
+
616
619
  //////////////////////////////////////////////////////////////////////////////
617
620
  // Inner Classes and Structs
618
621
 
@@ -677,13 +680,7 @@ class Http2ServerTransport final : public ServerTransport,
677
680
 
678
681
  RefCountedPtr<UnstartedCallDestination> call_destination_;
679
682
 
680
- // TODO(akshitpatel) : [PH2][P0] : Remove this when write path is ready.
681
- MpscReceiver<Http2Frame> outgoing_frames_;
682
-
683
- // TODO(tjagtap) : [PH2][P0] : These are copied as is from the client
684
- // transport. Take a look if modifications are needed.
685
-
686
- RefCountedPtr<Party> general_party_; // Refer Gemini.md for party slot usage
683
+ RefCountedPtr<Party> general_party_; // Refer AGENTS.md for party slot usage
687
684
  std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine_;
688
685
 
689
686
  PromiseEndpoint endpoint_;
@@ -694,7 +691,6 @@ class Http2ServerTransport final : public ServerTransport,
694
691
  absl::flat_hash_map<uint32_t, RefCountedPtr<Stream>> stream_list_
695
692
  ABSL_GUARDED_BY(transport_mutex_);
696
693
 
697
- GRPC_UNUSED uint32_t next_stream_id_;
698
694
  HPackCompressor encoder_;
699
695
  bool is_transport_closed_ ABSL_GUARDED_BY(transport_mutex_) = false;
700
696
  Latch<void> transport_closed_latch_;
@@ -715,6 +711,8 @@ class Http2ServerTransport final : public ServerTransport,
715
711
  // Tracks the max allowed stream id. Currently this is only set on receiving a
716
712
  // graceful GOAWAY frame.
717
713
  GRPC_UNUSED uint32_t max_allowed_stream_id_ = RFC9113::kMaxStreamId31Bit;
714
+ // Tracks last stream id received by the transport.
715
+ uint32_t last_incoming_stream_id_ = 0;
718
716
 
719
717
  // Duration between two consecutive keepalive pings.
720
718
  Duration keepalive_time_;
@@ -116,7 +116,7 @@ Http2ErrorCode Http2Settings::Apply(uint16_t key, uint32_t value) {
116
116
  max_frame_size_ = value;
117
117
  break;
118
118
  case kMaxHeaderListSizeWireId:
119
- max_header_list_size_ = std::min(value, 16777216u);
119
+ max_header_list_size_ = std::min(value, kDefaultMaxHeaderListSize);
120
120
  break;
121
121
  case kGrpcAllowTrueBinaryMetadataWireId:
122
122
  if (value > 1) return Http2ErrorCode::kProtocolError;
@@ -20,6 +20,7 @@
20
20
  #include <grpc/support/port_platform.h>
21
21
  #include <stdint.h>
22
22
 
23
+ #include <algorithm>
23
24
  #include <cstdint>
24
25
  #include <optional>
25
26
 
@@ -50,6 +51,23 @@ class Http2Settings {
50
51
 
51
52
  constexpr static uint8_t kNumSettings = 9u;
52
53
 
54
+ // RFC9113 defines the default value for some of these settings.
55
+ // https://datatracker.ietf.org/doc/html/rfc9113#name-defined-settings
56
+ // RFC defined defaults for RFC defined settings :
57
+ constexpr static uint32_t kDefaultHeaderTableSize = 4096u;
58
+ constexpr static uint32_t kDefaultMaxConcurrentStreams = 4294967295u;
59
+ constexpr static uint32_t kDefaultInitialWindowSize = 65535u;
60
+ constexpr static uint32_t kDefaultMaxFrameSize = 16384u;
61
+ constexpr static bool kDefaultEnablePush = true;
62
+
63
+ // gRPC defined defaults for RFC defined settings :
64
+ constexpr static uint32_t kDefaultMaxHeaderListSize = 16777216u;
65
+
66
+ // gRPC defined defaults.
67
+ constexpr static uint32_t kDefaultPreferredReceiveCryptoMessageSize = 0u;
68
+ constexpr static bool kDefaultAllowTrueBinaryMetadata = false;
69
+ constexpr static bool kDefaultAllowSecurityFrame = false;
70
+
53
71
  void Diff(bool is_first_send, const Http2Settings& old_setting,
54
72
  absl::FunctionRef<void(uint16_t key, uint32_t value)> cb) const;
55
73
  GRPC_MUST_USE_RESULT http2::Http2ErrorCode Apply(uint16_t key,
@@ -81,7 +99,7 @@ class Http2Settings {
81
99
  }
82
100
  void SetEnablePush(bool x) { enable_push_ = x; }
83
101
  void SetMaxHeaderListSize(uint32_t x) {
84
- max_header_list_size_ = std::min(x, 16777216u);
102
+ max_header_list_size_ = std::min(x, kDefaultMaxHeaderListSize);
85
103
  }
86
104
  void SetAllowTrueBinaryMetadata(bool x) { allow_true_binary_metadata_ = x; }
87
105
  void SetMaxFrameSize(uint32_t x) {
@@ -178,41 +196,42 @@ class Http2Settings {
178
196
  // RFC9113 states the default value for SETTINGS_HEADER_TABLE_SIZE
179
197
  // Currently this is set only once in the lifetime of a transport.
180
198
  // We plan to change that in the future.
181
- uint32_t header_table_size_ = 4096u;
199
+ uint32_t header_table_size_ = kDefaultHeaderTableSize;
182
200
 
183
201
  // CLIENT : Set only once in the lifetime of a client transport. This is set
184
202
  // to 0 for client.
185
203
  // SERVER : This setting can change for the server. This is usually changed to
186
204
  // handle memory pressure.
187
- uint32_t initial_max_concurrent_streams_ = 4294967295u;
188
- uint32_t max_concurrent_streams_ = 4294967295u;
205
+ uint32_t initial_max_concurrent_streams_ = kDefaultMaxConcurrentStreams;
206
+ uint32_t max_concurrent_streams_ = kDefaultMaxConcurrentStreams;
189
207
 
190
208
  // RFC9113 states the default for SETTINGS_INITIAL_WINDOW_SIZE
191
209
  // Both client and servers can change this setting. This is usually changed to
192
210
  // handle memory pressure.
193
- uint32_t initial_window_size_ = 65535u;
211
+ uint32_t initial_window_size_ = kDefaultInitialWindowSize;
194
212
 
195
213
  // RFC9113 states the default for SETTINGS_MAX_FRAME_SIZE
196
214
  // Both client and servers can change this setting. This is usually changed to
197
215
  // handle memory pressure.
198
- uint32_t max_frame_size_ = 16384u;
216
+ uint32_t max_frame_size_ = kDefaultMaxFrameSize;
199
217
 
200
218
  // This is an advisory but we currently enforce it.
201
219
  // Set only once in the lifetime of a transport currently.
202
220
  // When a peer that updates this more than once, that may indicate either an
203
221
  // underlying issue or a malicious peer.
204
- uint32_t max_header_list_size_ = 16777216u;
222
+ uint32_t max_header_list_size_ = kDefaultMaxHeaderListSize;
205
223
 
206
224
  // gRPC defined setting
207
225
  // Both client and servers can change this setting. This is usually changed to
208
226
  // handle memory pressure.
209
- uint32_t preferred_receive_crypto_message_size_ = 0u;
227
+ uint32_t preferred_receive_crypto_message_size_ =
228
+ kDefaultPreferredReceiveCryptoMessageSize;
210
229
 
211
230
  // RFC9113 defined default is true. However, for gRPC we always then set it to
212
231
  // false via the SetEnablePush function
213
232
  // Currently this is set only once in the lifetime of a transport.
214
233
  // We have no plans to support this in the future.
215
- bool enable_push_ = true;
234
+ bool enable_push_ = kDefaultEnablePush;
216
235
 
217
236
  // gRPC defined setting
218
237
  // Currently this is set only once in the lifetime of a transport.
@@ -221,7 +240,7 @@ class Http2Settings {
221
240
  // flag. Both peers can send each other the default non-binary METADATA
222
241
  // irrespective of this flag. This flag says if we are willing to accept
223
242
  // Binary-Metadata from the peer or not.
224
- bool allow_true_binary_metadata_ = false;
243
+ bool allow_true_binary_metadata_ = kDefaultAllowTrueBinaryMetadata;
225
244
 
226
245
  // gRPC defined setting
227
246
  // Unlike most other SETTINGS, this setting is negotiated between the client
@@ -229,7 +248,7 @@ class Http2Settings {
229
248
  // apply the custom SECURITY frame.
230
249
  // Currently this is set only once in the lifetime of a transport.
231
250
  // Disconnect if it is received more than once from the peer.
232
- bool allow_security_frame_ = false;
251
+ bool allow_security_frame_ = kDefaultAllowSecurityFrame;
233
252
  };
234
253
 
235
254
  } // namespace grpc_core
@@ -66,6 +66,11 @@ namespace grpc_core {
66
66
  #define GRPC_SETTINGS_TIMEOUT_DLOG \
67
67
  DLOG_IF(INFO, GRPC_TRACE_FLAG_ENABLED(http2_ph2_transport))
68
68
 
69
+ struct ApplySettingsResult {
70
+ bool did_change_peer_max_concurrent_streams = false;
71
+ bool should_spawn_security_frame_loop = false;
72
+ };
73
+
69
74
  // This class can only be used only from a promise based HTTP2 transports
70
75
  // general_party_ .
71
76
  // This class is designed with the assumption that only 1 SETTINGS frame will be
@@ -74,8 +79,10 @@ namespace grpc_core {
74
79
  class SettingsPromiseManager final : public RefCounted<SettingsPromiseManager> {
75
80
  public:
76
81
  explicit SettingsPromiseManager(
82
+ const bool is_client,
77
83
  absl::AnyInvocable<void(absl::StatusOr<uint32_t>)> on_receive_settings)
78
- : on_receive_first_settings_(std::move(on_receive_settings)),
84
+ : is_client_(is_client),
85
+ on_receive_first_settings_(std::move(on_receive_settings)),
79
86
  state_(SettingsState::kWaitingForFirstPeerSettings) {
80
87
  pending_peer_settings_.reserve(Http2Settings::kNumSettings + 1);
81
88
  }
@@ -230,7 +237,8 @@ class SettingsPromiseManager final : public RefCounted<SettingsPromiseManager> {
230
237
  // the peer that that needs some special handling too.
231
238
  http2::Http2ErrorCode MaybeReportAndApplyBufferedPeerSettings(
232
239
  grpc_event_engine::experimental::EventEngine* event_engine,
233
- bool& should_spawn_security_frame_loop) {
240
+ ApplySettingsResult& apply_settings_result) {
241
+ const uint32_t old_setting = settings_.peer().max_concurrent_streams();
234
242
  std::vector<Http2SettingsFrame::Setting> settings_to_apply;
235
243
  settings_to_apply.reserve(pending_peer_settings_.size());
236
244
  for (const auto& [id, value] : pending_peer_settings_) {
@@ -239,10 +247,21 @@ class SettingsPromiseManager final : public RefCounted<SettingsPromiseManager> {
239
247
  pending_peer_settings_.clear();
240
248
  http2::Http2ErrorCode status =
241
249
  settings_.ApplyIncomingSettings(settings_to_apply);
250
+ if (status == http2::Http2ErrorCode::kNoError && is_client_) {
251
+ // Since PH2-Servers do not initiate streams, we ignore this setting for
252
+ // Servers.
253
+ const uint32_t applied_max_concurrent_streams =
254
+ settings_.peer().max_concurrent_streams();
255
+ apply_settings_result.did_change_peer_max_concurrent_streams =
256
+ (applied_max_concurrent_streams != old_setting);
257
+ // TODO(tjagtap) : [PH2][P0] : Plumb this with the StateWatcher code.
258
+ }
259
+
242
260
  if (state_ == SettingsState::kFirstPeerSettingsReceived) {
243
261
  MaybeReportInitialSettings(event_engine);
244
262
  state_ = SettingsState::kReady;
245
- should_spawn_security_frame_loop = IsSecurityFrameExpected();
263
+ apply_settings_result.should_spawn_security_frame_loop =
264
+ IsSecurityFrameExpected();
246
265
  }
247
266
  GRPC_DCHECK(pending_peer_settings_.empty());
248
267
  return status;
@@ -316,15 +335,11 @@ class SettingsPromiseManager final : public RefCounted<SettingsPromiseManager> {
316
335
  };
317
336
 
318
337
  private:
319
- Http2SettingsManager settings_;
320
-
321
338
  //////////////////////////////////////////////////////////////////////////////
322
339
  // Plumbing Settings with Chttp2Connector class
323
340
 
324
341
  void MaybeReportInitialSettings(
325
342
  grpc_event_engine::experimental::EventEngine* event_engine) {
326
- // TODO(tjagtap) [PH2][P2] Relook at this while writing server. I think this
327
- // will be different for client and server.
328
343
  if (on_receive_first_settings_ != nullptr) {
329
344
  GRPC_DCHECK(state_ == SettingsState::kFirstPeerSettingsReceived);
330
345
  GRPC_DCHECK(event_engine != nullptr);
@@ -345,8 +360,6 @@ class SettingsPromiseManager final : public RefCounted<SettingsPromiseManager> {
345
360
 
346
361
  void MaybeReportInitialSettingsAbort(
347
362
  grpc_event_engine::experimental::EventEngine* event_engine) {
348
- // TODO(tjagtap) [PH2][P2] Relook at this while writing server. I think this
349
- // will be different for client and server.
350
363
  if (on_receive_first_settings_ != nullptr) {
351
364
  GRPC_DCHECK(event_engine != nullptr);
352
365
  GRPC_DCHECK(state_ != SettingsState::kReady);
@@ -447,6 +460,7 @@ class SettingsPromiseManager final : public RefCounted<SettingsPromiseManager> {
447
460
 
448
461
  //////////////////////////////////////////////////////////////////////////////
449
462
  // Data Members for SETTINGS being received from the peer.
463
+ const bool is_client_;
450
464
 
451
465
  absl::AnyInvocable<void(absl::StatusOr<uint32_t>)> on_receive_first_settings_;
452
466
  absl::flat_hash_map<uint16_t, uint32_t> pending_peer_settings_;
@@ -465,6 +479,7 @@ class SettingsPromiseManager final : public RefCounted<SettingsPromiseManager> {
465
479
  // make them writable. This is tracked via channelz in case it causes any
466
480
  // performance issues in the future.
467
481
  size_t num_peer_initial_window_size_increases_ = 0;
482
+ Http2SettingsManager settings_;
468
483
  };
469
484
 
470
485
  } // namespace grpc_core
@@ -73,6 +73,8 @@ namespace http2 {
73
73
  // [PH2][EXT] This is a TODO related to a project unrelated to PH2 but happening
74
74
  // in parallel.
75
75
  // [PH2][CHTTP2] This TODO is a part of CHTTP2 deletion.
76
+ // [PH2][Px][FCV3] This TODO is related to Flow Control plumbing with the
77
+ // Application and the Call V3 stack.
76
78
 
77
79
  constexpr Duration kDefaultPingTimeout = Duration::Minutes(1);
78
80
  constexpr Duration kDefaultKeepaliveTimeout = Duration::Seconds(20);
@@ -269,6 +271,14 @@ uint32_t MaxNewStreamsPerRead(const ChannelArgs& channel_args) {
269
271
  10000);
270
272
  }
271
273
 
274
+ uint32_t GetMaxSecurityFrameSize(const ChannelArgs& channel_args) {
275
+ return static_cast<uint32_t>(
276
+ Clamp(channel_args.GetInt(GRPC_ARG_MAX_SECURITY_FRAME_SIZE)
277
+ .value_or(GrpcErrors::kMaxSecurityFrameSize),
278
+ GrpcErrors::kMinMaxSecurityFrameSize,
279
+ static_cast<int>(GrpcErrors::kMaxSecurityFrameSize)));
280
+ }
281
+
272
282
  ///////////////////////////////////////////////////////////////////////////////
273
283
  // ChannelZ helpers
274
284
 
@@ -399,6 +409,22 @@ bool ProcessIncomingWindowUpdateFrameFlowControl(
399
409
 
400
410
  void MaybeAddTransportWindowUpdateFrame(
401
411
  chttp2::TransportFlowControl& flow_control, FrameSender& frame_sender) {
412
+ // Known Limitation:
413
+ // 1. writing_anyway is set to true always. This might cause the write cycle
414
+ // to just write 1 window update frame in one entire iteration of the
415
+ // Multiplexer Loop, making it wasteful. In most of the scenarios this is fine
416
+ // as TriggerWriteCycle is only invoked from code points that want to write
417
+ // frames on the wire.
418
+ // 2. This is because we write control frames before we write HEADER and DATA
419
+ // frames. So we don't know if we are going to write or not when we call
420
+ // this function.
421
+ // 3. Setting writing_anyway to false always might be a problem, because we
422
+ // would rather send a WINDOW_UPDATE frame with a small increment, than not
423
+ // send it at all.
424
+ // 4. In the future if we want to fix this, we need to call
425
+ // MaybeAddTransportWindowUpdateFrame once while writing control frames, and
426
+ // once after all the DATA and HEADER frames are written for the current write
427
+ // cycle.
402
428
  uint32_t window_size =
403
429
  flow_control.DesiredAnnounceSize(/*writing_anyway=*/true);
404
430
  if (window_size > 0) {
@@ -151,6 +151,8 @@ void ReadSettingsFromChannelArgs(const ChannelArgs& channel_args,
151
151
 
152
152
  uint32_t MaxNewStreamsPerRead(const ChannelArgs& channel_args);
153
153
 
154
+ uint32_t GetMaxSecurityFrameSize(const ChannelArgs& channel_args);
155
+
154
156
  ///////////////////////////////////////////////////////////////////////////////
155
157
  // ChannelZ helpers
156
158
 
@@ -95,6 +95,9 @@
95
95
  // bits being used for flags defined above)
96
96
  #define CLOSURE_BARRIER_FIRST_REF_BIT (1 << 16)
97
97
 
98
+ constexpr uint32_t kMaxSecurityFrameSize = 16u * 1024u;
99
+ constexpr int kMinMaxSecurityFrameSize = 0;
100
+
98
101
  // streams are kept in various linked lists depending on what things need to
99
102
  // happen to them... this enum labels each list
100
103
  typedef enum {
@@ -462,6 +465,7 @@ struct grpc_chttp2_transport final : public grpc_core::FilterStackTransport,
462
465
  /// parser for goaway frames
463
466
  grpc_chttp2_goaway_parser goaway_parser;
464
467
  // parser for secure frames
468
+ uint32_t max_security_frame_size;
465
469
  grpc_chttp2_security_frame_parser security_frame_parser;
466
470
 
467
471
  grpc_core::chttp2::TransportFlowControl flow_control;
@@ -984,8 +984,9 @@ static grpc_error_handle init_settings_frame_parser(grpc_chttp2_transport* t) {
984
984
  }
985
985
 
986
986
  static grpc_error_handle init_security_frame_parser(grpc_chttp2_transport* t) {
987
- grpc_error_handle err =
988
- grpc_chttp2_security_frame_parser_begin_frame(&t->security_frame_parser);
987
+ grpc_error_handle err = grpc_chttp2_security_frame_parser_begin_frame(
988
+ &t->security_frame_parser, t->incoming_frame_size,
989
+ t->max_security_frame_size);
989
990
  if (!err.ok()) return err;
990
991
  t->parser = grpc_chttp2_transport::Parser{
991
992
  "security_frame", grpc_chttp2_security_frame_parser_parse,
@@ -115,7 +115,7 @@ std::optional<Duration> PingManager::MaybeGetSerializedPingFrames(
115
115
  << " next_allowed_ping_interval: "
116
116
  << next_allowed_ping_interval;
117
117
  GRPC_DCHECK(!opaque_data_.has_value());
118
- frame_sender.ReserveRegularFrames(pending_ping_acks_.size() + 1);
118
+ frame_sender.ReserveRegularFrames(pending_ping_acks_.size());
119
119
 
120
120
  // Get the serialized ping acks if needed.
121
121
  for (uint64_t opaque_data : pending_ping_acks_) {
@@ -58,17 +58,11 @@ void Chttp2PingRatePolicy::SetDefaults(const ChannelArgs& args) {
58
58
  Chttp2PingRatePolicy::RequestSendPingResult
59
59
  Chttp2PingRatePolicy::RequestSendPing(Duration next_allowed_ping_interval,
60
60
  size_t inflight_pings) const {
61
- if (max_inflight_pings_ > 0) {
62
- if (!IsMaxInflightPingsStrictLimitEnabled()) {
63
- if (inflight_pings > static_cast<size_t>(max_inflight_pings_)) {
64
- return TooManyRecentPings{};
65
- }
66
- } else {
67
- if (inflight_pings >= static_cast<size_t>(max_inflight_pings_)) {
68
- return TooManyRecentPings{};
69
- }
70
- }
61
+ if (max_inflight_pings_ > 0 &&
62
+ inflight_pings >= static_cast<size_t>(max_inflight_pings_)) {
63
+ return TooManyRecentPings{};
71
64
  }
65
+
72
66
  const Timestamp next_allowed_ping =
73
67
  last_ping_sent_time_ + next_allowed_ping_interval;
74
68
  const Timestamp now = Timestamp::Now();