3 * Copyright 2015-2016 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>
26 #include <grpc/support/alloc.h>
27 #include <grpc/support/string_util.h>
29 #include "src/core/ext/filters/client_channel/parse_address.h"
30 #include "src/core/ext/filters/client_channel/resolver_registry.h"
31 #include "src/core/ext/filters/client_channel/server_address.h"
32 #include "src/core/lib/channel/channel_args.h"
33 #include "src/core/lib/gpr/string.h"
34 #include "src/core/lib/iomgr/combiner.h"
35 #include "src/core/lib/iomgr/resolve_address.h"
36 #include "src/core/lib/iomgr/unix_sockets_posix.h"
37 #include "src/core/lib/slice/slice_internal.h"
38 #include "src/core/lib/slice/slice_string_helpers.h"
44 class SockaddrResolver : public Resolver {
46 SockaddrResolver(ServerAddressList addresses, ResolverArgs args);
47 ~SockaddrResolver() override;
49 void StartLocked() override;
51 void ShutdownLocked() override {}
54 ServerAddressList addresses_;
55 const grpc_channel_args* channel_args_ = nullptr;
58 SockaddrResolver::SockaddrResolver(ServerAddressList addresses,
60 : Resolver(args.combiner, std::move(args.result_handler)),
61 addresses_(std::move(addresses)),
62 channel_args_(grpc_channel_args_copy(args.args)) {}
64 SockaddrResolver::~SockaddrResolver() {
65 grpc_channel_args_destroy(channel_args_);
68 void SockaddrResolver::StartLocked() {
70 result.addresses = std::move(addresses_);
71 // TODO(roth): Use std::move() once channel args is converted to C++.
72 result.args = channel_args_;
73 channel_args_ = nullptr;
74 result_handler()->ReturnResult(std::move(result));
81 void DoNothing(void* ignored) {}
83 bool ParseUri(const grpc_uri* uri,
84 bool parse(const grpc_uri* uri, grpc_resolved_address* dst),
85 ServerAddressList* addresses) {
86 if (0 != strcmp(uri->authority, "")) {
87 gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme",
91 // Construct addresses.
92 grpc_slice path_slice =
93 grpc_slice_new(uri->path, strlen(uri->path), DoNothing);
94 grpc_slice_buffer path_parts;
95 grpc_slice_buffer_init(&path_parts);
96 grpc_slice_split(path_slice, ",", &path_parts);
97 bool errors_found = false;
98 for (size_t i = 0; i < path_parts.count; i++) {
99 grpc_uri ith_uri = *uri;
100 UniquePtr<char> part_str(grpc_slice_to_c_string(path_parts.slices[i]));
101 ith_uri.path = part_str.get();
102 grpc_resolved_address addr;
103 if (!parse(&ith_uri, &addr)) {
107 if (addresses != nullptr) {
108 addresses->emplace_back(addr, nullptr /* args */);
111 grpc_slice_buffer_destroy_internal(&path_parts);
112 grpc_slice_unref_internal(path_slice);
113 return !errors_found;
116 OrphanablePtr<Resolver> CreateSockaddrResolver(
118 bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) {
119 ServerAddressList addresses;
120 if (!ParseUri(args.uri, parse, &addresses)) return nullptr;
121 // Instantiate resolver.
122 return OrphanablePtr<Resolver>(
123 New<SockaddrResolver>(std::move(addresses), std::move(args)));
126 class IPv4ResolverFactory : public ResolverFactory {
128 bool IsValidUri(const grpc_uri* uri) const override {
129 return ParseUri(uri, grpc_parse_ipv4, nullptr);
132 OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
133 return CreateSockaddrResolver(std::move(args), grpc_parse_ipv4);
136 const char* scheme() const override { return "ipv4"; }
139 class IPv6ResolverFactory : public ResolverFactory {
141 bool IsValidUri(const grpc_uri* uri) const override {
142 return ParseUri(uri, grpc_parse_ipv6, nullptr);
145 OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
146 return CreateSockaddrResolver(std::move(args), grpc_parse_ipv6);
149 const char* scheme() const override { return "ipv6"; }
152 #ifdef GRPC_HAVE_UNIX_SOCKET
153 class UnixResolverFactory : public ResolverFactory {
155 bool IsValidUri(const grpc_uri* uri) const override {
156 return ParseUri(uri, grpc_parse_unix, nullptr);
159 OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
160 return CreateSockaddrResolver(std::move(args), grpc_parse_unix);
163 UniquePtr<char> GetDefaultAuthority(grpc_uri* uri) const override {
164 return UniquePtr<char>(gpr_strdup("localhost"));
167 const char* scheme() const override { return "unix"; }
169 #endif // GRPC_HAVE_UNIX_SOCKET
173 } // namespace grpc_core
175 void grpc_resolver_sockaddr_init() {
176 grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
177 grpc_core::UniquePtr<grpc_core::ResolverFactory>(
178 grpc_core::New<grpc_core::IPv4ResolverFactory>()));
179 grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
180 grpc_core::UniquePtr<grpc_core::ResolverFactory>(
181 grpc_core::New<grpc_core::IPv6ResolverFactory>()));
182 #ifdef GRPC_HAVE_UNIX_SOCKET
183 grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
184 grpc_core::UniquePtr<grpc_core::ResolverFactory>(
185 grpc_core::New<grpc_core::UnixResolverFactory>()));
189 void grpc_resolver_sockaddr_shutdown() {}