Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2015 gRPC authors. |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 4 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 8 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 10 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 16 | * |
| 17 | */ |
| 18 | |
Craig Tiller | 9eb0fde | 2017-03-31 16:59:30 -0700 | [diff] [blame] | 19 | #include "src/core/ext/filters/client_channel/resolver_registry.h" |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 20 | |
| 21 | #include <string.h> |
| 22 | |
| 23 | #include <grpc/support/alloc.h> |
| 24 | #include <grpc/support/log.h> |
| 25 | #include <grpc/support/string_util.h> |
| 26 | |
| 27 | #define MAX_RESOLVERS 10 |
David Garcia Quintas | fa0896b | 2016-09-23 16:10:19 -0700 | [diff] [blame] | 28 | #define DEFAULT_RESOLVER_PREFIX_MAX_LENGTH 32 |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 29 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 30 | static grpc_resolver_factory* g_all_of_the_resolvers[MAX_RESOLVERS]; |
Craig Tiller | eb3b12e | 2015-06-26 14:42:49 -0700 | [diff] [blame] | 31 | static int g_number_of_resolvers = 0; |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 32 | |
David Garcia Quintas | fa0896b | 2016-09-23 16:10:19 -0700 | [diff] [blame] | 33 | static char g_default_resolver_prefix[DEFAULT_RESOLVER_PREFIX_MAX_LENGTH] = |
| 34 | "dns:///"; |
Craig Tiller | eb3b12e | 2015-06-26 14:42:49 -0700 | [diff] [blame] | 35 | |
David Garcia Quintas | fa0896b | 2016-09-23 16:10:19 -0700 | [diff] [blame] | 36 | void grpc_resolver_registry_init() {} |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 37 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 38 | void grpc_resolver_registry_shutdown(void) { |
David Garcia Quintas | fa0896b | 2016-09-23 16:10:19 -0700 | [diff] [blame] | 39 | for (int i = 0; i < g_number_of_resolvers; i++) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 40 | grpc_resolver_factory_unref(g_all_of_the_resolvers[i]); |
| 41 | } |
Craig Tiller | 5deda3d | 2016-05-05 12:34:19 -0700 | [diff] [blame] | 42 | // FIXME(ctiller): this should live in grpc_resolver_registry_init, |
Mark D. Roth | 2137cd8 | 2016-09-14 09:04:00 -0700 | [diff] [blame] | 43 | // however that would have the client_channel plugin call this AFTER we start |
Craig Tiller | 5deda3d | 2016-05-05 12:34:19 -0700 | [diff] [blame] | 44 | // registering resolvers from third party plugins, and so they'd never show |
| 45 | // up. |
| 46 | // We likely need some kind of dependency system for plugins.... what form |
| 47 | // that takes is TBD. |
| 48 | g_number_of_resolvers = 0; |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 49 | } |
| 50 | |
David Garcia Quintas | fa0896b | 2016-09-23 16:10:19 -0700 | [diff] [blame] | 51 | void grpc_resolver_registry_set_default_prefix( |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 52 | const char* default_resolver_prefix) { |
David Garcia Quintas | a60dcca | 2016-09-26 11:09:29 -0700 | [diff] [blame] | 53 | const size_t len = strlen(default_resolver_prefix); |
| 54 | GPR_ASSERT(len < DEFAULT_RESOLVER_PREFIX_MAX_LENGTH && |
| 55 | "default resolver prefix too long"); |
| 56 | GPR_ASSERT(len > 0 && "default resolver prefix can't be empty"); |
| 57 | // By the previous assert, default_resolver_prefix is safe to be copied with a |
| 58 | // plain strcpy. |
| 59 | strcpy(g_default_resolver_prefix, default_resolver_prefix); |
David Garcia Quintas | fa0896b | 2016-09-23 16:10:19 -0700 | [diff] [blame] | 60 | } |
| 61 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 62 | void grpc_register_resolver_type(grpc_resolver_factory* factory) { |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 63 | int i; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 64 | for (i = 0; i < g_number_of_resolvers; i++) { |
Yuchen Zeng | 3d80323 | 2016-11-30 15:17:31 -0800 | [diff] [blame] | 65 | GPR_ASSERT(0 != strcmp(factory->vtable->scheme, |
| 66 | g_all_of_the_resolvers[i]->vtable->scheme)); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 67 | } |
| 68 | GPR_ASSERT(g_number_of_resolvers != MAX_RESOLVERS); |
| 69 | grpc_resolver_factory_ref(factory); |
Craig Tiller | bc85be1 | 2015-08-24 10:36:39 -0700 | [diff] [blame] | 70 | g_all_of_the_resolvers[g_number_of_resolvers++] = factory; |
Craig Tiller | eb3b12e | 2015-06-26 14:42:49 -0700 | [diff] [blame] | 71 | } |
| 72 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 73 | static grpc_resolver_factory* lookup_factory(const char* name) { |
Craig Tiller | eb3b12e | 2015-06-26 14:42:49 -0700 | [diff] [blame] | 74 | int i; |
| 75 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 76 | for (i = 0; i < g_number_of_resolvers; i++) { |
Craig Tiller | 65938df | 2016-03-31 13:08:49 -0700 | [diff] [blame] | 77 | if (0 == strcmp(name, g_all_of_the_resolvers[i]->vtable->scheme)) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 78 | return g_all_of_the_resolvers[i]; |
Craig Tiller | eb3b12e | 2015-06-26 14:42:49 -0700 | [diff] [blame] | 79 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 80 | } |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 81 | return nullptr; |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 82 | } |
| 83 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 84 | grpc_resolver_factory* grpc_resolver_factory_lookup(const char* name) { |
| 85 | grpc_resolver_factory* f = lookup_factory(name); |
Craig Tiller | 65938df | 2016-03-31 13:08:49 -0700 | [diff] [blame] | 86 | if (f) grpc_resolver_factory_ref(f); |
| 87 | return f; |
| 88 | } |
| 89 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 90 | static grpc_resolver_factory* lookup_factory_by_uri(grpc_uri* uri) { |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 91 | if (!uri) return nullptr; |
Craig Tiller | 65938df | 2016-03-31 13:08:49 -0700 | [diff] [blame] | 92 | return lookup_factory(uri->scheme); |
| 93 | } |
| 94 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 95 | static grpc_resolver_factory* resolve_factory(grpc_exec_ctx* exec_ctx, |
| 96 | const char* target, |
| 97 | grpc_uri** uri, |
| 98 | char** canonical_target) { |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 99 | grpc_resolver_factory* factory = nullptr; |
Craig Tiller | eb3b12e | 2015-06-26 14:42:49 -0700 | [diff] [blame] | 100 | |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 101 | GPR_ASSERT(uri != nullptr); |
Yuchen Zeng | c40d1d8 | 2017-02-15 20:42:06 -0800 | [diff] [blame] | 102 | *uri = grpc_uri_parse(exec_ctx, target, 1); |
Craig Tiller | 65938df | 2016-03-31 13:08:49 -0700 | [diff] [blame] | 103 | factory = lookup_factory_by_uri(*uri); |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 104 | if (factory == nullptr) { |
David Garcia Quintas | a60dcca | 2016-09-26 11:09:29 -0700 | [diff] [blame] | 105 | grpc_uri_destroy(*uri); |
Mark D. Roth | 201db7d | 2016-12-12 09:36:02 -0800 | [diff] [blame] | 106 | gpr_asprintf(canonical_target, "%s%s", g_default_resolver_prefix, target); |
Yuchen Zeng | c40d1d8 | 2017-02-15 20:42:06 -0800 | [diff] [blame] | 107 | *uri = grpc_uri_parse(exec_ctx, *canonical_target, 1); |
David Garcia Quintas | a60dcca | 2016-09-26 11:09:29 -0700 | [diff] [blame] | 108 | factory = lookup_factory_by_uri(*uri); |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 109 | if (factory == nullptr) { |
Yuchen Zeng | c40d1d8 | 2017-02-15 20:42:06 -0800 | [diff] [blame] | 110 | grpc_uri_destroy(grpc_uri_parse(exec_ctx, target, 0)); |
| 111 | grpc_uri_destroy(grpc_uri_parse(exec_ctx, *canonical_target, 0)); |
Mark D. Roth | 201db7d | 2016-12-12 09:36:02 -0800 | [diff] [blame] | 112 | gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target, |
| 113 | *canonical_target); |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 114 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 115 | } |
Craig Tiller | bc85be1 | 2015-08-24 10:36:39 -0700 | [diff] [blame] | 116 | return factory; |
| 117 | } |
| 118 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 119 | grpc_resolver* grpc_resolver_create(grpc_exec_ctx* exec_ctx, const char* target, |
| 120 | const grpc_channel_args* args, |
| 121 | grpc_pollset_set* pollset_set, |
| 122 | grpc_combiner* combiner) { |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 123 | grpc_uri* uri = nullptr; |
| 124 | char* canonical_target = nullptr; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 125 | grpc_resolver_factory* factory = |
Yuchen Zeng | c40d1d8 | 2017-02-15 20:42:06 -0800 | [diff] [blame] | 126 | resolve_factory(exec_ctx, target, &uri, &canonical_target); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 127 | grpc_resolver* resolver; |
Mark D. Roth | 98abfd3 | 2016-10-21 08:10:51 -0700 | [diff] [blame] | 128 | grpc_resolver_args resolver_args; |
| 129 | memset(&resolver_args, 0, sizeof(resolver_args)); |
| 130 | resolver_args.uri = uri; |
| 131 | resolver_args.args = args; |
Yuchen Zeng | 63e3e3b | 2016-12-15 12:06:33 -0800 | [diff] [blame] | 132 | resolver_args.pollset_set = pollset_set; |
Craig Tiller | 972470b | 2017-02-09 15:05:36 -0800 | [diff] [blame] | 133 | resolver_args.combiner = combiner; |
Yuchen Zeng | 63e3e3b | 2016-12-15 12:06:33 -0800 | [diff] [blame] | 134 | resolver = |
| 135 | grpc_resolver_factory_create_resolver(exec_ctx, factory, &resolver_args); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 136 | grpc_uri_destroy(uri); |
Mark D. Roth | 201db7d | 2016-12-12 09:36:02 -0800 | [diff] [blame] | 137 | gpr_free(canonical_target); |
Craig Tiller | 3bc8ebd | 2015-06-24 15:41:15 -0700 | [diff] [blame] | 138 | return resolver; |
| 139 | } |
Craig Tiller | bc85be1 | 2015-08-24 10:36:39 -0700 | [diff] [blame] | 140 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 141 | char* grpc_get_default_authority(grpc_exec_ctx* exec_ctx, const char* target) { |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 142 | grpc_uri* uri = nullptr; |
| 143 | char* canonical_target = nullptr; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 144 | grpc_resolver_factory* factory = |
Yuchen Zeng | c40d1d8 | 2017-02-15 20:42:06 -0800 | [diff] [blame] | 145 | resolve_factory(exec_ctx, target, &uri, &canonical_target); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 146 | char* authority = grpc_resolver_factory_get_default_authority(factory, uri); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 147 | grpc_uri_destroy(uri); |
Mark D. Roth | 201db7d | 2016-12-12 09:36:02 -0800 | [diff] [blame] | 148 | gpr_free(canonical_target); |
Craig Tiller | bc85be1 | 2015-08-24 10:36:39 -0700 | [diff] [blame] | 149 | return authority; |
| 150 | } |
Mark D. Roth | 201db7d | 2016-12-12 09:36:02 -0800 | [diff] [blame] | 151 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 152 | char* grpc_resolver_factory_add_default_prefix_if_needed( |
| 153 | grpc_exec_ctx* exec_ctx, const char* target) { |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 154 | grpc_uri* uri = nullptr; |
| 155 | char* canonical_target = nullptr; |
Yuchen Zeng | c40d1d8 | 2017-02-15 20:42:06 -0800 | [diff] [blame] | 156 | resolve_factory(exec_ctx, target, &uri, &canonical_target); |
Mark D. Roth | 201db7d | 2016-12-12 09:36:02 -0800 | [diff] [blame] | 157 | grpc_uri_destroy(uri); |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 158 | return canonical_target == nullptr ? gpr_strdup(target) : canonical_target; |
Mark D. Roth | 201db7d | 2016-12-12 09:36:02 -0800 | [diff] [blame] | 159 | } |