grpc 0.15.0 → 1.0.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +127 -159
  3. data/etc/roots.pem +784 -509
  4. data/include/grpc/grpc_posix.h +8 -0
  5. data/include/grpc/impl/codegen/byte_buffer.h +5 -4
  6. data/include/grpc/impl/codegen/grpc_types.h +2 -0
  7. data/include/grpc/impl/codegen/port_platform.h +2 -1
  8. data/include/grpc/module.modulemap +15 -0
  9. data/src/core/ext/census/grpc_filter.c +3 -0
  10. data/src/core/ext/client_config/channel_connectivity.c +4 -3
  11. data/src/core/ext/client_config/client_channel.c +6 -0
  12. data/src/core/ext/client_config/subchannel.c +2 -0
  13. data/src/core/ext/client_config/subchannel_call_holder.c +2 -5
  14. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +2 -1
  15. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +2 -1
  16. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +171 -104
  17. data/src/core/ext/transport/chttp2/transport/internal.h +5 -3
  18. data/src/core/ext/transport/chttp2/transport/parsing.c +4 -3
  19. data/src/core/ext/transport/chttp2/transport/status_conversion.c +8 -2
  20. data/src/core/ext/transport/chttp2/transport/status_conversion.h +1 -1
  21. data/src/core/lib/channel/channel_stack.c +12 -1
  22. data/src/core/lib/channel/channel_stack.h +5 -0
  23. data/src/core/lib/channel/http_client_filter.c +7 -1
  24. data/src/core/lib/debug/trace.c +6 -2
  25. data/src/core/lib/iomgr/error.c +62 -19
  26. data/src/core/lib/iomgr/error.h +10 -6
  27. data/src/core/lib/iomgr/ev_epoll_linux.c +1872 -0
  28. data/src/core/lib/{surface/surface_trace.h → iomgr/ev_epoll_linux.h} +11 -12
  29. data/src/core/lib/iomgr/ev_posix.c +9 -6
  30. data/src/core/lib/iomgr/ev_posix.h +3 -0
  31. data/src/core/lib/iomgr/network_status_tracker.c +121 -0
  32. data/{include/grpc/grpc_zookeeper.h → src/core/lib/iomgr/network_status_tracker.h} +8 -26
  33. data/src/core/lib/iomgr/socket_utils_common_posix.c +22 -0
  34. data/src/core/lib/iomgr/socket_utils_posix.h +3 -0
  35. data/src/core/lib/iomgr/tcp_posix.c +6 -2
  36. data/src/core/lib/iomgr/tcp_server.h +3 -0
  37. data/src/core/lib/iomgr/tcp_server_posix.c +114 -16
  38. data/src/core/lib/iomgr/tcp_server_windows.c +1 -0
  39. data/src/core/lib/iomgr/tcp_windows.c +5 -0
  40. data/src/core/lib/iomgr/udp_server.c +28 -16
  41. data/src/core/lib/iomgr/wakeup_fd_eventfd.c +4 -2
  42. data/src/core/lib/profiling/basic_timers.c +4 -4
  43. data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -3
  44. data/src/core/lib/security/credentials/credentials.c +1 -1
  45. data/src/core/lib/security/credentials/credentials.h +4 -5
  46. data/src/core/lib/security/credentials/fake/fake_credentials.c +2 -2
  47. data/src/core/lib/security/credentials/iam/iam_credentials.c +1 -1
  48. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +7 -6
  49. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +6 -4
  50. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +4 -3
  51. data/src/core/lib/security/transport/client_auth_filter.c +10 -7
  52. data/src/core/lib/surface/byte_buffer_reader.c +6 -4
  53. data/src/core/lib/surface/call.c +64 -51
  54. data/src/core/lib/surface/call.h +0 -1
  55. data/src/core/lib/surface/channel.c +10 -8
  56. data/src/core/lib/surface/completion_queue.c +26 -12
  57. data/src/core/lib/surface/completion_queue.h +4 -0
  58. data/src/core/lib/surface/init.c +6 -1
  59. data/src/core/lib/surface/version.c +1 -1
  60. data/src/core/lib/transport/transport.c +62 -29
  61. data/src/core/lib/transport/transport.h +8 -5
  62. data/src/core/lib/transport/transport_op_string.c +14 -3
  63. data/src/ruby/ext/grpc/rb_byte_buffer.c +4 -1
  64. data/src/ruby/ext/grpc/rb_call.c +87 -54
  65. data/src/ruby/ext/grpc/rb_call.h +1 -1
  66. data/src/ruby/ext/grpc/rb_call_credentials.c +1 -30
  67. data/src/ruby/ext/grpc/rb_channel.c +25 -50
  68. data/src/ruby/ext/grpc/rb_channel_credentials.c +1 -31
  69. data/src/ruby/ext/grpc/rb_completion_queue.c +15 -134
  70. data/src/ruby/ext/grpc/rb_completion_queue.h +3 -7
  71. data/src/ruby/ext/grpc/rb_grpc.c +2 -4
  72. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  73. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +4 -1
  74. data/src/ruby/ext/grpc/rb_server.c +81 -133
  75. data/src/ruby/ext/grpc/rb_server_credentials.c +4 -33
  76. data/src/ruby/lib/grpc/generic/active_call.rb +40 -55
  77. data/src/ruby/lib/grpc/generic/bidi_call.rb +21 -23
  78. data/src/ruby/lib/grpc/generic/client_stub.rb +20 -15
  79. data/src/ruby/lib/grpc/generic/rpc_server.rb +15 -37
  80. data/src/ruby/lib/grpc/generic/service.rb +1 -1
  81. data/src/ruby/lib/grpc/version.rb +1 -1
  82. data/src/ruby/pb/test/client.rb +25 -7
  83. data/src/ruby/pb/test/server.rb +7 -5
  84. data/src/ruby/spec/call_spec.rb +1 -2
  85. data/src/ruby/spec/channel_spec.rb +2 -3
  86. data/src/ruby/spec/client_server_spec.rb +74 -59
  87. data/src/ruby/spec/generic/active_call_spec.rb +66 -86
  88. data/src/ruby/spec/generic/client_stub_spec.rb +27 -48
  89. data/src/ruby/spec/generic/rpc_server_spec.rb +4 -34
  90. data/src/ruby/spec/pb/health/checker_spec.rb +0 -2
  91. data/src/ruby/spec/server_spec.rb +20 -24
  92. metadata +9 -8
  93. data/src/ruby/spec/completion_queue_spec.rb +0 -42
