blob: cf987a02e017bd5047da184f16c614f94d9fe718 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller19482442016-01-25 09:59:20 -08003 * Copyright 2015-2016, 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 Tilleradcb92d2016-03-28 10:14:05 -070043#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
Craig Tiller9533d042016-03-25 17:11:06 -070044#include "src/core/lib/census/grpc_filter.h"
45#include "src/core/lib/channel/channel_args.h"
46#include "src/core/lib/channel/client_channel.h"
47#include "src/core/lib/channel/compress_filter.h"
48#include "src/core/lib/channel/http_client_filter.h"
49#include "src/core/lib/client_config/resolver_registry.h"
50#include "src/core/lib/iomgr/tcp_client.h"
51#include "src/core/lib/surface/api_trace.h"
52#include "src/core/lib/surface/channel.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080053
Craig Tillera82950e2015-09-22 12:33:20 -070054typedef struct {
Craig Tiller91624662015-06-25 16:31:02 -070055 grpc_connector base;
56 gpr_refcount refs;
Craig Tiller5f84c842015-06-26 16:08:21 -070057
Craig Tiller33825112015-09-18 07:44:19 -070058 grpc_closure *notify;
Craig Tiller04c5d4b2015-06-26 17:21:41 -070059 grpc_connect_in_args args;
60 grpc_connect_out_args *result;
yang-g074c6fc2015-11-05 23:14:07 -080061 grpc_closure initial_string_sent;
62 gpr_slice_buffer initial_string_buffer;
Craig Tillerdfff1b82015-09-21 14:39:57 -070063
64 grpc_endpoint *tcp;
65
Craig Tillerdfff1b82015-09-21 14:39:57 -070066 grpc_closure connected;
Craig Tiller91624662015-06-25 16:31:02 -070067} connector;
68
Craig Tillera82950e2015-09-22 12:33:20 -070069static void connector_ref(grpc_connector *con) {
70 connector *c = (connector *)con;
71 gpr_ref(&c->refs);
Craig Tiller91624662015-06-25 16:31:02 -070072}
73
Craig Tillera82950e2015-09-22 12:33:20 -070074static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
75 connector *c = (connector *)con;
76 if (gpr_unref(&c->refs)) {
yang-g074c6fc2015-11-05 23:14:07 -080077 /* c->initial_string_buffer does not need to be destroyed */
Craig Tillera82950e2015-09-22 12:33:20 -070078 gpr_free(c);
79 }
Craig Tiller91624662015-06-25 16:31:02 -070080}
81
yang-gf8843fb2015-11-21 12:33:22 -080082static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
Craig Tiller6c396862016-01-28 13:53:40 -080083 bool success) {
yang-gf8843fb2015-11-21 12:33:22 -080084 connector_unref(exec_ctx, arg);
85}
yang-g074c6fc2015-11-05 23:14:07 -080086
Craig Tiller6c396862016-01-28 13:53:40 -080087static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
Craig Tiller5f84c842015-06-26 16:08:21 -070088 connector *c = arg;
Craig Tiller33825112015-09-18 07:44:19 -070089 grpc_closure *notify;
Craig Tillerdfff1b82015-09-21 14:39:57 -070090 grpc_endpoint *tcp = c->tcp;
Craig Tillera82950e2015-09-22 12:33:20 -070091 if (tcp != NULL) {
yang-g074c6fc2015-11-05 23:14:07 -080092 if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
yang-gf8843fb2015-11-21 12:33:22 -080093 grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
94 c);
yang-g074c6fc2015-11-05 23:14:07 -080095 gpr_slice_buffer_init(&c->initial_string_buffer);
96 gpr_slice_buffer_add(&c->initial_string_buffer,
97 c->args.initial_connect_string);
yang-gf8843fb2015-11-21 12:33:22 -080098 connector_ref(arg);
yang-g074c6fc2015-11-05 23:14:07 -080099 grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
100 &c->initial_string_sent);
101 }
Craig Tillerb2b42612015-11-20 12:02:17 -0800102 c->result->transport =
103 grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1);
Craig Tillera82950e2015-09-22 12:33:20 -0700104 grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
105 0);
106 GPR_ASSERT(c->result->transport);
Julien Boeuf5b194032015-12-17 16:00:51 -0800107 c->result->channel_args = c->args.channel_args;
Craig Tillera82950e2015-09-22 12:33:20 -0700108 } else {
109 memset(c->result, 0, sizeof(*c->result));
110 }
Craig Tiller5f84c842015-06-26 16:08:21 -0700111 notify = c->notify;
112 c->notify = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700113 notify->cb(exec_ctx, notify->cb_arg, 1);
Craig Tiller5f84c842015-06-26 16:08:21 -0700114}
115
Craig Tillera82950e2015-09-22 12:33:20 -0700116static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {}
Craig Tiller131f6ed2015-09-15 08:20:20 -0700117
Craig Tillera82950e2015-09-22 12:33:20 -0700118static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con,
119 const grpc_connect_in_args *args,
120 grpc_connect_out_args *result,
121 grpc_closure *notify) {
122 connector *c = (connector *)con;
123 GPR_ASSERT(c->notify == NULL);
124 GPR_ASSERT(notify->cb);
Craig Tiller5f84c842015-06-26 16:08:21 -0700125 c->notify = notify;
Craig Tiller04c5d4b2015-06-26 17:21:41 -0700126 c->args = *args;
127 c->result = result;
Craig Tillerdfff1b82015-09-21 14:39:57 -0700128 c->tcp = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700129 grpc_closure_init(&c->connected, connected, c);
130 grpc_tcp_client_connect(exec_ctx, &c->connected, &c->tcp,
131 args->interested_parties, args->addr, args->addr_len,
132 args->deadline);
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700133}
134
Craig Tiller079a11b2015-06-30 10:07:15 -0700135static const grpc_connector_vtable connector_vtable = {
Craig Tillera82950e2015-09-22 12:33:20 -0700136 connector_ref, connector_unref, connector_shutdown, connector_connect};
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700137
Craig Tillera82950e2015-09-22 12:33:20 -0700138typedef struct {
Craig Tiller5f84c842015-06-26 16:08:21 -0700139 grpc_subchannel_factory base;
140 gpr_refcount refs;
Craig Tillerd9a50882015-06-29 15:57:36 -0700141 grpc_channel_args *merge_args;
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700142 grpc_channel *master;
Craig Tiller5f84c842015-06-26 16:08:21 -0700143} subchannel_factory;
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700144
Craig Tillera82950e2015-09-22 12:33:20 -0700145static void subchannel_factory_ref(grpc_subchannel_factory *scf) {
146 subchannel_factory *f = (subchannel_factory *)scf;
147 gpr_ref(&f->refs);
Craig Tiller5f84c842015-06-26 16:08:21 -0700148}
149
Craig Tillera82950e2015-09-22 12:33:20 -0700150static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
151 grpc_subchannel_factory *scf) {
152 subchannel_factory *f = (subchannel_factory *)scf;
153 if (gpr_unref(&f->refs)) {
154 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
155 grpc_channel_args_destroy(f->merge_args);
Craig Tillera82950e2015-09-22 12:33:20 -0700156 gpr_free(f);
157 }
Craig Tiller5f84c842015-06-26 16:08:21 -0700158}
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700159
Craig Tillera82950e2015-09-22 12:33:20 -0700160static grpc_subchannel *subchannel_factory_create_subchannel(
161 grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf,
162 grpc_subchannel_args *args) {
163 subchannel_factory *f = (subchannel_factory *)scf;
164 connector *c = gpr_malloc(sizeof(*c));
165 grpc_channel_args *final_args =
166 grpc_channel_args_merge(args->args, f->merge_args);
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700167 grpc_subchannel *s;
Craig Tillera82950e2015-09-22 12:33:20 -0700168 memset(c, 0, sizeof(*c));
Craig Tiller91624662015-06-25 16:31:02 -0700169 c->base.vtable = &connector_vtable;
Craig Tillera82950e2015-09-22 12:33:20 -0700170 gpr_ref_init(&c->refs, 1);
Craig Tillerd9a50882015-06-29 15:57:36 -0700171 args->args = final_args;
Craig Tiller8cdba662016-01-22 20:01:55 -0800172 s = grpc_subchannel_create(exec_ctx, &c->base, args);
Craig Tillera82950e2015-09-22 12:33:20 -0700173 grpc_connector_unref(exec_ctx, &c->base);
174 grpc_channel_args_destroy(final_args);
Craig Tillerf7afa1f2015-06-26 09:02:20 -0700175 return s;
Craig Tiller91624662015-06-25 16:31:02 -0700176}
177
Craig Tiller079a11b2015-06-30 10:07:15 -0700178static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {
Craig Tillera82950e2015-09-22 12:33:20 -0700179 subchannel_factory_ref, subchannel_factory_unref,
180 subchannel_factory_create_subchannel};
Craig Tiller91624662015-06-25 16:31:02 -0700181
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800182/* Create a client channel:
183 Asynchronously: - resolve target
184 - connect to it (trying alternatives as presented)
185 - perform handshakes */
Craig Tillera82950e2015-09-22 12:33:20 -0700186grpc_channel *grpc_insecure_channel_create(const char *target,
187 const grpc_channel_args *args,
188 void *reserved) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800189 grpc_channel *channel = NULL;
Craig Tillerf5f17122015-06-25 08:47:26 -0700190 grpc_resolver *resolver;
Craig Tiller5f84c842015-06-26 16:08:21 -0700191 subchannel_factory *f;
Craig Tillerf5768a62015-09-22 10:54:34 -0700192 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700193 GRPC_API_TRACE(
194 "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
195 (target, args, reserved));
Craig Tillera82950e2015-09-22 12:33:20 -0700196 GPR_ASSERT(!reserved);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800197
Craig Tillerb2b42612015-11-20 12:02:17 -0800198 channel =
Craig Tiller178edfa2016-02-17 20:54:46 -0800199 grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700200
Craig Tillera82950e2015-09-22 12:33:20 -0700201 f = gpr_malloc(sizeof(*f));
Craig Tiller5f84c842015-06-26 16:08:21 -0700202 f->base.vtable = &subchannel_factory_vtable;
Craig Tillera82950e2015-09-22 12:33:20 -0700203 gpr_ref_init(&f->refs, 1);
Craig Tillera82950e2015-09-22 12:33:20 -0700204 f->merge_args = grpc_channel_args_copy(args);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700205 f->master = channel;
Craig Tillera82950e2015-09-22 12:33:20 -0700206 GRPC_CHANNEL_INTERNAL_REF(f->master, "subchannel_factory");
207 resolver = grpc_resolver_create(target, &f->base);
208 if (!resolver) {
yang-gc0ed5092015-12-09 08:48:08 -0800209 GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, f->master, "subchannel_factory");
210 grpc_subchannel_factory_unref(&exec_ctx, &f->base);
211 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillera82950e2015-09-22 12:33:20 -0700212 return NULL;
213 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800214
Craig Tillera82950e2015-09-22 12:33:20 -0700215 grpc_client_channel_set_resolver(
216 &exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
217 GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create");
218 grpc_subchannel_factory_unref(&exec_ctx, &f->base);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700219
Craig Tillera82950e2015-09-22 12:33:20 -0700220 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800221
222 return channel;
Craig Tiller190d3602015-02-18 09:23:38 -0800223}