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
@@ -17,11 +17,16 @@
17
17
  #include "src/core/xds/grpc/xds_common_types.h"
18
18
 
19
19
  #include <string>
20
+ #include <utility>
20
21
 
22
+ #include "src/core/call/metadata_batch.h"
23
+ #include "src/core/lib/slice/slice.h"
21
24
  #include "src/core/util/match.h"
22
25
  #include "src/core/util/string.h"
23
- #include "src/core/util/time.h"
26
+ #include "absl/status/status.h"
24
27
  #include "absl/strings/match.h"
28
+ #include "absl/strings/str_cat.h"
29
+ #include "absl/strings/string_view.h"
25
30
 
26
31
  namespace grpc_core {
27
32
 
@@ -115,43 +120,6 @@ bool CommonTlsContext::Empty() const {
115
120
  certificate_validation_context.Empty();
116
121
  }
117
122
 
118
- //
119
- // XdsGrpcService
120
- //
121
-
122
- std::string XdsGrpcService::ToString() const {
123
- std::string result = "{";
124
- bool is_first = true;
125
- if (server_target != nullptr) {
126
- StrAppend(result, "server_target=");
127
- StrAppend(result, server_target->Key());
128
- is_first = false;
129
- }
130
- if (timeout != Duration::Zero()) {
131
- if (!is_first) StrAppend(result, ", ");
132
- StrAppend(result, "timeout=");
133
- StrAppend(result, timeout.ToString());
134
- is_first = false;
135
- }
136
- if (!initial_metadata.empty()) {
137
- if (!is_first) StrAppend(result, ", ");
138
- StrAppend(result, "initial_metadata=[");
139
- bool is_first_metadata = true;
140
- for (const auto& metadata : initial_metadata) {
141
- if (!is_first_metadata) StrAppend(result, ", ");
142
- StrAppend(result, "{key=");
143
- StrAppend(result, metadata.first);
144
- StrAppend(result, ", value=");
145
- StrAppend(result, metadata.second);
146
- StrAppend(result, "}");
147
- is_first_metadata = false;
148
- }
149
- StrAppend(result, "]");
150
- }
151
- StrAppend(result, "}");
152
- return result;
153
- }
154
-
155
123
  //
156
124
  // HeaderMutationRules
157
125
  //
@@ -210,4 +178,92 @@ std::string HeaderMutationRules::ToString() const {
210
178
  return result;
211
179
  }
212
180
 
181
+ //
182
+ // XdsHeaderValueOption
183
+ //
184
+
185
+ namespace {
186
+
187
+ void ApplyHeaderValueOptionMutation(const XdsHeaderValueOption& header,
188
+ grpc_metadata_batch& md) {
189
+ auto& [header_key, header_value] = header.header;
190
+ std::string buffer;
191
+ auto existing_value = md.GetStringValue(header_key, &buffer);
192
+ switch (header.append_action) {
193
+ case XdsHeaderValueOption::AppendAction::kAppendIfExistsOrAdd: {
194
+ if (!existing_value.has_value()) {
195
+ md.Append(header_key, Slice::FromCopiedString(header_value),
196
+ [](absl::string_view, const Slice&) {});
197
+ } else if (!header_value.empty()) {
198
+ std::string concatenated_val =
199
+ absl::StrCat(*existing_value, ",", header_value);
200
+ md.Remove(absl::string_view(header_key));
201
+ md.Append(header_key,
202
+ Slice::FromCopiedString(std::move(concatenated_val)),
203
+ [](absl::string_view, const Slice&) {});
204
+ }
205
+ break;
206
+ }
207
+ case XdsHeaderValueOption::AppendAction::kAddIfAbsent: {
208
+ if (!existing_value.has_value()) {
209
+ md.Append(header_key, Slice::FromCopiedString(header_value),
210
+ [](absl::string_view, const Slice&) {});
211
+ }
212
+ break;
213
+ }
214
+ case XdsHeaderValueOption::AppendAction::kOverwriteIfExists: {
215
+ if (existing_value.has_value()) {
216
+ md.Remove(absl::string_view(header_key));
217
+ md.Append(header_key, Slice::FromCopiedString(header_value),
218
+ [](absl::string_view, const Slice&) {});
219
+ }
220
+ break;
221
+ }
222
+ case XdsHeaderValueOption::AppendAction::kOverwriteIfExistsOrAdd: {
223
+ md.Remove(absl::string_view(header_key));
224
+ md.Append(header_key, Slice::FromCopiedString(header_value),
225
+ [](absl::string_view, const Slice&) {});
226
+ break;
227
+ }
228
+ }
229
+ }
230
+
231
+ } // namespace
232
+
233
+ absl::Status ApplyXdsHeaderMutationsRemoval(absl::string_view remove_header,
234
+ const HeaderMutationRules* rules,
235
+ grpc_metadata_batch& md) {
236
+ bool allowed = true;
237
+ bool disallow_is_error = false;
238
+ if (rules != nullptr) {
239
+ allowed = rules->IsMutationAllowed(std::string(remove_header));
240
+ disallow_is_error = rules->disallow_is_error;
241
+ }
242
+ if (allowed) {
243
+ md.Remove(absl::string_view(remove_header));
244
+ } else if (disallow_is_error) {
245
+ return absl::InternalError(
246
+ absl::StrCat("Forbidden header removal: ", remove_header));
247
+ }
248
+ return absl::OkStatus();
249
+ }
250
+
251
+ absl::Status ApplyXdsHeaderMutationsAddition(
252
+ const XdsHeaderValueOption& set_header, const HeaderMutationRules* rules,
253
+ grpc_metadata_batch& md) {
254
+ bool allowed = true;
255
+ bool disallow_is_error = false;
256
+ if (rules != nullptr) {
257
+ allowed = rules->IsMutationAllowed(std::string(set_header.header.first));
258
+ disallow_is_error = rules->disallow_is_error;
259
+ }
260
+ if (allowed) {
261
+ ApplyHeaderValueOptionMutation(set_header, md);
262
+ } else if (disallow_is_error) {
263
+ return absl::InternalError(
264
+ absl::StrCat("Forbidden header mutation: ", set_header.header.first));
265
+ }
266
+ return absl::OkStatus();
267
+ }
268
+
213
269
  } // namespace grpc_core
