• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include <grpc/support/port_platform.h>
18 
19 #include <algorithm>
20 #include <memory>
21 #include <string>
22 #include <utility>
23 
24 #include "absl/log/log.h"
25 #include "absl/status/statusor.h"
26 #include "absl/strings/str_split.h"
27 #include "absl/strings/string_view.h"
28 #include "src/core/config/core_configuration.h"
29 #include "src/core/lib/address_utils/parse_address.h"
30 #include "src/core/lib/channel/channel_args.h"
31 #include "src/core/lib/iomgr/port.h"
32 #include "src/core/lib/iomgr/resolved_address.h"
33 #include "src/core/resolver/endpoint_addresses.h"
34 #include "src/core/resolver/resolver.h"
35 #include "src/core/resolver/resolver_factory.h"
36 #include "src/core/util/orphanable.h"
37 #include "src/core/util/uri.h"
38 
39 namespace grpc_core {
40 
41 namespace {
42 
43 class SockaddrResolver final : public Resolver {
44  public:
45   SockaddrResolver(EndpointAddressesList addresses, ResolverArgs args);
46 
47   void StartLocked() override;
48 
ShutdownLocked()49   void ShutdownLocked() override {}
50 
51  private:
52   std::unique_ptr<ResultHandler> result_handler_;
53   EndpointAddressesList addresses_;
54   ChannelArgs channel_args_;
55 };
56 
SockaddrResolver(EndpointAddressesList addresses,ResolverArgs args)57 SockaddrResolver::SockaddrResolver(EndpointAddressesList addresses,
58                                    ResolverArgs args)
59     : result_handler_(std::move(args.result_handler)),
60       addresses_(std::move(addresses)),
61       channel_args_(std::move(args.args)) {}
62 
StartLocked()63 void SockaddrResolver::StartLocked() {
64   Result result;
65   result.addresses = std::move(addresses_);
66   result.args = std::move(channel_args_);
67   result_handler_->ReportResult(std::move(result));
68 }
69 
70 //
71 // Factory
72 //
73 
ParseUri(const URI & uri,bool parse (const URI & uri,grpc_resolved_address * dst),EndpointAddressesList * addresses)74 bool ParseUri(const URI& uri,
75               bool parse(const URI& uri, grpc_resolved_address* dst),
76               EndpointAddressesList* addresses) {
77   if (!uri.authority().empty()) {
78     LOG(ERROR) << "authority-based URIs not supported by the " << uri.scheme()
79                << " scheme";
80     return false;
81   }
82   // Construct addresses.
83   bool errors_found = false;
84   for (absl::string_view ith_path : absl::StrSplit(uri.path(), ',')) {
85     if (ith_path.empty()) {
86       // Skip targets which are empty.
87       continue;
88     }
89     auto ith_uri = URI::Create(uri.scheme(), "", std::string(ith_path), {}, "");
90     grpc_resolved_address addr;
91     if (!ith_uri.ok() || !parse(*ith_uri, &addr)) {
92       errors_found = true;
93       break;
94     }
95     if (addresses != nullptr) {
96       addresses->emplace_back(addr, ChannelArgs());
97     }
98   }
99   return !errors_found;
100 }
101 
CreateSockaddrResolver(ResolverArgs args,bool parse (const URI & uri,grpc_resolved_address * dst))102 OrphanablePtr<Resolver> CreateSockaddrResolver(
103     ResolverArgs args, bool parse(const URI& uri, grpc_resolved_address* dst)) {
104   EndpointAddressesList addresses;
105   if (!ParseUri(args.uri, parse, &addresses)) return nullptr;
106   // Instantiate resolver.
107   return MakeOrphanable<SockaddrResolver>(std::move(addresses),
108                                           std::move(args));
109 }
110 
111 class IPv4ResolverFactory final : public ResolverFactory {
112  public:
scheme() const113   absl::string_view scheme() const override { return "ipv4"; }
114 
IsValidUri(const URI & uri) const115   bool IsValidUri(const URI& uri) const override {
116     return ParseUri(uri, grpc_parse_ipv4, nullptr);
117   }
118 
CreateResolver(ResolverArgs args) const119   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
120     return CreateSockaddrResolver(std::move(args), grpc_parse_ipv4);
121   }
122 };
123 
124 class IPv6ResolverFactory final : public ResolverFactory {
125  public:
scheme() const126   absl::string_view scheme() const override { return "ipv6"; }
127 
IsValidUri(const URI & uri) const128   bool IsValidUri(const URI& uri) const override {
129     return ParseUri(uri, grpc_parse_ipv6, nullptr);
130   }
131 
CreateResolver(ResolverArgs args) const132   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
133     return CreateSockaddrResolver(std::move(args), grpc_parse_ipv6);
134   }
135 };
136 
137 #ifdef GRPC_HAVE_UNIX_SOCKET
138 class UnixResolverFactory final : public ResolverFactory {
139  public:
scheme() const140   absl::string_view scheme() const override { return "unix"; }
141 
IsValidUri(const URI & uri) const142   bool IsValidUri(const URI& uri) const override {
143     return ParseUri(uri, grpc_parse_unix, nullptr);
144   }
145 
CreateResolver(ResolverArgs args) const146   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
147     return CreateSockaddrResolver(std::move(args), grpc_parse_unix);
148   }
149 };
150 
151 class UnixAbstractResolverFactory final : public ResolverFactory {
152  public:
scheme() const153   absl::string_view scheme() const override { return "unix-abstract"; }
154 
IsValidUri(const URI & uri) const155   bool IsValidUri(const URI& uri) const override {
156     return ParseUri(uri, grpc_parse_unix_abstract, nullptr);
157   }
158 
CreateResolver(ResolverArgs args) const159   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
160     return CreateSockaddrResolver(std::move(args), grpc_parse_unix_abstract);
161   }
162 };
163 #endif  // GRPC_HAVE_UNIX_SOCKET
164 
165 #ifdef GRPC_HAVE_VSOCK
166 class VSockResolverFactory final : public ResolverFactory {
167  public:
scheme() const168   absl::string_view scheme() const override { return "vsock"; }
169 
IsValidUri(const URI & uri) const170   bool IsValidUri(const URI& uri) const override {
171     return ParseUri(uri, grpc_parse_vsock, nullptr);
172   }
173 
CreateResolver(ResolverArgs args) const174   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
175     return CreateSockaddrResolver(std::move(args), grpc_parse_vsock);
176   }
177 };
178 
179 #endif  // GRPC_HAVE_VSOCK
180 
181 }  // namespace
182 
RegisterSockaddrResolver(CoreConfiguration::Builder * builder)183 void RegisterSockaddrResolver(CoreConfiguration::Builder* builder) {
184   builder->resolver_registry()->RegisterResolverFactory(
185       std::make_unique<IPv4ResolverFactory>());
186   builder->resolver_registry()->RegisterResolverFactory(
187       std::make_unique<IPv6ResolverFactory>());
188 #ifdef GRPC_HAVE_UNIX_SOCKET
189   builder->resolver_registry()->RegisterResolverFactory(
190       std::make_unique<UnixResolverFactory>());
191   builder->resolver_registry()->RegisterResolverFactory(
192       std::make_unique<UnixAbstractResolverFactory>());
193 #endif
194 #ifdef GRPC_HAVE_VSOCK
195   builder->resolver_registry()->RegisterResolverFactory(
196       std::make_unique<VSockResolverFactory>());
197 #endif
198 }
199 
200 }  // namespace grpc_core
201