blob: e7f66649b5d406fbcb702fbd7537b933f17f0432 [file] [log] [blame]
Craig Tiller698d00c2015-07-20 12:32:58 -07001/*
2 *
Craig Tillerd4c98332016-03-31 13:45:47 -07003 * Copyright 2015-2016, Google Inc.
Craig Tiller698d00c2015-07-20 12:32:58 -07004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
David Garcia Quintas64ddf132016-03-30 23:53:50 -070034#include <stdbool.h>
Craig Tiller698d00c2015-07-20 12:32:58 -070035#include <stdio.h>
Mark D. Roth72d0b162016-09-30 09:49:50 -070036#include <stdlib.h>
Craig Tiller698d00c2015-07-20 12:32:58 -070037#include <string.h>
Craig Tiller698d00c2015-07-20 12:32:58 -070038
39#include <grpc/support/alloc.h>
40#include <grpc/support/host_port.h>
David Garcia Quintasf47240e2016-04-04 13:51:29 -070041#include <grpc/support/port_platform.h>
Craig Tiller698d00c2015-07-20 12:32:58 -070042#include <grpc/support/string_util.h>
43
Mark D. Rothae07f7f2016-10-21 15:23:53 -070044#include "src/core/ext/client_channel/lb_policy_factory.h"
Mark D. Roth2137cd82016-09-14 09:04:00 -070045#include "src/core/ext/client_channel/parse_address.h"
46#include "src/core/ext/client_channel/resolver_registry.h"
Mark D. Roth72d0b162016-09-30 09:49:50 -070047#include "src/core/lib/channel/channel_args.h"
Craig Tiller972470b2017-02-09 15:05:36 -080048#include "src/core/lib/iomgr/combiner.h"
Craig Tiller9533d042016-03-25 17:11:06 -070049#include "src/core/lib/iomgr/resolve_address.h"
50#include "src/core/lib/iomgr/unix_sockets_posix.h"
Craig Tillera59c16c2016-10-31 07:25:01 -070051#include "src/core/lib/slice/slice_internal.h"
Craig Tiller0f310802016-10-26 16:25:56 -070052#include "src/core/lib/slice/slice_string_helpers.h"
Craig Tiller9533d042016-03-25 17:11:06 -070053#include "src/core/lib/support/string.h"
Craig Tiller698d00c2015-07-20 12:32:58 -070054
Craig Tillera82950e2015-09-22 12:33:20 -070055typedef struct {
Craig Tiller698d00c2015-07-20 12:32:58 -070056 /** base class: must be first */
57 grpc_resolver base;
David Garcia Quintas2bfd2752015-08-20 11:42:29 -070058 /** the addresses that we've 'resolved' */
Mark D. Rothc5c38782016-09-16 08:51:01 -070059 grpc_lb_addresses *addresses;
Mark D. Roth98abfd32016-10-21 08:10:51 -070060 /** channel args */
61 grpc_channel_args *channel_args;
Craig Tiller698d00c2015-07-20 12:32:58 -070062 /** have we published? */
Mark D. Rothf655c852016-09-06 10:40:38 -070063 bool published;
Craig Tiller698d00c2015-07-20 12:32:58 -070064 /** pending next completion, or NULL */
Craig Tiller33825112015-09-18 07:44:19 -070065 grpc_closure *next_completion;
Mark D. Rothff4df062016-08-22 15:02:49 -070066 /** target result address for next completion */
Mark D. Rothaf842452016-10-21 15:05:15 -070067 grpc_channel_args **target_result;
Craig Tiller698d00c2015-07-20 12:32:58 -070068} sockaddr_resolver;
69
Craig Tillera82950e2015-09-22 12:33:20 -070070static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
Craig Tiller698d00c2015-07-20 12:32:58 -070071
Craig Tillera82950e2015-09-22 12:33:20 -070072static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
73 sockaddr_resolver *r);
Craig Tiller698d00c2015-07-20 12:32:58 -070074
Craig Tiller972470b2017-02-09 15:05:36 -080075static void sockaddr_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
76static void sockaddr_channel_saw_error_locked(grpc_exec_ctx *exec_ctx,
77 grpc_resolver *r);
78static void sockaddr_next_locked(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
79 grpc_channel_args **target_result,
80 grpc_closure *on_complete);
Craig Tiller698d00c2015-07-20 12:32:58 -070081
82static const grpc_resolver_vtable sockaddr_resolver_vtable = {
Craig Tiller972470b2017-02-09 15:05:36 -080083 sockaddr_destroy, sockaddr_shutdown_locked,
84 sockaddr_channel_saw_error_locked, sockaddr_next_locked};
Craig Tiller698d00c2015-07-20 12:32:58 -070085
Craig Tiller972470b2017-02-09 15:05:36 -080086static void sockaddr_shutdown_locked(grpc_exec_ctx *exec_ctx,
87 grpc_resolver *resolver) {
Craig Tillera82950e2015-09-22 12:33:20 -070088 sockaddr_resolver *r = (sockaddr_resolver *)resolver;
Craig Tillera82950e2015-09-22 12:33:20 -070089 if (r->next_completion != NULL) {
Mark D. Rothff4df062016-08-22 15:02:49 -070090 *r->target_result = NULL;
Craig Tiller91031da2016-12-28 15:44:25 -080091 grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
Craig Tillera82950e2015-09-22 12:33:20 -070092 r->next_completion = NULL;
93 }
Craig Tiller698d00c2015-07-20 12:32:58 -070094}
95
Craig Tiller972470b2017-02-09 15:05:36 -080096static void sockaddr_channel_saw_error_locked(grpc_exec_ctx *exec_ctx,
97 grpc_resolver *resolver) {
Craig Tiller486ea352015-11-24 16:58:41 -080098 sockaddr_resolver *r = (sockaddr_resolver *)resolver;
Mark D. Rothf655c852016-09-06 10:40:38 -070099 r->published = false;
Craig Tiller486ea352015-11-24 16:58:41 -0800100 sockaddr_maybe_finish_next_locked(exec_ctx, r);
Craig Tiller486ea352015-11-24 16:58:41 -0800101}
Craig Tiller698d00c2015-07-20 12:32:58 -0700102
Craig Tiller972470b2017-02-09 15:05:36 -0800103static void sockaddr_next_locked(grpc_exec_ctx *exec_ctx,
104 grpc_resolver *resolver,
105 grpc_channel_args **target_result,
106 grpc_closure *on_complete) {
Craig Tillera82950e2015-09-22 12:33:20 -0700107 sockaddr_resolver *r = (sockaddr_resolver *)resolver;
Craig Tillera82950e2015-09-22 12:33:20 -0700108 GPR_ASSERT(!r->next_completion);
Craig Tiller698d00c2015-07-20 12:32:58 -0700109 r->next_completion = on_complete;
Mark D. Rothff4df062016-08-22 15:02:49 -0700110 r->target_result = target_result;
Craig Tillera82950e2015-09-22 12:33:20 -0700111 sockaddr_maybe_finish_next_locked(exec_ctx, r);
Craig Tiller698d00c2015-07-20 12:32:58 -0700112}
113
Craig Tillera82950e2015-09-22 12:33:20 -0700114static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
115 sockaddr_resolver *r) {
Craig Tillera82950e2015-09-22 12:33:20 -0700116 if (r->next_completion != NULL && !r->published) {
Mark D. Rothf655c852016-09-06 10:40:38 -0700117 r->published = true;
Mark D. Roth36869962016-10-21 10:43:45 -0700118 grpc_arg arg = grpc_lb_addresses_create_channel_arg(r->addresses);
Mark D. Rothaf842452016-10-21 15:05:15 -0700119 *r->target_result =
Mark D. Roth36869962016-10-21 10:43:45 -0700120 grpc_channel_args_copy_and_add(r->channel_args, &arg, 1);
Craig Tiller91031da2016-12-28 15:44:25 -0800121 grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
Craig Tillera82950e2015-09-22 12:33:20 -0700122 r->next_completion = NULL;
123 }
Craig Tiller698d00c2015-07-20 12:32:58 -0700124}
125
Craig Tillera82950e2015-09-22 12:33:20 -0700126static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
127 sockaddr_resolver *r = (sockaddr_resolver *)gr;
Craig Tiller87a7e1f2016-11-09 09:42:19 -0800128 grpc_lb_addresses_destroy(exec_ctx, r->addresses);
129 grpc_channel_args_destroy(exec_ctx, r->channel_args);
Craig Tillera82950e2015-09-22 12:33:20 -0700130 gpr_free(r);
Craig Tiller698d00c2015-07-20 12:32:58 -0700131}
132
Craig Tillera82950e2015-09-22 12:33:20 -0700133static char *ip_get_default_authority(grpc_uri *uri) {
Craig Tillerbc85be12015-08-24 10:36:39 -0700134 const char *path = uri->path;
Craig Tillera82950e2015-09-22 12:33:20 -0700135 if (path[0] == '/') ++path;
136 return gpr_strdup(path);
Craig Tillerbc85be12015-08-24 10:36:39 -0700137}
138
Craig Tillera82950e2015-09-22 12:33:20 -0700139static char *ipv4_get_default_authority(grpc_resolver_factory *factory,
140 grpc_uri *uri) {
141 return ip_get_default_authority(uri);
Craig Tillerbc85be12015-08-24 10:36:39 -0700142}
143
Craig Tillera82950e2015-09-22 12:33:20 -0700144static char *ipv6_get_default_authority(grpc_resolver_factory *factory,
145 grpc_uri *uri) {
146 return ip_get_default_authority(uri);
Craig Tillerbc85be12015-08-24 10:36:39 -0700147}
148
murgatroid99623dd4f2016-08-08 17:31:27 -0700149#ifdef GRPC_HAVE_UNIX_SOCKET
Craig Tillerf82ddc42016-04-05 17:15:07 -0700150char *unix_get_default_authority(grpc_resolver_factory *factory,
151 grpc_uri *uri) {
152 return gpr_strdup("localhost");
153}
154#endif
155
Craig Tillera82950e2015-09-22 12:33:20 -0700156static void do_nothing(void *ignored) {}
Craig Tiller45724b32015-09-22 10:42:19 -0700157
Craig Tillera59c16c2016-10-31 07:25:01 -0700158static grpc_resolver *sockaddr_create(grpc_exec_ctx *exec_ctx,
159 grpc_resolver_args *args,
Mark D. Roth07aab592016-10-04 10:02:00 -0700160 int parse(grpc_uri *uri,
murgatroid99dedb9232016-09-26 13:54:04 -0700161 grpc_resolved_address *dst)) {
Craig Tillera82950e2015-09-22 12:33:20 -0700162 if (0 != strcmp(args->uri->authority, "")) {
163 gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
164 args->uri->scheme);
165 return NULL;
166 }
Mark D. Rothb34b0552016-10-03 13:34:55 -0700167 /* Construct addresses. */
Craig Tillerd41a4a72016-10-26 16:16:06 -0700168 grpc_slice path_slice =
169 grpc_slice_new(args->uri->path, strlen(args->uri->path), do_nothing);
170 grpc_slice_buffer path_parts;
171 grpc_slice_buffer_init(&path_parts);
172 grpc_slice_split(path_slice, ",", &path_parts);
Mark D. Roth557c9902016-10-24 11:12:05 -0700173 grpc_lb_addresses *addresses =
174 grpc_lb_addresses_create(path_parts.count, NULL /* user_data_vtable */);
Mark D. Rothb34b0552016-10-03 13:34:55 -0700175 bool errors_found = false;
176 for (size_t i = 0; i < addresses->num_addresses; i++) {
Craig Tillera82950e2015-09-22 12:33:20 -0700177 grpc_uri ith_uri = *args->uri;
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800178 char *part_str = grpc_slice_to_c_string(path_parts.slices[i]);
Craig Tillera82950e2015-09-22 12:33:20 -0700179 ith_uri.path = part_str;
murgatroid99fde76d72016-10-07 15:09:53 -0700180 if (!parse(&ith_uri, &addresses->addresses[i].address)) {
murgatroid9908b0fab2016-09-23 14:35:49 -0700181 errors_found = true; /* GPR_TRUE */
David Garcia Quintas2bfd2752015-08-20 11:42:29 -0700182 }
Craig Tillera82950e2015-09-22 12:33:20 -0700183 gpr_free(part_str);
184 if (errors_found) break;
185 }
Craig Tillera59c16c2016-10-31 07:25:01 -0700186 grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
187 grpc_slice_unref_internal(exec_ctx, path_slice);
Craig Tillera82950e2015-09-22 12:33:20 -0700188 if (errors_found) {
Craig Tiller87a7e1f2016-11-09 09:42:19 -0800189 grpc_lb_addresses_destroy(exec_ctx, addresses);
Craig Tillera82950e2015-09-22 12:33:20 -0700190 return NULL;
191 }
Mark D. Rothb34b0552016-10-03 13:34:55 -0700192 /* Instantiate resolver. */
193 sockaddr_resolver *r = gpr_malloc(sizeof(sockaddr_resolver));
194 memset(r, 0, sizeof(*r));
Mark D. Rothb34b0552016-10-03 13:34:55 -0700195 r->addresses = addresses;
Mark D. Roth201db7d2016-12-12 09:36:02 -0800196 r->channel_args = grpc_channel_args_copy(args->args);
Craig Tiller0bfad142017-02-17 16:01:08 -0800197 grpc_resolver_init(&r->base, &sockaddr_resolver_vtable, args->combiner);
Craig Tiller698d00c2015-07-20 12:32:58 -0700198 return &r->base;
199}
200
201/*
202 * FACTORY
203 */
204
Craig Tillera82950e2015-09-22 12:33:20 -0700205static void sockaddr_factory_ref(grpc_resolver_factory *factory) {}
Craig Tiller698d00c2015-07-20 12:32:58 -0700206
Craig Tillera82950e2015-09-22 12:33:20 -0700207static void sockaddr_factory_unref(grpc_resolver_factory *factory) {}
Craig Tiller698d00c2015-07-20 12:32:58 -0700208
Craig Tillerf82ddc42016-04-05 17:15:07 -0700209#define DECL_FACTORY(name) \
Craig Tillerbc85be12015-08-24 10:36:39 -0700210 static grpc_resolver *name##_factory_create_resolver( \
Craig Tillera59c16c2016-10-31 07:25:01 -0700211 grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory, \
212 grpc_resolver_args *args) { \
213 return sockaddr_create(exec_ctx, args, parse_##name); \
Craig Tillerbc85be12015-08-24 10:36:39 -0700214 } \
215 static const grpc_resolver_factory_vtable name##_factory_vtable = { \
216 sockaddr_factory_ref, sockaddr_factory_unref, \
Craig Tillerf82ddc42016-04-05 17:15:07 -0700217 name##_factory_create_resolver, name##_get_default_authority, #name}; \
Craig Tillerbc85be12015-08-24 10:36:39 -0700218 static grpc_resolver_factory name##_resolver_factory = { \
Craig Tiller65938df2016-03-31 13:08:49 -0700219 &name##_factory_vtable}
Craig Tiller698d00c2015-07-20 12:32:58 -0700220
murgatroid99623dd4f2016-08-08 17:31:27 -0700221#ifdef GRPC_HAVE_UNIX_SOCKET
Craig Tillerf82ddc42016-04-05 17:15:07 -0700222DECL_FACTORY(unix);
Craig Tiller698d00c2015-07-20 12:32:58 -0700223#endif
Craig Tillerf82ddc42016-04-05 17:15:07 -0700224DECL_FACTORY(ipv4);
225DECL_FACTORY(ipv6);
Craig Tiller65938df2016-03-31 13:08:49 -0700226
227void grpc_resolver_sockaddr_init(void) {
228 grpc_register_resolver_type(&ipv4_resolver_factory);
229 grpc_register_resolver_type(&ipv6_resolver_factory);
murgatroid99623dd4f2016-08-08 17:31:27 -0700230#ifdef GRPC_HAVE_UNIX_SOCKET
Craig Tiller65938df2016-03-31 13:08:49 -0700231 grpc_register_resolver_type(&unix_resolver_factory);
232#endif
233}
234
235void grpc_resolver_sockaddr_shutdown(void) {}