grpc 1.22.1 → 1.23.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 (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 +264 -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 +41 -60
  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 +0 -1
  54. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +0 -8
  55. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +0 -7
  56. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +0 -1
  57. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +37 -22
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +137 -80
  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 +6 -9
  63. data/src/core/ext/transport/chttp2/transport/parsing.cc +37 -20
  64. data/src/core/ext/transport/chttp2/transport/stream_map.cc +28 -18
  65. data/src/core/ext/transport/chttp2/transport/writing.cc +0 -1
  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 +38 -32
  176. data/src/core/lib/gpr/host_port.cc +0 -98
@@ -47,7 +47,7 @@
47
47
 
48
48
  namespace {
49
49
  struct channel_data {
50
- /* We take a reference to the channel stack for the timer callback */
50
+ /* The channel stack to which we take refs for pending callbacks. */
51
51
  grpc_channel_stack* channel_stack;
52
52
  /* Guards access to max_age_timer, max_age_timer_pending, max_age_grace_timer
53
53
  and max_age_grace_timer_pending */
@@ -122,8 +122,8 @@ struct channel_data {
122
122
 
123
123
  MAX_IDLE_STATE_SEEN_ENTER_IDLE: The state after the timer is set and the at
124
124
  least one call has arrived after the timer is set, BUT the channel
125
- currently has 1 or 1+ active calls. If the timer is fired in this state, we
126
- will reschudle it.
125
+ currently has 0 active calls. If the timer is fired in this state, we will
126
+ reschudle it.
127
127
 
128
128
  max_idle_timer will not be cancelled (unless the channel is shutting down).
129
129
  If the timer callback is called when the max_idle_timer is valid (i.e.
@@ -111,15 +111,14 @@ static void on_handshake_done(void* arg, grpc_error* error) {
111
111
  } else {
112
112
  error = GRPC_ERROR_REF(error);
113
113
  }
114
- memset(c->result, 0, sizeof(*c->result));
114
+ c->result->reset();
115
115
  } else {
116
116
  grpc_endpoint_delete_from_pollset_set(args->endpoint,
117
117
  c->args.interested_parties);
118
118
  c->result->transport =
119
119
  grpc_create_chttp2_transport(args->args, args->endpoint, true);
120
- grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket_node =
120
+ c->result->socket =
121
121
  grpc_chttp2_transport_get_socket_node(c->result->transport);
122
- c->result->socket_uuid = socket_node == nullptr ? 0 : socket_node->uuid();
123
122
  GPR_ASSERT(c->result->transport);
124
123
  // TODO(roth): We ideally want to wait until we receive HTTP/2
125
124
  // settings from the server before we consider the connection
@@ -180,7 +179,7 @@ static void connected(void* arg, grpc_error* error) {
180
179
  } else {
181
180
  error = GRPC_ERROR_REF(error);
182
181
  }
183
- memset(c->result, 0, sizeof(*c->result));
182
+ c->result->reset();
184
183
  grpc_closure* notify = c->notify;
185
184
  c->notify = nullptr;
186
185
  GRPC_CLOSURE_SCHED(notify, error);
@@ -37,7 +37,6 @@
37
37
  #include "src/core/lib/channel/channel_args.h"
38
38
  #include "src/core/lib/channel/handshaker.h"
39
39
  #include "src/core/lib/channel/handshaker_registry.h"
40
- #include "src/core/lib/gpr/host_port.h"
41
40
  #include "src/core/lib/iomgr/endpoint.h"
42
41
  #include "src/core/lib/iomgr/resolve_address.h"
43
42
  #include "src/core/lib/iomgr/resource_quota.h"
@@ -318,7 +317,7 @@ static grpc_error* chttp2_server_add_acceptor(grpc_server* server,
318
317
  *arg_val = grpc_tcp_server_create_fd_handler(tcp_server);
319
318
 
320
319
  grpc_server_add_listener(server, state, server_start_listener,
321
- server_destroy_listener, /* socket_uuid */ 0);
320
+ server_destroy_listener, /* node */ nullptr);
322
321
  return err;
323
322
 
324
323
  /* Error path: cleanup and return */
@@ -346,7 +345,6 @@ grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr,
346
345
  grpc_error** errors = nullptr;
347
346
  size_t naddrs = 0;
348
347
  const grpc_arg* arg = nullptr;
349
- intptr_t socket_uuid = 0;
350
348
 
351
349
  *port_num = -1;
352
350
 
@@ -414,15 +412,18 @@ grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr,
414
412
 
415
413
  arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ);
416
414
  if (grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT)) {
415
+ char* socket_name = nullptr;
416
+ gpr_asprintf(&socket_name, "chttp2 listener %s", addr);
417
417
  state->channelz_listen_socket =
418
418
  grpc_core::MakeRefCounted<grpc_core::channelz::ListenSocketNode>(
419
- grpc_core::UniquePtr<char>(gpr_strdup(addr)));
420
- socket_uuid = state->channelz_listen_socket->uuid();
419
+ grpc_core::UniquePtr<char>(gpr_strdup(addr)),
420
+ grpc_core::UniquePtr<char>(socket_name));
421
421
  }
422
422
 
423
423
  /* Register with the server only upon success */
424
424
  grpc_server_add_listener(server, state, server_start_listener,
425
- server_destroy_listener, socket_uuid);
425
+ server_destroy_listener,
426
+ state->channelz_listen_socket);
426
427
  goto done;
427
428
 
428
429
  /* Error path: cleanup and return */
@@ -74,8 +74,6 @@
74
74
  #define DEFAULT_MAX_PINGS_BETWEEN_DATA 2
75
75
  #define DEFAULT_MAX_PING_STRIKES 2
76
76
 
77
- #define DEFAULT_MAX_PENDING_INDUCED_FRAMES 10000
78
-
79
77
  static int g_default_client_keepalive_time_ms =
80
78
  DEFAULT_CLIENT_KEEPALIVE_TIME_MS;
81
79
  static int g_default_client_keepalive_timeout_ms =
@@ -107,7 +105,6 @@ static void write_action(void* t, grpc_error* error);
107
105
  static void write_action_end_locked(void* t, grpc_error* error);
108
106
 
109
107
  static void read_action_locked(void* t, grpc_error* error);
110
- static void continue_read_action_locked(grpc_chttp2_transport* t);
111
108
 
112
109
  static void complete_fetch_locked(void* gs, grpc_error* error);
113
110
  /** Set a transport level setting, and push it to our peer */
@@ -381,10 +378,13 @@ static bool read_channel_args(grpc_chttp2_transport* t,
381
378
  if (channelz_enabled) {
382
379
  // TODO(ncteisen): add an API to endpoint to query for local addr, and pass
383
380
  // it in here, so SocketNode knows its own address.
381
+ char* socket_name = nullptr;
382
+ gpr_asprintf(&socket_name, "%s %s", get_vtable()->name, t->peer_string);
384
383
  t->channelz_socket =
385
384
  grpc_core::MakeRefCounted<grpc_core::channelz::SocketNode>(
386
385
  grpc_core::UniquePtr<char>(),
387
- grpc_core::UniquePtr<char>(gpr_strdup(t->peer_string)));
386
+ grpc_core::UniquePtr<char>(gpr_strdup(t->peer_string)),
387
+ grpc_core::UniquePtr<char>(socket_name));
388
388
  }
389
389
  return enable_bdp;
390
390
  }
