3 * Copyright 2015 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <grpc/support/port_platform.h>
21 #include "src/core/ext/filters/client_channel/resolver_registry.h"
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 #include <grpc/support/string_util.h>
35 RegistryState() : default_prefix_(gpr_strdup("dns:///")) {}
37 void SetDefaultPrefix(const char* default_resolver_prefix) {
38 GPR_ASSERT(default_resolver_prefix != nullptr);
39 GPR_ASSERT(*default_resolver_prefix != '\0');
40 default_prefix_.reset(gpr_strdup(default_resolver_prefix));
43 void RegisterResolverFactory(UniquePtr<ResolverFactory> factory) {
44 for (size_t i = 0; i < factories_.size(); ++i) {
45 GPR_ASSERT(strcmp(factories_[i]->scheme(), factory->scheme()) != 0);
47 factories_.push_back(std::move(factory));
50 ResolverFactory* LookupResolverFactory(const char* scheme) const {
51 for (size_t i = 0; i < factories_.size(); ++i) {
52 if (strcmp(scheme, factories_[i]->scheme()) == 0) {
53 return factories_[i].get();
59 // Returns the factory for the scheme of \a target. If \a target does
60 // not parse as a URI, prepends \a default_prefix_ and tries again.
61 // If URI parsing is successful (in either attempt), sets \a uri to
62 // point to the parsed URI.
63 // If \a default_prefix_ needs to be prepended, sets \a canonical_target
64 // to the canonical target string.
65 ResolverFactory* FindResolverFactory(const char* target, grpc_uri** uri,
66 char** canonical_target) const {
67 GPR_ASSERT(uri != nullptr);
68 *uri = grpc_uri_parse(target, 1);
69 ResolverFactory* factory =
70 *uri == nullptr ? nullptr : LookupResolverFactory((*uri)->scheme);
71 if (factory == nullptr) {
72 grpc_uri_destroy(*uri);
73 gpr_asprintf(canonical_target, "%s%s", default_prefix_.get(), target);
74 *uri = grpc_uri_parse(*canonical_target, 1);
76 *uri == nullptr ? nullptr : LookupResolverFactory((*uri)->scheme);
77 if (factory == nullptr) {
78 grpc_uri_destroy(grpc_uri_parse(target, 0));
79 grpc_uri_destroy(grpc_uri_parse(*canonical_target, 0));
80 gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
88 // We currently support 10 factories without doing additional
89 // allocation. This number could be raised if there is a case where
90 // more factories are needed and the additional allocations are
91 // hurting performance (which is unlikely, since these allocations
92 // only occur at gRPC initialization time).
93 InlinedVector<UniquePtr<ResolverFactory>, 10> factories_;
94 UniquePtr<char> default_prefix_;
97 static RegistryState* g_state = nullptr;
102 // ResolverRegistry::Builder
105 void ResolverRegistry::Builder::InitRegistry() {
106 if (g_state == nullptr) g_state = New<RegistryState>();
109 void ResolverRegistry::Builder::ShutdownRegistry() {
114 void ResolverRegistry::Builder::SetDefaultPrefix(
115 const char* default_resolver_prefix) {
117 g_state->SetDefaultPrefix(default_resolver_prefix);
120 void ResolverRegistry::Builder::RegisterResolverFactory(
121 UniquePtr<ResolverFactory> factory) {
123 g_state->RegisterResolverFactory(std::move(factory));
130 ResolverFactory* ResolverRegistry::LookupResolverFactory(const char* scheme) {
131 GPR_ASSERT(g_state != nullptr);
132 return g_state->LookupResolverFactory(scheme);
135 bool ResolverRegistry::IsValidTarget(const char* target) {
136 grpc_uri* uri = nullptr;
137 char* canonical_target = nullptr;
138 ResolverFactory* factory =
139 g_state->FindResolverFactory(target, &uri, &canonical_target);
140 bool result = factory == nullptr ? false : factory->IsValidUri(uri);
141 grpc_uri_destroy(uri);
142 gpr_free(canonical_target);
146 OrphanablePtr<Resolver> ResolverRegistry::CreateResolver(
147 const char* target, const grpc_channel_args* args,
148 grpc_pollset_set* pollset_set, grpc_combiner* combiner,
149 UniquePtr<Resolver::ResultHandler> result_handler) {
150 GPR_ASSERT(g_state != nullptr);
151 grpc_uri* uri = nullptr;
152 char* canonical_target = nullptr;
153 ResolverFactory* factory =
154 g_state->FindResolverFactory(target, &uri, &canonical_target);
155 ResolverArgs resolver_args;
156 resolver_args.uri = uri;
157 resolver_args.args = args;
158 resolver_args.pollset_set = pollset_set;
159 resolver_args.combiner = combiner;
160 resolver_args.result_handler = std::move(result_handler);
161 OrphanablePtr<Resolver> resolver =
162 factory == nullptr ? nullptr
163 : factory->CreateResolver(std::move(resolver_args));
164 grpc_uri_destroy(uri);
165 gpr_free(canonical_target);
169 UniquePtr<char> ResolverRegistry::GetDefaultAuthority(const char* target) {
170 GPR_ASSERT(g_state != nullptr);
171 grpc_uri* uri = nullptr;
172 char* canonical_target = nullptr;
173 ResolverFactory* factory =
174 g_state->FindResolverFactory(target, &uri, &canonical_target);
175 UniquePtr<char> authority =
176 factory == nullptr ? nullptr : factory->GetDefaultAuthority(uri);
177 grpc_uri_destroy(uri);
178 gpr_free(canonical_target);
182 UniquePtr<char> ResolverRegistry::AddDefaultPrefixIfNeeded(const char* target) {
183 GPR_ASSERT(g_state != nullptr);
184 grpc_uri* uri = nullptr;
185 char* canonical_target = nullptr;
186 g_state->FindResolverFactory(target, &uri, &canonical_target);
187 grpc_uri_destroy(uri);
188 return UniquePtr<char>(canonical_target == nullptr ? gpr_strdup(target)
192 } // namespace grpc_core