xref: /aosp_15_r20/external/cronet/net/dns/public/win_dns_system_settings_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/dns/public/win_dns_system_settings.h"
6 
7 #include "testing/gtest/include/gtest/gtest.h"
8 
9 namespace net {
10 
11 namespace {
12 
13 struct AdapterInfo {
14   IFTYPE if_type;
15   IF_OPER_STATUS oper_status;
16   const WCHAR* dns_suffix;
17   std::string dns_server_addresses[4];  // Empty string indicates end.
18   uint16_t ports[4];
19 };
20 
CreateAdapterAddresses(const AdapterInfo * infos)21 std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> CreateAdapterAddresses(
22     const AdapterInfo* infos) {
23   size_t num_adapters = 0;
24   size_t num_addresses = 0;
25   for (size_t i = 0; infos[i].if_type; ++i) {
26     ++num_adapters;
27     for (size_t j = 0; !infos[i].dns_server_addresses[j].empty(); ++j) {
28       ++num_addresses;
29     }
30   }
31 
32   size_t heap_size = num_adapters * sizeof(IP_ADAPTER_ADDRESSES) +
33                      num_addresses * (sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS) +
34                                       sizeof(struct sockaddr_storage));
35   std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> heap(
36       static_cast<IP_ADAPTER_ADDRESSES*>(malloc(heap_size)));
37   CHECK(heap.get());
38   memset(heap.get(), 0, heap_size);
39 
40   IP_ADAPTER_ADDRESSES* adapters = heap.get();
41   IP_ADAPTER_DNS_SERVER_ADDRESS* addresses =
42       reinterpret_cast<IP_ADAPTER_DNS_SERVER_ADDRESS*>(adapters + num_adapters);
43   struct sockaddr_storage* storage =
44       reinterpret_cast<struct sockaddr_storage*>(addresses + num_addresses);
45 
46   for (size_t i = 0; i < num_adapters; ++i) {
47     const AdapterInfo& info = infos[i];
48     IP_ADAPTER_ADDRESSES* adapter = adapters + i;
49     if (i + 1 < num_adapters)
50       adapter->Next = adapter + 1;
51     adapter->IfType = info.if_type;
52     adapter->OperStatus = info.oper_status;
53     adapter->DnsSuffix = const_cast<PWCHAR>(info.dns_suffix);
54     IP_ADAPTER_DNS_SERVER_ADDRESS* address = nullptr;
55     for (size_t j = 0; !info.dns_server_addresses[j].empty(); ++j) {
56       --num_addresses;
57       if (j == 0) {
58         address = adapter->FirstDnsServerAddress = addresses + num_addresses;
59       } else {
60         // Note that |address| is moving backwards.
61         address = address->Next = address - 1;
62       }
63       IPAddress ip;
64       CHECK(ip.AssignFromIPLiteral(info.dns_server_addresses[j]));
65       IPEndPoint ipe = IPEndPoint(ip, info.ports[j]);
66       address->Address.lpSockaddr =
67           reinterpret_cast<LPSOCKADDR>(storage + num_addresses);
68       socklen_t length = sizeof(struct sockaddr_storage);
69       CHECK(ipe.ToSockAddr(address->Address.lpSockaddr, &length));
70       address->Address.iSockaddrLength = static_cast<int>(length);
71     }
72   }
73 
74   return heap;
75 }
76 
TEST(WinDnsSystemSettings,GetAllNameServersEmpty)77 TEST(WinDnsSystemSettings, GetAllNameServersEmpty) {
78   AdapterInfo infos[3] = {
79       {
80           .if_type = IF_TYPE_USB,
81           .oper_status = IfOperStatusUp,
82           .dns_suffix = L"example.com",
83           .dns_server_addresses = {},
84       },
85       {
86           .if_type = IF_TYPE_USB,
87           .oper_status = IfOperStatusUp,
88           .dns_suffix = L"foo.bar",
89           .dns_server_addresses = {},
90       },
91       {0}};
92 
93   WinDnsSystemSettings settings;
94   settings.addresses = CreateAdapterAddresses(infos);
95   std::optional<std::vector<IPEndPoint>> nameservers =
96       settings.GetAllNameservers();
97   EXPECT_TRUE(nameservers.has_value());
98   EXPECT_TRUE(nameservers.value().empty());
99 }
100 
TEST(WinDnsSystemSettings,GetAllNameServersStatelessDiscoveryAdresses)101 TEST(WinDnsSystemSettings, GetAllNameServersStatelessDiscoveryAdresses) {
102   AdapterInfo infos[3] = {
103       {
104           .if_type = IF_TYPE_USB,
105           .oper_status = IfOperStatusUp,
106           .dns_suffix = L"example.com",
107           .dns_server_addresses = {"fec0:0:0:ffff::1", "fec0:0:0:ffff::2"},
108       },
109       {
110           .if_type = IF_TYPE_USB,
111           .oper_status = IfOperStatusUp,
112           .dns_suffix = L"foo.bar",
113           .dns_server_addresses = {"fec0:0:0:ffff::3"},
114       },
115       {0}};
116 
117   WinDnsSystemSettings settings;
118   settings.addresses = CreateAdapterAddresses(infos);
119   std::optional<std::vector<IPEndPoint>> nameservers =
120       settings.GetAllNameservers();
121   EXPECT_TRUE(nameservers.has_value());
122   EXPECT_TRUE(nameservers.value().empty());
123 }
124 
TEST(WinDnsSystemSettings,GetAllNameServersValid)125 TEST(WinDnsSystemSettings, GetAllNameServersValid) {
126   AdapterInfo infos[3] = {
127       {.if_type = IF_TYPE_USB,
128        .oper_status = IfOperStatusUp,
129        .dns_suffix = L"example.com",
130        .dns_server_addresses = {"8.8.8.8", "10.0.0.10"},
131        .ports = {11, 22}},
132       {.if_type = IF_TYPE_USB,
133        .oper_status = IfOperStatusUp,
134        .dns_suffix = L"foo.bar",
135        .dns_server_addresses = {"2001:ffff::1111",
136                                 "aaaa:bbbb:cccc:dddd:eeee:ffff:0:1"},
137        .ports = {33, 44}},
138       {0}};
139 
140   WinDnsSystemSettings settings;
141   settings.addresses = CreateAdapterAddresses(infos);
142   std::optional<std::vector<IPEndPoint>> nameservers =
143       settings.GetAllNameservers();
144   EXPECT_TRUE(nameservers.has_value());
145   EXPECT_EQ(4u, nameservers.value().size());
146   EXPECT_EQ(nameservers.value()[0].ToString(), "8.8.8.8:11");
147   EXPECT_EQ(nameservers.value()[1].ToString(), "10.0.0.10:22");
148   EXPECT_EQ(nameservers.value()[2].ToString(), "[2001:ffff::1111]:33");
149   EXPECT_EQ(nameservers.value()[3].ToString(),
150             "[aaaa:bbbb:cccc:dddd:eeee:ffff:0:1]:44");
151 }
152 }  // namespace
153 
154 }  // namespace net
155