@@ -785,12 +785,6 @@ static void destroy_stream(grpc_transport* gt, grpc_stream* gs,
785
785
  GRPC_ERROR_NONE);
786
786
  }
787
787
 
788
- grpc_chttp2_stream* grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport* t,
789
- uint32_t id) {
790
- return static_cast<grpc_chttp2_stream*>(
791
- grpc_chttp2_stream_map_find(&t->stream_map, id));
792
- }
793
-
794
788
  grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t,
795
789
  uint32_t id) {
796
790
  if (t->channel_callback.accept_stream == nullptr) {
@@ -803,8 +797,10 @@ grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t,
803
797
  !grpc_resource_user_safe_alloc(t->resource_user,
804
798
  GRPC_RESOURCE_QUOTA_CALL_SIZE)) {
805
799
  gpr_log(GPR_ERROR, "Memory exhausted, rejecting the stream.");
806
- grpc_chttp2_add_rst_stream_to_next_write(t, id, GRPC_HTTP2_REFUSED_STREAM,
807
- nullptr);
800
+ grpc_slice_buffer_add(
801
+ &t->qbuf,
802
+ grpc_chttp2_rst_stream_create(
803
+ id, static_cast<uint32_t>(GRPC_HTTP2_REFUSED_STREAM), nullptr));
808
804
  grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM);
809
805
  return nullptr;
810
806
  }
