|
|
|
@ -33,6 +33,7 @@ |
|
|
|
|
|
|
|
|
|
#include <stdbool.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
@ -40,8 +41,10 @@ |
|
|
|
|
#include <grpc/support/port_platform.h> |
|
|
|
|
#include <grpc/support/string_util.h> |
|
|
|
|
|
|
|
|
|
#include "src/core/ext/client_config/method_config.h" |
|
|
|
|
#include "src/core/ext/client_config/parse_address.h" |
|
|
|
|
#include "src/core/ext/client_config/resolver_registry.h" |
|
|
|
|
#include "src/core/lib/channel/channel_args.h" |
|
|
|
|
#include "src/core/lib/iomgr/resolve_address.h" |
|
|
|
|
#include "src/core/lib/iomgr/unix_sockets_posix.h" |
|
|
|
|
#include "src/core/lib/support/string.h" |
|
|
|
@ -53,6 +56,8 @@ typedef struct { |
|
|
|
|
gpr_refcount refs; |
|
|
|
|
/** load balancing policy name */ |
|
|
|
|
char *lb_policy_name; |
|
|
|
|
/** method config table */ |
|
|
|
|
grpc_method_config_table *method_config_table; |
|
|
|
|
|
|
|
|
|
/** the addresses that we've 'resolved' */ |
|
|
|
|
grpc_lb_addresses *addresses; |
|
|
|
@ -120,9 +125,15 @@ static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, |
|
|
|
|
sockaddr_resolver *r) { |
|
|
|
|
if (r->next_completion != NULL && !r->published) { |
|
|
|
|
r->published = true; |
|
|
|
|
grpc_channel_args *lb_policy_args = NULL; |
|
|
|
|
if (r->method_config_table != NULL) { |
|
|
|
|
const grpc_arg arg = grpc_method_config_table_create_channel_arg( |
|
|
|
|
r->method_config_table); |
|
|
|
|
lb_policy_args = grpc_channel_args_copy_and_add(NULL /* src */, &arg, 1); |
|
|
|
|
} |
|
|
|
|
*r->target_result = grpc_resolver_result_create( |
|
|
|
|
"", grpc_lb_addresses_copy(r->addresses, NULL /* user_data_copy */), |
|
|
|
|
r->lb_policy_name, NULL); |
|
|
|
|
r->lb_policy_name, lb_policy_args); |
|
|
|
|
grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL); |
|
|
|
|
r->next_completion = NULL; |
|
|
|
|
} |
|
|
|
@ -133,6 +144,7 @@ static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { |
|
|
|
|
gpr_mu_destroy(&r->mu); |
|
|
|
|
grpc_lb_addresses_destroy(r->addresses, NULL /* user_data_destroy */); |
|
|
|
|
gpr_free(r->lb_policy_name); |
|
|
|
|
grpc_method_config_table_unref(r->method_config_table); |
|
|
|
|
gpr_free(r); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -164,30 +176,29 @@ static void do_nothing(void *ignored) {} |
|
|
|
|
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)); |
|
|
|
|
sockaddr_resolver *r = gpr_malloc(sizeof(sockaddr_resolver)); |
|
|
|
|
memset(r, 0, sizeof(*r)); |
|
|
|
|
|
|
|
|
|
// Initialize LB policy name.
|
|
|
|
|
r->lb_policy_name = |
|
|
|
|
gpr_strdup(grpc_uri_get_query_arg(args->uri, "lb_policy")); |
|
|
|
|
if (r->lb_policy_name == NULL) { |
|
|
|
|
r->lb_policy_name = gpr_strdup(default_lb_policy_name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Get lb_enabled arg.
|
|
|
|
|
const char *lb_enabled_qpart = |
|
|
|
|
grpc_uri_get_query_arg(args->uri, "lb_enabled"); |
|
|
|
|
/* anything other than "0" is interpreted as true */ |
|
|
|
|
// 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) { |
|
|
|
|
lb_enabled_qpart != NULL && strcmp("0", lb_enabled_qpart) != 0; |
|
|
|
|
if (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, |
|
|
|
@ -196,16 +207,14 @@ static grpc_resolver *sockaddr_create( |
|
|
|
|
abort(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (r->lb_policy_name == NULL) { |
|
|
|
|
r->lb_policy_name = gpr_strdup(default_lb_policy_name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
path_slice = |
|
|
|
|
// 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); |
|
|
|
|
r->addresses = grpc_lb_addresses_create(path_parts.count); |
|
|
|
|
bool errors_found = false; |
|
|
|
|
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); |
|
|
|
@ -219,7 +228,6 @@ static grpc_resolver *sockaddr_create( |
|
|
|
|
r->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) { |
|
|
|
@ -229,6 +237,43 @@ static grpc_resolver *sockaddr_create( |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Construct method config table.
|
|
|
|
|
// We only support parameters for a single method.
|
|
|
|
|
const char *method_name = grpc_uri_get_query_arg(args->uri, "method_name"); |
|
|
|
|
if (method_name != NULL) { |
|
|
|
|
const char *wait_for_ready_str = |
|
|
|
|
grpc_uri_get_query_arg(args->uri, "wait_for_ready"); |
|
|
|
|
// Anything other than "0" is interpreted as true.
|
|
|
|
|
bool wait_for_ready = |
|
|
|
|
wait_for_ready_str != NULL && strcmp("0", wait_for_ready_str) != 0; |
|
|
|
|
const char* timeout_str = |
|
|
|
|
grpc_uri_get_query_arg(args->uri, "timeout_seconds"); |
|
|
|
|
gpr_timespec timeout = { |
|
|
|
|
timeout_str == NULL ? 0 : atoi(timeout_str), 0, GPR_CLOCK_MONOTONIC}; |
|
|
|
|
const char* max_request_message_bytes_str = |
|
|
|
|
grpc_uri_get_query_arg(args->uri, "max_request_message_bytes"); |
|
|
|
|
int32_t max_request_message_bytes = |
|
|
|
|
max_request_message_bytes_str == NULL |
|
|
|
|
? 0 : atoi(max_request_message_bytes_str); |
|
|
|
|
const char* max_response_message_bytes_str = |
|
|
|
|
grpc_uri_get_query_arg(args->uri, "max_response_message_bytes"); |
|
|
|
|
int32_t max_response_message_bytes = |
|
|
|
|
max_response_message_bytes_str == NULL |
|
|
|
|
? 0 : atoi(max_response_message_bytes_str); |
|
|
|
|
grpc_method_config *method_config = grpc_method_config_create( |
|
|
|
|
wait_for_ready_str == NULL ? NULL : &wait_for_ready, |
|
|
|
|
timeout_str == NULL ? NULL : &timeout, |
|
|
|
|
max_request_message_bytes_str == NULL |
|
|
|
|
? NULL : &max_request_message_bytes, |
|
|
|
|
max_response_message_bytes_str == NULL |
|
|
|
|
? NULL : &max_response_message_bytes); |
|
|
|
|
grpc_method_config_table_entry entry = { |
|
|
|
|
grpc_mdstr_from_string(method_name), method_config}; |
|
|
|
|
r->method_config_table = grpc_method_config_table_create(1, &entry); |
|
|
|
|
GRPC_MDSTR_UNREF(entry.method_name); |
|
|
|
|
grpc_method_config_unref(method_config); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpr_ref_init(&r->refs, 1); |
|
|
|
|
gpr_mu_init(&r->mu); |
|
|
|
|
grpc_resolver_init(&r->base, &sockaddr_resolver_vtable); |
|
|
|
|