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
@@ -85,7 +85,9 @@ class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> {
85
85
  size_t parent_data_size;
86
86
  };
87
87
 
88
- explicit ConnectedSubchannel(grpc_channel_stack* channel_stack);
88
+ explicit ConnectedSubchannel(grpc_channel_stack* channel_stack,
89
+ channelz::SubchannelNode* channelz_subchannel,
90
+ intptr_t socket_uuid);
89
91
  ~ConnectedSubchannel();
90
92
 
91
93
  grpc_channel_stack* channel_stack() { return channel_stack_; }
@@ -94,9 +96,18 @@ class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> {
94
96
  grpc_closure* closure);
95
97
  void Ping(grpc_closure* on_initiate, grpc_closure* on_ack);
96
98
  grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call);
99
+ channelz::SubchannelNode* channelz_subchannel() {
100
+ return channelz_subchannel_;
101
+ }
102
+ intptr_t socket_uuid() { return socket_uuid_; }
97
103
 
98
104
  private:
99
105
  grpc_channel_stack* channel_stack_;
106
+ // backpointer to the channelz node in this connected subchannel's
107
+ // owning subchannel.
108
+ channelz::SubchannelNode* channelz_subchannel_;
109
+ // uuid of this subchannel's socket. 0 if this subchannel is not connected.
110
+ const intptr_t socket_uuid_;
100
111
  };
101
112
 
102
113
  } // namespace grpc_core
@@ -119,6 +130,8 @@ void grpc_subchannel_call_unref(
119
130
  grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node(
120
131
  grpc_subchannel* subchannel);
121
132
 
133
+ intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel);
134
+
122
135
  /** Returns a pointer to the parent data associated with \a subchannel_call.
123
136
  The data will be of the size specified in \a parent_data_size
124
137
  field of the args passed to \a grpc_connected_subchannel_create_call(). */
@@ -184,6 +197,8 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector,
184
197
  void grpc_get_subchannel_address_arg(const grpc_channel_args* args,
185
198
  grpc_resolved_address* addr);
186
199
 
200
+ const char* grpc_subchannel_get_target(grpc_subchannel* subchannel);
201
+
187
202
  /// Returns the URI string for the address to connect to.
188
203
  const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args);
189
204
 