@@ -103,6 +103,7 @@ struct grpc_tcp_server {
103
103
  /* Public function. Allocates the proper data structures to hold a
104
104
  grpc_tcp_server. */
105
105
  grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,
106
+ const grpc_channel_args *args,
106
107
  grpc_tcp_server **server) {
107
108
  grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
108
109
  gpr_ref_init(&s->refs, 1);
@@ -37,6 +37,7 @@
37
37
 
38
38
  #include <limits.h>
39
39
 
40
+ #include "src/core/lib/iomgr/network_status_tracker.h"
40
41
  #include "src/core/lib/iomgr/sockaddr_windows.h"
41
42
 
42
43
  #include <grpc/support/alloc.h>
@@ -378,6 +379,7 @@ static void win_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
378
379
  }
379
380
 
380
381
  static void win_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
382
+ grpc_network_status_unregister_endpoint(ep);
381
383
  grpc_tcp *tcp = (grpc_tcp *)ep;
382
384
  TCP_UNREF(tcp, "destroy");
383
385
  }
@@ -401,6 +403,9 @@ grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket, char *peer_string) {
401
403
  grpc_closure_init(&tcp->on_read, on_read, tcp);
402
404
  grpc_closure_init(&tcp->on_write, on_write, tcp);
403
405
  tcp->peer_string = gpr_strdup(peer_string);
406
+ /* Tell network status tracking code about the new endpoint */
407
+ grpc_network_status_register_endpoint(&tcp->base);
408
+
404
409
  return &tcp->base;
405
410
  }
406
411
 
@@ -60,6 +60,7 @@
60
60
  #include <grpc/support/string_util.h>
61
61
  #include <grpc/support/sync.h>
62
62
  #include <grpc/support/time.h>
63
+ #include "src/core/lib/iomgr/error.h"
63
64
  #include "src/core/lib/iomgr/ev_posix.h"
64
65
  #include "src/core/lib/iomgr/resolve_address.h"
65
66
  #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -128,7 +129,7 @@ grpc_udp_server *grpc_udp_server_create(void) {
128
129
  }
129
130
 
130
131
  static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
131
- grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1, NULL);
132
+ grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
132
133
 
133
134
  gpr_mu_destroy(&s->mu);
134
135
  gpr_cv_destroy(&s->cv);
@@ -138,7 +139,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
138
139
  }
139
140
 
140
141
  static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server,
