Merge pull request #3035 from ctiller/naming-crisis

Refactor default host name resolution
pull/3078/head
David G. Quintas 9 years ago
commit 52730d3bea
  1. 8
      include/grpc/grpc.h
  2. 9
      include/grpc/grpc_security.h
  3. 33
      src/core/channel/http_client_filter.c
  4. 8
      src/core/client_config/resolver_factory.c
  5. 12
      src/core/client_config/resolver_factory.h
  6. 91
      src/core/client_config/resolver_registry.c
  7. 15
      src/core/client_config/resolver_registry.h
  8. 25
      src/core/client_config/resolvers/dns_resolver.c
  9. 49
      src/core/client_config/resolvers/sockaddr_resolver.c
  10. 11
      src/core/client_config/resolvers/zookeeper_resolver.c
  11. 44
      src/core/surface/channel.c
  12. 8
      src/core/surface/init.c
  13. 2
      test/core/end2end/tests/default_host.c
  14. 4
      test/cpp/end2end/generic_end2end_test.cc

@ -134,6 +134,14 @@ typedef struct {
/** Secondary user agent: goes at the end of the user-agent metadata /** Secondary user agent: goes at the end of the user-agent metadata
sent on each request */ sent on each request */
#define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent" #define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
/* The caller of the secure_channel_create functions may override the target
name used for SSL host name checking using this channel argument which is of
type GRPC_ARG_STRING. This *should* be used for testing only.
If this argument is not specified, the name used for SSL host name checking
will be the target parameter (assuming that the secure channel is an SSL
channel). If this parameter is specified and the underlying is not an SSL
channel, it will just be ignored. */
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
/** Connectivity state of a channel. */ /** Connectivity state of a channel. */
typedef enum { typedef enum {

@ -142,15 +142,6 @@ grpc_credentials *grpc_iam_credentials_create(const char *authorization_token,
/* --- Secure channel creation. --- */ /* --- Secure channel creation. --- */
/* The caller of the secure_channel_create functions may override the target
name used for SSL host name checking using this channel argument which is of
type GRPC_ARG_STRING. This *should* be used for testing only.
If this argument is not specified, the name used for SSL host name checking
will be the target parameter (assuming that the secure channel is an SSL
channel). If this parameter is specified and the underlying is not an SSL
channel, it will just be ignored. */
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
/* Creates a secure channel using the passed-in credentials. */ /* Creates a secure channel using the passed-in credentials. */
grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
const char *target, const char *target,

@ -45,7 +45,6 @@ typedef struct call_data {
grpc_linked_mdelem content_type; grpc_linked_mdelem content_type;
grpc_linked_mdelem user_agent; grpc_linked_mdelem user_agent;
int sent_initial_metadata; int sent_initial_metadata;
int sent_authority;
int got_initial_metadata; int got_initial_metadata;
grpc_stream_op_buffer *recv_ops; grpc_stream_op_buffer *recv_ops;
@ -64,7 +63,6 @@ typedef struct channel_data {
grpc_mdelem *scheme; grpc_mdelem *scheme;
grpc_mdelem *content_type; grpc_mdelem *content_type;
grpc_mdelem *status; grpc_mdelem *status;
grpc_mdelem *default_authority;
/** complete user agent mdelem */ /** complete user agent mdelem */
grpc_mdelem *user_agent; grpc_mdelem *user_agent;
} channel_data; } channel_data;
@ -103,7 +101,6 @@ static void hc_on_recv(void *user_data, int success) {
static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data; grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data; channel_data *channeld = elem->channel_data;
/* eat the things we'd like to set ourselves */ /* eat the things we'd like to set ourselves */
if (md->key == channeld->method->key) return NULL; if (md->key == channeld->method->key) return NULL;
@ -111,10 +108,6 @@ static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
if (md->key == channeld->te_trailers->key) return NULL; if (md->key == channeld->te_trailers->key) return NULL;
if (md->key == channeld->content_type->key) return NULL; if (md->key == channeld->content_type->key) return NULL;
if (md->key == channeld->user_agent->key) return NULL; if (md->key == channeld->user_agent->key) return NULL;
if (channeld->default_authority &&
channeld->default_authority->key == md->key) {
calld->sent_authority = 1;
}
return md; return md;
} }
@ -138,11 +131,6 @@ static void hc_mutate_op(grpc_call_element *elem,
GRPC_MDELEM_REF(channeld->method)); GRPC_MDELEM_REF(channeld->method));
grpc_metadata_batch_add_head(&op->data.metadata, &calld->scheme, grpc_metadata_batch_add_head(&op->data.metadata, &calld->scheme,
GRPC_MDELEM_REF(channeld->scheme)); GRPC_MDELEM_REF(channeld->scheme));
if (channeld->default_authority && !calld->sent_authority) {
grpc_metadata_batch_add_head(
&op->data.metadata, &calld->authority,
GRPC_MDELEM_REF(channeld->default_authority));
}
grpc_metadata_batch_add_tail(&op->data.metadata, &calld->te_trailers, grpc_metadata_batch_add_tail(&op->data.metadata, &calld->te_trailers,
GRPC_MDELEM_REF(channeld->te_trailers)); GRPC_MDELEM_REF(channeld->te_trailers));
grpc_metadata_batch_add_tail(&op->data.metadata, &calld->content_type, grpc_metadata_batch_add_tail(&op->data.metadata, &calld->content_type,
@ -175,7 +163,6 @@ static void init_call_elem(grpc_call_element *elem,
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
calld->sent_initial_metadata = 0; calld->sent_initial_metadata = 0;
calld->got_initial_metadata = 0; calld->got_initial_metadata = 0;
calld->sent_authority = 0;
calld->on_done_recv = NULL; calld->on_done_recv = NULL;
grpc_iomgr_closure_init(&calld->hc_on_recv, hc_on_recv, elem); grpc_iomgr_closure_init(&calld->hc_on_recv, hc_on_recv, elem);
if (initial_op) hc_mutate_op(elem, initial_op); if (initial_op) hc_mutate_op(elem, initial_op);
@ -257,8 +244,6 @@ static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx,
static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
const grpc_channel_args *channel_args, const grpc_channel_args *channel_args,
grpc_mdctx *mdctx, int is_first, int is_last) { grpc_mdctx *mdctx, int is_first, int is_last) {
size_t i;
/* grab pointers to our data from the channel element */ /* grab pointers to our data from the channel element */
channel_data *channeld = elem->channel_data; channel_data *channeld = elem->channel_data;
@ -267,21 +252,6 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
path */ path */
GPR_ASSERT(!is_last); GPR_ASSERT(!is_last);
channeld->default_authority = NULL;
if (channel_args) {
for (i = 0; i < channel_args->num_args; i++) {
if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
if (channel_args->args[i].type != GRPC_ARG_STRING) {
gpr_log(GPR_ERROR, "%s: must be an string",
GRPC_ARG_DEFAULT_AUTHORITY);
} else {
channeld->default_authority = grpc_mdelem_from_strings(
mdctx, ":authority", channel_args->args[i].value.string);
}
}
}
}
/* initialize members */ /* initialize members */
channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers"); channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers");
channeld->method = grpc_mdelem_from_strings(mdctx, ":method", "POST"); channeld->method = grpc_mdelem_from_strings(mdctx, ":method", "POST");
@ -306,9 +276,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
GRPC_MDELEM_UNREF(channeld->content_type); GRPC_MDELEM_UNREF(channeld->content_type);
GRPC_MDELEM_UNREF(channeld->status); GRPC_MDELEM_UNREF(channeld->status);
GRPC_MDELEM_UNREF(channeld->user_agent); GRPC_MDELEM_UNREF(channeld->user_agent);
if (channeld->default_authority) {
GRPC_MDELEM_UNREF(channeld->default_authority);
}
} }
const grpc_channel_filter grpc_http_client_filter = { const grpc_channel_filter grpc_http_client_filter = {

@ -45,6 +45,12 @@ void grpc_resolver_factory_unref(grpc_resolver_factory *factory) {
grpc_resolver *grpc_resolver_factory_create_resolver( grpc_resolver *grpc_resolver_factory_create_resolver(
grpc_resolver_factory *factory, grpc_uri *uri, grpc_resolver_factory *factory, grpc_uri *uri,
grpc_subchannel_factory *subchannel_factory) { grpc_subchannel_factory *subchannel_factory) {
if (!factory) return NULL; if (factory == NULL) return NULL;
return factory->vtable->create_resolver(factory, uri, subchannel_factory); return factory->vtable->create_resolver(factory, uri, subchannel_factory);
} }
char *grpc_resolver_factory_get_default_authority(
grpc_resolver_factory *factory, grpc_uri *uri) {
if (factory == NULL) return NULL;
return factory->vtable->get_default_authority(factory, uri);
}

@ -51,9 +51,16 @@ struct grpc_resolver_factory_vtable {
void (*ref)(grpc_resolver_factory *factory); void (*ref)(grpc_resolver_factory *factory);
void (*unref)(grpc_resolver_factory *factory); void (*unref)(grpc_resolver_factory *factory);
/** Implementation of grpc_resolver_factory_create_resolver */
grpc_resolver *(*create_resolver)( grpc_resolver *(*create_resolver)(
grpc_resolver_factory *factory, grpc_uri *uri, grpc_resolver_factory *factory, grpc_uri *uri,
grpc_subchannel_factory *subchannel_factory); grpc_subchannel_factory *subchannel_factory);
/** Implementation of grpc_resolver_factory_get_default_authority */
char *(*get_default_authority)(grpc_resolver_factory *factory, grpc_uri *uri);
/** URI scheme that this factory implements */
const char *scheme;
}; };
void grpc_resolver_factory_ref(grpc_resolver_factory *resolver); void grpc_resolver_factory_ref(grpc_resolver_factory *resolver);
@ -64,4 +71,9 @@ grpc_resolver *grpc_resolver_factory_create_resolver(
grpc_resolver_factory *factory, grpc_uri *uri, grpc_resolver_factory *factory, grpc_uri *uri,
grpc_subchannel_factory *subchannel_factory); grpc_subchannel_factory *subchannel_factory);
/** Return a (freshly allocated with gpr_malloc) string representing
the default authority to use for this scheme. */
char *grpc_resolver_factory_get_default_authority(
grpc_resolver_factory *factory, grpc_uri *uri);
#endif /* GRPC_INTERNAL_CORE_CONFIG_RESOLVER_FACTORY_H */ #endif /* GRPC_INTERNAL_CORE_CONFIG_RESOLVER_FACTORY_H */

@ -41,41 +41,33 @@
#define MAX_RESOLVERS 10 #define MAX_RESOLVERS 10
typedef struct { static grpc_resolver_factory *g_all_of_the_resolvers[MAX_RESOLVERS];
char *scheme;
grpc_resolver_factory *factory;
} registered_resolver;
static registered_resolver g_all_of_the_resolvers[MAX_RESOLVERS];
static int g_number_of_resolvers = 0; static int g_number_of_resolvers = 0;
static char *g_default_resolver_scheme; static char *g_default_resolver_prefix;
void grpc_resolver_registry_init(const char *default_resolver_scheme) { void grpc_resolver_registry_init(const char *default_resolver_prefix) {
g_number_of_resolvers = 0; g_number_of_resolvers = 0;
g_default_resolver_scheme = gpr_strdup(default_resolver_scheme); g_default_resolver_prefix = gpr_strdup(default_resolver_prefix);
} }
void grpc_resolver_registry_shutdown(void) { void grpc_resolver_registry_shutdown(void) {
int i; int i;
for (i = 0; i < g_number_of_resolvers; i++) { for (i = 0; i < g_number_of_resolvers; i++) {
gpr_free(g_all_of_the_resolvers[i].scheme); grpc_resolver_factory_unref(g_all_of_the_resolvers[i]);
grpc_resolver_factory_unref(g_all_of_the_resolvers[i].factory);
} }
gpr_free(g_default_resolver_scheme); gpr_free(g_default_resolver_prefix);
} }
void grpc_register_resolver_type(const char *scheme, void grpc_register_resolver_type(grpc_resolver_factory *factory) {
grpc_resolver_factory *factory) {
int i; int i;
for (i = 0; i < g_number_of_resolvers; i++) { for (i = 0; i < g_number_of_resolvers; i++) {
GPR_ASSERT(0 != strcmp(scheme, g_all_of_the_resolvers[i].scheme)); GPR_ASSERT(0 != strcmp(factory->vtable->scheme,
g_all_of_the_resolvers[i]->vtable->scheme));
} }
GPR_ASSERT(g_number_of_resolvers != MAX_RESOLVERS); GPR_ASSERT(g_number_of_resolvers != MAX_RESOLVERS);
g_all_of_the_resolvers[g_number_of_resolvers].scheme = gpr_strdup(scheme);
grpc_resolver_factory_ref(factory); grpc_resolver_factory_ref(factory);
g_all_of_the_resolvers[g_number_of_resolvers].factory = factory; g_all_of_the_resolvers[g_number_of_resolvers++] = factory;
g_number_of_resolvers++;
} }
static grpc_resolver_factory *lookup_factory(grpc_uri *uri) { static grpc_resolver_factory *lookup_factory(grpc_uri *uri) {
@ -85,40 +77,57 @@ static grpc_resolver_factory *lookup_factory(grpc_uri *uri) {
if (!uri) return NULL; if (!uri) return NULL;
for (i = 0; i < g_number_of_resolvers; i++) { for (i = 0; i < g_number_of_resolvers; i++) {
if (0 == strcmp(uri->scheme, g_all_of_the_resolvers[i].scheme)) { if (0 == strcmp(uri->scheme, g_all_of_the_resolvers[i]->vtable->scheme)) {
return g_all_of_the_resolvers[i].factory; return g_all_of_the_resolvers[i];
} }
} }
return NULL; return NULL;
} }
grpc_resolver *grpc_resolver_create( static grpc_resolver_factory *resolve_factory(const char *target,
const char *name, grpc_subchannel_factory *subchannel_factory) { grpc_uri **uri) {
grpc_uri *uri;
char *tmp; char *tmp;
grpc_resolver_factory *factory = NULL; grpc_resolver_factory *factory = NULL;
grpc_resolver *resolver;
GPR_ASSERT(uri != NULL);
uri = grpc_uri_parse(name, 1); *uri = grpc_uri_parse(target, 1);
factory = lookup_factory(uri); factory = lookup_factory(*uri);
if (factory == NULL && g_default_resolver_scheme != NULL) { if (factory == NULL) {
grpc_uri_destroy(uri); if (g_default_resolver_prefix != NULL) {
gpr_asprintf(&tmp, "%s%s", g_default_resolver_scheme, name); grpc_uri_destroy(*uri);
uri = grpc_uri_parse(tmp, 1); gpr_asprintf(&tmp, "%s%s", g_default_resolver_prefix, target);
factory = lookup_factory(uri); *uri = grpc_uri_parse(tmp, 1);
if (factory == NULL) { factory = lookup_factory(*uri);
grpc_uri_destroy(grpc_uri_parse(name, 0)); if (factory == NULL) {
grpc_uri_destroy(grpc_uri_parse(tmp, 0)); grpc_uri_destroy(grpc_uri_parse(target, 0));
gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", name, tmp); grpc_uri_destroy(grpc_uri_parse(tmp, 0));
gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
tmp);
}
gpr_free(tmp);
} else {
grpc_uri_destroy(grpc_uri_parse(target, 0));
gpr_log(GPR_ERROR, "don't know how to resolve '%s'", target);
} }
gpr_free(tmp);
} else if (factory == NULL) {
grpc_uri_destroy(grpc_uri_parse(name, 0));
gpr_log(GPR_ERROR, "don't know how to resolve '%s'", name);
} }
resolver = return factory;
}
grpc_resolver *grpc_resolver_create(
const char *target, grpc_subchannel_factory *subchannel_factory) {
grpc_uri *uri = NULL;
grpc_resolver_factory *factory = resolve_factory(target, &uri);
grpc_resolver *resolver =
grpc_resolver_factory_create_resolver(factory, uri, subchannel_factory); grpc_resolver_factory_create_resolver(factory, uri, subchannel_factory);
grpc_uri_destroy(uri); grpc_uri_destroy(uri);
return resolver; return resolver;
} }
char *grpc_get_default_authority(const char *target) {
grpc_uri *uri = NULL;
grpc_resolver_factory *factory = resolve_factory(target, &uri);
char *authority = grpc_resolver_factory_get_default_authority(factory, uri);
grpc_uri_destroy(uri);
return authority;
}

@ -44,19 +44,22 @@ void grpc_resolver_registry_shutdown(void);
If \a priority is greater than zero, then the resolver will be eligible If \a priority is greater than zero, then the resolver will be eligible
to resolve names that are passed in with no scheme. Higher priority to resolve names that are passed in with no scheme. Higher priority
resolvers will be tried before lower priority schemes. */ resolvers will be tried before lower priority schemes. */
void grpc_register_resolver_type(const char *scheme, void grpc_register_resolver_type(grpc_resolver_factory *factory);
grpc_resolver_factory *factory);
/** Create a resolver given \a name. /** Create a resolver given \a target.
First tries to parse \a name as a URI. If this succeeds, tries First tries to parse \a target as a URI. If this succeeds, tries
to locate a registered resolver factory based on the URI scheme. to locate a registered resolver factory based on the URI scheme.
If parsing or location fails, prefixes default_prefix from If parsing or location fails, prefixes default_prefix from
grpc_resolver_registry_init to name, and tries again (if default_prefix grpc_resolver_registry_init to target, and tries again (if default_prefix
was not NULL). was not NULL).
If a resolver factory was found, use it to instantiate a resolver and If a resolver factory was found, use it to instantiate a resolver and
return it. return it.
If a resolver factory was not found, return NULL. */ If a resolver factory was not found, return NULL. */
grpc_resolver *grpc_resolver_create( grpc_resolver *grpc_resolver_create(
const char *name, grpc_subchannel_factory *subchannel_factory); const char *target, grpc_subchannel_factory *subchannel_factory);
/** Given a target, return a (freshly allocated with gpr_malloc) string
representing the default authority to pass from a client. */
char *grpc_get_default_authority(const char *target);
#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H */ #endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H */

@ -203,9 +203,6 @@ static grpc_resolver *dns_create(
grpc_subchannel_factory *subchannel_factory) { grpc_subchannel_factory *subchannel_factory) {
dns_resolver *r; dns_resolver *r;
const char *path = uri->path; const char *path = uri->path;
grpc_arg default_host_arg;
char *host;
char *port;
if (0 != strcmp(uri->authority, "")) { if (0 != strcmp(uri->authority, "")) {
gpr_log(GPR_ERROR, "authority based uri's not supported"); gpr_log(GPR_ERROR, "authority based uri's not supported");
@ -214,17 +211,6 @@ static grpc_resolver *dns_create(
if (path[0] == '/') ++path; if (path[0] == '/') ++path;
gpr_split_host_port(path, &host, &port);
default_host_arg.type = GRPC_ARG_STRING;
default_host_arg.key = GRPC_ARG_DEFAULT_AUTHORITY;
default_host_arg.value.string = host;
subchannel_factory = grpc_subchannel_factory_add_channel_arg(
subchannel_factory, &default_host_arg);
gpr_free(host);
gpr_free(port);
r = gpr_malloc(sizeof(dns_resolver)); r = gpr_malloc(sizeof(dns_resolver));
memset(r, 0, sizeof(*r)); memset(r, 0, sizeof(*r));
gpr_ref_init(&r->refs, 1); gpr_ref_init(&r->refs, 1);
@ -233,6 +219,7 @@ static grpc_resolver *dns_create(
r->name = gpr_strdup(path); r->name = gpr_strdup(path);
r->default_port = gpr_strdup(default_port); r->default_port = gpr_strdup(default_port);
r->subchannel_factory = subchannel_factory; r->subchannel_factory = subchannel_factory;
grpc_subchannel_factory_ref(subchannel_factory);
r->lb_policy_factory = lb_policy_factory; r->lb_policy_factory = lb_policy_factory;
return &r->base; return &r->base;
} }
@ -252,8 +239,16 @@ static grpc_resolver *dns_factory_create_resolver(
subchannel_factory); subchannel_factory);
} }
char *dns_factory_get_default_host_name(grpc_resolver_factory *factory,
grpc_uri *uri) {
const char *path = uri->path;
if (path[0] == '/') ++path;
return gpr_strdup(path);
}
static const grpc_resolver_factory_vtable dns_factory_vtable = { static const grpc_resolver_factory_vtable dns_factory_vtable = {
dns_factory_ref, dns_factory_unref, dns_factory_create_resolver}; dns_factory_ref, dns_factory_unref, dns_factory_create_resolver,
dns_factory_get_default_host_name, "dns"};
static grpc_resolver_factory dns_resolver_factory = {&dns_factory_vtable}; static grpc_resolver_factory dns_resolver_factory = {&dns_factory_vtable};
grpc_resolver_factory *grpc_dns_resolver_factory_create() { grpc_resolver_factory *grpc_dns_resolver_factory_create() {

@ -166,8 +166,29 @@ static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, int *len) {
return 1; return 1;
} }
static char *unix_get_default_authority(grpc_resolver_factory *factory,
grpc_uri *uri) {
return gpr_strdup("localhost");
}
#endif #endif
static char *ip_get_default_authority(grpc_uri *uri) {
const char *path = uri->path;
if (path[0] == '/') ++path;
return gpr_strdup(path);
}
static char *ipv4_get_default_authority(grpc_resolver_factory *factory,
grpc_uri *uri) {
return ip_get_default_authority(uri);
}
static char *ipv6_get_default_authority(grpc_resolver_factory *factory,
grpc_uri *uri) {
return ip_get_default_authority(uri);
}
static int parse_ipv4(grpc_uri *uri, struct sockaddr_storage *addr, int *len) { static int parse_ipv4(grpc_uri *uri, struct sockaddr_storage *addr, int *len) {
const char *host_port = uri->path; const char *host_port = uri->path;
char *host; char *host;
@ -313,20 +334,20 @@ static void sockaddr_factory_ref(grpc_resolver_factory *factory) {}
static void sockaddr_factory_unref(grpc_resolver_factory *factory) {} static void sockaddr_factory_unref(grpc_resolver_factory *factory) {}
#define DECL_FACTORY(name) \ #define DECL_FACTORY(name) \
static grpc_resolver *name##_factory_create_resolver( \ static grpc_resolver *name##_factory_create_resolver( \
grpc_resolver_factory *factory, grpc_uri *uri, \ grpc_resolver_factory *factory, grpc_uri *uri, \
grpc_subchannel_factory *subchannel_factory) { \ grpc_subchannel_factory *subchannel_factory) { \
return sockaddr_create(uri, grpc_create_pick_first_lb_policy, \ return sockaddr_create(uri, grpc_create_pick_first_lb_policy, \
subchannel_factory, parse_##name); \ subchannel_factory, parse_##name); \
} \ } \
static const grpc_resolver_factory_vtable name##_factory_vtable = { \ static const grpc_resolver_factory_vtable name##_factory_vtable = { \
sockaddr_factory_ref, sockaddr_factory_unref, \ sockaddr_factory_ref, sockaddr_factory_unref, \
name##_factory_create_resolver}; \ name##_factory_create_resolver, name##_get_default_authority, #name}; \
static grpc_resolver_factory name##_resolver_factory = { \ static grpc_resolver_factory name##_resolver_factory = { \
&name##_factory_vtable}; \ &name##_factory_vtable}; \
grpc_resolver_factory *grpc_##name##_resolver_factory_create() { \ grpc_resolver_factory *grpc_##name##_resolver_factory_create() { \
return &name##_resolver_factory; \ return &name##_resolver_factory; \
} }
#ifdef GPR_POSIX_SOCKET #ifdef GPR_POSIX_SOCKET

@ -467,8 +467,7 @@ static grpc_resolver *zookeeper_create(
} }
static void zookeeper_plugin_init() { static void zookeeper_plugin_init() {
grpc_register_resolver_type("zookeeper", grpc_register_resolver_type(grpc_zookeeper_resolver_factory_create());
grpc_zookeeper_resolver_factory_create());
} }
void grpc_zookeeper_register() { void grpc_zookeeper_register() {
@ -483,6 +482,11 @@ static void zookeeper_factory_ref(grpc_resolver_factory *factory) {}
static void zookeeper_factory_unref(grpc_resolver_factory *factory) {} static void zookeeper_factory_unref(grpc_resolver_factory *factory) {}
static char *zookeeper_factory_get_default_hostname(
grpc_resolver_factory *factory, grpc_uri *uri) {
return NULL;
}
static grpc_resolver *zookeeper_factory_create_resolver( static grpc_resolver *zookeeper_factory_create_resolver(
grpc_resolver_factory *factory, grpc_uri *uri, grpc_resolver_factory *factory, grpc_uri *uri,
grpc_subchannel_factory *subchannel_factory) { grpc_subchannel_factory *subchannel_factory) {
@ -492,7 +496,8 @@ static grpc_resolver *zookeeper_factory_create_resolver(
static const grpc_resolver_factory_vtable zookeeper_factory_vtable = { static const grpc_resolver_factory_vtable zookeeper_factory_vtable = {
zookeeper_factory_ref, zookeeper_factory_unref, zookeeper_factory_ref, zookeeper_factory_unref,
zookeeper_factory_create_resolver}; zookeeper_factory_create_resolver, zookeeper_factory_get_default_hostname,
"zookeeper"};
static grpc_resolver_factory zookeeper_resolver_factory = { static grpc_resolver_factory zookeeper_resolver_factory = {
&zookeeper_factory_vtable}; &zookeeper_factory_vtable};

@ -40,6 +40,7 @@
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
#include "src/core/client_config/resolver_registry.h"
#include "src/core/iomgr/iomgr.h" #include "src/core/iomgr/iomgr.h"
#include "src/core/support/string.h" #include "src/core/support/string.h"
#include "src/core/surface/call.h" #include "src/core/surface/call.h"
@ -70,6 +71,7 @@ struct grpc_channel {
grpc_mdstr *grpc_message_string; grpc_mdstr *grpc_message_string;
grpc_mdstr *path_string; grpc_mdstr *path_string;
grpc_mdstr *authority_string; grpc_mdstr *authority_string;
grpc_mdelem *default_authority;
/** mdelem for grpc-status: 0 thru grpc-status: 2 */ /** mdelem for grpc-status: 0 thru grpc-status: 2 */
grpc_mdelem *grpc_status_elem[NUM_CACHED_STATUS_ELEMS]; grpc_mdelem *grpc_status_elem[NUM_CACHED_STATUS_ELEMS];
@ -134,10 +136,47 @@ grpc_channel *grpc_channel_create_from_filters(
} else { } else {
channel->max_message_length = args->args[i].value.integer; channel->max_message_length = args->args[i].value.integer;
} }
} else if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
if (args->args[i].type != GRPC_ARG_STRING) {
gpr_log(GPR_ERROR, "%s: must be an string",
GRPC_ARG_DEFAULT_AUTHORITY);
} else {
if (channel->default_authority) {
/* setting this takes precedence over anything else */
GRPC_MDELEM_UNREF(channel->default_authority);
}
channel->default_authority = grpc_mdelem_from_strings(
mdctx, ":authority", 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: must be an string",
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
} else {
if (channel->default_authority) {
/* other ways of setting this (notably ssl) take precedence */
gpr_log(GPR_ERROR, "%s: default host already set some other way",
GRPC_ARG_DEFAULT_AUTHORITY);
} else {
channel->default_authority = grpc_mdelem_from_strings(
mdctx, ":authority", args->args[i].value.string);
}
}
} }
} }
} }
if (channel->is_client && channel->default_authority == NULL &&
target != NULL) {
char *default_authority = grpc_get_default_authority(target);
if (default_authority) {
channel->default_authority = grpc_mdelem_from_strings(
channel->metadata_context, ":authority", default_authority);
}
gpr_free(default_authority);
}
grpc_channel_stack_init(filters, num_filters, channel, args, grpc_channel_stack_init(filters, num_filters, channel, args,
channel->metadata_context, channel->metadata_context,
CHANNEL_STACK_FROM_CHANNEL(channel)); CHANNEL_STACK_FROM_CHANNEL(channel));
@ -161,6 +200,8 @@ static grpc_call *grpc_channel_create_call_internal(
send_metadata[num_metadata++] = path_mdelem; send_metadata[num_metadata++] = path_mdelem;
if (authority_mdelem != NULL) { if (authority_mdelem != NULL) {
send_metadata[num_metadata++] = authority_mdelem; send_metadata[num_metadata++] = authority_mdelem;
} else if (channel->default_authority != NULL) {
send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority);
} }
return grpc_call_create(channel, parent_call, propagation_mask, cq, NULL, return grpc_call_create(channel, parent_call, propagation_mask, cq, NULL,
@ -251,6 +292,9 @@ static void destroy_channel(void *p, int ok) {
} }
gpr_free(rc); gpr_free(rc);
} }
if (channel->default_authority != NULL) {
GRPC_MDELEM_UNREF(channel->default_authority);
}
grpc_mdctx_unref(channel->metadata_context); grpc_mdctx_unref(channel->metadata_context);
gpr_mu_destroy(&channel->registered_call_mu); gpr_mu_destroy(&channel->registered_call_mu);
gpr_free(channel->target); gpr_free(channel->target);

