grpc 1.78.0 → 1.80.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 +22 -8
- data/include/grpc/credentials.h +47 -37
- data/include/grpc/credentials_cpp.h +39 -0
- data/include/grpc/event_engine/event_engine.h +8 -3
- data/include/grpc/grpc.h +4 -0
- data/include/grpc/impl/call.h +9 -0
- data/include/grpc/impl/channel_arg_names.h +7 -0
- data/include/grpc/module.modulemap +2 -0
- data/include/grpc/private_key_signer.h +104 -0
- data/include/grpc/support/port_platform.h +6 -0
- data/src/core/call/call_filters.h +101 -78
- data/src/core/call/call_spine.h +91 -68
- data/src/core/call/call_state.h +60 -4
- data/src/core/call/client_call.cc +9 -9
- data/src/core/call/client_call.h +1 -1
- data/src/core/call/metadata_batch.cc +2 -0
- data/src/core/call/metadata_batch.h +48 -1
- data/src/core/call/metadata_info.cc +35 -0
- data/src/core/call/metadata_info.h +2 -0
- data/src/core/call/simple_slice_based_metadata.h +2 -1
- data/src/core/channelz/channelz.cc +9 -6
- data/src/core/channelz/channelz.h +7 -4
- data/src/core/channelz/property_list.h +5 -0
- data/src/core/channelz/v2tov1/convert.cc +1 -1
- data/src/core/channelz/v2tov1/legacy_api.cc +164 -307
- data/src/core/client_channel/buffered_call.cc +7 -3
- data/src/core/client_channel/buffered_call.h +11 -5
- data/src/core/client_channel/client_channel.cc +106 -44
- data/src/core/client_channel/client_channel.h +3 -6
- data/src/core/client_channel/client_channel_filter.cc +90 -64
- data/src/core/client_channel/client_channel_filter.h +3 -6
- data/src/core/client_channel/client_channel_internal.h +5 -0
- data/src/core/client_channel/config_selector.h +17 -12
- data/src/core/client_channel/dynamic_filters.cc +8 -7
- data/src/core/client_channel/dynamic_filters.h +7 -5
- data/src/core/client_channel/retry_filter.cc +1 -1
- data/src/core/client_channel/retry_filter.h +2 -2
- data/src/core/client_channel/subchannel.cc +1682 -266
- data/src/core/client_channel/subchannel.h +411 -134
- data/src/core/client_channel/subchannel_stream_client.cc +22 -18
- data/src/core/client_channel/subchannel_stream_client.h +8 -9
- data/src/core/client_channel/subchannel_stream_limiter.cc +76 -0
- data/src/core/client_channel/subchannel_stream_limiter.h +51 -0
- data/src/core/config/config_vars.cc +9 -1
- data/src/core/config/config_vars.h +6 -0
- data/src/core/credentials/call/call_creds_registry.h +51 -22
- data/src/core/credentials/call/call_creds_registry_init.cc +86 -2
- data/src/core/credentials/call/external/aws_external_account_credentials.cc +2 -2
- data/src/core/credentials/call/external/external_account_credentials.cc +11 -4
- data/src/core/credentials/call/external/file_external_account_credentials.cc +2 -2
- data/src/core/credentials/transport/channel_creds_registry.h +71 -20
- data/src/core/credentials/transport/channel_creds_registry_init.cc +338 -29
- data/src/core/credentials/transport/ssl/ssl_credentials.cc +43 -24
- data/src/core/credentials/transport/ssl/ssl_credentials.h +7 -1
- data/src/core/credentials/transport/ssl/ssl_security_connector.cc +2 -8
- data/src/core/credentials/transport/ssl/ssl_security_connector.h +4 -3
- data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +25 -5
- data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +7 -5
- data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +181 -109
- data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +55 -42
- data/src/core/credentials/transport/tls/grpc_tls_credentials_options.cc +28 -23
- data/src/core/credentials/transport/tls/grpc_tls_credentials_options.h +26 -23
- data/src/core/credentials/transport/tls/spiffe_utils.cc +2 -2
- data/src/core/credentials/transport/tls/ssl_utils.cc +18 -18
- data/src/core/credentials/transport/tls/ssl_utils.h +12 -10
- data/src/core/credentials/transport/tls/tls_security_connector.cc +106 -74
- data/src/core/credentials/transport/tls/tls_security_connector.h +12 -8
- data/src/core/credentials/transport/xds/xds_credentials.cc +76 -32
- data/src/core/credentials/transport/xds/xds_credentials.h +4 -2
- data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +117 -35
- data/src/core/ext/filters/fault_injection/fault_injection_filter.h +42 -4
- data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +58 -29
- data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +19 -11
- data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +82 -25
- data/src/core/ext/filters/stateful_session/stateful_session_filter.h +28 -3
- data/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc +9 -7
- data/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h +1 -1
- data/src/core/ext/transport/chttp2/transport/call_tracer_wrapper.h +7 -1
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +117 -67
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +2 -0
- data/src/core/ext/transport/chttp2/transport/flow_control.h +11 -1
- data/src/core/ext/transport/chttp2/transport/frame.cc +2 -15
- data/src/core/ext/transport/chttp2/transport/frame.h +0 -4
- data/src/core/ext/transport/chttp2/transport/goaway.cc +17 -2
- data/src/core/ext/transport/chttp2/transport/goaway.h +27 -6
- data/src/core/ext/transport/chttp2/transport/header_assembler.h +8 -21
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +101 -40
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +95 -0
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +923 -772
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +406 -423
- data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -0
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +8 -1
- data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +25 -13
- data/src/core/ext/transport/chttp2/transport/http2_transport.cc +71 -24
- data/src/core/ext/transport/chttp2/transport/http2_transport.h +25 -49
- data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +2 -2
- data/src/core/ext/transport/chttp2/transport/incoming_metadata_tracker.h +29 -9
- data/src/core/ext/transport/chttp2/transport/internal.h +6 -2
- data/src/core/ext/transport/chttp2/transport/keepalive.cc +14 -20
- data/src/core/ext/transport/chttp2/transport/keepalive.h +9 -6
- data/src/core/ext/transport/chttp2/transport/parsing.cc +11 -0
- data/src/core/ext/transport/chttp2/transport/ping_promise.cc +34 -74
- data/src/core/ext/transport/chttp2/transport/ping_promise.h +123 -79
- data/src/core/ext/transport/chttp2/transport/security_frame.h +233 -3
- data/src/core/ext/transport/chttp2/transport/stream.h +152 -73
- data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +155 -85
- data/src/core/ext/transport/chttp2/transport/transport_common.h +0 -5
- data/src/core/ext/transport/chttp2/transport/writable_streams.h +8 -7
- data/src/core/ext/transport/chttp2/transport/write_cycle.cc +86 -0
- data/src/core/ext/transport/chttp2/transport/write_cycle.h +355 -0
- data/src/core/ext/transport/chttp2/transport/writing.cc +31 -29
- data/src/core/ext/upb-gen/cel/expr/checked.upb.h +1875 -0
- data/src/core/ext/upb-gen/cel/expr/checked.upb_minitable.c +409 -0
- data/src/core/ext/upb-gen/cel/expr/checked.upb_minitable.h +56 -0
- data/src/core/ext/upb-gen/cel/expr/syntax.upb.h +2223 -0
- data/src/core/ext/upb-gen/cel/expr/syntax.upb_minitable.c +489 -0
- data/src/core/ext/upb-gen/cel/expr/syntax.upb_minitable.h +60 -0
- data/src/core/ext/upb-gen/envoy/config/accesslog/v3/accesslog.upb.h +2 -1
- data/src/core/ext/upb-gen/envoy/config/bootstrap/v3/bootstrap.upb.h +130 -18
- data/src/core/ext/upb-gen/envoy/config/bootstrap/v3/bootstrap.upb_minitable.c +18 -13
- data/src/core/ext/upb-gen/envoy/config/cluster/v3/cluster.upb.h +70 -38
- data/src/core/ext/upb-gen/envoy/config/cluster/v3/cluster.upb_minitable.c +20 -17
- data/src/core/ext/upb-gen/envoy/config/common/matcher/v3/matcher.upb.h +26 -10
- data/src/core/ext/upb-gen/envoy/config/common/matcher/v3/matcher.upb_minitable.c +8 -7
- data/src/core/ext/upb-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upb.h +495 -0
- data/src/core/ext/upb-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upb_minitable.c +114 -0
- data/src/core/ext/upb-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upb_minitable.h +36 -0
- data/src/core/ext/upb-gen/envoy/config/core/v3/address.upb.h +26 -10
- data/src/core/ext/upb-gen/envoy/config/core/v3/address.upb_minitable.c +8 -7
- data/src/core/ext/upb-gen/envoy/config/core/v3/cel.upb.h +121 -0
- data/src/core/ext/upb-gen/envoy/config/core/v3/cel.upb_minitable.c +54 -0
- data/src/core/ext/upb-gen/envoy/config/core/v3/cel.upb_minitable.h +32 -0
- data/src/core/ext/upb-gen/envoy/config/core/v3/grpc_service.upb.h +143 -9
- data/src/core/ext/upb-gen/envoy/config/core/v3/grpc_service.upb_minitable.c +18 -6
- data/src/core/ext/upb-gen/envoy/config/core/v3/protocol.upb.h +112 -11
- data/src/core/ext/upb-gen/envoy/config/core/v3/protocol.upb_minitable.c +22 -9
- data/src/core/ext/upb-gen/envoy/config/core/v3/proxy_protocol.upb.h +276 -0
- data/src/core/ext/upb-gen/envoy/config/core/v3/proxy_protocol.upb_minitable.c +60 -5
- data/src/core/ext/upb-gen/envoy/config/core/v3/proxy_protocol.upb_minitable.h +4 -0
- data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb.h +72 -0
- data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb_minitable.c +23 -2
- data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb_minitable.h +2 -0
- data/src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb.h +129 -13
- data/src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb_minitable.c +36 -10
- data/src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb_minitable.h +2 -0
- data/src/core/ext/upb-gen/envoy/config/listener/v3/quic_config.upb.h +30 -0
- data/src/core/ext/upb-gen/envoy/config/listener/v3/quic_config.upb_minitable.c +5 -3
- data/src/core/ext/upb-gen/envoy/config/metrics/v3/metrics_service.upb.h +16 -0
- data/src/core/ext/upb-gen/envoy/config/metrics/v3/metrics_service.upb_minitable.c +4 -3
- data/src/core/ext/upb-gen/envoy/config/metrics/v3/stats.upb.h +31 -0
- data/src/core/ext/upb-gen/envoy/config/metrics/v3/stats.upb_minitable.c +5 -3
- data/src/core/ext/upb-gen/envoy/config/overload/v3/overload.upb.h +2 -1
- data/src/core/ext/upb-gen/envoy/config/rbac/v3/rbac.upb.h +63 -0
- data/src/core/ext/upb-gen/envoy/config/rbac/v3/rbac.upb_minitable.c +12 -7
- data/src/core/ext/upb-gen/envoy/config/route/v3/route.upb.h +97 -81
- data/src/core/ext/upb-gen/envoy/config/route/v3/route.upb_minitable.c +40 -23
- data/src/core/ext/upb-gen/envoy/config/route/v3/route_components.upb.h +604 -228
- data/src/core/ext/upb-gen/envoy/config/route/v3/route_components.upb_minitable.c +146 -100
- data/src/core/ext/upb-gen/envoy/config/tap/v3/common.upb.h +30 -0
- data/src/core/ext/upb-gen/envoy/config/tap/v3/common.upb_minitable.c +5 -3
- data/src/core/ext/upb-gen/envoy/config/trace/v3/opentelemetry.upb.h +35 -3
- data/src/core/ext/upb-gen/envoy/config/trace/v3/opentelemetry.upb_minitable.c +7 -4
- data/src/core/ext/upb-gen/envoy/config/trace/v3/zipkin.upb.h +66 -14
- data/src/core/ext/upb-gen/envoy/config/trace/v3/zipkin.upb_minitable.c +22 -11
- data/src/core/ext/upb-gen/envoy/extensions/clusters/aggregate/v3/cluster.upb.h +87 -0
- data/src/core/ext/upb-gen/envoy/extensions/clusters/aggregate/v3/cluster.upb_minitable.c +29 -2
- data/src/core/ext/upb-gen/envoy/extensions/clusters/aggregate/v3/cluster.upb_minitable.h +2 -0
- data/src/core/ext/upb-gen/envoy/extensions/filters/http/rbac/v3/rbac.upb.h +0 -1
- data/src/core/ext/upb-gen/envoy/extensions/filters/http/rbac/v3/rbac.upb_minitable.c +0 -1
- data/src/core/ext/upb-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb.h +20 -4
- data/src/core/ext/upb-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb_minitable.c +5 -4
- data/src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +239 -60
- data/src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb_minitable.c +59 -28
- data/src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb_minitable.h +2 -0
- data/src/core/ext/upb-gen/envoy/extensions/grpc_service/call_credentials/access_token/v3/access_token_credentials.upb.h +89 -0
- data/src/core/ext/upb-gen/envoy/extensions/grpc_service/call_credentials/access_token/v3/access_token_credentials.upb_minitable.c +50 -0
- data/src/core/ext/upb-gen/envoy/extensions/grpc_service/call_credentials/access_token/v3/access_token_credentials.upb_minitable.h +32 -0
- data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/tls/v3/tls_credentials.upb.h +135 -0
- data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/tls/v3/tls_credentials.upb_minitable.c +53 -0
- data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/tls/v3/tls_credentials.upb_minitable.h +32 -0
- data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/xds/v3/xds_credentials.upb.h +105 -0
- data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/xds/v3/xds_credentials.upb_minitable.c +51 -0
- data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/xds/v3/xds_credentials.upb_minitable.h +32 -0
- data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb.h +32 -0
- data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb_minitable.c +6 -3
- data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb.h +206 -0
- data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb_minitable.c +41 -8
- data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb_minitable.h +2 -0
- data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/common.upb.h +64 -0
- data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/common.upb_minitable.c +4 -3
- data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb.h +64 -0
- data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c +31 -5
- data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.h +2 -0
- data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +283 -14
- data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +48 -11
- data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +2 -0
- data/src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb.h +144 -6
- data/src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.c +35 -7
- data/src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.h +2 -0
- data/src/core/ext/upb-gen/envoy/type/tracing/v3/custom_tag.upb.h +42 -21
- data/src/core/ext/upb-gen/envoy/type/tracing/v3/custom_tag.upb_minitable.c +9 -8
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h +164 -1
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c +37 -6
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h +2 -0
- data/src/core/ext/upb-gen/xds/type/matcher/v3/cel.upb.h +0 -1
- data/src/core/ext/upb-gen/xds/type/matcher/v3/cel.upb_minitable.c +0 -1
- data/src/core/ext/upb-gen/xds/type/matcher/v3/http_inputs.upb.h +0 -1
- data/src/core/ext/upb-gen/xds/type/matcher/v3/http_inputs.upb_minitable.c +0 -1
- data/src/core/ext/upb-gen/xds/type/matcher/v3/matcher.upb.h +26 -11
- data/src/core/ext/upb-gen/xds/type/matcher/v3/matcher.upb_minitable.c +8 -8
- data/src/core/ext/upb-gen/xds/type/matcher/v3/string.upb.h +33 -0
- data/src/core/ext/upb-gen/xds/type/matcher/v3/string.upb_minitable.c +14 -3
- data/src/core/ext/upb-gen/xds/type/v3/cel.upb.h +90 -10
- data/src/core/ext/upb-gen/xds/type/v3/cel.upb_minitable.c +18 -7
- data/src/core/ext/upbdefs-gen/cel/expr/checked.upbdefs.c +248 -0
- data/src/core/ext/upbdefs-gen/cel/expr/checked.upbdefs.h +97 -0
- data/src/core/ext/upbdefs-gen/cel/expr/syntax.upbdefs.c +283 -0
- data/src/core/ext/upbdefs-gen/cel/expr/syntax.upbdefs.h +107 -0
- data/src/core/ext/upbdefs-gen/envoy/config/accesslog/v3/accesslog.upbdefs.c +213 -211
- data/src/core/ext/upbdefs-gen/envoy/config/bootstrap/v3/bootstrap.upbdefs.c +635 -614
- data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/cluster.upbdefs.c +1012 -1000
- data/src/core/ext/upbdefs-gen/envoy/config/common/matcher/v3/matcher.upbdefs.c +276 -273
- data/src/core/ext/upbdefs-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upbdefs.c +152 -0
- data/src/core/ext/upbdefs-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upbdefs.h +47 -0
- data/src/core/ext/upbdefs-gen/envoy/config/core/v3/address.upbdefs.c +149 -144
- data/src/core/ext/upbdefs-gen/envoy/config/core/v3/base.upbdefs.c +367 -370
- data/src/core/ext/upbdefs-gen/envoy/config/core/v3/cel.upbdefs.c +63 -0
- data/src/core/ext/upbdefs-gen/envoy/config/core/v3/cel.upbdefs.h +37 -0
- data/src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_service.upbdefs.c +297 -284
- data/src/core/ext/upbdefs-gen/envoy/config/core/v3/protocol.upbdefs.c +492 -469
- data/src/core/ext/upbdefs-gen/envoy/config/core/v3/proxy_protocol.upbdefs.c +74 -43
- data/src/core/ext/upbdefs-gen/envoy/config/core/v3/proxy_protocol.upbdefs.h +10 -0
- data/src/core/ext/upbdefs-gen/envoy/config/core/v3/substitution_format_string.upbdefs.c +60 -59
- data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint_components.upbdefs.c +202 -184
- data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint_components.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener.upbdefs.c +354 -339
- data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/quic_config.upbdefs.c +28 -19
- data/src/core/ext/upbdefs-gen/envoy/config/metrics/v3/metrics_service.upbdefs.c +30 -27
- data/src/core/ext/upbdefs-gen/envoy/config/metrics/v3/stats.upbdefs.c +71 -66
- data/src/core/ext/upbdefs-gen/envoy/config/overload/v3/overload.upbdefs.c +94 -91
- data/src/core/ext/upbdefs-gen/envoy/config/rbac/v3/rbac.upbdefs.c +386 -369
- data/src/core/ext/upbdefs-gen/envoy/config/route/v3/route.upbdefs.c +60 -57
- data/src/core/ext/upbdefs-gen/envoy/config/route/v3/route_components.upbdefs.c +1974 -1884
- data/src/core/ext/upbdefs-gen/envoy/config/tap/v3/common.upbdefs.c +119 -112
- data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/opentelemetry.upbdefs.c +62 -51
- data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/zipkin.upbdefs.c +109 -88
- data/src/core/ext/upbdefs-gen/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c +54 -36
- data/src/core/ext/upbdefs-gen/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c +78 -84
- data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upbdefs.c +48 -46
- data/src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c +1041 -984
- data/src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c +304 -290
- data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c +94 -77
- data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +246 -193
- data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.c +37 -23
- data/src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-gen/envoy/type/tracing/v3/custom_tag.upbdefs.c +5 -3
- data/src/core/ext/upbdefs-gen/google/api/http.upbdefs.c +4 -4
- data/src/core/ext/upbdefs-gen/google/api/httpbody.upbdefs.c +4 -5
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c +113 -87
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-gen/udpa/annotations/migrate.upbdefs.c +5 -5
- data/src/core/ext/upbdefs-gen/udpa/annotations/security.upbdefs.c +6 -5
- data/src/core/ext/upbdefs-gen/udpa/annotations/sensitive.upbdefs.c +5 -5
- data/src/core/ext/upbdefs-gen/udpa/annotations/status.upbdefs.c +5 -5
- data/src/core/ext/upbdefs-gen/udpa/annotations/versioning.upbdefs.c +5 -5
- data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/cel.upbdefs.c +25 -30
- data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/http_inputs.upbdefs.c +14 -20
- data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/matcher.upbdefs.c +180 -183
- data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/string.upbdefs.c +56 -47
- data/src/core/ext/upbdefs-gen/xds/type/v3/cel.upbdefs.c +69 -47
- data/src/core/filter/filter_chain.h +95 -0
- data/src/core/handshaker/http_connect/{http_connect_handshaker.cc → http_connect_client_handshaker.cc} +32 -31
- data/src/core/handshaker/http_connect/{http_connect_handshaker.h → http_connect_client_handshaker.h} +4 -4
- data/src/core/handshaker/http_connect/http_proxy_mapper.cc +1 -1
- data/src/core/handshaker/http_connect/xds_http_proxy_mapper.cc +1 -1
- data/src/core/handshaker/security/pipelined_secure_endpoint.cc +14 -13
- data/src/core/handshaker/security/secure_endpoint.cc +282 -68
- data/src/core/handshaker/security/secure_endpoint.h +0 -7
- data/src/core/lib/channel/channel_args.h +1 -1
- data/src/core/lib/channel/promise_based_filter.cc +17 -4
- data/src/core/lib/channel/promise_based_filter.h +3 -2
- data/src/core/lib/debug/trace_flags.cc +2 -0
- data/src/core/lib/debug/trace_flags.h +1 -0
- data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +35 -8
- data/src/core/lib/event_engine/cf_engine/dns_service_resolver.h +1 -2
- data/src/core/lib/event_engine/event_engine.cc +9 -0
- data/src/core/lib/event_engine/extensions/tcp_trace.h +0 -3
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +2 -2
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +1 -1
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +34 -9
- data/src/core/lib/event_engine/posix_engine/posix_engine.h +24 -2
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +1 -3
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +141 -14
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +19 -2
- data/src/core/lib/event_engine/posix_engine/posix_interface.h +7 -0
- data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +21 -3
- data/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc +16 -0
- data/src/core/lib/experiments/experiments.cc +309 -201
- data/src/core/lib/experiments/experiments.h +141 -80
- data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +2 -2
- data/src/core/lib/iomgr/resolve_address.h +0 -2
- data/src/core/lib/iomgr/resolved_address.h +0 -2
- data/src/core/lib/iomgr/tcp_posix.cc +13 -5
- data/src/core/lib/iomgr/tcp_server.cc +0 -5
- data/src/core/lib/iomgr/tcp_server.h +0 -7
- data/src/core/lib/iomgr/tcp_server_posix.cc +0 -17
- data/src/core/lib/iomgr/tcp_server_utils_posix.h +0 -3
- data/src/core/lib/iomgr/tcp_server_windows.cc +12 -51
- data/src/core/lib/promise/all_ok.h +17 -12
- data/src/core/lib/promise/cancel_callback.h +12 -13
- data/src/core/lib/promise/detail/join_state.h +626 -0
- data/src/core/lib/promise/detail/promise_factory.h +14 -14
- data/src/core/lib/promise/for_each.h +32 -8
- data/src/core/lib/promise/if.h +9 -7
- data/src/core/lib/promise/loop.h +18 -16
- data/src/core/lib/promise/map.h +54 -47
- data/src/core/lib/promise/mpsc.h +11 -10
- data/src/core/lib/promise/observable.h +6 -6
- data/src/core/lib/promise/party.h +25 -19
- data/src/core/lib/promise/poll.h +5 -5
- data/src/core/lib/promise/prioritized_race.h +10 -7
- data/src/core/lib/promise/promise.h +16 -11
- data/src/core/lib/promise/race.h +6 -5
- data/src/core/lib/promise/seq.h +109 -74
- data/src/core/lib/promise/try_join.h +14 -6
- data/src/core/lib/promise/try_seq.h +76 -60
- data/src/core/lib/resource_quota/api.cc +7 -0
- data/src/core/lib/resource_quota/arena.h +1 -1
- data/src/core/lib/resource_quota/memory_quota.cc +4 -1
- data/src/core/lib/resource_quota/resource_quota.cc +2 -1
- data/src/core/lib/resource_quota/resource_quota.h +3 -0
- data/src/core/lib/resource_quota/stream_quota.cc +77 -1
- data/src/core/lib/resource_quota/stream_quota.h +64 -1
- data/src/core/lib/resource_quota/telemetry.h +1 -1
- data/src/core/lib/surface/call.cc +13 -0
- data/src/core/lib/surface/call_utils.h +58 -43
- data/src/core/lib/surface/channel.h +1 -4
- data/src/core/lib/surface/completion_queue.cc +13 -6
- data/src/core/lib/surface/validate_metadata.cc +20 -15
- data/src/core/lib/surface/validate_metadata.h +3 -1
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/promise_endpoint.cc +1 -1
- data/src/core/lib/transport/promise_endpoint.h +1 -1
- data/src/core/lib/transport/transport.h +5 -0
- data/src/core/load_balancing/health_check_client.cc +1 -15
- data/src/core/load_balancing/health_check_client_internal.h +0 -2
- data/src/core/load_balancing/oob_backend_metric.cc +1 -5
- data/src/core/load_balancing/oob_backend_metric_internal.h +0 -1
- data/src/core/load_balancing/xds/xds_cluster_impl.cc +12 -9
- data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -2
- data/src/core/resolver/xds/xds_resolver.cc +162 -116
- data/src/core/server/server.cc +18 -1
- data/src/core/server/server.h +2 -0
- data/src/core/server/xds_server_config_fetcher.cc +4 -4
- data/src/core/telemetry/call_tracer.cc +87 -2
- data/src/core/telemetry/call_tracer.h +46 -8
- data/src/core/telemetry/instrument.cc +102 -40
- data/src/core/telemetry/instrument.h +246 -65
- data/src/core/tsi/fake_transport_security.cc +3 -1
- data/src/core/tsi/ssl_transport_security.cc +516 -137
- data/src/core/tsi/ssl_transport_security.h +28 -22
- data/src/core/tsi/ssl_transport_security_utils.cc +2 -2
- data/src/core/tsi/ssl_transport_security_utils.h +2 -2
- data/src/core/util/bitset.h +6 -0
- data/src/core/util/function_signature.h +3 -1
- data/src/core/util/http_client/httpcli_security_connector.cc +2 -1
- data/src/core/util/json/json_reader.cc +0 -4
- data/src/core/xds/grpc/certificate_provider_store.cc +2 -1
- data/src/core/xds/grpc/certificate_provider_store.h +3 -17
- data/src/core/xds/grpc/certificate_provider_store_interface.h +61 -0
- data/src/core/xds/grpc/xds_bootstrap_grpc.cc +48 -0
- data/src/core/xds/grpc/xds_bootstrap_grpc.h +18 -0
- data/src/core/xds/grpc/xds_certificate_provider.cc +7 -2
- data/src/core/xds/grpc/xds_certificate_provider.h +13 -2
- data/src/core/xds/grpc/xds_client_grpc.cc +13 -6
- data/src/core/xds/grpc/xds_client_grpc.h +10 -7
- data/src/core/xds/grpc/xds_cluster.cc +18 -4
- data/src/core/xds/grpc/xds_cluster.h +17 -2
- data/src/core/xds/grpc/xds_cluster_parser.cc +36 -11
- data/src/core/xds/grpc/xds_common_types.cc +45 -0
- data/src/core/xds/grpc/xds_common_types.h +31 -0
- data/src/core/xds/grpc/xds_common_types_parser.cc +274 -16
- data/src/core/xds/grpc/xds_common_types_parser.h +12 -0
- data/src/core/xds/grpc/xds_http_fault_filter.cc +128 -24
- data/src/core/xds/grpc/xds_http_fault_filter.h +19 -10
- data/src/core/xds/grpc/xds_http_filter.cc +38 -0
- data/src/core/xds/grpc/xds_http_filter.h +70 -47
- data/src/core/xds/grpc/xds_http_filter_registry.cc +48 -14
- data/src/core/xds/grpc/xds_http_filter_registry.h +29 -15
- data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +88 -22
- data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +22 -11
- data/src/core/xds/grpc/xds_http_rbac_filter.cc +36 -20
- data/src/core/xds/grpc/xds_http_rbac_filter.h +19 -10
- data/src/core/xds/grpc/xds_http_stateful_session_filter.cc +143 -26
- data/src/core/xds/grpc/xds_http_stateful_session_filter.h +19 -10
- data/src/core/xds/grpc/xds_listener.cc +4 -1
- data/src/core/xds/grpc/xds_listener.h +10 -2
- data/src/core/xds/grpc/xds_listener_parser.cc +23 -18
- data/src/core/xds/grpc/xds_matcher.cc +40 -5
- data/src/core/xds/grpc/xds_matcher.h +13 -0
- data/src/core/xds/grpc/xds_matcher_action.h +1 -1
- data/src/core/xds/grpc/xds_matcher_parse.cc +60 -40
- data/src/core/xds/grpc/xds_matcher_parse.h +2 -1
- data/src/core/xds/grpc/xds_route_config.cc +12 -1
- data/src/core/xds/grpc/xds_route_config.h +15 -2
- data/src/core/xds/grpc/xds_route_config_parser.cc +11 -5
- data/src/core/xds/grpc/xds_routing.cc +181 -6
- data/src/core/xds/grpc/xds_routing.h +57 -0
- data/src/core/xds/grpc/xds_server_grpc.cc +55 -43
- data/src/core/xds/grpc/xds_server_grpc.h +13 -6
- data/src/core/xds/grpc/xds_server_grpc_interface.h +3 -2
- data/src/core/xds/grpc/xds_transport_grpc.cc +12 -6
- data/src/core/xds/grpc/xds_transport_grpc.h +5 -1
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +12 -8
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +18 -12
- data/src/ruby/lib/grpc/grpc.rb +7 -9
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/generate_proto_ruby.sh +1 -1
- data/src/ruby/spec/client_server_spec.rb +1 -1
- data/src/ruby/spec/generic/rpc_server_pool_spec.rb +1 -1
- data/src/ruby/spec/generic/rpc_server_spec.rb +3 -4
- data/src/ruby/spec/spec_helper.rb +1 -1
- metadata +64 -14
- data/src/core/ext/transport/chttp2/transport/security_frame.cc +0 -31
- data/src/core/handshaker/security/legacy_secure_endpoint.cc +0 -597
|
@@ -23,10 +23,8 @@
|
|
|
23
23
|
#include <grpc/support/port_platform.h>
|
|
24
24
|
#include <limits.h>
|
|
25
25
|
|
|
26
|
-
#include <algorithm>
|
|
27
26
|
#include <cstddef>
|
|
28
27
|
#include <cstdint>
|
|
29
|
-
#include <iterator>
|
|
30
28
|
#include <memory>
|
|
31
29
|
#include <optional>
|
|
32
30
|
#include <string>
|
|
@@ -37,7 +35,6 @@
|
|
|
37
35
|
#include "src/core/call/message.h"
|
|
38
36
|
#include "src/core/call/metadata.h"
|
|
39
37
|
#include "src/core/call/metadata_batch.h"
|
|
40
|
-
#include "src/core/call/metadata_info.h"
|
|
41
38
|
#include "src/core/channelz/channelz.h"
|
|
42
39
|
#include "src/core/ext/transport/chttp2/transport/flow_control.h"
|
|
43
40
|
#include "src/core/ext/transport/chttp2/transport/flow_control_manager.h"
|
|
@@ -53,23 +50,23 @@
|
|
|
53
50
|
#include "src/core/ext/transport/chttp2/transport/keepalive.h"
|
|
54
51
|
#include "src/core/ext/transport/chttp2/transport/message_assembler.h"
|
|
55
52
|
#include "src/core/ext/transport/chttp2/transport/ping_promise.h"
|
|
53
|
+
#include "src/core/ext/transport/chttp2/transport/security_frame.h"
|
|
56
54
|
#include "src/core/ext/transport/chttp2/transport/stream.h"
|
|
57
55
|
#include "src/core/ext/transport/chttp2/transport/stream_data_queue.h"
|
|
58
56
|
#include "src/core/ext/transport/chttp2/transport/transport_common.h"
|
|
57
|
+
#include "src/core/ext/transport/chttp2/transport/write_cycle.h"
|
|
59
58
|
#include "src/core/lib/channel/channel_args.h"
|
|
60
59
|
#include "src/core/lib/iomgr/exec_ctx.h"
|
|
61
|
-
#include "src/core/lib/promise/activity.h"
|
|
62
|
-
#include "src/core/lib/promise/context.h"
|
|
63
60
|
#include "src/core/lib/promise/for_each.h"
|
|
64
61
|
#include "src/core/lib/promise/if.h"
|
|
65
62
|
#include "src/core/lib/promise/loop.h"
|
|
66
63
|
#include "src/core/lib/promise/map.h"
|
|
67
|
-
#include "src/core/lib/promise/match_promise.h"
|
|
68
64
|
#include "src/core/lib/promise/party.h"
|
|
69
65
|
#include "src/core/lib/promise/poll.h"
|
|
70
66
|
#include "src/core/lib/promise/promise.h"
|
|
71
67
|
#include "src/core/lib/promise/race.h"
|
|
72
68
|
#include "src/core/lib/promise/sleep.h"
|
|
69
|
+
#include "src/core/lib/promise/status_flag.h"
|
|
73
70
|
#include "src/core/lib/promise/try_seq.h"
|
|
74
71
|
#include "src/core/lib/resource_quota/arena.h"
|
|
75
72
|
#include "src/core/lib/resource_quota/resource_quota.h"
|
|
@@ -85,25 +82,24 @@
|
|
|
85
82
|
#include "src/core/util/ref_counted_ptr.h"
|
|
86
83
|
#include "src/core/util/sync.h"
|
|
87
84
|
#include "src/core/util/time.h"
|
|
88
|
-
#include "absl/base/thread_annotations.h"
|
|
89
85
|
#include "absl/container/flat_hash_map.h"
|
|
90
86
|
#include "absl/log/log.h"
|
|
91
87
|
#include "absl/status/status.h"
|
|
92
88
|
#include "absl/strings/cord.h"
|
|
93
89
|
#include "absl/strings/str_cat.h"
|
|
94
90
|
#include "absl/strings/string_view.h"
|
|
95
|
-
#include "absl/types/span.h"
|
|
96
91
|
|
|
97
92
|
namespace grpc_core {
|
|
98
93
|
namespace http2 {
|
|
99
94
|
|
|
100
|
-
// TODO(akshitpatel)(tjagtap) [PH2][
|
|
95
|
+
// TODO(akshitpatel)(tjagtap) [PH2][P1] : When settings frame increases incoming
|
|
101
96
|
// window size, our transport must make the streams that were blocked on stream
|
|
102
97
|
// flow control as writeable.
|
|
103
98
|
|
|
104
99
|
// As a gRPC server never initiates a stream, the last incoming stream id on
|
|
105
100
|
// the client side will always be 0.
|
|
106
101
|
constexpr uint32_t kLastIncomingStreamIdClient = 0;
|
|
102
|
+
const bool kIsClient = true;
|
|
107
103
|
|
|
108
104
|
using grpc_event_engine::experimental::EventEngine;
|
|
109
105
|
using StreamWritabilityUpdate =
|
|
@@ -113,39 +109,13 @@ using StreamWritabilityUpdate =
|
|
|
113
109
|
// and it is functions. The code will be written iteratively.
|
|
114
110
|
// Do not use or edit any of these functions unless you are
|
|
115
111
|
// familiar with the PH2 project (Moving chttp2 to promises.)
|
|
116
|
-
// TODO(tjagtap) : [PH2][
|
|
117
|
-
// rollout
|
|
118
|
-
|
|
119
|
-
template <typename Factory>
|
|
120
|
-
void Http2ClientTransport::SpawnInfallible(RefCountedPtr<Party> party,
|
|
121
|
-
absl::string_view name,
|
|
122
|
-
Factory&& factory) {
|
|
123
|
-
party->Spawn(name, std::forward<Factory>(factory), [](Empty) {});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
template <typename Factory>
|
|
127
|
-
void Http2ClientTransport::SpawnInfallibleTransportParty(absl::string_view name,
|
|
128
|
-
Factory&& factory) {
|
|
129
|
-
SpawnInfallible(general_party_, name, std::forward<Factory>(factory));
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
template <typename Factory>
|
|
133
|
-
void Http2ClientTransport::SpawnGuardedTransportParty(absl::string_view name,
|
|
134
|
-
Factory&& factory) {
|
|
135
|
-
general_party_->Spawn(
|
|
136
|
-
name, std::forward<Factory>(factory),
|
|
137
|
-
[self = RefAsSubclass<Http2ClientTransport>()](absl::Status status) {
|
|
138
|
-
if (!status.ok()) {
|
|
139
|
-
GRPC_UNUSED absl::Status error = self->HandleError(
|
|
140
|
-
/*stream_id=*/std::nullopt, ToHttpOkOrConnError(status));
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
}
|
|
112
|
+
// TODO(tjagtap) : [PH2][P5] : Update the experimental status of the code when
|
|
113
|
+
// http2 rollout is completed.
|
|
144
114
|
|
|
145
115
|
void Http2ClientTransport::PerformOp(grpc_transport_op* op) {
|
|
146
116
|
// Notes : Refer : src/core/ext/transport/chaotic_good/client_transport.cc
|
|
147
117
|
// Functions : StartConnectivityWatch, StopConnectivityWatch, PerformOp
|
|
148
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
118
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::PerformOp Begin";
|
|
149
119
|
bool did_stuff = false;
|
|
150
120
|
if (op->start_connectivity_watch != nullptr) {
|
|
151
121
|
StartConnectivityWatch(op->start_connectivity_watch_state,
|
|
@@ -161,7 +131,7 @@ void Http2ClientTransport::PerformOp(grpc_transport_op* op) {
|
|
|
161
131
|
GRPC_DCHECK(did_stuff) << "Unimplemented transport perform op ";
|
|
162
132
|
|
|
163
133
|
ExecCtx::Run(DEBUG_LOCATION, op->on_consumed, absl::OkStatus());
|
|
164
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
134
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::PerformOp End";
|
|
165
135
|
// TODO(tjagtap) : [PH2][P2] :
|
|
166
136
|
// Refer src/core/ext/transport/chttp2/transport/chttp2_transport.cc
|
|
167
137
|
// perform_transport_op_locked
|
|
@@ -193,8 +163,9 @@ void Http2ClientTransport::ReportDisconnection(
|
|
|
193
163
|
void Http2ClientTransport::ReportDisconnectionLocked(
|
|
194
164
|
const absl::Status& status, StateWatcher::DisconnectInfo disconnect_info,
|
|
195
165
|
const char* reason) {
|
|
196
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
197
|
-
|
|
166
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
167
|
+
<< "Http2ClientTransport::ReportDisconnectionLocked status="
|
|
168
|
+
<< status.ToString() << "; reason=" << reason;
|
|
198
169
|
state_tracker_.SetState(GRPC_CHANNEL_TRANSIENT_FAILURE, status, reason);
|
|
199
170
|
NotifyStateWatcherOnDisconnectLocked(status, disconnect_info);
|
|
200
171
|
}
|
|
@@ -230,8 +201,27 @@ void Http2ClientTransport::NotifyStateWatcherOnDisconnectLocked(
|
|
|
230
201
|
});
|
|
231
202
|
}
|
|
232
203
|
|
|
204
|
+
absl::Status Http2ClientTransport::AckPing(uint64_t opaque_data) {
|
|
205
|
+
// It is possible that the PingRatePolicy may decide to not send a ping
|
|
206
|
+
// request (in cases like the number of inflight pings is too high).
|
|
207
|
+
// When this happens, it becomes important to ensure that if a ping ack
|
|
208
|
+
// is received and there is an "important" outstanding ping request, we
|
|
209
|
+
// should retry to send it out now.
|
|
210
|
+
if (ping_manager_->AckPing(opaque_data)) {
|
|
211
|
+
if (ping_manager_->ImportantPingRequested()) {
|
|
212
|
+
return TriggerWriteCycle();
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::AckPing Unknown ping "
|
|
216
|
+
"response received for ping id="
|
|
217
|
+
<< opaque_data;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return absl::OkStatus();
|
|
221
|
+
}
|
|
222
|
+
|
|
233
223
|
void Http2ClientTransport::Orphan() {
|
|
234
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
224
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::Orphan Begin";
|
|
235
225
|
// Accessing general_party here is not advisable. It may so happen that
|
|
236
226
|
// the party is already freed/may free up any time. The only guarantee here
|
|
237
227
|
// is that the transport is still valid.
|
|
@@ -239,37 +229,33 @@ void Http2ClientTransport::Orphan() {
|
|
|
239
229
|
MaybeSpawnCloseTransport(
|
|
240
230
|
ToHttpOkOrConnError(absl::UnavailableError("Orphaned")));
|
|
241
231
|
Unref();
|
|
242
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
232
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::Orphan End";
|
|
243
233
|
}
|
|
244
234
|
|
|
245
235
|
///////////////////////////////////////////////////////////////////////////////
|
|
246
236
|
// Processing each type of frame
|
|
247
237
|
|
|
248
|
-
Http2Status Http2ClientTransport::
|
|
238
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(Http2DataFrame&& frame) {
|
|
249
239
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-data
|
|
250
240
|
GRPC_HTTP2_CLIENT_DLOG
|
|
251
|
-
<< "Http2ClientTransport
|
|
252
|
-
<< frame.stream_id << ", end_stream
|
|
253
|
-
<< ", payload=" << MaybeTruncatePayload(frame.payload)
|
|
241
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(DataFrame) { stream_id="
|
|
242
|
+
<< frame.stream_id << ", end_stream:" << frame.end_stream
|
|
254
243
|
<< ", payload length=" << frame.payload.Length() << "}";
|
|
255
244
|
|
|
256
245
|
// TODO(akshitpatel) : [PH2][P3] : Investigate if we should do this even if
|
|
257
246
|
// the function returns a non-ok status?
|
|
258
247
|
ping_manager_->ReceivedDataFrame();
|
|
259
248
|
|
|
260
|
-
// Lookup stream
|
|
261
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
262
|
-
<< "Http2ClientTransport ProcessHttp2DataFrame LookupStream";
|
|
263
249
|
RefCountedPtr<Stream> stream = LookupStream(frame.stream_id);
|
|
264
250
|
|
|
265
251
|
ValueOrHttp2Status<chttp2::FlowControlAction> flow_control_action =
|
|
266
252
|
ProcessIncomingDataFrameFlowControl(current_frame_header_, flow_control_,
|
|
267
|
-
stream);
|
|
253
|
+
stream.get());
|
|
268
254
|
if (!flow_control_action.IsOk()) {
|
|
269
255
|
return ValueOrHttp2Status<chttp2::FlowControlAction>::TakeStatus(
|
|
270
256
|
std::move(flow_control_action));
|
|
271
257
|
}
|
|
272
|
-
ActOnFlowControlAction(flow_control_action.value(), stream);
|
|
258
|
+
ActOnFlowControlAction(flow_control_action.value(), stream.get());
|
|
273
259
|
|
|
274
260
|
if (stream == nullptr) {
|
|
275
261
|
// TODO(tjagtap) : [PH2][P2] : Implement the correct behaviour later.
|
|
@@ -277,7 +263,7 @@ Http2Status Http2ClientTransport::ProcessHttp2DataFrame(Http2DataFrame frame) {
|
|
|
277
263
|
// or "half-closed (local)" state, the recipient MUST respond with a stream
|
|
278
264
|
// error (Section 5.4.2) of type STREAM_CLOSED.
|
|
279
265
|
GRPC_HTTP2_CLIENT_DLOG
|
|
280
|
-
<< "Http2ClientTransport
|
|
266
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(DataFrame) { stream_id="
|
|
281
267
|
<< frame.stream_id << "} Lookup Failed";
|
|
282
268
|
return Http2Status::Ok();
|
|
283
269
|
}
|
|
@@ -292,36 +278,41 @@ Http2Status Http2ClientTransport::ProcessHttp2DataFrame(Http2DataFrame frame) {
|
|
|
292
278
|
|
|
293
279
|
// Add frame to assembler
|
|
294
280
|
GRPC_HTTP2_CLIENT_DLOG
|
|
295
|
-
<< "Http2ClientTransport
|
|
296
|
-
|
|
281
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(DataFrame) "
|
|
282
|
+
"AppendNewDataFrame";
|
|
283
|
+
GrpcMessageAssembler& assembler = stream->GetGrpcMessageAssembler();
|
|
297
284
|
Http2Status status =
|
|
298
285
|
assembler.AppendNewDataFrame(frame.payload, frame.end_stream);
|
|
299
286
|
if (!status.IsOk()) {
|
|
300
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
301
|
-
|
|
287
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
288
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(DataFrame) "
|
|
289
|
+
"AppendNewDataFrame Failed";
|
|
302
290
|
return status;
|
|
303
291
|
}
|
|
304
292
|
|
|
305
293
|
// Pass the messages up the stack if it is ready.
|
|
306
294
|
while (true) {
|
|
307
295
|
GRPC_HTTP2_CLIENT_DLOG
|
|
308
|
-
<< "Http2ClientTransport
|
|
296
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(DataFrame) "
|
|
297
|
+
"ExtractMessage";
|
|
309
298
|
ValueOrHttp2Status<MessageHandle> result = assembler.ExtractMessage();
|
|
310
299
|
if (!result.IsOk()) {
|
|
311
300
|
GRPC_HTTP2_CLIENT_DLOG
|
|
312
|
-
<< "Http2ClientTransport
|
|
301
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(DataFrame) "
|
|
302
|
+
"ExtractMessage Failed";
|
|
313
303
|
return ValueOrHttp2Status<MessageHandle>::TakeStatus(std::move(result));
|
|
314
304
|
}
|
|
315
305
|
MessageHandle message = TakeValue(std::move(result));
|
|
316
306
|
if (message != nullptr) {
|
|
317
307
|
GRPC_HTTP2_CLIENT_DLOG
|
|
318
|
-
<< "Http2ClientTransport
|
|
308
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(DataFrame) "
|
|
309
|
+
"SpawnPushMessage "
|
|
319
310
|
<< message->DebugString();
|
|
320
|
-
stream->
|
|
311
|
+
stream->GetCallHandler().SpawnPushMessage(std::move(message));
|
|
321
312
|
continue;
|
|
322
313
|
}
|
|
323
314
|
GRPC_HTTP2_CLIENT_DLOG
|
|
324
|
-
<< "Http2ClientTransport
|
|
315
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(DataFrame) While Break";
|
|
325
316
|
break;
|
|
326
317
|
}
|
|
327
318
|
|
|
@@ -337,14 +328,13 @@ Http2Status Http2ClientTransport::ProcessHttp2DataFrame(Http2DataFrame frame) {
|
|
|
337
328
|
return Http2Status::Ok();
|
|
338
329
|
}
|
|
339
330
|
|
|
340
|
-
Http2Status Http2ClientTransport::
|
|
341
|
-
Http2HeaderFrame frame) {
|
|
331
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(
|
|
332
|
+
Http2HeaderFrame&& frame) {
|
|
342
333
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-headers
|
|
343
334
|
GRPC_HTTP2_CLIENT_DLOG
|
|
344
|
-
<< "Http2ClientTransport
|
|
335
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(HeaderFrame) { stream_id="
|
|
345
336
|
<< frame.stream_id << ", end_headers=" << frame.end_headers
|
|
346
|
-
<< ", end_stream=" << frame.end_stream
|
|
347
|
-
<< ", payload=" << MaybeTruncatePayload(frame.payload) << " }";
|
|
337
|
+
<< ", end_stream=" << frame.end_stream << " }";
|
|
348
338
|
// State update MUST happen before processing the frame.
|
|
349
339
|
incoming_headers_.OnHeaderReceived(frame);
|
|
350
340
|
|
|
@@ -360,7 +350,8 @@ Http2Status Http2ClientTransport::ProcessHttp2HeaderFrame(
|
|
|
360
350
|
// receives an unexpected stream identifier MUST respond with a connection
|
|
361
351
|
// error (Section 5.4.1) of type PROTOCOL_ERROR.
|
|
362
352
|
GRPC_HTTP2_CLIENT_DLOG
|
|
363
|
-
<< "Http2ClientTransport
|
|
353
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(HeaderFrame) { "
|
|
354
|
+
"stream_id="
|
|
364
355
|
<< frame.stream_id << "} Lookup Failed";
|
|
365
356
|
return ParseAndDiscardHeaders(std::move(frame.payload), frame.end_headers,
|
|
366
357
|
/*stream=*/nullptr, Http2Status::Ok());
|
|
@@ -368,85 +359,49 @@ Http2Status Http2ClientTransport::ProcessHttp2HeaderFrame(
|
|
|
368
359
|
|
|
369
360
|
if (stream->IsStreamHalfClosedRemote()) {
|
|
370
361
|
return ParseAndDiscardHeaders(
|
|
371
|
-
std::move(frame.payload), frame.end_headers, stream,
|
|
362
|
+
std::move(frame.payload), frame.end_headers, stream.get(),
|
|
372
363
|
Http2Status::Http2StreamError(
|
|
373
364
|
Http2ErrorCode::kStreamClosed,
|
|
374
365
|
std::string(RFC9113::kHalfClosedRemoteState)));
|
|
375
366
|
}
|
|
376
367
|
|
|
377
|
-
if (incoming_headers_.
|
|
378
|
-
stream->
|
|
379
|
-
stream->
|
|
368
|
+
if (incoming_headers_.DidReceiveDuplicateMetadata(
|
|
369
|
+
stream->IsInitialMetadataReceived(),
|
|
370
|
+
stream->IsTrailingMetadataReceived())) {
|
|
380
371
|
return ParseAndDiscardHeaders(
|
|
381
|
-
std::move(frame.payload), frame.end_headers, stream,
|
|
372
|
+
std::move(frame.payload), frame.end_headers, stream.get(),
|
|
382
373
|
Http2Status::Http2StreamError(
|
|
383
374
|
Http2ErrorCode::kInternalError,
|
|
384
375
|
std::string(GrpcErrors::kTooManyMetadata)));
|
|
385
376
|
}
|
|
386
377
|
|
|
387
|
-
Http2Status append_result =
|
|
378
|
+
Http2Status append_result =
|
|
379
|
+
stream->GetHeaderAssembler().AppendHeaderFrame(frame);
|
|
388
380
|
if (!append_result.IsOk()) {
|
|
389
381
|
// Frame payload is not consumed if AppendHeaderFrame returns a non-OK
|
|
390
382
|
// status. We need to process it to keep our in consistent state.
|
|
391
383
|
return ParseAndDiscardHeaders(std::move(frame.payload), frame.end_headers,
|
|
392
|
-
stream, std::move(append_result));
|
|
384
|
+
stream.get(), std::move(append_result));
|
|
393
385
|
}
|
|
394
386
|
|
|
395
387
|
Http2Status status = ProcessMetadata(stream);
|
|
396
388
|
if (!status.IsOk()) {
|
|
397
389
|
// Frame payload has been moved to the HeaderAssembler. So calling
|
|
398
390
|
// ParseAndDiscardHeaders with an empty buffer.
|
|
399
|
-
return ParseAndDiscardHeaders(SliceBuffer(), frame.end_headers,
|
|
400
|
-
std::move(status));
|
|
391
|
+
return ParseAndDiscardHeaders(SliceBuffer(), frame.end_headers,
|
|
392
|
+
stream.get(), std::move(status));
|
|
401
393
|
}
|
|
402
394
|
|
|
403
395
|
// Frame payload has either been processed or moved to the HeaderAssembler.
|
|
404
396
|
return Http2Status::Ok();
|
|
405
397
|
}
|
|
406
398
|
|
|
407
|
-
Http2Status Http2ClientTransport::
|
|
408
|
-
|
|
409
|
-
HeaderAssembler& assembler = stream->header_assembler;
|
|
410
|
-
CallHandler call = stream->call;
|
|
411
|
-
|
|
412
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ProcessMetadata";
|
|
413
|
-
if (assembler.IsReady()) {
|
|
414
|
-
ValueOrHttp2Status<ServerMetadataHandle> read_result =
|
|
415
|
-
assembler.ReadMetadata(parser_, !incoming_headers_.HeaderHasEndStream(),
|
|
416
|
-
/*is_client=*/true,
|
|
417
|
-
/*max_header_list_size_soft_limit=*/
|
|
418
|
-
incoming_headers_.soft_limit(),
|
|
419
|
-
/*max_header_list_size_hard_limit=*/
|
|
420
|
-
settings_->acked().max_header_list_size());
|
|
421
|
-
if (read_result.IsOk()) {
|
|
422
|
-
ServerMetadataHandle metadata = TakeValue(std::move(read_result));
|
|
423
|
-
if (incoming_headers_.HeaderHasEndStream()) {
|
|
424
|
-
// TODO(tjagtap) : [PH2][P1] : Is this the right way to differentiate
|
|
425
|
-
// between initial and trailing metadata?
|
|
426
|
-
stream->MarkHalfClosedRemote();
|
|
427
|
-
stream->did_receive_trailing_metadata = true;
|
|
428
|
-
BeginCloseStream(stream, /*reset_stream_error_code=*/std::nullopt,
|
|
429
|
-
std::move(metadata));
|
|
430
|
-
} else {
|
|
431
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ProcessMetadata "
|
|
432
|
-
"SpawnPushServerInitialMetadata";
|
|
433
|
-
stream->did_receive_initial_metadata = true;
|
|
434
|
-
call.SpawnPushServerInitialMetadata(std::move(metadata));
|
|
435
|
-
}
|
|
436
|
-
return Http2Status::Ok();
|
|
437
|
-
}
|
|
438
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ProcessMetadata Failed";
|
|
439
|
-
return ValueOrHttp2Status<Arena::PoolPtr<grpc_metadata_batch>>::TakeStatus(
|
|
440
|
-
std::move(read_result));
|
|
441
|
-
}
|
|
442
|
-
return Http2Status::Ok();
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
Http2Status Http2ClientTransport::ProcessHttp2RstStreamFrame(
|
|
446
|
-
Http2RstStreamFrame frame) {
|
|
399
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(
|
|
400
|
+
Http2RstStreamFrame&& frame) {
|
|
447
401
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-rst_stream
|
|
448
402
|
GRPC_HTTP2_CLIENT_DLOG
|
|
449
|
-
<< "Http2ClientTransport
|
|
403
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(RstStreamFrame) { "
|
|
404
|
+
"stream_id="
|
|
450
405
|
<< frame.stream_id << ", error_code=" << frame.error_code << " }";
|
|
451
406
|
|
|
452
407
|
Http2ErrorCode error_code = FrameErrorCodeToHttp2ErrorCode(frame.error_code);
|
|
@@ -455,7 +410,8 @@ Http2Status Http2ClientTransport::ProcessHttp2RstStreamFrame(
|
|
|
455
410
|
RefCountedPtr<Stream> stream = LookupStream(frame.stream_id);
|
|
456
411
|
if (stream != nullptr) {
|
|
457
412
|
stream->MarkHalfClosedRemote();
|
|
458
|
-
BeginCloseStream(
|
|
413
|
+
BeginCloseStream(std::move(stream),
|
|
414
|
+
/*reset_stream_error_code=*/std::nullopt,
|
|
459
415
|
CancelledServerMetadataFromStatus(status));
|
|
460
416
|
}
|
|
461
417
|
|
|
@@ -464,13 +420,13 @@ Http2Status Http2ClientTransport::ProcessHttp2RstStreamFrame(
|
|
|
464
420
|
return Http2Status::Ok();
|
|
465
421
|
}
|
|
466
422
|
|
|
467
|
-
Http2Status Http2ClientTransport::
|
|
468
|
-
Http2SettingsFrame frame) {
|
|
423
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(
|
|
424
|
+
Http2SettingsFrame&& frame) {
|
|
469
425
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-settings
|
|
470
426
|
|
|
471
427
|
GRPC_HTTP2_CLIENT_DLOG
|
|
472
|
-
<< "Http2ClientTransport
|
|
473
|
-
<< ", settings length=" << frame.settings.size() << "}";
|
|
428
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(SettingsFrame) { ack="
|
|
429
|
+
<< frame.ack << ", settings length=" << frame.settings.size() << "}";
|
|
474
430
|
|
|
475
431
|
if (!frame.ack) {
|
|
476
432
|
Http2Status status = ValidateSettingsValues(frame.settings);
|
|
@@ -478,7 +434,11 @@ Http2Status Http2ClientTransport::ProcessHttp2SettingsFrame(
|
|
|
478
434
|
return status;
|
|
479
435
|
}
|
|
480
436
|
settings_->BufferPeerSettings(std::move(frame.settings));
|
|
481
|
-
|
|
437
|
+
absl::Status trigger_write_status = TriggerWriteCycle();
|
|
438
|
+
if (!trigger_write_status.ok()) {
|
|
439
|
+
return ToHttpOkOrConnError(trigger_write_status);
|
|
440
|
+
}
|
|
441
|
+
|
|
482
442
|
if (GPR_UNLIKELY(!settings_->IsFirstPeerSettingsApplied())) {
|
|
483
443
|
// Apply the first settings before we read any other frames.
|
|
484
444
|
reader_state_.SetPauseReadLoop();
|
|
@@ -501,63 +461,53 @@ Http2Status Http2ClientTransport::ProcessHttp2SettingsFrame(
|
|
|
501
461
|
return Http2Status::Ok();
|
|
502
462
|
}
|
|
503
463
|
|
|
504
|
-
|
|
464
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(Http2PingFrame&& frame) {
|
|
505
465
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-ping
|
|
506
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
},
|
|
532
|
-
[]() {
|
|
533
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
534
|
-
<< "Http2ClientTransport ProcessHttp2PingFrame "
|
|
535
|
-
"test_only_ack_pings_ is false. Ignoring the ping "
|
|
536
|
-
"request.";
|
|
537
|
-
return Immediate(Http2Status::Ok());
|
|
538
|
-
});
|
|
539
|
-
}));
|
|
466
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
467
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(PingFrame) { ack="
|
|
468
|
+
<< frame.ack << ", opaque=" << frame.opaque << " }";
|
|
469
|
+
if (frame.ack) {
|
|
470
|
+
return ToHttpOkOrConnError(AckPing(frame.opaque));
|
|
471
|
+
} else {
|
|
472
|
+
if (test_only_ack_pings_) {
|
|
473
|
+
// TODO(akshitpatel) : [PH2][P2] : Have a counter to track number
|
|
474
|
+
// of pending induced frames (Ping/Settings Ack). This is to
|
|
475
|
+
// ensure that if write is taking a long time, we can stop reads
|
|
476
|
+
// and prioritize writes. RFC9113: PING responses SHOULD be given
|
|
477
|
+
// higher priority than any other frame.
|
|
478
|
+
ping_manager_->AddPendingPingAck(frame.opaque);
|
|
479
|
+
// TODO(akshitpatel) : [PH2][P2] : This is done assuming that the
|
|
480
|
+
// other ProcessFrame promises may return stream or connection
|
|
481
|
+
// failures. If this does not turn out to be true, consider
|
|
482
|
+
// returning absl::Status here.
|
|
483
|
+
return ToHttpOkOrConnError(TriggerWriteCycle());
|
|
484
|
+
} else {
|
|
485
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
486
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(PingFrame) "
|
|
487
|
+
"test_only_ack_pings_ is false. Ignoring the ping request.";
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return Http2Status::Ok();
|
|
540
491
|
}
|
|
541
492
|
|
|
542
|
-
Http2Status Http2ClientTransport::
|
|
543
|
-
Http2GoawayFrame frame) {
|
|
493
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(
|
|
494
|
+
Http2GoawayFrame&& frame) {
|
|
544
495
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-goaway
|
|
545
496
|
GRPC_HTTP2_CLIENT_DLOG
|
|
546
|
-
<< "Http2ClientTransport
|
|
497
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(GoawayFrame) { "
|
|
547
498
|
"last_stream_id="
|
|
548
|
-
<< frame.last_stream_id << ", error_code=" << frame.error_code
|
|
549
|
-
<< ", debug_data=" << frame.debug_data.as_string_view() << "}";
|
|
499
|
+
<< frame.last_stream_id << ", error_code=" << frame.error_code << "}";
|
|
550
500
|
LOG_IF(ERROR,
|
|
551
501
|
frame.error_code != static_cast<uint32_t>(Http2ErrorCode::kNoError))
|
|
552
|
-
<< "Received GOAWAY frame with error code: " << frame.error_code
|
|
553
|
-
<< " and debug data: " << frame.debug_data.as_string_view();
|
|
502
|
+
<< "Received GOAWAY frame with error code: " << frame.error_code;
|
|
554
503
|
|
|
555
504
|
uint32_t last_stream_id = 0;
|
|
556
505
|
absl::Status status(ErrorCodeToAbslStatusCode(
|
|
557
506
|
FrameErrorCodeToHttp2ErrorCode(frame.error_code)),
|
|
558
|
-
frame.debug_data.
|
|
559
|
-
|
|
560
|
-
|
|
507
|
+
frame.debug_data.empty()
|
|
508
|
+
? absl::string_view("GOAWAY received")
|
|
509
|
+
: frame.debug_data.as_string_view());
|
|
510
|
+
if (GoawayManager::IsGracefulGoaway(frame)) {
|
|
561
511
|
const uint32_t next_stream_id = PeekNextStreamId();
|
|
562
512
|
last_stream_id = (next_stream_id > 1) ? next_stream_id - 2 : 0;
|
|
563
513
|
} else {
|
|
@@ -570,7 +520,8 @@ Http2Status Http2ClientTransport::ProcessHttp2GoawayFrame(
|
|
|
570
520
|
MutexLock lock(&transport_mutex_);
|
|
571
521
|
if (CanCloseTransportLocked()) {
|
|
572
522
|
close_transport = true;
|
|
573
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
523
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::ProcessIncomingFrame("
|
|
524
|
+
"GoawayFrame) "
|
|
574
525
|
"stream_list_ is empty";
|
|
575
526
|
}
|
|
576
527
|
}
|
|
@@ -596,7 +547,7 @@ Http2Status Http2ClientTransport::ProcessHttp2GoawayFrame(
|
|
|
596
547
|
keepalive_time_.millis() > max_keepalive_time_millis
|
|
597
548
|
? INT_MAX
|
|
598
549
|
: keepalive_time_.millis() * KEEPALIVE_TIME_BACKOFF_MULTIPLIER;
|
|
599
|
-
if (!
|
|
550
|
+
if (!IsSubchannelConnectionScalingEnabled()) {
|
|
600
551
|
status.SetPayload(kKeepaliveThrottlingKey,
|
|
601
552
|
absl::Cord(std::to_string(throttled_keepalive_time)));
|
|
602
553
|
}
|
|
@@ -614,7 +565,9 @@ Http2Status Http2ClientTransport::ProcessHttp2GoawayFrame(
|
|
|
614
565
|
Http2ErrorCodeToFrameErrorCode(Http2ErrorCode::kNoError)
|
|
615
566
|
? Http2ErrorCodeToFrameErrorCode(Http2ErrorCode::kInternalError)
|
|
616
567
|
: frame.error_code)),
|
|
617
|
-
|
|
568
|
+
frame.debug_data.empty()
|
|
569
|
+
? std::string("GOAWAY received")
|
|
570
|
+
: std::string(frame.debug_data.as_string_view())));
|
|
618
571
|
}
|
|
619
572
|
|
|
620
573
|
// lie: use transient failure from the transport to indicate goaway has been
|
|
@@ -623,11 +576,11 @@ Http2Status Http2ClientTransport::ProcessHttp2GoawayFrame(
|
|
|
623
576
|
return Http2Status::Ok();
|
|
624
577
|
}
|
|
625
578
|
|
|
626
|
-
Http2Status Http2ClientTransport::
|
|
627
|
-
Http2WindowUpdateFrame frame) {
|
|
579
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(
|
|
580
|
+
Http2WindowUpdateFrame&& frame) {
|
|
628
581
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-window_update
|
|
629
582
|
GRPC_HTTP2_CLIENT_DLOG
|
|
630
|
-
<< "Http2ClientTransport
|
|
583
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(WindowUpdateFrame) { "
|
|
631
584
|
" stream_id="
|
|
632
585
|
<< frame.stream_id << ", increment=" << frame.increment << "}";
|
|
633
586
|
|
|
@@ -647,22 +600,21 @@ Http2Status Http2ClientTransport::ProcessHttp2WindowUpdateFrame(
|
|
|
647
600
|
}
|
|
648
601
|
}
|
|
649
602
|
|
|
650
|
-
const bool should_trigger_write =
|
|
651
|
-
|
|
603
|
+
const bool should_trigger_write = ProcessIncomingWindowUpdateFrameFlowControl(
|
|
604
|
+
frame, flow_control_, stream.get());
|
|
652
605
|
if (should_trigger_write) {
|
|
653
|
-
|
|
606
|
+
return ToHttpOkOrConnError(TriggerWriteCycle());
|
|
654
607
|
}
|
|
655
608
|
return Http2Status::Ok();
|
|
656
609
|
}
|
|
657
610
|
|
|
658
|
-
Http2Status Http2ClientTransport::
|
|
659
|
-
Http2ContinuationFrame frame) {
|
|
611
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(
|
|
612
|
+
Http2ContinuationFrame&& frame) {
|
|
660
613
|
// https://www.rfc-editor.org/rfc/rfc9113.html#name-continuation
|
|
661
614
|
GRPC_HTTP2_CLIENT_DLOG
|
|
662
|
-
<< "Http2ClientTransport
|
|
615
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(ContinuationFrame) { "
|
|
663
616
|
"stream_id="
|
|
664
|
-
<< frame.stream_id << ", end_headers=" << frame.end_headers
|
|
665
|
-
<< ", payload=" << MaybeTruncatePayload(frame.payload) << " }";
|
|
617
|
+
<< frame.stream_id << ", end_headers=" << frame.end_headers << " }";
|
|
666
618
|
|
|
667
619
|
// State update MUST happen before processing the frame.
|
|
668
620
|
incoming_headers_.OnContinuationReceived(frame);
|
|
@@ -682,102 +634,102 @@ Http2Status Http2ClientTransport::ProcessHttp2ContinuationFrame(
|
|
|
682
634
|
|
|
683
635
|
if (stream->IsStreamHalfClosedRemote()) {
|
|
684
636
|
return ParseAndDiscardHeaders(
|
|
685
|
-
std::move(frame.payload), frame.end_headers, stream,
|
|
637
|
+
std::move(frame.payload), frame.end_headers, stream.get(),
|
|
686
638
|
Http2Status::Http2StreamError(
|
|
687
639
|
Http2ErrorCode::kStreamClosed,
|
|
688
640
|
std::string(RFC9113::kHalfClosedRemoteState)));
|
|
689
641
|
}
|
|
690
642
|
|
|
691
643
|
Http2Status append_result =
|
|
692
|
-
stream->
|
|
644
|
+
stream->GetHeaderAssembler().AppendContinuationFrame(frame);
|
|
693
645
|
if (!append_result.IsOk()) {
|
|
694
646
|
// Frame payload is not consumed if AppendContinuationFrame returns a
|
|
695
647
|
// non-OK status. We need to process it to keep our in consistent state.
|
|
696
648
|
return ParseAndDiscardHeaders(std::move(frame.payload), frame.end_headers,
|
|
697
|
-
stream, std::move(append_result));
|
|
649
|
+
stream.get(), std::move(append_result));
|
|
698
650
|
}
|
|
699
651
|
|
|
700
652
|
Http2Status status = ProcessMetadata(stream);
|
|
701
653
|
if (!status.IsOk()) {
|
|
702
654
|
// Frame payload is consumed by HeaderAssembler. So passing an empty
|
|
703
655
|
// SliceBuffer to ParseAndDiscardHeaders.
|
|
704
|
-
return ParseAndDiscardHeaders(SliceBuffer(), frame.end_headers,
|
|
705
|
-
std::move(status));
|
|
656
|
+
return ParseAndDiscardHeaders(SliceBuffer(), frame.end_headers,
|
|
657
|
+
stream.get(), std::move(status));
|
|
706
658
|
}
|
|
707
659
|
|
|
708
660
|
// Frame payload has either been processed or moved to the HeaderAssembler.
|
|
709
661
|
return Http2Status::Ok();
|
|
710
662
|
}
|
|
711
663
|
|
|
712
|
-
Http2Status Http2ClientTransport::
|
|
713
|
-
Http2SecurityFrame frame) {
|
|
714
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
715
|
-
|
|
716
|
-
<< frame.payload.Length() << " }";
|
|
664
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(
|
|
665
|
+
Http2SecurityFrame&& frame) {
|
|
666
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
667
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(SecurityFrame) ";
|
|
717
668
|
if (settings_->IsSecurityFrameExpected()) {
|
|
718
|
-
|
|
719
|
-
// Just the frame.payload needs to be passed to the endpoint_ object.
|
|
720
|
-
// Refer usage of TransportFramingEndpointExtension.
|
|
669
|
+
security_frame_handler_->ProcessPayload(std::move(frame.payload));
|
|
721
670
|
}
|
|
722
|
-
// Ignore the Security frame if it is not expected.
|
|
723
671
|
return Http2Status::Ok();
|
|
724
672
|
}
|
|
725
673
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
674
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(
|
|
675
|
+
GRPC_UNUSED Http2UnknownFrame&& frame) {
|
|
676
|
+
// RFC9113: Implementations MUST ignore and discard frames of
|
|
677
|
+
// unknown types.
|
|
678
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
679
|
+
<< "Http2ClientTransport::ProcessIncomingFrame(UnknownFrame) ";
|
|
680
|
+
return Http2Status::Ok();
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
Http2Status Http2ClientTransport::ProcessIncomingFrame(
|
|
684
|
+
GRPC_UNUSED Http2EmptyFrame&& frame) {
|
|
685
|
+
LOG(DFATAL) << "ParseFramePayload should never return a Http2EmptyFrame";
|
|
686
|
+
return Http2Status::Ok();
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
Http2Status Http2ClientTransport::ProcessMetadata(
|
|
690
|
+
RefCountedPtr<Stream> stream) {
|
|
691
|
+
HeaderAssembler& assembler = stream->GetHeaderAssembler();
|
|
692
|
+
CallHandler& call = stream->GetCallHandler();
|
|
693
|
+
|
|
694
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::ProcessMetadata";
|
|
695
|
+
if (assembler.IsReady()) {
|
|
696
|
+
ValueOrHttp2Status<ServerMetadataHandle> read_result =
|
|
697
|
+
assembler.ReadMetadata(parser_, !incoming_headers_.HeaderHasEndStream(),
|
|
698
|
+
/*max_header_list_size_soft_limit=*/
|
|
699
|
+
incoming_headers_.soft_limit(),
|
|
700
|
+
/*max_header_list_size_hard_limit=*/
|
|
701
|
+
settings_->acked().max_header_list_size());
|
|
702
|
+
if (read_result.IsOk()) {
|
|
703
|
+
ServerMetadataHandle metadata = TakeValue(std::move(read_result));
|
|
704
|
+
if (incoming_headers_.HeaderHasEndStream()) {
|
|
705
|
+
stream->MarkHalfClosedRemote();
|
|
706
|
+
stream->SetTrailingMetadataReceived();
|
|
707
|
+
BeginCloseStream(std::move(stream),
|
|
708
|
+
/*reset_stream_error_code=*/std::nullopt,
|
|
709
|
+
std::move(metadata));
|
|
710
|
+
} else {
|
|
711
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::ProcessMetadata "
|
|
712
|
+
"SpawnPushServerInitialMetadata";
|
|
713
|
+
metadata->Set(PeerString(), incoming_headers_.peer_string());
|
|
714
|
+
stream->SetInitialMetadataReceived();
|
|
715
|
+
call.SpawnPushServerInitialMetadata(std::move(metadata));
|
|
716
|
+
}
|
|
717
|
+
return Http2Status::Ok();
|
|
718
|
+
}
|
|
719
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::ProcessMetadata Failed";
|
|
720
|
+
return ValueOrHttp2Status<Arena::PoolPtr<grpc_metadata_batch>>::TakeStatus(
|
|
721
|
+
std::move(read_result));
|
|
722
|
+
}
|
|
723
|
+
return Http2Status::Ok();
|
|
770
724
|
}
|
|
771
725
|
|
|
772
726
|
Http2Status Http2ClientTransport::ParseAndDiscardHeaders(
|
|
773
|
-
SliceBuffer&& buffer, const bool is_end_headers,
|
|
774
|
-
|
|
775
|
-
DebugLocation whence) {
|
|
727
|
+
SliceBuffer&& buffer, const bool is_end_headers, Stream* stream,
|
|
728
|
+
Http2Status&& original_status, DebugLocation whence) {
|
|
776
729
|
const bool is_initial_metadata = !incoming_headers_.HeaderHasEndStream();
|
|
777
730
|
const uint32_t incoming_stream_id = incoming_headers_.GetStreamId();
|
|
778
731
|
GRPC_HTTP2_CLIENT_DLOG
|
|
779
|
-
<< "Http2ClientTransport
|
|
780
|
-
"size: "
|
|
732
|
+
<< "Http2ClientTransport::ParseAndDiscardHeaders buffer size: "
|
|
781
733
|
<< buffer.Length() << " is_initial_metadata: " << is_initial_metadata
|
|
782
734
|
<< " is_end_headers: " << is_end_headers
|
|
783
735
|
<< " incoming_stream_id: " << incoming_stream_id
|
|
@@ -790,7 +742,7 @@ Http2Status Http2ClientTransport::ParseAndDiscardHeaders(
|
|
|
790
742
|
HeaderAssembler::ParseHeaderArgs{
|
|
791
743
|
/*is_initial_metadata=*/is_initial_metadata,
|
|
792
744
|
/*is_end_headers=*/is_end_headers,
|
|
793
|
-
/*is_client=*/
|
|
745
|
+
/*is_client=*/kIsClient,
|
|
794
746
|
/*max_header_list_size_soft_limit=*/
|
|
795
747
|
incoming_headers_.soft_limit(),
|
|
796
748
|
/*max_header_list_size_hard_limit=*/
|
|
@@ -802,35 +754,9 @@ Http2Status Http2ClientTransport::ParseAndDiscardHeaders(
|
|
|
802
754
|
|
|
803
755
|
///////////////////////////////////////////////////////////////////////////////
|
|
804
756
|
// Read Related Promises and Promise Factories
|
|
805
|
-
auto Http2ClientTransport::EndpointReadSlice(const size_t num_bytes) {
|
|
806
|
-
return Map(
|
|
807
|
-
endpoint_.ReadSlice(num_bytes),
|
|
808
|
-
[self = RefAsSubclass<Http2ClientTransport>(),
|
|
809
|
-
num_bytes](absl::StatusOr<Slice> status) {
|
|
810
|
-
if (status.ok()) {
|
|
811
|
-
self->keepalive_manager_->GotData();
|
|
812
|
-
self->ztrace_collector_->Append(PromiseEndpointReadTrace{num_bytes});
|
|
813
|
-
}
|
|
814
|
-
return status;
|
|
815
|
-
});
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
auto Http2ClientTransport::EndpointRead(const size_t num_bytes) {
|
|
819
|
-
return Map(
|
|
820
|
-
endpoint_.Read(num_bytes),
|
|
821
|
-
[self = RefAsSubclass<Http2ClientTransport>(),
|
|
822
|
-
num_bytes](absl::StatusOr<SliceBuffer> status) {
|
|
823
|
-
if (status.ok()) {
|
|
824
|
-
self->keepalive_manager_->GotData();
|
|
825
|
-
self->ztrace_collector_->Append(PromiseEndpointReadTrace{num_bytes});
|
|
826
|
-
}
|
|
827
|
-
return status;
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
|
-
|
|
831
757
|
auto Http2ClientTransport::ReadAndProcessOneFrame() {
|
|
832
758
|
GRPC_HTTP2_CLIENT_DLOG
|
|
833
|
-
<< "Http2ClientTransport
|
|
759
|
+
<< "Http2ClientTransport::ReadAndProcessOneFrame Factory";
|
|
834
760
|
return AssertResultType<absl::Status>(TrySeq(
|
|
835
761
|
// Fetch the first kFrameHeaderSize bytes of the Frame, these contain
|
|
836
762
|
// the frame header.
|
|
@@ -838,136 +764,128 @@ auto Http2ClientTransport::ReadAndProcessOneFrame() {
|
|
|
838
764
|
// Parse the frame header.
|
|
839
765
|
[](Slice header_bytes) -> Http2FrameHeader {
|
|
840
766
|
GRPC_HTTP2_CLIENT_DLOG
|
|
841
|
-
<< "Http2ClientTransport
|
|
767
|
+
<< "Http2ClientTransport::ReadAndProcessOneFrame Parse "
|
|
842
768
|
<< header_bytes.as_string_view();
|
|
843
769
|
return Http2FrameHeader::Parse(header_bytes.begin());
|
|
844
770
|
},
|
|
845
771
|
// Validate the incoming frame as per the current state of the transport
|
|
846
|
-
[
|
|
772
|
+
[this](Http2FrameHeader header) {
|
|
847
773
|
Http2Status status = ValidateFrameHeader(
|
|
848
|
-
/*max_frame_size_setting*/
|
|
849
|
-
.max_frame_size(),
|
|
774
|
+
/*max_frame_size_setting*/ settings_->acked().max_frame_size(),
|
|
850
775
|
/*incoming_header_in_progress*/
|
|
851
|
-
|
|
776
|
+
incoming_headers_.IsWaitingForContinuationFrame(),
|
|
852
777
|
/*incoming_header_stream_id*/
|
|
853
|
-
|
|
778
|
+
incoming_headers_.GetStreamId(),
|
|
854
779
|
/*current_frame_header*/ header,
|
|
855
|
-
/*last_stream_id=*/
|
|
856
|
-
/*is_client=*/
|
|
857
|
-
|
|
780
|
+
/*last_stream_id=*/GetLastStreamId(),
|
|
781
|
+
/*is_client=*/kIsClient, /*is_first_settings_processed=*/
|
|
782
|
+
settings_->IsFirstPeerSettingsApplied());
|
|
858
783
|
|
|
859
784
|
if (GPR_UNLIKELY(!status.IsOk())) {
|
|
860
785
|
GRPC_DCHECK(status.GetType() ==
|
|
861
786
|
Http2Status::Http2ErrorType::kConnectionError);
|
|
862
|
-
return
|
|
787
|
+
return HandleError(std::nullopt, std::move(status));
|
|
863
788
|
}
|
|
864
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
789
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
790
|
+
<< "Http2ClientTransport::ReadAndProcessOneFrame "
|
|
791
|
+
"Validated Frame Header:"
|
|
792
|
+
<< header.ToString();
|
|
793
|
+
current_frame_header_ = header;
|
|
868
794
|
return absl::OkStatus();
|
|
869
795
|
},
|
|
870
796
|
// Read the payload of the frame.
|
|
871
|
-
[
|
|
797
|
+
[this]() {
|
|
872
798
|
GRPC_HTTP2_CLIENT_DLOG
|
|
873
|
-
<< "Http2ClientTransport
|
|
874
|
-
return AssertResultType<absl::StatusOr<SliceBuffer>>(
|
|
875
|
-
self->EndpointRead(self->current_frame_header_.length));
|
|
876
|
-
},
|
|
877
|
-
// Parse the payload of the frame based on frame type.
|
|
878
|
-
[self = RefAsSubclass<Http2ClientTransport>()](
|
|
879
|
-
SliceBuffer payload) -> absl::StatusOr<Http2Frame> {
|
|
880
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
881
|
-
<< "Http2ClientTransport ReadAndProcessOneFrame ParseFramePayload "
|
|
882
|
-
<< MaybeTruncatePayload(payload);
|
|
883
|
-
ValueOrHttp2Status<Http2Frame> frame =
|
|
884
|
-
ParseFramePayload(self->current_frame_header_, std::move(payload));
|
|
885
|
-
if (!frame.IsOk()) {
|
|
886
|
-
return self->HandleError(
|
|
887
|
-
self->current_frame_header_.stream_id,
|
|
888
|
-
ValueOrHttp2Status<Http2Frame>::TakeStatus(std::move(frame)));
|
|
889
|
-
}
|
|
890
|
-
return TakeValue(std::move(frame));
|
|
891
|
-
},
|
|
892
|
-
[self = RefAsSubclass<Http2ClientTransport>()](
|
|
893
|
-
GRPC_UNUSED Http2Frame frame) {
|
|
894
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
895
|
-
<< "Http2ClientTransport ReadAndProcessOneFrame ProcessOneFrame";
|
|
799
|
+
<< "Http2ClientTransport::ReadAndProcessOneFrame Read Frame ";
|
|
896
800
|
return AssertResultType<absl::Status>(Map(
|
|
897
|
-
|
|
898
|
-
[
|
|
899
|
-
if (!
|
|
900
|
-
return
|
|
901
|
-
|
|
801
|
+
EndpointRead(current_frame_header_.length),
|
|
802
|
+
[this](absl::StatusOr<SliceBuffer>&& payload) {
|
|
803
|
+
if (GPR_UNLIKELY(!payload.ok())) {
|
|
804
|
+
return payload.status();
|
|
805
|
+
}
|
|
806
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
807
|
+
<< "Http2ClientTransport::ReadAndProcessOneFrame "
|
|
808
|
+
"ParseFramePayload payload length: "
|
|
809
|
+
<< payload.value().Length();
|
|
810
|
+
ValueOrHttp2Status<Http2Frame> frame = ParseFramePayload(
|
|
811
|
+
current_frame_header_, TakeValue(std::move(payload)));
|
|
812
|
+
if (GPR_UNLIKELY(!frame.IsOk())) {
|
|
813
|
+
return HandleError(current_frame_header_.stream_id,
|
|
814
|
+
ValueOrHttp2Status<Http2Frame>::TakeStatus(
|
|
815
|
+
std::move(frame)));
|
|
816
|
+
}
|
|
817
|
+
Http2Status status =
|
|
818
|
+
ProcessOneIncomingFrame(TakeValue(std::move(frame)));
|
|
819
|
+
if (GPR_UNLIKELY(!status.IsOk())) {
|
|
820
|
+
return HandleError(current_frame_header_.stream_id,
|
|
821
|
+
std::move(status));
|
|
902
822
|
}
|
|
903
823
|
return absl::OkStatus();
|
|
904
824
|
}));
|
|
905
825
|
},
|
|
906
|
-
[
|
|
907
|
-
return
|
|
826
|
+
[this]() -> Poll<absl::Status> {
|
|
827
|
+
return reader_state_.MaybePauseReadLoop();
|
|
908
828
|
}));
|
|
909
829
|
}
|
|
910
830
|
|
|
911
831
|
auto Http2ClientTransport::ReadLoop() {
|
|
912
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
913
|
-
return AssertResultType<absl::Status>(
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
return Continue();
|
|
920
|
-
});
|
|
921
|
-
}));
|
|
832
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::ReadLoop Factory";
|
|
833
|
+
return AssertResultType<absl::Status>(Loop([this]() {
|
|
834
|
+
return TrySeq(ReadAndProcessOneFrame(), []() -> LoopCtl<absl::Status> {
|
|
835
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::ReadLoop Continue";
|
|
836
|
+
return Continue();
|
|
837
|
+
});
|
|
838
|
+
}));
|
|
922
839
|
}
|
|
923
840
|
|
|
924
841
|
///////////////////////////////////////////////////////////////////////////////
|
|
925
842
|
// Flow Control for the Transport
|
|
926
843
|
|
|
927
844
|
auto Http2ClientTransport::FlowControlPeriodicUpdateLoop() {
|
|
928
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
845
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
846
|
+
<< "Http2ClientTransport::FlowControlPeriodicUpdateLoop Factory";
|
|
929
847
|
return AssertResultType<absl::Status>(
|
|
930
|
-
Loop([
|
|
848
|
+
Loop([this]() {
|
|
931
849
|
GRPC_HTTP2_CLIENT_DLOG
|
|
932
|
-
<< "Http2ClientTransport
|
|
850
|
+
<< "Http2ClientTransport::FlowControlPeriodicUpdateLoop Loop";
|
|
933
851
|
return TrySeq(
|
|
934
852
|
// TODO(tjagtap) [PH2][P2][BDP] Remove this static sleep when the
|
|
935
853
|
// BDP code is done.
|
|
936
854
|
Sleep(chttp2::kFlowControlPeriodicUpdateTimer),
|
|
937
|
-
[
|
|
855
|
+
[this]() -> Poll<absl::Status> {
|
|
938
856
|
GRPC_HTTP2_CLIENT_DLOG
|
|
939
|
-
<< "Http2ClientTransport
|
|
940
|
-
|
|
941
|
-
|
|
857
|
+
<< "Http2ClientTransport::FlowControlPeriodicUpdateLoop "
|
|
858
|
+
"PeriodicUpdate()";
|
|
859
|
+
chttp2::FlowControlAction action = flow_control_.PeriodicUpdate();
|
|
942
860
|
bool is_action_empty = action == chttp2::FlowControlAction();
|
|
943
861
|
// This may trigger a write cycle
|
|
944
|
-
|
|
862
|
+
ActOnFlowControlAction(action, nullptr);
|
|
945
863
|
if (is_action_empty) {
|
|
946
864
|
// TODO(tjagtap) [PH2][P2][BDP] Remove this when the BDP code is
|
|
947
865
|
// done. We must continue to do PeriodicUpdate once BDP is in
|
|
948
866
|
// place.
|
|
949
|
-
MutexLock lock(&
|
|
950
|
-
if (
|
|
951
|
-
|
|
867
|
+
MutexLock lock(&transport_mutex_);
|
|
868
|
+
if (GetActiveStreamCountLocked() == 0) {
|
|
869
|
+
AddPeriodicUpdatePromiseWaker();
|
|
952
870
|
return Pending{};
|
|
953
871
|
}
|
|
954
872
|
}
|
|
955
873
|
return absl::OkStatus();
|
|
956
874
|
},
|
|
957
|
-
[
|
|
875
|
+
[]() -> LoopCtl<absl::Status> { return Continue{}; });
|
|
958
876
|
}));
|
|
959
877
|
}
|
|
960
878
|
|
|
961
879
|
// Equivalent to grpc_chttp2_act_on_flowctl_action in chttp2_transport.cc
|
|
962
880
|
void Http2ClientTransport::ActOnFlowControlAction(
|
|
963
|
-
const chttp2::FlowControlAction& action,
|
|
881
|
+
const chttp2::FlowControlAction& action, Stream* stream) {
|
|
964
882
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::ActOnFlowControlAction"
|
|
965
883
|
<< action.DebugString();
|
|
966
884
|
if (action.send_stream_update() != kNoActionNeeded) {
|
|
967
885
|
if (GPR_LIKELY(stream != nullptr)) {
|
|
968
886
|
GRPC_DCHECK_GT(stream->GetStreamId(), 0u);
|
|
969
887
|
if (stream->CanSendWindowUpdateFrames()) {
|
|
970
|
-
|
|
888
|
+
flow_control_.AddStreamToWindowUpdateList(stream->GetStreamId());
|
|
971
889
|
GRPC_HTTP2_CLIENT_DLOG
|
|
972
890
|
<< "Http2ClientTransport::ActOnFlowControlAction "
|
|
973
891
|
"added stream "
|
|
@@ -990,7 +908,10 @@ void Http2ClientTransport::ActOnFlowControlAction(
|
|
|
990
908
|
// updates to the peer, causing the peer to block unnecessarily while
|
|
991
909
|
// waiting for flow control tokens.
|
|
992
910
|
reader_state_.SetPauseReadLoop();
|
|
993
|
-
|
|
911
|
+
if (!TriggerWriteCycleOrHandleError()) {
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
|
|
994
915
|
GRPC_HTTP2_CLIENT_DLOG << "Update Immediately : "
|
|
995
916
|
<< action.ImmediateUpdateReasons();
|
|
996
917
|
}
|
|
@@ -998,18 +919,34 @@ void Http2ClientTransport::ActOnFlowControlAction(
|
|
|
998
919
|
|
|
999
920
|
///////////////////////////////////////////////////////////////////////////////
|
|
1000
921
|
// Write Related Promises and Promise Factories
|
|
922
|
+
auto Http2ClientTransport::EndpointWrite(SliceBuffer&& output_buf) {
|
|
923
|
+
size_t output_buf_length = output_buf.Length();
|
|
924
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::EndpointWrite output_buf: "
|
|
925
|
+
<< output_buf_length;
|
|
1001
926
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
927
|
+
transport_write_context_.GetWriteCycle().BeginWrite(output_buf_length);
|
|
928
|
+
return Map(
|
|
929
|
+
endpoint_.Write(std::forward<SliceBuffer>(output_buf),
|
|
930
|
+
TransportWriteContext::GetWriteArgs(settings_->peer())),
|
|
931
|
+
[this](absl::Status status) {
|
|
932
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
933
|
+
<< "Http2ClientTransport::EndpointWrite complete with status = "
|
|
934
|
+
<< status;
|
|
935
|
+
transport_write_context_.GetWriteCycle().EndWrite(status.ok());
|
|
936
|
+
return status;
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
absl::Status Http2ClientTransport::PrepareControlFrames() {
|
|
941
|
+
FrameSender frame_sender =
|
|
942
|
+
transport_write_context_.GetWriteCycle().GetFrameSender();
|
|
943
|
+
if (transport_write_context_.IsFirstWrite()) {
|
|
1005
944
|
// RFC9113: That is, the connection preface starts with the string
|
|
1006
|
-
// "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
|
|
1007
|
-
//
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
Slice::FromCopiedString(GRPC_CHTTP2_CLIENT_CONNECT_STRING));
|
|
1012
|
-
settings_->MaybeGetSettingsAndSettingsAckFrames(flow_control_, output_buf);
|
|
945
|
+
// "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n". This connection preface string will
|
|
946
|
+
// be sent as part of the first write cycle. This sequence MUST be followed
|
|
947
|
+
// by a SETTINGS frame, which MAY be empty.
|
|
948
|
+
settings_->MaybeGetSettingsAndSettingsAckFrames(flow_control_,
|
|
949
|
+
frame_sender);
|
|
1013
950
|
// TODO(tjagtap) [PH2][P2][Server] : This will be opposite for server. We
|
|
1014
951
|
// must read before we write for the server. So the ReadLoop will be Spawned
|
|
1015
952
|
// just after the constructor, and the write loop should be spawned only
|
|
@@ -1018,7 +955,6 @@ auto Http2ClientTransport::ProcessAndWriteControlFrames() {
|
|
|
1018
955
|
// Because the client is expected to write before it reads, we spawn the
|
|
1019
956
|
// ReadLoop of the client only after the first write is queued.
|
|
1020
957
|
SpawnGuardedTransportParty("ReadLoop", UntilTransportClosed(ReadLoop()));
|
|
1021
|
-
is_first_write_ = false;
|
|
1022
958
|
}
|
|
1023
959
|
|
|
1024
960
|
// Order of Control Frames is important.
|
|
@@ -1029,86 +965,105 @@ auto Http2ClientTransport::ProcessAndWriteControlFrames() {
|
|
|
1029
965
|
// 4. WINDOW_UPDATE
|
|
1030
966
|
// 5. Custom gRPC security frame
|
|
1031
967
|
|
|
1032
|
-
goaway_manager_.MaybeGetSerializedGoawayFrame(
|
|
968
|
+
goaway_manager_.MaybeGetSerializedGoawayFrame(frame_sender);
|
|
969
|
+
bool should_spawn_security_frame_loop = false;
|
|
1033
970
|
http2::Http2ErrorCode apply_status =
|
|
1034
|
-
settings_->MaybeReportAndApplyBufferedPeerSettings(
|
|
971
|
+
settings_->MaybeReportAndApplyBufferedPeerSettings(
|
|
972
|
+
event_engine_.get(), should_spawn_security_frame_loop);
|
|
973
|
+
if (should_spawn_security_frame_loop) {
|
|
974
|
+
const SecurityFrameHandler::EndpointExtensionState state =
|
|
975
|
+
security_frame_handler_->Initialize(event_engine_);
|
|
976
|
+
if (state.is_set) {
|
|
977
|
+
SpawnInfallibleTransportParty("SecurityFrameLoop",
|
|
978
|
+
UntilTransportClosed(SecurityFrameLoop()));
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
1035
982
|
if (!goaway_manager_.IsImmediateGoAway() &&
|
|
1036
983
|
apply_status == http2::Http2ErrorCode::kNoError) {
|
|
1037
984
|
EnforceLatestIncomingSettings();
|
|
1038
|
-
settings_->MaybeGetSettingsAndSettingsAckFrames(flow_control_,
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
985
|
+
settings_->MaybeGetSettingsAndSettingsAckFrames(flow_control_,
|
|
986
|
+
frame_sender);
|
|
987
|
+
MaybeSpawnDelayedPing(ping_manager_->MaybeGetSerializedPingFrames(
|
|
988
|
+
frame_sender, NextAllowedPingInterval()));
|
|
989
|
+
MaybeGetWindowUpdateFrames(frame_sender);
|
|
990
|
+
security_frame_handler_->MaybeAppendSecurityFrame(frame_sender);
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
if (apply_status != http2::Http2ErrorCode::kNoError) {
|
|
994
|
+
return HandleError(std::nullopt,
|
|
995
|
+
Http2Status::Http2ConnectionError(
|
|
996
|
+
apply_status, "Failed to apply incoming settings"));
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
return absl::OkStatus();
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
auto Http2ClientTransport::MaybeWriteUrgentFrames() {
|
|
1003
|
+
return AssertResultType<absl::Status>(If(
|
|
1004
|
+
transport_write_context_.GetWriteCycle().CanSerializeUrgentFrames(),
|
|
1005
|
+
[this]() mutable {
|
|
1006
|
+
WriteCycle& write_cycle = transport_write_context_.GetWriteCycle();
|
|
1007
|
+
const uint64_t buffer_length = write_cycle.GetUrgentFrameCount();
|
|
1008
|
+
ztrace_collector_->Append(PromiseEndpointWriteTrace{buffer_length});
|
|
1009
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
1010
|
+
<< "Http2ClientTransport::MaybeWriteUrgentFrames frame count: "
|
|
1011
|
+
<< buffer_length;
|
|
1012
|
+
return EndpointWrite(write_cycle.SerializeUrgentFrames(
|
|
1013
|
+
WriteCycle::SerializeStats{should_reset_ping_clock_}));
|
|
1014
|
+
},
|
|
1015
|
+
[]() { return absl::OkStatus(); }));
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
void Http2ClientTransport::NotifyFramesWriteDone() {
|
|
1066
1019
|
// Notify Control modules that we have sent the frames.
|
|
1067
1020
|
// All notifications are expected to be synchronous.
|
|
1068
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1021
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::NotifyFramesWriteDone";
|
|
1069
1022
|
reader_state_.ResumeReadLoopIfPaused();
|
|
1070
|
-
ping_manager_->NotifyPingSent();
|
|
1023
|
+
MaybeSpawnPingTimeout(ping_manager_->NotifyPingSent());
|
|
1071
1024
|
goaway_manager_.NotifyGoawaySent();
|
|
1072
1025
|
MaybeSpawnWaitForSettingsTimeout();
|
|
1073
1026
|
}
|
|
1074
1027
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
Serialize(absl::Span<Http2Frame>(frames), output_buf)
|
|
1079
|
-
.should_reset_ping_clock;
|
|
1080
|
-
size_t output_buf_length = output_buf.Length();
|
|
1081
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport SerializeAndWrite Write "
|
|
1082
|
-
"output_buf.length() = "
|
|
1083
|
-
<< output_buf_length;
|
|
1028
|
+
void Http2ClientTransport::NotifyUrgentFramesWriteDone() {}
|
|
1029
|
+
|
|
1030
|
+
auto Http2ClientTransport::SerializeAndWrite() {
|
|
1084
1031
|
return AssertResultType<absl::Status>(If(
|
|
1085
|
-
|
|
1086
|
-
[
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1032
|
+
transport_write_context_.GetWriteCycle().CanSerializeRegularFrames(),
|
|
1033
|
+
[this]() mutable {
|
|
1034
|
+
WriteCycle& write_cycle = transport_write_context_.GetWriteCycle();
|
|
1035
|
+
const uint64_t frame_count = write_cycle.GetRegularFrameCount();
|
|
1036
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
1037
|
+
<< "Http2ClientTransport::SerializeAndWrite frame count: "
|
|
1038
|
+
<< frame_count;
|
|
1039
|
+
ztrace_collector_->Append(PromiseEndpointWriteTrace{frame_count});
|
|
1040
|
+
return EndpointWrite(write_cycle.SerializeRegularFrames(
|
|
1041
|
+
WriteCycle::SerializeStats{should_reset_ping_clock_}));
|
|
1090
1042
|
},
|
|
1091
1043
|
[]() { return absl::OkStatus(); }));
|
|
1092
1044
|
}
|
|
1093
1045
|
|
|
1094
|
-
absl::
|
|
1095
|
-
|
|
1046
|
+
absl::Status Http2ClientTransport::DequeueStreamFrames(
|
|
1047
|
+
RefCountedPtr<Stream> stream, WriteCycle& write_cycle) {
|
|
1096
1048
|
// write_bytes_remaining_ is passed as an upper bound on the max
|
|
1097
1049
|
// number of tokens that can be dequeued to prevent dequeuing huge
|
|
1098
1050
|
// data frames when write_bytes_remaining_ is very low. As the
|
|
1099
1051
|
// available transport tokens can only range from 0 to 2^31 - 1,
|
|
1100
1052
|
// we are clamping the write_bytes_remaining_ to that range.
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1053
|
+
FrameSender frame_sender = write_cycle.GetFrameSender();
|
|
1054
|
+
const uint32_t tokens = GetMaxPermittedDequeue(
|
|
1055
|
+
flow_control_, stream->GetStreamFlowControl(),
|
|
1056
|
+
write_cycle.GetWriteBytesRemaining(), settings_->peer());
|
|
1057
|
+
const uint32_t stream_flow_control_tokens =
|
|
1058
|
+
static_cast<uint32_t>(GetStreamFlowControlTokens(
|
|
1059
|
+
stream->GetStreamFlowControl(), settings_->peer()));
|
|
1060
|
+
stream->GetStreamFlowControl().ReportIfStalled(
|
|
1061
|
+
/*is_client=*/kIsClient, stream->GetStreamId(), settings_->peer());
|
|
1108
1062
|
StreamDataQueue<ClientMetadataHandle>::DequeueResult result =
|
|
1109
1063
|
stream->DequeueFrames(tokens, stream_flow_control_tokens,
|
|
1110
|
-
settings_->peer().max_frame_size(), encoder_
|
|
1111
|
-
|
|
1064
|
+
settings_->peer().max_frame_size(), encoder_,
|
|
1065
|
+
frame_sender);
|
|
1066
|
+
ProcessOutgoingDataFrameFlowControl(stream->GetStreamFlowControl(),
|
|
1112
1067
|
result.flow_control_tokens_consumed);
|
|
1113
1068
|
if (result.is_writable) {
|
|
1114
1069
|
// Stream is still writable. Enqueue it back to the writable
|
|
@@ -1118,7 +1073,7 @@ Http2ClientTransport::DequeueStreamFrames(RefCountedPtr<Stream> stream) {
|
|
|
1118
1073
|
|
|
1119
1074
|
if (GPR_UNLIKELY(!status.ok())) {
|
|
1120
1075
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1121
|
-
<< "Http2ClientTransport
|
|
1076
|
+
<< "Http2ClientTransport::DequeueStreamFrames Failed to "
|
|
1122
1077
|
"enqueue stream "
|
|
1123
1078
|
<< stream->GetStreamId() << " with status: " << status;
|
|
1124
1079
|
// Close transport if we fail to enqueue stream.
|
|
@@ -1134,9 +1089,9 @@ Http2ClientTransport::DequeueStreamFrames(RefCountedPtr<Stream> stream) {
|
|
|
1134
1089
|
// multiplexer loop as the stream will never be writable again. Additionally,
|
|
1135
1090
|
// the other two stream refs, CallHandler OnDone and OutboundLoop will be
|
|
1136
1091
|
// dropped by Callv3 triggering cleaning up the stream object.
|
|
1137
|
-
if (result.
|
|
1092
|
+
if (result.IsInitialMetadataDequeued()) {
|
|
1138
1093
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1139
|
-
<< "Http2ClientTransport
|
|
1094
|
+
<< "Http2ClientTransport::DequeueStreamFrames InitialMetadataDequeued "
|
|
1140
1095
|
"stream_id = "
|
|
1141
1096
|
<< stream->GetStreamId();
|
|
1142
1097
|
stream->SentInitialMetadata();
|
|
@@ -1144,178 +1099,170 @@ Http2ClientTransport::DequeueStreamFrames(RefCountedPtr<Stream> stream) {
|
|
|
1144
1099
|
AddToStreamList(stream);
|
|
1145
1100
|
}
|
|
1146
1101
|
|
|
1147
|
-
if (result.
|
|
1148
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
<< stream->GetStreamId();
|
|
1102
|
+
if (result.IsHalfCloseDequeued()) {
|
|
1103
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::DequeueStreamFrames "
|
|
1104
|
+
"HalfCloseDequeued stream_id = "
|
|
1105
|
+
<< stream->GetStreamId();
|
|
1152
1106
|
stream->MarkHalfClosedLocal();
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1107
|
+
|
|
1108
|
+
if (stream->IsTrailingMetadataReceived()) {
|
|
1109
|
+
CloseStream(*stream, CloseStreamArgs{/*close_reads=*/true,
|
|
1110
|
+
/*close_writes=*/true});
|
|
1111
|
+
}
|
|
1157
1112
|
}
|
|
1158
|
-
if (result.
|
|
1113
|
+
if (result.IsResetStreamDequeued()) {
|
|
1159
1114
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1160
|
-
<< "Http2ClientTransport
|
|
1115
|
+
<< "Http2ClientTransport::DequeueStreamFrames ResetStreamDequeued "
|
|
1161
1116
|
"stream_id = "
|
|
1162
1117
|
<< stream->GetStreamId();
|
|
1163
1118
|
stream->MarkHalfClosedLocal();
|
|
1164
|
-
CloseStream(stream, CloseStreamArgs{/*close_reads=*/true,
|
|
1165
|
-
|
|
1119
|
+
CloseStream(*stream, CloseStreamArgs{/*close_reads=*/true,
|
|
1120
|
+
/*close_writes=*/true});
|
|
1166
1121
|
}
|
|
1167
1122
|
|
|
1168
1123
|
// Update the write_bytes_remaining_ based on the bytes consumed
|
|
1169
1124
|
// in the current dequeue.
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
<< write_bytes_remaining_ << " total_bytes_consumed = "
|
|
1177
|
-
<< result.total_bytes_consumed
|
|
1125
|
+
// Note: We do tend to overestimate the bytes consumed here. This may result
|
|
1126
|
+
// in sending less data than target_write_size_.
|
|
1127
|
+
|
|
1128
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::DequeueStreamFrames "
|
|
1129
|
+
"After dequeue: "
|
|
1130
|
+
<< write_cycle.DebugString()
|
|
1178
1131
|
<< " stream_id = " << stream->GetStreamId()
|
|
1179
1132
|
<< " is_writable = " << result.is_writable
|
|
1180
1133
|
<< " stream_priority = "
|
|
1181
|
-
<< static_cast<uint8_t>(result.priority)
|
|
1182
|
-
|
|
1183
|
-
return std::move(result.frames);
|
|
1134
|
+
<< static_cast<uint8_t>(result.priority);
|
|
1135
|
+
return absl::OkStatus();
|
|
1184
1136
|
}
|
|
1185
1137
|
|
|
1186
1138
|
// This MultiplexerLoop promise is responsible for Multiplexing multiple gRPC
|
|
1187
1139
|
// Requests (HTTP2 Streams) and writing them into one common endpoint.
|
|
1188
1140
|
auto Http2ClientTransport::MultiplexerLoop() {
|
|
1189
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1190
|
-
return AssertResultType<
|
|
1191
|
-
absl::Status>(Loop([self = RefAsSubclass<Http2ClientTransport>()]() {
|
|
1192
|
-
self->write_bytes_remaining_ = self->GetMaxWriteSize();
|
|
1193
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport MultiplexerLoop "
|
|
1194
|
-
<< " max_write_size_=" << self->GetMaxWriteSize();
|
|
1141
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::MultiplexerLoop Factory";
|
|
1142
|
+
return AssertResultType<absl::Status>(Loop([this]() {
|
|
1195
1143
|
return TrySeq(
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
}
|
|
1213
|
-
self->NotifyControlFramesWriteDone();
|
|
1214
|
-
return absl::OkStatus();
|
|
1215
|
-
});
|
|
1216
|
-
},
|
|
1217
|
-
[self]() -> absl::StatusOr<std::vector<Http2Frame>> {
|
|
1218
|
-
std::vector<Http2Frame> frames;
|
|
1219
|
-
// Drain all the writable streams till we have written
|
|
1220
|
-
// max_write_size_ bytes of data or there is no more data to send. In
|
|
1221
|
-
// some cases, we may write more than max_write_size_ bytes(like
|
|
1222
|
-
// writing metadata).
|
|
1223
|
-
while (self->write_bytes_remaining_ > 0) {
|
|
1224
|
-
std::optional<RefCountedPtr<Stream>> optional_stream =
|
|
1225
|
-
self->writable_stream_list_.ImmediateNext(
|
|
1226
|
-
self->AreTransportFlowControlTokensAvailable());
|
|
1227
|
-
if (!optional_stream.has_value()) {
|
|
1228
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
1229
|
-
<< "Http2ClientTransport MultiplexerLoop "
|
|
1230
|
-
"No writable streams available, write_bytes_remaining_ = "
|
|
1231
|
-
<< self->write_bytes_remaining_;
|
|
1232
|
-
break;
|
|
1144
|
+
Map(writable_stream_list_.WaitForReady(
|
|
1145
|
+
AreTransportFlowControlTokensAvailable()),
|
|
1146
|
+
[this](absl::StatusOr<Empty> status) -> absl::Status {
|
|
1147
|
+
if (GPR_UNLIKELY(!status.ok())) {
|
|
1148
|
+
return status.status();
|
|
1149
|
+
}
|
|
1150
|
+
transport_write_context_.StartWriteCycle();
|
|
1151
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::MultiplexerLoop "
|
|
1152
|
+
"Created WriteCycle: "
|
|
1153
|
+
<< transport_write_context_.DebugString();
|
|
1154
|
+
return PrepareControlFrames();
|
|
1155
|
+
}),
|
|
1156
|
+
[this] {
|
|
1157
|
+
return Map(MaybeWriteUrgentFrames(), [this](absl::Status status) {
|
|
1158
|
+
if (GPR_UNLIKELY(!status.ok())) {
|
|
1159
|
+
return status;
|
|
1233
1160
|
}
|
|
1234
|
-
|
|
1161
|
+
NotifyUrgentFramesWriteDone();
|
|
1162
|
+
WriteCycle& write_cycle = transport_write_context_.GetWriteCycle();
|
|
1235
1163
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1236
|
-
<< "Http2ClientTransport
|
|
1237
|
-
|
|
1238
|
-
<<
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
if (!
|
|
1164
|
+
<< "Http2ClientTransport::MultiplexerLoop "
|
|
1165
|
+
<< "Starting to iterate over writable stream list "
|
|
1166
|
+
<< write_cycle.DebugString();
|
|
1167
|
+
// Drain all the writable streams till we have written
|
|
1168
|
+
// max_write_size_ bytes of data or there is no more data to send.
|
|
1169
|
+
// In some cases, we may write more than max_write_size_ bytes(like
|
|
1170
|
+
// writing metadata).
|
|
1171
|
+
while (write_cycle.GetWriteBytesRemaining() > 0) {
|
|
1172
|
+
std::optional<RefCountedPtr<Stream>> optional_stream =
|
|
1173
|
+
writable_stream_list_.ImmediateNext(
|
|
1174
|
+
AreTransportFlowControlTokensAvailable());
|
|
1175
|
+
if (!optional_stream.has_value()) {
|
|
1248
1176
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1249
|
-
<< "Http2ClientTransport
|
|
1250
|
-
"
|
|
1251
|
-
|
|
1252
|
-
<< stream.get() << " closing this stream.";
|
|
1253
|
-
self->BeginCloseStream(
|
|
1254
|
-
stream, /*reset_stream_error_code=*/std::nullopt,
|
|
1255
|
-
CancelledServerMetadataFromStatus(status));
|
|
1256
|
-
continue;
|
|
1177
|
+
<< "Http2ClientTransport::MultiplexerLoop "
|
|
1178
|
+
"No writable streams available ";
|
|
1179
|
+
break;
|
|
1257
1180
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1181
|
+
RefCountedPtr<Stream> stream = std::move(optional_stream.value());
|
|
1182
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
1183
|
+
<< "Http2ClientTransport::MultiplexerLoop "
|
|
1184
|
+
"Next writable stream id = "
|
|
1185
|
+
<< stream->GetStreamId()
|
|
1186
|
+
<< " is_closed_for_writes = " << stream->IsClosedForWrites();
|
|
1187
|
+
|
|
1188
|
+
if (stream->GetStreamId() == kInvalidStreamId) {
|
|
1189
|
+
GRPC_DCHECK(stream->IsStreamIdle());
|
|
1190
|
+
// TODO(akshitpatel) : [PH2][P5] : We will waste a stream id in
|
|
1191
|
+
// the rare scenario where the stream is aborted before it can
|
|
1192
|
+
// be written to. This is a possible area to optimize in future.
|
|
1193
|
+
absl::Status status = InitializeStream(*stream);
|
|
1194
|
+
if (!status.ok()) {
|
|
1195
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
1196
|
+
<< "Http2ClientTransport::MultiplexerLoop "
|
|
1197
|
+
"Failed to assign stream id and add to stream list for"
|
|
1198
|
+
" stream: "
|
|
1199
|
+
<< stream.get() << " closing this stream.";
|
|
1200
|
+
BeginCloseStream(std::move(stream),
|
|
1201
|
+
/*reset_stream_error_code=*/std::nullopt,
|
|
1202
|
+
CancelledServerMetadataFromStatus(status));
|
|
1203
|
+
continue;
|
|
1204
|
+
}
|
|
1269
1205
|
}
|
|
1270
1206
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1207
|
+
if (GPR_LIKELY(!stream->IsClosedForWrites())) {
|
|
1208
|
+
absl::Status status = DequeueStreamFrames(
|
|
1209
|
+
std::move(stream),
|
|
1210
|
+
transport_write_context_.GetWriteCycle());
|
|
1211
|
+
if (GPR_UNLIKELY(!status.ok())) {
|
|
1212
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
1213
|
+
<< "Http2ClientTransport::MultiplexerLoop "
|
|
1214
|
+
"Failed to dequeue stream frames with status: "
|
|
1215
|
+
<< status;
|
|
1216
|
+
return status;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1276
1219
|
}
|
|
1277
|
-
}
|
|
1278
1220
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
<< self->write_bytes_remaining_;
|
|
1221
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::MultiplexerLoop "
|
|
1222
|
+
"After draining all writable streams "
|
|
1223
|
+
<< write_cycle.DebugString();
|
|
1283
1224
|
|
|
1284
|
-
|
|
1225
|
+
return absl::OkStatus();
|
|
1226
|
+
});
|
|
1285
1227
|
},
|
|
1286
|
-
[
|
|
1287
|
-
return
|
|
1228
|
+
[this]() {
|
|
1229
|
+
return Map(SerializeAndWrite(), [this](absl::Status status) {
|
|
1230
|
+
if (GPR_UNLIKELY(!status.ok())) {
|
|
1231
|
+
return status;
|
|
1232
|
+
}
|
|
1233
|
+
NotifyFramesWriteDone();
|
|
1234
|
+
return absl::OkStatus();
|
|
1235
|
+
});
|
|
1288
1236
|
},
|
|
1289
|
-
[
|
|
1290
|
-
if (
|
|
1237
|
+
[this]() -> LoopCtl<absl::Status> {
|
|
1238
|
+
if (should_reset_ping_clock_) {
|
|
1291
1239
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1292
|
-
<< "Http2ClientTransport
|
|
1293
|
-
|
|
1294
|
-
|
|
1240
|
+
<< "Http2ClientTransport::MultiplexerLoop ResetPingClock";
|
|
1241
|
+
ping_manager_->ResetPingClock(/*is_client=*/kIsClient);
|
|
1242
|
+
should_reset_ping_clock_ = false;
|
|
1295
1243
|
}
|
|
1244
|
+
transport_write_context_.EndWriteCycle();
|
|
1296
1245
|
return Continue();
|
|
1297
1246
|
});
|
|
1298
1247
|
}));
|
|
1299
1248
|
}
|
|
1300
1249
|
|
|
1301
|
-
absl::Status Http2ClientTransport::InitializeStream(
|
|
1302
|
-
RefCountedPtr<Stream> stream) {
|
|
1250
|
+
absl::Status Http2ClientTransport::InitializeStream(Stream& stream) {
|
|
1303
1251
|
absl::StatusOr<uint32_t> next_stream_id = NextStreamId();
|
|
1304
1252
|
if (!next_stream_id.ok()) {
|
|
1305
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1253
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::InitializeStream "
|
|
1306
1254
|
"Failed to get next stream id for stream: "
|
|
1307
|
-
<< stream
|
|
1255
|
+
<< &stream;
|
|
1308
1256
|
return std::move(next_stream_id).status();
|
|
1309
1257
|
}
|
|
1310
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1258
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::InitializeStream "
|
|
1311
1259
|
"Assigned stream id: "
|
|
1312
|
-
<< next_stream_id.value()
|
|
1313
|
-
<< " to stream: " << stream.get()
|
|
1260
|
+
<< next_stream_id.value() << " to stream: " << &stream
|
|
1314
1261
|
<< ", allow_true_binary_metadata:"
|
|
1315
1262
|
<< settings_->peer().allow_true_binary_metadata();
|
|
1316
|
-
stream
|
|
1317
|
-
|
|
1318
|
-
|
|
1263
|
+
stream.InitializeStream(next_stream_id.value(),
|
|
1264
|
+
settings_->peer().allow_true_binary_metadata(),
|
|
1265
|
+
settings_->acked().allow_true_binary_metadata());
|
|
1319
1266
|
return absl::OkStatus();
|
|
1320
1267
|
}
|
|
1321
1268
|
|
|
@@ -1326,9 +1273,10 @@ void Http2ClientTransport::AddToStreamList(RefCountedPtr<Stream> stream) {
|
|
|
1326
1273
|
GRPC_DCHECK(stream != nullptr) << "stream is null";
|
|
1327
1274
|
GRPC_DCHECK_GT(stream->GetStreamId(), 0u) << "stream id is invalid";
|
|
1328
1275
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1329
|
-
<< "Http2ClientTransport
|
|
1276
|
+
<< "Http2ClientTransport::AddToStreamList for stream id: "
|
|
1330
1277
|
<< stream->GetStreamId();
|
|
1331
|
-
|
|
1278
|
+
const uint32_t stream_id = stream->GetStreamId();
|
|
1279
|
+
stream_list_.emplace(stream_id, std::move(stream));
|
|
1332
1280
|
// TODO(tjagtap) [PH2][P2][BDP] Remove this when the BDP code is done.
|
|
1333
1281
|
if (GetActiveStreamCountLocked() == 1) {
|
|
1334
1282
|
should_wake_periodic_updates = true;
|
|
@@ -1363,36 +1311,22 @@ void Http2ClientTransport::MaybeSpawnWaitForSettingsTimeout() {
|
|
|
1363
1311
|
if (settings_->ShouldSpawnWaitForSettingsTimeout()) {
|
|
1364
1312
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1365
1313
|
<< "Http2ClientTransport::MaybeSpawnWaitForSettingsTimeout Spawning";
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1314
|
+
SpawnWithOnDoneTransportParty("WaitForSettingsTimeout",
|
|
1315
|
+
settings_->WaitForSettingsTimeout(),
|
|
1316
|
+
WaitForSettingsTimeoutOnDone());
|
|
1369
1317
|
}
|
|
1370
1318
|
}
|
|
1371
1319
|
|
|
1372
|
-
void Http2ClientTransport::MaybeGetWindowUpdateFrames(
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
1379
|
-
<< "Http2ClientTransport::MaybeGetWindowUpdateFrames Transport Window "
|
|
1380
|
-
"Update : "
|
|
1381
|
-
<< window_size;
|
|
1382
|
-
frames.emplace_back(Http2WindowUpdateFrame{/*stream_id=*/0, window_size});
|
|
1383
|
-
flow_control_.SentUpdate(window_size);
|
|
1384
|
-
}
|
|
1385
|
-
for (const uint32_t stream_id : window_update_list_) {
|
|
1320
|
+
void Http2ClientTransport::MaybeGetWindowUpdateFrames(
|
|
1321
|
+
FrameSender& frame_sender) {
|
|
1322
|
+
frame_sender.ReserveRegularFrames(flow_control_.window_update_list_size() +
|
|
1323
|
+
1);
|
|
1324
|
+
MaybeAddTransportWindowUpdateFrame(flow_control_, frame_sender);
|
|
1325
|
+
for (const uint32_t stream_id : flow_control_.DrainWindowUpdateList()) {
|
|
1386
1326
|
RefCountedPtr<Stream> stream = LookupStream(stream_id);
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
if (!frames.empty()) {
|
|
1391
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
1392
|
-
<< "Http2ClientTransport::MaybeGetWindowUpdateFrames Total Window "
|
|
1393
|
-
"Update Frames : "
|
|
1394
|
-
<< frames.size();
|
|
1395
|
-
Serialize(absl::Span<Http2Frame>(frames), output_buf);
|
|
1327
|
+
if (stream != nullptr) {
|
|
1328
|
+
MaybeAddStreamWindowUpdateFrame(*stream, frame_sender);
|
|
1329
|
+
}
|
|
1396
1330
|
}
|
|
1397
1331
|
}
|
|
1398
1332
|
|
|
@@ -1400,7 +1334,7 @@ void Http2ClientTransport::MaybeGetWindowUpdateFrames(SliceBuffer& output_buf) {
|
|
|
1400
1334
|
// Constructor Destructor
|
|
1401
1335
|
|
|
1402
1336
|
Http2ClientTransport::Http2ClientTransport(
|
|
1403
|
-
PromiseEndpoint endpoint,
|
|
1337
|
+
PromiseEndpoint endpoint, const ChannelArgs& channel_args,
|
|
1404
1338
|
std::shared_ptr<EventEngine> event_engine,
|
|
1405
1339
|
absl::AnyInvocable<void(absl::StatusOr<uint32_t>)> on_receive_settings)
|
|
1406
1340
|
: channelz::DataSource(http2::CreateChannelzSocketNode(
|
|
@@ -1411,11 +1345,12 @@ Http2ClientTransport::Http2ClientTransport(
|
|
|
1411
1345
|
std::move(on_receive_settings))),
|
|
1412
1346
|
next_stream_id_(/*Initial Stream ID*/ 1),
|
|
1413
1347
|
should_reset_ping_clock_(false),
|
|
1414
|
-
|
|
1415
|
-
|
|
1348
|
+
incoming_headers_(IncomingMetadataTracker::GetPeerString(endpoint_)),
|
|
1349
|
+
transport_write_context_(kIsClient),
|
|
1416
1350
|
ping_manager_(std::nullopt),
|
|
1417
1351
|
keepalive_manager_(std::nullopt),
|
|
1418
1352
|
goaway_manager_(GoawayInterfaceImpl::Make(this)),
|
|
1353
|
+
security_frame_handler_(MakeRefCounted<SecurityFrameHandler>()),
|
|
1419
1354
|
memory_owner_(channel_args.GetObject<ResourceQuota>()
|
|
1420
1355
|
->memory_quota()
|
|
1421
1356
|
->CreateMemoryOwner()),
|
|
@@ -1424,13 +1359,13 @@ Http2ClientTransport::Http2ClientTransport(
|
|
|
1424
1359
|
channel_args.GetBool(GRPC_ARG_HTTP2_BDP_PROBE).value_or(true),
|
|
1425
1360
|
&memory_owner_),
|
|
1426
1361
|
ztrace_collector_(std::make_shared<PromiseHttp2ZTraceCollector>()) {
|
|
1427
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1362
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::Http2ClientTransport Begin";
|
|
1428
1363
|
// Initialize the general party and write party.
|
|
1429
1364
|
RefCountedPtr<Arena> party_arena = SimpleArenaAllocator(0)->MakeArena();
|
|
1430
1365
|
party_arena->SetContext<EventEngine>(event_engine_.get());
|
|
1431
1366
|
general_party_ = Party::Make(std::move(party_arena));
|
|
1432
1367
|
|
|
1433
|
-
InitLocalSettings(settings_->mutable_local(), /*is_client=*/
|
|
1368
|
+
InitLocalSettings(settings_->mutable_local(), /*is_client=*/kIsClient);
|
|
1434
1369
|
TransportChannelArgs args;
|
|
1435
1370
|
ReadChannelArgs(channel_args, args);
|
|
1436
1371
|
|
|
@@ -1442,28 +1377,28 @@ Http2ClientTransport::Http2ClientTransport(
|
|
|
1442
1377
|
KeepAliveInterfaceImpl::Make(this),
|
|
1443
1378
|
((args.keepalive_timeout < args.ping_timeout) ? args.keepalive_timeout
|
|
1444
1379
|
: Duration::Infinity()),
|
|
1445
|
-
args.keepalive_time
|
|
1446
|
-
|
|
1447
|
-
if (settings_->local().allow_security_frame()) {
|
|
1448
|
-
// TODO(tjagtap) : [PH2][P3] : Setup the plumbing to pass the security frame
|
|
1449
|
-
// to the endpoing via TransportFramingEndpointExtension.
|
|
1450
|
-
// Also decide if this plumbing is done here, or when the peer sends
|
|
1451
|
-
// allow_security_frame too.
|
|
1452
|
-
}
|
|
1380
|
+
args.keepalive_time);
|
|
1453
1381
|
|
|
1454
1382
|
GRPC_DCHECK(ping_manager_.has_value());
|
|
1455
1383
|
GRPC_DCHECK(keepalive_manager_.has_value());
|
|
1456
1384
|
SourceConstructed();
|
|
1457
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1385
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::Http2ClientTransport End";
|
|
1458
1386
|
}
|
|
1459
1387
|
|
|
1460
1388
|
void Http2ClientTransport::SpawnTransportLoops() {
|
|
1461
1389
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::SpawnTransportLoops Begin";
|
|
1390
|
+
MaybeSpawnKeepaliveLoop();
|
|
1462
1391
|
SpawnGuardedTransportParty(
|
|
1463
1392
|
"FlowControlPeriodicUpdateLoop",
|
|
1464
1393
|
UntilTransportClosed(FlowControlPeriodicUpdateLoop()));
|
|
1465
1394
|
|
|
1466
|
-
|
|
1395
|
+
if (!TriggerWriteCycleOrHandleError()) {
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
// For Client, write happens before read. So MultiplexerLoop is spawned first.
|
|
1399
|
+
// ReadLoop is spawned after the first write.
|
|
1400
|
+
// For Server, read happens before write. So ReadLoop is spawned first.
|
|
1401
|
+
// MultiplexerLoop is spawned after the first read.
|
|
1467
1402
|
SpawnGuardedTransportParty("MultiplexerLoop",
|
|
1468
1403
|
UntilTransportClosed(MultiplexerLoop()));
|
|
1469
1404
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::SpawnTransportLoops End";
|
|
@@ -1473,7 +1408,7 @@ void Http2ClientTransport::ReadChannelArgs(const ChannelArgs& channel_args,
|
|
|
1473
1408
|
TransportChannelArgs& args) {
|
|
1474
1409
|
http2::ReadChannelArgs(channel_args, args, settings_->mutable_local(),
|
|
1475
1410
|
flow_control_,
|
|
1476
|
-
/*is_client=*/
|
|
1411
|
+
/*is_client=*/kIsClient);
|
|
1477
1412
|
|
|
1478
1413
|
// Assign the channel args to the member variables.
|
|
1479
1414
|
keepalive_time_ = args.keepalive_time;
|
|
@@ -1493,10 +1428,38 @@ void Http2ClientTransport::ReadChannelArgs(const ChannelArgs& channel_args,
|
|
|
1493
1428
|
}
|
|
1494
1429
|
}
|
|
1495
1430
|
|
|
1431
|
+
absl::Status Http2ClientTransport::HandleError(
|
|
1432
|
+
const std::optional<uint32_t> stream_id, Http2Status status,
|
|
1433
|
+
DebugLocation whence) {
|
|
1434
|
+
Http2Status::Http2ErrorType error_type = status.GetType();
|
|
1435
|
+
GRPC_DCHECK(error_type != Http2Status::Http2ErrorType::kOk);
|
|
1436
|
+
|
|
1437
|
+
if (error_type == Http2Status::Http2ErrorType::kStreamError) {
|
|
1438
|
+
GRPC_HTTP2_CLIENT_ERROR_DLOG
|
|
1439
|
+
<< "Http2ClientTransport::HandleError Stream Error:"
|
|
1440
|
+
<< status.DebugString();
|
|
1441
|
+
GRPC_DCHECK(stream_id.has_value());
|
|
1442
|
+
// Passing a cancelled server metadata handle to propagate the error
|
|
1443
|
+
// to the upper layers.
|
|
1444
|
+
BeginCloseStream(
|
|
1445
|
+
LookupStream(stream_id.value()),
|
|
1446
|
+
Http2ErrorCodeToFrameErrorCode(status.GetStreamErrorCode()),
|
|
1447
|
+
CancelledServerMetadataFromStatus(status.GetAbslStreamError()), whence);
|
|
1448
|
+
return absl::OkStatus();
|
|
1449
|
+
} else if (error_type == Http2Status::Http2ErrorType::kConnectionError) {
|
|
1450
|
+
GRPC_HTTP2_CLIENT_ERROR_DLOG
|
|
1451
|
+
<< "Http2ClientTransport::HandleError Connection Error:"
|
|
1452
|
+
<< status.DebugString();
|
|
1453
|
+
absl::Status absl_status = status.GetAbslConnectionError();
|
|
1454
|
+
MaybeSpawnCloseTransport(std::move(status), whence);
|
|
1455
|
+
return absl_status;
|
|
1456
|
+
}
|
|
1457
|
+
GPR_UNREACHABLE_CODE(return absl::InternalError("Invalid error type"));
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1496
1460
|
// This function MUST be idempotent. This function MUST be called from the
|
|
1497
1461
|
// transport party.
|
|
1498
|
-
void Http2ClientTransport::CloseStream(
|
|
1499
|
-
CloseStreamArgs args,
|
|
1462
|
+
void Http2ClientTransport::CloseStream(Stream& stream, CloseStreamArgs args,
|
|
1500
1463
|
DebugLocation whence) {
|
|
1501
1464
|
std::optional<Http2Status> close_transport_error;
|
|
1502
1465
|
|
|
@@ -1504,22 +1467,21 @@ void Http2ClientTransport::CloseStream(RefCountedPtr<Stream> stream,
|
|
|
1504
1467
|
// TODO(akshitpatel) : [PH2][P3] : Measure the impact of holding mutex
|
|
1505
1468
|
// throughout this function.
|
|
1506
1469
|
MutexLock lock(&transport_mutex_);
|
|
1507
|
-
GRPC_DCHECK(stream != nullptr) << "stream is null";
|
|
1508
1470
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1509
1471
|
<< "Http2ClientTransport::CloseStream for stream id: "
|
|
1510
|
-
<< stream
|
|
1472
|
+
<< stream.GetStreamId() << " close_reads=" << args.close_reads
|
|
1511
1473
|
<< " close_writes=" << args.close_writes
|
|
1512
1474
|
<< " incoming_headers_=" << incoming_headers_.DebugString()
|
|
1513
1475
|
<< " location=" << whence.file() << ":" << whence.line();
|
|
1514
1476
|
|
|
1515
1477
|
if (args.close_writes) {
|
|
1516
|
-
stream
|
|
1478
|
+
stream.SetWriteClosed();
|
|
1517
1479
|
}
|
|
1518
1480
|
|
|
1519
1481
|
if (args.close_reads) {
|
|
1520
1482
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1521
1483
|
<< "Http2ClientTransport::CloseStream for stream id: "
|
|
1522
|
-
<< stream
|
|
1484
|
+
<< stream.GetStreamId() << " closing stream for reads.";
|
|
1523
1485
|
// If the stream is closed while reading HEADER/CONTINUATION frames, we
|
|
1524
1486
|
// should still parse the enqueued buffer to maintain HPACK state between
|
|
1525
1487
|
// peers.
|
|
@@ -1529,25 +1491,24 @@ void Http2ClientTransport::CloseStream(RefCountedPtr<Stream> stream,
|
|
|
1529
1491
|
HeaderAssembler::ParseHeaderArgs{
|
|
1530
1492
|
/*is_initial_metadata=*/!incoming_headers_.HeaderHasEndStream(),
|
|
1531
1493
|
/*is_end_headers=*/false,
|
|
1532
|
-
/*is_client=*/
|
|
1494
|
+
/*is_client=*/kIsClient,
|
|
1533
1495
|
/*max_header_list_size_soft_limit=*/
|
|
1534
1496
|
incoming_headers_.soft_limit(),
|
|
1535
1497
|
/*max_header_list_size_hard_limit=*/
|
|
1536
1498
|
settings_->acked().max_header_list_size(),
|
|
1537
1499
|
/*stream_id=*/incoming_headers_.GetStreamId(),
|
|
1538
1500
|
},
|
|
1539
|
-
stream, /*original_status=*/Http2Status::Ok());
|
|
1501
|
+
&stream, /*original_status=*/Http2Status::Ok());
|
|
1540
1502
|
if (result.GetType() == Http2Status::Http2ErrorType::kConnectionError) {
|
|
1541
1503
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1542
1504
|
<< "Http2ClientTransport::CloseStream for stream id: "
|
|
1543
|
-
<< stream
|
|
1544
|
-
<< " failed to partially process header: "
|
|
1505
|
+
<< stream.GetStreamId() << " failed to partially process header: "
|
|
1545
1506
|
<< result.DebugString();
|
|
1546
1507
|
close_transport_error.emplace(std::move(result));
|
|
1547
1508
|
}
|
|
1548
1509
|
}
|
|
1549
1510
|
|
|
1550
|
-
stream_list_.erase(stream
|
|
1511
|
+
stream_list_.erase(stream.GetStreamId());
|
|
1551
1512
|
if (!close_transport_error.has_value() && CanCloseTransportLocked()) {
|
|
1552
1513
|
// TODO(akshitpatel) : [PH2][P3] : Is kInternalError the right error
|
|
1553
1514
|
// code to use here? IMO it should be kNoError.
|
|
@@ -1653,7 +1614,9 @@ void Http2ClientTransport::BeginCloseStream(
|
|
|
1653
1614
|
} else {
|
|
1654
1615
|
// Callers taking this path:
|
|
1655
1616
|
// 1. Reading Trailing Metadata (MAY send half close from OnDone).
|
|
1656
|
-
|
|
1617
|
+
// If a half close frame has already been sent, we should close the stream
|
|
1618
|
+
// for reads and writes.
|
|
1619
|
+
if (stream->IsHalfClosedLocal() || stream->IsStreamClosed()) {
|
|
1657
1620
|
close_reads = true;
|
|
1658
1621
|
close_writes = true;
|
|
1659
1622
|
GRPC_HTTP2_CLIENT_DLOG
|
|
@@ -1664,7 +1627,7 @@ void Http2ClientTransport::BeginCloseStream(
|
|
|
1664
1627
|
}
|
|
1665
1628
|
|
|
1666
1629
|
if (close_reads || close_writes) {
|
|
1667
|
-
CloseStream(stream, CloseStreamArgs{close_reads, close_writes}, whence);
|
|
1630
|
+
CloseStream(*stream, CloseStreamArgs{close_reads, close_writes}, whence);
|
|
1668
1631
|
}
|
|
1669
1632
|
|
|
1670
1633
|
// If the call was cancelled, the stream MUST be closed for reads.
|
|
@@ -1691,7 +1654,6 @@ void Http2ClientTransport::CloseTransport() {
|
|
|
1691
1654
|
transport_closed_latch_.Set();
|
|
1692
1655
|
settings_->HandleTransportShutdown(event_engine_.get());
|
|
1693
1656
|
|
|
1694
|
-
MutexLock lock(&transport_mutex_);
|
|
1695
1657
|
// This is the only place where the general_party_ is reset.
|
|
1696
1658
|
general_party_.reset();
|
|
1697
1659
|
}
|
|
@@ -1727,16 +1689,18 @@ void Http2ClientTransport::MaybeSpawnCloseTransport(Http2Status http2_status,
|
|
|
1727
1689
|
"CloseTransport", [self = RefAsSubclass<Http2ClientTransport>(),
|
|
1728
1690
|
stream_list = std::move(stream_list),
|
|
1729
1691
|
http2_status = std::move(http2_status)]() mutable {
|
|
1692
|
+
self->security_frame_handler_->OnTransportClosed();
|
|
1730
1693
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1731
|
-
<< "Http2ClientTransport::
|
|
1694
|
+
<< "Http2ClientTransport::MaybeSpawnCloseTransport "
|
|
1695
|
+
"Cleaning up call stacks";
|
|
1732
1696
|
// Clean up the call stacks for all active streams.
|
|
1733
1697
|
for (const auto& pair : stream_list) {
|
|
1734
1698
|
// There is no merit in transitioning the stream to
|
|
1735
1699
|
// closed state here as the subsequent lookups would
|
|
1736
1700
|
// fail. Also, as this is running on the transport
|
|
1737
1701
|
// party, there would not be concurrent access to the stream.
|
|
1738
|
-
|
|
1739
|
-
self->BeginCloseStream(stream,
|
|
1702
|
+
RefCountedPtr<Stream> stream = pair.second;
|
|
1703
|
+
self->BeginCloseStream(std::move(stream),
|
|
1740
1704
|
Http2ErrorCodeToFrameErrorCode(
|
|
1741
1705
|
http2_status.GetConnectionErrorCode()),
|
|
1742
1706
|
CancelledServerMetadataFromStatus(
|
|
@@ -1784,11 +1748,11 @@ bool Http2ClientTransport::CanCloseTransportLocked() const {
|
|
|
1784
1748
|
}
|
|
1785
1749
|
|
|
1786
1750
|
Http2ClientTransport::~Http2ClientTransport() {
|
|
1787
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1751
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::~Http2ClientTransport Begin";
|
|
1788
1752
|
GRPC_DCHECK(stream_list_.empty());
|
|
1789
1753
|
GRPC_DCHECK(general_party_ == nullptr);
|
|
1790
1754
|
memory_owner_.Reset();
|
|
1791
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1755
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::~Http2ClientTransport End";
|
|
1792
1756
|
}
|
|
1793
1757
|
|
|
1794
1758
|
void Http2ClientTransport::SpawnAddChannelzData(RefCountedPtr<Party> party,
|
|
@@ -1797,7 +1761,7 @@ void Http2ClientTransport::SpawnAddChannelzData(RefCountedPtr<Party> party,
|
|
|
1797
1761
|
std::move(party), "AddData",
|
|
1798
1762
|
[self = RefAsSubclass<Http2ClientTransport>(),
|
|
1799
1763
|
sink = std::move(sink)]() mutable {
|
|
1800
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::
|
|
1764
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::SpawnAddChannelzData";
|
|
1801
1765
|
sink.AddData(
|
|
1802
1766
|
"Http2ClientTransport",
|
|
1803
1767
|
channelz::PropertyList()
|
|
@@ -1809,7 +1773,8 @@ void Http2ClientTransport::SpawnAddChannelzData(RefCountedPtr<Party> party,
|
|
|
1809
1773
|
self->flow_control_.stats().ChannelzProperties()));
|
|
1810
1774
|
self->general_party_->ExportToChannelz("Http2ClientTransport Party",
|
|
1811
1775
|
sink);
|
|
1812
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
1776
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
1777
|
+
<< "Http2ClientTransport::SpawnAddChannelzData End";
|
|
1813
1778
|
return Empty{};
|
|
1814
1779
|
});
|
|
1815
1780
|
}
|
|
@@ -1819,48 +1784,103 @@ void Http2ClientTransport::AddData(channelz::DataSink sink) {
|
|
|
1819
1784
|
|
|
1820
1785
|
event_engine_->Run([self = RefAsSubclass<Http2ClientTransport>(),
|
|
1821
1786
|
sink = std::move(sink)]() mutable {
|
|
1822
|
-
|
|
1787
|
+
RefCountedPtr<Party> party = nullptr;
|
|
1823
1788
|
{
|
|
1824
|
-
// Apart from CloseTransport, this is the only place where a lock is taken
|
|
1825
|
-
// to access general_party_. All other access to general_party_ happens
|
|
1826
|
-
// on the general party itself and hence do not race with CloseTransport.
|
|
1827
|
-
// TODO(akshitpatel) : [PH2][P4] : Check if a new mutex is needed to
|
|
1828
|
-
// protect general_party_. Curently transport_mutex_ can is used in
|
|
1829
|
-
// these places:
|
|
1830
|
-
// 1. In promises running on the transport party
|
|
1831
|
-
// 2. In AddData promise
|
|
1832
|
-
// 3. In Orphan function.
|
|
1833
|
-
// 4. Stream creation (this will be removed soon).
|
|
1834
|
-
// Given that #1 is already serialized (guaranteed by party), #2 is on
|
|
1835
|
-
// demand and #3 happens once for the lifetime of the transport while
|
|
1836
|
-
// closing the transport, the contention should be minimal.
|
|
1837
1789
|
MutexLock lock(&self->transport_mutex_);
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
// Potential fix to hold a ref to the party inside the mutex and do a
|
|
1843
|
-
// spawn outside the mutex. The only side effect is that this introduces
|
|
1844
|
-
// an additional ref to the party other the transport's copy.
|
|
1845
|
-
if (GPR_UNLIKELY(self->general_party_ == nullptr)) {
|
|
1846
|
-
is_party_null = true;
|
|
1790
|
+
if (GPR_LIKELY(!self->is_transport_closed_)) {
|
|
1791
|
+
GRPC_DCHECK(self->general_party_ != nullptr);
|
|
1792
|
+
party = self->general_party_;
|
|
1793
|
+
} else {
|
|
1847
1794
|
GRPC_HTTP2_CLIENT_DLOG
|
|
1848
|
-
<< "Http2ClientTransport::AddData
|
|
1849
|
-
"null. Transport is closed.";
|
|
1795
|
+
<< "Http2ClientTransport::AddData Transport is closed.";
|
|
1850
1796
|
}
|
|
1851
1797
|
}
|
|
1852
1798
|
|
|
1853
1799
|
ExecCtx exec_ctx;
|
|
1854
|
-
if (
|
|
1855
|
-
self->SpawnAddChannelzData(
|
|
1800
|
+
if (party != nullptr) {
|
|
1801
|
+
self->SpawnAddChannelzData(std::move(party), std::move(sink));
|
|
1856
1802
|
}
|
|
1857
1803
|
self.reset(); // Cleanup with exec_ctx in scope
|
|
1858
1804
|
});
|
|
1859
1805
|
}
|
|
1860
1806
|
|
|
1807
|
+
RefCountedPtr<channelz::SocketNode> Http2ClientTransport::GetSocketNode()
|
|
1808
|
+
const {
|
|
1809
|
+
const channelz::BaseNode* node = channelz::DataSource::channelz_node();
|
|
1810
|
+
if (node == nullptr) {
|
|
1811
|
+
return nullptr;
|
|
1812
|
+
}
|
|
1813
|
+
return const_cast<channelz::BaseNode*>(node)
|
|
1814
|
+
->RefAsSubclass<channelz::SocketNode>();
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1861
1817
|
///////////////////////////////////////////////////////////////////////////////
|
|
1862
1818
|
// Stream Related Operations
|
|
1863
1819
|
|
|
1820
|
+
absl::StatusOr<uint32_t> Http2ClientTransport::NextStreamId() {
|
|
1821
|
+
if (next_stream_id_ > GetMaxAllowedStreamId()) {
|
|
1822
|
+
// TODO(tjagtap) : [PH2][P3] : Handle case if transport runs out of stream
|
|
1823
|
+
// ids
|
|
1824
|
+
// RFC9113 : Stream identifiers cannot be reused. Long-lived connections
|
|
1825
|
+
// can result in an endpoint exhausting the available range of stream
|
|
1826
|
+
// identifiers. A client that is unable to establish a new stream
|
|
1827
|
+
// identifier can establish a new connection for new streams. A server
|
|
1828
|
+
// that is unable to establish a new stream identifier can send a GOAWAY
|
|
1829
|
+
// frame so that the client is forced to open a new connection for new
|
|
1830
|
+
// streams.
|
|
1831
|
+
return absl::ResourceExhaustedError("No more stream ids available");
|
|
1832
|
+
}
|
|
1833
|
+
// TODO(akshitpatel) : [PH2][P3] : There is a channel arg to delay
|
|
1834
|
+
// starting new streams instead of failing them. This needs to be
|
|
1835
|
+
// implemented.
|
|
1836
|
+
{
|
|
1837
|
+
// TODO(tjagtap) : [PH2][P1] : For a server we will have to do
|
|
1838
|
+
// this for incoming streams only. If a server receives more
|
|
1839
|
+
// streams from a client than is allowed by the clients settings,
|
|
1840
|
+
// whether or not we should fail is debatable.
|
|
1841
|
+
MutexLock lock(&transport_mutex_);
|
|
1842
|
+
if (GetActiveStreamCountLocked() >=
|
|
1843
|
+
settings_->peer().max_concurrent_streams()) {
|
|
1844
|
+
return absl::ResourceExhaustedError("Reached max concurrent streams");
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
// RFC9113 : Streams initiated by a client MUST use odd-numbered stream
|
|
1849
|
+
// identifiers.
|
|
1850
|
+
uint32_t new_stream_id = std::exchange(next_stream_id_, next_stream_id_ + 2);
|
|
1851
|
+
if (GPR_UNLIKELY(next_stream_id_ > GetMaxAllowedStreamId())) {
|
|
1852
|
+
ReportDisconnection(
|
|
1853
|
+
absl::ResourceExhaustedError("Transport Stream IDs exhausted"),
|
|
1854
|
+
{}, // TODO(tjagtap) : [PH2][P2] : Report better disconnect info.
|
|
1855
|
+
"no_more_stream_ids");
|
|
1856
|
+
}
|
|
1857
|
+
return new_stream_id;
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
absl::Status Http2ClientTransport::MaybeAddStreamToWritableStreamList(
|
|
1861
|
+
RefCountedPtr<Stream> stream,
|
|
1862
|
+
const StreamDataQueue<ClientMetadataHandle>::StreamWritabilityUpdate
|
|
1863
|
+
result) {
|
|
1864
|
+
if (result.became_writable) {
|
|
1865
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
1866
|
+
<< "Http2ClientTransport::MaybeAddStreamToWritableStreamList Stream "
|
|
1867
|
+
"id: "
|
|
1868
|
+
<< stream->GetStreamId() << " became writable";
|
|
1869
|
+
// TODO(akshitpatel) [Perf]: Might be worth exploring if this funciton
|
|
1870
|
+
// should take a raw stream ptr and take a ref here.
|
|
1871
|
+
absl::Status status =
|
|
1872
|
+
writable_stream_list_.Enqueue(std::move(stream), result.priority);
|
|
1873
|
+
if (!status.ok()) {
|
|
1874
|
+
return HandleError(
|
|
1875
|
+
std::nullopt,
|
|
1876
|
+
Http2Status::Http2ConnectionError(
|
|
1877
|
+
Http2ErrorCode::kRefusedStream,
|
|
1878
|
+
"Failed to enqueue stream to writable stream list"));
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
return absl::OkStatus();
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1864
1884
|
RefCountedPtr<Stream> Http2ClientTransport::LookupStream(uint32_t stream_id) {
|
|
1865
1885
|
MutexLock lock(&transport_mutex_);
|
|
1866
1886
|
auto it = stream_list_.find(stream_id);
|
|
@@ -1875,64 +1895,69 @@ RefCountedPtr<Stream> Http2ClientTransport::LookupStream(uint32_t stream_id) {
|
|
|
1875
1895
|
|
|
1876
1896
|
bool Http2ClientTransport::SetOnDone(CallHandler call_handler,
|
|
1877
1897
|
RefCountedPtr<Stream> stream) {
|
|
1878
|
-
return call_handler.OnDone(
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
<< " status=" << enqueue_result.status();
|
|
1899
|
-
} else {
|
|
1900
|
-
enqueue_result = stream->EnqueueHalfClosed();
|
|
1901
|
-
GRPC_HTTP2_CLIENT_DLOG << "Enqueued HalfClosed with result="
|
|
1902
|
-
<< enqueue_result.status();
|
|
1903
|
-
}
|
|
1898
|
+
return call_handler.OnDone([self = RefAsSubclass<Http2ClientTransport>(),
|
|
1899
|
+
stream =
|
|
1900
|
+
std::move(stream)](bool cancelled) mutable {
|
|
1901
|
+
GRPC_HTTP2_CLIENT_DLOG << "PH2: Client call " << self.get()
|
|
1902
|
+
<< " id=" << stream->GetStreamId()
|
|
1903
|
+
<< " done: cancelled=" << cancelled;
|
|
1904
|
+
absl::StatusOr<StreamWritabilityUpdate> enqueue_result;
|
|
1905
|
+
GRPC_HTTP2_CLIENT_DLOG << "PH2: Client call " << self.get()
|
|
1906
|
+
<< " id=" << stream->GetStreamId()
|
|
1907
|
+
<< " done: stream=" << stream.get()
|
|
1908
|
+
<< " cancelled=" << cancelled;
|
|
1909
|
+
|
|
1910
|
+
// If the stream is already closed for writes, then we don't need to
|
|
1911
|
+
// enqueue the reset stream or the half closed frame.
|
|
1912
|
+
if (stream->IsClosedForWrites()) {
|
|
1913
|
+
GRPC_HTTP2_CLIENT_DLOG << "PH2: Client call " << self.get()
|
|
1914
|
+
<< " id=" << stream->GetStreamId()
|
|
1915
|
+
<< " done: stream already closed for writes";
|
|
1916
|
+
return;
|
|
1917
|
+
}
|
|
1904
1918
|
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1919
|
+
if (cancelled) {
|
|
1920
|
+
// In most of the cases, EnqueueResetStream would be a no-op as
|
|
1921
|
+
// BeginCloseStream would have already enqueued the reset stream.
|
|
1922
|
+
// Currently only Aborts from application will actually enqueue
|
|
1923
|
+
// the reset stream here.
|
|
1924
|
+
enqueue_result = stream->EnqueueResetStream(
|
|
1925
|
+
static_cast<uint32_t>(Http2ErrorCode::kCancel));
|
|
1926
|
+
GRPC_HTTP2_CLIENT_DLOG << "Enqueued ResetStream with error code="
|
|
1927
|
+
<< static_cast<uint32_t>(Http2ErrorCode::kCancel)
|
|
1928
|
+
<< " status=" << enqueue_result.status();
|
|
1929
|
+
} else {
|
|
1930
|
+
enqueue_result = stream->EnqueueHalfClosed();
|
|
1931
|
+
GRPC_HTTP2_CLIENT_DLOG << "Enqueued HalfClosed with result="
|
|
1932
|
+
<< enqueue_result.status();
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
if (GPR_LIKELY(enqueue_result.ok())) {
|
|
1936
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
1937
|
+
<< "Http2ClientTransport::SetOnDone "
|
|
1938
|
+
"MaybeAddStreamToWritableStreamList for stream= "
|
|
1939
|
+
<< stream->GetStreamId() << " enqueue_result={became_writable="
|
|
1940
|
+
<< enqueue_result.value().became_writable << ", priority="
|
|
1941
|
+
<< static_cast<uint8_t>(enqueue_result.value().priority) << "}";
|
|
1942
|
+
GRPC_UNUSED absl::Status status =
|
|
1943
|
+
self->MaybeAddStreamToWritableStreamList(std::move(stream),
|
|
1944
|
+
enqueue_result.value());
|
|
1945
|
+
}
|
|
1946
|
+
});
|
|
1917
1947
|
}
|
|
1918
1948
|
|
|
1919
1949
|
std::optional<RefCountedPtr<Stream>> Http2ClientTransport::MakeStream(
|
|
1920
1950
|
CallHandler call_handler) {
|
|
1921
1951
|
// https://datatracker.ietf.org/doc/html/rfc9113#name-stream-identifiers
|
|
1922
1952
|
RefCountedPtr<Stream> stream;
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
// place.
|
|
1926
|
-
MutexLock lock(&transport_mutex_);
|
|
1927
|
-
stream = MakeRefCounted<Stream>(call_handler, flow_control_);
|
|
1928
|
-
}
|
|
1929
|
-
const bool on_done_added = SetOnDone(call_handler, stream);
|
|
1953
|
+
stream = MakeRefCounted<Stream>(call_handler, flow_control_);
|
|
1954
|
+
const bool on_done_added = SetOnDone(std::move(call_handler), stream);
|
|
1930
1955
|
if (!on_done_added) return std::nullopt;
|
|
1931
|
-
return stream;
|
|
1956
|
+
return std::move(stream);
|
|
1932
1957
|
}
|
|
1933
1958
|
|
|
1934
1959
|
uint32_t Http2ClientTransport::GetMaxAllowedStreamId() const {
|
|
1935
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1960
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::GetMaxAllowedStreamId "
|
|
1936
1961
|
<< max_allowed_stream_id_;
|
|
1937
1962
|
return max_allowed_stream_id_;
|
|
1938
1963
|
}
|
|
@@ -1940,7 +1965,7 @@ uint32_t Http2ClientTransport::GetMaxAllowedStreamId() const {
|
|
|
1940
1965
|
void Http2ClientTransport::SetMaxAllowedStreamId(
|
|
1941
1966
|
const uint32_t max_allowed_stream_id) {
|
|
1942
1967
|
const uint32_t old_max_allowed_stream_id = GetMaxAllowedStreamId();
|
|
1943
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
1968
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::SetMaxAllowedStreamId "
|
|
1944
1969
|
<< " max_allowed_stream_id: " << max_allowed_stream_id
|
|
1945
1970
|
<< " old_allowed_max_stream_id: "
|
|
1946
1971
|
<< old_max_allowed_stream_id;
|
|
@@ -1962,115 +1987,241 @@ void Http2ClientTransport::SetMaxAllowedStreamId(
|
|
|
1962
1987
|
}
|
|
1963
1988
|
|
|
1964
1989
|
///////////////////////////////////////////////////////////////////////////////
|
|
1965
|
-
// Call Spine related operations
|
|
1990
|
+
// Http2ClientTransport - Call Spine related operations
|
|
1966
1991
|
|
|
1967
|
-
auto Http2ClientTransport::CallOutboundLoop(
|
|
1968
|
-
|
|
1969
|
-
ClientMetadataHandle metadata) {
|
|
1970
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop";
|
|
1992
|
+
auto Http2ClientTransport::CallOutboundLoop(RefCountedPtr<Stream> stream) {
|
|
1993
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CallOutboundLoop";
|
|
1971
1994
|
GRPC_DCHECK(stream != nullptr);
|
|
1972
1995
|
|
|
1973
|
-
auto send_message = [
|
|
1974
|
-
stream](MessageHandle&& message) mutable {
|
|
1975
|
-
return TrySeq(stream->EnqueueMessage(std::move(message)),
|
|
1976
|
-
[self, stream](const StreamWritabilityUpdate result) mutable {
|
|
1977
|
-
GRPC_HTTP2_CLIENT_DLOG
|
|
1978
|
-
<< "Http2ClientTransport CallOutboundLoop "
|
|
1979
|
-
"Enqueued Message";
|
|
1980
|
-
return self->MaybeAddStreamToWritableStreamList(
|
|
1981
|
-
std::move(stream), result);
|
|
1982
|
-
});
|
|
1983
|
-
};
|
|
1984
|
-
|
|
1985
|
-
auto send_initial_metadata = [self = RefAsSubclass<Http2ClientTransport>(),
|
|
1986
|
-
stream,
|
|
1987
|
-
metadata = std::move(metadata)]() mutable {
|
|
1996
|
+
auto send_message = [this, stream](MessageHandle&& message) mutable {
|
|
1988
1997
|
return TrySeq(
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
"Enqueued Initial Metadata";
|
|
1995
|
-
return self->MaybeAddStreamToWritableStreamList(std::move(stream),
|
|
1996
|
-
result);
|
|
1998
|
+
stream->EnqueueMessage(std::move(message)),
|
|
1999
|
+
[this, stream](const StreamWritabilityUpdate result) mutable {
|
|
2000
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CallOutboundLoop "
|
|
2001
|
+
"Enqueued Message";
|
|
2002
|
+
return MaybeAddStreamToWritableStreamList(std::move(stream), result);
|
|
1997
2003
|
});
|
|
1998
2004
|
};
|
|
1999
2005
|
|
|
2000
|
-
auto
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2006
|
+
auto send_initial_metadata =
|
|
2007
|
+
[this, stream](ClientMetadataHandle&& metadata) mutable {
|
|
2008
|
+
absl::StatusOr<StreamWritabilityUpdate> enqueue_result =
|
|
2009
|
+
stream->EnqueueInitialMetadata(
|
|
2010
|
+
std::forward<ClientMetadataHandle>(metadata));
|
|
2011
|
+
if (GPR_UNLIKELY(!enqueue_result.ok())) {
|
|
2012
|
+
return enqueue_result.status();
|
|
2013
|
+
}
|
|
2014
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop "
|
|
2015
|
+
"Enqueued Initial Metadata";
|
|
2016
|
+
return MaybeAddStreamToWritableStreamList(std::move(stream),
|
|
2017
|
+
enqueue_result.value());
|
|
2018
|
+
};
|
|
2019
|
+
|
|
2020
|
+
auto send_half_closed = [this, stream]() mutable {
|
|
2021
|
+
absl::StatusOr<StreamWritabilityUpdate> enqueue_result =
|
|
2022
|
+
stream->EnqueueHalfClosed();
|
|
2023
|
+
if (GPR_UNLIKELY(!enqueue_result.ok())) {
|
|
2024
|
+
return enqueue_result.status();
|
|
2025
|
+
}
|
|
2026
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop "
|
|
2027
|
+
"Enqueued Half Closed";
|
|
2028
|
+
return MaybeAddStreamToWritableStreamList(std::move(stream),
|
|
2029
|
+
enqueue_result.value());
|
|
2010
2030
|
};
|
|
2031
|
+
|
|
2011
2032
|
return GRPC_LATENT_SEE_PROMISE(
|
|
2012
2033
|
"Ph2CallOutboundLoop",
|
|
2013
2034
|
TrySeq(
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2035
|
+
Map(stream->GetCallHandler().PullClientInitialMetadata(),
|
|
2036
|
+
[send_initial_metadata = std::move(send_initial_metadata)](
|
|
2037
|
+
ValueOrFailure<ClientMetadataHandle> metadata) mutable {
|
|
2038
|
+
if (GPR_UNLIKELY(!metadata.ok())) {
|
|
2039
|
+
return absl::InternalError(
|
|
2040
|
+
"Failed to pull client initial metadata");
|
|
2041
|
+
}
|
|
2042
|
+
return std::move(send_initial_metadata)(
|
|
2043
|
+
TakeValue(std::move(metadata)));
|
|
2044
|
+
}),
|
|
2045
|
+
ForEach(MessagesFrom(stream->GetCallHandler()),
|
|
2046
|
+
std::move(send_message)),
|
|
2047
|
+
[send_half_closed = std::move(send_half_closed)]() mutable {
|
|
2048
|
+
return std::move(send_half_closed)();
|
|
2024
2049
|
},
|
|
2025
|
-
[
|
|
2026
|
-
return Map(
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2050
|
+
[stream]() mutable {
|
|
2051
|
+
return Map(
|
|
2052
|
+
stream->GetCallHandler().WasCancelled(), [](bool cancelled) {
|
|
2053
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
2054
|
+
<< "Http2ClientTransport::CallOutboundLoop End with "
|
|
2055
|
+
"cancelled="
|
|
2056
|
+
<< cancelled;
|
|
2057
|
+
return (cancelled) ? absl::CancelledError()
|
|
2058
|
+
: absl::OkStatus();
|
|
2059
|
+
});
|
|
2033
2060
|
}));
|
|
2034
2061
|
}
|
|
2035
2062
|
|
|
2036
2063
|
void Http2ClientTransport::StartCall(CallHandler call_handler) {
|
|
2037
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
|
2064
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::StartCall Begin";
|
|
2065
|
+
|
|
2038
2066
|
call_handler.SpawnGuarded(
|
|
2039
2067
|
"OutboundLoop",
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2068
|
+
[self = RefAsSubclass<Http2ClientTransport>(), call_handler]() mutable {
|
|
2069
|
+
std::optional<RefCountedPtr<Stream>> stream =
|
|
2070
|
+
self->MakeStream(std::move(call_handler));
|
|
2071
|
+
|
|
2072
|
+
return If(
|
|
2073
|
+
stream.has_value(),
|
|
2074
|
+
[self = std::move(self), stream]() mutable {
|
|
2075
|
+
return Map(self->CallOutboundLoop(std::move(stream.value())),
|
|
2076
|
+
[self](absl::Status status) { return status; });
|
|
2077
|
+
},
|
|
2078
|
+
[]() { return absl::InternalError("Failed to make stream"); });
|
|
2079
|
+
});
|
|
2080
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::StartCall End";
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2084
|
+
// Http2ClientTransport - Test Only Functions
|
|
2085
|
+
|
|
2086
|
+
int64_t Http2ClientTransport::TestOnlyTransportFlowControlWindow() {
|
|
2087
|
+
return flow_control_.remote_window();
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
int64_t Http2ClientTransport::TestOnlyGetStreamFlowControlWindow(
|
|
2091
|
+
const uint32_t stream_id) {
|
|
2092
|
+
RefCountedPtr<Stream> stream = LookupStream(stream_id);
|
|
2093
|
+
if (stream == nullptr) {
|
|
2094
|
+
return -1;
|
|
2095
|
+
}
|
|
2096
|
+
return stream->GetStreamFlowControl().remote_window_delta();
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2100
|
+
// Http2ClientTransport - Ping Helpers
|
|
2101
|
+
|
|
2102
|
+
void Http2ClientTransport::MaybeSpawnPingTimeout(
|
|
2103
|
+
std::optional<uint64_t> opaque_data) {
|
|
2104
|
+
if (opaque_data.has_value()) {
|
|
2105
|
+
SpawnGuardedTransportParty(
|
|
2106
|
+
"PingTimeout", [self = RefAsSubclass<Http2ClientTransport>(),
|
|
2107
|
+
opaque_data = *opaque_data]() {
|
|
2108
|
+
return self->ping_manager_->TimeoutPromise(opaque_data);
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
void Http2ClientTransport::MaybeSpawnDelayedPing(
|
|
2113
|
+
std::optional<Duration> delayed_ping_wait) {
|
|
2114
|
+
if (delayed_ping_wait.has_value()) {
|
|
2115
|
+
SpawnGuardedTransportParty(
|
|
2116
|
+
"DelayedPing", [self = RefAsSubclass<Http2ClientTransport>(),
|
|
2117
|
+
wait = *delayed_ping_wait]() {
|
|
2118
|
+
GRPC_HTTP2_PING_LOG << "Scheduling delayed ping after wait=" << wait;
|
|
2119
|
+
return self->ping_manager_->DelayedPingPromise(wait);
|
|
2120
|
+
});
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
void Http2ClientTransport::MaybeSpawnKeepaliveLoop() {
|
|
2125
|
+
if (keepalive_manager_->IsKeepAliveLoopNeeded()) {
|
|
2126
|
+
SpawnGuardedTransportParty(
|
|
2127
|
+
"KeepaliveLoop", [self = RefAsSubclass<Http2ClientTransport>()]() {
|
|
2128
|
+
return self->keepalive_manager_->KeepaliveLoop();
|
|
2129
|
+
});
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2134
|
+
// Class PingSystemInterfaceImpl
|
|
2135
|
+
|
|
2136
|
+
std::unique_ptr<PingInterface>
|
|
2137
|
+
Http2ClientTransport::PingSystemInterfaceImpl::Make(
|
|
2138
|
+
Http2ClientTransport* transport) {
|
|
2139
|
+
return std::make_unique<PingSystemInterfaceImpl>(
|
|
2140
|
+
PingSystemInterfaceImpl(transport));
|
|
2073
2141
|
}
|
|
2074
2142
|
|
|
2143
|
+
absl::Status Http2ClientTransport::PingSystemInterfaceImpl::TriggerWrite() {
|
|
2144
|
+
return transport_->TriggerWriteCycle();
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
Promise<absl::Status>
|
|
2148
|
+
Http2ClientTransport::PingSystemInterfaceImpl::PingTimeout() {
|
|
2149
|
+
GRPC_HTTP2_CLIENT_DLOG << "PingSystemInterfaceImpl::PingTimeout at time: "
|
|
2150
|
+
<< Timestamp::Now();
|
|
2151
|
+
|
|
2152
|
+
// TODO(akshitpatel) : [PH2][P2] : The error code here has been chosen
|
|
2153
|
+
// based on CHTTP2's usage of GRPC_STATUS_UNAVAILABLE (which corresponds
|
|
2154
|
+
// to kRefusedStream). However looking at RFC9113, definition of
|
|
2155
|
+
// kRefusedStream doesn't seem to fit this case. We should revisit this
|
|
2156
|
+
// and update the error code.
|
|
2157
|
+
return Immediate(transport_->HandleError(
|
|
2158
|
+
std::nullopt,
|
|
2159
|
+
Http2Status::Http2ConnectionError(Http2ErrorCode::kRefusedStream,
|
|
2160
|
+
GRPC_CHTTP2_PING_TIMEOUT_STR)));
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2164
|
+
// Class KeepAliveInterfaceImpl
|
|
2165
|
+
|
|
2166
|
+
std::unique_ptr<KeepAliveInterface>
|
|
2167
|
+
Http2ClientTransport::KeepAliveInterfaceImpl::Make(
|
|
2168
|
+
Http2ClientTransport* transport) {
|
|
2169
|
+
return std::make_unique<KeepAliveInterfaceImpl>(
|
|
2170
|
+
KeepAliveInterfaceImpl(transport));
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
Promise<absl::Status>
|
|
2174
|
+
Http2ClientTransport::KeepAliveInterfaceImpl::SendPingAndWaitForAck() {
|
|
2175
|
+
return TrySeq(
|
|
2176
|
+
[transport = transport_] { return transport->TriggerWriteCycle(); },
|
|
2177
|
+
[transport = transport_] { return transport->WaitForPingAck(); });
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
Promise<absl::Status>
|
|
2181
|
+
Http2ClientTransport::KeepAliveInterfaceImpl::OnKeepAliveTimeout() {
|
|
2182
|
+
GRPC_HTTP2_CLIENT_DLOG
|
|
2183
|
+
<< "KeepAliveInterfaceImpl::OnKeepAliveTimeout triggered";
|
|
2184
|
+
// TODO(akshitpatel) : [PH2][P2] : The error code here has been chosen
|
|
2185
|
+
// based on CHTTP2's usage of GRPC_STATUS_UNAVAILABLE (which corresponds
|
|
2186
|
+
// to kRefusedStream). However looking at RFC9113, definition of
|
|
2187
|
+
// kRefusedStream doesn't seem to fit this case. We should revisit this
|
|
2188
|
+
// and update the error code.
|
|
2189
|
+
return Immediate(transport_->HandleError(
|
|
2190
|
+
std::nullopt,
|
|
2191
|
+
Http2Status::Http2ConnectionError(Http2ErrorCode::kRefusedStream,
|
|
2192
|
+
GRPC_CHTTP2_KEEPALIVE_TIMEOUT_STR)));
|
|
2193
|
+
}
|
|
2194
|
+
|
|
2195
|
+
bool Http2ClientTransport::KeepAliveInterfaceImpl::NeedToSendKeepAlivePing() {
|
|
2196
|
+
bool need_to_send_ping = false;
|
|
2197
|
+
{
|
|
2198
|
+
MutexLock lock(&transport_->transport_mutex_);
|
|
2199
|
+
need_to_send_ping = (transport_->keepalive_permit_without_calls_ ||
|
|
2200
|
+
transport_->GetActiveStreamCountLocked() > 0);
|
|
2201
|
+
}
|
|
2202
|
+
return need_to_send_ping;
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2206
|
+
// Class GoawayInterfaceImpl
|
|
2207
|
+
|
|
2208
|
+
std::unique_ptr<GoawayInterface>
|
|
2209
|
+
Http2ClientTransport::GoawayInterfaceImpl::Make(
|
|
2210
|
+
Http2ClientTransport* transport) {
|
|
2211
|
+
return std::make_unique<GoawayInterfaceImpl>(GoawayInterfaceImpl(transport));
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
uint32_t Http2ClientTransport::GoawayInterfaceImpl::GetLastAcceptedStreamId() {
|
|
2215
|
+
LOG(DFATAL) << "GetLastAcceptedStreamId is not implemented for client "
|
|
2216
|
+
"transport.";
|
|
2217
|
+
return 0;
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
// TODO(akshitpatel) : [PH2][P2] : Eventually there should be a separate ref
|
|
2221
|
+
// counted struct/class passed to all the transport promises/members. This
|
|
2222
|
+
// will help removing back references from the transport members to
|
|
2223
|
+
// transport and greatly simpilfy the cleanup path. Need to do this for
|
|
2224
|
+
// PingSystemInterfaceImpl, KeepAliveInterfaceImpl and GoawayInterfaceImpl.
|
|
2225
|
+
|
|
2075
2226
|
} // namespace http2
|
|
2076
2227
|
} // namespace grpc_core
|