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