Line data Source code
1 : /*
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 <string.h>
35 :
36 : #include <grpc/grpc.h>
37 : #include <grpc/support/alloc.h>
38 : #include <grpc/support/host_port.h>
39 : #include <grpc/support/log.h>
40 : #include <grpc/support/string_util.h>
41 :
42 : #include "src/core/support/string.h"
43 : #include "src/core/iomgr/resolve_address.h"
44 : #include "src/core/iomgr/socket_utils_posix.h"
45 :
46 : #include "test/core/end2end/cq_verifier.h"
47 : #include "test/core/util/port.h"
48 : #include "test/core/util/test_config.h"
49 :
50 : /* This test exercises IPv4, IPv6, and dualstack sockets in various ways. */
51 :
52 416 : static void *tag(gpr_intptr i) { return (void *)i; }
53 :
54 116 : static gpr_timespec ms_from_now(int ms) {
55 116 : return GRPC_TIMEOUT_MILLIS_TO_DEADLINE(ms);
56 : }
57 :
58 58 : static void drain_cq(grpc_completion_queue *cq) {
59 : grpc_event ev;
60 : do {
61 58 : ev = grpc_completion_queue_next(cq, ms_from_now(5000), NULL);
62 58 : } while (ev.type != GRPC_QUEUE_SHUTDOWN);
63 58 : }
64 :
65 22 : static void do_nothing(void *ignored) {}
66 :
67 58 : void test_connect(const char *server_host, const char *client_host, int port,
68 : int expect_ok) {
69 : char *client_hostport;
70 : char *server_hostport;
71 : grpc_channel *client;
72 : grpc_server *server;
73 : grpc_completion_queue *cq;
74 : grpc_call *c;
75 : grpc_call *s;
76 : cq_verifier *cqv;
77 : gpr_timespec deadline;
78 : int got_port;
79 : grpc_op ops[6];
80 : grpc_op *op;
81 : grpc_metadata_array initial_metadata_recv;
82 : grpc_metadata_array trailing_metadata_recv;
83 : grpc_metadata_array request_metadata_recv;
84 : grpc_status_code status;
85 : grpc_call_error error;
86 58 : char *details = NULL;
87 58 : size_t details_capacity = 0;
88 58 : int was_cancelled = 2;
89 : grpc_call_details call_details;
90 : char *peer;
91 :
92 58 : if (port == 0) {
93 58 : port = grpc_pick_unused_port_or_die();
94 : }
95 :
96 58 : gpr_join_host_port(&server_hostport, server_host, port);
97 :
98 58 : grpc_metadata_array_init(&initial_metadata_recv);
99 58 : grpc_metadata_array_init(&trailing_metadata_recv);
100 58 : grpc_metadata_array_init(&request_metadata_recv);
101 58 : grpc_call_details_init(&call_details);
102 :
103 : /* Create server. */
104 58 : cq = grpc_completion_queue_create(NULL);
105 58 : server = grpc_server_create(NULL, NULL);
106 58 : grpc_server_register_completion_queue(server, cq, NULL);
107 58 : GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port(
108 : server, server_hostport)) > 0);
109 58 : if (port == 0) {
110 0 : port = got_port;
111 : } else {
112 58 : GPR_ASSERT(port == got_port);
113 : }
114 58 : grpc_server_start(server);
115 58 : cqv = cq_verifier_create(cq);
116 :
117 : /* Create client. */
118 58 : if (client_host[0] == 'i') {
119 : /* for ipv4:/ipv6: addresses, concatenate the port to each of the parts */
120 : size_t i;
121 : gpr_slice uri_slice;
122 : gpr_slice_buffer uri_parts;
123 : char **hosts_with_port;
124 :
125 22 : uri_slice =
126 22 : gpr_slice_new((char *)client_host, strlen(client_host), do_nothing);
127 22 : gpr_slice_buffer_init(&uri_parts);
128 22 : gpr_slice_split(uri_slice, ",", &uri_parts);
129 22 : hosts_with_port = gpr_malloc(sizeof(char *) * uri_parts.count);
130 50 : for (i = 0; i < uri_parts.count; i++) {
131 28 : char *uri_part_str = gpr_dump_slice(uri_parts.slices[i], GPR_DUMP_ASCII);
132 28 : gpr_asprintf(&hosts_with_port[i], "%s:%d", uri_part_str, port);
133 28 : gpr_free(uri_part_str);
134 : }
135 22 : client_hostport = gpr_strjoin_sep((const char **)hosts_with_port,
136 : uri_parts.count, ",", NULL);
137 50 : for (i = 0; i < uri_parts.count; i++) {
138 28 : gpr_free(hosts_with_port[i]);
139 : }
140 22 : gpr_free(hosts_with_port);
141 22 : gpr_slice_buffer_destroy(&uri_parts);
142 22 : gpr_slice_unref(uri_slice);
143 : } else {
144 36 : gpr_join_host_port(&client_hostport, client_host, port);
145 : }
146 58 : client = grpc_insecure_channel_create(client_hostport, NULL, NULL);
147 :
148 58 : gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)",
149 : server_hostport, client_hostport, expect_ok ? "success" : "failure");
150 :
151 58 : gpr_free(client_hostport);
152 58 : gpr_free(server_hostport);
153 :
154 58 : if (expect_ok) {
155 : /* Normal deadline, shouldn't be reached. */
156 46 : deadline = ms_from_now(60000);
157 : } else {
158 : /* Give up faster when failure is expected.
159 : BUG: Setting this to 1000 reveals a memory leak (b/18608927). */
160 12 : deadline = ms_from_now(1500);
161 : }
162 :
163 : /* Send a trivial request. */
164 58 : c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
165 : "/foo", "foo.test.google.fr", deadline, NULL);
166 58 : GPR_ASSERT(c);
167 :
168 58 : op = ops;
169 58 : op->op = GRPC_OP_SEND_INITIAL_METADATA;
170 58 : op->data.send_initial_metadata.count = 0;
171 58 : op->flags = 0;
172 58 : op->reserved = NULL;
173 58 : op++;
174 58 : op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
175 58 : op->flags = 0;
176 58 : op->reserved = NULL;
177 58 : op++;
178 58 : op->op = GRPC_OP_RECV_INITIAL_METADATA;
179 58 : op->data.recv_initial_metadata = &initial_metadata_recv;
180 58 : op->flags = 0;
181 58 : op->reserved = NULL;
182 58 : op++;
183 58 : op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
184 58 : op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
185 58 : op->data.recv_status_on_client.status = &status;
186 58 : op->data.recv_status_on_client.status_details = &details;
187 58 : op->data.recv_status_on_client.status_details_capacity = &details_capacity;
188 58 : op->flags = 0;
189 58 : op->reserved = NULL;
190 58 : op++;
191 58 : error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
192 58 : GPR_ASSERT(GRPC_CALL_OK == error);
193 :
194 58 : if (expect_ok) {
195 : /* Check for a successful request. */
196 46 : error = grpc_server_request_call(server, &s, &call_details,
197 : &request_metadata_recv, cq, cq, tag(101));
198 46 : GPR_ASSERT(GRPC_CALL_OK == error);
199 46 : cq_expect_completion(cqv, tag(101), 1);
200 46 : cq_verify(cqv);
201 :
202 46 : op = ops;
203 46 : op->op = GRPC_OP_SEND_INITIAL_METADATA;
204 46 : op->data.send_initial_metadata.count = 0;
205 46 : op->flags = 0;
206 46 : op++;
207 46 : op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
208 46 : op->data.send_status_from_server.trailing_metadata_count = 0;
209 46 : op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
210 46 : op->data.send_status_from_server.status_details = "xyz";
211 46 : op->flags = 0;
212 46 : op++;
213 46 : op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
214 46 : op->data.recv_close_on_server.cancelled = &was_cancelled;
215 46 : op->flags = 0;
216 46 : op++;
217 46 : error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
218 46 : GPR_ASSERT(GRPC_CALL_OK == error);
219 :
220 46 : cq_expect_completion(cqv, tag(102), 1);
221 46 : cq_expect_completion(cqv, tag(1), 1);
222 46 : cq_verify(cqv);
223 :
224 46 : peer = grpc_call_get_peer(c);
225 46 : gpr_log(GPR_DEBUG, "got peer: '%s'", peer);
226 46 : gpr_free(peer);
227 :
228 46 : GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
229 46 : GPR_ASSERT(0 == strcmp(details, "xyz"));
230 46 : GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
231 46 : GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
232 46 : GPR_ASSERT(was_cancelled == 1);
233 :
234 46 : grpc_call_destroy(s);
235 : } else {
236 : /* Check for a failed connection. */
237 12 : cq_expect_completion(cqv, tag(1), 1);
238 12 : cq_verify(cqv);
239 :
240 12 : GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED);
241 : }
242 :
243 58 : grpc_call_destroy(c);
244 :
245 58 : cq_verifier_destroy(cqv);
246 :
247 : /* Destroy client. */
248 58 : grpc_channel_destroy(client);
249 :
250 : /* Destroy server. */
251 58 : grpc_server_shutdown_and_notify(server, cq, tag(1000));
252 58 : GPR_ASSERT(grpc_completion_queue_pluck(cq, tag(1000),
253 : GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5),
254 : NULL).type == GRPC_OP_COMPLETE);
255 58 : grpc_server_destroy(server);
256 58 : grpc_completion_queue_shutdown(cq);
257 58 : drain_cq(cq);
258 58 : grpc_completion_queue_destroy(cq);
259 :
260 58 : grpc_metadata_array_destroy(&initial_metadata_recv);
261 58 : grpc_metadata_array_destroy(&trailing_metadata_recv);
262 58 : grpc_metadata_array_destroy(&request_metadata_recv);
263 :
264 58 : grpc_call_details_destroy(&call_details);
265 58 : gpr_free(details);
266 58 : }
267 :
268 2 : int external_dns_works(const char *host) {
269 2 : grpc_resolved_addresses *res = grpc_blocking_resolve_address(host, "80");
270 2 : if (res != NULL) {
271 2 : grpc_resolved_addresses_destroy(res);
272 2 : return 1;
273 : }
274 0 : return 0;
275 : }
276 :
277 1 : int main(int argc, char **argv) {
278 1 : int do_ipv6 = 1;
279 :
280 1 : grpc_test_init(argc, argv);
281 1 : grpc_init();
282 :
283 1 : if (!grpc_ipv6_loopback_available()) {
284 0 : gpr_log(GPR_INFO, "Can't bind to ::1. Skipping IPv6 tests.");
285 0 : do_ipv6 = 0;
286 : }
287 :
288 : /* For coverage, test with and without dualstack sockets. */
289 4 : for (grpc_forbid_dualstack_sockets_for_testing = 0;
290 3 : grpc_forbid_dualstack_sockets_for_testing <= 1;
291 2 : grpc_forbid_dualstack_sockets_for_testing++) {
292 : /* :: and 0.0.0.0 are handled identically. */
293 2 : test_connect("::", "127.0.0.1", 0, 1);
294 2 : test_connect("::", "::ffff:127.0.0.1", 0, 1);
295 2 : test_connect("::", "ipv4:127.0.0.1", 0, 1);
296 2 : test_connect("::", "ipv6:[::ffff:127.0.0.1]", 0, 1);
297 2 : test_connect("::", "localhost", 0, 1);
298 2 : test_connect("0.0.0.0", "127.0.0.1", 0, 1);
299 2 : test_connect("0.0.0.0", "::ffff:127.0.0.1", 0, 1);
300 2 : test_connect("0.0.0.0", "ipv4:127.0.0.1", 0, 1);
301 2 : test_connect("0.0.0.0", "ipv4:127.0.0.1,127.0.0.2,127.0.0.3", 0, 1);
302 2 : test_connect("0.0.0.0", "ipv6:[::ffff:127.0.0.1],[::ffff:127.0.0.2]", 0, 1);
303 2 : test_connect("0.0.0.0", "localhost", 0, 1);
304 2 : if (do_ipv6) {
305 2 : test_connect("::", "::1", 0, 1);
306 2 : test_connect("0.0.0.0", "::1", 0, 1);
307 2 : test_connect("::", "ipv6:[::1]", 0, 1);
308 2 : test_connect("0.0.0.0", "ipv6:[::1]", 0, 1);
309 : }
310 :
311 : /* These only work when the families agree. */
312 2 : test_connect("127.0.0.1", "127.0.0.1", 0, 1);
313 2 : test_connect("127.0.0.1", "ipv4:127.0.0.1", 0, 1);
314 2 : if (do_ipv6) {
315 2 : test_connect("::1", "::1", 0, 1);
316 2 : test_connect("::1", "127.0.0.1", 0, 0);
317 2 : test_connect("127.0.0.1", "::1", 0, 0);
318 2 : test_connect("::1", "ipv6:[::1]", 0, 1);
319 2 : test_connect("::1", "ipv4:127.0.0.1", 0, 0);
320 2 : test_connect("127.0.0.1", "ipv6:[::1]", 0, 0);
321 : }
322 :
323 2 : if (!external_dns_works("loopback46.unittest.grpc.io")) {
324 0 : gpr_log(GPR_INFO, "Skipping tests that depend on *.unittest.grpc.io.");
325 : } else {
326 2 : test_connect("loopback46.unittest.grpc.io", "loopback4.unittest.grpc.io",
327 : 0, 1);
328 2 : test_connect("loopback4.unittest.grpc.io", "loopback46.unittest.grpc.io",
329 : 0, 1);
330 2 : if (do_ipv6) {
331 2 : test_connect("loopback46.unittest.grpc.io",
332 : "loopback6.unittest.grpc.io", 0, 1);
333 2 : test_connect("loopback6.unittest.grpc.io",
334 : "loopback46.unittest.grpc.io", 0, 1);
335 2 : test_connect("loopback4.unittest.grpc.io", "loopback6.unittest.grpc.io",
336 : 0, 0);
337 2 : test_connect("loopback6.unittest.grpc.io", "loopback4.unittest.grpc.io",
338 : 0, 0);
339 : }
340 : }
341 : }
342 :
343 1 : grpc_shutdown();
344 :
345 1 : return 0;
346 : }
|