grpc 1.21.0 → 1.22.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +422 -62
  3. data/include/grpc/grpc_security.h +61 -5
  4. data/include/grpc/grpc_security_constants.h +1 -1
  5. data/include/grpc/impl/codegen/gpr_types.h +1 -1
  6. data/include/grpc/slice.h +2 -2
  7. data/src/core/ext/filters/client_channel/backup_poller.cc +2 -3
  8. data/src/core/ext/filters/client_channel/backup_poller.h +5 -2
  9. data/src/core/ext/filters/client_channel/client_channel.cc +260 -122
  10. data/src/core/ext/filters/client_channel/client_channel.h +0 -8
  11. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +3 -84
  12. data/src/core/ext/filters/client_channel/client_channel_channelz.h +2 -28
  13. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +2 -8
  14. data/src/core/ext/filters/client_channel/health/health_check_client.cc +5 -4
  15. data/src/core/ext/filters/client_channel/lb_policy.cc +16 -2
  16. data/src/core/ext/filters/client_channel/lb_policy.h +92 -98
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +63 -87
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +6 -2
  19. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +35 -87
  20. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +18 -74
  21. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +167 -217
  22. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +216 -190
  23. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +6 -2
  24. data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -1
  25. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +1 -1
  26. data/src/core/ext/filters/client_channel/lb_policy_registry.h +1 -1
  27. data/src/core/ext/filters/client_channel/resolver.h +1 -1
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +6 -3
  29. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +0 -1
  30. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -0
  31. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +8 -8
  32. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +7 -7
  33. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +28 -64
  34. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +4 -12
  35. data/src/core/ext/filters/client_channel/server_address.cc +4 -6
  36. data/src/core/ext/filters/client_channel/server_address.h +1 -3
  37. data/src/core/ext/filters/client_channel/service_config.cc +20 -22
  38. data/src/core/ext/filters/client_channel/service_config.h +26 -28
  39. data/src/core/ext/filters/client_channel/subchannel.cc +261 -160
  40. data/src/core/ext/filters/client_channel/subchannel.h +97 -23
  41. data/src/core/ext/filters/client_channel/subchannel_interface.h +113 -0
  42. data/src/core/ext/filters/message_size/message_size_filter.cc +12 -12
  43. data/src/core/ext/filters/message_size/message_size_filter.h +2 -2
  44. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +50 -2
  45. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +2 -2
  46. data/src/core/ext/transport/chttp2/transport/frame_data.cc +31 -36
  47. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +3 -2
  48. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +71 -52
  49. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +18 -3
  50. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +5 -12
  51. data/src/core/ext/transport/chttp2/transport/hpack_table.h +10 -1
  52. data/src/core/ext/transport/chttp2/transport/internal.h +3 -3
  53. data/src/core/ext/transport/chttp2/transport/parsing.cc +39 -57
  54. data/src/core/lib/channel/channelz.cc +136 -19
  55. data/src/core/lib/channel/channelz.h +36 -40
  56. data/src/core/lib/channel/channelz_registry.cc +74 -106
  57. data/src/core/lib/channel/channelz_registry.h +10 -28
  58. data/src/core/lib/channel/context.h +1 -1
  59. data/src/core/lib/channel/handshaker.cc +6 -0
  60. data/src/core/lib/compression/compression.cc +13 -8
  61. data/src/core/lib/compression/compression_internal.cc +14 -10
  62. data/src/core/lib/compression/compression_internal.h +1 -1
  63. data/src/core/lib/compression/stream_compression.cc +3 -2
  64. data/src/core/lib/compression/stream_compression.h +2 -2
  65. data/src/core/lib/compression/stream_compression_gzip.cc +9 -9
  66. data/src/core/lib/gpr/env.h +1 -1
  67. data/src/core/lib/gpr/string.cc +8 -1
  68. data/src/core/lib/gpr/string.h +6 -1
  69. data/src/core/lib/gprpp/fork.cc +1 -1
  70. data/src/core/lib/gprpp/fork.h +5 -1
  71. data/src/core/lib/gprpp/global_config.h +9 -0
  72. data/src/core/lib/gprpp/global_config_custom.h +1 -1
  73. data/src/core/lib/gprpp/inlined_vector.h +8 -0
  74. data/src/core/lib/gprpp/map.h +38 -21
  75. data/src/core/lib/gprpp/memory.h +2 -2
  76. data/src/core/lib/gprpp/orphanable.h +1 -1
  77. data/src/core/lib/gprpp/ref_counted.h +9 -4
  78. data/src/core/lib/http/httpcli.cc +3 -3
  79. data/src/core/lib/iomgr/buffer_list.h +1 -1
  80. data/src/core/lib/iomgr/call_combiner.cc +1 -1
  81. data/src/core/lib/iomgr/call_combiner.h +1 -1
  82. data/src/core/lib/iomgr/cfstream_handle.cc +3 -2
  83. data/src/core/lib/iomgr/cfstream_handle.h +4 -0
  84. data/src/core/lib/iomgr/error.cc +3 -3
  85. data/src/core/lib/iomgr/error.h +9 -3
  86. data/src/core/lib/iomgr/error_internal.h +1 -1
  87. data/src/core/lib/iomgr/ev_epoll1_linux.cc +1 -1
  88. data/src/core/lib/iomgr/ev_posix.cc +3 -3
  89. data/src/core/lib/iomgr/ev_posix.h +3 -2
  90. data/src/core/lib/iomgr/ev_windows.cc +2 -2
  91. data/src/core/lib/iomgr/iomgr.cc +4 -4
  92. data/src/core/lib/iomgr/lockfree_event.cc +1 -1
  93. data/src/core/lib/iomgr/port.h +5 -1
  94. data/src/core/lib/iomgr/tcp_posix.cc +1 -3
  95. data/src/core/lib/iomgr/tcp_server.cc +5 -0
  96. data/src/core/lib/iomgr/tcp_server.h +24 -0
  97. data/src/core/lib/iomgr/tcp_server_custom.cc +11 -9
  98. data/src/core/lib/iomgr/tcp_server_posix.cc +72 -11
  99. data/src/core/lib/iomgr/tcp_server_utils_posix.h +3 -0
  100. data/src/core/lib/iomgr/tcp_server_windows.cc +11 -9
  101. data/src/core/lib/iomgr/tcp_uv.cc +5 -6
  102. data/src/core/lib/iomgr/timer.h +2 -1
  103. data/src/core/lib/iomgr/udp_server.cc +2 -2
  104. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +1 -1
  105. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +20 -2
  106. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +2 -2
  107. data/src/core/lib/security/security_connector/security_connector.h +1 -1
  108. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +1 -1
  109. data/src/core/lib/security/transport/auth_filters.h +3 -0
  110. data/src/core/lib/security/transport/client_auth_filter.cc +13 -0
  111. data/src/core/lib/security/transport/security_handshaker.cc +7 -7
  112. data/src/core/lib/slice/b64.h +2 -2
  113. data/src/core/lib/slice/slice.cc +82 -10
  114. data/src/core/lib/slice/slice_buffer.cc +49 -21
  115. data/src/core/lib/slice/slice_hash_table.h +2 -2
  116. data/src/core/lib/slice/slice_intern.cc +15 -16
  117. data/src/core/lib/slice/slice_internal.h +52 -0
  118. data/src/core/lib/slice/slice_string_helpers.cc +10 -1
  119. data/src/core/lib/slice/slice_string_helpers.h +3 -1
  120. data/src/core/lib/slice/slice_utils.h +50 -0
  121. data/src/core/lib/slice/slice_weak_hash_table.h +2 -2
  122. data/src/core/lib/surface/call.cc +14 -8
  123. data/src/core/lib/surface/channel.cc +89 -97
  124. data/src/core/lib/surface/channel.h +60 -6
  125. data/src/core/lib/surface/completion_queue.cc +49 -36
  126. data/src/core/lib/surface/completion_queue.h +2 -1
  127. data/src/core/lib/surface/server.cc +8 -8
  128. data/src/core/lib/surface/validate_metadata.cc +14 -8
  129. data/src/core/lib/surface/validate_metadata.h +13 -2
  130. data/src/core/lib/surface/version.cc +1 -1
  131. data/src/core/lib/transport/metadata.cc +56 -26
  132. data/src/core/lib/transport/metadata.h +91 -75
  133. data/src/core/lib/transport/static_metadata.cc +262 -176
  134. data/src/core/lib/transport/static_metadata.h +272 -180
  135. data/src/core/lib/transport/transport.cc +1 -1
  136. data/src/core/lib/transport/transport.h +8 -2
  137. data/src/core/tsi/alts/handshaker/alts_shared_resource.h +1 -1
  138. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  139. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +5 -2
  140. data/src/ruby/lib/grpc/version.rb +1 -1
  141. metadata +37 -35