@@ -1049,19 +1045,6 @@ static void write_action_begin_locked(void* gt, grpc_error* error_ignored) {
1049
1045
  GRPC_CLOSURE_SCHED(
1050
1046
  GRPC_CLOSURE_INIT(&t->write_action, write_action, t, scheduler),
1051
1047
  GRPC_ERROR_NONE);
1052
- if (t->reading_paused_on_pending_induced_frames) {
1053
- GPR_ASSERT(t->num_pending_induced_frames == 0);
1054
- /* We had paused reading, because we had many induced frames (SETTINGS
1055
- * ACK, PINGS ACK and RST_STREAMS) pending in t->qbuf. Now that we have
1056
- * been able to flush qbuf, we can resume reading. */
1057
- GRPC_CHTTP2_IF_TRACING(gpr_log(
1058
- GPR_INFO,
1059
- "transport %p : Resuming reading after being paused due to too "
1060
- "many unwritten SETTINGS ACK, PINGS ACK and RST_STREAM frames",
1061
- t));
1062
- t->reading_paused_on_pending_induced_frames = false;
1063
- continue_read_action_locked(t);
1064
- }
1065
1048
  } else {
1066
1049
  GRPC_STATS_INC_HTTP2_SPURIOUS_WRITES_BEGUN();
1067
1050
  set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE, "begin writing nothing");
@@ -1131,6 +1114,7 @@ static void write_action_end_locked(void* tp, grpc_error* error) {
1131
1114
  }
1132
1115
 
1133
1116
  grpc_chttp2_end_write(t, GRPC_ERROR_REF(error));
1117
+
1134
1118
  GRPC_CHTTP2_UNREF_TRANSPORT(t, "writing");
1135
1119
  }
1136
1120
 
@@ -1153,6 +1137,7 @@ static void queue_setting_update(grpc_chttp2_transport* t,
1153
1137
 
1154
1138
  void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t,
1155
1139
  uint32_t goaway_error,
1140
+ uint32_t last_stream_id,
1156
1141
  const grpc_slice& goaway_text) {
1157
1142
  // Discard the error from a previous goaway frame (if any)
1158
1143
  if (t->goaway_error != GRPC_ERROR_NONE) {
@@ -1166,6 +1151,9 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t,
1166
1151
  GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
1167
1152
  GRPC_ERROR_STR_RAW_BYTES, goaway_text);
1168
1153
 
1154
+ GRPC_CHTTP2_IF_TRACING(
1155
+ gpr_log(GPR_INFO, "transport %p got goaway with last stream id %d", t,
1156
+ last_stream_id));
1169
1157
  /* We want to log this irrespective of whether http tracing is enabled */
1170
1158
  gpr_log(GPR_INFO, "%s: Got goaway [%d] err=%s", t->peer_string, goaway_error,
1171
1159
  grpc_error_string(t->goaway_error));
@@ -1204,8 +1192,9 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t) {
1204
1192
  grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) {
1205
1193
  /* safe since we can't (legally) be parsing this stream yet */
1206
1194
  GRPC_CHTTP2_IF_TRACING(gpr_log(
1207
- GPR_INFO, "HTTP:%s: Allocating new grpc_chttp2_stream %p to id %d",
1208
- t->is_client ? "CLI" : "SVR", s, t->next_stream_id));
1195
+ GPR_INFO,
1196
+ "HTTP:%s: Transport %p allocating new grpc_chttp2_stream %p to id %d",
1197
+ t->is_client ? "CLI" : "SVR", t, s, t->next_stream_id));
1209
1198
 
