grpc 1.1.2 → 1.2.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 (255) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1257 -404
  3. data/etc/roots.pem +189 -102
  4. data/include/grpc/census.h +7 -7
  5. data/include/grpc/compression.h +4 -4
  6. data/include/grpc/grpc.h +13 -7
  7. data/include/grpc/impl/codegen/atm_gcc_atomic.h +26 -9
  8. data/include/grpc/impl/codegen/grpc_types.h +39 -30
  9. data/include/grpc/impl/codegen/slice.h +24 -6
  10. data/include/grpc/impl/codegen/sync.h +8 -0
  11. data/include/grpc/load_reporting.h +63 -0
  12. data/include/grpc/slice.h +37 -1
  13. data/include/grpc/slice_buffer.h +7 -0
  14. data/include/grpc/support/alloc.h +3 -0
  15. data/include/grpc/support/useful.h +3 -0
  16. data/src/core/ext/census/gen/census.pb.h +1 -1
  17. data/src/core/ext/census/gen/trace_context.pb.c +9 -36
  18. data/src/core/ext/census/gen/trace_context.pb.h +20 -26
  19. data/src/core/ext/census/grpc_filter.c +3 -5
  20. data/src/core/ext/census/trace_context.c +1 -1
  21. data/src/core/ext/census/trace_context.h +3 -0
  22. data/src/core/ext/census/trace_label.h +61 -0
  23. data/src/core/ext/census/trace_propagation.h +63 -0
  24. data/src/core/ext/census/trace_status.h +45 -0
  25. data/src/core/ext/census/trace_string.h +50 -0
  26. data/src/core/ext/census/tracing.c +31 -11
  27. data/src/core/ext/census/tracing.h +124 -0
  28. data/src/core/ext/client_channel/client_channel.c +456 -368
  29. data/src/core/ext/client_channel/client_channel.h +4 -0
  30. data/src/core/ext/client_channel/client_channel_plugin.c +6 -1
  31. data/src/core/ext/client_channel/connector.c +3 -3
  32. data/src/core/ext/client_channel/connector.h +4 -3
  33. data/src/core/ext/client_channel/http_connect_handshaker.c +62 -72
  34. data/src/core/ext/client_channel/http_connect_handshaker.h +7 -10
  35. data/src/core/ext/client_channel/http_proxy.c +125 -0
  36. data/src/core/ext/client_channel/http_proxy.h +39 -0
  37. data/src/core/ext/client_channel/lb_policy.c +56 -35
  38. data/src/core/ext/client_channel/lb_policy.h +46 -39
  39. data/src/core/ext/client_channel/lb_policy_factory.h +1 -0
  40. data/src/core/ext/client_channel/parse_address.c +32 -6
  41. data/src/core/ext/client_channel/proxy_mapper.c +63 -0
  42. data/src/core/ext/client_channel/proxy_mapper.h +89 -0
  43. data/src/core/ext/client_channel/proxy_mapper_registry.c +133 -0
  44. data/src/core/ext/client_channel/proxy_mapper_registry.h +59 -0
  45. data/src/core/ext/client_channel/resolver.c +16 -9
  46. data/src/core/ext/client_channel/resolver.h +23 -12
  47. data/src/core/ext/client_channel/resolver_factory.h +1 -0
  48. data/src/core/ext/client_channel/resolver_registry.c +15 -11
  49. data/src/core/ext/client_channel/resolver_registry.h +5 -3
  50. data/src/core/ext/client_channel/subchannel.c +44 -27
  51. data/src/core/ext/client_channel/subchannel.h +6 -2
  52. data/src/core/ext/client_channel/uri_parser.c +26 -14
  53. data/src/core/ext/client_channel/uri_parser.h +3 -1
  54. data/src/core/ext/lb_policy/grpclb/grpclb.c +220 -209
  55. data/src/core/ext/lb_policy/grpclb/grpclb_channel.h +56 -0
  56. data/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c +107 -0
  57. data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +3 -6
  58. data/src/core/ext/lb_policy/pick_first/pick_first.c +71 -116
  59. data/src/core/ext/lb_policy/round_robin/round_robin.c +52 -67
  60. data/src/core/ext/load_reporting/load_reporting.c +20 -0
  61. data/src/core/ext/load_reporting/load_reporting.h +1 -16
  62. data/src/core/ext/load_reporting/load_reporting_filter.c +28 -54
  63. data/src/core/ext/resolver/dns/native/dns_resolver.c +31 -45
  64. data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +20 -29
  65. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +11 -8
  66. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +11 -2
  67. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +143 -46
  68. data/src/core/ext/transport/chttp2/server/chttp2_server.c +12 -50
  69. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +1 -1
  70. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +1 -1
  71. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +7 -7
  72. data/src/core/ext/transport/chttp2/transport/bin_encoder.c +1 -2
  73. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -2
  74. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
  75. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +606 -374
  76. data/src/core/ext/transport/chttp2/transport/frame_ping.c +17 -5
  77. data/src/core/ext/transport/chttp2/transport/frame_ping.h +2 -2
  78. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +9 -13
  79. data/src/core/ext/transport/chttp2/transport/frame_settings.c +12 -11
  80. data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -1
  81. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +5 -6
  82. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +100 -53
  83. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -2
  84. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +126 -70
  85. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +13 -7
  86. data/src/core/ext/transport/chttp2/transport/hpack_table.c +22 -19
  87. data/src/core/ext/transport/chttp2/transport/hpack_table.h +6 -6
  88. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +23 -11
  89. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -2
  90. data/src/core/ext/transport/chttp2/transport/internal.h +169 -42
  91. data/src/core/ext/transport/chttp2/transport/parsing.c +98 -41
  92. data/src/core/ext/transport/chttp2/transport/stream_lists.c +29 -14
  93. data/src/core/ext/transport/chttp2/transport/writing.c +137 -15
  94. data/src/core/lib/channel/channel_stack.c +14 -44
  95. data/src/core/lib/channel/channel_stack.h +10 -17
  96. data/src/core/lib/channel/channel_stack_builder.c +2 -3
  97. data/src/core/lib/channel/compress_filter.c +54 -46
  98. data/src/core/lib/channel/connected_channel.c +4 -4
  99. data/src/core/lib/channel/connected_channel.h +5 -0
  100. data/src/core/lib/channel/context.h +3 -0
  101. data/src/core/lib/channel/deadline_filter.c +61 -61
  102. data/src/core/lib/channel/deadline_filter.h +8 -5
  103. data/src/core/lib/channel/handshaker.c +47 -7
  104. data/src/core/lib/channel/handshaker.h +21 -3
  105. data/src/core/lib/channel/http_client_filter.c +149 -99
  106. data/src/core/lib/channel/http_server_filter.c +163 -147
  107. data/src/core/lib/channel/message_size_filter.c +15 -10
  108. data/src/core/lib/compression/algorithm_metadata.h +4 -4
  109. data/src/core/lib/compression/compression.c +17 -23
  110. data/src/core/lib/http/httpcli.c +3 -2
  111. data/src/core/lib/http/httpcli.h +2 -1
  112. data/src/core/lib/http/httpcli_security_connector.c +2 -3
  113. data/src/core/lib/http/parser.c +2 -2
  114. data/src/core/lib/iomgr/closure.c +6 -3
  115. data/src/core/lib/iomgr/closure.h +4 -2
  116. data/src/core/lib/iomgr/combiner.c +35 -5
  117. data/src/core/lib/iomgr/combiner.h +21 -2
  118. data/src/core/lib/iomgr/endpoint.c +3 -2
  119. data/src/core/lib/iomgr/endpoint.h +3 -2
  120. data/src/core/lib/iomgr/error.c +60 -94
  121. data/src/core/lib/iomgr/error.h +7 -10
  122. data/src/core/lib/iomgr/error_internal.h +54 -0
  123. data/src/core/lib/iomgr/ev_epoll_linux.c +253 -109
  124. data/src/core/lib/iomgr/ev_poll_posix.c +61 -29
  125. data/src/core/lib/iomgr/ev_posix.c +7 -8
  126. data/src/core/lib/iomgr/ev_posix.h +4 -4
  127. data/src/core/lib/iomgr/exec_ctx.c +11 -6
  128. data/src/core/lib/iomgr/exec_ctx.h +11 -14
  129. data/src/core/lib/iomgr/executor.c +2 -2
  130. data/src/core/lib/iomgr/load_file.c +1 -1
  131. data/src/core/lib/iomgr/network_status_tracker.c +5 -81
  132. data/src/core/lib/iomgr/pollset.h +1 -3
  133. data/src/core/lib/iomgr/pollset_set.h +2 -1
  134. data/src/core/lib/iomgr/pollset_set_uv.c +2 -1
  135. data/src/core/lib/iomgr/pollset_set_windows.c +2 -1
  136. data/src/core/lib/iomgr/pollset_uv.c +25 -11
  137. data/src/core/lib/iomgr/pollset_windows.c +0 -11
  138. data/src/core/lib/iomgr/resolve_address_uv.c +50 -2
  139. data/src/core/lib/iomgr/resource_quota.c +41 -11
  140. data/src/core/lib/iomgr/resource_quota.h +6 -0
  141. data/src/core/lib/iomgr/sockaddr_utils.c +33 -17
  142. data/src/core/lib/iomgr/sockaddr_utils.h +4 -0
  143. data/src/core/lib/iomgr/tcp_client_posix.c +2 -3
  144. data/src/core/lib/iomgr/tcp_client_uv.c +1 -3
  145. data/src/core/lib/iomgr/tcp_client_windows.c +21 -6
  146. data/src/core/lib/iomgr/tcp_posix.c +4 -5
  147. data/src/core/lib/iomgr/tcp_server_posix.c +269 -94
  148. data/src/core/lib/iomgr/tcp_server_windows.c +1 -1
  149. data/src/core/lib/iomgr/tcp_uv.c +11 -5
  150. data/src/core/lib/iomgr/tcp_windows.c +20 -7
  151. data/src/core/lib/iomgr/timer_generic.c +15 -22
  152. data/src/core/lib/iomgr/timer_generic.h +1 -1
  153. data/src/core/lib/iomgr/timer_uv.c +10 -6
  154. data/src/core/lib/iomgr/timer_uv.h +1 -1
  155. data/src/core/lib/iomgr/udp_server.c +45 -6
  156. data/src/core/lib/iomgr/udp_server.h +7 -1
  157. data/src/core/lib/iomgr/unix_sockets_posix.c +11 -1
  158. data/src/core/lib/json/json.c +1 -2
  159. data/src/core/lib/profiling/basic_timers.c +17 -3
  160. data/src/core/lib/security/context/security_context.c +3 -10
  161. data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -8
  162. data/src/core/lib/security/credentials/credentials.c +48 -2
  163. data/src/core/lib/security/credentials/credentials.h +13 -0
  164. data/src/core/lib/security/credentials/credentials_metadata.c +1 -2
  165. data/src/core/lib/security/credentials/fake/fake_credentials.c +6 -8
  166. data/src/core/lib/security/credentials/fake/fake_credentials.h +15 -0
  167. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +3 -3
  168. data/src/core/lib/security/credentials/iam/iam_credentials.c +1 -2
  169. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -2
  170. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +5 -8
  171. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
  172. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +3 -5
  173. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +15 -13
  174. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +2 -4
  175. data/src/core/lib/security/transport/client_auth_filter.c +72 -47
  176. data/src/core/lib/security/transport/lb_targets_info.c +70 -0
  177. data/src/core/lib/security/transport/lb_targets_info.h +47 -0
  178. data/src/core/lib/security/transport/secure_endpoint.c +3 -3
  179. data/src/core/lib/security/transport/security_connector.c +125 -28
  180. data/src/core/lib/security/transport/security_connector.h +4 -3
  181. data/src/core/lib/security/transport/security_handshaker.c +13 -9
  182. data/src/core/lib/security/transport/server_auth_filter.c +31 -40
  183. data/src/core/lib/security/util/b64.c +1 -1
  184. data/src/core/lib/slice/slice.c +110 -20
  185. data/src/core/lib/slice/slice_buffer.c +92 -39
  186. data/src/core/lib/{transport/mdstr_hash_table.c → slice/slice_hash_table.c} +40 -33
  187. data/src/core/lib/{transport/mdstr_hash_table.h → slice/slice_hash_table.h} +21 -21
  188. data/src/core/lib/slice/slice_intern.c +346 -0
  189. data/src/core/lib/slice/slice_internal.h +15 -0
  190. data/src/core/lib/slice/slice_string_helpers.c +5 -0
  191. data/src/core/lib/slice/slice_string_helpers.h +5 -0
  192. data/src/core/lib/support/alloc.c +26 -1
  193. data/src/core/lib/support/cmdline.c +2 -4
  194. data/src/core/lib/support/cpu_posix.c +2 -7
  195. data/src/core/lib/support/histogram.c +1 -2
  196. data/src/core/lib/support/log_posix.c +8 -4
  197. data/src/core/lib/support/spinlock.h +52 -0
  198. data/src/core/lib/support/subprocess_posix.c +1 -2
  199. data/src/core/lib/support/sync.c +7 -1
  200. data/src/core/lib/support/sync_posix.c +9 -0
  201. data/src/core/lib/support/time_windows.c +7 -1
  202. data/src/core/lib/surface/call.c +647 -629
  203. data/src/core/lib/surface/call.h +4 -1
  204. data/src/core/lib/surface/call_details.c +8 -2
  205. data/src/core/lib/surface/call_log_batch.c +17 -6
  206. data/src/core/lib/surface/channel.c +49 -59
  207. data/src/core/lib/surface/channel.h +5 -6
  208. data/src/core/lib/surface/completion_queue.c +16 -45
  209. data/src/core/lib/surface/completion_queue.h +0 -3
  210. data/src/core/lib/surface/init.c +6 -2
  211. data/src/core/lib/surface/init_secure.c +1 -1
  212. data/src/core/lib/surface/lame_client.c +14 -4
  213. data/src/core/lib/surface/server.c +79 -82
  214. data/src/core/lib/surface/validate_metadata.c +46 -15
  215. data/src/core/lib/surface/validate_metadata.h +43 -0
  216. data/src/core/lib/surface/version.c +2 -2
  217. data/src/core/lib/transport/bdp_estimator.c +104 -0
  218. data/src/core/lib/transport/bdp_estimator.h +76 -0
  219. data/src/core/lib/transport/connectivity_state.c +33 -13
  220. data/src/core/lib/transport/connectivity_state.h +15 -5
  221. data/src/core/lib/transport/error_utils.c +124 -0
  222. data/src/core/lib/transport/error_utils.h +56 -0
  223. data/src/core/{ext/transport/chttp2 → lib}/transport/http2_errors.h +18 -18
  224. data/src/core/lib/transport/metadata.c +259 -503
  225. data/src/core/lib/transport/metadata.h +69 -68
  226. data/src/core/lib/transport/metadata_batch.c +183 -63
  227. data/src/core/lib/transport/metadata_batch.h +50 -26
  228. data/src/core/lib/transport/pid_controller.c +28 -8
  229. data/src/core/lib/transport/pid_controller.h +15 -2
  230. data/src/core/lib/transport/service_config.c +21 -18
  231. data/src/core/lib/transport/service_config.h +5 -5
  232. data/src/core/lib/transport/static_metadata.c +753 -112
  233. data/src/core/lib/transport/static_metadata.h +403 -264
  234. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.c +18 -20
  235. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.h +9 -10
  236. data/src/core/lib/transport/timeout_encoding.c +11 -9
  237. data/src/core/lib/transport/timeout_encoding.h +3 -1
  238. data/src/core/lib/transport/transport.c +47 -87
  239. data/src/core/lib/transport/transport.h +20 -25
  240. data/src/core/lib/transport/transport_op_string.c +7 -19
  241. data/src/core/lib/tsi/fake_transport_security.c +2 -4
  242. data/src/core/lib/tsi/ssl_transport_security.c +7 -16
  243. data/src/core/lib/tsi/transport_security.c +2 -4
  244. data/src/ruby/ext/grpc/extconf.rb +4 -1
  245. data/src/ruby/ext/grpc/rb_byte_buffer.c +7 -0
  246. data/src/ruby/ext/grpc/rb_byte_buffer.h +3 -0
  247. data/src/ruby/ext/grpc/rb_call.c +47 -46
  248. data/src/ruby/ext/grpc/rb_channel.c +21 -6
  249. data/src/ruby/ext/grpc/rb_compression_options.c +9 -6
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -2
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +59 -8
  252. data/src/ruby/ext/grpc/rb_server.c +6 -4
  253. data/src/ruby/lib/grpc/generic/client_stub.rb +1 -1
  254. data/src/ruby/lib/grpc/version.rb +1 -1
  255. metadata +33 -9