@@ -35,6 +35,7 @@
35
35
  #include "src/core/lib/profiling/timers.h"
36
36
  #include "src/core/lib/slice/slice_internal.h"
37
37
  #include "src/core/lib/slice/slice_string_helpers.h"
38
+ #include "src/core/lib/surface/validate_metadata.h"
38
39
  #include "src/core/lib/transport/http2_errors.h"
39
40
 
40
41
  typedef enum {
@@ -627,7 +628,7 @@ static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md,
627
628
  if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
628
629
  char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
629
630
  char* v = nullptr;
630
- if (grpc_is_binary_header(GRPC_MDKEY(md))) {
631
+ if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) {
631
632
  v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX);
632
633
  } else {
633
634
  v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
@@ -1494,7 +1495,13 @@ static grpc_error* parse_key_string(grpc_chttp2_hpack_parser* p,
1494
1495
  /* check if a key represents a binary header or not */
1495
1496
 
1496
1497
  static bool is_binary_literal_header(grpc_chttp2_hpack_parser* p) {
1497
- return grpc_is_binary_header(
1498
+ /* We know that either argument here is a reference counter slice.
1499
+ * 1. If a result of grpc_slice_from_static_buffer, the refcount is set to
1500
+ * NoopRefcount.
1501
+ * 2. If it's p->key.data.referenced, then p->key.copied was set to false,
1502
+ * which occurs in begin_parse_string() - where the refcount is set to
1503
+ * p->current_slice_refcount, which is not null. */
1504
+ return grpc_is_refcounted_slice_binary_header(
1498
1505
  p->key.copied ? grpc_slice_from_static_buffer(p->key.data.copied.str,
1499
1506
  p->key.data.copied.length)
1500
1507
  : p->key.data.referenced);
@@ -1511,7 +1518,15 @@ static grpc_error* is_binary_indexed_header(grpc_chttp2_hpack_parser* p,
1511
1518
  static_cast<intptr_t>(p->index)),
1512
1519
  GRPC_ERROR_INT_SIZE, static_cast<intptr_t>(p->table.num_ents));
1513
1520
  }
1514
- *is = grpc_is_binary_header(GRPC_MDKEY(elem));
1521
+ /* We know that GRPC_MDKEY(elem) points to a reference counted slice since:
1522
+ * 1. elem was a result of grpc_chttp2_hptbl_lookup
1523
+ * 2. An item in this table is either static (see entries with
1524
+ * index < GRPC_CHTTP2_LAST_STATIC_ENTRY or added via
1525
+ * grpc_chttp2_hptbl_add).
1526
+ * 3. If added via grpc_chttp2_hptbl_add, the entry is either static or
1527
+ * interned.
1528
+ * 4. Both static and interned element slices have non-null refcounts. */
1529
+ *is = grpc_is_refcounted_slice_binary_header(GRPC_MDKEY(elem));
1515
1530
  return GRPC_ERROR_NONE;
1516
1531
  }
1517
1532
 
@@ -29,6 +29,7 @@
29
29
 
30
30
  #include "src/core/lib/debug/trace.h"
31
31
  #include "src/core/lib/gpr/murmur_hash.h"
32
+ #include "src/core/lib/surface/validate_metadata.h"
32
33
  #include "src/core/lib/transport/static_metadata.h"
33
34
 
34
35
  extern grpc_core::TraceFlag grpc_http_trace;
@@ -375,9 +376,11 @@ static size_t get_base64_encoded_size(size_t raw_length) {
375
376
 
376
377
  size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem,
377
378
  bool use_true_binary_metadata) {
378
- size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
379
+ const uint8_t* key_buf = GRPC_SLICE_START_PTR(GRPC_MDKEY(elem));
380
+ size_t key_len = GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
381
+ size_t overhead_and_key = 32 + key_len;
379
382
  size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
380
- if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
383
+ if (grpc_key_is_binary_header(key_buf, key_len)) {
381
384
  return overhead_and_key + (use_true_binary_metadata
382
385
  ? value_len + 1
383
386
  : get_base64_encoded_size(value_len));
@@ -385,13 +388,3 @@ size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem,
385
388
  return overhead_and_key + value_len;
386
389
  }
387
390
  }
388
-
389
- uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md) {
390
- if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
391
- uint8_t index = GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table;
392
- if (index < GRPC_CHTTP2_LAST_STATIC_ENTRY) {
393
- return index + 1; // Hpack static metadata element indices start at 1
394
- }
395
- }
396
- return 0;
397
- }
@@ -24,6 +24,7 @@
24
24
  #include <grpc/slice.h>
