SHA256
1
0
forked from pool/c-ares

Accepting request 746633 from home:adamm:node_test

Previous set of patches broke NodeJS 12.x unit tests. With the
complete upstream snapshot, the tests pass as the regressions
are fixed.

- Update to upstream snapshot 20191108
  * getaddrinfo - avoid infinite loop in case of NXDOMAIN
  * ares_getenv - return NULL in all cases
  * implement ares_getaddrinfo
- onion-crash.patch: removed, upstreamed.
- removed upstream patches that are part of the snapshot:
  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
  0010-Disable-failing-test.patch
- disable-live-tests.patch - updated

OBS-URL: https://build.opensuse.org/request/show/746633
OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/c-ares?expand=0&rev=11
This commit is contained in:
Tomáš Chvátal 2019-11-08 14:58:09 +00:00 committed by Git OBS Bridge
parent 4c1bcc5dd1
commit 42b6c9750c
17 changed files with 41 additions and 7627 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,280 +0,0 @@
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

View File

@ -1,781 +0,0 @@
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(), &notimplrsp));
+ 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(), &notimplrsp));
+ 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(), &notimplrsp));
+ 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(), &notimplrsp));
+ 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(), &notimplrsp));
+ 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(), &notimplrsp));
+ 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

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +0,0 @@
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

View File

@ -1,37 +0,0 @@
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

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +0,0 @@
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

View File

@ -1,70 +0,0 @@
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

View File

@ -1,36 +0,0 @@
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

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:327ca0ac334f8bcdc8d9da0cbc5e0ff2e304c248aab6cac8835936b1e3548a86
size 1362964

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6cdb97871f2930530c97deb7cf5c8fa4be5a0b02c7cea6e7c7667672a39d6852
size 1347687

View File

@ -1,11 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQEzBAABCgAdFiEEJ+3q8i86vOtQ25oSXMkI/bceEsIFAlvPiSoACgkQXMkI/bce
EsL1Twf/fAocxkO1QNQ0OQcX1Ga/LD37Z0S9gMNoOcW9ptB0G2A1T4IW4aN2gnko
tofSzeJ5kZZQ3Dk11MiWWxkowZn2+hE+/H13JRUgkJ9W0HS9wqxiTZksS2xORjvx
2KMeBLTcd2ordcnTP1Ufb8rzH9++3G+rgeAP7tqVnYx9y55u5onoAgwLwuw+ypOJ
ua0gjxysxCvg9li+c2ZvuOrFIv3sS7VBSsRJhoJwSVslCGGiDOQpH/AMq4Er7jBL
cTqVYUy3d7leaeRuGJaQb3q/CG8o+iE9CQBmituTYauP7fXQrjPdVKq7IQyqTboi
1M24ymm+IBgICBxVzXfx+PuotbwXIg==
=XhwX
-----END PGP SIGNATURE-----

View File

@ -1,3 +1,25 @@
-------------------------------------------------------------------
Fri Nov 8 11:16:29 UTC 2019 - Adam Majer <adam.majer@suse.de>
- Update to upstream snapshot 20191108
* getaddrinfo - avoid infinite loop in case of NXDOMAIN
* ares_getenv - return NULL in all cases
* implement ares_getaddrinfo
- onion-crash.patch: removed, upstreamed.
- removed upstream patches that are part of the snapshot:
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
0010-Disable-failing-test.patch
- disable-live-tests.patch - updated
-------------------------------------------------------------------
Wed Oct 23 15:11:27 UTC 2019 - Michał Rostecki <mrostecki@opensuse.org>

View File

@ -18,39 +18,22 @@
%define libname libcares2
Name: c-ares
Version: 1.15.0
Version: 1.15.0~20191108
Release: 0
Summary: Library for asynchronous name resolves
License: MIT
Group: Development/Libraries/C and C++
URL: http://c-ares.haxx.se/
Source0: http://c-ares.haxx.se/download/%{name}-%{version}.tar.gz
Source1: http://c-ares.haxx.se/download/%{name}-%{version}.tar.gz.asc
#Source0: https://c-ares.haxx.se/daily-snapshot/c-ares-1.15.0-20191108.tar.gz
Source0: c-ares-1.15.0-20191108.tar.gz
#Source0: http://c-ares.haxx.se/download/%{name}-%{version}.tar.gz
#Source1: http://c-ares.haxx.se/download/%{name}-%{version}.tar.gz.asc
Source3: %{name}.keyring
Source4: baselibs.conf
Patch0: 0001-Use-RPM-compiler-options.patch
Patch1: disable-live-tests.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
#Patch12: 0010-Disable-failing-test.patch
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: gcc-c++
@ -85,7 +68,7 @@ asynchronously. c-ares is a fork of the library named 'ares', written
by Greg Hudson at MIT.
%prep
%autosetup -p1
%autosetup -p1 -n c-ares-1.15.0-20191108
# Remove bogus cflags checking
sed -i -e '/XC_CHECK_BUILD_FLAGS/d' configure.ac

View File

@ -1,19 +1,20 @@
Index: c-ares-1.15.0/test/Makefile.inc
Index: c-ares-1.15.0-20191108/test/Makefile.inc
===================================================================
--- c-ares-1.15.0.orig/test/Makefile.inc
+++ c-ares-1.15.0/test/Makefile.inc
@@ -13,7 +13,6 @@ TESTSOURCES = ares-test-main.cc \
--- c-ares-1.15.0-20191108.orig/test/Makefile.inc
+++ c-ares-1.15.0-20191108/test/Makefile.inc
@@ -13,8 +13,6 @@ TESTSOURCES = ares-test-main.cc \
ares-test-parse-srv.cc \
ares-test-parse-txt.cc \
ares-test-misc.cc \
- ares-test-live.cc \
- ares-test-live-ai.cc \
ares-test-mock.cc \
ares-test-mock-ai.cc \
ares-test-internal.cc \
dns-proto.cc \
Index: c-ares-1.15.0/test/ares-test-misc.cc
Index: c-ares-1.15.0-20191108/test/ares-test-misc.cc
===================================================================
--- c-ares-1.15.0.orig/test/ares-test-misc.cc
+++ c-ares-1.15.0/test/ares-test-misc.cc
--- c-ares-1.15.0-20191108.orig/test/ares-test-misc.cc
+++ c-ares-1.15.0-20191108/test/ares-test-misc.cc
@@ -47,10 +47,12 @@ TEST_F(DefaultChannelTest, SetServers) {
EXPECT_EQ(expected, GetNameServers(channel_));

View File

@ -1,35 +0,0 @@
https://github.com/c-ares/c-ares/pull/241
From 98297b969880855c4ed514935bf5bb4cf2ae1ec0 Mon Sep 17 00:00:00 2001
From: XadillaX <i@2333.moe>
Date: Thu, 31 Jan 2019 13:14:06 +0800
Subject: [PATCH] fix: init bufp before reject .onion to make it can be free
correctly
---
ares_create_query.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/ares_create_query.c b/ares_create_query.c
index 1606b1a1..9efce17c 100644
--- a/ares_create_query.c
+++ b/ares_create_query.c
@@ -94,14 +94,14 @@ int ares_create_query(const char *name, int dnsclass, int type,
size_t buflen;
unsigned char *buf;
- /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
- if (ares__is_onion_domain(name))
- return ARES_ENOTFOUND;
-
/* Set our results early, in case we bail out early with an error. */
*buflenp = 0;
*bufp = NULL;
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ return ARES_ENOTFOUND;
+
/* Allocate a memory area for the maximum size this packet might need. +2
* is for the length byte and zero termination if no dots or ecscaping is
* used.