1 /*
2 *
3 * Copyright 2015-2016 gRPC authors.
4 *
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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 */
18
19 #include <grpc/support/port_platform.h>
20
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "absl/strings/str_split.h"
27
28 #include <grpc/support/alloc.h>
29 #include <grpc/support/string_util.h>
30
31 #include "src/core/ext/filters/client_channel/resolver_registry.h"
32 #include "src/core/ext/filters/client_channel/server_address.h"
33 #include "src/core/lib/channel/channel_args.h"
34 #include "src/core/lib/gpr/string.h"
35 #include "src/core/lib/iomgr/parse_address.h"
36 #include "src/core/lib/iomgr/resolve_address.h"
37 #include "src/core/lib/iomgr/unix_sockets_posix.h"
38 #include "src/core/lib/slice/slice_internal.h"
39 #include "src/core/lib/slice/slice_string_helpers.h"
40
41 namespace grpc_core {
42
43 namespace {
44
45 class SockaddrResolver : public Resolver {
46 public:
47 SockaddrResolver(ServerAddressList addresses, ResolverArgs args);
48 ~SockaddrResolver() override;
49
50 void StartLocked() override;
51
ShutdownLocked()52 void ShutdownLocked() override {}
53
54 private:
55 std::unique_ptr<ResultHandler> result_handler_;
56 ServerAddressList addresses_;
57 const grpc_channel_args* channel_args_ = nullptr;
58 };
59
SockaddrResolver(ServerAddressList addresses,ResolverArgs args)60 SockaddrResolver::SockaddrResolver(ServerAddressList addresses,
61 ResolverArgs args)
62 : result_handler_(std::move(args.result_handler)),
63 addresses_(std::move(addresses)),
64 channel_args_(grpc_channel_args_copy(args.args)) {}
65
~SockaddrResolver()66 SockaddrResolver::~SockaddrResolver() {
67 grpc_channel_args_destroy(channel_args_);
68 }
69
StartLocked()70 void SockaddrResolver::StartLocked() {
71 Result result;
72 result.addresses = std::move(addresses_);
73 // TODO(roth): Use std::move() once channel args is converted to C++.
74 result.args = channel_args_;
75 channel_args_ = nullptr;
76 result_handler_->ReturnResult(std::move(result));
77 }
78
79 //
80 // Factory
81 //
82
ParseUri(const URI & uri,bool parse (const URI & uri,grpc_resolved_address * dst),ServerAddressList * addresses)83 bool ParseUri(const URI& uri,
84 bool parse(const URI& uri, grpc_resolved_address* dst),
85 ServerAddressList* addresses) {
86 if (!uri.authority().empty()) {
87 gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme",
88 uri.scheme().c_str());
89 return false;
90 }
91 // Construct addresses.
92 bool errors_found = false;
93 for (absl::string_view ith_path : absl::StrSplit(uri.path(), ',')) {
94 URI ith_uri(uri.scheme(), "", std::string(ith_path), {}, "");
95 grpc_resolved_address addr;
96 if (!parse(ith_uri, &addr)) {
97 errors_found = true;
98 break;
99 }
100 if (addresses != nullptr) {
101 addresses->emplace_back(addr, nullptr /* args */);
102 }
103 }
104 return !errors_found;
105 }
106
CreateSockaddrResolver(ResolverArgs args,bool parse (const URI & uri,grpc_resolved_address * dst))107 OrphanablePtr<Resolver> CreateSockaddrResolver(
108 ResolverArgs args, bool parse(const URI& uri, grpc_resolved_address* dst)) {
109 ServerAddressList addresses;
110 if (!ParseUri(args.uri, parse, &addresses)) return nullptr;
111 // Instantiate resolver.
112 return MakeOrphanable<SockaddrResolver>(std::move(addresses),
113 std::move(args));
114 }
115
116 class IPv4ResolverFactory : public ResolverFactory {
117 public:
IsValidUri(const URI & uri) const118 bool IsValidUri(const URI& uri) const override {
119 return ParseUri(uri, grpc_parse_ipv4, nullptr);
120 }
121
CreateResolver(ResolverArgs args) const122 OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
123 return CreateSockaddrResolver(std::move(args), grpc_parse_ipv4);
124 }
125
scheme() const126 const char* scheme() const override { return "ipv4"; }
127 };
128
129 class IPv6ResolverFactory : public ResolverFactory {
130 public:
IsValidUri(const URI & uri) const131 bool IsValidUri(const URI& uri) const override {
132 return ParseUri(uri, grpc_parse_ipv6, nullptr);
133 }
134
CreateResolver(ResolverArgs args) const135 OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
136 return CreateSockaddrResolver(std::move(args), grpc_parse_ipv6);
137 }
138
scheme() const139 const char* scheme() const override { return "ipv6"; }
140 };
141
142 #ifdef GRPC_HAVE_UNIX_SOCKET
143 class UnixResolverFactory : public ResolverFactory {
144 public:
IsValidUri(const URI & uri) const145 bool IsValidUri(const URI& uri) const override {
146 return ParseUri(uri, grpc_parse_unix, nullptr);
147 }
148
CreateResolver(ResolverArgs args) const149 OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
150 return CreateSockaddrResolver(std::move(args), grpc_parse_unix);
151 }
152
GetDefaultAuthority(const URI &) const153 std::string GetDefaultAuthority(const URI& /*uri*/) const override {
154 return "localhost";
155 }
156
scheme() const157 const char* scheme() const override { return "unix"; }
158 };
159
160 class UnixAbstractResolverFactory : public ResolverFactory {
161 public:
IsValidUri(const URI & uri) const162 bool IsValidUri(const URI& uri) const override {
163 return ParseUri(uri, grpc_parse_unix_abstract, nullptr);
164 }
165
CreateResolver(ResolverArgs args) const166 OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
167 return CreateSockaddrResolver(std::move(args), grpc_parse_unix_abstract);
168 }
169
GetDefaultAuthority(const URI &) const170 std::string GetDefaultAuthority(const URI& /*uri*/) const override {
171 return "localhost";
172 }
173
scheme() const174 const char* scheme() const override { return "unix-abstract"; }
175 };
176 #endif // GRPC_HAVE_UNIX_SOCKET
177
178 } // namespace
179
180 } // namespace grpc_core
181
grpc_resolver_sockaddr_init()182 void grpc_resolver_sockaddr_init() {
183 grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
184 absl::make_unique<grpc_core::IPv4ResolverFactory>());
185 grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
186 absl::make_unique<grpc_core::IPv6ResolverFactory>());
187 #ifdef GRPC_HAVE_UNIX_SOCKET
188 grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
189 absl::make_unique<grpc_core::UnixResolverFactory>());
190 grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
191 absl::make_unique<grpc_core::UnixAbstractResolverFactory>());
192 #endif
193 }
194
grpc_resolver_sockaddr_shutdown()195 void grpc_resolver_sockaddr_shutdown() {}
196