141
- bool success) {
142
+ grpc_error *error) {
142
143
  grpc_udp_server *s = server;
143
144
  gpr_mu_lock(&s->mu);
144
145
  s->destroyed_ports++;
@@ -217,14 +218,23 @@ static int prepare_socket(int fd, const struct sockaddr *addr,
217
218
  goto error;
218
219
  }
219
220
 
220
- if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1)) {
221
- gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
222
- strerror(errno));
221
+ if (grpc_set_socket_nonblocking(fd, 1) != GRPC_ERROR_NONE) {
222
+ gpr_log(GPR_ERROR, "Unable to set nonblocking %d: %s", fd, strerror(errno));
223
+ goto error;
224
+ }
225
+ if (grpc_set_socket_cloexec(fd, 1) != GRPC_ERROR_NONE) {
226
+ gpr_log(GPR_ERROR, "Unable to set cloexec %d: %s", fd, strerror(errno));
227
+ goto error;
223
228
  }
224
229
 
225
- if (grpc_set_socket_ip_pktinfo_if_possible(fd) &&
226
- addr->sa_family == AF_INET6) {
227
- grpc_set_socket_ipv6_recvpktinfo_if_possible(fd);
230
+ if (grpc_set_socket_ip_pktinfo_if_possible(fd) != GRPC_ERROR_NONE) {
231
+ gpr_log(GPR_ERROR, "Unable to set ip_pktinfo.");
232
+ goto error;
233
+ } else if (addr->sa_family == AF_INET6) {
234
+ if (grpc_set_socket_ipv6_recvpktinfo_if_possible(fd) != GRPC_ERROR_NONE) {
235
+ gpr_log(GPR_ERROR, "Unable to set ipv6_recvpktinfo.");
236
+ goto error;
237
+ }
228
238
  }
229
239
 
230
240
  GPR_ASSERT(addr_len < ~(socklen_t)0);
@@ -241,15 +251,15 @@ static int prepare_socket(int fd, const struct sockaddr *addr,
241
251
  goto error;
242
252
  }
243
253
 
244
- if (!grpc_set_socket_sndbuf(fd, buffer_size_bytes)) {
254
+ if (grpc_set_socket_sndbuf(fd, buffer_size_bytes) != GRPC_ERROR_NONE) {
245
255
  gpr_log(GPR_ERROR, "Failed to set send buffer size to %d bytes",
246
- buf_size_bytes);
256
+ buffer_size_bytes);
247
257
  goto error;
248
258
  }
249
259
 
250
- if (!grpc_set_socket_rcvbuf(fd, buffer_size_bytes)) {
260
+ if (grpc_set_socket_rcvbuf(fd, buffer_size_bytes) != GRPC_ERROR_NONE) {
251
261
  gpr_log(GPR_ERROR, "Failed to set receive buffer size to %d bytes",
252
- buf_size_bytes);
262
+ buffer_size_bytes);
253
263
  goto error;
254
264
  }
255
265
 
@@ -263,10 +273,10 @@ error:
263
273
  }
264
274
 
265
275
  /* event manager callback when reads are ready */
266
- static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
276
+ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
267
277
  server_port *sp = arg;
268
278
 
269
- if (!success) {
279
+ if (error != GRPC_ERROR_NONE) {
270
280
  gpr_mu_lock(&sp->server->mu);
271
281
  if (0 == --sp->server->active_ports) {
272
282
  gpr_mu_unlock(&sp->server->mu);
@@ -369,7 +379,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr,
369
379
  /* Try listening on IPv6 first. */
370
380
  addr = (struct sockaddr *)&wild6;
371
381
  addr_len = sizeof(wild6);
372
- fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode);
382
+ // TODO(rjshade): Test and propagate the returned grpc_error*:
383
+ grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd);
373
384
  allocated_port1 =
374
385
  add_socket_to_server(s, fd, addr, addr_len, read_cb, orphan_cb);
375
386
  if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
@@ -384,7 +395,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr,
384
395
  addr_len = sizeof(wild4);
385
396
  }
386
397
 
387
- fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode);
398
+ // TODO(rjshade): Test and propagate the returned grpc_error*:
399
+ grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd);
388
400
  if (fd < 0) {
389
401
  gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
390
402
  }
@@ -84,8 +84,10 @@ static void eventfd_destroy(grpc_wakeup_fd* fd_info) {
84
84
  }
85
85
 
86
86
  static int eventfd_check_availability(void) {
87
- /* TODO(klempner): Actually check if eventfd is available */
88
- return 1;
87
+ const int efd = eventfd(0, 0);
88
+ const int is_available = efd >= 0;
89
+ if (is_available) close(efd);
90
+ return is_available;
89
91
  }
90
92
 
