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:
parent
4c1bcc5dd1
commit
42b6c9750c
File diff suppressed because it is too large
Load Diff
@ -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
|
|
||||||
|
|
@ -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(), ¬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
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -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
|
|
||||||
|
|
@ -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
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
3
c-ares-1.15.0-20191108.tar.gz
Normal file
3
c-ares-1.15.0-20191108.tar.gz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:327ca0ac334f8bcdc8d9da0cbc5e0ff2e304c248aab6cac8835936b1e3548a86
|
||||||
|
size 1362964
|
@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:6cdb97871f2930530c97deb7cf5c8fa4be5a0b02c7cea6e7c7667672a39d6852
|
|
||||||
size 1347687
|
|
@ -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-----
|
|
@ -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>
|
Wed Oct 23 15:11:27 UTC 2019 - Michał Rostecki <mrostecki@opensuse.org>
|
||||||
|
|
||||||
|
31
c-ares.spec
31
c-ares.spec
@ -18,39 +18,22 @@
|
|||||||
|
|
||||||
%define libname libcares2
|
%define libname libcares2
|
||||||
Name: c-ares
|
Name: c-ares
|
||||||
Version: 1.15.0
|
Version: 1.15.0~20191108
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: Library for asynchronous name resolves
|
Summary: Library for asynchronous name resolves
|
||||||
License: MIT
|
License: MIT
|
||||||
Group: Development/Libraries/C and C++
|
Group: Development/Libraries/C and C++
|
||||||
URL: http://c-ares.haxx.se/
|
URL: http://c-ares.haxx.se/
|
||||||
Source0: http://c-ares.haxx.se/download/%{name}-%{version}.tar.gz
|
#Source0: https://c-ares.haxx.se/daily-snapshot/c-ares-1.15.0-20191108.tar.gz
|
||||||
Source1: http://c-ares.haxx.se/download/%{name}-%{version}.tar.gz.asc
|
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
|
Source3: %{name}.keyring
|
||||||
Source4: baselibs.conf
|
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
|
|
||||||
# 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
|
# PATCH-FIX-OPENSUSE 0010-Disable-failing-test.patch
|
||||||
Patch12: 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++
|
||||||
@ -85,7 +68,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
|
||||||
%autosetup -p1
|
%autosetup -p1 -n c-ares-1.15.0-20191108
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -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-20191108.orig/test/Makefile.inc
|
||||||
+++ c-ares-1.15.0/test/Makefile.inc
|
+++ c-ares-1.15.0-20191108/test/Makefile.inc
|
||||||
@@ -13,7 +13,6 @@ TESTSOURCES = ares-test-main.cc \
|
@@ -13,8 +13,6 @@ TESTSOURCES = ares-test-main.cc \
|
||||||
ares-test-parse-srv.cc \
|
ares-test-parse-srv.cc \
|
||||||
ares-test-parse-txt.cc \
|
ares-test-parse-txt.cc \
|
||||||
ares-test-misc.cc \
|
ares-test-misc.cc \
|
||||||
- ares-test-live.cc \
|
- ares-test-live.cc \
|
||||||
|
- ares-test-live-ai.cc \
|
||||||
ares-test-mock.cc \
|
ares-test-mock.cc \
|
||||||
|
ares-test-mock-ai.cc \
|
||||||
ares-test-internal.cc \
|
ares-test-internal.cc \
|
||||||
dns-proto.cc \
|
Index: c-ares-1.15.0-20191108/test/ares-test-misc.cc
|
||||||
Index: c-ares-1.15.0/test/ares-test-misc.cc
|
|
||||||
===================================================================
|
===================================================================
|
||||||
--- c-ares-1.15.0.orig/test/ares-test-misc.cc
|
--- c-ares-1.15.0-20191108.orig/test/ares-test-misc.cc
|
||||||
+++ c-ares-1.15.0/test/ares-test-misc.cc
|
+++ c-ares-1.15.0-20191108/test/ares-test-misc.cc
|
||||||
@@ -47,10 +47,12 @@ TEST_F(DefaultChannelTest, SetServers) {
|
@@ -47,10 +47,12 @@ TEST_F(DefaultChannelTest, SetServers) {
|
||||||
EXPECT_EQ(expected, GetNameServers(channel_));
|
EXPECT_EQ(expected, GetNameServers(channel_));
|
||||||
|
|
||||||
|
@ -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.
|
|
Loading…
Reference in New Issue
Block a user