@@ -35,16 +35,18 @@
35
35
  #include "src/core/lib/channel/channel_stack.h"
36
36
  #include "src/core/lib/iomgr/timer.h"
37
37
 
38
+ typedef enum grpc_deadline_timer_state {
39
+ GRPC_DEADLINE_STATE_INITIAL,
40
+ GRPC_DEADLINE_STATE_PENDING,
41
+ GRPC_DEADLINE_STATE_FINISHED
42
+ } grpc_deadline_timer_state;
43
+
38
44
  // State used for filters that enforce call deadlines.
39
45
  // Must be the first field in the filter's call_data.
40
46
  typedef struct grpc_deadline_state {
41
47
  // We take a reference to the call stack for the timer callback.
42
48
  grpc_call_stack* call_stack;
43
- // Guards access to timer_pending and timer.
44
- gpr_mu timer_mu;
45
- // True if the timer callback is currently pending.
46
- bool timer_pending;
47
- // The deadline timer.
49
+ gpr_atm timer_state;
48
50
  grpc_timer timer;
49
51
  grpc_closure timer_callback;
50
52
  // Closure to invoke when the call is complete.
@@ -60,6 +62,7 @@ typedef struct grpc_deadline_state {
60
62
  // elem->call_data is a grpc_deadline_state.
61
63
  //
62
64
 
65
+ // assumes elem->call_data is zero'd
63
66
  void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
64
67
  grpc_call_stack* call_stack);
65
68
  void grpc_deadline_state_destroy(grpc_exec_ctx* exec_ctx,
@@ -55,8 +55,8 @@ void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx,
55
55
  }
56
56
 
57
57
  void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
58
- grpc_handshaker* handshaker) {
59
- handshaker->vtable->shutdown(exec_ctx, handshaker);
58
+ grpc_handshaker* handshaker, grpc_error* why) {
59
+ handshaker->vtable->shutdown(exec_ctx, handshaker, why);
60
60
  }