91
93
  const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable = {
@@ -141,11 +141,11 @@ static void write_log(gpr_timer_log *log) {
141
141
  entry->tm = gpr_time_0(entry->tm.clock_type);
142
142
  }
143
143
  fprintf(output_file,
144
- "{\"t\": %"PRId64".%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": "
144
+ "{\"t\": %" PRId64
145
+ ".%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": "
145
146
  "\"%s\", \"file\": \"%s\", \"line\": %d, \"imp\": %d}\n",
146
- entry->tm.tv_sec, entry->tm.tv_nsec, entry->thd,
147
- entry->type, entry->tagstr, entry->file, entry->line,
148
- entry->important);
147
+ entry->tm.tv_sec, entry->tm.tv_nsec, entry->thd, entry->type,
148
+ entry->tagstr, entry->file, entry->line, entry->important);
149
149
  }
150
150
  }
151
151
 
@@ -72,11 +72,12 @@ static void composite_call_md_context_destroy(
72
72
  static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
73
73
  grpc_credentials_md *md_elems,
74
74
  size_t num_md,
75
- grpc_credentials_status status) {
75
+ grpc_credentials_status status,
76
+ const char *error_details) {
76
77
  grpc_composite_call_credentials_metadata_context *ctx =
77
78
  (grpc_composite_call_credentials_metadata_context *)user_data;
78
79
  if (status != GRPC_CREDENTIALS_OK) {
79
- ctx->cb(exec_ctx, ctx->user_data, NULL, 0, status);
80
+ ctx->cb(exec_ctx, ctx->user_data, NULL, 0, status, error_details);
80
81
  return;
81
82
  }
82
83
 
@@ -101,7 +102,7 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
101
102
 
102
103
  /* We're done!. */
103
104
  ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries,
104
- ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK);
105
+ ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK, NULL);
105
106
  composite_call_md_context_destroy(ctx);
106
107
  }
107
108
 
@@ -117,7 +117,7 @@ void grpc_call_credentials_get_request_metadata(
117
117
  grpc_credentials_metadata_cb cb, void *user_data) {
118
118
  if (creds == NULL || creds->vtable->get_request_metadata == NULL) {
119
119
  if (cb != NULL) {
120
- cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
120
+ cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK, NULL);
121
121
  }
122
122
  return;
123
123
  }
@@ -156,11 +156,10 @@ void grpc_credentials_md_store_unref(grpc_credentials_md_store *store);
156
156
 
157
157
  /* --- grpc_call_credentials. --- */
158
158
 
159
- typedef void (*grpc_credentials_metadata_cb)(grpc_exec_ctx *exec_ctx,
160
- void *user_data,
161
- grpc_credentials_md *md_elems,
162
- size_t num_md,
163
- grpc_credentials_status status);
159
+ /* error_details must be NULL if status is GRPC_CREDENTIALS_OK. */
160
+ typedef void (*grpc_credentials_metadata_cb)(
161
+ grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
162
+ size_t num_md, grpc_credentials_status status, const char *error_details);
164
163
 
165
164
  typedef struct {
166
165
  void (*destruct)(grpc_call_credentials *c);
@@ -100,7 +100,7 @@ static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
100
100
  (grpc_credentials_metadata_request *)user_data;
101
101
  grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds;
102
102
  r->cb(exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries,
103
- GRPC_CREDENTIALS_OK);
103
+ GRPC_CREDENTIALS_OK, NULL);
104
104
  grpc_credentials_metadata_request_destroy(r);
105
105
  }
106
106
 
@@ -117,7 +117,7 @@ static void md_only_test_get_request_metadata(
117
117
  grpc_closure_create(on_simulated_token_fetch_done, cb_arg),
118
118
  GRPC_ERROR_NONE);
119
119
  } else {
120
- cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK);
120
+ cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK, NULL);
121
121
  }
122
122
  }
123
123
 
@@ -55,7 +55,7 @@ static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
55
55
  void *user_data) {
56
56
  grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
57
57
  cb(exec_ctx, user_data, c->iam_md->entries, c->iam_md->num_entries,
58
- GRPC_CREDENTIALS_OK);
58
+ GRPC_CREDENTIALS_OK, NULL);
59
59
  }
60
60
 
61
61
  static grpc_call_credentials_vtable iam_vtable = {iam_destruct,
@@ -113,10 +113,11 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
113
113
 
114
114
  if (jwt_md != NULL) {
115
115
  cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries,
116
- GRPC_CREDENTIALS_OK);
116
+ GRPC_CREDENTIALS_OK, NULL);
117
117
  grpc_credentials_md_store_unref(jwt_md);
118
118
  } else {
119
- cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR);
119
+ cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR,
120
+ "Could not generate JWT.");
120
121
  }