@@ -23,11 +23,11 @@
23
23
  #include <variant>
24
24
  #include <vector>
25
25
 
26
+ #include "src/core/call/metadata_batch.h"
26
27
  #include "src/core/util/json/json.h"
27
28
  #include "src/core/util/matchers.h"
28
- #include "src/core/util/time.h"
29
29
  #include "src/core/util/validation_errors.h"
30
- #include "src/core/xds/grpc/xds_server_grpc.h"
30
+ #include "absl/status/status.h"
31
31
  #include "absl/strings/string_view.h"
32
32
 
33
33
  namespace grpc_core {
@@ -89,22 +89,6 @@ struct XdsExtension {
89
89
  std::vector<ValidationErrors::ScopedField> validation_fields;
90
90
  };
91
91
 
92
- struct XdsGrpcService {
93
- std::unique_ptr<GrpcXdsServerTarget> server_target;
94
- Duration timeout;
95
- std::vector<std::pair<std::string, std::string>> initial_metadata;
96
-
97
- bool operator==(const XdsGrpcService& other) const {
98
- if (timeout != other.timeout) return false;
99
- if (initial_metadata != other.initial_metadata) return false;
100
- if (server_target == nullptr) return other.server_target == nullptr;
101
- if (other.server_target == nullptr) return false;
102
- return server_target->Equals(*other.server_target);
103
- }
104
-
105
- std::string ToString() const;
106
- };
107
-
108
92
  struct HeaderMutationRules {
109
93
  bool disallow_all = false;
110
94
  bool disallow_is_error = false;
@@ -129,6 +113,37 @@ struct HeaderMutationRules {
129
113
  }
130
114
  };
131
115
 
116
+ struct XdsHeaderValueOption {
117
+ enum class AppendAction {
118
+ // If the header already exists in the metadata batch, comma-concatenate the
119
+ // new value.
120
+ // Otherwise, append a new metadata entry.
121
+ kAppendIfExistsOrAdd = 0,
122
+ // Add the header only if it is not currently present in the metadata batch.
123
+ kAddIfAbsent = 1,
124
+ // Discard any existing entries in the metadata batch and append the new
125
+ // value.
126
+ kOverwriteIfExistsOrAdd = 2,
127
+ // If the header already exists, discard existing entries and replace with
128
+ // the new value.
129
+ // If absent, do nothing.
130
+ kOverwriteIfExists = 3
131
+ };
132
+
133
+ // The targeted metadata key and value to apply during mutation.
134
+ std::pair<std::string, std::string> header;
135
+ // Rule specifying how to merge or overwrite existing metadata batch entries.
136
+ AppendAction append_action;
137
+ };
138
+
139
+ absl::Status ApplyXdsHeaderMutationsRemoval(absl::string_view remove_header,
140
+ const HeaderMutationRules* rules,
141
+ grpc_metadata_batch& md);
142
+
143
+ absl::Status ApplyXdsHeaderMutationsAddition(
144
+ const XdsHeaderValueOption& set_header, const HeaderMutationRules* rules,
145
+ grpc_metadata_batch& md);
146
+
132
147
  } // namespace grpc_core