@@ -73,7 +73,8 @@ static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) {
73
73
 
74
74
  int grpc_subchannel_key_compare(const grpc_subchannel_key* a,
75
75
  const grpc_subchannel_key* b) {
76
- if (g_force_creation) return false;
76
+ // To pretend the keys are different, return a non-zero value.
77
+ if (GPR_UNLIKELY(g_force_creation)) return 1;
77
78
  int c = GPR_ICMP(a->args.filter_count, b->args.filter_count);
78
79
  if (c != 0) return c;
79
80
  if (a->args.filter_count > 0) {
@@ -65,13 +65,10 @@ void grpc_subchannel_index_ref(void);
65
65
  void grpc_subchannel_index_unref(void);
66
66
 
67
67
  /** \em TEST ONLY.
68
- * If \a force_creation is true, all key comparisons will be false, resulting in
68
+ * If \a force_creation is true, all keys are regarded different, resulting in
69
69
  * new subchannels always being created. Otherwise, the keys will be compared as
70
70
  * usual.
71
71
  *
72
- * This function is *not* threadsafe on purpose: it should *only* be used in
73
- * test code.
74
- *
75
72
  * Tests using this function \em MUST run tests with and without \a
76
73
  * force_creation set. */
77
74
  void grpc_subchannel_index_test_only_set_force_creation(bool force_creation);
@@ -51,12 +51,15 @@ struct call_data {
51
51
  grpc_linked_mdelem user_agent;
52
52
  // State for handling recv_initial_metadata ops.
53
53
  grpc_metadata_batch* recv_initial_metadata;
54
+ grpc_error* recv_initial_metadata_error;
54
55
  grpc_closure* original_recv_initial_metadata_ready;
55
56
  grpc_closure recv_initial_metadata_ready;
56
57
  // State for handling recv_trailing_metadata ops.
57
58
  grpc_metadata_batch* recv_trailing_metadata;
58
59
  grpc_closure* original_recv_trailing_metadata_ready;
59
60
  grpc_closure recv_trailing_metadata_ready;
61
+ grpc_error* recv_trailing_metadata_error;
62
+ bool seen_recv_trailing_metadata_ready;
60
63
  // State for handling send_message ops.
61
64
  grpc_transport_stream_op_batch* send_message_batch;
62
65
  size_t send_message_bytes_read;
@@ -78,7 +81,12 @@ struct channel_data {
78
81
  static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem,
79
82
  grpc_metadata_batch* b) {
80
83
  if (b->idx.named.status != nullptr) {
81
- if (grpc_mdelem_eq(b->idx.named.status->md, GRPC_MDELEM_STATUS_200)) {
84
+ /* If both gRPC status and HTTP status are provided in the response, we
85
+ * should prefer the gRPC status code, as mentioned in
86
+ * https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md.
87
+ */
88
+ if (b->idx.named.grpc_status != nullptr ||
89
+ grpc_mdelem_eq(b->idx.named.status->md, GRPC_MDELEM_STATUS_200)) {
82
90
  grpc_metadata_batch_remove(b, b->idx.named.status);
83
91
  } else {
84
92
  char* val = grpc_dump_slice(GRPC_MDVALUE(b->idx.named.status->md),
@@ -147,21 +155,39 @@ static void recv_initial_metadata_ready(void* user_data, grpc_error* error) {
147
155
  call_data* calld = static_cast<call_data*>(elem->call_data);
148
156
  if (error == GRPC_ERROR_NONE) {
149
157
  error = client_filter_incoming_metadata(elem, calld->recv_initial_metadata);
158
+ calld->recv_initial_metadata_error = GRPC_ERROR_REF(error);
150
159
  } else {
151
160
  GRPC_ERROR_REF(error);
152
161
  }
153
- GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready, error);
162
+ grpc_closure* closure = calld->original_recv_initial_metadata_ready;
163
+ calld->original_recv_initial_metadata_ready = nullptr;
164
+ if (calld->seen_recv_trailing_metadata_ready) {
165
+ GRPC_CALL_COMBINER_START(
166
+ calld->call_combiner, &calld->recv_trailing_metadata_ready,
167
+ calld->recv_trailing_metadata_error, "continue recv_trailing_metadata");
168
+ }
169
+ GRPC_CLOSURE_RUN(closure, error);
154
170
  }
155
171
 
156
172
  static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) {
157
173
  grpc_call_element* elem = static_cast<grpc_call_element*>(user_data);
158
174
  call_data* calld = static_cast<call_data*>(elem->call_data);
175
+ if (calld->original_recv_initial_metadata_ready != nullptr) {
176
+ calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error);
177
+ calld->seen_recv_trailing_metadata_ready = true;
178
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner,
179
+ "deferring recv_trailing_metadata_ready until "
180
+ "after recv_initial_metadata_ready");
181
+ return;
182
+ }
159
183
  if (error == GRPC_ERROR_NONE) {
160
184
  error =
161
185
  client_filter_incoming_metadata(elem, calld->recv_trailing_metadata);
162
186
  } else {
163
187
  GRPC_ERROR_REF(error);
164
188
  }
189
+ error = grpc_error_add_child(
190
+ error, GRPC_ERROR_REF(calld->recv_initial_metadata_error));
165
191
  GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error);
166
192
  }
167
193
 
@@ -434,7 +460,10 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
434
460
  /* Destructor for call_data */
435
461
  static void destroy_call_elem(grpc_call_element* elem,
436
462
  const grpc_call_final_info* final_info,
437
- grpc_closure* ignored) {}
463
+ grpc_closure* ignored) {
464
+ call_data* calld = static_cast<call_data*>(elem->call_data);
465
+ GRPC_ERROR_UNREF(calld->recv_initial_metadata_error);
466
+ }
438
467
 
439
468
  static grpc_mdelem scheme_from_args(const grpc_channel_args* args) {
440
469
  unsigned i;
@@ -23,6 +23,7 @@
23
23
  #include <grpc/support/alloc.h>
24
24
  #include <grpc/support/log.h>
25
25
  #include <string.h>
26
+ #include "src/core/lib/channel/channel_args.h"
26
27
  #include "src/core/lib/gprpp/manual_constructor.h"
27
28
  #include "src/core/lib/profiling/timers.h"
28
29
  #include "src/core/lib/slice/b64.h"
@@ -50,6 +51,7 @@ struct call_data {
50
51
 
51
52
  // State for intercepting recv_initial_metadata.
52
53
  grpc_closure recv_initial_metadata_ready;
54
+ grpc_error* recv_initial_metadata_ready_error;
53
55
  grpc_closure* original_recv_initial_metadata_ready;
54
56
  grpc_metadata_batch* recv_initial_metadata;
55
57
  uint32_t* recv_initial_metadata_flags;
@@ -60,6 +62,16 @@ struct call_data {
60
62
  grpc_closure recv_message_ready;
61
63
  grpc_core::OrphanablePtr<grpc_core::ByteStream>* recv_message;
62
64
  bool seen_recv_message_ready;
65
+
66
+ // State for intercepting recv_trailing_metadata
67
+ grpc_closure recv_trailing_metadata_ready;
68
+ grpc_closure* original_recv_trailing_metadata_ready;
69
+ grpc_error* recv_trailing_metadata_ready_error;
70
+ bool seen_recv_trailing_metadata_ready;
71
+ };
72
+
73
+ struct channel_data {
74
+ bool surface_user_agent;
63
75
  };
64
76
 
65
77
  } // namespace
@@ -258,6 +270,11 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem,
258
270
  GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":authority")));
259
271
  }