121
122
  }
122
123
 
@@ -149,11 +150,11 @@ grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
149
150
  "grpc_service_account_jwt_access_credentials_create("
150
151
  "json_key=%s, "
151
152
  "token_lifetime="
152
- "gpr_timespec { tv_sec: %"PRId64", tv_nsec: %d, clock_type: %d }, "
153
+ "gpr_timespec { tv_sec: %" PRId64
154
+ ", tv_nsec: %d, clock_type: %d }, "
153
155
  "reserved=%p)",
154
- 5,
155
- (json_key, token_lifetime.tv_sec, token_lifetime.tv_nsec,
156
- (int)token_lifetime.clock_type, reserved));
156
+ 5, (json_key, token_lifetime.tv_sec, token_lifetime.tv_nsec,
157
+ (int)token_lifetime.clock_type, reserved));
157
158
  GPR_ASSERT(reserved == NULL);
158
159
  return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
159
160
  grpc_auth_json_key_create_from_string(json_key), token_lifetime);
@@ -235,10 +235,11 @@ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx,
235
235
  c->token_expiration =
236
236
  gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime);
237
237
  r->cb(exec_ctx, r->user_data, c->access_token_md->entries,
238
- c->access_token_md->num_entries, status);
238
+ c->access_token_md->num_entries, GRPC_CREDENTIALS_OK, NULL);
239
239
  } else {
240
240
  c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
241
- r->cb(exec_ctx, r->user_data, NULL, 0, status);
241
+ r->cb(exec_ctx, r->user_data, NULL, 0, status,
242
+ "Error occured when fetching oauth2 token.");
242
243
  }
243
244
  gpr_mu_unlock(&c->mu);
244
245
  grpc_credentials_metadata_request_destroy(r);
@@ -266,7 +267,7 @@ static void oauth2_token_fetcher_get_request_metadata(
266
267
  }
267
268
  if (cached_access_token_md != NULL) {
268
269
  cb(exec_ctx, user_data, cached_access_token_md->entries,
269
- cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK);
270
+ cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK, NULL);
270
271
  grpc_credentials_md_store_unref(cached_access_token_md);
271
272
  } else {
272
273
  c->fetch_func(
@@ -404,7 +405,8 @@ static void access_token_get_request_metadata(
404
405
  grpc_polling_entity *pollent, grpc_auth_metadata_context context,
405
406
  grpc_credentials_metadata_cb cb, void *user_data) {
406
407
  grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
407
- cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
408
+ cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK,
409
+ NULL);
408
410
  }
409
411
 
410
412
  static grpc_call_credentials_vtable access_token_vtable = {
@@ -67,7 +67,8 @@ static void plugin_md_request_metadata_ready(void *request,
67
67
  gpr_log(GPR_ERROR, "Getting metadata from plugin failed with error: %s",
68
68
  error_details);
69
69
  }
70
- r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR);
70
+ r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR,
71
+ error_details);
71
72
  } else {
72
73
  size_t i;
73
74
  grpc_credentials_md *md_array = NULL;
@@ -79,7 +80,7 @@ static void plugin_md_request_metadata_ready(void *request,
79
80
  gpr_slice_from_copied_buffer(md[i].value, md[i].value_length);
80
81
  }
81
82
  }
82
- r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK);
83
+ r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK, NULL);
83
84
  if (md_array != NULL) {
84
85
  for (i = 0; i < num_md; i++) {
85
86
  gpr_slice_unref(md_array[i].key);
@@ -107,7 +108,7 @@ static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
107
108
  c->plugin.get_metadata(c->plugin.state, context,
108
109
  plugin_md_request_metadata_ready, request);
109
110
  } else {
110
- cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
111
+ cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK, NULL);
111
112
  }
112
113
  }
113
114
 
@@ -91,14 +91,16 @@ static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
91
91
  grpc_status_code status, const char *error_msg) {
92
92
  call_data *calld = elem->call_data;
93
93
  gpr_log(GPR_ERROR, "Client side authentication failure: %s", error_msg);
94
- grpc_transport_stream_op_add_cancellation(&calld->op, status);
94
+ gpr_slice error_slice = gpr_slice_from_copied_string(error_msg);
95
+ grpc_transport_stream_op_add_close(&calld->op, status, &error_slice);
95
96
  grpc_call_next_op(exec_ctx, elem, &calld->op);
96
97
  }
97
98
 
98
99
  static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
99
100
  grpc_credentials_md *md_elems,
100
101
  size_t num_md,
