grpc 1.15.0 → 1.16.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 (138) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +158 -80
  3. data/etc/roots.pem +23 -0
  4. data/include/grpc/grpc.h +13 -1
  5. data/include/grpc/grpc_security.h +2 -2
  6. data/include/grpc/grpc_security_constants.h +24 -19
  7. data/include/grpc/impl/codegen/grpc_types.h +23 -5
  8. data/include/grpc/impl/codegen/port_platform.h +1 -0
  9. data/src/core/ext/filters/client_channel/client_channel.cc +95 -10
  10. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +71 -0
  11. data/src/core/ext/filters/client_channel/client_channel_channelz.h +45 -11
  12. data/src/core/ext/filters/client_channel/connector.h +3 -0
  13. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -1
  14. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +5 -3
  15. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +12 -32
  16. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +6 -5
  17. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +20 -15
  18. data/src/core/ext/filters/client_channel/lb_policy_factory.h +2 -4
  19. data/src/core/ext/filters/client_channel/parse_address.cc +27 -4
  20. data/src/core/ext/filters/client_channel/parse_address.h +3 -0
  21. data/src/core/ext/filters/client_channel/resolver.h +1 -12
  22. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +1 -11
  23. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +80 -19
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +9 -3
  25. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +5 -0
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +70 -0
  27. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +1 -11
  28. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -16
  29. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +2 -1
  30. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +0 -7
  31. data/src/core/ext/filters/client_channel/subchannel.cc +45 -7
  32. data/src/core/ext/filters/client_channel/subchannel.h +16 -1
  33. data/src/core/ext/filters/client_channel/subchannel_index.cc +2 -1
  34. data/src/core/ext/filters/client_channel/subchannel_index.h +1 -4
  35. data/src/core/ext/filters/http/client/http_client_filter.cc +32 -3
  36. data/src/core/ext/filters/http/server/http_server_filter.cc +59 -1
  37. data/src/core/ext/filters/max_age/max_age_filter.cc +1 -2
  38. data/src/core/ext/filters/message_size/message_size_filter.cc +59 -3
  39. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +2 -0
  40. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +1 -1
  41. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +1 -1
  42. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +286 -228
  43. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +2 -0
  44. data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -0
  45. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +14 -3
  46. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +29 -0
  47. data/src/core/ext/transport/chttp2/transport/hpack_table.h +9 -0
  48. data/src/core/ext/transport/chttp2/transport/internal.h +10 -0
  49. data/src/core/ext/transport/chttp2/transport/parsing.cc +85 -54
  50. data/src/core/ext/transport/chttp2/transport/writing.cc +6 -0
  51. data/src/core/lib/channel/channel_trace.cc +51 -56
  52. data/src/core/lib/channel/channel_trace.h +30 -25
  53. data/src/core/lib/channel/channelz.cc +235 -61
  54. data/src/core/lib/channel/channelz.h +179 -48
  55. data/src/core/lib/channel/channelz_registry.cc +95 -23
  56. data/src/core/lib/channel/channelz_registry.h +15 -42
  57. data/src/core/lib/gpr/sync_posix.cc +42 -0
  58. data/src/core/lib/http/httpcli.cc +1 -1
  59. data/src/core/lib/iomgr/buffer_list.cc +134 -0
  60. data/src/core/lib/iomgr/buffer_list.h +96 -0
  61. data/src/core/lib/iomgr/endpoint.cc +2 -2
  62. data/src/core/lib/iomgr/endpoint.h +6 -2
  63. data/src/core/lib/iomgr/endpoint_pair_posix.cc +2 -2
  64. data/src/core/lib/iomgr/error.cc +29 -18
  65. data/src/core/lib/iomgr/error.h +8 -0
  66. data/src/core/lib/iomgr/ev_epoll1_linux.cc +4 -0
  67. data/src/core/lib/iomgr/ev_epollex_linux.cc +4 -0
  68. data/src/core/lib/iomgr/ev_posix.cc +16 -10
  69. data/src/core/lib/iomgr/exec_ctx.h +0 -7
  70. data/src/core/lib/iomgr/{ev_epollsig_linux.h → internal_errqueue.cc} +13 -12
  71. data/src/core/lib/iomgr/internal_errqueue.h +83 -0
  72. data/src/core/lib/iomgr/port.h +11 -2
  73. data/src/core/lib/iomgr/socket_utils_common_posix.cc +90 -0
  74. data/src/core/lib/iomgr/socket_utils_posix.h +7 -0
  75. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -1
  76. data/src/core/lib/iomgr/tcp_custom.cc +1 -1
  77. data/src/core/lib/iomgr/tcp_posix.cc +306 -13
  78. data/src/core/lib/iomgr/tcp_posix.h +3 -0
  79. data/src/core/lib/iomgr/tcp_server_posix.cc +2 -2
  80. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +4 -1
  81. data/src/core/lib/iomgr/tcp_windows.cc +1 -1
  82. data/src/core/lib/iomgr/timer_generic.cc +13 -12
  83. data/src/core/lib/iomgr/timer_heap.cc +2 -2
  84. data/src/core/lib/iomgr/timer_heap.h +3 -3
  85. data/src/core/lib/iomgr/timer_manager.cc +28 -3
  86. data/src/core/lib/iomgr/timer_manager.h +2 -2
  87. data/src/core/lib/iomgr/udp_server.cc +1 -1
  88. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc +2 -1
  89. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc +2 -1
  90. data/src/core/lib/security/security_connector/security_connector.cc +7 -7
  91. data/src/core/lib/security/transport/secure_endpoint.cc +2 -2
  92. data/src/core/lib/security/transport/security_handshaker.cc +1 -1
  93. data/src/core/lib/security/transport/server_auth_filter.cc +53 -4
  94. data/src/core/lib/slice/slice.cc +8 -0
  95. data/src/core/lib/slice/slice_internal.h +5 -0
  96. data/src/core/lib/surface/call.cc +149 -253
  97. data/src/core/lib/surface/call.h +1 -0
  98. data/src/core/lib/surface/channel.cc +17 -13
  99. data/src/core/lib/surface/completion_queue.cc +21 -17
  100. data/src/core/lib/surface/completion_queue.h +1 -18
  101. data/src/core/lib/surface/completion_queue_factory.cc +3 -3
  102. data/src/core/lib/surface/init_secure.cc +1 -1
  103. data/src/core/lib/surface/server.cc +77 -4
  104. data/src/core/lib/surface/server.h +4 -0
  105. data/src/core/lib/surface/version.cc +2 -2
  106. data/src/core/lib/transport/metadata.cc +0 -18
  107. data/src/core/lib/transport/metadata.h +0 -3
  108. data/src/core/lib/transport/metadata_batch.cc +2 -2
  109. data/src/core/lib/transport/metadata_batch.h +2 -0
  110. data/src/core/lib/transport/static_metadata.cc +220 -249
  111. data/src/core/lib/transport/static_metadata.h +189 -191
  112. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +5 -4
  113. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc +3 -1
  114. data/src/core/tsi/alts/handshaker/alts_tsi_event.cc +4 -2
  115. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +6 -5
  116. data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +3 -1
  117. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc +2 -2
  118. data/src/core/tsi/alts_transport_security.cc +3 -1
  119. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +2 -1
  120. data/src/ruby/ext/grpc/rb_call.c +1 -0
  121. data/src/ruby/ext/grpc/rb_channel.c +3 -0
  122. data/src/ruby/ext/grpc/rb_grpc.c +31 -1
  123. data/src/ruby/ext/grpc/rb_grpc.h +2 -0
  124. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +6 -0
  125. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +12 -3
  126. data/src/ruby/ext/grpc/rb_server.c +2 -0
  127. data/src/ruby/lib/grpc/errors.rb +0 -1
  128. data/src/ruby/lib/grpc/generic/rpc_desc.rb +3 -3
  129. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  130. data/src/ruby/lib/grpc/version.rb +1 -1
  131. data/src/ruby/spec/channel_spec.rb +44 -0
  132. data/src/ruby/spec/client_auth_spec.rb +5 -5
  133. data/src/ruby/spec/generic/client_stub_spec.rb +13 -9
  134. data/src/ruby/spec/generic/rpc_server_spec.rb +3 -3
  135. data/src/ruby/spec/pb/codegen/package_option_spec.rb +53 -0
  136. data/src/ruby/spec/support/services.rb +28 -22
  137. metadata +35 -31
  138. data/src/core/lib/iomgr/ev_epollsig_linux.cc +0 -1743
