grpc_channel *grpc_secure_channel_create_with_factories( const grpc_secure_channel_factory *factories, size_t num_factories, grpc_credentials *creds, const char *target, const grpc_channel_args *args) { size_t i; if (creds == NULL) { gpr_log(GPR_ERROR, "No credentials to create a secure channel."); return grpc_lame_client_channel_create(); } if (grpc_credentials_has_request_metadata_only(creds)) { gpr_log(GPR_ERROR, "Credentials is insufficient to create a secure channel."); return grpc_lame_client_channel_create(); } for (i = 0; i < num_factories; i++) { grpc_credentials *composite_creds = NULL; grpc_credentials *transport_security_creds = NULL; transport_security_creds = grpc_credentials_contains_type( creds, factories[i].creds_type, &composite_creds); if (transport_security_creds != NULL) { return factories[i].factory(transport_security_creds, composite_creds, target, args); } } gpr_log(GPR_ERROR, "Unknown credentials type %s for creating a secure channel.", creds->type); return grpc_lame_client_channel_create(); }
/* 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 */ }
grpc_channel *grpc_insecure_channel_create_from_fd( const char *target, int fd, const grpc_channel_args *args) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_API_TRACE("grpc_insecure_channel_create(target=%p, fd=%d, args=%p)", 3, (target, fd, args)); grpc_arg default_authority_arg; default_authority_arg.type = GRPC_ARG_STRING; default_authority_arg.key = GRPC_ARG_DEFAULT_AUTHORITY; default_authority_arg.value.string = "test.authority"; grpc_channel_args *final_args = grpc_channel_args_copy_and_add(args, &default_authority_arg, 1); int flags = fcntl(fd, F_GETFL, 0); GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0); grpc_endpoint *client = grpc_tcp_client_create_from_fd( &exec_ctx, grpc_fd_create(fd, "client"), args, "fd-client"); grpc_transport *transport = grpc_create_chttp2_transport(&exec_ctx, final_args, client, 1); GPR_ASSERT(transport); grpc_channel *channel = grpc_channel_create( &exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_channel_args_destroy(final_args); grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); return channel != NULL ? channel : grpc_lame_client_channel_create( target, GRPC_STATUS_INTERNAL, "Failed to create client channel"); }
grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds, grpc_credentials *request_metadata_creds, const char *target, const grpc_channel_args *args) { grpc_channel_security_context *ctx = NULL; grpc_channel *channel = NULL; grpc_security_status status = GRPC_SECURITY_OK; size_t i = 0; const char *overridden_target_name = NULL; grpc_arg arg; grpc_channel_args *new_args; for (i = 0; args && i < args->num_args; i++) { grpc_arg *arg = &args->args[i]; if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 && arg->type == GRPC_ARG_STRING) { overridden_target_name = arg->value.string; break; } } status = grpc_ssl_channel_security_context_create( request_metadata_creds, grpc_ssl_credentials_get_config(ssl_creds), target, overridden_target_name, &ctx); if (status != GRPC_SECURITY_OK) { return grpc_lame_client_channel_create(); } arg.type = GRPC_ARG_STRING; arg.key = GRPC_ARG_HTTP2_SCHEME; arg.value.string = "https"; new_args = grpc_channel_args_copy_and_add(args, &arg); channel = grpc_secure_channel_create_internal(target, new_args, ctx); grpc_security_context_unref(&ctx->base); grpc_channel_args_destroy(new_args); return channel; }
/* Create a client channel: Asynchronously: - resolve target - connect to it (trying alternatives as presented) - perform handshakes */ grpc_channel *grpc_insecure_channel_create(const char *target, const grpc_channel_args *args, void *reserved) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_API_TRACE( "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3, (target, args, reserved)); GPR_ASSERT(!reserved); 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); f->merge_args = grpc_channel_args_copy(args); grpc_channel *channel = client_channel_factory_create_channel( &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, NULL); if (channel != NULL) { f->master = channel; GRPC_CHANNEL_INTERNAL_REF(f->master, "grpc_insecure_channel_create"); } grpc_client_channel_factory_unref(&exec_ctx, &f->base); grpc_exec_ctx_finish(&exec_ctx); return channel != NULL ? channel : grpc_lame_client_channel_create( target, GRPC_STATUS_INTERNAL, "Failed to create client channel"); }
int main(int argc, char **argv) { grpc_channel *chan; grpc_call *call; grpc_completion_queue *cq; cq_verifier *cqv; grpc_op ops[6]; grpc_op *op; grpc_metadata_array trailing_metadata_recv; grpc_status_code status; char *details = NULL; size_t details_capacity = 0; grpc_test_init(argc, argv); grpc_init(); grpc_metadata_array_init(&trailing_metadata_recv); chan = grpc_lame_client_channel_create("lampoon:national"); GPR_ASSERT(chan); cq = grpc_completion_queue_create(); call = grpc_channel_create_call(chan, cq, "/Foo", "anywhere", GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100)); GPR_ASSERT(call); cqv = cq_verifier_create(cq); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op->flags = 0; op++; op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; op->data.recv_status_on_client.status = &status; op->data.recv_status_on_client.status_details = &details; op->data.recv_status_on_client.status_details_capacity = &details_capacity; op->flags = 0; op++; GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call, ops, op - ops, tag(1))); /* the call should immediately fail */ cq_expect_completion(cqv, tag(1), 1); cq_verify(cqv); grpc_call_destroy(call); grpc_channel_destroy(chan); cq_verifier_destroy(cqv); grpc_completion_queue_destroy(cq); grpc_metadata_array_destroy(&trailing_metadata_recv); gpr_free(details); grpc_shutdown(); return 0; }
int main(int argc, char **argv) { grpc_channel *chan; grpc_call *call; grpc_metadata md = {"a", "b", 1, {{NULL, NULL, NULL}}}; grpc_completion_queue *cq; cq_verifier *cqv; grpc_test_init(argc, argv); grpc_init(); chan = grpc_lame_client_channel_create(); GPR_ASSERT(chan); call = grpc_channel_create_call_old(chan, "/Foo", "anywhere", GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100)); GPR_ASSERT(call); cq = grpc_completion_queue_create(); cqv = cq_verifier_create(cq); /* we should be able to add metadata */ GPR_ASSERT(GRPC_CALL_OK == grpc_call_add_metadata_old(call, &md, 0)); /* and invoke the call */ GPR_ASSERT(GRPC_CALL_OK == grpc_call_invoke_old(call, cq, tag(2), tag(3), 0)); /* the call should immediately fail */ cq_expect_client_metadata_read(cqv, tag(2), NULL); cq_expect_finished(cqv, tag(3), NULL); cq_verify(cqv); grpc_call_destroy(call); grpc_channel_destroy(chan); cq_verifier_destroy(cqv); grpc_completion_queue_destroy(cq); grpc_shutdown(); return 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; }
int main(int argc, char **argv) { grpc_channel *chan; grpc_call *call; grpc_completion_queue *cq; cq_verifier *cqv; grpc_op ops[6]; grpc_op *op; grpc_metadata_array initial_metadata_recv; grpc_metadata_array trailing_metadata_recv; grpc_status_code status; grpc_call_error error; grpc_slice details; char *peer; grpc_test_init(argc, argv); grpc_init(); grpc_metadata_array_init(&initial_metadata_recv); grpc_metadata_array_init(&trailing_metadata_recv); chan = grpc_lame_client_channel_create( "lampoon:national", GRPC_STATUS_UNKNOWN, "Rpc sent on a lame channel."); GPR_ASSERT(chan); test_transport_op(chan); GPR_ASSERT(GRPC_CHANNEL_SHUTDOWN == grpc_channel_check_connectivity_state(chan, 0)); cq = grpc_completion_queue_create(NULL); grpc_slice host = grpc_slice_from_static_string("anywhere"); call = grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, grpc_slice_from_static_string("/Foo"), &host, grpc_timeout_seconds_to_deadline(100), NULL); GPR_ASSERT(call); cqv = cq_verifier_create(cq); memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_RECV_INITIAL_METADATA; op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; op->flags = 0; op->reserved = NULL; op++; error = grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); /* the call should immediately fail */ CQ_EXPECT_COMPLETION(cqv, tag(1), 0); cq_verify(cqv); memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; op->data.recv_status_on_client.status = &status; op->data.recv_status_on_client.status_details = &details; op->flags = 0; op->reserved = NULL; op++; error = grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(2), NULL); GPR_ASSERT(GRPC_CALL_OK == error); /* the call should immediately fail */ CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); peer = grpc_call_get_peer(call); GPR_ASSERT(strcmp(peer, "lampoon:national") == 0); gpr_free(peer); grpc_call_destroy(call); grpc_channel_destroy(chan); cq_verifier_destroy(cqv); grpc_completion_queue_destroy(cq); grpc_metadata_array_destroy(&initial_metadata_recv); grpc_metadata_array_destroy(&trailing_metadata_recv); grpc_slice_unref(details); grpc_shutdown(); return 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_credentials *creds, const char *target, const grpc_channel_args *args) { 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; if (grpc_find_security_connector_in_args(args) != NULL) { gpr_log(GPR_ERROR, "Cannot set security context in channel args."); return grpc_lame_client_channel_create(target); } if (grpc_credentials_create_security_connector( creds, target, args, NULL, &connector, &new_args_from_connector) != GRPC_SECURITY_OK) { return grpc_lame_client_channel_create(target); } mdctx = grpc_mdctx_create(); 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, 1); /* TODO(census) if (grpc_channel_args_is_census_enabled(args)) { filters[n++] = &grpc_client_census_filter; } */ filters[n++] = &grpc_compress_filter; filters[n++] = &grpc_client_channel_filter; GPR_ASSERT(n <= MAX_FILTERS); 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(&connector->base, "subchannel_factory"); f->security_connector = connector; f->merge_args = grpc_channel_args_copy(args_copy); resolver = grpc_resolver_create(target, &f->base); if (!resolver) { return NULL; } channel = grpc_channel_create_from_filters(target, filters, n, args_copy, mdctx, 1); grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), resolver); GRPC_RESOLVER_UNREF(resolver, "create"); grpc_subchannel_factory_unref(&f->base); GRPC_SECURITY_CONNECTOR_UNREF(&connector->base, "channel_create"); grpc_channel_args_destroy(args_copy); if (new_args_from_connector != NULL) { grpc_channel_args_destroy(new_args_from_connector); } return channel; }