101
- grpc_credentials_status status) {
102
+ grpc_credentials_status status,
103
+ const char *error_details) {
102
104
  grpc_call_element *elem = (grpc_call_element *)user_data;
103
105
  call_data *calld = elem->call_data;
104
106
  grpc_transport_stream_op *op = &calld->op;
@@ -107,7 +109,9 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
107
109
  reset_auth_metadata_context(&calld->auth_md_context);
108
110
  if (status != GRPC_CREDENTIALS_OK) {
109
111
  bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
110
- "Credentials failed to get metadata.");
112
+ (error_details != NULL && strlen(error_details) > 0)
113
+ ? error_details
114
+ : "Credentials failed to get metadata.");
111
115
  return;
112
116
  }
113
117
  GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
@@ -172,7 +176,7 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
172
176
  calld->creds = grpc_composite_call_credentials_create(channel_call_creds,
173
177
  ctx->creds, NULL);
174
178
  if (calld->creds == NULL) {
175
- bubble_up_error(exec_ctx, elem, GRPC_STATUS_INTERNAL,
179
+ bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
176
180
  "Incompatible credentials set on channel and call.");
177
181
  return;
178
182
  }
@@ -201,7 +205,7 @@ static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
201
205
  char *error_msg;
202
206
  gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
203
207
  grpc_mdstr_as_c_string(calld->host));
204
- bubble_up_error(exec_ctx, elem, GRPC_STATUS_INTERNAL, error_msg);
208
+ bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED, error_msg);
205
209
  gpr_free(error_msg);
206
210
  }
207
211
  }
@@ -220,8 +224,7 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
220
224
  grpc_linked_mdelem *l;
221
225
  grpc_client_security_context *sec_ctx = NULL;
222
226
 
223
- if (calld->security_context_set == 0 &&
224
- op->cancel_with_status == GRPC_STATUS_OK) {
227
+ if (calld->security_context_set == 0 && op->cancel_error == GRPC_ERROR_NONE) {
225
228
  calld->security_context_set = 1;
226
229
  GPR_ASSERT(op->context);
227
230
  if (op->context[GRPC_CONTEXT_SECURITY].value == NULL) {
@@ -54,8 +54,8 @@ static int is_compressed(grpc_byte_buffer *buffer) {
54
54
  return 1 /* GPR_TRUE */;
55
55
  }
56
56
 
57
- void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
58
- grpc_byte_buffer *buffer) {
57
+ int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
58
+ grpc_byte_buffer *buffer) {
59
59
  gpr_slice_buffer decompressed_slices_buffer;
60
60
  reader->buffer_in = buffer;
61
61
  switch (reader->buffer_in->type) {
@@ -67,9 +67,10 @@ void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
67
67
  &decompressed_slices_buffer) == 0) {
68
68
  gpr_log(GPR_ERROR,
69
69
  "Unexpected error decompressing data for algorithm with enum "
70
- "value '%d'. Reading data as if it were uncompressed.",
70
+ "value '%d'.",
71
71
  reader->buffer_in->data.raw.compression);
72
- reader->buffer_out = reader->buffer_in;
72
+ memset(reader, 0, sizeof(*reader));
73
+ return 0;
73
74
  } else { /* all fine */
74
75
  reader->buffer_out =
75
76
  grpc_raw_byte_buffer_create(decompressed_slices_buffer.slices,
@@ -82,6 +83,7 @@ void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
82
83
  reader->current.index = 0;
83
84
  break;
84
85
  }
86
+ return 1;
85
87
  }
86
88
 
87
89
  void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) {
@@ -259,7 +259,8 @@ grpc_call *grpc_call_create(
259
259
  call->metadata_batch[i][j].deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
260
260
  }
261
261
  }
262
- call->send_deadline = send_deadline;
262
+ call->send_deadline =
263
+ gpr_convert_clock_type(send_deadline, GPR_CLOCK_MONOTONIC);
263
264
  GRPC_CHANNEL_INTERNAL_REF(channel, "call");
264
265
  /* initial refcount dropped by grpc_call_destroy */
265
266
  grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call,
@@ -402,8 +403,51 @@ static void set_status_code(grpc_call *call, status_source source,
402
403
 
403
404
  call->status[source].is_set = 1;
404
405
  call->status[source].code = (grpc_status_code)status;
406
+ }
405
407
 
406
- /* TODO(ctiller): what to do about the flush that was previously here */
408
+ static void set_status_details(grpc_call *call, status_source source,
409
+ grpc_mdstr *status) {
410
+ if (call->status[source].details != NULL) {
411
+ GRPC_MDSTR_UNREF(status);
412
+ } else {
413
+ call->status[source].details = status;
414
+ }
415
+ }
416
+
417
+ static void get_final_status(grpc_call *call,
418
+ void (*set_value)(grpc_status_code code,
419
+ void *user_data),
420
+ void *set_value_user_data) {
421
+ int i;
422
+ for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
423
+ if (call->status[i].is_set) {
424
+ set_value(call->status[i].code, set_value_user_data);
425
+ return;
426
+ }
427
+ }
428
+ if (call->is_client) {
429
+ set_value(GRPC_STATUS_UNKNOWN, set_value_user_data);
430
+ } else {
431
+ set_value(GRPC_STATUS_OK, set_value_user_data);
432
+ }
433
+ }
434
+
435
+ static void set_status_from_error(grpc_call *call, status_source source,
436
+ grpc_error *error) {
437
+ intptr_t status;
438
+ if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) {
439
+ set_status_code(call, source, (uint32_t)status);
440
+ } else {
441
+ set_status_code(call, source, GRPC_STATUS_INTERNAL);
442
+ }
443
+ const char *msg = grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE);
444
+ bool free_msg = false;
445
+ if (msg == NULL) {
446
+ free_msg = true;
447
+ msg = grpc_error_string(error);
448
+ }
449
+ set_status_details(call, source, grpc_mdstr_from_string(msg));
450
+ if (free_msg) grpc_error_free_string(msg);
407
451
  }
