示例#1
0
grpc_call *grpc_channel_create_pollset_set_call(
    grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
    uint32_t propagation_mask, grpc_pollset_set *pollset_set, grpc_slice method,
    const grpc_slice *host, gpr_timespec deadline, void *reserved) {
  GPR_ASSERT(!reserved);
  return grpc_channel_create_call_internal(
      exec_ctx, channel, parent_call, propagation_mask, NULL, pollset_set,
      grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_PATH,
                              grpc_slice_ref_internal(method)),
      host != NULL ? grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_AUTHORITY,
                                             grpc_slice_ref_internal(*host))
                   : GRPC_MDNULL,
      deadline);
}
示例#2
0
static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
                                    grpc_credentials_md *md_elems,
                                    size_t num_md,
                                    grpc_credentials_status status) {
  grpc_call_element *elem = (grpc_call_element *)user_data;
  call_data *calld = elem->call_data;
  channel_data *chand = elem->channel_data;
  grpc_transport_stream_op *op = &calld->op;
  grpc_metadata_batch *mdb;
  size_t i;
  reset_service_url(calld);
  if (status != GRPC_CREDENTIALS_OK) {
    bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
                    "Credentials failed to get metadata.");
    return;
  }
  GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
  GPR_ASSERT(op->send_ops && op->send_ops->nops > calld->op_md_idx &&
             op->send_ops->ops[calld->op_md_idx].type == GRPC_OP_METADATA);
  mdb = &op->send_ops->ops[calld->op_md_idx].data.metadata;
  for (i = 0; i < num_md; i++) {
    grpc_metadata_batch_add_tail(
        mdb, &calld->md_links[i],
        grpc_mdelem_from_slices(chand->md_ctx, gpr_slice_ref(md_elems[i].key),
                                gpr_slice_ref(md_elems[i].value)));
  }
  grpc_call_next_op(exec_ctx, elem, op);
}
static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
                                    grpc_credentials_md *md_elems,
                                    size_t num_md,
                                    grpc_credentials_status status,
                                    const char *error_details) {
  grpc_call_element *elem = (grpc_call_element *)user_data;
  call_data *calld = elem->call_data;
  grpc_transport_stream_op *op = &calld->op;
  grpc_metadata_batch *mdb;
  size_t i;
  reset_auth_metadata_context(&calld->auth_md_context);
  if (status != GRPC_CREDENTIALS_OK) {
    bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
                    (error_details != NULL && strlen(error_details) > 0)
                        ? error_details
                        : "Credentials failed to get metadata.");
    return;
  }
  GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
  GPR_ASSERT(op->send_initial_metadata != NULL);
  mdb = op->send_initial_metadata;
  for (i = 0; i < num_md; i++) {
    grpc_metadata_batch_add_tail(
        mdb, &calld->md_links[i],
        grpc_mdelem_from_slices(gpr_slice_ref(md_elems[i].key),
                                gpr_slice_ref(md_elems[i].value)));
  }
  grpc_call_next_op(exec_ctx, elem, op);
}
示例#4
0
static grpc_error *fill_in_metadata(grpc_exec_ctx *exec_ctx, inproc_stream *s,
                                    const grpc_metadata_batch *metadata,
                                    uint32_t flags, grpc_metadata_batch *out_md,
                                    uint32_t *outflags, bool *markfilled) {
  if (GRPC_TRACER_ON(grpc_inproc_trace)) {
    log_metadata(metadata, s->t->is_client, outflags != NULL);
  }

  if (outflags != NULL) {
    *outflags = flags;
  }
  if (markfilled != NULL) {
    *markfilled = true;
  }
  grpc_error *error = GRPC_ERROR_NONE;
  for (grpc_linked_mdelem *elem = metadata->list.head;
       (elem != NULL) && (error == GRPC_ERROR_NONE); elem = elem->next) {
    grpc_linked_mdelem *nelem = gpr_arena_alloc(s->arena, sizeof(*nelem));
    nelem->md = grpc_mdelem_from_slices(
        exec_ctx, grpc_slice_intern(GRPC_MDKEY(elem->md)),
        grpc_slice_intern(GRPC_MDVALUE(elem->md)));

    error = grpc_metadata_batch_link_tail(exec_ctx, out_md, nelem);
  }
  return error;
}
示例#5
0
grpc_call *grpc_channel_create_call(grpc_channel *channel,
                                    grpc_call *parent_call,
                                    uint32_t propagation_mask,
                                    grpc_completion_queue *cq,
                                    grpc_slice method, const grpc_slice *host,
                                    gpr_timespec deadline, void *reserved) {
  GPR_ASSERT(!reserved);
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_call *call = grpc_channel_create_call_internal(
      &exec_ctx, channel, parent_call, propagation_mask, cq, NULL,
      grpc_mdelem_from_slices(&exec_ctx, GRPC_MDSTR_PATH,
                              grpc_slice_ref_internal(method)),
      host != NULL ? grpc_mdelem_from_slices(&exec_ctx, GRPC_MDSTR_AUTHORITY,
                                             grpc_slice_ref_internal(*host))
                   : GRPC_MDNULL,
      deadline);
  grpc_exec_ctx_finish(&exec_ctx);
  return call;
}
示例#6
0
static void deadline_enc(grpc_exec_ctx *exec_ctx,
                         grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
                         framer_state *st) {
  char timeout_str[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE];
  grpc_mdelem mdelem;
  grpc_http2_encode_timeout(
      gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str);
  mdelem = grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_TIMEOUT,
                                   grpc_slice_from_copied_string(timeout_str));
  hpack_enc(exec_ctx, c, mdelem, st);
  GRPC_MDELEM_UNREF(exec_ctx, mdelem);
}
示例#7
0
void *grpc_channel_register_call(grpc_channel *channel, const char *method,
                                 const char *host, void *reserved) {
  registered_call *rc = gpr_malloc(sizeof(registered_call));
  GRPC_API_TRACE(
      "grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)",
      4, (channel, method, host, reserved));
  GPR_ASSERT(!reserved);
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

  rc->path = grpc_mdelem_from_slices(
      &exec_ctx, GRPC_MDSTR_PATH,
      grpc_slice_intern(grpc_slice_from_static_string(method)));
  rc->authority =
      host ? grpc_mdelem_from_slices(
                 &exec_ctx, GRPC_MDSTR_AUTHORITY,
                 grpc_slice_intern(grpc_slice_from_static_string(host)))
           : GRPC_MDNULL;
  gpr_mu_lock(&channel->registered_call_mu);
  rc->next = channel->registered_calls;
  channel->registered_calls = rc;
  gpr_mu_unlock(&channel->registered_call_mu);
  grpc_exec_ctx_finish(&exec_ctx);
  return rc;
}
示例#8
0
static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
                                    grpc_credentials_md *md_elems,
                                    size_t num_md,
                                    grpc_credentials_status status,
                                    const char *error_details) {
  grpc_call_element *elem = (grpc_call_element *)user_data;
  call_data *calld = elem->call_data;
  grpc_transport_stream_op *op = &calld->op;
  grpc_metadata_batch *mdb;
  size_t i;
  reset_auth_metadata_context(&calld->auth_md_context);
  grpc_error *error = GRPC_ERROR_NONE;
  if (status != GRPC_CREDENTIALS_OK) {
    error = grpc_error_set_int(
        GRPC_ERROR_CREATE(error_details != NULL && strlen(error_details) > 0
                              ? error_details
                              : "Credentials failed to get metadata."),
        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED);
  } else {
    GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
    GPR_ASSERT(op->send_initial_metadata != NULL);
    mdb = op->send_initial_metadata;
    for (i = 0; i < num_md; i++) {
      add_error(&error,
                grpc_metadata_batch_add_tail(
                    exec_ctx, mdb, &calld->md_links[i],
                    grpc_mdelem_from_slices(
                        exec_ctx, grpc_slice_ref_internal(md_elems[i].key),
                        grpc_slice_ref_internal(md_elems[i].value))));
    }
  }
  if (error == GRPC_ERROR_NONE) {
    grpc_call_next_op(exec_ctx, elem, op);
  } else {
    grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
  }
}
示例#9
0
grpc_channel *grpc_channel_create_with_builder(
    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
    grpc_channel_stack_type channel_stack_type) {
  char *target = gpr_strdup(grpc_channel_stack_builder_get_target(builder));
  grpc_channel_args *args = grpc_channel_args_copy(
      grpc_channel_stack_builder_get_channel_arguments(builder));
  grpc_channel *channel;
  grpc_error *error = grpc_channel_stack_builder_finish(
      exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL,
      (void **)&channel);
  if (error != GRPC_ERROR_NONE) {
    gpr_log(GPR_ERROR, "channel stack builder failed: %s",
            grpc_error_string(error));
    GRPC_ERROR_UNREF(error);
    gpr_free(target);
    goto done;
  }

  memset(channel, 0, sizeof(*channel));
  channel->target = target;
  channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
  gpr_mu_init(&channel->registered_call_mu);
  channel->registered_calls = NULL;

  gpr_atm_no_barrier_store(
      &channel->call_size_estimate,
      (gpr_atm)CHANNEL_STACK_FROM_CHANNEL(channel)->call_stack_size);

  grpc_compression_options_init(&channel->compression_options);
  for (size_t i = 0; i < args->num_args; i++) {
    if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
      if (args->args[i].type != GRPC_ARG_STRING) {
        gpr_log(GPR_ERROR, "%s ignored: it must be a string",
                GRPC_ARG_DEFAULT_AUTHORITY);
      } else {
        if (!GRPC_MDISNULL(channel->default_authority)) {
          /* setting this takes precedence over anything else */
          GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
        }
        channel->default_authority = grpc_mdelem_from_slices(
            exec_ctx, GRPC_MDSTR_AUTHORITY,
            grpc_slice_intern(
                grpc_slice_from_static_string(args->args[i].value.string)));
      }
    } else if (0 ==
               strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
      if (args->args[i].type != GRPC_ARG_STRING) {
        gpr_log(GPR_ERROR, "%s ignored: it must be a string",
                GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
      } else {
        if (!GRPC_MDISNULL(channel->default_authority)) {
          /* other ways of setting this (notably ssl) take precedence */
          gpr_log(GPR_ERROR,
                  "%s ignored: default host already set some other way",
                  GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
        } else {
          channel->default_authority = grpc_mdelem_from_slices(
              exec_ctx, GRPC_MDSTR_AUTHORITY,
              grpc_slice_intern(
                  grpc_slice_from_static_string(args->args[i].value.string)));
        }
      }
    } else if (0 == strcmp(args->args[i].key,
                           GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
      channel->compression_options.default_level.is_set = true;
      channel->compression_options.default_level.level =
          (grpc_compression_level)grpc_channel_arg_get_integer(
              &args->args[i],
              (grpc_integer_options){GRPC_COMPRESS_LEVEL_NONE,
                                     GRPC_COMPRESS_LEVEL_NONE,
                                     GRPC_COMPRESS_LEVEL_COUNT - 1});
    } else if (0 == strcmp(args->args[i].key,
                           GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
      channel->compression_options.default_algorithm.is_set = true;
      channel->compression_options.default_algorithm.algorithm =
          (grpc_compression_algorithm)grpc_channel_arg_get_integer(
              &args->args[i],
              (grpc_integer_options){GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
                                     GRPC_COMPRESS_ALGORITHMS_COUNT - 1});
    } else if (0 ==
               strcmp(args->args[i].key,
                      GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
      channel->compression_options.enabled_algorithms_bitset =
          (uint32_t)args->args[i].value.integer |
          0x1; /* always support no compression */
    }
  }

done:
  grpc_channel_args_destroy(exec_ctx, args);
  return channel;
}
示例#10
0
static void fail_helper_locked(grpc_exec_ctx *exec_ctx, inproc_stream *s,
                               grpc_error *error) {
  INPROC_LOG(GPR_DEBUG, "read_state_machine %p fail_helper", s);
  // If we're failing this side, we need to make sure that
  // we also send or have already sent trailing metadata
  if (!s->trailing_md_sent) {
    // Send trailing md to the other side indicating cancellation
    s->trailing_md_sent = true;

    grpc_metadata_batch fake_md;
    grpc_metadata_batch_init(&fake_md);

    inproc_stream *other = s->other_side;
    grpc_metadata_batch *dest = (other == NULL) ? &s->write_buffer_trailing_md
                                                : &other->to_read_trailing_md;
    bool *destfilled = (other == NULL) ? &s->write_buffer_trailing_md_filled
                                       : &other->to_read_trailing_md_filled;
    fill_in_metadata(exec_ctx, s, &fake_md, 0, dest, NULL, destfilled);
    grpc_metadata_batch_destroy(exec_ctx, &fake_md);

    if (other != NULL) {
      if (other->cancel_other_error == GRPC_ERROR_NONE) {
        other->cancel_other_error = GRPC_ERROR_REF(error);
      }
      if (other->reads_needed) {
        if (!other->read_closure_scheduled) {
          GRPC_CLOSURE_SCHED(exec_ctx, &other->read_closure,
                             GRPC_ERROR_REF(error));
          other->read_closure_scheduled = true;
        }
        other->reads_needed = false;
      }
    } else if (s->write_buffer_cancel_error == GRPC_ERROR_NONE) {
      s->write_buffer_cancel_error = GRPC_ERROR_REF(error);
    }
  }
  if (s->recv_initial_md_op) {
    grpc_error *err;
    if (!s->t->is_client) {
      // If this is a server, provide initial metadata with a path and authority
      // since it expects that as well as no error yet
      grpc_metadata_batch fake_md;
      grpc_metadata_batch_init(&fake_md);
      grpc_linked_mdelem *path_md = gpr_arena_alloc(s->arena, sizeof(*path_md));
      path_md->md =
          grpc_mdelem_from_slices(exec_ctx, g_fake_path_key, g_fake_path_value);
      GPR_ASSERT(grpc_metadata_batch_link_tail(exec_ctx, &fake_md, path_md) ==
                 GRPC_ERROR_NONE);
      grpc_linked_mdelem *auth_md = gpr_arena_alloc(s->arena, sizeof(*auth_md));
      auth_md->md =
          grpc_mdelem_from_slices(exec_ctx, g_fake_auth_key, g_fake_auth_value);
      GPR_ASSERT(grpc_metadata_batch_link_tail(exec_ctx, &fake_md, auth_md) ==
                 GRPC_ERROR_NONE);

      fill_in_metadata(
          exec_ctx, s, &fake_md, 0,
          s->recv_initial_md_op->payload->recv_initial_metadata
              .recv_initial_metadata,
          s->recv_initial_md_op->payload->recv_initial_metadata.recv_flags,
          NULL);
      grpc_metadata_batch_destroy(exec_ctx, &fake_md);
      err = GRPC_ERROR_NONE;
    } else {
      err = GRPC_ERROR_REF(error);
    }
    INPROC_LOG(GPR_DEBUG,
               "fail_helper %p scheduling initial-metadata-ready %p %p", s,
               error, err);
    GRPC_CLOSURE_SCHED(exec_ctx,
                       s->recv_initial_md_op->payload->recv_initial_metadata
                           .recv_initial_metadata_ready,
                       err);
    // Last use of err so no need to REF and then UNREF it

    if ((s->recv_initial_md_op != s->recv_message_op) &&
        (s->recv_initial_md_op != s->recv_trailing_md_op)) {
      INPROC_LOG(GPR_DEBUG,
                 "fail_helper %p scheduling initial-metadata-on-complete %p",
                 error, s);
      GRPC_CLOSURE_SCHED(exec_ctx, s->recv_initial_md_op->on_complete,
                         GRPC_ERROR_REF(error));
    }
    s->recv_initial_md_op = NULL;
  }
  if (s->recv_message_op) {
    INPROC_LOG(GPR_DEBUG, "fail_helper %p scheduling message-ready %p", s,
               error);
    GRPC_CLOSURE_SCHED(
        exec_ctx, s->recv_message_op->payload->recv_message.recv_message_ready,
        GRPC_ERROR_REF(error));
    if (s->recv_message_op != s->recv_trailing_md_op) {
      INPROC_LOG(GPR_DEBUG, "fail_helper %p scheduling message-on-complete %p",
                 s, error);
      GRPC_CLOSURE_SCHED(exec_ctx, s->recv_message_op->on_complete,
                         GRPC_ERROR_REF(error));
    }
    s->recv_message_op = NULL;
  }
  if (s->recv_trailing_md_op) {
    INPROC_LOG(GPR_DEBUG,
               "fail_helper %p scheduling trailing-md-on-complete %p", s,
               error);
    GRPC_CLOSURE_SCHED(exec_ctx, s->recv_trailing_md_op->on_complete,
                       GRPC_ERROR_REF(error));
    s->recv_trailing_md_op = NULL;
  }
  close_other_side_locked(exec_ctx, s, "fail_helper:other_side");
  close_stream_locked(exec_ctx, s);

  GRPC_ERROR_UNREF(error);
}