@@ -34,6 +34,8 @@ extern bool g_flow_control_enabled;
34
34
  grpc_transport* grpc_create_chttp2_transport(
35
35
  const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client);
36
36
 
37
+ intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport);
38
+
37
39
  /// Takes ownership of \a read_buffer, which (if non-NULL) contains
38
40
  /// leftover bytes previously read from the endpoint (e.g., by handshakers).
39
41
  /// If non-null, \a notify_on_receive_settings will be scheduled when
@@ -62,6 +62,7 @@ grpc_error* grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser* parser,
62
62
 
63
63
  if (flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) {
64
64
  s->received_last_frame = true;
65
+ s->eos_received = true;
65
66
  } else {
66
67
  s->received_last_frame = false;
67
68
  }
@@ -191,6 +192,9 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames(
191
192
  GPR_ASSERT(stream_out != nullptr);
192
193
  GPR_ASSERT(p->parsing_frame == nullptr);
193
194
  p->frame_size |= (static_cast<uint32_t>(*cur));
195
+ if (t->channelz_socket != nullptr) {
196
+ t->channelz_socket->RecordMessageReceived();
197
+ }
194
198
  p->state = GRPC_CHTTP2_DATA_FRAME;
195
199
  ++cur;
196
200
  message_flags = 0;
@@ -525,7 +525,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
525
525
 
526
526
  /* should this elem be in the table? */
527
527
  size_t decoder_space_usage =
528
- grpc_mdelem_get_size_in_hpack_table(elem, st->use_true_binary_metadata);
528
+ grpc_chttp2_get_size_in_hpack_table(elem, st->use_true_binary_metadata);
529
529
  bool should_add_elem = elem_interned &&
530
530
  decoder_space_usage < MAX_DECODER_SPACE_USAGE &&
531
531
  c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >=
@@ -688,11 +688,22 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c,
688
688
  emit_advertise_table_size_change(c, &st);
689
689
  }