25
25
  #include "src/core/lib/iomgr/error.h"
26
26
  #include "src/core/lib/transport/metadata.h"
27
+ #include "src/core/lib/transport/static_metadata.h"
27
28
 
28
29
  /* HPACK header table */
29
30
 
@@ -90,7 +91,15 @@ size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem,
90
91
  /* Returns the static hpack table index that corresponds to /a elem. Returns 0
91
92
  if /a elem is not statically stored or if it is not in the static hpack
92
93
  table */
93
- uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md);
94
+ inline uintptr_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md) {
95
+ uintptr_t index =
96
+ reinterpret_cast<grpc_core::StaticMetadata*>(GRPC_MDELEM_DATA(md)) -
97
+ grpc_static_mdelem_table;
98
+ if (index < GRPC_CHTTP2_LAST_STATIC_ENTRY) {
99
+ return index + 1; // Hpack static metadata element indices start at 1
100
+ }
101
+ return 0;
102
+ }
94
103
 
95
104
  /* Find a key/value pair in the table... returns the index in the table of the
96
105
  most similar entry, or 0 if the value was not found */
@@ -225,14 +225,14 @@ class Chttp2IncomingByteStream : public ByteStream {
225
225
  // TODO(roth): When I converted this class to C++, I wanted to make it
226
226
  // inherit from RefCounted or InternallyRefCounted instead of continuing
227
227
  // to use its own custom ref-counting code. However, that would require
228
- // using multiple inheritence, which sucks in general. And to make matters
228
+ // using multiple inheritance, which sucks in general. And to make matters
229
229
  // worse, it causes problems with our New<> and Delete<> wrappers.
230
230
  // Specifically, unless RefCounted is first in the list of parent classes,
231
231
  // it will see a different value of the address of the object than the one
232
232
  // we actually allocated, in which case gpr_free() will be called on a
233
233
  // different address than the one we got from gpr_malloc(), thus causing a
234
234
  // crash. Given the fragility of depending on that, as well as a desire to
235
- // avoid multiple inheritence in general, I've decided to leave this
235
+ // avoid multiple inheritance in general, I've decided to leave this
236
236
  // alone for now. We can revisit this once we're able to link against
237
237
  // libc++, at which point we can eliminate New<> and Delete<> and
238
238
  // switch to std::shared_ptr<>.
@@ -499,7 +499,7 @@ typedef enum {
499
499
  GRPC_METADATA_NOT_PUBLISHED,
500
500
  GRPC_METADATA_SYNTHESIZED_FROM_FAKE,
501
501
  GRPC_METADATA_PUBLISHED_FROM_WIRE,
502
- GPRC_METADATA_PUBLISHED_AT_CLOSE
502
+ GRPC_METADATA_PUBLISHED_AT_CLOSE
503
503
  } grpc_published_metadata_method;
504
504
 
505
505
  struct grpc_chttp2_stream {
@@ -28,6 +28,7 @@
28
28
 
29
29
  #include "src/core/lib/profiling/timers.h"
30
30
  #include "src/core/lib/slice/slice_string_helpers.h"
31
+ #include "src/core/lib/slice/slice_utils.h"
31
32
  #include "src/core/lib/transport/http2_errors.h"
32
33
  #include "src/core/lib/transport/static_metadata.h"
33
34
  #include "src/core/lib/transport/status_conversion.h"
@@ -410,53 +411,42 @@ static void on_initial_header(void* tp, grpc_mdelem md) {
410
411
  gpr_free(value);
411
412
  }
412
413
 
413
- if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
414
- // We don't use grpc_mdelem_eq here to avoid executing additional
415
- // instructions. The reasoning is if the payload is not equal, we already
416
- // know that the metadata elements are not equal because the md is
417
- // confirmed to be static. If we had used grpc_mdelem_eq here, then if the
418
- // payloads are not equal, grpc_mdelem_eq executes more instructions to
419
- // determine if they're equal or not.
420
- if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload ||
421
- md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) {
422
- s->seen_error = true;
423
- }
424
- } else {
425
- if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
426
- !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
427
- /* TODO(ctiller): check for a status like " 0" */
428
- s->seen_error = true;
429
- }
430
-
431
- if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
432
- grpc_millis* cached_timeout = static_cast<grpc_millis*>(
433
- grpc_mdelem_get_user_data(md, free_timeout));
434
- grpc_millis timeout;
435
- if (cached_timeout != nullptr) {
436
- timeout = *cached_timeout;
437
- } else {
438
- if (GPR_UNLIKELY(
439
- !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) {
440
- char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
441
- gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
442
- gpr_free(val);
443
- timeout = GRPC_MILLIS_INF_FUTURE;
444
- }
445
- if (GRPC_MDELEM_IS_INTERNED(md)) {
446
- /* store the result */
447
- cached_timeout =
448
- static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis)));
449
- *cached_timeout = timeout;
450
- grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
451
- }
414
+ // If md.payload == GRPC_MDELEM_GRPC_STATUS_1 or GRPC_MDELEM_GRPC_STATUS_2,
415
+ // then we have seen an error. In fact, if it is a GRPC_STATUS and it's
416
+ // not equal to GRPC_MDELEM_GRPC_STATUS_0, then we have seen an error.
417
+ if (grpc_slice_eq_static_interned(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
418
+ !grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
419
+ /* TODO(ctiller): check for a status like " 0" */
420
+ s->seen_error = true;
421
+ } else if (grpc_slice_eq_static_interned(GRPC_MDKEY(md),
422
+ GRPC_MDSTR_GRPC_TIMEOUT)) {
423
+ grpc_millis* cached_timeout =
424
+ static_cast<grpc_millis*>(grpc_mdelem_get_user_data(md, free_timeout));
425
+ grpc_millis timeout;
426
+ if (cached_timeout != nullptr) {
427
+ timeout = *cached_timeout;
428
+ } else {
429
+ if (GPR_UNLIKELY(
430
+ !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) {
431
+ char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
432
+ gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
433
+ gpr_free(val);
434
+ timeout = GRPC_MILLIS_INF_FUTURE;
452
435
  }
453
- if (timeout != GRPC_MILLIS_INF_FUTURE) {
454
- grpc_chttp2_incoming_metadata_buffer_set_deadline(
455
- &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout);
436
+ if (GRPC_MDELEM_IS_INTERNED(md)) {
437
+ /* store the result */
438
+ cached_timeout =
439
+ static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis)));
440
+ *cached_timeout = timeout;
441
+ grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
456
442
  }
457
- GRPC_MDELEM_UNREF(md);
458
- return;
459
443
  }
444
+ if (timeout != GRPC_MILLIS_INF_FUTURE) {
445
+ grpc_chttp2_incoming_metadata_buffer_set_deadline(
446
+ &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout);
447
+ }
448
+ GRPC_MDELEM_UNREF(md);
449
+ return;
460
450
  }
