示例#1
0
文件: server.c 项目: PiotrSikora/grpc
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                 grpc_channel_element *elem) {
  size_t i;
  channel_data *chand = elem->channel_data;
  if (chand->registered_methods) {
    for (i = 0; i < chand->registered_method_slots; i++) {
      if (chand->registered_methods[i].method) {
        GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
      }
      if (chand->registered_methods[i].host) {
        GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
      }
    }
    gpr_free(chand->registered_methods);
  }
  if (chand->server) {
    gpr_mu_lock(&chand->server->mu_global);
    chand->next->prev = chand->prev;
    chand->prev->next = chand->next;
    chand->next = chand->prev = chand;
    maybe_finish_shutdown(exec_ctx, chand->server);
    gpr_mu_unlock(&chand->server->mu_global);
    server_unref(exec_ctx, chand->server);
  }
}
示例#2
0
/* Destructor for call_data */
static void destroy_call_elem(grpc_call_element *elem) {
  call_data *calld = elem->call_data;
  grpc_credentials_unref(calld->creds);
  if (calld->host != NULL) {
    GRPC_MDSTR_UNREF(calld->host);
  }
  if (calld->method != NULL) {
    GRPC_MDSTR_UNREF(calld->method);
  }
}
/* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                              const grpc_call_stats *stats, void *ignored) {
  call_data *calld = elem->call_data;
  grpc_call_credentials_unref(calld->creds);
  if (calld->host != NULL) {
    GRPC_MDSTR_UNREF(calld->host);
  }
  if (calld->method != NULL) {
    GRPC_MDSTR_UNREF(calld->method);
  }
  reset_auth_metadata_context(&calld->auth_md_context);
}
示例#4
0
/* Destructor for channel data */
static void destroy_channel_elem(grpc_channel_element *elem) {
  channel_data *channeld = elem->channel_data;
  grpc_compression_algorithm algo_idx;

  GRPC_MDSTR_UNREF(channeld->mdstr_request_compression_algorithm_key);
  GRPC_MDSTR_UNREF(channeld->mdstr_outgoing_compression_algorithm_key);
  GRPC_MDSTR_UNREF(channeld->mdstr_compression_capabilities_key);
  for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
    GRPC_MDELEM_UNREF(channeld->mdelem_compression_algorithms[algo_idx]);
  }
  GRPC_MDELEM_UNREF(channeld->mdelem_accept_encoding);
}
示例#5
0
/* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
                              grpc_call_element *elem) {
  call_data *calld = elem->call_data;
  grpc_credentials_unref(calld->creds);
  if (calld->host != NULL) {
    GRPC_MDSTR_UNREF(calld->host);
  }
  if (calld->method != NULL) {
    GRPC_MDSTR_UNREF(calld->method);
  }
  reset_service_url(calld);
}
示例#6
0
/* Called either:
     - in response to an API call (or similar) from above, to send something
     - a network event (or similar) from below, to receive something
   op contains type and call direction information, in addition to the data
   that is being sent or received. */
