• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include "src/core/lib/iomgr/port.h"
20 
21 // This test won't work except with posix sockets enabled
22 #ifdef GRPC_POSIX_SOCKET
23 
24 #include <string.h>
25 
26 #include <grpc/grpc.h>
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
29 #include <grpc/support/string_util.h>
30 
31 #include "src/core/lib/gpr/host_port.h"
32 #include "src/core/lib/gpr/string.h"
33 #include "src/core/lib/iomgr/error.h"
34 #include "src/core/lib/iomgr/resolve_address.h"
35 #include "src/core/lib/iomgr/sockaddr_utils.h"
36 #include "src/core/lib/iomgr/socket_utils_posix.h"
37 #include "src/core/lib/slice/slice_string_helpers.h"
38 #include "test/core/end2end/cq_verifier.h"
39 #include "test/core/util/port.h"
40 #include "test/core/util/test_config.h"
41 
42 /* This test exercises IPv4, IPv6, and dualstack sockets in various ways. */
43 
tag(intptr_t i)44 static void* tag(intptr_t i) { return (void*)i; }
45 
drain_cq(grpc_completion_queue * cq)46 static void drain_cq(grpc_completion_queue* cq) {
47   grpc_event ev;
48   do {
49     ev = grpc_completion_queue_next(
50         cq, grpc_timeout_milliseconds_to_deadline(5000), nullptr);
51   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
52 }
53 
do_nothing(void * ignored)54 static void do_nothing(void* ignored) {}
55 
log_resolved_addrs(const char * label,const char * hostname)56 static void log_resolved_addrs(const char* label, const char* hostname) {
57   grpc_resolved_addresses* res = nullptr;
58   grpc_error* error = grpc_blocking_resolve_address(hostname, "80", &res);
59   if (error != GRPC_ERROR_NONE || res == nullptr) {
60     GRPC_LOG_IF_ERROR(hostname, error);
61     return;
62   }
63   for (size_t i = 0; i < res->naddrs; ++i) {
64     char* addr_str = grpc_sockaddr_to_uri(&res->addrs[i]);
65     gpr_log(GPR_INFO, "%s: %s", label, addr_str);
66     gpr_free(addr_str);
67   }
68   grpc_resolved_addresses_destroy(res);
69 }
70 
test_connect(const char * server_host,const char * client_host,int port,int expect_ok)71 void test_connect(const char* server_host, const char* client_host, int port,
72                   int expect_ok) {
73   char* client_hostport;
74   char* server_hostport;
75   grpc_channel* client;
76   grpc_server* server;
77   grpc_completion_queue* cq;
78   grpc_completion_queue* shutdown_cq;
79   grpc_call* c;
80   grpc_call* s;
81   cq_verifier* cqv;
82   gpr_timespec deadline;
83   int got_port;
84   grpc_op ops[6];
85   grpc_op* op;
86   grpc_metadata_array initial_metadata_recv;
87   grpc_metadata_array trailing_metadata_recv;
88   grpc_metadata_array request_metadata_recv;
89   grpc_status_code status;
90   grpc_call_error error;
91   grpc_slice details;
92   int was_cancelled = 2;
93   grpc_call_details call_details;
94   char* peer;
95   int picked_port = 0;
96 
97   if (port == 0) {
98     port = grpc_pick_unused_port_or_die();
99     picked_port = 1;
100   }
101 
102   gpr_join_host_port(&server_hostport, server_host, port);
103 
104   grpc_metadata_array_init(&initial_metadata_recv);
105   grpc_metadata_array_init(&trailing_metadata_recv);
106   grpc_metadata_array_init(&request_metadata_recv);
107   grpc_call_details_init(&call_details);
108 
109   /* Create server. */
110   cq = grpc_completion_queue_create_for_next(nullptr);
111   server = grpc_server_create(nullptr, nullptr);
112   grpc_server_register_completion_queue(server, cq, nullptr);
113   GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port(
114                   server, server_hostport)) > 0);
115   if (port == 0) {
116     port = got_port;
117   } else {
118     GPR_ASSERT(port == got_port);
119   }
120   grpc_server_start(server);
121   cqv = cq_verifier_create(cq);
122 
123   /* Create client. */
124   if (client_host[0] == 'i') {
125     /* for ipv4:/ipv6: addresses, concatenate the port to each of the parts */
126     size_t i;
127     grpc_slice uri_slice;
128     grpc_slice_buffer uri_parts;
129     char** hosts_with_port;
130 
131     uri_slice = grpc_slice_new(const_cast<char*>(client_host),
132                                strlen(client_host), do_nothing);
133     grpc_slice_buffer_init(&uri_parts);
134     grpc_slice_split(uri_slice, ",", &uri_parts);
135     hosts_with_port =
136         static_cast<char**>(gpr_malloc(sizeof(char*) * uri_parts.count));
137     for (i = 0; i < uri_parts.count; i++) {
138       char* uri_part_str = grpc_slice_to_c_string(uri_parts.slices[i]);
139       gpr_asprintf(&hosts_with_port[i], "%s:%d", uri_part_str, port);
140       gpr_free(uri_part_str);
141     }
142     client_hostport = gpr_strjoin_sep((const char**)hosts_with_port,
143                                       uri_parts.count, ",", nullptr);
144     for (i = 0; i < uri_parts.count; i++) {
145       gpr_free(hosts_with_port[i]);
146     }
147     gpr_free(hosts_with_port);
148     grpc_slice_buffer_destroy(&uri_parts);
149     grpc_slice_unref(uri_slice);
150   } else {
151     gpr_join_host_port(&client_hostport, client_host, port);
152   }
153   client = grpc_insecure_channel_create(client_hostport, nullptr, nullptr);
154 
155   gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)",
156           server_hostport, client_hostport, expect_ok ? "success" : "failure");
157   log_resolved_addrs("server resolved addr", server_host);
158   log_resolved_addrs("client resolved addr", client_host);
159 
160   gpr_free(client_hostport);
161   gpr_free(server_hostport);
162 
163   if (expect_ok) {
164     /* Normal deadline, shouldn't be reached. */
165     deadline = grpc_timeout_milliseconds_to_deadline(60000);
166   } else {
167     /* Give up faster when failure is expected.
168        BUG: Setting this to 1000 reveals a memory leak (b/18608927). */
169     deadline = grpc_timeout_milliseconds_to_deadline(8000);
170   }
171 
172   /* Send a trivial request. */
173   grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr");
174   c = grpc_channel_create_call(client, nullptr, GRPC_PROPAGATE_DEFAULTS, cq,
175                                grpc_slice_from_static_string("/foo"), &host,
176                                deadline, nullptr);
177   GPR_ASSERT(c);
178 
179   memset(ops, 0, sizeof(ops));
180   op = ops;
181   op->op = GRPC_OP_SEND_INITIAL_METADATA;
182   op->data.send_initial_metadata.count = 0;
183   op->flags = expect_ok ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0;
184   op->reserved = nullptr;
185   op++;
186   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
187   op->flags = 0;
188   op->reserved = nullptr;
189   op++;
190   op->op = GRPC_OP_RECV_INITIAL_METADATA;
191   op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
192   op->flags = 0;
193   op->reserved = nullptr;
194   op++;
195   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
196   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
197   op->data.recv_status_on_client.status = &status;
198   op->data.recv_status_on_client.status_details = &details;
199   op->flags = 0;
200   op->reserved = nullptr;
201   op++;
202   error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
203                                 nullptr);
204   GPR_ASSERT(GRPC_CALL_OK == error);
205 
206   if (expect_ok) {
207     /* Check for a successful request. */
208     error = grpc_server_request_call(server, &s, &call_details,
209                                      &request_metadata_recv, cq, cq, tag(101));
210     GPR_ASSERT(GRPC_CALL_OK == error);
211     CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
212     cq_verify(cqv);
213 
214     memset(ops, 0, sizeof(ops));
215     op = ops;
216     op->op = GRPC_OP_SEND_INITIAL_METADATA;
217     op->data.send_initial_metadata.count = 0;
218     op->flags = 0;
219     op++;
220     op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
221     op->data.send_status_from_server.trailing_metadata_count = 0;
222     op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
223     grpc_slice status_details = grpc_slice_from_static_string("xyz");
224     op->data.send_status_from_server.status_details = &status_details;
225     op->flags = 0;
226     op++;
227     op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
228     op->data.recv_close_on_server.cancelled = &was_cancelled;
229     op->flags = 0;
230     op++;
231     error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
232                                   tag(102), nullptr);
233     GPR_ASSERT(GRPC_CALL_OK == error);
234 
235     CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
236     CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
237     cq_verify(cqv);
238 
239     peer = grpc_call_get_peer(c);
240     gpr_log(GPR_DEBUG, "got peer: '%s'", peer);
241     gpr_free(peer);
242 
243     GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
244     GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
245     GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
246     GPR_ASSERT(0 ==
247                grpc_slice_str_cmp(call_details.host, "foo.test.google.fr"));
248     GPR_ASSERT(was_cancelled == 1);
249 
250     grpc_call_unref(s);
251   } else {
252     /* Check for a failed connection. */
253     CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
254     cq_verify(cqv);
255 
256     gpr_log(GPR_INFO, "status: %d (expected: %d)", status,
257             GRPC_STATUS_UNAVAILABLE);
258     GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
259   }
260 
261   grpc_call_unref(c);
262 
263   cq_verifier_destroy(cqv);
264 
265   /* Destroy client. */
266   grpc_channel_destroy(client);
267 
268   /* Destroy server. */
269   shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
270   grpc_server_shutdown_and_notify(server, shutdown_cq, tag(1000));
271   GPR_ASSERT(grpc_completion_queue_pluck(shutdown_cq, tag(1000),
272                                          grpc_timeout_seconds_to_deadline(5),
273                                          nullptr)
274                  .type == GRPC_OP_COMPLETE);
275   grpc_server_destroy(server);
276   grpc_completion_queue_destroy(shutdown_cq);
277   grpc_completion_queue_shutdown(cq);
278   drain_cq(cq);
279   grpc_completion_queue_destroy(cq);
280 
281   grpc_metadata_array_destroy(&initial_metadata_recv);
282   grpc_metadata_array_destroy(&trailing_metadata_recv);
283   grpc_metadata_array_destroy(&request_metadata_recv);
284 
285   grpc_call_details_destroy(&call_details);
286   grpc_slice_unref(details);
287   if (picked_port) {
288     grpc_recycle_unused_port(port);
289   }
290 }
291 
external_dns_works(const char * host)292 int external_dns_works(const char* host) {
293   grpc_resolved_addresses* res = nullptr;
294   grpc_error* error = grpc_blocking_resolve_address(host, "80", &res);
295   GRPC_ERROR_UNREF(error);
296   if (res != nullptr) {
297     grpc_resolved_addresses_destroy(res);
298     return 1;
299   }
300   return 0;
301 }
302 
main(int argc,char ** argv)303 int main(int argc, char** argv) {
304   int do_ipv6 = 1;
305 
306   grpc_test_init(argc, argv);
307   grpc_init();
308 
309   if (!grpc_ipv6_loopback_available()) {
310     gpr_log(GPR_INFO, "Can't bind to ::1.  Skipping IPv6 tests.");
311     do_ipv6 = 0;
312   }
313 
314   /* For coverage, test with and without dualstack sockets. */
315   for (grpc_forbid_dualstack_sockets_for_testing = 0;
316        grpc_forbid_dualstack_sockets_for_testing <= 1;
317        grpc_forbid_dualstack_sockets_for_testing++) {
318     /* :: and 0.0.0.0 are handled identically. */
319     test_connect("::", "127.0.0.1", 0, 1);
320     test_connect("::", "::ffff:127.0.0.1", 0, 1);
321     test_connect("::", "ipv4:127.0.0.1", 0, 1);
322     test_connect("::", "ipv6:[::ffff:127.0.0.1]", 0, 1);
323     test_connect("::", "localhost", 0, 1);
324     test_connect("0.0.0.0", "127.0.0.1", 0, 1);
325     test_connect("0.0.0.0", "::ffff:127.0.0.1", 0, 1);
326     test_connect("0.0.0.0", "ipv4:127.0.0.1", 0, 1);
327     test_connect("0.0.0.0", "ipv4:127.0.0.1,127.0.0.2,127.0.0.3", 0, 1);
328     test_connect("0.0.0.0", "ipv6:[::ffff:127.0.0.1],[::ffff:127.0.0.2]", 0, 1);
329     test_connect("0.0.0.0", "localhost", 0, 1);
330     if (do_ipv6) {
331       test_connect("::", "::1", 0, 1);
332       test_connect("0.0.0.0", "::1", 0, 1);
333       test_connect("::", "ipv6:[::1]", 0, 1);
334       test_connect("0.0.0.0", "ipv6:[::1]", 0, 1);
335     }
336 
337     /* These only work when the families agree. */
338     test_connect("127.0.0.1", "127.0.0.1", 0, 1);
339     test_connect("127.0.0.1", "ipv4:127.0.0.1", 0, 1);
340     if (do_ipv6) {
341       test_connect("::1", "::1", 0, 1);
342       test_connect("::1", "127.0.0.1", 0, 0);
343       test_connect("127.0.0.1", "::1", 0, 0);
344       test_connect("::1", "ipv6:[::1]", 0, 1);
345       test_connect("::1", "ipv4:127.0.0.1", 0, 0);
346       test_connect("127.0.0.1", "ipv6:[::1]", 0, 0);
347     }
348 
349     if (!external_dns_works("loopback46.unittest.grpc.io")) {
350       gpr_log(GPR_INFO, "Skipping tests that depend on *.unittest.grpc.io.");
351     } else {
352       test_connect("loopback46.unittest.grpc.io", "loopback4.unittest.grpc.io",
353                    0, 1);
354       test_connect("loopback4.unittest.grpc.io", "loopback46.unittest.grpc.io",
355                    0, 1);
356       if (do_ipv6) {
357         test_connect("loopback46.unittest.grpc.io",
358                      "loopback6.unittest.grpc.io", 0, 1);
359         test_connect("loopback6.unittest.grpc.io",
360                      "loopback46.unittest.grpc.io", 0, 1);
361         test_connect("loopback4.unittest.grpc.io", "loopback6.unittest.grpc.io",
362                      0, 0);
363         test_connect("loopback6.unittest.grpc.io", "loopback4.unittest.grpc.io",
364                      0, 0);
365       }
366     }
367   }
368 
369   grpc_shutdown();
370 
371   return 0;
372 }
373 
374 #else /* GRPC_POSIX_SOCKET */
375 
main(int argc,char ** argv)376 int main(int argc, char** argv) { return 1; }
377 
378 #endif /* GRPC_POSIX_SOCKET */
379