grpc 1.22.0 → 1.23.0

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 (176) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +487 -649
  3. data/include/grpc/grpc_security.h +25 -0
  4. data/include/grpc/impl/codegen/grpc_types.h +11 -2
  5. data/include/grpc/impl/codegen/port_platform.h +12 -0
  6. data/src/core/ext/filters/client_channel/backup_poller.cc +4 -2
  7. data/src/core/ext/filters/client_channel/client_channel.cc +477 -182
  8. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +25 -16
  9. data/src/core/ext/filters/client_channel/client_channel_channelz.h +11 -6
  10. data/src/core/ext/filters/client_channel/connector.h +10 -2
  11. data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -3
  12. data/src/core/ext/filters/client_channel/http_proxy.cc +9 -10
  13. data/src/core/ext/filters/client_channel/lb_policy.cc +2 -17
  14. data/src/core/ext/filters/client_channel/lb_policy.h +36 -8
  15. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +22 -8
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +86 -52
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +7 -0
  18. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +73 -72
  19. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +8 -12
  20. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +25 -101
  21. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +5 -5
  22. data/src/core/ext/filters/client_channel/parse_address.cc +29 -26
  23. data/src/core/ext/filters/client_channel/resolver.h +3 -11
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +5 -3
  25. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +405 -82
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +44 -51
  27. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +0 -1
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +0 -1
  29. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +11 -6
  30. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +130 -65
  31. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +8 -3
  32. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +31 -14
  33. data/src/core/ext/filters/client_channel/resolver_factory.h +4 -0
  34. data/src/core/ext/filters/client_channel/resolver_registry.cc +11 -0
  35. data/src/core/ext/filters/client_channel/resolver_registry.h +3 -0
  36. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +10 -49
  37. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +1 -14
  38. data/src/core/ext/filters/client_channel/retry_throttle.h +2 -3
  39. data/src/core/ext/filters/client_channel/subchannel.cc +65 -58
  40. data/src/core/ext/filters/client_channel/subchannel.h +65 -45
  41. data/src/core/ext/filters/client_channel/subchannel_interface.h +15 -30
  42. data/src/core/ext/filters/client_idle/client_idle_filter.cc +262 -0
  43. data/src/core/ext/filters/http/client/http_client_filter.cc +4 -5
  44. data/src/core/ext/filters/http/client_authority_filter.cc +2 -2
  45. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +140 -152
  46. data/src/core/ext/filters/max_age/max_age_filter.cc +3 -3
  47. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +3 -4
  48. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +7 -6
  49. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +63 -38
  50. data/src/core/ext/transport/chttp2/transport/context_list.cc +3 -1
  51. data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -4
  52. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +1 -1
  53. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -0
  54. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +8 -0
  55. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +7 -0
  56. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +1 -0
  57. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +37 -22
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +136 -81
  59. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -0
  60. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +7 -166
  61. data/src/core/ext/transport/chttp2/transport/hpack_table.h +41 -15
  62. data/src/core/ext/transport/chttp2/transport/internal.h +13 -2
  63. data/src/core/ext/transport/chttp2/transport/parsing.cc +35 -22
  64. data/src/core/ext/transport/chttp2/transport/stream_map.cc +28 -18
  65. data/src/core/ext/transport/chttp2/transport/writing.cc +1 -0
  66. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
  67. data/src/core/lib/channel/channelz.cc +80 -33
  68. data/src/core/lib/channel/channelz.h +28 -13
  69. data/src/core/lib/compression/compression.cc +1 -2
  70. data/src/core/lib/compression/compression_args.cc +13 -6
  71. data/src/core/lib/compression/compression_args.h +3 -2
  72. data/src/core/lib/compression/compression_internal.cc +1 -1
  73. data/src/core/lib/gpr/env_linux.cc +10 -21
  74. data/src/core/lib/gpr/env_posix.cc +0 -5
  75. data/src/core/lib/gpr/string.cc +7 -2
  76. data/src/core/lib/gpr/string.h +1 -0
  77. data/src/core/lib/gpr/sync_posix.cc +0 -129
  78. data/src/core/lib/gprpp/debug_location.h +3 -2
  79. data/src/core/lib/gprpp/fork.cc +14 -21
  80. data/src/core/lib/gprpp/fork.h +15 -4
  81. data/src/core/lib/gprpp/host_port.cc +118 -0
  82. data/src/core/lib/{gpr → gprpp}/host_port.h +27 -11
  83. data/src/core/lib/gprpp/map.h +25 -0
  84. data/src/core/lib/gprpp/memory.h +26 -9
  85. data/src/core/lib/gprpp/ref_counted.h +63 -21
  86. data/src/core/lib/gprpp/string_view.h +143 -0
  87. data/src/core/lib/gprpp/thd.h +10 -1
  88. data/src/core/lib/gprpp/thd_posix.cc +25 -0
  89. data/src/core/lib/gprpp/thd_windows.cc +9 -1
  90. data/src/core/lib/http/httpcli_security_connector.cc +3 -1
  91. data/src/core/lib/iomgr/cfstream_handle.cc +6 -1
  92. data/src/core/lib/iomgr/cfstream_handle.h +8 -2
  93. data/src/core/lib/iomgr/combiner.cc +4 -4
  94. data/src/core/lib/iomgr/error.cc +18 -8
  95. data/src/core/lib/iomgr/error.h +2 -0
  96. data/src/core/lib/iomgr/ev_posix.cc +4 -2
  97. data/src/core/lib/iomgr/executor.cc +4 -1
  98. data/src/core/lib/iomgr/executor/mpmcqueue.cc +183 -0
  99. data/src/core/lib/iomgr/executor/mpmcqueue.h +178 -0
  100. data/src/core/lib/iomgr/executor/threadpool.cc +138 -0
  101. data/src/core/lib/iomgr/executor/threadpool.h +153 -0
  102. data/src/core/lib/iomgr/fork_posix.cc +4 -2
  103. data/src/core/lib/iomgr/iocp_windows.cc +2 -2
  104. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +14 -0
  105. data/src/core/lib/iomgr/iomgr_uv.cc +3 -0
  106. data/src/core/lib/iomgr/lockfree_event.cc +3 -3
  107. data/src/core/lib/iomgr/resolve_address_custom.cc +16 -20
  108. data/src/core/lib/iomgr/resolve_address_posix.cc +8 -10
  109. data/src/core/lib/iomgr/resolve_address_windows.cc +6 -8
  110. data/src/core/lib/iomgr/sockaddr_utils.cc +5 -3
  111. data/src/core/lib/iomgr/socket_utils_common_posix.cc +0 -1
  112. data/src/core/lib/iomgr/socket_windows.h +1 -1
  113. data/src/core/lib/iomgr/tcp_client_cfstream.cc +7 -6
  114. data/src/core/lib/iomgr/tcp_client_custom.cc +1 -0
  115. data/src/core/lib/iomgr/tcp_custom.cc +4 -0
  116. data/src/core/lib/iomgr/tcp_posix.cc +8 -2
  117. data/src/core/lib/iomgr/tcp_server_custom.cc +1 -0
  118. data/src/core/lib/iomgr/tcp_server_windows.cc +1 -1
  119. data/src/core/lib/iomgr/tcp_windows.cc +7 -7
  120. data/src/core/lib/iomgr/timer_custom.cc +1 -0
  121. data/src/core/lib/iomgr/timer_manager.cc +0 -29
  122. data/src/core/lib/security/credentials/credentials.cc +84 -0
  123. data/src/core/lib/security/credentials/credentials.h +58 -2
  124. data/src/core/lib/security/credentials/jwt/json_token.cc +6 -2
  125. data/src/core/lib/security/credentials/jwt/json_token.h +1 -1
  126. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +245 -24
  127. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +16 -0
  128. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +3 -2
  129. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +21 -25
  130. data/src/core/lib/security/security_connector/local/local_security_connector.cc +3 -2
  131. data/src/core/lib/security/security_connector/security_connector.cc +1 -1
  132. data/src/core/lib/security/security_connector/security_connector.h +1 -1
  133. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +19 -19
  134. data/src/core/lib/security/security_connector/ssl_utils.cc +26 -31
  135. data/src/core/lib/security/security_connector/ssl_utils.h +11 -8
  136. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +16 -20
  137. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +4 -3
  138. data/src/core/lib/security/transport/client_auth_filter.cc +1 -2
  139. data/src/core/lib/security/util/json_util.cc +19 -5
  140. data/src/core/lib/security/util/json_util.h +3 -1
  141. data/src/core/lib/slice/slice.cc +69 -50
  142. data/src/core/lib/slice/slice_buffer.cc +6 -5
  143. data/src/core/lib/slice/slice_hash_table.h +3 -7
  144. data/src/core/lib/slice/slice_intern.cc +130 -39
  145. data/src/core/lib/slice/slice_internal.h +8 -0
  146. data/src/core/lib/slice/slice_utils.h +120 -0
  147. data/src/core/lib/slice/slice_weak_hash_table.h +2 -7
  148. data/src/core/lib/surface/call.cc +8 -3
  149. data/src/core/lib/surface/channel.cc +31 -8
  150. data/src/core/lib/surface/completion_queue.cc +17 -7
  151. data/src/core/lib/surface/init_secure.cc +4 -1
  152. data/src/core/lib/surface/lame_client.cc +2 -2
  153. data/src/core/lib/surface/server.cc +34 -35
  154. data/src/core/lib/surface/server.h +8 -17
  155. data/src/core/lib/surface/version.cc +1 -1
  156. data/src/core/lib/transport/byte_stream.cc +3 -5
  157. data/src/core/lib/transport/byte_stream.h +1 -2
  158. data/src/core/lib/transport/error_utils.cc +10 -1
  159. data/src/core/lib/transport/metadata.cc +202 -35
  160. data/src/core/lib/transport/metadata.h +81 -6
  161. data/src/core/lib/transport/static_metadata.cc +1257 -465
  162. data/src/core/lib/transport/static_metadata.h +190 -347
  163. data/src/core/lib/transport/timeout_encoding.cc +7 -0
  164. data/src/core/lib/transport/timeout_encoding.h +3 -2
  165. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  166. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +0 -1
  167. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -7
  168. data/src/core/tsi/ssl_transport_security.cc +35 -43
  169. data/src/core/tsi/ssl_transport_security.h +2 -1
  170. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  171. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  172. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  173. data/src/ruby/lib/grpc/grpc.rb +1 -1
  174. data/src/ruby/lib/grpc/version.rb +1 -1
  175. metadata +39 -33
  176. data/src/core/lib/gpr/host_port.cc +0 -98