690
690
  for (size_t i = 0; i < extra_headers_size; ++i) {
691
- hpack_enc(c, *extra_headers[i], &st);
691
+ grpc_mdelem md = *extra_headers[i];
692
+ uint8_t static_index = grpc_chttp2_get_static_hpack_table_index(md);
693
+ if (static_index) {
694
+ emit_indexed(c, static_index, &st);
695
+ } else {
696
+ hpack_enc(c, md, &st);
697
+ }
692
698
  }
693
699
  grpc_metadata_batch_assert_ok(metadata);
694
700
  for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) {
695
- hpack_enc(c, l->md, &st);
701
+ uint8_t static_index = grpc_chttp2_get_static_hpack_table_index(l->md);
702
+ if (static_index) {
703
+ emit_indexed(c, static_index, &st);
704
+ } else {
705
+ hpack_enc(c, l->md, &st);
706
+ }
696
707
  }
697
708
  grpc_millis deadline = metadata->deadline;
698
709
  if (deadline != GRPC_MILLIS_INF_FUTURE) {
@@ -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/transport/static_metadata.h"
32
33
 
33
34
  extern grpc_core::TraceFlag grpc_http_trace;
34
35
 
@@ -366,3 +367,31 @@ grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
366
367
 
367
368
  return r;
368
369
  }