133
148
 
134
149
  #endif // GRPC_SRC_CORE_XDS_GRPC_XDS_COMMON_TYPES_H
@@ -26,6 +26,7 @@
26
26
  #include <string>
27
27
  #include <utility>
28
28
 
29
+ #include "envoy/config/common/mutation_rules/v3/mutation_rules.upb.h"
29
30
  #include "envoy/config/core/v3/address.upb.h"
30
31
  #include "envoy/config/core/v3/base.upb.h"
31
32
  #include "envoy/extensions/transport_sockets/tls/v3/common.upb.h"
@@ -39,11 +40,11 @@
39
40
  #include "src/core/lib/address_utils/parse_address.h"
40
41
  #include "src/core/lib/surface/validate_metadata.h"
41
42
  #include "src/core/util/down_cast.h"
42
- #include "src/core/util/env.h"
43
43
  #include "src/core/util/json/json_reader.h"
44
44
  #include "src/core/util/upb_utils.h"
45
45
  #include "src/core/util/validation_errors.h"
46
46
  #include "src/core/xds/grpc/xds_bootstrap_grpc.h"
47
+ #include "src/core/xds/grpc/xds_common_types.h"
47
48
  #include "src/core/xds/xds_client/xds_client.h"
48
49
  #include "upb/base/status.hpp"
49
50
  #include "upb/json/encode.h"
@@ -618,7 +619,7 @@ std::optional<XdsExtension> ExtractXdsExtension(
618
619
  }
619
620
 
620
621
  //
621
- // ParseXdsGrpcService()
622
+ // ParseXdsHeader()
622
623
  //
623
624
 
