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));
+}