61
61
 
62
62
  void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
@@ -92,16 +92,52 @@ struct grpc_handshake_manager {
92
92
  void* user_data;
93
93
  // Handshaker args.
94
94
  grpc_handshaker_args args;
95
+ // Links to the previous and next managers in a list of all pending handshakes
96
+ // Used at server side only.
97
+ grpc_handshake_manager* prev;
98
+ grpc_handshake_manager* next;
95
99
  };
96
100
 
97
101
  grpc_handshake_manager* grpc_handshake_manager_create() {
98
- grpc_handshake_manager* mgr = gpr_malloc(sizeof(grpc_handshake_manager));
99
- memset(mgr, 0, sizeof(*mgr));
102
+ grpc_handshake_manager* mgr = gpr_zalloc(sizeof(grpc_handshake_manager));
100
103
  gpr_mu_init(&mgr->mu);
101
104
  gpr_ref_init(&mgr->refs, 1);
102
105
  return mgr;
103
106
  }
104
107
 
108
+ void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head,
109
+ grpc_handshake_manager* mgr) {
110
+ GPR_ASSERT(mgr->prev == NULL);
111
+ GPR_ASSERT(mgr->next == NULL);
112
+ mgr->next = *head;
113
+ if (*head) {
114
+ (*head)->prev = mgr;
115
+ }
116
+ *head = mgr;
117
+ }
118
+
119
+ void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head,
120
+ grpc_handshake_manager* mgr) {
121
+ if (mgr->next != NULL) {
122
+ mgr->next->prev = mgr->prev;
123
+ }
124
+ if (mgr->prev != NULL) {
125
+ mgr->prev->next = mgr->next;
126
+ } else {
127
+ GPR_ASSERT(*head == mgr);
128
+ *head = mgr->next;
129
+ }
130
+ }
131
+
132
+ void grpc_handshake_manager_pending_list_shutdown_all(
133
+ grpc_exec_ctx* exec_ctx, grpc_handshake_manager* head, grpc_error* why) {
134
+ while (head != NULL) {
135
+ grpc_handshake_manager_shutdown(exec_ctx, head, GRPC_ERROR_REF(why));
136
+ head = head->next;
137
+ }
138
+ GRPC_ERROR_UNREF(why);
139
+ }
140
+
105
141
  static bool is_power_of_2(size_t n) { return (n & (n - 1)) == 0; }