624
625
  namespace {
@@ -645,7 +646,9 @@ std::optional<std::string> GetHeaderValue(upb_StringView upb_value,
645
646
  return std::string(value);
646
647
  }
647
648
 
648
- std::pair<std::string, std::string> ParseHeader(
649
+ } // namespace
650
+
651
+ std::pair<std::string, std::string> ParseXdsHeader(
649
652
  const envoy_config_core_v3_HeaderValue* header_value,
650
653
  ValidationErrors* errors) {
651
654
  // key
@@ -682,35 +685,42 @@ std::pair<std::string, std::string> ParseHeader(
682
685
  return {std::string(key), value.has_value() ? std::move(*value) : ""};
683
686
  }
684
687
 
685
- } // namespace
688
+ //
689
+ // ParseXdsGrpcService()
690
+ //
686
691
 
687
- XdsGrpcService ParseXdsGrpcService(
692
+ GrpcXdsServerTarget ParseXdsGrpcService(
688
693
  const XdsResourceType::DecodeContext& context,
689
694
  const envoy_config_core_v3_GrpcService* grpc_service,
690
695
  ValidationErrors* errors) {
691
696
  if (grpc_service == nullptr) {
692
697
  errors->AddError("field not set");
693
- return {};
698
+ return GrpcXdsServerTarget(/*server_uri=*/"",
699
+ /*channel_creds_config=*/nullptr,
700
+ /*call_creds_configs=*/{});
694
701
  }
695
- XdsGrpcService xds_grpc_service;
696
702
  // timeout
697
- if (auto* timeout = envoy_config_core_v3_GrpcService_timeout(grpc_service);
698
- timeout != nullptr) {
703
+ Duration timeout = Duration::Zero();
704
+ if (auto* timeout_proto =
705
+ envoy_config_core_v3_GrpcService_timeout(grpc_service);
706
+ timeout_proto != nullptr) {
699
707
  ValidationErrors::ScopedField field(errors, ".timeout");
700
- xds_grpc_service.timeout = ParseDuration(timeout, errors);
701
- if (xds_grpc_service.timeout <= Duration::Zero()) {
708
+ timeout = ParseDuration(timeout_proto, errors);
709
+ if (timeout <= Duration::Zero()) {
702
710
  errors->AddError("duration must be positive");
703
711
  }
704
712
  }
705
713
  // initial_metadata
714
+ std::vector<std::pair<std::string, std::string>> initial_metadata;
706
715
  size_t initial_metadata_size;
707
- auto* initial_metadata = envoy_config_core_v3_GrpcService_initial_metadata(
708
- grpc_service, &initial_metadata_size);
716
+ auto* initial_metadata_proto =
717
+ envoy_config_core_v3_GrpcService_initial_metadata(grpc_service,
718
+ &initial_metadata_size);
709
719
  for (size_t i = 0; i < initial_metadata_size; ++i) {
710
720
  ValidationErrors::ScopedField field(
711
721
  errors, absl::StrCat(".initial_metadata[", i, "]"));
712
- xds_grpc_service.initial_metadata.push_back(
713
- ParseHeader(initial_metadata[i], errors));
722
+ initial_metadata.push_back(
723
+ ParseXdsHeader(initial_metadata_proto[i], errors));
714
724
  }
715
725
  // google_grpc
716
726
  ValidationErrors::ScopedField field(errors, ".google_grpc");
@@ -718,103 +728,103 @@ XdsGrpcService ParseXdsGrpcService(
718
728
  envoy_config_core_v3_GrpcService_google_grpc(grpc_service);
719
729
  if (google_grpc == nullptr) {
720
730
  errors->AddError("field not set");
721
- } else {
722
- // target_uri
723
- std::string target_uri = UpbStringToStdString(
724
- envoy_config_core_v3_GrpcService_GoogleGrpc_target_uri(google_grpc));
725
- if (!CoreConfiguration::Get().resolver_registry().IsValidTarget(
726
- target_uri)) {
727
- ValidationErrors::ScopedField field(errors, ".target_uri");
728
- errors->AddError("invalid target URI");
729
- }
730
- // credentials
731
- RefCountedPtr<const ChannelCredsConfig> channel_creds_config;
732
- std::vector<RefCountedPtr<const CallCredsConfig>> call_creds_configs;
733
- if (DownCast<const GrpcXdsServer&>(context.server).TrustedXdsServer()) {
734
- // Trusted xDS server. Use credentials from the GoogleGrpc proto.
735
- // First, look at channel creds.
736
- {
737
- ValidationErrors::ScopedField field(errors,
738
- ".channel_credentials_plugin");
739
- size_t size;
740
- const auto* const* channel_creds_plugin =
741
- envoy_config_core_v3_GrpcService_GoogleGrpc_channel_credentials_plugin(
742
- google_grpc, &size);
743
- if (size == 0) {
744
- errors->AddError("field not set");
745
- } else {
746
- const auto& registry =
747
- CoreConfiguration::Get().channel_creds_registry();
748
- const auto& certificate_providers =
749
- DownCast<const GrpcXdsBootstrap&>(context.client->bootstrap())
750
- .certificate_providers();
751
- for (size_t i = 0; i < size; ++i) {
752
- ValidationErrors::ScopedField field(errors,
753
- absl::StrCat("[", i, "]"));
754
- absl::string_view type = UpbStringToAbsl(
755
- google_protobuf_Any_type_url(channel_creds_plugin[i]));
756
- if (!StripTypePrefix(type, errors)) continue;
757
- if (!registry.IsProtoSupported(type)) continue;
758
- ValidationErrors::ScopedField field2(errors, ".value");
759
- absl::string_view serialized_config = UpbStringToAbsl(
760
- google_protobuf_Any_value(channel_creds_plugin[i]));
761
- channel_creds_config = registry.ParseProto(
762
- type, serialized_config, certificate_providers, errors);
763
- break;
764
- }
765
- if (channel_creds_config == nullptr) {
766
- errors->AddError("no supported channel credentials type found");
767
- }
768
- }
769
- }
770
- // Now look at call creds.
771
- {
772
- ValidationErrors::ScopedField field(errors, ".call_credentials_plugin");
773
- size_t size;
774
- const auto* const* call_creds_plugin =
775
- envoy_config_core_v3_GrpcService_GoogleGrpc_call_credentials_plugin(
776
- google_grpc, &size);
777
- const auto& registry = CoreConfiguration::Get().call_creds_registry();
731
+ return GrpcXdsServerTarget(/*server_uri=*/"",
732
+ /*channel_creds_config=*/nullptr,
733
+ /*call_creds_configs=*/{});
734
+ }
735
+ // target_uri
736
+ std::string target_uri = UpbStringToStdString(
737
+ envoy_config_core_v3_GrpcService_GoogleGrpc_target_uri(google_grpc));
738
+ if (!CoreConfiguration::Get().resolver_registry().IsValidTarget(target_uri)) {
739
+ ValidationErrors::ScopedField field(errors, ".target_uri");
740
+ errors->AddError("invalid target URI");
741
+ }
742
+ // credentials
743
+ RefCountedPtr<const ChannelCredsConfig> channel_creds_config;
744
+ std::vector<RefCountedPtr<const CallCredsConfig>> call_creds_configs;
745
+ if (DownCast<const GrpcXdsServer&>(context.server).TrustedXdsServer()) {
746
+ // Trusted xDS server. Use credentials from the GoogleGrpc proto.
747
+ // First, look at channel creds.
748
+ {
749
+ ValidationErrors::ScopedField field(errors,
750
+ ".channel_credentials_plugin");
751
+ size_t size;
752
+ const auto* const* channel_creds_plugin =
753
+ envoy_config_core_v3_GrpcService_GoogleGrpc_channel_credentials_plugin(
754
+ google_grpc, &size);
755
+ if (size == 0) {
756
+ errors->AddError("field not set");
757
+ } else {
758
+ const auto& registry =
759
+ CoreConfiguration::Get().channel_creds_registry();
760
+ const auto& certificate_providers =
761
+ DownCast<const GrpcXdsBootstrap&>(context.client->bootstrap())
762
+ .certificate_providers();
778
763
  for (size_t i = 0; i < size; ++i) {
779
764
  ValidationErrors::ScopedField field(errors,
780
765
  absl::StrCat("[", i, "]"));
781
766
  absl::string_view type = UpbStringToAbsl(
782
- google_protobuf_Any_type_url(call_creds_plugin[i]));
767
+ google_protobuf_Any_type_url(channel_creds_plugin[i]));
783
768
  if (!StripTypePrefix(type, errors)) continue;
784
769
  if (!registry.IsProtoSupported(type)) continue;
785
770
  ValidationErrors::ScopedField field2(errors, ".value");
786
- absl::string_view serialized_config =
787
- UpbStringToAbsl(google_protobuf_Any_value(call_creds_plugin[i]));
788
- call_creds_configs.push_back(
789
- registry.ParseProto(type, serialized_config, errors));
771
+ absl::string_view serialized_config = UpbStringToAbsl(
772
+ google_protobuf_Any_value(channel_creds_plugin[i]));
773
+ channel_creds_config = registry.ParseProto(
774
+ type, serialized_config, certificate_providers, errors);
775
+ break;
776
+ }
777
+ if (channel_creds_config == nullptr) {
778
+ errors->AddError("no supported channel credentials type found");
790
779
  }
791
780
  }
792
- } else {
793
- // Not a trusted xDS server. Do lookup in bootstrap.
794
- const auto& bootstrap =
795
- DownCast<const GrpcXdsBootstrap&>(context.client->bootstrap());
796
- auto& allowed_grpc_services = bootstrap.allowed_grpc_services();
797
- auto it = allowed_grpc_services.find(target_uri);
798
- if (it == allowed_grpc_services.end()) {
799
- ValidationErrors::ScopedField field(errors, ".target_uri");
800
- errors->AddError(
801
- "service not present in \"allowed_grpc_services\" "
802
- "in bootstrap config");
803
- } else {
804
- channel_creds_config = it->second.channel_creds_config;
805
- call_creds_configs = it->second.call_creds_configs;
781
+ }
782
+ // Now look at call creds.
783
+ {
784
+ ValidationErrors::ScopedField field(errors, ".call_credentials_plugin");
785
+ size_t size;
786
+ const auto* const* call_creds_plugin =
787
+ envoy_config_core_v3_GrpcService_GoogleGrpc_call_credentials_plugin(
788
+ google_grpc, &size);
789
+ const auto& registry = CoreConfiguration::Get().call_creds_registry();
790
+ for (size_t i = 0; i < size; ++i) {
791
+ ValidationErrors::ScopedField field(errors, absl::StrCat("[", i, "]"));
792
+ absl::string_view type =
793
+ UpbStringToAbsl(google_protobuf_Any_type_url(call_creds_plugin[i]));
794
+ if (!StripTypePrefix(type, errors)) continue;
795
+ if (!registry.IsProtoSupported(type)) continue;
796
+ ValidationErrors::ScopedField field2(errors, ".value");
797
+ absl::string_view serialized_config =
798
+ UpbStringToAbsl(google_protobuf_Any_value(call_creds_plugin[i]));
799
+ call_creds_configs.push_back(
800
+ registry.ParseProto(type, serialized_config, errors));
806
801
  }
807
802
  }
808
- xds_grpc_service.server_target = std::make_unique<GrpcXdsServerTarget>(
809
- target_uri, std::move(channel_creds_config),
810
- std::move(call_creds_configs));
803
+ } else {
804
+ // Not a trusted xDS server. Do lookup in bootstrap.
805
+ const auto& bootstrap =
806
+ DownCast<const GrpcXdsBootstrap&>(context.client->bootstrap());
807
+ auto& allowed_grpc_services = bootstrap.allowed_grpc_services();
808
+ auto it = allowed_grpc_services.find(target_uri);
809
+ if (it == allowed_grpc_services.end()) {
810
+ ValidationErrors::ScopedField field(errors, ".target_uri");
811
+ errors->AddError(
812
+ "service not present in \"allowed_grpc_services\" "
813
+ "in bootstrap config");
814
+ } else {
815
+ channel_creds_config = it->second.channel_creds_config;
816
+ call_creds_configs = it->second.call_creds_configs;
817
+ }
811
818
  }
812
- return xds_grpc_service;
819
+ return GrpcXdsServerTarget(target_uri, std::move(channel_creds_config),
820
+ std::move(call_creds_configs),
821
+ std::move(initial_metadata), timeout);
813
822
  }
814
823
 
815
824
  //
816
825
  // ParseHeaderMutationRules()
817
826
  //
827
+
818
828
  namespace {
819
829
 
820
830
  std::unique_ptr<RE2> ParseRegexMatcher(
@@ -842,13 +852,15 @@ HeaderMutationRules ParseHeaderMutationRules(
842
852
  return {};
843
853
  }
844
854
  HeaderMutationRules header_mutation_rules_config;
845
- header_mutation_rules_config.disallow_all =
855
+ header_mutation_rules_config.disallow_all = ParseBoolValue(
846
856
  envoy_config_common_mutation_rules_v3_HeaderMutationRules_disallow_all(
847
- header_mutation_rules);
848
- header_mutation_rules_config.disallow_is_error =
857
+ header_mutation_rules));
858
+ const google_protobuf_BoolValue* disallow_is_error_proto =
849
859
  envoy_config_common_mutation_rules_v3_HeaderMutationRules_disallow_is_error(
850
860
  header_mutation_rules);
851
- const auto* disallow_expression_proto =
861
+ header_mutation_rules_config.disallow_is_error =
862
+ ParseBoolValue(disallow_is_error_proto);
863
+ const envoy_type_matcher_v3_RegexMatcher* disallow_expression_proto =
852
864
  envoy_config_common_mutation_rules_v3_HeaderMutationRules_disallow_expression(
853
865
  header_mutation_rules);
854
866
  if (disallow_expression_proto != nullptr) {
@@ -857,7 +869,7 @@ HeaderMutationRules ParseHeaderMutationRules(
857
869
  header_mutation_rules_config.disallow_expression =
858
870
  ParseRegexMatcher(disallow_expression_proto, errors);
859
871
  }
860
- const auto* allow_expression_proto =
872
+ const envoy_type_matcher_v3_RegexMatcher* allow_expression_proto =
861
873
  envoy_config_common_mutation_rules_v3_HeaderMutationRules_allow_expression(
862
874
  header_mutation_rules);
863
875
  if (allow_expression_proto != nullptr) {
@@ -869,4 +881,60 @@ HeaderMutationRules ParseHeaderMutationRules(
869
881
  return header_mutation_rules_config;
870
882
  }
871
883
 
884
+ //
885
+ // ParseXdsHeaderValueOption()
886
+ //
887
+
888
+ namespace {
889
+
890
+ XdsHeaderValueOption::AppendAction ParseXdsHeaderValueOptionAppendAction(
891
+ int32_t header_value_option_append_action, ValidationErrors* errors) {
892
+ switch (header_value_option_append_action) {
893
+ case envoy_config_core_v3_HeaderValueOption_APPEND_IF_EXISTS_OR_ADD:
894
+ return XdsHeaderValueOption::AppendAction::kAppendIfExistsOrAdd;
895
+ case envoy_config_core_v3_HeaderValueOption_ADD_IF_ABSENT:
896
+ return XdsHeaderValueOption::AppendAction::kAddIfAbsent;
897
+ case envoy_config_core_v3_HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD:
898
+ return XdsHeaderValueOption::AppendAction::kOverwriteIfExistsOrAdd;
899
+ case envoy_config_core_v3_HeaderValueOption_OVERWRITE_IF_EXISTS:
900
+ return XdsHeaderValueOption::AppendAction::kOverwriteIfExists;
901
+ default:
902
+ errors->AddError("unsupported append action");
903
+ return XdsHeaderValueOption::AppendAction::kAppendIfExistsOrAdd;
904
+ }
905
+ }
906
+
907
+ } // namespace
908
+
909
+ XdsHeaderValueOption ParseXdsHeaderValueOption(
910
+ const envoy_config_core_v3_HeaderValueOption* header_value_option_config,
911
+ ValidationErrors* errors) {
912
+ if (header_value_option_config == nullptr) {
913
+ errors->AddError("field is not present");
914
+ return {};
915
+ }
916
+ XdsHeaderValueOption header_value_option;
917
+ // parse header
918
+ {
919
+ ValidationErrors::ScopedField field(errors, ".header");
920
+ if (const auto* header = envoy_config_core_v3_HeaderValueOption_header(
921
+ header_value_option_config);
922
+ header != nullptr) {
923
+ header_value_option.header = ParseXdsHeader(header, errors);
924
+ } else {
925
+ errors->AddError("field not set");
926
+ }
927
+ }
928
+ // parse header_append_action
929
+ {
930
+ ValidationErrors::ScopedField field(errors, ".append_action");
931
+ int32_t header_append_action =
932
+ envoy_config_core_v3_HeaderValueOption_append_action(
933
+ header_value_option_config);
934
+ header_value_option.append_action =
935
+ ParseXdsHeaderValueOptionAppendAction(header_append_action, errors);
936
+ }
937
+ return header_value_option;
938
+ }
939
+
872
940
  } // namespace grpc_core
@@ -17,6 +17,7 @@
17
17
  #ifndef GRPC_SRC_CORE_XDS_GRPC_XDS_COMMON_TYPES_PARSER_H
18
18
  #define GRPC_SRC_CORE_XDS_GRPC_XDS_COMMON_TYPES_PARSER_H
19
19
 
20
+ #include <cstdint>
20
21
  #include <optional>
21
22
 
22
23
  #include "envoy/config/common/mutation_rules/v3/mutation_rules.upb.h"
@@ -34,6 +35,7 @@
34
35
  #include "src/core/util/time.h"
35
36
  #include "src/core/util/validation_errors.h"
36
37
  #include "src/core/xds/grpc/xds_common_types.h"
38
+ #include "src/core/xds/grpc/xds_server_grpc.h"
37
39
  #include "src/core/xds/xds_client/xds_resource_type.h"
38
40
  #include "xds/type/matcher/v3/string.upb.h"
39
41
 
@@ -90,7 +92,7 @@ std::optional<XdsExtension> ExtractXdsExtension(
90
92
  const XdsResourceType::DecodeContext& context,
91
93
  const google_protobuf_Any* any, ValidationErrors* errors);
92
94
 
93
- XdsGrpcService ParseXdsGrpcService(
95
+ GrpcXdsServerTarget ParseXdsGrpcService(
94
96
  const XdsResourceType::DecodeContext& context,
95
97
  const envoy_config_core_v3_GrpcService* grpc_service,
96
98
  ValidationErrors* errors);
@@ -100,6 +102,21 @@ HeaderMutationRules ParseHeaderMutationRules(
100
102
  header_mutation_rules,
101
103
  ValidationErrors* errors);
102
104
 
105
+ XdsHeaderValueOption ParseXdsHeaderValueOption(
106
+ const envoy_config_core_v3_HeaderValueOption* header_value_option_config,
107
+ ValidationErrors* errors);
108
+
109
+ // TODO(roth): We would ideally like to use a Slice for the header value, but
110
+ // Slice isn't copyable, which makes it problematic to store here. The down-side
111
+ // of this approach is that we need to make a copy when we apply the header
112
+ // value to each RPC rather than just taking a new ref to the slice. Consider
113
+ // solving this problem by adding a new RefCountedSlice class to represent an
114
+ // immutable, ref-counted slice that can be turned into a Slice and thus added
115
+ // to RPC metadata without a copy.
116
+ std::pair<std::string, std::string> ParseXdsHeader(
117
+ const envoy_config_core_v3_HeaderValue* header_value,
118
+ ValidationErrors* errors);
119
+
103
120
  } // namespace grpc_core
104
121
 
105
122
  #endif // GRPC_SRC_CORE_XDS_GRPC_XDS_COMMON_TYPES_PARSER_H