408
452
 
409
453
  static void set_incoming_compression_algorithm(
@@ -492,32 +536,6 @@ uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
492
536
  return encodings_accepted_by_peer;
493
537
  }
494
538
 
495
- static void set_status_details(grpc_call *call, status_source source,
496
- grpc_mdstr *status) {
497
- if (call->status[source].details != NULL) {
498
- GRPC_MDSTR_UNREF(call->status[source].details);
499
- }
500
- call->status[source].details = status;
501
- }
502
-
503
- static void get_final_status(grpc_call *call,
504
- void (*set_value)(grpc_status_code code,
505
- void *user_data),
506
- void *set_value_user_data) {
507
- int i;
508
- for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
509
- if (call->status[i].is_set) {
510
- set_value(call->status[i].code, set_value_user_data);
511
- return;
512
- }
513
- }
514
- if (call->is_client) {
515
- set_value(GRPC_STATUS_UNKNOWN, set_value_user_data);
516
- } else {
517
- set_value(GRPC_STATUS_OK, set_value_user_data);
518
- }
519
- }
520
-
521
539
  static void get_final_details(grpc_call *call, char **out_details,
522
540
  size_t *out_details_capacity) {
523
541
  int i;
@@ -741,8 +759,7 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call *c,
741
759
  typedef struct termination_closure {
742
760
  grpc_closure closure;
743
761
  grpc_call *call;
744
- grpc_status_code status;
745
- gpr_slice optional_message;
762
+ grpc_error *error;
746
763
  grpc_closure *op_closure;
747
764
  enum { TC_CANCEL, TC_CLOSE } type;
748
765
  } termination_closure;
@@ -758,7 +775,7 @@ static void done_termination(grpc_exec_ctx *exec_ctx, void *tcp,
758
775
  GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "close");
759
776
  break;
760
777
  }
761
- gpr_slice_unref(tc->optional_message);
778
+ GRPC_ERROR_UNREF(tc->error);
762
779
  grpc_exec_ctx_sched(exec_ctx, tc->op_closure, GRPC_ERROR_NONE, NULL);
763
780
  gpr_free(tc);
764
781
  }