370
+
371
+ static size_t get_base64_encoded_size(size_t raw_length) {
372
+ static const uint8_t tail_xtra[3] = {0, 2, 3};
373
+ return raw_length / 3 * 4 + tail_xtra[raw_length % 3];
374
+ }
375
+
376
+ size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem,
377
+ bool use_true_binary_metadata) {
378
+ size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
379
+ size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
380
+ if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
381
+ return overhead_and_key + (use_true_binary_metadata
382
+ ? value_len + 1
383
+ : get_base64_encoded_size(value_len));
384
+ } else {
385
+ return overhead_and_key + value_len;
386
+ }
387
+ }
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
+ }
@@ -83,6 +83,15 @@ grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl,
83
83
  /* add a table entry to the index */
84
84
  grpc_error* grpc_chttp2_hptbl_add(grpc_chttp2_hptbl* tbl,
85
85
  grpc_mdelem md) GRPC_MUST_USE_RESULT;
86
+
87
+ size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem,
88
+ bool use_true_binary_metadata);
89
+
90
+ /* Returns the static hpack table index that corresponds to /a elem. Returns 0
91
+ if /a elem is not statically stored or if it is not in the static hpack
92
+ table */
93
+ uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md);
94
+
86
95
  /* Find a key/value pair in the table... returns the index in the table of the
87
96
  most similar entry, or 0 if the value was not found */
88
97
  typedef struct {
@@ -36,6 +36,7 @@
36
36
  #include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
37
37
  #include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
38
38
  #include "src/core/ext/transport/chttp2/transport/stream_map.h"
39
+ #include "src/core/lib/channel/channelz.h"
39
40
  #include "src/core/lib/compression/stream_compression.h"
40
41
  #include "src/core/lib/gprpp/manual_constructor.h"
41
42
  #include "src/core/lib/iomgr/combiner.h"
@@ -246,6 +247,8 @@ class Chttp2IncomingByteStream : public ByteStream {
246
247
  static void NextLocked(void* arg, grpc_error* error_ignored);
247
248
  static void OrphanLocked(void* arg, grpc_error* error_ignored);
248
249
 
250
+ void MaybeCreateStreamDecompressionCtx();
251
+
249
252
  grpc_chttp2_transport* transport_; // Immutable.
250
253
  grpc_chttp2_stream* stream_; // Immutable.
251
254
 
@@ -469,6 +472,9 @@ struct grpc_chttp2_transport {
469
472
  bool keepalive_permit_without_calls;
470
473
  /** keep-alive state machine state */
471
474
  grpc_chttp2_keepalive_state keepalive_state;
475
+
476
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> channelz_socket;
477
+ uint32_t num_messages_in_next_write;
472
478
  };
473
479
 
474
480
  typedef enum {
@@ -532,6 +538,10 @@ struct grpc_chttp2_stream {
532
538
  /** Has trailing metadata been received. */
533
539
  bool received_trailing_metadata;
534
540
 
541
+ /* have we sent or received the EOS bit? */
542
+ bool eos_received;
543
+ bool eos_sent;
544
+
535
545
  /** the error that resulted in this stream being read-closed */
536
546
  grpc_error* read_closed_error;
537
547
  /** the error that resulted in this stream being write-closed */
@@ -409,67 +409,81 @@ static void on_initial_header(void* tp, grpc_mdelem md) {
409
409
  gpr_free(value);
410
410
  }
411
411
 
412
- if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
413
- !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
414
- /* TODO(ctiller): check for a status like " 0" */
415
- s->seen_error = true;
416
- }
412
+ if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
413
+ // We don't use grpc_mdelem_eq here to avoid executing additional
414
+ // instructions. The reasoning is if the payload is not equal, we already
415
+ // know that the metadata elements are not equal because the md is
416
+ // confirmed to be static. If we had used grpc_mdelem_eq here, then if the
417
+ // payloads are not equal, grpc_mdelem_eq executes more instructions to
418
+ // determine if they're equal or not.
419
+ if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload ||
420
+ md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) {
421
+ s->seen_error = true;
422
+ }
423
+ } else {
424
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
425
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
426
+ /* TODO(ctiller): check for a status like " 0" */
427
+ s->seen_error = true;
428
+ }
417
429
 
418
- if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
419
- grpc_millis* cached_timeout =
420
- static_cast<grpc_millis*>(grpc_mdelem_get_user_data(md, free_timeout));
421
- grpc_millis timeout;
422
- if (cached_timeout != nullptr) {
423
- timeout = *cached_timeout;
424
- } else {
425
- if (GPR_UNLIKELY(
426
- !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) {
427
- char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
428
- gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
429
- gpr_free(val);
430
- timeout = GRPC_MILLIS_INF_FUTURE;
430
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
431
+ grpc_millis* cached_timeout = static_cast<grpc_millis*>(
432
+ grpc_mdelem_get_user_data(md, free_timeout));
433
+ grpc_millis timeout;
434
+ if (cached_timeout != nullptr) {
435
+ timeout = *cached_timeout;
436
+ } else {
437
+ if (GPR_UNLIKELY(
438
+ !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) {
439
+ char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
440
+ gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
441
+ gpr_free(val);
442
+ timeout = GRPC_MILLIS_INF_FUTURE;
443
+ }
444
+ if (GRPC_MDELEM_IS_INTERNED(md)) {
445
+ /* store the result */
446
+ cached_timeout =
447
+ static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis)));
448
+ *cached_timeout = timeout;
449
+ grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
450
+ }
431
451
  }
432
- if (GRPC_MDELEM_IS_INTERNED(md)) {
433
- /* store the result */
434
- cached_timeout =
435
- static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis)));
436
- *cached_timeout = timeout;
437
- grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
452
+ if (timeout != GRPC_MILLIS_INF_FUTURE) {
453
+ grpc_chttp2_incoming_metadata_buffer_set_deadline(
454
+ &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout);
438
455
  }
