From f68e472f5c8c5e4e4b8e815550f85192c00f1f8e Mon Sep 17 00:00:00 2001 From: Hongyu Chen Date: Fri, 7 Aug 2015 18:06:42 -0700 Subject: Re-install census filters. --- src/core/surface/channel_create.c | 4 ++-- src/core/surface/secure_channel_create.c | 4 ++-- src/core/surface/server.c | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'src/core/surface') diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c index 707d615688..4379b3d016 100644 --- a/src/core/surface/channel_create.c +++ b/src/core/surface/channel_create.c @@ -38,6 +38,7 @@ #include +#include "src/core/channel/census_filter.h" #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" #include "src/core/channel/compress_filter.h" @@ -163,10 +164,9 @@ grpc_channel *grpc_insecure_channel_create(const char *target, subchannel_factory *f; grpc_mdctx *mdctx = grpc_mdctx_create(); int n = 0; - /* TODO(census) if (grpc_channel_args_is_census_enabled(args)) { filters[n++] = &grpc_client_census_filter; - } */ + } filters[n++] = &grpc_compress_filter; filters[n++] = &grpc_client_channel_filter; GPR_ASSERT(n <= MAX_FILTERS); diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index 1f89353025..11c2bc8287 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -38,6 +38,7 @@ #include +#include "src/core/channel/census_filter.h" #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" #include "src/core/channel/compress_filter.h" @@ -213,10 +214,9 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, args_copy = grpc_channel_args_copy_and_add( new_args_from_connector != NULL ? new_args_from_connector : args, &connector_arg, 1); - /* TODO(census) if (grpc_channel_args_is_census_enabled(args)) { filters[n++] = &grpc_client_census_filter; - } */ + } filters[n++] = &grpc_compress_filter; filters[n++] = &grpc_client_channel_filter; GPR_ASSERT(n <= MAX_FILTERS); diff --git a/src/core/surface/server.c b/src/core/surface/server.c index cd1dc589e1..27070836f3 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -818,10 +818,9 @@ grpc_server *grpc_server_create_from_filters( server->channel_filters = gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *)); server->channel_filters[0] = &server_surface_filter; - /* TODO(census): restore this once we rework census filter if (census_enabled) { server->channel_filters[1] = &grpc_server_census_filter; - } */ + } for (i = 0; i < filter_count; i++) { server->channel_filters[i + 1 + census_enabled] = filters[i]; } -- cgit v1.2.3 From fdc1dc744baa194f220a5d103ca73dde290c7d4b Mon Sep 17 00:00:00 2001 From: Hongyu Chen Date: Wed, 19 Aug 2015 16:58:12 -0700 Subject: Move census_filters from .../channel to .../census --- BUILD | 12 +- Makefile | 4 +- build.json | 4 +- gRPC.podspec | 6 +- src/core/census/census_filter.c | 197 +++++++++++++++++++++ src/core/census/census_filter.h | 44 +++++ src/core/channel/census_filter.c | 197 --------------------- src/core/channel/census_filter.h | 44 ----- src/core/surface/channel_create.c | 2 +- src/core/surface/secure_channel_create.c | 2 +- src/core/surface/server.c | 2 +- tools/doxygen/Doxyfile.core.internal | 4 +- tools/run_tests/sources_and_headers.json | 12 +- vsprojects/grpc/grpc.vcxproj | 6 +- vsprojects/grpc/grpc.vcxproj.filters | 10 +- vsprojects/grpc_unsecure/grpc_unsecure.vcxproj | 6 +- .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 10 +- 17 files changed, 281 insertions(+), 281 deletions(-) create mode 100644 src/core/census/census_filter.c create mode 100644 src/core/census/census_filter.h delete mode 100644 src/core/channel/census_filter.c delete mode 100644 src/core/channel/census_filter.h (limited to 'src/core/surface') diff --git a/BUILD b/BUILD index d38b9cee10..b24ba311e2 100644 --- a/BUILD +++ b/BUILD @@ -145,7 +145,7 @@ cc_library( "src/core/tsi/ssl_transport_security.h", "src/core/tsi/transport_security.h", "src/core/tsi/transport_security_interface.h", - "src/core/channel/census_filter.h", + "src/core/census/census_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", @@ -267,8 +267,8 @@ cc_library( "src/core/tsi/fake_transport_security.c", "src/core/tsi/ssl_transport_security.c", "src/core/tsi/transport_security.c", + "src/core/census/census_filter.c", "src/core/census/grpc_context.c", - "src/core/channel/census_filter.c", "src/core/channel/channel_args.c", "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", @@ -409,7 +409,7 @@ cc_library( cc_library( name = "grpc_unsecure", srcs = [ - "src/core/channel/census_filter.h", + "src/core/census/census_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", @@ -511,8 +511,8 @@ cc_library( "src/core/census/context.h", "src/core/census/rpc_stat_id.h", "src/core/surface/init_unsecure.c", + "src/core/census/census_filter.c", "src/core/census/grpc_context.c", - "src/core/channel/census_filter.c", "src/core/channel/channel_args.c", "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", @@ -997,8 +997,8 @@ objc_library( "src/core/tsi/fake_transport_security.c", "src/core/tsi/ssl_transport_security.c", "src/core/tsi/transport_security.c", + "src/core/census/census_filter.c", "src/core/census/grpc_context.c", - "src/core/channel/census_filter.c", "src/core/channel/channel_args.c", "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", @@ -1137,7 +1137,7 @@ objc_library( "src/core/tsi/ssl_transport_security.h", "src/core/tsi/transport_security.h", "src/core/tsi/transport_security_interface.h", - "src/core/channel/census_filter.h", + "src/core/census/census_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", diff --git a/Makefile b/Makefile index aabf1bbd04..995a4954e4 100644 --- a/Makefile +++ b/Makefile @@ -3976,8 +3976,8 @@ LIBGRPC_SRC = \ src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ + src/core/census/census_filter.c \ src/core/census/grpc_context.c \ - src/core/channel/census_filter.c \ src/core/channel/channel_args.c \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ @@ -4249,8 +4249,8 @@ endif LIBGRPC_UNSECURE_SRC = \ src/core/surface/init_unsecure.c \ + src/core/census/census_filter.c \ src/core/census/grpc_context.c \ - src/core/channel/census_filter.c \ src/core/channel/channel_args.c \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ diff --git a/build.json b/build.json index ab6a39a20f..3e3e71a684 100644 --- a/build.json +++ b/build.json @@ -114,7 +114,7 @@ "include/grpc/status.h" ], "headers": [ - "src/core/channel/census_filter.h", + "src/core/census/census_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", @@ -215,8 +215,8 @@ "src/core/transport/transport_impl.h" ], "src": [ + "src/core/census/census_filter.c", "src/core/census/grpc_context.c", - "src/core/channel/census_filter.c", "src/core/channel/channel_args.c", "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", diff --git a/gRPC.podspec b/gRPC.podspec index d1e95a1652..b57960a896 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -147,7 +147,7 @@ Pod::Spec.new do |s| 'src/core/tsi/ssl_transport_security.h', 'src/core/tsi/transport_security.h', 'src/core/tsi/transport_security_interface.h', - 'src/core/channel/census_filter.h', + 'src/core/census/census_filter.h', 'src/core/channel/channel_args.h', 'src/core/channel/channel_stack.h', 'src/core/channel/client_channel.h', @@ -276,8 +276,8 @@ Pod::Spec.new do |s| 'src/core/tsi/fake_transport_security.c', 'src/core/tsi/ssl_transport_security.c', 'src/core/tsi/transport_security.c', + 'src/core/census/census_filter.c', 'src/core/census/grpc_context.c', - 'src/core/channel/census_filter.c', 'src/core/channel/channel_args.c', 'src/core/channel/channel_stack.c', 'src/core/channel/client_channel.c', @@ -415,7 +415,7 @@ Pod::Spec.new do |s| 'src/core/tsi/ssl_transport_security.h', 'src/core/tsi/transport_security.h', 'src/core/tsi/transport_security_interface.h', - 'src/core/channel/census_filter.h', + 'src/core/census/census_filter.h', 'src/core/channel/channel_args.h', 'src/core/channel/channel_stack.h', 'src/core/channel/client_channel.h', diff --git a/src/core/census/census_filter.c b/src/core/census/census_filter.c new file mode 100644 index 0000000000..31db686cf3 --- /dev/null +++ b/src/core/census/census_filter.c @@ -0,0 +1,197 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/census/census_filter.h" + +#include +#include + +#include "include/grpc/census.h" +#include "src/core/census/rpc_stat_id.h" +#include "src/core/channel/channel_stack.h" +#include "src/core/channel/noop_filter.h" +#include "src/core/statistics/census_interface.h" +#include "src/core/statistics/census_rpc_stats.h" +#include +#include +#include +#include + +typedef struct call_data { + census_op_id op_id; + census_context* ctxt; + gpr_timespec start_ts; + int error; + + /* recv callback */ + grpc_stream_op_buffer* recv_ops; + grpc_iomgr_closure* on_done_recv; +} call_data; + +typedef struct channel_data { + grpc_mdstr* path_str; /* pointer to meta data str with key == ":path" */ +} channel_data; + +static void extract_and_annotate_method_tag(grpc_stream_op_buffer* sopb, + call_data* calld, + channel_data* chand) { + grpc_linked_mdelem* m; + size_t i; + for (i = 0; i < sopb->nops; i++) { + grpc_stream_op* op = &sopb->ops[i]; + if (op->type != GRPC_OP_METADATA) continue; + for (m = op->data.metadata.list.head; m != NULL; m = m->next) { + if (m->md->key == chand->path_str) { + gpr_log(GPR_DEBUG, "%s", + (const char*)GPR_SLICE_START_PTR(m->md->value->slice)); + /* Add method tag here */ + } + } + } +} + +static void client_mutate_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { + call_data* calld = elem->call_data; + channel_data* chand = elem->channel_data; + if (op->send_ops) { + extract_and_annotate_method_tag(op->send_ops, calld, chand); + } +} + +static void client_start_transport_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { + client_mutate_op(elem, op); + grpc_call_next_op(elem, op); +} + +static void server_on_done_recv(void* ptr, int success) { + grpc_call_element* elem = ptr; + call_data* calld = elem->call_data; + channel_data* chand = elem->channel_data; + if (success) { + extract_and_annotate_method_tag(calld->recv_ops, calld, chand); + } + calld->on_done_recv->cb(calld->on_done_recv->cb_arg, success); +} + +static void server_mutate_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { + call_data* calld = elem->call_data; + if (op->recv_ops) { + /* substitute our callback for the op callback */ + calld->recv_ops = op->recv_ops; + calld->on_done_recv = op->on_done_recv; + op->on_done_recv = calld->on_done_recv; + } +} + +static void server_start_transport_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { + call_data* calld = elem->call_data; + GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); + server_mutate_op(elem, op); + grpc_call_next_op(elem, op); +} + +static void client_init_call_elem(grpc_call_element* elem, + const void* server_transport_data, + grpc_transport_stream_op* initial_op) { + call_data* d = elem->call_data; + GPR_ASSERT(d != NULL); + d->start_ts = gpr_now(GPR_CLOCK_REALTIME); + if (initial_op) client_mutate_op(elem, initial_op); +} + +static void client_destroy_call_elem(grpc_call_element* elem) { + call_data* d = elem->call_data; + GPR_ASSERT(d != NULL); + /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ +} + +static void server_init_call_elem(grpc_call_element* elem, + const void* server_transport_data, + grpc_transport_stream_op* initial_op) { + call_data* d = elem->call_data; + GPR_ASSERT(d != NULL); + d->start_ts = gpr_now(GPR_CLOCK_REALTIME); + /* TODO(hongyu): call census_tracing_start_op here. */ + grpc_iomgr_closure_init(d->on_done_recv, server_on_done_recv, elem); + if (initial_op) server_mutate_op(elem, initial_op); +} + +static void server_destroy_call_elem(grpc_call_element* elem) { + call_data* d = elem->call_data; + GPR_ASSERT(d != NULL); + /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */ +} + +static void init_channel_elem(grpc_channel_element* elem, grpc_channel* master, + const grpc_channel_args* args, grpc_mdctx* mdctx, + int is_first, int is_last) { + channel_data* chand = elem->channel_data; + GPR_ASSERT(chand != NULL); + chand->path_str = grpc_mdstr_from_string(mdctx, ":path", 0); +} + +static void destroy_channel_elem(grpc_channel_element* elem) { + channel_data* chand = elem->channel_data; + GPR_ASSERT(chand != NULL); + if (chand->path_str != NULL) { + GRPC_MDSTR_UNREF(chand->path_str); + } +} + +const grpc_channel_filter grpc_client_census_filter = { + client_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + client_init_call_elem, + client_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "census-client"}; + +const grpc_channel_filter grpc_server_census_filter = { + server_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + server_init_call_elem, + server_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "census-server"}; diff --git a/src/core/census/census_filter.h b/src/core/census/census_filter.h new file mode 100644 index 0000000000..4f9759f0db --- /dev/null +++ b/src/core/census/census_filter.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H +#define GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H + +#include "src/core/channel/channel_stack.h" + +/* Census filters: provides tracing and stats collection functionalities. It + needs to reside right below the surface filter in the channel stack. */ +extern const grpc_channel_filter grpc_client_census_filter; +extern const grpc_channel_filter grpc_server_census_filter; + +#endif /* GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H */ diff --git a/src/core/channel/census_filter.c b/src/core/channel/census_filter.c deleted file mode 100644 index 53d70be356..0000000000 --- a/src/core/channel/census_filter.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "src/core/channel/census_filter.h" - -#include -#include - -#include "include/grpc/census.h" -#include "src/core/census/rpc_stat_id.h" -#include "src/core/channel/channel_stack.h" -#include "src/core/channel/noop_filter.h" -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" -#include -#include -#include -#include - -typedef struct call_data { - census_op_id op_id; - census_context* ctxt; - gpr_timespec start_ts; - int error; - - /* recv callback */ - grpc_stream_op_buffer* recv_ops; - grpc_iomgr_closure* on_done_recv; -} call_data; - -typedef struct channel_data { - grpc_mdstr* path_str; /* pointer to meta data str with key == ":path" */ -} channel_data; - -static void extract_and_annotate_method_tag(grpc_stream_op_buffer* sopb, - call_data* calld, - channel_data* chand) { - grpc_linked_mdelem* m; - size_t i; - for (i = 0; i < sopb->nops; i++) { - grpc_stream_op* op = &sopb->ops[i]; - if (op->type != GRPC_OP_METADATA) continue; - for (m = op->data.metadata.list.head; m != NULL; m = m->next) { - if (m->md->key == chand->path_str) { - gpr_log(GPR_DEBUG, "%s", - (const char*)GPR_SLICE_START_PTR(m->md->value->slice)); - /* Add method tag here */ - } - } - } -} - -static void client_mutate_op(grpc_call_element* elem, - grpc_transport_stream_op* op) { - call_data* calld = elem->call_data; - channel_data* chand = elem->channel_data; - if (op->send_ops) { - extract_and_annotate_method_tag(op->send_ops, calld, chand); - } -} - -static void client_start_transport_op(grpc_call_element* elem, - grpc_transport_stream_op* op) { - client_mutate_op(elem, op); - grpc_call_next_op(elem, op); -} - -static void server_on_done_recv(void* ptr, int success) { - grpc_call_element* elem = ptr; - call_data* calld = elem->call_data; - channel_data* chand = elem->channel_data; - if (success) { - extract_and_annotate_method_tag(calld->recv_ops, calld, chand); - } - calld->on_done_recv->cb(calld->on_done_recv->cb_arg, success); -} - -static void server_mutate_op(grpc_call_element* elem, - grpc_transport_stream_op* op) { - call_data* calld = elem->call_data; - if (op->recv_ops) { - /* substitute our callback for the op callback */ - calld->recv_ops = op->recv_ops; - calld->on_done_recv = op->on_done_recv; - op->on_done_recv = calld->on_done_recv; - } -} - -static void server_start_transport_op(grpc_call_element* elem, - grpc_transport_stream_op* op) { - call_data* calld = elem->call_data; - GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); - server_mutate_op(elem, op); - grpc_call_next_op(elem, op); -} - -static void client_init_call_elem(grpc_call_element* elem, - const void* server_transport_data, - grpc_transport_stream_op* initial_op) { - call_data* d = elem->call_data; - GPR_ASSERT(d != NULL); - d->start_ts = gpr_now(GPR_CLOCK_REALTIME); - if (initial_op) client_mutate_op(elem, initial_op); -} - -static void client_destroy_call_elem(grpc_call_element* elem) { - call_data* d = elem->call_data; - GPR_ASSERT(d != NULL); - /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ -} - -static void server_init_call_elem(grpc_call_element* elem, - const void* server_transport_data, - grpc_transport_stream_op* initial_op) { - call_data* d = elem->call_data; - GPR_ASSERT(d != NULL); - d->start_ts = gpr_now(GPR_CLOCK_REALTIME); - /* TODO(hongyu): call census_tracing_start_op here. */ - grpc_iomgr_closure_init(d->on_done_recv, server_on_done_recv, elem); - if (initial_op) server_mutate_op(elem, initial_op); -} - -static void server_destroy_call_elem(grpc_call_element* elem) { - call_data* d = elem->call_data; - GPR_ASSERT(d != NULL); - /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */ -} - -static void init_channel_elem(grpc_channel_element* elem, grpc_channel* master, - const grpc_channel_args* args, grpc_mdctx* mdctx, - int is_first, int is_last) { - channel_data* chand = elem->channel_data; - GPR_ASSERT(chand != NULL); - chand->path_str = grpc_mdstr_from_string(mdctx, ":path", 0); -} - -static void destroy_channel_elem(grpc_channel_element* elem) { - channel_data* chand = elem->channel_data; - GPR_ASSERT(chand != NULL); - if (chand->path_str != NULL) { - GRPC_MDSTR_UNREF(chand->path_str); - } -} - -const grpc_channel_filter grpc_client_census_filter = { - client_start_transport_op, - grpc_channel_next_op, - sizeof(call_data), - client_init_call_elem, - client_destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "census-client"}; - -const grpc_channel_filter grpc_server_census_filter = { - server_start_transport_op, - grpc_channel_next_op, - sizeof(call_data), - server_init_call_elem, - server_destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "census-server"}; diff --git a/src/core/channel/census_filter.h b/src/core/channel/census_filter.h deleted file mode 100644 index 4f9759f0db..0000000000 --- a/src/core/channel/census_filter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H -#define GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H - -#include "src/core/channel/channel_stack.h" - -/* Census filters: provides tracing and stats collection functionalities. It - needs to reside right below the surface filter in the channel stack. */ -extern const grpc_channel_filter grpc_client_census_filter; -extern const grpc_channel_filter grpc_server_census_filter; - -#endif /* GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H */ diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c index 4379b3d016..4d01be3d7d 100644 --- a/src/core/surface/channel_create.c +++ b/src/core/surface/channel_create.c @@ -38,7 +38,7 @@ #include -#include "src/core/channel/census_filter.h" +#include "src/core/census/census_filter.h" #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" #include "src/core/channel/compress_filter.h" diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index 93a372928f..943bddfc0c 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -38,7 +38,7 @@ #include -#include "src/core/channel/census_filter.h" +#include "src/core/census/census_filter.h" #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" #include "src/core/channel/compress_filter.h" diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 27070836f3..22d399cf1f 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -41,7 +41,7 @@ #include #include -#include "src/core/channel/census_filter.h" +#include "src/core/census/census_filter.h" #include "src/core/channel/channel_args.h" #include "src/core/channel/connected_channel.h" #include "src/core/iomgr/iomgr.h" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 0619f76e27..f5d5dc0f80 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -780,7 +780,7 @@ src/core/tsi/fake_transport_security.h \ src/core/tsi/ssl_transport_security.h \ src/core/tsi/transport_security.h \ src/core/tsi/transport_security_interface.h \ -src/core/channel/census_filter.h \ +src/core/census/census_filter.h \ src/core/channel/channel_args.h \ src/core/channel/channel_stack.h \ src/core/channel/client_channel.h \ @@ -902,8 +902,8 @@ src/core/surface/secure_channel_create.c \ src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ +src/core/census/census_filter.c \ src/core/census/grpc_context.c \ -src/core/channel/census_filter.c \ src/core/channel/channel_args.c \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 38bf532f44..cc74397cea 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -12222,9 +12222,9 @@ "include/grpc/grpc.h", "include/grpc/grpc_security.h", "include/grpc/status.h", + "src/core/census/census_filter.h", "src/core/census/context.h", "src/core/census/rpc_stat_id.h", - "src/core/channel/census_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", @@ -12347,14 +12347,14 @@ "include/grpc/grpc.h", "include/grpc/grpc_security.h", "include/grpc/status.h", + "src/core/census/census_filter.c", + "src/core/census/census_filter.h", "src/core/census/context.c", "src/core/census/context.h", "src/core/census/grpc_context.c", "src/core/census/initialize.c", "src/core/census/record_stat.c", "src/core/census/rpc_stat_id.h", - "src/core/channel/census_filter.c", - "src/core/channel/census_filter.h", "src/core/channel/channel_args.c", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.c", @@ -12694,9 +12694,9 @@ "include/grpc/compression.h", "include/grpc/grpc.h", "include/grpc/status.h", + "src/core/census/census_filter.h", "src/core/census/context.h", "src/core/census/rpc_stat_id.h", - "src/core/channel/census_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", @@ -12805,14 +12805,14 @@ "include/grpc/compression.h", "include/grpc/grpc.h", "include/grpc/status.h", + "src/core/census/census_filter.c", + "src/core/census/census_filter.h", "src/core/census/context.c", "src/core/census/context.h", "src/core/census/grpc_context.c", "src/core/census/initialize.c", "src/core/census/record_stat.c", "src/core/census/rpc_stat_id.h", - "src/core/channel/census_filter.c", - "src/core/channel/census_filter.h", "src/core/channel/channel_args.c", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.c", diff --git a/vsprojects/grpc/grpc.vcxproj b/vsprojects/grpc/grpc.vcxproj index a87ad29d49..950e385ee7 100644 --- a/vsprojects/grpc/grpc.vcxproj +++ b/vsprojects/grpc/grpc.vcxproj @@ -242,7 +242,7 @@ - + @@ -387,9 +387,9 @@ - + - + diff --git a/vsprojects/grpc/grpc.vcxproj.filters b/vsprojects/grpc/grpc.vcxproj.filters index c8812faa85..d6ecdbba41 100644 --- a/vsprojects/grpc/grpc.vcxproj.filters +++ b/vsprojects/grpc/grpc.vcxproj.filters @@ -64,11 +64,11 @@ src\core\tsi - + src\core\census - - src\core\channel + + src\core\census src\core\channel @@ -482,8 +482,8 @@ src\core\tsi - - src\core\channel + + src\core\census src\core\channel diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj index 06da784323..acd83c6080 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj @@ -225,7 +225,7 @@ - + @@ -330,9 +330,9 @@ - + - + diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters index 2d10960a79..12da3fa1e3 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -4,11 +4,11 @@ src\core\surface - + src\core\census - - src\core\channel + + src\core\census src\core\channel @@ -380,8 +380,8 @@ - - src\core\channel + + src\core\census src\core\channel -- cgit v1.2.3 From 49772e00eb9606c3192b88f348d9cbcb22eb93c2 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 21 Aug 2015 08:08:37 -0700 Subject: Outlaw illegal metadata characters --- Makefile | 32 +++++++++- build.json | 10 +++ src/core/channel/compress_filter.h | 2 +- src/core/surface/call.c | 5 +- src/core/transport/metadata.c | 26 +++++++- src/core/transport/metadata.h | 1 + tools/codegen/core/gen_legal_metadata_characters.c | 73 ++++++++++++++++++++++ tools/run_tests/sources_and_headers.json | 12 ++++ tools/run_tests/tests.json | 1 + vsprojects/Grpc.mak | 8 +++ 10 files changed, 163 insertions(+), 7 deletions(-) create mode 100644 tools/codegen/core/gen_legal_metadata_characters.c (limited to 'src/core/surface') diff --git a/Makefile b/Makefile index 31628b4412..f7ace3186a 100644 --- a/Makefile +++ b/Makefile @@ -793,6 +793,7 @@ fling_server: $(BINDIR)/$(CONFIG)/fling_server fling_stream_test: $(BINDIR)/$(CONFIG)/fling_stream_test fling_test: $(BINDIR)/$(CONFIG)/fling_test gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables +gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters gpr_cmdline_test: $(BINDIR)/$(CONFIG)/gpr_cmdline_test gpr_env_test: $(BINDIR)/$(CONFIG)/gpr_env_test gpr_file_test: $(BINDIR)/$(CONFIG)/gpr_file_test @@ -3386,7 +3387,7 @@ test_python: static_c tools: tools_c tools_cxx -tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt +tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt tools_cxx: privatelibs_cxx @@ -7122,6 +7123,35 @@ endif endif +GEN_LEGAL_METADATA_CHARACTERS_SRC = \ + tools/codegen/core/gen_legal_metadata_characters.c \ + +GEN_LEGAL_METADATA_CHARACTERS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_LEGAL_METADATA_CHARACTERS_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/gen_legal_metadata_characters: openssl_dep_error + +else + +$(BINDIR)/$(CONFIG)/gen_legal_metadata_characters: $(GEN_LEGAL_METADATA_CHARACTERS_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(GEN_LEGAL_METADATA_CHARACTERS_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters + +endif + +$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_legal_metadata_characters.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +deps_gen_legal_metadata_characters: $(GEN_LEGAL_METADATA_CHARACTERS_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GEN_LEGAL_METADATA_CHARACTERS_OBJS:.o=.dep) +endif +endif + + GPR_CMDLINE_TEST_SRC = \ test/core/support/cmdline_test.c \ diff --git a/build.json b/build.json index bd707d2e34..c6a670970b 100644 --- a/build.json +++ b/build.json @@ -1143,6 +1143,16 @@ "grpc" ] }, + { + "name": "gen_legal_metadata_characters", + "build": "tool", + "language": "c", + "src": [ + "tools/codegen/core/gen_legal_metadata_characters.c" + ], + "deps": [ + ] + }, { "name": "gpr_cmdline_test", "build": "test", diff --git a/src/core/channel/compress_filter.h b/src/core/channel/compress_filter.h index 0917e81ca4..415459bca6 100644 --- a/src/core/channel/compress_filter.h +++ b/src/core/channel/compress_filter.h @@ -36,7 +36,7 @@ #include "src/core/channel/channel_stack.h" -#define GRPC_COMPRESS_REQUEST_ALGORITHM_KEY "internal:grpc-encoding-request" +#define GRPC_COMPRESS_REQUEST_ALGORITHM_KEY "grpc-internal-encoding-request" /** Compression filter for outgoing data. * diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 33f277da46..4426bbbce9 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -1046,10 +1046,11 @@ static int prepare_application_metadata(grpc_call *call, size_t count, (const gpr_uint8 *)md->value, md->value_length, 1); if (!grpc_mdstr_is_legal_header(l->md->key)) { - gpr_log(GPR_ERROR, "attempt to send invalid metadata key"); + gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", + grpc_mdstr_as_c_string(l->md->key)); return 0; } else if (!grpc_mdstr_is_bin_suffixed(l->md->key) && - !grpc_mdstr_is_legal_header(l->md->value)) { + !grpc_mdstr_is_legal_nonbin_header(l->md->value)) { gpr_log(GPR_ERROR, "attempt to send invalid metadata value"); return 0; } diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c index f92e87e9dd..d758351feb 100644 --- a/src/core/transport/metadata.c +++ b/src/core/transport/metadata.c @@ -681,16 +681,36 @@ void grpc_mdctx_locked_mdelem_unref(grpc_mdctx *ctx, void grpc_mdctx_unlock(grpc_mdctx *ctx) { unlock(ctx); } -int grpc_mdstr_is_legal_header(grpc_mdstr *s) { - /* TODO(ctiller): consider caching this, or computing it on construction */ +static int conforms_to(grpc_mdstr *s, const gpr_uint8 *legal_bits) { const gpr_uint8 *p = GPR_SLICE_START_PTR(s->slice); const gpr_uint8 *e = GPR_SLICE_END_PTR(s->slice); for (; p != e; p++) { - if (*p < 32 || *p > 126) return 0; + int idx = *p; + int byte = idx / 8; + int bit = idx % 8; + if ((legal_bits[byte] & (1 << bit)) == 0) return 0; } return 1; } +int grpc_mdstr_is_legal_header(grpc_mdstr *s) { + static const gpr_uint8 legal_header_bits[256 / 8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0x03, 0xfe, 0xff, 0xff, + 0x07, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + /* TODO(ctiller): consider caching this, or computing it on construction */ + return conforms_to(s, legal_header_bits); +} + +int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s) { + static const gpr_uint8 legal_header_bits[256 / 8] = { + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + return conforms_to(s, legal_header_bits); +} + int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s) { /* TODO(ctiller): consider caching this */ return grpc_is_binary_header((const char *)GPR_SLICE_START_PTR(s->slice), diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h index a7af49ba55..eb17747be7 100644 --- a/src/core/transport/metadata.h +++ b/src/core/transport/metadata.h @@ -154,6 +154,7 @@ void grpc_mdelem_unref(grpc_mdelem *md); const char *grpc_mdstr_as_c_string(grpc_mdstr *s); int grpc_mdstr_is_legal_header(grpc_mdstr *s); +int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s); int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s); /* Batch mode metadata functions. diff --git a/tools/codegen/core/gen_legal_metadata_characters.c b/tools/codegen/core/gen_legal_metadata_characters.c new file mode 100644 index 0000000000..5e32d91d50 --- /dev/null +++ b/tools/codegen/core/gen_legal_metadata_characters.c @@ -0,0 +1,73 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* generates constant table for metadata.c */ + +#include +#include + +static unsigned char legal_bits[256 / 8]; + +static void legal(int x) { + int byte = x / 8; + int bit = x % 8; + legal_bits[byte] |= 1 << bit; +} + +static void dump(void) { + int i; + + printf("static const gpr_uint8 legal_header_bits[256/8] = "); + for (i = 0; i < 256 / 8; i++) + printf("%c 0x%02x", i ? ',' : '{', legal_bits[i]); + printf(" };\n"); +} + +static void clear(void) { memset(legal_bits, 0, sizeof(legal_bits)); } + +int main(void) { + int i; + + clear(); + for (i = 'a'; i <= 'z'; i++) legal(i); + for (i = 'A'; i <= 'Z'; i++) legal(i); + for (i = '0'; i <= '9'; i++) legal(i); + legal('-'); + dump(); + + clear(); + for (i = 32; i <= 126; i++) legal(i); + dump(); + + return 0; +} diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 50f078586d..142c84901d 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -237,6 +237,18 @@ "tools/codegen/core/gen_hpack_tables.c" ] }, + { + "deps": [ + "gpr", + "grpc" + ], + "headers": [], + "language": "c", + "name": "gen_legal_metadata_characters", + "src": [ + "tools/codegen/core/gen_legal_metadata_characters.c" + ] + }, { "deps": [ "gpr", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 6c06d74834..127b1dfc40 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -1538,6 +1538,7 @@ "posix", "windows" ], + "exclude_configs": [], "flaky": false, "language": "c++", "name": "status_test", diff --git a/vsprojects/Grpc.mak b/vsprojects/Grpc.mak index 662de784f7..3d853d9c76 100644 --- a/vsprojects/Grpc.mak +++ b/vsprojects/Grpc.mak @@ -183,6 +183,14 @@ gen_hpack_tables: gen_hpack_tables.exe echo Running gen_hpack_tables $(OUT_DIR)\gen_hpack_tables.exe +gen_legal_metadata_characters.exe: build_gpr build_grpc $(OUT_DIR) + echo Building gen_legal_metadata_characters + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\tools\codegen\core\gen_legal_metadata_characters.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gen_legal_metadata_characters.exe" Debug\gpr.lib Debug\grpc.lib $(LIBS) $(OUT_DIR)\gen_legal_metadata_characters.obj +gen_legal_metadata_characters: gen_legal_metadata_characters.exe + echo Running gen_legal_metadata_characters + $(OUT_DIR)\gen_legal_metadata_characters.exe + gpr_cmdline_test.exe: build_gpr_test_util build_gpr $(OUT_DIR) echo Building gpr_cmdline_test $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\support\cmdline_test.c -- cgit v1.2.3 From e09dc78e74f481dd06bf2f9ea643026f5e94bb5b Mon Sep 17 00:00:00 2001 From: Hongyu Chen Date: Fri, 21 Aug 2015 11:28:33 -0700 Subject: rename census_filter.{c,h} to grpc_filter.{c,h} --- BUILD | 12 +- Makefile | 4 +- build.json | 4 +- gRPC.podspec | 6 +- src/core/census/census_filter.c | 197 --------------------- src/core/census/census_filter.h | 44 ----- src/core/census/grpc_filter.c | 197 +++++++++++++++++++++ src/core/census/grpc_filter.h | 44 +++++ src/core/surface/channel_create.c | 2 +- src/core/surface/secure_channel_create.c | 2 +- src/core/surface/server.c | 2 +- tools/doxygen/Doxyfile.core.internal | 4 +- tools/run_tests/sources_and_headers.json | 12 +- vsprojects/grpc/grpc.vcxproj | 6 +- vsprojects/grpc/grpc.vcxproj.filters | 6 +- vsprojects/grpc_unsecure/grpc_unsecure.vcxproj | 6 +- .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 +- 17 files changed, 277 insertions(+), 277 deletions(-) delete mode 100644 src/core/census/census_filter.c delete mode 100644 src/core/census/census_filter.h create mode 100644 src/core/census/grpc_filter.c create mode 100644 src/core/census/grpc_filter.h (limited to 'src/core/surface') diff --git a/BUILD b/BUILD index ae98fe02ae..043d38e1fc 100644 --- a/BUILD +++ b/BUILD @@ -143,7 +143,7 @@ cc_library( "src/core/tsi/ssl_transport_security.h", "src/core/tsi/transport_security.h", "src/core/tsi/transport_security_interface.h", - "src/core/census/census_filter.h", + "src/core/census/grpc_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", @@ -266,8 +266,8 @@ cc_library( "src/core/tsi/fake_transport_security.c", "src/core/tsi/ssl_transport_security.c", "src/core/tsi/transport_security.c", - "src/core/census/census_filter.c", "src/core/census/grpc_context.c", + "src/core/census/grpc_filter.c", "src/core/channel/channel_args.c", "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", @@ -410,7 +410,7 @@ cc_library( cc_library( name = "grpc_unsecure", srcs = [ - "src/core/census/census_filter.h", + "src/core/census/grpc_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", @@ -513,8 +513,8 @@ cc_library( "src/core/census/context.h", "src/core/census/rpc_stat_id.h", "src/core/surface/init_unsecure.c", - "src/core/census/census_filter.c", "src/core/census/grpc_context.c", + "src/core/census/grpc_filter.c", "src/core/channel/channel_args.c", "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", @@ -1018,8 +1018,8 @@ objc_library( "src/core/tsi/fake_transport_security.c", "src/core/tsi/ssl_transport_security.c", "src/core/tsi/transport_security.c", - "src/core/census/census_filter.c", "src/core/census/grpc_context.c", + "src/core/census/grpc_filter.c", "src/core/channel/channel_args.c", "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", @@ -1159,7 +1159,7 @@ objc_library( "src/core/tsi/ssl_transport_security.h", "src/core/tsi/transport_security.h", "src/core/tsi/transport_security_interface.h", - "src/core/census/census_filter.h", + "src/core/census/grpc_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", diff --git a/Makefile b/Makefile index 934c2c4863..8bcdc79fde 100644 --- a/Makefile +++ b/Makefile @@ -4080,8 +4080,8 @@ LIBGRPC_SRC = \ src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ - src/core/census/census_filter.c \ src/core/census/grpc_context.c \ + src/core/census/grpc_filter.c \ src/core/channel/channel_args.c \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ @@ -4354,8 +4354,8 @@ endif LIBGRPC_UNSECURE_SRC = \ src/core/surface/init_unsecure.c \ - src/core/census/census_filter.c \ src/core/census/grpc_context.c \ + src/core/census/grpc_filter.c \ src/core/channel/channel_args.c \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ diff --git a/build.json b/build.json index a0c9c8dfd8..70dec998ec 100644 --- a/build.json +++ b/build.json @@ -114,7 +114,7 @@ "include/grpc/status.h" ], "headers": [ - "src/core/census/census_filter.h", + "src/core/census/grpc_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", @@ -216,8 +216,8 @@ "src/core/transport/transport_impl.h" ], "src": [ - "src/core/census/census_filter.c", "src/core/census/grpc_context.c", + "src/core/census/grpc_filter.c", "src/core/channel/channel_args.c", "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", diff --git a/gRPC.podspec b/gRPC.podspec index 6878f5937b..0e826b5ba2 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -145,7 +145,7 @@ Pod::Spec.new do |s| 'src/core/tsi/ssl_transport_security.h', 'src/core/tsi/transport_security.h', 'src/core/tsi/transport_security_interface.h', - 'src/core/census/census_filter.h', + 'src/core/census/grpc_filter.h', 'src/core/channel/channel_args.h', 'src/core/channel/channel_stack.h', 'src/core/channel/client_channel.h', @@ -275,8 +275,8 @@ Pod::Spec.new do |s| 'src/core/tsi/fake_transport_security.c', 'src/core/tsi/ssl_transport_security.c', 'src/core/tsi/transport_security.c', - 'src/core/census/census_filter.c', 'src/core/census/grpc_context.c', + 'src/core/census/grpc_filter.c', 'src/core/channel/channel_args.c', 'src/core/channel/channel_stack.c', 'src/core/channel/client_channel.c', @@ -415,7 +415,7 @@ Pod::Spec.new do |s| 'src/core/tsi/ssl_transport_security.h', 'src/core/tsi/transport_security.h', 'src/core/tsi/transport_security_interface.h', - 'src/core/census/census_filter.h', + 'src/core/census/grpc_filter.h', 'src/core/channel/channel_args.h', 'src/core/channel/channel_stack.h', 'src/core/channel/client_channel.h', diff --git a/src/core/census/census_filter.c b/src/core/census/census_filter.c deleted file mode 100644 index 31db686cf3..0000000000 --- a/src/core/census/census_filter.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "src/core/census/census_filter.h" - -#include -#include - -#include "include/grpc/census.h" -#include "src/core/census/rpc_stat_id.h" -#include "src/core/channel/channel_stack.h" -#include "src/core/channel/noop_filter.h" -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" -#include -#include -#include -#include - -typedef struct call_data { - census_op_id op_id; - census_context* ctxt; - gpr_timespec start_ts; - int error; - - /* recv callback */ - grpc_stream_op_buffer* recv_ops; - grpc_iomgr_closure* on_done_recv; -} call_data; - -typedef struct channel_data { - grpc_mdstr* path_str; /* pointer to meta data str with key == ":path" */ -} channel_data; - -static void extract_and_annotate_method_tag(grpc_stream_op_buffer* sopb, - call_data* calld, - channel_data* chand) { - grpc_linked_mdelem* m; - size_t i; - for (i = 0; i < sopb->nops; i++) { - grpc_stream_op* op = &sopb->ops[i]; - if (op->type != GRPC_OP_METADATA) continue; - for (m = op->data.metadata.list.head; m != NULL; m = m->next) { - if (m->md->key == chand->path_str) { - gpr_log(GPR_DEBUG, "%s", - (const char*)GPR_SLICE_START_PTR(m->md->value->slice)); - /* Add method tag here */ - } - } - } -} - -static void client_mutate_op(grpc_call_element* elem, - grpc_transport_stream_op* op) { - call_data* calld = elem->call_data; - channel_data* chand = elem->channel_data; - if (op->send_ops) { - extract_and_annotate_method_tag(op->send_ops, calld, chand); - } -} - -static void client_start_transport_op(grpc_call_element* elem, - grpc_transport_stream_op* op) { - client_mutate_op(elem, op); - grpc_call_next_op(elem, op); -} - -static void server_on_done_recv(void* ptr, int success) { - grpc_call_element* elem = ptr; - call_data* calld = elem->call_data; - channel_data* chand = elem->channel_data; - if (success) { - extract_and_annotate_method_tag(calld->recv_ops, calld, chand); - } - calld->on_done_recv->cb(calld->on_done_recv->cb_arg, success); -} - -static void server_mutate_op(grpc_call_element* elem, - grpc_transport_stream_op* op) { - call_data* calld = elem->call_data; - if (op->recv_ops) { - /* substitute our callback for the op callback */ - calld->recv_ops = op->recv_ops; - calld->on_done_recv = op->on_done_recv; - op->on_done_recv = calld->on_done_recv; - } -} - -static void server_start_transport_op(grpc_call_element* elem, - grpc_transport_stream_op* op) { - call_data* calld = elem->call_data; - GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); - server_mutate_op(elem, op); - grpc_call_next_op(elem, op); -} - -static void client_init_call_elem(grpc_call_element* elem, - const void* server_transport_data, - grpc_transport_stream_op* initial_op) { - call_data* d = elem->call_data; - GPR_ASSERT(d != NULL); - d->start_ts = gpr_now(GPR_CLOCK_REALTIME); - if (initial_op) client_mutate_op(elem, initial_op); -} - -static void client_destroy_call_elem(grpc_call_element* elem) { - call_data* d = elem->call_data; - GPR_ASSERT(d != NULL); - /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ -} - -static void server_init_call_elem(grpc_call_element* elem, - const void* server_transport_data, - grpc_transport_stream_op* initial_op) { - call_data* d = elem->call_data; - GPR_ASSERT(d != NULL); - d->start_ts = gpr_now(GPR_CLOCK_REALTIME); - /* TODO(hongyu): call census_tracing_start_op here. */ - grpc_iomgr_closure_init(d->on_done_recv, server_on_done_recv, elem); - if (initial_op) server_mutate_op(elem, initial_op); -} - -static void server_destroy_call_elem(grpc_call_element* elem) { - call_data* d = elem->call_data; - GPR_ASSERT(d != NULL); - /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */ -} - -static void init_channel_elem(grpc_channel_element* elem, grpc_channel* master, - const grpc_channel_args* args, grpc_mdctx* mdctx, - int is_first, int is_last) { - channel_data* chand = elem->channel_data; - GPR_ASSERT(chand != NULL); - chand->path_str = grpc_mdstr_from_string(mdctx, ":path", 0); -} - -static void destroy_channel_elem(grpc_channel_element* elem) { - channel_data* chand = elem->channel_data; - GPR_ASSERT(chand != NULL); - if (chand->path_str != NULL) { - GRPC_MDSTR_UNREF(chand->path_str); - } -} - -const grpc_channel_filter grpc_client_census_filter = { - client_start_transport_op, - grpc_channel_next_op, - sizeof(call_data), - client_init_call_elem, - client_destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "census-client"}; - -const grpc_channel_filter grpc_server_census_filter = { - server_start_transport_op, - grpc_channel_next_op, - sizeof(call_data), - server_init_call_elem, - server_destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "census-server"}; diff --git a/src/core/census/census_filter.h b/src/core/census/census_filter.h deleted file mode 100644 index 1453c05d28..0000000000 --- a/src/core/census/census_filter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H -#define GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H - -#include "src/core/channel/channel_stack.h" - -/* Census filters: provides tracing and stats collection functionalities. It - needs to reside right below the surface filter in the channel stack. */ -extern const grpc_channel_filter grpc_client_census_filter; -extern const grpc_channel_filter grpc_server_census_filter; - -#endif /* GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H */ diff --git a/src/core/census/grpc_filter.c b/src/core/census/grpc_filter.c new file mode 100644 index 0000000000..fbedb35661 --- /dev/null +++ b/src/core/census/grpc_filter.c @@ -0,0 +1,197 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/census/grpc_filter.h" + +#include +#include + +#include "include/grpc/census.h" +#include "src/core/census/rpc_stat_id.h" +#include "src/core/channel/channel_stack.h" +#include "src/core/channel/noop_filter.h" +#include "src/core/statistics/census_interface.h" +#include "src/core/statistics/census_rpc_stats.h" +#include +#include +#include +#include + +typedef struct call_data { + census_op_id op_id; + census_context* ctxt; + gpr_timespec start_ts; + int error; + + /* recv callback */ + grpc_stream_op_buffer* recv_ops; + grpc_iomgr_closure* on_done_recv; +} call_data; + +typedef struct channel_data { + grpc_mdstr* path_str; /* pointer to meta data str with key == ":path" */ +} channel_data; + +static void extract_and_annotate_method_tag(grpc_stream_op_buffer* sopb, + call_data* calld, + channel_data* chand) { + grpc_linked_mdelem* m; + size_t i; + for (i = 0; i < sopb->nops; i++) { + grpc_stream_op* op = &sopb->ops[i]; + if (op->type != GRPC_OP_METADATA) continue; + for (m = op->data.metadata.list.head; m != NULL; m = m->next) { + if (m->md->key == chand->path_str) { + gpr_log(GPR_DEBUG, "%s", + (const char*)GPR_SLICE_START_PTR(m->md->value->slice)); + /* Add method tag here */ + } + } + } +} + +static void client_mutate_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { + call_data* calld = elem->call_data; + channel_data* chand = elem->channel_data; + if (op->send_ops) { + extract_and_annotate_method_tag(op->send_ops, calld, chand); + } +} + +static void client_start_transport_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { + client_mutate_op(elem, op); + grpc_call_next_op(elem, op); +} + +static void server_on_done_recv(void* ptr, int success) { + grpc_call_element* elem = ptr; + call_data* calld = elem->call_data; + channel_data* chand = elem->channel_data; + if (success) { + extract_and_annotate_method_tag(calld->recv_ops, calld, chand); + } + calld->on_done_recv->cb(calld->on_done_recv->cb_arg, success); +} + +static void server_mutate_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { + call_data* calld = elem->call_data; + if (op->recv_ops) { + /* substitute our callback for the op callback */ + calld->recv_ops = op->recv_ops; + calld->on_done_recv = op->on_done_recv; + op->on_done_recv = calld->on_done_recv; + } +} + +static void server_start_transport_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { + call_data* calld = elem->call_data; + GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); + server_mutate_op(elem, op); + grpc_call_next_op(elem, op); +} + +static void client_init_call_elem(grpc_call_element* elem, + const void* server_transport_data, + grpc_transport_stream_op* initial_op) { + call_data* d = elem->call_data; + GPR_ASSERT(d != NULL); + d->start_ts = gpr_now(GPR_CLOCK_REALTIME); + if (initial_op) client_mutate_op(elem, initial_op); +} + +static void client_destroy_call_elem(grpc_call_element* elem) { + call_data* d = elem->call_data; + GPR_ASSERT(d != NULL); + /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ +} + +static void server_init_call_elem(grpc_call_element* elem, + const void* server_transport_data, + grpc_transport_stream_op* initial_op) { + call_data* d = elem->call_data; + GPR_ASSERT(d != NULL); + d->start_ts = gpr_now(GPR_CLOCK_REALTIME); + /* TODO(hongyu): call census_tracing_start_op here. */ + grpc_iomgr_closure_init(d->on_done_recv, server_on_done_recv, elem); + if (initial_op) server_mutate_op(elem, initial_op); +} + +static void server_destroy_call_elem(grpc_call_element* elem) { + call_data* d = elem->call_data; + GPR_ASSERT(d != NULL); + /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */ +} + +static void init_channel_elem(grpc_channel_element* elem, grpc_channel* master, + const grpc_channel_args* args, grpc_mdctx* mdctx, + int is_first, int is_last) { + channel_data* chand = elem->channel_data; + GPR_ASSERT(chand != NULL); + chand->path_str = grpc_mdstr_from_string(mdctx, ":path", 0); +} + +static void destroy_channel_elem(grpc_channel_element* elem) { + channel_data* chand = elem->channel_data; + GPR_ASSERT(chand != NULL); + if (chand->path_str != NULL) { + GRPC_MDSTR_UNREF(chand->path_str); + } +} + +const grpc_channel_filter grpc_client_census_filter = { + client_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + client_init_call_elem, + client_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "census-client"}; + +const grpc_channel_filter grpc_server_census_filter = { + server_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + server_init_call_elem, + server_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "census-server"}; diff --git a/src/core/census/grpc_filter.h b/src/core/census/grpc_filter.h new file mode 100644 index 0000000000..1453c05d28 --- /dev/null +++ b/src/core/census/grpc_filter.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H +#define GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H + +#include "src/core/channel/channel_stack.h" + +/* Census filters: provides tracing and stats collection functionalities. It + needs to reside right below the surface filter in the channel stack. */ +extern const grpc_channel_filter grpc_client_census_filter; +extern const grpc_channel_filter grpc_server_census_filter; + +#endif /* GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H */ diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c index 1b3707a091..707251da89 100644 --- a/src/core/surface/channel_create.c +++ b/src/core/surface/channel_create.c @@ -38,7 +38,7 @@ #include -#include "src/core/census/census_filter.h" +#include "src/core/census/grpc_filter.h" #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" #include "src/core/channel/compress_filter.h" diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index cf204e112b..eccee24698 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -38,7 +38,7 @@ #include -#include "src/core/census/census_filter.h" +#include "src/core/census/grpc_filter.h" #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" #include "src/core/channel/compress_filter.h" diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 145fa6ee1a..292bf6fab8 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -41,7 +41,7 @@ #include #include -#include "src/core/census/census_filter.h" +#include "src/core/census/grpc_filter.h" #include "src/core/channel/channel_args.h" #include "src/core/channel/connected_channel.h" #include "src/core/iomgr/iomgr.h" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 5b0abc571b..d27c5d9246 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -780,7 +780,7 @@ src/core/tsi/fake_transport_security.h \ src/core/tsi/ssl_transport_security.h \ src/core/tsi/transport_security.h \ src/core/tsi/transport_security_interface.h \ -src/core/census/census_filter.h \ +src/core/census/grpc_filter.h \ src/core/channel/channel_args.h \ src/core/channel/channel_stack.h \ src/core/channel/client_channel.h \ @@ -903,8 +903,8 @@ src/core/surface/secure_channel_create.c \ src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ -src/core/census/census_filter.c \ src/core/census/grpc_context.c \ +src/core/census/grpc_filter.c \ src/core/channel/channel_args.c \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index c7e5af6e71..97659c11a6 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -12269,8 +12269,8 @@ "include/grpc/grpc.h", "include/grpc/grpc_security.h", "include/grpc/status.h", - "src/core/census/census_filter.h", "src/core/census/context.h", + "src/core/census/grpc_filter.h", "src/core/census/rpc_stat_id.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", @@ -12395,11 +12395,11 @@ "include/grpc/grpc.h", "include/grpc/grpc_security.h", "include/grpc/status.h", - "src/core/census/census_filter.c", - "src/core/census/census_filter.h", "src/core/census/context.c", "src/core/census/context.h", "src/core/census/grpc_context.c", + "src/core/census/grpc_filter.c", + "src/core/census/grpc_filter.h", "src/core/census/initialize.c", "src/core/census/record_stat.c", "src/core/census/rpc_stat_id.h", @@ -12744,8 +12744,8 @@ "include/grpc/compression.h", "include/grpc/grpc.h", "include/grpc/status.h", - "src/core/census/census_filter.h", "src/core/census/context.h", + "src/core/census/grpc_filter.h", "src/core/census/rpc_stat_id.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", @@ -12856,11 +12856,11 @@ "include/grpc/compression.h", "include/grpc/grpc.h", "include/grpc/status.h", - "src/core/census/census_filter.c", - "src/core/census/census_filter.h", "src/core/census/context.c", "src/core/census/context.h", "src/core/census/grpc_context.c", + "src/core/census/grpc_filter.c", + "src/core/census/grpc_filter.h", "src/core/census/initialize.c", "src/core/census/record_stat.c", "src/core/census/rpc_stat_id.h", diff --git a/vsprojects/grpc/grpc.vcxproj b/vsprojects/grpc/grpc.vcxproj index aacf42d373..500cf9feb5 100644 --- a/vsprojects/grpc/grpc.vcxproj +++ b/vsprojects/grpc/grpc.vcxproj @@ -242,7 +242,7 @@ - + @@ -388,10 +388,10 @@ - - + + diff --git a/vsprojects/grpc/grpc.vcxproj.filters b/vsprojects/grpc/grpc.vcxproj.filters index 40551bf3e7..02060b7830 100644 --- a/vsprojects/grpc/grpc.vcxproj.filters +++ b/vsprojects/grpc/grpc.vcxproj.filters @@ -64,10 +64,10 @@ src\core\tsi - + src\core\census - + src\core\census @@ -485,7 +485,7 @@ src\core\tsi - + src\core\census diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj index 004565b6da..13c018c020 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj @@ -225,7 +225,7 @@ - + @@ -331,10 +331,10 @@ - - + + diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters index f2fa433881..5adcdd6092 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -4,10 +4,10 @@ src\core\surface - + src\core\census - + src\core\census @@ -383,7 +383,7 @@ - + src\core\census -- cgit v1.2.3 From bc85be10ef420f35d660bc12afb47580acec3143 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 24 Aug 2015 10:36:39 -0700 Subject: Refactor default host name resolution Rephrase API's such that resolvers are constrained to be able to provide a default host given just the text of the URI channel target. This avoids needing to rewrite such details in the core library during retries, and generally makes things much saner to debug. --- src/core/channel/http_client_filter.c | 33 --------- src/core/client_config/resolver_factory.c | 6 ++ src/core/client_config/resolver_factory.h | 9 +++ src/core/client_config/resolver_registry.c | 79 ++++++++++++---------- src/core/client_config/resolver_registry.h | 15 ++-- src/core/client_config/resolvers/dns_resolver.c | 25 +++---- .../client_config/resolvers/sockaddr_resolver.c | 49 ++++++++++---- .../client_config/resolvers/zookeeper_resolver.c | 11 ++- src/core/surface/channel.c | 24 +++++++ src/core/surface/init.c | 8 +-- test/core/end2end/tests/default_host.c | 2 +- 11 files changed, 148 insertions(+), 113 deletions(-) (limited to 'src/core/surface') diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index 48c623d359..2b61d33c29 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -45,7 +45,6 @@ typedef struct call_data { grpc_linked_mdelem content_type; grpc_linked_mdelem user_agent; int sent_initial_metadata; - int sent_authority; int got_initial_metadata; grpc_stream_op_buffer *recv_ops; @@ -64,7 +63,6 @@ typedef struct channel_data { grpc_mdelem *scheme; grpc_mdelem *content_type; grpc_mdelem *status; - grpc_mdelem *default_authority; /** complete user agent mdelem */ grpc_mdelem *user_agent; } channel_data; @@ -103,7 +101,6 @@ static void hc_on_recv(void *user_data, int success) { static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { grpc_call_element *elem = user_data; - call_data *calld = elem->call_data; channel_data *channeld = elem->channel_data; /* eat the things we'd like to set ourselves */ if (md->key == channeld->method->key) return NULL; @@ -111,10 +108,6 @@ static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { if (md->key == channeld->te_trailers->key) return NULL; if (md->key == channeld->content_type->key) return NULL; if (md->key == channeld->user_agent->key) return NULL; - if (channeld->default_authority && - channeld->default_authority->key == md->key) { - calld->sent_authority = 1; - } return md; } @@ -138,11 +131,6 @@ static void hc_mutate_op(grpc_call_element *elem, GRPC_MDELEM_REF(channeld->method)); grpc_metadata_batch_add_head(&op->data.metadata, &calld->scheme, GRPC_MDELEM_REF(channeld->scheme)); - if (channeld->default_authority && !calld->sent_authority) { - grpc_metadata_batch_add_head( - &op->data.metadata, &calld->authority, - GRPC_MDELEM_REF(channeld->default_authority)); - } grpc_metadata_batch_add_tail(&op->data.metadata, &calld->te_trailers, GRPC_MDELEM_REF(channeld->te_trailers)); grpc_metadata_batch_add_tail(&op->data.metadata, &calld->content_type, @@ -175,7 +163,6 @@ static void init_call_elem(grpc_call_element *elem, call_data *calld = elem->call_data; calld->sent_initial_metadata = 0; calld->got_initial_metadata = 0; - calld->sent_authority = 0; calld->on_done_recv = NULL; grpc_iomgr_closure_init(&calld->hc_on_recv, hc_on_recv, elem); if (initial_op) hc_mutate_op(elem, initial_op); @@ -257,8 +244,6 @@ static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx, static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *channel_args, grpc_mdctx *mdctx, int is_first, int is_last) { - size_t i; - /* grab pointers to our data from the channel element */ channel_data *channeld = elem->channel_data; @@ -267,21 +252,6 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, path */ GPR_ASSERT(!is_last); - channeld->default_authority = NULL; - if (channel_args) { - for (i = 0; i < channel_args->num_args; i++) { - if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) { - if (channel_args->args[i].type != GRPC_ARG_STRING) { - gpr_log(GPR_ERROR, "%s: must be an string", - GRPC_ARG_DEFAULT_AUTHORITY); - } else { - channeld->default_authority = grpc_mdelem_from_strings( - mdctx, ":authority", channel_args->args[i].value.string); - } - } - } - } - /* initialize members */ channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers"); channeld->method = grpc_mdelem_from_strings(mdctx, ":method", "POST"); @@ -306,9 +276,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) { GRPC_MDELEM_UNREF(channeld->content_type); GRPC_MDELEM_UNREF(channeld->status); GRPC_MDELEM_UNREF(channeld->user_agent); - if (channeld->default_authority) { - GRPC_MDELEM_UNREF(channeld->default_authority); - } } const grpc_channel_filter grpc_http_client_filter = { diff --git a/src/core/client_config/resolver_factory.c b/src/core/client_config/resolver_factory.c index 6721977e21..bf631cefd1 100644 --- a/src/core/client_config/resolver_factory.c +++ b/src/core/client_config/resolver_factory.c @@ -48,3 +48,9 @@ grpc_resolver *grpc_resolver_factory_create_resolver( if (!factory) return NULL; return factory->vtable->create_resolver(factory, uri, subchannel_factory); } + +char *grpc_resolver_factory_get_default_authority( + grpc_resolver_factory *factory, grpc_uri *uri) { + if (!factory) return NULL; + return factory->vtable->get_default_authority(factory, uri); +} diff --git a/src/core/client_config/resolver_factory.h b/src/core/client_config/resolver_factory.h index c5d85499c6..73a0564230 100644 --- a/src/core/client_config/resolver_factory.h +++ b/src/core/client_config/resolver_factory.h @@ -54,6 +54,10 @@ struct grpc_resolver_factory_vtable { grpc_resolver *(*create_resolver)( grpc_resolver_factory *factory, grpc_uri *uri, grpc_subchannel_factory *subchannel_factory); + + char *(*get_default_authority)(grpc_resolver_factory *factory, grpc_uri *uri); + + const char *scheme; }; void grpc_resolver_factory_ref(grpc_resolver_factory *resolver); @@ -64,4 +68,9 @@ grpc_resolver *grpc_resolver_factory_create_resolver( grpc_resolver_factory *factory, grpc_uri *uri, grpc_subchannel_factory *subchannel_factory); +/** Return a (freshly allocated with gpr_malloc) string representing + the default authority to use for this scheme. */ +char *grpc_resolver_factory_get_default_authority( + grpc_resolver_factory *factory, grpc_uri *uri); + #endif /* GRPC_INTERNAL_CORE_CONFIG_RESOLVER_FACTORY_H */ diff --git a/src/core/client_config/resolver_registry.c b/src/core/client_config/resolver_registry.c index 16be2da994..3aff4630fb 100644 --- a/src/core/client_config/resolver_registry.c +++ b/src/core/client_config/resolver_registry.c @@ -41,41 +41,33 @@ #define MAX_RESOLVERS 10 -typedef struct { - char *scheme; - grpc_resolver_factory *factory; -} registered_resolver; - -static registered_resolver g_all_of_the_resolvers[MAX_RESOLVERS]; +static grpc_resolver_factory *g_all_of_the_resolvers[MAX_RESOLVERS]; static int g_number_of_resolvers = 0; -static char *g_default_resolver_scheme; +static char *g_default_resolver_prefix; -void grpc_resolver_registry_init(const char *default_resolver_scheme) { +void grpc_resolver_registry_init(const char *default_resolver_prefix) { g_number_of_resolvers = 0; - g_default_resolver_scheme = gpr_strdup(default_resolver_scheme); + g_default_resolver_prefix = gpr_strdup(default_resolver_prefix); } void grpc_resolver_registry_shutdown(void) { int i; for (i = 0; i < g_number_of_resolvers; i++) { - gpr_free(g_all_of_the_resolvers[i].scheme); - grpc_resolver_factory_unref(g_all_of_the_resolvers[i].factory); + grpc_resolver_factory_unref(g_all_of_the_resolvers[i]); } - gpr_free(g_default_resolver_scheme); + gpr_free(g_default_resolver_prefix); } -void grpc_register_resolver_type(const char *scheme, - grpc_resolver_factory *factory) { +void grpc_register_resolver_type(grpc_resolver_factory *factory) { int i; for (i = 0; i < g_number_of_resolvers; i++) { - GPR_ASSERT(0 != strcmp(scheme, g_all_of_the_resolvers[i].scheme)); + GPR_ASSERT(0 != strcmp(factory->vtable->scheme, + g_all_of_the_resolvers[i]->vtable->scheme)); } GPR_ASSERT(g_number_of_resolvers != MAX_RESOLVERS); - g_all_of_the_resolvers[g_number_of_resolvers].scheme = gpr_strdup(scheme); grpc_resolver_factory_ref(factory); - g_all_of_the_resolvers[g_number_of_resolvers].factory = factory; - g_number_of_resolvers++; + g_all_of_the_resolvers[g_number_of_resolvers++] = factory; } static grpc_resolver_factory *lookup_factory(grpc_uri *uri) { @@ -85,40 +77,53 @@ static grpc_resolver_factory *lookup_factory(grpc_uri *uri) { if (!uri) return NULL; for (i = 0; i < g_number_of_resolvers; i++) { - if (0 == strcmp(uri->scheme, g_all_of_the_resolvers[i].scheme)) { - return g_all_of_the_resolvers[i].factory; + if (0 == strcmp(uri->scheme, g_all_of_the_resolvers[i]->vtable->scheme)) { + return g_all_of_the_resolvers[i]; } } return NULL; } -grpc_resolver *grpc_resolver_create( - const char *name, grpc_subchannel_factory *subchannel_factory) { - grpc_uri *uri; +static grpc_resolver_factory *resolve_factory(const char *target, + grpc_uri **uri) { char *tmp; grpc_resolver_factory *factory = NULL; - grpc_resolver *resolver; - - uri = grpc_uri_parse(name, 1); - factory = lookup_factory(uri); - if (factory == NULL && g_default_resolver_scheme != NULL) { - grpc_uri_destroy(uri); - gpr_asprintf(&tmp, "%s%s", g_default_resolver_scheme, name); - uri = grpc_uri_parse(tmp, 1); - factory = lookup_factory(uri); + + *uri = grpc_uri_parse(target, 1); + factory = lookup_factory(*uri); + if (factory == NULL && g_default_resolver_prefix != NULL) { + grpc_uri_destroy(*uri); + gpr_asprintf(&tmp, "%s%s", g_default_resolver_prefix, target); + *uri = grpc_uri_parse(tmp, 1); + factory = lookup_factory(*uri); if (factory == NULL) { - grpc_uri_destroy(grpc_uri_parse(name, 0)); + grpc_uri_destroy(grpc_uri_parse(target, 0)); grpc_uri_destroy(grpc_uri_parse(tmp, 0)); - gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", name, tmp); + gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target, tmp); } gpr_free(tmp); } else if (factory == NULL) { - grpc_uri_destroy(grpc_uri_parse(name, 0)); - gpr_log(GPR_ERROR, "don't know how to resolve '%s'", name); + grpc_uri_destroy(grpc_uri_parse(target, 0)); + gpr_log(GPR_ERROR, "don't know how to resolve '%s'", target); } - resolver = + return factory; +} + +grpc_resolver *grpc_resolver_create( + const char *target, grpc_subchannel_factory *subchannel_factory) { + grpc_uri *uri = NULL; + grpc_resolver_factory *factory = resolve_factory(target, &uri); + grpc_resolver *resolver = grpc_resolver_factory_create_resolver(factory, uri, subchannel_factory); grpc_uri_destroy(uri); return resolver; } + +char *grpc_get_default_authority(const char *target) { + grpc_uri *uri = NULL; + grpc_resolver_factory *factory = resolve_factory(target, &uri); + char *authority = grpc_resolver_factory_get_default_authority(factory, uri); + grpc_uri_destroy(uri); + return authority; +} diff --git a/src/core/client_config/resolver_registry.h b/src/core/client_config/resolver_registry.h index 31aa47620a..5a7193b7ae 100644 --- a/src/core/client_config/resolver_registry.h +++ b/src/core/client_config/resolver_registry.h @@ -44,19 +44,22 @@ void grpc_resolver_registry_shutdown(void); If \a priority is greater than zero, then the resolver will be eligible to resolve names that are passed in with no scheme. Higher priority resolvers will be tried before lower priority schemes. */ -void grpc_register_resolver_type(const char *scheme, - grpc_resolver_factory *factory); +void grpc_register_resolver_type(grpc_resolver_factory *factory); -/** Create a resolver given \a name. - First tries to parse \a name as a URI. If this succeeds, tries +/** Create a resolver given \a target. + First tries to parse \a target as a URI. If this succeeds, tries to locate a registered resolver factory based on the URI scheme. If parsing or location fails, prefixes default_prefix from - grpc_resolver_registry_init to name, and tries again (if default_prefix + grpc_resolver_registry_init to target, and tries again (if default_prefix was not NULL). If a resolver factory was found, use it to instantiate a resolver and return it. If a resolver factory was not found, return NULL. */ grpc_resolver *grpc_resolver_create( - const char *name, grpc_subchannel_factory *subchannel_factory); + const char *target, grpc_subchannel_factory *subchannel_factory); + +/** Given a target, return a (freshly allocated with gpr_malloc) string + representing the default authority to pass from a client. */ +char *grpc_get_default_authority(const char *target); #endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H */ diff --git a/src/core/client_config/resolvers/dns_resolver.c b/src/core/client_config/resolvers/dns_resolver.c index 7b35b7902f..84643c464a 100644 --- a/src/core/client_config/resolvers/dns_resolver.c +++ b/src/core/client_config/resolvers/dns_resolver.c @@ -203,9 +203,6 @@ static grpc_resolver *dns_create( grpc_subchannel_factory *subchannel_factory) { dns_resolver *r; const char *path = uri->path; - grpc_arg default_host_arg; - char *host; - char *port; if (0 != strcmp(uri->authority, "")) { gpr_log(GPR_ERROR, "authority based uri's not supported"); @@ -214,17 +211,6 @@ static grpc_resolver *dns_create( if (path[0] == '/') ++path; - gpr_split_host_port(path, &host, &port); - - default_host_arg.type = GRPC_ARG_STRING; - default_host_arg.key = GRPC_ARG_DEFAULT_AUTHORITY; - default_host_arg.value.string = host; - subchannel_factory = grpc_subchannel_factory_add_channel_arg( - subchannel_factory, &default_host_arg); - - gpr_free(host); - gpr_free(port); - r = gpr_malloc(sizeof(dns_resolver)); memset(r, 0, sizeof(*r)); gpr_ref_init(&r->refs, 1); @@ -233,6 +219,7 @@ static grpc_resolver *dns_create( r->name = gpr_strdup(path); r->default_port = gpr_strdup(default_port); r->subchannel_factory = subchannel_factory; + grpc_subchannel_factory_ref(subchannel_factory); r->lb_policy_factory = lb_policy_factory; return &r->base; } @@ -252,8 +239,16 @@ static grpc_resolver *dns_factory_create_resolver( subchannel_factory); } +char *dns_factory_get_default_host_name(grpc_resolver_factory *factory, + grpc_uri *uri) { + const char *path = uri->path; + if (path[0] == '/') ++path; + return gpr_strdup(path); +} + static const grpc_resolver_factory_vtable dns_factory_vtable = { - dns_factory_ref, dns_factory_unref, dns_factory_create_resolver}; + dns_factory_ref, dns_factory_unref, dns_factory_create_resolver, + dns_factory_get_default_host_name, "dns"}; static grpc_resolver_factory dns_resolver_factory = {&dns_factory_vtable}; grpc_resolver_factory *grpc_dns_resolver_factory_create() { diff --git a/src/core/client_config/resolvers/sockaddr_resolver.c b/src/core/client_config/resolvers/sockaddr_resolver.c index 74584e7e2c..eeafef4174 100644 --- a/src/core/client_config/resolvers/sockaddr_resolver.c +++ b/src/core/client_config/resolvers/sockaddr_resolver.c @@ -156,8 +156,29 @@ static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, int *len) { return 1; } + +static char *unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { + return gpr_strdup("localhost"); +} #endif +static char *ip_get_default_authority(grpc_uri *uri) { + const char *path = uri->path; + if (path[0] == '/') ++path; + return gpr_strdup(path); +} + +static char *ipv4_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { + return ip_get_default_authority(uri); +} + +static char *ipv6_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { + return ip_get_default_authority(uri); +} + static int parse_ipv4(grpc_uri *uri, struct sockaddr_storage *addr, int *len) { const char *host_port = uri->path; char *host; @@ -276,20 +297,20 @@ static void sockaddr_factory_ref(grpc_resolver_factory *factory) {} static void sockaddr_factory_unref(grpc_resolver_factory *factory) {} -#define DECL_FACTORY(name) \ - static grpc_resolver *name##_factory_create_resolver( \ - grpc_resolver_factory *factory, grpc_uri *uri, \ - grpc_subchannel_factory *subchannel_factory) { \ - return sockaddr_create(uri, grpc_create_pick_first_lb_policy, \ - subchannel_factory, parse_##name); \ - } \ - static const grpc_resolver_factory_vtable name##_factory_vtable = { \ - sockaddr_factory_ref, sockaddr_factory_unref, \ - name##_factory_create_resolver}; \ - static grpc_resolver_factory name##_resolver_factory = { \ - &name##_factory_vtable}; \ - grpc_resolver_factory *grpc_##name##_resolver_factory_create() { \ - return &name##_resolver_factory; \ +#define DECL_FACTORY(name) \ + static grpc_resolver *name##_factory_create_resolver( \ + grpc_resolver_factory *factory, grpc_uri *uri, \ + grpc_subchannel_factory *subchannel_factory) { \ + return sockaddr_create(uri, grpc_create_pick_first_lb_policy, \ + subchannel_factory, parse_##name); \ + } \ + static const grpc_resolver_factory_vtable name##_factory_vtable = { \ + sockaddr_factory_ref, sockaddr_factory_unref, \ + name##_factory_create_resolver, name##_get_default_authority, #name}; \ + static grpc_resolver_factory name##_resolver_factory = { \ + &name##_factory_vtable}; \ + grpc_resolver_factory *grpc_##name##_resolver_factory_create() { \ + return &name##_resolver_factory; \ } #ifdef GPR_POSIX_SOCKET diff --git a/src/core/client_config/resolvers/zookeeper_resolver.c b/src/core/client_config/resolvers/zookeeper_resolver.c index acb2ba136e..da399f9954 100644 --- a/src/core/client_config/resolvers/zookeeper_resolver.c +++ b/src/core/client_config/resolvers/zookeeper_resolver.c @@ -467,8 +467,7 @@ static grpc_resolver *zookeeper_create( } static void zookeeper_plugin_init() { - grpc_register_resolver_type("zookeeper", - grpc_zookeeper_resolver_factory_create()); + grpc_register_resolver_type(grpc_zookeeper_resolver_factory_create()); } void grpc_zookeeper_register() { @@ -483,6 +482,11 @@ static void zookeeper_factory_ref(grpc_resolver_factory *factory) {} static void zookeeper_factory_unref(grpc_resolver_factory *factory) {} +static char *zookeeper_factory_get_default_hostname( + grpc_resolver_factory *factory, grpc_uri *uri) { + return NULL; +} + static grpc_resolver *zookeeper_factory_create_resolver( grpc_resolver_factory *factory, grpc_uri *uri, grpc_subchannel_factory *subchannel_factory) { @@ -492,7 +496,8 @@ static grpc_resolver *zookeeper_factory_create_resolver( static const grpc_resolver_factory_vtable zookeeper_factory_vtable = { zookeeper_factory_ref, zookeeper_factory_unref, - zookeeper_factory_create_resolver}; + zookeeper_factory_create_resolver, zookeeper_factory_get_default_hostname, + "zookeeper"}; static grpc_resolver_factory zookeeper_resolver_factory = { &zookeeper_factory_vtable}; diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index e50251566d..7378929ca4 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -40,6 +40,7 @@ #include #include +#include "src/core/client_config/resolver_registry.h" #include "src/core/iomgr/iomgr.h" #include "src/core/support/string.h" #include "src/core/surface/call.h" @@ -70,6 +71,7 @@ struct grpc_channel { grpc_mdstr *grpc_message_string; grpc_mdstr *path_string; grpc_mdstr *authority_string; + grpc_mdelem *default_authority; /** mdelem for grpc-status: 0 thru grpc-status: 2 */ grpc_mdelem *grpc_status_elem[NUM_CACHED_STATUS_ELEMS]; @@ -134,10 +136,27 @@ grpc_channel *grpc_channel_create_from_filters( } else { channel->max_message_length = args->args[i].value.integer; } + } else if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) { + if (args->args[i].type != GRPC_ARG_STRING) { + gpr_log(GPR_ERROR, "%s: must be an string", + GRPC_ARG_DEFAULT_AUTHORITY); + } else { + channel->default_authority = grpc_mdelem_from_strings( + mdctx, ":authority", args->args[i].value.string); + } } } } + if (channel->is_client && channel->default_authority == NULL) { + char *default_authority = grpc_get_default_authority(target); + if (default_authority) { + channel->default_authority = grpc_mdelem_from_strings( + channel->metadata_context, ":authority", default_authority); + } + gpr_free(default_authority); + } + grpc_channel_stack_init(filters, num_filters, channel, args, channel->metadata_context, CHANNEL_STACK_FROM_CHANNEL(channel)); @@ -161,6 +180,8 @@ static grpc_call *grpc_channel_create_call_internal( send_metadata[num_metadata++] = path_mdelem; if (authority_mdelem != NULL) { send_metadata[num_metadata++] = authority_mdelem; + } else if (channel->default_authority != NULL) { + send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority); } return grpc_call_create(channel, parent_call, propagation_mask, cq, NULL, @@ -251,6 +272,9 @@ static void destroy_channel(void *p, int ok) { } gpr_free(rc); } + if (channel->default_authority != NULL) { + GRPC_MDELEM_UNREF(channel->default_authority); + } grpc_mdctx_unref(channel->metadata_context); gpr_mu_destroy(&channel->registered_call_mu); gpr_free(channel->target); diff --git a/src/core/surface/init.c b/src/core/surface/init.c index d9044549f2..0d48cd42d7 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -86,11 +86,11 @@ void grpc_init(void) { if (++g_initializations == 1) { gpr_time_init(); grpc_resolver_registry_init("dns:///"); - grpc_register_resolver_type("dns", grpc_dns_resolver_factory_create()); - grpc_register_resolver_type("ipv4", grpc_ipv4_resolver_factory_create()); - grpc_register_resolver_type("ipv6", grpc_ipv6_resolver_factory_create()); + grpc_register_resolver_type(grpc_dns_resolver_factory_create()); + grpc_register_resolver_type(grpc_ipv4_resolver_factory_create()); + grpc_register_resolver_type(grpc_ipv6_resolver_factory_create()); #ifdef GPR_POSIX_SOCKET - grpc_register_resolver_type("unix", grpc_unix_resolver_factory_create()); + grpc_register_resolver_type(grpc_unix_resolver_factory_create()); #endif grpc_register_tracer("channel", &grpc_trace_channel); grpc_register_tracer("surface", &grpc_surface_trace); diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c index 97c19db331..57f65b834b 100644 --- a/test/core/end2end/tests/default_host.c +++ b/test/core/end2end/tests/default_host.c @@ -201,7 +201,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "localhost")); + GPR_ASSERT(0 == strncmp(call_details.host, "localhost", 9)); GPR_ASSERT(was_cancelled == 1); gpr_free(details); -- cgit v1.2.3 From 25bf313c5f1cf620879232d864c69b25c39e3f4c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 24 Aug 2015 12:35:28 -0700 Subject: Fix for lame clients --- src/core/surface/channel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/surface') diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index 7378929ca4..78eeed1f59 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -148,7 +148,8 @@ grpc_channel *grpc_channel_create_from_filters( } } - if (channel->is_client && channel->default_authority == NULL) { + if (channel->is_client && channel->default_authority == NULL && + target != NULL) { char *default_authority = grpc_get_default_authority(target); if (default_authority) { channel->default_authority = grpc_mdelem_from_strings( -- cgit v1.2.3 From 775ec1decd597d9ecdf916e3d220b44283075ed9 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 25 Aug 2015 11:03:53 -0700 Subject: Use SSL override as a default host name if none is specified --- include/grpc/grpc.h | 8 ++++++++ include/grpc/grpc_security.h | 9 --------- src/core/surface/channel.c | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 9 deletions(-) (limited to 'src/core/surface') diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 101fc88d8f..145052b6d3 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -134,6 +134,14 @@ typedef struct { /** Secondary user agent: goes at the end of the user-agent metadata sent on each request */ #define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent" +/* The caller of the secure_channel_create functions may override the target + name used for SSL host name checking using this channel argument which is of + type GRPC_ARG_STRING. This *should* be used for testing only. + If this argument is not specified, the name used for SSL host name checking + will be the target parameter (assuming that the secure channel is an SSL + channel). If this parameter is specified and the underlying is not an SSL + channel, it will just be ignored. */ +#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override" /** Connectivity state of a channel. */ typedef enum { diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 7f8f4d4a05..de565b2d2f 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -142,15 +142,6 @@ grpc_credentials *grpc_iam_credentials_create(const char *authorization_token, /* --- Secure channel creation. --- */ -/* The caller of the secure_channel_create functions may override the target - name used for SSL host name checking using this channel argument which is of - type GRPC_ARG_STRING. This *should* be used for testing only. - If this argument is not specified, the name used for SSL host name checking - will be the target parameter (assuming that the secure channel is an SSL - channel). If this parameter is specified and the underlying is not an SSL - channel, it will just be ignored. */ -#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override" - /* Creates a secure channel using the passed-in credentials. */ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, const char *target, diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index 78eeed1f59..586402e21c 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -141,9 +141,28 @@ grpc_channel *grpc_channel_create_from_filters( gpr_log(GPR_ERROR, "%s: must be an string", GRPC_ARG_DEFAULT_AUTHORITY); } else { + if (channel->default_authority) { + /* setting this takes precedence over anything else */ + GRPC_MDELEM_UNREF(channel->default_authority); + } channel->default_authority = grpc_mdelem_from_strings( mdctx, ":authority", args->args[i].value.string); } + } else if (0 == + strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) { + if (args->args[i].type != GRPC_ARG_STRING) { + gpr_log(GPR_ERROR, "%s: must be an string", + GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); + } else { + if (channel->default_authority) { + /* other ways of setting this (notably ssl) take precedence */ + gpr_log(GPR_ERROR, "%s: default host already set some other way", + GRPC_ARG_DEFAULT_AUTHORITY); + } else { + channel->default_authority = grpc_mdelem_from_strings( + mdctx, ":authority", args->args[i].value.string); + } + } } } } -- cgit v1.2.3 From c5b570f97efb29db5b624e2dc360aa7e6b03780f Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Tue, 25 Aug 2015 17:47:55 -0700 Subject: Adding void* at then end of security related method in order to have a stable ABI. --- src/core/security/client_auth_filter.c | 3 +- src/core/security/credentials.c | 35 +++++++++++++++------- src/core/security/google_default_credentials.c | 6 ++-- src/core/surface/secure_channel_create.c | 4 ++- src/cpp/client/secure_credentials.cc | 21 ++++++------- src/cpp/server/secure_server_credentials.cc | 2 +- src/csharp/ext/grpc_csharp_ext.c | 8 ++--- src/node/ext/channel.cc | 2 +- src/node/ext/credentials.cc | 11 +++---- src/node/ext/server_credentials.cc | 7 ++--- .../GRPCClient/private/GRPCSecureChannel.m | 7 +++-- src/php/ext/grpc/channel.c | 2 +- src/php/ext/grpc/credentials.c | 6 ++-- src/php/ext/grpc/server_credentials.c | 2 +- src/python/grpcio/grpc/_adapter/_c/types/channel.c | 3 +- .../grpc/_adapter/_c/types/client_credentials.c | 20 +++++++------ .../grpc/_adapter/_c/types/server_credentials.c | 2 +- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd | 2 +- src/ruby/ext/grpc/rb_channel.c | 2 +- src/ruby/ext/grpc/rb_credentials.c | 11 +++---- src/ruby/ext/grpc/rb_server_credentials.c | 5 ++-- 21 files changed, 91 insertions(+), 70 deletions(-) (limited to 'src/core/surface') diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index 8e63978b82..f3ecfd0e60 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -153,7 +153,8 @@ static void send_security_metadata(grpc_call_element *elem, } if (channel_creds_has_md && call_creds_has_md) { - calld->creds = grpc_composite_credentials_create(channel_creds, ctx->creds); + calld->creds = + grpc_composite_credentials_create(channel_creds, ctx->creds, NULL); if (calld->creds == NULL) { bubble_up_error(elem, GRPC_STATUS_INVALID_ARGUMENT, "Incompatible credentials set on channel and call."); diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index 8852cab3e7..362d5f4b6f 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -298,8 +298,10 @@ static void ssl_build_server_config( } grpc_credentials *grpc_ssl_credentials_create( - const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair) { + const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, + void *reserved) { grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials)); + GPR_ASSERT(reserved == NULL); memset(c, 0, sizeof(grpc_ssl_credentials)); c->base.type = GRPC_CREDENTIALS_TYPE_SSL; c->base.vtable = &ssl_vtable; @@ -310,9 +312,11 @@ grpc_credentials *grpc_ssl_credentials_create( grpc_server_credentials *grpc_ssl_server_credentials_create( const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, - size_t num_key_cert_pairs, int force_client_auth) { + size_t num_key_cert_pairs, int force_client_auth, void *reserved) { grpc_ssl_server_credentials *c = gpr_malloc(sizeof(grpc_ssl_server_credentials)); + GPR_ASSERT(reserved == NULL); + memset(c, 0, sizeof(grpc_ssl_credentials)); memset(c, 0, sizeof(grpc_ssl_server_credentials)); c->base.type = GRPC_CREDENTIALS_TYPE_SSL; c->base.vtable = &ssl_server_vtable; @@ -430,7 +434,8 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key( } grpc_credentials *grpc_service_account_jwt_access_credentials_create( - const char *json_key, gpr_timespec token_lifetime) { + const char *json_key, gpr_timespec token_lifetime, void *reserved) { + GPR_ASSERT(reserved == NULL); return grpc_service_account_jwt_access_credentials_create_from_auth_json_key( grpc_auth_json_key_create_from_string(json_key), token_lifetime); } @@ -635,9 +640,10 @@ static void compute_engine_fetch_oauth2( metadata_req); } -grpc_credentials *grpc_compute_engine_credentials_create(void) { +grpc_credentials *grpc_compute_engine_credentials_create(void *reserved) { grpc_oauth2_token_fetcher_credentials *c = gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials)); + GPR_ASSERT(reserved == NULL); init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2); c->base.vtable = &compute_engine_vtable; return &c->base; @@ -693,10 +699,11 @@ static void service_account_fetch_oauth2( } grpc_credentials *grpc_service_account_credentials_create( - const char *json_key, const char *scope, gpr_timespec token_lifetime) { + const char *json_key, const char *scope, gpr_timespec token_lifetime, + void *reserved) { grpc_service_account_credentials *c; grpc_auth_json_key key = grpc_auth_json_key_create_from_string(json_key); - + GPR_ASSERT(reserved == NULL); if (scope == NULL || (strlen(scope) == 0) || !grpc_auth_json_key_is_valid(&key)) { gpr_log(GPR_ERROR, @@ -766,7 +773,8 @@ grpc_credentials *grpc_refresh_token_credentials_create_from_auth_refresh_token( } grpc_credentials *grpc_refresh_token_credentials_create( - const char *json_refresh_token) { + const char *json_refresh_token, void *reserved) { + GPR_ASSERT(reserved == NULL); return grpc_refresh_token_credentials_create_from_auth_refresh_token( grpc_auth_refresh_token_create_from_string(json_refresh_token)); } @@ -867,11 +875,12 @@ static grpc_credentials_vtable access_token_vtable = { access_token_has_request_metadata_only, access_token_get_request_metadata, NULL}; -grpc_credentials *grpc_access_token_credentials_create( - const char *access_token) { +grpc_credentials *grpc_access_token_credentials_create(const char *access_token, + void *reserved) { grpc_access_token_credentials *c = gpr_malloc(sizeof(grpc_access_token_credentials)); char *token_md_value; + GPR_ASSERT(reserved == NULL); memset(c, 0, sizeof(grpc_access_token_credentials)); c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2; c->base.vtable = &access_token_vtable; @@ -1101,12 +1110,14 @@ static grpc_credentials_array get_creds_array(grpc_credentials **creds_addr) { } grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1, - grpc_credentials *creds2) { + grpc_credentials *creds2, + void *reserved) { size_t i; size_t creds_array_byte_size; grpc_credentials_array creds1_array; grpc_credentials_array creds2_array; grpc_composite_credentials *c; + GPR_ASSERT(reserved == NULL); GPR_ASSERT(creds1 != NULL); GPR_ASSERT(creds2 != NULL); c = gpr_malloc(sizeof(grpc_composite_credentials)); @@ -1209,8 +1220,10 @@ static grpc_credentials_vtable iam_vtable = { iam_get_request_metadata, NULL}; grpc_credentials *grpc_iam_credentials_create(const char *token, - const char *authority_selector) { + const char *authority_selector, + void *reserved) { grpc_iam_credentials *c; + GPR_ASSERT(reserved == NULL); GPR_ASSERT(token != NULL); GPR_ASSERT(authority_selector != NULL); c = gpr_malloc(sizeof(grpc_iam_credentials)); diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c index 3631de867a..f9aa5187ce 100644 --- a/src/core/security/google_default_credentials.c +++ b/src/core/security/google_default_credentials.c @@ -194,7 +194,7 @@ grpc_credentials *grpc_google_default_credentials_create(void) { int need_compute_engine_creds = is_stack_running_on_compute_engine(); compute_engine_detection_done = 1; if (need_compute_engine_creds) { - result = grpc_compute_engine_credentials_create(); + result = grpc_compute_engine_credentials_create(NULL); } } @@ -202,9 +202,9 @@ end: if (!serving_cached_credentials && result != NULL) { /* Blend with default ssl credentials and add a global reference so that it can be cached and re-served. */ - grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL); + grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL); default_credentials = grpc_credentials_ref( - grpc_composite_credentials_create(ssl_creds, result)); + grpc_composite_credentials_create(ssl_creds, result, NULL)); GPR_ASSERT(default_credentials != NULL); grpc_credentials_unref(ssl_creds); grpc_credentials_unref(result); diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index eccee24698..35b60bdbef 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -185,7 +185,8 @@ static const grpc_subchannel_factory_vtable subchannel_factory_vtable = { - perform handshakes */ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, const char *target, - const grpc_channel_args *args) { + const grpc_channel_args *args, + void *reserved) { grpc_channel *channel; grpc_arg connector_arg; grpc_channel_args *args_copy; @@ -198,6 +199,7 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, const grpc_channel_filter *filters[MAX_FILTERS]; int n = 0; + GPR_ASSERT(reserved == NULL); if (grpc_find_security_connector_in_args(args) != NULL) { gpr_log(GPR_ERROR, "Cannot set security context in channel args."); return grpc_lame_client_channel_create( diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index f368f2590a..e0642469b4 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -46,7 +46,8 @@ std::shared_ptr SecureCredentials::CreateChannel( args.SetChannelArgs(&channel_args); return CreateChannelInternal( args.GetSslTargetNameOverride(), - grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)); + grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args, + nullptr)); } bool SecureCredentials::ApplyToCall(grpc_call* call) { @@ -75,14 +76,14 @@ std::shared_ptr SslCredentials( grpc_credentials* c_creds = grpc_ssl_credentials_create( options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), - options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair); + options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair, nullptr); return WrapCredentials(c_creds); } // Builds credentials for use when running in GCE std::shared_ptr ComputeEngineCredentials() { GrpcLibrary init; // To call grpc_init(). - return WrapCredentials(grpc_compute_engine_credentials_create()); + return WrapCredentials(grpc_compute_engine_credentials_create(nullptr)); } // Builds service account credentials. @@ -99,7 +100,7 @@ std::shared_ptr ServiceAccountCredentials( gpr_timespec lifetime = gpr_time_from_seconds(token_lifetime_seconds, GPR_TIMESPAN); return WrapCredentials(grpc_service_account_credentials_create( - json_key.c_str(), scope.c_str(), lifetime)); + json_key.c_str(), scope.c_str(), lifetime, nullptr)); } // Builds JWT credentials. @@ -114,15 +115,15 @@ std::shared_ptr ServiceAccountJWTAccessCredentials( gpr_timespec lifetime = gpr_time_from_seconds(token_lifetime_seconds, GPR_TIMESPAN); return WrapCredentials(grpc_service_account_jwt_access_credentials_create( - json_key.c_str(), lifetime)); + json_key.c_str(), lifetime, nullptr)); } // Builds refresh token credentials. std::shared_ptr RefreshTokenCredentials( const grpc::string& json_refresh_token) { GrpcLibrary init; // To call grpc_init(). - return WrapCredentials( - grpc_refresh_token_credentials_create(json_refresh_token.c_str())); + return WrapCredentials(grpc_refresh_token_credentials_create( + json_refresh_token.c_str(), nullptr)); } // Builds access token credentials. @@ -130,7 +131,7 @@ std::shared_ptr AccessTokenCredentials( const grpc::string& access_token) { GrpcLibrary init; // To call grpc_init(). return WrapCredentials( - grpc_access_token_credentials_create(access_token.c_str())); + grpc_access_token_credentials_create(access_token.c_str(), nullptr)); } // Builds IAM credentials. @@ -139,7 +140,7 @@ std::shared_ptr IAMCredentials( const grpc::string& authority_selector) { GrpcLibrary init; // To call grpc_init(). return WrapCredentials(grpc_iam_credentials_create( - authorization_token.c_str(), authority_selector.c_str())); + authorization_token.c_str(), authority_selector.c_str(), nullptr)); } // Combines two credentials objects into a composite credentials. @@ -154,7 +155,7 @@ std::shared_ptr CompositeCredentials( SecureCredentials* s2 = creds2->AsSecureCredentials(); if (s1 && s2) { return WrapCredentials(grpc_composite_credentials_create( - s1->GetRawCreds(), s2->GetRawCreds())); + s1->GetRawCreds(), s2->GetRawCreds(), nullptr)); } return nullptr; } diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index f203cf7f49..5bce9ca8b2 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -52,7 +52,7 @@ std::shared_ptr SslServerCredentials( grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create( options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), &pem_key_cert_pairs[0], pem_key_cert_pairs.size(), - options.force_client_auth); + options.force_client_auth, nullptr); return std::shared_ptr( new SecureServerCredentials(c_creds)); } diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 489e219c49..70c0fbcc50 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -837,11 +837,11 @@ grpcsharp_ssl_credentials_create(const char *pem_root_certs, if (key_cert_pair_cert_chain || key_cert_pair_private_key) { key_cert_pair.cert_chain = key_cert_pair_cert_chain; key_cert_pair.private_key = key_cert_pair_private_key; - return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair); + return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair, NULL); } else { GPR_ASSERT(!key_cert_pair_cert_chain); GPR_ASSERT(!key_cert_pair_private_key); - return grpc_ssl_credentials_create(pem_root_certs, NULL); + return grpc_ssl_credentials_create(pem_root_certs, NULL, NULL); } } @@ -852,7 +852,7 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_credentials_release(grpc_credentials *cre GPR_EXPORT grpc_channel *GPR_CALLTYPE grpcsharp_secure_channel_create(grpc_credentials *creds, const char *target, const grpc_channel_args *args) { - return grpc_secure_channel_create(creds, target, args); + return grpc_secure_channel_create(creds, target, args, NULL); } GPR_EXPORT grpc_server_credentials *GPR_CALLTYPE @@ -876,7 +876,7 @@ grpcsharp_ssl_server_credentials_create( } creds = grpc_ssl_server_credentials_create(pem_root_certs, key_cert_pairs, num_key_cert_pairs, - force_client_auth); + force_client_auth, NULL); gpr_free(key_cert_pairs); return creds; } diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc index a61c830099..9aed96bbf5 100644 --- a/src/node/ext/channel.cc +++ b/src/node/ext/channel.cc @@ -161,7 +161,7 @@ NAN_METHOD(Channel::New) { NULL); } else { wrapped_channel = - grpc_secure_channel_create(creds, *host, channel_args_ptr); + grpc_secure_channel_create(creds, *host, channel_args_ptr, NULL); } if (channel_args_ptr != NULL) { free(channel_args_ptr->args); diff --git a/src/node/ext/credentials.cc b/src/node/ext/credentials.cc index 21d61f1a7f..85a823a108 100644 --- a/src/node/ext/credentials.cc +++ b/src/node/ext/credentials.cc @@ -156,7 +156,8 @@ NAN_METHOD(Credentials::CreateSsl) { "createSSl's third argument must be a Buffer if provided"); } grpc_credentials *creds = grpc_ssl_credentials_create( - root_certs, key_cert_pair.private_key == NULL ? NULL : &key_cert_pair); + root_certs, key_cert_pair.private_key == NULL ? NULL : &key_cert_pair, + NULL); if (creds == NULL) { NanReturnNull(); } @@ -176,7 +177,7 @@ NAN_METHOD(Credentials::CreateComposite) { Credentials *creds1 = ObjectWrap::Unwrap(args[0]->ToObject()); Credentials *creds2 = ObjectWrap::Unwrap(args[1]->ToObject()); grpc_credentials *creds = grpc_composite_credentials_create( - creds1->wrapped_credentials, creds2->wrapped_credentials); + creds1->wrapped_credentials, creds2->wrapped_credentials, NULL); if (creds == NULL) { NanReturnNull(); } @@ -185,7 +186,7 @@ NAN_METHOD(Credentials::CreateComposite) { NAN_METHOD(Credentials::CreateGce) { NanScope(); - grpc_credentials *creds = grpc_compute_engine_credentials_create(); + grpc_credentials *creds = grpc_compute_engine_credentials_create(NULL); if (creds == NULL) { NanReturnNull(); } @@ -202,8 +203,8 @@ NAN_METHOD(Credentials::CreateIam) { } NanUtf8String auth_token(args[0]); NanUtf8String auth_selector(args[1]); - grpc_credentials *creds = grpc_iam_credentials_create(*auth_token, - *auth_selector); + grpc_credentials *creds = + grpc_iam_credentials_create(*auth_token, *auth_selector, NULL); if (creds == NULL) { NanReturnNull(); } diff --git a/src/node/ext/server_credentials.cc b/src/node/ext/server_credentials.cc index 6e17197e16..b1201eb664 100644 --- a/src/node/ext/server_credentials.cc +++ b/src/node/ext/server_credentials.cc @@ -178,11 +178,8 @@ NAN_METHOD(ServerCredentials::CreateSsl) { key_cert_pairs[i].cert_chain = ::node::Buffer::Data( pair_obj->Get(cert_key)); } - grpc_server_credentials *creds = - grpc_ssl_server_credentials_create(root_certs, - key_cert_pairs, - key_cert_pair_count, - force_client_auth); + grpc_server_credentials *creds = grpc_ssl_server_credentials_create( + root_certs, key_cert_pairs, key_cert_pair_count, force_client_auth, NULL); delete key_cert_pairs; if (creds == NULL) { NanReturnNull(); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m index 0a54804bb2..ce16655330 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m @@ -49,7 +49,7 @@ static grpc_credentials *CertificatesAtPath(NSString *path, NSError **errorPtr) // Passing NULL to grpc_ssl_credentials_create produces behavior we don't want, so return. return NULL; } - return grpc_ssl_credentials_create(contentInASCII.bytes, NULL); + return grpc_ssl_credentials_create(contentInASCII.bytes, NULL, NULL); } @implementation GRPCSecureChannel @@ -101,8 +101,9 @@ static grpc_credentials *CertificatesAtPath(NSString *path, NSError **errorPtr) - (instancetype)initWithHost:(NSString *)host credentials:(grpc_credentials *)credentials args:(grpc_channel_args *)args { - return (self = - [super initWithChannel:grpc_secure_channel_create(credentials, host.UTF8String, args)]); + return (self = [super + initWithChannel:grpc_secure_channel_create( + credentials, host.UTF8String, args, NULL)]); } // TODO(jcanizales): GRPCSecureChannel and GRPCUnsecuredChannel are just convenience initializers diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index 7a981675de..c92edaff6e 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -148,7 +148,7 @@ PHP_METHOD(Channel, __construct) { return; } if (args_array == NULL) { - channel->wrapped = grpc_insecure_channel_create(target, NULL, NULL); + channel->wrapped = grpc_insecure_channel_create(target, NULL, NULL, NULL); } else { array_hash = Z_ARRVAL_P(args_array); if (zend_hash_find(array_hash, "credentials", sizeof("credentials"), diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c index 01cb94e3aa..0eba6608bb 100644 --- a/src/php/ext/grpc/credentials.c +++ b/src/php/ext/grpc/credentials.c @@ -130,7 +130,7 @@ PHP_METHOD(Credentials, createSsl) { } grpc_credentials *creds = grpc_ssl_credentials_create( pem_root_certs, - pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair); + pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL); zval *creds_object = grpc_php_wrap_credentials(creds); RETURN_DESTROY_ZVAL(creds_object); } @@ -160,7 +160,7 @@ PHP_METHOD(Credentials, createComposite) { (wrapped_grpc_credentials *)zend_object_store_get_object( cred2_obj TSRMLS_CC); grpc_credentials *creds = - grpc_composite_credentials_create(cred1->wrapped, cred2->wrapped); + grpc_composite_credentials_create(cred1->wrapped, cred2->wrapped, NULL); zval *creds_object = grpc_php_wrap_credentials(creds); RETURN_DESTROY_ZVAL(creds_object); } @@ -170,7 +170,7 @@ PHP_METHOD(Credentials, createComposite) { * @return Credentials The new GCE credentials object */ PHP_METHOD(Credentials, createGce) { - grpc_credentials *creds = grpc_compute_engine_credentials_create(); + grpc_credentials *creds = grpc_compute_engine_credentials_create(NULL); zval *creds_object = grpc_php_wrap_credentials(creds); RETURN_DESTROY_ZVAL(creds_object); } diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c index e9183c4598..79188246bc 100644 --- a/src/php/ext/grpc/server_credentials.c +++ b/src/php/ext/grpc/server_credentials.c @@ -118,7 +118,7 @@ PHP_METHOD(ServerCredentials, createSsl) { /* TODO: add a force_client_auth field in ServerCredentials and pass it as * the last parameter. */ grpc_server_credentials *creds = grpc_ssl_server_credentials_create( - pem_root_certs, &pem_key_cert_pair, 1, 0); + pem_root_certs, &pem_key_cert_pair, 1, 0, NULL); zval *creds_object = grpc_php_wrap_server_credentials(creds); RETURN_DESTROY_ZVAL(creds_object); } diff --git a/src/python/grpcio/grpc/_adapter/_c/types/channel.c b/src/python/grpcio/grpc/_adapter/_c/types/channel.c index c577ac05eb..35715e81d4 100644 --- a/src/python/grpcio/grpc/_adapter/_c/types/channel.c +++ b/src/python/grpcio/grpc/_adapter/_c/types/channel.c @@ -106,7 +106,8 @@ Channel *pygrpc_Channel_new( } self = (Channel *)type->tp_alloc(type, 0); if (creds) { - self->c_chan = grpc_secure_channel_create(creds->c_creds, target, &c_args); + self->c_chan = + grpc_secure_channel_create(creds->c_creds, target, &c_args, NULL); } else { self->c_chan = grpc_insecure_channel_create(target, &c_args, NULL); } diff --git a/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c index e314c15324..36fd207464 100644 --- a/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c +++ b/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c @@ -135,9 +135,10 @@ ClientCredentials *pygrpc_ClientCredentials_ssl( if (private_key && cert_chain) { key_cert_pair.private_key = private_key; key_cert_pair.cert_chain = cert_chain; - self->c_creds = grpc_ssl_credentials_create(root_certs, &key_cert_pair); + self->c_creds = + grpc_ssl_credentials_create(root_certs, &key_cert_pair, NULL); } else { - self->c_creds = grpc_ssl_credentials_create(root_certs, NULL); + self->c_creds = grpc_ssl_credentials_create(root_certs, NULL, NULL); } if (!self->c_creds) { Py_DECREF(self); @@ -159,8 +160,8 @@ ClientCredentials *pygrpc_ClientCredentials_composite( return NULL; } self = (ClientCredentials *)type->tp_alloc(type, 0); - self->c_creds = grpc_composite_credentials_create( - creds1->c_creds, creds2->c_creds); + self->c_creds = + grpc_composite_credentials_create(creds1->c_creds, creds2->c_creds, NULL); if (!self->c_creds) { Py_DECREF(self); PyErr_SetString(PyExc_RuntimeError, "couldn't create composite credentials"); @@ -172,7 +173,7 @@ ClientCredentials *pygrpc_ClientCredentials_composite( ClientCredentials *pygrpc_ClientCredentials_compute_engine( PyTypeObject *type, PyObject *ignored) { ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0); - self->c_creds = grpc_compute_engine_credentials_create(); + self->c_creds = grpc_compute_engine_credentials_create(NULL); if (!self->c_creds) { Py_DECREF(self); PyErr_SetString(PyExc_RuntimeError, @@ -195,7 +196,7 @@ ClientCredentials *pygrpc_ClientCredentials_service_account( } self = (ClientCredentials *)type->tp_alloc(type, 0); self->c_creds = grpc_service_account_credentials_create( - json_key, scope, pygrpc_cast_double_to_gpr_timespec(lifetime)); + json_key, scope, pygrpc_cast_double_to_gpr_timespec(lifetime), NULL); if (!self->c_creds) { Py_DECREF(self); PyErr_SetString(PyExc_RuntimeError, @@ -218,7 +219,7 @@ ClientCredentials *pygrpc_ClientCredentials_jwt( } self = (ClientCredentials *)type->tp_alloc(type, 0); self->c_creds = grpc_service_account_jwt_access_credentials_create( - json_key, pygrpc_cast_double_to_gpr_timespec(lifetime)); + json_key, pygrpc_cast_double_to_gpr_timespec(lifetime), NULL); if (!self->c_creds) { Py_DECREF(self); PyErr_SetString(PyExc_RuntimeError, "couldn't create JWT credentials"); @@ -237,7 +238,8 @@ ClientCredentials *pygrpc_ClientCredentials_refresh_token( return NULL; } self = (ClientCredentials *)type->tp_alloc(type, 0); - self->c_creds = grpc_refresh_token_credentials_create(json_refresh_token); + self->c_creds = + grpc_refresh_token_credentials_create(json_refresh_token, NULL); if (!self->c_creds) { Py_DECREF(self); PyErr_SetString(PyExc_RuntimeError, @@ -259,7 +261,7 @@ ClientCredentials *pygrpc_ClientCredentials_iam( } self = (ClientCredentials *)type->tp_alloc(type, 0); self->c_creds = grpc_iam_credentials_create(authorization_token, - authority_selector); + authority_selector, NULL); if (!self->c_creds) { Py_DECREF(self); PyErr_SetString(PyExc_RuntimeError, "couldn't create IAM credentials"); diff --git a/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c index f6859b79d7..2ba855e76c 100644 --- a/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c +++ b/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c @@ -131,7 +131,7 @@ ServerCredentials *pygrpc_ServerCredentials_ssl( /* TODO: Add a force_client_auth parameter in the python object and pass it here as the last arg. */ self->c_creds = grpc_ssl_server_credentials_create( - root_certs, key_cert_pairs, num_key_cert_pairs, 0); + root_certs, key_cert_pairs, num_key_cert_pairs, 0, NULL); gpr_free(key_cert_pairs); return self; } diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd index d065383587..c793774c8d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd @@ -332,7 +332,7 @@ cdef extern from "grpc/grpc_security.h": grpc_server_credentials *grpc_ssl_server_credentials_create( const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, - size_t num_key_cert_pairs); + size_t num_key_cert_pairs) void grpc_server_credentials_release(grpc_server_credentials *creds) int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 6491aa4fb4..90afdc3fe1 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -150,7 +150,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) { ch = grpc_insecure_channel_create(target_chars, &args, NULL); } else { creds = grpc_rb_get_wrapped_credentials(credentials); - ch = grpc_secure_channel_create(creds, target_chars, &args); + ch = grpc_secure_channel_create(creds, target_chars, &args, NULL); } if (args.args != NULL) { xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */ diff --git a/src/ruby/ext/grpc/rb_credentials.c b/src/ruby/ext/grpc/rb_credentials.c index a9dcdbce9f..ac3804df6f 100644 --- a/src/ruby/ext/grpc/rb_credentials.c +++ b/src/ruby/ext/grpc/rb_credentials.c @@ -154,7 +154,7 @@ static VALUE grpc_rb_default_credentials_create(VALUE cls) { Creates the default credential instances. */ static VALUE grpc_rb_compute_engine_credentials_create(VALUE cls) { grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials); - wrapper->wrapped = grpc_compute_engine_credentials_create(); + wrapper->wrapped = grpc_compute_engine_credentials_create(NULL); if (wrapper->wrapped == NULL) { rb_raise(rb_eRuntimeError, "could not create composite engine credentials, not sure why"); @@ -181,8 +181,8 @@ static VALUE grpc_rb_composite_credentials_create(VALUE self, VALUE other) { TypedData_Get_Struct(other, grpc_rb_credentials, &grpc_rb_credentials_data_type, other_wrapper); wrapper = ALLOC(grpc_rb_credentials); - wrapper->wrapped = grpc_composite_credentials_create(self_wrapper->wrapped, - other_wrapper->wrapped); + wrapper->wrapped = grpc_composite_credentials_create( + self_wrapper->wrapped, other_wrapper->wrapped, NULL); if (wrapper->wrapped == NULL) { rb_raise(rb_eRuntimeError, "could not create composite credentials, not sure why"); @@ -234,12 +234,13 @@ static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) { return Qnil; } if (pem_private_key == Qnil && pem_cert_chain == Qnil) { - creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), NULL); + creds = + grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), NULL, NULL); } else { key_cert_pair.private_key = RSTRING_PTR(pem_private_key); key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain); creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), - &key_cert_pair); + &key_cert_pair, NULL); } if (creds == NULL) { rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why"); diff --git a/src/ruby/ext/grpc/rb_server_credentials.c b/src/ruby/ext/grpc/rb_server_credentials.c index 62c211d769..6af4c86c45 100644 --- a/src/ruby/ext/grpc/rb_server_credentials.c +++ b/src/ruby/ext/grpc/rb_server_credentials.c @@ -178,10 +178,11 @@ static VALUE grpc_rb_server_credentials_init(VALUE self, VALUE pem_root_certs, key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain); /* TODO Add a force_client_auth parameter and pass it here. */ if (pem_root_certs == Qnil) { - creds = grpc_ssl_server_credentials_create(NULL, &key_cert_pair, 1, 0); + creds = + grpc_ssl_server_credentials_create(NULL, &key_cert_pair, 1, 0, NULL); } else { creds = grpc_ssl_server_credentials_create(RSTRING_PTR(pem_root_certs), - &key_cert_pair, 1, 0); + &key_cert_pair, 1, 0, NULL); } if (creds == NULL) { rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why"); -- cgit v1.2.3 From a0461e52f3b90afa6054f48a32a654a9c7d28f6f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 26 Aug 2015 17:26:09 -0700 Subject: Fix an edge case in call.c If we get a full incoming buffer, we'll issue a read with max_recv_bytes==0, deadlocking the flow control code. Instead, hold off on advertising reading until the buffer gets a little more clear, then start pulling. --- src/core/surface/call.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/core/surface') diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 4426bbbce9..f25ef74a92 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -630,9 +630,6 @@ static void unlock(grpc_call *call) { call->cancel_alarm = 0; if (!call->receiving && need_more_data(call)) { - op.recv_ops = &call->recv_ops; - op.recv_state = &call->recv_state; - op.on_done_recv = &call->on_done_recv; if (grpc_bbq_empty(&call->incoming_queue) && call->reading_message) { op.max_recv_bytes = call->incoming_message_length - call->incoming_message.length + MAX_RECV_PEEK_AHEAD; @@ -644,9 +641,14 @@ static void unlock(grpc_call *call) { op.max_recv_bytes = MAX_RECV_PEEK_AHEAD - buffered_bytes; } } - call->receiving = 1; - GRPC_CALL_INTERNAL_REF(call, "receiving"); - start_op = 1; + if (op.max_recv_bytes != 0) { + op.recv_ops = &call->recv_ops; + op.recv_state = &call->recv_state; + op.on_done_recv = &call->on_done_recv; + call->receiving = 1; + GRPC_CALL_INTERNAL_REF(call, "receiving"); + start_op = 1; + } } if (!call->sending) { -- cgit v1.2.3 From 3fecb24c555f45bac9110cd4a5947de91f11a78b Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 31 Aug 2015 16:38:58 -0700 Subject: Add a little experiment --- src/core/surface/call.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/core/surface') diff --git a/src/core/surface/call.c b/src/core/surface/call.c index f25ef74a92..a8b4d65fbc 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -641,7 +641,9 @@ static void unlock(grpc_call *call) { op.max_recv_bytes = MAX_RECV_PEEK_AHEAD - buffered_bytes; } } - if (op.max_recv_bytes != 0) { + /* TODO(ctiller): 1024 is basically to cover a bug + I don't understand yet */ + if (op.max_recv_bytes > 1024) { op.recv_ops = &call->recv_ops; op.recv_state = &call->recv_state; op.on_done_recv = &call->on_done_recv; -- cgit v1.2.3 From 0d728c1e9eb9f685eedc27788e6923378d115459 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 1 Sep 2015 20:23:09 +0200 Subject: Bumping revision to 0.11 for beta. --- Makefile | 2 +- build.yaml | 2 +- src/core/surface/version.c | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/core/surface') diff --git a/Makefile b/Makefile index b724ee2a7c..00875cd8e7 100644 --- a/Makefile +++ b/Makefile @@ -309,7 +309,7 @@ E = @echo Q = @ endif -VERSION = 0.10.1.0 +VERSION = 0.11.0.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/build.yaml b/build.yaml index 183c0ae78f..31a1e328a8 100644 --- a/build.yaml +++ b/build.yaml @@ -3,7 +3,7 @@ '#3': Please refer to the templates directory for more information. settings: '#': The public version number of the library. - version: {major: 0, minor: 10, micro: 1, build: 0} + version: {major: 0, minor: 11, micro: 0, build: 0} filegroups: - name: census public_headers: [include/grpc/census.h] diff --git a/src/core/surface/version.c b/src/core/surface/version.c index d7aaba3868..4b90e06a04 100644 --- a/src/core/surface/version.c +++ b/src/core/surface/version.c @@ -37,5 +37,5 @@ #include const char *grpc_version_string(void) { - return "0.10.1.0"; + return "0.11.0.0"; } diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 96708c0622..a352341774 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.10.1.0 +PROJECT_NUMBER = 0.11.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 185d24720c..dfaeb43ca7 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.10.1.0 +PROJECT_NUMBER = 0.11.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 4c83e22b7f..beb0128e41 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.10.1.0 +PROJECT_NUMBER = 0.11.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 729f8bf2ff..fdc32c7776 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.10.1.0 +PROJECT_NUMBER = 0.11.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a -- cgit v1.2.3 From d6599a39e48b152eeb1b55d427fbe5f22817b663 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 3 Sep 2015 09:37:02 -0700 Subject: Replicate C++ docs from master to beta branch Original PR #3074 by @dgquintas --- examples/cpp/helloworld/greeter_async_client.cc | 52 ++++++-- examples/cpp/helloworld/greeter_async_server.cc | 60 ++++++++-- examples/cpp/helloworld/greeter_client.cc | 24 +++- examples/cpp/helloworld/greeter_server.cc | 15 ++- include/grpc++/channel.h | 13 +- include/grpc++/client_context.h | 103 ++++++++++++++-- include/grpc++/completion_queue.h | 91 ++++++++++---- include/grpc++/create_channel.h | 19 ++- include/grpc++/grpc++.h | 64 ++++++++++ include/grpc++/security/auth_context.h | 26 +++- include/grpc++/security/credentials.h | 100 +++++++++++----- include/grpc++/security/server_credentials.h | 12 +- include/grpc++/server.h | 65 ++++++++-- include/grpc++/server_builder.h | 63 ++++++---- include/grpc++/support/async_stream.h | 37 ++++-- include/grpc++/support/byte_buffer.h | 14 ++- include/grpc++/support/channel_arguments.h | 25 ++-- include/grpc++/support/slice.h | 26 +++- include/grpc++/support/status.h | 12 ++ include/grpc++/support/status_code_enum.h | 153 +++++++++++------------- include/grpc++/support/string_ref.h | 13 +- include/grpc++/support/sync_stream.h | 89 +++++++++----- include/grpc/grpc.h | 8 +- src/core/surface/completion_queue.h | 2 +- src/cpp/util/byte_buffer.cc | 6 + 25 files changed, 786 insertions(+), 306 deletions(-) create mode 100644 include/grpc++/grpc++.h (limited to 'src/core/surface') diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc index 605fb7fb3a..923c8ffa74 100644 --- a/examples/cpp/helloworld/greeter_async_client.cc +++ b/examples/cpp/helloworld/greeter_async_client.cc @@ -35,13 +35,8 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include + #include "helloworld.grpc.pb.h" using grpc::Channel; @@ -58,39 +53,72 @@ class GreeterClient { explicit GreeterClient(std::shared_ptr channel) : stub_(Greeter::NewStub(channel)) {} + // Assambles the client's payload, sends it and presents the response back + // from the server. std::string SayHello(const std::string& user) { + // Data we are sending to the server. HelloRequest request; request.set_name(user); + + // Container for the data we expect from the server. HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. ClientContext context; + + // The producer-consumer queue we use to communicate asynchronously with the + // gRPC runtime. CompletionQueue cq; + + // Storage for the status of the RPC upon completion. Status status; + // stub_->AsyncSayHello() perform the RPC call, returning an instance we + // store in "rpc". Because we are using the asynchronous API, we need the + // hold on to the "rpc" instance in order to get updates on the ongoig RPC. std::unique_ptr > rpc( stub_->AsyncSayHello(&context, request, &cq)); + + // Request that, upon completion of the RPC, "reply" be updated with the + // server's response; "status" with the indication of whether the operation + // was successful. Tag the request with the integer 1. rpc->Finish(&reply, &status, (void*)1); void* got_tag; bool ok = false; + // Block until the next result is available in the completion queue "cq". cq.Next(&got_tag, &ok); - GPR_ASSERT(ok); + + // Verify that the result from "cq" corresponds, by its tag, our previous + // request. GPR_ASSERT(got_tag == (void*)1); + // ... and that the request was completed successfully. Note that "ok" + // corresponds solely to the request for updates introduced by Finish(). + GPR_ASSERT(ok); + // Act upon the status of the actual RPC. if (status.ok()) { return reply.message(); } else { - return "Rpc failed"; + return "RPC failed"; } } private: + // Out of the passed in Channel comes the stub, stored here, our view of the + // server's exposed services. std::unique_ptr stub_; }; int main(int argc, char** argv) { - GreeterClient greeter(grpc::CreateChannel( - "localhost:50051", grpc::InsecureCredentials())); + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureCredentials()). + GreeterClient greeter( + grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials())); std::string user("world"); - std::string reply = greeter.SayHello(user); + std::string reply = greeter.SayHello(user); // The actual RPC call! std::cout << "Greeter received: " << reply << std::endl; return 0; diff --git a/examples/cpp/helloworld/greeter_async_server.cc b/examples/cpp/helloworld/greeter_async_server.cc index 189c3afe6d..b2047a8ce5 100644 --- a/examples/cpp/helloworld/greeter_async_server.cc +++ b/examples/cpp/helloworld/greeter_async_server.cc @@ -36,13 +36,8 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include + #include "helloworld.grpc.pb.h" using grpc::Server; @@ -59,6 +54,7 @@ class ServerImpl final { public: ~ServerImpl() { server_->Shutdown(); + // Always shutdown the completion queue after the server. cq_->Shutdown(); } @@ -67,56 +63,102 @@ class ServerImpl final { std::string server_address("0.0.0.0:50051"); ServerBuilder builder; + // Listen on the given address without any authentication mechanism. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service_" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *asynchronous* service. builder.RegisterAsyncService(&service_); + // Get hold of the completion queue used for the asynchronous communication + // with the gRPC runtime. cq_ = builder.AddCompletionQueue(); + // Finally assemble the server. server_ = builder.BuildAndStart(); std::cout << "Server listening on " << server_address << std::endl; + // Proceed to the server's main loop. HandleRpcs(); } private: + // Class encompasing the state and logic needed to serve a request. class CallData { public: + // Take in the "service" instance (in this case representing an asynchronous + // server) and the completion queue "cq" used for asynchronous communication + // with the gRPC runtime. CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq) : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) { + // Invoke the serving logic right away. Proceed(); } void Proceed() { if (status_ == CREATE) { + // As part of the initial CREATE state, we *request* that the system + // start processing SayHello requests. In this request, "this" acts are + // the tag uniquely identifying the request (so that different CallData + // instances can serve different requests concurrently), in this case + // the memory address of this CallData instance. service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_, this); + // Make this instance progress to the PROCESS state. status_ = PROCESS; } else if (status_ == PROCESS) { + // Spawn a new CallData instance to serve new clients while we process + // the one for this CallData. The instance will deallocate itself as + // part of its FINISH state. new CallData(service_, cq_); + + // The actual processing. std::string prefix("Hello "); reply_.set_message(prefix + request_.name()); + + // And we are done! Let the gRPC runtime know we've finished, using the + // memory address of this instance as the uniquely identifying tag for + // the event. responder_.Finish(reply_, Status::OK, this); status_ = FINISH; } else { + GPR_ASSERT(status_ == FINISH); + // Once in the FINISH state, deallocate ourselves (CallData). delete this; } } private: + // The means of communication with the gRPC runtime for an asynchronous + // server. Greeter::AsyncService* service_; + // The producer-consumer queue where for asynchronous server notifications. ServerCompletionQueue* cq_; + // Context for the rpc, allowing to tweak aspects of it such as the use + // of compression, authentication, as well as to send metadata back to the + // client. ServerContext ctx_; + + // What we get from the client. HelloRequest request_; + // What we send back to the client. HelloReply reply_; + + // The means to get back to the client. ServerAsyncResponseWriter responder_; + + // Let's implement a tiny state machine with the following states. enum CallStatus { CREATE, PROCESS, FINISH }; - CallStatus status_; + CallStatus status_; // The current serving state. }; // This can be run in multiple threads if needed. void HandleRpcs() { + // Spawn a new CallData instance to serve new clients. new CallData(&service_, cq_.get()); - void* tag; + void* tag; // uniquely identifies a request. bool ok; while (true) { + // Block waiting to read the next event from the completion queue. The + // event is uniquely identified by its tag, which in this case is the + // memory address of a CallData instance. cq_->Next(&tag, &ok); GPR_ASSERT(ok); static_cast(tag)->Proceed(); diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc index bfb7c12724..6cd8353a9f 100644 --- a/examples/cpp/helloworld/greeter_client.cc +++ b/examples/cpp/helloworld/greeter_client.cc @@ -35,11 +35,8 @@ #include #include -#include -#include -#include -#include -#include +#include + #include "helloworld.grpc.pb.h" using grpc::Channel; @@ -54,17 +51,28 @@ class GreeterClient { GreeterClient(std::shared_ptr channel) : stub_(Greeter::NewStub(channel)) {} + // Assambles the client's payload, sends it and presents the response back + // from the server. std::string SayHello(const std::string& user) { + // Data we are sending to the server. HelloRequest request; request.set_name(user); + + // Container for the data we expect from the server. HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. ClientContext context; + // The actual RPC. Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. if (status.ok()) { return reply.message(); } else { - return "Rpc failed"; + return "RPC failed"; } } @@ -73,6 +81,10 @@ class GreeterClient { }; int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureCredentials()). GreeterClient greeter( grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials())); std::string user("world"); diff --git a/examples/cpp/helloworld/greeter_server.cc b/examples/cpp/helloworld/greeter_server.cc index b434752d87..9eab32c62b 100644 --- a/examples/cpp/helloworld/greeter_server.cc +++ b/examples/cpp/helloworld/greeter_server.cc @@ -35,11 +35,8 @@ #include #include -#include -#include -#include -#include -#include +#include + #include "helloworld.grpc.pb.h" using grpc::Server; @@ -50,6 +47,7 @@ using helloworld::HelloRequest; using helloworld::HelloReply; using helloworld::Greeter; +// Logic and data behind the server's behavior. class GreeterServiceImpl final : public Greeter::Service { Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override { @@ -64,10 +62,17 @@ void RunServer() { GreeterServiceImpl service; ServerBuilder builder; + // Listen on the given address without any authentication mechanism. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. builder.RegisterService(&service); + // Finally assemble the server. std::unique_ptr server(builder.BuildAndStart()); std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. server->Wait(); } diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h index a8af74175b..60c816d58a 100644 --- a/include/grpc++/channel.h +++ b/include/grpc++/channel.h @@ -65,18 +65,19 @@ class ClientAsyncReaderWriter; template class ClientAsyncResponseReader; +/// Channels represent a connection to an endpoint. Created by \a CreateChannel. class Channel GRPC_FINAL : public GrpcLibrary, public CallHook, public std::enable_shared_from_this { public: ~Channel(); - // Get the current channel state. If the channel is in IDLE and try_to_connect - // is set to true, try to connect. + /// Get the current channel state. If the channel is in IDLE and + /// \a try_to_connect is set to true, try to connect. grpc_connectivity_state GetState(bool try_to_connect); - // Return the tag on cq when the channel state is changed or deadline expires. - // GetState needs to called to get the current state. + /// Return the \a tag on \a cq when the channel state is changed or \a + /// deadline expires. \a GetState needs to called to get the current state. template void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline, CompletionQueue* cq, void* tag) { @@ -84,8 +85,8 @@ class Channel GRPC_FINAL : public GrpcLibrary, NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag); } - // Blocking wait for channel state change or deadline expiration. - // GetState needs to called to get the current state. + /// Blocking wait for channel state change or \a deadline expiration. + /// \a GetState needs to called to get the current state. template bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) { TimePoint deadline_tp(deadline); diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h index 917a1222a8..7046f939e5 100644 --- a/include/grpc++/client_context.h +++ b/include/grpc++/client_context.h @@ -31,6 +31,21 @@ * */ +/// A ClientContext allows the person implementing a service client to: +/// +/// - Add custom metadata key-value pairs that will propagated to the server +/// side. +/// - Control call settings such as compression and authentication. +/// - Initial and trailing metadata coming from the server. +/// - Get performance metrics (ie, census). +/// +/// Context settings are only relevant to the call they are invoked with, that +/// is to say, they aren't sticky. Some of these settings, such as the +/// compression options, can be made persistant at channel construction time +/// (see \a grpc::CreateCustomChannel). +/// +/// \warning ClientContext instances should \em not be reused across rpcs. + #ifndef GRPCXX_CLIENT_CONTEXT_H #define GRPCXX_CLIENT_CONTEXT_H @@ -72,6 +87,11 @@ template class ClientAsyncResponseReader; class ServerContext; +/// Options for \a ClientContext::FromServerContext specifying which traits from +/// the \a ServerContext to propagate (copy) from it into a new \a +/// ClientContext. +/// +/// \see ClientContext::FromServerContext class PropagationOptions { public: PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {} @@ -131,26 +151,66 @@ class ClientContext { ClientContext(); ~ClientContext(); - /// Create a new ClientContext that propagates some or all of its attributes + /// Create a new \a ClientContext as a child of an incoming server call, + /// according to \a options (\see PropagationOptions). + /// + /// \param server_context The source server context to use as the basis for + /// constructing the client context. + /// \param options The options controlling what to copy from the \a + /// server_context. + /// + /// \return A newly constructed \a ClientContext instance based on \a + /// server_context, with traits propagated (copied) according to \a options. static std::unique_ptr FromServerContext( const ServerContext& server_context, PropagationOptions options = PropagationOptions()); + /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with + /// a client call. These are made available at the server side by the \a + /// grpc::ServerContext::client_metadata() method. + /// + /// \warning This method should only be called before invoking the rpc. + /// + /// \param meta_key The metadata key. If \a meta_value is binary data, it must + /// end in "-bin". + /// \param meta_value The metadata value. If its value is binary, it must be + /// base64-encoding (see https://tools.ietf.org/html/rfc4648#section-4) and \a + /// meta_key must end in "-bin". void AddMetadata(const grpc::string& meta_key, const grpc::string& meta_value); + /// Return a collection of initial metadata key-value pairs. Note that keys + /// may happen more than once (ie, a \a std::multimap is returned). + /// + /// \warning This method should only be called after initial metadata has been + /// received. For streaming calls, see \a + /// ClientReaderInterface::WaitForInitialMetadata(). + /// + /// \return A multimap of initial metadata key-value pairs from the server. const std::multimap& GetServerInitialMetadata() { GPR_ASSERT(initial_metadata_received_); return recv_initial_metadata_; } + /// Return a collection of trailing metadata key-value pairs. Note that keys + /// may happen more than once (ie, a \a std::multimap is returned). + /// + /// \warning This method is only callable once the stream has finished. + /// + /// \return A multimap of metadata trailing key-value pairs from the server. const std::multimap& GetServerTrailingMetadata() { // TODO(yangg) check finished return trailing_metadata_; } + /// Set the deadline for the client call. + /// + /// \warning This method should only be called before invoking the rpc. + /// + /// \param deadline the deadline for the client call. Units are determined by + /// the type used. template void set_deadline(const T& deadline) { TimePoint deadline_tp(deadline); @@ -158,40 +218,65 @@ class ClientContext { } #ifndef GRPC_CXX0X_NO_CHRONO + /// Return the deadline for the client call. std::chrono::system_clock::time_point deadline() { return Timespec2Timepoint(deadline_); } #endif // !GRPC_CXX0X_NO_CHRONO + /// Return a \a gpr_timespec representation of the client call's deadline. gpr_timespec raw_deadline() { return deadline_; } + /// Set the per call authority header (see + /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3). void set_authority(const grpc::string& authority) { authority_ = authority; } - // Set credentials for the rpc. + /// Return the authentication context for this client call. + /// + /// \see grpc::AuthContext. + std::shared_ptr auth_context() const; + + /// Set credentials for the client call. + /// + /// A credentials object encapsulates all the state needed by a client to + /// authenticate with a server and make various assertions, e.g., about the + /// client’s identity, role, or whether it is authorized to make a particular + /// call. + /// + /// \see https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md void set_credentials(const std::shared_ptr& creds) { creds_ = creds; } + /// Return the compression algorithm to be used by the client call. grpc_compression_algorithm compression_algorithm() const { return compression_algorithm_; } + /// Set \a algorithm to be the compression algorithm used for the client call. + /// + /// \param algorith The compression algorithm used for the client call. void set_compression_algorithm(grpc_compression_algorithm algorithm); - std::shared_ptr auth_context() const; - - // Return the peer uri in a string. - // WARNING: this value is never authenticated or subject to any security - // related code. It must not be used for any authentication related - // functionality. Instead, use auth_context. + /// Return the peer uri in a string. + /// + /// \warning This value is never authenticated or subject to any security + /// related code. It must not be used for any authentication related + /// functionality. Instead, use auth_context. + /// + /// \return The call's peer URI. grpc::string peer() const; - // Get and set census context + /// Get and set census context void set_census_context(struct census_context* ccp) { census_context_ = ccp; } struct census_context* census_context() const { return census_context_; } + /// Send a best-effort out-of-band cancel. The call could be in any stage. + /// e.g. if it is already finished, it may still return success. + /// + /// There is no guarantee the call will be cancelled. void TryCancel(); private: diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h index d81d2e735d..0ea970417e 100644 --- a/include/grpc++/completion_queue.h +++ b/include/grpc++/completion_queue.h @@ -31,6 +31,8 @@ * */ +/// A completion queue implements a concurrent producer-consumer queue, with two +/// main methods, \a Next and \a AsyncNext. #ifndef GRPCXX_COMPLETION_QUEUE_H #define GRPCXX_COMPLETION_QUEUE_H @@ -67,53 +69,79 @@ class UnknownMethodHandler; class Channel; class ClientContext; +class CompletionQueueTag; class CompletionQueue; class RpcMethod; class Server; class ServerBuilder; class ServerContext; -class CompletionQueueTag { - public: - virtual ~CompletionQueueTag() {} - // Called prior to returning from Next(), return value - // is the status of the operation (return status is the default thing - // to do) - // If this function returns false, the tag is dropped and not returned - // from the completion queue - virtual bool FinalizeResult(void** tag, bool* status) = 0; -}; - -// grpc_completion_queue wrapper class +/// A thin wrapper around \a grpc_completion_queue (see / \a +/// src/core/surface/completion_queue.h). class CompletionQueue : public GrpcLibrary { public: + /// Default constructor. Implicitly creates a \a grpc_completion_queue + /// instance. CompletionQueue(); + + /// Wrap \a take, taking ownership of the instance. + /// + /// \param take The completion queue instance to wrap. Ownership is taken. explicit CompletionQueue(grpc_completion_queue* take); - ~CompletionQueue() GRPC_OVERRIDE; - // Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT - enum NextStatus { SHUTDOWN, GOT_EVENT, TIMEOUT }; + /// Destructor. Destroys the owned wrapped completion queue / instance. + ~CompletionQueue() GRPC_OVERRIDE; - // Nonblocking (until deadline) read from queue. - // Cannot rely on result of tag or ok if return is TIMEOUT + /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT. + enum NextStatus { + SHUTDOWN, ///< The completion queue has been shutdown. + GOT_EVENT, ///< Got a new event; \a tag will be filled in with its + ///< associated value; \a ok indicating its success. + TIMEOUT ///< deadline was reached. + }; + + /// Read from the queue, blocking up to \a deadline (or the queue's shutdown). + /// Both \a tag and \a ok are updated upon success (if an event is available + /// within the \a deadline). A \a tag points to an arbitrary location usually + /// employed to uniquely identify an event. + /// + /// \param tag[out] Upon sucess, updated to point to the event's tag. + /// \param ok[out] Upon sucess, true if read a regular event, false otherwise. + /// \param deadline[in] How long to block in wait for an event. + /// + /// \return The type of event read. template NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) { TimePoint deadline_tp(deadline); return AsyncNextInternal(tag, ok, deadline_tp.raw_time()); } - // Blocking read from queue. - // Returns false if the queue is ready for destruction, true if event - + /// Read from the queue, blocking until an event is available or the queue is + /// shutting down. + /// + /// \param tag[out] Updated to point to the read event's tag. + /// \param ok[out] true if read a regular event, false otherwise. + /// + /// \return true if read a regular event, false if the queue is shutting down. bool Next(void** tag, bool* ok) { return (AsyncNextInternal(tag, ok, gpr_inf_future(GPR_CLOCK_REALTIME)) != SHUTDOWN); } - // Shutdown has to be called, and the CompletionQueue can only be - // destructed when false is returned from Next(). + /// Request the shutdown of the queue. + /// + /// \warning This method must be called at some point. Once invoked, \a Next + /// will start to return false and \a AsyncNext will return \a + /// NextStatus::SHUTDOWN. Only once either one of these methods does that + /// (that is, once the queue has been \em drained) can an instance of this + /// class be destroyed. void Shutdown(); + /// Returns a \em raw pointer to the underlying \a grpc_completion_queue + /// instance. + /// + /// \warning Remember that the returned instance is owned. No transfer of + /// owership is performed. grpc_completion_queue* cq() { return cq_; } private: @@ -150,16 +178,29 @@ class CompletionQueue : public GrpcLibrary { NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); - // Wraps grpc_completion_queue_pluck. - // Cannot be mixed with calls to Next(). + /// Wraps \a grpc_completion_queue_pluck. + /// \warning Must not be mixed with calls to \a Next. bool Pluck(CompletionQueueTag* tag); - // Does a single polling pluck on tag + /// Performs a single polling pluck on \a tag. void TryPluck(CompletionQueueTag* tag); grpc_completion_queue* cq_; // owned }; +/// An interface allowing implementors to process and filter event tags. +class CompletionQueueTag { + public: + virtual ~CompletionQueueTag() {} + // Called prior to returning from Next(), return value is the status of the + // operation (return status is the default thing to do). If this function + // returns false, the tag is dropped and not returned from the completion + // queue + virtual bool FinalizeResult(void** tag, bool* status) = 0; +}; + +/// A specific type of completion queue used by the processing of notifications +/// by servers. Instantiated by \a ServerBuilder. class ServerCompletionQueue : public CompletionQueue { private: friend class ServerBuilder; diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h index 72f05174e1..196d2927a9 100644 --- a/include/grpc++/create_channel.h +++ b/include/grpc++/create_channel.h @@ -42,13 +42,24 @@ namespace grpc { -// If creds does not hold an object or is invalid, a lame channel is returned. +/// Create a new \a Channel pointing to \a target +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not hold +/// an object or is invalid, a lame channel is returned. +/// \param args Options for channel creation. std::shared_ptr CreateChannel( const grpc::string& target, const std::shared_ptr& creds); -// For advanced use and testing ONLY. Override default channel arguments only -// if necessary. -// If creds does not hold an object or is invalid, a lame channel is returned. +/// Create a new \em custom \a Channel pointing to \a target +/// +/// \warning For advanced use and testing ONLY. Override default channel +/// arguments only if necessary. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not hold +/// an object or is invalid, a lame channel is returned. +/// \param args Options for channel creation. std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args); diff --git a/include/grpc++/grpc++.h b/include/grpc++/grpc++.h new file mode 100644 index 0000000000..b7d5fb0bbc --- /dev/null +++ b/include/grpc++/grpc++.h @@ -0,0 +1,64 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/// \mainpage gRPC C++ API +/// +/// The gRPC C++ API mainly consists of the following classes: +/// - grpc::Channel, which represents the connection to an endpoint. See [the +/// gRPC Concepts page](http://www.grpc.io/docs/guides/concepts.html) for more +/// details. Channels are created by the factory function grpc::CreateChannel. +/// - grpc::CompletionQueue, the producer-consumer queue used for all +/// asynchronous communication with the gRPC runtime. +/// - grpc::ClientContext and grpc::ServerContext, where optional configuration +/// for an RPC can be set, such as setting custom metadata to be conveyed to the +/// peer, compression settings, authentication, etc. +/// - grpc::Server, representing a gRPC server, created by grpc::ServerBuilder. +/// +/// Refer to the +/// [examples](https://github.com/grpc/grpc/blob/master/examples/cpp) +/// for code putting these pieces into play. + +#ifndef GRPCXX_GRPCXX_H +#define GRPCXX_GRPCXX_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#endif // GRPCXX_GRPCXX_H diff --git a/include/grpc++/security/auth_context.h b/include/grpc++/security/auth_context.h index fc2701e806..4b1bbd85bc 100644 --- a/include/grpc++/security/auth_context.h +++ b/include/grpc++/security/auth_context.h @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -73,26 +74,41 @@ class AuthPropertyIterator const char* name_; }; +/// Class encapsulating the Authentication Information. +/// +/// It includes the secure identity of the peer, the type of secure transport +/// used as well as any other properties required by the authorization layer. class AuthContext { public: virtual ~AuthContext() {} - // Returns true if the peer is authenticated. + /// Returns true if the peer is authenticated. virtual bool IsPeerAuthenticated() const = 0; - // A peer identity, in general is one or more properties (in which case they - // have the same name). + /// A peer identity. + /// + /// It is, in general, comprised of one or more properties (in which case they + /// have the same name). virtual std::vector GetPeerIdentity() const = 0; virtual grpc::string GetPeerIdentityPropertyName() const = 0; - // Returns all the property values with the given name. + /// Returns all the property values with the given name. virtual std::vector FindPropertyValues( const grpc::string& name) const = 0; - // Iteration over all the properties. + /// Iteration over all the properties. virtual AuthPropertyIterator begin() const = 0; virtual AuthPropertyIterator end() const = 0; + static string transport_security_type_property_name() { + return GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME; + } + static string ssl_transport_security_type() { + return GRPC_SSL_TRANSPORT_SECURITY_TYPE; + } + static string x509_cn_property_name() { return GRPC_X509_CN_PROPERTY_NAME; } + static string x509_san_property_name() { return GRPC_X509_SAN_PROPERTY_NAME; } + // Mutation functions: should only be used by an AuthMetadataProcessor. virtual void AddProperty(const grpc::string& key, const grpc::string_ref& value) = 0; diff --git a/include/grpc++/security/credentials.h b/include/grpc++/security/credentials.h index ce5a9e0606..e423849714 100644 --- a/include/grpc++/security/credentials.h +++ b/include/grpc++/security/credentials.h @@ -44,9 +44,17 @@ class ChannelArguments; class Channel; class SecureCredentials; +/// A credentials object encapsulates all the state needed by a client to +/// authenticate with a server and make various assertions, e.g., about the +/// client’s identity, role, or whether it is authorized to make a particular +/// call. +/// +/// \see https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md class Credentials : public GrpcLibrary { public: ~Credentials() GRPC_OVERRIDE; + + /// Apply this instance's credentials to \a call. virtual bool ApplyToCall(grpc_call* call) = 0; protected: @@ -65,68 +73,96 @@ class Credentials : public GrpcLibrary { const grpc::string& target, const ChannelArguments& args) = 0; }; -// Options used to build SslCredentials -// pem_roots_cert is the buffer containing the PEM encoding of the server root -// certificates. If this parameter is empty, the default roots will be used. -// pem_private_key is the buffer containing the PEM encoding of the client's -// private key. This parameter can be empty if the client does not have a -// private key. -// pem_cert_chain is the buffer containing the PEM encoding of the client's -// certificate chain. This parameter can be empty if the client does not have -// a certificate chain. +/// Options used to build SslCredentials. struct SslCredentialsOptions { + /// The buffer containing the PEM encoding of the server root certificates. If + /// this parameter is empty, the default roots will be used. The default + /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH + /// environment variable pointing to a file on the file system containing the + /// roots. grpc::string pem_root_certs; + + /// The buffer containing the PEM encoding of the client's private key. This + /// parameter can be empty if the client does not have a private key. grpc::string pem_private_key; + + /// The buffer containing the PEM encoding of the client's certificate chain. + /// This parameter can be empty if the client does not have a certificate + /// chain. grpc::string pem_cert_chain; }; -// Factories for building different types of Credentials -// The functions may return empty shared_ptr when credentials cannot be created. -// If a Credentials pointer is returned, it can still be invalid when used to -// create a channel. A lame channel will be created then and all rpcs will -// fail on it. - -// Builds credentials with reasonable defaults. +// Factories for building different types of Credentials The functions may +// return empty shared_ptr when credentials cannot be created. If a +// Credentials pointer is returned, it can still be invalid when used to create +// a channel. A lame channel will be created then and all rpcs will fail on it. + +/// Builds credentials with reasonable defaults. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. std::shared_ptr GoogleDefaultCredentials(); -// Builds SSL Credentials given SSL specific options +/// Builds SSL Credentials given SSL specific options std::shared_ptr SslCredentials( const SslCredentialsOptions& options); -// Builds credentials for use when running in GCE +/// Builds credentials for use when running in GCE +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. std::shared_ptr GoogleComputeEngineCredentials(); -// Builds Service Account JWT Access credentials. -// json_key is the JSON key string containing the client's private key. -// token_lifetime_seconds is the lifetime in seconds of each Json Web Token -// (JWT) created with this credentials. It should not exceed -// grpc_max_auth_token_lifetime or will be cropped to this value. +/// Builds Service Account JWT Access credentials. +/// json_key is the JSON key string containing the client's private key. +/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token +/// (JWT) created with this credentials. It should not exceed +/// grpc_max_auth_token_lifetime or will be cropped to this value. std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, long token_lifetime_seconds); -// Builds refresh token credentials. -// json_refresh_token is the JSON string containing the refresh token along -// with a client_id and client_secret. +/// Builds refresh token credentials. +/// json_refresh_token is the JSON string containing the refresh token along +/// with a client_id and client_secret. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. std::shared_ptr GoogleRefreshTokenCredentials( const grpc::string& json_refresh_token); -// Builds access token credentials. -// access_token is an oauth2 access token that was fetched using an out of band -// mechanism. +/// Builds access token credentials. +/// access_token is an oauth2 access token that was fetched using an out of band +/// mechanism. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. std::shared_ptr AccessTokenCredentials( const grpc::string& access_token); -// Builds IAM credentials. +/// Builds IAM credentials. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. std::shared_ptr GoogleIAMCredentials( const grpc::string& authorization_token, const grpc::string& authority_selector); -// Combines two credentials objects into a composite credentials +/// Combines two credentials objects into a composite credentials std::shared_ptr CompositeCredentials( const std::shared_ptr& creds1, const std::shared_ptr& creds2); -// Credentials for an unencrypted, unauthenticated channel +/// Credentials for an unencrypted, unauthenticated channel std::shared_ptr InsecureCredentials(); } // namespace grpc diff --git a/include/grpc++/security/server_credentials.h b/include/grpc++/security/server_credentials.h index 2094c7403c..e933825ec3 100644 --- a/include/grpc++/security/server_credentials.h +++ b/include/grpc++/security/server_credentials.h @@ -45,7 +45,7 @@ struct grpc_server; namespace grpc { class Server; -// grpc_server_credentials wrapper class. +// Wrapper around \a grpc_server_credentials, a way to authenticate a server. class ServerCredentials { public: virtual ~ServerCredentials(); @@ -58,11 +58,16 @@ class ServerCredentials { private: friend class ::grpc::Server; + /// Tries to bind \a server to the given \a addr (eg, localhost:1234, + /// 192.168.1.1:31416, [::1]:27182, etc.) + /// + /// \return bound port number on sucess, 0 on failure. + // TODO(dgq): the "port" part seems to be a misnomer. virtual int AddPortToServer(const grpc::string& addr, grpc_server* server) = 0; }; -// Options to create ServerCredentials with SSL +/// Options to create ServerCredentials with SSL struct SslServerCredentialsOptions { SslServerCredentialsOptions() : force_client_auth(false) {} @@ -75,10 +80,11 @@ struct SslServerCredentialsOptions { bool force_client_auth; }; -// Builds SSL ServerCredentials given SSL specific options +/// Builds SSL ServerCredentials given SSL specific options std::shared_ptr SslServerCredentials( const SslServerCredentialsOptions& options); +/// Builds insecure server credentials. std::shared_ptr InsecureServerCredentials(); } // namespace grpc diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 22d14ee652..18a8017880 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -57,24 +57,30 @@ class RpcServiceMethod; class ServerAsyncStreamingInterface; class ThreadPoolInterface; -// Currently it only supports handling rpcs in a single thread. +/// Models a gRPC server. +/// +/// Servers are configured and started via \a grpc::ServerBuilder. class Server GRPC_FINAL : public GrpcLibrary, private CallHook { public: ~Server(); - // Shutdown the server, block until all rpc processing finishes. - // Forcefully terminate pending calls after deadline expires. + /// Shutdown the server, blocking until all rpc processing finishes. + /// Forcefully terminate pending calls after \a deadline expires. + /// + /// \param deadline How long to wait until pending rpcs are forcefully + /// terminated. template void Shutdown(const T& deadline) { ShutdownInternal(TimePoint(deadline).raw_time()); } - // Shutdown the server, waiting for all rpc processing to finish. + /// Shutdown the server, waiting for all rpc processing to finish. void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); } - // Block waiting for all work to complete (the server must either - // be shutting down or some other thread must call Shutdown for this - // function to ever return) + /// Block waiting for all work to complete. + /// + /// \warning The server must be either shutting down or some other thread must + /// call \a Shutdown for this function to ever return. void Wait(); private: @@ -86,22 +92,57 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook { class AsyncRequest; class ShutdownRequest; - // ServerBuilder use only + /// Server constructors. To be used by \a ServerBuilder only. + /// + /// \param thread_pool The threadpool instance to use for call processing. + /// \param thread_pool_owned Does the server own the \a thread_pool instance? + /// \param max_message_size Maximum message length that the channel can + /// receive. Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, int max_message_size); - // Register a service. This call does not take ownership of the service. - // The service must exist for the lifetime of the Server instance. + + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the Server instance. bool RegisterService(const grpc::string* host, RpcService* service); + + /// Register an asynchronous service. This call does not take ownership of the + /// service. The service must exist for the lifetime of the Server instance. bool RegisterAsyncService(const grpc::string* host, AsynchronousService* service); + + /// Register a generic service. This call does not take ownership of the + /// service. The service must exist for the lifetime of the Server instance. void RegisterAsyncGenericService(AsyncGenericService* service); - // Add a listening port. Can be called multiple times. + + /// Tries to bind \a server to the given \a addr. + /// + /// It can be invoked multiple times. + /// + /// \param addr The address to try to bind to the server (eg, localhost:1234, + /// 192.168.1.1:31416, [::1]:27182, etc.). + /// \params creds The credentials associated with the server. + /// + /// \return bound port number on sucess, 0 on failure. + /// + /// \warning It's an error to call this method on an already started server. int AddListeningPort(const grpc::string& addr, ServerCredentials* creds); - // Start the server. + + /// Start the server. + /// + /// \param cqs Completion queues for handling asynchronous services. The + /// caller is required to keep all completion queues live until the server is + /// destroyed. + /// \param num_cqs How many completion queues does \a cqs hold. + /// + /// \return true on a successful shutdown. bool Start(ServerCompletionQueue** cqs, size_t num_cqs); void HandleQueueClosed(); + + /// Process one or more incoming calls. void RunRpc(); + + /// Schedule \a RunRpc to run in the threadpool. void ScheduleCallback(); void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) GRPC_OVERRIDE; diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h index 8cd2048592..496e7862c5 100644 --- a/include/grpc++/server_builder.h +++ b/include/grpc++/server_builder.h @@ -51,57 +51,68 @@ class ServerCredentials; class SynchronousService; class ThreadPoolInterface; +/// A builder class for the creation and startup of \a grpc::Server instances. class ServerBuilder { public: ServerBuilder(); - // Register a service. This call does not take ownership of the service. - // The service must exist for the lifetime of the Server instance returned by - // BuildAndStart(). - // Matches requests with any :authority + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the \a Server instance returned + /// by \a BuildAndStart(). + /// Matches requests with any :authority void RegisterService(SynchronousService* service); - // Register an asynchronous service. - // This call does not take ownership of the service or completion queue. - // The service and completion queuemust exist for the lifetime of the Server - // instance returned by BuildAndStart(). - // Matches requests with any :authority + /// Register an asynchronous service. + /// This call does not take ownership of the service or completion queue. + /// The service and completion queuemust exist for the lifetime of the \a + /// Server instance returned by \a BuildAndStart(). + /// Matches requests with any :authority void RegisterAsyncService(AsynchronousService* service); - // Register a generic service. - // Matches requests with any :authority + /// Register a generic service. + /// Matches requests with any :authority void RegisterAsyncGenericService(AsyncGenericService* service); - // Register a service. This call does not take ownership of the service. - // The service must exist for the lifetime of the Server instance returned by - // BuildAndStart(). - // Only matches requests with :authority \a host + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the \a Server instance returned + /// by BuildAndStart(). + /// Only matches requests with :authority \a host void RegisterService(const grpc::string& host, SynchronousService* service); - // Register an asynchronous service. - // This call does not take ownership of the service or completion queue. - // The service and completion queuemust exist for the lifetime of the Server - // instance returned by BuildAndStart(). - // Only matches requests with :authority \a host + /// Register an asynchronous service. + /// This call does not take ownership of the service or completion queue. + /// The service and completion queuemust exist for the lifetime of the \a + /// Server instance returned by \a BuildAndStart(). + /// Only matches requests with :authority equal to \a host void RegisterAsyncService(const grpc::string& host, AsynchronousService* service); - // Set max message size in bytes. + /// Set max message size in bytes. void SetMaxMessageSize(int max_message_size) { max_message_size_ = max_message_size; } - // Add a listening port. Can be called multiple times. + /// Tries to bind \a server to the given \a addr. + /// + /// It can be invoked multiple times. + /// + /// \param addr The address to try to bind to the server (eg, localhost:1234, + /// 192.168.1.1:31416, [::1]:27182, etc.). + /// \params creds The credentials associated with the server. + /// \param selected_port[out] Upon success, updated to contain the port + /// number. \a nullptr otherwise. + /// + // TODO(dgq): the "port" part seems to be a misnomer. void AddListeningPort(const grpc::string& addr, std::shared_ptr creds, int* selected_port = nullptr); - // Add a completion queue for handling asynchronous services - // Caller is required to keep this completion queue live until - // the server is destroyed. + /// Add a completion queue for handling asynchronous services + /// Caller is required to keep this completion queue live until + /// the server is destroyed. std::unique_ptr AddCompletionQueue(); - // Return a running server which is ready for processing rpcs. + /// Return a running server which is ready for processing calls. std::unique_ptr BuildAndStart(); private: diff --git a/include/grpc++/support/async_stream.h b/include/grpc++/support/async_stream.h index 4c12fda12f..b4dae30cd5 100644 --- a/include/grpc++/support/async_stream.h +++ b/include/grpc++/support/async_stream.h @@ -45,32 +45,48 @@ namespace grpc { -// Async interfaces -// Common interface for all client side streaming. +/// Common interface for all client side asynchronous streaming. class ClientAsyncStreamingInterface { public: virtual ~ClientAsyncStreamingInterface() {} + /// Request notification of the reading of the initial metadata. Completion + /// will be notified by \a tag on the associated completion queue. + /// + /// \param[in] tag Tag identifying this request. virtual void ReadInitialMetadata(void* tag) = 0; + /// Request notification completion. + /// + /// \param[out] status To be updated with the operation status. + /// \param[in] tag Tag identifying this request. virtual void Finish(Status* status, void* tag) = 0; }; -// An interface that yields a sequence of R messages. +/// An interface that yields a sequence of messages of type \a R. template class AsyncReaderInterface { public: virtual ~AsyncReaderInterface() {} + /// Read a message of type \a R into \a msg. Completion will be notified by \a + /// tag on the associated completion queue. + /// + /// \param[out] msg Where to eventually store the read message. + /// \param[in] tag The tag identifying the operation. virtual void Read(R* msg, void* tag) = 0; }; -// An interface that can be fed a sequence of W messages. +/// An interface that can be fed a sequence of messages of type \a W. template class AsyncWriterInterface { public: virtual ~AsyncWriterInterface() {} + /// Request the writing of \a msg with identifying tag \a tag. + /// + /// \param[in] msg The message to be written. + /// \param[in] tag The tag identifying the operation. virtual void Write(const W& msg, void* tag) = 0; }; @@ -81,7 +97,7 @@ class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface, template class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface { public: - // Create a stream and write the first request out. + /// Create a stream and write the first request out. template ClientAsyncReader(Channel* channel, CompletionQueue* cq, const RpcMethod& method, ClientContext* context, @@ -131,10 +147,14 @@ class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface { CallOpSet finish_ops_; }; +/// Common interface for client side asynchronous writing. template class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface, public AsyncWriterInterface { public: + /// Signal the client is done with the writes. + /// + /// \param[in] tag The tag identifying the operation. virtual void WritesDone(void* tag) = 0; }; @@ -194,12 +214,15 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface { CallOpClientRecvStatus> finish_ops_; }; -// Client-side interface for bi-directional streaming. +/// Client-side interface for asynchronous bi-directional streaming. template class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface, public AsyncWriterInterface, public AsyncReaderInterface { public: + /// Signal the client is done with the writes. + /// + /// \param[in] tag The tag identifying the operation. virtual void WritesDone(void* tag) = 0; }; @@ -373,7 +396,7 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface, CallOpSet finish_ops_; }; -// Server-side interface for bi-directional streaming. +/// Server-side interface for asynchronous bi-directional streaming. template class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface, public AsyncWriterInterface, diff --git a/include/grpc++/support/byte_buffer.h b/include/grpc++/support/byte_buffer.h index 3f8cc25f47..c413703970 100644 --- a/include/grpc++/support/byte_buffer.h +++ b/include/grpc++/support/byte_buffer.h @@ -46,21 +46,24 @@ namespace grpc { +/// A sequence of bytes. class ByteBuffer GRPC_FINAL { public: + /// Constuct an empty buffer. ByteBuffer() : buffer_(nullptr) {} + /// Construct buffer from \a slices, of which there are \a nslices. ByteBuffer(const Slice* slices, size_t nslices); - ~ByteBuffer() { - if (buffer_) { - grpc_byte_buffer_destroy(buffer_); - } - } + ~ByteBuffer(); + /// Dump (read) the buffer contents into \a slices. void Dump(std::vector* slices) const; + /// Remove all data. void Clear(); + + /// Buffer size in bytes. size_t Length() const; private: @@ -78,6 +81,7 @@ class ByteBuffer GRPC_FINAL { buffer_ = buf; } + // For \a SerializationTraits's usage. grpc_byte_buffer* buffer() const { return buffer_; } grpc_byte_buffer* buffer_; diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h index cee68467c7..9957712a96 100644 --- a/include/grpc++/support/channel_arguments.h +++ b/include/grpc++/support/channel_arguments.h @@ -46,9 +46,9 @@ namespace testing { class ChannelArgumentsTest; } // namespace testing -// Options for channel creation. The user can use generic setters to pass -// key value pairs down to c channel creation code. For grpc related options, -// concrete setters are provided. +/// Options for channel creation. The user can use generic setters to pass +/// key value pairs down to c channel creation code. For grpc related options, +/// concrete setters are provided. class ChannelArguments { public: ChannelArguments() {} @@ -62,21 +62,26 @@ class ChannelArguments { void Swap(ChannelArguments& other); - // grpc specific channel argument setters - // Set target name override for SSL host name checking. + /// Populates this instance with the arguments from \a channel_args. Does not + /// take ownership of \a channel_args. + /// + /// Note that the underlying arguments are shared. Changes made to either \a + /// channel_args or this instance would be reflected on both. + void SetChannelArgs(grpc_channel_args* channel_args) const; + + // gRPC specific channel argument setters + /// Set target name override for SSL host name checking. void SetSslTargetNameOverride(const grpc::string& name); // TODO(yangg) add flow control options - - // Set the compression algorithm for the channel. + /// Set the compression algorithm for the channel. void SetCompressionAlgorithm(grpc_compression_algorithm algorithm); // Generic channel argument setters. Only for advanced use cases. + /// Set an integer argument \a value under \a key. void SetInt(const grpc::string& key, int value); + /// Set a textual argument \a value under \a key. void SetString(const grpc::string& key, const grpc::string& value); - // Populates given channel_args with args_, does not take ownership. - void SetChannelArgs(grpc_channel_args* channel_args) const; - private: friend class SecureCredentials; friend class testing::ChannelArgumentsTest; diff --git a/include/grpc++/support/slice.h b/include/grpc++/support/slice.h index b2343a7f3d..456379cc5b 100644 --- a/include/grpc++/support/slice.h +++ b/include/grpc++/support/slice.h @@ -39,28 +39,42 @@ namespace grpc { +/// A wrapper around \a grpc_slice. +/// +/// A slice represents a contiguous reference counted array of bytes. +/// It is cheap to take references to a slice, and it is cheap to create a +/// slice pointing to a subset of another slice. class Slice GRPC_FINAL { public: - // construct empty slice + /// Construct an empty slice. Slice(); - // destructor - drops one ref + // Destructor - drops one reference. ~Slice(); - // construct slice from grpc slice, adding a ref + enum AddRef { ADD_REF }; + /// Construct a slice from \a slice, adding a reference. Slice(gpr_slice slice, AddRef); - // construct slice from grpc slice, stealing a ref + enum StealRef { STEAL_REF }; + /// Construct a slice from \a slice, stealing a reference. Slice(gpr_slice slice, StealRef); - // copy constructor - adds a ref + + /// Copy constructor, adds a reference. Slice(const Slice& other); - // assignment - ref count is unchanged + + /// Assignment, reference count is unchanged. Slice& operator=(Slice other) { std::swap(slice_, other.slice_); return *this; } + /// Byte size. size_t size() const { return GPR_SLICE_LENGTH(slice_); } + + /// Raw pointer to the beginning (first element) of the slice. const gpr_uint8* begin() const { return GPR_SLICE_START_PTR(slice_); } + + /// Raw pointer to the end (one byte \em past the last element) of the slice. const gpr_uint8* end() const { return GPR_SLICE_END_PTR(slice_); } private: diff --git a/include/grpc++/support/status.h b/include/grpc++/support/status.h index 05750ff600..e59bac92d1 100644 --- a/include/grpc++/support/status.h +++ b/include/grpc++/support/status.h @@ -39,19 +39,31 @@ namespace grpc { +/// Did it work? If it didn't, why? +/// +/// See \a grpc::StatusCode for details on the available code and their meaning. class Status { public: + /// Construct an OK instance. Status() : code_(StatusCode::OK) {} + + /// Construct an instance with associated \a code and \a details (also + // referred to as "error_message"). Status(StatusCode code, const grpc::string& details) : code_(code), details_(details) {} // Pre-defined special status objects. + /// An OK pre-defined instance. static const Status& OK; + /// A CANCELLED pre-defined instance. static const Status& CANCELLED; + /// Return the instance's error code. StatusCode error_code() const { return code_; } + /// Return the instance's error message. grpc::string error_message() const { return details_; } + /// Is the status OK? bool ok() const { return code_ == StatusCode::OK; } private: diff --git a/include/grpc++/support/status_code_enum.h b/include/grpc++/support/status_code_enum.h index 7cb40452c8..ee05b40b51 100644 --- a/include/grpc++/support/status_code_enum.h +++ b/include/grpc++/support/status_code_enum.h @@ -37,120 +37,113 @@ namespace grpc { enum StatusCode { - /* Not an error; returned on success */ + /// Not an error; returned on success. OK = 0, - /* The operation was cancelled (typically by the caller). */ + /// The operation was cancelled (typically by the caller). CANCELLED = 1, - /* Unknown error. An example of where this error may be returned is - if a Status value received from another address space belongs to - an error-space that is not known in this address space. Also - errors raised by APIs that do not return enough error information - may be converted to this error. */ + /// Unknown error. An example of where this error may be returned is if a + /// Status value received from another address space belongs to an error-space + /// that is not known in this address space. Also errors raised by APIs that + /// do not return enough error information may be converted to this error. UNKNOWN = 2, - /* Client specified an invalid argument. Note that this differs - from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments - that are problematic regardless of the state of the system - (e.g., a malformed file name). */ + /// Client specified an invalid argument. Note that this differs from + /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are + /// problematic regardless of the state of the system (e.g., a malformed file + /// name). INVALID_ARGUMENT = 3, - /* Deadline expired before operation could complete. For operations - that change the state of the system, this error may be returned - even if the operation has completed successfully. For example, a - successful response from a server could have been delayed long - enough for the deadline to expire. */ + /// Deadline expired before operation could complete. For operations that + /// change the state of the system, this error may be returned even if the + /// operation has completed successfully. For example, a successful response + /// from a server could have been delayed long enough for the deadline to + /// expire. DEADLINE_EXCEEDED = 4, - /* Some requested entity (e.g., file or directory) was not found. */ + /// Some requested entity (e.g., file or directory) was not found. NOT_FOUND = 5, - /* Some entity that we attempted to create (e.g., file or directory) - already exists. */ + /// Some entity that we attempted to create (e.g., file or directory) already + /// exists. ALREADY_EXISTS = 6, - /* The caller does not have permission to execute the specified - operation. PERMISSION_DENIED must not be used for rejections - caused by exhausting some resource (use RESOURCE_EXHAUSTED - instead for those errors). PERMISSION_DENIED must not be - used if the caller can not be identified (use UNAUTHENTICATED - instead for those errors). */ + /// The caller does not have permission to execute the specified operation. + /// PERMISSION_DENIED must not be used for rejections caused by exhausting + /// some resource (use RESOURCE_EXHAUSTED instead for those errors). + /// PERMISSION_DENIED must not be used if the caller can not be identified + /// (use UNAUTHENTICATED instead for those errors). PERMISSION_DENIED = 7, - /* The request does not have valid authentication credentials for the - operation. */ + /// The request does not have valid authentication credentials for the + /// operation. UNAUTHENTICATED = 16, - /* Some resource has been exhausted, perhaps a per-user quota, or - perhaps the entire file system is out of space. */ + /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the + /// entire file system is out of space. RESOURCE_EXHAUSTED = 8, - /* Operation was rejected because the system is not in a state - required for the operation's execution. For example, directory - to be deleted may be non-empty, an rmdir operation is applied to - a non-directory, etc. - - A litmus test that may help a service implementor in deciding - between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: - (a) Use UNAVAILABLE if the client can retry just the failing call. - (b) Use ABORTED if the client should retry at a higher-level - (e.g., restarting a read-modify-write sequence). - (c) Use FAILED_PRECONDITION if the client should not retry until - the system state has been explicitly fixed. E.g., if an "rmdir" - fails because the directory is non-empty, FAILED_PRECONDITION - should be returned since the client should not retry unless - they have first fixed up the directory by deleting files from it. - (d) Use FAILED_PRECONDITION if the client performs conditional - REST Get/Update/Delete on a resource and the resource on the - server does not match the condition. E.g., conflicting - read-modify-write on the same resource. */ + /// Operation was rejected because the system is not in a state required for + /// the operation's execution. For example, directory to be deleted may be + /// non-empty, an rmdir operation is applied to a non-directory, etc. + /// + /// A litmus test that may help a service implementor in deciding + /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: + /// (a) Use UNAVAILABLE if the client can retry just the failing call. + /// (b) Use ABORTED if the client should retry at a higher-level + /// (e.g., restarting a read-modify-write sequence). + /// (c) Use FAILED_PRECONDITION if the client should not retry until + /// the system state has been explicitly fixed. E.g., if an "rmdir" + /// fails because the directory is non-empty, FAILED_PRECONDITION + /// should be returned since the client should not retry unless + /// they have first fixed up the directory by deleting files from it. + /// (d) Use FAILED_PRECONDITION if the client performs conditional + /// REST Get/Update/Delete on a resource and the resource on the + /// server does not match the condition. E.g., conflicting + /// read-modify-write on the same resource. FAILED_PRECONDITION = 9, - /* The operation was aborted, typically due to a concurrency issue - like sequencer check failures, transaction aborts, etc. - - See litmus test above for deciding between FAILED_PRECONDITION, - ABORTED, and UNAVAILABLE. */ + /// The operation was aborted, typically due to a concurrency issue like + /// sequencer check failures, transaction aborts, etc. + /// + /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, + /// and UNAVAILABLE. ABORTED = 10, - /* Operation was attempted past the valid range. E.g., seeking or - reading past end of file. - - Unlike INVALID_ARGUMENT, this error indicates a problem that may - be fixed if the system state changes. For example, a 32-bit file - system will generate INVALID_ARGUMENT if asked to read at an - offset that is not in the range [0,2^32-1], but it will generate - OUT_OF_RANGE if asked to read from an offset past the current - file size. - - There is a fair bit of overlap between FAILED_PRECONDITION and - OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific - error) when it applies so that callers who are iterating through - a space can easily look for an OUT_OF_RANGE error to detect when - they are done. */ + /// Operation was attempted past the valid range. E.g., seeking or reading + /// past end of file. + /// + /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed + /// if the system state changes. For example, a 32-bit file system will + /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the + /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from + /// an offset past the current file size. + /// + /// There is a fair bit of overlap between FAILED_PRECONDITION and + /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error) + /// when it applies so that callers who are iterating through a space can + /// easily look for an OUT_OF_RANGE error to detect when they are done. OUT_OF_RANGE = 11, - /* Operation is not implemented or not supported/enabled in this service. */ + /// Operation is not implemented or not supported/enabled in this service. UNIMPLEMENTED = 12, - /* Internal errors. Means some invariants expected by underlying - system has been broken. If you see one of these errors, - something is very broken. */ + /// Internal errors. Means some invariants expected by underlying System has + /// been broken. If you see one of these errors, Something is very broken. INTERNAL = 13, - /* The service is currently unavailable. This is a most likely a - transient condition and may be corrected by retrying with - a backoff. - - See litmus test above for deciding between FAILED_PRECONDITION, - ABORTED, and UNAVAILABLE. */ + /// The service is currently unavailable. This is a most likely a transient + /// condition and may be corrected by retrying with a backoff. + /// + /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, + /// and UNAVAILABLE. UNAVAILABLE = 14, - /* Unrecoverable data loss or corruption. */ + /// Unrecoverable data loss or corruption. DATA_LOSS = 15, - /* Force users to include a default branch: */ + /// Force users to include a default branch: DO_NOT_USE = -1 }; diff --git a/include/grpc++/support/string_ref.h b/include/grpc++/support/string_ref.h index 2bc1fecefe..a17e167d2b 100644 --- a/include/grpc++/support/string_ref.h +++ b/include/grpc++/support/string_ref.h @@ -41,11 +41,14 @@ namespace grpc { -// This class is a non owning reference to a string. -// It should be a strict subset of the upcoming std::string_ref. See: -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html -// The constexpr is dropped or replaced with const for legacy compiler -// compatibility. +/// This class is a non owning reference to a string. +/// +/// It should be a strict subset of the upcoming std::string_ref. +/// +/// \see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html +/// +/// The constexpr is dropped or replaced with const for legacy compiler +/// compatibility. class string_ref { public: // types diff --git a/include/grpc++/support/sync_stream.h b/include/grpc++/support/sync_stream.h index b4bb637ff2..514363338d 100644 --- a/include/grpc++/support/sync_stream.h +++ b/include/grpc++/support/sync_stream.h @@ -45,60 +45,78 @@ namespace grpc { -// Common interface for all client side streaming. +/// Common interface for all synchronous client side streaming. class ClientStreamingInterface { public: virtual ~ClientStreamingInterface() {} - // Wait until the stream finishes, and return the final status. When the - // client side declares it has no more message to send, either implicitly or - // by calling WritesDone, it needs to make sure there is no more message to - // be received from the server, either implicitly or by getting a false from - // a Read(). - // This function will return either: - // - when all incoming messages have been read and the server has returned - // status - // - OR when the server has returned a non-OK status + /// Wait until the stream finishes, and return the final status. When the + /// client side declares it has no more message to send, either implicitly or + /// by calling \a WritesDone(), it needs to make sure there is no more message + /// to be received from the server, either implicitly or by getting a false + /// from a \a Read(). + /// + /// This function will return either: + /// - when all incoming messages have been read and the server has returned + /// status. + /// - OR when the server has returned a non-OK status. virtual Status Finish() = 0; }; -// An interface that yields a sequence of R messages. +/// An interface that yields a sequence of messages of type \a R. template class ReaderInterface { public: virtual ~ReaderInterface() {} - // Blocking read a message and parse to msg. Returns true on success. - // The method returns false when there will be no more incoming messages, - // either because the other side has called WritesDone or the stream has - // failed (or been cancelled). + /// Blocking read a message and parse to \a msg. Returns \a true on success. + /// + /// \param[out] msg The read message. + /// + /// \return \a false when there will be no more incoming messages, either + /// because the other side has called \a WritesDone() or the stream has failed + /// (or been cancelled). virtual bool Read(R* msg) = 0; }; -// An interface that can be fed a sequence of W messages. +/// An interface that can be fed a sequence of messages of type \a W. template class WriterInterface { public: virtual ~WriterInterface() {} - // Blocking write msg to the stream. Returns true on success. - // Returns false when the stream has been closed. + /// Blocking write \a msg to the stream with options. + /// + /// \param msg The message to be written to the stream. + /// \param options Options affecting the write operation. + /// + /// \return \a true on success, \a false when the stream has been closed. virtual bool Write(const W& msg, const WriteOptions& options) = 0; + /// Blocking write \a msg to the stream with default options. + /// + /// \param msg The message to be written to the stream. + /// + /// \return \a true on success, \a false when the stream has been closed. inline bool Write(const W& msg) { return Write(msg, WriteOptions()); } }; +/// Client-side interface for streaming reads of message of type \a R. template class ClientReaderInterface : public ClientStreamingInterface, public ReaderInterface { public: + /// Blocking wait for initial metadata from server. The received metadata + /// can only be accessed after this call returns. Should only be called before + /// the first read. Calling this method is optional, and if it is not called + /// the metadata will be available in ClientContext after the first read. virtual void WaitForInitialMetadata() = 0; }; template class ClientReader GRPC_FINAL : public ClientReaderInterface { public: - // Blocking create a stream and write the first request out. + /// Blocking create a stream and write the first request out. template ClientReader(Channel* channel, const RpcMethod& method, ClientContext* context, const W& request) @@ -113,17 +131,13 @@ class ClientReader GRPC_FINAL : public ClientReaderInterface { cq_.Pluck(&ops); } - // Blocking wait for initial metadata from server. The received metadata - // can only be accessed after this call returns. Should only be called before - // the first read. Calling this method is optional, and if it is not called - // the metadata will be available in ClientContext after the first read. void WaitForInitialMetadata() { GPR_ASSERT(!context_->initial_metadata_received_); CallOpSet ops; ops.RecvInitialMetadata(context_); call_.PerformOps(&ops); - cq_.Pluck(&ops); // status ignored + cq_.Pluck(&ops); /// status ignored } bool Read(R* msg) GRPC_OVERRIDE { @@ -151,17 +165,22 @@ class ClientReader GRPC_FINAL : public ClientReaderInterface { Call call_; }; +/// Client-side interface for streaming writes of message of type \a W. template class ClientWriterInterface : public ClientStreamingInterface, public WriterInterface { public: + /// Half close writing from the client. + /// Block until writes are completed. + /// + /// \return Whether the writes were successful. virtual bool WritesDone() = 0; }; template class ClientWriter : public ClientWriterInterface { public: - // Blocking create a stream. + /// Blocking create a stream. template ClientWriter(Channel* channel, const RpcMethod& method, ClientContext* context, R* response) @@ -191,7 +210,7 @@ class ClientWriter : public ClientWriterInterface { return cq_.Pluck(&ops); } - // Read the final response and wait for the final status. + /// Read the final response and wait for the final status. Status Finish() GRPC_OVERRIDE { Status status; finish_ops_.ClientRecvStatus(context_, &status); @@ -207,20 +226,28 @@ class ClientWriter : public ClientWriterInterface { Call call_; }; -// Client-side interface for bi-directional streaming. +/// Client-side interface for bi-directional streaming. template class ClientReaderWriterInterface : public ClientStreamingInterface, public WriterInterface, public ReaderInterface { public: + /// Blocking wait for initial metadata from server. The received metadata + /// can only be accessed after this call returns. Should only be called before + /// the first read. Calling this method is optional, and if it is not called + /// the metadata will be available in ClientContext after the first read. virtual void WaitForInitialMetadata() = 0; + + /// Block until writes are completed. + /// + /// \return Whether the writes were successful. virtual bool WritesDone() = 0; }; template class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface { public: - // Blocking create a stream. + /// Blocking create a stream. ClientReaderWriter(Channel* channel, const RpcMethod& method, ClientContext* context) : context_(context), call_(channel->CreateCall(method, context, &cq_)) { @@ -230,10 +257,6 @@ class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface { cq_.Pluck(&ops); } - // Blocking wait for initial metadata from server. The received metadata - // can only be accessed after this call returns. Should only be called before - // the first read. Calling this method is optional, and if it is not called - // the metadata will be available in ClientContext after the first read. void WaitForInitialMetadata() { GPR_ASSERT(!context_->initial_metadata_received_); @@ -344,7 +367,7 @@ class ServerWriter GRPC_FINAL : public WriterInterface { ServerContext* const ctx_; }; -// Server-side interface for bi-directional streaming. +/// Server-side interface for bi-directional streaming. template class ServerReaderWriter GRPC_FINAL : public WriterInterface, public ReaderInterface { diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index a75f356312..47f3df6605 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -47,11 +47,9 @@ extern "C" { /*! \mainpage GRPC Core * - * \section intro_sec The GRPC Core library is a low-level library designed - * to be wrapped by higher level libraries. - * - * The top-level API is provided in grpc.h. - * Security related functionality lives in grpc_security.h. + * The GRPC Core library is a low-level library designed to be wrapped by higher + * level libraries. The top-level API is provided in grpc.h. Security related + * functionality lives in grpc_security.h. */ /** Completion Queues enable notification of the completion of asynchronous diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h index 8de024aaea..74dc09e36e 100644 --- a/src/core/surface/completion_queue.h +++ b/src/core/surface/completion_queue.h @@ -34,7 +34,7 @@ #ifndef GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H #define GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H -/* Internal API for completion channels */ +/* Internal API for completion queues */ #include "src/core/iomgr/pollset.h" #include diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer.cc index e46e656beb..755234d7e8 100644 --- a/src/cpp/util/byte_buffer.cc +++ b/src/cpp/util/byte_buffer.cc @@ -45,6 +45,12 @@ ByteBuffer::ByteBuffer(const Slice* slices, size_t nslices) { buffer_ = grpc_raw_byte_buffer_create(c_slices.data(), nslices); } +ByteBuffer::~ByteBuffer() { + if (buffer_) { + grpc_byte_buffer_destroy(buffer_); + } +} + void ByteBuffer::Clear() { if (buffer_) { grpc_byte_buffer_destroy(buffer_); -- cgit v1.2.3