You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
10 KiB
277 lines
10 KiB
#include "ares-test-ai.h" |
|
#include "dns-proto.h" |
|
|
|
#ifdef HAVE_NETDB_H |
|
#include <netdb.h> |
|
#endif |
|
|
|
#include <arpa/inet.h> |
|
#include <sstream> |
|
#include <vector> |
|
|
|
using testing::InvokeWithoutArgs; |
|
using testing::DoAll; |
|
|
|
namespace ares { |
|
namespace test { |
|
|
|
MATCHER_P(IncludesNumAddresses, n, "") { |
|
int cnt = 0; |
|
for (const ares_addrinfo* ai = arg; ai != NULL; ai = ai->ai_next) |
|
cnt++; |
|
return n == cnt; |
|
} |
|
|
|
MATCHER_P(IncludesV4Address, address, "") { |
|
in_addr addressnum = {}; |
|
if (!inet_pton(AF_INET, address, &addressnum)) |
|
return false; // wrong number format? |
|
for (const ares_addrinfo* ai = arg; ai != NULL; ai = ai->ai_next) { |
|
if (ai->ai_family != AF_INET) |
|
continue; |
|
if (reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr.s_addr == |
|
addressnum.s_addr) |
|
return true; // found |
|
} |
|
return false; |
|
} |
|
|
|
MATCHER_P(IncludesV6Address, address, "") { |
|
in6_addr addressnum = {}; |
|
if (!inet_pton(AF_INET6, address, &addressnum)) { |
|
return false; // wrong number format? |
|
} |
|
for (const ares_addrinfo* ai = arg; ai != NULL; ai = ai->ai_next) { |
|
if (ai->ai_family != AF_INET6) |
|
continue; |
|
if (!memcmp( |
|
reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr.s6_addr, |
|
addressnum.s6_addr, sizeof(addressnum.s6_addr))) |
|
return true; // found |
|
} |
|
return false; |
|
} |
|
|
|
// UDP only so mock server doesn't get confused by concatenated requests |
|
TEST_P(MockUDPChannelTestAI, ParallelLookups) { |
|
DNSPacket rsp1; |
|
rsp1.set_response().set_aa() |
|
.add_question(new DNSQuestion("www.google.com", ns_t_a)) |
|
.add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5})); |
|
ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &rsp1)); |
|
DNSPacket rsp2; |
|
rsp2.set_response().set_aa() |
|
.add_question(new DNSQuestion("www.example.com", ns_t_a)) |
|
.add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4})); |
|
ON_CALL(server_, OnRequest("www.example.com", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &rsp2)); |
|
|
|
struct ares_addrinfo hints = {}; |
|
hints.ai_family = AF_INET; |
|
AIResult result1; |
|
ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result1); |
|
AIResult result2; |
|
ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AICallback, &result2); |
|
AIResult result3; |
|
ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result3); |
|
Process(); |
|
|
|
EXPECT_TRUE(result1.done); |
|
EXPECT_EQ(result1.status, ARES_SUCCESS); |
|
EXPECT_THAT(result1.airesult, IncludesNumAddresses(1)); |
|
EXPECT_THAT(result1.airesult, IncludesV4Address("2.3.4.5")); |
|
ares_freeaddrinfo(result1.airesult); |
|
|
|
EXPECT_TRUE(result2.done); |
|
EXPECT_EQ(result2.status, ARES_SUCCESS); |
|
EXPECT_THAT(result2.airesult, IncludesNumAddresses(1)); |
|
EXPECT_THAT(result2.airesult, IncludesV4Address("1.2.3.4")); |
|
ares_freeaddrinfo(result2.airesult); |
|
|
|
EXPECT_TRUE(result3.done); |
|
EXPECT_EQ(result3.status, ARES_SUCCESS); |
|
EXPECT_THAT(result3.airesult, IncludesNumAddresses(1)); |
|
EXPECT_THAT(result3.airesult, IncludesV4Address("2.3.4.5")); |
|
ares_freeaddrinfo(result3.airesult); |
|
} |
|
|
|
TEST_P(MockChannelTestAI, FamilyV6) { |
|
DNSPacket rsp6; |
|
rsp6.set_response().set_aa() |
|
.add_question(new DNSQuestion("example.com", ns_t_aaaa)) |
|
.add_answer(new DNSAaaaRR("example.com", 100, |
|
{0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03})); |
|
ON_CALL(server_, OnRequest("example.com", ns_t_aaaa)) |
|
.WillByDefault(SetReply(&server_, &rsp6)); |
|
AIResult result; |
|
struct ares_addrinfo hints = {}; |
|
hints.ai_family = AF_INET6; |
|
ares_getaddrinfo(channel_, "example.com.", NULL, &hints, |
|
AICallback, &result); |
|
Process(); |
|
EXPECT_TRUE(result.done); |
|
EXPECT_EQ(result.status, ARES_SUCCESS); |
|
EXPECT_THAT(result.airesult, IncludesNumAddresses(1)); |
|
EXPECT_THAT(result.airesult, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303")); |
|
ares_freeaddrinfo(result.airesult); |
|
} |
|
|
|
|
|
TEST_P(MockChannelTestAI, FamilyV4) { |
|
DNSPacket rsp4; |
|
rsp4.set_response().set_aa() |
|
.add_question(new DNSQuestion("example.com", ns_t_a)) |
|
.add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})); |
|
ON_CALL(server_, OnRequest("example.com", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &rsp4)); |
|
AIResult result = {}; |
|
struct ares_addrinfo hints = {}; |
|
hints.ai_family = AF_INET; |
|
ares_getaddrinfo(channel_, "example.com.", NULL, &hints, |
|
AICallback, &result); |
|
Process(); |
|
EXPECT_TRUE(result.done); |
|
EXPECT_EQ(result.status, ARES_SUCCESS); |
|
EXPECT_THAT(result.airesult, IncludesNumAddresses(1)); |
|
EXPECT_THAT(result.airesult, IncludesV4Address("2.3.4.5")); |
|
ares_freeaddrinfo(result.airesult); |
|
} |
|
|
|
TEST_P(MockChannelTestAI, FamilyV4_MultipleAddresses) { |
|
DNSPacket rsp4; |
|
rsp4.set_response().set_aa() |
|
.add_question(new DNSQuestion("example.com", ns_t_a)) |
|
.add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})) |
|
.add_answer(new DNSARR("example.com", 100, {7, 8, 9, 0})); |
|
ON_CALL(server_, OnRequest("example.com", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &rsp4)); |
|
AIResult result = {}; |
|
struct ares_addrinfo hints = {}; |
|
hints.ai_family = AF_INET; |
|
ares_getaddrinfo(channel_, "example.com.", NULL, &hints, |
|
AICallback, &result); |
|
Process(); |
|
EXPECT_TRUE(result.done); |
|
EXPECT_EQ(result.status, ARES_SUCCESS); |
|
EXPECT_THAT(result.airesult, IncludesNumAddresses(2)); |
|
EXPECT_THAT(result.airesult, IncludesV4Address("2.3.4.5")); |
|
EXPECT_THAT(result.airesult, IncludesV4Address("7.8.9.0")); |
|
ares_freeaddrinfo(result.airesult); |
|
} |
|
|
|
TEST_P(MockChannelTestAI, FamilyUnspecified) { |
|
DNSPacket rsp6; |
|
rsp6.set_response().set_aa() |
|
.add_question(new DNSQuestion("example.com", ns_t_aaaa)) |
|
.add_answer(new DNSAaaaRR("example.com", 100, |
|
{0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03})); |
|
ON_CALL(server_, OnRequest("example.com", ns_t_aaaa)) |
|
.WillByDefault(SetReply(&server_, &rsp6)); |
|
DNSPacket rsp4; |
|
rsp4.set_response().set_aa() |
|
.add_question(new DNSQuestion("example.com", ns_t_a)) |
|
.add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})); |
|
ON_CALL(server_, OnRequest("example.com", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &rsp4)); |
|
AIResult result; |
|
struct ares_addrinfo hints = {}; |
|
hints.ai_family = AF_UNSPEC; |
|
ares_getaddrinfo(channel_, "example.com.", NULL, &hints, |
|
AICallback, &result); |
|
Process(); |
|
EXPECT_TRUE(result.done); |
|
EXPECT_EQ(result.status, ARES_SUCCESS); |
|
EXPECT_THAT(result.airesult, IncludesNumAddresses(2)); |
|
EXPECT_THAT(result.airesult, IncludesV4Address("2.3.4.5")); |
|
EXPECT_THAT(result.airesult, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303")); |
|
ares_freeaddrinfo(result.airesult); |
|
} |
|
|
|
TEST_P(MockChannelTestAI, SearchDomains) { |
|
DNSPacket nofirst; |
|
nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain) |
|
.add_question(new DNSQuestion("www.first.com", ns_t_a)); |
|
ON_CALL(server_, OnRequest("www.first.com", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &nofirst)); |
|
DNSPacket nosecond; |
|
nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain) |
|
.add_question(new DNSQuestion("www.second.org", ns_t_a)); |
|
ON_CALL(server_, OnRequest("www.second.org", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &nosecond)); |
|
DNSPacket yesthird; |
|
yesthird.set_response().set_aa() |
|
.add_question(new DNSQuestion("www.third.gov", ns_t_a)) |
|
.add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5})); |
|
ON_CALL(server_, OnRequest("www.third.gov", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &yesthird)); |
|
|
|
AIResult result; |
|
struct ares_addrinfo hints = {}; |
|
hints.ai_family = AF_INET; |
|
ares_getaddrinfo(channel_, "www", NULL, &hints, AICallback, &result); |
|
Process(); |
|
EXPECT_TRUE(result.done); |
|
EXPECT_EQ(result.status, ARES_SUCCESS); |
|
EXPECT_THAT(result.airesult, IncludesNumAddresses(1)); |
|
EXPECT_THAT(result.airesult, IncludesV4Address("2.3.4.5")); |
|
ares_freeaddrinfo(result.airesult); |
|
} |
|
|
|
TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) { |
|
DNSPacket nofirst; |
|
nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain) |
|
.add_question(new DNSQuestion("www.first.com", ns_t_aaaa)); |
|
ON_CALL(server_, OnRequest("www.first.com", ns_t_aaaa)) |
|
.WillByDefault(SetReply(&server_, &nofirst)); |
|
DNSPacket nofirst4; |
|
nofirst4.set_response().set_aa().set_rcode(ns_r_nxdomain) |
|
.add_question(new DNSQuestion("www.first.com", ns_t_a)); |
|
ON_CALL(server_, OnRequest("www.first.com", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &nofirst4)); |
|
|
|
DNSPacket nosecond; |
|
nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain) |
|
.add_question(new DNSQuestion("www.second.org", ns_t_aaaa)); |
|
ON_CALL(server_, OnRequest("www.second.org", ns_t_aaaa)) |
|
.WillByDefault(SetReply(&server_, &nosecond)); |
|
DNSPacket yessecond4; |
|
yessecond4.set_response().set_aa() |
|
.add_question(new DNSQuestion("www.second.org", ns_t_a)) |
|
.add_answer(new DNSARR("www.second.org", 0x0200, {2, 3, 4, 5})); |
|
ON_CALL(server_, OnRequest("www.second.org", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &yessecond4)); |
|
|
|
DNSPacket failthird; |
|
failthird.set_response().set_aa().set_rcode(ns_r_servfail) |
|
.add_question(new DNSQuestion("www.third.gov", ns_t_aaaa)); |
|
ON_CALL(server_, OnRequest("www.third.gov", ns_t_aaaa)) |
|
.WillByDefault(SetReply(&server_, &failthird)); |
|
DNSPacket failthird4; |
|
failthird4.set_response().set_aa().set_rcode(ns_r_servfail) |
|
.add_question(new DNSQuestion("www.third.gov", ns_t_a)); |
|
ON_CALL(server_, OnRequest("www.third.gov", ns_t_a)) |
|
.WillByDefault(SetReply(&server_, &failthird4)); |
|
|
|
AIResult result; |
|
struct ares_addrinfo hints = {}; |
|
hints.ai_family = AF_UNSPEC; |
|
ares_getaddrinfo(channel_, "www", NULL, &hints, AICallback, &result); |
|
Process(); |
|
EXPECT_TRUE(result.done); |
|
EXPECT_EQ(result.status, ARES_SUCCESS); |
|
EXPECT_THAT(result.airesult, IncludesNumAddresses(1)); |
|
EXPECT_THAT(result.airesult, IncludesV4Address("2.3.4.5")); |
|
ares_freeaddrinfo(result.airesult); |
|
} |
|
|
|
INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI, |
|
::testing::Values(std::make_pair<int, bool>(AF_INET, false))); |
|
|
|
INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockUDPChannelTestAI, |
|
::testing::ValuesIn(ares::test::families)); |
|
|
|
} // namespace test |
|
} // namespace ares
|
|
|