blob: b16a3ebf4511633e766a17e11f98694915478bf7 [file] [log] [blame]
yang-g72941642015-11-06 23:23:20 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
yang-g72941642015-11-06 23:23:20 -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 */
murgatroid99085f9af2016-10-24 09:55:44 -070033
34/* With the addition of a libuv endpoint, sockaddr.h now includes uv.h when
35 using that endpoint. Because of various transitive includes in uv.h,
36 including windows.h on Windows, uv.h must be included before other system
37 headers. Therefore, sockaddr.h must always be included first */
murgatroid99c36f6ea2016-10-03 09:24:09 -070038#include "src/core/lib/iomgr/sockaddr.h"
39
yang-g72941642015-11-06 23:23:20 -080040#include <string.h>
41
42#include <grpc/grpc.h>
Craig Tillerf6f9cf32016-10-26 17:19:47 -070043#include <grpc/slice.h>
yang-g72941642015-11-06 23:23:20 -080044#include <grpc/support/alloc.h>
45#include <grpc/support/host_port.h>
46#include <grpc/support/log.h>
Craig Tiller9d861202016-05-11 10:12:57 -070047#include <grpc/support/thd.h>
yang-g72941642015-11-06 23:23:20 -080048
Mark D. Roth2137cd82016-09-14 09:04:00 -070049#include "src/core/ext/client_channel/initial_connect_string.h"
Craig Tiller9533d042016-03-25 17:11:06 -070050#include "src/core/lib/iomgr/sockaddr.h"
Julien Boeuf8ca294e2016-05-02 14:56:30 -070051#include "src/core/lib/security/credentials/fake/fake_credentials.h"
Craig Tillerf6f9cf32016-10-26 17:19:47 -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"
yang-g72941642015-11-06 23:23:20 -080054#include "test/core/util/port.h"
55#include "test/core/util/test_config.h"
56#include "test/core/util/test_tcp_server.h"
57
58struct rpc_state {
59 char *target;
yang-gf8843fb2015-11-21 12:33:22 -080060 grpc_channel_credentials *creds;
yang-g72941642015-11-06 23:23:20 -080061 grpc_completion_queue *cq;
62 grpc_channel *channel;
63 grpc_call *call;
64 grpc_op op;
Craig Tillerd41a4a72016-10-26 16:16:06 -070065 grpc_slice_buffer incoming_buffer;
66 grpc_slice_buffer temp_incoming_buffer;
yang-g72941642015-11-06 23:23:20 -080067 grpc_endpoint *tcp;
Craig Tiller5f902c12016-05-12 10:31:39 -070068 gpr_atm done_atm;
yang-g72941642015-11-06 23:23:20 -080069};
70
71static const char *magic_connect_string = "magic initial string";
72static int server_port;
73static struct rpc_state state;
74static grpc_closure on_read;
75
Craig Tillerf707d622016-05-06 14:26:12 -070076static void handle_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
77 GPR_ASSERT(error == GRPC_ERROR_NONE);
Craig Tillerd41a4a72016-10-26 16:16:06 -070078 grpc_slice_buffer_move_into(&state.temp_incoming_buffer,
Craig Tillerf6f9cf32016-10-26 17:19:47 -070079 &state.incoming_buffer);
Yuchen Zeng64c0e8d2016-06-10 11:19:51 -070080 gpr_log(GPR_DEBUG, "got %" PRIuPTR " bytes, magic is %" PRIuPTR " bytes",
Craig Tiller468ee4c2016-05-23 11:01:34 -070081 state.incoming_buffer.length, strlen(magic_connect_string));
yang-g72941642015-11-06 23:23:20 -080082 if (state.incoming_buffer.length > strlen(magic_connect_string)) {
Craig Tiller5f902c12016-05-12 10:31:39 -070083 gpr_atm_rel_store(&state.done_atm, 1);
yang-g72941642015-11-06 23:23:20 -080084 grpc_endpoint_shutdown(exec_ctx, state.tcp);
85 grpc_endpoint_destroy(exec_ctx, state.tcp);
86 } else {
Nicolas "Pixel" Nobleac5e2ee2015-12-01 22:46:13 +010087 grpc_endpoint_read(exec_ctx, state.tcp, &state.temp_incoming_buffer,
88 &on_read);
yang-g72941642015-11-06 23:23:20 -080089 }
90}
91
Dan Bornfa6b6062016-01-08 21:01:59 -080092static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
Craig Tiller29dc4902016-05-20 08:43:48 -070093 grpc_pollset *accepting_pollset,
Dan Born5d81d152016-01-12 20:29:29 -080094 grpc_tcp_server_acceptor *acceptor) {
yang-g72941642015-11-06 23:23:20 -080095 test_tcp_server *server = arg;
96 grpc_closure_init(&on_read, handle_read, NULL);
Craig Tillerd41a4a72016-10-26 16:16:06 -070097 grpc_slice_buffer_init(&state.incoming_buffer);
98 grpc_slice_buffer_init(&state.temp_incoming_buffer);
yang-g72941642015-11-06 23:23:20 -080099 state.tcp = tcp;
Craig Tiller69b093b2016-02-25 19:04:07 -0800100 grpc_endpoint_add_to_pollset(exec_ctx, tcp, server->pollset);
Yang Gao42630b02015-11-17 00:56:45 -0800101 grpc_endpoint_read(exec_ctx, tcp, &state.temp_incoming_buffer, &on_read);
yang-g72941642015-11-06 23:23:20 -0800102}
103
murgatroid997871f732016-09-23 13:49:05 -0700104static void set_magic_initial_string(grpc_resolved_address **addr,
Craig Tillerd41a4a72016-10-26 16:16:06 -0700105 grpc_slice *connect_string) {
yang-g72941642015-11-06 23:23:20 -0800106 GPR_ASSERT(addr);
murgatroid997871f732016-09-23 13:49:05 -0700107 GPR_ASSERT((*addr)->len);
Craig Tillerd41a4a72016-10-26 16:16:06 -0700108 *connect_string = grpc_slice_from_copied_string(magic_connect_string);
yang-g72941642015-11-06 23:23:20 -0800109}
110
murgatroid997871f732016-09-23 13:49:05 -0700111static void reset_addr_and_set_magic_string(grpc_resolved_address **addr,
Craig Tillerd41a4a72016-10-26 16:16:06 -0700112 grpc_slice *connect_string) {
yang-g72941642015-11-06 23:23:20 -0800113 struct sockaddr_in target;
Craig Tillerd41a4a72016-10-26 16:16:06 -0700114 *connect_string = grpc_slice_from_copied_string(magic_connect_string);
yang-g72941642015-11-06 23:23:20 -0800115 gpr_free(*addr);
116 target.sin_family = AF_INET;
117 target.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
118 target.sin_port = htons((uint16_t)server_port);
murgatroid997871f732016-09-23 13:49:05 -0700119 *addr = (grpc_resolved_address *)gpr_malloc(sizeof(grpc_resolved_address));
David Garcia Quintas4f9b7642016-11-03 16:15:34 -0700120 (*addr)->len = sizeof(target);
murgatroid997871f732016-09-23 13:49:05 -0700121 memcpy((*addr)->addr, &target, sizeof(target));
yang-g72941642015-11-06 23:23:20 -0800122}
123
yang-g64b19662015-11-07 00:25:26 -0800124static gpr_timespec n_sec_deadline(int seconds) {
125 return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
126 gpr_time_from_seconds(seconds, GPR_TIMESPAN));
127}
128
yang-g72941642015-11-06 23:23:20 -0800129static void start_rpc(int use_creds, int target_port) {
yang-g72941642015-11-06 23:23:20 -0800130 state.cq = grpc_completion_queue_create(NULL);
131 if (use_creds) {
132 state.creds = grpc_fake_transport_security_credentials_create();
133 } else {
134 state.creds = NULL;
135 }
136 gpr_join_host_port(&state.target, "127.0.0.1", target_port);
137 if (use_creds) {
138 state.channel =
139 grpc_secure_channel_create(state.creds, state.target, NULL, NULL);
140 } else {
141 state.channel = grpc_insecure_channel_create(state.target, NULL, NULL);
142 }
143 state.call = grpc_channel_create_call(
144 state.channel, NULL, GRPC_PROPAGATE_DEFAULTS, state.cq, "/Service/Method",
145 "localhost", gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
David Garcia Quintasa301eaa2016-05-06 16:59:03 -0700146 memset(&state.op, 0, sizeof(state.op));
yang-g72941642015-11-06 23:23:20 -0800147 state.op.op = GRPC_OP_SEND_INITIAL_METADATA;
148 state.op.data.send_initial_metadata.count = 0;
149 state.op.flags = 0;
150 state.op.reserved = NULL;
151 GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(state.call, &state.op,
152 (size_t)(1), NULL, NULL));
Craig Tiller9d861202016-05-11 10:12:57 -0700153 grpc_completion_queue_next(state.cq, n_sec_deadline(5), NULL);
yang-g72941642015-11-06 23:23:20 -0800154}
155
156static void cleanup_rpc(void) {
yang-g64b19662015-11-07 00:25:26 -0800157 grpc_event ev;
Craig Tillerd41a4a72016-10-26 16:16:06 -0700158 grpc_slice_buffer_destroy(&state.incoming_buffer);
159 grpc_slice_buffer_destroy(&state.temp_incoming_buffer);
yang-gf8843fb2015-11-21 12:33:22 -0800160 grpc_channel_credentials_unref(state.creds);
yang-g72941642015-11-06 23:23:20 -0800161 grpc_call_destroy(state.call);
yang-g64b19662015-11-07 00:25:26 -0800162 grpc_completion_queue_shutdown(state.cq);
163 do {
164 ev = grpc_completion_queue_next(state.cq, n_sec_deadline(1), NULL);
165 } while (ev.type != GRPC_QUEUE_SHUTDOWN);
166 grpc_completion_queue_destroy(state.cq);
yang-g72941642015-11-06 23:23:20 -0800167 grpc_channel_destroy(state.channel);
168 gpr_free(state.target);
169}
170
Craig Tiller9d861202016-05-11 10:12:57 -0700171typedef struct {
172 test_tcp_server *server;
173 gpr_event *signal_when_done;
174} poll_args;
175
176static void actually_poll_server(void *arg) {
177 poll_args *pa = arg;
178 gpr_timespec deadline = n_sec_deadline(10);
Craig Tiller468ee4c2016-05-23 11:01:34 -0700179 while (true) {
180 bool done = gpr_atm_acq_load(&state.done_atm) != 0;
181 gpr_timespec time_left =
182 gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME));
Yuchen Zeng1f24af82016-06-10 13:15:07 -0700183 gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09" PRId32, done,
Yuchen Zeng64c0e8d2016-06-10 11:19:51 -0700184 time_left.tv_sec, time_left.tv_nsec);
Craig Tiller468ee4c2016-05-23 11:01:34 -0700185 if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) {
186 break;
187 }
Craig Tiller9d861202016-05-11 10:12:57 -0700188 test_tcp_server_poll(pa->server, 1);
yang-g72941642015-11-06 23:23:20 -0800189 }
Craig Tiller9d861202016-05-11 10:12:57 -0700190 gpr_event_set(pa->signal_when_done, (void *)1);
191 gpr_free(pa);
192}
193
194static void poll_server_until_read_done(test_tcp_server *server,
195 gpr_event *signal_when_done) {
Craig Tiller468ee4c2016-05-23 11:01:34 -0700196 gpr_atm_rel_store(&state.done_atm, 0);
Craig Tiller9d861202016-05-11 10:12:57 -0700197 gpr_thd_id id;
198 poll_args *pa = gpr_malloc(sizeof(*pa));
199 pa->server = server;
200 pa->signal_when_done = signal_when_done;
201 gpr_thd_new(&id, actually_poll_server, pa, NULL);
yang-g72941642015-11-06 23:23:20 -0800202}
203
Craig Tillerd41a4a72016-10-26 16:16:06 -0700204static void match_initial_magic_string(grpc_slice_buffer *buffer) {
yang-g72941642015-11-06 23:23:20 -0800205 size_t i, j, cmp_length;
206 size_t magic_length = strlen(magic_connect_string);
207 GPR_ASSERT(buffer->length >= magic_length);
208 for (i = 0, j = 0; i < state.incoming_buffer.count && j < magic_length; i++) {
209 char *dump =
Craig Tiller0f310802016-10-26 16:25:56 -0700210 grpc_dump_slice(state.incoming_buffer.slices[i], GPR_DUMP_ASCII);
yang-g72941642015-11-06 23:23:20 -0800211 cmp_length = GPR_MIN(strlen(dump), magic_length - j);
212 GPR_ASSERT(strncmp(dump, magic_connect_string + j, cmp_length) == 0);
213 j += cmp_length;
214 gpr_free(dump);
215 }
216}
217
218static void test_initial_string(test_tcp_server *server, int secure) {
Craig Tiller9d861202016-05-11 10:12:57 -0700219 gpr_event ev;
220 gpr_event_init(&ev);
yang-g72941642015-11-06 23:23:20 -0800221 grpc_test_set_initial_connect_string_function(set_magic_initial_string);
Craig Tiller9d861202016-05-11 10:12:57 -0700222 poll_server_until_read_done(server, &ev);
yang-g72941642015-11-06 23:23:20 -0800223 start_rpc(secure, server_port);
Craig Tiller9d861202016-05-11 10:12:57 -0700224 gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
yang-g72941642015-11-06 23:23:20 -0800225 match_initial_magic_string(&state.incoming_buffer);
226 cleanup_rpc();
227}
228
229static void test_initial_string_with_redirect(test_tcp_server *server,
230 int secure) {
Craig Tiller9d861202016-05-11 10:12:57 -0700231 gpr_event ev;
232 gpr_event_init(&ev);
yang-g72941642015-11-06 23:23:20 -0800233 int another_port = grpc_pick_unused_port_or_die();
234 grpc_test_set_initial_connect_string_function(
235 reset_addr_and_set_magic_string);
Craig Tiller9d861202016-05-11 10:12:57 -0700236 poll_server_until_read_done(server, &ev);
yang-g72941642015-11-06 23:23:20 -0800237 start_rpc(secure, another_port);
Craig Tiller9d861202016-05-11 10:12:57 -0700238 gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
yang-g72941642015-11-06 23:23:20 -0800239 match_initial_magic_string(&state.incoming_buffer);
240 cleanup_rpc();
241}
242
243static void run_test(void (*test)(test_tcp_server *server, int secure),
244 int secure) {
245 test_tcp_server test_server;
246 server_port = grpc_pick_unused_port_or_die();
247 test_tcp_server_init(&test_server, on_connect, &test_server);
248 test_tcp_server_start(&test_server, server_port);
249 test(&test_server, secure);
250 test_tcp_server_destroy(&test_server);
251}
252
253int main(int argc, char **argv) {
254 grpc_test_init(argc, argv);
255 grpc_init();
256
257 run_test(test_initial_string, 0);
258 run_test(test_initial_string, 1);
259 run_test(test_initial_string_with_redirect, 0);
260 run_test(test_initial_string_with_redirect, 1);
261
262 grpc_shutdown();
263 return 0;
264}