resolv_integration_test: Test RRs in authority section and additional section

The authority section and additional section may have relevant
information about the query. Although getanswer() of
packages/modules/DnsResolver/getaddrinfo.cpp doesn't parse the
content, check them that don't crash the resolver, just in case.

Test: cd packages/modules/DnsResolver && atest
Change-Id: I2b441687a574616f775737b469ebb3cc2dbc377e
diff --git a/resolv_integration_test.cpp b/resolv_integration_test.cpp
index 27e21d2..207dd05 100644
--- a/resolv_integration_test.cpp
+++ b/resolv_integration_test.cpp
@@ -3486,3 +3486,115 @@
     EXPECT_GE(3000, std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
     EXPECT_LE(1000, std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
 }
+
+// Parameterized tests.
+// TODO: Merge the existing tests as parameterized test if possible.
+// TODO: Perhaps move parameterized tests to an independent file.
+enum class CallType { GETADDRINFO, GETHOSTBYNAME };
+class ResolverParameterizedTest : public ResolverTest,
+                                  public testing::WithParamInterface<CallType> {};
+
+INSTANTIATE_TEST_SUITE_P(TestQueryCall, ResolverParameterizedTest,
+                         testing::Values(CallType::GETADDRINFO, CallType::GETHOSTBYNAME),
+                         [](const testing::TestParamInfo<CallType>& info) {
+                             std::string name;
+                             switch (info.param) {
+                                 case CallType::GETADDRINFO:
+                                     name = "GetAddrInfo";
+                                     break;
+                                 case CallType::GETHOSTBYNAME:
+                                     name = "GetHostByName";
+                                     break;
+                                 default:
+                                     name = "InvalidParameter";  // Should not happen.
+                             }
+                             return name;
+                         });
+
+TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
+    // DNS response may have more information in authority section and additional section.
+    // Currently, getanswer() of packages/modules/DnsResolver/getaddrinfo.cpp doesn't parse the
+    // content of authority section and additional section. Test these sections if they crash
+    // the resolver, just in case. See also RFC 1035 section 4.1.
+    const auto& calltype = GetParam();
+    test::DNSHeader header(kDefaultDnsHeader);
+
+    // Create a DNS response which has a authoritative nameserver record in authority
+    // section and its relevant address record in additional section.
+    //
+    // Question
+    //   hello.example.com.     IN      A
+    // Answer
+    //   hello.example.com.     IN      A   1.2.3.4
+    // Authority:
+    //   hello.example.com.     IN      NS  ns1.example.com.
+    // Additional:
+    //   ns1.example.com.       IN      A   5.6.7.8
+    //
+    // A response may have only question, answer, and authority section. Current testing response
+    // should be able to cover this condition.
+
+    // Question section.
+    test::DNSQuestion question{
+            .qname = {.name = kHelloExampleCom},
+            .qtype = ns_type::ns_t_a,
+            .qclass = ns_c_in,
+    };
+    header.questions.push_back(std::move(question));
+
+    // Answer section.
+    test::DNSRecord recordAnswer{
+            .name = {.name = kHelloExampleCom},
+            .rtype = ns_type::ns_t_a,
+            .rclass = ns_c_in,
+            .ttl = 0,  // no cache
+    };
+    EXPECT_TRUE(test::DNSResponder::fillRdata("1.2.3.4", recordAnswer));
+    header.answers.push_back(std::move(recordAnswer));
+
+    // Authority section.
+    test::DNSRecord recordAuthority{
+            .name = {.name = kHelloExampleCom},
+            .rtype = ns_type::ns_t_ns,
+            .rclass = ns_c_in,
+            .ttl = 0,  // no cache
+    };
+    EXPECT_TRUE(test::DNSResponder::fillRdata("ns1.example.com.", recordAuthority));
+    header.authorities.push_back(std::move(recordAuthority));
+
+    // Additional section.
+    test::DNSRecord recordAdditional{
+            .name = {.name = "ns1.example.com."},
+            .rtype = ns_type::ns_t_a,
+            .rclass = ns_c_in,
+            .ttl = 0,  // no cache
+    };
+    EXPECT_TRUE(test::DNSResponder::fillRdata("5.6.7.8", recordAdditional));
+    header.additionals.push_back(std::move(recordAdditional));
+
+    // Start DNS server.
+    test::DNSResponder dns(test::DNSResponder::MappingType::DNS_HEADER);
+    dns.addMappingDnsHeader(kHelloExampleCom, ns_type::ns_t_a, header);
+    ASSERT_TRUE(dns.startServer());
+    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
+    dns.clearQueries();
+
+    // Expect that get the address and the resolver doesn't crash.
+    if (calltype == CallType::GETADDRINFO) {
+        const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
+        ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
+        EXPECT_TRUE(result != nullptr);
+        EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
+        EXPECT_EQ("1.2.3.4", ToString(result));
+    } else if (calltype == CallType::GETHOSTBYNAME) {
+        const hostent* result = gethostbyname("hello");
+        EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
+        ASSERT_FALSE(result == nullptr);
+        ASSERT_EQ(4, result->h_length);
+        ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+        EXPECT_EQ("1.2.3.4", ToString(result));
+        EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+    } else {
+        FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
+    }
+}
\ No newline at end of file