1210
1199
  GPR_ASSERT(s->id == 0);
1211
1200
  s->id = t->next_stream_id;
@@ -1245,10 +1234,10 @@ static grpc_closure* add_closure_barrier(grpc_closure* closure) {
1245
1234
  return closure;
1246
1235
  }
1247
1236
 
1248
- static void null_then_run_closure(grpc_closure** closure, grpc_error* error) {
1237
+ static void null_then_sched_closure(grpc_closure** closure) {
1249
1238
  grpc_closure* c = *closure;
1250
1239
  *closure = nullptr;
1251
- GRPC_CLOSURE_RUN(c, error);
1240
+ GRPC_CLOSURE_SCHED(c, GRPC_ERROR_NONE);
1252
1241
  }
1253
1242
 
1254
1243
  void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t,
@@ -1915,7 +1904,7 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_chttp2_transport* t,
1915
1904
  }
1916
1905
  grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0],
1917
1906
  s->recv_initial_metadata);
1918
- null_then_run_closure(&s->recv_initial_metadata_ready, GRPC_ERROR_NONE);
1907
+ null_then_sched_closure(&s->recv_initial_metadata_ready);
1919
1908
  }
1920
1909
  }
1921
1910
 
@@ -1995,10 +1984,10 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t,
1995
1984
  s->unprocessed_incoming_frames_buffer_cached_length =
1996
1985
  s->unprocessed_incoming_frames_buffer.length;
1997
1986
  if (error == GRPC_ERROR_NONE && *s->recv_message != nullptr) {
1998
- null_then_run_closure(&s->recv_message_ready, GRPC_ERROR_NONE);
1987
+ null_then_sched_closure(&s->recv_message_ready);
1999
1988
  } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) {
2000
1989
  *s->recv_message = nullptr;
2001
- null_then_run_closure(&s->recv_message_ready, GRPC_ERROR_NONE);
1990
+ null_then_sched_closure(&s->recv_message_ready);
2002
1991
  }
2003
1992
  GRPC_ERROR_UNREF(error);
2004
1993
  }
@@ -2024,9 +2013,10 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t,
2024
2013
  * maybe decompress the next 5 bytes in the stream. */
2025
2014
  if (s->stream_decompression_method ==
2026
2015
  GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) {
2027
- grpc_slice_buffer_move_first(&s->frame_storage,
2028
- GRPC_HEADER_SIZE_IN_BYTES,
2029
- &s->unprocessed_incoming_frames_buffer);
2016
+ grpc_slice_buffer_move_first(
2017
+ &s->frame_storage,
2018
+ GPR_MIN(s->frame_storage.length, GRPC_HEADER_SIZE_IN_BYTES),
2019
+ &s->unprocessed_incoming_frames_buffer);
2030
2020
  if (s->unprocessed_incoming_frames_buffer.length > 0) {
2031
2021
  s->unprocessed_incoming_frames_decompressed = true;
2032
2022
  pending_data = true;
@@ -2064,8 +2054,7 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t,
2064
2054
  s->collecting_stats = nullptr;
2065
2055
  grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1],
2066
2056
  s->recv_trailing_metadata);
2067
- null_then_run_closure(&s->recv_trailing_metadata_finished,
2068
- GRPC_ERROR_NONE);
2057
+ null_then_sched_closure(&s->recv_trailing_metadata_finished);
2069
2058
  }
2070
2059
  }
2071
2060
  }