@@ -767,7 +784,7 @@ static void send_cancel(grpc_exec_ctx *exec_ctx, void *tcp, grpc_error *error) {
767
784
  grpc_transport_stream_op op;
768
785
  termination_closure *tc = tcp;
769
786
  memset(&op, 0, sizeof(op));
770
- op.cancel_with_status = tc->status;
787
+ op.cancel_error = tc->error;
771
788
  /* reuse closure to catch completion */
772
789
  grpc_closure_init(&tc->closure, done_termination, tc);
773
790
  op.on_complete = &tc->closure;
@@ -778,8 +795,7 @@ static void send_close(grpc_exec_ctx *exec_ctx, void *tcp, grpc_error *error) {
778
795
  grpc_transport_stream_op op;
779
796
  termination_closure *tc = tcp;
780
797
  memset(&op, 0, sizeof(op));
781
- tc->optional_message = gpr_slice_ref(tc->optional_message);
782
- grpc_transport_stream_op_add_close(&op, tc->status, &tc->optional_message);
798
+ op.close_error = tc->error;
783
799
  /* reuse closure to catch completion */
784
800
  grpc_closure_init(&tc->closure, done_termination, tc);
785
801
  tc->op_closure = op.on_complete;
@@ -789,14 +805,7 @@ static void send_close(grpc_exec_ctx *exec_ctx, void *tcp, grpc_error *error) {
789
805
 
790
806
  static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
791
807
  termination_closure *tc) {
792
- grpc_mdstr *details = NULL;
793
- if (GPR_SLICE_LENGTH(tc->optional_message) > 0) {
794
- tc->optional_message = gpr_slice_ref(tc->optional_message);
795
- details = grpc_mdstr_from_slice(tc->optional_message);
796
- }
797
-
798
- set_status_code(tc->call, STATUS_FROM_API_OVERRIDE, (uint32_t)tc->status);
799
- set_status_details(tc->call, STATUS_FROM_API_OVERRIDE, details);
808
+ set_status_from_error(tc->call, STATUS_FROM_API_OVERRIDE, tc->error);
800
809
 
801
810
  if (tc->type == TC_CANCEL) {
802
811
  grpc_closure_init(&tc->closure, send_cancel, tc);
@@ -812,13 +821,15 @@ static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
812
821
  static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
813
822
  grpc_status_code status,
814
823
  const char *description) {
824
+ GPR_ASSERT(status != GRPC_STATUS_OK);
815
825
  termination_closure *tc = gpr_malloc(sizeof(*tc));
816
826
  memset(tc, 0, sizeof(termination_closure));
817
827
  tc->type = TC_CANCEL;
818
828
  tc->call = c;
819
- tc->optional_message = gpr_slice_from_copied_string(description);
820
- GPR_ASSERT(status != GRPC_STATUS_OK);
821
- tc->status = status;
829
+ tc->error = grpc_error_set_int(
830
+ grpc_error_set_str(GRPC_ERROR_CREATE(description),
831
+ GRPC_ERROR_STR_GRPC_MESSAGE, description),
832
+ GRPC_ERROR_INT_GRPC_STATUS, status);
822
833
 
823
834
  return terminate_with_status(exec_ctx, tc);
824
835
  }
@@ -826,13 +837,15 @@ static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
826
837
  static grpc_call_error close_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
827
838
  grpc_status_code status,
828
839
  const char *description) {
840
+ GPR_ASSERT(status != GRPC_STATUS_OK);
829
841
  termination_closure *tc = gpr_malloc(sizeof(*tc));
830
842
  memset(tc, 0, sizeof(termination_closure));
831
843
  tc->type = TC_CLOSE;
832
844
  tc->call = c;
833
- tc->optional_message = gpr_slice_from_copied_string(description);
834
- GPR_ASSERT(status != GRPC_STATUS_OK);
835
- tc->status = status;
845
+ tc->error = grpc_error_set_int(
846
+ grpc_error_set_str(GRPC_ERROR_CREATE(description),
847
+ GRPC_ERROR_STR_GRPC_MESSAGE, description),
848
+ GRPC_ERROR_INT_GRPC_STATUS, status);
836
849
 
837
850
  return terminate_with_status(exec_ctx, tc);
838
851
  }
@@ -1194,7 +1207,7 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
1194
1207
  } else if (grpc_compression_options_is_algorithm_enabled(
1195
1208
  &compression_options, algo) == 0) {
1196
1209
  /* check if algorithm is supported by current channel config */
1197
- char *algo_name;
1210
+ char *algo_name = NULL;
1198
1211
  grpc_compression_algorithm_name(algo, &algo_name);
1199
1212
  gpr_asprintf(&error_msg, "Compression algorithm '%s' is disabled.",
1200
1213
  algo_name);
@@ -1213,7 +1226,7 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
1213
1226
  call->incoming_compression_algorithm)) {
1214
1227
  extern int grpc_compression_trace;
1215
1228
  if (grpc_compression_trace) {
1216
- char *algo_name;
1229
+ char *algo_name = NULL;
1217
1230
  grpc_compression_algorithm_name(call->incoming_compression_algorithm,
1218
1231
  &algo_name);
1219
1232
  gpr_log(GPR_ERROR,
@@ -1414,7 +1427,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1414
1427
  const grpc_compression_algorithm calgo =
1415
1428
  compression_algorithm_for_level_locked(
1416
1429
  call, effective_compression_level);
1417
- char *calgo_name;
1430
+ char *calgo_name = NULL;
1418
1431
  grpc_compression_algorithm_name(calgo, &calgo_name);
1419
1432
  // the following will be picked up by the compress filter and used as
1420
1433
  // the call's compression algorithm.