static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
                                    grpc_call_element *elem,
                                    grpc_transport_stream_op *op) {
  /* grab pointers to our data from the call element */
  call_data *calld = elem->call_data;
  channel_data *chand = elem->channel_data;
  grpc_linked_mdelem *l;
  grpc_client_security_context *sec_ctx = NULL;

  if (calld->security_context_set == 0 &&
      op->cancel_with_status == GRPC_STATUS_OK) {
    calld->security_context_set = 1;
    GPR_ASSERT(op->context);
    if (op->context[GRPC_CONTEXT_SECURITY].value == NULL) {
      op->context[GRPC_CONTEXT_SECURITY].value =
          grpc_client_security_context_create();
      op->context[GRPC_CONTEXT_SECURITY].destroy =
          grpc_client_security_context_destroy;
    }
    sec_ctx = op->context[GRPC_CONTEXT_SECURITY].value;
    GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
    sec_ctx->auth_context =
        GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter");
  }

  if (op->send_initial_metadata != NULL) {
    for (l = op->send_initial_metadata->list.head; l != NULL; l = l->next) {
      grpc_mdelem *md = l->md;
      /* Pointer comparison is OK for md_elems created from the same context.
       */
      if (md->key == GRPC_MDSTR_AUTHORITY) {
        if (calld->host != NULL) GRPC_MDSTR_UNREF(calld->host);
        calld->host = GRPC_MDSTR_REF(md->value);
      } else if (md->key == GRPC_MDSTR_PATH) {
        if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method);
        calld->method = GRPC_MDSTR_REF(md->value);
      }
    }
    if (calld->host != NULL) {
      const char *call_host = grpc_mdstr_as_c_string(calld->host);
      calld->op = *op; /* Copy op (originates from the caller's stack). */
      grpc_channel_security_connector_check_call_host(
          exec_ctx, chand->security_connector, call_host, chand->auth_context,
          on_host_checked, elem);
      return; /* early exit */
    }
  }

  /* pass control down the stack */
  grpc_call_next_op(exec_ctx, elem, op);
}
示例#7
0
static void test_things_stick_around(void) {
  grpc_mdctx *ctx;
  size_t i, j;
  char *buffer;
  size_t nstrs = 1000;
  grpc_mdstr **strs = gpr_malloc(sizeof(grpc_mdstr *) * nstrs);
  size_t *shuf = gpr_malloc(sizeof(size_t) * nstrs);
  grpc_mdstr *test;

  LOG_TEST("test_things_stick_around");

  ctx = grpc_mdctx_create();

  for (i = 0; i < nstrs; i++) {
    gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", i);
    strs[i] = grpc_mdstr_from_string(ctx, buffer);
    shuf[i] = i;
    gpr_free(buffer);
  }

  for (i = 0; i < nstrs; i++) {
    GRPC_MDSTR_REF(strs[i]);
    GRPC_MDSTR_UNREF(strs[i]);
  }

  for (i = 0; i < nstrs; i++) {
    size_t p = (size_t)rand() % nstrs;
    size_t q = (size_t)rand() % nstrs;
    size_t temp = shuf[p];
    shuf[p] = shuf[q];
    shuf[q] = temp;
  }

  for (i = 0; i < nstrs; i++) {
    GRPC_MDSTR_UNREF(strs[shuf[i]]);
    for (j = i + 1; j < nstrs; j++) {
      gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", shuf[j]);
      test = grpc_mdstr_from_string(ctx, buffer);
      GPR_ASSERT(test == strs[shuf[j]]);
      GRPC_MDSTR_UNREF(test);
      gpr_free(buffer);
    }
  }

  grpc_mdctx_unref(ctx);
  gpr_free(strs);
  gpr_free(shuf);
}
示例#8
0
static void destroy_channel_elem(grpc_channel_element* elem) {
  channel_data* chand = elem->channel_data;
  GPR_ASSERT(chand != NULL);
  if (chand->path_str != NULL) {
    GRPC_MDSTR_UNREF(chand->path_str);
  }
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_channel_element *elem) {
  /* grab pointers to our data from the channel element */
  channel_data *channeld = elem->channel_data;

  GRPC_MDELEM_UNREF(channeld->te_trailers);
  GRPC_MDELEM_UNREF(channeld->status_ok);
  GRPC_MDELEM_UNREF(channeld->status_not_found);
  GRPC_MDELEM_UNREF(channeld->method_post);
  GRPC_MDELEM_UNREF(channeld->http_scheme);
  GRPC_MDELEM_UNREF(channeld->https_scheme);
  GRPC_MDELEM_UNREF(channeld->grpc_scheme);
  GRPC_MDELEM_UNREF(channeld->content_type);
  GRPC_MDSTR_UNREF(channeld->path_key);
  GRPC_MDSTR_UNREF(channeld->authority_key);
  GRPC_MDSTR_UNREF(channeld->host_key);
}
示例#10
0
文件: call.c 项目: robottomw/grpc
static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, int success) {
  size_t i;
  int ii;
  grpc_call *c = call;
  GPR_TIMER_BEGIN("destroy_call", 0);
  for (i = 0; i < 2; i++) {
    grpc_metadata_batch_destroy(
        &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
  }
  if (c->receiving_stream != NULL) {
    grpc_byte_stream_destroy(c->receiving_stream);
  }
  grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c));
  GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, c->channel, "call");
  gpr_mu_destroy(&c->mu);
  for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
    if (c->status[i].details) {
      GRPC_MDSTR_UNREF(c->status[i].details);
    }
  }
  for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
    GRPC_MDELEM_UNREF(c->send_extra_metadata[ii].md);
  }
  for (i = 0; i < GRPC_CONTEXT_COUNT; i++) {
    if (c->context[i].destroy) {
      c->context[i].destroy(c->context[i].value);
    }
  }
  if (c->cq) {
    GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
  }
  gpr_free(c);
  GPR_TIMER_END("destroy_call", 0);
}
示例#11
0
文件: call.c 项目: robottomw/grpc
static void set_status_details(grpc_call *call, status_source source,
                               grpc_mdstr *status) {
  if (call->status[source].details != NULL) {
    GRPC_MDSTR_UNREF(call->status[source].details);
  }
  call->status[source].details = status;
}
示例#12
0
void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
  int i;
  for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) {
    if (c->entries_keys[i]) GRPC_MDSTR_UNREF(c->entries_keys[i]);
    if (c->entries_elems[i]) GRPC_MDELEM_UNREF(c->entries_elems[i]);
  }
  gpr_free(c->table_elem_size);
}
示例#13
0
static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
                              grpc_call_element *elem) {
  channel_data *chand = elem->channel_data;
  call_data *calld = elem->call_data;

  GPR_ASSERT(calld->state != PENDING);

  if (calld->host) {
    GRPC_MDSTR_UNREF(calld->host);
  }
  if (calld->path) {
    GRPC_MDSTR_UNREF(calld->path);
  }

  gpr_mu_destroy(&calld->mu_state);

  server_unref(exec_ctx, chand->server);
}
示例#14
0
static void test_create_string(void) {
  grpc_mdstr *s1, *s2, *s3;

  LOG_TEST("test_create_string");

  grpc_init();
  s1 = grpc_mdstr_from_string("hello");
  s2 = grpc_mdstr_from_string("hello");
  s3 = grpc_mdstr_from_string("very much not hello");
  GPR_ASSERT(s1 == s2);
  GPR_ASSERT(s3 != s1);
  GPR_ASSERT(gpr_slice_str_cmp(s1->slice, "hello") == 0);
  GPR_ASSERT(gpr_slice_str_cmp(s3->slice, "very much not hello") == 0);
  GRPC_MDSTR_UNREF(s1);
  GRPC_MDSTR_UNREF(s2);
  GRPC_MDSTR_UNREF(s3);
  grpc_shutdown();
}
示例#15
0
/* Destructor for channel data */
static void destroy_channel_elem(grpc_channel_element *elem) {
  /* grab pointers to our data from the channel element */
  channel_data *chand = elem->channel_data;
  grpc_channel_security_connector *ctx = chand->security_connector;
  if (ctx != NULL)
    GRPC_SECURITY_CONNECTOR_UNREF(&ctx->base, "client_auth_filter");
  if (chand->authority_string != NULL) {
    GRPC_MDSTR_UNREF(chand->authority_string);
  }
  if (chand->error_msg_key != NULL) {
    GRPC_MDSTR_UNREF(chand->error_msg_key);
  }
  if (chand->status_key != NULL) {
    GRPC_MDSTR_UNREF(chand->status_key);
  }
  if (chand->path_string != NULL) {
    GRPC_MDSTR_UNREF(chand->path_string);
  }
}
示例#16
0
static void test_create_string(void) {
  grpc_mdctx *ctx;
  grpc_mdstr *s1, *s2, *s3;

  LOG_TEST("test_create_string");

  ctx = grpc_mdctx_create();
  s1 = grpc_mdstr_from_string(ctx, "hello");
  s2 = grpc_mdstr_from_string(ctx, "hello");
  s3 = grpc_mdstr_from_string(ctx, "very much not hello");
  GPR_ASSERT(s1 == s2);
  GPR_ASSERT(s3 != s1);
  GPR_ASSERT(gpr_slice_str_cmp(s1->slice, "hello") == 0);
  GPR_ASSERT(gpr_slice_str_cmp(s3->slice, "very much not hello") == 0);
  GRPC_MDSTR_UNREF(s1);
  GRPC_MDSTR_UNREF(s2);
  grpc_mdctx_unref(ctx);
  GRPC_MDSTR_UNREF(s3);
}
示例#17
0
文件: server.c 项目: NaughtyCode/grpc
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                              const grpc_call_stats *stats, void *ignored) {
  channel_data *chand = elem->channel_data;
  call_data *calld = elem->call_data;

  GPR_ASSERT(calld->state != PENDING);

  if (calld->host) {
    GRPC_MDSTR_UNREF(calld->host);
  }
  if (calld->path) {
    GRPC_MDSTR_UNREF(calld->path);
  }
  grpc_metadata_array_destroy(&calld->initial_metadata);

  gpr_mu_destroy(&calld->mu_state);

  server_unref(exec_ctx, chand->server);
}
示例#18
0
文件: channel.c 项目: wangyikai/grpc
static void destroy_channel(grpc_exec_ctx *exec_ctx, grpc_channel *channel) {
  size_t i;
  grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(channel));
  for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) {
    GRPC_MDELEM_UNREF(channel->grpc_status_elem[i]);
  }
  GRPC_MDSTR_UNREF(channel->grpc_status_string);
  GRPC_MDSTR_UNREF(channel->grpc_compression_algorithm_string);
  GRPC_MDSTR_UNREF(channel->grpc_encodings_accepted_by_peer_string);
  GRPC_MDSTR_UNREF(channel->grpc_message_string);
  GRPC_MDSTR_UNREF(channel->path_string);
  GRPC_MDSTR_UNREF(channel->authority_string);
  while (channel->registered_calls) {
    registered_call *rc = channel->registered_calls;
    channel->registered_calls = rc->next;
    GRPC_MDELEM_UNREF(rc->path);
    if (rc->authority) {
      GRPC_MDELEM_UNREF(rc->authority);
    }
    gpr_free(rc);
  }
  if (channel->default_authority != NULL) {
    GRPC_MDELEM_UNREF(channel->default_authority);
  }
  grpc_mdctx_unref(channel->metadata_context);
  gpr_mu_destroy(&channel->registered_call_mu);
  gpr_free(channel->target);
  gpr_free(channel);
}
示例#19
0
static void test_slices_work(void) {
  /* ensure no memory leaks when switching representation from mdstr to slice */
  grpc_mdstr *str;
  gpr_slice slice;

  LOG_TEST("test_slices_work");

  grpc_init();

  str = grpc_mdstr_from_string(
      "123456789012345678901234567890123456789012345678901234567890");
  slice = gpr_slice_ref(str->slice);
  GRPC_MDSTR_UNREF(str);
  gpr_slice_unref(slice);

  str = grpc_mdstr_from_string(
      "123456789012345678901234567890123456789012345678901234567890");
  slice = gpr_slice_ref(str->slice);
  gpr_slice_unref(slice);
  GRPC_MDSTR_UNREF(str);

  grpc_shutdown();
}
示例#20
0
static void destruct_transport(grpc_exec_ctx *exec_ctx,
                               grpc_chttp2_transport *t) {
  size_t i;

  gpr_mu_lock(&t->mu);

  GPR_ASSERT(t->ep == NULL);

  gpr_slice_buffer_destroy(&t->global.qbuf);

  gpr_slice_buffer_destroy(&t->writing.outbuf);
  grpc_chttp2_hpack_compressor_destroy(&t->writing.hpack_compressor);

  gpr_slice_buffer_destroy(&t->parsing.qbuf);
  gpr_slice_buffer_destroy(&t->read_buffer);
  grpc_chttp2_hpack_parser_destroy(&t->parsing.hpack_parser);
  grpc_chttp2_goaway_parser_destroy(&t->parsing.goaway_parser);

  GRPC_MDSTR_UNREF(t->parsing.str_grpc_timeout);

  for (i = 0; i < STREAM_LIST_COUNT; i++) {
    GPR_ASSERT(t->lists[i].head == NULL);
    GPR_ASSERT(t->lists[i].tail == NULL);
  }

  GPR_ASSERT(grpc_chttp2_stream_map_size(&t->parsing_stream_map) == 0);
  GPR_ASSERT(grpc_chttp2_stream_map_size(&t->new_stream_map) == 0);

  grpc_chttp2_stream_map_destroy(&t->parsing_stream_map);
  grpc_chttp2_stream_map_destroy(&t->new_stream_map);
  grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker);

  gpr_mu_unlock(&t->mu);
  gpr_mu_destroy(&t->mu);

  /* callback remaining pings: they're not allowed to call into the transpot,
     and maybe they hold resources that need to be freed */
  while (t->global.pings.next != &t->global.pings) {
    grpc_chttp2_outstanding_ping *ping = t->global.pings.next;
    grpc_exec_ctx_enqueue(exec_ctx, ping->on_recv, 0);
    ping->next->prev = ping->prev;
    ping->prev->next = ping->next;
    gpr_free(ping);
  }

  grpc_mdctx_unref(t->metadata_context);

  gpr_free(t->peer_string);
  gpr_free(t);
}
示例#21
0
文件: channel.c 项目: hmings888/grpc
static void destroy_channel(void *p, int ok) {
    grpc_channel *channel = p;
    size_t i;
    grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel));
    for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) {
        GRPC_MDELEM_UNREF(channel->grpc_status_elem[i]);
    }
    GRPC_MDSTR_UNREF(channel->grpc_status_string);
    GRPC_MDSTR_UNREF(channel->grpc_compression_level_string);
    GRPC_MDSTR_UNREF(channel->grpc_message_string);
    GRPC_MDSTR_UNREF(channel->path_string);
    GRPC_MDSTR_UNREF(channel->authority_string);
    while (channel->registered_calls) {
        registered_call *rc = channel->registered_calls;
        channel->registered_calls = rc->next;
        GRPC_MDELEM_UNREF(rc->path);
        GRPC_MDELEM_UNREF(rc->authority);
        gpr_free(rc);
    }
    grpc_mdctx_unref(channel->metadata_context);
    gpr_mu_destroy(&channel->registered_call_mu);
    gpr_free(channel);
}
示例#22
0
static void test_base64_and_huffman_works(void) {
  grpc_mdstr *str;
  gpr_slice slice1;
  gpr_slice slice2;

  LOG_TEST("test_base64_and_huffman_works");

  grpc_init();
  str = grpc_mdstr_from_string("abcdefg");
  slice1 = grpc_mdstr_as_base64_encoded_and_huffman_compressed(str);
  slice2 = grpc_chttp2_base64_encode_and_huffman_compress(str->slice);
  GPR_ASSERT(0 == gpr_slice_cmp(slice1, slice2));

  gpr_slice_unref(slice2);
  GRPC_MDSTR_UNREF(str);
  grpc_shutdown();
}
示例#23
0
grpc_mdstr_hash_table* grpc_service_config_create_method_config_table(
    grpc_exec_ctx* exec_ctx, const grpc_service_config* service_config,
    void* (*create_value)(const grpc_json* method_config_json),
    const grpc_mdstr_hash_table_vtable* vtable) {
  const grpc_json* json = service_config->json_tree;
  // Traverse parsed JSON tree.
  if (json->type != GRPC_JSON_OBJECT || json->key != NULL) return NULL;
  size_t num_entries = 0;
  grpc_mdstr_hash_table_entry* entries = NULL;
  for (grpc_json* field = json->child; field != NULL; field = field->next) {
    if (field->key == NULL) return NULL;
    if (strcmp(field->key, "methodConfig") == 0) {
      if (entries != NULL) return NULL;  // Duplicate.
      if (field->type != GRPC_JSON_ARRAY) return NULL;
      // Find number of entries.
      for (grpc_json* method = field->child; method != NULL;
           method = method->next) {
        num_entries += count_names_in_method_config_json(method);
      }
      // Populate method config table entries.
      entries = gpr_malloc(num_entries * sizeof(grpc_mdstr_hash_table_entry));
      size_t idx = 0;
      for (grpc_json* method = field->child; method != NULL;
           method = method->next) {
        if (!parse_json_method_config(exec_ctx, method, create_value, vtable,
                                      entries, &idx)) {
          return NULL;
        }
      }
      GPR_ASSERT(idx == num_entries);
    }
  }
  // Instantiate method config table.
  grpc_mdstr_hash_table* method_config_table = NULL;
  if (entries != NULL) {
    method_config_table = grpc_mdstr_hash_table_create(num_entries, entries);
    // Clean up.
    for (size_t i = 0; i < num_entries; ++i) {
      GRPC_MDSTR_UNREF(exec_ctx, entries[i].key);
      vtable->destroy_value(exec_ctx, entries[i].value);
    }
    gpr_free(entries);
  }
  return method_config_table;
}
示例#24
0
void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
                                   const grpc_mdstr* path) {
  void* value = grpc_mdstr_hash_table_get(table, path);
  // If we didn't find a match for the path, try looking for a wildcard
  // entry (i.e., change "/service/method" to "/service/*").
  if (value == NULL) {
    const char* path_str = grpc_mdstr_as_c_string(path);
    const char* sep = strrchr(path_str, '/') + 1;
    const size_t len = (size_t)(sep - path_str);
    char* buf = gpr_malloc(len + 2);  // '*' and NUL
    memcpy(buf, path_str, len);
    buf[len] = '*';
    buf[len + 1] = '\0';
    grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf);
    gpr_free(buf);
    value = grpc_mdstr_hash_table_get(table, wildcard_path);
    GRPC_MDSTR_UNREF(wildcard_path);
  }
  return value;
}
示例#25
0
/* Destructor for call_data */
static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
                                 grpc_call_element *elem,
                                 const grpc_call_final_info *final_info,
                                 void *and_free_memory) {
  call_data *calld = elem->call_data;
  grpc_deadline_state_destroy(exec_ctx, elem);
  GRPC_MDSTR_UNREF(calld->path);
  GRPC_ERROR_UNREF(calld->cancel_error);
  grpc_subchannel_call *call = GET_CALL(calld);
  if (call != NULL && call != CANCELLED_CALL) {
    GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
  }
  GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
  gpr_mu_destroy(&calld->mu);
  GPR_ASSERT(calld->waiting_ops_count == 0);
  if (calld->connected_subchannel != NULL) {
    GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, calld->connected_subchannel,
                                    "picked");
  }
  gpr_free(calld->waiting_ops);
  gpr_free(and_free_memory);
}
示例#26
0
/* Called either:
     - in response to an API call (or similar) from above, to send something
     - a network event (or similar) from below, to receive something
   op contains type and call direction information, in addition to the data
   that is being sent or received. */