@@ -22,6 +22,7 @@
22
22
  #include <grpc/support/port_platform.h>
23
23
 
24
24
  #include <grpc/slice.h>
25
+ #include "src/core/lib/gprpp/memory.h"
25
26
  #include "src/core/lib/iomgr/error.h"
26
27
  #include "src/core/lib/transport/metadata.h"
27
28
  #include "src/core/lib/transport/static_metadata.h"
@@ -46,32 +47,45 @@
46
47
  #endif
47
48
 
48
49
  /* hpack decoder table */
49
- typedef struct {
50
+ struct grpc_chttp2_hptbl {
51
+ static uint32_t entries_for_bytes(uint32_t bytes) {
52
+ return (bytes + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) /
53
+ GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
54
+ }
55
+ static constexpr uint32_t kInitialCapacity =
56
+ (GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD -
57
+ 1) /
58
+ GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
59
+
60
+ grpc_chttp2_hptbl() {
61
+ GPR_DEBUG_ASSERT(!ents);
62
+ constexpr uint32_t AllocSize = sizeof(*ents) * kInitialCapacity;
63
+ ents = static_cast<grpc_mdelem*>(gpr_malloc(AllocSize));
64
+ memset(ents, 0, AllocSize);
65
+ }
66
+
50
67
  /* the first used entry in ents */
51
- uint32_t first_ent;
68
+ uint32_t first_ent = 0;
52
69
  /* how many entries are in the table */
53
- uint32_t num_ents;
70
+ uint32_t num_ents = 0;
54
71
  /* the amount of memory used by the table, according to the hpack algorithm */
55
- uint32_t mem_used;
72
+ uint32_t mem_used = 0;
56
73
  /* the max memory allowed to be used by the table, according to the hpack
57
74
  algorithm */
58
- uint32_t max_bytes;
75
+ uint32_t max_bytes = GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE;
59
76
  /* the currently agreed size of the table, according to the hpack algorithm */
60
- uint32_t current_table_bytes;
77
+ uint32_t current_table_bytes = GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE;
61
78
  /* Maximum number of entries we could possibly fit in the table, given defined
62
79
  overheads */
63
- uint32_t max_entries;
80
+ uint32_t max_entries = kInitialCapacity;
64
81
  /* Number of entries allocated in ents */
65
- uint32_t cap_entries;
82
+ uint32_t cap_entries = kInitialCapacity;
66
83
  /* a circular buffer of headers - this is stored in the opposite order to
67
84
  what hpack specifies, in order to simplify table management a little...
68
85
  meaning lookups need to SUBTRACT from the end position */
69
- grpc_mdelem* ents;
70
- grpc_mdelem static_ents[GRPC_CHTTP2_LAST_STATIC_ENTRY];
71
- } grpc_chttp2_hptbl;
86
+ grpc_mdelem* ents = nullptr;
87
+ };
72
88
 
