• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2017 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 <grpc/grpc.h>
20 #include <grpc/support/alloc.h>
21 #include <grpc/support/log.h>
22 #include <grpc/support/string_util.h>
23 #include <grpc/support/sync.h>
24 #include <grpc/support/time.h>
25 #include <string.h>
26 
27 #include <gflags/gflags.h>
28 #include <gmock/gmock.h>
29 #include <sys/types.h>
30 #include <vector>
31 
32 #include <address_sorting/address_sorting.h>
33 #include "test/cpp/util/subprocess.h"
34 #include "test/cpp/util/test_config.h"
35 
36 #include "src/core/ext/filters/client_channel/client_channel.h"
37 #include "src/core/ext/filters/client_channel/resolver.h"
38 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
39 #include "src/core/ext/filters/client_channel/resolver_registry.h"
40 #include "src/core/lib/channel/channel_args.h"
41 #include "src/core/lib/gpr/env.h"
42 #include "src/core/lib/gpr/host_port.h"
43 #include "src/core/lib/gpr/string.h"
44 #include "src/core/lib/iomgr/combiner.h"
45 #include "src/core/lib/iomgr/executor.h"
46 #include "src/core/lib/iomgr/iomgr.h"
47 #include "src/core/lib/iomgr/resolve_address.h"
48 #include "src/core/lib/iomgr/sockaddr_utils.h"
49 #include "test/core/util/port.h"
50 #include "test/core/util/test_config.h"
51 
52 #ifndef GPR_WINDOWS
53 #include <arpa/inet.h>
54 #include <sys/socket.h>
55 #endif
56 
57 namespace {
58 
59 struct TestAddress {
60   std::string dest_addr;
61   int family;
62 };
63 
TestAddressToGrpcResolvedAddress(TestAddress test_addr)64 grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) {
65   char* host;
66   char* port;
67   grpc_resolved_address resolved_addr;
68   gpr_split_host_port(test_addr.dest_addr.c_str(), &host, &port);
69   if (test_addr.family == AF_INET) {
70     sockaddr_in in_dest;
71     memset(&in_dest, 0, sizeof(sockaddr_in));
72     in_dest.sin_port = htons(atoi(port));
73     in_dest.sin_family = AF_INET;
74     GPR_ASSERT(inet_pton(AF_INET, host, &in_dest.sin_addr) == 1);
75     memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in));
76     resolved_addr.len = sizeof(sockaddr_in);
77   } else {
78     GPR_ASSERT(test_addr.family == AF_INET6);
79     sockaddr_in6 in6_dest;
80     memset(&in6_dest, 0, sizeof(sockaddr_in6));
81     in6_dest.sin6_port = htons(atoi(port));
82     in6_dest.sin6_family = AF_INET6;
83     GPR_ASSERT(inet_pton(AF_INET6, host, &in6_dest.sin6_addr) == 1);
84     memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6));
85     resolved_addr.len = sizeof(sockaddr_in6);
86   }
87   gpr_free(host);
88   gpr_free(port);
89   return resolved_addr;
90 }
91 
92 class MockSourceAddrFactory : public address_sorting_source_addr_factory {
93  public:
MockSourceAddrFactory(bool ipv4_supported,bool ipv6_supported,const std::map<std::string,TestAddress> & dest_addr_to_src_addr)94   MockSourceAddrFactory(
95       bool ipv4_supported, bool ipv6_supported,
96       const std::map<std::string, TestAddress>& dest_addr_to_src_addr)
97       : ipv4_supported_(ipv4_supported),
98         ipv6_supported_(ipv6_supported),
99         dest_addr_to_src_addr_(dest_addr_to_src_addr) {}
100 
GetSourceAddr(const address_sorting_address * dest_addr,address_sorting_address * source_addr)101   bool GetSourceAddr(const address_sorting_address* dest_addr,
102                      address_sorting_address* source_addr) {
103     if ((address_sorting_abstract_get_family(dest_addr) ==
104              ADDRESS_SORTING_AF_INET &&
105          !ipv4_supported_) ||
106         (address_sorting_abstract_get_family(dest_addr) ==
107              ADDRESS_SORTING_AF_INET6 &&
108          !ipv6_supported_)) {
109       return false;
110     }
111     char* ip_addr_str;
112     grpc_resolved_address dest_addr_as_resolved_addr;
113     memcpy(&dest_addr_as_resolved_addr.addr, dest_addr, dest_addr->len);
114     dest_addr_as_resolved_addr.len = dest_addr->len;
115     grpc_sockaddr_to_string(&ip_addr_str, &dest_addr_as_resolved_addr,
116                             false /* normalize */);
117     auto it = dest_addr_to_src_addr_.find(ip_addr_str);
118     if (it == dest_addr_to_src_addr_.end()) {
119       gpr_log(GPR_DEBUG, "can't find |%s| in dest to src map", ip_addr_str);
120       gpr_free(ip_addr_str);
121       return false;
122     }
123     gpr_free(ip_addr_str);
124     grpc_resolved_address source_addr_as_resolved_addr =
125         TestAddressToGrpcResolvedAddress(it->second);
126     memcpy(source_addr->addr, &source_addr_as_resolved_addr.addr,
127            source_addr_as_resolved_addr.len);
128     source_addr->len = source_addr_as_resolved_addr.len;
129     return true;
130   }
131 
132  private:
133   // user provided test config
134   bool ipv4_supported_;
135   bool ipv6_supported_;
136   std::map<std::string, TestAddress> dest_addr_to_src_addr_;
137 };
138 
mock_source_addr_factory_wrapper_get_source_addr(address_sorting_source_addr_factory * factory,const address_sorting_address * dest_addr,address_sorting_address * source_addr)139 static bool mock_source_addr_factory_wrapper_get_source_addr(
140     address_sorting_source_addr_factory* factory,
141     const address_sorting_address* dest_addr,
142     address_sorting_address* source_addr) {
143   MockSourceAddrFactory* mock =
144       reinterpret_cast<MockSourceAddrFactory*>(factory);
145   return mock->GetSourceAddr(dest_addr, source_addr);
146 }
147 
mock_source_addr_factory_wrapper_destroy(address_sorting_source_addr_factory * factory)148 void mock_source_addr_factory_wrapper_destroy(
149     address_sorting_source_addr_factory* factory) {
150   MockSourceAddrFactory* mock =
151       reinterpret_cast<MockSourceAddrFactory*>(factory);
152   delete mock;
153 }
154 
155 const address_sorting_source_addr_factory_vtable kMockSourceAddrFactoryVtable =
156     {
157         mock_source_addr_factory_wrapper_get_source_addr,
158         mock_source_addr_factory_wrapper_destroy,
159 };
160 
OverrideAddressSortingSourceAddrFactory(bool ipv4_supported,bool ipv6_supported,const std::map<std::string,TestAddress> & dest_addr_to_src_addr)161 void OverrideAddressSortingSourceAddrFactory(
162     bool ipv4_supported, bool ipv6_supported,
163     const std::map<std::string, TestAddress>& dest_addr_to_src_addr) {
164   address_sorting_source_addr_factory* factory = new MockSourceAddrFactory(
165       ipv4_supported, ipv6_supported, dest_addr_to_src_addr);
166   factory->vtable = &kMockSourceAddrFactoryVtable;
167   address_sorting_override_source_addr_factory_for_testing(factory);
168 }
169 
BuildLbAddrInputs(std::vector<TestAddress> test_addrs)170 grpc_lb_addresses* BuildLbAddrInputs(std::vector<TestAddress> test_addrs) {
171   grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr);
172   lb_addrs->addresses =
173       (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size());
174   lb_addrs->num_addresses = test_addrs.size();
175   for (size_t i = 0; i < test_addrs.size(); i++) {
176     lb_addrs->addresses[i].address =
177         TestAddressToGrpcResolvedAddress(test_addrs[i]);
178   }
179   return lb_addrs;
180 }
181 
VerifyLbAddrOutputs(grpc_lb_addresses * lb_addrs,std::vector<std::string> expected_addrs)182 void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs,
183                          std::vector<std::string> expected_addrs) {
184   EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size());
185   for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
186     char* ip_addr_str;
187     grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address,
188                             false /* normalize */);
189     EXPECT_EQ(expected_addrs[i], ip_addr_str);
190     gpr_free(ip_addr_str);
191   }
192   grpc_core::ExecCtx exec_ctx;
193   grpc_lb_addresses_destroy(lb_addrs);
194 }
195 
196 /* We need to run each test case inside of its own
197  * isolated grpc_init/grpc_shutdown pair, so that
198  * the "address sorting source addr factory" can be
199  * restored to its default for each test case. */
200 class AddressSortingTest : public ::testing::Test {
201  protected:
SetUp()202   void SetUp() override { grpc_init(); }
TearDown()203   void TearDown() override { grpc_shutdown(); }
204 };
205 
206 /* Tests for rule 1 */
TEST_F(AddressSortingTest,TestDepriotizesUnreachableAddresses)207 TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
208   bool ipv4_supported = true;
209   bool ipv6_supported = true;
210   OverrideAddressSortingSourceAddrFactory(
211       ipv4_supported, ipv6_supported,
212       {
213           {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}},
214       });
215   auto* lb_addrs = BuildLbAddrInputs({
216       {"1.2.3.4:443", AF_INET},
217       {"5.6.7.8:443", AF_INET},
218   });
219   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
220   VerifyLbAddrOutputs(lb_addrs, {
221                                     "1.2.3.4:443",
222                                     "5.6.7.8:443",
223                                 });
224 }
225 
TEST_F(AddressSortingTest,TestDepriotizesUnsupportedDomainIpv6)226 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
227   bool ipv4_supported = true;
228   bool ipv6_supported = false;
229   OverrideAddressSortingSourceAddrFactory(
230       ipv4_supported, ipv6_supported,
231       {
232           {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
233       });
234   auto lb_addrs = BuildLbAddrInputs({
235       {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
236       {"1.2.3.4:443", AF_INET},
237   });
238   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
239   VerifyLbAddrOutputs(lb_addrs, {
240                                     "1.2.3.4:443",
241                                     "[2607:f8b0:400a:801::1002]:443",
242                                 });
243 }
244 
TEST_F(AddressSortingTest,TestDepriotizesUnsupportedDomainIpv4)245 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
246   bool ipv4_supported = false;
247   bool ipv6_supported = true;
248   OverrideAddressSortingSourceAddrFactory(
249       ipv4_supported, ipv6_supported,
250       {
251           {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
252           {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}},
253       });
254   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
255       {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
256       {"1.2.3.4:443", AF_INET},
257   });
258   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
259   VerifyLbAddrOutputs(lb_addrs, {
260                                     "[2607:f8b0:400a:801::1002]:443",
261                                     "1.2.3.4:443",
262                                 });
263 }
264 
265 /* Tests for rule 2 */
266 
TEST_F(AddressSortingTest,TestDepriotizesNonMatchingScope)267 TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
268   bool ipv4_supported = true;
269   bool ipv6_supported = true;
270   OverrideAddressSortingSourceAddrFactory(
271       ipv4_supported, ipv6_supported,
272       {
273           {"[2000:f8b0:400a:801::1002]:443",
274            {"[fec0::1000]:0", AF_INET6}},  // global and site-local scope
275           {"[fec0::5000]:443",
276            {"[fec0::5001]:0", AF_INET6}},  // site-local and site-local scope
277       });
278   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
279       {"[2000:f8b0:400a:801::1002]:443", AF_INET6},
280       {"[fec0::5000]:443", AF_INET6},
281   });
282   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
283   VerifyLbAddrOutputs(lb_addrs, {
284                                     "[fec0::5000]:443",
285                                     "[2000:f8b0:400a:801::1002]:443",
286                                 });
287 }
288 
289 /* Tests for rule 5 */
290 
TEST_F(AddressSortingTest,TestUsesLabelFromDefaultTable)291 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
292   bool ipv4_supported = true;
293   bool ipv6_supported = true;
294   OverrideAddressSortingSourceAddrFactory(
295       ipv4_supported, ipv6_supported,
296       {
297           {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
298           {"[2001::5001]:443",
299            {"[2001::5002]:0", AF_INET6}},  // matching labels
300       });
301   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
302       {"[2002::5001]:443", AF_INET6},
303       {"[2001::5001]:443", AF_INET6},
304   });
305   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
306   VerifyLbAddrOutputs(lb_addrs, {
307                                     "[2001::5001]:443",
308                                     "[2002::5001]:443",
309                                 });
310 }
311 
312 /* Flip the input on the test above to reorder the sort function's
313  * comparator's inputs. */
TEST_F(AddressSortingTest,TestUsesLabelFromDefaultTableInputFlipped)314 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
315   bool ipv4_supported = true;
316   bool ipv6_supported = true;
317   OverrideAddressSortingSourceAddrFactory(
318       ipv4_supported, ipv6_supported,
319       {
320           {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
321           {"[2001::5001]:443",
322            {"[2001::5002]:0", AF_INET6}},  // matching labels
323       });
324   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
325       {"[2001::5001]:443", AF_INET6},
326       {"[2002::5001]:443", AF_INET6},
327   });
328   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
329   VerifyLbAddrOutputs(lb_addrs, {
330                                     "[2001::5001]:443",
331                                     "[2002::5001]:443",
332                                 });
333 }
334 
335 /* Tests for rule 6 */
336 
TEST_F(AddressSortingTest,TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address)337 TEST_F(AddressSortingTest,
338        TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) {
339   bool ipv4_supported = true;
340   bool ipv6_supported = true;
341   OverrideAddressSortingSourceAddrFactory(
342       ipv4_supported, ipv6_supported,
343       {
344           {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
345           {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}},
346       });
347   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
348       {"[3ffe::5001]:443", AF_INET6},
349       {"1.2.3.4:443", AF_INET},
350   });
351   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
352   VerifyLbAddrOutputs(
353       lb_addrs, {
354                     // The AF_INET address should be IPv4-mapped by the sort,
355                     // and IPv4-mapped
356                     // addresses have higher precedence than 3ffe::/16 by spec.
357                     "1.2.3.4:443",
358                     "[3ffe::5001]:443",
359                 });
360 }
361 
TEST_F(AddressSortingTest,TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress)362 TEST_F(AddressSortingTest,
363        TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress) {
364   bool ipv4_supported = true;
365   bool ipv6_supported = true;
366 // Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
367 #if GPR_APPLE == 1
368   const char* v4_compat_dest = "[::0.0.0.2]:443";
369   const char* v4_compat_src = "[::0.0.0.2]:0";
370 #else
371   const char* v4_compat_dest = "[::2]:443";
372   const char* v4_compat_src = "[::2]:0";
373 #endif
374   OverrideAddressSortingSourceAddrFactory(
375       ipv4_supported, ipv6_supported,
376       {
377           {"[::1]:443", {"[::1]:0", AF_INET6}},
378           {v4_compat_dest, {v4_compat_src, AF_INET6}},
379       });
380   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
381       {v4_compat_dest, AF_INET6},
382       {"[::1]:443", AF_INET6},
383   });
384   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
385   VerifyLbAddrOutputs(lb_addrs, {
386                                     "[::1]:443",
387                                     v4_compat_dest,
388                                 });
389 }
390 
TEST_F(AddressSortingTest,TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress)391 TEST_F(AddressSortingTest,
392        TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) {
393   bool ipv4_supported = true;
394   bool ipv6_supported = true;
395   OverrideAddressSortingSourceAddrFactory(
396       ipv4_supported, ipv6_supported,
397       {
398           // 1234::2 for src and dest to make sure that prefix matching has no
399           // influence on this test.
400           {"[1234::2]:443", {"[1234::2]:0", AF_INET6}},
401           {"[::1]:443", {"[::1]:0", AF_INET6}},
402       });
403   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
404       {"[1234::2]:443", AF_INET6},
405       {"[::1]:443", AF_INET6},
406   });
407   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
408   VerifyLbAddrOutputs(
409       lb_addrs,
410       {
411           // ::1 should match the localhost precedence entry and be prioritized
412           "[::1]:443",
413           "[1234::2]:443",
414       });
415 }
416 
TEST_F(AddressSortingTest,TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress)417 TEST_F(AddressSortingTest,
418        TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {
419   bool ipv4_supported = true;
420   bool ipv6_supported = true;
421   OverrideAddressSortingSourceAddrFactory(
422       ipv4_supported, ipv6_supported,
423       {
424           {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}},
425           {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
426       });
427   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
428       {"[2001::1234]:443", AF_INET6},
429       {"[2000::5001]:443", AF_INET6},
430   });
431   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
432   VerifyLbAddrOutputs(
433       lb_addrs, {
434                     // The 2000::/16 address should match the ::/0 prefix rule
435                     "[2000::5001]:443",
436                     "[2001::1234]:443",
437                 });
438 }
439 
TEST_F(AddressSortingTest,TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect)440 TEST_F(
441     AddressSortingTest,
442     TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect) {
443   bool ipv4_supported = true;
444   bool ipv6_supported = true;
445   OverrideAddressSortingSourceAddrFactory(
446       ipv4_supported, ipv6_supported,
447       {
448           {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}},
449           {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
450       });
451   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
452       {"[2001::1231]:443", AF_INET6},
453       {"[2000::5001]:443", AF_INET6},
454   });
455   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
456   VerifyLbAddrOutputs(lb_addrs, {
457                                     "[2000::5001]:443",
458                                     "[2001::1231]:443",
459                                 });
460 }
461 
TEST_F(AddressSortingTest,TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses)462 TEST_F(AddressSortingTest,
463        TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) {
464   bool ipv4_supported = true;
465   bool ipv6_supported = true;
466   OverrideAddressSortingSourceAddrFactory(
467       ipv4_supported, ipv6_supported,
468       {
469           {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
470           {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}},
471       });
472   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
473       {"[fec0::1234]:443", AF_INET6},
474       {"[fc00::5001]:443", AF_INET6},
475   });
476   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
477   VerifyLbAddrOutputs(lb_addrs, {
478                                     "[fc00::5001]:443",
479                                     "[fec0::1234]:443",
480                                 });
481 }
482 
TEST_F(AddressSortingTest,TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses)483 TEST_F(
484     AddressSortingTest,
485     TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses) {
486   bool ipv4_supported = true;
487   bool ipv6_supported = true;
488   // Use embedded ipv4 addresses with leading 1's instead of zero's to be
489   // compatible with inet_ntop implementations that can display such
490   // addresses with leading zero's as e.g.: "::ffff:0:2", as on windows.
491   OverrideAddressSortingSourceAddrFactory(
492       ipv4_supported, ipv6_supported,
493       {
494           {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}},
495           {"[1234::2]:443", {"[1234::3]:0", AF_INET6}},
496       });
497   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
498       {"[::ffff:1.1.1.2]:443", AF_INET6},
499       {"[1234::2]:443", AF_INET6},
500   });
501   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
502   VerifyLbAddrOutputs(lb_addrs, {
503                                     // ::ffff:0:2 should match the v4-mapped
504                                     // precedence entry and be deprioritized.
505                                     "[1234::2]:443",
506                                     "[::ffff:1.1.1.2]:443",
507                                 });
508 }
509 
510 /* Tests for rule 8 */
511 
TEST_F(AddressSortingTest,TestPrefersSmallerScope)512 TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
513   bool ipv4_supported = true;
514   bool ipv6_supported = true;
515   OverrideAddressSortingSourceAddrFactory(
516       ipv4_supported, ipv6_supported,
517       {
518           // Both of these destinations have the same precedence in default
519           // policy
520           // table.
521           {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
522           {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
523       });
524   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
525       {"[3ffe::5001]:443", AF_INET6},
526       {"[fec0::1234]:443", AF_INET6},
527   });
528   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
529   VerifyLbAddrOutputs(lb_addrs, {
530                                     "[fec0::1234]:443",
531                                     "[3ffe::5001]:443",
532                                 });
533 }
534 
535 /* Tests for rule 9 */
536 
TEST_F(AddressSortingTest,TestPrefersLongestMatchingSrcDstPrefix)537 TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
538   bool ipv4_supported = true;
539   bool ipv6_supported = true;
540   OverrideAddressSortingSourceAddrFactory(
541       ipv4_supported, ipv6_supported,
542       {
543           // Both of these destinations have the same precedence in default
544           // policy
545           // table.
546           {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}},
547           {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}},
548       });
549   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
550       {"[3ffe:5001::]:443", AF_INET6},
551       {"[3ffe:1234::]:443", AF_INET6},
552   });
553   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
554   VerifyLbAddrOutputs(lb_addrs, {
555                                     "[3ffe:1234::]:443",
556                                     "[3ffe:5001::]:443",
557                                 });
558 }
559 
TEST_F(AddressSortingTest,TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress)560 TEST_F(AddressSortingTest,
561        TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) {
562   bool ipv4_supported = true;
563   bool ipv6_supported = true;
564   OverrideAddressSortingSourceAddrFactory(
565       ipv4_supported, ipv6_supported,
566       {
567           {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}},
568           {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}},
569       });
570   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
571       {"[3ffe::5001]:443", AF_INET6},
572       {"[3ffe::1234]:443", AF_INET6},
573   });
574   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
575   VerifyLbAddrOutputs(lb_addrs, {
576                                     "[3ffe::1234]:443",
577                                     "[3ffe::5001]:443",
578                                 });
579 }
580 
TEST_F(AddressSortingTest,TestPrefersLongestPrefixStressInnerBytePrefix)581 TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
582   bool ipv4_supported = true;
583   bool ipv6_supported = true;
584   OverrideAddressSortingSourceAddrFactory(
585       ipv4_supported, ipv6_supported,
586       {
587           {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}},
588           {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}},
589       });
590   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
591       {"[3ffe:8000::]:443", AF_INET6},
592       {"[3ffe:2000::]:443", AF_INET6},
593   });
594   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
595   VerifyLbAddrOutputs(lb_addrs, {
596                                     "[3ffe:2000::]:443",
597                                     "[3ffe:8000::]:443",
598                                 });
599 }
600 
TEST_F(AddressSortingTest,TestPrefersLongestPrefixDiffersOnHighestBitOfByte)601 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
602   bool ipv4_supported = true;
603   bool ipv6_supported = true;
604   OverrideAddressSortingSourceAddrFactory(
605       ipv4_supported, ipv6_supported,
606       {
607           {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}},
608           {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}},
609       });
610   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
611       {"[3ffe:6::]:443", AF_INET6},
612       {"[3ffe:c::]:443", AF_INET6},
613   });
614   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
615   VerifyLbAddrOutputs(lb_addrs, {
616                                     "[3ffe:c::]:443",
617                                     "[3ffe:6::]:443",
618                                 });
619 }
620 
TEST_F(AddressSortingTest,TestPrefersLongestPrefixDiffersByLastBit)621 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
622   bool ipv4_supported = true;
623   bool ipv6_supported = true;
624   OverrideAddressSortingSourceAddrFactory(
625       ipv4_supported, ipv6_supported,
626       {
627           {"[3ffe:1111:1111:1111::]:443",
628            {"[3ffe:1111:1111:1111::]:0", AF_INET6}},
629           {"[3ffe:1111:1111:1110::]:443",
630            {"[3ffe:1111:1111:1111::]:0", AF_INET6}},
631       });
632   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
633       {"[3ffe:1111:1111:1110::]:443", AF_INET6},
634       {"[3ffe:1111:1111:1111::]:443", AF_INET6},
635   });
636   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
637   VerifyLbAddrOutputs(lb_addrs, {
638                                     "[3ffe:1111:1111:1111::]:443",
639                                     "[3ffe:1111:1111:1110::]:443",
640                                 });
641 }
642 
643 /* Tests for rule 10 */
644 
TEST_F(AddressSortingTest,TestStableSort)645 TEST_F(AddressSortingTest, TestStableSort) {
646   bool ipv4_supported = true;
647   bool ipv6_supported = true;
648   OverrideAddressSortingSourceAddrFactory(
649       ipv4_supported, ipv6_supported,
650       {
651           {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}},
652           {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}},
653       });
654   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
655       {"[3ffe::1234]:443", AF_INET6},
656       {"[3ffe::1235]:443", AF_INET6},
657   });
658   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
659   VerifyLbAddrOutputs(lb_addrs, {
660                                     "[3ffe::1234]:443",
661                                     "[3ffe::1235]:443",
662                                 });
663 }
664 
TEST_F(AddressSortingTest,TestStableSortFiveElements)665 TEST_F(AddressSortingTest, TestStableSortFiveElements) {
666   bool ipv4_supported = true;
667   bool ipv6_supported = true;
668   OverrideAddressSortingSourceAddrFactory(
669       ipv4_supported, ipv6_supported,
670       {
671           {"[3ffe::1231]:443", {"[3ffe::1201]:0", AF_INET6}},
672           {"[3ffe::1232]:443", {"[3ffe::1202]:0", AF_INET6}},
673           {"[3ffe::1233]:443", {"[3ffe::1203]:0", AF_INET6}},
674           {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}},
675           {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}},
676       });
677   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
678       {"[3ffe::1231]:443", AF_INET6},
679       {"[3ffe::1232]:443", AF_INET6},
680       {"[3ffe::1233]:443", AF_INET6},
681       {"[3ffe::1234]:443", AF_INET6},
682       {"[3ffe::1235]:443", AF_INET6},
683   });
684   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
685   VerifyLbAddrOutputs(lb_addrs, {
686                                     "[3ffe::1231]:443",
687                                     "[3ffe::1232]:443",
688                                     "[3ffe::1233]:443",
689                                     "[3ffe::1234]:443",
690                                     "[3ffe::1235]:443",
691                                 });
692 }
693 
TEST_F(AddressSortingTest,TestStableSortNoSrcAddrsExist)694 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
695   bool ipv4_supported = true;
696   bool ipv6_supported = true;
697   OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
698   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
699       {"[3ffe::1231]:443", AF_INET6},
700       {"[3ffe::1232]:443", AF_INET6},
701       {"[3ffe::1233]:443", AF_INET6},
702       {"[3ffe::1234]:443", AF_INET6},
703       {"[3ffe::1235]:443", AF_INET6},
704   });
705   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
706   VerifyLbAddrOutputs(lb_addrs, {
707                                     "[3ffe::1231]:443",
708                                     "[3ffe::1232]:443",
709                                     "[3ffe::1233]:443",
710                                     "[3ffe::1234]:443",
711                                     "[3ffe::1235]:443",
712                                 });
713 }
714 
TEST_F(AddressSortingTest,TestStableSortNoSrcAddrsExistWithIpv4)715 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
716   bool ipv4_supported = true;
717   bool ipv6_supported = true;
718   OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
719   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
720       {"[::ffff:5.6.7.8]:443", AF_INET6},
721       {"1.2.3.4:443", AF_INET},
722   });
723   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
724   VerifyLbAddrOutputs(lb_addrs, {
725                                     "[::ffff:5.6.7.8]:443",
726                                     "1.2.3.4:443",
727                                 });
728 }
729 
TEST_F(AddressSortingTest,TestStableSortV4CompatAndSiteLocalAddresses)730 TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
731   bool ipv4_supported = true;
732   bool ipv6_supported = true;
733 // Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
734 #if GPR_APPLE == 1
735   const char* v4_compat_dest = "[::0.0.0.2]:443";
736   const char* v4_compat_src = "[::0.0.0.3]:0";
737 #else
738   const char* v4_compat_dest = "[::2]:443";
739   const char* v4_compat_src = "[::3]:0";
740 #endif
741   OverrideAddressSortingSourceAddrFactory(
742       ipv4_supported, ipv6_supported,
743       {
744           {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}},
745           {v4_compat_dest, {v4_compat_src, AF_INET6}},
746       });
747   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
748       {"[fec0::2000]:443", AF_INET6},
749       {v4_compat_dest, AF_INET6},
750   });
751   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
752   VerifyLbAddrOutputs(lb_addrs,
753                       {
754                           // The sort should be stable since
755                           // v4-compatible has same precedence as site-local.
756                           "[fec0::2000]:443",
757                           v4_compat_dest,
758                       });
759 }
760 
761 /* TestPrefersIpv6Loopback tests the actual "address probing" code
762  * for the current platform, without any mocks.
763  * This test relies on the assumption that the ipv6 loopback address is
764  * available in the hosts/containers that grpc C/C++ tests run on
765  * (whether ipv4 loopback is available or not, an available ipv6
766  * loopback should be preferred). */
TEST_F(AddressSortingTest,TestPrefersIpv6Loopback)767 TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
768   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
769       {"[::1]:443", AF_INET6},
770       {"127.0.0.1:443", AF_INET},
771   });
772   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
773   VerifyLbAddrOutputs(lb_addrs, {
774                                     "[::1]:443",
775                                     "127.0.0.1:443",
776                                 });
777 }
778 
779 /* Flip the order of the inputs above and expect the same output order
780  * (try to rule out influence of arbitrary qsort ordering) */
TEST_F(AddressSortingTest,TestPrefersIpv6LoopbackInputsFlipped)781 TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {
782   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
783       {"127.0.0.1:443", AF_INET},
784       {"[::1]:443", AF_INET6},
785   });
786   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
787   VerifyLbAddrOutputs(lb_addrs, {
788                                     "[::1]:443",
789                                     "127.0.0.1:443",
790                                 });
791 }
792 
793 /* Try to rule out false positives in the above two tests in which
794  * the sorter might think that neither ipv6 or ipv4 loopback is
795  * available, but ipv6 loopback is still preferred only due
796  * to precedance table lookups. */
TEST_F(AddressSortingTest,TestSorterKnowsIpv6LoopbackIsAvailable)797 TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) {
798   sockaddr_in6 ipv6_loopback;
799   memset(&ipv6_loopback, 0, sizeof(ipv6_loopback));
800   ipv6_loopback.sin6_family = AF_INET6;
801   ((char*)&ipv6_loopback.sin6_addr)[15] = 1;
802   ipv6_loopback.sin6_port = htons(443);
803   // Set up the source and destination parameters of
804   // address_sorting_get_source_addr
805   address_sorting_address sort_input_dest;
806   memcpy(&sort_input_dest.addr, &ipv6_loopback, sizeof(ipv6_loopback));
807   sort_input_dest.len = sizeof(ipv6_loopback);
808   address_sorting_address source_for_sort_input_dest;
809   memset(&source_for_sort_input_dest, 0, sizeof(source_for_sort_input_dest));
810   // address_sorting_get_source_addr returns true if a source address was found
811   // for the destination address, otherwise false.
812   EXPECT_TRUE(address_sorting_get_source_addr_for_testing(
813       &sort_input_dest, &source_for_sort_input_dest));
814   // Now also check that the source address was filled in correctly.
815   EXPECT_GT(source_for_sort_input_dest.len, 0u);
816   sockaddr_in6* source_addr_output =
817       (sockaddr_in6*)source_for_sort_input_dest.addr;
818   EXPECT_EQ(source_addr_output->sin6_family, AF_INET6);
819   char* buf = static_cast<char*>(gpr_zalloc(100));
820   EXPECT_NE(inet_ntop(AF_INET6, &source_addr_output->sin6_addr, buf, 100),
821             nullptr)
822       << "inet_ntop failed. Errno: " + std::to_string(errno);
823   std::string source_addr_str(buf);
824   gpr_free(buf);
825   // This test
826   // assumes that the source address for any loopback destination is also the
827   // loopback address.
828   EXPECT_EQ(source_addr_str, "::1");
829 }
830 
831 }  // namespace
832 
main(int argc,char ** argv)833 int main(int argc, char** argv) {
834   char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");
835   if (resolver == nullptr || strlen(resolver) == 0) {
836     gpr_setenv("GRPC_DNS_RESOLVER", "ares");
837   } else if (strcmp("ares", resolver)) {
838     gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver);
839   }
840   gpr_free(resolver);
841   grpc_test_init(argc, argv);
842   ::testing::InitGoogleTest(&argc, argv);
843   auto result = RUN_ALL_TESTS();
844   // Test sequential and nested inits and shutdowns.
845   grpc_init();
846   grpc_init();
847   grpc_shutdown();
848   grpc_shutdown();
849   grpc_init();
850   grpc_shutdown();
851   return result;
852 }
853