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
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
//
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2026 gRPC authors.
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
//
|
|
17
|
+
|
|
18
|
+
#include "src/core/credentials/transport/tls/grpc_tls_certificate_selector.h"
|
|
19
|
+
|
|
20
|
+
#include <openssl/bio.h>
|
|
21
|
+
#include <openssl/crypto.h>
|
|
22
|
+
#include <openssl/pem.h>
|
|
23
|
+
#if defined(OPENSSL_IS_BORINGSSL)
|
|
24
|
+
#include <openssl/bytestring.h>
|
|
25
|
+
#endif
|
|
26
|
+
|
|
27
|
+
#include <cstdint>
|
|
28
|
+
#include <memory>
|
|
29
|
+
#include <vector>
|
|
30
|
+
|
|
31
|
+
#include "src/core/util/grpc_check.h"
|
|
32
|
+
#include "src/core/util/match.h"
|
|
33
|
+
#include "src/core/util/status_helper.h"
|
|
34
|
+
#include "absl/status/status.h"
|
|
35
|
+
#include "absl/status/statusor.h"
|
|
36
|
+
#include "absl/strings/string_view.h"
|
|
37
|
+
|
|
38
|
+
#if defined(OPENSSL_IS_BORINGSSL)
|
|
39
|
+
|
|
40
|
+
namespace grpc_core {
|
|
41
|
+
namespace {
|
|
42
|
+
|
|
43
|
+
// TODO(lwge): Consider moving these into a util library.
|
|
44
|
+
absl::StatusOr<std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>>
|
|
45
|
+
ParseCertificateChainFromDer(const std::vector<std::string>& der_cert_chain) {
|
|
46
|
+
if (der_cert_chain.empty()) {
|
|
47
|
+
return absl::InvalidArgumentError("The cert chain is empty.");
|
|
48
|
+
}
|
|
49
|
+
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> raw_cert_chain;
|
|
50
|
+
raw_cert_chain.reserve(der_cert_chain.size());
|
|
51
|
+
for (absl::string_view cert : der_cert_chain) {
|
|
52
|
+
bssl::UniquePtr<CRYPTO_BUFFER> raw_cert(CRYPTO_BUFFER_new(
|
|
53
|
+
reinterpret_cast<const uint8_t*>(cert.data()), cert.size(),
|
|
54
|
+
/*pool=*/nullptr));
|
|
55
|
+
if (raw_cert == nullptr) {
|
|
56
|
+
return absl::InvalidArgumentError("Failed to create raw cert.");
|
|
57
|
+
}
|
|
58
|
+
raw_cert_chain.push_back(std::move(raw_cert));
|
|
59
|
+
}
|
|
60
|
+
return std::move(raw_cert_chain);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
absl::StatusOr<std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>>
|
|
64
|
+
ParseCertificateChainFromPem(absl::string_view pem_cert_chain) {
|
|
65
|
+
if (pem_cert_chain.empty()) {
|
|
66
|
+
return absl::InvalidArgumentError("The cert chain is empty.");
|
|
67
|
+
}
|
|
68
|
+
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> raw_cert_chain;
|
|
69
|
+
bssl::UniquePtr<BIO> bio(
|
|
70
|
+
BIO_new_mem_buf(pem_cert_chain.data(), pem_cert_chain.size()));
|
|
71
|
+
uint8_t* cert_data = nullptr;
|
|
72
|
+
long cert_len;
|
|
73
|
+
while (PEM_bytes_read_bio(&cert_data, &cert_len, nullptr, PEM_STRING_X509,
|
|
74
|
+
bio.get(), nullptr, nullptr)) {
|
|
75
|
+
raw_cert_chain.push_back(bssl::UniquePtr<CRYPTO_BUFFER>(
|
|
76
|
+
CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(cert_data), cert_len,
|
|
77
|
+
/*pool=*/nullptr)));
|
|
78
|
+
OPENSSL_free(cert_data);
|
|
79
|
+
}
|
|
80
|
+
if (raw_cert_chain.empty()) {
|
|
81
|
+
return absl::InvalidArgumentError("Failed to parse cert chain.");
|
|
82
|
+
}
|
|
83
|
+
return std::move(raw_cert_chain);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
absl::StatusOr<bssl::UniquePtr<EVP_PKEY>> ParsePrivateKeyFromDer(
|
|
87
|
+
absl::string_view der_private_key) {
|
|
88
|
+
CBS cbs;
|
|
89
|
+
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(der_private_key.data()),
|
|
90
|
+
der_private_key.size());
|
|
91
|
+
bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_private_key(&cbs));
|
|
92
|
+
if (pkey == nullptr || CBS_len(&cbs) != 0) {
|
|
93
|
+
return absl::InvalidArgumentError("Failed to parse private key.");
|
|
94
|
+
}
|
|
95
|
+
return std::move(pkey);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
absl::StatusOr<bssl::UniquePtr<EVP_PKEY>> ParsePrivateKeyFromPem(
|
|
99
|
+
absl::string_view pem_private_key) {
|
|
100
|
+
GRPC_CHECK_LE(pem_private_key.size(), static_cast<size_t>(INT_MAX));
|
|
101
|
+
bssl::UniquePtr<BIO> pem(BIO_new_mem_buf(
|
|
102
|
+
pem_private_key.data(), static_cast<int>(pem_private_key.size())));
|
|
103
|
+
if (pem == nullptr) {
|
|
104
|
+
return absl::InvalidArgumentError("Failed to create pem BIO.");
|
|
105
|
+
}
|
|
106
|
+
bssl::UniquePtr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(
|
|
107
|
+
pem.get(), nullptr, nullptr, const_cast<char*>("")));
|
|
108
|
+
if (pkey == nullptr) {
|
|
109
|
+
return absl::InvalidArgumentError("Failed to read private key.");
|
|
110
|
+
}
|
|
111
|
+
return std::move(pkey);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// The type of the given private key string must match the parser.
|
|
115
|
+
absl::Status CreatePrivateKey(
|
|
116
|
+
std::variant<absl::string_view, std::shared_ptr<PrivateKeySigner>>
|
|
117
|
+
private_key,
|
|
118
|
+
CertificateSelector::SelectCertificateResult& result,
|
|
119
|
+
absl::AnyInvocable<
|
|
120
|
+
absl::StatusOr<bssl::UniquePtr<EVP_PKEY>>(absl::string_view)>
|
|
121
|
+
parser) {
|
|
122
|
+
return MatchMutable(
|
|
123
|
+
&private_key,
|
|
124
|
+
[&](absl::string_view* key) {
|
|
125
|
+
absl::StatusOr<bssl::UniquePtr<EVP_PKEY>> pkey = parser(*key);
|
|
126
|
+
if (!pkey.ok()) {
|
|
127
|
+
return pkey.status();
|
|
128
|
+
}
|
|
129
|
+
result.private_key = *std::move(pkey);
|
|
130
|
+
return absl::OkStatus();
|
|
131
|
+
},
|
|
132
|
+
[&](std::shared_ptr<PrivateKeySigner>* key_signer) {
|
|
133
|
+
result.private_key = std::move(*key_signer);
|
|
134
|
+
return absl::OkStatus();
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
} // namespace
|
|
139
|
+
|
|
140
|
+
absl::StatusOr<CertificateSelector::SelectCertificateResult>
|
|
141
|
+
CertificateSelector::CreateSelectCertificateResult(
|
|
142
|
+
const std::vector<std::string>& der_cert_chain,
|
|
143
|
+
std::variant<absl::string_view, std::shared_ptr<PrivateKeySigner>>
|
|
144
|
+
der_private_key) {
|
|
145
|
+
absl::StatusOr<std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>> raw_cert_chain =
|
|
146
|
+
ParseCertificateChainFromDer(der_cert_chain);
|
|
147
|
+
GRPC_RETURN_IF_ERROR(raw_cert_chain.status());
|
|
148
|
+
SelectCertificateResult result;
|
|
149
|
+
result.certificate_chain = *std::move(raw_cert_chain);
|
|
150
|
+
GRPC_RETURN_IF_ERROR(
|
|
151
|
+
CreatePrivateKey(der_private_key, result, ParsePrivateKeyFromDer));
|
|
152
|
+
return std::move(result);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
absl::StatusOr<CertificateSelector::SelectCertificateResult>
|
|
156
|
+
CertificateSelector::CreateSelectCertificateResult(
|
|
157
|
+
absl::string_view pem_cert_chain,
|
|
158
|
+
std::variant<absl::string_view, std::shared_ptr<PrivateKeySigner>>
|
|
159
|
+
pem_private_key) {
|
|
160
|
+
absl::StatusOr<std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>> raw_cert_chain =
|
|
161
|
+
ParseCertificateChainFromPem(pem_cert_chain);
|
|
162
|
+
GRPC_RETURN_IF_ERROR(raw_cert_chain.status());
|
|
163
|
+
SelectCertificateResult result;
|
|
164
|
+
result.certificate_chain = *std::move(raw_cert_chain);
|
|
165
|
+
GRPC_RETURN_IF_ERROR(
|
|
166
|
+
CreatePrivateKey(pem_private_key, result, ParsePrivateKeyFromPem));
|
|
167
|
+
return std::move(result);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
} // namespace grpc_core
|
|
171
|
+
|
|
172
|
+
#endif // OPENSSL_IS_BORINGSSL
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
//
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2026 gRPC authors.
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
//
|
|
17
|
+
|
|
18
|
+
#ifndef GRPC_SRC_CORE_CREDENTIALS_TRANSPORT_TLS_GRPC_TLS_CERTIFICATE_SELECTOR_H
|
|
19
|
+
#define GRPC_SRC_CORE_CREDENTIALS_TRANSPORT_TLS_GRPC_TLS_CERTIFICATE_SELECTOR_H
|
|
20
|
+
|
|
21
|
+
#include <grpc/private_key_signer.h>
|
|
22
|
+
#include <openssl/bio.h>
|
|
23
|
+
|
|
24
|
+
#include <memory>
|
|
25
|
+
#include <string>
|
|
26
|
+
#include <variant>
|
|
27
|
+
#include <vector>
|
|
28
|
+
|
|
29
|
+
#include "absl/functional/any_invocable.h"
|
|
30
|
+
#include "absl/status/statusor.h"
|
|
31
|
+
#include "absl/strings/string_view.h"
|
|
32
|
+
|
|
33
|
+
namespace grpc_core {
|
|
34
|
+
|
|
35
|
+
// Performs server-side certificate selection during the handshake based on the
|
|
36
|
+
// SNI. Users must implement the `SelectCertificate` and `Cancel` methods.
|
|
37
|
+
// The implementation must be thread-safe, as `SelectCertificate` may be called
|
|
38
|
+
// for multiple TLS handshakes at the same time.
|
|
39
|
+
class CertificateSelector {
|
|
40
|
+
#if defined(OPENSSL_IS_BORINGSSL)
|
|
41
|
+
public:
|
|
42
|
+
struct SelectCertificateInfo {
|
|
43
|
+
std::string sni;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// TODO(lwge): This should be an opaque struct when moved to a public header.
|
|
47
|
+
struct SelectCertificateResult {
|
|
48
|
+
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> certificate_chain;
|
|
49
|
+
std::variant<bssl::UniquePtr<EVP_PKEY>, std::shared_ptr<PrivateKeySigner>>
|
|
50
|
+
private_key;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Returns a SelectCertificateResult given a DER-encoded certificate chain,
|
|
54
|
+
// and DER-encoded private key string or a signer.
|
|
55
|
+
static absl::StatusOr<SelectCertificateResult> CreateSelectCertificateResult(
|
|
56
|
+
const std::vector<std::string>& der_cert_chain,
|
|
57
|
+
std::variant<absl::string_view, std::shared_ptr<PrivateKeySigner>>
|
|
58
|
+
der_private_key);
|
|
59
|
+
|
|
60
|
+
// Returns a SelectCertificateResult given a PEM-encoded certificate chain,
|
|
61
|
+
// and PEM-encoded private key string or a signer.
|
|
62
|
+
static absl::StatusOr<SelectCertificateResult> CreateSelectCertificateResult(
|
|
63
|
+
absl::string_view pem_cert_chain,
|
|
64
|
+
std::variant<absl::string_view, std::shared_ptr<PrivateKeySigner>>
|
|
65
|
+
pem_private_key);
|
|
66
|
+
|
|
67
|
+
// Handle to be passed to `Cancel`, to enable user to clean up any resources
|
|
68
|
+
// used during an asynchronous certificate selection operation that is
|
|
69
|
+
// cancelled.
|
|
70
|
+
class AsyncCertificateSelectionHandle {
|
|
71
|
+
public:
|
|
72
|
+
virtual ~AsyncCertificateSelectionHandle() = default;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
using OnSelectCertificateComplete =
|
|
76
|
+
absl::AnyInvocable<void(absl::StatusOr<SelectCertificateResult>)>;
|
|
77
|
+
|
|
78
|
+
virtual ~CertificateSelector() = default;
|
|
79
|
+
|
|
80
|
+
// Performs the cert selection based on `SelectCertificateInfo`.
|
|
81
|
+
// Since the client is not required to provide the server name in the
|
|
82
|
+
// ClientHello, the implementation should make a decision by itself on what to
|
|
83
|
+
// return.
|
|
84
|
+
// May return either synchronously or asynchronously.
|
|
85
|
+
// For synchronous returns, directly returns either the selected certificate
|
|
86
|
+
// or a failed status, and the callback will never be invoked.
|
|
87
|
+
// For asynchronous implementations, returns a handle for the asynchronous
|
|
88
|
+
// signing operation. The function argument on_complete must be called by
|
|
89
|
+
// the implementer when the async certificate selection operation is complete.
|
|
90
|
+
// on_complete must not be invoked synchronously within SelectCertificate().
|
|
91
|
+
virtual std::variant<absl::StatusOr<SelectCertificateResult>,
|
|
92
|
+
std::shared_ptr<AsyncCertificateSelectionHandle>>
|
|
93
|
+
SelectCertificate(const SelectCertificateInfo& info,
|
|
94
|
+
OnSelectCertificateComplete on_complete) = 0;
|
|
95
|
+
|
|
96
|
+
// Cancels the async select cert call corresponding to the handle.
|
|
97
|
+
virtual void Cancel(std::shared_ptr<AsyncCertificateSelectionHandle>) = 0;
|
|
98
|
+
#endif // OPENSSL_IS_BORINGSSL
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
} // namespace grpc_core
|
|
102
|
+
|
|
103
|
+
#endif // GRPC_SRC_CORE_CREDENTIALS_TRANSPORT_TLS_GRPC_TLS_CERTIFICATE_SELECTOR_H
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
#include <grpc/support/port_platform.h>
|
|
20
20
|
|
|
21
21
|
#if !defined(GPR_LINUX) && !defined(GPR_ANDROID) && !defined(GPR_FREEBSD) && \
|
|
22
|
-
!defined(GPR_APPLE) && !defined(
|
|
22
|
+
!defined(GPR_APPLE) && !defined(GPR_NETBSD) && !defined(GPR_OPENBSD) && \
|
|
23
|
+
!defined(GPR_WINDOWS)
|
|
23
24
|
|
|
24
25
|
#include <grpc/slice.h>
|
|
25
26
|
#include <grpc/slice_buffer.h>
|
|
@@ -33,4 +34,4 @@ grpc_slice LoadSystemRootCerts() { return grpc_empty_slice(); }
|
|
|
33
34
|
} // namespace grpc_core
|
|
34
35
|
|
|
35
36
|
#endif // !(GPR_LINUX || GPR_ANDROID || GPR_FREEBSD || GPR_APPLE ||
|
|
36
|
-
// GPR_WINDOWS)
|
|
37
|
+
// GPR_NETBSD || GPR_OPENBSD || GPR_WINDOWS)
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
#include <vector>
|
|
24
24
|
|
|
25
25
|
#if defined(GPR_LINUX) || defined(GPR_ANDROID) || defined(GPR_FREEBSD) || \
|
|
26
|
-
defined(GPR_APPLE)
|
|
26
|
+
defined(GPR_APPLE) || defined(GPR_NETBSD) || defined(GPR_OPENBSD)
|
|
27
27
|
|
|
28
28
|
#include <dirent.h>
|
|
29
29
|
#include <fcntl.h>
|
|
@@ -59,7 +59,13 @@ const char* kCertDirectories[] = {""};
|
|
|
59
59
|
#elif defined(GPR_APPLE) // endif GPR_FREEBSD
|
|
60
60
|
const char* kCertFiles[] = {"/etc/ssl/cert.pem"};
|
|
61
61
|
const char* kCertDirectories[] = {""};
|
|
62
|
-
#
|
|
62
|
+
#elif defined(GPR_NETBSD) // endif GPR_APPLE
|
|
63
|
+
const char* kCertFiles[] = {"/etc/openssl/certs/ca-certificates.crt"};
|
|
64
|
+
const char* kCertDirectories[] = {"/etc/openssl/certs"};
|
|
65
|
+
#elif defined(GPR_OPENBSD) // endif GPR_NETBSD
|
|
66
|
+
const char* kCertFiles[] = {"/etc/ssl/cert.pem"};
|
|
67
|
+
const char* kCertDirectories[] = {""};
|
|
68
|
+
#endif // GPR_OPENBSD
|
|
63
69
|
|
|
64
70
|
grpc_slice GetSystemRootCerts() {
|
|
65
71
|
size_t num_cert_files_ = GPR_ARRAY_SIZE(kCertFiles);
|
|
@@ -163,4 +169,5 @@ grpc_slice LoadSystemRootCerts() {
|
|
|
163
169
|
|
|
164
170
|
} // namespace grpc_core
|
|
165
171
|
|
|
166
|
-
#endif // GPR_LINUX || GPR_ANDROID || GPR_FREEBSD || GPR_APPLE
|
|
172
|
+
#endif // GPR_LINUX || GPR_ANDROID || GPR_FREEBSD || GPR_APPLE ||
|
|
173
|
+
// GPR_NETNSD || GPR_OPENBSD
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
#include "src/core/lib/channel/channel_args.h"
|
|
40
40
|
#include "src/core/lib/iomgr/exec_ctx.h"
|
|
41
41
|
#include "src/core/lib/promise/promise.h"
|
|
42
|
+
#include "src/core/telemetry/metrics.h"
|
|
42
43
|
#include "src/core/transport/auth_context.h"
|
|
43
44
|
#include "src/core/tsi/ssl_transport_security.h"
|
|
44
45
|
#include "src/core/util/debug_location.h"
|
|
@@ -363,11 +364,17 @@ void TlsChannelSecurityConnector::add_handshakers(
|
|
|
363
364
|
? target_name_.c_str()
|
|
364
365
|
: overridden_target_name_.c_str();
|
|
365
366
|
}
|
|
367
|
+
auto stats_plugin_group =
|
|
368
|
+
args.GetObject<GlobalStatsPluginRegistry::StatsPluginGroup>();
|
|
369
|
+
RefCountedPtr<CollectionScope> collection_scope =
|
|
370
|
+
stats_plugin_group != nullptr ? stats_plugin_group->GetCollectionScope()
|
|
371
|
+
: nullptr;
|
|
366
372
|
tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
|
|
367
373
|
client_handshaker_factory_, server_name_indication,
|
|
368
374
|
/*network_bio_buf_size=*/0,
|
|
369
375
|
/*ssl_bio_buf_size=*/0,
|
|
370
|
-
args.GetOwnedString(GRPC_ARG_TRANSPORT_PROTOCOLS),
|
|
376
|
+
args.GetOwnedString(GRPC_ARG_TRANSPORT_PROTOCOLS),
|
|
377
|
+
std::move(collection_scope), &tsi_hs);
|
|
371
378
|
if (result != TSI_OK) {
|
|
372
379
|
LOG(ERROR) << "Handshaker creation failed with error "
|
|
373
380
|
<< tsi_result_to_string(result);
|
|
@@ -648,10 +655,15 @@ void TlsServerSecurityConnector::add_handshakers(
|
|
|
648
655
|
MutexLock lock(&mu_);
|
|
649
656
|
tsi_handshaker* tsi_hs = nullptr;
|
|
650
657
|
if (server_handshaker_factory_ != nullptr) {
|
|
658
|
+
auto stats_plugin_group =
|
|
659
|
+
args.GetObject<GlobalStatsPluginRegistry::StatsPluginGroup>();
|
|
660
|
+
RefCountedPtr<CollectionScope> collection_scope =
|
|
661
|
+
stats_plugin_group != nullptr ? stats_plugin_group->GetCollectionScope()
|
|
662
|
+
: nullptr;
|
|
651
663
|
// Instantiate TSI handshaker.
|
|
652
664
|
tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
|
|
653
665
|
server_handshaker_factory_, /*network_bio_buf_size=*/0,
|
|
654
|
-
/*ssl_bio_buf_size=*/0, &tsi_hs);
|
|
666
|
+
/*ssl_bio_buf_size=*/0, std::move(collection_scope), &tsi_hs);
|
|
655
667
|
if (result != TSI_OK) {
|
|
656
668
|
LOG(ERROR) << "Handshaker creation failed with error "
|
|
657
669
|
<< tsi_result_to_string(result);
|
|
@@ -20,17 +20,16 @@
|
|
|
20
20
|
|
|
21
21
|
#include <grpc/grpc_security_constants.h>
|
|
22
22
|
#include <grpc/impl/channel_arg_names.h>
|
|
23
|
-
#include <grpc/support/port_platform.h>
|
|
24
23
|
|
|
25
24
|
#include <optional>
|
|
26
25
|
|
|
26
|
+
#include "src/core/config/experiment_env_var.h"
|
|
27
27
|
#include "src/core/credentials/transport/tls/grpc_tls_certificate_provider.h"
|
|
28
28
|
#include "src/core/credentials/transport/tls/grpc_tls_credentials_options.h"
|
|
29
29
|
#include "src/core/credentials/transport/tls/tls_credentials.h"
|
|
30
30
|
#include "src/core/credentials/transport/tls/tls_utils.h"
|
|
31
31
|
#include "src/core/lib/channel/channel_args.h"
|
|
32
32
|
#include "src/core/load_balancing/xds/xds_channel_args.h"
|
|
33
|
-
#include "src/core/util/env.h"
|
|
34
33
|
#include "src/core/util/grpc_check.h"
|
|
35
34
|
#include "src/core/util/host_port.h"
|
|
36
35
|
#include "src/core/util/useful.h"
|
|
@@ -40,15 +39,6 @@ namespace grpc_core {
|
|
|
40
39
|
|
|
41
40
|
namespace {
|
|
42
41
|
|
|
43
|
-
// TODO(mlumish): Remove this after 1.80
|
|
44
|
-
bool UseChannelAuthorityIfNoSNIApplicable() {
|
|
45
|
-
auto value = GetEnv("GRPC_USE_CHANNEL_AUTHORITY_IF_NO_SNI_APPLICABLE");
|
|
46
|
-
if (!value.has_value()) return false;
|
|
47
|
-
bool parsed_value;
|
|
48
|
-
bool parse_succeeded = gpr_parse_bool_value(value->c_str(), &parsed_value);
|
|
49
|
-
return parse_succeeded && parsed_value;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
42
|
bool XdsVerifySubjectAlternativeNames(
|
|
53
43
|
const char* const* subject_alternative_names,
|
|
54
44
|
size_t subject_alternative_names_size,
|
|
@@ -194,7 +184,9 @@ XdsCredentials::create_security_connector(
|
|
|
194
184
|
tls_credentials_options->set_sni_override(
|
|
195
185
|
xds_certificate_provider->sni());
|
|
196
186
|
} else {
|
|
197
|
-
|
|
187
|
+
// TODO(mlumish): Remove this after 1.80
|
|
188
|
+
if (!IsExperimentEnvVarEnabled(
|
|
189
|
+
"GRPC_USE_CHANNEL_AUTHORITY_IF_NO_SNI_APPLICABLE")) {
|
|
198
190
|
tls_credentials_options->set_sni_override("");
|
|
199
191
|
}
|
|
200
192
|
}
|
|
@@ -205,7 +205,8 @@ struct RbacConfig {
|
|
|
205
205
|
std::map<std::string, Policy> policies;
|
|
206
206
|
// Defaults to kNone since its json field is optional.
|
|
207
207
|
Rbac::AuditCondition audit_condition = Rbac::AuditCondition::kNone;
|
|
208
|
-
std::vector<std::
|
|
208
|
+
std::vector<std::shared_ptr<const AuditLoggerFactory::Config>>
|
|
209
|
+
logger_configs;
|
|
209
210
|
|
|
210
211
|
Rules() {}
|
|
211
212
|
Rules(const Rules&) = delete;
|
|
@@ -438,11 +438,16 @@ void NewChttp2ServerListener::ActiveConnection::SendGoAwayImplLocked() {
|
|
|
438
438
|
transport->PerformOp(op);
|
|
439
439
|
}
|
|
440
440
|
},
|
|
441
|
-
[](
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
441
|
+
[](const RefCountedPtr<http2::Http2ServerTransport>& transport) {
|
|
442
|
+
// Send a GOAWAY if the transport exists
|
|
443
|
+
if (transport != nullptr) {
|
|
444
|
+
grpc_transport_op* op = grpc_make_transport_op(nullptr);
|
|
445
|
+
// We send a non-ok status here to send the status message in the
|
|
446
|
+
// GOAWAY frame.
|
|
447
|
+
op->goaway_error =
|
|
448
|
+
absl::UnavailableError("Server is stopping to serve requests.");
|
|
449
|
+
transport->PerformOp(op);
|
|
450
|
+
}
|
|
446
451
|
});
|
|
447
452
|
}
|
|
448
453
|
}
|
|
@@ -468,11 +473,14 @@ void NewChttp2ServerListener::ActiveConnection::
|
|
|
468
473
|
transport->PerformOp(op);
|
|
469
474
|
}
|
|
470
475
|
},
|
|
471
|
-
[](
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
+
[](const RefCountedPtr<http2::Http2ServerTransport>& transport) {
|
|
477
|
+
// Disconnect immediately if the transport exists
|
|
478
|
+
if (transport != nullptr) {
|
|
479
|
+
grpc_transport_op* op = grpc_make_transport_op(nullptr);
|
|
480
|
+
op->disconnect_with_error = absl::UnavailableError(
|
|
481
|
+
"Drain grace time expired. Closing connection immediately.");
|
|
482
|
+
transport->PerformOp(op);
|
|
483
|
+
}
|
|
476
484
|
});
|
|
477
485
|
}
|
|
478
486
|
|
|
@@ -736,9 +744,7 @@ absl::StatusOr<int> Chttp2ServerAddPort(Server* server, const char* addr,
|
|
|
736
744
|
resolved = grpc_resolve_vsock_address(parsed_addr_unprefixed);
|
|
737
745
|
GRPC_RETURN_IF_ERROR(resolved.status());
|
|
738
746
|
} else {
|
|
739
|
-
if (IsEventEngineDnsNonClientChannelEnabled()
|
|
740
|
-
!grpc_event_engine::experimental::
|
|
741
|
-
EventEngineExperimentDisabledForPython()) {
|
|
747
|
+
if (IsEventEngineDnsNonClientChannelEnabled()) {
|
|
742
748
|
absl::StatusOr<std::unique_ptr<EventEngine::DNSResolver>> ee_resolver =
|
|
743
749
|
args.GetObjectRef<EventEngine>()->GetDNSResolver(
|
|
744
750
|
EventEngine::DNSResolver::ResolverOptions());
|
|
@@ -545,6 +545,10 @@ static void read_channel_args(grpc_chttp2_transport* t,
|
|
|
545
545
|
|
|
546
546
|
t->settings.mutable_local().SetAllowSecurityFrame(
|
|
547
547
|
channel_args.GetBool(GRPC_ARG_SECURITY_FRAME_ALLOWED).value_or(false));
|
|
548
|
+
t->max_security_frame_size = static_cast<uint32_t>(grpc_core::Clamp(
|
|
549
|
+
channel_args.GetInt(GRPC_ARG_MAX_SECURITY_FRAME_SIZE)
|
|
550
|
+
.value_or(kMaxSecurityFrameSize),
|
|
551
|
+
kMinMaxSecurityFrameSize, static_cast<int>(kMaxSecurityFrameSize)));
|
|
548
552
|
|
|
549
553
|
t->ping_on_rst_stream_percent = grpc_core::Clamp(
|
|
550
554
|
channel_args.GetInt(GRPC_ARG_HTTP2_PING_ON_RST_STREAM_PERCENT)
|
|
@@ -759,7 +763,8 @@ grpc_chttp2_transport::grpc_chttp2_transport(
|
|
|
759
763
|
grpc_core::GlobalStatsPluginRegistry::StatsPluginGroup>();
|
|
760
764
|
if (epte != nullptr && stats_plugin_group != nullptr) {
|
|
761
765
|
epte->EnableTcpTelemetry(stats_plugin_group->GetCollectionScope(),
|
|
762
|
-
/*is_control_endpoint=*/false
|
|
766
|
+
/*is_control_endpoint=*/false,
|
|
767
|
+
/*trace_full_buffer=*/false);
|
|
763
768
|
epte->SetTcpTracer(std::make_shared<grpc_core::DefaultTcpTracer>(
|
|
764
769
|
std::move(stats_plugin_group)));
|
|
765
770
|
}
|
|
@@ -1372,14 +1377,11 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t,
|
|
|
1372
1377
|
uint32_t last_stream_id,
|
|
1373
1378
|
absl::string_view goaway_text) {
|
|
1374
1379
|
t->goaway_error = grpc_error_set_int(
|
|
1375
|
-
grpc_error_set_int(
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
DEBUG_LOCATION, {}),
|
|
1381
|
-
grpc_core::StatusIntProperty::kHttp2Error,
|
|
1382
|
-
static_cast<intptr_t>(goaway_error)),
|
|
1380
|
+
grpc_error_set_int(absl::UnavailableError(absl::StrFormat(
|
|
1381
|
+
"GOAWAY received; Error code: %u; Debug Text: %s",
|
|
1382
|
+
goaway_error, goaway_text)),
|
|
1383
|
+
grpc_core::StatusIntProperty::kHttp2Error,
|
|
1384
|
+
static_cast<intptr_t>(goaway_error)),
|
|
1383
1385
|
grpc_core::StatusIntProperty::kRpcStatus, GRPC_STATUS_UNAVAILABLE);
|
|
1384
1386
|
|
|
1385
1387
|
GRPC_TRACE_LOG(http, INFO)
|
|
@@ -119,12 +119,12 @@ std::string FlowControlAction::ImmediateUpdateReasons() const {
|
|
|
119
119
|
return result;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
TransportFlowControl::TransportFlowControl(absl::string_view
|
|
122
|
+
TransportFlowControl::TransportFlowControl(absl::string_view peer_name,
|
|
123
123
|
bool enable_bdp_probe,
|
|
124
124
|
MemoryOwner* memory_owner)
|
|
125
125
|
: memory_owner_(memory_owner),
|
|
126
126
|
enable_bdp_probe_(enable_bdp_probe),
|
|
127
|
-
bdp_estimator_(
|
|
127
|
+
bdp_estimator_(peer_name) {}
|
|
128
128
|
|
|
129
129
|
uint32_t TransportFlowControl::DesiredAnnounceSize(bool writing_anyway) const {
|
|
130
130
|
const uint32_t target_announced_window =
|
|
@@ -201,7 +201,8 @@ std::ostream& operator<<(std::ostream& out, const FlowControlAction& action);
|
|
|
201
201
|
// This class manages the flow control at a connection level.
|
|
202
202
|
class TransportFlowControl final {
|
|
203
203
|
public:
|
|
204
|
-
explicit TransportFlowControl(absl::string_view
|
|
204
|
+
explicit TransportFlowControl(absl::string_view peer_name,
|
|
205
|
+
bool enable_bdp_probe,
|
|
205
206
|
MemoryOwner* memory_owner);
|
|
206
207
|
~TransportFlowControl() {}
|
|
207
208
|
|
|
@@ -318,7 +319,7 @@ class TransportFlowControl final {
|
|
|
318
319
|
// Call periodically (at a low-ish rate, 100ms - 10s makes sense)
|
|
319
320
|
// to perform more complex flow control calculations and return an action
|
|
320
321
|
// to let the transport change its parameters.
|
|
321
|
-
// TODO(tjagtap) [PH2][P2] Plumb with PH2 flow control.
|
|
322
|
+
// TODO(tjagtap) [PH2][P2][FCV3] Plumb with PH2 flow control.
|
|
322
323
|
FlowControlAction PeriodicUpdate();
|
|
323
324
|
|
|
324
325
|
int64_t test_only_target_window() const { return target_window(); }
|
|
@@ -831,7 +831,8 @@ Http2Status ValidateFrameHeader(const uint32_t max_frame_size_setting,
|
|
|
831
831
|
const uint32_t last_stream_id,
|
|
832
832
|
const bool is_client,
|
|
833
833
|
const bool is_first_settings_processed,
|
|
834
|
-
Http2FrameCountTracker& tracker
|
|
834
|
+
Http2FrameCountTracker& tracker,
|
|
835
|
+
const uint32_t max_security_frame_size) {
|
|
835
836
|
const bool is_data_frame =
|
|
836
837
|
current_frame_header.type == static_cast<uint8_t>(FrameType::kData);
|
|
837
838
|
const bool is_continuation_frame =
|
|
@@ -861,6 +862,16 @@ Http2Status ValidateFrameHeader(const uint32_t max_frame_size_setting,
|
|
|
861
862
|
", Max Size = ", max_frame_size_setting));
|
|
862
863
|
}
|
|
863
864
|
|
|
865
|
+
if (GPR_UNLIKELY(current_frame_header.type ==
|
|
866
|
+
static_cast<uint8_t>(FrameType::kCustomSecurity) &&
|
|
867
|
+
current_frame_header.length > max_security_frame_size)) {
|
|
868
|
+
return Http2Status::Http2ConnectionError(
|
|
869
|
+
Http2ErrorCode::kFrameSizeError,
|
|
870
|
+
absl::StrCat(GrpcErrors::kSecurityFrameTooLarge,
|
|
871
|
+
max_security_frame_size,
|
|
872
|
+
", Received size : ", current_frame_header.length));
|
|
873
|
+
}
|
|
874
|
+
|
|
864
875
|
// RFC 9113 (Section 6.10) requires that if a HEADERS frame does not have
|
|
865
876
|
// END_HEADERS set, it must be followed by a contiguous sequence of
|
|
866
877
|
// CONTINUATION frames for the same stream, ending with END_HEADERS. No other
|
|
@@ -928,3 +939,49 @@ Http2Status ValidateFrameHeader(const uint32_t max_frame_size_setting,
|
|
|
928
939
|
return Http2Status::Ok();
|
|
929
940
|
}
|
|
930
941
|
} // namespace grpc_core
|
|
942
|
+
|
|
943
|
+
/*
|
|
944
|
+
A note on Security Frames
|
|
945
|
+
|
|
946
|
+
Security Frame is a custom frame defined by gRPC.
|
|
947
|
+
|
|
948
|
+
SECURITY Frame
|
|
949
|
+
|
|
950
|
+
The SECURITY frame (type=200) is used to transmit out-of-band security and
|
|
951
|
+
transport-level privacy information between peers.
|
|
952
|
+
|
|
953
|
+
Both peers MUST agree to allow SECURITY frames.
|
|
954
|
+
|
|
955
|
+
+------------------------+
|
|
956
|
+
| Payload Length |
|
|
957
|
+
| (24) |
|
|
958
|
+
+--------+--------+------+
|
|
959
|
+
| Type | Flags |
|
|
960
|
+
| (200) | (8) |
|
|
961
|
+
+-+------+--------+---------------+
|
|
962
|
+
|R| Stream Identifier |
|
|
963
|
+
| | (31) |
|
|
964
|
+
+=+===============================+
|
|
965
|
+
| Security Payload (*) ...
|
|
966
|
+
+---------------------------------+
|
|
967
|
+
|
|
968
|
+
The SECURITY frame payload contains opaque data intended for the registered
|
|
969
|
+
transport framing endpoint extension.
|
|
970
|
+
|
|
971
|
+
The SECURITY frame does not define flags.
|
|
972
|
+
|
|
973
|
+
Payload Size Limits and Chunking
|
|
974
|
+
|
|
975
|
+
The current implementation of the SECURITY frame has a HARD limit of 16,384
|
|
976
|
+
bytes (16 KB) for its payload.
|
|
977
|
+
|
|
978
|
+
This strict 16 KB limit is enforced because 16,384 bytes is the minimum
|
|
979
|
+
valid value for SETTINGS_MAX_FRAME_SIZE (the smallest maximum frame size an
|
|
980
|
+
HTTP/2 peer is allowed to advertise). Currently, the SECURITY frame does not
|
|
981
|
+
support chunking. Therefore, if a peer attempts to send a SECURITY payload
|
|
982
|
+
larger than the receiver's advertised SETTINGS_MAX_FRAME_SIZE, the endpoint
|
|
983
|
+
MUST treat this as a CONNECTION ERROR of type FRAME_SIZE_ERROR. By enforcing
|
|
984
|
+
a hard 16 KB upper bound, we guarantee that the frame will safely fit within any
|
|
985
|
+
compliant peer's single-frame receive buffer without requiring payload chunking.
|
|
986
|
+
|
|
987
|
+
*/
|