Exemple #1
0
static grpc_resolver* fake_resolver_create(grpc_resolver_factory* factory,
                                           grpc_resolver_args* args) {
  if (0 != strcmp(args->uri->authority, "")) {
    gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
            args->uri->scheme);
    return NULL;
  }
  // Get lb_enabled arg.  Anything other than "0" is interpreted as true.
  const char* lb_enabled_qpart =
      grpc_uri_get_query_arg(args->uri, "lb_enabled");
  const bool lb_enabled =
      lb_enabled_qpart != NULL && strcmp("0", lb_enabled_qpart) != 0;
  // Construct addresses.
  gpr_slice path_slice =
      gpr_slice_new(args->uri->path, strlen(args->uri->path), do_nothing);
  gpr_slice_buffer path_parts;
  gpr_slice_buffer_init(&path_parts);
  gpr_slice_split(path_slice, ",", &path_parts);
  grpc_lb_addresses* addresses = grpc_lb_addresses_create(path_parts.count);
  bool errors_found = false;
  for (size_t i = 0; i < addresses->num_addresses; i++) {
    grpc_uri ith_uri = *args->uri;
    char* part_str = gpr_dump_slice(path_parts.slices[i], GPR_DUMP_ASCII);
    ith_uri.path = part_str;
    if (!parse_ipv4(
            &ith_uri,
            (struct sockaddr_storage*)(&addresses->addresses[i].address.addr),
            &addresses->addresses[i].address.len)) {
      errors_found = true;
    }
    gpr_free(part_str);
    addresses->addresses[i].is_balancer = lb_enabled;
    if (errors_found) break;
  }
  gpr_slice_buffer_destroy(&path_parts);
  gpr_slice_unref(path_slice);
  if (errors_found) {
    grpc_lb_addresses_destroy(addresses, NULL /* user_data_destroy */);
    return NULL;
  }
  // Instantiate resolver.
  fake_resolver* r = gpr_malloc(sizeof(fake_resolver));
  memset(r, 0, sizeof(*r));
  r->target_name = gpr_strdup(args->uri->path);
  r->addresses = addresses;
  r->lb_policy_name =
      gpr_strdup(grpc_uri_get_query_arg(args->uri, "lb_policy"));
  gpr_mu_init(&r->mu);
  grpc_resolver_init(&r->base, &fake_resolver_vtable);
  return &r->base;
}
Exemple #2
0
static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
  size_t i;
  grpc_compression_algorithm algorithm;
  gpr_slice_buffer accept_encoding_parts;
  gpr_slice accept_encoding_slice;
  void *accepted_user_data;

  accepted_user_data =
      grpc_mdelem_get_user_data(mdel, destroy_encodings_accepted_by_peer);
  if (accepted_user_data != NULL) {
    call->encodings_accepted_by_peer =
        (gpr_uint32)(((gpr_uintptr)accepted_user_data) - 1);
    return;
  }

  accept_encoding_slice = mdel->value->slice;
  gpr_slice_buffer_init(&accept_encoding_parts);
  gpr_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);

  /* No need to zero call->encodings_accepted_by_peer: grpc_call_create already
   * zeroes the whole grpc_call */
  /* Always support no compression */
  GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
  for (i = 0; i < accept_encoding_parts.count; i++) {
    const gpr_slice *accept_encoding_entry_slice =
        &accept_encoding_parts.slices[i];
    if (grpc_compression_algorithm_parse(
            (const char *)GPR_SLICE_START_PTR(*accept_encoding_entry_slice),
            GPR_SLICE_LENGTH(*accept_encoding_entry_slice), &algorithm)) {
      GPR_BITSET(&call->encodings_accepted_by_peer, algorithm);
    } else {
      char *accept_encoding_entry_str =
          gpr_dump_slice(*accept_encoding_entry_slice, GPR_DUMP_ASCII);
      gpr_log(GPR_ERROR,
              "Invalid entry in accept encoding metadata: '%s'. Ignoring.",
              accept_encoding_entry_str);
      gpr_free(accept_encoding_entry_str);
    }
  }

  gpr_slice_buffer_destroy(&accept_encoding_parts);

  grpc_mdelem_set_user_data(
      mdel, destroy_encodings_accepted_by_peer,
      (void *)(((gpr_uintptr)call->encodings_accepted_by_peer) + 1));
}
static grpc_resolver *sockaddr_create(grpc_resolver_args *args,
                                      int parse(grpc_uri *uri,
                                                struct sockaddr_storage *dst,
                                                size_t *len)) {
  if (0 != strcmp(args->uri->authority, "")) {
    gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
            args->uri->scheme);
    return NULL;
  }
  /* Construct addresses. */
  gpr_slice path_slice =
      gpr_slice_new(args->uri->path, strlen(args->uri->path), do_nothing);
  gpr_slice_buffer path_parts;
  gpr_slice_buffer_init(&path_parts);
  gpr_slice_split(path_slice, ",", &path_parts);
  grpc_lb_addresses *addresses = grpc_lb_addresses_create(path_parts.count);
  bool errors_found = false;
  for (size_t i = 0; i < addresses->num_addresses; i++) {
    grpc_uri ith_uri = *args->uri;
    char *part_str = gpr_dump_slice(path_parts.slices[i], GPR_DUMP_ASCII);
    ith_uri.path = part_str;
    if (!parse(
            &ith_uri,
            (struct sockaddr_storage *)(&addresses->addresses[i].address.addr),
            &addresses->addresses[i].address.len)) {
      errors_found = true;
    }
    gpr_free(part_str);
    if (errors_found) break;
  }
  gpr_slice_buffer_destroy(&path_parts);
  gpr_slice_unref(path_slice);
  if (errors_found) {
    grpc_lb_addresses_destroy(addresses, NULL /* user_data_destroy */);
    return NULL;
  }
  /* Instantiate resolver. */
  sockaddr_resolver *r = gpr_malloc(sizeof(sockaddr_resolver));
  memset(r, 0, sizeof(*r));
  r->target_name = gpr_strdup(args->uri->path);
  r->addresses = addresses;
  gpr_mu_init(&r->mu);
  grpc_resolver_init(&r->base, &sockaddr_resolver_vtable);
  return &r->base;
}
Exemple #4
0
void test_connect(const char *server_host, const char *client_host, int port,
                  int expect_ok) {
  char *client_hostport;
  char *server_hostport;
  grpc_channel *client;
  grpc_server *server;
  grpc_completion_queue *cq;
  grpc_call *c;
  grpc_call *s;
  cq_verifier *cqv;
  gpr_timespec deadline;
  int got_port;
  grpc_op ops[6];
  grpc_op *op;
  grpc_metadata_array initial_metadata_recv;
  grpc_metadata_array trailing_metadata_recv;
  grpc_metadata_array request_metadata_recv;
  grpc_status_code status;
  grpc_call_error error;
  char *details = NULL;
  size_t details_capacity = 0;
  int was_cancelled = 2;
  grpc_call_details call_details;
  char *peer;
  int picked_port = 0;

  if (port == 0) {
    port = grpc_pick_unused_port_or_die();
    picked_port = 1;
  }

  gpr_join_host_port(&server_hostport, server_host, port);

  grpc_metadata_array_init(&initial_metadata_recv);
  grpc_metadata_array_init(&trailing_metadata_recv);
  grpc_metadata_array_init(&request_metadata_recv);
  grpc_call_details_init(&call_details);

  /* Create server. */
  cq = grpc_completion_queue_create(NULL);
  server = grpc_server_create(NULL, NULL);
  grpc_server_register_completion_queue(server, cq, NULL);
  GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port(
                  server, server_hostport)) > 0);
  if (port == 0) {
    port = got_port;
  } else {
    GPR_ASSERT(port == got_port);
  }
  grpc_server_start(server);
  cqv = cq_verifier_create(cq);

  /* Create client. */
  if (client_host[0] == 'i') {
    /* for ipv4:/ipv6: addresses, concatenate the port to each of the parts */
    size_t i;
    gpr_slice uri_slice;
    gpr_slice_buffer uri_parts;
    char **hosts_with_port;

    uri_slice =
        gpr_slice_new((char *)client_host, strlen(client_host), do_nothing);
    gpr_slice_buffer_init(&uri_parts);
    gpr_slice_split(uri_slice, ",", &uri_parts);
    hosts_with_port = gpr_malloc(sizeof(char *) * uri_parts.count);
    for (i = 0; i < uri_parts.count; i++) {
      char *uri_part_str = gpr_dump_slice(uri_parts.slices[i], GPR_DUMP_ASCII);
      gpr_asprintf(&hosts_with_port[i], "%s:%d", uri_part_str, port);
      gpr_free(uri_part_str);
    }
    client_hostport = gpr_strjoin_sep((const char **)hosts_with_port,
                                      uri_parts.count, ",", NULL);
    for (i = 0; i < uri_parts.count; i++) {
      gpr_free(hosts_with_port[i]);
    }
    gpr_free(hosts_with_port);
    gpr_slice_buffer_destroy(&uri_parts);
    gpr_slice_unref(uri_slice);
  } else {
    gpr_join_host_port(&client_hostport, client_host, port);
  }
  client = grpc_insecure_channel_create(client_hostport, NULL, NULL);

  gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)",
          server_hostport, client_hostport, expect_ok ? "success" : "failure");

  gpr_free(client_hostport);
  gpr_free(server_hostport);

  if (expect_ok) {
    /* Normal deadline, shouldn't be reached. */
    deadline = ms_from_now(60000);
  } else {
    /* Give up faster when failure is expected.
       BUG: Setting this to 1000 reveals a memory leak (b/18608927). */
    deadline = ms_from_now(1500);
  }

  /* Send a trivial request. */
  c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
                               "/foo", "foo.test.google.fr", deadline, NULL);
  GPR_ASSERT(c);

  memset(ops, 0, sizeof(ops));
  op = ops;
  op->op = GRPC_OP_SEND_INITIAL_METADATA;
  op->data.send_initial_metadata.count = 0;
  op->flags = expect_ok ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0;
  op->reserved = NULL;
  op++;
  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  op->flags = 0;
  op->reserved = NULL;
  op++;
  op->op = GRPC_OP_RECV_INITIAL_METADATA;
  op->data.recv_initial_metadata = &initial_metadata_recv;
  op->flags = 0;
  op->reserved = NULL;
  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->reserved = NULL;
  op++;
  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
  GPR_ASSERT(GRPC_CALL_OK == error);

  if (expect_ok) {
    /* Check for a successful request. */
    error = grpc_server_request_call(server, &s, &call_details,
                                     &request_metadata_recv, cq, cq, tag(101));
    GPR_ASSERT(GRPC_CALL_OK == error);
    CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
    cq_verify(cqv);

    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++;
    op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
    op->data.send_status_from_server.trailing_metadata_count = 0;
    op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
    op->data.send_status_from_server.status_details = "xyz";
    op->flags = 0;
    op++;
    op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
    op->data.recv_close_on_server.cancelled = &was_cancelled;
    op->flags = 0;
    op++;
    error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
    GPR_ASSERT(GRPC_CALL_OK == error);

    CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
    CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
    cq_verify(cqv);

    peer = grpc_call_get_peer(c);
    gpr_log(GPR_DEBUG, "got peer: '%s'", peer);
    gpr_free(peer);

    GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
    GPR_ASSERT(0 == strcmp(details, "xyz"));
    GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
    GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
    GPR_ASSERT(was_cancelled == 1);

    grpc_call_destroy(s);
  } else {
    /* Check for a failed connection. */
    CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
    cq_verify(cqv);

    GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
  }

  grpc_call_destroy(c);

  cq_verifier_destroy(cqv);

  /* Destroy client. */
  grpc_channel_destroy(client);

  /* Destroy server. */
  grpc_server_shutdown_and_notify(server, cq, tag(1000));
  GPR_ASSERT(grpc_completion_queue_pluck(
                 cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
                 .type == GRPC_OP_COMPLETE);
  grpc_server_destroy(server);
  grpc_completion_queue_shutdown(cq);
  drain_cq(cq);
  grpc_completion_queue_destroy(cq);

  grpc_metadata_array_destroy(&initial_metadata_recv);
  grpc_metadata_array_destroy(&trailing_metadata_recv);
  grpc_metadata_array_destroy(&request_metadata_recv);

  grpc_call_details_destroy(&call_details);
  gpr_free(details);
  if (picked_port) {
    grpc_recycle_unused_port(port);
  }
}
Exemple #5
0
static void test_strsplit(void) {
  gpr_slice_buffer *parts;
  gpr_slice str;

  LOG_TEST_NAME("test_strsplit");

  parts = gpr_malloc(sizeof(gpr_slice_buffer));
  gpr_slice_buffer_init(parts);

  str = gpr_slice_from_copied_string("one, two, three, four");
  gpr_slice_split(str, ", ", parts);
  GPR_ASSERT(4 == parts->count);
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], "one"));
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[1], "two"));
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[2], "three"));
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[3], "four"));
  gpr_slice_buffer_reset_and_unref(parts);
  gpr_slice_unref(str);

  /* separator not present in string */
  str = gpr_slice_from_copied_string("one two three four");
  gpr_slice_split(str, ", ", parts);
  GPR_ASSERT(1 == parts->count);
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], "one two three four"));
  gpr_slice_buffer_reset_and_unref(parts);
  gpr_slice_unref(str);

  /* separator at the end */
  str = gpr_slice_from_copied_string("foo,");
  gpr_slice_split(str, ",", parts);
  GPR_ASSERT(2 == parts->count);
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], "foo"));
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[1], ""));
  gpr_slice_buffer_reset_and_unref(parts);
  gpr_slice_unref(str);

  /* separator at the beginning */
  str = gpr_slice_from_copied_string(",foo");
  gpr_slice_split(str, ",", parts);
  GPR_ASSERT(2 == parts->count);
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], ""));
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[1], "foo"));
  gpr_slice_buffer_reset_and_unref(parts);
  gpr_slice_unref(str);

  /* standalone separator */
  str = gpr_slice_from_copied_string(",");
  gpr_slice_split(str, ",", parts);
  GPR_ASSERT(2 == parts->count);
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], ""));
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[1], ""));
  gpr_slice_buffer_reset_and_unref(parts);
  gpr_slice_unref(str);

  /* empty input */
  str = gpr_slice_from_copied_string("");
  gpr_slice_split(str, ", ", parts);
  GPR_ASSERT(1 == parts->count);
  GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], ""));
  gpr_slice_buffer_reset_and_unref(parts);
  gpr_slice_unref(str);

  gpr_slice_buffer_destroy(parts);
  gpr_free(parts);
}
static grpc_resolver *sockaddr_create(
    grpc_resolver_args *args, const char *default_lb_policy_name,
    int parse(grpc_uri *uri, struct sockaddr_storage *dst, size_t *len)) {
  size_t i;
  int errors_found = 0; /* GPR_FALSE */
  sockaddr_resolver *r;
  gpr_slice path_slice;
  gpr_slice_buffer path_parts;

  if (0 != strcmp(args->uri->authority, "")) {
    gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
            args->uri->scheme);
    return NULL;
  }

  r = gpr_malloc(sizeof(sockaddr_resolver));
  memset(r, 0, sizeof(*r));

  r->lb_policy_name = NULL;
  if (0 != strcmp(args->uri->query, "")) {
    gpr_slice query_slice;
    gpr_slice_buffer query_parts;

    query_slice =
        gpr_slice_new(args->uri->query, strlen(args->uri->query), do_nothing);
    gpr_slice_buffer_init(&query_parts);
    gpr_slice_split(query_slice, "=", &query_parts);
    GPR_ASSERT(query_parts.count == 2);
    if (0 == gpr_slice_str_cmp(query_parts.slices[0], "lb_policy")) {
      r->lb_policy_name = gpr_dump_slice(query_parts.slices[1], GPR_DUMP_ASCII);
    }
    gpr_slice_buffer_destroy(&query_parts);
    gpr_slice_unref(query_slice);
  }
  if (r->lb_policy_name == NULL) {
    r->lb_policy_name = gpr_strdup(default_lb_policy_name);
  }

  path_slice =
      gpr_slice_new(args->uri->path, strlen(args->uri->path), do_nothing);
  gpr_slice_buffer_init(&path_parts);

  gpr_slice_split(path_slice, ",", &path_parts);
  r->num_addrs = path_parts.count;
  r->addrs = gpr_malloc(sizeof(struct sockaddr_storage) * r->num_addrs);
  r->addrs_len = gpr_malloc(sizeof(*r->addrs_len) * r->num_addrs);

  for (i = 0; i < r->num_addrs; i++) {
    grpc_uri ith_uri = *args->uri;
    char *part_str = gpr_dump_slice(path_parts.slices[i], GPR_DUMP_ASCII);
    ith_uri.path = part_str;
    if (!parse(&ith_uri, &r->addrs[i], &r->addrs_len[i])) {
      errors_found = 1; /* GPR_TRUE */
    }
    gpr_free(part_str);
    if (errors_found) break;
  }

  gpr_slice_buffer_destroy(&path_parts);
  gpr_slice_unref(path_slice);
  if (errors_found) {
    gpr_free(r->lb_policy_name);
    gpr_free(r->addrs);
    gpr_free(r->addrs_len);
    gpr_free(r);
    return NULL;
  }

  gpr_ref_init(&r->refs, 1);
  gpr_mu_init(&r->mu);
  grpc_resolver_init(&r->base, &sockaddr_resolver_vtable);
  r->subchannel_factory = args->subchannel_factory;
  grpc_subchannel_factory_ref(r->subchannel_factory);

  return &r->base;
}
Exemple #7
0
static grpc_resolver *sockaddr_create(
    grpc_resolver_args *args, const char *default_lb_policy_name,
    int parse(grpc_uri *uri, struct sockaddr_storage *dst, size_t *len)) {
  bool errors_found = false;
  sockaddr_resolver *r;
  gpr_slice path_slice;
  gpr_slice_buffer path_parts;

  if (0 != strcmp(args->uri->authority, "")) {
    gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
            args->uri->scheme);
    return NULL;
  }

  r = gpr_malloc(sizeof(sockaddr_resolver));
  memset(r, 0, sizeof(*r));

  r->lb_policy_name =
      gpr_strdup(grpc_uri_get_query_arg(args->uri, "lb_policy"));
  const char *lb_enabled_qpart =
      grpc_uri_get_query_arg(args->uri, "lb_enabled");
  /* anything other than "0" is interpreted as true */
  const bool lb_enabled =
      (lb_enabled_qpart != NULL && (strcmp("0", lb_enabled_qpart) != 0));

  if (r->lb_policy_name != NULL && strcmp("grpclb", r->lb_policy_name) == 0 &&
      !lb_enabled) {
    /* we want grpclb but the "resolved" addresses aren't LB enabled. Bail
     * out, as this is meant mostly for tests. */
    gpr_log(GPR_ERROR,
            "Requested 'grpclb' LB policy but resolved addresses don't "
            "support load balancing.");
    abort();
  }

  if (r->lb_policy_name == NULL) {
    r->lb_policy_name = gpr_strdup(default_lb_policy_name);
  }

  path_slice =
      gpr_slice_new(args->uri->path, strlen(args->uri->path), do_nothing);
  gpr_slice_buffer_init(&path_parts);

  gpr_slice_split(path_slice, ",", &path_parts);
  r->addresses = grpc_lb_addresses_create(path_parts.count);
  for (size_t i = 0; i < r->addresses->num_addresses; i++) {
    grpc_uri ith_uri = *args->uri;
    char *part_str = gpr_dump_slice(path_parts.slices[i], GPR_DUMP_ASCII);
    ith_uri.path = part_str;
    if (!parse(&ith_uri, (struct sockaddr_storage *)(&r->addresses->addresses[i]
                                                          .address.addr),
               &r->addresses->addresses[i].address.len)) {
      errors_found = true;
    }
    gpr_free(part_str);
    r->addresses->addresses[i].is_balancer = lb_enabled;
    if (errors_found) break;
  }

  r->target_name = gpr_strdup(args->uri->path);
  gpr_slice_buffer_destroy(&path_parts);
  gpr_slice_unref(path_slice);
  if (errors_found) {
    gpr_free(r->lb_policy_name);
    gpr_free(r->target_name);
    grpc_lb_addresses_destroy(r->addresses, NULL /* user_data_destroy */);
    gpr_free(r);
    return NULL;
  }

  gpr_ref_init(&r->refs, 1);
  gpr_mu_init(&r->mu);
  grpc_resolver_init(&r->base, &sockaddr_resolver_vtable);

  return &r->base;
}