Exemplo n.º 1
0
/* Create a secure client channel:
   Asynchronously: - resolve target
                   - connect to it (trying alternatives as presented)
                   - perform handshakes */
grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
        const char *target,
        const grpc_channel_args *args,
        void *reserved) {
    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);
        return grpc_lame_client_channel_create(
                   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) {
        grpc_exec_ctx_finish(&exec_ctx);
        return grpc_lame_client_channel_create(
                   target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
    }
    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);
    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, new_args);
    // Clean up.
    GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
                                  "secure_client_channel_factory_create_channel");
    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 */
}
Exemplo n.º 2
0
/* Create a secure client channel:
   Asynchronously: - resolve target
                   - connect to it (trying alternatives as presented)
                   - perform handshakes */
grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
                                         const char *target,
                                         const grpc_channel_args *args,
                                         void *reserved) {
  grpc_channel *channel;
  grpc_arg connector_arg;
  grpc_channel_args *args_copy;
  grpc_channel_args *new_args_from_connector;
  grpc_channel_security_connector *security_connector;
  grpc_mdctx *mdctx;
  grpc_resolver *resolver;
  subchannel_factory *f;
#define MAX_FILTERS 3
  const grpc_channel_filter *filters[MAX_FILTERS];
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  size_t n = 0;

  GRPC_API_TRACE(
      "grpc_secure_channel_create(creds=%p, target=%s, args=%p, "
      "reserved=%p)",
      4, (creds, target, args, reserved));
  GPR_ASSERT(reserved == NULL);

  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);
    return grpc_lame_client_channel_create(
        target, GRPC_STATUS_INVALID_ARGUMENT,
        "Security connector exists in channel args.");
  }

  if (grpc_channel_credentials_create_security_connector(
          creds, target, args, &security_connector, &new_args_from_connector) !=
      GRPC_SECURITY_OK) {
    grpc_exec_ctx_finish(&exec_ctx);
    return grpc_lame_client_channel_create(
        target, GRPC_STATUS_INVALID_ARGUMENT,
        "Failed to create security connector.");
  }
  mdctx = grpc_mdctx_create();

  connector_arg = grpc_security_connector_to_arg(&security_connector->base);
  args_copy = grpc_channel_args_copy_and_add(
      new_args_from_connector != NULL ? new_args_from_connector : args,
      &connector_arg, 1);
  if (grpc_channel_args_is_census_enabled(args)) {
    filters[n++] = &grpc_client_census_filter;
  }
  filters[n++] = &grpc_compress_filter;
  filters[n++] = &grpc_client_channel_filter;
  GPR_ASSERT(n <= MAX_FILTERS);

  channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
                                             args_copy, mdctx, 1);

  f = gpr_malloc(sizeof(*f));
  f->base.vtable = &subchannel_factory_vtable;
  gpr_ref_init(&f->refs, 1);
  grpc_mdctx_ref(mdctx);
  f->mdctx = mdctx;
  GRPC_SECURITY_CONNECTOR_REF(&security_connector->base, "subchannel_factory");
  f->security_connector = security_connector;
  f->merge_args = grpc_channel_args_copy(args_copy);
  f->master = channel;
  GRPC_CHANNEL_INTERNAL_REF(channel, "subchannel_factory");
  resolver = grpc_resolver_create(target, &f->base);
  if (!resolver) {
    grpc_exec_ctx_finish(&exec_ctx);
    return NULL;
  }

  grpc_client_channel_set_resolver(
      &exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
  GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create");
  grpc_subchannel_factory_unref(&exec_ctx, &f->base);
  GRPC_SECURITY_CONNECTOR_UNREF(&security_connector->base, "channel_create");

  grpc_channel_args_destroy(args_copy);
  if (new_args_from_connector != NULL) {
    grpc_channel_args_destroy(new_args_from_connector);
  }

  grpc_exec_ctx_finish(&exec_ctx);

  return channel;
}