260
272
 
273
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
274
+ if (!chand->surface_user_agent && b->idx.named.user_agent != nullptr) {
275
+ grpc_metadata_batch_remove(b, b->idx.named.user_agent);
276
+ }
277
+
261
278
  return error;
262
279
  }
263
280
 
@@ -267,6 +284,7 @@ static void hs_recv_initial_metadata_ready(void* user_data, grpc_error* err) {
267
284
  calld->seen_recv_initial_metadata_ready = true;
268
285
  if (err == GRPC_ERROR_NONE) {
269
286
  err = hs_filter_incoming_metadata(elem, calld->recv_initial_metadata);
287
+ calld->recv_initial_metadata_ready_error = GRPC_ERROR_REF(err);
270
288
  if (calld->seen_recv_message_ready) {
271
289
  // We've already seen the recv_message callback, but we previously
272
290
  // deferred it, so we need to return it here.
@@ -286,6 +304,13 @@ static void hs_recv_initial_metadata_ready(void* user_data, grpc_error* err) {
286
304
  } else {
287
305
  GRPC_ERROR_REF(err);
288
306
  }
307
+ if (calld->seen_recv_trailing_metadata_ready) {
308
+ GRPC_CALL_COMBINER_START(calld->call_combiner,
309
+ &calld->recv_trailing_metadata_ready,
310
+ calld->recv_trailing_metadata_ready_error,
311
+ "resuming hs_recv_trailing_metadata_ready from "
312
+ "hs_recv_initial_metadata_ready");
313
+ }
289
314
  GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready, err);
290
315
  }
291
316
 
@@ -313,6 +338,23 @@ static void hs_recv_message_ready(void* user_data, grpc_error* err) {
313
338
  }
314
339
  }
315
340
 
341
+ static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) {
342
+ grpc_call_element* elem = static_cast<grpc_call_element*>(user_data);
343
+ call_data* calld = static_cast<call_data*>(elem->call_data);
344
+ if (!calld->seen_recv_initial_metadata_ready) {
345
+ calld->recv_trailing_metadata_ready_error = GRPC_ERROR_REF(err);
346
+ calld->seen_recv_trailing_metadata_ready = true;
347
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner,
348
+ "deferring hs_recv_trailing_metadata_ready until "
349
+ "ater hs_recv_initial_metadata_ready");
350
+ return;
351
+ }
352
+ err = grpc_error_add_child(
353
+ GRPC_ERROR_REF(err),
354
+ GRPC_ERROR_REF(calld->recv_initial_metadata_ready_error));
355
+ GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err);
356
+ }
357
+
316
358
  static grpc_error* hs_mutate_op(grpc_call_element* elem,
317
359
  grpc_transport_stream_op_batch* op) {
318
360
  /* grab pointers to our data from the call element */
@@ -357,6 +399,13 @@ static grpc_error* hs_mutate_op(grpc_call_element* elem,
357
399
  op->payload->recv_message.recv_message_ready = &calld->recv_message_ready;
358
400
  }
359
401
 
402
+ if (op->recv_trailing_metadata) {
403
+ calld->original_recv_trailing_metadata_ready =
404
+ op->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
405
+ op->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
406
+ &calld->recv_trailing_metadata_ready;
407
+ }
408
+
360
409
  if (op->send_trailing_metadata) {
361
410
  grpc_error* error = hs_filter_outgoing_metadata(
362
411
  elem, op->payload->send_trailing_metadata.send_trailing_metadata);
@@ -389,6 +438,9 @@ static grpc_error* hs_init_call_elem(grpc_call_element* elem,
389
438
  grpc_schedule_on_exec_ctx);
390
439
  GRPC_CLOSURE_INIT(&calld->recv_message_ready, hs_recv_message_ready, elem,
391
440
  grpc_schedule_on_exec_ctx);
441
+ GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready,
442
+ hs_recv_trailing_metadata_ready, elem,
443
+ grpc_schedule_on_exec_ctx);
392
444
  return GRPC_ERROR_NONE;
393
445
  }
394
446
 
@@ -397,6 +449,7 @@ static void hs_destroy_call_elem(grpc_call_element* elem,
397
449
  const grpc_call_final_info* final_info,
398
450
  grpc_closure* ignored) {
399
451
  call_data* calld = static_cast<call_data*>(elem->call_data);
452
+ GRPC_ERROR_UNREF(calld->recv_initial_metadata_ready_error);
400
453
  if (calld->have_read_stream) {
401
454
  calld->read_stream->Orphan();
402
455
  }
@@ -405,7 +458,12 @@ static void hs_destroy_call_elem(grpc_call_element* elem,
405
458
  /* Constructor for channel_data */
406
459
  static grpc_error* hs_init_channel_elem(grpc_channel_element* elem,
407
460
  grpc_channel_element_args* args) {
461
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
408
462
  GPR_ASSERT(!args->is_last);
463
+ chand->surface_user_agent = grpc_channel_arg_get_bool(
464
+ grpc_channel_args_find(args->channel_args,
465
+ const_cast<char*>(GRPC_ARG_SURFACE_USER_AGENT)),
466
+ true);
409
467
  return GRPC_ERROR_NONE;
410
468
  }
411
469
 
@@ -419,7 +477,7 @@ const grpc_channel_filter grpc_http_server_filter = {
419
477
  hs_init_call_elem,
420
478
  grpc_call_stack_ignore_set_pollset_or_pollset_set,
421
479
  hs_destroy_call_elem,
422
- 0,
480
+ sizeof(channel_data),
423
481
  hs_init_channel_elem,
424
482
  hs_destroy_channel_elem,
425
483
  grpc_channel_next_get_info,
@@ -429,8 +429,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
429
429
  ? GRPC_MILLIS_INF_FUTURE
430
430
  : DEFAULT_MAX_CONNECTION_IDLE_MS;
431
431
  chand->idle_state = MAX_IDLE_STATE_INIT;
432
- gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis,
433
- GRPC_MILLIS_INF_PAST);
432
+ gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, GPR_ATM_MIN);
434
433
  for (size_t i = 0; i < args->channel_args->num_args; ++i) {
435
434
  if (0 == strcmp(args->channel_args->args[i].key,
436
435
  GRPC_ARG_MAX_CONNECTION_AGE_MS)) {
@@ -99,10 +99,17 @@ struct call_data {
99
99
  // recv_message_ready up-call on transport_stream_op, and remember to
100
100
  // call our next_recv_message_ready member after handling it.
101
101
  grpc_closure recv_message_ready;
102
+ grpc_closure recv_trailing_metadata_ready;
103
+ // The error caused by a message that is too large, or GRPC_ERROR_NONE
104
+ grpc_error* error;
102
105
  // Used by recv_message_ready.
103
106
  grpc_core::OrphanablePtr<grpc_core::ByteStream>* recv_message;
104
107
  // Original recv_message_ready callback, invoked after our own.
105
108
  grpc_closure* next_recv_message_ready;
109
+ // Original recv_trailing_metadata callback, invoked after our own.
110
+ grpc_closure* original_recv_trailing_metadata_ready;
111
+ bool seen_recv_trailing_metadata;
112
+ grpc_error* recv_trailing_metadata_error;
106
113
  };
107
114
 
108
115
  struct channel_data {
@@ -130,18 +137,52 @@ static void recv_message_ready(void* user_data, grpc_error* error) {
130
137
  grpc_error* new_error = grpc_error_set_int(
131
138
  GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
132
139
  GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED);
140
+ GRPC_ERROR_UNREF(calld->error);
133
141
  if (error == GRPC_ERROR_NONE) {
134
142
  error = new_error;
135
143
  } else {
136
144
  error = grpc_error_add_child(error, new_error);
137
- GRPC_ERROR_UNREF(new_error);
138
145
  }
146
+ calld->error = GRPC_ERROR_REF(error);
139
147
  gpr_free(message_string);
140
148
  } else {
141
149
  GRPC_ERROR_REF(error);
142
150
  }
143
151
  // Invoke the next callback.
144
- GRPC_CLOSURE_RUN(calld->next_recv_message_ready, error);
152
+ grpc_closure* closure = calld->next_recv_message_ready;
153
+ calld->next_recv_message_ready = nullptr;
154
+ if (calld->seen_recv_trailing_metadata) {
155
+ /* We might potentially see another RECV_MESSAGE op. In that case, we do not
156
+ * want to run the recv_trailing_metadata_ready closure again. The newer
157
+ * RECV_MESSAGE op cannot cause any errors since the transport has already
158
+ * invoked the recv_trailing_metadata_ready closure and all further
159
+ * RECV_MESSAGE ops will get null payloads. */
160
+ calld->seen_recv_trailing_metadata = false;
161
+ GRPC_CALL_COMBINER_START(calld->call_combiner,
162
+ &calld->recv_trailing_metadata_ready,
163
+ calld->recv_trailing_metadata_error,
164
+ "continue recv_trailing_metadata_ready");
165
+ }
166
+ GRPC_CLOSURE_RUN(closure, error);
167
+ }
168
+
169
+ // Callback invoked on completion of recv_trailing_metadata
170
+ // Notifies the recv_trailing_metadata batch of any message size failures
171
+ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) {
172
+ grpc_call_element* elem = static_cast<grpc_call_element*>(user_data);
173
+ call_data* calld = static_cast<call_data*>(elem->call_data);
174
+ if (calld->next_recv_message_ready != nullptr) {
175
+ calld->seen_recv_trailing_metadata = true;
176
+ calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error);
177
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner,
178
+ "deferring recv_trailing_metadata_ready until "
179
+ "after recv_message_ready");
180
+ return;
181
+ }
182
+ error =
183
+ grpc_error_add_child(GRPC_ERROR_REF(error), GRPC_ERROR_REF(calld->error));
184
+ // Invoke the next callback.
185
+ GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error);
145
186
  }
146
187
 
147
188
  // Start transport stream op.
@@ -172,6 +213,13 @@ static void start_transport_stream_op_batch(
172
213
  calld->recv_message = op->payload->recv_message.recv_message;
173
214
  op->payload->recv_message.recv_message_ready = &calld->recv_message_ready;
174
215
  }
216
+ // Inject callback for receiving trailing metadata.
217
+ if (op->recv_trailing_metadata) {
218
+ calld->original_recv_trailing_metadata_ready =
219
+ op->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
220
+ op->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
221
+ &calld->recv_trailing_metadata_ready;
222
+ }
175
223
  // Chain to the next filter.
176
224
  grpc_call_next_op(elem, op);
177
225
  }
@@ -183,8 +231,13 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
183
231
  call_data* calld = static_cast<call_data*>(elem->call_data);
184
232
  calld->call_combiner = args->call_combiner;
185
233
  calld->next_recv_message_ready = nullptr;
234
+ calld->original_recv_trailing_metadata_ready = nullptr;
235
+ calld->error = GRPC_ERROR_NONE;
186
236
  GRPC_CLOSURE_INIT(&calld->recv_message_ready, recv_message_ready, elem,
187
237
  grpc_schedule_on_exec_ctx);
238
+ GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready,
239
+ recv_trailing_metadata_ready, elem,
240
+ grpc_schedule_on_exec_ctx);
188
241
  // Get max sizes from channel data, then merge in per-method config values.
189
242
  // Note: Per-method config is only available on the client, so we
190
243
  // apply the max request size to the send limit and the max response
@@ -213,7 +266,10 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
213
266
  // Destructor for call_data.
214
267
  static void destroy_call_elem(grpc_call_element* elem,
215
268
  const grpc_call_final_info* final_info,
216
- grpc_closure* ignored) {}
269
+ grpc_closure* ignored) {
270
+ call_data* calld = (call_data*)elem->call_data;
271
+ GRPC_ERROR_UNREF(calld->error);
272
+ }
217
273
 
218
274
  static int default_size(const grpc_channel_args* args,
219
275
  int without_minimal_stack) {
@@ -117,6 +117,8 @@ static void on_handshake_done(void* arg, grpc_error* error) {
117
117
  c->args.interested_parties);
118
118
  c->result->transport =
119
119
  grpc_create_chttp2_transport(args->args, args->endpoint, true);
120
+ c->result->socket_uuid =
121
+ grpc_chttp2_transport_get_socket_uuid(c->result->transport);
120
122
  GPR_ASSERT(c->result->transport);
121
123
  // TODO(roth): We ideally want to wait until we receive HTTP/2
122
124
  // settings from the server before we consider the connection
@@ -50,7 +50,7 @@ grpc_channel* grpc_insecure_channel_create_from_fd(
50
50
  GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0);
51
51
 
52
52
  grpc_endpoint* client = grpc_tcp_client_create_from_fd(
53
- grpc_fd_create(fd, "client", false), args, "fd-client");
53
+ grpc_fd_create(fd, "client", true), args, "fd-client");
54
54
 
55
55
  grpc_transport* transport =
56
56
  grpc_create_chttp2_transport(final_args, client, true);
@@ -44,7 +44,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
44
44
  gpr_asprintf(&name, "fd:%d", fd);
45
45
 
46
46
  grpc_endpoint* server_endpoint =
47
- grpc_tcp_create(grpc_fd_create(fd, name, false),
47
+ grpc_tcp_create(grpc_fd_create(fd, name, true),
48
48
  grpc_server_get_channel_args(server), name);
49
49
 
50
50
  gpr_free(name);