73
- /* initialize a hpack table */
74
- void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl);
75
89
  void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl* tbl);
76
90
  void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl* tbl,
77
91
  uint32_t max_bytes);
@@ -79,8 +93,20 @@ grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl,
79
93
  uint32_t bytes);
80
94
 
81
95
  /* lookup a table entry based on its hpack index */
82
- grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl,
83
- uint32_t index);
96
+ grpc_mdelem grpc_chttp2_hptbl_lookup_dynamic_index(const grpc_chttp2_hptbl* tbl,
97
+ uint32_t tbl_index);
98
+ inline grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl,
99
+ uint32_t index) {
100
+ /* Static table comes first, just return an entry from it.
101
+ NB: This imposes the constraint that the first
102
+ GRPC_CHTTP2_LAST_STATIC_ENTRY entries in the core static metadata table
103
+ must follow the hpack standard. If that changes, we *must* not rely on
104
+ reading the core static metadata table here; at that point we'd need our
105
+ own singleton static metadata in the correct order. */
106
+ return index <= GRPC_CHTTP2_LAST_STATIC_ENTRY
107
+ ? grpc_static_mdelem_manifested[index - 1]
108
+ : grpc_chttp2_hptbl_lookup_dynamic_index(tbl, index);
109
+ }
84
110
  /* add a table entry to the index */