456
+ GRPC_MDELEM_UNREF(md);
457
+ return;
439
458
  }
440
- if (timeout != GRPC_MILLIS_INF_FUTURE) {
441
- grpc_chttp2_incoming_metadata_buffer_set_deadline(
442
- &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout);
443
- }
459
+ }
460
+
461
+ const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
462
+ const size_t metadata_size_limit =
463
+ t->settings[GRPC_ACKED_SETTINGS]
464
+ [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
465
+ if (new_size > metadata_size_limit) {
466
+ gpr_log(GPR_DEBUG,
467
+ "received initial metadata size exceeds limit (%" PRIuPTR
468
+ " vs. %" PRIuPTR ")",
469
+ new_size, metadata_size_limit);
470
+ grpc_chttp2_cancel_stream(
471
+ t, s,
472
+ grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
473
+ "received initial metadata size exceeds limit"),
474
+ GRPC_ERROR_INT_GRPC_STATUS,
475
+ GRPC_STATUS_RESOURCE_EXHAUSTED));
476
+ grpc_chttp2_parsing_become_skip_parser(t);
477
+ s->seen_error = true;
444
478
  GRPC_MDELEM_UNREF(md);
445
479
  } else {
446
- const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
447
- const size_t metadata_size_limit =
448
- t->settings[GRPC_ACKED_SETTINGS]
449
- [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
450
- if (new_size > metadata_size_limit) {
451
- gpr_log(GPR_DEBUG,
452
- "received initial metadata size exceeds limit (%" PRIuPTR
453
- " vs. %" PRIuPTR ")",
454
- new_size, metadata_size_limit);
455
- grpc_chttp2_cancel_stream(
456
- t, s,
457
- grpc_error_set_int(
458
- GRPC_ERROR_CREATE_FROM_STATIC_STRING(
459
- "received initial metadata size exceeds limit"),
460
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
480
+ grpc_error* error =
481
+ grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md);
482
+ if (error != GRPC_ERROR_NONE) {
483
+ grpc_chttp2_cancel_stream(t, s, error);
461
484
  grpc_chttp2_parsing_become_skip_parser(t);
462
485
  s->seen_error = true;
463
486
  GRPC_MDELEM_UNREF(md);
464
- } else {
465
- grpc_error* error =
466
- grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md);
467
- if (error != GRPC_ERROR_NONE) {
468
- grpc_chttp2_cancel_stream(t, s, error);
469
- grpc_chttp2_parsing_become_skip_parser(t);
470
- s->seen_error = true;
471
- GRPC_MDELEM_UNREF(md);
472
- }
473
487
  }
474
488
  }
475
489
  }
@@ -491,8 +505,19 @@ static void on_trailing_header(void* tp, grpc_mdelem md) {
491
505
  gpr_free(value);
492
506
  }
493
507
 
494
- if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
495
- !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
508
+ if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
509
+ // We don't use grpc_mdelem_eq here to avoid executing additional
510
+ // instructions. The reasoning is if the payload is not equal, we already
511
+ // know that the metadata elements are not equal because the md is
512
+ // confirmed to be static. If we had used grpc_mdelem_eq here, then if the
513
+ // payloads are not equal, grpc_mdelem_eq executes more instructions to
514
+ // determine if they're equal or not.
515
+ if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload ||
516
+ md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) {
517
+ s->seen_error = true;
518
+ }
519
+ } else if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
520
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
496
521
  /* TODO(ctiller): check for a status like " 0" */