461
451
 
462
452
  const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
@@ -506,19 +496,11 @@ static void on_trailing_header(void* tp, grpc_mdelem md) {
506
496
  gpr_free(value);
507
497
  }
508
498
 
509
- if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
510
- // We don't use grpc_mdelem_eq here to avoid executing additional
511
- // instructions. The reasoning is if the payload is not equal, we already
512
- // know that the metadata elements are not equal because the md is
513
- // confirmed to be static. If we had used grpc_mdelem_eq here, then if the
514
- // payloads are not equal, grpc_mdelem_eq executes more instructions to
515
- // determine if they're equal or not.
516
- if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload ||
517
- md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) {
518
- s->seen_error = true;
519
- }
520
- } else if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
521
- !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
499
+ // If md.payload == GRPC_MDELEM_GRPC_STATUS_1 or GRPC_MDELEM_GRPC_STATUS_2,
500
+ // then we have seen an error. In fact, if it is a GRPC_STATUS and it's
501
+ // not equal to GRPC_MDELEM_GRPC_STATUS_0, then we have seen an error.
502
+ if (grpc_slice_eq_static_interned(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
503
+ !grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
522
504
  /* TODO(ctiller): check for a status like " 0" */
523
505
  s->seen_error = true;
524
506
  }
@@ -40,12 +40,51 @@
40
40
  #include "src/core/lib/slice/slice_internal.h"
41
41
  #include "src/core/lib/surface/channel.h"
42
42
  #include "src/core/lib/surface/server.h"
43
+ #include "src/core/lib/transport/connectivity_state.h"
43
44
  #include "src/core/lib/transport/error_utils.h"
44
45
  #include "src/core/lib/uri/uri_parser.h"
45
46
 
46
47
  namespace grpc_core {
47
48
  namespace channelz {
48
49
 
50
+ //
51
+ // channel arg code
52
+ //
53
+
54
+ namespace {
55
+
56
+ void* parent_uuid_copy(void* p) { return p; }
57
+ void parent_uuid_destroy(void* p) {}
58
+ int parent_uuid_cmp(void* p1, void* p2) { return GPR_ICMP(p1, p2); }
59
+ const grpc_arg_pointer_vtable parent_uuid_vtable = {
60
+ parent_uuid_copy, parent_uuid_destroy, parent_uuid_cmp};
61
+
62
+ } // namespace
63
+
64
+ grpc_arg MakeParentUuidArg(intptr_t parent_uuid) {
65
+ // We would ideally like to store the uuid in an integer argument.
66
+ // Unfortunately, that won't work, because intptr_t (the type used for
67
+ // uuids) doesn't fit in an int (the type used for integer args).
68
+ // So instead, we use a hack to store it as a pointer, because
69
+ // intptr_t should be the same size as void*.
70
+ static_assert(sizeof(intptr_t) <= sizeof(void*),
71
+ "can't fit intptr_t inside of void*");
72
+ return grpc_channel_arg_pointer_create(
73
+ const_cast<char*>(GRPC_ARG_CHANNELZ_PARENT_UUID),
74
+ reinterpret_cast<void*>(parent_uuid), &parent_uuid_vtable);
75
+ }
76
+
77
+ intptr_t GetParentUuidFromArgs(const grpc_channel_args& args) {
78
+ const grpc_arg* arg =
79
+ grpc_channel_args_find(&args, GRPC_ARG_CHANNELZ_PARENT_UUID);
80
+ if (arg == nullptr || arg->type != GRPC_ARG_POINTER) return 0;
81
+ return reinterpret_cast<intptr_t>(arg->value.pointer.p);
82
+ }
83
+
84
+ //
85
+ // BaseNode
86
+ //
87
+
49
88
  BaseNode::BaseNode(EntityType type) : type_(type), uuid_(-1) {
50
89
  // The registry will set uuid_ under its lock.
51
90
  ChannelzRegistry::Register(this);
@@ -61,6 +100,10 @@ char* BaseNode::RenderJsonString() {
61
100
  return json_str;
62
101
  }
63
102
 
103
+ //
104
+ // CallCountingHelper
105
+ //
106
+
64
107
  CallCountingHelper::CallCountingHelper() {
65
108
  num_cores_ = GPR_MAX(1, gpr_cpu_num_cores());
66
109
  per_cpu_counter_data_storage_ = static_cast<AtomicCounterData*>(
@@ -137,15 +180,17 @@ void CallCountingHelper::PopulateCallCounts(grpc_json* json) {
137
180
  }
138
181
  }
139
182
 
140
- ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
141
- bool is_top_level_channel)
142
- : BaseNode(is_top_level_channel ? EntityType::kTopLevelChannel
143
- : EntityType::kInternalChannel),
144
- channel_(channel),
145
- target_(UniquePtr<char>(grpc_channel_get_target(channel_))),
146
- trace_(channel_tracer_max_nodes) {}
183
+ //
184
+ // ChannelNode
185
+ //
147
186
 
148
- ChannelNode::~ChannelNode() {}
187
+ ChannelNode::ChannelNode(UniquePtr<char> target,
188
+ size_t channel_tracer_max_nodes, intptr_t parent_uuid)
189
+ : BaseNode(parent_uuid == 0 ? EntityType::kTopLevelChannel
190
+ : EntityType::kInternalChannel),
191
+ target_(std::move(target)),
192
+ trace_(channel_tracer_max_nodes),
193
+ parent_uuid_(parent_uuid) {}
149
194
 
150
195
  grpc_json* ChannelNode::RenderJson() {
151
196
  // We need to track these three json objects to build our object
@@ -167,9 +212,19 @@ grpc_json* ChannelNode::RenderJson() {
167
212
  GRPC_JSON_OBJECT, false);
168
213
  json = data;
169
214
  json_iterator = nullptr;
170
- // template method. Child classes may override this to add their specific
171
- // functionality.
172
- PopulateConnectivityState(json);
215
+ // connectivity state
216
+ // If low-order bit is on, then the field is set.
217
+ int state_field = connectivity_state_.Load(MemoryOrder::RELAXED);
218
+ if ((state_field & 1) != 0) {
219
+ grpc_connectivity_state state =
220
+ static_cast<grpc_connectivity_state>(state_field >> 1);
221
+ json = grpc_json_create_child(nullptr, json, "state", nullptr,
222
+ GRPC_JSON_OBJECT, false);
223
+ grpc_json_create_child(nullptr, json, "state",
224
+ grpc_connectivity_state_name(state),
225
+ GRPC_JSON_STRING, false);
226
+ json = data;
227
+ }
173
228
  // populate the target.
174
229
  GPR_ASSERT(target_.get() != nullptr);
175
230
  grpc_json_create_child(nullptr, json, "target", target_.get(),
@@ -189,13 +244,64 @@ grpc_json* ChannelNode::RenderJson() {
189
244
  return top_level_json;
190
245
  }
191
246
 
192
- RefCountedPtr<ChannelNode> ChannelNode::MakeChannelNode(
193
- grpc_channel* channel, size_t channel_tracer_max_nodes,
194
- bool is_top_level_channel) {
195
- return MakeRefCounted<grpc_core::channelz::ChannelNode>(
196
- channel, channel_tracer_max_nodes, is_top_level_channel);
247
+ void ChannelNode::PopulateChildRefs(grpc_json* json) {
248
+ MutexLock lock(&child_mu_);
249
+ grpc_json* json_iterator = nullptr;
250
+ if (!child_subchannels_.empty()) {
251
+ grpc_json* array_parent = grpc_json_create_child(
252
+ nullptr, json, "subchannelRef", nullptr, GRPC_JSON_ARRAY, false);
253
+ for (const auto& p : child_subchannels_) {
254
+ json_iterator =
255
+ grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr,
256
+ GRPC_JSON_OBJECT, false);
257
+ grpc_json_add_number_string_child(json_iterator, nullptr, "subchannelId",
258
+ p.first);
259
+ }
260
+ }
261
+ if (!child_channels_.empty()) {
262
+ grpc_json* array_parent = grpc_json_create_child(
263
+ nullptr, json, "channelRef", nullptr, GRPC_JSON_ARRAY, false);
264
+ json_iterator = nullptr;
265
+ for (const auto& p : child_channels_) {
266
+ json_iterator =
267
+ grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr,
268
+ GRPC_JSON_OBJECT, false);
269
+ grpc_json_add_number_string_child(json_iterator, nullptr, "channelId",
270
+ p.first);
271
+ }
272
+ }
273
+ }
274
+
275
+ void ChannelNode::SetConnectivityState(grpc_connectivity_state state) {
276
+ // Store with low-order bit set to indicate that the field is set.
277
+ int state_field = (state << 1) + 1;
278
+ connectivity_state_.Store(state_field, MemoryOrder::RELAXED);
279
+ }
280
+
281
+ void ChannelNode::AddChildChannel(intptr_t child_uuid) {
282
+ MutexLock lock(&child_mu_);
283
+ child_channels_.insert(MakePair(child_uuid, true));
284
+ }
285
+
286
+ void ChannelNode::RemoveChildChannel(intptr_t child_uuid) {
287
+ MutexLock lock(&child_mu_);
288
+ child_channels_.erase(child_uuid);
197
289
  }
198
290
 
291
+ void ChannelNode::AddChildSubchannel(intptr_t child_uuid) {
292
+ MutexLock lock(&child_mu_);
293
+ child_subchannels_.insert(MakePair(child_uuid, true));
294
+ }
295
+
296
+ void ChannelNode::RemoveChildSubchannel(intptr_t child_uuid) {
297
+ MutexLock lock(&child_mu_);
298
+ child_subchannels_.erase(child_uuid);
299
+ }
300
+
301
+ //
302
+ // ServerNode
303
+ //
304
+
199
305
  ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes)
200
306
  : BaseNode(EntityType::kServer),
201
307
  server_(server),
@@ -281,8 +387,14 @@ grpc_json* ServerNode::RenderJson() {
281
387
  return top_level_json;
282
388
  }
283
389
 
284
- static void PopulateSocketAddressJson(grpc_json* json, const char* name,
285
- const char* addr_str) {
390
+ //
391
+ // SocketNode
392
+ //
393
+
394
+ namespace {
395
+
396
+ void PopulateSocketAddressJson(grpc_json* json, const char* name,
397
+ const char* addr_str) {
286
398
  if (addr_str == nullptr) return;
287
399
  grpc_json* json_iterator = nullptr;
288
400
  json_iterator = grpc_json_create_child(json_iterator, json, name, nullptr,
@@ -312,7 +424,6 @@ static void PopulateSocketAddressJson(grpc_json* json, const char* name,
312
424
  b64_host, GRPC_JSON_STRING, true);
313
425
  gpr_free(host);
314
426
  gpr_free(port);
315
-
316
427
  } else if (uri != nullptr && strcmp(uri->scheme, "unix") == 0) {
317
428
  json_iterator = grpc_json_create_child(json_iterator, json, "uds_address",
318
429
  nullptr, GRPC_JSON_OBJECT, false);
@@ -332,6 +443,8 @@ static void PopulateSocketAddressJson(grpc_json* json, const char* name,
332
443
  grpc_uri_destroy(uri);
333
444
  }
334
445
 
446
+ } // namespace
447
+
335
448
  SocketNode::SocketNode(UniquePtr<char> local, UniquePtr<char> remote)
336
449
  : BaseNode(EntityType::kSocket),
337
450
  local_(std::move(local)),
@@ -448,6 +561,10 @@ grpc_json* SocketNode::RenderJson() {
448
561
  return top_level_json;
449
562
  }
450
563
 
564
+ //
565
+ // ListenSocketNode
566
+ //
567
+
451
568
  ListenSocketNode::ListenSocketNode(UniquePtr<char> local_addr)
452
569
  : BaseNode(EntityType::kSocket), local_addr_(std::move(local_addr)) {}
453
570