Commit 5d131a1f authored by estark's avatar estark Committed by Commit bot

Always treat .localhost as loopback

This means that .localhost is always redirected to localhost in DNS
lookups, and |net::IsLocalhost| returns true for .localhost hostnames.

BUG=455825

Review URL: https://codereview.chromium.org/938093003

Cr-Commit-Position: refs/heads/master@{#322452}
parent 9bbd8ea8
......@@ -981,10 +981,9 @@ int GetPortFromSockaddr(const struct sockaddr* address, socklen_t address_len) {
}
bool IsLocalhost(const std::string& host) {
if (host == "localhost" ||
host == "localhost.localdomain" ||
host == "localhost6" ||
host == "localhost6.localdomain6")
if (host == "localhost" || host == "localhost.localdomain" ||
host == "localhost6" || host == "localhost6.localdomain6" ||
IsLocalhostTLD(host))
return true;
IPAddressNumber ip_number;
......@@ -1014,6 +1013,24 @@ bool IsLocalhost(const std::string& host) {
return false;
}
bool IsLocalhostTLD(const std::string& host) {
const char kLocalhostTLD[] = ".localhost";
const size_t kLocalhostTLDLength = arraysize(kLocalhostTLD) - 1;
if (host.empty())
return false;
size_t host_len = host.size();
if (*host.rbegin() == '.')
--host_len;
if (host_len < kLocalhostTLDLength)
return false;
const char* host_suffix = host.data() + host_len - kLocalhostTLDLength;
return base::strncasecmp(host_suffix, kLocalhostTLD, kLocalhostTLDLength) ==
0;
}
NetworkInterface::NetworkInterface()
: type(NetworkChangeNotifier::CONNECTION_UNKNOWN), prefix_length(0) {
}
......
......@@ -441,6 +441,8 @@ NET_EXPORT_PRIVATE int GetPortFromSockaddr(const struct sockaddr* address,
// machine.
NET_EXPORT_PRIVATE bool IsLocalhost(const std::string& host);
NET_EXPORT_PRIVATE bool IsLocalhostTLD(const std::string& host);
// A subset of IP address attributes which are actionable by the
// application layer. Currently unimplemented for all hosts;
// IP_ADDRESS_ATTRIBUTE_NONE is always returned.
......
......@@ -803,6 +803,7 @@ TEST(NetUtilTest, IsLocalhost) {
EXPECT_TRUE(net::IsLocalhost("127.255.0.0"));
EXPECT_TRUE(net::IsLocalhost("::1"));
EXPECT_TRUE(net::IsLocalhost("0:0:0:0:0:0:0:1"));
EXPECT_TRUE(net::IsLocalhost("foo.localhost"));
EXPECT_FALSE(net::IsLocalhost("localhostx"));
EXPECT_FALSE(net::IsLocalhost("foo.localdomain"));
......@@ -816,6 +817,16 @@ TEST(NetUtilTest, IsLocalhost) {
EXPECT_FALSE(net::IsLocalhost("0:0:0:0:1:0:0:1"));
EXPECT_FALSE(net::IsLocalhost("::1:1"));
EXPECT_FALSE(net::IsLocalhost("0:0:0:0:0:0:0:0:1"));
EXPECT_FALSE(net::IsLocalhost("foo.localhost.com"));
EXPECT_FALSE(net::IsLocalhost("foo.localhoste"));
}
TEST(NetUtilTest, IsLocalhostTLD) {
EXPECT_TRUE(net::IsLocalhostTLD("foo.localhost"));
EXPECT_TRUE(net::IsLocalhostTLD("foo.localhost."));
EXPECT_FALSE(net::IsLocalhostTLD("foo.localhos"));
EXPECT_FALSE(net::IsLocalhostTLD("foo.localhost.com"));
EXPECT_FALSE(net::IsLocalhost("foo.localhoste"));
}
// Verify GetNetworkList().
......
......@@ -72,6 +72,8 @@ const unsigned kNegativeCacheEntryTTLSeconds = 0;
// Minimum TTL for successful resolutions with DnsTask.
const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds;
const char kLocalhost[] = "localhost.";
// We use a separate histogram name for each platform to facilitate the
// display of error codes by their symbolic name (since each platform has
// different mappings).
......@@ -1291,7 +1293,13 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
}
void AddRequest(scoped_ptr<Request> req) {
DCHECK_EQ(key_.hostname, req->info().hostname());
// .localhost queries are redirected to "localhost." to make sure
// that they are never sent out on the network, per RFC 6761.
if (IsLocalhostTLD(req->info().hostname())) {
DCHECK_EQ(key_.hostname, kLocalhost);
} else {
DCHECK_EQ(key_.hostname, req->info().hostname());
}
req->set_job(this);
priority_tracker_.Add(req->priority());
......@@ -2214,7 +2222,13 @@ HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
}
}
return Key(info.hostname(), effective_address_family, effective_flags);
std::string hostname = info.hostname();
// Redirect .localhost queries to "localhost." to make sure that they
// are never sent out on the network, per RFC 6761.
if (IsLocalhostTLD(info.hostname()))
hostname = kLocalhost;
return Key(hostname, effective_address_family, effective_flags);
}
void HostResolverImpl::AbortAllInProgressJobs() {
......
......@@ -550,6 +550,17 @@ TEST_F(HostResolverImplTest, AsynchronousLookup) {
EXPECT_EQ("just.testing", proc_->GetCaptureList()[0].hostname);
}
TEST_F(HostResolverImplTest, LocalhostLookup) {
proc_->SignalMultiple(1u);
Request* req = CreateRequest("foo.localhost", 80);
EXPECT_EQ(ERR_IO_PENDING, req->Resolve());
EXPECT_EQ(OK, req->WaitForResult());
EXPECT_TRUE(req->HasOneAddress("127.0.0.1", 80));
EXPECT_EQ("localhost.", proc_->GetCaptureList()[0].hostname);
}
TEST_F(HostResolverImplTest, EmptyListMeansNameNotResolved) {
proc_->AddRuleForAllFamilies("just.testing", "");
proc_->SignalMultiple(1u);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment