grpc 1.82.0 → 1.83.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +8 -5
- data/etc/roots.pem +10400 -3855
- data/include/grpc/grpc_audit_logging.h +2 -2
- data/include/grpc/grpc_security_constants.h +2 -0
- data/include/grpc/impl/channel_arg_names.h +23 -0
- data/src/core/call/call_filters.h +19 -3
- data/src/core/call/call_spine.h +4 -4
- data/src/core/call/client_call.cc +1 -1
- data/src/core/call/metadata.cc +7 -2
- data/src/core/call/server_call.cc +13 -3
- data/src/core/call/server_call.h +5 -3
- data/src/core/client_channel/backup_poller.cc +2 -17
- data/src/core/client_channel/client_channel.cc +17 -14
- data/src/core/client_channel/client_channel.h +3 -1
- data/src/core/client_channel/client_channel_filter.cc +11 -13
- data/src/core/client_channel/client_channel_service_config.cc +5 -13
- data/src/core/client_channel/direct_channel.cc +5 -1
- data/src/core/client_channel/direct_channel.h +3 -1
- data/src/core/config/experiment_env_var.cc +30 -0
- data/src/core/config/experiment_env_var.h +26 -0
- data/src/core/credentials/call/regional_access_boundary_fetcher.cc +6 -6
- data/src/core/credentials/transport/ssl/ssl_security_connector.cc +14 -2
- data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.cc +172 -0
- data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.h +103 -0
- data/src/core/credentials/transport/tls/load_system_roots_fallback.cc +3 -2
- data/src/core/credentials/transport/tls/load_system_roots_supported.cc +10 -3
- data/src/core/credentials/transport/tls/tls_security_connector.cc +14 -2
- data/src/core/credentials/transport/xds/xds_credentials.cc +4 -12
- data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +2 -1
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +19 -13
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +11 -9
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/flow_control.h +3 -2
- data/src/core/ext/transport/chttp2/transport/frame.cc +58 -1
- data/src/core/ext/transport/chttp2/transport/frame.h +13 -1
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -4
- data/src/core/ext/transport/chttp2/transport/frame_security.cc +10 -1
- data/src/core/ext/transport/chttp2/transport/frame_security.h +2 -1
- data/src/core/ext/transport/chttp2/transport/goaway.cc +11 -1
- data/src/core/ext/transport/chttp2/transport/goaway.h +17 -1
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +9 -0
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +117 -276
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +44 -17
- data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +382 -496
- data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +75 -77
- data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +30 -11
- data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +24 -9
- data/src/core/ext/transport/chttp2/transport/http2_transport.cc +26 -0
- data/src/core/ext/transport/chttp2/transport/http2_transport.h +2 -0
- data/src/core/ext/transport/chttp2/transport/internal.h +4 -0
- data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
- data/src/core/ext/transport/chttp2/transport/ping_promise.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +4 -10
- data/src/core/ext/transport/chttp2/transport/read_context.h +62 -20
- data/src/core/ext/transport/chttp2/transport/security_frame.h +1 -0
- data/src/core/ext/transport/chttp2/transport/stream.h +271 -120
- data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +77 -61
- data/src/core/handshaker/security/secure_endpoint.cc +0 -13
- data/src/core/lib/channel/promise_based_filter.cc +77 -3
- data/src/core/lib/channel/promise_based_filter.h +238 -184
- data/src/core/lib/event_engine/extensions/receive_coalescing_extension.h +0 -4
- data/src/core/lib/event_engine/extensions/tcp_trace.h +1 -1
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +2 -12
- data/src/core/lib/event_engine/shim.cc +2 -16
- data/src/core/lib/event_engine/shim.h +0 -4
- data/src/core/lib/experiments/experiments.cc +51 -102
- data/src/core/lib/experiments/experiments.h +37 -59
- data/src/core/lib/iomgr/error.cc +3 -73
- data/src/core/lib/iomgr/error.h +8 -6
- data/src/core/lib/iomgr/error_cfstream.cc +1 -2
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +2 -6
- data/src/core/lib/iomgr/ev_poll_posix.cc +2 -6
- data/src/core/lib/iomgr/tcp_posix.cc +2 -6
- data/src/core/lib/security/authorization/audit_logging.cc +2 -2
- data/src/core/lib/security/authorization/audit_logging.h +3 -3
- data/src/core/lib/security/authorization/grpc_authorization_engine.cc +11 -13
- data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
- data/src/core/lib/security/authorization/matchers.cc +20 -20
- data/src/core/lib/security/authorization/matchers.h +15 -16
- data/src/core/lib/security/authorization/rbac_policy.h +1 -1
- data/src/core/lib/security/authorization/stdout_logger.cc +3 -3
- data/src/core/lib/security/authorization/stdout_logger.h +6 -5
- data/src/core/lib/surface/call.cc +0 -8
- data/src/core/lib/surface/call.h +2 -0
- data/src/core/lib/surface/channel.cc +21 -2
- data/src/core/lib/surface/channel.h +14 -6
- data/src/core/lib/surface/filter_stack_call.cc +10 -29
- data/src/core/lib/surface/legacy_channel.cc +7 -7
- data/src/core/lib/surface/legacy_channel.h +3 -1
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/bdp_estimator.cc +13 -13
- data/src/core/lib/transport/bdp_estimator.h +9 -5
- data/src/core/lib/transport/error_utils.cc +26 -138
- data/src/core/lib/transport/promise_endpoint.h +2 -4
- data/src/core/load_balancing/grpclb/grpclb.cc +2 -1
- data/src/core/load_balancing/pick_first/pick_first.cc +33 -2
- data/src/core/load_balancing/pick_first/pick_first.h +6 -0
- data/src/core/load_balancing/ring_hash/ring_hash.cc +3 -10
- data/src/core/load_balancing/rls/rls.cc +2 -1
- data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +2 -7
- data/src/core/load_balancing/xds/cds.cc +80 -56
- data/src/core/load_balancing/xds/cds.h +21 -0
- data/src/core/mitigation_engine/mitigation.h +53 -0
- data/src/core/mitigation_engine/mitigation_provider.h +62 -0
- data/src/core/resolver/dns/dns_resolver_plugin.cc +1 -6
- data/src/core/resolver/xds/xds_resolver.cc +14 -11
- data/src/core/server/server.h +1 -4
- data/src/core/server/server_config_selector.h +5 -4
- data/src/core/server/server_config_selector_filter.cc +67 -80
- data/src/core/server/xds_server_config_fetcher.cc +681 -692
- data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -12
- data/src/core/telemetry/call_tracer.cc +49 -2
- data/src/core/telemetry/call_tracer.h +1 -0
- data/src/core/telemetry/tcp_tracer.h +38 -0
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
- data/src/core/tsi/ssl_telemetry_utils.cc +343 -0
- data/src/core/tsi/ssl_telemetry_utils.h +74 -0
- data/src/core/tsi/ssl_transport_security.cc +577 -301
- data/src/core/tsi/ssl_transport_security.h +22 -6
- data/src/core/tsi/ssl_transport_security_utils.cc +2 -0
- data/src/core/tsi/transport_security.h +7 -0
- data/src/core/util/http_client/httpcli.cc +1 -4
- data/src/core/util/http_client/httpcli_security_connector.cc +2 -1
- data/src/core/util/status_helper.cc +71 -192
- data/src/core/util/status_helper.h +16 -21
- data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +2 -11
- data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -7
- data/src/core/xds/grpc/xds_cluster_parser.cc +5 -16
- data/src/core/xds/grpc/xds_common_types.cc +94 -38
- data/src/core/xds/grpc/xds_common_types.h +33 -18
- data/src/core/xds/grpc/xds_common_types_parser.cc +168 -100
- data/src/core/xds/grpc/xds_common_types_parser.h +18 -1
- data/src/core/xds/grpc/xds_endpoint_parser.cc +6 -17
- data/src/core/xds/grpc/xds_http_filter_registry.cc +2 -10
- data/src/core/xds/grpc/xds_http_rbac_filter.cc +3 -12
- data/src/core/xds/grpc/xds_metadata_parser.cc +0 -2
- data/src/core/xds/grpc/xds_route_config_parser.cc +7 -11
- data/src/core/xds/grpc/xds_routing.cc +113 -82
- data/src/core/xds/grpc/xds_routing.h +70 -20
- data/src/core/xds/grpc/xds_server_grpc.cc +22 -13
- data/src/core/xds/grpc/xds_server_grpc.h +16 -2
- data/src/core/xds/grpc/xds_server_grpc_interface.h +10 -0
- data/src/core/xds/grpc/xds_transport_grpc.cc +123 -18
- data/src/core/xds/grpc/xds_transport_grpc.h +28 -4
- data/src/core/xds/xds_client/lrs_client.cc +3 -7
- data/src/core/xds/xds_client/xds_bootstrap.cc +4 -16
- data/src/core/xds/xds_client/xds_client.cc +2 -15
- data/src/core/xds/xds_client/xds_transport.h +3 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +1 -1
- metadata +9 -1
|
@@ -33,7 +33,6 @@
|
|
|
33
33
|
#include "src/core/call/metadata_batch.h"
|
|
34
34
|
#include "src/core/ext/transport/chttp2/transport/flow_control.h"
|
|
35
35
|
#include "src/core/ext/transport/chttp2/transport/frame.h"
|
|
36
|
-
#include "src/core/ext/transport/chttp2/transport/header_assembler.h"
|
|
37
36
|
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
|
|
38
37
|
#include "src/core/ext/transport/chttp2/transport/http2_status.h"
|
|
39
38
|
#include "src/core/ext/transport/chttp2/transport/message_assembler.h"
|
|
@@ -44,6 +43,7 @@
|
|
|
44
43
|
#include "src/core/util/ref_counted.h"
|
|
45
44
|
#include "src/core/util/ref_counted_ptr.h"
|
|
46
45
|
#include "absl/log/log.h"
|
|
46
|
+
#include "absl/status/status.h"
|
|
47
47
|
|
|
48
48
|
namespace grpc_core {
|
|
49
49
|
namespace http2 {
|
|
@@ -54,13 +54,159 @@ namespace http2 {
|
|
|
54
54
|
constexpr uint32_t kStreamQueueSize = /*1 MB*/ 1024u * 1024u;
|
|
55
55
|
constexpr uint32_t kInvalidStreamId = 0u;
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
struct StreamStateChange {
|
|
58
|
+
bool reads_became_closed = false;
|
|
59
|
+
bool stream_became_closed = false;
|
|
60
|
+
std::string DebugString() const {
|
|
61
|
+
return absl::StrCat("reads_became_closed: ", reads_became_closed,
|
|
62
|
+
" stream_became_closed: ", stream_became_closed);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
class StreamState {
|
|
67
|
+
public:
|
|
68
|
+
explicit StreamState(const bool started) : started_(started) {}
|
|
69
|
+
~StreamState() = default;
|
|
70
|
+
|
|
71
|
+
// StreamState is neither movable nor copyable.
|
|
72
|
+
StreamState(const StreamState&) = delete;
|
|
73
|
+
StreamState& operator=(const StreamState&) = delete;
|
|
74
|
+
StreamState(StreamState&&) = delete;
|
|
75
|
+
StreamState& operator=(StreamState&&) = delete;
|
|
76
|
+
|
|
77
|
+
// State queries
|
|
78
|
+
bool started() const { return started_; }
|
|
79
|
+
bool reads_closed() const { return reads_closed_; }
|
|
80
|
+
bool half_closed_local() const { return half_closed_local_; }
|
|
81
|
+
bool writes_closed() const {
|
|
82
|
+
return writes_closed_.load(std::memory_order_relaxed);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// A stream is closed when both reads and writes are closed.
|
|
86
|
+
bool IsClosed() const { return reads_closed() && writes_closed(); }
|
|
87
|
+
|
|
88
|
+
// A stream is idle if it has not started yet and has not been closed.
|
|
89
|
+
// Note: HTTP/2 does not allow direct transitions from Idle to Half-Closed
|
|
90
|
+
// states (it must go through Open first, which sets `started_` to true).
|
|
91
|
+
// The only transition from Idle for an unstarted stream is to Closed
|
|
92
|
+
// (e.g., via local cancellation). Thus, checking `!started() && !IsClosed()`
|
|
93
|
+
// is sufficient to identify the Idle state.
|
|
94
|
+
bool IsIdle() const { return !started() && !IsClosed(); }
|
|
95
|
+
|
|
96
|
+
bool IsOpen() const {
|
|
97
|
+
return started() && !reads_closed() && !writes_closed() &&
|
|
98
|
+
!half_closed_local();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
bool IsHalfClosedRemote() const { return reads_closed() && !writes_closed(); }
|
|
102
|
+
|
|
103
|
+
bool IsHalfClosedLocal() const {
|
|
104
|
+
return !reads_closed() && half_closed_local();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
bool IsHalfClosedLocalSent() const { return half_closed_local(); }
|
|
108
|
+
|
|
109
|
+
std::string DebugString() const {
|
|
110
|
+
return absl::StrCat(
|
|
111
|
+
"started:", started_, " reads_closed:", reads_closed_,
|
|
112
|
+
" half_closed_local:", half_closed_local_,
|
|
113
|
+
" writes_closed:", writes_closed_.load(std::memory_order_relaxed));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Semantic state transitions
|
|
117
|
+
void OnInitialMetadataSent() {
|
|
118
|
+
GRPC_DCHECK(!started_);
|
|
119
|
+
started_ = true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
StreamStateChange OnHalfCloseSent() {
|
|
123
|
+
return RunTransition([this]() {
|
|
124
|
+
half_closed_local_ = true;
|
|
125
|
+
MaybeUpdateWritesClosed();
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
StreamStateChange OnTrailingMetadataReceived() {
|
|
130
|
+
return RunTransition([this]() {
|
|
131
|
+
reads_closed_ = true;
|
|
132
|
+
MaybeUpdateWritesClosed();
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
StreamStateChange OnHalfCloseReceived() {
|
|
137
|
+
return RunTransition([this]() { reads_closed_ = true; });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
StreamStateChange OnResetReceived() {
|
|
141
|
+
return RunTransition([this]() {
|
|
142
|
+
reads_closed_ = true;
|
|
143
|
+
half_closed_local_ = true;
|
|
144
|
+
writes_closed_.store(true, std::memory_order_relaxed);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
StreamStateChange OnResetSent() {
|
|
149
|
+
return RunTransition([this]() {
|
|
150
|
+
reads_closed_ = true;
|
|
151
|
+
half_closed_local_ = true;
|
|
152
|
+
writes_closed_.store(true, std::memory_order_relaxed);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
StreamStateChange OnInitiateReset() {
|
|
157
|
+
return RunTransition([this]() { reads_closed_ = true; });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Force setters for fallback/init errors
|
|
161
|
+
StreamStateChange ForceClose() {
|
|
162
|
+
return RunTransition([this]() {
|
|
163
|
+
reads_closed_ = true;
|
|
164
|
+
half_closed_local_ = true;
|
|
165
|
+
writes_closed_.store(true, std::memory_order_relaxed);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private:
|
|
170
|
+
template <typename F>
|
|
171
|
+
StreamStateChange RunTransition(F&& transition_func) {
|
|
172
|
+
const bool was_read_closed = reads_closed_;
|
|
173
|
+
const bool was_closed = IsClosed();
|
|
174
|
+
|
|
175
|
+
transition_func();
|
|
176
|
+
GRPC_HTTP2_STREAM_LOG << "StreamState transition from "
|
|
177
|
+
<< "{reads_closed: " << was_read_closed
|
|
178
|
+
<< ", closed: " << was_closed << "}"
|
|
179
|
+
<< " to " << DebugString();
|
|
180
|
+
return {/*reads_became_closed=*/!was_read_closed && reads_closed(),
|
|
181
|
+
/*stream_became_closed=*/!was_closed && IsClosed()};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
void MaybeUpdateWritesClosed() {
|
|
185
|
+
// Client: if we sent half close and peer closed reads, writes are closed.
|
|
186
|
+
// Server: half_closed_local_ is never explicitly set, so this function is
|
|
187
|
+
// mostly a no-op.
|
|
188
|
+
if (reads_closed_ && half_closed_local_) {
|
|
189
|
+
writes_closed_.store(true, std::memory_order_relaxed);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Started is set to true when initial metadata has been sent on the wire.
|
|
194
|
+
// For client, this is when initial metadata has been sent on the wire. For
|
|
195
|
+
// server, this is when initial metadata has been received from the wire.
|
|
196
|
+
bool started_ = false;
|
|
197
|
+
|
|
198
|
+
// Has peer sent a frame notifying that no more frames will be sent (trailing
|
|
199
|
+
// metadata or RST or half close).
|
|
200
|
+
bool reads_closed_ = false;
|
|
201
|
+
|
|
202
|
+
// Has the transport sent a frame notifying peer that no more data frames will
|
|
203
|
+
// be sent (half close). Note: Client can still send RST after this point
|
|
204
|
+
// until writes are fully closed.
|
|
205
|
+
bool half_closed_local_ = false;
|
|
206
|
+
|
|
207
|
+
// Absolutely nothing can be sent for this stream now (after RST or after both
|
|
208
|
+
// half_close and reads_closed for client).
|
|
209
|
+
std::atomic<bool> writes_closed_{false};
|
|
64
210
|
};
|
|
65
211
|
|
|
66
212
|
// Managing the streams
|
|
@@ -70,12 +216,12 @@ class Stream : public RefCounted<Stream> {
|
|
|
70
216
|
chttp2::TransportFlowControl& transport_flow_control)
|
|
71
217
|
: flow_control_(&transport_flow_control),
|
|
72
218
|
call_(std::move(call_handler)),
|
|
73
|
-
|
|
219
|
+
state_(/*started=*/false),
|
|
74
220
|
stream_id_(kInvalidStreamId),
|
|
75
|
-
stream_state_(HttpStreamState::kIdle),
|
|
76
221
|
did_receive_initial_metadata_(false),
|
|
77
222
|
did_receive_trailing_metadata_(false),
|
|
78
223
|
did_push_server_trailing_metadata_(false),
|
|
224
|
+
did_cancel_(false),
|
|
79
225
|
data_queue_(MakeRefCounted<StreamDataQueue<ClientMetadataHandle>>(
|
|
80
226
|
std::get<CallHandler>(call_).arena(), /*is_client*/ true,
|
|
81
227
|
/*queue_size*/ kStreamQueueSize)) {}
|
|
@@ -86,12 +232,12 @@ class Stream : public RefCounted<Stream> {
|
|
|
86
232
|
const bool allow_true_binary_metadata_peer)
|
|
87
233
|
: flow_control_(&transport_flow_control),
|
|
88
234
|
call_(std::move(call_initiator)),
|
|
89
|
-
|
|
235
|
+
state_(/*started=*/true),
|
|
90
236
|
stream_id_(stream_id),
|
|
91
|
-
stream_state_(HttpStreamState::kIdle),
|
|
92
237
|
did_receive_initial_metadata_(false),
|
|
93
238
|
did_receive_trailing_metadata_(false),
|
|
94
239
|
did_push_server_trailing_metadata_(false),
|
|
240
|
+
did_cancel_(false),
|
|
95
241
|
data_queue_(MakeRefCounted<StreamDataQueue<ClientMetadataHandle>>(
|
|
96
242
|
std::get<CallInitiator>(call_).arena(), /*is_client*/ false,
|
|
97
243
|
/*queue_size*/ kStreamQueueSize)) {
|
|
@@ -103,15 +249,9 @@ class Stream : public RefCounted<Stream> {
|
|
|
103
249
|
Stream& operator=(const Stream&) = delete;
|
|
104
250
|
Stream& operator=(Stream&&) = delete;
|
|
105
251
|
|
|
106
|
-
// TODO(akshitpatel) : [PH2][P4] : SetStreamId can be avoided if we pass the
|
|
107
|
-
// stream id as a parameter to the dequeue function. The only downside here
|
|
108
|
-
// is that we will be creating two new disassemblers for every dequeue call.
|
|
109
|
-
// The upside is that we save 8 bytes per call. Decide based on benchmark
|
|
110
|
-
// results.
|
|
111
252
|
void InitializeClientStream(const uint32_t stream_id,
|
|
112
253
|
const bool allow_true_binary_metadata_peer) {
|
|
113
|
-
GRPC_DCHECK(
|
|
114
|
-
<< "Client Only Function";
|
|
254
|
+
GRPC_DCHECK(is_client()) << "Client Only Function";
|
|
115
255
|
GRPC_DCHECK_NE(stream_id, 0u);
|
|
116
256
|
GRPC_DCHECK_EQ(this->stream_id_, 0u);
|
|
117
257
|
GRPC_HTTP2_STREAM_LOG << "Stream::InitializeClientStream stream_id="
|
|
@@ -148,7 +288,7 @@ class Stream : public RefCounted<Stream> {
|
|
|
148
288
|
}
|
|
149
289
|
|
|
150
290
|
auto EnqueueHalfClosed() {
|
|
151
|
-
GRPC_DCHECK(
|
|
291
|
+
GRPC_DCHECK(is_client());
|
|
152
292
|
GRPC_HTTP2_STREAM_LOG << "Stream::EnqueueHalfClosed";
|
|
153
293
|
return data_queue_->EnqueueHalfClosed();
|
|
154
294
|
}
|
|
@@ -164,14 +304,12 @@ class Stream : public RefCounted<Stream> {
|
|
|
164
304
|
const uint32_t stream_flow_control_tokens,
|
|
165
305
|
const uint32_t max_frame_length, HPackCompressor& encoder,
|
|
166
306
|
FrameSender& frame_sender) {
|
|
167
|
-
HttpStreamState state = stream_state_;
|
|
168
307
|
// Reset stream MUST not be sent if the stream is idle or closed.
|
|
169
308
|
return data_queue_->DequeueFrames(tokens, max_frame_length,
|
|
170
309
|
stream_flow_control_tokens, encoder,
|
|
171
310
|
frame_sender,
|
|
172
311
|
/*can_send_reset_stream=*/
|
|
173
|
-
!(
|
|
174
|
-
state == HttpStreamState::kClosed));
|
|
312
|
+
!(IsStreamIdle() || IsStreamClosed()));
|
|
175
313
|
}
|
|
176
314
|
|
|
177
315
|
auto UpdateStreamWritability(const int64_t stream_fc_tokens) {
|
|
@@ -180,105 +318,91 @@ class Stream : public RefCounted<Stream> {
|
|
|
180
318
|
|
|
181
319
|
////////////////////////////////////////////////////////////////////////////
|
|
182
320
|
// Stream State Management
|
|
183
|
-
// All state management helpers MUST be called from the transport party.
|
|
184
|
-
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
void MarkHalfClosedLocal() {
|
|
203
|
-
switch (stream_state_) {
|
|
204
|
-
case HttpStreamState::kIdle:
|
|
205
|
-
GRPC_DCHECK(false) << "MarkHalfClosedLocal called for an idle stream";
|
|
206
|
-
break;
|
|
207
|
-
case HttpStreamState::kOpen:
|
|
208
|
-
GRPC_HTTP2_STREAM_LOG
|
|
209
|
-
<< "Stream::MarkHalfClosedLocal stream_id=" << stream_id_
|
|
210
|
-
<< " transitioning to kHalfClosedLocal";
|
|
211
|
-
stream_state_ = HttpStreamState::kHalfClosedLocal;
|
|
212
|
-
break;
|
|
213
|
-
case HttpStreamState::kHalfClosedRemote:
|
|
214
|
-
GRPC_HTTP2_STREAM_LOG
|
|
215
|
-
<< "Stream::MarkHalfClosedLocal stream_id=" << stream_id_
|
|
216
|
-
<< " transitioning to kClosed";
|
|
217
|
-
stream_state_ = HttpStreamState::kClosed;
|
|
218
|
-
break;
|
|
219
|
-
case HttpStreamState::kHalfClosedLocal:
|
|
220
|
-
break;
|
|
221
|
-
case HttpStreamState::kClosed:
|
|
222
|
-
GRPC_HTTP2_STREAM_LOG
|
|
223
|
-
<< "Stream::MarkHalfClosedLocal stream_id=" << stream_id_
|
|
224
|
-
<< " already closed";
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
321
|
+
// All state management helpers, MUST be called from the transport party.
|
|
322
|
+
|
|
323
|
+
// HTTP/2 stream states
|
|
324
|
+
bool IsStreamIdle() const { return state_.IsIdle(); }
|
|
325
|
+
bool IsOpen() const { return state_.IsOpen(); }
|
|
326
|
+
bool IsStreamClosed() const { return state_.IsClosed(); }
|
|
327
|
+
bool IsStreamHalfClosedRemote() const { return state_.IsHalfClosedRemote(); }
|
|
328
|
+
bool IsHalfClosedLocal() const { return state_.IsHalfClosedLocal(); }
|
|
329
|
+
bool IsHalfClosedLocalSent() const { return state_.IsHalfClosedLocalSent(); }
|
|
330
|
+
|
|
331
|
+
// gRPC stream state
|
|
332
|
+
bool IsClosedForReads() const { return state_.reads_closed(); }
|
|
333
|
+
bool IsClosedForWrites() const { return state_.writes_closed(); }
|
|
334
|
+
|
|
335
|
+
// Semantic state transitions
|
|
336
|
+
void OnInitialMetadataSent() {
|
|
337
|
+
GRPC_DCHECK(is_client());
|
|
338
|
+
state_.OnInitialMetadataSent();
|
|
227
339
|
}
|
|
228
340
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
GRPC_DCHECK(false) << "MarkHalfClosedRemote called for an idle stream";
|
|
233
|
-
break;
|
|
234
|
-
case HttpStreamState::kOpen:
|
|
235
|
-
GRPC_HTTP2_STREAM_LOG
|
|
236
|
-
<< "Stream::MarkHalfClosedRemote stream_id=" << stream_id_
|
|
237
|
-
<< " transitioning to kHalfClosedRemote";
|
|
238
|
-
stream_state_ = HttpStreamState::kHalfClosedRemote;
|
|
239
|
-
break;
|
|
240
|
-
case HttpStreamState::kHalfClosedLocal:
|
|
241
|
-
GRPC_HTTP2_STREAM_LOG
|
|
242
|
-
<< "Stream::MarkHalfClosedRemote stream_id=" << stream_id_
|
|
243
|
-
<< " transitioning to kClosed";
|
|
244
|
-
stream_state_ = HttpStreamState::kClosed;
|
|
245
|
-
break;
|
|
246
|
-
case HttpStreamState::kHalfClosedRemote:
|
|
247
|
-
break;
|
|
248
|
-
case HttpStreamState::kClosed:
|
|
249
|
-
GRPC_HTTP2_STREAM_LOG
|
|
250
|
-
<< "Stream::MarkHalfClosedRemote stream_id=" << stream_id_
|
|
251
|
-
<< " already closed";
|
|
252
|
-
break;
|
|
253
|
-
}
|
|
341
|
+
StreamStateChange OnHalfCloseSent() {
|
|
342
|
+
GRPC_DCHECK(is_client());
|
|
343
|
+
return state_.OnHalfCloseSent();
|
|
254
344
|
}
|
|
255
345
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
346
|
+
StreamStateChange OnTrailingMetadataReceived(ServerMetadataHandle metadata) {
|
|
347
|
+
SetTrailingMetadataReceived();
|
|
348
|
+
const StreamStateChange change = state_.OnTrailingMetadataReceived();
|
|
349
|
+
if (is_client()) {
|
|
350
|
+
MaybePushServerTrailingMetadata(std::move(metadata));
|
|
351
|
+
} else {
|
|
352
|
+
// Server: custom HTTP2 implementations might send trailing metadata.
|
|
353
|
+
// We just close reads and do nothing else (upper layers discard client
|
|
354
|
+
// trailers).
|
|
355
|
+
GRPC_HTTP2_STREAM_LOG << "Stream::OnTrailingMetadataReceived Server "
|
|
356
|
+
"stream_id="
|
|
357
|
+
<< stream_id_
|
|
358
|
+
<< " StreamStateChange=" << change.DebugString();
|
|
359
|
+
if (change.reads_became_closed) {
|
|
360
|
+
GetCallInitiator().SpawnFinishSends();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return change;
|
|
261
364
|
}
|
|
262
|
-
|
|
263
|
-
|
|
365
|
+
|
|
366
|
+
StreamStateChange OnHalfCloseReceived() {
|
|
367
|
+
GRPC_DCHECK(is_server());
|
|
368
|
+
const StreamStateChange change = state_.OnHalfCloseReceived();
|
|
369
|
+
if (change.reads_became_closed) {
|
|
370
|
+
GetCallInitiator().SpawnFinishSends();
|
|
371
|
+
}
|
|
372
|
+
return change;
|
|
264
373
|
}
|
|
265
|
-
|
|
266
|
-
|
|
374
|
+
|
|
375
|
+
StreamStateChange OnResetReceived(absl::Status status) {
|
|
376
|
+
const StreamStateChange change = state_.OnResetReceived();
|
|
377
|
+
CancelCall(std::move(status));
|
|
378
|
+
return change;
|
|
267
379
|
}
|
|
268
380
|
|
|
269
|
-
|
|
381
|
+
StreamStateChange OnResetSent() {
|
|
382
|
+
const StreamStateChange change = state_.OnResetSent();
|
|
270
383
|
|
|
271
|
-
|
|
272
|
-
|
|
384
|
+
// Fallback cancel. Safe even for normal completion as CallSpine would have
|
|
385
|
+
// already processed trailing metadata, making Cancel a no-op.
|
|
386
|
+
CancelCall(absl::CancelledError("RST stream sent"));
|
|
387
|
+
return change;
|
|
273
388
|
}
|
|
274
389
|
|
|
275
|
-
|
|
276
|
-
|
|
390
|
+
StreamStateChange OnInitiateReset(absl::Status status) {
|
|
391
|
+
const StreamStateChange change = state_.OnInitiateReset();
|
|
392
|
+
CancelCall(std::move(status));
|
|
393
|
+
return change;
|
|
277
394
|
}
|
|
278
395
|
|
|
396
|
+
StreamStateChange ForceClose(absl::Status status) {
|
|
397
|
+
const StreamStateChange change = state_.ForceClose();
|
|
398
|
+
CancelCall(std::move(status));
|
|
399
|
+
return change;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
inline uint32_t GetStreamId() const { return stream_id_; }
|
|
403
|
+
|
|
279
404
|
inline bool CanSendWindowUpdateFrames() const {
|
|
280
|
-
return
|
|
281
|
-
stream_state_ == HttpStreamState::kHalfClosedLocal;
|
|
405
|
+
return IsOpen() || IsHalfClosedLocal();
|
|
282
406
|
}
|
|
283
407
|
|
|
284
408
|
inline Http2Status CanStreamReceiveDataFrames() const {
|
|
@@ -296,7 +420,7 @@ class Stream : public RefCounted<Stream> {
|
|
|
296
420
|
}
|
|
297
421
|
|
|
298
422
|
void MaybePushServerTrailingMetadata(ServerMetadataHandle&& metadata) {
|
|
299
|
-
GRPC_DCHECK(
|
|
423
|
+
GRPC_DCHECK(is_client());
|
|
300
424
|
GRPC_HTTP2_STREAM_LOG << "Stream::MaybePushServerTrailingMetadata "
|
|
301
425
|
"stream_id="
|
|
302
426
|
<< stream_id_
|
|
@@ -330,20 +454,45 @@ class Stream : public RefCounted<Stream> {
|
|
|
330
454
|
return std::get<CallHandler>(call_);
|
|
331
455
|
}
|
|
332
456
|
|
|
457
|
+
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION const CallHandler& GetCallHandler()
|
|
458
|
+
const {
|
|
459
|
+
return std::get<CallHandler>(call_);
|
|
460
|
+
}
|
|
461
|
+
|
|
333
462
|
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION CallInitiator& GetCallInitiator() {
|
|
334
463
|
return std::get<CallInitiator>(call_);
|
|
335
464
|
}
|
|
336
465
|
|
|
466
|
+
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION const CallInitiator& GetCallInitiator()
|
|
467
|
+
const {
|
|
468
|
+
return std::get<CallInitiator>(call_);
|
|
469
|
+
}
|
|
470
|
+
|
|
337
471
|
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION GrpcMessageAssembler&
|
|
338
472
|
GetGrpcMessageAssembler() {
|
|
339
473
|
return assembler_;
|
|
340
474
|
}
|
|
341
475
|
|
|
476
|
+
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION const GrpcMessageAssembler&
|
|
477
|
+
GetGrpcMessageAssembler() const {
|
|
478
|
+
return assembler_;
|
|
479
|
+
}
|
|
480
|
+
|
|
342
481
|
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION chttp2::StreamFlowControl&
|
|
343
482
|
GetStreamFlowControl() {
|
|
344
483
|
return flow_control_;
|
|
345
484
|
}
|
|
346
485
|
|
|
486
|
+
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION const chttp2::StreamFlowControl&
|
|
487
|
+
GetStreamFlowControl() const {
|
|
488
|
+
return flow_control_;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
bool is_client() const { return std::holds_alternative<CallHandler>(call_); }
|
|
492
|
+
bool is_server() const {
|
|
493
|
+
return std::holds_alternative<CallInitiator>(call_);
|
|
494
|
+
}
|
|
495
|
+
|
|
347
496
|
private:
|
|
348
497
|
void InitializeStream(const bool allow_true_binary_metadata_peer) {
|
|
349
498
|
GRPC_HTTP2_STREAM_LOG << "Stream::InitializeStream stream_id="
|
|
@@ -356,21 +505,23 @@ class Stream : public RefCounted<Stream> {
|
|
|
356
505
|
chttp2::StreamFlowControl flow_control_;
|
|
357
506
|
std::variant<CallInitiator, CallHandler> call_;
|
|
358
507
|
|
|
359
|
-
// This
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
508
|
+
// This function is idempotent.
|
|
509
|
+
void CancelCall(absl::Status&& status) {
|
|
510
|
+
if (std::exchange(did_cancel_, true)) return;
|
|
511
|
+
if (is_client()) {
|
|
512
|
+
MaybePushServerTrailingMetadata(
|
|
513
|
+
CancelledServerMetadataFromStatus(status));
|
|
514
|
+
} else {
|
|
515
|
+
GetCallInitiator().SpawnCancel(std::forward<absl::Status>(status));
|
|
516
|
+
}
|
|
517
|
+
}
|
|
368
518
|
|
|
369
|
-
|
|
370
|
-
|
|
519
|
+
StreamState state_;
|
|
520
|
+
uint32_t stream_id_;
|
|
371
521
|
bool did_receive_initial_metadata_;
|
|
372
522
|
bool did_receive_trailing_metadata_;
|
|
373
523
|
bool did_push_server_trailing_metadata_;
|
|
524
|
+
bool did_cancel_;
|
|
374
525
|
// Change this if ClientMetadataHandle and ServerMetadataHandle are changed
|
|
375
526
|
// to different types.
|
|
376
527
|
RefCountedPtr<StreamDataQueue<Arena::PoolPtr<grpc_metadata_batch>>>
|