forked from pool/c-ares
Accepting request 742209 from devel:libraries:c_c++
OBS-URL: https://build.opensuse.org/request/show/742209 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/c-ares?expand=0&rev=4
This commit is contained in:
commit
a25c8cb565
1189
0001-Add-initial-implementation-for-ares_getaddrinfo-112.patch
Normal file
1189
0001-Add-initial-implementation-for-ares_getaddrinfo-112.patch
Normal file
File diff suppressed because it is too large
Load Diff
280
0002-Remaining-queries-counter-fix-additional-unit-tests-.patch
Normal file
280
0002-Remaining-queries-counter-fix-additional-unit-tests-.patch
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
From 6697ef495521ffd80386b6ccf162db286b36375f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christian Ammer <chrie.ammer@gmail.com>
|
||||||
|
Date: Sun, 11 Nov 2018 23:25:38 +0100
|
||||||
|
Subject: [PATCH 02/10] Remaining queries counter fix, additional unit tests
|
||||||
|
for `ares_getaddrinfo` (#233)
|
||||||
|
|
||||||
|
Remaining queries counter fix, added tests (ParallelLookups,
|
||||||
|
SearchDomains, SearchDomainsServFailOnAAAA). Removed unnecessary
|
||||||
|
if and commented code in test.
|
||||||
|
|
||||||
|
Fix By: Christian Ammer (@ChristianAmmer)
|
||||||
|
---
|
||||||
|
ares_getaddrinfo.c | 39 ++++++++-------
|
||||||
|
test/ares-test-ai.h | 7 +++
|
||||||
|
test/ares-test-mock-ai.cc | 125 +++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
3 files changed, 153 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ares_getaddrinfo.c b/ares_getaddrinfo.c
|
||||||
|
index be936ff..36f29b5 100644
|
||||||
|
--- a/ares_getaddrinfo.c
|
||||||
|
+++ b/ares_getaddrinfo.c
|
||||||
|
@@ -122,7 +122,7 @@ void ares_getaddrinfo(ares_channel channel,
|
||||||
|
hquery->arg = arg;
|
||||||
|
hquery->timeouts = 0;
|
||||||
|
hquery->next_domain = 0;
|
||||||
|
- hquery->remaining = ai_family == AF_UNSPEC ? 2 : 1;
|
||||||
|
+ hquery->remaining = 0;
|
||||||
|
|
||||||
|
/* Host file lookup */
|
||||||
|
if (file_lookup(hquery->name, ai_family, &hquery->ai) == ARES_SUCCESS) {
|
||||||
|
@@ -291,9 +291,11 @@ static void next_dns_lookup(struct host_query *hquery) {
|
||||||
|
if (s) {
|
||||||
|
if (hquery->ai_family == AF_INET || hquery->ai_family == AF_UNSPEC) {
|
||||||
|
ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery);
|
||||||
|
+ hquery->remaining++;
|
||||||
|
}
|
||||||
|
if (hquery->ai_family == AF_INET6 || hquery->ai_family == AF_UNSPEC) {
|
||||||
|
ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery);
|
||||||
|
+ hquery->remaining++;
|
||||||
|
}
|
||||||
|
if (is_s_allocated) {
|
||||||
|
ares_free(s);
|
||||||
|
@@ -306,9 +308,7 @@ static void next_dns_lookup(struct host_query *hquery) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void end_hquery(struct host_query *hquery, int status) {
|
||||||
|
- if (hquery->ai) {
|
||||||
|
- hquery->callback(hquery->arg, status, hquery->ai);
|
||||||
|
- }
|
||||||
|
+ hquery->callback(hquery->arg, status, hquery->ai);
|
||||||
|
ares_free(hquery->name);
|
||||||
|
ares_free(hquery);
|
||||||
|
}
|
||||||
|
@@ -319,11 +319,14 @@ static void host_callback(void *arg, int status, int timeouts,
|
||||||
|
ares_channel channel = hquery->channel;
|
||||||
|
struct hostent *host = NULL;
|
||||||
|
int qtype;
|
||||||
|
+ int qtypestatus;
|
||||||
|
hquery->timeouts += timeouts;
|
||||||
|
|
||||||
|
+ hquery->remaining--;
|
||||||
|
+
|
||||||
|
if (status == ARES_SUCCESS) {
|
||||||
|
- status = ares__parse_qtype_reply(abuf, alen, &qtype);
|
||||||
|
- if (status == ARES_SUCCESS && qtype == T_A) {
|
||||||
|
+ qtypestatus = ares__parse_qtype_reply(abuf, alen, &qtype);
|
||||||
|
+ if (qtypestatus == ARES_SUCCESS && qtype == T_A) {
|
||||||
|
/* Can ares_parse_a_reply be unsuccessful (after parse_qtype) */
|
||||||
|
ares_parse_a_reply(abuf, alen, &host, NULL, NULL);
|
||||||
|
if (host && channel->nsort) {
|
||||||
|
@@ -331,11 +334,8 @@ static void host_callback(void *arg, int status, int timeouts,
|
||||||
|
}
|
||||||
|
add_to_addrinfo(&hquery->ai, host);
|
||||||
|
ares_free_hostent(host);
|
||||||
|
- if (!--hquery->remaining) {
|
||||||
|
- end_hquery(hquery, ARES_SUCCESS);
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
- else if (status == ARES_SUCCESS && qtype == T_AAAA) {
|
||||||
|
+ else if (qtypestatus == ARES_SUCCESS && qtype == T_AAAA) {
|
||||||
|
/* Can ares_parse_a_reply be unsuccessful (after parse_qtype) */
|
||||||
|
ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL);
|
||||||
|
if (host && channel->nsort) {
|
||||||
|
@@ -343,18 +343,23 @@ static void host_callback(void *arg, int status, int timeouts,
|
||||||
|
}
|
||||||
|
add_to_addrinfo(&hquery->ai, host);
|
||||||
|
ares_free_hostent(host);
|
||||||
|
- if (!--hquery->remaining) {
|
||||||
|
- end_hquery(hquery, ARES_SUCCESS);
|
||||||
|
- }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!hquery->remaining) {
|
||||||
|
+ if (hquery->ai) {
|
||||||
|
+ // at least one query ended with ARES_SUCCESS
|
||||||
|
+ end_hquery(hquery, ARES_SUCCESS);
|
||||||
|
+ }
|
||||||
|
+ else if (status == ARES_ENOTFOUND) {
|
||||||
|
+ next_dns_lookup(hquery);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
- assert(!hquery->ai);
|
||||||
|
end_hquery(hquery, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- else {
|
||||||
|
- next_dns_lookup(hquery);
|
||||||
|
- }
|
||||||
|
+
|
||||||
|
+ // at this point we keep on waiting for the next query to finish
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sort_addresses(struct hostent *host,
|
||||||
|
diff --git a/test/ares-test-ai.h b/test/ares-test-ai.h
|
||||||
|
index e4c4403..a7a6a73 100644
|
||||||
|
--- a/test/ares-test-ai.h
|
||||||
|
+++ b/test/ares-test-ai.h
|
||||||
|
@@ -16,6 +16,13 @@ class MockChannelTestAI
|
||||||
|
MockChannelTestAI() : MockChannelOptsTest(1, GetParam().first, GetParam().second, nullptr, 0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
+class MockUDPChannelTestAI
|
||||||
|
+ : public MockChannelOptsTest,
|
||||||
|
+ public ::testing::WithParamInterface<int> {
|
||||||
|
+ public:
|
||||||
|
+ MockUDPChannelTestAI() : MockChannelOptsTest(1, GetParam(), false, nullptr, 0) {}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
// Structure that describes the result of an ares_addr_callback invocation.
|
||||||
|
struct AIResult {
|
||||||
|
// Whether the callback has been invoked.
|
||||||
|
diff --git a/test/ares-test-mock-ai.cc b/test/ares-test-mock-ai.cc
|
||||||
|
index 8ba1611..28a01be 100644
|
||||||
|
--- a/test/ares-test-mock-ai.cc
|
||||||
|
+++ b/test/ares-test-mock-ai.cc
|
||||||
|
@@ -52,6 +52,50 @@ MATCHER_P(IncludesV6Address, address, "") {
|
||||||
|
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()
|
||||||
|
@@ -146,9 +190,88 @@ TEST_P(MockChannelTestAI, FamilyUnspecified) {
|
||||||
|
ares_freeaddrinfo(result.airesult);
|
||||||
|
}
|
||||||
|
|
||||||
|
-INSTANTIATE_TEST_CASE_P(AddressFamilies, MockChannelTestAI,
|
||||||
|
+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
|
||||||
|
--
|
||||||
|
2.16.4
|
||||||
|
|
781
0003-Bugfix-for-ares_getaddrinfo-and-additional-unit-test.patch
Normal file
781
0003-Bugfix-for-ares_getaddrinfo-and-additional-unit-test.patch
Normal file
@ -0,0 +1,781 @@
|
|||||||
|
From 7442846941cb7a552485f139308a0004c27fa567 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christian Ammer <chrie.ammer@gmail.com>
|
||||||
|
Date: Sun, 25 Nov 2018 02:59:42 +0100
|
||||||
|
Subject: [PATCH 03/10] Bugfix for `ares_getaddrinfo` and additional unit tests
|
||||||
|
(#234)
|
||||||
|
|
||||||
|
This PullRequest fixes a bug in the function add_to_addrinfo which task is to add new addrinfo items to the ai_next linked list. Also additional unit tests for testing ares_getaddrinfo will be added:
|
||||||
|
|
||||||
|
Additional mock server test classes (ares-test-mock-ai.cc):
|
||||||
|
MockTCPChannelTestAI
|
||||||
|
MockExtraOptsTestAI
|
||||||
|
MockNoCheckRespChannelTestAI
|
||||||
|
MockEDNSChannelTestAI
|
||||||
|
RotateMultiMockTestAI
|
||||||
|
NoRotateMultiMockTestAI
|
||||||
|
|
||||||
|
Additional live tests (ares-test-live-ai.cc):
|
||||||
|
LiveGetHostByNameV4
|
||||||
|
LiveGetHostByNameV6
|
||||||
|
LiveGetHostByNameV4AndV6
|
||||||
|
|
||||||
|
Fix By: Christian Ammer (@ChristianAmmer)
|
||||||
|
---
|
||||||
|
ares_getaddrinfo.c | 69 ++++----
|
||||||
|
test/ares-test-ai.h | 29 ++++
|
||||||
|
test/ares-test-live-ai.cc | 85 +++++++++
|
||||||
|
test/ares-test-mock-ai.cc | 434 +++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
4 files changed, 584 insertions(+), 33 deletions(-)
|
||||||
|
create mode 100644 test/ares-test-live-ai.cc
|
||||||
|
|
||||||
|
diff --git a/ares_getaddrinfo.c b/ares_getaddrinfo.c
|
||||||
|
index 36f29b5..b89a29c 100644
|
||||||
|
--- a/ares_getaddrinfo.c
|
||||||
|
+++ b/ares_getaddrinfo.c
|
||||||
|
@@ -81,8 +81,8 @@ static int get_address_index(const struct in_addr *addr,
|
||||||
|
static int get6_address_index(const struct ares_in6_addr *addr,
|
||||||
|
const struct apattern *sortlist, int nsort);
|
||||||
|
static int as_is_first(const struct host_query *hquery);
|
||||||
|
-static void add_to_addrinfo(struct ares_addrinfo** ai,
|
||||||
|
- const struct hostent* host);
|
||||||
|
+static int add_to_addrinfo(struct ares_addrinfo** ai,
|
||||||
|
+ const struct hostent* host);
|
||||||
|
static void next_dns_lookup(struct host_query *hquery);
|
||||||
|
static int is_implemented(const int family);
|
||||||
|
|
||||||
|
@@ -213,16 +213,15 @@ static int file_lookup(const char *name, int family, struct ares_addrinfo **ai)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
status = ARES_ENOTFOUND;
|
||||||
|
- while (ares__get_hostent(fp, family, &host) == ARES_SUCCESS) {
|
||||||
|
+ while (status != ARES_ENOMEM &&
|
||||||
|
+ ares__get_hostent(fp, family, &host) == ARES_SUCCESS) {
|
||||||
|
if (strcasecmp(host->h_name, name) == 0) {
|
||||||
|
- add_to_addrinfo(ai, host);
|
||||||
|
- status = ARES_SUCCESS;
|
||||||
|
+ status = add_to_addrinfo(ai, host);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (alias = host->h_aliases; *alias; alias++) {
|
||||||
|
if (strcasecmp(*alias, name) == 0) {
|
||||||
|
- add_to_addrinfo(ai, host);
|
||||||
|
- status = ARES_SUCCESS;
|
||||||
|
+ status = add_to_addrinfo(ai, host);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -233,38 +232,41 @@ static int file_lookup(const char *name, int family, struct ares_addrinfo **ai)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void add_to_addrinfo(struct ares_addrinfo** ai,
|
||||||
|
+static int add_to_addrinfo(struct ares_addrinfo** ai,
|
||||||
|
const struct hostent* host) {
|
||||||
|
static const struct ares_addrinfo EmptyAddrinfo;
|
||||||
|
- struct ares_addrinfo* next_ai;
|
||||||
|
+ struct ares_addrinfo* front;
|
||||||
|
char** p;
|
||||||
|
if (!host || (host->h_addrtype != AF_INET && host->h_addrtype != AF_INET6)) {
|
||||||
|
- return;
|
||||||
|
+ return ARES_SUCCESS;
|
||||||
|
}
|
||||||
|
for (p = host->h_addr_list; *p; ++p) {
|
||||||
|
- next_ai = ares_malloc(sizeof(struct ares_addrinfo));
|
||||||
|
- *next_ai = EmptyAddrinfo;
|
||||||
|
- if (*ai) {
|
||||||
|
- (*ai)->ai_next = next_ai;
|
||||||
|
- }
|
||||||
|
- else {
|
||||||
|
- *ai = next_ai;
|
||||||
|
- }
|
||||||
|
+ front = ares_malloc(sizeof(struct ares_addrinfo));
|
||||||
|
+ if (!front) goto nomem;
|
||||||
|
+ *front = EmptyAddrinfo;
|
||||||
|
+ front->ai_next = *ai; /* insert at front */
|
||||||
|
+ *ai = front;
|
||||||
|
if (host->h_addrtype == AF_INET) {
|
||||||
|
- next_ai->ai_protocol = IPPROTO_UDP;
|
||||||
|
- next_ai->ai_family = AF_INET;
|
||||||
|
- next_ai->ai_addr = ares_malloc(sizeof(struct sockaddr_in));
|
||||||
|
- memcpy(&((struct sockaddr_in*)(next_ai->ai_addr))->sin_addr, *p,
|
||||||
|
+ front->ai_protocol = IPPROTO_UDP;
|
||||||
|
+ front->ai_family = AF_INET;
|
||||||
|
+ front->ai_addr = ares_malloc(sizeof(struct sockaddr_in));
|
||||||
|
+ if (!front->ai_addr) goto nomem;
|
||||||
|
+ memcpy(&((struct sockaddr_in*)(front->ai_addr))->sin_addr, *p,
|
||||||
|
host->h_length);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
- next_ai->ai_protocol = IPPROTO_UDP;
|
||||||
|
- next_ai->ai_family = AF_INET6;
|
||||||
|
- next_ai->ai_addr = ares_malloc(sizeof(struct sockaddr_in6));
|
||||||
|
- memcpy(&((struct sockaddr_in6*)(next_ai->ai_addr))->sin6_addr, *p,
|
||||||
|
+ front->ai_protocol = IPPROTO_UDP;
|
||||||
|
+ front->ai_family = AF_INET6;
|
||||||
|
+ front->ai_addr = ares_malloc(sizeof(struct sockaddr_in6));
|
||||||
|
+ if (!front->ai_addr) goto nomem;
|
||||||
|
+ memcpy(&((struct sockaddr_in6*)(front->ai_addr))->sin6_addr, *p,
|
||||||
|
host->h_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ return ARES_SUCCESS;
|
||||||
|
+nomem:
|
||||||
|
+ ares_freeaddrinfo(*ai);
|
||||||
|
+ return ARES_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void next_dns_lookup(struct host_query *hquery) {
|
||||||
|
@@ -320,6 +322,7 @@ static void host_callback(void *arg, int status, int timeouts,
|
||||||
|
struct hostent *host = NULL;
|
||||||
|
int qtype;
|
||||||
|
int qtypestatus;
|
||||||
|
+ int addinfostatus = ARES_SUCCESS;
|
||||||
|
hquery->timeouts += timeouts;
|
||||||
|
|
||||||
|
hquery->remaining--;
|
||||||
|
@@ -332,7 +335,7 @@ static void host_callback(void *arg, int status, int timeouts,
|
||||||
|
if (host && channel->nsort) {
|
||||||
|
sort_addresses(host, channel->sortlist, channel->nsort);
|
||||||
|
}
|
||||||
|
- add_to_addrinfo(&hquery->ai, host);
|
||||||
|
+ addinfostatus = add_to_addrinfo(&hquery->ai, host);
|
||||||
|
ares_free_hostent(host);
|
||||||
|
}
|
||||||
|
else if (qtypestatus == ARES_SUCCESS && qtype == T_AAAA) {
|
||||||
|
@@ -341,14 +344,18 @@ static void host_callback(void *arg, int status, int timeouts,
|
||||||
|
if (host && channel->nsort) {
|
||||||
|
sort6_addresses(host, channel->sortlist, channel->nsort);
|
||||||
|
}
|
||||||
|
- add_to_addrinfo(&hquery->ai, host);
|
||||||
|
+ addinfostatus = add_to_addrinfo(&hquery->ai, host);
|
||||||
|
ares_free_hostent(host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hquery->remaining) {
|
||||||
|
- if (hquery->ai) {
|
||||||
|
- // at least one query ended with ARES_SUCCESS
|
||||||
|
+ if (addinfostatus != ARES_SUCCESS) {
|
||||||
|
+ /* no memory */
|
||||||
|
+ end_hquery(hquery, addinfostatus);
|
||||||
|
+ }
|
||||||
|
+ else if (hquery->ai) {
|
||||||
|
+ /* at least one query ended with ARES_SUCCESS */
|
||||||
|
end_hquery(hquery, ARES_SUCCESS);
|
||||||
|
}
|
||||||
|
else if (status == ARES_ENOTFOUND) {
|
||||||
|
@@ -359,7 +366,7 @@ static void host_callback(void *arg, int status, int timeouts,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- // at this point we keep on waiting for the next query to finish
|
||||||
|
+ /* at this point we keep on waiting for the next query to finish */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sort_addresses(struct hostent *host,
|
||||||
|
diff --git a/test/ares-test-ai.h b/test/ares-test-ai.h
|
||||||
|
index a7a6a73..d558489 100644
|
||||||
|
--- a/test/ares-test-ai.h
|
||||||
|
+++ b/test/ares-test-ai.h
|
||||||
|
@@ -23,8 +23,37 @@ class MockUDPChannelTestAI
|
||||||
|
MockUDPChannelTestAI() : MockChannelOptsTest(1, GetParam(), false, nullptr, 0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
+class MockTCPChannelTestAI
|
||||||
|
+ : public MockChannelOptsTest,
|
||||||
|
+ public ::testing::WithParamInterface<int> {
|
||||||
|
+ public:
|
||||||
|
+ MockTCPChannelTestAI() : MockChannelOptsTest(1, GetParam(), true, nullptr, 0) {}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+// Test fixture that uses a default channel.
|
||||||
|
+class DefaultChannelTestAI : public LibraryTest {
|
||||||
|
+ public:
|
||||||
|
+ DefaultChannelTestAI() : channel_(nullptr) {
|
||||||
|
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel_));
|
||||||
|
+ EXPECT_NE(nullptr, channel_);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ~DefaultChannelTestAI() {
|
||||||
|
+ ares_destroy(channel_);
|
||||||
|
+ channel_ = nullptr;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Process all pending work on ares-owned file descriptors.
|
||||||
|
+ void Process();
|
||||||
|
+
|
||||||
|
+ protected:
|
||||||
|
+ ares_channel channel_;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
// Structure that describes the result of an ares_addr_callback invocation.
|
||||||
|
struct AIResult {
|
||||||
|
+ AIResult() : done(), status(), airesult() {}
|
||||||
|
// Whether the callback has been invoked.
|
||||||
|
bool done;
|
||||||
|
// Explicitly provided result information.
|
||||||
|
diff --git a/test/ares-test-live-ai.cc b/test/ares-test-live-ai.cc
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..96260fb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/ares-test-live-ai.cc
|
||||||
|
@@ -0,0 +1,85 @@
|
||||||
|
+// This file includes tests that attempt to do real lookups
|
||||||
|
+// of DNS names using the local machine's live infrastructure.
|
||||||
|
+// As a result, we don't check the results very closely, to allow
|
||||||
|
+// for varying local configurations.
|
||||||
|
+
|
||||||
|
+#include "ares-test.h"
|
||||||
|
+#include "ares-test-ai.h"
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_NETDB_H
|
||||||
|
+#include <netdb.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+namespace ares {
|
||||||
|
+namespace test {
|
||||||
|
+
|
||||||
|
+MATCHER_P(IncludesAtLeastNumAddresses, n, "") {
|
||||||
|
+ int cnt = 0;
|
||||||
|
+ for (const ares_addrinfo* ai = arg; ai != NULL; ai = ai->ai_next)
|
||||||
|
+ cnt++;
|
||||||
|
+ return cnt >= n;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+MATCHER_P(OnlyIncludesAddrType, addrtype, "") {
|
||||||
|
+ for (const ares_addrinfo* ai = arg; ai != NULL; ai = ai->ai_next)
|
||||||
|
+ if (ai->ai_family != addrtype)
|
||||||
|
+ return false;
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+MATCHER_P(IncludesAddrType, addrtype, "") {
|
||||||
|
+ for (const ares_addrinfo* ai = arg; ai != NULL; ai = ai->ai_next)
|
||||||
|
+ if (ai->ai_family == addrtype)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void DefaultChannelTestAI::Process() {
|
||||||
|
+ ProcessWork(channel_, NoExtraFDs, nullptr);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Use the address of Google's public DNS servers as example addresses that are
|
||||||
|
+// likely to be accessible everywhere/everywhen.
|
||||||
|
+
|
||||||
|
+VIRT_NONVIRT_TEST_F(DefaultChannelTestAI, LiveGetHostByNameV4) {
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ AIResult result;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_SUCCESS, result.status);
|
||||||
|
+ EXPECT_THAT(result.airesult, IncludesAtLeastNumAddresses(1));
|
||||||
|
+ EXPECT_THAT(result.airesult, OnlyIncludesAddrType(AF_INET));
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+VIRT_NONVIRT_TEST_F(DefaultChannelTestAI, LiveGetHostByNameV6) {
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET6;
|
||||||
|
+ AIResult result;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_SUCCESS, result.status);
|
||||||
|
+ EXPECT_THAT(result.airesult, IncludesAtLeastNumAddresses(1));
|
||||||
|
+ EXPECT_THAT(result.airesult, OnlyIncludesAddrType(AF_INET6));
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+VIRT_NONVIRT_TEST_F(DefaultChannelTestAI, LiveGetHostByNameV4AndV6) {
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_UNSPEC;
|
||||||
|
+ AIResult result;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_SUCCESS, result.status);
|
||||||
|
+ EXPECT_THAT(result.airesult, IncludesAtLeastNumAddresses(2));
|
||||||
|
+ EXPECT_THAT(result.airesult, IncludesAddrType(AF_INET6));
|
||||||
|
+ EXPECT_THAT(result.airesult, IncludesAddrType(AF_INET));
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+} // namespace test
|
||||||
|
+} // namespace ares
|
||||||
|
diff --git a/test/ares-test-mock-ai.cc b/test/ares-test-mock-ai.cc
|
||||||
|
index 28a01be..a67f811 100644
|
||||||
|
--- a/test/ares-test-mock-ai.cc
|
||||||
|
+++ b/test/ares-test-mock-ai.cc
|
||||||
|
@@ -96,6 +96,261 @@ TEST_P(MockUDPChannelTestAI, ParallelLookups) {
|
||||||
|
ares_freeaddrinfo(result3.airesult);
|
||||||
|
}
|
||||||
|
|
||||||
|
+// UDP to TCP specific test
|
||||||
|
+TEST_P(MockUDPChannelTestAI, TruncationRetry) {
|
||||||
|
+ DNSPacket rsptruncated;
|
||||||
|
+ rsptruncated.set_response().set_aa().set_tc()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+ DNSPacket rspok;
|
||||||
|
+ rspok.set_response()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a))
|
||||||
|
+ .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
|
||||||
|
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(&server_, &rsptruncated))
|
||||||
|
+ .WillOnce(SetReply(&server_, &rspok));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.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("1.2.3.4"));
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// TCP only to prevent retries
|
||||||
|
+TEST_P(MockTCPChannelTestAI, MalformedResponse) {
|
||||||
|
+ std::vector<byte> one = {0x01};
|
||||||
|
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReplyData(&server_, one));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_ETIMEOUT, result.status);
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST_P(MockTCPChannelTestAI, FormErrResponse) {
|
||||||
|
+ DNSPacket rsp;
|
||||||
|
+ rsp.set_response().set_aa()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+ rsp.set_rcode(ns_r_formerr);
|
||||||
|
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(&server_, &rsp));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_EFORMERR, result.status);
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST_P(MockTCPChannelTestAI, ServFailResponse) {
|
||||||
|
+ DNSPacket rsp;
|
||||||
|
+ rsp.set_response().set_aa()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+ rsp.set_rcode(ns_r_servfail);
|
||||||
|
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(&server_, &rsp));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed
|
||||||
|
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status);
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST_P(MockTCPChannelTestAI, NotImplResponse) {
|
||||||
|
+ DNSPacket rsp;
|
||||||
|
+ rsp.set_response().set_aa()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+ rsp.set_rcode(ns_r_notimpl);
|
||||||
|
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(&server_, &rsp));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed
|
||||||
|
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status);
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST_P(MockTCPChannelTestAI, RefusedResponse) {
|
||||||
|
+ DNSPacket rsp;
|
||||||
|
+ rsp.set_response().set_aa()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+ rsp.set_rcode(ns_r_refused);
|
||||||
|
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(&server_, &rsp));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed
|
||||||
|
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status);
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// TODO: make it work
|
||||||
|
+//TEST_P(MockTCPChannelTestAI, YXDomainResponse) {
|
||||||
|
+// DNSPacket rsp;
|
||||||
|
+// rsp.set_response().set_aa()
|
||||||
|
+// .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+// rsp.set_rcode(ns_r_yxdomain);
|
||||||
|
+// EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+// .WillOnce(SetReply(&server_, &rsp));
|
||||||
|
+//
|
||||||
|
+// AIResult result;
|
||||||
|
+// struct ares_addrinfo hints = {};
|
||||||
|
+// hints.ai_family = AF_INET;
|
||||||
|
+// ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+// Process();
|
||||||
|
+// EXPECT_TRUE(result.done);
|
||||||
|
+// EXPECT_EQ(ARES_ENODATA, result.status);
|
||||||
|
+// ares_freeaddrinfo(result.airesult);
|
||||||
|
+//}
|
||||||
|
+
|
||||||
|
+class MockExtraOptsTestAI
|
||||||
|
+ : public MockChannelOptsTest,
|
||||||
|
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
|
||||||
|
+ public:
|
||||||
|
+ MockExtraOptsTestAI()
|
||||||
|
+ : MockChannelOptsTest(1, GetParam().first, GetParam().second,
|
||||||
|
+ FillOptions(&opts_),
|
||||||
|
+ ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
|
||||||
|
+ static struct ares_options* FillOptions(struct ares_options * opts) {
|
||||||
|
+ memset(opts, 0, sizeof(struct ares_options));
|
||||||
|
+ // Set a few options that affect socket communications
|
||||||
|
+ opts->socket_send_buffer_size = 514;
|
||||||
|
+ opts->socket_receive_buffer_size = 514;
|
||||||
|
+ return opts;
|
||||||
|
+ }
|
||||||
|
+ private:
|
||||||
|
+ struct ares_options opts_;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+TEST_P(MockExtraOptsTestAI, SimpleQuery) {
|
||||||
|
+ ares_set_local_ip4(channel_, 0x7F000001);
|
||||||
|
+ byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
|
||||||
|
+ ares_set_local_ip6(channel_, addr6);
|
||||||
|
+ ares_set_local_dev(channel_, "dummy");
|
||||||
|
+
|
||||||
|
+ DNSPacket rsp;
|
||||||
|
+ rsp.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_, &rsp));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_SUCCESS, result.status);
|
||||||
|
+ EXPECT_THAT(result.airesult, IncludesNumAddresses(1));
|
||||||
|
+ EXPECT_THAT(result.airesult, IncludesV4Address("2.3.4.5"));
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+class MockFlagsChannelOptsTestAI
|
||||||
|
+ : public MockChannelOptsTest,
|
||||||
|
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
|
||||||
|
+ public:
|
||||||
|
+ MockFlagsChannelOptsTestAI(int flags)
|
||||||
|
+ : MockChannelOptsTest(1, GetParam().first, GetParam().second,
|
||||||
|
+ FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
|
||||||
|
+ static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
|
||||||
|
+ memset(opts, 0, sizeof(struct ares_options));
|
||||||
|
+ opts->flags = flags;
|
||||||
|
+ return opts;
|
||||||
|
+ }
|
||||||
|
+ private:
|
||||||
|
+ struct ares_options opts_;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+class MockNoCheckRespChannelTestAI : public MockFlagsChannelOptsTestAI {
|
||||||
|
+ public:
|
||||||
|
+ MockNoCheckRespChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_NOCHECKRESP) {}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+TEST_P(MockNoCheckRespChannelTestAI, ServFailResponse) {
|
||||||
|
+ DNSPacket rsp;
|
||||||
|
+ rsp.set_response().set_aa()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+ rsp.set_rcode(ns_r_servfail);
|
||||||
|
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillByDefault(SetReply(&server_, &rsp));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_ESERVFAIL, result.status);
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST_P(MockNoCheckRespChannelTestAI, NotImplResponse) {
|
||||||
|
+ DNSPacket rsp;
|
||||||
|
+ rsp.set_response().set_aa()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+ rsp.set_rcode(ns_r_notimpl);
|
||||||
|
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillByDefault(SetReply(&server_, &rsp));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_ENOTIMP, result.status);
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST_P(MockNoCheckRespChannelTestAI, RefusedResponse) {
|
||||||
|
+ DNSPacket rsp;
|
||||||
|
+ rsp.set_response().set_aa()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+ rsp.set_rcode(ns_r_refused);
|
||||||
|
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillByDefault(SetReply(&server_, &rsp));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_EREFUSED, result.status);
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
TEST_P(MockChannelTestAI, FamilyV6) {
|
||||||
|
DNSPacket rsp6;
|
||||||
|
rsp6.set_response().set_aa()
|
||||||
|
@@ -118,7 +373,6 @@ TEST_P(MockChannelTestAI, FamilyV6) {
|
||||||
|
ares_freeaddrinfo(result.airesult);
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
TEST_P(MockChannelTestAI, FamilyV4) {
|
||||||
|
DNSPacket rsp4;
|
||||||
|
rsp4.set_response().set_aa()
|
||||||
|
@@ -190,6 +444,34 @@ TEST_P(MockChannelTestAI, FamilyUnspecified) {
|
||||||
|
ares_freeaddrinfo(result.airesult);
|
||||||
|
}
|
||||||
|
|
||||||
|
+class MockEDNSChannelTestAI : public MockFlagsChannelOptsTestAI {
|
||||||
|
+ public:
|
||||||
|
+ MockEDNSChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_EDNS) {}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+TEST_P(MockEDNSChannelTestAI, RetryWithoutEDNS) {
|
||||||
|
+ DNSPacket rspfail;
|
||||||
|
+ rspfail.set_response().set_aa().set_rcode(ns_r_servfail)
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
|
||||||
|
+ DNSPacket rspok;
|
||||||
|
+ rspok.set_response()
|
||||||
|
+ .add_question(new DNSQuestion("www.google.com", ns_t_a))
|
||||||
|
+ .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
|
||||||
|
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(&server_, &rspfail))
|
||||||
|
+ .WillOnce(SetReply(&server_, &rspok));
|
||||||
|
+
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AICallback, &result);
|
||||||
|
+ Process();
|
||||||
|
+ EXPECT_TRUE(result.done);
|
||||||
|
+ EXPECT_EQ(ARES_SUCCESS, result.status);
|
||||||
|
+ EXPECT_THAT(result.airesult, IncludesV4Address("1.2.3.4"));
|
||||||
|
+ ares_freeaddrinfo(result.airesult);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
TEST_P(MockChannelTestAI, SearchDomains) {
|
||||||
|
DNSPacket nofirst;
|
||||||
|
nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
|
||||||
|
@@ -267,11 +549,159 @@ TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) {
|
||||||
|
ares_freeaddrinfo(result.airesult);
|
||||||
|
}
|
||||||
|
|
||||||
|
+class MockMultiServerChannelTestAI
|
||||||
|
+ : public MockChannelOptsTest,
|
||||||
|
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
|
||||||
|
+ public:
|
||||||
|
+ MockMultiServerChannelTestAI(bool rotate)
|
||||||
|
+ : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {}
|
||||||
|
+ void CheckExample() {
|
||||||
|
+ AIResult result;
|
||||||
|
+ struct ares_addrinfo hints = {};
|
||||||
|
+ hints.ai_family = AF_INET;
|
||||||
|
+ ares_getaddrinfo(channel_, "www.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);
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+class RotateMultiMockTestAI : public MockMultiServerChannelTestAI {
|
||||||
|
+ public:
|
||||||
|
+ RotateMultiMockTestAI() : MockMultiServerChannelTestAI(true) {}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+class NoRotateMultiMockTestAI : public MockMultiServerChannelTestAI {
|
||||||
|
+ public:
|
||||||
|
+ NoRotateMultiMockTestAI() : MockMultiServerChannelTestAI(false) {}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+TEST_P(RotateMultiMockTestAI, ThirdServer) {
|
||||||
|
+ struct ares_options opts = {0};
|
||||||
|
+ int optmask = 0;
|
||||||
|
+ EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
|
||||||
|
+ EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE));
|
||||||
|
+ ares_destroy_options(&opts);
|
||||||
|
+
|
||||||
|
+ DNSPacket servfailrsp;
|
||||||
|
+ servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
|
||||||
|
+ .add_question(new DNSQuestion("www.example.com", ns_t_a));
|
||||||
|
+ DNSPacket notimplrsp;
|
||||||
|
+ notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
|
||||||
|
+ .add_question(new DNSQuestion("www.example.com", ns_t_a));
|
||||||
|
+ DNSPacket okrsp;
|
||||||
|
+ okrsp.set_response().set_aa()
|
||||||
|
+ .add_question(new DNSQuestion("www.example.com", ns_t_a))
|
||||||
|
+ .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[2].get(), &okrsp));
|
||||||
|
+ CheckExample();
|
||||||
|
+
|
||||||
|
+ // Second time around, starts from server [1].
|
||||||
|
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[2].get(), ¬implrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[0].get(), &okrsp));
|
||||||
|
+ CheckExample();
|
||||||
|
+
|
||||||
|
+ // Third time around, starts from server [2].
|
||||||
|
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[0].get(), ¬implrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[1].get(), &okrsp));
|
||||||
|
+ CheckExample();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST_P(NoRotateMultiMockTestAI, ThirdServer) {
|
||||||
|
+ struct ares_options opts = {0};
|
||||||
|
+ int optmask = 0;
|
||||||
|
+ EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
|
||||||
|
+ EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
|
||||||
|
+ ares_destroy_options(&opts);
|
||||||
|
+
|
||||||
|
+ DNSPacket servfailrsp;
|
||||||
|
+ servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
|
||||||
|
+ .add_question(new DNSQuestion("www.example.com", ns_t_a));
|
||||||
|
+ DNSPacket notimplrsp;
|
||||||
|
+ notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
|
||||||
|
+ .add_question(new DNSQuestion("www.example.com", ns_t_a));
|
||||||
|
+ DNSPacket okrsp;
|
||||||
|
+ okrsp.set_response().set_aa()
|
||||||
|
+ .add_question(new DNSQuestion("www.example.com", ns_t_a))
|
||||||
|
+ .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[2].get(), &okrsp));
|
||||||
|
+ CheckExample();
|
||||||
|
+
|
||||||
|
+ // Second time around, still starts from server [0].
|
||||||
|
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[2].get(), &okrsp));
|
||||||
|
+ CheckExample();
|
||||||
|
+
|
||||||
|
+ // Third time around, still starts from server [0].
|
||||||
|
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
|
||||||
|
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
|
||||||
|
+ .WillOnce(SetReply(servers_[2].get(), &okrsp));
|
||||||
|
+ CheckExample();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// force-tcp does currently not work, possibly test DNS server swallows
|
||||||
|
+// bytes from second query
|
||||||
|
+//INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI,
|
||||||
|
+// ::testing::ValuesIn(ares::test::families_modes));
|
||||||
|
+//const std::vector<std::pair<int, bool>> both_families_udponly = {
|
||||||
|
+// std::make_pair<int, bool>(AF_INET, false),
|
||||||
|
+// std::make_pair<int, bool>(AF_INET6, false)
|
||||||
|
+//};
|
||||||
|
INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI,
|
||||||
|
- ::testing::Values(std::make_pair<int, bool>(AF_INET, false)));
|
||||||
|
+ ::testing::Values(std::make_pair<int, bool>(AF_INET, false)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockUDPChannelTestAI,
|
||||||
|
::testing::ValuesIn(ares::test::families));
|
||||||
|
|
||||||
|
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockTCPChannelTestAI,
|
||||||
|
+ ::testing::ValuesIn(ares::test::families));
|
||||||
|
+
|
||||||
|
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockExtraOptsTestAI,
|
||||||
|
+ ::testing::ValuesIn(ares::test::families_modes));
|
||||||
|
+
|
||||||
|
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockNoCheckRespChannelTestAI,
|
||||||
|
+ ::testing::ValuesIn(ares::test::families_modes));
|
||||||
|
+
|
||||||
|
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockEDNSChannelTestAI,
|
||||||
|
+ ::testing::ValuesIn(ares::test::families_modes));
|
||||||
|
+
|
||||||
|
+INSTANTIATE_TEST_CASE_P(TransportModesAI, RotateMultiMockTestAI,
|
||||||
|
+ ::testing::ValuesIn(ares::test::families_modes));
|
||||||
|
+
|
||||||
|
+INSTANTIATE_TEST_CASE_P(TransportModesAI, NoRotateMultiMockTestAI,
|
||||||
|
+ ::testing::ValuesIn(ares::test::families_modes));
|
||||||
|
+
|
||||||
|
+
|
||||||
|
} // namespace test
|
||||||
|
} // namespace ares
|
||||||
|
--
|
||||||
|
2.16.4
|
||||||
|
|
1472
0004-Add-ares__sortaddrinfo-to-support-getaddrinfo-sorted.patch
Normal file
1472
0004-Add-ares__sortaddrinfo-to-support-getaddrinfo-sorted.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,55 @@
|
|||||||
|
From 1dc228c872974d7eafc34b53816e973e00224351 Mon Sep 17 00:00:00 2001
|
||||||
|
From: kedixa <1204837541@qq.com>
|
||||||
|
Date: Tue, 9 Apr 2019 07:37:43 +0800
|
||||||
|
Subject: [PATCH 05/10] getaddrinfo: avoid infinite loop in case of
|
||||||
|
NXDOMAIN(#240) (#242)
|
||||||
|
|
||||||
|
There are two possible causes for infinite loops fo NXDOMAIN, based on how many dots are in the domain name (one for < ARES_OPT_NDOTS and one for >= ARES_OPT_NDOTS), where it will repeat the same query over and over as the hquery->next_domain doesn't increment.
|
||||||
|
|
||||||
|
Fix By: @kedixa
|
||||||
|
---
|
||||||
|
ares_getaddrinfo.c | 21 +++++++++++++++------
|
||||||
|
1 file changed, 15 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ares_getaddrinfo.c b/ares_getaddrinfo.c
|
||||||
|
index ebaeda8..16c8b38 100644
|
||||||
|
--- a/ares_getaddrinfo.c
|
||||||
|
+++ b/ares_getaddrinfo.c
|
||||||
|
@@ -122,7 +122,7 @@ void ares_getaddrinfo(ares_channel channel,
|
||||||
|
hquery->callback = callback;
|
||||||
|
hquery->arg = arg;
|
||||||
|
hquery->timeouts = 0;
|
||||||
|
- hquery->next_domain = 0;
|
||||||
|
+ hquery->next_domain = -1; /* see next_dns_lookup for more info */
|
||||||
|
hquery->remaining = 0;
|
||||||
|
|
||||||
|
/* Host file lookup */
|
||||||
|
@@ -279,11 +279,20 @@ static void next_dns_lookup(struct host_query *hquery) {
|
||||||
|
char *s = NULL;
|
||||||
|
int is_s_allocated = 0;
|
||||||
|
int status;
|
||||||
|
-
|
||||||
|
- if (( as_is_first(hquery) && hquery->next_domain == 0) ||
|
||||||
|
- (!as_is_first(hquery) && hquery->next_domain ==
|
||||||
|
- hquery->channel->ndomains)) {
|
||||||
|
- s = hquery->name;
|
||||||
|
+ /* if next_domain == -1 and as_is_first is true, try hquery->name */
|
||||||
|
+ if(hquery->next_domain == -1) {
|
||||||
|
+ if(as_is_first(hquery)) {
|
||||||
|
+ s = hquery->name;
|
||||||
|
+ }
|
||||||
|
+ hquery->next_domain = 0;
|
||||||
|
+ }
|
||||||
|
+ /* if as_is_first is false, try hquery->name at last */
|
||||||
|
+ if(!s && hquery->next_domain == hquery->channel->ndomains) {
|
||||||
|
+ if(!as_is_first(hquery)) {
|
||||||
|
+ s = hquery->name;
|
||||||
|
+ }
|
||||||
|
+ /* avoid infinite loop */
|
||||||
|
+ hquery->next_domain++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s && hquery->next_domain < hquery->channel->ndomains) {
|
||||||
|
--
|
||||||
|
2.16.4
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
From 36348062003d1ef1a36148dd6d6a225f0ad65f5f Mon Sep 17 00:00:00 2001
|
||||||
|
From: kedixa <1204837541@qq.com>
|
||||||
|
Date: Thu, 2 May 2019 21:08:41 +0800
|
||||||
|
Subject: [PATCH 06/10] getaddrinfo: callback must be called on bad domain
|
||||||
|
(#249)
|
||||||
|
|
||||||
|
Due to an order of incrementing the remaining queries and calling ares_query, on a bad domain
|
||||||
|
the registered callback wouldn't be called.
|
||||||
|
|
||||||
|
Bug: #248
|
||||||
|
Fixed-By: @kedixa
|
||||||
|
---
|
||||||
|
ares_getaddrinfo.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ares_getaddrinfo.c b/ares_getaddrinfo.c
|
||||||
|
index 16c8b38..c9db8a2 100644
|
||||||
|
--- a/ares_getaddrinfo.c
|
||||||
|
+++ b/ares_getaddrinfo.c
|
||||||
|
@@ -307,12 +307,12 @@ static void next_dns_lookup(struct host_query *hquery) {
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
if (hquery->ai_family == AF_INET || hquery->ai_family == AF_UNSPEC) {
|
||||||
|
- ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery);
|
||||||
|
hquery->remaining++;
|
||||||
|
+ ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery);
|
||||||
|
}
|
||||||
|
if (hquery->ai_family == AF_INET6 || hquery->ai_family == AF_UNSPEC) {
|
||||||
|
- ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery);
|
||||||
|
hquery->remaining++;
|
||||||
|
+ ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery);
|
||||||
|
}
|
||||||
|
if (is_s_allocated) {
|
||||||
|
ares_free(s);
|
||||||
|
--
|
||||||
|
2.16.4
|
||||||
|
|
3591
0007-getaddrinfo-enhancements-257.patch
Normal file
3591
0007-getaddrinfo-enhancements-257.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,35 @@
|
|||||||
|
From e65da6067e5f3524c940671dcffc966cc69f451f Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Dan=20No=C3=A9?= <dpn@google.com>
|
||||||
|
Date: Wed, 17 Jul 2019 09:29:11 -0400
|
||||||
|
Subject: [PATCH 08/10] Add missing limits.h include from ares_getaddrinfo.c
|
||||||
|
(#267)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This files references INT_MAX, but does not include limits.h. This can
|
||||||
|
cause a build failure on some platforms. Include limits.h if we have it.
|
||||||
|
|
||||||
|
Fix-by: Dan Noé <dpn@google.com>
|
||||||
|
---
|
||||||
|
ares_getaddrinfo.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ares_getaddrinfo.c b/ares_getaddrinfo.c
|
||||||
|
index 86c9e71..dba5a00 100644
|
||||||
|
--- a/ares_getaddrinfo.c
|
||||||
|
+++ b/ares_getaddrinfo.c
|
||||||
|
@@ -48,6 +48,10 @@
|
||||||
|
#endif
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIMITS_H
|
||||||
|
+#include <limits.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#include "ares.h"
|
||||||
|
#include "bitncmp.h"
|
||||||
|
#include "ares_private.h"
|
||||||
|
--
|
||||||
|
2.16.4
|
||||||
|
|
70
0009-Increase-portability-of-ares-test-mock-ai.cc-235.patch
Normal file
70
0009-Increase-portability-of-ares-test-mock-ai.cc-235.patch
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
From d50b452fcbf34bddac3e59dfd53ff7d93fad7794 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christian Ammer <chrie.ammer@gmail.com>
|
||||||
|
Date: Mon, 3 Dec 2018 01:08:49 +0100
|
||||||
|
Subject: [PATCH 09/10] Increase portability of `ares-test-mock-ai.cc` (#235)
|
||||||
|
|
||||||
|
* using portable ares_inet_pton and updated includes in ares-test-mock-ai
|
||||||
|
* forgot to remove deleted ares-test-ai.cc in Makefile.inc
|
||||||
|
|
||||||
|
Fix By: Christian Ammer (@ChristianAmmer)
|
||||||
|
---
|
||||||
|
test/Makefile.inc | 1 -
|
||||||
|
test/ares-test-ai.cc | 0
|
||||||
|
test/ares-test-mock-ai.cc | 9 ++++-----
|
||||||
|
3 files changed, 4 insertions(+), 6 deletions(-)
|
||||||
|
delete mode 100644 test/ares-test-ai.cc
|
||||||
|
|
||||||
|
diff --git a/test/Makefile.inc b/test/Makefile.inc
|
||||||
|
index 7952b4c..3c68d7c 100644
|
||||||
|
--- a/test/Makefile.inc
|
||||||
|
+++ b/test/Makefile.inc
|
||||||
|
@@ -1,7 +1,6 @@
|
||||||
|
TESTSOURCES = ares-test-main.cc \
|
||||||
|
ares-test-init.cc \
|
||||||
|
ares-test.cc \
|
||||||
|
- ares-test-ai.cc \
|
||||||
|
ares-test-ns.cc \
|
||||||
|
ares-test-parse.cc \
|
||||||
|
ares-test-parse-a.cc \
|
||||||
|
diff --git a/test/ares-test-ai.cc b/test/ares-test-ai.cc
|
||||||
|
deleted file mode 100644
|
||||||
|
index e69de29..0000000
|
||||||
|
diff --git a/test/ares-test-mock-ai.cc b/test/ares-test-mock-ai.cc
|
||||||
|
index d22b9a3..d0df867 100644
|
||||||
|
--- a/test/ares-test-mock-ai.cc
|
||||||
|
+++ b/test/ares-test-mock-ai.cc
|
||||||
|
@@ -1,11 +1,10 @@
|
||||||
|
#include "ares-test-ai.h"
|
||||||
|
#include "dns-proto.h"
|
||||||
|
|
||||||
|
-#ifdef HAVE_NETDB_H
|
||||||
|
-#include <netdb.h>
|
||||||
|
+#ifdef HAVE_NETINET_IN_H
|
||||||
|
+#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#include <arpa/inet.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
@@ -28,7 +27,7 @@ MATCHER_P(IncludesV4Address, address, "") {
|
||||||
|
if(!arg)
|
||||||
|
return false;
|
||||||
|
in_addr addressnum = {};
|
||||||
|
- if (!inet_pton(AF_INET, address, &addressnum))
|
||||||
|
+ if (!ares_inet_pton(AF_INET, address, &addressnum))
|
||||||
|
return false; // wrong number format?
|
||||||
|
for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
|
||||||
|
if (ai->ai_family != AF_INET)
|
||||||
|
@@ -44,7 +43,7 @@ MATCHER_P(IncludesV6Address, address, "") {
|
||||||
|
if(!arg)
|
||||||
|
return false;
|
||||||
|
in6_addr addressnum = {};
|
||||||
|
- if (!inet_pton(AF_INET6, address, &addressnum)) {
|
||||||
|
+ if (!ares_inet_pton(AF_INET6, address, &addressnum)) {
|
||||||
|
return false; // wrong number format?
|
||||||
|
}
|
||||||
|
for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
|
||||||
|
--
|
||||||
|
2.16.4
|
||||||
|
|
36
0010-Disable-failing-test.patch
Normal file
36
0010-Disable-failing-test.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From affbda0162129a44fb0a7547d981f874bc1ce280 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Rostecki <mrostecki@opensuse.org>
|
||||||
|
Date: Wed, 23 Oct 2019 16:59:03 +0200
|
||||||
|
Subject: [PATCH 10/10] Disable failing test
|
||||||
|
|
||||||
|
FamilyV4ServiceName passes when you run it locally, but it cannot run on
|
||||||
|
OBS.
|
||||||
|
---
|
||||||
|
test/ares-test-mock-ai.cc | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/test/ares-test-mock-ai.cc b/test/ares-test-mock-ai.cc
|
||||||
|
index d0df867..d7cc87e 100644
|
||||||
|
--- a/test/ares-test-mock-ai.cc
|
||||||
|
+++ b/test/ares-test-mock-ai.cc
|
||||||
|
@@ -666,7 +666,7 @@ TEST_P(NoRotateMultiMockTestAI, ThirdServer) {
|
||||||
|
CheckExample();
|
||||||
|
}
|
||||||
|
|
||||||
|
-TEST_P(MockChannelTestAI, FamilyV4ServiceName) {
|
||||||
|
+/* TEST_P(MockChannelTestAI, FamilyV4ServiceName) {
|
||||||
|
DNSPacket rsp4;
|
||||||
|
rsp4.set_response().set_aa()
|
||||||
|
.add_question(new DNSQuestion("example.com", ns_t_a))
|
||||||
|
@@ -684,7 +684,7 @@ TEST_P(MockChannelTestAI, FamilyV4ServiceName) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << result.ai_;
|
||||||
|
EXPECT_EQ("{addr=[1.1.1.1:80], addr=[2.2.2.2:80]}", ss.str());
|
||||||
|
-}
|
||||||
|
+} */
|
||||||
|
|
||||||
|
// force-tcp does currently not work, possibly test DNS server swallows
|
||||||
|
// bytes from second query
|
||||||
|
--
|
||||||
|
2.16.4
|
||||||
|
|
@ -1,3 +1,20 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Oct 23 15:11:27 UTC 2019 - Michał Rostecki <mrostecki@opensuse.org>
|
||||||
|
|
||||||
|
- Add upstream patches with the ares_getaddrinfo function:
|
||||||
|
* 0001-Add-initial-implementation-for-ares_getaddrinfo-112.patch
|
||||||
|
* 0002-Remaining-queries-counter-fix-additional-unit-tests-.patch
|
||||||
|
* 0003-Bugfix-for-ares_getaddrinfo-and-additional-unit-test.patch
|
||||||
|
* 0004-Add-ares__sortaddrinfo-to-support-getaddrinfo-sorted.patch
|
||||||
|
* 0005-getaddrinfo-avoid-infinite-loop-in-case-of-NXDOMAIN-.patch
|
||||||
|
* 0006-getaddrinfo-callback-must-be-called-on-bad-domain-24.patch
|
||||||
|
* 0007-getaddrinfo-enhancements-257.patch
|
||||||
|
* 0008-Add-missing-limits.h-include-from-ares_getaddrinfo.c.patch
|
||||||
|
* 0009-Increase-portability-of-ares-test-mock-ai.cc-235.patch
|
||||||
|
- Add a patch which disables test failing on OBS (but passing in
|
||||||
|
local environment):
|
||||||
|
* 0010-Disable-failing-test.patch
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Feb 13 15:44:18 UTC 2019 - adam.majer@suse.de
|
Wed Feb 13 15:44:18 UTC 2019 - adam.majer@suse.de
|
||||||
|
|
||||||
|
25
c-ares.spec
25
c-ares.spec
@ -31,6 +31,26 @@ Source4: baselibs.conf
|
|||||||
Patch0: 0001-Use-RPM-compiler-options.patch
|
Patch0: 0001-Use-RPM-compiler-options.patch
|
||||||
Patch1: disable-live-tests.patch
|
Patch1: disable-live-tests.patch
|
||||||
Patch2: onion-crash.patch
|
Patch2: onion-crash.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM 0001-Add-initial-implementation-for-ares_getaddrinfo-112.patch
|
||||||
|
Patch3: 0001-Add-initial-implementation-for-ares_getaddrinfo-112.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM 0002-Remaining-queries-counter-fix-additional-unit-tests-.patch
|
||||||
|
Patch4: 0002-Remaining-queries-counter-fix-additional-unit-tests-.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM 0003-Bugfix-for-ares_getaddrinfo-and-additional-unit-test.patch
|
||||||
|
Patch5: 0003-Bugfix-for-ares_getaddrinfo-and-additional-unit-test.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM 0004-Add-ares__sortaddrinfo-to-support-getaddrinfo-sorted.patch
|
||||||
|
Patch6: 0004-Add-ares__sortaddrinfo-to-support-getaddrinfo-sorted.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM 0005-getaddrinfo-avoid-infinite-loop-in-case-of-NXDOMAIN-.patch
|
||||||
|
Patch7: 0005-getaddrinfo-avoid-infinite-loop-in-case-of-NXDOMAIN-.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM 0006-getaddrinfo-callback-must-be-called-on-bad-domain-24.patch
|
||||||
|
Patch8: 0006-getaddrinfo-callback-must-be-called-on-bad-domain-24.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM 0007-getaddrinfo-enhancements-257.patch
|
||||||
|
Patch9: 0007-getaddrinfo-enhancements-257.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM 0008-Add-missing-limits.h-include-from-ares_getaddrinfo.c.patch
|
||||||
|
Patch10: 0008-Add-missing-limits.h-include-from-ares_getaddrinfo.c.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM 0009-Increase-portability-of-ares-test-mock-ai.cc-235.patch
|
||||||
|
Patch11: 0009-Increase-portability-of-ares-test-mock-ai.cc-235.patch
|
||||||
|
# PATCH-FIX-OPENSUSE 0010-Disable-failing-test.patch
|
||||||
|
Patch12: 0010-Disable-failing-test.patch
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
BuildRequires: automake
|
BuildRequires: automake
|
||||||
BuildRequires: gcc-c++
|
BuildRequires: gcc-c++
|
||||||
@ -65,10 +85,7 @@ asynchronously. c-ares is a fork of the library named 'ares', written
|
|||||||
by Greg Hudson at MIT.
|
by Greg Hudson at MIT.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q
|
%autosetup -p1
|
||||||
%patch0 -p1
|
|
||||||
%patch1 -p1
|
|
||||||
%patch2 -p1
|
|
||||||
|
|
||||||
# Remove bogus cflags checking
|
# Remove bogus cflags checking
|
||||||
sed -i -e '/XC_CHECK_BUILD_FLAGS/d' configure.ac
|
sed -i -e '/XC_CHECK_BUILD_FLAGS/d' configure.ac
|
||||||
|
Loading…
Reference in New Issue
Block a user