OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
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 <resolv.h> | |
6 | |
7 #include "base/sys_byteorder.h" | |
8 #include "net/dns/dns_config_service_posix.h" | |
9 | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 | |
12 #if !defined(OS_ANDROID) | |
13 | |
14 namespace net { | |
15 namespace { | |
16 | |
17 // MAXNS is normally 3, but let's test 4 if possible. | |
18 const char* const kNameserversIPv4[] = { | |
19 "8.8.8.8", | |
20 "192.168.1.1", | |
21 "63.1.2.4", | |
22 "1.0.0.1", | |
23 }; | |
24 | |
25 #if defined(OS_LINUX) | |
26 const char* const kNameserversIPv6[] = { | |
27 NULL, | |
28 "2001:DB8:0::42", | |
29 NULL, | |
30 "::FFFF:129.144.52.38", | |
31 }; | |
32 #endif | |
33 | |
34 // Fills in |res| with sane configuration. | |
35 void InitializeResState(res_state res) { | |
36 memset(res, 0, sizeof(*res)); | |
37 res->options = RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH | | |
38 RES_ROTATE; | |
39 res->ndots = 2; | |
40 res->retrans = 4; | |
41 res->retry = 7; | |
42 | |
43 const char kDnsrch[] = "chromium.org" "\0" "example.com"; | |
44 memcpy(res->defdname, kDnsrch, sizeof(kDnsrch)); | |
45 res->dnsrch[0] = res->defdname; | |
46 res->dnsrch[1] = res->defdname + sizeof("chromium.org"); | |
47 | |
48 for (unsigned i = 0; i < arraysize(kNameserversIPv4) && i < MAXNS; ++i) { | |
49 struct sockaddr_in sa; | |
50 sa.sin_family = AF_INET; | |
51 sa.sin_port = base::HostToNet16(NS_DEFAULTPORT + i); | |
52 inet_pton(AF_INET, kNameserversIPv4[i], &sa.sin_addr); | |
53 res->nsaddr_list[i] = sa; | |
54 ++res->nscount; | |
55 } | |
56 | |
57 #if defined(OS_LINUX) | |
58 // Install IPv6 addresses, replacing the corresponding IPv4 addresses. | |
59 unsigned nscount6 = 0; | |
60 for (unsigned i = 0; i < arraysize(kNameserversIPv6) && i < MAXNS; ++i) { | |
61 if (!kNameserversIPv6[i]) | |
62 continue; | |
63 // Must use malloc to mimick res_ninit. | |
64 struct sockaddr_in6 *sa6; | |
65 sa6 = (struct sockaddr_in6 *)malloc(sizeof(*sa6)); | |
66 sa6->sin6_family = AF_INET6; | |
67 sa6->sin6_port = base::HostToNet16(NS_DEFAULTPORT - i); | |
68 inet_pton(AF_INET6, kNameserversIPv6[i], &sa6->sin6_addr); | |
69 res->_u._ext.nsaddrs[i] = sa6; | |
70 memset(&res->nsaddr_list[i], 0, sizeof res->nsaddr_list[i]); | |
71 ++nscount6; | |
72 } | |
73 res->_u._ext.nscount6 = nscount6; | |
74 #endif | |
75 } | |
76 | |
77 void CloseResState(res_state res) { | |
78 #if defined(OS_LINUX) | |
79 for (int i = 0; i < res->nscount; ++i) { | |
80 if (res->_u._ext.nsaddrs[i] != NULL) | |
81 free(res->_u._ext.nsaddrs[i]); | |
82 } | |
83 #endif | |
84 } | |
85 | |
86 void InitializeExpectedConfig(DnsConfig* config) { | |
87 config->ndots = 2; | |
88 config->timeout = base::TimeDelta::FromSeconds(4); | |
89 config->attempts = 7; | |
90 config->rotate = true; | |
91 config->edns0 = false; | |
92 config->append_to_multi_label_name = true; | |
93 config->search.clear(); | |
94 config->search.push_back("chromium.org"); | |
95 config->search.push_back("example.com"); | |
96 | |
97 config->nameservers.clear(); | |
98 for (unsigned i = 0; i < arraysize(kNameserversIPv4) && i < MAXNS; ++i) { | |
99 IPAddressNumber ip; | |
100 ParseIPLiteralToNumber(kNameserversIPv4[i], &ip); | |
101 config->nameservers.push_back(IPEndPoint(ip, NS_DEFAULTPORT + i)); | |
102 } | |
103 | |
104 #if defined(OS_LINUX) | |
105 for (unsigned i = 0; i < arraysize(kNameserversIPv6) && i < MAXNS; ++i) { | |
106 if (!kNameserversIPv6[i]) | |
107 continue; | |
108 IPAddressNumber ip; | |
109 ParseIPLiteralToNumber(kNameserversIPv6[i], &ip); | |
110 config->nameservers[i] = IPEndPoint(ip, NS_DEFAULTPORT - i); | |
111 } | |
112 #endif | |
113 } | |
114 | |
115 TEST(DnsConfigServicePosixTest, ConvertResStateToDnsConfig) { | |
116 struct __res_state res; | |
117 DnsConfig config; | |
118 EXPECT_FALSE(config.IsValid()); | |
119 InitializeResState(&res); | |
120 ASSERT_EQ(internal::CONFIG_PARSE_POSIX_OK, | |
121 internal::ConvertResStateToDnsConfig(res, &config)); | |
122 CloseResState(&res); | |
123 EXPECT_TRUE(config.IsValid()); | |
124 | |
125 DnsConfig expected_config; | |
126 EXPECT_FALSE(expected_config.EqualsIgnoreHosts(config)); | |
127 InitializeExpectedConfig(&expected_config); | |
128 EXPECT_TRUE(expected_config.EqualsIgnoreHosts(config)); | |
129 } | |
130 | |
131 TEST(DnsConfigServicePosixTest, RejectEmptyNameserver) { | |
132 struct __res_state res = {}; | |
133 res.options = RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH; | |
134 const char kDnsrch[] = "chromium.org"; | |
135 memcpy(res.defdname, kDnsrch, sizeof(kDnsrch)); | |
136 res.dnsrch[0] = res.defdname; | |
137 | |
138 struct sockaddr_in sa = {}; | |
139 sa.sin_family = AF_INET; | |
140 sa.sin_port = base::HostToNet16(NS_DEFAULTPORT); | |
141 sa.sin_addr.s_addr = INADDR_ANY; | |
142 res.nsaddr_list[0] = sa; | |
143 sa.sin_addr.s_addr = 0xCAFE1337; | |
144 res.nsaddr_list[1] = sa; | |
145 res.nscount = 2; | |
146 | |
147 DnsConfig config; | |
148 EXPECT_EQ(internal::CONFIG_PARSE_POSIX_NULL_ADDRESS, | |
149 internal::ConvertResStateToDnsConfig(res, &config)); | |
150 | |
151 sa.sin_addr.s_addr = 0xDEADBEEF; | |
152 res.nsaddr_list[0] = sa; | |
153 EXPECT_EQ(internal::CONFIG_PARSE_POSIX_OK, | |
154 internal::ConvertResStateToDnsConfig(res, &config)); | |
155 } | |
156 | |
157 } // namespace | |
158 } // namespace net | |
159 | |
160 #endif // !OS_ANDROID | |
OLD | NEW |