blob: 0ed115793b078e9217ef16a60658f4b1611fc081 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * 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/grpc.h>
35
36#include <stdlib.h>
37#include <string.h>
38
Craig Tiller91624662015-06-25 16:31:02 -070039#include <grpc/support/alloc.h>
yang-g074c6fc2015-11-05 23:14:07 -080040#include <grpc/support/slice.h>
41#include <grpc/support/slice_buffer.h>
Craig Tiller91624662015-06-25 16:31:02 -070042
Craig Tiller4a6dad32016-04-01 13:51:14 -070043#include "src/core/ext/client_config/client_channel.h"
44#include "src/core/ext/client_config/resolver_registry.h"
Craig Tillerd0bcc432016-03-31 14:30:51 -070045#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
Craig Tiller9533d042016-03-25 17:11:06 -070046#include "src/core/lib/channel/channel_args.h"
Craig Tiller9533d042016-03-25 17:11:06 -070047#include "src/core/lib/channel/compress_filter.h"
48#include "src/core/lib/channel/http_client_filter.h"
Craig Tiller9533d042016-03-25 17:11:06 -070049#include "src/core/lib/iomgr/tcp_client.h"
50#include "src/core/lib/surface/api_trace.h"
51#include "src/core/lib/surface/channel.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080052
Craig Tillera82950e2015-09-22 12:33:20 -070053typedef struct {
Craig Tiller91624662015-06-25 16:31:02 -070054 grpc_connector base;
55 gpr_refcount refs;
Craig Tiller5f84c842015-06-26 16:08:21 -070056
Craig Tiller33825112015-09-18 07:44:19 -070057 grpc_closure *notify;
Craig Tiller04c5d4b2015-06-26 17:21:41 -070058 grpc_connect_in_args args;
59 grpc_connect_out_args *result;
yang-g074c6fc2015-11-05 23:14:07 -080060 grpc_closure initial_string_sent;
61 gpr_slice_buffer initial_string_buffer;
Craig Tillerdfff1b82015-09-21 14:39:57 -070062
63 grpc_endpoint *tcp;
64
Craig Tillerdfff1b82015-09-21 14:39:57 -070065 grpc_closure connected;
Craig Tiller91624662015-06-25 16:31:02 -070066} connector;
67
Craig Tillera82950e2015-09-22 12:33:20 -070068static void connector_ref(grpc_connector *con) {
69 connector *c = (connector *)con;
70 gpr_ref(&c->refs);
Craig Tiller91624662015-06-25 16:31:02 -070071}
72
Craig Tillera82950e2015-09-22 12:33:20 -070073static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
74 connector *c = (connector *)con;
75 if (gpr_unref(&c->refs)) {
yang-g074c6fc2015-11-05 23:14:07 -080076 /* c->initial_string_buffer does not need to be destroyed */
Craig Tillera82950e2015-09-22 12:33:20 -070077 gpr_free(c);
78 }
Craig Tiller91624662015-06-25 16:31:02 -070079}
80
yang-gf8843fb2015-11-21 12:33:22 -080081static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
Craig Tiller6c396862016-01-28 13:53:40 -080082 bool success) {
yang-gf8843fb2015-11-21 12:33:22 -080083 connector_unref(exec_ctx, arg);
84}
yang-g074c6fc2015-11-05 23:14:07 -080085
Craig Tiller6c396862016-01-28 13:53:40 -080086static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
Craig Tiller5f84c842015-06-26 16:08:21 -070087 connector *c = arg;
Craig Tiller33825112015-09-18 07:44:19 -070088 grpc_closure *notify;
Craig Tillerdfff1b82015-09-21 14:39:57 -070089 grpc_endpoint *tcp = c->tcp;
Craig Tillera82950e2015-09-22 12:33:20 -070090 if (tcp != NULL) {
yang-g074c6fc2015-11-05 23:14:07 -080091 if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
yang-gf8843fb2015-11-21 12:33:22 -080092 grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
93 c);
yang-g074c6fc2015-11-05 23:14:07 -080094 gpr_slice_buffer_init(&c->initial_string_buffer);
95 gpr_slice_buffer_add(&c->initial_string_buffer,
96 c->args.initial_connect_string);
yang-gf8843fb2015-11-21 12:33:22 -080097 connector_ref(arg);
yang-g074c6fc2015-11-05 23:14:07 -080098 grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
99 &c->initial_string_sent);
100 }
Craig Tillerb2b42612015-11-20 12:02:17 -0800101 c->result->transport =
102 grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1);
Craig Tillera82950e2015-09-22 12:33:20 -0700103 grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
104 0);
105 GPR_ASSERT(c->result->transport);
Julien Boeuf5b194032015-12-17 16:00:51 -0800106 c->result->channel_args = c->args.channel_args;
Craig Tillera82950e2015-09-22 12:33:20 -0700107 } else {
108 memset(c->result, 0, sizeof(*c->result));
109 }
Craig Tiller5f84c842015-06-26 16:08:21 -0700110 notify = c->notify;
111 c->notify = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700112 notify->cb(exec_ctx, notify->cb_arg, 1);
Craig Tiller5f84c842015-06-26 16:08:21 -0700113}
114
Craig Tillera82950e2015-09-22 12:33:20 -0700115static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {}
Craig Tiller131f6ed2015-09-15 08:20:20 -0700116
Craig Tillera82950e2015-09-22 12:33:20 -0700117static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con,
118 const grpc_connect_in_args *args,
119 grpc_connect_out_args *result,
120 grpc_closure *notify) {
121 connector *c = (connector *)con;
122 GPR_ASSERT(c->notify == NULL);
123 GPR_ASSERT(notify->cb);
Craig Tiller5f84c842015-06-26 16:08:21 -0700124 c->notify = notify;
Craig Tiller04c5d4b2015-06-26 17:21:41 -0700125 c->args = *args;
126 c->result = result;
Craig Tillerdfff1b82015-09-21 14:39:57 -0700127 c->tcp = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700128 grpc_closure_init(&c->connected, connected, c);
129 grpc_tcp_client_connect(exec_ctx, &c->connected, &c->tcp,
130 args->interested_parties, args->addr, args->addr_len,
131 args->deadline);
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700132}
133
Craig Tiller079a11b2015-06-30 10:07:15 -0700134static const grpc_connector_vtable connector_vtable = {
Craig Tillera82950e2015-09-22 12:33:20 -0700135 connector_ref, connector_unref, connector_shutdown, connector_connect};
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700136
Craig Tillera82950e2015-09-22 12:33:20 -0700137typedef struct {
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700138 grpc_client_channel_factory base;
Craig Tiller5f84c842015-06-26 16:08:21 -0700139 gpr_refcount refs;
Craig Tillerd9a50882015-06-29 15:57:36 -0700140 grpc_channel_args *merge_args;
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700141 grpc_channel *master;
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700142} client_channel_factory;
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700143
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700144static void client_channel_factory_ref(
145 grpc_client_channel_factory *cc_factory) {
146 client_channel_factory *f = (client_channel_factory *)cc_factory;
Craig Tillera82950e2015-09-22 12:33:20 -0700147 gpr_ref(&f->refs);
Craig Tiller5f84c842015-06-26 16:08:21 -0700148}
149
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700150static void client_channel_factory_unref(
151 grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
152 client_channel_factory *f = (client_channel_factory *)cc_factory;
Craig Tillera82950e2015-09-22 12:33:20 -0700153 if (gpr_unref(&f->refs)) {
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700154 if (f->master != NULL) {
155 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master,
156 "client_channel_factory");
157 }
Craig Tillera82950e2015-09-22 12:33:20 -0700158 grpc_channel_args_destroy(f->merge_args);
Craig Tillera82950e2015-09-22 12:33:20 -0700159 gpr_free(f);
160 }
Craig Tiller5f84c842015-06-26 16:08:21 -0700161}
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700162
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700163static grpc_subchannel *client_channel_factory_create_subchannel(
164 grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
Craig Tillera82950e2015-09-22 12:33:20 -0700165 grpc_subchannel_args *args) {
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700166 client_channel_factory *f = (client_channel_factory *)cc_factory;
Craig Tillera82950e2015-09-22 12:33:20 -0700167 connector *c = gpr_malloc(sizeof(*c));
168 grpc_channel_args *final_args =
169 grpc_channel_args_merge(args->args, f->merge_args);
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700170 grpc_subchannel *s;
Craig Tillera82950e2015-09-22 12:33:20 -0700171 memset(c, 0, sizeof(*c));
Craig Tiller91624662015-06-25 16:31:02 -0700172 c->base.vtable = &connector_vtable;
Craig Tillera82950e2015-09-22 12:33:20 -0700173 gpr_ref_init(&c->refs, 1);
Craig Tillerd9a50882015-06-29 15:57:36 -0700174 args->args = final_args;
Craig Tiller8cdba662016-01-22 20:01:55 -0800175 s = grpc_subchannel_create(exec_ctx, &c->base, args);
Craig Tillera82950e2015-09-22 12:33:20 -0700176 grpc_connector_unref(exec_ctx, &c->base);
177 grpc_channel_args_destroy(final_args);
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700178 return s;
Craig Tiller91624662015-06-25 16:31:02 -0700179}
180
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700181static grpc_channel *client_channel_factory_create_channel(
182 grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
David Garcia Quintas0b868c72016-04-01 14:28:22 -0700183 const char *target, grpc_client_channel_type type,
184 grpc_channel_args *args) {
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700185 client_channel_factory *f = (client_channel_factory *)cc_factory;
186 grpc_channel_args *final_args = grpc_channel_args_merge(args, f->merge_args);
187 grpc_channel *channel = grpc_channel_create(exec_ctx, target, final_args,
188 GRPC_CLIENT_CHANNEL, NULL);
189 grpc_channel_args_destroy(final_args);
190 grpc_resolver *resolver = grpc_resolver_create(target, &f->base);
191 if (!resolver) {
192 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
193 "client_channel_factory_create_channel");
194 return NULL;
195 }
196
197 grpc_client_channel_set_resolver(
198 exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
199 GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create_channel");
200
201 return channel;
202}
203
204static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
205 {client_channel_factory_ref, client_channel_factory_unref,
206 client_channel_factory_create_subchannel,
207 client_channel_factory_create_channel};
Craig Tiller91624662015-06-25 16:31:02 -0700208
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800209/* Create a client channel:
210 Asynchronously: - resolve target
211 - connect to it (trying alternatives as presented)
212 - perform handshakes */
Craig Tillera82950e2015-09-22 12:33:20 -0700213grpc_channel *grpc_insecure_channel_create(const char *target,
214 const grpc_channel_args *args,
215 void *reserved) {
Craig Tillerf5768a62015-09-22 10:54:34 -0700216 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700217 GRPC_API_TRACE(
218 "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
219 (target, args, reserved));
Craig Tillera82950e2015-09-22 12:33:20 -0700220 GPR_ASSERT(!reserved);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800221
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700222 client_channel_factory *f = gpr_malloc(sizeof(*f));
223 memset(f, 0, sizeof(*f));
224 f->base.vtable = &client_channel_factory_vtable;
Craig Tillera82950e2015-09-22 12:33:20 -0700225 gpr_ref_init(&f->refs, 1);
Craig Tillera82950e2015-09-22 12:33:20 -0700226 f->merge_args = grpc_channel_args_copy(args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800227
David Garcia Quintas0b868c72016-04-01 14:28:22 -0700228 grpc_channel *channel = client_channel_factory_create_channel(
229 &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, NULL);
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700230 if (channel != NULL) {
231 f->master = channel;
232 GRPC_CHANNEL_INTERNAL_REF(f->master, "grpc_insecure_channel_create");
233 }
234 grpc_client_channel_factory_unref(&exec_ctx, &f->base);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700235
Craig Tillera82950e2015-09-22 12:33:20 -0700236 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800237
David Garcia Quintasfcf7ad62016-03-29 21:55:34 -0700238 return channel; /* may be NULL */
Craig Tiller190d3602015-02-18 09:23:38 -0800239}