grpc 1.82.0 → 1.83.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8 -5
  3. data/etc/roots.pem +10400 -3855
  4. data/include/grpc/grpc_audit_logging.h +2 -2
  5. data/include/grpc/grpc_security_constants.h +2 -0
  6. data/include/grpc/impl/channel_arg_names.h +23 -0
  7. data/src/core/call/call_filters.h +19 -3
  8. data/src/core/call/call_spine.h +4 -4
  9. data/src/core/call/client_call.cc +1 -1
  10. data/src/core/call/metadata.cc +7 -2
  11. data/src/core/call/server_call.cc +13 -3
  12. data/src/core/call/server_call.h +5 -3
  13. data/src/core/client_channel/backup_poller.cc +2 -17
  14. data/src/core/client_channel/client_channel.cc +17 -14
  15. data/src/core/client_channel/client_channel.h +3 -1
  16. data/src/core/client_channel/client_channel_filter.cc +11 -13
  17. data/src/core/client_channel/client_channel_service_config.cc +5 -13
  18. data/src/core/client_channel/direct_channel.cc +5 -1
  19. data/src/core/client_channel/direct_channel.h +3 -1
  20. data/src/core/config/experiment_env_var.cc +30 -0
  21. data/src/core/config/experiment_env_var.h +26 -0
  22. data/src/core/credentials/call/regional_access_boundary_fetcher.cc +6 -6
  23. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +14 -2
  24. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.cc +172 -0
  25. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.h +103 -0
  26. data/src/core/credentials/transport/tls/load_system_roots_fallback.cc +3 -2
  27. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +10 -3
  28. data/src/core/credentials/transport/tls/tls_security_connector.cc +14 -2
  29. data/src/core/credentials/transport/xds/xds_credentials.cc +4 -12
  30. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +2 -1
  31. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +19 -13
  32. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +11 -9
  33. data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -2
  34. data/src/core/ext/transport/chttp2/transport/flow_control.h +3 -2
  35. data/src/core/ext/transport/chttp2/transport/frame.cc +58 -1
  36. data/src/core/ext/transport/chttp2/transport/frame.h +13 -1
  37. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -4
  38. data/src/core/ext/transport/chttp2/transport/frame_security.cc +10 -1
  39. data/src/core/ext/transport/chttp2/transport/frame_security.h +2 -1
  40. data/src/core/ext/transport/chttp2/transport/goaway.cc +11 -1
  41. data/src/core/ext/transport/chttp2/transport/goaway.h +17 -1
  42. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +9 -0
  43. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +117 -276
  44. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +44 -17
  45. data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +382 -496
  46. data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +75 -77
  47. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -1
  48. data/src/core/ext/transport/chttp2/transport/http2_settings.h +30 -11
  49. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +24 -9
  50. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +26 -0
  51. data/src/core/ext/transport/chttp2/transport/http2_transport.h +2 -0
  52. data/src/core/ext/transport/chttp2/transport/internal.h +4 -0
  53. data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
  54. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +1 -1
  55. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +4 -10
  56. data/src/core/ext/transport/chttp2/transport/read_context.h +62 -20
  57. data/src/core/ext/transport/chttp2/transport/security_frame.h +1 -0
  58. data/src/core/ext/transport/chttp2/transport/stream.h +271 -120
  59. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +77 -61
  60. data/src/core/handshaker/security/secure_endpoint.cc +0 -13
  61. data/src/core/lib/channel/promise_based_filter.cc +77 -3
  62. data/src/core/lib/channel/promise_based_filter.h +238 -184
  63. data/src/core/lib/event_engine/extensions/receive_coalescing_extension.h +0 -4
  64. data/src/core/lib/event_engine/extensions/tcp_trace.h +1 -1
  65. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +2 -12
  66. data/src/core/lib/event_engine/shim.cc +2 -16
  67. data/src/core/lib/event_engine/shim.h +0 -4
  68. data/src/core/lib/experiments/experiments.cc +51 -102
  69. data/src/core/lib/experiments/experiments.h +37 -59
  70. data/src/core/lib/iomgr/error.cc +3 -73
  71. data/src/core/lib/iomgr/error.h +8 -6
  72. data/src/core/lib/iomgr/error_cfstream.cc +1 -2
  73. data/src/core/lib/iomgr/ev_epoll1_linux.cc +2 -6
  74. data/src/core/lib/iomgr/ev_poll_posix.cc +2 -6
  75. data/src/core/lib/iomgr/tcp_posix.cc +2 -6
  76. data/src/core/lib/security/authorization/audit_logging.cc +2 -2
  77. data/src/core/lib/security/authorization/audit_logging.h +3 -3
  78. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +11 -13
  79. data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
  80. data/src/core/lib/security/authorization/matchers.cc +20 -20
  81. data/src/core/lib/security/authorization/matchers.h +15 -16
  82. data/src/core/lib/security/authorization/rbac_policy.h +1 -1
  83. data/src/core/lib/security/authorization/stdout_logger.cc +3 -3
  84. data/src/core/lib/security/authorization/stdout_logger.h +6 -5
  85. data/src/core/lib/surface/call.cc +0 -8
  86. data/src/core/lib/surface/call.h +2 -0
  87. data/src/core/lib/surface/channel.cc +21 -2
  88. data/src/core/lib/surface/channel.h +14 -6
  89. data/src/core/lib/surface/filter_stack_call.cc +10 -29
  90. data/src/core/lib/surface/legacy_channel.cc +7 -7
  91. data/src/core/lib/surface/legacy_channel.h +3 -1
  92. data/src/core/lib/surface/version.cc +2 -2
  93. data/src/core/lib/transport/bdp_estimator.cc +13 -13
  94. data/src/core/lib/transport/bdp_estimator.h +9 -5
  95. data/src/core/lib/transport/error_utils.cc +26 -138
  96. data/src/core/lib/transport/promise_endpoint.h +2 -4
  97. data/src/core/load_balancing/grpclb/grpclb.cc +2 -1
  98. data/src/core/load_balancing/pick_first/pick_first.cc +33 -2
  99. data/src/core/load_balancing/pick_first/pick_first.h +6 -0
  100. data/src/core/load_balancing/ring_hash/ring_hash.cc +3 -10
  101. data/src/core/load_balancing/rls/rls.cc +2 -1
  102. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +2 -7
  103. data/src/core/load_balancing/xds/cds.cc +80 -56
  104. data/src/core/load_balancing/xds/cds.h +21 -0
  105. data/src/core/mitigation_engine/mitigation.h +53 -0
  106. data/src/core/mitigation_engine/mitigation_provider.h +62 -0
  107. data/src/core/resolver/dns/dns_resolver_plugin.cc +1 -6
  108. data/src/core/resolver/xds/xds_resolver.cc +14 -11
  109. data/src/core/server/server.h +1 -4
  110. data/src/core/server/server_config_selector.h +5 -4
  111. data/src/core/server/server_config_selector_filter.cc +67 -80
  112. data/src/core/server/xds_server_config_fetcher.cc +681 -692
  113. data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -12
  114. data/src/core/telemetry/call_tracer.cc +49 -2
  115. data/src/core/telemetry/call_tracer.h +1 -0
  116. data/src/core/telemetry/tcp_tracer.h +38 -0
  117. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  118. data/src/core/tsi/ssl_telemetry_utils.cc +343 -0
  119. data/src/core/tsi/ssl_telemetry_utils.h +74 -0
  120. data/src/core/tsi/ssl_transport_security.cc +577 -301
  121. data/src/core/tsi/ssl_transport_security.h +22 -6
  122. data/src/core/tsi/ssl_transport_security_utils.cc +2 -0
  123. data/src/core/tsi/transport_security.h +7 -0
  124. data/src/core/util/http_client/httpcli.cc +1 -4
  125. data/src/core/util/http_client/httpcli_security_connector.cc +2 -1
  126. data/src/core/util/status_helper.cc +71 -192
  127. data/src/core/util/status_helper.h +16 -21
  128. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +2 -11
  129. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -7
  130. data/src/core/xds/grpc/xds_cluster_parser.cc +5 -16
  131. data/src/core/xds/grpc/xds_common_types.cc +94 -38
  132. data/src/core/xds/grpc/xds_common_types.h +33 -18
  133. data/src/core/xds/grpc/xds_common_types_parser.cc +168 -100
  134. data/src/core/xds/grpc/xds_common_types_parser.h +18 -1
  135. data/src/core/xds/grpc/xds_endpoint_parser.cc +6 -17
  136. data/src/core/xds/grpc/xds_http_filter_registry.cc +2 -10
  137. data/src/core/xds/grpc/xds_http_rbac_filter.cc +3 -12
  138. data/src/core/xds/grpc/xds_metadata_parser.cc +0 -2
  139. data/src/core/xds/grpc/xds_route_config_parser.cc +7 -11
  140. data/src/core/xds/grpc/xds_routing.cc +113 -82
  141. data/src/core/xds/grpc/xds_routing.h +70 -20
  142. data/src/core/xds/grpc/xds_server_grpc.cc +22 -13
  143. data/src/core/xds/grpc/xds_server_grpc.h +16 -2
  144. data/src/core/xds/grpc/xds_server_grpc_interface.h +10 -0
  145. data/src/core/xds/grpc/xds_transport_grpc.cc +123 -18
  146. data/src/core/xds/grpc/xds_transport_grpc.h +28 -4
  147. data/src/core/xds/xds_client/lrs_client.cc +3 -7
  148. data/src/core/xds/xds_client/xds_bootstrap.cc +4 -16
  149. data/src/core/xds/xds_client/xds_client.cc +2 -15
  150. data/src/core/xds/xds_client/xds_transport.h +3 -0
  151. data/src/ruby/lib/grpc/version.rb +1 -1
  152. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +1 -1
  153. metadata +9 -1
@@ -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(GPR_WINDOWS)
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
- #endif // GPR_APPLE
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), &tsi_hs);
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
- if (!UseChannelAuthorityIfNoSNIApplicable()) {
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::unique_ptr<AuditLoggerFactory::Config>> logger_configs;
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
- [](GRPC_UNUSED const RefCountedPtr<http2::Http2ServerTransport>&
442
- transport) {
443
- // TODO(akshitpatel) [PH2][P0] : Add support for GOAWAY for
444
- // Http2ServerTransport.
445
- LOG(FATAL) << "Not implemented";
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
- [](GRPC_UNUSED const RefCountedPtr<http2::Http2ServerTransport>&
472
- transport) {
473
- // TODO(akshitpatel) [PH2][P0] : Add support for disconnect immediately
474
- // for Http2ServerTransport.
475
- LOG(FATAL) << "Not implemented";
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
- grpc_core::StatusCreate(
1377
- absl::StatusCode::kUnavailable,
1378
- absl::StrFormat("GOAWAY received; Error code: %u; Debug Text: %s",
1379
- goaway_error, goaway_text),
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 name,
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_(name) {}
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 name, bool enable_bdp_probe,
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
+ */