|  | @@ -54,6 +54,10 @@
 | 
	
		
			
				|  |  |  #include "src/core/lib/surface/channel.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/tsi/transport_security_interface.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +// connector
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  typedef struct {
 | 
	
		
			
				|  |  |    grpc_connector base;
 | 
	
		
			
				|  |  |    gpr_refcount refs;
 | 
	
	
		
			
				|  | @@ -216,10 +220,13 @@ static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con,
 | 
	
		
			
				|  |  |  static const grpc_connector_vtable connector_vtable = {
 | 
	
		
			
				|  |  |      connector_ref, connector_unref, connector_shutdown, connector_connect};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +// client_channel_factory
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  typedef struct {
 | 
	
		
			
				|  |  |    grpc_client_channel_factory base;
 | 
	
		
			
				|  |  |    gpr_refcount refs;
 | 
	
		
			
				|  |  | -  grpc_channel_args *merge_args;
 | 
	
		
			
				|  |  |    grpc_channel_security_connector *security_connector;
 | 
	
		
			
				|  |  |  } client_channel_factory;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -235,7 +242,6 @@ static void client_channel_factory_unref(
 | 
	
		
			
				|  |  |    if (gpr_unref(&f->refs)) {
 | 
	
		
			
				|  |  |      GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
 | 
	
		
			
				|  |  |                                    "client_channel_factory");
 | 
	
		
			
				|  |  | -    grpc_channel_args_destroy(f->merge_args);
 | 
	
		
			
				|  |  |      gpr_free(f);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -245,9 +251,6 @@ static grpc_subchannel *client_channel_factory_create_subchannel(
 | 
	
		
			
				|  |  |      grpc_subchannel_args *args) {
 | 
	
		
			
				|  |  |    client_channel_factory *f = (client_channel_factory *)cc_factory;
 | 
	
		
			
				|  |  |    connector *c = gpr_malloc(sizeof(*c));
 | 
	
		
			
				|  |  | -  grpc_channel_args *final_args =
 | 
	
		
			
				|  |  | -      grpc_channel_args_merge(args->args, f->merge_args);
 | 
	
		
			
				|  |  | -  grpc_subchannel *s;
 | 
	
		
			
				|  |  |    memset(c, 0, sizeof(*c));
 | 
	
		
			
				|  |  |    c->base.vtable = &connector_vtable;
 | 
	
		
			
				|  |  |    c->security_connector = f->security_connector;
 | 
	
	
		
			
				|  | @@ -261,10 +264,8 @@ static grpc_subchannel *client_channel_factory_create_subchannel(
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    gpr_mu_init(&c->mu);
 | 
	
		
			
				|  |  |    gpr_ref_init(&c->refs, 1);
 | 
	
		
			
				|  |  | -  args->args = final_args;
 | 
	
		
			
				|  |  | -  s = grpc_subchannel_create(exec_ctx, &c->base, args);
 | 
	
		
			
				|  |  | +  grpc_subchannel *s = grpc_subchannel_create(exec_ctx, &c->base, args);
 | 
	
		
			
				|  |  |    grpc_connector_unref(exec_ctx, &c->base);
 | 
	
		
			
				|  |  | -  grpc_channel_args_destroy(final_args);
 | 
	
		
			
				|  |  |    return s;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -273,13 +274,9 @@ static grpc_channel *client_channel_factory_create_channel(
 | 
	
		
			
				|  |  |      const char *target, grpc_client_channel_type type,
 | 
	
		
			
				|  |  |      grpc_channel_args *args) {
 | 
	
		
			
				|  |  |    client_channel_factory *f = (client_channel_factory *)cc_factory;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  grpc_channel_args *final_args = grpc_channel_args_merge(args, f->merge_args);
 | 
	
		
			
				|  |  | -  grpc_channel *channel = grpc_channel_create(exec_ctx, target, final_args,
 | 
	
		
			
				|  |  | +  grpc_channel *channel = grpc_channel_create(exec_ctx, target, args,
 | 
	
		
			
				|  |  |                                                GRPC_CLIENT_CHANNEL, NULL);
 | 
	
		
			
				|  |  | -  grpc_channel_args_destroy(final_args);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  grpc_resolver *resolver = grpc_resolver_create(target);
 | 
	
		
			
				|  |  | +  grpc_resolver *resolver = grpc_resolver_create(target, args);
 | 
	
		
			
				|  |  |    if (resolver != NULL) {
 | 
	
		
			
				|  |  |      grpc_client_channel_finish_initialization(
 | 
	
		
			
				|  |  |          exec_ctx, grpc_channel_get_channel_stack(channel), resolver, &f->base);
 | 
	
	
		
			
				|  | @@ -289,7 +286,6 @@ static grpc_channel *client_channel_factory_create_channel(
 | 
	
		
			
				|  |  |                                  "client_channel_factory_create_channel");
 | 
	
		
			
				|  |  |      channel = NULL;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
 | 
	
		
			
				|  |  |                                  "client_channel_factory_create_channel");
 | 
	
		
			
				|  |  |    return channel;
 | 
	
	
		
			
				|  | @@ -308,19 +304,13 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
 | 
	
		
			
				|  |  |                                           const char *target,
 | 
	
		
			
				|  |  |                                           const grpc_channel_args *args,
 | 
	
		
			
				|  |  |                                           void *reserved) {
 | 
	
		
			
				|  |  | -  grpc_arg connector_arg;
 | 
	
		
			
				|  |  | -  grpc_channel_args *args_copy;
 | 
	
		
			
				|  |  | -  grpc_channel_args *new_args_from_connector;
 | 
	
		
			
				|  |  | -  grpc_channel_security_connector *security_connector;
 | 
	
		
			
				|  |  | -  client_channel_factory *f;
 | 
	
		
			
				|  |  |    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    GRPC_API_TRACE(
 | 
	
		
			
				|  |  |        "grpc_secure_channel_create(creds=%p, target=%s, args=%p, "
 | 
	
		
			
				|  |  |        "reserved=%p)",
 | 
	
		
			
				|  |  |        4, (creds, target, args, reserved));
 | 
	
		
			
				|  |  |    GPR_ASSERT(reserved == NULL);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +  // Make sure security connector does not already exist in args.
 | 
	
		
			
				|  |  |    if (grpc_find_security_connector_in_args(args) != NULL) {
 | 
	
		
			
				|  |  |      gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
 | 
	
		
			
				|  |  |      grpc_exec_ctx_finish(&exec_ctx);
 | 
	
	
		
			
				|  | @@ -328,7 +318,9 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
 | 
	
		
			
				|  |  |          target, GRPC_STATUS_INTERNAL,
 | 
	
		
			
				|  |  |          "Security connector exists in channel args.");
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +  // Create security connector and construct new channel args.
 | 
	
		
			
				|  |  | +  grpc_channel_security_connector *security_connector;
 | 
	
		
			
				|  |  | +  grpc_channel_args *new_args_from_connector;
 | 
	
		
			
				|  |  |    if (grpc_channel_credentials_create_security_connector(
 | 
	
		
			
				|  |  |            creds, target, args, &security_connector, &new_args_from_connector) !=
 | 
	
		
			
				|  |  |        GRPC_SECURITY_OK) {
 | 
	
	
		
			
				|  | @@ -336,32 +328,28 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
 | 
	
		
			
				|  |  |      return grpc_lame_client_channel_create(
 | 
	
		
			
				|  |  |          target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  connector_arg = grpc_security_connector_to_arg(&security_connector->base);
 | 
	
		
			
				|  |  | -  args_copy = grpc_channel_args_copy_and_add(
 | 
	
		
			
				|  |  | +  grpc_arg connector_arg =
 | 
	
		
			
				|  |  | +      grpc_security_connector_to_arg(&security_connector->base);
 | 
	
		
			
				|  |  | +  grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
 | 
	
		
			
				|  |  |        new_args_from_connector != NULL ? new_args_from_connector : args,
 | 
	
		
			
				|  |  |        &connector_arg, 1);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  f = gpr_malloc(sizeof(*f));
 | 
	
		
			
				|  |  | -  memset(f, 0, sizeof(*f));
 | 
	
		
			
				|  |  | -  f->base.vtable = &client_channel_factory_vtable;
 | 
	
		
			
				|  |  | -  gpr_ref_init(&f->refs, 1);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  f->merge_args = grpc_channel_args_copy(args_copy);
 | 
	
		
			
				|  |  | -  grpc_channel_args_destroy(args_copy);
 | 
	
		
			
				|  |  |    if (new_args_from_connector != NULL) {
 | 
	
		
			
				|  |  |      grpc_channel_args_destroy(new_args_from_connector);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +  // Create client channel factory.
 | 
	
		
			
				|  |  | +  client_channel_factory *f = gpr_malloc(sizeof(*f));
 | 
	
		
			
				|  |  | +  memset(f, 0, sizeof(*f));
 | 
	
		
			
				|  |  | +  f->base.vtable = &client_channel_factory_vtable;
 | 
	
		
			
				|  |  | +  gpr_ref_init(&f->refs, 1);
 | 
	
		
			
				|  |  |    GRPC_SECURITY_CONNECTOR_REF(&security_connector->base,
 | 
	
		
			
				|  |  |                                "grpc_secure_channel_create");
 | 
	
		
			
				|  |  |    f->security_connector = security_connector;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +  // Create channel.
 | 
	
		
			
				|  |  |    grpc_channel *channel = client_channel_factory_create_channel(
 | 
	
		
			
				|  |  | -      &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, NULL);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +      &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
 | 
	
		
			
				|  |  | +  // Clean up.
 | 
	
		
			
				|  |  | +  grpc_channel_args_destroy(new_args);
 | 
	
		
			
				|  |  |    grpc_client_channel_factory_unref(&exec_ctx, &f->base);
 | 
	
		
			
				|  |  |    grpc_exec_ctx_finish(&exec_ctx);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    return channel; /* may be NULL */
 | 
	
		
			
				|  |  |  }
 |