106
142
 
107
143
  void grpc_handshake_manager_add(grpc_handshake_manager* mgr,
@@ -141,14 +177,17 @@ void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx,
141
177
  }
142
178
 
143
179
  void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx,
144
- grpc_handshake_manager* mgr) {
180
+ grpc_handshake_manager* mgr,
181
+ grpc_error* why) {
145
182
  gpr_mu_lock(&mgr->mu);
146
183
  // Shutdown the handshaker that's currently in progress, if any.
147
184
  if (!mgr->shutdown && mgr->index > 0) {
148
185
  mgr->shutdown = true;
149
- grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[mgr->index - 1]);
186
+ grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[mgr->index - 1],
187
+ GRPC_ERROR_REF(why));
150
188
  }
151
189
  gpr_mu_unlock(&mgr->mu);
190
+ GRPC_ERROR_UNREF(why);
152
191
  }
153
192
 
154
193
  // Helper function to call either the next handshaker or the
@@ -197,7 +236,8 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void* arg,
197
236
  static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
198
237
  grpc_handshake_manager* mgr = arg;
199
238
  if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled.
200
- grpc_handshake_manager_shutdown(exec_ctx, mgr);
239
+ grpc_handshake_manager_shutdown(exec_ctx, mgr,
240
+ GRPC_ERROR_CREATE("Handshake timed out"));
201
241
  }
202
242
  grpc_handshake_manager_unref(exec_ctx, mgr);