@@ -2074,7 +2063,7 @@ static void remove_stream(grpc_chttp2_transport* t, uint32_t id,
2074
2063
  grpc_error* error) {
2075
2064
  grpc_chttp2_stream* s = static_cast<grpc_chttp2_stream*>(
2076
2065
  grpc_chttp2_stream_map_delete(&t->stream_map, id));
2077
- GPR_ASSERT(s);
2066
+ GPR_DEBUG_ASSERT(s);
2078
2067
  if (t->incoming_stream == s) {
2079
2068
  t->incoming_stream = nullptr;
2080
2069
  grpc_chttp2_parsing_become_skip_parser(t);
@@ -2124,8 +2113,10 @@ void grpc_chttp2_cancel_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
2124
2113
  grpc_http2_error_code http_error;
2125
2114
  grpc_error_get_status(due_to_error, s->deadline, nullptr, nullptr,
2126
2115
  &http_error, nullptr);
2127
- grpc_chttp2_add_rst_stream_to_next_write(
2128
- t, s->id, static_cast<uint32_t>(http_error), &s->stats.outgoing);
2116
+ grpc_slice_buffer_add(
2117
+ &t->qbuf,
2118
+ grpc_chttp2_rst_stream_create(
2119
+ s->id, static_cast<uint32_t>(http_error), &s->stats.outgoing));
2129
2120
  grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM);
2130
2121
  }
2131
2122
  }
@@ -2158,7 +2149,7 @@ void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
2158
2149
  &s->metadata_buffer[1],
