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.
5 #include "net/base/net_util.h"
11 #include "base/files/file_path.h"
12 #include "base/format_macros.h"
13 #include "base/scoped_native_library.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/sys_byteorder.h"
19 #include "base/time/time.h"
20 #include "net/base/address_list.h"
21 #include "net/base/ip_endpoint.h"
23 #if !defined(OS_NACL) && !defined(OS_WIN)
25 #include <netinet/in.h>
26 #if defined(OS_MACOSX)
29 #include <netinet/in_var.h>
32 #endif // !OS_NACL && !OS_WIN
33 #include "testing/gtest/include/gtest/gtest.h"
39 #include "base/win/windows_version.h"
42 #if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_WIN)
43 #include "net/base/address_tracker_linux.h"
44 #endif // !OS_MACOSX && !OS_NACL && !OS_WIN
46 using base::ASCIIToUTF16
;
47 using base::WideToUTF16
;
54 const char* const header_name
;
55 const char* const expected
;
58 const unsigned char kLocalhostIPv4
[] = {127, 0, 0, 1};
59 const unsigned char kLocalhostIPv6
[] =
60 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
61 const uint16_t kLocalhostLookupPort
= 80;
63 // Fills in sockaddr for the given 32-bit address (IPv4.)
64 // |bytes| should be an array of length 4.
65 void MakeIPv4Address(const uint8_t* bytes
, int port
, SockaddrStorage
* storage
) {
66 memset(&storage
->addr_storage
, 0, sizeof(storage
->addr_storage
));
67 storage
->addr_len
= sizeof(struct sockaddr_in
);
68 struct sockaddr_in
* addr4
= reinterpret_cast<sockaddr_in
*>(storage
->addr
);
69 addr4
->sin_port
= base::HostToNet16(port
);
70 addr4
->sin_family
= AF_INET
;
71 memcpy(&addr4
->sin_addr
, bytes
, 4);
74 // Fills in sockaddr for the given 128-bit address (IPv6.)
75 // |bytes| should be an array of length 16.
76 void MakeIPv6Address(const uint8_t* bytes
, int port
, SockaddrStorage
* storage
) {
77 memset(&storage
->addr_storage
, 0, sizeof(storage
->addr_storage
));
78 storage
->addr_len
= sizeof(struct sockaddr_in6
);
79 struct sockaddr_in6
* addr6
= reinterpret_cast<sockaddr_in6
*>(storage
->addr
);
80 addr6
->sin6_port
= base::HostToNet16(port
);
81 addr6
->sin6_family
= AF_INET6
;
82 memcpy(&addr6
->sin6_addr
, bytes
, 16);
85 bool HasEndpoint(const IPEndPoint
& endpoint
, const AddressList
& addresses
) {
86 for (const auto& address
: addresses
) {
87 if (endpoint
== address
)
93 void TestBothLoopbackIPs(const std::string
& host
) {
94 IPEndPoint
localhost_ipv4(
95 IPAddressNumber(kLocalhostIPv4
,
96 kLocalhostIPv4
+ arraysize(kLocalhostIPv4
)),
97 kLocalhostLookupPort
);
98 IPEndPoint
localhost_ipv6(
99 IPAddressNumber(kLocalhostIPv6
,
100 kLocalhostIPv6
+ arraysize(kLocalhostIPv6
)),
101 kLocalhostLookupPort
);
103 AddressList addresses
;
104 EXPECT_TRUE(ResolveLocalHostname(host
, kLocalhostLookupPort
, &addresses
));
105 EXPECT_EQ(2u, addresses
.size());
106 EXPECT_TRUE(HasEndpoint(localhost_ipv4
, addresses
));
107 EXPECT_TRUE(HasEndpoint(localhost_ipv6
, addresses
));
110 void TestIPv6LoopbackOnly(const std::string
& host
) {
111 IPEndPoint
localhost_ipv6(
112 IPAddressNumber(kLocalhostIPv6
,
113 kLocalhostIPv6
+ arraysize(kLocalhostIPv6
)),
114 kLocalhostLookupPort
);
116 AddressList addresses
;
117 EXPECT_TRUE(ResolveLocalHostname(host
, kLocalhostLookupPort
, &addresses
));
118 EXPECT_EQ(1u, addresses
.size());
119 EXPECT_TRUE(HasEndpoint(localhost_ipv6
, addresses
));
122 } // anonymous namespace
124 TEST(NetUtilTest
, GetIdentityFromURL
) {
126 const char* const input_url
;
127 const char* const expected_username
;
128 const char* const expected_password
;
131 "http://username:password@google.com",
135 { // Test for http://crbug.com/19200
136 "http://username:p@ssword@google.com",
140 { // Special URL characters should be unescaped.
141 "http://username:p%3fa%26s%2fs%23@google.com",
145 { // Username contains %20.
146 "http://use rname:password@google.com",
151 "http://use%00rname:password@google.com",
155 { // Use a '+' in the username.
156 "http://use+rname:password@google.com",
160 { // Use a '&' in the password.
161 "http://username:p&ssword@google.com",
166 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
167 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS
"]: %s", i
,
168 tests
[i
].input_url
));
169 GURL
url(tests
[i
].input_url
);
171 base::string16 username
, password
;
172 GetIdentityFromURL(url
, &username
, &password
);
174 EXPECT_EQ(ASCIIToUTF16(tests
[i
].expected_username
), username
);
175 EXPECT_EQ(ASCIIToUTF16(tests
[i
].expected_password
), password
);
179 // Try extracting a username which was encoded with UTF8.
180 TEST(NetUtilTest
, GetIdentityFromURL_UTF8
) {
181 GURL
url(WideToUTF16(L
"http://foo:\x4f60\x597d@blah.com"));
183 EXPECT_EQ("foo", url
.username());
184 EXPECT_EQ("%E4%BD%A0%E5%A5%BD", url
.password());
186 // Extract the unescaped identity.
187 base::string16 username
, password
;
188 GetIdentityFromURL(url
, &username
, &password
);
190 // Verify that it was decoded as UTF8.
191 EXPECT_EQ(ASCIIToUTF16("foo"), username
);
192 EXPECT_EQ(WideToUTF16(L
"\x4f60\x597d"), password
);
195 TEST(NetUtilTest
, CompliantHost
) {
196 struct CompliantHostCase
{
197 const char* const host
;
198 bool expected_output
;
201 const CompliantHostCase compliant_host_cases
[] = {
227 {"1.2.3.4.5.", true},
230 for (size_t i
= 0; i
< arraysize(compliant_host_cases
); ++i
) {
231 EXPECT_EQ(compliant_host_cases
[i
].expected_output
,
232 IsCanonicalizedHostCompliant(compliant_host_cases
[i
].host
));
236 TEST(NetUtilTest
, ParseHostAndPort
) {
238 const char* const input
;
240 const char* const expected_host
;
244 {"foo:10", true, "foo", 10},
245 {"foo", true, "foo", -1},
247 "[1080:0:0:0:8:800:200C:4171]:11",
249 "1080:0:0:0:8:800:200C:4171",
253 "[1080:0:0:0:8:800:200C:4171]",
255 "1080:0:0:0:8:800:200C:4171",
259 // Because no validation is done on the host, the following are accepted,
260 // even though they are invalid names.
261 {"]", true, "]", -1},
262 {"::1", true, ":", 1},
264 {"foo:bar", false, "", -1},
265 {"foo:", false, "", -1},
266 {":", false, "", -1},
267 {":80", false, "", -1},
269 {"porttoolong:300000", false, "", -1},
270 {"usrname@host", false, "", -1},
271 {"usrname:password@host", false, "", -1},
272 {":password@host", false, "", -1},
273 {":password@host:80", false, "", -1},
274 {":password@host", false, "", -1},
275 {"@host", false, "", -1},
276 {"[", false, "", -1},
277 {"[]", false, "", -1},
280 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
283 bool ok
= ParseHostAndPort(tests
[i
].input
, &host
, &port
);
285 EXPECT_EQ(tests
[i
].success
, ok
);
287 if (tests
[i
].success
) {
288 EXPECT_EQ(tests
[i
].expected_host
, host
);
289 EXPECT_EQ(tests
[i
].expected_port
, port
);
294 TEST(NetUtilTest
, GetHostAndPort
) {
297 const char* const expected_host_and_port
;
299 { GURL("http://www.foo.com/x"), "www.foo.com:80"},
300 { GURL("http://www.foo.com:21/x"), "www.foo.com:21"},
302 // For IPv6 literals should always include the brackets.
303 { GURL("http://[1::2]/x"), "[1::2]:80"},
304 { GURL("http://[::a]:33/x"), "[::a]:33"},
306 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
307 std::string host_and_port
= GetHostAndPort(tests
[i
].url
);
308 EXPECT_EQ(std::string(tests
[i
].expected_host_and_port
), host_and_port
);
312 TEST(NetUtilTest
, GetHostAndOptionalPort
) {
315 const char* const expected_host_and_port
;
317 { GURL("http://www.foo.com/x"), "www.foo.com"},
318 { GURL("http://www.foo.com:21/x"), "www.foo.com:21"},
320 // For IPv6 literals should always include the brackets.
321 { GURL("http://[1::2]/x"), "[1::2]"},
322 { GURL("http://[::a]:33/x"), "[::a]:33"},
324 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
325 std::string host_and_port
= GetHostAndOptionalPort(tests
[i
].url
);
326 EXPECT_EQ(std::string(tests
[i
].expected_host_and_port
), host_and_port
);
330 TEST(NetUtilTest
, NetAddressToString_IPv4
) {
333 const char* const result
;
335 {{0, 0, 0, 0}, "0.0.0.0"},
336 {{127, 0, 0, 1}, "127.0.0.1"},
337 {{192, 168, 0, 1}, "192.168.0.1"},
340 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
341 SockaddrStorage storage
;
342 MakeIPv4Address(tests
[i
].addr
, 80, &storage
);
343 std::string result
= NetAddressToString(storage
.addr
, storage
.addr_len
);
344 EXPECT_EQ(std::string(tests
[i
].result
), result
);
348 TEST(NetUtilTest
, NetAddressToString_IPv6
) {
351 const char* const result
;
353 {{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE, 0xDC, 0xBA,
354 0x98, 0x76, 0x54, 0x32, 0x10},
355 "fedc:ba98:7654:3210:fedc:ba98:7654:3210"},
358 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
359 SockaddrStorage storage
;
360 MakeIPv6Address(tests
[i
].addr
, 80, &storage
);
361 EXPECT_EQ(std::string(tests
[i
].result
),
362 NetAddressToString(storage
.addr
, storage
.addr_len
));
366 TEST(NetUtilTest
, NetAddressToStringWithPort_IPv4
) {
367 uint8_t addr
[] = {127, 0, 0, 1};
368 SockaddrStorage storage
;
369 MakeIPv4Address(addr
, 166, &storage
);
370 std::string result
= NetAddressToStringWithPort(storage
.addr
,
372 EXPECT_EQ("127.0.0.1:166", result
);
375 TEST(NetUtilTest
, NetAddressToStringWithPort_IPv6
) {
377 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE, 0xDC, 0xBA,
378 0x98, 0x76, 0x54, 0x32, 0x10
380 SockaddrStorage storage
;
381 MakeIPv6Address(addr
, 361, &storage
);
382 std::string result
= NetAddressToStringWithPort(storage
.addr
,
385 // May fail on systems that don't support IPv6.
387 EXPECT_EQ("[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:361", result
);
390 TEST(NetUtilTest
, GetHostName
) {
391 // We can't check the result of GetHostName() directly, since the result
392 // will differ across machines. Our goal here is to simply exercise the
393 // code path, and check that things "look about right".
394 std::string hostname
= GetHostName();
395 EXPECT_FALSE(hostname
.empty());
398 TEST(NetUtilTest
, SimplifyUrlForRequest
) {
400 const char* const input_url
;
401 const char* const expected_simplified_url
;
404 // Reference section should be stripped.
405 "http://www.google.com:78/foobar?query=1#hash",
406 "http://www.google.com:78/foobar?query=1",
409 // Reference section can itself contain #.
410 "http://192.168.0.1?query=1#hash#10#11#13#14",
411 "http://192.168.0.1?query=1",
413 { // Strip username/password.
414 "http://user:pass@google.com",
415 "http://google.com/",
417 { // Strip both the reference and the username/password.
418 "http://user:pass@google.com:80/sup?yo#X#X",
419 "http://google.com/sup?yo",
421 { // Try an HTTPS URL -- strip both the reference and the username/password.
422 "https://user:pass@google.com:80/sup?yo#X#X",
423 "https://google.com:80/sup?yo",
425 { // Try an FTP URL -- strip both the reference and the username/password.
426 "ftp://user:pass@google.com:80/sup?yo#X#X",
427 "ftp://google.com:80/sup?yo",
429 { // Try a nonstandard URL
430 "foobar://user:pass@google.com:80/sup?yo#X#X",
431 "foobar://user:pass@google.com:80/sup?yo",
434 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
435 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS
"]: %s", i
,
436 tests
[i
].input_url
));
437 GURL
input_url(GURL(tests
[i
].input_url
));
438 GURL
expected_url(GURL(tests
[i
].expected_simplified_url
));
439 EXPECT_EQ(expected_url
, SimplifyUrlForRequest(input_url
));
443 TEST(NetUtilTest
, GetHostOrSpecFromURL
) {
444 EXPECT_EQ("example.com",
445 GetHostOrSpecFromURL(GURL("http://example.com/test")));
446 EXPECT_EQ("example.com",
447 GetHostOrSpecFromURL(GURL("http://example.com./test")));
448 EXPECT_EQ("file:///tmp/test.html",
449 GetHostOrSpecFromURL(GURL("file:///tmp/test.html")));
452 TEST(NetUtilTest
, GetAddressFamily
) {
453 IPAddressNumber number
;
454 EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &number
));
455 EXPECT_EQ(ADDRESS_FAMILY_IPV4
, GetAddressFamily(number
));
456 EXPECT_TRUE(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number
));
457 EXPECT_EQ(ADDRESS_FAMILY_IPV6
, GetAddressFamily(number
));
460 TEST(NetUtilTest
, IsLocalhost
) {
461 EXPECT_TRUE(IsLocalhost("localhost"));
462 EXPECT_TRUE(IsLocalhost("localHosT"));
463 EXPECT_TRUE(IsLocalhost("localhost."));
464 EXPECT_TRUE(IsLocalhost("localHost."));
465 EXPECT_TRUE(IsLocalhost("localhost.localdomain"));
466 EXPECT_TRUE(IsLocalhost("localhost.localDOMain"));
467 EXPECT_TRUE(IsLocalhost("localhost.localdomain."));
468 EXPECT_TRUE(IsLocalhost("localhost6"));
469 EXPECT_TRUE(IsLocalhost("localhost6."));
470 EXPECT_TRUE(IsLocalhost("localhost6.localdomain6"));
471 EXPECT_TRUE(IsLocalhost("localhost6.localdomain6."));
472 EXPECT_TRUE(IsLocalhost("127.0.0.1"));
473 EXPECT_TRUE(IsLocalhost("127.0.1.0"));
474 EXPECT_TRUE(IsLocalhost("127.1.0.0"));
475 EXPECT_TRUE(IsLocalhost("127.0.0.255"));
476 EXPECT_TRUE(IsLocalhost("127.0.255.0"));
477 EXPECT_TRUE(IsLocalhost("127.255.0.0"));
478 EXPECT_TRUE(IsLocalhost("::1"));
479 EXPECT_TRUE(IsLocalhost("0:0:0:0:0:0:0:1"));
480 EXPECT_TRUE(IsLocalhost("foo.localhost"));
481 EXPECT_TRUE(IsLocalhost("foo.localhost."));
483 EXPECT_FALSE(IsLocalhost("localhostx"));
484 EXPECT_FALSE(IsLocalhost("localhost.x"));
485 EXPECT_FALSE(IsLocalhost("foo.localdomain"));
486 EXPECT_FALSE(IsLocalhost("foo.localdomain.x"));
487 EXPECT_FALSE(IsLocalhost("localhost6x"));
488 EXPECT_FALSE(IsLocalhost("localhost.localdomain6"));
489 EXPECT_FALSE(IsLocalhost("localhost6.localdomain"));
490 EXPECT_FALSE(IsLocalhost("127.0.0.1.1"));
491 EXPECT_FALSE(IsLocalhost(".127.0.0.255"));
492 EXPECT_FALSE(IsLocalhost("::2"));
493 EXPECT_FALSE(IsLocalhost("::1:1"));
494 EXPECT_FALSE(IsLocalhost("0:0:0:0:1:0:0:1"));
495 EXPECT_FALSE(IsLocalhost("::1:1"));
496 EXPECT_FALSE(IsLocalhost("0:0:0:0:0:0:0:0:1"));
497 EXPECT_FALSE(IsLocalhost("foo.localhost.com"));
498 EXPECT_FALSE(IsLocalhost("foo.localhoste"));
501 TEST(NetUtilTest
, ResolveLocalHostname
) {
502 AddressList addresses
;
504 TestBothLoopbackIPs("localhost");
505 TestBothLoopbackIPs("localhoST");
506 TestBothLoopbackIPs("localhost.");
507 TestBothLoopbackIPs("localhoST.");
508 TestBothLoopbackIPs("localhost.localdomain");
509 TestBothLoopbackIPs("localhost.localdomAIn");
510 TestBothLoopbackIPs("localhost.localdomain.");
511 TestBothLoopbackIPs("localhost.localdomAIn.");
512 TestBothLoopbackIPs("foo.localhost");
513 TestBothLoopbackIPs("foo.localhOSt");
514 TestBothLoopbackIPs("foo.localhost.");
515 TestBothLoopbackIPs("foo.localhOSt.");
517 TestIPv6LoopbackOnly("localhost6");
518 TestIPv6LoopbackOnly("localhoST6");
519 TestIPv6LoopbackOnly("localhost6.");
520 TestIPv6LoopbackOnly("localhost6.localdomain6");
521 TestIPv6LoopbackOnly("localhost6.localdomain6.");
524 ResolveLocalHostname("127.0.0.1", kLocalhostLookupPort
, &addresses
));
525 EXPECT_FALSE(ResolveLocalHostname("::1", kLocalhostLookupPort
, &addresses
));
526 EXPECT_FALSE(ResolveLocalHostname("0:0:0:0:0:0:0:1", kLocalhostLookupPort
,
529 ResolveLocalHostname("localhostx", kLocalhostLookupPort
, &addresses
));
531 ResolveLocalHostname("localhost.x", kLocalhostLookupPort
, &addresses
));
532 EXPECT_FALSE(ResolveLocalHostname("foo.localdomain", kLocalhostLookupPort
,
534 EXPECT_FALSE(ResolveLocalHostname("foo.localdomain.x", kLocalhostLookupPort
,
537 ResolveLocalHostname("localhost6x", kLocalhostLookupPort
, &addresses
));
538 EXPECT_FALSE(ResolveLocalHostname("localhost.localdomain6",
539 kLocalhostLookupPort
, &addresses
));
540 EXPECT_FALSE(ResolveLocalHostname("localhost6.localdomain",
541 kLocalhostLookupPort
, &addresses
));
543 ResolveLocalHostname("127.0.0.1.1", kLocalhostLookupPort
, &addresses
));
545 ResolveLocalHostname(".127.0.0.255", kLocalhostLookupPort
, &addresses
));
546 EXPECT_FALSE(ResolveLocalHostname("::2", kLocalhostLookupPort
, &addresses
));
547 EXPECT_FALSE(ResolveLocalHostname("::1:1", kLocalhostLookupPort
, &addresses
));
548 EXPECT_FALSE(ResolveLocalHostname("0:0:0:0:1:0:0:1", kLocalhostLookupPort
,
550 EXPECT_FALSE(ResolveLocalHostname("::1:1", kLocalhostLookupPort
, &addresses
));
551 EXPECT_FALSE(ResolveLocalHostname("0:0:0:0:0:0:0:0:1", kLocalhostLookupPort
,
553 EXPECT_FALSE(ResolveLocalHostname("foo.localhost.com", kLocalhostLookupPort
,
556 ResolveLocalHostname("foo.localhoste", kLocalhostLookupPort
, &addresses
));
559 TEST(NetUtilTest
, IsLocalhostTLD
) {
560 EXPECT_TRUE(IsLocalhostTLD("foo.localhost"));
561 EXPECT_TRUE(IsLocalhostTLD("foo.localhoST"));
562 EXPECT_TRUE(IsLocalhostTLD("foo.localhost."));
563 EXPECT_TRUE(IsLocalhostTLD("foo.localhoST."));
564 EXPECT_FALSE(IsLocalhostTLD("foo.localhos"));
565 EXPECT_FALSE(IsLocalhostTLD("foo.localhost.com"));
566 EXPECT_FALSE(IsLocalhost("foo.localhoste"));
569 TEST(NetUtilTest
, GoogleHost
) {
570 struct GoogleHostCase
{
572 bool expected_output
;
575 const GoogleHostCase google_host_cases
[] = {
576 {GURL("http://.google.com"), true},
577 {GURL("http://.youtube.com"), true},
578 {GURL("http://.gmail.com"), true},
579 {GURL("http://.doubleclick.net"), true},
580 {GURL("http://.gstatic.com"), true},
581 {GURL("http://.googlevideo.com"), true},
582 {GURL("http://.googleusercontent.com"), true},
583 {GURL("http://.googlesyndication.com"), true},
584 {GURL("http://.google-analytics.com"), true},
585 {GURL("http://.googleadservices.com"), true},
586 {GURL("http://.googleapis.com"), true},
587 {GURL("http://a.google.com"), true},
588 {GURL("http://b.youtube.com"), true},
589 {GURL("http://c.gmail.com"), true},
590 {GURL("http://google.com"), false},
591 {GURL("http://youtube.com"), false},
592 {GURL("http://gmail.com"), false},
593 {GURL("http://google.coma"), false},
594 {GURL("http://agoogle.com"), false},
595 {GURL("http://oogle.com"), false},
596 {GURL("http://google.co"), false},
597 {GURL("http://oggole.com"), false},
600 for (size_t i
= 0; i
< arraysize(google_host_cases
); ++i
) {
601 EXPECT_EQ(google_host_cases
[i
].expected_output
,
602 HasGoogleHost(google_host_cases
[i
].url
));
606 struct NonUniqueNameTestData
{
608 const char* const hostname
;
611 // Google Test pretty-printer.
612 void PrintTo(const NonUniqueNameTestData
& data
, std::ostream
* os
) {
613 ASSERT_TRUE(data
.hostname
);
614 *os
<< " hostname: " << testing::PrintToString(data
.hostname
)
615 << "; is_unique: " << testing::PrintToString(data
.is_unique
);
618 const NonUniqueNameTestData kNonUniqueNameTestData
[] = {
619 // Domains under ICANN-assigned domains.
620 { true, "google.com" },
621 { true, "google.co.uk" },
622 // Domains under private registries.
623 { true, "appspot.com" },
624 { true, "test.appspot.com" },
625 // Unreserved IPv4 addresses (in various forms).
627 { true, "99.64.0.0" },
628 { true, "212.15.0.0" },
630 { true, "212.15.0" },
631 { true, "3557752832" },
632 // Reserved IPv4 addresses (in various forms).
633 { false, "192.168.0.0" },
634 { false, "192.168.0.6" },
635 { false, "10.0.0.5" },
638 { false, "3232235526" },
639 // Unreserved IPv6 addresses.
640 { true, "FFC0:ba98:7654:3210:FEDC:BA98:7654:3210" },
641 { true, "2000:ba98:7654:2301:EFCD:BA98:7654:3210" },
642 // Reserved IPv6 addresses.
643 { false, "::192.9.5.5" },
644 { false, "FEED::BEEF" },
645 { false, "FEC0:ba98:7654:3210:FEDC:BA98:7654:3210" },
646 // 'internal'/non-IANA assigned domains.
647 { false, "intranet" },
648 { false, "intranet." },
649 { false, "intranet.example" },
650 { false, "host.intranet.example" },
651 // gTLDs under discussion, but not yet assigned.
652 { false, "intranet.corp" },
653 { false, "intranet.internal" },
654 // Invalid host names are treated as unique - but expected to be
655 // filtered out before then.
656 { true, "junk)(£)$*!@~#" },
657 { true, "w$w.example.com" },
658 { true, "nocolonsallowed:example" },
659 { true, "[::4.5.6.9]" },
662 class NetUtilNonUniqueNameTest
663 : public testing::TestWithParam
<NonUniqueNameTestData
> {
665 virtual ~NetUtilNonUniqueNameTest() {}
668 bool IsUnique(const std::string
& hostname
) {
669 return !IsHostnameNonUnique(hostname
);
673 // Test that internal/non-unique names are properly identified as such, but
674 // that IP addresses and hosts beneath registry-controlled domains are flagged
676 TEST_P(NetUtilNonUniqueNameTest
, IsHostnameNonUnique
) {
677 const NonUniqueNameTestData
& test_data
= GetParam();
679 EXPECT_EQ(test_data
.is_unique
, IsUnique(test_data
.hostname
));
682 INSTANTIATE_TEST_CASE_P(, NetUtilNonUniqueNameTest
,
683 testing::ValuesIn(kNonUniqueNameTestData
));