From 50cb169af06c9165c117e327d88713503f786c4b Mon Sep 17 00:00:00 2001 From: Qiancheng Zhao Date: Mon, 8 Jul 2019 13:44:55 -0700 Subject: [PATCH] add IsValidTarget api to ResolverRegistry --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 2 + .../resolver/dns/native/dns_resolver.cc | 11 +++-- .../resolver/fake/fake_resolver.cc | 2 + .../resolver/sockaddr/sockaddr_resolver.cc | 44 +++++++++++++------ .../filters/client_channel/resolver_factory.h | 4 ++ .../client_channel/resolver_registry.cc | 11 +++++ .../client_channel/resolver_registry.h | 3 ++ 7 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 43b28bc9650..4e7bb5ec482 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -433,6 +433,8 @@ void AresDnsResolver::StartResolvingLocked() { class AresDnsResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { return true; } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return OrphanablePtr(New(std::move(args))); } diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 1abe9ad3e44..bc6d73acac7 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -258,11 +258,16 @@ void NativeDnsResolver::StartResolvingLocked() { class NativeDnsResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver(ResolverArgs args) const override { - if (GPR_UNLIKELY(0 != strcmp(args.uri->authority, ""))) { + bool IsValidUri(const grpc_uri* uri) const override { + if (GPR_UNLIKELY(0 != strcmp(uri->authority, ""))) { gpr_log(GPR_ERROR, "authority based dns uri's not supported"); - return OrphanablePtr(nullptr); + return false; } + return true; + } + + OrphanablePtr CreateResolver(ResolverArgs args) const override { + if (!IsValidUri(args.uri)) return nullptr; return OrphanablePtr(New(std::move(args))); } diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index ff728a3dc43..5ecdf4e8d16 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -315,6 +315,8 @@ namespace { class FakeResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { return true; } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return OrphanablePtr(New(std::move(args))); } diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index 517b9297af4..532fd6df9b7 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -80,24 +80,23 @@ void SockaddrResolver::StartLocked() { void DoNothing(void* ignored) {} -OrphanablePtr CreateSockaddrResolver( - ResolverArgs args, - bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) { - if (0 != strcmp(args.uri->authority, "")) { +bool ParseUri(const grpc_uri* uri, + bool parse(const grpc_uri* uri, grpc_resolved_address* dst), + ServerAddressList* addresses) { + if (0 != strcmp(uri->authority, "")) { gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme", - args.uri->scheme); - return nullptr; + uri->scheme); + return false; } // Construct addresses. grpc_slice path_slice = - grpc_slice_new(args.uri->path, strlen(args.uri->path), DoNothing); + grpc_slice_new(uri->path, strlen(uri->path), DoNothing); grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); - ServerAddressList addresses; bool errors_found = false; for (size_t i = 0; i < path_parts.count; i++) { - grpc_uri ith_uri = *args.uri; + grpc_uri ith_uri = *uri; UniquePtr part_str(grpc_slice_to_c_string(path_parts.slices[i])); ith_uri.path = part_str.get(); grpc_resolved_address addr; @@ -105,13 +104,20 @@ OrphanablePtr CreateSockaddrResolver( errors_found = true; break; } - addresses.emplace_back(addr, nullptr /* args */); + if (addresses != nullptr) { + addresses->emplace_back(addr, nullptr /* args */); + } } grpc_slice_buffer_destroy_internal(&path_parts); grpc_slice_unref_internal(path_slice); - if (errors_found) { - return OrphanablePtr(nullptr); - } + return !errors_found; +} + +OrphanablePtr CreateSockaddrResolver( + ResolverArgs args, + bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) { + ServerAddressList addresses; + if (!ParseUri(args.uri, parse, &addresses)) return nullptr; // Instantiate resolver. return OrphanablePtr( New(std::move(addresses), std::move(args))); @@ -119,6 +125,10 @@ OrphanablePtr CreateSockaddrResolver( class IPv4ResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { + return ParseUri(uri, grpc_parse_ipv4, nullptr); + } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return CreateSockaddrResolver(std::move(args), grpc_parse_ipv4); } @@ -128,6 +138,10 @@ class IPv4ResolverFactory : public ResolverFactory { class IPv6ResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { + return ParseUri(uri, grpc_parse_ipv6, nullptr); + } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return CreateSockaddrResolver(std::move(args), grpc_parse_ipv6); } @@ -138,6 +152,10 @@ class IPv6ResolverFactory : public ResolverFactory { #ifdef GRPC_HAVE_UNIX_SOCKET class UnixResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { + return ParseUri(uri, grpc_parse_unix, nullptr); + } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return CreateSockaddrResolver(std::move(args), grpc_parse_unix); } diff --git a/src/core/ext/filters/client_channel/resolver_factory.h b/src/core/ext/filters/client_channel/resolver_factory.h index 273fd8d24f0..7fed48b9570 100644 --- a/src/core/ext/filters/client_channel/resolver_factory.h +++ b/src/core/ext/filters/client_channel/resolver_factory.h @@ -47,6 +47,10 @@ struct ResolverArgs { class ResolverFactory { public: + /// Returns a bool indicating whether the input uri is valid to create a + /// resolver. + virtual bool IsValidUri(const grpc_uri* uri) const GRPC_ABSTRACT; + /// Returns a new resolver instance. virtual OrphanablePtr CreateResolver(ResolverArgs args) const GRPC_ABSTRACT; diff --git a/src/core/ext/filters/client_channel/resolver_registry.cc b/src/core/ext/filters/client_channel/resolver_registry.cc index 5b00eab341e..509c4ef38fa 100644 --- a/src/core/ext/filters/client_channel/resolver_registry.cc +++ b/src/core/ext/filters/client_channel/resolver_registry.cc @@ -132,6 +132,17 @@ ResolverFactory* ResolverRegistry::LookupResolverFactory(const char* scheme) { return g_state->LookupResolverFactory(scheme); } +bool ResolverRegistry::IsValidTarget(const char* target) { + grpc_uri* uri = nullptr; + char* canonical_target = nullptr; + ResolverFactory* factory = + g_state->FindResolverFactory(target, &uri, &canonical_target); + bool result = factory == nullptr ? false : factory->IsValidUri(uri); + grpc_uri_destroy(uri); + gpr_free(canonical_target); + return result; +} + OrphanablePtr ResolverRegistry::CreateResolver( const char* target, const grpc_channel_args* args, grpc_pollset_set* pollset_set, grpc_combiner* combiner, diff --git a/src/core/ext/filters/client_channel/resolver_registry.h b/src/core/ext/filters/client_channel/resolver_registry.h index 0eec6782609..4248a065439 100644 --- a/src/core/ext/filters/client_channel/resolver_registry.h +++ b/src/core/ext/filters/client_channel/resolver_registry.h @@ -50,6 +50,9 @@ class ResolverRegistry { static void RegisterResolverFactory(UniquePtr factory); }; + /// Checks whether the user input \a target is valid to create a resolver. + static bool IsValidTarget(const char* target); + /// Creates a resolver given \a target. /// First tries to parse \a target as a URI. If this succeeds, tries /// to locate a registered resolver factory based on the URI scheme.