2159
2150
  grpc_mdelem_from_slices(
2160
2151
  GRPC_MDSTR_GRPC_STATUS,
2161
- grpc_slice_from_copied_string(status_string))));
2152
+ grpc_core::UnmanagedMemorySlice(status_string))));
2162
2153
  if (!GRPC_SLICE_IS_EMPTY(slice)) {
2163
2154
  GRPC_LOG_IF_ERROR(
2164
2155
  "add_status_message",
@@ -2436,8 +2427,9 @@ static void close_from_api(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
2436
2427
  grpc_slice_buffer_add(&t->qbuf, status_hdr);
2437
2428
  grpc_slice_buffer_add(&t->qbuf, message_pfx);
2438
2429
  grpc_slice_buffer_add(&t->qbuf, grpc_slice_ref_internal(slice));
2439
- grpc_chttp2_add_rst_stream_to_next_write(t, s->id, GRPC_HTTP2_NO_ERROR,
2440
- &s->stats.outgoing);
2430
+ grpc_slice_buffer_add(
2431
+ &t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR,
2432
+ &s->stats.outgoing));
2441
2433
 
2442
2434
  grpc_chttp2_mark_stream_closed(t, s, 1, 1, error);
2443
2435
  grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_CLOSE_FROM_API);
@@ -2608,16 +2600,10 @@ static void read_action_locked(void* tp, grpc_error* error) {
2608
2600
  grpc_slice_buffer_reset_and_unref_internal(&t->read_buffer);
2609
2601
 
2610
2602
  if (keep_reading) {
2611
- if (t->num_pending_induced_frames >= DEFAULT_MAX_PENDING_INDUCED_FRAMES) {
2612
- t->reading_paused_on_pending_induced_frames = true;
2613
- GRPC_CHTTP2_IF_TRACING(
2614
- gpr_log(GPR_INFO,
2615
- "transport %p : Pausing reading due to too "
2616
- "many unwritten SETTINGS ACK and RST_STREAM frames",
2617
- t));
2618
- } else {
2619
- continue_read_action_locked(t);
2620
- }
2603
+ const bool urgent = t->goaway_error != GRPC_ERROR_NONE;
2604
+ grpc_endpoint_read(t->ep, &t->read_buffer, &t->read_action_locked, urgent);
2605
+ grpc_chttp2_act_on_flowctl_action(t->flow_control->MakeAction(), t,
2606
+ nullptr);
2621
2607
  GRPC_CHTTP2_UNREF_TRANSPORT(t, "keep_reading");
2622
2608
  } else {
2623
2609
  GRPC_CHTTP2_UNREF_TRANSPORT(t, "reading_action");
@@ -2626,12 +2612,6 @@ static void read_action_locked(void* tp, grpc_error* error) {
2626
2612
  GRPC_ERROR_UNREF(error);
2627
2613
  }
2628
2614
 
2629
- static void continue_read_action_locked(grpc_chttp2_transport* t) {
2630
- const bool urgent = t->goaway_error != GRPC_ERROR_NONE;
2631
- grpc_endpoint_read(t->ep, &t->read_buffer, &t->read_action_locked, urgent);
2632
- grpc_chttp2_act_on_flowctl_action(t->flow_control->MakeAction(), t, nullptr);
2633
- }
2634
-
2635
2615
  // t is reffed prior to calling the first time, and once the callback chain
2636
2616
  // that kicks off finishes, it's unreffed
2637
2617
  static void schedule_bdp_ping_locked(grpc_chttp2_transport* t) {
@@ -2847,7 +2827,8 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) {
2847
2827
  static void connectivity_state_set(grpc_chttp2_transport* t,
2848
2828
  grpc_connectivity_state state,
2849
2829
  const char* reason) {
2850
- GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "set connectivity_state=%d", state));
2830
+ GRPC_CHTTP2_IF_TRACING(
2831
+ gpr_log(GPR_INFO, "transport %p set connectivity_state=%d", t, state));
2851
2832
  grpc_connectivity_state_set(&t->channel_callback.state_tracker, state,
2852
2833
  reason);
2853
2834
  }
@@ -46,7 +46,9 @@ void ContextList::Execute(void* arg, grpc_core::Timestamps* ts,
46
46
  ContextList* to_be_freed;
47
47
  while (head != nullptr) {
48
48
  if (write_timestamps_callback_g) {
49
- ts->byte_offset = static_cast<uint32_t>(head->byte_offset_);
49
+ if (ts) {
50
+ ts->byte_offset = static_cast<uint32_t>(head->byte_offset_);
51
+ }
50
52
  write_timestamps_callback_g(head->trace_context_, ts, error);
51
53
  }
52
54
  to_be_freed = head;
@@ -137,10 +137,10 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames(
137
137
  p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID,
138
138
  static_cast<intptr_t>(s->id));
139
139
  gpr_free(msg);
140
- p->error =
141
- grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES,
142
- grpc_dump_slice_to_slice(
143
- *slice, GPR_DUMP_HEX | GPR_DUMP_ASCII));
140
+ p->error = grpc_error_set_str(
141
+ p->error, GRPC_ERROR_STR_RAW_BYTES,
142
+ grpc_slice_from_moved_string(grpc_core::UniquePtr<char>(
143
+ grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII))));
144
144
  p->error =
145
145
  grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg);
146
146
  p->state = GRPC_CHTTP2_DATA_ERROR;
@@ -139,7 +139,7 @@ grpc_error* grpc_chttp2_goaway_parser_parse(void* parser,
139
139
  p->state = GRPC_CHTTP2_GOAWAY_DEBUG;
140
140
  if (is_last) {
141
141
  grpc_chttp2_add_incoming_goaway(
142
- t, p->error_code,
142
+ t, p->error_code, p->last_stream_id,
143
143
  grpc_slice_new(p->debug_data, p->debug_length, gpr_free));
144
144
  p->debug_data = nullptr;
145
145
  }
@@ -118,7 +118,6 @@ grpc_error* grpc_chttp2_ping_parser_parse(void* parser,
118
118
  t->ping_acks = static_cast<uint64_t*>(gpr_realloc(
119
119
  t->ping_acks, t->ping_ack_capacity * sizeof(*t->ping_acks)));
120
120
  }
121
- t->num_pending_induced_frames++;
122
121
  t->ping_acks[t->ping_ack_count++] = p->opaque_8bytes;
123
122
  grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_PING_RESPONSE);
124
123
  }
@@ -58,14 +58,6 @@ grpc_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code,
58
58
  return slice;
59
59
  }
60
60
 
