From 74e03a24ae2d1e750b13b3f6b93c37020573eda8 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 13 Jul 2016 10:12:17 -0700 Subject: [PATCH 01/12] Add handshaker API. --- src/core/lib/channel/handshaker.c | 53 +++++++++++++++++++++++ src/core/lib/channel/handshaker.h | 71 +++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 src/core/lib/channel/handshaker.c create mode 100644 src/core/lib/channel/handshaker.h diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c new file mode 100644 index 00000000000..00d810e63df --- /dev/null +++ b/src/core/lib/channel/handshaker.c @@ -0,0 +1,53 @@ +/* + * + * Copyright 2016, 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/lib/channel/handshaker.h" + +void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, + grpc_handshaker** handshaker) { + handshaker->vtable = vtable; +} + +void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker) { + handshaker->vtable->destroy(exec_ctx, handshaker); +} + +void grpc_handshaker_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, + grpc_endpoint* endpoint_in, gpr_timespec deadline, grpc_closure *on_done) { + handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint_in, + deadline, on_done); +} + +#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h new file mode 100644 index 00000000000..1ca85fd0088 --- /dev/null +++ b/src/core/lib/channel/handshaker.h @@ -0,0 +1,71 @@ +/* + * + * Copyright 2016, 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_CORE_LIB_CHANNEL_HANDSHAKER_H +#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H + +#include + +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/exec_ctx.h" + +// FIXME: document + +typedef struct grpc_handshaker grpc_handshaker; + +struct grpc_handshaker_vtable { + void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + + void (*do_handshake)( + grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, + grpc_endpoint* endpoint_in, gpr_timespec deadline, + grpc_closure *on_done); +}; + +struct grpc_handshaker { + const struct grpc_handshaker_vtable *vtable; +}; + +// Called by concrete implementations to initialize the base struct. +void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, + grpc_handshaker** handshaker); + +// Convenient wrappers for invoking methods via the vtable. +void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker); +void grpc_handshaker_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, + grpc_endpoint* in, gpr_timespec deadline, grpc_closure *on_done); + +#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From c05539f8a464ebc81e7295879d4a85ff69843cd7 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 09:12:51 -0700 Subject: [PATCH 02/12] Tweaked grpc_handshaker API and added grpc_handshake_manager API. --- src/core/lib/channel/handshaker.c | 115 +++++++++++++++++++++++++++++- src/core/lib/channel/handshaker.h | 41 ++++++++++- 2 files changed, 150 insertions(+), 6 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 00d810e63df..3018b95464c 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -33,6 +33,10 @@ #include "src/core/lib/channel/handshaker.h" +// +// grpc_handshaker +// + void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, grpc_handshaker** handshaker) { handshaker->vtable = vtable; @@ -43,11 +47,116 @@ void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, handshaker->vtable->destroy(exec_ctx, handshaker); } +void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker) { + handshaker->vtable->shutdown(exec_ctx, handshaker); +} + void grpc_handshaker_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint_in, gpr_timespec deadline, grpc_closure *on_done) { - handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint_in, - deadline, on_done); + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg) { + handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, + deadline, cb, arg); +} + +// +// grpc_handshake_manager +// + +// State used while chaining handshakers. +struct grpc_handshaker_state { + // The index of the handshaker to invoke next. + size_t index; + // The deadline for all handshakers. + gpr_timespec deadline; + // The final callback and arg to invoke after the last handshaker. + grpc_handshaker_done_cb final_cb; + void* final_arg; +}; + +struct grpc_handshake_manager { + // An array of handshakers added via grpc_handshake_manager_add(). + size_t count; + grpc_handshaker* handshakers; + // State used while chaining handshakers. + grpc_handshaker_state* state; +}; + +grpc_handshake_manager* grpc_handshake_manager_create() { + grpc_handshake_manager* mgr = gpr_malloc(sizeof(grpc_handshake_manager)); + memset(mgr, 0, sizeof(*mgr)); + return mgr; +} + +void grpc_handshake_manager_add(grpc_handshaker* handshaker, + grpc_handshake_manager* mgr) { + mgr->handshakers = gpr_realloc(mgr->handshakers, + (mgr->count + 1) * sizeof(grpc_handshaker*)); + mgr->handshakers[mgr->count++] = handshaker; +} + +void grpc_handshake_manager_destroy( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { + for (int i = 0; i < mgr->count; ++i) { + grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); + } + gpr_free(mgr); +} + +void grpc_handshake_manager_shutdown( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { + // FIXME: maybe check which handshaker is currently in progress, and + // only shut down that one? + for (int i = 0; i < mgr->count; ++i) { + grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[i]); + } + if (mgr->state != NULL) { + gpr_free(mgr->state); + mgr->state = NULL; + } +} + +// A function used as the handshaker-done callback when chaining +// handshakers together. +static void call_next_handshaker(grpc_exec_ctx* exec_ctx, + grpc_endpoint* endpoint, void* arg) { + grpc_handshake_manager* mgr = arg; + GPR_ASSERT(mgr->state != NULL); + GPR_ASSERT(mgr->state->index < mgr->count); + grpc_handshaker_done_cb cb = call_next_handshaker; + // If this is the last handshaker, use the caller-supplied callback + // and arg instead of chaining back to this function again. + if (mgr->state->index == mgr->count - 1) { + cb = mgr->state->final_cb; + arg = mgr->state->final_arg; + } + // Invoke handshaker. + grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index], + endpoint, mgr->state->deadline, cb, arg); + ++mgr->state->index; + // If this is the last handshaker, clean up state. + if (mgr->state->index == mgr->count) { + gpr_free(mgr->state); + mgr->state = NULL; + } +} + +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg) { + if (mgr->count == 0) { + // No handshakers registered, so we just immediately call the done + // callback with the passed-in endpoint. + cb(exec_ctx, endpoint, arg); + } else { + GPR_ASSERT(mgr->state == NULL); + mgr->state = gpr_malloc(sizeof(grpc_handshaker_state)); + memset(mgr->state, 0, sizeof(grpc_handshaker_state)); + *mgr->state = {0, deadline, cb, arg}; + call_next_handshaker(exec_ctx, endpoint, mgr); + } } #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 1ca85fd0088..c4e3bef5a50 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -40,17 +40,26 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" +// +// grpc_handshaker -- API for initial handshaking for a new connection +// + // FIXME: document typedef struct grpc_handshaker grpc_handshaker; +typedef void (*grpc_handshaker_done_cb)( + grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, void* arg); + struct grpc_handshaker_vtable { void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + void (*do_handshake)( grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint_in, gpr_timespec deadline, - grpc_closure *on_done); + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); }; struct grpc_handshaker { @@ -64,8 +73,34 @@ void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, // Convenient wrappers for invoking methods via the vtable. void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); +void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker); void grpc_handshaker_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* in, gpr_timespec deadline, grpc_closure *on_done); + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); + +// +// grpc_handshake_manager -- manages a set of handshakers +// + +typedef struct grpc_handshake_manager grpc_handshake_manager; + +grpc_handshake_manager* grpc_handshake_manager_create(); + +// Handshakers will be invoked in the order added. +void grpc_handshake_manager_add(grpc_handshaker* handshaker, + grpc_handshake_manager* mgr); + +void grpc_handshake_manager_destroy( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); + +void grpc_handshake_manager_shutdown( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); + +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From 1d3b2cc84948b874985951039fab1965d0a30ef5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 09:18:12 -0700 Subject: [PATCH 03/12] clang-format --- src/core/lib/channel/handshaker.c | 33 +++++++++++++------------- src/core/lib/channel/handshaker.h | 39 ++++++++++++++++--------------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 3018b95464c..65c2a96df70 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -52,12 +52,13 @@ void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, handshaker->vtable->shutdown(exec_ctx, handshaker); } -void grpc_handshaker_do_handshake( - grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg) { - handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, - deadline, cb, arg); +void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker, + grpc_endpoint* endpoint, + gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg) { + handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, deadline, cb, + arg); } // @@ -96,16 +97,16 @@ void grpc_handshake_manager_add(grpc_handshaker* handshaker, mgr->handshakers[mgr->count++] = handshaker; } -void grpc_handshake_manager_destroy( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { +void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr) { for (int i = 0; i < mgr->count; ++i) { grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); } gpr_free(mgr); } -void grpc_handshake_manager_shutdown( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { +void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr) { // FIXME: maybe check which handshaker is currently in progress, and // only shut down that one? for (int i = 0; i < mgr->count; ++i) { @@ -142,10 +143,12 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, } } -void grpc_handshake_manager_do_handshake( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg) { +void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, + gpr_timespec deadline, + grpc_handshaker_done_cb cb, + void* arg) { if (mgr->count == 0) { // No handshakers registered, so we just immediately call the done // callback with the passed-in endpoint. @@ -158,5 +161,3 @@ void grpc_handshake_manager_do_handshake( call_next_handshaker(exec_ctx, endpoint, mgr); } } - -#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index c4e3bef5a50..583df4b2419 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -48,22 +48,21 @@ typedef struct grpc_handshaker grpc_handshaker; -typedef void (*grpc_handshaker_done_cb)( - grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, void* arg); +typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx, + grpc_endpoint* endpoint, void* arg); struct grpc_handshaker_vtable { void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); - void (*do_handshake)( - grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); + void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, + grpc_endpoint* endpoint, gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); }; struct grpc_handshaker { - const struct grpc_handshaker_vtable *vtable; + const struct grpc_handshaker_vtable* vtable; }; // Called by concrete implementations to initialize the base struct. @@ -75,10 +74,11 @@ void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); -void grpc_handshaker_do_handshake( - grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); +void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker, + grpc_endpoint* endpoint, + gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); // // grpc_handshake_manager -- manages a set of handshakers @@ -92,15 +92,16 @@ grpc_handshake_manager* grpc_handshake_manager_create(); void grpc_handshake_manager_add(grpc_handshaker* handshaker, grpc_handshake_manager* mgr); -void grpc_handshake_manager_destroy( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); +void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr); -void grpc_handshake_manager_shutdown( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); +void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr); -void grpc_handshake_manager_do_handshake( - grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); +void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, + gpr_timespec deadline, + grpc_handshaker_done_cb cb, void* arg); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From dfbdefedd381b57dd33631aea3a79659ac019bc9 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 09:18:22 -0700 Subject: [PATCH 04/12] Added handshaker.[ch] to build.yaml. --- BUILD | 8 ++++++++ CMakeLists.txt | 3 +++ Makefile | 3 +++ binding.gyp | 1 + build.yaml | 2 ++ config.m4 | 1 + gRPC-Core.podspec | 3 +++ gRPC.podspec | 3 +++ grpc.gemspec | 2 ++ package.xml | 2 ++ src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 ++ tools/run_tests/sources_and_headers.json | 3 +++ vsprojects/vcxproj/grpc/grpc.vcxproj | 3 +++ vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 ++++++ vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 3 +++ .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 ++++++ 17 files changed, 52 insertions(+) diff --git a/BUILD b/BUILD index 33323be229d..8a6d7fdc0a6 100644 --- a/BUILD +++ b/BUILD @@ -165,6 +165,7 @@ cc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -316,6 +317,7 @@ cc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -552,6 +554,7 @@ cc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -693,6 +696,7 @@ cc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -904,6 +908,7 @@ cc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -1032,6 +1037,7 @@ cc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -1791,6 +1797,7 @@ objc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -2006,6 +2013,7 @@ objc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c0059cd2db..1f647e0a988 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,6 +139,7 @@ add_library(grpc src/core/lib/channel/channel_stack_builder.c src/core/lib/channel/compress_filter.c src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c src/core/lib/channel/http_client_filter.c src/core/lib/channel/http_server_filter.c src/core/lib/compression/compression.c @@ -344,6 +345,7 @@ add_library(grpc_cronet src/core/lib/channel/channel_stack_builder.c src/core/lib/channel/compress_filter.c src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c src/core/lib/channel/http_client_filter.c src/core/lib/channel/http_server_filter.c src/core/lib/compression/compression.c @@ -526,6 +528,7 @@ add_library(grpc_unsecure src/core/lib/channel/channel_stack_builder.c src/core/lib/channel/compress_filter.c src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c src/core/lib/channel/http_client_filter.c src/core/lib/channel/http_server_filter.c src/core/lib/compression/compression.c diff --git a/Makefile b/Makefile index e958b145e77..efc1cec90c8 100644 --- a/Makefile +++ b/Makefile @@ -2479,6 +2479,7 @@ LIBGRPC_SRC = \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ @@ -2751,6 +2752,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ @@ -3092,6 +3094,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ diff --git a/binding.gyp b/binding.gyp index e1130ad01ab..1dd7ee95555 100644 --- a/binding.gyp +++ b/binding.gyp @@ -568,6 +568,7 @@ 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', diff --git a/build.yaml b/build.yaml index 071d4a8e1ea..21490d00d9c 100644 --- a/build.yaml +++ b/build.yaml @@ -156,6 +156,7 @@ filegroups: - src/core/lib/channel/compress_filter.h - src/core/lib/channel/connected_channel.h - src/core/lib/channel/context.h + - src/core/lib/channel/handshaker.h - src/core/lib/channel/http_client_filter.h - src/core/lib/channel/http_server_filter.h - src/core/lib/compression/algorithm_metadata.h @@ -234,6 +235,7 @@ filegroups: - src/core/lib/channel/channel_stack_builder.c - src/core/lib/channel/compress_filter.c - src/core/lib/channel/connected_channel.c + - src/core/lib/channel/handshaker.c - src/core/lib/channel/http_client_filter.c - src/core/lib/channel/http_server_filter.c - src/core/lib/compression/compression.c diff --git a/config.m4 b/config.m4 index 0c3322d8efe..e4e410884d0 100644 --- a/config.m4 +++ b/config.m4 @@ -87,6 +87,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e10e05387b1..afe9cffc4c6 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -256,6 +256,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', @@ -411,6 +412,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', @@ -609,6 +611,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', diff --git a/gRPC.podspec b/gRPC.podspec index fd58bd6281f..78cb164fac9 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -168,6 +168,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', @@ -353,6 +354,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', @@ -551,6 +553,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', diff --git a/grpc.gemspec b/grpc.gemspec index 369851b0f24..6b8beba9078 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -177,6 +177,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/compress_filter.h ) s.files += %w( src/core/lib/channel/connected_channel.h ) s.files += %w( src/core/lib/channel/context.h ) + s.files += %w( src/core/lib/channel/handshaker.h ) s.files += %w( src/core/lib/channel/http_client_filter.h ) s.files += %w( src/core/lib/channel/http_server_filter.h ) s.files += %w( src/core/lib/compression/algorithm_metadata.h ) @@ -332,6 +333,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/channel_stack_builder.c ) s.files += %w( src/core/lib/channel/compress_filter.c ) s.files += %w( src/core/lib/channel/connected_channel.c ) + s.files += %w( src/core/lib/channel/handshaker.c ) s.files += %w( src/core/lib/channel/http_client_filter.c ) s.files += %w( src/core/lib/channel/http_server_filter.c ) s.files += %w( src/core/lib/compression/compression.c ) diff --git a/package.xml b/package.xml index d7d10b3f7cc..b4ec9f994f7 100644 --- a/package.xml +++ b/package.xml @@ -184,6 +184,7 @@ + @@ -339,6 +340,7 @@ + diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index b37e27c27ea..fc0908b2f1b 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -81,6 +81,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 8233da957d1..62cf5cc8c7a 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -796,6 +796,7 @@ src/core/lib/channel/channel_stack_builder.h \ src/core/lib/channel/compress_filter.h \ src/core/lib/channel/connected_channel.h \ src/core/lib/channel/context.h \ +src/core/lib/channel/handshaker.h \ src/core/lib/channel/http_client_filter.h \ src/core/lib/channel/http_server_filter.h \ src/core/lib/compression/algorithm_metadata.h \ @@ -951,6 +952,7 @@ src/core/lib/channel/channel_stack.c \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ +src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index cdbc254f430..ee24a63077a 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -5712,6 +5712,7 @@ "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -5805,6 +5806,8 @@ "src/core/lib/channel/connected_channel.c", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.c", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.c", diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index a9e96dab462..33485d3dc91 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -305,6 +305,7 @@ + @@ -468,6 +469,8 @@ + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index be77e53f457..a21d873b88f 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -19,6 +19,9 @@ src\core\lib\channel + + src\core\lib\channel + src\core\lib\channel @@ -671,6 +674,9 @@ src\core\lib\channel + + src\core\lib\channel + src\core\lib\channel diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 1cfe06aec6d..3a3610d524d 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -294,6 +294,7 @@ + @@ -435,6 +436,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index c33c6650e70..bec089e860e 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -22,6 +22,9 @@ src\core\lib\channel + + src\core\lib\channel + src\core\lib\channel @@ -578,6 +581,9 @@ src\core\lib\channel + + src\core\lib\channel + src\core\lib\channel From 7c2a58c107d9c64ed27642a916d60e1776788f0e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 11:53:47 -0700 Subject: [PATCH 05/12] Fix build problems. --- src/core/lib/channel/handshaker.c | 23 +++++++++++++++-------- src/core/lib/channel/handshaker.h | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 65c2a96df70..5b8c08bc151 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -31,6 +31,11 @@ * */ +#include + +#include +#include + #include "src/core/lib/channel/handshaker.h" // @@ -38,7 +43,7 @@ // void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, - grpc_handshaker** handshaker) { + grpc_handshaker* handshaker) { handshaker->vtable = vtable; } @@ -79,9 +84,9 @@ struct grpc_handshaker_state { struct grpc_handshake_manager { // An array of handshakers added via grpc_handshake_manager_add(). size_t count; - grpc_handshaker* handshakers; + grpc_handshaker** handshakers; // State used while chaining handshakers. - grpc_handshaker_state* state; + struct grpc_handshaker_state* state; }; grpc_handshake_manager* grpc_handshake_manager_create() { @@ -99,7 +104,7 @@ void grpc_handshake_manager_add(grpc_handshaker* handshaker, void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { - for (int i = 0; i < mgr->count; ++i) { + for (size_t i = 0; i < mgr->count; ++i) { grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); } gpr_free(mgr); @@ -109,7 +114,7 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr) { // FIXME: maybe check which handshaker is currently in progress, and // only shut down that one? - for (int i = 0; i < mgr->count; ++i) { + for (size_t i = 0; i < mgr->count; ++i) { grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[i]); } if (mgr->state != NULL) { @@ -155,9 +160,11 @@ void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, cb(exec_ctx, endpoint, arg); } else { GPR_ASSERT(mgr->state == NULL); - mgr->state = gpr_malloc(sizeof(grpc_handshaker_state)); - memset(mgr->state, 0, sizeof(grpc_handshaker_state)); - *mgr->state = {0, deadline, cb, arg}; + mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state)); + memset(mgr->state, 0, sizeof(*mgr->state)); + mgr->state->deadline = deadline; + mgr->state->final_cb = cb; + mgr->state->final_arg = arg; call_next_handshaker(exec_ctx, endpoint, mgr); } } diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 583df4b2419..8cb6fdbc805 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -67,7 +67,7 @@ struct grpc_handshaker { // Called by concrete implementations to initialize the base struct. void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, - grpc_handshaker** handshaker); + grpc_handshaker* handshaker); // Convenient wrappers for invoking methods via the vtable. void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, From dba5d2708c6d59a73b65d378440dc64b3af2b873 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Jul 2016 13:45:05 -0700 Subject: [PATCH 06/12] Use handshake_manager API in client and server. --- .../chttp2/client/insecure/channel_create.c | 34 +++++++++++---- .../client/secure/secure_channel_create.c | 28 ++++++++++--- .../chttp2/server/insecure/server_chttp2.c | 42 +++++++++++++++---- .../server/secure/server_secure_chttp2.c | 32 +++++++++++--- src/core/lib/channel/handshaker.h | 2 + 5 files changed, 111 insertions(+), 27 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 85f9efb3b63..648a9d90a5f 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -45,6 +45,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/http_client_filter.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/surface/api_trace.h" @@ -63,6 +64,8 @@ typedef struct { grpc_endpoint *tcp; grpc_closure connected; + + grpc_handshake_manager *handshake_mgr; } connector; static void connector_ref(grpc_connector *con) { @@ -74,6 +77,7 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { connector *c = (connector *)con; if (gpr_unref(&c->refs)) { /* c->initial_string_buffer does not need to be destroyed */ + grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); gpr_free(c); } } @@ -83,6 +87,19 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, connector_unref(exec_ctx, arg); } +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + void *arg) { + connector *c = arg; + c->result->transport = + grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, endpoint, 1); + GPR_ASSERT(c->result->transport); + grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0); + c->result->channel_args = grpc_channel_args_copy(c->args.channel_args); + grpc_closure *notify = c->notify; + c->notify = NULL; + grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_NONE, NULL); +} + static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; grpc_closure *notify; @@ -97,19 +114,17 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector_ref(arg); grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); + } else { + grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, + c->args.deadline, on_handshake_done, + c); } - c->result->transport = - grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1); - grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, - 0); - GPR_ASSERT(c->result->transport); - c->result->channel_args = grpc_channel_args_copy(c->args.channel_args); } else { memset(c->result, 0, sizeof(*c->result)); + notify = c->notify; + c->notify = NULL; + grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } - notify = c->notify; - c->notify = NULL; - grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {} @@ -171,6 +186,7 @@ static grpc_subchannel *client_channel_factory_create_subchannel( memset(c, 0, sizeof(*c)); c->base.vtable = &connector_vtable; gpr_ref_init(&c->refs, 1); + c->handshake_mgr = grpc_handshake_manager_create(); args->args = final_args; s = grpc_subchannel_create(exec_ctx, &c->base, args); grpc_connector_unref(exec_ctx, &c->base); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 721ba82d8f7..30477ded1a3 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -44,6 +44,7 @@ #include "src/core/ext/client_config/resolver_registry.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" @@ -69,6 +70,8 @@ typedef struct { grpc_endpoint *newly_connecting_endpoint; grpc_closure connected_closure; + + grpc_handshake_manager *handshake_mgr; } connector; static void connector_ref(grpc_connector *con) { @@ -80,6 +83,7 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { connector *c = (connector *)con; if (gpr_unref(&c->refs)) { /* c->initial_string_buffer does not need to be destroyed */ + grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); gpr_free(c); } } @@ -116,12 +120,23 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_NONE, NULL); } +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + void *arg) { + connector *c = arg; + // TODO(roth, jboeuf): Convert security connector handshaking to use new + // handshake API, and then move the code from on_secure_handshake_done() + // into this function. + grpc_channel_security_connector_do_handshake(exec_ctx, c->security_connector, + endpoint, c->args.deadline, + on_secure_handshake_done, c); +} + static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_channel_security_connector_do_handshake( - exec_ctx, c->security_connector, c->connecting_endpoint, c->args.deadline, - on_secure_handshake_done, c); + grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, + c->connecting_endpoint, c->args.deadline, + on_handshake_done, c); } static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -142,9 +157,9 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); } else { - grpc_channel_security_connector_do_handshake( - exec_ctx, c->security_connector, tcp, c->args.deadline, - on_secure_handshake_done, c); + grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, + c->args.deadline, on_handshake_done, + c); } } else { memset(c->result, 0, sizeof(*c->result)); @@ -227,6 +242,7 @@ static grpc_subchannel *client_channel_factory_create_subchannel( memset(c, 0, sizeof(*c)); c->base.vtable = &connector_vtable; c->security_connector = f->security_connector; + c->handshake_mgr = grpc_handshake_manager_create(); gpr_mu_init(&c->mu); gpr_ref_init(&c->refs, 1); args->args = final_args; diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index e5c987925c3..d3748f576d5 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -38,15 +38,23 @@ #include #include #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/http_server_filter.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/server.h" -static void new_transport(grpc_exec_ctx *exec_ctx, void *server, - grpc_endpoint *tcp, grpc_pollset *accepting_pollset, - grpc_tcp_server_acceptor *acceptor) { +typedef struct server_connect_state { + grpc_server *server; + grpc_pollset *accepting_pollset; + grpc_tcp_server_acceptor *acceptor; + grpc_handshake_manager *handshake_mgr; +} server_connect_state; + +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + void *arg) { + server_connect_state *state = arg; /* * Beware that the call to grpc_create_chttp2_transport() has to happen before * grpc_tcp_server_destroy(). This is fine here, but similar code @@ -55,17 +63,37 @@ static void new_transport(grpc_exec_ctx *exec_ctx, void *server, * case. */ grpc_transport *transport = grpc_create_chttp2_transport( - exec_ctx, grpc_server_get_channel_args(server), tcp, 0); - grpc_server_setup_transport(exec_ctx, server, transport, accepting_pollset, - grpc_server_get_channel_args(server)); + exec_ctx, grpc_server_get_channel_args(state->server), endpoint, 0); + grpc_server_setup_transport(exec_ctx, state->server, transport, + state->accepting_pollset, + grpc_server_get_channel_args(state->server)); grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); + // Clean up. + grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); + gpr_free(state); +} + +static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp, + grpc_pollset *accepting_pollset, + grpc_tcp_server_acceptor *acceptor) { + server_connect_state *state = gpr_malloc(sizeof(server_connect_state)); + state->server = server; + state->accepting_pollset = accepting_pollset; + state->acceptor = acceptor; + state->handshake_mgr = grpc_handshake_manager_create(); + // TODO(roth): We should really get this timeout value from channel + // args instead of hard-coding it. + const gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); + grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, + deadline, on_handshake_done, state); } /* Server callback: start listening on our ports */ static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) { grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport, + grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, on_accept, server); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index c42810e9130..57931bdb43b 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -42,6 +42,7 @@ #include #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/http_server_filter.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -68,6 +69,10 @@ typedef struct server_secure_state { typedef struct server_secure_connect { server_secure_state *state; grpc_pollset *accepting_pollset; + grpc_tcp_server_acceptor *acceptor; + gpr_timespec deadline; // FIXME: remove when we eliminate + // grpc_server_security_connector_do_handshake() + grpc_handshake_manager *handshake_mgr; } server_secure_connect; static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); } @@ -122,6 +127,19 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, gpr_free(state); } +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + void *arg) { + server_secure_connect *state = arg; + grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); + state->handshake_mgr = NULL; + // TODO(roth, jboeuf): Convert security connector handshaking to use new + // handshake API, and then move the code from on_secure_handshake_done() + // into this function. + grpc_server_security_connector_do_handshake( + exec_ctx, state->state->sc, state->acceptor, endpoint, state->deadline, + on_secure_handshake_done, state); +} + static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, grpc_pollset *accepting_pollset, grpc_tcp_server_acceptor *acceptor) { @@ -129,11 +147,15 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, state->state = statep; state_ref(state->state); state->accepting_pollset = accepting_pollset; - grpc_server_security_connector_do_handshake( - exec_ctx, state->state->sc, acceptor, tcp, - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(120, GPR_TIMESPAN)), - on_secure_handshake_done, state); + state->acceptor = acceptor; + // TODO(roth): We should really get this timeout value from channel + // args instead of hard-coding it. + state->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(120, GPR_TIMESPAN)); + state->handshake_mgr = grpc_handshake_manager_create(); + grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, + state->deadline, on_handshake_done, + state); } /* Server callback: start listening on our ports */ diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 8cb6fdbc805..9d084f07177 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -40,6 +40,8 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" +// FIXME: high-level documentation + // // grpc_handshaker -- API for initial handshaking for a new connection // From 45015dc8dac51979fe7bffdc20a92e895e57180e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 15 Jul 2016 08:48:25 -0700 Subject: [PATCH 07/12] Plumb channel args through handshakers. --- .../chttp2/client/insecure/channel_create.c | 12 ++-- .../client/secure/secure_channel_create.c | 21 +++--- .../chttp2/server/insecure/server_chttp2.c | 10 ++- .../server/secure/server_secure_chttp2.c | 31 +++++---- src/core/lib/channel/channel_args.h | 2 + src/core/lib/channel/handshaker.c | 35 ++++++---- src/core/lib/channel/handshaker.h | 67 ++++++++++++++----- 7 files changed, 116 insertions(+), 62 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 648a9d90a5f..154c4493ffc 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -88,13 +88,13 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - void *arg) { - connector *c = arg; + grpc_channel_args* args, void *user_data) { + connector *c = user_data; c->result->transport = - grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, endpoint, 1); + grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1); GPR_ASSERT(c->result->transport); grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0); - c->result->channel_args = grpc_channel_args_copy(c->args.channel_args); + c->result->channel_args = args; grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_NONE, NULL); @@ -102,7 +102,6 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_closure *notify; grpc_endpoint *tcp = c->tcp; if (tcp != NULL) { if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) { @@ -116,12 +115,13 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { &c->initial_string_sent); } else { grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, + c->args.channel_args, c->args.deadline, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); - notify = c->notify; + grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 30477ded1a3..f071e31cb32 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -72,6 +72,9 @@ typedef struct { grpc_closure connected_closure; grpc_handshake_manager *handshake_mgr; + + // TODO(roth): Remove once we eliminate on_secure_handshake_done(). + grpc_channel_args* tmp_args; } connector; static void connector_ref(grpc_connector *con) { @@ -83,6 +86,7 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { connector *c = (connector *)con; if (gpr_unref(&c->refs)) { /* c->initial_string_buffer does not need to be destroyed */ + grpc_channel_args_destroy(c->tmp_args); grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); gpr_free(c); } @@ -93,7 +97,6 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context) { connector *c = arg; - grpc_closure *notify; gpr_mu_lock(&c->mu); if (c->connecting_endpoint == NULL) { memset(c->result, 0, sizeof(*c->result)); @@ -113,19 +116,20 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, 0); auth_context_arg = grpc_auth_context_to_arg(auth_context); c->result->channel_args = grpc_channel_args_copy_and_add( - c->args.channel_args, &auth_context_arg, 1); + c->tmp_args, &auth_context_arg, 1); } - notify = c->notify; + grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_NONE, NULL); } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - void *arg) { - connector *c = arg; + grpc_channel_args* args, void *user_data) { + connector *c = user_data; // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() // into this function. + c->tmp_args = args; grpc_channel_security_connector_do_handshake(exec_ctx, c->security_connector, endpoint, c->args.deadline, on_secure_handshake_done, c); @@ -135,13 +139,13 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, - c->connecting_endpoint, c->args.deadline, + c->connecting_endpoint, + c->args.channel_args, c->args.deadline, on_handshake_done, c); } static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_closure *notify; grpc_endpoint *tcp = c->newly_connecting_endpoint; if (tcp != NULL) { gpr_mu_lock(&c->mu); @@ -158,12 +162,13 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { &c->initial_string_sent); } else { grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, + c->args.channel_args, c->args.deadline, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); - notify = c->notify; + grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index d3748f576d5..920875f6947 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -37,7 +37,9 @@ #include #include #include + #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/http_server_filter.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -53,8 +55,8 @@ typedef struct server_connect_state { } server_connect_state; static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - void *arg) { - server_connect_state *state = arg; + grpc_channel_args* args, void *user_data) { + server_connect_state *state = user_data; /* * Beware that the call to grpc_create_chttp2_transport() has to happen before * grpc_tcp_server_destroy(). This is fine here, but similar code @@ -63,12 +65,13 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, * case. */ grpc_transport *transport = grpc_create_chttp2_transport( - exec_ctx, grpc_server_get_channel_args(state->server), endpoint, 0); + exec_ctx, args, endpoint, 0); grpc_server_setup_transport(exec_ctx, state->server, transport, state->accepting_pollset, grpc_server_get_channel_args(state->server)); grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); // Clean up. + grpc_channel_args_destroy(args); grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); gpr_free(state); } @@ -86,6 +89,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp, const gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, + grpc_server_get_channel_args(server), deadline, on_handshake_done, state); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index 57931bdb43b..e3184bc1f93 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -70,9 +70,11 @@ typedef struct server_secure_connect { server_secure_state *state; grpc_pollset *accepting_pollset; grpc_tcp_server_acceptor *acceptor; - gpr_timespec deadline; // FIXME: remove when we eliminate - // grpc_server_security_connector_do_handshake() grpc_handshake_manager *handshake_mgr; + // TODO(roth): Remove the following two fields when we eliminate + // grpc_server_security_connector_do_handshake(). + gpr_timespec deadline; + grpc_channel_args* args; } server_secure_connect; static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); } @@ -102,13 +104,11 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, transport = grpc_create_chttp2_transport( exec_ctx, grpc_server_get_channel_args(state->state->server), secure_endpoint, 0); - grpc_channel_args *args_copy; grpc_arg args_to_add[2]; args_to_add[0] = grpc_server_credentials_to_arg(state->state->creds); args_to_add[1] = grpc_auth_context_to_arg(auth_context); - args_copy = grpc_channel_args_copy_and_add( - grpc_server_get_channel_args(state->state->server), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); + grpc_channel_args *args_copy = grpc_channel_args_copy_and_add( + state->args, args_to_add, GPR_ARRAY_SIZE(args_to_add)); grpc_server_setup_transport(exec_ctx, state->state->server, transport, state->accepting_pollset, args_copy); grpc_channel_args_destroy(args_copy); @@ -123,18 +123,20 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, } else { gpr_log(GPR_ERROR, "Secure transport failed with error %d", status); } + grpc_channel_args_destroy(state->args); state_unref(state->state); gpr_free(state); } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - void *arg) { - server_secure_connect *state = arg; - grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); - state->handshake_mgr = NULL; + grpc_channel_args* args, void *user_data) { + server_secure_connect *state = user_data; // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() // into this function. + grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); + state->handshake_mgr = NULL; + state->args = args; grpc_server_security_connector_do_handshake( exec_ctx, state->state->sc, state->acceptor, endpoint, state->deadline, on_secure_handshake_done, state); @@ -148,14 +150,15 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, state_ref(state->state); state->accepting_pollset = accepting_pollset; state->acceptor = acceptor; + state->handshake_mgr = grpc_handshake_manager_create(); // TODO(roth): We should really get this timeout value from channel // args instead of hard-coding it. state->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); - state->handshake_mgr = grpc_handshake_manager_create(); - grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, - state->deadline, on_handshake_done, - state); + grpc_handshake_manager_do_handshake( + exec_ctx, state->handshake_mgr, tcp, + grpc_server_get_channel_args(state->state->server), state->deadline, + on_handshake_done, state); } /* Server callback: start listening on our ports */ diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h index 653d04f4279..aec61ee7c62 100644 --- a/src/core/lib/channel/channel_args.h +++ b/src/core/lib/channel/channel_args.h @@ -37,6 +37,8 @@ #include #include +// Channel args are intentionally immutable, to avoid the need for locking. + /** Copy the arguments in \a src into a new instance */ grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src); diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 5b8c08bc151..7dcbe1df9ce 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -36,6 +36,7 @@ #include #include +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" // @@ -60,10 +61,11 @@ void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, + grpc_channel_args* args, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg) { - handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, deadline, cb, - arg); + grpc_handshaker_done_cb cb, void* user_data) { + handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args, + deadline, cb, user_data); } // @@ -76,9 +78,9 @@ struct grpc_handshaker_state { size_t index; // The deadline for all handshakers. gpr_timespec deadline; - // The final callback and arg to invoke after the last handshaker. + // The final callback and user_data to invoke after the last handshaker. grpc_handshaker_done_cb final_cb; - void* final_arg; + void* final_user_data; }; struct grpc_handshake_manager { @@ -126,20 +128,23 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, // A function used as the handshaker-done callback when chaining // handshakers together. static void call_next_handshaker(grpc_exec_ctx* exec_ctx, - grpc_endpoint* endpoint, void* arg) { - grpc_handshake_manager* mgr = arg; + grpc_endpoint* endpoint, + grpc_channel_args* args, + void* user_data) { + grpc_handshake_manager* mgr = user_data; GPR_ASSERT(mgr->state != NULL); GPR_ASSERT(mgr->state->index < mgr->count); grpc_handshaker_done_cb cb = call_next_handshaker; // If this is the last handshaker, use the caller-supplied callback - // and arg instead of chaining back to this function again. + // and user_data instead of chaining back to this function again. if (mgr->state->index == mgr->count - 1) { cb = mgr->state->final_cb; - arg = mgr->state->final_arg; + user_data = mgr->state->final_user_data; } // Invoke handshaker. grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index], - endpoint, mgr->state->deadline, cb, arg); + endpoint, args, mgr->state->deadline, cb, + user_data); ++mgr->state->index; // If this is the last handshaker, clean up state. if (mgr->state->index == mgr->count) { @@ -151,20 +156,22 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, + const grpc_channel_args* args, gpr_timespec deadline, grpc_handshaker_done_cb cb, - void* arg) { + void* user_data) { + grpc_channel_args* args_copy = grpc_channel_args_copy(args); if (mgr->count == 0) { // No handshakers registered, so we just immediately call the done // callback with the passed-in endpoint. - cb(exec_ctx, endpoint, arg); + cb(exec_ctx, endpoint, args_copy, user_data); } else { GPR_ASSERT(mgr->state == NULL); mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state)); memset(mgr->state, 0, sizeof(*mgr->state)); mgr->state->deadline = deadline; mgr->state->final_cb = cb; - mgr->state->final_arg = arg; - call_next_handshaker(exec_ctx, endpoint, mgr); + mgr->state->final_user_data = user_data; + call_next_handshaker(exec_ctx, endpoint, args_copy, mgr); } } diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 9d084f07177..6a39529150a 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -34,44 +34,62 @@ #ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H #define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H +#include #include #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" -// FIXME: high-level documentation +/// Handshakers are used to perform initial handshakes on a connection +/// before the client sends the initial request. Some examples of what +/// a handshaker can be used for includes support for HTTP CONNECT on +/// the client side and various types of security initialization. +/// +/// In general, handshakers should be used via a handshake manager. -// -// grpc_handshaker -- API for initial handshaking for a new connection -// - -// FIXME: document +/// +/// grpc_handshaker +/// typedef struct grpc_handshaker grpc_handshaker; +/// Callback type invoked when a handshaker is done. +/// Takes ownership of \a args. typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx, - grpc_endpoint* endpoint, void* arg); + grpc_endpoint* endpoint, + grpc_channel_args* args, + void* user_data); struct grpc_handshaker_vtable { + /// Destroys the handshaker. void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + /// Shuts down the handshaker (e.g., to clean up when the operation is + /// aborted in the middle). void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + /// Performs handshaking. When finished, calls \a cb with \a user_data. + /// Takes ownership of \a args. void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, - grpc_endpoint* endpoint, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); + grpc_endpoint* endpoint, grpc_channel_args* args, + gpr_timespec deadline, grpc_handshaker_done_cb cb, + void* user_data); }; +/// Base struct. To subclass, make this the first member of the +/// implementation struct. struct grpc_handshaker { const struct grpc_handshaker_vtable* vtable; }; -// Called by concrete implementations to initialize the base struct. +/// Called by concrete implementations to initialize the base struct. void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, grpc_handshaker* handshaker); -// Convenient wrappers for invoking methods via the vtable. +/// Convenient wrappers for invoking methods via the vtable. +/// These probably do not need to be called from anywhere but +/// grpc_handshake_manager. void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, @@ -79,31 +97,46 @@ void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, + grpc_channel_args* args, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); + grpc_handshaker_done_cb cb, void* user_data); -// -// grpc_handshake_manager -- manages a set of handshakers -// +/// +/// grpc_handshake_manager +/// typedef struct grpc_handshake_manager grpc_handshake_manager; +/// Creates a new handshake manager. Caller takes ownership. grpc_handshake_manager* grpc_handshake_manager_create(); -// Handshakers will be invoked in the order added. +/// Adds a handshaker to the handshake manager. +/// Takes ownership of \a mgr. void grpc_handshake_manager_add(grpc_handshaker* handshaker, grpc_handshake_manager* mgr); +/// Destroys the handshake manager. void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); +/// Shuts down the handshake manager (e.g., to clean up when the operation is +/// aborted in the middle). +/// The caller must still call grpc_handshake_manager_destroy() after +/// calling this function. void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr); +/// Invokes handshakers in the order they were added. +/// Does NOT take ownership of \a args. Instead, makes a copy before +/// invoking the first handshaker. +/// If successful, invokes \a cb with \a user_data after all handshakers +/// have completed. void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, + const grpc_channel_args* args, gpr_timespec deadline, - grpc_handshaker_done_cb cb, void* arg); + grpc_handshaker_done_cb cb, + void* user_data); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From b3ce178b28ebb842408f8cdc5b116816a0171095 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 20 Jul 2016 09:25:25 -0700 Subject: [PATCH 08/12] clang-format --- .../chttp2/client/insecure/channel_create.c | 9 ++++---- .../client/secure/secure_channel_create.c | 22 +++++++++---------- .../chttp2/server/insecure/server_chttp2.c | 6 ++--- .../server/secure/server_secure_chttp2.c | 4 ++-- src/core/lib/channel/handshaker.c | 14 +++++------- src/core/lib/channel/handshaker.h | 11 ++++------ 6 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 154c4493ffc..162cc6bd6ab 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -88,7 +88,7 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args* args, void *user_data) { + grpc_channel_args *args, void *user_data) { connector *c = user_data; c->result->transport = grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1); @@ -114,10 +114,9 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); } else { - grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, - c->args.channel_args, - c->args.deadline, on_handshake_done, - c); + grpc_handshake_manager_do_handshake( + exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, + c->args.deadline, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 4554c33c8c6..dde35f253dd 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -74,7 +74,7 @@ typedef struct { grpc_handshake_manager *handshake_mgr; // TODO(roth): Remove once we eliminate on_secure_handshake_done(). - grpc_channel_args* tmp_args; + grpc_channel_args *tmp_args; } connector; static void connector_ref(grpc_connector *con) { @@ -117,8 +117,8 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0); auth_context_arg = grpc_auth_context_to_arg(auth_context); - c->result->channel_args = grpc_channel_args_copy_and_add( - c->tmp_args, &auth_context_arg, 1); + c->result->channel_args = + grpc_channel_args_copy_and_add(c->tmp_args, &auth_context_arg, 1); } grpc_closure *notify = c->notify; c->notify = NULL; @@ -126,7 +126,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args* args, void *user_data) { + grpc_channel_args *args, void *user_data) { connector *c = user_data; // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() @@ -140,10 +140,9 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, - c->connecting_endpoint, - c->args.channel_args, c->args.deadline, - on_handshake_done, c); + grpc_handshake_manager_do_handshake( + exec_ctx, c->handshake_mgr, c->connecting_endpoint, c->args.channel_args, + c->args.deadline, on_handshake_done, c); } static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -163,10 +162,9 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); } else { - grpc_handshake_manager_do_handshake(exec_ctx, c->handshake_mgr, tcp, - c->args.channel_args, - c->args.deadline, on_handshake_done, - c); + grpc_handshake_manager_do_handshake( + exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, + c->args.deadline, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index 920875f6947..b8d816c1279 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -55,7 +55,7 @@ typedef struct server_connect_state { } server_connect_state; static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args* args, void *user_data) { + grpc_channel_args *args, void *user_data) { server_connect_state *state = user_data; /* * Beware that the call to grpc_create_chttp2_transport() has to happen before @@ -64,8 +64,8 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, * (as in server_secure_chttp2.c) needs to add synchronization to avoid this * case. */ - grpc_transport *transport = grpc_create_chttp2_transport( - exec_ctx, args, endpoint, 0); + grpc_transport *transport = + grpc_create_chttp2_transport(exec_ctx, args, endpoint, 0); grpc_server_setup_transport(exec_ctx, state->server, transport, state->accepting_pollset, grpc_server_get_channel_args(state->server)); diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index e3184bc1f93..bc714f4e5bc 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -74,7 +74,7 @@ typedef struct server_secure_connect { // TODO(roth): Remove the following two fields when we eliminate // grpc_server_security_connector_do_handshake(). gpr_timespec deadline; - grpc_channel_args* args; + grpc_channel_args *args; } server_secure_connect; static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); } @@ -129,7 +129,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args* args, void *user_data) { + grpc_channel_args *args, void *user_data) { server_secure_connect *state = user_data; // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 7dcbe1df9ce..9191ae63395 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -129,8 +129,7 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, // handshakers together. static void call_next_handshaker(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, - grpc_channel_args* args, - void* user_data) { + grpc_channel_args* args, void* user_data) { grpc_handshake_manager* mgr = user_data; GPR_ASSERT(mgr->state != NULL); GPR_ASSERT(mgr->state->index < mgr->count); @@ -153,13 +152,10 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, } } -void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, - grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, - const grpc_channel_args* args, - gpr_timespec deadline, - grpc_handshaker_done_cb cb, - void* user_data) { +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, const grpc_channel_args* args, + gpr_timespec deadline, grpc_handshaker_done_cb cb, void* user_data) { grpc_channel_args* args_copy = grpc_channel_args_copy(args); if (mgr->count == 0) { // No handshakers registered, so we just immediately call the done diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 6a39529150a..b8aa78c2454 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -131,12 +131,9 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, /// invoking the first handshaker. /// If successful, invokes \a cb with \a user_data after all handshakers /// have completed. -void grpc_handshake_manager_do_handshake(grpc_exec_ctx* exec_ctx, - grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, - const grpc_channel_args* args, - gpr_timespec deadline, - grpc_handshaker_done_cb cb, - void* user_data); +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, const grpc_channel_args* args, + gpr_timespec deadline, grpc_handshaker_done_cb cb, void* user_data); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From 5682a52cee47d6bbdd71bf1426cd603b306cc2b7 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 20 Jul 2016 09:54:41 -0700 Subject: [PATCH 09/12] Add acceptor parameter. --- .../chttp2/client/insecure/channel_create.c | 2 +- .../chttp2/client/secure/secure_channel_create.c | 4 ++-- .../chttp2/server/insecure/server_chttp2.c | 3 ++- .../chttp2/server/secure/server_secure_chttp2.c | 2 +- src/core/lib/channel/handshaker.c | 13 +++++++++---- src/core/lib/channel/handshaker.h | 12 +++++++++--- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 162cc6bd6ab..645a011748d 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -116,7 +116,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { } else { grpc_handshake_manager_do_handshake( exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, - c->args.deadline, on_handshake_done, c); + c->args.deadline, NULL /* acceptor */, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index dde35f253dd..01d949add3a 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -142,7 +142,7 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, connector *c = arg; grpc_handshake_manager_do_handshake( exec_ctx, c->handshake_mgr, c->connecting_endpoint, c->args.channel_args, - c->args.deadline, on_handshake_done, c); + c->args.deadline, NULL /* acceptor */, on_handshake_done, c); } static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -164,7 +164,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { } else { grpc_handshake_manager_do_handshake( exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, - c->args.deadline, on_handshake_done, c); + c->args.deadline, NULL /* acceptor */, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index b8d816c1279..8dac63c33bc 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -90,7 +90,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp, gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, grpc_server_get_channel_args(server), - deadline, on_handshake_done, state); + deadline, acceptor, on_handshake_done, + state); } /* Server callback: start listening on our ports */ diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index bc714f4e5bc..2b25fa09e64 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -158,7 +158,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, grpc_handshake_manager_do_handshake( exec_ctx, state->handshake_mgr, tcp, grpc_server_get_channel_args(state->state->server), state->deadline, - on_handshake_done, state); + acceptor, on_handshake_done, state); } /* Server callback: start listening on our ports */ diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 9191ae63395..9db04440ee8 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -63,9 +63,10 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, grpc_channel_args* args, gpr_timespec deadline, + grpc_tcp_server_acceptor *acceptor, grpc_handshaker_done_cb cb, void* user_data) { handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args, - deadline, cb, user_data); + deadline, acceptor, cb, user_data); } // @@ -78,6 +79,8 @@ struct grpc_handshaker_state { size_t index; // The deadline for all handshakers. gpr_timespec deadline; + // The acceptor to call the handshakers with. + grpc_tcp_server_acceptor *acceptor; // The final callback and user_data to invoke after the last handshaker. grpc_handshaker_done_cb final_cb; void* final_user_data; @@ -142,8 +145,8 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, } // Invoke handshaker. grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index], - endpoint, args, mgr->state->deadline, cb, - user_data); + endpoint, args, mgr->state->deadline, + mgr->state->acceptor, cb, user_data); ++mgr->state->index; // If this is the last handshaker, clean up state. if (mgr->state->index == mgr->count) { @@ -155,7 +158,8 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void grpc_handshake_manager_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, const grpc_channel_args* args, - gpr_timespec deadline, grpc_handshaker_done_cb cb, void* user_data) { + gpr_timespec deadline, grpc_tcp_server_acceptor *acceptor, + grpc_handshaker_done_cb cb, void* user_data) { grpc_channel_args* args_copy = grpc_channel_args_copy(args); if (mgr->count == 0) { // No handshakers registered, so we just immediately call the done @@ -166,6 +170,7 @@ void grpc_handshake_manager_do_handshake( mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state)); memset(mgr->state, 0, sizeof(*mgr->state)); mgr->state->deadline = deadline; + mgr->state->acceptor = acceptor; mgr->state->final_cb = cb; mgr->state->final_user_data = user_data; call_next_handshaker(exec_ctx, endpoint, args_copy, mgr); diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index b8aa78c2454..b1e91dba4f2 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -40,6 +40,7 @@ #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/tcp_server.h" /// Handshakers are used to perform initial handshakes on a connection /// before the client sends the initial request. Some examples of what @@ -71,10 +72,12 @@ struct grpc_handshaker_vtable { /// Performs handshaking. When finished, calls \a cb with \a user_data. /// Takes ownership of \a args. + /// \a acceptor will be NULL for client-side handshakers. void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, grpc_channel_args* args, - gpr_timespec deadline, grpc_handshaker_done_cb cb, - void* user_data); + gpr_timespec deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_handshaker_done_cb cb, void* user_data); }; /// Base struct. To subclass, make this the first member of the @@ -99,6 +102,7 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, grpc_channel_args* args, gpr_timespec deadline, + grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data); /// @@ -129,11 +133,13 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, /// Invokes handshakers in the order they were added. /// Does NOT take ownership of \a args. Instead, makes a copy before /// invoking the first handshaker. +/// \a acceptor will be NULL for client-side handshakers. /// If successful, invokes \a cb with \a user_data after all handshakers /// have completed. void grpc_handshake_manager_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, const grpc_channel_args* args, - gpr_timespec deadline, grpc_handshaker_done_cb cb, void* user_data); + gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, + grpc_handshaker_done_cb cb, void* user_data); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ From 0b84add2818028cfc881358c6f81bb4a5ac3d135 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 20 Jul 2016 10:08:48 -0700 Subject: [PATCH 10/12] Avoid allocating memory for each individual handshaker. Also fix memory leak. --- src/core/lib/channel/handshaker.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 9db04440ee8..ed8eb4a7f84 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -100,10 +100,24 @@ grpc_handshake_manager* grpc_handshake_manager_create() { return mgr; } +static bool is_power_of_2(size_t n) { + return (n & (n - 1)) == 0; +} + void grpc_handshake_manager_add(grpc_handshaker* handshaker, grpc_handshake_manager* mgr) { - mgr->handshakers = gpr_realloc(mgr->handshakers, - (mgr->count + 1) * sizeof(grpc_handshaker*)); + // To avoid allocating memory for each handshaker we add, we double + // the number of elements every time we need more. + size_t realloc_count = 0; + if (mgr->count == 0) { + realloc_count = 2; + } else if (mgr->count >= 2 && is_power_of_2(mgr->count)) { + realloc_count = mgr->count * 2; + } + if (realloc_count > 0) { + mgr->handshakers = gpr_realloc(mgr->handshakers, + realloc_count * sizeof(grpc_handshaker*)); + } mgr->handshakers[mgr->count++] = handshaker; } @@ -112,6 +126,7 @@ void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, for (size_t i = 0; i < mgr->count; ++i) { grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); } + gpr_free(mgr->handshakers); gpr_free(mgr); } From ac8df657a56cbb8010eec54755051da0a333cd0e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 21 Jul 2016 07:25:24 -0700 Subject: [PATCH 11/12] clang-format --- src/core/lib/channel/handshaker.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index ed8eb4a7f84..b3ee0ed6f93 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -63,7 +63,7 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, grpc_channel_args* args, gpr_timespec deadline, - grpc_tcp_server_acceptor *acceptor, + grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data) { handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args, deadline, acceptor, cb, user_data); @@ -80,7 +80,7 @@ struct grpc_handshaker_state { // The deadline for all handshakers. gpr_timespec deadline; // The acceptor to call the handshakers with. - grpc_tcp_server_acceptor *acceptor; + grpc_tcp_server_acceptor* acceptor; // The final callback and user_data to invoke after the last handshaker. grpc_handshaker_done_cb final_cb; void* final_user_data; @@ -100,9 +100,7 @@ grpc_handshake_manager* grpc_handshake_manager_create() { return mgr; } -static bool is_power_of_2(size_t n) { - return (n & (n - 1)) == 0; -} +static bool is_power_of_2(size_t n) { return (n & (n - 1)) == 0; } void grpc_handshake_manager_add(grpc_handshaker* handshaker, grpc_handshake_manager* mgr) { @@ -115,8 +113,8 @@ void grpc_handshake_manager_add(grpc_handshaker* handshaker, realloc_count = mgr->count * 2; } if (realloc_count > 0) { - mgr->handshakers = gpr_realloc(mgr->handshakers, - realloc_count * sizeof(grpc_handshaker*)); + mgr->handshakers = + gpr_realloc(mgr->handshakers, realloc_count * sizeof(grpc_handshaker*)); } mgr->handshakers[mgr->count++] = handshaker; } @@ -173,7 +171,7 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void grpc_handshake_manager_do_handshake( grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, grpc_endpoint* endpoint, const grpc_channel_args* args, - gpr_timespec deadline, grpc_tcp_server_acceptor *acceptor, + gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data) { grpc_channel_args* args_copy = grpc_channel_args_copy(args); if (mgr->count == 0) { From b16b1f29c3aa7238814cd70a4abcee0f35dc6b9f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 21 Jul 2016 11:24:32 -0700 Subject: [PATCH 12/12] clang-format --- .../ext/transport/chttp2/server/insecure/server_chttp2.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index 8dac63c33bc..016ce110fe0 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -88,10 +88,9 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp, // args instead of hard-coding it. const gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); - grpc_handshake_manager_do_handshake(exec_ctx, state->handshake_mgr, tcp, - grpc_server_get_channel_args(server), - deadline, acceptor, on_handshake_done, - state); + grpc_handshake_manager_do_handshake( + exec_ctx, state->handshake_mgr, tcp, grpc_server_get_channel_args(server), + deadline, acceptor, on_handshake_done, state); } /* Server callback: start listening on our ports */