blob: be515d26897aea7aa3d25eba7e15be39137fa7ad [file] [log] [blame]
Craig Tilleracf0f072015-06-29 08:24:16 -07001/*
2 *
3 * Copyright 2015, Google Inc.
4 * 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
34#include <grpc/support/port_platform.h>
35#ifdef GPR_POSIX_SOCKET
36
37#include "src/core/client_config/resolvers/unix_resolver_posix.h"
38
39#include <string.h>
40#include <sys/un.h>
41
42#include <grpc/support/alloc.h>
43#include <grpc/support/string_util.h>
44
45#include "src/core/client_config/lb_policies/pick_first.h"
46#include "src/core/iomgr/resolve_address.h"
47#include "src/core/support/string.h"
48
49typedef struct {
50 /** base class: must be first */
51 grpc_resolver base;
52 /** refcount */
53 gpr_refcount refs;
54 /** subchannel factory */
55 grpc_subchannel_factory *subchannel_factory;
56 /** load balancing policy factory */
57 grpc_lb_policy *(*lb_policy_factory)(grpc_subchannel **subchannels,
58 size_t num_subchannels);
59
60 /** the address that we've 'resolved' */
61 struct sockaddr_un addr;
62 int addr_len;
63
64 /** mutex guarding the rest of the state */
65 gpr_mu mu;
66 /** have we published? */
67 int published;
68 /** pending next completion, or NULL */
69 grpc_iomgr_closure *next_completion;
70 /** target config address for next completion */
71 grpc_client_config **target_config;
72} unix_resolver;
73
Craig Tiller98465032015-06-29 14:36:42 -070074static void unix_destroy(grpc_resolver *r);
Craig Tilleracf0f072015-06-29 08:24:16 -070075
76static void unix_maybe_finish_next_locked(unix_resolver *r);
77
Craig Tilleracf0f072015-06-29 08:24:16 -070078static void unix_shutdown(grpc_resolver *r);
79static void unix_channel_saw_error(grpc_resolver *r,
Craig Tiller4ab82d22015-06-29 09:40:33 -070080 struct sockaddr *failing_address,
81 int failing_address_len);
Craig Tilleracf0f072015-06-29 08:24:16 -070082static void unix_next(grpc_resolver *r, grpc_client_config **target_config,
Craig Tiller4ab82d22015-06-29 09:40:33 -070083 grpc_iomgr_closure *on_complete);
Craig Tilleracf0f072015-06-29 08:24:16 -070084
85static const grpc_resolver_vtable unix_resolver_vtable = {
Craig Tiller98465032015-06-29 14:36:42 -070086 unix_destroy, unix_shutdown, unix_channel_saw_error, unix_next};
Craig Tilleracf0f072015-06-29 08:24:16 -070087
88static void unix_shutdown(grpc_resolver *resolver) {
89 unix_resolver *r = (unix_resolver *)resolver;
90 gpr_mu_lock(&r->mu);
91 if (r->next_completion != NULL) {
92 *r->target_config = NULL;
93 /* TODO(ctiller): add delayed callback */
94 grpc_iomgr_add_callback(r->next_completion);
95 r->next_completion = NULL;
96 }
97 gpr_mu_unlock(&r->mu);
98}
99
100static void unix_channel_saw_error(grpc_resolver *resolver, struct sockaddr *sa,
Craig Tiller4ab82d22015-06-29 09:40:33 -0700101 int len) {}
Craig Tilleracf0f072015-06-29 08:24:16 -0700102
103static void unix_next(grpc_resolver *resolver,
Craig Tiller4ab82d22015-06-29 09:40:33 -0700104 grpc_client_config **target_config,
105 grpc_iomgr_closure *on_complete) {
Craig Tilleracf0f072015-06-29 08:24:16 -0700106 unix_resolver *r = (unix_resolver *)resolver;
107 gpr_mu_lock(&r->mu);
108 GPR_ASSERT(!r->next_completion);
109 r->next_completion = on_complete;
110 r->target_config = target_config;
111 unix_maybe_finish_next_locked(r);
112 gpr_mu_unlock(&r->mu);
113}
114
115static void unix_maybe_finish_next_locked(unix_resolver *r) {
116 grpc_client_config *cfg;
117 grpc_lb_policy *lb_policy;
118 grpc_subchannel *subchannel;
119 grpc_subchannel_args args;
120
121 if (r->next_completion != NULL && !r->published) {
122 cfg = grpc_client_config_create();
123 memset(&args, 0, sizeof(args));
Craig Tiller4ab82d22015-06-29 09:40:33 -0700124 args.addr = (struct sockaddr *)&r->addr;
Craig Tilleracf0f072015-06-29 08:24:16 -0700125 args.addr_len = r->addr_len;
Craig Tiller4ab82d22015-06-29 09:40:33 -0700126 subchannel =
127 grpc_subchannel_factory_create_subchannel(r->subchannel_factory, &args);
Craig Tilleracf0f072015-06-29 08:24:16 -0700128 lb_policy = r->lb_policy_factory(&subchannel, 1);
129 grpc_client_config_set_lb_policy(cfg, lb_policy);
130 GRPC_LB_POLICY_UNREF(lb_policy, "unix");
131 r->published = 1;
132 *r->target_config = cfg;
133 grpc_iomgr_add_callback(r->next_completion);
134 r->next_completion = NULL;
135 }
136}
137
Craig Tiller98465032015-06-29 14:36:42 -0700138static void unix_destroy(grpc_resolver *gr) {
Craig Tiller079a11b2015-06-30 10:07:15 -0700139 unix_resolver *r = (unix_resolver *)gr;
Craig Tilleracf0f072015-06-29 08:24:16 -0700140 gpr_mu_destroy(&r->mu);
141 grpc_subchannel_factory_unref(r->subchannel_factory);
142 gpr_free(r);
143}
144
145static grpc_resolver *unix_create(
146 grpc_uri *uri,
147 grpc_lb_policy *(*lb_policy_factory)(grpc_subchannel **subchannels,
148 size_t num_subchannels),
149 grpc_subchannel_factory *subchannel_factory) {
150 unix_resolver *r;
151
152 if (0 != strcmp(uri->authority, "")) {
153 gpr_log(GPR_ERROR, "authority based uri's not supported");
154 return NULL;
155 }
156
157 r = gpr_malloc(sizeof(unix_resolver));
158 memset(r, 0, sizeof(*r));
159 gpr_ref_init(&r->refs, 1);
160 gpr_mu_init(&r->mu);
Craig Tiller98465032015-06-29 14:36:42 -0700161 grpc_resolver_init(&r->base, &unix_resolver_vtable);
Craig Tilleracf0f072015-06-29 08:24:16 -0700162 r->subchannel_factory = subchannel_factory;
163 r->lb_policy_factory = lb_policy_factory;
164
165 r->addr.sun_family = AF_UNIX;
166 strcpy(r->addr.sun_path, uri->path);
167 r->addr_len = strlen(r->addr.sun_path) + sizeof(r->addr.sun_family) + 1;
168
169 grpc_subchannel_factory_ref(subchannel_factory);
170 return &r->base;
171}
172
173/*
174 * FACTORY
175 */
176
177static void unix_factory_ref(grpc_resolver_factory *factory) {}
178
179static void unix_factory_unref(grpc_resolver_factory *factory) {}
180
181static grpc_resolver *unix_factory_create_resolver(
182 grpc_resolver_factory *factory, grpc_uri *uri,
183 grpc_subchannel_factory *subchannel_factory) {
Craig Tiller4ab82d22015-06-29 09:40:33 -0700184 return unix_create(uri, grpc_create_pick_first_lb_policy, subchannel_factory);
Craig Tilleracf0f072015-06-29 08:24:16 -0700185}
186
187static const grpc_resolver_factory_vtable unix_factory_vtable = {
188 unix_factory_ref, unix_factory_unref, unix_factory_create_resolver};
189static grpc_resolver_factory unix_resolver_factory = {&unix_factory_vtable};
190
191grpc_resolver_factory *grpc_unix_resolver_factory_create() {
192 return &unix_resolver_factory;
193}
194
195#endif