497
522
  s->seen_error = true;
498
523
  }
@@ -598,6 +623,9 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t,
598
623
  gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted"));
599
624
  return init_skip_frame_parser(t, 1);
600
625
  }
626
+ if (t->channelz_socket != nullptr) {
627
+ t->channelz_socket->RecordStreamStartedFromRemote();
628
+ }
601
629
  } else {
602
630
  t->incoming_stream = s;
603
631
  }
@@ -611,6 +639,9 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t,
611
639
  }
612
640
  t->parser = grpc_chttp2_header_parser_parse;
613
641
  t->parser_data = &t->hpack_parser;
642
+ if (t->header_eof) {
643
+ s->eos_received = true;
644
+ }
614
645
  switch (s->header_frames_received) {
615
646
  case 0:
616
647
  if (t->is_client && t->header_eof) {
@@ -569,6 +569,7 @@ class StreamWriteContext {
569
569
  void SentLastFrame() {
570
570
  s_->send_trailing_metadata = nullptr;
571
571
  s_->sent_trailing_metadata = true;
572
+ s_->eos_sent = true;
572
573
 
573
574
  if (!t_->is_client && !s_->read_closed) {
574
575
  grpc_slice_buffer_add(
@@ -632,6 +633,11 @@ void grpc_chttp2_end_write(grpc_chttp2_transport* t, grpc_error* error) {
632
633
  GPR_TIMER_SCOPE("grpc_chttp2_end_write", 0);
633
634
  grpc_chttp2_stream* s;
634
635
 
636
+ if (t->channelz_socket != nullptr) {
637
+ t->channelz_socket->RecordMessagesSent(t->num_messages_in_next_write);
638
+ }
639
+ t->num_messages_in_next_write = 0;
640
+
635
641
  while (grpc_chttp2_list_pop_writing_stream(t, &s)) {
636
642
  if (s->sending_bytes != 0) {
637
643
  update_list(t, s, static_cast<int64_t>(s->sending_bytes),
@@ -41,40 +41,42 @@
41
41
  namespace grpc_core {
42
42
  namespace channelz {
43
43
 
44
- ChannelTrace::TraceEvent::TraceEvent(
45
- Severity severity, grpc_slice data,
46
- RefCountedPtr<ChannelNode> referenced_channel, ReferencedType type)
44
+ ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data,
45
+ RefCountedPtr<BaseNode> referenced_entity)
47
46
  : severity_(severity),
48
47
  data_(data),
49
48
  timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(),
50
49
  GPR_CLOCK_REALTIME)),
51
50
  next_(nullptr),
52
- referenced_channel_(std::move(referenced_channel)),
53
- referenced_type_(type) {}
51
+ referenced_entity_(std::move(referenced_entity)),
52
+ memory_usage_(sizeof(TraceEvent) + grpc_slice_memory_usage(data)) {}
54
53
 
55
54
  ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data)
56
55
  : severity_(severity),
57
56
  data_(data),
58
57
  timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(),
59
58
  GPR_CLOCK_REALTIME)),
60
- next_(nullptr) {}
59
+ next_(nullptr),
60
+ memory_usage_(sizeof(TraceEvent) + grpc_slice_memory_usage(data)) {}
61
61
 
62
62
  ChannelTrace::TraceEvent::~TraceEvent() { grpc_slice_unref_internal(data_); }
63
63
 
64
- ChannelTrace::ChannelTrace(size_t max_events)
64
+ ChannelTrace::ChannelTrace(size_t max_event_memory)
65
65
  : num_events_logged_(0),
66
- list_size_(0),
67
- max_list_size_(max_events),
66
+ event_list_memory_usage_(0),
67
+ max_event_memory_(max_event_memory),
68
68
  head_trace_(nullptr),
69
69
  tail_trace_(nullptr) {
70
- if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0
70
+ if (max_event_memory_ == 0)
71
+ return; // tracing is disabled if max_event_memory_ == 0
71
72
  gpr_mu_init(&tracer_mu_);
72
73
  time_created_ = grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(),
73
74
  GPR_CLOCK_REALTIME);
74
75
  }
75
76
 
76
77
  ChannelTrace::~ChannelTrace() {
77
- if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0
78
+ if (max_event_memory_ == 0)
79
+ return; // tracing is disabled if max_event_memory_ == 0
78
80
  TraceEvent* it = head_trace_;
79
81
  while (it != nullptr) {
80
82
  TraceEvent* to_free = it;
@@ -95,38 +97,30 @@ void ChannelTrace::AddTraceEventHelper(TraceEvent* new_trace_event) {
95
97
  tail_trace_->set_next(new_trace_event);
96
98
  tail_trace_ = tail_trace_->next();
97
99
  }
98
- ++list_size_;
99
- // maybe garbage collect the end
100
- if (list_size_ > max_list_size_) {
100
+ event_list_memory_usage_ += new_trace_event->memory_usage();
101
+ // maybe garbage collect the tail until we are under the memory limit.
102
+ while (event_list_memory_usage_ > max_event_memory_) {
101
103
  TraceEvent* to_free = head_trace_;
104
+ event_list_memory_usage_ -= to_free->memory_usage();
102
105
  head_trace_ = head_trace_->next();
103
106
  Delete<TraceEvent>(to_free);
104
- --list_size_;
105
107
  }
106
108
  }
107
109
 
108
110
  void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) {
109
- if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0
111
+ if (max_event_memory_ == 0)
112
+ return; // tracing is disabled if max_event_memory_ == 0
110
113
  AddTraceEventHelper(New<TraceEvent>(severity, data));
111
114
  }
112
115
 
113
- void ChannelTrace::AddTraceEventReferencingChannel(
114
- Severity severity, grpc_slice data,
115
- RefCountedPtr<ChannelNode> referenced_channel) {
116
- if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0
117
- // create and fill up the new event
118
- AddTraceEventHelper(New<TraceEvent>(
119
- severity, data, std::move(referenced_channel), ReferencedType::Channel));
120
- }
121
-
122
- void ChannelTrace::AddTraceEventReferencingSubchannel(
116
+ void ChannelTrace::AddTraceEventWithReference(
123
117
  Severity severity, grpc_slice data,
124
- RefCountedPtr<ChannelNode> referenced_subchannel) {
125
- if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0
118
+ RefCountedPtr<BaseNode> referenced_entity) {
119
+ if (max_event_memory_ == 0)
120
+ return; // tracing is disabled if max_event_memory_ == 0
126
121
  // create and fill up the new event
127
- AddTraceEventHelper(New<TraceEvent>(severity, data,
128
- std::move(referenced_subchannel),
129
- ReferencedType::Subchannel));
122
+ AddTraceEventHelper(
123
+ New<TraceEvent>(severity, data, std::move(referenced_entity)));
130
124
  }
131
125
 
132
126
  namespace {
@@ -157,45 +151,46 @@ void ChannelTrace::TraceEvent::RenderTraceEvent(grpc_json* json) const {
157
151
  json_iterator = grpc_json_create_child(json_iterator, json, "timestamp",
158
152
  gpr_format_timespec(timestamp_),
159
153
  GRPC_JSON_STRING, true);
160
- if (referenced_channel_ != nullptr) {
154
+ if (referenced_entity_ != nullptr) {
155
+ const bool is_channel =
156
+ (referenced_entity_->type() == BaseNode::EntityType::kTopLevelChannel ||
157
+ referenced_entity_->type() == BaseNode::EntityType::kInternalChannel);
161
158
  char* uuid_str;
162
- gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_channel_->channel_uuid());
159
+ gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_entity_->uuid());
163
160
  grpc_json* child_ref = grpc_json_create_child(
164
- json_iterator, json,
165
- (referenced_type_ == ReferencedType::Channel) ? "channelRef"
166
- : "subchannelRef",
161
+ json_iterator, json, is_channel ? "channelRef" : "subchannelRef",
167
162
  nullptr, GRPC_JSON_OBJECT, false);
168
163
  json_iterator = grpc_json_create_child(
169
- nullptr, child_ref,
170
- (referenced_type_ == ReferencedType::Channel) ? "channelId"
171
- : "subchannelId",
172
- uuid_str, GRPC_JSON_STRING, true);
164
+ nullptr, child_ref, is_channel ? "channelId" : "subchannelId", uuid_str,
165
+ GRPC_JSON_STRING, true);
173
166
  json_iterator = child_ref;
174
167
  }
175
168
  }
176
169
 
177
170
  grpc_json* ChannelTrace::RenderJson() const {
178
- if (!max_list_size_)
179
- return nullptr; // tracing is disabled if max_events == 0
171
+ if (max_event_memory_ == 0)
172
+ return nullptr; // tracing is disabled if max_event_memory_ == 0
180
173
  grpc_json* json = grpc_json_create(GRPC_JSON_OBJECT);
181
- char* num_events_logged_str;
182
- gpr_asprintf(&num_events_logged_str, "%" PRId64, num_events_logged_);
183
174
  grpc_json* json_iterator = nullptr;
184
- json_iterator =
185
- grpc_json_create_child(json_iterator, json, "numEventsLogged",
186
- num_events_logged_str, GRPC_JSON_STRING, true);
175
+ if (num_events_logged_ > 0) {
176
+ json_iterator = grpc_json_add_number_string_child(
177
+ json, json_iterator, "numEventsLogged", num_events_logged_);
178
+ }
187
179
  json_iterator = grpc_json_create_child(
188
180
  json_iterator, json, "creationTimestamp",
189
181
  gpr_format_timespec(time_created_), GRPC_JSON_STRING, true);
190
- grpc_json* events = grpc_json_create_child(json_iterator, json, "events",
191
- nullptr, GRPC_JSON_ARRAY, false);
192
- json_iterator = nullptr;
193
- TraceEvent* it = head_trace_;
194
- while (it != nullptr) {
195
- json_iterator = grpc_json_create_child(json_iterator, events, nullptr,
196
- nullptr, GRPC_JSON_OBJECT, false);
197
- it->RenderTraceEvent(json_iterator);
198
- it = it->next();
182
+ // only add in the event list if it is non-empty.
183
+ if (head_trace_ != nullptr) {
184
+ grpc_json* events = grpc_json_create_child(json_iterator, json, "events",
185
+ nullptr, GRPC_JSON_ARRAY, false);
186
+ json_iterator = nullptr;
187
+ TraceEvent* it = head_trace_;
188
+ while (it != nullptr) {
189
+ json_iterator = grpc_json_create_child(json_iterator, events, nullptr,
190
+ nullptr, GRPC_JSON_OBJECT, false);
191
+ it->RenderTraceEvent(json_iterator);
192
+ it = it->next();
193
+ }
199
194
  }
200
195
  return json;
201
196
  }