85
111
  grpc_error* grpc_chttp2_hptbl_add(grpc_chttp2_hptbl* tbl,
86
112
  grpc_mdelem md) GRPC_MUST_USE_RESULT;
@@ -493,6 +493,13 @@ struct grpc_chttp2_transport {
493
493
  grpc_core::ContextList* cl = nullptr;
494
494
  grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> channelz_socket;
495
495
  uint32_t num_messages_in_next_write = 0;
496
+ /** The number of pending induced frames (SETTINGS_ACK, PINGS_ACK and
497
+ * RST_STREAM) in the outgoing buffer (t->qbuf). If this number goes beyond
498
+ * DEFAULT_MAX_PENDING_INDUCED_FRAMES, we pause reading new frames. We would
499
+ * only continue reading when we are able to write to the socket again,
500
+ * thereby reducing the number of induced frames. */
501
+ uint32_t num_pending_induced_frames = 0;
502
+ bool reading_paused_on_pending_induced_frames = false;
496
503
  };
497
504
 
498
505
  typedef enum {
@@ -745,13 +752,17 @@ void grpc_chttp2_act_on_flowctl_action(
745
752
 
746
753
  /********* End of Flow Control ***************/
747
754
 
748
- grpc_chttp2_stream* grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport* t,
749
- uint32_t id);
755
+ inline grpc_chttp2_stream* grpc_chttp2_parsing_lookup_stream(
756
+ grpc_chttp2_transport* t, uint32_t id) {
757
+ return static_cast<grpc_chttp2_stream*>(
758
+ grpc_chttp2_stream_map_find(&t->stream_map, id));
759
+ }
750
760
  grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t,
751
761
  uint32_t id);
752
762
 
753
763
  void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t,
754
764
  uint32_t goaway_error,
765
+ uint32_t last_stream_id,
755
766
  const grpc_slice& goaway_text);
756
767
 
757
768
  void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport* t);
@@ -382,10 +382,9 @@ error_handler:
382
382
  if (s != nullptr) {
383
383
  grpc_chttp2_mark_stream_closed(t, s, true, false, err);
384
384
  }
385
- grpc_slice_buffer_add(
386
- &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id,
387
- GRPC_HTTP2_PROTOCOL_ERROR,
388
- &s->stats.outgoing));
385
+ grpc_chttp2_add_rst_stream_to_next_write(t, t->incoming_stream_id,
386
+ GRPC_HTTP2_PROTOCOL_ERROR,
387
+ &s->stats.outgoing);
389
388
  return init_skip_frame_parser(t, 0);
