RFC6761 localhost definition includes subdomains

RFC6761 6.3 states:
  The domain "localhost." and any names falling within ".localhost."

We were only honoring "localhost".

Fixes: #477
Fix By: Brad House (@bradh352)
pull/503/head
bradh352 2 years ago
parent a306ed4238
commit 25523e23ab
  1. 25
      src/lib/ares_getaddrinfo.c
  2. 27
      test/ares-test-live.cc

@ -404,6 +404,27 @@ static void end_hquery(struct host_query *hquery, int status)
ares_free(hquery); ares_free(hquery);
} }
static int is_localhost(const char *name)
{
/* RFC6761 6.3 says : The domain "localhost." and any names falling within ".localhost." */
size_t len;
if (name == NULL)
return 0;
if (strcmp(name, "localhost") == 0)
return 1;
len = strlen(name);
if (len < 10 /* strlen(".localhost") */)
return 0;
if (strcmp(name + (len - 10 /* strlen(".localhost") */), ".localhost") == 0)
return 1;
return 0;
}
static int file_lookup(struct host_query *hquery) static int file_lookup(struct host_query *hquery)
{ {
FILE *fp; FILE *fp;
@ -492,7 +513,7 @@ static int file_lookup(struct host_query *hquery)
* IP loopback address for address queries". * IP loopback address for address queries".
* We will also ignore ALL errors when trying to resolve localhost, such * We will also ignore ALL errors when trying to resolve localhost, such
* as permissions errors reading /etc/hosts or a malformed /etc/hosts */ * as permissions errors reading /etc/hosts or a malformed /etc/hosts */
if (status != ARES_SUCCESS && strcmp(hquery->name, "localhost") == 0) if (status != ARES_SUCCESS && is_localhost(hquery->name))
{ {
return ares__addrinfo_localhost(hquery->name, hquery->port, return ares__addrinfo_localhost(hquery->name, hquery->port,
&hquery->hints, hquery->ai); &hquery->hints, hquery->ai);
@ -509,7 +530,7 @@ static void next_lookup(struct host_query *hquery, int status)
/* RFC6761 section 6.3 #3 says "Name resolution APIs SHOULD NOT send /* RFC6761 section 6.3 #3 says "Name resolution APIs SHOULD NOT send
* queries for localhost names to their configured caching DNS * queries for localhost names to their configured caching DNS
* server(s)." */ * server(s)." */
if (strcmp(hquery->name, "localhost") != 0) if (is_localhost(hquery->name))
{ {
/* DNS lookup */ /* DNS lookup */
if (next_dns_lookup(hquery)) if (next_dns_lookup(hquery))

@ -158,12 +158,37 @@ TEST_P(DefaultChannelModeTest, LiveGetLocalhostByNameV6) {
ares_gethostbyname(channel_, "localhost", AF_INET6, HostCallback, &result); ares_gethostbyname(channel_, "localhost", AF_INET6, HostCallback, &result);
Process(); Process();
EXPECT_TRUE(result.done_); EXPECT_TRUE(result.done_);
if (result.status_ != ARES_ECONNREFUSED) {
EXPECT_EQ(1, (int)result.host_.addrs_.size()); EXPECT_EQ(1, (int)result.host_.addrs_.size());
EXPECT_EQ(AF_INET6, result.host_.addrtype_); EXPECT_EQ(AF_INET6, result.host_.addrtype_);
std::stringstream ss; std::stringstream ss;
ss << HostEnt(result.host_); ss << HostEnt(result.host_);
EXPECT_NE(std::string::npos, result.host_.name_.find("localhost")); EXPECT_NE(std::string::npos, result.host_.name_.find("localhost"));
}
TEST_P(DefaultChannelModeTest, LiveGetNonExistLocalhostByNameV4) {
HostResult result;
ares_gethostbyname(channel_, "idonotexist.localhost", AF_INET, HostCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
EXPECT_EQ(1, (int)result.host_.addrs_.size());
EXPECT_EQ(AF_INET, result.host_.addrtype_);
EXPECT_NE(std::string::npos, result.host_.name_.find("idonotexist.localhost"));
}
TEST_P(DefaultChannelModeTest, LiveGetNonExistLocalhostByNameV6) {
HostResult result;
ares_gethostbyname(channel_, "idonotexist.localhost", AF_INET6, HostCallback, &result);
Process();
EXPECT_TRUE(result.done_);
if (result.status_ != ARES_ECONNREFUSED) {
EXPECT_EQ(1, (int)result.host_.addrs_.size());
EXPECT_EQ(AF_INET6, result.host_.addrtype_);
std::stringstream ss;
ss << HostEnt(result.host_);
EXPECT_NE(std::string::npos, result.host_.name_.find("idonotexist.localhost"));
} }
} }

Loading…
Cancel
Save