203
243
  }
@@ -86,7 +86,8 @@ typedef struct {
86
86
 
87
87
  /// Shuts down the handshaker (e.g., to clean up when the operation is
88
88
  /// aborted in the middle).
89
- void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker);
89
+ void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker,
90
+ grpc_error* why);
90
91
 
91
92
  /// Performs handshaking, modifying \a args as needed (e.g., to
92
93
  /// replace \a endpoint with a wrapped endpoint).
@@ -111,7 +112,7 @@ void grpc_handshaker_init(const grpc_handshaker_vtable* vtable,
111
112
  void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx,
112
113
  grpc_handshaker* handshaker);
113
114
  void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
114
- grpc_handshaker* handshaker);
115
+ grpc_handshaker* handshaker, grpc_error* why);
115
116
  void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
116
117
  grpc_handshaker* handshaker,
117
118
  grpc_tcp_server_acceptor* acceptor,
@@ -141,7 +142,8 @@ void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx,
141
142
  /// The caller must still call grpc_handshake_manager_destroy() after
142
143
  /// calling this function.
143
144
  void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx,
144
- grpc_handshake_manager* mgr);
145
+ grpc_handshake_manager* mgr,
146
+ grpc_error* why);
145
147
 
146
148
  /// Invokes handshakers in the order they were added.
147
149
  /// Takes ownership of \a endpoint, and then passes that ownership to
@@ -161,4 +163,20 @@ void grpc_handshake_manager_do_handshake(
161
163
  gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor,
162
164
  grpc_iomgr_cb_func on_handshake_done, void* user_data);
163
165
 
166
+ /// Add \a mgr to the server side list of all pending handshake managers, the
167
+ /// list starts with \a *head.
168
+ // Not thread-safe. Caller needs to synchronize.
169
+ void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head,
170
+ grpc_handshake_manager* mgr);
171
+
172
+ /// Remove \a mgr from the server side list of all pending handshake managers.
173
+ // Not thread-safe. Caller needs to synchronize.
174
+ void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head,
175
+ grpc_handshake_manager* mgr);
176
+
177
+ /// Shutdown all pending handshake managers on the server side.
178
+ // Not thread-safe. Caller needs to synchronize.
179
+ void grpc_handshake_manager_pending_list_shutdown_all(
180
+ grpc_exec_ctx* exec_ctx, grpc_handshake_manager* head, grpc_error* why);
181
+
164
182
  #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */
@@ -38,6 +38,7 @@
38
38
  #include "src/core/lib/profiling/timers.h"
39
39
  #include "src/core/lib/slice/percent_encoding.h"
40
40
  #include "src/core/lib/slice/slice_internal.h"
41
+ #include "src/core/lib/slice/slice_string_helpers.h"
41
42
  #include "src/core/lib/support/string.h"
42
43
  #include "src/core/lib/transport/static_metadata.h"
43
44
  #include "src/core/lib/transport/transport_impl.h"
@@ -88,77 +89,104 @@ typedef struct call_data {
88
89
  } call_data;
89
90
 
90
91
  typedef struct channel_data {
91
- grpc_mdelem *static_scheme;
92
- grpc_mdelem *user_agent;
92
+ grpc_mdelem static_scheme;
93
+ grpc_mdelem user_agent;
93
94
  size_t max_payload_size_for_get;
94
95
  } channel_data;
95
96
 
96
- static grpc_mdelem *client_recv_filter(grpc_exec_ctx *exec_ctx, void *user_data,
97
- grpc_mdelem *md) {
98
- grpc_call_element *elem = user_data;
99
- if (md == GRPC_MDELEM_STATUS_200) {
100
- return NULL;
101
- } else if (md->key == GRPC_MDSTR_STATUS) {
102
- char *message_string;
103
- gpr_asprintf(&message_string, "Received http2 header with status: %s",
104
- grpc_mdstr_as_c_string(md->value));
105
- grpc_slice message = grpc_slice_from_copied_string(message_string);
106
- gpr_free(message_string);
107
- grpc_call_element_send_close_with_message(exec_ctx, elem,
108
- GRPC_STATUS_CANCELLED, &message);
109
- return NULL;
110
- } else if (md->key == GRPC_MDSTR_GRPC_MESSAGE) {
111
- grpc_slice pct_decoded_msg =
112
- grpc_permissive_percent_decode_slice(md->value->slice);
113
- if (grpc_slice_is_equivalent(pct_decoded_msg, md->value->slice)) {
114
- grpc_slice_unref_internal(exec_ctx, pct_decoded_msg);
115
- return md;
97
+ static grpc_error *client_filter_incoming_metadata(grpc_exec_ctx *exec_ctx,
98
+ grpc_call_element *elem,
99
+ grpc_metadata_batch *b) {
100
+ if (b->idx.named.status != NULL) {
101
+ if (grpc_mdelem_eq(b->idx.named.status->md, GRPC_MDELEM_STATUS_200)) {
102
+ grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.status);
116
103
  } else {
117
- return grpc_mdelem_from_metadata_strings(
118
- exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
119
- grpc_mdstr_from_slice(exec_ctx, pct_decoded_msg));
104
+ char *val = grpc_dump_slice(GRPC_MDVALUE(b->idx.named.status->md),
105
+ GPR_DUMP_ASCII);
106
+ char *msg;
107
+ gpr_asprintf(&msg, "Received http2 header with status: %s", val);
108
+ grpc_error *e = grpc_error_set_str(
109
+ grpc_error_set_int(
110
+ grpc_error_set_str(
111
+ GRPC_ERROR_CREATE(
112
+ "Received http2 :status header with non-200 OK status"),
113
+ GRPC_ERROR_STR_VALUE, val),
114
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED),
115
+ GRPC_ERROR_STR_GRPC_MESSAGE, msg);
116
+ gpr_free(val);
117
+ gpr_free(msg);
118
+ return e;
120
119
  }
121
- } else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
122
- return NULL;
123
- } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
124
- const char *value_str = grpc_mdstr_as_c_string(md->value);
125
- if (strncmp(value_str, EXPECTED_CONTENT_TYPE,
126
- EXPECTED_CONTENT_TYPE_LENGTH) == 0 &&
127
- (value_str[EXPECTED_CONTENT_TYPE_LENGTH] == '+' ||
128
- value_str[EXPECTED_CONTENT_TYPE_LENGTH] == ';')) {
129
- /* Although the C implementation doesn't (currently) generate them,
130
- any custom +-suffix is explicitly valid. */
131
- /* TODO(klempner): We should consider preallocating common values such
132
- as +proto or +json, or at least stashing them if we see them. */
133
- /* TODO(klempner): Should we be surfacing this to application code? */
120
+ }
121
+
122
+ if (b->idx.named.grpc_message != NULL) {
123
+ grpc_slice pct_decoded_msg = grpc_permissive_percent_decode_slice(
124
+ GRPC_MDVALUE(b->idx.named.grpc_message->md));
125
+ if (grpc_slice_is_equivalent(pct_decoded_msg,
126
+ GRPC_MDVALUE(b->idx.named.grpc_message->md))) {
127
+ grpc_slice_unref_internal(exec_ctx, pct_decoded_msg);
134
128
  } else {
135
- /* TODO(klempner): We're currently allowing this, but we shouldn't
136
- see it without a proxy so log for now. */
137
- gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str);
129
+ grpc_metadata_batch_set_value(exec_ctx, b->idx.named.grpc_message,
130
+ pct_decoded_msg);
138
131
  }
139
- return NULL;
140
132
  }
141
- return md;
133
+
134
+ if (b->idx.named.content_type != NULL) {
135
+ if (!grpc_mdelem_eq(b->idx.named.content_type->md,
136
+ GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) {
137
+ if (grpc_slice_buf_start_eq(GRPC_MDVALUE(b->idx.named.content_type->md),
138
+ EXPECTED_CONTENT_TYPE,
139
+ EXPECTED_CONTENT_TYPE_LENGTH) &&
140
+ (GRPC_SLICE_START_PTR(GRPC_MDVALUE(
141
+ b->idx.named.content_type->md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
142
+ '+' ||
143
+ GRPC_SLICE_START_PTR(GRPC_MDVALUE(
144
+ b->idx.named.content_type->md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
145
+ ';')) {
146
+ /* Although the C implementation doesn't (currently) generate them,
147
+ any custom +-suffix is explicitly valid. */
148
+ /* TODO(klempner): We should consider preallocating common values such
149
+ as +proto or +json, or at least stashing them if we see them. */
150
+ /* TODO(klempner): Should we be surfacing this to application code? */
151
+ } else {
152
+ /* TODO(klempner): We're currently allowing this, but we shouldn't
153
+ see it without a proxy so log for now. */
154
+ char *val = grpc_dump_slice(GRPC_MDVALUE(b->idx.named.content_type->md),
155
+ GPR_DUMP_ASCII);
156
+ gpr_log(GPR_INFO, "Unexpected content-type '%s'", val);
157
+ gpr_free(val);
158
+ }
159
+ }
160
+ grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.content_type);
161
+ }
162
+
163
+ return GRPC_ERROR_NONE;
142
164
  }
143
165
 
144
166
  static void hc_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
145
167
  void *user_data, grpc_error *error) {
146
168
  grpc_call_element *elem = user_data;
147
169
  call_data *calld = elem->call_data;
148
- grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
149
- client_recv_filter, elem);
150
- grpc_closure_run(exec_ctx, calld->on_done_recv_initial_metadata,
151
- GRPC_ERROR_REF(error));
170
+ if (error == GRPC_ERROR_NONE) {
171
+ error = client_filter_incoming_metadata(exec_ctx, elem,
172
+ calld->recv_initial_metadata);
173
+ } else {
174
+ GRPC_ERROR_REF(error);
175
+ }
176
+ grpc_closure_run(exec_ctx, calld->on_done_recv_initial_metadata, error);
152
177
  }
153
178
 
154
179
  static void hc_on_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
155
180
  void *user_data, grpc_error *error) {
156
181
  grpc_call_element *elem = user_data;
157
182
  call_data *calld = elem->call_data;
158
- grpc_metadata_batch_filter(exec_ctx, calld->recv_trailing_metadata,
159
- client_recv_filter, elem);
160
- grpc_closure_run(exec_ctx, calld->on_done_recv_trailing_metadata,
161
- GRPC_ERROR_REF(error));
183
+ if (error == GRPC_ERROR_NONE) {
184
+ error = client_filter_incoming_metadata(exec_ctx, elem,
185
+ calld->recv_trailing_metadata);
186
+ } else {
187
+ GRPC_ERROR_REF(error);
188
+ }
189
+ grpc_closure_run(exec_ctx, calld->on_done_recv_trailing_metadata, error);
162
190
  }
163
191
 
164
192
  static void hc_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
@@ -179,15 +207,12 @@ static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
179
207
  calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
180
208
  }
181
209
 
182
- static grpc_mdelem *client_strip_filter(grpc_exec_ctx *exec_ctx,
183
- void *user_data, grpc_mdelem *md) {
184
- /* eat the things we'd like to set ourselves */
185
- if (md->key == GRPC_MDSTR_METHOD) return NULL;
186
- if (md->key == GRPC_MDSTR_SCHEME) return NULL;
187
- if (md->key == GRPC_MDSTR_TE) return NULL;
188
- if (md->key == GRPC_MDSTR_CONTENT_TYPE) return NULL;
189
- if (md->key == GRPC_MDSTR_USER_AGENT) return NULL;
190
- return md;
210
+ static void remove_if_present(grpc_exec_ctx *exec_ctx,
211
+ grpc_metadata_batch *batch,
212
+ grpc_metadata_batch_callouts_index idx) {
213
+ if (batch->idx.array[idx] != NULL) {
214
+ grpc_metadata_batch_remove(exec_ctx, batch, batch->idx.array[idx]);
215
+ }
191
216
  }
192
217
 
193
218
  static void continue_send_message(grpc_exec_ctx *exec_ctx,
@@ -226,18 +251,20 @@ static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
226
251
  }
227
252
  }
228
253
 
229
- static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
230
- grpc_transport_stream_op *op) {
254
+ static grpc_error *hc_mutate_op(grpc_exec_ctx *exec_ctx,
255
+ grpc_call_element *elem,
256
+ grpc_transport_stream_op *op) {
231
257
  /* grab pointers to our data from the call element */
232
258
  call_data *calld = elem->call_data;
233
259
  channel_data *channeld = elem->channel_data;
260
+ grpc_error *error;
234
261
 
235
262
  if (op->send_initial_metadata != NULL) {
236
263
  /* Decide which HTTP VERB to use. We use GET if the request is marked
237
264
  cacheable, and the operation contains both initial metadata and send
238
265
  message, and the payload is below the size threshold, and all the data
239
266
  for this request is immediately available. */
240
- grpc_mdelem *method = GRPC_MDELEM_METHOD_POST;
267
+ grpc_mdelem method = GRPC_MDELEM_METHOD_POST;
241
268
  if ((op->send_initial_metadata_flags &
242
269
  GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) &&
243
270
  op->send_message != NULL &&
@@ -254,7 +281,7 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
254
281
  }
255
282
 
256
283
  /* Attempt to read the data from send_message and create a header field. */
257
- if (method == GRPC_MDELEM_METHOD_GET) {
284
+ if (grpc_mdelem_eq(method, GRPC_MDELEM_METHOD_GET)) {
258
285
  /* allocate memory to hold the entire payload */
259
286
  calld->payload_bytes = gpr_malloc(op->send_message->length);
260
287
 
@@ -267,12 +294,14 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
267
294
  if (calld->send_message_blocked == false) {
268
295
  /* when all the send_message data is available, then create a MDELEM and
269
296
  append to headers */
270
- grpc_mdelem *payload_bin = grpc_mdelem_from_metadata_strings(
297
+ grpc_mdelem payload_bin = grpc_mdelem_from_slices(
271
298
  exec_ctx, GRPC_MDSTR_GRPC_PAYLOAD_BIN,
272
- grpc_mdstr_from_buffer(calld->payload_bytes,
273
- op->send_message->length));
274
- grpc_metadata_batch_add_tail(op->send_initial_metadata,
275
- &calld->payload_bin, payload_bin);
299
+ grpc_slice_from_copied_buffer((const char *)calld->payload_bytes,
300
+ op->send_message->length));
301
+ error =
302
+ grpc_metadata_batch_add_tail(exec_ctx, op->send_initial_metadata,
303
+ &calld->payload_bin, payload_bin);
304
+ if (error != GRPC_ERROR_NONE) return error;
276
305
  calld->on_complete = op->on_complete;
277
306
  op->on_complete = &calld->hc_on_complete;
278
307
  op->send_message = NULL;
@@ -285,21 +314,35 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
285
314
  }
286
315
  }
287
316
 
288
- grpc_metadata_batch_filter(exec_ctx, op->send_initial_metadata,
289
- client_strip_filter, elem);
317
+ remove_if_present(exec_ctx, op->send_initial_metadata, GRPC_BATCH_METHOD);
318
+ remove_if_present(exec_ctx, op->send_initial_metadata, GRPC_BATCH_SCHEME);
319
+ remove_if_present(exec_ctx, op->send_initial_metadata, GRPC_BATCH_TE);
320
+ remove_if_present(exec_ctx, op->send_initial_metadata,
321
+ GRPC_BATCH_CONTENT_TYPE);
322
+ remove_if_present(exec_ctx, op->send_initial_metadata,
323
+ GRPC_BATCH_USER_AGENT);
324
+
290
325
  /* Send : prefixed headers, which have to be before any application
291
326
  layer headers. */
292
- grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
293
- method);
294
- grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme,
295
- channeld->static_scheme);
296
- grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers,
297
- GRPC_MDELEM_TE_TRAILERS);
298
- grpc_metadata_batch_add_tail(
299
- op->send_initial_metadata, &calld->content_type,
327
+ error = grpc_metadata_batch_add_head(exec_ctx, op->send_initial_metadata,
328
+ &calld->method, method);
329
+ if (error != GRPC_ERROR_NONE) return error;
330
+ error =
331
+ grpc_metadata_batch_add_head(exec_ctx, op->send_initial_metadata,
332
+ &calld->scheme, channeld->static_scheme);
333
+ if (error != GRPC_ERROR_NONE) return error;
334
+ error = grpc_metadata_batch_add_tail(exec_ctx, op->send_initial_metadata,
335
+ &calld->te_trailers,
336
+ GRPC_MDELEM_TE_TRAILERS);
337
+ if (error != GRPC_ERROR_NONE) return error;
338
+ error = grpc_metadata_batch_add_tail(
339
+ exec_ctx, op->send_initial_metadata, &calld->content_type,
300
340
  GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC);
301
- grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->user_agent,
302
- GRPC_MDELEM_REF(channeld->user_agent));
341
+ if (error != GRPC_ERROR_NONE) return error;
342
+ error = grpc_metadata_batch_add_tail(exec_ctx, op->send_initial_metadata,
343
+ &calld->user_agent,
344
+ GRPC_MDELEM_REF(channeld->user_agent));
345
+ if (error != GRPC_ERROR_NONE) return error;
303
346
  }