390
389
  } else {
391
390
  return err;
@@ -394,6 +393,32 @@ error_handler:
394
393
 
395
394
  static void free_timeout(void* p) { gpr_free(p); }
396
395
 
396
+ static bool md_key_cmp(grpc_mdelem md, const grpc_slice& reference) {
397
+ GPR_DEBUG_ASSERT(grpc_slice_is_interned(GRPC_MDKEY(md)));
398
+ return GRPC_MDKEY(md).refcount == reference.refcount;
399
+ }
400
+
401
+ static bool md_cmp(grpc_mdelem md, grpc_mdelem ref_md,
402
+ const grpc_slice& ref_key) {
403
+ if (GPR_LIKELY(GRPC_MDELEM_IS_INTERNED(md))) {
404
+ return md.payload == ref_md.payload;
405
+ }
406
+ if (md_key_cmp(md, ref_key)) {
407
+ return grpc_slice_eq_static_interned(GRPC_MDVALUE(md),
408
+ GRPC_MDVALUE(ref_md));
409
+ }
410
+ return false;
411
+ }
412
+
413
+ static bool is_nonzero_status(grpc_mdelem md) {
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
+ // TODO(ctiller): check for a status like " 0"
418
+ return md_key_cmp(md, GRPC_MDSTR_GRPC_STATUS) &&
419
+ !md_cmp(md, GRPC_MDELEM_GRPC_STATUS_0, GRPC_MDSTR_GRPC_STATUS);
420
+ }
421
+
397
422
  static void on_initial_header(void* tp, grpc_mdelem md) {
398
423
  GPR_TIMER_SCOPE("on_initial_header", 0);
399
424
 
@@ -411,15 +436,9 @@ static void on_initial_header(void* tp, grpc_mdelem md) {
411
436
  gpr_free(value);
412
437
  }
413
438
 
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" */
439
+ if (is_nonzero_status(md)) { // not GRPC_MDELEM_GRPC_STATUS_0?
420
440
  s->seen_error = true;
421
- } else if (grpc_slice_eq_static_interned(GRPC_MDKEY(md),
422
- GRPC_MDSTR_GRPC_TIMEOUT)) {
441
+ } else if (md_key_cmp(md, GRPC_MDSTR_GRPC_TIMEOUT)) {
423
442
  grpc_millis* cached_timeout =
424
443
  static_cast<grpc_millis*>(grpc_mdelem_get_user_data(md, free_timeout));
425
444
  grpc_millis timeout;
@@ -496,12 +515,7 @@ static void on_trailing_header(void* tp, grpc_mdelem md) {
496
515
  gpr_free(value);
497
516
  }
498
517
 
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)) {
504
- /* TODO(ctiller): check for a status like " 0" */
518
+ if (is_nonzero_status(md)) { // not GRPC_MDELEM_GRPC_STATUS_0?
505
519
  s->seen_error = true;
506
520
  }
507
521
 
@@ -750,10 +764,9 @@ static grpc_error* parse_frame_slice(grpc_chttp2_transport* t,
750
764
  grpc_chttp2_parsing_become_skip_parser(t);
751
765
  if (s) {
752
766
  s->forced_close_error = err;
753
- grpc_slice_buffer_add(
754
- &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id,
755
- GRPC_HTTP2_PROTOCOL_ERROR,
756
- &s->stats.outgoing));
767
+ grpc_chttp2_add_rst_stream_to_next_write(t, t->incoming_stream_id,
768
+ GRPC_HTTP2_PROTOCOL_ERROR,
769
+ &s->stats.outgoing);
757
770
  } else {
758
771
  GRPC_ERROR_UNREF(err);
759
772
  }
@@ -27,7 +27,7 @@
27
27
 
28
28
  void grpc_chttp2_stream_map_init(grpc_chttp2_stream_map* map,
29
29
  size_t initial_capacity) {
30
- GPR_ASSERT(initial_capacity > 1);
30
+ GPR_DEBUG_ASSERT(initial_capacity > 1);
31
31
  map->keys =
32
32
  static_cast<uint32_t*>(gpr_malloc(sizeof(uint32_t) * initial_capacity));
33
33
  map->values =
@@ -63,9 +63,17 @@ void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map* map, uint32_t key,
63
63
  uint32_t* keys = map->keys;
64
64
  void** values = map->values;
65
65
 
66
+ // The first assertion ensures that the table is monotonically increasing.
66
67
  GPR_ASSERT(count == 0 || keys[count - 1] < key);
67
- GPR_ASSERT(value);
68
- GPR_ASSERT(grpc_chttp2_stream_map_find(map, key) == nullptr);
68
+ GPR_DEBUG_ASSERT(value);
69
+ // Asserting that the key is not already in the map can be a debug assertion.
70
+ // Why: we're already checking that the map elements are monotonically
71
+ // increasing. If we re-add a key, i.e. if the key is already present, then
72
+ // either it is the most recently added key in the map (in which case the
73
+ // first assertion fails due to key == last_key) or there is a more recently
74
+ // added (larger) key at the end of the map: in which case the first assertion
75
+ // still fails due to key < last_key.
76
+ GPR_DEBUG_ASSERT(grpc_chttp2_stream_map_find(map, key) == nullptr);
69
77
 
70
78
  if (count == capacity) {
71
79
  if (map->free > capacity / 4) {
@@ -74,7 +82,7 @@ void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map* map, uint32_t key,
74
82
  } else {
75
83
  /* resize when less than 25% of the table is free, because compaction
76
84
  won't help much */
77
- map->capacity = capacity = 3 * capacity / 2;
85
+ map->capacity = capacity = 2 * capacity;
78
86
  map->keys = keys = static_cast<uint32_t*>(
79
87
  gpr_realloc(keys, capacity * sizeof(uint32_t)));
80
88
  map->values = values =
@@ -87,6 +95,7 @@ void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map* map, uint32_t key,
87
95
  map->count = count + 1;
88
96
  }
89
97
 
98
+ template <bool strict_find>
90
99
  static void** find(grpc_chttp2_stream_map* map, uint32_t key) {
91
100
  size_t min_idx = 0;
92
101
  size_t max_idx = map->count;
@@ -95,7 +104,8 @@ static void** find(grpc_chttp2_stream_map* map, uint32_t key) {
95
104
  void** values = map->values;
96
105
  uint32_t mid_key;
97
106
 
98
- if (max_idx == 0) return nullptr;
107
+ GPR_DEBUG_ASSERT(!strict_find || max_idx > 0);
108
+ if (!strict_find && max_idx == 0) return nullptr;
99
109
 
100
110
  while (min_idx < max_idx) {
101
111
  /* find the midpoint, avoiding overflow */
@@ -112,28 +122,28 @@ static void** find(grpc_chttp2_stream_map* map, uint32_t key) {
112
122
  }
113
123
  }
114
124
 
125
+ GPR_DEBUG_ASSERT(!strict_find);
115
126
  return nullptr;
116
127
  }
117
128
 
118
129
  void* grpc_chttp2_stream_map_delete(grpc_chttp2_stream_map* map, uint32_t key) {
119
- void** pvalue = find(map, key);
120
- void* out = nullptr;
121
- if (pvalue != nullptr) {
122
- out = *pvalue;
123
- *pvalue = nullptr;
124
- map->free += (out != nullptr);
125
- /* recognize complete emptyness and ensure we can skip
126
- * defragmentation later */
127
- if (map->free == map->count) {
128
- map->free = map->count = 0;
129
- }
130
- GPR_ASSERT(grpc_chttp2_stream_map_find(map, key) == nullptr);
130
+ void** pvalue = find<true>(map, key);
131
+ GPR_DEBUG_ASSERT(pvalue != nullptr);
132
+ void* out = *pvalue;
133
+ GPR_DEBUG_ASSERT(out != nullptr);
134
+ *pvalue = nullptr;
135
+ map->free++;
136
+ /* recognize complete emptyness and ensure we can skip
137
+ defragmentation later */
138
+ if (map->free == map->count) {
139
+ map->free = map->count = 0;
131
140
  }
141
+ GPR_DEBUG_ASSERT(grpc_chttp2_stream_map_find(map, key) == nullptr);
132
142
  return out;
133
143
  }
134
144
 
135
145
  void* grpc_chttp2_stream_map_find(grpc_chttp2_stream_map* map, uint32_t key) {
136
- void** pvalue = find(map, key);
146
+ void** pvalue = find<false>(map, key);
137
147
  return pvalue != nullptr ? *pvalue : nullptr;
138
148
  }
139
149
 
@@ -219,6 +219,7 @@ class WriteContext {
219
219
  void FlushQueuedBuffers() {
220
220
  /* simple writes are queued to qbuf, and flushed here */
221
221
  grpc_slice_buffer_move_into(&t_->qbuf, &t_->outbuf);
222
+ t_->num_pending_induced_frames = 0;
222
223
  GPR_ASSERT(t_->qbuf.count == 0);
223
224
  }
224
225
 
@@ -1203,7 +1203,7 @@ void inproc_transports_create(grpc_transport** server_transport,
1203
1203
  */
1204
1204
  void grpc_inproc_transport_init(void) {
1205
1205
  grpc_core::ExecCtx exec_ctx;
1206
- g_empty_slice = grpc_slice_from_static_buffer(nullptr, 0);
1206
+ g_empty_slice = grpc_core::ExternallyManagedSlice();
1207
1207
 
1208
1208
  grpc_slice key_tmp = grpc_slice_from_static_string(":path");
1209
1209
  g_fake_path_key = grpc_slice_intern(key_tmp);
@@ -30,9 +30,9 @@
30
30
 
31
31
  #include "src/core/lib/channel/channelz_registry.h"
32
32
  #include "src/core/lib/channel/status_util.h"
33
- #include "src/core/lib/gpr/host_port.h"
34
33
  #include "src/core/lib/gpr/string.h"
35
34
  #include "src/core/lib/gpr/useful.h"
35
+ #include "src/core/lib/gprpp/host_port.h"
36
36
  #include "src/core/lib/gprpp/memory.h"
37
37
  #include "src/core/lib/iomgr/error.h"
38
38
  #include "src/core/lib/iomgr/exec_ctx.h"
@@ -85,7 +85,8 @@ intptr_t GetParentUuidFromArgs(const grpc_channel_args& args) {
85
85
  // BaseNode
86
86
  //
87
87
 
88
- BaseNode::BaseNode(EntityType type) : type_(type), uuid_(-1) {
88
+ BaseNode::BaseNode(EntityType type, UniquePtr<char> name)
89
+ : type_(type), uuid_(-1), name_(std::move(name)) {
89
90
  // The registry will set uuid_ under its lock.
90
91
  ChannelzRegistry::Register(this);
91
92
  }
@@ -187,11 +188,29 @@ void CallCountingHelper::PopulateCallCounts(grpc_json* json) {
187
188
  ChannelNode::ChannelNode(UniquePtr<char> target,
188
189
  size_t channel_tracer_max_nodes, intptr_t parent_uuid)
189
190
  : BaseNode(parent_uuid == 0 ? EntityType::kTopLevelChannel
190
- : EntityType::kInternalChannel),
191
+ : EntityType::kInternalChannel,
192
+ UniquePtr<char>(gpr_strdup(target.get()))),
191
193
  target_(std::move(target)),
192
194
  trace_(channel_tracer_max_nodes),
193
195
  parent_uuid_(parent_uuid) {}
194
196
 
197
+ const char* ChannelNode::GetChannelConnectivityStateChangeString(
198
+ grpc_connectivity_state state) {
199
+ switch (state) {
200
+ case GRPC_CHANNEL_IDLE:
201
+ return "Channel state change to IDLE";
202
+ case GRPC_CHANNEL_CONNECTING:
203
+ return "Channel state change to CONNECTING";
204
+ case GRPC_CHANNEL_READY:
205
+ return "Channel state change to READY";
206
+ case GRPC_CHANNEL_TRANSIENT_FAILURE:
207
+ return "Channel state change to TRANSIENT_FAILURE";
208
+ case GRPC_CHANNEL_SHUTDOWN:
209
+ return "Channel state change to SHUTDOWN";
210
+ }
211
+ GPR_UNREACHABLE_CODE(return "UNKNOWN");
212
+ }
213
+
195
214
  grpc_json* ChannelNode::RenderJson() {
196
215
  // We need to track these three json objects to build our object
197
216
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
@@ -303,37 +322,57 @@ void ChannelNode::RemoveChildSubchannel(intptr_t child_uuid) {
303
322
  //
304
323
 
305
324
  ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes)
306
- : BaseNode(EntityType::kServer),
307
- server_(server),
325
+ : BaseNode(EntityType::kServer, /* name */ nullptr),
308
326
  trace_(channel_tracer_max_nodes) {}
309
327
 
310
328
  ServerNode::~ServerNode() {}
311
329
 
330
+ void ServerNode::AddChildSocket(RefCountedPtr<SocketNode> node) {
331
+ MutexLock lock(&child_mu_);
332
+ child_sockets_.insert(MakePair(node->uuid(), std::move(node)));
333
+ }
334
+
335
+ void ServerNode::RemoveChildSocket(intptr_t child_uuid) {
336
+ MutexLock lock(&child_mu_);
337
+ child_sockets_.erase(child_uuid);
338
+ }
339
+
340
+ void ServerNode::AddChildListenSocket(RefCountedPtr<ListenSocketNode> node) {
341
+ MutexLock lock(&child_mu_);
342
+ child_listen_sockets_.insert(MakePair(node->uuid(), std::move(node)));
343
+ }
344
+
345
+ void ServerNode::RemoveChildListenSocket(intptr_t child_uuid) {
346
+ MutexLock lock(&child_mu_);
347
+ child_listen_sockets_.erase(child_uuid);
348
+ }
349
+
312
350
  char* ServerNode::RenderServerSockets(intptr_t start_socket_id,
313
351
  intptr_t max_results) {
314
- // if user does not set max_results, we choose 500.
352
+ // If user does not set max_results, we choose 500.
315
353
  size_t pagination_limit = max_results == 0 ? 500 : max_results;
316
354
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
317
355
  grpc_json* json = top_level_json;
318
356
  grpc_json* json_iterator = nullptr;
319
- ChildSocketsList socket_refs;
320
- grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id);
321
- // declared early so it can be used outside of the loop.
322
- size_t i = 0;
323
- if (!socket_refs.empty()) {
324
- // create list of socket refs
357
+ MutexLock lock(&child_mu_);
358
+ size_t sockets_rendered = 0;
359
+ if (!child_sockets_.empty()) {
360
+ // Create list of socket refs
325
361
  grpc_json* array_parent = grpc_json_create_child(
326
362
  nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false);
327
- for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) {
363
+ const size_t limit = GPR_MIN(child_sockets_.size(), pagination_limit);
364
+ for (auto it = child_sockets_.lower_bound(start_socket_id);
365
+ it != child_sockets_.end() && sockets_rendered < limit;
366
+ ++it, ++sockets_rendered) {
328
367
  grpc_json* socket_ref_json = grpc_json_create_child(
329
368
  nullptr, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false);
330
369
  json_iterator = grpc_json_add_number_string_child(
331
- socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid());
370
+ socket_ref_json, nullptr, "socketId", it->first);
332
371
  grpc_json_create_child(json_iterator, socket_ref_json, "name",
333
- socket_refs[i]->remote(), GRPC_JSON_STRING, false);
372
+ it->second->name(), GRPC_JSON_STRING, false);
334
373
  }
335
374
  }
336
- if (i == socket_refs.size()) {
375
+ if (sockets_rendered == child_sockets_.size()) {
337
376
  json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
338
377
  GRPC_JSON_TRUE, false);
339
378
  }
@@ -371,17 +410,19 @@ grpc_json* ServerNode::RenderJson() {
371
410
  // ask CallCountingHelper to populate trace and call count data.
372
411
  call_counter_.PopulateCallCounts(json);
373
412
  json = top_level_json;
374
- ChildRefsList listen_sockets;
375
- grpc_server_populate_listen_sockets(server_, &listen_sockets);
376
- if (!listen_sockets.empty()) {
413
+ // Render listen sockets
414
+ MutexLock lock(&child_mu_);
415
+ if (!child_listen_sockets_.empty()) {
377
416
  grpc_json* array_parent = grpc_json_create_child(
378
417
  nullptr, json, "listenSocket", nullptr, GRPC_JSON_ARRAY, false);
379
- for (size_t i = 0; i < listen_sockets.size(); ++i) {
418
+ for (const auto& it : child_listen_sockets_) {
380
419
  json_iterator =
381
420
  grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr,
382
421
  GRPC_JSON_OBJECT, false);
383
- grpc_json_add_number_string_child(json_iterator, nullptr, "socketId",
384
- listen_sockets[i]);
422
+ grpc_json* sibling_iterator = grpc_json_add_number_string_child(
423
+ json_iterator, nullptr, "socketId", it.first);
424
+ grpc_json_create_child(sibling_iterator, json_iterator, "name",
425
+ it.second->name(), GRPC_JSON_STRING, false);
385
426
  }
386
427
  }
387
428
  return top_level_json;
@@ -406,14 +447,15 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name,
406
447
  (strcmp(uri->scheme, "ipv6") == 0))) {
407
448
  const char* host_port = uri->path;
408
449
  if (*host_port == '/') ++host_port;
409
- char* host = nullptr;
410
- char* port = nullptr;
411
- GPR_ASSERT(gpr_split_host_port(host_port, &host, &port));
450
+ UniquePtr<char> host;
451
+ UniquePtr<char> port;
452
+ GPR_ASSERT(SplitHostPort(host_port, &host, &port));
412
453
  int port_num = -1;
413
454
  if (port != nullptr) {
414
- port_num = atoi(port);
455
+ port_num = atoi(port.get());
415
456
  }
416
- char* b64_host = grpc_base64_encode(host, strlen(host), false, false);
457
+ char* b64_host =
458
+ grpc_base64_encode(host.get(), strlen(host.get()), false, false);
417
459
  json_iterator = grpc_json_create_child(json_iterator, json, "tcpip_address",
418
460
  nullptr, GRPC_JSON_OBJECT, false);
419
461
  json = json_iterator;
@@ -422,8 +464,6 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name,
422
464
  "port", port_num);
423
465
  json_iterator = grpc_json_create_child(json_iterator, json, "ip_address",
424
466
  b64_host, GRPC_JSON_STRING, true);
425
- gpr_free(host);
426
- gpr_free(port);
427
467
  } else if (uri != nullptr && strcmp(uri->scheme, "unix") == 0) {
428
468
  json_iterator = grpc_json_create_child(json_iterator, json, "uds_address",
429
469
  nullptr, GRPC_JSON_OBJECT, false);
@@ -445,8 +485,9 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name,
445
485
 
446
486
  } // namespace
447
487
 
448
- SocketNode::SocketNode(UniquePtr<char> local, UniquePtr<char> remote)
449
- : BaseNode(EntityType::kSocket),
488
+ SocketNode::SocketNode(UniquePtr<char> local, UniquePtr<char> remote,
489
+ UniquePtr<char> name)
490
+ : BaseNode(EntityType::kSocket, std::move(name)),
450
491
  local_(std::move(local)),
451
492
  remote_(std::move(remote)) {}
452
493
 
@@ -486,6 +527,8 @@ grpc_json* SocketNode::RenderJson() {
486
527
  json_iterator = nullptr;
487
528
  json_iterator = grpc_json_add_number_string_child(json, json_iterator,
488
529
  "socketId", uuid());
530
+ json_iterator = grpc_json_create_child(json_iterator, json, "name", name(),
531
+ GRPC_JSON_STRING, false);
489
532
  json = top_level_json;
490
533
  PopulateSocketAddressJson(json, "remote", remote_.get());
491
534
  PopulateSocketAddressJson(json, "local", local_.get());
@@ -565,8 +608,10 @@ grpc_json* SocketNode::RenderJson() {
565
608
  // ListenSocketNode
566
609
  //
567
610
 
568
- ListenSocketNode::ListenSocketNode(UniquePtr<char> local_addr)
569
- : BaseNode(EntityType::kSocket), local_addr_(std::move(local_addr)) {}
611
+ ListenSocketNode::ListenSocketNode(UniquePtr<char> local_addr,
612
+ UniquePtr<char> name)
613
+ : BaseNode(EntityType::kSocket, std::move(name)),
614
+ local_addr_(std::move(local_addr)) {}
570
615
 
571
616
  grpc_json* ListenSocketNode::RenderJson() {
572
617
  // We need to track these three json objects to build our object
@@ -580,6 +625,8 @@ grpc_json* ListenSocketNode::RenderJson() {
580
625
  json_iterator = nullptr;
581
626
  json_iterator = grpc_json_add_number_string_child(json, json_iterator,
582
627
  "socketId", uuid());
628
+ json_iterator = grpc_json_create_child(json_iterator, json, "name", name(),
629
+ GRPC_JSON_STRING, false);
583
630
  json = top_level_json;
584
631
  PopulateSocketAddressJson(json, "local", local_addr_.get());
585
632