static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
                                    grpc_call_element *elem,
                                    grpc_transport_stream_op *op) {
  /* grab pointers to our data from the call element */
  call_data *calld = elem->call_data;
  channel_data *chand = elem->channel_data;
  grpc_linked_mdelem *l;
  size_t i;
  grpc_client_security_context *sec_ctx = NULL;

  if (calld->security_context_set == 0 &&
      op->cancel_with_status == GRPC_STATUS_OK) {
    calld->security_context_set = 1;
    GPR_ASSERT(op->context);
    if (op->context[GRPC_CONTEXT_SECURITY].value == NULL) {
      op->context[GRPC_CONTEXT_SECURITY].value =
          grpc_client_security_context_create();
      op->context[GRPC_CONTEXT_SECURITY].destroy =
          grpc_client_security_context_destroy;
    }
    sec_ctx = op->context[GRPC_CONTEXT_SECURITY].value;
    GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
    sec_ctx->auth_context = GRPC_AUTH_CONTEXT_REF(
        chand->security_connector->base.auth_context, "client_auth_filter");
  }

  if (op->bind_pollset != NULL) {
    calld->pollset = op->bind_pollset;
  }

  if (op->send_ops != NULL && !calld->sent_initial_metadata) {
    size_t nops = op->send_ops->nops;
    grpc_stream_op *ops = op->send_ops->ops;
    for (i = 0; i < nops; i++) {
      grpc_stream_op *sop = &ops[i];
      if (sop->type != GRPC_OP_METADATA) continue;
      calld->op_md_idx = i;
      calld->sent_initial_metadata = 1;
      for (l = sop->data.metadata.list.head; l != NULL; l = l->next) {
        grpc_mdelem *md = l->md;
        /* Pointer comparison is OK for md_elems created from the same context.
         */
        if (md->key == chand->authority_string) {
          if (calld->host != NULL) GRPC_MDSTR_UNREF(calld->host);
          calld->host = GRPC_MDSTR_REF(md->value);
        } else if (md->key == chand->path_string) {
          if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method);
          calld->method = GRPC_MDSTR_REF(md->value);
        }
      }
      if (calld->host != NULL) {
        grpc_security_status status;
        const char *call_host = grpc_mdstr_as_c_string(calld->host);
        calld->op = *op; /* Copy op (originates from the caller's stack). */
        status = grpc_channel_security_connector_check_call_host(
            exec_ctx, chand->security_connector, call_host, on_host_checked,
            elem);
        if (status != GRPC_SECURITY_OK) {
          if (status == GRPC_SECURITY_ERROR) {
            char *error_msg;
            gpr_asprintf(&error_msg,
                         "Invalid host %s set in :authority metadata.",
                         call_host);
            bubble_up_error(exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT,
                            error_msg);
            gpr_free(error_msg);
          }
          return; /* early exit */
        }
      }
      send_security_metadata(exec_ctx, elem, op);
      return; /* early exit */
    }
  }

  /* pass control down the stack */
  grpc_call_next_op(exec_ctx, elem, op);
}
示例#27
0
/* add an element to the decoder table */
static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) {
  uint32_t key_hash = elem->key->hash;
  uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash);
  uint32_t new_index = c->tail_remote_index + c->table_elems + 1;
  size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);

  GPR_ASSERT(elem_size < 65536);

  if (elem_size > c->max_table_size) {
    while (c->table_size > 0) {
      evict_entry(c);
    }
    return;
  }

  /* Reserve space for this element in the remote table: if this overflows
     the current table, drop elements until it fits, matching the decompressor
     algorithm */
  while (c->table_size + elem_size > c->max_table_size) {
    evict_entry(c);
  }
  GPR_ASSERT(c->table_elems < c->max_table_size);
  c->table_elem_size[new_index % c->cap_table_elems] = (uint16_t)elem_size;
  c->table_size = (uint16_t)(c->table_size + elem_size);
  c->table_elems++;

  /* Store this element into {entries,indices}_elem */
  if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == elem) {
    /* already there: update with new index */
    c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
  } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == elem) {
    /* already there (cuckoo): update with new index */
    c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
  } else if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == NULL) {
    /* not there, but a free element: add */
    c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
    c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
  } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == NULL) {
    /* not there (cuckoo), but a free element: add */
    c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
    c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
  } else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] <
             c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) {
    /* not there: replace oldest */
    GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
    c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
    c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
  } else {
    /* not there: replace oldest */
    GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
    c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
    c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
  }

  /* do exactly the same for the key (so we can find by that again too) */

  if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key) {
    c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
  } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key) {
    c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
  } else if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == NULL) {
    c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key);
    c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
  } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == NULL) {
    c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key);
    c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
  } else if (c->indices_keys[HASH_FRAGMENT_2(key_hash)] <
             c->indices_keys[HASH_FRAGMENT_3(key_hash)]) {
    GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_2(key_hash)]);
    c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key);
    c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
  } else {
    GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_3(key_hash)]);
    c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key);
    c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
  }
}
示例#28
0
static void test_create_channel_stack(void) {
  const grpc_channel_filter filter = {
      call_func,
      channel_func,
      sizeof(int),
      call_init_func,
      grpc_call_stack_ignore_set_pollset_or_pollset_set,
      call_destroy_func,
      sizeof(int),
      channel_init_func,
      channel_destroy_func,
      get_peer,
      grpc_channel_next_get_info,
      "some_test_filter"};
  const grpc_channel_filter *filters = &filter;
  grpc_channel_stack *channel_stack;
  grpc_call_stack *call_stack;
  grpc_channel_element *channel_elem;
  grpc_call_element *call_elem;
  grpc_arg arg;
  grpc_channel_args chan_args;
  int *channel_data;
  int *call_data;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_mdstr *path = grpc_mdstr_from_string("/service/method");

  arg.type = GRPC_ARG_INTEGER;
  arg.key = "test_key";
  arg.value.integer = 42;

  chan_args.num_args = 1;
  chan_args.args = &arg;

  channel_stack = gpr_malloc(grpc_channel_stack_size(&filters, 1));
  grpc_channel_stack_init(&exec_ctx, 1, free_channel, channel_stack, &filters,
                          1, &chan_args, NULL, "test", channel_stack);
  GPR_ASSERT(channel_stack->count == 1);
  channel_elem = grpc_channel_stack_element(channel_stack, 0);
  channel_data = (int *)channel_elem->channel_data;
  GPR_ASSERT(*channel_data == 0);

  call_stack = gpr_malloc(channel_stack->call_stack_size);
  grpc_error *error =
      grpc_call_stack_init(&exec_ctx, channel_stack, 1, free_call, call_stack,
                           NULL, NULL, path, gpr_now(GPR_CLOCK_MONOTONIC),
                           gpr_inf_future(GPR_CLOCK_MONOTONIC), call_stack);
  GPR_ASSERT(error == GRPC_ERROR_NONE);
  GPR_ASSERT(call_stack->count == 1);
  call_elem = grpc_call_stack_element(call_stack, 0);
  GPR_ASSERT(call_elem->filter == channel_elem->filter);
  GPR_ASSERT(call_elem->channel_data == channel_elem->channel_data);
  call_data = (int *)call_elem->call_data;
  GPR_ASSERT(*call_data == 0);
  GPR_ASSERT(*channel_data == 1);

  GRPC_CALL_STACK_UNREF(&exec_ctx, call_stack, "done");
  grpc_exec_ctx_flush(&exec_ctx);
  GPR_ASSERT(*channel_data == 2);

  GRPC_CHANNEL_STACK_UNREF(&exec_ctx, channel_stack, "done");

  grpc_exec_ctx_finish(&exec_ctx);
  GRPC_MDSTR_UNREF(path);
}