dns_responder: Truncate UDP response which is larger than 512 bytes
Add support for testing truncated UDP is received and retrying over TCP.
test: cd packages/modules/DnsResolver && atest
Change-Id: I741110402c02771b6ad70a185ac946658d62224e
diff --git a/tests/resolv_integration_test.cpp b/tests/resolv_integration_test.cpp
index f95daee..8b500c4 100644
--- a/tests/resolv_integration_test.cpp
+++ b/tests/resolv_integration_test.cpp
@@ -3762,7 +3762,8 @@
class ResolverParameterizedTest : public ResolverTest,
public testing::WithParamInterface<CallType> {
protected:
- void VerifyQueryHelloExampleComV4(const test::DNSResponder& dns, const CallType calltype) {
+ void VerifyQueryHelloExampleComV4(const test::DNSResponder& dns, const CallType calltype,
+ const bool verifyNumQueries = true) {
if (calltype == CallType::GETADDRINFO) {
const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
@@ -3778,7 +3779,7 @@
} else {
FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
}
- EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
+ if (verifyNumQueries) EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
}
};
@@ -3992,3 +3993,43 @@
VerifyQueryHelloExampleComV4(dns, calltype);
}
}
+
+TEST_P(ResolverParameterizedTest, TruncatedResponse) {
+ const auto& calltype = GetParam();
+
+ const size_t kMaxmiumLabelSize = 63; // see RFC 1035 section 2.3.4.
+ const std::string kDomainName = ".example.com.";
+ const std::string kCnameA = std::string(kMaxmiumLabelSize, 'a') + kDomainName;
+ const std::string kCnameB = std::string(kMaxmiumLabelSize, 'b') + kDomainName;
+ const std::string kCnameC = std::string(kMaxmiumLabelSize, 'c') + kDomainName;
+ const std::string kCnameD = std::string(kMaxmiumLabelSize, 'd') + kDomainName;
+
+ // Build a response message which exceeds 512 bytes by CNAME chain.
+ //
+ // Ignoring the other fields of the message, the response message has 8 CNAMEs in 5 answer RRs
+ // and each CNAME has 77 bytes as the follows. The response message at least has 616 bytes in
+ // answer section and has already exceeded 512 bytes totally.
+ //
+ // The CNAME is presented as:
+ // 0 1 64 65 72 73 76 77
+ // +---+--........--+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ // | 63| {x, .., x} | 7 | e | x | a | m | p | l | e | 3 | c | o | m | 0 |
+ // +---+--........--+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ // ^-- x = {a, b, c, d}
+ //
+ const std::vector<DnsRecord> records = {
+ {kHelloExampleCom, ns_type::ns_t_cname, kCnameA},
+ {kCnameA, ns_type::ns_t_cname, kCnameB},
+ {kCnameB, ns_type::ns_t_cname, kCnameC},
+ {kCnameC, ns_type::ns_t_cname, kCnameD},
+ {kCnameD, ns_type::ns_t_a, kHelloExampleComAddrV4},
+ };
+ test::DNSResponder dns;
+ StartDns(dns, records);
+ ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+
+ // Expect UDP response is truncated. The resolver retries over TCP. See RFC 1035 section 4.2.1.
+ VerifyQueryHelloExampleComV4(dns, calltype, false);
+ EXPECT_EQ(1U, GetNumQueriesForProtocol(dns, IPPROTO_UDP, kHelloExampleCom));
+ EXPECT_EQ(1U, GetNumQueriesForProtocol(dns, IPPROTO_TCP, kHelloExampleCom));
+}