61
- void grpc_chttp2_add_rst_stream_to_next_write(
62
- grpc_chttp2_transport* t, uint32_t id, uint32_t code,
63
- grpc_transport_one_way_stats* stats) {
64
- t->num_pending_induced_frames++;
65
- grpc_slice_buffer_add(&t->qbuf,
66
- grpc_chttp2_rst_stream_create(id, code, stats));
67
- }
68
-
69
61
  grpc_error* grpc_chttp2_rst_stream_parser_begin_frame(
70
62
  grpc_chttp2_rst_stream_parser* parser, uint32_t length, uint8_t flags) {
71
63
  if (length != 4) {
@@ -33,13 +33,6 @@ typedef struct {
33
33
  grpc_slice grpc_chttp2_rst_stream_create(uint32_t stream_id, uint32_t code,
34
34
  grpc_transport_one_way_stats* stats);
35
35
 
36
- // Adds RST_STREAM frame to t->qbuf (buffer for the next write). Should be
37
- // called when we want to add RST_STREAM and we are not in
38
- // write_action_begin_locked.
39
- void grpc_chttp2_add_rst_stream_to_next_write(
40
- grpc_chttp2_transport* t, uint32_t id, uint32_t code,
41
- grpc_transport_one_way_stats* stats);
42
-
43
36
  grpc_error* grpc_chttp2_rst_stream_parser_begin_frame(
44
37
  grpc_chttp2_rst_stream_parser* parser, uint32_t length, uint8_t flags);
45
38
  grpc_error* grpc_chttp2_rst_stream_parser_parse(void* parser,
@@ -132,7 +132,6 @@ grpc_error* grpc_chttp2_settings_parser_parse(void* p, grpc_chttp2_transport* t,
132
132
  if (is_last) {
133
133
  memcpy(parser->target_settings, parser->incoming_settings,
134
134
  GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t));
135
- t->num_pending_induced_frames++;
136
135
  grpc_slice_buffer_add(&t->qbuf, grpc_chttp2_settings_ack_create());
137
136
  if (t->notify_on_receive_settings != nullptr) {
138
137
  GRPC_CLOSURE_SCHED(t->notify_on_receive_settings,
@@ -130,8 +130,9 @@ static void begin_frame(framer_state* st) {
130
130
  space to add at least about_to_add bytes -- finishes the current frame if
131
131
  needed */
132
132
  static void ensure_space(framer_state* st, size_t need_bytes) {
133
- if (st->output->length - st->output_length_at_start_of_frame + need_bytes <=
134
- st->max_frame_size) {
133
+ if (GPR_LIKELY(st->output->length - st->output_length_at_start_of_frame +
134
+ need_bytes <=
135
+ st->max_frame_size)) {
135
136
  return;
136
137
  }
137
138
  finish_frame(st, 0, 0);
@@ -380,10 +381,11 @@ static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor* c,
380
381
  uint32_t len_val_len;
381
382
  GPR_ASSERT(len_val <= UINT32_MAX);
382
383
  len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1);
383
- GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40,
384
- add_tiny_header_data(st, len_pfx), len_pfx);
384
+ GPR_DEBUG_ASSERT(len_pfx + len_val_len < GRPC_SLICE_INLINED_SIZE);
385
+ uint8_t* data = add_tiny_header_data(st, len_pfx + len_val_len);
386
+ GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40, data, len_pfx);
385
387
  GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, value.huffman_prefix,
386
- add_tiny_header_data(st, len_val_len), len_val_len);
388
+ &data[len_pfx], len_val_len);
387
389
  add_wire_value(st, value);
388
390
  }
389
391
 
@@ -397,10 +399,11 @@ static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor* c,
397
399
  uint32_t len_val_len;
398
400
  GPR_ASSERT(len_val <= UINT32_MAX);
399
401
  len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1);
400
- GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00,
401
- add_tiny_header_data(st, len_pfx), len_pfx);
402
+ GPR_DEBUG_ASSERT(len_pfx + len_val_len < GRPC_SLICE_INLINED_SIZE);
403
+ uint8_t* data = add_tiny_header_data(st, len_pfx + len_val_len);
404
+ GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00, data, len_pfx);
402
405
  GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, value.huffman_prefix,
403
- add_tiny_header_data(st, len_val_len), len_val_len);
406
+ &data[len_pfx], len_val_len);
404
407
  add_wire_value(st, value);
405
408
  }
406
409
 
@@ -417,9 +420,10 @@ static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor* c,
417
420
  uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
418
421
  GPR_ASSERT(len_key <= UINT32_MAX);
419
422
  GPR_ASSERT(wire_value_length(value) <= UINT32_MAX);