304
347
 
305
348
  if (op->recv_initial_metadata != NULL) {
@@ -315,6 +358,8 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
315
358
  calld->on_done_recv_trailing_metadata = op->on_complete;
316
359
  op->on_complete = &calld->hc_on_recv_trailing_metadata;
317
360
  }
361
+
362
+ return GRPC_ERROR_NONE;
318
363
  }
319
364
 
320
365
  static void hc_start_transport_op(grpc_exec_ctx *exec_ctx,
@@ -322,21 +367,26 @@ static void hc_start_transport_op(grpc_exec_ctx *exec_ctx,
322
367
  grpc_transport_stream_op *op) {
323
368
  GPR_TIMER_BEGIN("hc_start_transport_op", 0);
324
369
  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
325
- hc_mutate_op(exec_ctx, elem, op);
326
- GPR_TIMER_END("hc_start_transport_op", 0);
327
- call_data *calld = elem->call_data;
328
- if (op->send_message != NULL && calld->send_message_blocked) {
329
- /* Don't forward the op. send_message contains slices that aren't ready
330
- yet. The call will be forwarded by the op_complete of slice read call. */
370
+ grpc_error *error = hc_mutate_op(exec_ctx, elem, op);
371
+ if (error != GRPC_ERROR_NONE) {
372
+ grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
331
373
  } else {
332
- grpc_call_next_op(exec_ctx, elem, op);
374
+ call_data *calld = elem->call_data;
375
+ if (op->send_message != NULL && calld->send_message_blocked) {
376
+ /* Don't forward the op. send_message contains slices that aren't ready
377
+ yet. The call will be forwarded by the op_complete of slice read call.
378
+ */
379
+ } else {
380
+ grpc_call_next_op(exec_ctx, elem, op);
381
+ }
333
382
  }
383
+ GPR_TIMER_END("hc_start_transport_op", 0);
334
384
  }
335
385
 
336
386
  /* Constructor for call_data */
337
387
  static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
338
388
  grpc_call_element *elem,
339
- grpc_call_element_args *args) {
389
+ const grpc_call_element_args *args) {
340
390
  call_data *calld = elem->call_data;
341
391
  calld->on_done_recv_initial_metadata = NULL;
342
392
  calld->on_done_recv_trailing_metadata = NULL;
@@ -367,18 +417,18 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
367
417
  grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
368
418
  }
369
419
 
370
- static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
420
+ static grpc_mdelem scheme_from_args(const grpc_channel_args *args) {
371
421
  unsigned i;
372
422
  size_t j;
373
- grpc_mdelem *valid_schemes[] = {GRPC_MDELEM_SCHEME_HTTP,
374
- GRPC_MDELEM_SCHEME_HTTPS};
423
+ grpc_mdelem valid_schemes[] = {GRPC_MDELEM_SCHEME_HTTP,
424
+ GRPC_MDELEM_SCHEME_HTTPS};
375
425
  if (args != NULL) {
376
426
  for (i = 0; i < args->num_args; ++i) {
377
427
  if (args->args[i].type == GRPC_ARG_STRING &&
378
428
  strcmp(args->args[i].key, GRPC_ARG_HTTP2_SCHEME) == 0) {
379
429
  for (j = 0; j < GPR_ARRAY_SIZE(valid_schemes); j++) {
380
- if (0 == strcmp(grpc_mdstr_as_c_string(valid_schemes[j]->value),
381
- args->args[i].value.string)) {
430
+ if (0 == grpc_slice_str_cmp(GRPC_MDVALUE(valid_schemes[j]),
431
+ args->args[i].value.string)) {
382
432
  return valid_schemes[j];
383
433
  }
384
434
  }
@@ -404,13 +454,13 @@ static size_t max_payload_size_from_args(const grpc_channel_args *args) {
404
454
  return kMaxPayloadSizeForGet;
405
455
  }
406
456
 
407
- static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
408
- const char *transport_name) {
457
+ static grpc_slice user_agent_from_args(const grpc_channel_args *args,
458
+ const char *transport_name) {
409
459
  gpr_strvec v;
410
460
  size_t i;
411
461
  int is_first = 1;
412
462
  char *tmp;
413
- grpc_mdstr *result;
463
+ grpc_slice result;
414
464
 
415
465
  gpr_strvec_init(&v);
416
466
 
@@ -448,7 +498,7 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
448
498
 
449
499
  tmp = gpr_strvec_flatten(&v, NULL);
450
500
  gpr_strvec_destroy(&v);
451
- result = grpc_mdstr_from_string(tmp);
501
+ result = grpc_slice_intern(grpc_slice_from_static_string(tmp));
452
502
  gpr_free(tmp);
453
503
 
454
504
  return result;
@@ -464,7 +514,7 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
464
514
  chand->static_scheme = scheme_from_args(args->channel_args);
465
515
  chand->max_payload_size_for_get =
466
516
  max_payload_size_from_args(args->channel_args);
467
- chand->user_agent = grpc_mdelem_from_metadata_strings(
517
+ chand->user_agent = grpc_mdelem_from_slices(
468
518
  exec_ctx, GRPC_MDSTR_USER_AGENT,
469
519
  user_agent_from_args(args->channel_args,
470
520
  args->optional_transport->vtable->name));