diff options
Diffstat (limited to 'src/core/surface/secure_channel_create.c')
-rw-r--r-- | src/core/surface/secure_channel_create.c | 147 |
1 files changed, 130 insertions, 17 deletions
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index fae3e4e90a..ad11c3954b 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -31,36 +31,131 @@ * */ -#include "src/core/iomgr/sockaddr.h" - #include <grpc/grpc.h> #include <stdlib.h> #include <string.h> -#include "src/core/channel/census_filter.h" +#include <grpc/support/alloc.h> + #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" -#include "src/core/channel/client_setup.h" -#include "src/core/channel/connected_channel.h" #include "src/core/channel/http_client_filter.h" -#include "src/core/iomgr/resolve_address.h" +#include "src/core/client_config/resolver_registry.h" #include "src/core/iomgr/tcp_client.h" #include "src/core/security/auth_filters.h" #include "src/core/security/credentials.h" #include "src/core/security/secure_transport_setup.h" -#include "src/core/support/string.h" #include "src/core/surface/channel.h" -#include "src/core/surface/client.h" #include "src/core/transport/chttp2_transport.h" -#include <grpc/grpc_security.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include <grpc/support/sync.h> -#include <grpc/support/useful.h> #include "src/core/tsi/transport_security_interface.h" +typedef struct { + grpc_connector base; + gpr_refcount refs; + + grpc_channel_security_connector *security_connector; + + grpc_iomgr_closure *notify; + grpc_connect_in_args args; + grpc_connect_out_args *result; +} connector; + +static void connector_ref(grpc_connector *con) { + connector *c = (connector *)con; + gpr_ref(&c->refs); +} + +static void connector_unref(grpc_connector *con) { + connector *c = (connector *)con; + if (gpr_unref(&c->refs)) { + gpr_free(c); + } +} + +static void on_secure_transport_setup_done(void *arg, + grpc_security_status status, + grpc_endpoint *secure_endpoint) { + connector *c = arg; + grpc_iomgr_closure *notify; + if (status != GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status); + memset(c->result, 0, sizeof(*c->result)); + notify = c->notify; + c->notify = NULL; + grpc_iomgr_add_callback(notify); + } else { + c->result->transport = grpc_create_chttp2_transport( + c->args.channel_args, secure_endpoint, + NULL, 0, c->args.metadata_context, 1); + } +} + +static void connected(void *arg, grpc_endpoint *tcp) { + connector *c = arg; + grpc_iomgr_closure *notify; + if (tcp != NULL) { + grpc_setup_secure_transport(&c->security_connector->base, tcp, + on_secure_transport_setup_done, c); + } else { + memset(c->result, 0, sizeof(*c->result)); + notify = c->notify; + c->notify = NULL; + grpc_iomgr_add_callback(notify); + } +} + +static void connector_connect( + grpc_connector *con, const grpc_connect_in_args *args, + grpc_connect_out_args *result, grpc_iomgr_closure *notify) { + connector *c = (connector *)con; + GPR_ASSERT(c->notify == NULL); + GPR_ASSERT(notify->cb); + c->notify = notify; + c->args = *args; + c->result = result; + grpc_tcp_client_connect(connected, c, args->interested_parties, args->addr, args->addr_len, args->deadline); +} + +static const grpc_connector_vtable connector_vtable = {connector_ref, connector_unref, connector_connect}; + +typedef struct { + grpc_subchannel_factory base; + gpr_refcount refs; + grpc_mdctx *mdctx; + grpc_channel_security_connector *security_connector; +} subchannel_factory; + +static void subchannel_factory_ref(grpc_subchannel_factory *scf) { + subchannel_factory *f = (subchannel_factory *)scf; + gpr_ref(&f->refs); +} + +static void subchannel_factory_unref(grpc_subchannel_factory *scf) { + subchannel_factory *f = (subchannel_factory *)scf; + if (gpr_unref(&f->refs)) { + grpc_mdctx_unref(f->mdctx); + gpr_free(f); + } +} + +static grpc_subchannel *subchannel_factory_create_subchannel(grpc_subchannel_factory *scf, grpc_subchannel_args *args) { + subchannel_factory *f = (subchannel_factory *)scf; + connector *c = gpr_malloc(sizeof(*c)); + grpc_subchannel *s; + memset(c, 0, sizeof(*c)); + c->base.vtable = &connector_vtable; + c->security_connector = f->security_connector; + gpr_ref_init(&c->refs, 1); + args->mdctx = f->mdctx; + s = grpc_subchannel_create(&c->base, args); + grpc_connector_unref(&c->base); + return s; +} + +static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {subchannel_factory_ref, subchannel_factory_unref, subchannel_factory_create_subchannel}; + +#if 0 typedef struct setup setup; /* A single setup request (started via initiate) */ @@ -203,6 +298,8 @@ static grpc_transport_setup_result complete_setup(void *channel_stack, mdctx); } +#endif + /* Create a secure client channel: Asynchronously: - resolve target - connect to it (trying alternatives as presented) @@ -210,13 +307,14 @@ static grpc_transport_setup_result complete_setup(void *channel_stack, grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, const char *target, const grpc_channel_args *args) { - setup *s; grpc_channel *channel; grpc_arg connector_arg; grpc_channel_args *args_copy; grpc_channel_args *new_args_from_connector; grpc_channel_security_connector *connector; grpc_mdctx *mdctx; + grpc_resolver *resolver; + subchannel_factory *f; #define MAX_FILTERS 3 const grpc_channel_filter *filters[MAX_FILTERS]; int n = 0; @@ -233,24 +331,37 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, } mdctx = grpc_mdctx_create(); - s = gpr_malloc(sizeof(setup)); connector_arg = grpc_security_connector_to_arg(&connector->base); args_copy = grpc_channel_args_copy_and_add( new_args_from_connector != NULL ? new_args_from_connector : args, &connector_arg); - filters[n++] = &grpc_client_surface_filter; /* TODO(census) if (grpc_channel_args_is_census_enabled(args)) { filters[n++] = &grpc_client_census_filter; } */ filters[n++] = &grpc_client_channel_filter; GPR_ASSERT(n <= MAX_FILTERS); + + f = gpr_malloc(sizeof(*f)); + f->base.vtable = &subchannel_factory_vtable; + gpr_ref_init(&f->refs, 1); + f->mdctx = mdctx; + f->security_connector = connector; + resolver = grpc_resolver_create(target, &f->base); + if (!resolver) { + return NULL; + } + channel = grpc_channel_create_from_filters(filters, n, args_copy, mdctx, 1); + grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), resolver); + grpc_resolver_unref(resolver); + grpc_channel_args_destroy(args_copy); if (new_args_from_connector != NULL) { grpc_channel_args_destroy(new_args_from_connector); } +#if 0 s->target = gpr_strdup(target); s->setup_callback = complete_setup; s->setup_user_data = grpc_channel_get_channel_stack(channel); @@ -258,5 +369,7 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, grpc_client_setup_create_and_attach(grpc_channel_get_channel_stack(channel), args, mdctx, initiate_setup, done_setup, s); +#endif + return channel; } |