@ -86,11 +86,11 @@ void grpc_init(void) {
if (++g_initializations == 1) { if (++g_initializations == 1) {
gpr_time_init(); gpr_time_init();
grpc_resolver_registry_init("dns:///"); grpc_resolver_registry_init("dns:///");
grpc_register_resolver_type("dns", grpc_dns_resolver_factory_create()); grpc_register_resolver_type(grpc_dns_resolver_factory_create());
grpc_register_resolver_type("ipv4", grpc_ipv4_resolver_factory_create()); grpc_register_resolver_type(grpc_ipv4_resolver_factory_create());
grpc_register_resolver_type("ipv6", grpc_ipv6_resolver_factory_create()); grpc_register_resolver_type(grpc_ipv6_resolver_factory_create());
#ifdef GPR_POSIX_SOCKET #ifdef GPR_POSIX_SOCKET
grpc_register_resolver_type("unix", grpc_unix_resolver_factory_create()); grpc_register_resolver_type(grpc_unix_resolver_factory_create());
#endif #endif
grpc_register_tracer("channel", &grpc_trace_channel); grpc_register_tracer("channel", &grpc_trace_channel);
grpc_register_tracer("surface", &grpc_surface_trace); grpc_register_tracer("surface", &grpc_surface_trace);

@ -201,7 +201,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(details, "xyz"));
GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
GPR_ASSERT(0 == strcmp(call_details.host, "localhost")); GPR_ASSERT(0 == strncmp(call_details.host, "localhost", 9));
GPR_ASSERT(was_cancelled == 1); GPR_ASSERT(was_cancelled == 1);
gpr_free(details); gpr_free(details);

@ -160,7 +160,7 @@ class GenericEnd2endTest : public ::testing::Test {
srv_cq_.get(), tag(4)); srv_cq_.get(), tag(4));
verify_ok(srv_cq_.get(), 4, true); verify_ok(srv_cq_.get(), 4, true);
EXPECT_EQ(server_host_, srv_ctx.host()); EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length()));
EXPECT_EQ(kMethodName, srv_ctx.method()); EXPECT_EQ(kMethodName, srv_ctx.method());
ByteBuffer recv_buffer; ByteBuffer recv_buffer;
stream.Read(&recv_buffer, tag(5)); stream.Read(&recv_buffer, tag(5));
@ -233,7 +233,7 @@ TEST_F(GenericEnd2endTest, SimpleBidiStreaming) {
srv_cq_.get(), tag(2)); srv_cq_.get(), tag(2));
verify_ok(srv_cq_.get(), 2, true); verify_ok(srv_cq_.get(), 2, true);
EXPECT_EQ(server_host_, srv_ctx.host()); EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length()));
EXPECT_EQ(kMethodName, srv_ctx.method()); EXPECT_EQ(kMethodName, srv_ctx.method());
std::unique_ptr<ByteBuffer> send_buffer = std::unique_ptr<ByteBuffer> send_buffer =

Loading…
Cancel
Save