420
- *add_tiny_header_data(st, 1) = 0x40;
421
- GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
422
- add_tiny_header_data(st, len_key_len), len_key_len);
423
+ GPR_DEBUG_ASSERT(1 + len_key_len < GRPC_SLICE_INLINED_SIZE);
424
+ uint8_t* data = add_tiny_header_data(st, 1 + len_key_len);
425
+ data[0] = 0x40;
426
+ GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, &data[1], len_key_len);
423
427
  add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem)));
424
428
  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, value.huffman_prefix,
425
429
  add_tiny_header_data(st, len_val_len), len_val_len);
@@ -439,9 +443,10 @@ static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor* c,
439
443
  uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
440
444
  GPR_ASSERT(len_key <= UINT32_MAX);
441
445
  GPR_ASSERT(wire_value_length(value) <= UINT32_MAX);
442
- *add_tiny_header_data(st, 1) = 0x00;
443
- GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
444
- add_tiny_header_data(st, len_key_len), len_key_len);
446
+ /* Preconditions passed; emit header. */
447
+ uint8_t* data = add_tiny_header_data(st, 1 + len_key_len);
448
+ data[0] = 0x00;
449
+ GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, &data[1], len_key_len);
445
450
  add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem)));
446
451
  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, value.huffman_prefix,
447
452
  add_tiny_header_data(st, len_val_len), len_val_len);
@@ -599,8 +604,8 @@ static void deadline_enc(grpc_chttp2_hpack_compressor* c, grpc_millis deadline,
599
604
  grpc_mdelem mdelem;
600
605
  grpc_http2_encode_timeout(deadline - grpc_core::ExecCtx::Get()->Now(),
601
606
  timeout_str);
602
- mdelem = grpc_mdelem_from_slices(GRPC_MDSTR_GRPC_TIMEOUT,
603
- grpc_slice_from_copied_string(timeout_str));
607
+ mdelem = grpc_mdelem_from_slices(
608
+ GRPC_MDSTR_GRPC_TIMEOUT, grpc_core::UnmanagedMemorySlice(timeout_str));
604
609
  hpack_enc(c, mdelem, st);
605
610
  GRPC_MDELEM_UNREF(mdelem);
606
611
  }
@@ -711,18 +716,28 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c,
711
716
  }
712
717
  for (size_t i = 0; i < extra_headers_size; ++i) {
713
718
  grpc_mdelem md = *extra_headers[i];
714
- uintptr_t static_index = grpc_chttp2_get_static_hpack_table_index(md);
715
- if (static_index) {
716
- emit_indexed(c, static_cast<uint32_t>(static_index), &st);
719
+ const bool is_static =
720
+ GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC;
721
+ uintptr_t static_index;
722
+ if (is_static &&
723
+ (static_index =
724
+ reinterpret_cast<grpc_core::StaticMetadata*>(GRPC_MDELEM_DATA(md))
725
+ ->StaticIndex()) < GRPC_CHTTP2_LAST_STATIC_ENTRY) {
726
+ emit_indexed(c, static_cast<uint32_t>(static_index + 1), &st);
717
727
  } else {
718
728
  hpack_enc(c, md, &st);
719
729
  }
720
730
  }
721
731
  grpc_metadata_batch_assert_ok(metadata);
722
732
  for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) {
723
- uintptr_t static_index = grpc_chttp2_get_static_hpack_table_index(l->md);
724
- if (static_index) {
725
- emit_indexed(c, static_cast<uint32_t>(static_index), &st);
733
+ const bool is_static =
734
+ GRPC_MDELEM_STORAGE(l->md) == GRPC_MDELEM_STORAGE_STATIC;
735
+ uintptr_t static_index;
736
+ if (is_static &&
737
+ (static_index = reinterpret_cast<grpc_core::StaticMetadata*>(
738
+ GRPC_MDELEM_DATA(l->md))
739
+ ->StaticIndex()) < GRPC_CHTTP2_LAST_STATIC_ENTRY) {
740
+ emit_indexed(c, static_cast<uint32_t>(static_index + 1), &st);
726
741
  } else {
727
742
  hpack_enc(c, l->md, &st);
728
743
  }